Add several skin record stats, profile rounds

This commit is contained in:
Eidolon 2024-02-29 18:09:26 -06:00
parent 19341b71a3
commit c22d6d75db
8 changed files with 137 additions and 8 deletions

View file

@ -122,6 +122,10 @@ extern preciptype_t curWeather;
struct skinrecord_t struct skinrecord_t
{ {
UINT32 wins; UINT32 wins;
UINT32 rounds;
UINT32 timeplayed;
UINT32 modetimeplayed[5]; // no GDGT_MAX, m_cond.h is not included in here... it might need to be?
UINT32 tumbletime;
}; };
struct unloaded_skin_t struct unloaded_skin_t

View file

@ -109,8 +109,18 @@ void srb2::save_ng_gamedata()
for (int i = 0; i < numskins; i++) for (int i = 0; i < numskins; i++)
{ {
srb2::GamedataSkinJson skin {}; srb2::GamedataSkinJson skin {};
std::string name = std::string(skins[i].name); skin_t& memskin = skins[i];
skin.records.wins = skins[i].records.wins;
std::string name = std::string(memskin.name);
skin.records.wins = memskin.records.wins;
skin.records.rounds = memskin.records.rounds;
skin.records.time.total = memskin.records.timeplayed;
skin.records.time.race = memskin.records.modetimeplayed[GDGT_RACE];
skin.records.time.battle = memskin.records.modetimeplayed[GDGT_BATTLE];
skin.records.time.prisons = memskin.records.modetimeplayed[GDGT_PRISONS];
skin.records.time.special = memskin.records.modetimeplayed[GDGT_SPECIAL];
skin.records.time.custom = memskin.records.modetimeplayed[GDGT_CUSTOM];
skin.records.time.tumble = memskin.records.tumbletime;
ng.skins[name] = std::move(skin); ng.skins[name] = std::move(skin);
} }
for (auto unloadedskin = unloadedskins; unloadedskin; unloadedskin = unloadedskin->next) for (auto unloadedskin = unloadedskins; unloadedskin; unloadedskin = unloadedskin->next)
@ -516,7 +526,16 @@ void srb2::load_ng_gamedata()
{ {
INT32 skin = R_SkinAvailableEx(skinpair.first.c_str(), false); INT32 skin = R_SkinAvailableEx(skinpair.first.c_str(), false);
skinrecord_t dummyrecord {}; skinrecord_t dummyrecord {};
dummyrecord.wins = skinpair.second.records.wins; dummyrecord.wins = skinpair.second.records.wins;
dummyrecord.rounds = skinpair.second.records.rounds;
dummyrecord.timeplayed = skinpair.second.records.time.total;
dummyrecord.modetimeplayed[GDGT_RACE] = skinpair.second.records.time.race;
dummyrecord.modetimeplayed[GDGT_BATTLE] = skinpair.second.records.time.battle;
dummyrecord.modetimeplayed[GDGT_PRISONS] = skinpair.second.records.time.prisons;
dummyrecord.modetimeplayed[GDGT_SPECIAL] = skinpair.second.records.time.special;
dummyrecord.modetimeplayed[GDGT_CUSTOM] = skinpair.second.records.time.custom;
dummyrecord.tumbletime = skinpair.second.records.time.tumble;
if (skin != -1) if (skin != -1)
{ {

View file

@ -120,11 +120,40 @@ struct GamedataChallengeGridJson final
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(GamedataChallengeGridJson, width, grid) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(GamedataChallengeGridJson, width, grid)
}; };
struct GamedataSkinRecordsPlaytimeJson final
{
uint32_t total;
uint32_t race;
uint32_t battle;
uint32_t prisons;
uint32_t special;
uint32_t custom;
uint32_t tumble;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
GamedataSkinRecordsPlaytimeJson,
total,
race,
battle,
prisons,
special,
custom,
tumble
)
};
struct GamedataSkinRecordsJson final struct GamedataSkinRecordsJson final
{ {
uint32_t wins; uint32_t wins;
uint32_t rounds;
GamedataSkinRecordsPlaytimeJson time;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(GamedataSkinRecordsJson, wins) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
GamedataSkinRecordsJson,
wins,
rounds,
time
)
}; };
struct GamedataSkinJson final struct GamedataSkinJson final

View file

@ -8196,11 +8196,19 @@ void K_KartPlayerHUDUpdate(player_t *player)
else else
player->karthud[khud_finish] = 0; player->karthud[khud_finish] = 0;
// Tumble time stat update
if (demo.playback == false && P_IsMachineLocalPlayer(player) == true) if (demo.playback == false && P_IsMachineLocalPlayer(player) == true)
{ {
if (player->tumbleBounces != 0 && gamedata->totaltumbletime != UINT32_MAX) if (player->tumbleBounces != 0 && gamedata->totaltumbletime != UINT32_MAX)
{ {
gamedata->totaltumbletime++; gamedata->totaltumbletime++;
if (player->skin >= 0 && player->skin < numskins)
{
skin_t *playerskin;
playerskin = &skins[player->skin];
playerskin->records.tumbletime++;
}
} }
} }
} }

View file

@ -88,6 +88,7 @@ profile_t* PR_MakeProfile(
memcpy(newprofile->controls, controlarray, sizeof(newprofile->controls)); memcpy(newprofile->controls, controlarray, sizeof(newprofile->controls));
newprofile->wins = 0; newprofile->wins = 0;
newprofile->rounds = 0;
return newprofile; return newprofile;
} }
@ -293,6 +294,7 @@ void PR_SaveProfiles(void)
jsonprof.followercolorname = std::string(skincolors[cprof->followercolor].name); jsonprof.followercolorname = std::string(skincolors[cprof->followercolor].name);
} }
jsonprof.records.wins = cprof->wins; jsonprof.records.wins = cprof->wins;
jsonprof.records.rounds = cprof->rounds;
jsonprof.preferences.kickstartaccel = cprof->kickstartaccel; jsonprof.preferences.kickstartaccel = cprof->kickstartaccel;
jsonprof.preferences.autoroulette = cprof->autoroulette; jsonprof.preferences.autoroulette = cprof->autoroulette;
jsonprof.preferences.litesteer = cprof->litesteer; jsonprof.preferences.litesteer = cprof->litesteer;
@ -458,6 +460,7 @@ void PR_LoadProfiles(void)
} }
newprof->wins = jsprof.records.wins; newprof->wins = jsprof.records.wins;
newprof->rounds = jsprof.records.rounds;
newprof->kickstartaccel = jsprof.preferences.kickstartaccel; newprof->kickstartaccel = jsprof.preferences.kickstartaccel;
newprof->autoroulette = jsprof.preferences.autoroulette; newprof->autoroulette = jsprof.preferences.autoroulette;
newprof->litesteer = jsprof.preferences.litesteer; newprof->litesteer = jsprof.preferences.litesteer;

View file

@ -36,8 +36,9 @@ namespace srb2
struct ProfileRecordsJson struct ProfileRecordsJson
{ {
uint32_t wins; uint32_t wins;
uint32_t rounds;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ProfileRecordsJson, wins) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ProfileRecordsJson, wins, rounds)
}; };
struct ProfilePreferencesJson struct ProfilePreferencesJson
@ -147,6 +148,7 @@ struct profile_t
UINT16 followercolor; // Follower color UINT16 followercolor; // Follower color
UINT32 wins; // I win I win I win UINT32 wins; // I win I win I win
UINT32 rounds; // I played I played I played
// Player-specific consvars. // Player-specific consvars.
// @TODO: List all of those // @TODO: List all of those

View file

@ -944,13 +944,64 @@ void P_Ticker(boolean run)
// Keep track of how long they've been playing! // Keep track of how long they've been playing!
gamedata->totalplaytime++; gamedata->totalplaytime++;
// Per-skin total playtime for all machine-local players
for (i = 0; i < MAXPLAYERS; i++)
{
skin_t *playerskin;
if (!P_IsMachineLocalPlayer(&players[i]))
{
continue;
}
if (!(playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)))
{
continue;
}
if (players[i].skin >= numskins)
{
continue;
}
playerskin = &skins[players[i].skin];
playerskin->records.timeplayed++;
}
if (gametype != GT_TUTORIAL) if (gametype != GT_TUTORIAL)
{ {
INT32 mode = M_GameDataGameType(gametype, battleprisons); INT32 mode = M_GameDataGameType(gametype, battleprisons);
// Gamedata mode playtime
if (mode >= 0 && mode < GDGT_MAX) if (mode >= 0 && mode < GDGT_MAX)
{ {
gamedata->modeplaytime[mode]++; gamedata->modeplaytime[mode]++;
} }
// Per-skin mode playtime
for (i = 0; i < MAXPLAYERS; i++)
{
skin_t *playerskin;
if (!P_IsMachineLocalPlayer(&players[i]))
{
continue;
}
if (!(playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)))
{
continue;
}
if (players[i].skin >= numskins)
{
continue;
}
playerskin = &skins[players[i].skin];
playerskin->records.modetimeplayed[mode]++;
}
} }
// TODO would this be laggy with more conditions in play... // TODO would this be laggy with more conditions in play...

View file

@ -1315,18 +1315,31 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
G_UpdateRecords(); G_UpdateRecords();
} }
if (!losing) // Profile and skin record updates
if (P_IsMachineLocalPlayer(player))
{ {
profile_t *pr = PR_GetPlayerProfile(player); profile_t *pr = PR_GetPlayerProfile(player);
// Profile records
if (pr != NULL) if (pr != NULL)
{ {
pr->wins++; if (!losing)
{
pr->wins++;
}
pr->rounds++;
PR_SaveProfiles(); PR_SaveProfiles();
} }
if (P_IsMachineLocalPlayer(player) && player->skin < numskins) // Skin records (saved to gamedata)
if (player->skin < numskins)
{ {
skins[player->skin].records.wins++; skin_t *playerskin = &skins[player->skin];
if (!losing)
{
playerskin->records.wins++;
}
playerskin->records.rounds++;
} }
} }