Skip to content

Commit

Permalink
Game: add duration, ship info, character name to savefile header
Browse files Browse the repository at this point in the history
- Add total playtime to save information
- Add ship name and hull name to save information
- Add player character's name to save information
- All additions should be save-compatible with the current version
  • Loading branch information
sturnclaw committed Aug 22, 2024
1 parent 2d1de34 commit ba98f82
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static const int s_saveVersion = 90;
Game::Game(const SystemPath &path, const double startDateTime, const char *shipType) :
m_galaxy(GalaxyGenerator::Create()),
m_time(startDateTime),
m_playedDuration(0),
m_state(State::NORMAL),
m_wantHyperspace(false),
m_hyperspaceProgress(0),
Expand Down Expand Up @@ -107,6 +108,9 @@ Game::Game(const SystemPath &path, const double startDateTime, const char *shipT
m_player->SetVelocity(randomOrthoDirection * orbitalVelocity);
}

// Record when we started playing this save so we can determine how long it's been played this session
m_sessionStartTimestamp = std::chrono::steady_clock::now().time_since_epoch().count();

CreateViews();

EmitPauseState(IsPaused());
Expand Down Expand Up @@ -189,6 +193,10 @@ Game::Game(const Json &jsonObj) :
for (Uint32 i = 0; i < hyperspaceCloudArray.size(); i++) {
m_hyperspaceClouds.push_back(static_cast<HyperspaceCloud *>(Body::FromJson(hyperspaceCloudArray[i], 0)));
}

const Json &gameInfo = jsonObj["game_info"];
m_playedDuration = gameInfo.value("duration", 0.0);

} catch (Json::type_error &) {
throw SavedGameCorruptException();
}
Expand All @@ -205,6 +213,8 @@ Game::Game(const Json &jsonObj) :

Pi::luaSerializer->UninitTableRefs();

m_sessionStartTimestamp = std::chrono::steady_clock::now().time_since_epoch().count();

EmitPauseState(IsPaused());

Pi::GetApp()->RequestProfileFrame("LoadGame");
Expand Down Expand Up @@ -267,9 +277,32 @@ void Game::ToJson(Json &jsonObj)
Json gameInfo = Json::object();
float credits = LuaObject<Player>::CallMethod<float>(Pi::player, "GetMoney");

// Get the player's character name
// TODO: add an easier way to get the player's character object once player+ship are split more firmly
pi_lua_import(Lua::manager->GetLuaState(), "Character");
LuaTable characters(Lua::manager->GetLuaState(), -1);

std::string character_name = characters.Sub("persistent").Sub("player").Get<std::string>("name");
gameInfo["character"] = character_name;

// Remove the Character table
lua_pop(Lua::manager->GetLuaState(), 1);

// Determine how long we've been playing this save (since we created or loaded it)
std::chrono::steady_clock::duration start_time(m_sessionStartTimestamp);
auto playtime_duration = std::chrono::steady_clock::now().time_since_epoch() - start_time;

auto playtime_this_session = std::chrono::duration_cast<std::chrono::seconds>(playtime_duration).count();

gameInfo["duration"] = m_playedDuration + playtime_this_session;

// Information about the player's ship
gameInfo["shipHull"] = Pi::player->GetShipType()->name;
gameInfo["shipName"] = Pi::player->GetShipName();

gameInfo["system"] = Pi::game->GetSpace()->GetStarSystem()->GetName();
gameInfo["credits"] = credits;
gameInfo["ship"] = Pi::player->GetShipType()->modelName;
gameInfo["ship"] = Pi::player->GetShipType()->id;
if (Pi::player->IsDocked()) {
gameInfo["docked_at"] = Pi::player->GetDockedWith()->GetSystemBody()->GetName();
}
Expand Down
3 changes: 3 additions & 0 deletions src/Game.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ class Game {
std::unique_ptr<Space> m_space;
double m_time;

int64_t m_sessionStartTimestamp;
double m_playedDuration;

enum class State {
NORMAL,
HYPERSPACE,
Expand Down
2 changes: 2 additions & 0 deletions src/Ship.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ class Ship : public DynamicBody {
void SetLabel(const std::string &label) override;
void SetShipName(const std::string &shipName);

const std::string &GetShipName() const { return m_shipName; }

float GetAtmosphericPressureLimit() const;
float GetPercentShields() const;
float GetPercentHull() const;
Expand Down
9 changes: 9 additions & 0 deletions src/lua/LuaGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ static int l_game_savegame_stats(lua_State *l)
t.Set("flight_state", gameInfo["flight_state"].get<std::string>());
if (gameInfo["docked_at"].is_string())
t.Set("docked_at", gameInfo["docked_at"].get<std::string>());

if (gameInfo.count("shipHull"))
t.Set("shipHull", gameInfo["shipHull"].get<std::string>());
if (gameInfo.count("shipName"))
t.Set("shipName", gameInfo["shipName"].get<std::string>());
if (gameInfo.count("duration"))
t.Set("duration", gameInfo["duration"].get<double>());
if (gameInfo.count("character"))
t.Set("character", gameInfo["character"].get<std::string>());
} else {
// this is an older saved game...try to show something useful
Json shipNode = rootNode["space"]["bodies"][rootNode["player"].get<int>() - 1];
Expand Down

0 comments on commit ba98f82

Please sign in to comment.