Fix rando items in gameplay stats (#6883)

Fixes a regression in displaying rando items and an oob check in the gameplay stats timestamps. Also adds missing random items to the list.
This commit is contained in:
A Green Spoon
2026-07-07 23:38:18 -04:00
committed by GitHub
parent bb6a80b480
commit 86fdb9bfe7
3 changed files with 166 additions and 33 deletions
+83 -15
View File
@@ -237,7 +237,7 @@ const char* const countMappings[] = {
#define COLOR_LIGHT_BLUE ImVec4(0.00f, 0.88f, 1.00f, 1.00f)
#define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f)
char itemTimestampDisplayName[TIMESTAMP_MAX][21] = { "" };
char itemTimestampDisplayName[TIMESTAMP_MAX][24] = { "" };
ImVec4 itemTimestampDisplayColor[TIMESTAMP_MAX];
typedef struct {
@@ -494,7 +494,7 @@ void DrawGameplayStatsTimestampsTab() {
ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch);
for (int i = 0; i < TIMESTAMP_MAX; i++) {
// To be shown, the entry must have a non-zero time and a string for its display name
if (itemTimestampDisplay[i].time > 0 && strnlen(itemTimestampDisplay[i].name, 21) > 1) {
if (itemTimestampDisplay[i].time > 0 && strnlen(itemTimestampDisplay[i].name, 24) > 1) {
GameplayStatsRow(itemTimestampDisplay[i].name, formatTimestampGameplayStat(itemTimestampDisplay[i].time),
itemTimestampDisplay[i].color);
}
@@ -831,19 +831,87 @@ void SetupDisplayNames() {
strcpy(itemTimestampDisplayName[ITEM_DOUBLE_DEFENSE], "Double Defense: ");
// Other events
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GOHMA], "Gohma Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_KING_DODONGO], "KD Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BARINADE], "Barinade Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_PHANTOM_GANON], "PG Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_VOLVAGIA], "Volvagia Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_MORPHA], "Morpha Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BONGO_BONGO], "Bongo Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_TWINROVA], "Twinrova Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANONDORF], "Ganondorf Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_BOSSRUSH_FINISH], "Boss Rush Finished: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_TRIFORCE_COMPLETED], "Triforce Completed: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GOHMA], "Gohma Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_KING_DODONGO], "KD Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BARINADE], "Barinade Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_PHANTOM_GANON], "PG Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_VOLVAGIA], "Volvagia Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_MORPHA], "Morpha Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BONGO_BONGO], "Bongo Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_TWINROVA], "Twinrova Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANONDORF], "Ganondorf Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_BOSSRUSH_FINISH], "Boss Rush Finished: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_TRIFORCE_COMPLETED], "Triforce Completed: ");
// Rando items
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GOHMA_SOUL], "Gohma's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_KING_DODONGO_SOUL], "Dodongo's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BARINADE_SOUL], "Barinade's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_PHANTOM_GANON_SOUL], "Phantom Ganon's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_VOLVAGIA_SOUL], "Volvagia's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_MORPHA_SOUL], "Morpha's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BONGO_BONGO_SOUL], "Bongo Bongo's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_TWINROVA_SOUL], "Twinrova's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GANON_SOUL], "Ganon's Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BRONZE_SCALE], "Bronze Scale: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_OCARINA_A_BUTTON], "Ocarina A Button: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_OCARINA_C_UP_BUTTON], "Ocarina C-Up Button: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_OCARINA_C_DOWN_BUTTON], "Ocarina C-Down Button: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_OCARINA_C_LEFT_BUTTON], "Ocarina C-Left Button: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_OCARINA_C_RIGHT_BUTTON], "Ocarina C-Right Button:");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_FISHING_POLE], "Fishing Pole: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GUARD_HOUSE_KEY], "Guard House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_MARKET_BAZAAR_KEY], "MK Bazaar Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_MARKET_POTION_SHOP_KEY], "MK Potion Shop Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_MASK_SHOP_KEY], "Mask Shop Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_MARKET_SHOOTING_GALLERY_KEY], "MK Shooting Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BOMBCHU_BOWLING_KEY], "Bombchu Bowling Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_TREASURE_CHEST_GAME_BUILDING_KEY], "Treasure Game Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BOMBCHU_SHOP_KEY], "Bombchu Shop Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_RICHARDS_HOUSE_KEY], "Richard's House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_ALLEY_HOUSE_KEY], "Alley House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_KAK_BAZAAR_KEY], "Kak Bazaar Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_KAK_POTION_SHOP_KEY], "Kak Potion Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BOSS_HOUSE_KEY], "Boss's House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GRANNYS_POTION_SHOP_KEY], "Granny's Shop Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SKULLTULA_HOUSE_KEY], "Skulltula House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_IMPAS_HOUSE_KEY], "Impa's House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_WINDMILL_KEY], "Windmill Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_KAK_SHOOTING_GALLERY_KEY], "Kak Shooting Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_DAMPES_HUT_KEY], "Dampe's Hut Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_TALONS_HOUSE_KEY], "Talon's House Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_STABLES_KEY], "Stables Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_BACK_TOWER_KEY], "Back Tower Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_HYLIA_LAB_KEY], "Hylia Lab Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_FISHING_HOLE_KEY], "Fishing Hole Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_CHILD_WALLET], "Child's Wallet: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_TYCOON_WALLET], "Tycoon Wallet: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_DEKU_STICK_BAG], "Deku Stick Bag: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_DEKU_NUT_BAG], "Deku Nut Bag: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GRAB], "Power Bracelet: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_CLIMB], "Climb: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_CRAWL], "Crawl: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_OPEN_CHESTS], "Open Chests: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SPEAK_DEKU], "Speak Deku: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SPEAK_GERUDO], "Speak Gerudo: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SPEAK_GORON], "Speak Goron: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SPEAK_HYLIAN], "SpeakHylian: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SPEAK_KOKIRI], "Speak Kokiri: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SPEAK_ZORA], "Speak Zora: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_DMC_BEAN_SOUL], "DMC Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_DMT_BEAN_SOUL], "DMT Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_COLOSSUS_BEAN_SOUL], "Colossus Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GV_BEAN_SOUL], "GV Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GY_BEAN_SOUL], "GY Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_KF_BEAN_SOUL], "KF Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_LH_BEAN_SOUL], "LH Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_LW_BRIDGE_BEAN_SOUL], "LW Bridge Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_LW_MEADOW_BEAN_SOUL], "LW Meadow Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_ZR_BEAN_SOUL], "ZR Bean Soul: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SKELETON_KEY], "Skeleton Key: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_ROCS_FEATHER], "Roc's Feather: ");
// clang-format on
}
+27 -1
View File
@@ -92,7 +92,33 @@ typedef enum {
/* 0xD2 */ TIMESTAMP_FOUND_BACK_TOWER_KEY,
/* 0xD3 */ TIMESTAMP_FOUND_HYLIA_LAB_KEY,
/* 0xD4 */ TIMESTAMP_FOUND_FISHING_HOLE_KEY,
/* 0xD5 */ TIMESTAMP_MAX
/* 0xD5 */ TIMESTAMP_FOUND_CHILD_WALLET,
/* 0xD6 */ TIMESTAMP_FOUND_TYCOON_WALLET,
/* 0xD7 */ TIMESTAMP_FOUND_DEKU_STICK_BAG,
/* 0xD8 */ TIMESTAMP_FOUND_DEKU_NUT_BAG,
/* 0xD9 */ TIMESTAMP_FOUND_GRAB,
/* 0xDA */ TIMESTAMP_FOUND_CLIMB,
/* 0xDB */ TIMESTAMP_FOUND_CRAWL,
/* 0xDC */ TIMESTAMP_FOUND_OPEN_CHESTS,
/* 0xDD */ TIMESTAMP_FOUND_SPEAK_DEKU,
/* 0xDE */ TIMESTAMP_FOUND_SPEAK_GERUDO,
/* 0xDF */ TIMESTAMP_FOUND_SPEAK_GORON,
/* 0xE0 */ TIMESTAMP_FOUND_SPEAK_HYLIAN,
/* 0xE1 */ TIMESTAMP_FOUND_SPEAK_KOKIRI,
/* 0xE2 */ TIMESTAMP_FOUND_SPEAK_ZORA,
/* 0xE3 */ TIMESTAMP_FOUND_DMC_BEAN_SOUL,
/* 0xE4 */ TIMESTAMP_FOUND_DMT_BEAN_SOUL,
/* 0xE5 */ TIMESTAMP_FOUND_COLOSSUS_BEAN_SOUL,
/* 0xE6 */ TIMESTAMP_FOUND_GV_BEAN_SOUL,
/* 0xE7 */ TIMESTAMP_FOUND_GY_BEAN_SOUL,
/* 0xE8 */ TIMESTAMP_FOUND_KF_BEAN_SOUL,
/* 0xE9 */ TIMESTAMP_FOUND_LH_BEAN_SOUL,
/* 0xEA */ TIMESTAMP_FOUND_LW_BRIDGE_BEAN_SOUL,
/* 0xEB */ TIMESTAMP_FOUND_LW_MEADOW_BEAN_SOUL,
/* 0xEC */ TIMESTAMP_FOUND_ZR_BEAN_SOUL,
/* 0xED */ TIMESTAMP_FOUND_SKELETON_KEY,
/* 0xEE */ TIMESTAMP_FOUND_ROCS_FEATHER,
/* 0xF0 */ TIMESTAMP_MAX
} GameplayStatTimestamp;
typedef enum {
+56 -17
View File
@@ -1033,6 +1033,41 @@ static std::unordered_map<RandomizerGet, GameplayStatTimestamp> randomizerGetToS
{ RG_BACK_TOWER_KEY, TIMESTAMP_FOUND_BACK_TOWER_KEY },
{ RG_HYLIA_LAB_KEY, TIMESTAMP_FOUND_HYLIA_LAB_KEY },
{ RG_FISHING_HOLE_KEY, TIMESTAMP_FOUND_FISHING_HOLE_KEY },
{ RG_GREG_RUPEE, TIMESTAMP_FOUND_GREG },
{ RG_CHILD_WALLET, TIMESTAMP_FOUND_CHILD_WALLET },
{ RG_TYCOON_WALLET, TIMESTAMP_FOUND_TYCOON_WALLET },
{ RG_DEKU_STICK_BAG, TIMESTAMP_FOUND_DEKU_STICK_BAG },
{ RG_DEKU_NUT_BAG, TIMESTAMP_FOUND_DEKU_NUT_BAG },
{ RG_POWER_BRACELET, TIMESTAMP_FOUND_GRAB },
{ RG_CLIMB, TIMESTAMP_FOUND_CLIMB },
{ RG_CRAWL, TIMESTAMP_FOUND_CRAWL },
{ RG_OPEN_CHEST, TIMESTAMP_FOUND_OPEN_CHESTS },
{ RG_SPEAK_DEKU, TIMESTAMP_FOUND_SPEAK_DEKU },
{ RG_SPEAK_GERUDO, TIMESTAMP_FOUND_SPEAK_GERUDO },
{ RG_SPEAK_GORON, TIMESTAMP_FOUND_SPEAK_GORON },
{ RG_SPEAK_HYLIAN, TIMESTAMP_FOUND_SPEAK_HYLIAN },
{ RG_SPEAK_KOKIRI, TIMESTAMP_FOUND_SPEAK_KOKIRI },
{ RG_SPEAK_ZORA, TIMESTAMP_FOUND_SPEAK_ZORA },
{ RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, TIMESTAMP_FOUND_DMC_BEAN_SOUL },
{ RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, TIMESTAMP_FOUND_DMT_BEAN_SOUL },
{ RG_DESERT_COLOSSUS_BEAN_SOUL, TIMESTAMP_FOUND_COLOSSUS_BEAN_SOUL },
{ RG_GERUDO_VALLEY_BEAN_SOUL, TIMESTAMP_FOUND_GV_BEAN_SOUL },
{ RG_GRAVEYARD_BEAN_SOUL, TIMESTAMP_FOUND_GY_BEAN_SOUL },
{ RG_KOKIRI_FOREST_BEAN_SOUL, TIMESTAMP_FOUND_KF_BEAN_SOUL },
{ RG_LAKE_HYLIA_BEAN_SOUL, TIMESTAMP_FOUND_LH_BEAN_SOUL },
{ RG_LOST_WOODS_BRIDGE_BEAN_SOUL, TIMESTAMP_FOUND_LW_BRIDGE_BEAN_SOUL },
{ RG_LOST_WOODS_BEAN_SOUL, TIMESTAMP_FOUND_LW_MEADOW_BEAN_SOUL },
{ RG_ZORAS_RIVER_BEAN_SOUL, TIMESTAMP_FOUND_ZR_BEAN_SOUL },
{ RG_SKELETON_KEY, TIMESTAMP_FOUND_SKELETON_KEY },
{ RG_ROCS_FEATHER, TIMESTAMP_FOUND_ROCS_FEATHER },
};
// Gameplay stat tracking: Update time the item was acquired
@@ -1044,22 +1079,27 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
time = 1;
}
if (gSaveContext.ship.stats.itemTimestamp[item] == 0) {
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
gSaveContext.ship.stats.itemTimestamp[ITEM_KEY_BOSS] = time;
} else if (item == RG_MASTER_SWORD) {
gSaveContext.ship.stats.itemTimestamp[ITEM_SWORD_MASTER] = time;
} else if (randomizerGetToStatsTimeStamp.contains((RandomizerGet)item)) {
gSaveContext.ship.stats.itemTimestamp[randomizerGetToStatsTimeStamp[(RandomizerGet)item]] = time;
} else if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) {
gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] = time;
} else if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHU_BAG) {
gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = time;
} else if (item == RG_MAGIC_SINGLE) {
gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
} else if (item == RG_DOUBLE_DEFENSE) {
gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
}
int16_t timestampItem = -1;
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
timestampItem = ITEM_KEY_BOSS;
} else if (item == RG_MASTER_SWORD) {
timestampItem = ITEM_SWORD_MASTER;
} else if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) {
timestampItem = ITEM_BOTTLE;
} else if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHU_BAG) {
timestampItem = ITEM_BOMBCHU;
} else if (item == RG_MAGIC_SINGLE) {
timestampItem = ITEM_SINGLE_MAGIC;
} else if (item == RG_DOUBLE_DEFENSE) {
timestampItem = ITEM_DOUBLE_DEFENSE;
} else if (item >= RG_KEATON_MASK && item <= RG_MASK_OF_TRUTH) {
timestampItem = ITEM_MASK_KEATON + (item - RG_KEATON_MASK);
} else if (randomizerGetToStatsTimeStamp.contains((RandomizerGet)item)) {
timestampItem = randomizerGetToStatsTimeStamp[(RandomizerGet)item];
}
if (timestampItem != -1 && gSaveContext.ship.stats.itemTimestamp[timestampItem] == 0) {
gSaveContext.ship.stats.itemTimestamp[timestampItem] = time;
}
}
@@ -1104,7 +1144,6 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
Rupees_ChangeBy(99);
} else if (item == RG_GREG_RUPEE) {
Rupees_ChangeBy(1);
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_FOUND_GREG] = static_cast<u32>(GAMEPLAYSTAT_TOTAL_TIME);
}
return Return_Item_Entry(giEntry, RG_NONE);