tr1/savegame: move death count to resume info

This moves the death count from the global game info into the resume
info stats struct.
This commit is contained in:
lahm86 2025-04-07 20:01:59 +01:00
parent c853f43fa4
commit ba35a932b1
12 changed files with 57 additions and 53 deletions

View file

@ -273,11 +273,7 @@ void Lara_Control(void)
item->hit_points = -1;
if (!g_Lara.death_timer) {
Music_Stop();
g_GameInfo.death_count++;
if (Savegame_GetBoundSlot() != -1) {
Savegame_UpdateDeathCounters(
Savegame_GetBoundSlot(), &g_GameInfo);
}
Stats_AddDeath();
}
g_Lara.death_timer++;
// make sure the enemy healthbar is no longer rendered. If g_Lara later

View file

@ -42,7 +42,7 @@ void Savegame_SetCurrentInfo(int32_t current_slot, int32_t src_slot);
int32_t Savegame_GetLevelNumber(int32_t slot_num);
bool Savegame_UpdateDeathCounters(int32_t slot_num, GAME_INFO *game_info);
bool Savegame_UpdateDeathCounters(int32_t slot_num, int32_t death_count);
bool Savegame_LoadOnlyResumeInfo(int32_t slot_num, GAME_INFO *game_info);
void Savegame_ScanSavedGames(void);

View file

@ -40,7 +40,7 @@ typedef struct {
bool (*load_only_resume_info)(MYFILE *fp, GAME_INFO *game_info);
void (*save_to_file)(
MYFILE *fp, GAME_INFO *game_info, SAVEGAME_INFO *savegame_info);
bool (*update_death_counters)(MYFILE *fp, GAME_INFO *game_info);
bool (*update_death_counters)(MYFILE *fp, int32_t death_count);
} SAVEGAME_STRATEGY;
static int32_t m_SaveSlots = 0;
@ -69,7 +69,7 @@ static const SAVEGAME_STRATEGY m_Strategies[] = {
.load_from_file = Savegame_Legacy_LoadFromFile,
.load_only_resume_info = Savegame_Legacy_LoadOnlyResumeInfo,
.save_to_file = nullptr,
.update_death_counters = Savegame_Legacy_UpdateDeathCounters,
.update_death_counters = nullptr,
},
{ 0 },
};
@ -284,7 +284,6 @@ void Savegame_ProcessItemsBeforeSave(void)
void Savegame_InitCurrentInfo(void)
{
g_GameInfo.death_count = 0;
const GF_LEVEL_TABLE *const level_table = GF_GetLevelTable(GFLT_MAIN);
for (int32_t i = 0; i < level_table->count; i++) {
const GF_LEVEL *const level = &level_table->levels[i];
@ -578,9 +577,9 @@ bool Savegame_Save(const int32_t slot_num)
return ret;
}
bool Savegame_UpdateDeathCounters(int32_t slot_num, GAME_INFO *game_info)
bool Savegame_UpdateDeathCounters(
const int32_t slot_num, const int32_t death_count)
{
ASSERT(game_info != nullptr);
ASSERT(slot_num >= 0);
SAVEGAME_INFO *savegame_info = &m_SavegameInfo[slot_num];
ASSERT(savegame_info->format != 0);
@ -588,11 +587,12 @@ bool Savegame_UpdateDeathCounters(int32_t slot_num, GAME_INFO *game_info)
bool ret = false;
const SAVEGAME_STRATEGY *strategy = &m_Strategies[0];
while (strategy->format) {
if (savegame_info->format == strategy->format) {
if (savegame_info->format == strategy->format
&& strategy->update_death_counters != nullptr) {
MYFILE *fp =
File_Open(savegame_info->full_path, FILE_OPEN_READ_WRITE);
if (fp) {
ret = strategy->update_death_counters(fp, game_info);
ret = strategy->update_death_counters(fp, death_count);
File_Close(fp);
} else
break;

View file

@ -406,7 +406,11 @@ static bool M_LoadMisc(
if (header_version >= VERSION_4) {
game_info->bonus_level_unlock =
JSON_ObjectGetBool(misc_obj, "bonus_level_unlock", 0);
game_info->death_count = JSON_ObjectGetInt(misc_obj, "death_count", -1);
const GF_LEVEL *const current_level = Game_GetCurrentLevel();
RESUME_INFO *const resume = Savegame_GetCurrentInfo(current_level);
resume->stats.death_count =
JSON_ObjectGetInt(misc_obj, "death_count", -1);
}
return true;
}
@ -1036,7 +1040,10 @@ static JSON_OBJECT *M_DumpMisc(GAME_INFO *game_info)
JSON_ObjectAppendInt(misc_obj, "bonus_flag", Game_GetBonusFlag());
JSON_ObjectAppendBool(
misc_obj, "bonus_level_unlock", game_info->bonus_level_unlock);
JSON_ObjectAppendInt(misc_obj, "death_count", game_info->death_count);
const GF_LEVEL *const level = Game_GetCurrentLevel();
const RESUME_INFO *const resume = Savegame_GetCurrentInfo(level);
JSON_ObjectAppendInt(misc_obj, "death_count", resume->stats.death_count);
return misc_obj;
}
@ -1537,7 +1544,8 @@ void Savegame_BSON_SaveToFile(
savegame_info->features.restart = true;
}
bool Savegame_BSON_UpdateDeathCounters(MYFILE *fp, GAME_INFO *game_info)
bool Savegame_BSON_UpdateDeathCounters(
MYFILE *const fp, const int32_t death_count)
{
bool result = false;
int32_t version;
@ -1554,7 +1562,7 @@ bool Savegame_BSON_UpdateDeathCounters(MYFILE *fp, GAME_INFO *game_info)
goto cleanup;
}
JSON_ObjectEvictKey(misc_obj, "death_count");
JSON_ObjectAppendInt(misc_obj, "death_count", game_info->death_count);
JSON_ObjectAppendInt(misc_obj, "death_count", death_count);
File_Seek(fp, 0, FILE_SEEK_SET);
M_SaveRaw(fp, root, version);

View file

@ -15,4 +15,4 @@ bool Savegame_BSON_LoadFromFile(MYFILE *fp, GAME_INFO *game_info);
bool Savegame_BSON_LoadOnlyResumeInfo(MYFILE *fp, GAME_INFO *game_info);
void Savegame_BSON_SaveToFile(
MYFILE *fp, GAME_INFO *game_info, SAVEGAME_INFO *savegame_info);
bool Savegame_BSON_UpdateDeathCounters(MYFILE *fp, GAME_INFO *game_info);
bool Savegame_BSON_UpdateDeathCounters(MYFILE *fp, int32_t death_count);

View file

@ -378,7 +378,7 @@ static void M_ReadResumeInfo(MYFILE *const fp, GAME_INFO *const game_info)
if (is_ng_plus) {
Game_SetBonusFlag(GBF_NGPLUS);
}
game_info->death_count = -1;
resume_info->stats.death_count = -1;
}
const char *Savegame_Legacy_GetSaveFilePattern(void)
@ -575,9 +575,3 @@ bool Savegame_Legacy_LoadOnlyResumeInfo(MYFILE *fp, GAME_INFO *game_info)
Memory_FreePointer(&buffer);
return true;
}
bool Savegame_Legacy_UpdateDeathCounters(
MYFILE *const fp, GAME_INFO *const game_info)
{
return false;
}

View file

@ -13,4 +13,3 @@ const char *Savegame_Legacy_GetSaveFilePattern(void);
bool Savegame_Legacy_FillInfo(MYFILE *fp, SAVEGAME_INFO *info);
bool Savegame_Legacy_LoadFromFile(MYFILE *fp, GAME_INFO *game_info);
bool Savegame_Legacy_LoadOnlyResumeInfo(MYFILE *fp, GAME_INFO *game_info);
bool Savegame_Legacy_UpdateDeathCounters(MYFILE *fp, GAME_INFO *game_info);

View file

@ -328,3 +328,15 @@ void Stats_AddDistanceTravelled(const XYZ_32 pos, const XYZ_32 last_pos)
SQUARE(pos.z - last_pos.z) + SQUARE(pos.y - last_pos.y)
+ SQUARE(pos.x - last_pos.x));
}
void Stats_AddDeath(void)
{
const GF_LEVEL *const current_level = Game_GetCurrentLevel();
RESUME_INFO *const current_info = Savegame_GetCurrentInfo(current_level);
current_info->stats.death_count++;
const int32_t save_slot = Savegame_GetBoundSlot();
if (save_slot != -1) {
Savegame_UpdateDeathCounters(
save_slot, current_info->stats.death_count);
}
}

View file

@ -22,3 +22,4 @@ void Stats_AddAmmoHits(void);
void Stats_AddAmmoUsed(void);
void Stats_AddMedipacksUsed(double medipack_value);
void Stats_AddDistanceTravelled(XYZ_32 pos, XYZ_32 last_pos);
void Stats_AddDeath(void);

View file

@ -14,6 +14,7 @@ typedef struct STATS_COMMON {
uint32_t ammo_used;
double medipacks_used;
uint32_t distance_travelled;
int32_t death_count;
} STATS_COMMON;
typedef struct {

View file

@ -59,11 +59,8 @@ static const char *M_GetDialogTitle(UI_STATS_DIALOG *self);
static void M_AddRow(
UI_STATS_DIALOG *self, M_ROW_ROLE role, const char *key, const char *value);
static void M_AddRowFromRole(
UI_STATS_DIALOG *self, M_ROW_ROLE role, const STATS_COMMON *stats,
const GAME_INFO *game_info);
static void M_AddCommonRows(
UI_STATS_DIALOG *self, const STATS_COMMON *stats,
const GAME_INFO *game_info);
UI_STATS_DIALOG *self, M_ROW_ROLE role, const STATS_COMMON *stats);
static void M_AddCommonRows(UI_STATS_DIALOG *self, const STATS_COMMON *stats);
static void M_AddLevelStatsRows(UI_STATS_DIALOG *self);
static void M_AddFinalStatsRows(UI_STATS_DIALOG *self);
static void M_UpdateTimerRow(UI_STATS_DIALOG *self);
@ -146,7 +143,7 @@ static void M_AddRow(
static void M_AddRowFromRole(
UI_STATS_DIALOG *const self, const M_ROW_ROLE role,
const STATS_COMMON *const stats, const GAME_INFO *const game_info)
const STATS_COMMON *const stats)
{
char buf[50];
const char *const num_fmt =
@ -173,7 +170,7 @@ static void M_AddRowFromRole(
break;
case M_ROW_DEATHS:
sprintf(buf, GS(STATS_BASIC_FMT), game_info->death_count);
sprintf(buf, GS(STATS_BASIC_FMT), stats->death_count);
M_AddRow(self, role, GS(STATS_DEATHS), buf);
break;
@ -210,33 +207,31 @@ static void M_AddRowFromRole(
}
static void M_AddCommonRows(
UI_STATS_DIALOG *const self, const STATS_COMMON *const stats,
const GAME_INFO *const game_info)
UI_STATS_DIALOG *const self, const STATS_COMMON *const stats)
{
if (g_Config.gameplay.stat_detail_mode == SDM_MINIMAL) {
M_AddRowFromRole(self, M_ROW_KILLS, stats, game_info);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats, game_info);
M_AddRowFromRole(self, M_ROW_SECRETS, stats, game_info);
M_AddRowFromRole(self, M_ROW_TIMER, stats, game_info);
M_AddRowFromRole(self, M_ROW_KILLS, stats);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats);
M_AddRowFromRole(self, M_ROW_SECRETS, stats);
M_AddRowFromRole(self, M_ROW_TIMER, stats);
} else {
M_AddRowFromRole(self, M_ROW_TIMER, stats, game_info);
M_AddRowFromRole(self, M_ROW_SECRETS, stats, game_info);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats, game_info);
M_AddRowFromRole(self, M_ROW_KILLS, stats, game_info);
M_AddRowFromRole(self, M_ROW_TIMER, stats);
M_AddRowFromRole(self, M_ROW_SECRETS, stats);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats);
M_AddRowFromRole(self, M_ROW_KILLS, stats);
if (g_Config.gameplay.stat_detail_mode == SDM_FULL) {
M_AddRowFromRole(self, M_ROW_AMMO, stats, game_info);
M_AddRowFromRole(self, M_ROW_MEDIPACKS_USED, stats, game_info);
M_AddRowFromRole(self, M_ROW_DISTANCE_TRAVELLED, stats, game_info);
M_AddRowFromRole(self, M_ROW_AMMO, stats);
M_AddRowFromRole(self, M_ROW_MEDIPACKS_USED, stats);
M_AddRowFromRole(self, M_ROW_DISTANCE_TRAVELLED, stats);
}
}
if (g_Config.gameplay.enable_deaths_counter
&& game_info->death_count >= 0) {
if (g_Config.gameplay.enable_deaths_counter && stats->death_count >= 0) {
// Always use sum of all levels for the deaths.
// Deaths get stored in the resume info for the level they happen
// on, so if the player dies in Vilcabamba and reloads Caves, they
// should still see an incremented death counter.
M_AddRowFromRole(self, M_ROW_DEATHS, stats, game_info);
M_AddRowFromRole(self, M_ROW_DEATHS, stats);
}
}
@ -247,14 +242,14 @@ static void M_AddLevelStatsRows(UI_STATS_DIALOG *const self)
const RESUME_INFO *const current_info =
Savegame_GetCurrentInfo(current_level);
const STATS_COMMON *const stats = (STATS_COMMON *)&current_info->stats;
M_AddCommonRows(self, stats, &g_GameInfo);
M_AddCommonRows(self, stats);
}
static void M_AddFinalStatsRows(UI_STATS_DIALOG *const self)
{
FINAL_STATS final_stats;
Stats_ComputeFinal(self->level_type, &final_stats);
M_AddCommonRows(self, (STATS_COMMON *)&final_stats, &g_GameInfo);
M_AddCommonRows(self, (STATS_COMMON *)&final_stats);
}
static void M_UpdateTimerRow(UI_STATS_DIALOG *const self)

View file

@ -158,8 +158,6 @@ typedef struct {
} RESUME_INFO;
typedef struct {
int32_t death_count;
bool bonus_level_unlock;
int16_t save_initial_version;
PASSPORT_MODE passport_selection;