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
{
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

View file

@ -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)
{

View file

@ -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

View file

@ -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++;
}
}
}
}

View file

@ -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;

View file

@ -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

View file

@ -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...

View file

@ -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++;
}
}