From 8c23bcd67c8b98068f95d9c38f732f4805a42d9c Mon Sep 17 00:00:00 2001 From: Sarge-117 <108380086+Sarge-117@users.noreply.github.com> Date: Sat, 10 Dec 2022 12:37:33 -0800 Subject: [PATCH] Gameplay stats 1.1 (#2129) --- soh/soh/Enhancements/gameplaystats.cpp | 8 ++++++++ soh/soh/Enhancements/gameplaystats.h | 4 ++++ soh/src/code/z_parameter.c | 18 +++++++++++++++--- soh/src/code/z_play.c | 4 ++++ .../actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 1 + .../actors/ovl_player_actor/z_player.c | 7 +++++++ 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index ccdee19ec..9cc808bc2 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -193,6 +193,7 @@ void DrawStatsTracker(bool& open) { DisplayStatIfNonZero("Anubis: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ANUBIS]); DisplayStatIfNonZero("Armos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ARMOS]); + DisplayStatIfNonZero("Arwing: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ARWING]); DisplayStatIfNonZero("Bari: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BARI]); DisplayStatIfNonZero("Biri: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BIRI]); DisplayStatIfNonZero("Beamos: ", gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BEAMOS]); @@ -292,8 +293,14 @@ void DrawStatsTracker(bool& open) { DisplayStat("Damage Taken: ", gSaveContext.sohStats.count[COUNT_DAMAGE_TAKEN]); DisplayStat("Sword Swings: ", gSaveContext.sohStats.count[COUNT_SWORD_SWINGS]); DisplayStat("Steps Taken: ", gSaveContext.sohStats.count[COUNT_STEPS]); + // If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time) + if (CVar_GetS32("gMMBunnyHood", 0) || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) { + DisplayTimeHHMMSS(gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] / 2, "Bunny Hood Time: ", COLOR_WHITE); + } DisplayStat("Rolls: ", gSaveContext.sohStats.count[COUNT_ROLLS]); DisplayStat("Bonks: ", gSaveContext.sohStats.count[COUNT_BONKS]); + DisplayStat("Sidehops: ", gSaveContext.sohStats.count[COUNT_SIDEHOPS]); + DisplayStat("Backflips: ", gSaveContext.sohStats.count[COUNT_BACKFLIPS]); DisplayStat("Ice Traps: ", gSaveContext.sohStats.count[COUNT_ICE_TRAPS]); DisplayStat("Pauses: ", gSaveContext.sohStats.count[COUNT_PAUSES]); DisplayStat("Pots Smashed: ", gSaveContext.sohStats.count[COUNT_POTS_BROKEN]); @@ -393,6 +400,7 @@ void SetupDisplayNames() { strcpy(timestampDisplayName[ITEM_KOKIRI_EMERALD], "Kokiri's Emerald: "); strcpy(timestampDisplayName[ITEM_GORON_RUBY], "Goron's Ruby: "); strcpy(timestampDisplayName[ITEM_ZORA_SAPPHIRE], "Zora's Sapphire: "); + strcpy(timestampDisplayName[ITEM_KEY_BOSS], "Ganon's Boss Key: "); strcpy(timestampDisplayName[ITEM_SINGLE_MAGIC], "Magic: "); strcpy(timestampDisplayName[ITEM_DOUBLE_DEFENSE], "Double Defense: "); diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index dc0cfaa38..78bea8b9d 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -29,6 +29,7 @@ typedef enum { // Enemies defeated COUNT_ENEMIES_DEFEATED_ANUBIS, // EN_ANUBICE COUNT_ENEMIES_DEFEATED_ARMOS, // EN_AM + COUNT_ENEMIES_DEFEATED_ARWING, // EN_CLEAR_TAG COUNT_ENEMIES_DEFEATED_BARI, // EN_VALI COUNT_ENEMIES_DEFEATED_BEAMOS, // EN_VM COUNT_ENEMIES_DEFEATED_BIG_OCTO, // EN_BIGOKUTA @@ -132,6 +133,9 @@ typedef enum { COUNT_POTS_BROKEN, // z_obj_tsubo.c COUNT_BUSHES_CUT, // z_en_kusa.c COUNT_SWORD_SWINGS, // z_player.c + COUNT_SIDEHOPS, // z_player.c + COUNT_BACKFLIPS, // z_player.c + COUNT_TIME_BUNNY_HOOD, // z_play.c COUNT_MAX diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 020422d61..9e6654f91 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1616,11 +1616,18 @@ void func_80084BF4(PlayState* play, u16 flag) { // Gameplay stat tracking: Update time the item was acquired // (special cases for some duplicate items) -void GameplayStats_SetTimestamp(u8 item) { +void GameplayStats_SetTimestamp(PlayState* play, u8 item) { - if (gSaveContext.sohStats.timestamp[item] != 0) { + // If we already have a timestamp for this item, do nothing + if (gSaveContext.sohStats.timestamp[item] != 0){ return; } + // Use ITEM_KEY_BOSS only for Ganon's boss key - not any other boss keys + if (play != NULL) { + if (item == ITEM_KEY_BOSS && play->sceneNum != 13 && play->sceneNum != 10) { + return; + } + } u32 time = GAMEPLAYSTAT_TOTAL_TIME; @@ -1658,6 +1665,11 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { time = 1; } + // Use ITEM_KEY_BOSS to timestamp Ganon's boss key + if (item == RG_GANONS_CASTLE_BOSS_KEY) { + gSaveContext.sohStats.timestamp[ITEM_KEY_BOSS] = time; + } + // Count any bottled item as a bottle if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) { if (gSaveContext.sohStats.timestamp[ITEM_BOTTLE] == 0) { @@ -1698,7 +1710,7 @@ u8 Item_Give(PlayState* play, u8 item) { s16 temp; // Gameplay stats: Update the time the item was obtained - GameplayStats_SetTimestamp(item); + GameplayStats_SetTimestamp(play, item); slot = SLOT(item); if (item >= ITEM_STICKS_5) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index fe4ca7ca7..04f239ca8 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1087,6 +1087,10 @@ void Play_Update(PlayState* play) { // Gameplay stat tracking if (!gSaveContext.sohStats.gameComplete) { gSaveContext.sohStats.playTimer++; + + if (CVar_GetS32("gMMBunnyHood", 0) && Player_GetMask(play) == PLAYER_MASK_BUNNY) { + gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD]++; + } } func_800AA178(1); diff --git a/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index 7b63c77ab..317174e99 100644 --- a/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -374,6 +374,7 @@ void EnClearTag_Update(Actor* thisx, PlayState* play2) { if ((s8)this->actor.colChkInfo.health <= 0) { this->state = CLEAR_TAG_STATE_CRASHING; this->actor.velocity.y = 0.0f; + gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_ARWING]++; goto state_crashing; } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 9859a7ebe..89450c587 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -5350,6 +5350,13 @@ s32 func_8083BDBC(Player* this, PlayState* play) { } } else { func_8083BCD0(this, play, sp2C); + if (sp2C == 1 || sp2C == 3) { + gSaveContext.sohStats.count[COUNT_SIDEHOPS]++; + } + if (sp2C == 2) { + gSaveContext.sohStats.count[COUNT_BACKFLIPS]++; + } + return 1; } }