diff --git a/radiant/map/Map.cpp b/radiant/map/Map.cpp index 2223e4a267..7868bf3651 100644 --- a/radiant/map/Map.cpp +++ b/radiant/map/Map.cpp @@ -62,15 +62,10 @@ namespace map { - namespace - { - const char* const MAP_UNNAMED_STRING = N_("unnamed.map"); - - const char* const GKEY_LAST_CAM_POSITION = "/mapFormat/lastCameraPositionKey"; - const char* const GKEY_LAST_CAM_ANGLE = "/mapFormat/lastCameraAngleKey"; - const char* const GKEY_PLAYER_START_ECLASS = "/mapFormat/playerStartPoint"; - const char* const GKEY_PLAYER_HEIGHT = "/defaults/playerHeight"; - } +namespace +{ + const char* const MAP_UNNAMED_STRING = N_("unnamed.map"); +} Map::Map() : _lastCopyMapName(""), @@ -236,103 +231,6 @@ void Map::focusViews(const Vector3& point, const Vector3& angles) { GlobalXYWnd().setOrigin(point); } -void Map::removeCameraPosition() { - const std::string keyLastCamPos = game::current::getValue(GKEY_LAST_CAM_POSITION); - const std::string keyLastCamAngle = game::current::getValue(GKEY_LAST_CAM_ANGLE); - - if (_worldSpawnNode != NULL) { - // Retrieve the entity from the worldspawn node - Entity* worldspawn = Node_getEntity(_worldSpawnNode); - assert(worldspawn != NULL); // This must succeed - - worldspawn->setKeyValue(keyLastCamPos, ""); - worldspawn->setKeyValue(keyLastCamAngle, ""); - } -} - -/* greebo: Saves the current camera position/angles to worldspawn - */ -void Map::saveCameraPosition() -{ - const std::string keyLastCamPos = game::current::getValue(GKEY_LAST_CAM_POSITION); - const std::string keyLastCamAngle = game::current::getValue(GKEY_LAST_CAM_ANGLE); - - if (_worldSpawnNode != NULL) { - // Retrieve the entity from the worldspawn node - Entity* worldspawn = Node_getEntity(_worldSpawnNode); - assert(worldspawn != NULL); // This must succeed - - ui::CamWndPtr camWnd = GlobalCamera().getActiveCamWnd(); - if (camWnd == NULL) return; - - worldspawn->setKeyValue(keyLastCamPos, - string::to_string(camWnd->getCameraOrigin())); - worldspawn->setKeyValue(keyLastCamAngle, - string::to_string(camWnd->getCameraAngles())); - } -} - -/** Find the start position in the map and focus the viewport on it. - */ -void Map::gotoStartPosition() -{ - const std::string keyLastCamPos = game::current::getValue(GKEY_LAST_CAM_POSITION); - const std::string keyLastCamAngle = game::current::getValue(GKEY_LAST_CAM_ANGLE); - const std::string eClassPlayerStart = game::current::getValue(GKEY_PLAYER_START_ECLASS); - - Vector3 angles(0,0,0); - Vector3 origin(0,0,0); - - if (_worldSpawnNode != NULL) { - // Retrieve the entity from the worldspawn node - Entity* worldspawn = Node_getEntity(_worldSpawnNode); - assert(worldspawn != NULL); // This must succeed - - // Try to find a saved "last camera position" - const std::string savedOrigin = worldspawn->getKeyValue(keyLastCamPos); - - if (savedOrigin != "") - { - // Construct the vector out of the std::string - origin = string::convert(savedOrigin); - - angles = string::convert( - worldspawn->getKeyValue(keyLastCamAngle) - ); - - // Focus the view with the default angle - focusViews(origin, angles); - - // Remove the saved entity key value so it doesn't appear during map edit - removeCameraPosition(); - - return; - } - else - { - // Get the player start entity - Entity* playerStart = Scene_FindEntityByClass(eClassPlayerStart); - - if (playerStart != NULL) - { - // Get the entity origin - origin = string::convert( - playerStart->getKeyValue("origin") - ); - - // angua: move the camera upwards a bit - origin.z() += game::current::getValue(GKEY_PLAYER_HEIGHT); - - // Check for an angle key, and use it if present - angles[ui::CAMERA_YAW] = string::convert(playerStart->getKeyValue("angle"), 0); - } - } - } - - // Focus the view with the given parameters - focusViews(origin, angles); -} - scene::INodePtr Map::findWorldspawn() { scene::INodePtr worldspawn; @@ -396,9 +294,6 @@ void Map::load(const std::string& filename) { rMessage() << GlobalCounters().getCounter(counterPatches).get() << " patches\n"; rMessage() << GlobalCounters().getCounter(counterEntities).get() << " entities\n"; - // Move the view to a start position - gotoStartPosition(); - // Let the filtersystem update the filtered status of all instances GlobalFilterSystem().update(); @@ -419,9 +314,6 @@ bool Map::save(const MapFormatPtr& mapFormat) emitMapEvent(MapSaving); - // Store the camview position into worldspawn - saveCameraPosition(); - wxutil::ScopeTimer timer("map save"); blocker.setMessage(_("Saving Map")); @@ -431,9 +323,6 @@ bool Map::save(const MapFormatPtr& mapFormat) emitMapEvent(MapSaved); - // Remove the saved camera position - removeCameraPosition(); - if (success) { // Clear the modified flag diff --git a/radiant/map/Map.h b/radiant/map/Map.h index d5c8641b56..cdddf64222 100644 --- a/radiant/map/Map.h +++ b/radiant/map/Map.h @@ -170,18 +170,6 @@ class Map : */ MapFormatPtr getFormat(); - /** greebo: Removes or saves the camera position (into worldspawn) - */ - void removeCameraPosition(); - void saveCameraPosition(); - - /** greebo: Sets the camera to the start position. This uses - * the information stored in the worlspawn or - * the location of the info_player_start entity. - * If neither of these two exist, 0,0,0 is used. - */ - void gotoStartPosition(); - /** greebo: Asks the user if the current changes should be saved. * * @returns: true, if the user gave clearance (map was saved, had no diff --git a/radiant/map/MapPositionManager.cpp b/radiant/map/MapPositionManager.cpp index 251d3508ec..5ec43c0fa0 100644 --- a/radiant/map/MapPositionManager.cpp +++ b/radiant/map/MapPositionManager.cpp @@ -2,13 +2,18 @@ #include "maplib.h" #include "ientity.h" +#include "gamelib.h" #include "ieventmanager.h" #include "iregistry.h" #include "itextstream.h" #include "icommandsystem.h" #include "string/string.h" +#include "entitylib.h" #include +#include "camera/GlobalCamera.h" +#include "xyview/GlobalXYWnd.h" + namespace map { @@ -17,6 +22,11 @@ namespace map const std::string SAVE_COMMAND_ROOT = "SavePosition"; const std::string LOAD_COMMAND_ROOT = "LoadPosition"; + const char* const GKEY_LAST_CAM_POSITION = "/mapFormat/lastCameraPositionKey"; + const char* const GKEY_LAST_CAM_ANGLE = "/mapFormat/lastCameraAngleKey"; + const char* const GKEY_PLAYER_START_ECLASS = "/mapFormat/playerStartPoint"; + const char* const GKEY_PLAYER_HEIGHT = "/defaults/playerHeight"; + unsigned int MAX_POSITIONS = 10; } @@ -75,6 +85,83 @@ void MapPositionManager::loadPositions() } } +void MapPositionManager::removeLastCameraPosition() +{ + const std::string keyLastCamPos = game::current::getValue(GKEY_LAST_CAM_POSITION); + const std::string keyLastCamAngle = game::current::getValue(GKEY_LAST_CAM_ANGLE); + + Entity* worldspawn = map::current::getWorldspawn(); + + if (worldspawn != nullptr) + { + worldspawn->setKeyValue(keyLastCamPos, ""); + worldspawn->setKeyValue(keyLastCamAngle, ""); + } +} + +void MapPositionManager::saveLastCameraPosition() +{ + const std::string keyLastCamPos = game::current::getValue(GKEY_LAST_CAM_POSITION); + const std::string keyLastCamAngle = game::current::getValue(GKEY_LAST_CAM_ANGLE); + + Entity* worldspawn = map::current::getWorldspawn(); + + if (worldspawn != nullptr) + { + ui::CamWndPtr camWnd = GlobalCamera().getActiveCamWnd(); + if (camWnd == NULL) return; + + worldspawn->setKeyValue(keyLastCamPos, string::to_string(camWnd->getCameraOrigin())); + worldspawn->setKeyValue(keyLastCamAngle, string::to_string(camWnd->getCameraAngles())); + } +} + +void MapPositionManager::gotoLastCameraPosition() +{ + const std::string keyLastCamPos = game::current::getValue(GKEY_LAST_CAM_POSITION); + const std::string keyLastCamAngle = game::current::getValue(GKEY_LAST_CAM_ANGLE); + const std::string eClassPlayerStart = game::current::getValue(GKEY_PLAYER_START_ECLASS); + + Vector3 angles(0, 0, 0); + Vector3 origin(0, 0, 0); + + Entity* worldspawn = map::current::getWorldspawn(); + + if (worldspawn != nullptr) + { + // Try to find a saved "last camera position" + const std::string savedOrigin = worldspawn->getKeyValue(keyLastCamPos); + + if (!savedOrigin.empty()) + { + // Construct the vector out of the std::string + origin = string::convert(savedOrigin); + angles = string::convert(worldspawn->getKeyValue(keyLastCamAngle)); + } + else + { + // Get the player start entity + Entity* playerStart = Scene_FindEntityByClass(eClassPlayerStart); + + if (playerStart != NULL) + { + // Get the entity origin + origin = string::convert(playerStart->getKeyValue("origin")); + + // angua: move the camera upwards a bit + origin.z() += game::current::getValue(GKEY_PLAYER_HEIGHT); + + // Check for an angle key, and use it if present + angles[ui::CAMERA_YAW] = string::convert(playerStart->getKeyValue("angle"), 0); + } + } + } + + // Focus the view with the given parameters + GlobalCamera().focusCamera(origin, angles); + GlobalXYWnd().setOrigin(origin); +} + void MapPositionManager::savePositions() { Entity* worldspawn = map::current::getWorldspawn(); @@ -108,10 +195,12 @@ void MapPositionManager::onMapEvent(IMap::MapEvent ev) { // Store the map positions into the worldspawn spawnargs savePositions(); + saveLastCameraPosition(); } else if (ev == IMap::MapSaved) { // Remove the map positions again after saving + removeLastCameraPosition(); removePositions(); } else if (ev == IMap::MapLoaded) @@ -120,6 +209,9 @@ void MapPositionManager::onMapEvent(IMap::MapEvent ev) loadPositions(); // Remove them, so that the user doesn't get bothered with them removePositions(); + + gotoLastCameraPosition(); + removeLastCameraPosition(); } } diff --git a/radiant/map/MapPositionManager.h b/radiant/map/MapPositionManager.h index 435d4173d7..10cad489bc 100644 --- a/radiant/map/MapPositionManager.h +++ b/radiant/map/MapPositionManager.h @@ -30,6 +30,16 @@ class MapPositionManager void removePositions(); private: + /** + * greebo: Sets the camera to the start position. This uses the + * information stored in the worlspawn or the location of the + * info_player_start entity. If neither of these two exist, 0,0,0 is used. + */ + void gotoLastCameraPosition(); + + void saveLastCameraPosition(); + void removeLastCameraPosition(); + void onMapEvent(IMap::MapEvent ev); };