Skip to content

Commit

Permalink
#5168: Move last camera position save/restore code to MapPositionMana…
Browse files Browse the repository at this point in the history
…ger and tie it to the MapEvent listener.
  • Loading branch information
codereader committed Apr 16, 2020
1 parent 3814967 commit 3e5f911
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 127 deletions.
119 changes: 4 additions & 115 deletions radiant/map/Map.cpp
Expand Up @@ -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(""),
Expand Down Expand Up @@ -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<std::string>(GKEY_LAST_CAM_POSITION);
const std::string keyLastCamAngle = game::current::getValue<std::string>(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<std::string>(GKEY_LAST_CAM_POSITION);
const std::string keyLastCamAngle = game::current::getValue<std::string>(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<std::string>(GKEY_LAST_CAM_POSITION);
const std::string keyLastCamAngle = game::current::getValue<std::string>(GKEY_LAST_CAM_ANGLE);
const std::string eClassPlayerStart = game::current::getValue<std::string>(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<Vector3>(savedOrigin);

angles = string::convert<Vector3>(
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<Vector3>(
playerStart->getKeyValue("origin")
);

// angua: move the camera upwards a bit
origin.z() += game::current::getValue<float>(GKEY_PLAYER_HEIGHT);

// Check for an angle key, and use it if present
angles[ui::CAMERA_YAW] = string::convert<float>(playerStart->getKeyValue("angle"), 0);
}
}
}

// Focus the view with the given parameters
focusViews(origin, angles);
}

scene::INodePtr Map::findWorldspawn()
{
scene::INodePtr worldspawn;
Expand Down Expand Up @@ -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();

Expand All @@ -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"));
Expand All @@ -431,9 +323,6 @@ bool Map::save(const MapFormatPtr& mapFormat)

emitMapEvent(MapSaved);

// Remove the saved camera position
removeCameraPosition();

if (success)
{
// Clear the modified flag
Expand Down
12 changes: 0 additions & 12 deletions radiant/map/Map.h
Expand Up @@ -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
Expand Down
92 changes: 92 additions & 0 deletions radiant/map/MapPositionManager.cpp
Expand Up @@ -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 <functional>

#include "camera/GlobalCamera.h"
#include "xyview/GlobalXYWnd.h"

namespace map
{

Expand All @@ -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;
}

Expand Down Expand Up @@ -75,6 +85,83 @@ void MapPositionManager::loadPositions()
}
}

void MapPositionManager::removeLastCameraPosition()
{
const std::string keyLastCamPos = game::current::getValue<std::string>(GKEY_LAST_CAM_POSITION);
const std::string keyLastCamAngle = game::current::getValue<std::string>(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<std::string>(GKEY_LAST_CAM_POSITION);
const std::string keyLastCamAngle = game::current::getValue<std::string>(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<std::string>(GKEY_LAST_CAM_POSITION);
const std::string keyLastCamAngle = game::current::getValue<std::string>(GKEY_LAST_CAM_ANGLE);
const std::string eClassPlayerStart = game::current::getValue<std::string>(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<Vector3>(savedOrigin);
angles = string::convert<Vector3>(worldspawn->getKeyValue(keyLastCamAngle));
}
else
{
// Get the player start entity
Entity* playerStart = Scene_FindEntityByClass(eClassPlayerStart);

if (playerStart != NULL)
{
// Get the entity origin
origin = string::convert<Vector3>(playerStart->getKeyValue("origin"));

// angua: move the camera upwards a bit
origin.z() += game::current::getValue<float>(GKEY_PLAYER_HEIGHT);

// Check for an angle key, and use it if present
angles[ui::CAMERA_YAW] = string::convert<float>(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();
Expand Down Expand Up @@ -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)
Expand All @@ -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();
}
}

Expand Down
10 changes: 10 additions & 0 deletions radiant/map/MapPositionManager.h
Expand Up @@ -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);
};

Expand Down

0 comments on commit 3e5f911

Please sign in to comment.