From 3e05c967ab1d4756e763696e0ede2350e04e9e71 Mon Sep 17 00:00:00 2001 From: "Martin Felis (lola)" Date: Sun, 2 Jan 2011 21:04:11 +0100 Subject: [PATCH] improved editor (deletion of entities and better loading dialog) --- asteroids/Controller.cc | 4 ++- asteroids/Model.cc | 2 +- asteroids/View.cc | 71 +++++++++++++++++++++++++---------------- asteroids/View.h | 1 + engine/Engine.cc | 13 ++++++++ engine/Engine.h | 4 +++ engine/ModelBase.cc | 2 +- 7 files changed, 67 insertions(+), 30 deletions(-) diff --git a/asteroids/Controller.cc b/asteroids/Controller.cc index c817768..e98037c 100644 --- a/asteroids/Controller.cc +++ b/asteroids/Controller.cc @@ -35,6 +35,9 @@ bool Controller::OnReceiveEvent (const Engine::EventBasePtr &event) { void Controller::ResetPlayerEntity () { Engine::HaltSoundLoop(Engine::GetResourceFullPath("/data/sounds/thrust.wav")); + // We definitely have to reset the player entity id + GetModel()->SetPlayerEntityId(Engine::NullEntityId); + Engine::EntityBase *player_entity = GetModel()->GetEntity(GetModel()->GetPlayerEntityId()); // if we were unable to get the player then there is no need to invalidate @@ -46,7 +49,6 @@ void Controller::ResetPlayerEntity () { for (i = 0; i < EntityControllerMaxKeyStates; i++) player_entity->UnsetControllerKeyState(i); - GetModel()->SetPlayerEntityId(Engine::NullEntityId); } void Controller::ResetLevel() { diff --git a/asteroids/Model.cc b/asteroids/Model.cc index 19f78b4..2a318ba 100644 --- a/asteroids/Model.cc +++ b/asteroids/Model.cc @@ -250,7 +250,7 @@ int Model::DoLoadLevel (const char* filename) { std::fstream level_file (filename, std::ios::in); if (!level_file) { - Engine::LogError ("Unable to open file %s for writing!", filename); + Engine::LogError ("Unable to open file %s for reading!", filename); exit (-1); } diff --git a/asteroids/View.cc b/asteroids/View.cc index 1d70e9c..265b462 100644 --- a/asteroids/View.cc +++ b/asteroids/View.cc @@ -105,8 +105,10 @@ bool View::OnReceiveEvent (const Engine::EventBasePtr &event) { break; case EventLevelComplete: - PushViewState(ViewStateLevelComplete); - GetController()->ResetPlayerEntity(); + if (GetModel()->GetGameState() == GameStateRunning) { + PushViewState(ViewStateLevelComplete); + GetController()->ResetPlayerEntity(); + } break; case EventGameOver: @@ -489,6 +491,7 @@ void View::DrawUiMainMenu() { if (Engine::GUI::Button (6, "E", screen_right - 48, 20, 32, button_height)) { PushViewState(ViewStateEditor); + GetController()->ResetLevel(); } if (Engine::GUI::Button (4, "Quit", screen_right * 0.5 - 100, 380, button_width, button_height)) { @@ -768,14 +771,6 @@ void View::DrawUiEditor() { // DrawPageTitle ("Editor"); SelectFont ("console.ttf size=23"); - // Special case: if we get here and are currently in the editor state - // EditorStateTest, then we returned from our test. In this case we have to - // reset the editor state - if (mEditorState == EditorStateTest) { -// mEditorState = EditorStateUnknown; -// Engine::LogMessage ("Returned from testing"); - } - // The close button if (Engine::GUI::Button (1, "X", screen_right - 48, 20, 32, button_height) || Engine::GUI::CheckKeyPress(SDLK_ESCAPE)) { @@ -790,31 +785,40 @@ void View::DrawUiEditor() { } if (mEditorState != EditorStateTest) { - if (Engine::GUI::Button (2, "+", 30, 20, 32, button_height)) { + if (Engine::GUI::Button (2, "Add", 30, 20, 50, button_height)) { mEditorState = EditorStateAddEntity; } - if (Engine::GUI::Button (3, "M", 70, 20, 32, button_height)) { + if (Engine::GUI::Button (3, "Del", 85, 20, 50, button_height)) { + mEditorState = EditorStateDelEntity; + } + + if (Engine::GUI::Button (4, "Move", 140, 20, 65, button_height)) { mEditorState = EditorStateMoveEntity; } - if (Engine::GUI::Button (4, "V", 110, 20, 32, button_height)) { + if (Engine::GUI::Button (5, "Spd", 210, 20, 50, button_height)) { mEditorState = EditorStateEntityVelocity; } - if (Engine::GUI::Button (5, "S", 150, 20, 32, button_height)) { + if (Engine::GUI::Button (6, "Save", 265, 20, 65, button_height)) { mEditorState = EditorStateSave; } - if (Engine::GUI::Button (6, "L", 190, 20, 32, button_height)) { + if (Engine::GUI::Button (7, "Load", 335, 20, 65, button_height)) { mEditorState = EditorStateLoad; } - if (Engine::GUI::Button (7, "T", 230, 20, 32, button_height)) { - mEditorState = EditorStateTest; + // we only show the Test button when there is actually something to play + // (i.e. a player entity and at least one asteroid) + if (GetModel()->GetPlayerEntityId() != 0 + && GetModel()->mAsteroids.size() > 0) { + if (Engine::GUI::Button (8, "Test", 405, 20, 64, button_height)) { + mEditorState = EditorStateTest; - GetModel()->DoSaveLevel("level_edit_temp.txt"); - GetModel()->SetGameState(GameStateRunning); + GetModel()->DoSaveLevel("level_edit_temp.txt"); + GetModel()->SetGameState(GameStateRunning); + } } } @@ -834,21 +838,32 @@ void View::DrawUiEditor() { // an asteroid Engine::EntityBase* entity = NULL; - GameEntityType entity_type = GameEntityTypeShip; - if (GetModel()->GetPlayerEntityId() != 0) { + if (GetModel()->GetPlayerEntityId() != Engine::NullEntityId) { entity = Engine::CreateEntity(GameEntityTypeAsteroid); entity->mPhysicState->SetVelocity (vector3d (0., 0., -1.)); } else { entity = Engine::CreateEntity(GameEntityTypeShip); GetModel()->SetPlayerEntityId(entity->mId); - entity->mPhysicState->SetOrientation (vector3d (0., 90., 0.)); } // Now we want to insert an Asteroid at the given position entity->mPhysicState->SetPosition (vector3d (mouse_world_pos[0], 0., mouse_world_pos[2])); + } + } - mEditorState = EditorStateUnknown; + if (mEditorState == EditorStateDelEntity) { + SelectFont ("console.ttf size=12"); + Engine::GUI::Label (9999, "Deleting", 128, 16); + + if (controller->GetButtonState(MouseButtonLeft)) { + // Check if there is an entity near the given position + Engine::EntityBase* entity = Engine::GetEntityAt (mouse_world_pos); + + if (entity && entity->mType == GameEntityTypeAsteroid) { + Engine::LogMessage ("Killing entity with id %u", entity->mId); + GetModel()->UnregisterEntity (entity->mId); + } } } @@ -941,10 +956,12 @@ void View::DrawUiEditor() { if (Engine::GUI::LineEdit(52, 145, 210, level_name, 32)) GetModel()->SetLevelName(level_name); - if (Engine::GUI::Button (54, "Load", 145, 300, button_width, button_height)) { - GetModel()->DoLoadLevel((level_name + std::string(".txt")).c_str()); - Engine::LogMessage ("Load"); - mEditorState = EditorStateUnknown; + if (Engine::FileExists (level_name + std::string(".txt"))) { + if (Engine::GUI::Button (54, "Load", 145, 300, button_width, button_height)) { + GetModel()->DoLoadLevel((level_name + std::string(".txt")).c_str()); + Engine::LogMessage ("Load"); + mEditorState = EditorStateUnknown; + } } if (Engine::GUI::Button (55, "Cancel", screen_right - 140 - 5 - button_width, 300, button_width, button_height)) diff --git a/asteroids/View.h b/asteroids/View.h index da76599..84bfc49 100644 --- a/asteroids/View.h +++ b/asteroids/View.h @@ -136,6 +136,7 @@ class View : public Engine::ViewBase { enum EditorState { EditorStateUnknown = 0, EditorStateAddEntity, + EditorStateDelEntity, EditorStateMoveEntity, EditorStateSave, EditorStateEntityVelocity, diff --git a/engine/Engine.cc b/engine/Engine.cc index dc60a1a..681ab40 100644 --- a/engine/Engine.cc +++ b/engine/Engine.cc @@ -19,6 +19,7 @@ #include #include #include +#include int vasprintf (char **result, const char *format, va_list *string) { return 0; @@ -381,5 +382,17 @@ std::string GetUserDirFullPath (const std::string &path) { return EngineInstance->GetUserDirFullPath(path); } +bool FileExists (const std::string &path) { + boost::filesystem::path file_path (path); + + if (!boost::filesystem::exists(file_path)) + return false; + + if (boost::filesystem::is_directory(file_path)) + return false; + + return true; +} + } diff --git a/engine/Engine.h b/engine/Engine.h index 9d7da25..8c6a010 100644 --- a/engine/Engine.h +++ b/engine/Engine.h @@ -186,6 +186,10 @@ std::string GetResourceFullPath (const std::string &resource); /** \brief Returns the path to a file by prepending the user data path to it */ std::string GetUserDirFullPath (const std::string &path); + +/** \brief Checks whether a given file exists */ +bool FileExists (const std::string &path); + } /* Include the globally visible declarations of the other modules */ diff --git a/engine/ModelBase.cc b/engine/ModelBase.cc index 6f89f8b..9516697 100644 --- a/engine/ModelBase.cc +++ b/engine/ModelBase.cc @@ -22,6 +22,7 @@ int ModelBase::OnInit (int argc, char* argv[]) { mKilledEntities.clear (); mEntityIdCounter = 0; mDeltaSec = 0.; + mPlayerEntityId = NullEntityId; return 0; } @@ -192,7 +193,6 @@ EntityBase* ModelBase::GetEntityAt (const vector3d &pos) { return NULL; } - unsigned int ModelBase::CreateEntityId () { if (mEntityIdCounter == NullEntityId - 1) LogError ("Could not create valid entity id, reached maximum value of %u", mEntityIdCounter);