Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions prboom2/src/hexen/sv_save.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ typedef enum
ASEG_PLAYERS,
ASEG_SOUNDS,
ASEG_MISC,
ASEG_STATS,
ASEG_END
} gameArchiveSegment_t;

Expand Down Expand Up @@ -97,6 +98,17 @@ static int TargetPlayerCount;
extern int inv_ptr;
extern int curpos;

typedef struct
{
dboolean visited; // whether to reset stats
int killcount[MAX_MAXPLAYERS];
int maxkilldiscount[MAX_MAXPLAYERS];
int itemcount[MAX_MAXPLAYERS];
int secretcount[MAX_MAXPLAYERS];
} hub_mapstats_t;

static hub_mapstats_t hub_mapstats[MAX_MAPS];

typedef struct
{
size_t size;
Expand Down Expand Up @@ -1878,6 +1890,18 @@ static void UnarchivePolyobjs(void)
}
}

static void ArchiveStats(void)
{
SV_WriteLong(ASEG_STATS);
SV_Write(&hub_mapstats[gamemap], sizeof(hub_mapstats[gamemap]));
}

static void UnarchiveStats(void)
{
AssertSegment(ASEG_STATS);
SV_Read(&hub_mapstats[gamemap], sizeof(hub_mapstats[gamemap]));
}

void SV_SaveMap(void)
{
// Initialize the output buffer
Expand All @@ -1900,6 +1924,9 @@ void SV_SaveMap(void)
ArchiveSounds();
ArchiveMisc();

// DSDA Extra: save stats per map
ArchiveStats();

// Place a termination marker
SV_WriteLong(ASEG_END);
}
Expand Down Expand Up @@ -1928,12 +1955,64 @@ void SV_LoadMap(void)
UnarchiveSounds();
UnarchiveMisc();

// DSDA Extra: load stats per map
UnarchiveStats();

AssertSegment(ASEG_END);

// Free mobj list and save buffer
Z_Free(MobjList);
}

static void SV_SaveCurrentMapStats(void)
{
if (gamemap < MAX_MAPS)
{
hub_mapstats_t *hub_stats = &hub_mapstats[gamemap];
hub_stats->visited = true;

for (int i = 0; i < g_maxplayers; ++i)
{
if (!playeringame[i]) continue;
hub_stats->killcount[i] = players[i].killcount;
hub_stats->maxkilldiscount[i] = players[i].maxkilldiscount;
hub_stats->itemcount[i] = players[i].itemcount;
hub_stats->secretcount[i] = players[i].secretcount;
}
}
}

static void SV_LoadCurrentMapStats(void)
{
if (gamemap < MAX_MAPS)
{
hub_mapstats_t *hub_stats = &hub_mapstats[gamemap];

for (int i = 0; i < g_maxplayers; ++i)
{
if (!playeringame[i]) continue;

if (hub_stats->visited)
{
players[i].killcount = hub_stats->killcount[i];
players[i].maxkilldiscount = hub_stats->maxkilldiscount[i];
players[i].itemcount = hub_stats->itemcount[i];
players[i].secretcount = hub_stats->secretcount[i];
}
else
{
// First visit: reset
players[i].killcount = 0;
players[i].maxkilldiscount = 0;
players[i].itemcount = 0;
players[i].secretcount = 0;
}
}

hub_stats->visited = true;
}
}

void SV_MapTeleport(int map, int position)
{
int i;
Expand Down Expand Up @@ -1963,6 +2042,7 @@ void SV_MapTeleport(int map, int position)
else
{ // Entering new cluster - clear map archive
SV_Init();
memset(hub_mapstats, 0, sizeof(hub_mapstats)); // reset stats
}
}

Expand Down Expand Up @@ -2078,6 +2158,9 @@ void SV_MapTeleport(int map, int position)
}
randomclass = rClass;

// Load map stats (ex: kills)
SV_LoadCurrentMapStats();

// Redirect anything targeting a player mobj
if (TargetPlayerAddrs)
{
Expand Down
Loading