From c22d6d75db0f58c4f91b13e8ab3de6721b0529fc Mon Sep 17 00:00:00 2001 From: Eidolon Date: Thu, 29 Feb 2024 18:09:26 -0600 Subject: [PATCH] Add several skin record stats, profile rounds --- src/doomstat.h | 4 ++++ src/g_gamedata.cpp | 23 +++++++++++++++++++-- src/g_gamedata.h | 31 +++++++++++++++++++++++++++- src/k_kart.c | 8 ++++++++ src/k_profiles.cpp | 3 +++ src/k_profiles.h | 4 +++- src/p_tick.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 21 +++++++++++++++---- 8 files changed, 137 insertions(+), 8 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 42420d911..20af72ed1 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -122,6 +122,10 @@ extern preciptype_t curWeather; struct skinrecord_t { 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 diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp index 6cd19aaff..d95b3796e 100644 --- a/src/g_gamedata.cpp +++ b/src/g_gamedata.cpp @@ -109,8 +109,18 @@ void srb2::save_ng_gamedata() for (int i = 0; i < numskins; i++) { srb2::GamedataSkinJson skin {}; - std::string name = std::string(skins[i].name); - skin.records.wins = skins[i].records.wins; + skin_t& memskin = skins[i]; + + 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); } 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); skinrecord_t dummyrecord {}; + 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) { diff --git a/src/g_gamedata.h b/src/g_gamedata.h index f00874acd..0b34c477a 100644 --- a/src/g_gamedata.h +++ b/src/g_gamedata.h @@ -120,11 +120,40 @@ struct GamedataChallengeGridJson final 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 { 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 diff --git a/src/k_kart.c b/src/k_kart.c index 215265bca..f4122ee6f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8196,11 +8196,19 @@ void K_KartPlayerHUDUpdate(player_t *player) else player->karthud[khud_finish] = 0; + // Tumble time stat update if (demo.playback == false && P_IsMachineLocalPlayer(player) == true) { if (player->tumbleBounces != 0 && gamedata->totaltumbletime != UINT32_MAX) { gamedata->totaltumbletime++; + + if (player->skin >= 0 && player->skin < numskins) + { + skin_t *playerskin; + playerskin = &skins[player->skin]; + playerskin->records.tumbletime++; + } } } } diff --git a/src/k_profiles.cpp b/src/k_profiles.cpp index 1206c90c8..2d29e8c82 100644 --- a/src/k_profiles.cpp +++ b/src/k_profiles.cpp @@ -88,6 +88,7 @@ profile_t* PR_MakeProfile( memcpy(newprofile->controls, controlarray, sizeof(newprofile->controls)); newprofile->wins = 0; + newprofile->rounds = 0; return newprofile; } @@ -293,6 +294,7 @@ void PR_SaveProfiles(void) jsonprof.followercolorname = std::string(skincolors[cprof->followercolor].name); } jsonprof.records.wins = cprof->wins; + jsonprof.records.rounds = cprof->rounds; jsonprof.preferences.kickstartaccel = cprof->kickstartaccel; jsonprof.preferences.autoroulette = cprof->autoroulette; jsonprof.preferences.litesteer = cprof->litesteer; @@ -458,6 +460,7 @@ void PR_LoadProfiles(void) } newprof->wins = jsprof.records.wins; + newprof->rounds = jsprof.records.rounds; newprof->kickstartaccel = jsprof.preferences.kickstartaccel; newprof->autoroulette = jsprof.preferences.autoroulette; newprof->litesteer = jsprof.preferences.litesteer; diff --git a/src/k_profiles.h b/src/k_profiles.h index 1bbb48d6e..0d1c922bd 100644 --- a/src/k_profiles.h +++ b/src/k_profiles.h @@ -36,8 +36,9 @@ namespace srb2 struct ProfileRecordsJson { 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 @@ -147,6 +148,7 @@ struct profile_t UINT16 followercolor; // Follower color UINT32 wins; // I win I win I win + UINT32 rounds; // I played I played I played // Player-specific consvars. // @TODO: List all of those diff --git a/src/p_tick.c b/src/p_tick.c index 162941c64..a42161ce5 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -944,13 +944,64 @@ void P_Ticker(boolean run) // Keep track of how long they've been playing! 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) { INT32 mode = M_GameDataGameType(gametype, battleprisons); + + // Gamedata mode playtime if (mode >= 0 && mode < GDGT_MAX) { 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... diff --git a/src/p_user.c b/src/p_user.c index e4bdd8a3b..ecfe54dee 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1315,18 +1315,31 @@ void P_DoPlayerExit(player_t *player, pflags_t flags) G_UpdateRecords(); } - if (!losing) + // Profile and skin record updates + if (P_IsMachineLocalPlayer(player)) { profile_t *pr = PR_GetPlayerProfile(player); + + // Profile records if (pr != NULL) { - pr->wins++; + if (!losing) + { + pr->wins++; + } + pr->rounds++; 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++; } }