Debug menu

dev-time-step
krzys-h 2016-03-28 13:51:39 +02:00
parent 45c93f58ec
commit 4af02c86f8
13 changed files with 607 additions and 78 deletions

View File

@ -218,6 +218,7 @@ set(BASE_SOURCES
script/scriptfunc.cpp script/scriptfunc.cpp
sound/sound.cpp sound/sound.cpp
sound/sound_type.cpp sound/sound_type.cpp
ui/debug_menu.cpp
ui/displayinfo.cpp ui/displayinfo.cpp
ui/displaytext.cpp ui/displaytext.cpp
ui/object_interface.cpp ui/object_interface.cpp

View File

@ -149,7 +149,7 @@ enum EventType
EVENT_WINDOW4 = 84, //!< CDisplayInfo EVENT_WINDOW4 = 84, //!< CDisplayInfo
EVENT_WINDOW5 = 85, //!< all menu windows EVENT_WINDOW5 = 85, //!< all menu windows
EVENT_WINDOW6 = 86, //!< code battle interface EVENT_WINDOW6 = 86, //!< code battle interface
EVENT_WINDOW7 = 87, //!< (unused) EVENT_WINDOW7 = 87, //!< debug interface
EVENT_WINDOW8 = 88, //!< (unused) EVENT_WINDOW8 = 88, //!< (unused)
EVENT_WINDOW9 = 89, //!< CMainDialog and CStudio file selector EVENT_WINDOW9 = 89, //!< CMainDialog and CStudio file selector
@ -380,6 +380,29 @@ enum EventType
EVENT_CMD = 800, EVENT_CMD = 800,
EVENT_SPEED = 801, EVENT_SPEED = 801,
EVENT_DBG_STATS = 850,
EVENT_DBG_SPAWN_OBJ = 851,
EVENT_DBG_TELEPORT = 852,
EVENT_DBG_LIGHTNING = 853,
EVENT_DBG_CRASHSPHERES = 854,
EVENT_DBG_LIGHTS = 855,
EVENT_DBG_LIGHTS_DUMP = 856,
EVENT_SPAWN_CANCEL = 860,
EVENT_SPAWN_ME = 861,
EVENT_SPAWN_WHEELEDGRABBER = 862,
EVENT_SPAWN_WHEELEDSHOOTER = 863,
EVENT_SPAWN_PHAZERSHOOTER = 864,
EVENT_SPAWN_BOTFACTORY = 865,
EVENT_SPAWN_CONVERTER = 866,
EVENT_SPAWN_DERRICK = 867,
EVENT_SPAWN_POWERSTATION= 868,
EVENT_SPAWN_TITANIUM = 869,
EVENT_SPAWN_TITANIUMORE = 870,
EVENT_SPAWN_URANIUMORE = 871,
EVENT_SPAWN_POWERCELL = 872,
EVENT_SPAWN_NUCLEARCELL = 873,
EVENT_HYPER_PREV = 900, EVENT_HYPER_PREV = 900,
EVENT_HYPER_NEXT = 901, EVENT_HYPER_NEXT = 901,
EVENT_HYPER_HOME = 902, EVENT_HYPER_HOME = 902,

View File

@ -392,18 +392,6 @@ bool CEngine::ProcessEvent(const Event &event)
m_showStats = !m_showStats; m_showStats = !m_showStats;
return false; return false;
} }
if (data->key == KEY(F11))
{
m_debugLights = !m_debugLights;
return false;
}
if (data->key == KEY(F10))
{
m_debugDumpLights = true;
return false;
}
} }
// By default, pass on all events // By default, pass on all events
@ -1753,17 +1741,18 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
mouse.y <= max.y ); mouse.y <= max.y );
} }
int CEngine::DetectObject(Math::Point mouse) int CEngine::DetectObject(Math::Point mouse, Math::Vector& targetPos, bool terrain)
{ {
float min = 1000000.0f; float min = 1000000.0f;
int nearest = -1; int nearest = -1;
Math::Vector pos;
for (int objRank = 0; objRank < static_cast<int>( m_objects.size() ); objRank++) for (int objRank = 0; objRank < static_cast<int>( m_objects.size() ); objRank++)
{ {
if (! m_objects[objRank].used) if (! m_objects[objRank].used)
continue; continue;
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN && !terrain)
continue; continue;
if (! DetectBBox(objRank, mouse)) if (! DetectBBox(objRank, mouse))
@ -1792,10 +1781,11 @@ int CEngine::DetectObject(Math::Point mouse)
for (int i = 0; i < static_cast<int>( p3.vertices.size() ); i += 3) for (int i = 0; i < static_cast<int>( p3.vertices.size() ); i += 3)
{ {
float dist = 0.0f; float dist = 0.0f;
if (DetectTriangle(mouse, &p3.vertices[i], objRank, dist) && dist < min) if (DetectTriangle(mouse, &p3.vertices[i], objRank, dist, pos) && dist < min)
{ {
min = dist; min = dist;
nearest = objRank; nearest = objRank;
targetPos = pos;
} }
} }
} }
@ -1804,10 +1794,11 @@ int CEngine::DetectObject(Math::Point mouse)
for (int i = 0; i < static_cast<int>( p3.vertices.size() ) - 2; i += 1) for (int i = 0; i < static_cast<int>( p3.vertices.size() ) - 2; i += 1)
{ {
float dist = 0.0f; float dist = 0.0f;
if (DetectTriangle(mouse, &p3.vertices[i], objRank, dist) && dist < min) if (DetectTriangle(mouse, &p3.vertices[i], objRank, dist, pos) && dist < min)
{ {
min = dist; min = dist;
nearest = objRank; nearest = objRank;
targetPos = pos;
} }
} }
} }
@ -1818,7 +1809,7 @@ int CEngine::DetectObject(Math::Point mouse)
return nearest; return nearest;
} }
bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist) bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist, Math::Vector& pos)
{ {
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size())); assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
@ -1865,6 +1856,16 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan
if (! Math::IsInsideTriangle(a, b, c, mouse)) if (! Math::IsInsideTriangle(a, b, c, mouse))
return false; return false;
Math::Vector a2 = Math::Transform(m_objects[objRank].transform, triangle[0].coord);
Math::Vector b2 = Math::Transform(m_objects[objRank].transform, triangle[1].coord);
Math::Vector c2 = Math::Transform(m_objects[objRank].transform, triangle[2].coord);
Math::Vector e = Math::Transform(m_matView.Inverse(), Math::Vector(0.0f, 0.0f, -1.0f));
Math::Vector f = Math::Transform(m_matView.Inverse(), Math::Vector(
(mouse.x*2.0f-1.0f)*m_matProj.Inverse().Get(1,1),
(mouse.y*2.0f-1.0f)*m_matProj.Inverse().Get(2,2),
0.0f));
Math::Intersect(a2, b2, c2, e, f, pos);
dist = (p2D[0].z + p2D[1].z + p2D[2].z) / 3.0f; dist = (p2D[0].z + p2D[1].z + p2D[2].z) / 3.0f;
return true; return true;
} }
@ -5078,4 +5079,19 @@ void CEngine::SetStaticMeshTransparency(int meshHandle, float value)
SetObjectTransparency(objRank, value); SetObjectTransparency(objRank, value);
} }
void CEngine::SetDebugLights(bool debugLights)
{
m_debugLights = debugLights;
}
bool CEngine::GetDebugLights()
{
return m_debugLights;
}
void CEngine::DebugDumpLights()
{
m_debugDumpLights = true;
}
} // namespace Gfx } // namespace Gfx

View File

@ -841,7 +841,7 @@ public:
//! Detects the target object that is selected with the mouse //! Detects the target object that is selected with the mouse
/** Returns the rank of the object or -1. */ /** Returns the rank of the object or -1. */
int DetectObject(Math::Point mouse); int DetectObject(Math::Point mouse, Math::Vector& targetPos, bool terrain = false);
//! Creates a shadow for the given object //! Creates a shadow for the given object
void CreateShadowSpot(int objRank); void CreateShadowSpot(int objRank);
@ -1184,6 +1184,10 @@ public:
void ClearDisplayCrashSpheres(); void ClearDisplayCrashSpheres();
void AddDisplayCrashSpheres(const std::vector<Math::Sphere>& crashSpheres); void AddDisplayCrashSpheres(const std::vector<Math::Sphere>& crashSpheres);
void SetDebugLights(bool debugLights);
bool GetDebugLights();
void DebugDumpLights();
protected: protected:
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed) //! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
/** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/ /** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/
@ -1250,7 +1254,7 @@ protected:
bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max); bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max);
//! Detects whether the mouse is in a triangle. //! Detects whether the mouse is in a triangle.
bool DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist); bool DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist, Math::Vector& pos);
//! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window //! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window
/** The coordinated p2D.z gives the distance. */ /** The coordinated p2D.z gives the distance. */

View File

@ -82,16 +82,24 @@ bool CLightning::EventProcess(const Event &event)
bool CLightning::EventFrame(const Event &event) bool CLightning::EventFrame(const Event &event)
{ {
if (m_terrain == nullptr)
m_terrain = CRobotMain::GetInstancePointer()->GetTerrain();
if (m_camera == nullptr)
m_camera = CRobotMain::GetInstancePointer()->GetCamera();
if (m_sound == nullptr)
m_sound = CApplication::GetInstancePointer()->GetSound();
if (m_engine->GetPause()) return true; if (m_engine->GetPause()) return true;
if (CRobotMain::GetInstancePointer()->GetMovieLock()) return true; if (CRobotMain::GetInstancePointer()->GetMovieLock()) return true;
m_progress += event.rTime*m_speed; m_progress += event.rTime*m_speed;
if (m_phase == LightningPhase::Wait) if (m_phase == LightningPhase::Wait && m_lightningExists)
{ {
if (m_progress >= 1.0f) if (m_progress >= 1.0f)
{ {
m_pos.x = (Math::Rand()-0.5f)*(3200.0f-200.0f); m_pos.x = (Math::Rand()-0.5f)*(3200.0f-200.0f);
m_pos.z = (Math::Rand()-0.5f)*(3200.0f-200.0f); m_pos.z = (Math::Rand()-0.5f)*(3200.0f-200.0f);
m_pos.y = 0.0f; m_pos.y = 0.0f;
@ -127,21 +135,7 @@ bool CLightning::EventFrame(const Event &event)
} }
} }
Math::Vector eye = m_engine->GetEyePt(); StrikeAtPos(m_pos);
float dist = Math::Distance(m_pos, eye);
float deep = m_engine->GetDeepView();
if (dist < deep)
{
Math::Vector pos = eye+((m_pos-eye)*0.2f); // like so close!
m_sound->Play(SOUND_BLITZ, pos);
m_camera->StartOver(CAM_OVER_EFFECT_LIGHTNING, m_pos, 1.0f);
m_phase = LightningPhase::Flash;
m_progress = 0.0f;
m_speed = 1.0f;
}
} }
} }
@ -193,15 +187,6 @@ bool CLightning::Create(float sleep, float delay, float magnetic)
m_progress = 0.0f; m_progress = 0.0f;
m_speed = 1.0f / m_sleep; m_speed = 1.0f / m_sleep;
if (m_terrain == nullptr)
m_terrain = CRobotMain::GetInstancePointer()->GetTerrain();
if (m_camera == nullptr)
m_camera = CRobotMain::GetInstancePointer()->GetCamera();
if (m_sound == nullptr)
m_sound = CApplication::GetInstancePointer()->GetSound();
return false; return false;
} }
@ -233,7 +218,6 @@ bool CLightning::SetStatus(float sleep, float delay, float magnetic, float progr
void CLightning::Draw() void CLightning::Draw()
{ {
if (!m_lightningExists) return;
if (m_phase != LightningPhase::Flash) return; if (m_phase != LightningPhase::Flash) return;
CDevice* device = m_engine->GetDevice(); CDevice* device = m_engine->GetDevice();
@ -368,4 +352,25 @@ CObject* CLightning::SearchObject(Math::Vector pos)
} }
void CLightning::StrikeAtPos(Math::Vector pos)
{
m_pos = pos;
Math::Vector eye = m_engine->GetEyePt();
float dist = Math::Distance(m_pos, eye);
float deep = m_engine->GetDeepView();
if (dist < deep)
{
Math::Vector pos = eye+((m_pos-eye)*0.2f); // like so close!
m_sound->Play(SOUND_BLITZ, pos);
m_camera->StartOver(CAM_OVER_EFFECT_LIGHTNING, m_pos, 1.0f);
m_phase = LightningPhase::Flash;
m_progress = 0.0f;
m_speed = 1.0f;
}
}
} // namespace Gfx } // namespace Gfx

View File

@ -75,6 +75,9 @@ public:
//! Draws lightning //! Draws lightning
void Draw(); void Draw();
//! Shoots lightning strike at given position
void StrikeAtPos(Math::Vector pos);
protected: protected:
//! Updates lightning //! Updates lightning
bool EventFrame(const Event &event); bool EventFrame(const Event &event);

View File

@ -3724,12 +3724,4 @@ Color CParticle::GetFogColor(Math::Vector pos)
return result; return result;
} }
bool CParticle::WriteWheelTrace(const char *filename, int width, int height,
Math::Vector dl, Math::Vector ur)
{
// TODO: stub!
GetLogger()->Trace("CParticle::WriteWheelTrace(): stub!\n");
return true;
}
} // namespace Gfx } // namespace Gfx

View File

@ -291,9 +291,6 @@ public:
//! Draws all the particles //! Draws all the particles
void DrawParticle(int sheet); void DrawParticle(int sheet);
//! Writes a file containing all the tire tracks
bool WriteWheelTrace(const char *filename, int width, int height, Math::Vector dl, Math::Vector ur);
protected: protected:
//! Removes a particle of given rank //! Removes a particle of given rank
void DeleteRank(int rank); void DeleteRank(int rank);

View File

@ -86,6 +86,7 @@
#include "sound/sound.h" #include "sound/sound.h"
#include "ui/debug_menu.h"
#include "ui/displayinfo.h" #include "ui/displayinfo.h"
#include "ui/displaytext.h" #include "ui/displaytext.h"
#include "ui/maindialog.h" #include "ui/maindialog.h"
@ -162,6 +163,8 @@ CRobotMain::CRobotMain()
m_modelManager.get(), m_modelManager.get(),
m_particle); m_particle);
m_debugMenu = MakeUnique<Ui::CDebugMenu>(this, m_engine, m_objMan.get(), m_sound);
m_time = 0.0f; m_time = 0.0f;
m_gameTime = 0.0f; m_gameTime = 0.0f;
m_gameTimeAbsolute = 0.0f; m_gameTimeAbsolute = 0.0f;
@ -650,6 +653,12 @@ Phase CRobotMain::GetPhase()
bool CRobotMain::ProcessEvent(Event &event) bool CRobotMain::ProcessEvent(Event &event)
{ {
if (!m_ui->EventProcess(event)) return false; if (!m_ui->EventProcess(event)) return false;
if (m_phase == PHASE_SIMUL)
{
if (!m_editFull)
m_camera->EventProcess(event);
}
if (!m_debugMenu->EventProcess(event)) return false;
if (event.type == EVENT_FRAME) if (event.type == EVENT_FRAME)
{ {
@ -763,6 +772,15 @@ bool CRobotMain::ProcessEvent(Event &event)
} }
return false; return false;
} }
if (IsPhaseWithWorld(m_phase))
{
if (data->key == KEY(F11))
{
m_debugMenu->ToggleInterface();
return false;
}
}
} }
if (event.type == EVENT_KEY_DOWN && if (event.type == EVENT_KEY_DOWN &&
@ -830,9 +848,6 @@ bool CRobotMain::ProcessEvent(Event &event)
// Simulation phase of the game // Simulation phase of the game
if (m_phase == PHASE_SIMUL) if (m_phase == PHASE_SIMUL)
{ {
if (!m_editFull)
m_camera->EventProcess(event);
switch (event.type) switch (event.type)
{ {
case EVENT_KEY_DOWN: case EVENT_KEY_DOWN:
@ -841,11 +856,6 @@ bool CRobotMain::ProcessEvent(Event &event)
KeyCamera(event.type, data->slot); KeyCamera(event.type, data->slot);
HiliteClear(); HiliteClear();
if (data->key == KEY(F11))
{
m_particle->WriteWheelTrace("Savegame/t.png", 256, 256, Math::Vector(16.0f, 0.0f, -368.0f), Math::Vector(140.0f, 0.0f, -248.0f));
return false;
}
if (m_editLock) // current edition? if (m_editLock) // current edition?
{ {
if (data->slot == INPUT_SLOT_HELP) if (data->slot == INPUT_SLOT_HELP)
@ -1400,16 +1410,6 @@ void CRobotMain::ExecuteCmd(const std::string& cmd)
} }
return; return;
} }
if (cmd == "debugcrashon")
{
m_debugCrashSpheres = true;
return;
}
if (cmd == "debugcrashoff")
{
m_debugCrashSpheres = false;
return;
}
} }
if (cmd == "debugmode") if (cmd == "debugmode")
@ -1993,7 +1993,8 @@ CObject* CRobotMain::GetSelect()
//! Detects the object aimed by the mouse //! Detects the object aimed by the mouse
CObject* CRobotMain::DetectObject(Math::Point pos) CObject* CRobotMain::DetectObject(Math::Point pos)
{ {
int objRank = m_engine->DetectObject(pos); Math::Vector p;
int objRank = m_engine->DetectObject(pos, p);
for (CObject* obj : m_objMan->GetAllObjects()) for (CObject* obj : m_objMan->GetAllObjects())
{ {
@ -6007,3 +6008,13 @@ void CRobotMain::UpdateDebugCrashSpheres()
} }
} }
} }
void CRobotMain::SetDebugCrashSpheres(bool draw)
{
m_debugCrashSpheres = draw;
}
bool CRobotMain::GetDebugCrashSpheres()
{
return m_debugCrashSpheres;
}

View File

@ -113,6 +113,7 @@ class CMainMap;
class CInterface; class CInterface;
class CDisplayText; class CDisplayText;
class CDisplayInfo; class CDisplayInfo;
class CDebugMenu;
} }
struct NewScriptName struct NewScriptName
@ -361,6 +362,10 @@ public:
bool IsSelectable(CObject* obj); bool IsSelectable(CObject* obj);
void SetDebugCrashSpheres(bool draw);
bool GetDebugCrashSpheres();
protected: protected:
bool EventFrame(const Event &event); bool EventFrame(const Event &event);
bool EventObject(const Event &event); bool EventObject(const Event &event);
@ -432,6 +437,7 @@ protected:
std::unique_ptr<Ui::CInterface> m_interface; std::unique_ptr<Ui::CInterface> m_interface;
std::unique_ptr<Ui::CDisplayInfo> m_displayInfo; std::unique_ptr<Ui::CDisplayInfo> m_displayInfo;
std::unique_ptr<Ui::CDisplayText> m_displayText; std::unique_ptr<Ui::CDisplayText> m_displayText;
std::unique_ptr<Ui::CDebugMenu> m_debugMenu;
std::unique_ptr<CSettings> m_settings; std::unique_ptr<CSettings> m_settings;
//! Progress of loaded player //! Progress of loaded player

View File

@ -135,7 +135,8 @@ bool CTarget::GetTooltip(Math::Point pos, std::string &name)
CObject* CTarget::DetectFriendObject(Math::Point pos) CObject* CTarget::DetectFriendObject(Math::Point pos)
{ {
int objRank = m_engine->DetectObject(pos); Math::Vector p;
int objRank = m_engine->DetectObject(pos, p);
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{ {

400
src/ui/debug_menu.cpp Normal file
View File

@ -0,0 +1,400 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#include "ui/debug_menu.h"
#include "common/event.h"
#include "graphics/engine/lightning.h"
#include "graphics/engine/terrain.h"
#include "level/robotmain.h"
#include "object/object_create_params.h"
#include "object/object_manager.h"
#include "object/object.h"
#include "ui/controls/interface.h"
#include "ui/controls/window.h"
#include "ui/controls/check.h"
#include "ui/controls/button.h"
namespace Ui
{
CDebugMenu::CDebugMenu(CRobotMain* main, Gfx::CEngine* engine, CObjectManager* objMan, CSoundInterface* sound)
{
m_main = main;
m_interface = m_main->GetInterface();
m_engine = engine;
m_objMan = objMan;
m_sound = sound;
}
CDebugMenu::~CDebugMenu()
{
}
void CDebugMenu::ToggleInterface()
{
if (m_interface->SearchControl(EVENT_WINDOW7) == nullptr)
CreateInterface();
else
DestroyInterface();
}
const Math::Point dim = Math::Point(33.0f/640.0f, 33.0f/480.0f);
const float ox = 3.0f/640.0f, oy = 3.0f/480.0f;
const float sx = 33.0f/640.0f, sy = 33.0f/480.0f;
void CDebugMenu::CreateInterface()
{
CWindow* pw = m_interface->CreateWindows(Math::Point(), Math::Point(), 0, EVENT_WINDOW7);
Math::Point pos, ddim;
CCheck* pc;
CButton* pb;
ddim.x = 4*dim.x+4*ox;
ddim.y = 222.0f/480.0f;
pos.x = 1.0f-ddim.x;
pos.y = oy+sy*3.0f;
pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW7);
ddim.x = ddim.x - 4*ox;
ddim.y = dim.y*0.5f;
pos.x += 2*ox;
pos.y = oy+sy*9.0f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_DBG_SPAWN_OBJ);
pb->SetName("Spawn object");
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_DBG_TELEPORT);
pb->SetName("Teleport");
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_DBG_LIGHTNING);
pb->SetName("Lightning");
pos.y -= 0.048f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_DBG_STATS);
pc->SetName("Display stats");
pos.y -= 0.048f;
pos.y -= 0.048f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_DBG_CRASHSPHERES);
pc->SetName("Render crash spheres");
pos.y -= 0.048f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_DBG_LIGHTS);
pc->SetName("Render dynamic lights");
pos.y -= 0.048f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_DBG_LIGHTS_DUMP);
pb->SetName("Dump lights to log");
UpdateInterface();
}
void CDebugMenu::CreateSpawnInterface()
{
CWindow* pw = m_interface->CreateWindows(Math::Point(), Math::Point(), 0, EVENT_WINDOW7);
Math::Point pos, ddim;
CButton* pb;
ddim.x = 4*dim.x+4*ox;
ddim.y = 222.0f/480.0f;
pos.x = 1.0f-ddim.x;
pos.y = oy+sy*3.0f;
pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW7);
ddim.x = ddim.x - 4*ox;
ddim.y = dim.y*0.5f;
pos.x += 2*ox;
pos.y = oy+sy*9.0f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_SPAWN_CANCEL);
pb->SetName("Cancel");
pos.y -= dim.y;
pw->CreateButton(pos, dim, 128+8, EVENT_SPAWN_ME);
pos.x += dim.x;
pw->CreateButton(pos, dim, 128+9, EVENT_SPAWN_WHEELEDGRABBER);
pos.x += dim.x;
pw->CreateButton(pos, dim, 128+15, EVENT_SPAWN_WHEELEDSHOOTER);
pos.x += dim.x;
pw->CreateButton(pos, dim, 128+19, EVENT_SPAWN_PHAZERSHOOTER);
pos.x -= 3*dim.x;
pos.y -= dim.y;
pw->CreateButton(pos, dim, 128+32, EVENT_SPAWN_BOTFACTORY);
pos.x += dim.x;
pw->CreateButton(pos, dim, 128+34, EVENT_SPAWN_CONVERTER);
pos.x += dim.x;
pw->CreateButton(pos, dim, 128+33, EVENT_SPAWN_DERRICK);
pos.x += dim.x;
pw->CreateButton(pos, dim, 128+36, EVENT_SPAWN_POWERSTATION);
pos.x -= 3*dim.x;
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_SPAWN_TITANIUM);
pb->SetName("Titanium");
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_SPAWN_TITANIUMORE);
pb->SetName("TitaniumOre");
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_SPAWN_URANIUMORE);
pb->SetName("UraniumOre");
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_SPAWN_POWERCELL);
pb->SetName("PowerCell");
pos.y -= ddim.y;
pb = pw->CreateButton(pos, ddim, -1, EVENT_SPAWN_NUCLEARCELL);
pb->SetName("NuclearCell");
}
const std::map<EventType, ObjectType> SPAWN_TYPES = {
{EVENT_SPAWN_ME, OBJECT_HUMAN},
{EVENT_SPAWN_WHEELEDGRABBER, OBJECT_MOBILEwa},
{EVENT_SPAWN_WHEELEDSHOOTER, OBJECT_MOBILEwc},
{EVENT_SPAWN_PHAZERSHOOTER, OBJECT_MOBILErc},
{EVENT_SPAWN_BOTFACTORY, OBJECT_FACTORY},
{EVENT_SPAWN_CONVERTER, OBJECT_CONVERT},
{EVENT_SPAWN_DERRICK, OBJECT_DERRICK},
{EVENT_SPAWN_POWERSTATION, OBJECT_STATION},
{EVENT_SPAWN_TITANIUM, OBJECT_METAL},
{EVENT_SPAWN_TITANIUMORE, OBJECT_STONE},
{EVENT_SPAWN_URANIUMORE, OBJECT_URANIUM},
{EVENT_SPAWN_POWERCELL, OBJECT_POWER},
{EVENT_SPAWN_NUCLEARCELL, OBJECT_ATOMIC},
};
void CDebugMenu::UpdateInterface()
{
CCheck* pc;
CButton* pb;
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW7));
if (pw == nullptr) return;
pb = static_cast<CButton*>(pw->SearchControl(EVENT_DBG_LIGHTNING));
if (pb != nullptr)
{
pb->SetName(m_lightningActive ? "Disable lightning" : "Lightning");
}
pb = static_cast<CButton*>(pw->SearchControl(EVENT_DBG_TELEPORT));
if (pb != nullptr)
{
pb->SetName(m_teleportActive ? "Abort teleport" : "Teleport");
}
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_DBG_STATS));
if (pc != nullptr)
{
pc->SetState(STATE_CHECK, m_engine->GetShowStats());
}
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_DBG_CRASHSPHERES));
if (pc != nullptr)
{
pc->SetState(STATE_CHECK, m_main->GetDebugCrashSpheres());
}
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_DBG_LIGHTS));
if (pc != nullptr)
{
pc->SetState(STATE_CHECK, m_engine->GetDebugLights());
}
for (const auto& it : SPAWN_TYPES)
{
pb = static_cast<CButton*>(pw->SearchControl(it.first));
if (pb != nullptr)
{
pb->SetState(STATE_ENABLE, it.second != m_spawningType);
}
}
}
void CDebugMenu::DestroyInterface()
{
m_interface->DeleteControl(EVENT_WINDOW7);
m_spawningType = OBJECT_NULL;
}
bool CDebugMenu::EventProcess(const Event &event)
{
switch (event.type)
{
case EVENT_DBG_STATS:
m_engine->SetShowStats(!m_engine->GetShowStats());
UpdateInterface();
break;
case EVENT_DBG_SPAWN_OBJ:
DestroyInterface();
CreateSpawnInterface();
break;
case EVENT_DBG_TELEPORT:
if (!m_teleportActive)
{
if (m_main->GetSelect() != nullptr)
m_teleportActive = true;
else
m_sound->Play(SOUND_CLICK);
}
else
{
m_teleportActive = false;
}
UpdateInterface();
break;
case EVENT_DBG_LIGHTNING:
m_lightningActive = !m_lightningActive;
UpdateInterface();
break;
case EVENT_DBG_CRASHSPHERES:
m_main->SetDebugCrashSpheres(!m_main->GetDebugCrashSpheres());
UpdateInterface();
break;
case EVENT_DBG_LIGHTS:
m_engine->SetDebugLights(!m_engine->GetDebugLights());
UpdateInterface();
break;
case EVENT_DBG_LIGHTS_DUMP:
m_engine->DebugDumpLights();
break;
case EVENT_SPAWN_CANCEL:
DestroyInterface();
CreateInterface();
break;
case EVENT_SPAWN_ME:
case EVENT_SPAWN_WHEELEDGRABBER:
case EVENT_SPAWN_WHEELEDSHOOTER:
case EVENT_SPAWN_PHAZERSHOOTER:
case EVENT_SPAWN_BOTFACTORY:
case EVENT_SPAWN_CONVERTER:
case EVENT_SPAWN_DERRICK:
case EVENT_SPAWN_POWERSTATION:
case EVENT_SPAWN_TITANIUM:
case EVENT_SPAWN_TITANIUMORE:
case EVENT_SPAWN_URANIUMORE:
case EVENT_SPAWN_POWERCELL:
case EVENT_SPAWN_NUCLEARCELL:
m_spawningType = SPAWN_TYPES.at(event.type);
UpdateInterface();
break;
case EVENT_MOUSE_BUTTON_DOWN:
if (event.GetData<MouseButtonEventData>()->button == MOUSE_BUTTON_LEFT)
{
if (m_lightningActive)
{
return !HandleLightning(event.mousePos);
}
if (m_teleportActive)
{
return !HandleTeleport(event.mousePos);
}
if (m_spawningType != OBJECT_NULL)
{
return !HandleSpawnObject(m_spawningType, event.mousePos);
}
}
break;
case EVENT_MOUSE_MOVE:
if (m_spawningType != OBJECT_NULL || m_teleportActive || m_lightningActive)
{
return false;
}
break;
default:
break;
}
return true;
}
bool CDebugMenu::HandleSpawnObject(ObjectType type, Math::Point mousePos)
{
Math::Vector pos;
if (m_engine->DetectObject(mousePos, pos, true) == -1)
{
m_sound->Play(SOUND_CLICK, 1.0f, 0.5f);
return false;
}
ObjectCreateParams params;
params.pos = pos;
params.type = type;
params.power = 100.0f;
m_objMan->CreateObject(params);
// Update shortcuts in the upper-left corner
m_main->CreateShortcuts();
m_sound->Play(SOUND_RADAR, 2.0f, 1.5f);
return true;
}
bool CDebugMenu::HandleLightning(Math::Point mousePos)
{
Math::Vector pos;
if (m_engine->DetectObject(mousePos, pos, true) == -1)
{
m_sound->Play(SOUND_CLICK, 1.0f, 0.5f);
return false;
}
m_engine->GetLightning()->StrikeAtPos(pos);
return true;
}
bool CDebugMenu::HandleTeleport(Math::Point mousePos)
{
CObject* select = m_main->GetSelect();
Math::Vector pos;
if (m_engine->DetectObject(mousePos, pos, true) == -1 || !m_engine->GetTerrain()->AdjustToFloor(pos) || select == nullptr)
{
m_sound->Play(SOUND_CLICK, 1.0f, 0.5f);
m_teleportActive = false;
UpdateInterface();
return false;
}
select->SetPosition(pos);
m_sound->Play(SOUND_BUILD, 4.0f, 0.75f);
m_sound->Play(SOUND_BUILD, pos, 4.0f, 0.75f);
m_teleportActive = false;
UpdateInterface();
return true;
}
}

70
src/ui/debug_menu.h Normal file
View File

@ -0,0 +1,70 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include <math/point.h>
#include <sound/sound.h>
#include "object/object_type.h"
class CRobotMain;
class CObjectManager;
struct Event;
namespace Gfx
{
class CEngine;
}
namespace Ui
{
class CInterface;
class CDebugMenu
{
public:
CDebugMenu(CRobotMain* main, Gfx::CEngine* engine, CObjectManager* objMan, CSoundInterface* sound);
virtual ~CDebugMenu();
void ToggleInterface();
bool EventProcess(const Event& event);
protected:
void CreateInterface();
void CreateSpawnInterface();
void UpdateInterface();
void DestroyInterface();
bool HandleSpawnObject(ObjectType type, Math::Point mousePos);
bool HandleLightning(Math::Point mousePos);
bool HandleTeleport(Math::Point mousePos);
protected:
CRobotMain* m_main;
CInterface* m_interface;
Gfx::CEngine* m_engine;
CObjectManager* m_objMan;
CSoundInterface* m_sound;
ObjectType m_spawningType = OBJECT_NULL;
bool m_lightningActive = false;
bool m_teleportActive = false;
};
}