Replace std::string Game::telesummary and Game::quicksummary by Summary

Game::telesummary and Game::quicksummary stored the summary string for
the save files - which is the <summary> tag that says something like
"Space Station, 10:30:59". The game only ever displays the quicksave
variant of these two, for "Last Save:" on the map menu's SAVE tab.
So the telesave has a <summary> too, but it's never displayed anywhere.
(In fact, the area is often set to "nowhere"...)

However, the summary strings have another function: detect that both
the telesave and quicksave exist. If a summary string for a save is
empty, then that save is considered not to exist.

I'm refactoring the summary string system, by making the new variables
Game::last_telesave and Game::last_quicksave of type struct
Game::Summary. This struct should have all data necessary to display
the summary string at runtime, and thus translate it at runtime (so
we don't store a summary in a certain language and then display it in
the wrong font later - the summary can always be in the current
language). It also has an `exists` member, to replace the need to
check for empty strings.

The <summary> tag is now completely unused, but is still written to
for older versions of the game to read.

(This commit does not add the new string to the language files, since
Terry now added it separately in his own branch)
This commit is contained in:
Dav999 2023-09-12 14:36:58 +02:00 committed by Misa Elizabeth Kai
parent 64bad7d67f
commit 0ea41e7913
4 changed files with 93 additions and 98 deletions

View File

@ -108,53 +108,31 @@ static bool GetButtonFromString(const char *pText, SDL_GameControllerButton *but
return false;
}
static const char* get_summary(
// Unfortunate forward-declare... My hands are pretty tied
static void loadthissummary(
const char* filename,
struct Game::Summary* summary,
tinyxml2::XMLDocument& doc
);
static struct Game::Summary get_summary(
const char* filename,
const char* savename,
tinyxml2::XMLDocument& doc
) {
tinyxml2::XMLHandle hDoc(&doc);
tinyxml2::XMLElement* pElem;
bool success;
const char* retval = "";
struct Game::Summary summary;
SDL_zero(summary);
success = FILESYSTEM_loadTiXml2Document(filename, doc);
if (!success)
if (!FILESYSTEM_loadTiXml2Document(filename, doc))
{
vlog_info("%s not found", savename);
goto end;
return summary;
}
if (doc.Error())
{
vlog_error("Error parsing %s: %s", savename, doc.ErrorStr());
goto end;
}
loadthissummary(savename, &summary, doc);
for (pElem = hDoc
.FirstChildElement()
.FirstChildElement("Data")
.FirstChildElement()
.ToElement();
pElem != NULL;
pElem = pElem->NextSiblingElement())
{
const char* pKey = pElem->Value();
const char* pText = pElem->GetText();
if (pText == NULL)
{
pText = "";
}
if (SDL_strcmp(pKey, "summary") == 0)
{
retval = pText;
}
}
end:
return retval;
return summary;
}
void Game::init(void)
@ -339,11 +317,11 @@ void Game::init(void)
saveFilePath = FILESYSTEM_getUserSaveDirectory();
tinyxml2::XMLDocument doc;
quicksummary = get_summary("saves/qsave.vvv", "qsave.vvv", doc);
last_quicksave = get_summary("saves/qsave.vvv", "qsave.vvv", doc);
tinyxml2::XMLDocument docTele;
telesummary = get_summary("saves/tsave.vvv", "tsave.vvv", doc);
last_telesave = get_summary("saves/tsave.vvv", "tsave.vvv", doc);
screenshake = flashlight = 0 ;
@ -5595,6 +5573,8 @@ static void loadthissummary(
return;
}
summary->exists = true;
for (pElem = hDoc
.FirstChildElement()
.FirstChildElement("Data")
@ -5611,11 +5591,7 @@ static void loadthissummary(
pText = "";
}
if (SDL_strcmp(pKey, "summary") == 0)
{
summary->summary = pText;
}
else if (SDL_strcmp(pKey, "seconds") == 0)
if (SDL_strcmp(pKey, "seconds") == 0)
{
summary->seconds = help.Int(pText);
}
@ -5648,48 +5624,35 @@ void Game::loadsummary(void)
{
tinyxml2::XMLDocument doc;
if (!FILESYSTEM_loadTiXml2Document("saves/tsave.vvv", doc))
{
telesummary = "";
}
else
{
struct Summary summary;
SDL_zero(summary);
SDL_zero(last_telesave);
SDL_zero(last_quicksave);
loadthissummary("tsave.vvv", &summary, doc);
if (FILESYSTEM_loadTiXml2Document("saves/tsave.vvv", doc))
{
loadthissummary("tsave.vvv", &last_telesave, doc);
telesummary = summary.summary;
tele_gametime = giventimestring(
summary.hours,
summary.minutes,
summary.seconds
last_telesave.hours,
last_telesave.minutes,
last_telesave.seconds
);
tele_currentarea = map.currentarea(summary.saverx, summary.savery);
SDL_memcpy(tele_crewstats, summary.crewstats, sizeof(tele_crewstats));
tele_trinkets = summary.trinkets;
tele_currentarea = map.currentarea(last_telesave.saverx, last_telesave.savery);
SDL_memcpy(tele_crewstats, last_telesave.crewstats, sizeof(tele_crewstats));
tele_trinkets = last_telesave.trinkets;
}
if (!FILESYSTEM_loadTiXml2Document("saves/qsave.vvv", doc))
if (FILESYSTEM_loadTiXml2Document("saves/qsave.vvv", doc))
{
quicksummary = "";
}
else
{
struct Summary summary;
SDL_zero(summary);
loadthissummary("qsave.vvv", &last_quicksave, doc);
loadthissummary("qsave.vvv", &summary, doc);
quicksummary = summary.summary;
quick_gametime = giventimestring(
summary.hours,
summary.minutes,
summary.seconds
last_quicksave.hours,
last_quicksave.minutes,
last_quicksave.seconds
);
quick_currentarea = map.currentarea(summary.saverx, summary.savery);
SDL_memcpy(quick_crewstats, summary.crewstats, sizeof(quick_crewstats));
quick_trinkets = summary.trinkets;
quick_currentarea = map.currentarea(last_quicksave.saverx, last_quicksave.savery);
SDL_memcpy(quick_crewstats, last_quicksave.crewstats, sizeof(quick_crewstats));
quick_trinkets = last_quicksave.trinkets;
}
}
@ -5727,7 +5690,7 @@ bool Game::savetele(void)
vlog_info("Creating new tsave.vvv");
}
telesummary = writemaingamesave(doc);
last_telesave = writemaingamesave(doc);
if(!FILESYSTEM_saveTiXml2Document("saves/tsave.vvv", doc))
{
@ -5760,7 +5723,7 @@ bool Game::savequick(void)
vlog_info("Creating new qsave.vvv");
}
quicksummary = writemaingamesave(doc);
last_quicksave = writemaingamesave(doc);
if(!FILESYSTEM_saveTiXml2Document("saves/qsave.vvv", doc))
{
@ -5773,14 +5736,17 @@ bool Game::savequick(void)
}
// Returns summary of save
std::string Game::writemaingamesave(tinyxml2::XMLDocument& doc)
struct Game::Summary Game::writemaingamesave(tinyxml2::XMLDocument& doc)
{
//TODO make this code a bit cleaner.
struct Game::Summary summary;
SDL_zero(summary);
if (map.custommode || inspecial())
{
//Don't trash save data!
return "";
return summary;
}
xml::update_declaration(doc);
@ -5838,7 +5804,8 @@ std::string Game::writemaingamesave(tinyxml2::XMLDocument& doc)
xml::update_tag(msgs, "savepoint", savepoint);
xml::update_tag(msgs, "trinkets", trinkets());
int n_trinkets = trinkets();
xml::update_tag(msgs, "trinkets", n_trinkets);
//Special stats
@ -5879,8 +5846,18 @@ std::string Game::writemaingamesave(tinyxml2::XMLDocument& doc)
xml::update_tag(msgs, "finalstretch", (int) map.finalstretch);
std::string summary = savearea + ", " + timestring();
xml::update_tag(msgs, "summary", summary.c_str());
std::string legacy_summary = savearea + ", " + timestring();
xml::update_tag(msgs, "summary", legacy_summary.c_str());
summary.exists = true;
summary.seconds = seconds;
summary.minutes = minutes;
summary.hours = hours;
summary.saverx = saverx;
summary.savery = savery;
summary.trinkets = n_trinkets;
SDL_memcpy(summary.crewstats, crewstats, sizeof(summary.crewstats));
return summary;
}
@ -6032,8 +6009,8 @@ bool Game::customsavequick(const std::string& savfile)
}
}
std::string summary = savearea + ", " + timestring();
xml::update_tag(msgs, "summary", summary.c_str());
std::string legacy_summary = savearea + ", " + timestring();
xml::update_tag(msgs, "summary", legacy_summary.c_str());
if(!FILESYSTEM_saveTiXml2Document(("saves/"+levelfile+".vvv").c_str(), doc))
{
@ -7021,10 +6998,14 @@ void Game::deletequick(void)
return;
}
if( !FILESYSTEM_delete( "saves/qsave.vvv" ) )
if (!FILESYSTEM_delete("saves/qsave.vvv"))
{
vlog_error("Error deleting saves/qsave.vvv");
}
else
quicksummary = "";
{
SDL_zero(last_quicksave);
}
}
void Game::deletetele(void)
@ -7034,10 +7015,14 @@ void Game::deletetele(void)
return;
}
if( !FILESYSTEM_delete( "saves/tsave.vvv" ) )
if (!FILESYSTEM_delete("saves/tsave.vvv"))
{
vlog_error("Error deleting saves/tsave.vvv");
}
else
telesummary = "";
{
SDL_zero(last_telesave);
}
}
void Game::customdeletequick(const std::string& file)
@ -7191,7 +7176,7 @@ bool Game::anything_unlocked(void)
bool Game::save_exists(void)
{
return telesummary != "" || quicksummary != "";
return last_telesave.exists || last_quicksave.exists;
}
static void hardreset(void)

View File

@ -294,7 +294,7 @@ public:
struct Summary
{
const char* summary;
bool exists;
int seconds;
int minutes;
int hours;
@ -304,8 +304,11 @@ public:
bool crewstats[numcrew];
};
struct Summary last_telesave, last_quicksave;
bool save_exists(void);
void readmaingamesave(const char* savename, tinyxml2::XMLDocument& doc);
std::string writemaingamesave(tinyxml2::XMLDocument& doc);
struct Summary writemaingamesave(tinyxml2::XMLDocument& doc);
void initteleportermode(void);
@ -504,9 +507,6 @@ public:
std::string activity_lastprompt;
bool activity_gettext;
std::string telesummary, quicksummary;
bool save_exists(void);
bool backgroundtext;
int activeactivity, act_fade;

View File

@ -1773,13 +1773,13 @@ static void menuactionpress(void)
music.playef(Sound_VIRIDIAN);
startmode(Start_MAINGAME);
}
else if (game.telesummary == "")
else if (!game.last_telesave.exists)
{
//You at least have a quicksave, or you couldn't have gotten here
music.playef(Sound_VIRIDIAN);
startmode(Start_MAINGAME_QUICKSAVE);
}
else if (game.quicksummary == "")
else if (!game.last_quicksave.exists)
{
//You at least have a telesave, or you couldn't have gotten here
music.playef(Sound_VIRIDIAN);

View File

@ -2979,13 +2979,23 @@ void maprender(void)
font::print(PR_CEN, -1, 80, buffer, 255 - help.glow*2, 255 - help.glow*2, 255 - help.glow);
if (map.custommode || game.quicksummary == "")
if (map.custommode || !game.last_quicksave.exists)
{
break;
}
font::print(PR_CEN, -1, FLIP(100, 8), loc::gettext("Last Save:"), 164 - help.glow/4, 164 - help.glow/4, 164);
font::print(PR_CEN, -1, FLIP(112, 8), game.quicksummary, 164 - help.glow/4, 164 - help.glow/4, 164);
struct Game::Summary* last = &game.last_quicksave;
vformat_buf(
buffer, sizeof(buffer),
loc::gettext("{area}, {time}"),
"area:str, time:str",
map.currentarea(last->saverx, last->savery),
game.giventimestring(last->hours, last->minutes, last->seconds).c_str()
);
font::print(PR_CEN, -1, FLIP(112, 8), buffer, 164 - help.glow/4, 164 - help.glow/4, 164);
break;
}