mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-01-30 23:10:14 -05:00
Organize ship specific save context additions (#4597)
* Basic restructure * Undo most randomizerInf changes for now * Small fixes * Fix linux & mac builds? * Fix remnants of randomizerInf changes * Post-merge fix * Post-merge fix
This commit is contained in:
parent
0d80c4695f
commit
7f31fd2e4e
@ -157,6 +157,42 @@ typedef struct {
|
||||
char hintText[200];
|
||||
} HintLocationRando;
|
||||
|
||||
#pragma region SoH
|
||||
|
||||
typedef struct ShipRandomizerSaveContextData {
|
||||
u16 adultTradeItems;
|
||||
u8 triforcePiecesCollected;
|
||||
} ShipRandomizerSaveContextData;
|
||||
|
||||
typedef struct ShipBossRushSaveContextData {
|
||||
u32 isPaused;
|
||||
u8 options[BR_OPTIONS_MAX];
|
||||
} ShipBossRushSaveContextData;
|
||||
|
||||
typedef union ShipQuestSpecificSaveContextData {
|
||||
ShipRandomizerSaveContextData randomizer;
|
||||
ShipBossRushSaveContextData bossRush;
|
||||
} ShipQuestSpecificSaveContextData;
|
||||
|
||||
typedef struct ShipQuestSaveContextData {
|
||||
u8 id;
|
||||
ShipQuestSpecificSaveContextData data;
|
||||
} ShipQuestSaveContextData;
|
||||
|
||||
typedef struct ShipSaveContextData {
|
||||
u16 pendingSale;
|
||||
u16 pendingSaleMod;
|
||||
u8 pendingIceTrapCount;
|
||||
SohStats stats;
|
||||
FaroresWindData backupFW;
|
||||
ShipQuestSaveContextData quest;
|
||||
u8 maskMemory;
|
||||
//TODO: Move non-rando specific flags to a new sohInf and move the remaining randomizerInf to ShipRandomizerSaveContextData
|
||||
u16 randomizerInf[(RAND_INF_MAX + 15) / 16];
|
||||
} ShipSaveContextData;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
typedef struct {
|
||||
/* 0x0000 */ s32 entranceIndex; // start of `save` substruct, originally called "memory"
|
||||
/* 0x0004 */ s32 linkAge; // 0: Adult; 1: Child (see enum `LinkAge`)
|
||||
@ -270,25 +306,7 @@ typedef struct {
|
||||
/* 0x1420 */ s16 worldMapArea;
|
||||
/* 0x1422 */ s16 sunsSongState; // controls the effects of suns song
|
||||
/* 0x1424 */ s16 healthAccumulator;
|
||||
// #region SOH [General]
|
||||
// Upstream TODO: Move these to their own struct or name to more obviously specific to SoH
|
||||
/* */ u16 pendingSale;
|
||||
/* */ u16 pendingSaleMod;
|
||||
/* */ uint8_t questId;
|
||||
/* */ uint32_t isBossRushPaused;
|
||||
/* */ uint8_t bossRushOptions[BR_OPTIONS_MAX];
|
||||
/* */ u8 pendingIceTrapCount;
|
||||
/* */ SohStats sohStats;
|
||||
/* */ FaroresWindData backupFW;
|
||||
/* */ u8 maskMemory;
|
||||
// #endregion
|
||||
// #region SOH [Randomizer]
|
||||
// Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer
|
||||
/* */ u16 randomizerInf[(RAND_INF_MAX + 15) / 16];
|
||||
/* */ u8 mqDungeonCount;
|
||||
/* */ u16 adultTradeItems;
|
||||
/* */ u8 triforcePiecesCollected;
|
||||
// #endregion
|
||||
/* */ ShipSaveContextData ship;
|
||||
} SaveContext; // size = 0x1428
|
||||
|
||||
typedef enum {
|
||||
@ -298,10 +316,10 @@ typedef enum {
|
||||
/* 03 */ QUEST_BOSSRUSH,
|
||||
} Quest;
|
||||
|
||||
#define IS_VANILLA (gSaveContext.questId == QUEST_NORMAL)
|
||||
#define IS_MASTER_QUEST (gSaveContext.questId == QUEST_MASTER)
|
||||
#define IS_RANDO (gSaveContext.questId == QUEST_RANDOMIZER)
|
||||
#define IS_BOSS_RUSH (gSaveContext.questId == QUEST_BOSSRUSH)
|
||||
#define IS_VANILLA (gSaveContext.ship.quest.id == QUEST_NORMAL)
|
||||
#define IS_MASTER_QUEST (gSaveContext.ship.quest.id == QUEST_MASTER)
|
||||
#define IS_RANDO (gSaveContext.ship.quest.id == QUEST_RANDOMIZER)
|
||||
#define IS_BOSS_RUSH (gSaveContext.ship.quest.id == QUEST_BOSSRUSH)
|
||||
|
||||
typedef enum {
|
||||
/* 0x00 */ BTN_ENABLED,
|
||||
|
@ -265,10 +265,10 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) {
|
||||
gSaveContext.linkAge = LINK_AGE_ADULT;
|
||||
|
||||
// Change to Adult Link.
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ALL) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ALL) {
|
||||
BossRush_SetEquipment(LINK_AGE_ADULT);
|
||||
// Warp to credits.
|
||||
} else if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) {
|
||||
} else if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) {
|
||||
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
|
||||
gSaveContext.nextCutsceneIndex = 0xFFF2;
|
||||
play->transitionTrigger = TRANS_TRIGGER_START;
|
||||
@ -285,14 +285,14 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) {
|
||||
void BossRush_HandleBlueWarpHeal(PlayState* play) {
|
||||
|
||||
// This function gets called multiple times per blue warp, so only heal when player isn't at max HP.
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_EVERYBOSS &&
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_EVERYBOSS &&
|
||||
gSaveContext.health != gSaveContext.healthCapacity) {
|
||||
Health_ChangeBy(play, 320);
|
||||
}
|
||||
}
|
||||
|
||||
void BossRush_HandleCompleteBoss(PlayState* play) {
|
||||
gSaveContext.isBossRushPaused = 1;
|
||||
gSaveContext.ship.quest.data.bossRush.isPaused = true;
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
|
||||
@ -323,16 +323,16 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
|
||||
}
|
||||
|
||||
// Fully heal the player after Ganondorf
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_EVERYBOSS &&
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_EVERYBOSS &&
|
||||
play->sceneNum == SCENE_GANONDORF_BOSS) {
|
||||
Health_ChangeBy(play, 320);
|
||||
}
|
||||
|
||||
if ((CheckDungeonCount() == 3 && gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) ||
|
||||
if ((CheckDungeonCount() == 3 && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) ||
|
||||
play->sceneNum == SCENE_GANON_BOSS) {
|
||||
gSaveContext.sohStats.playTimer += 2;
|
||||
gSaveContext.sohStats.gameComplete = 1;
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_BOSSRUSH_FINISH] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.playTimer += 2;
|
||||
gSaveContext.ship.stats.gameComplete = 1;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_BOSSRUSH_FINISH] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,14 +344,14 @@ void BossRush_InitSave() {
|
||||
gSaveContext.playerName[i] = brPlayerName[i];
|
||||
}
|
||||
|
||||
gSaveContext.questId = QUEST_BOSSRUSH;
|
||||
gSaveContext.isBossRushPaused = 1;
|
||||
gSaveContext.ship.quest.id = QUEST_BOSSRUSH;
|
||||
gSaveContext.ship.quest.data.bossRush.isPaused = true;
|
||||
gSaveContext.entranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
|
||||
gSaveContext.cutsceneIndex = 0x8000;
|
||||
gSaveContext.isMagicAcquired = 1;
|
||||
|
||||
// Set magic
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_MAGIC] == BR_CHOICE_MAGIC_SINGLE) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_MAGIC] == BR_CHOICE_MAGIC_SINGLE) {
|
||||
gSaveContext.magicLevel = 1;
|
||||
gSaveContext.magic = 48;
|
||||
} else {
|
||||
@ -362,7 +362,7 @@ void BossRush_InitSave() {
|
||||
|
||||
// Set health
|
||||
u16 health = 16;
|
||||
switch (gSaveContext.bossRushOptions[BR_OPTIONS_HEARTS]) {
|
||||
switch (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HEARTS]) {
|
||||
case BR_CHOICE_HEARTS_7:
|
||||
health *= 7;
|
||||
break;
|
||||
@ -399,8 +399,9 @@ void BossRush_InitSave() {
|
||||
gSaveContext.eventChkInf[7] |= 0x80; // bongo bongo
|
||||
|
||||
// Sets all rando flags to false
|
||||
for (s32 i = 0; i < ARRAY_COUNT(gSaveContext.randomizerInf); i++) {
|
||||
gSaveContext.randomizerInf[i] = 0;
|
||||
// Boss Rush currently uses 2 randomizer flags (RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE & RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)
|
||||
for (s32 i = 0; i < ARRAY_COUNT(gSaveContext.ship.randomizerInf); i++) {
|
||||
gSaveContext.ship.randomizerInf[i] = 0;
|
||||
}
|
||||
|
||||
// Set items
|
||||
@ -411,11 +412,11 @@ void BossRush_InitSave() {
|
||||
ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE,
|
||||
};
|
||||
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_LONGSHOT] == BR_CHOICE_LONGSHOT_YES) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_LONGSHOT] == BR_CHOICE_LONGSHOT_YES) {
|
||||
brItems[9] = ITEM_LONGSHOT;
|
||||
}
|
||||
|
||||
switch (gSaveContext.bossRushOptions[BR_OPTIONS_BOTTLE]) {
|
||||
switch (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOTTLE]) {
|
||||
case BR_CHOICE_BOTTLE_EMPTY:
|
||||
brItems[18] = ITEM_BOTTLE;
|
||||
break;
|
||||
@ -435,7 +436,7 @@ void BossRush_InitSave() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BUNNYHOOD] == BR_CHOICE_BUNNYHOOD_YES) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BUNNYHOOD] == BR_CHOICE_BUNNYHOOD_YES) {
|
||||
brItems[23] = ITEM_MASK_BUNNY;
|
||||
}
|
||||
|
||||
@ -446,9 +447,9 @@ void BossRush_InitSave() {
|
||||
// Set consumable counts
|
||||
std::array<s8, 16> brAmmo = { 5, 5, 10, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_FULL) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_FULL) {
|
||||
brAmmo = { 10, 20, 20, 30, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
} else if (gSaveContext.bossRushOptions[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_MAXED) {
|
||||
} else if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_MAXED) {
|
||||
brAmmo = { 30, 40, 40, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
@ -462,17 +463,17 @@ void BossRush_InitSave() {
|
||||
gSaveContext.inventory.equipment |= 1 << 4; // Deku Shield
|
||||
gSaveContext.inventory.equipment |= 1 << 6; // Mirror Shield
|
||||
gSaveContext.inventory.equipment |= 1 << 9; // Goron Tunic
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BGS] == BR_CHOICE_BGS_YES) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BGS] == BR_CHOICE_BGS_YES) {
|
||||
gSaveContext.inventory.equipment |= 1 << 2; // Biggoron Sword
|
||||
gSaveContext.bgsFlag = 1;
|
||||
}
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_HOVERBOOTS] == BR_CHOICE_HOVERBOOTS_YES) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HOVERBOOTS] == BR_CHOICE_HOVERBOOTS_YES) {
|
||||
gSaveContext.inventory.equipment |= 1 << 14; // Hover Boots
|
||||
}
|
||||
|
||||
// Upgrades
|
||||
u8 upgradeLevel = 1;
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_MAXED) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_MAXED) {
|
||||
upgradeLevel = 3;
|
||||
}
|
||||
Inventory_ChangeUpgrade(UPG_QUIVER, upgradeLevel);
|
||||
@ -483,12 +484,12 @@ void BossRush_InitSave() {
|
||||
Inventory_ChangeUpgrade(UPG_STRENGTH, 1);
|
||||
|
||||
// Set flags and Link's age based on chosen settings.
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ADULT ||
|
||||
gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ADULT ||
|
||||
gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
|
||||
@ -516,7 +517,7 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
switch (id) {
|
||||
// Allow not healing before ganon
|
||||
case VB_GANON_HEAL_BEFORE_FIGHT: {
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_NEVER) {
|
||||
if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_NEVER) {
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
@ -669,7 +670,7 @@ void BossRush_OnActorInitHandler(void* actorRef) {
|
||||
void BossRush_OnSceneInitHandler(s16 sceneNum) {
|
||||
// Unpause the timer when the scene loaded isn't the Chamber of Sages.
|
||||
if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) {
|
||||
gSaveContext.isBossRushPaused = 0;
|
||||
gSaveContext.ship.quest.data.bossRush.isPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,7 +470,7 @@ static bool FWHandler(std::shared_ptr<Ship::Console> Console, const std::vector<
|
||||
break;
|
||||
case 2: //backup
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterFarore"), 0)) {
|
||||
gSaveContext.fw = gSaveContext.backupFW;
|
||||
gSaveContext.fw = gSaveContext.ship.backupFW;
|
||||
gSaveContext.fw.set = 1;
|
||||
INFO_MESSAGE("[SOH] Backup FW data copied! Reload scene to take effect.");
|
||||
return 0;
|
||||
|
@ -314,7 +314,7 @@ void DrawInfoTab() {
|
||||
UIWidgets::InsertHelpHoverText("Z-Targeting behavior");
|
||||
|
||||
if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) {
|
||||
ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, &gSaveContext.triforcePiecesCollected);
|
||||
ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, &gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
UIWidgets::InsertHelpHoverText("Currently obtained Triforce Pieces. For Triforce Hunt.");
|
||||
}
|
||||
|
||||
@ -416,17 +416,17 @@ void DrawBGSItemFlag(uint8_t itemID) {
|
||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
|
||||
ImGui::SameLine();
|
||||
int tradeIndex = itemID - ITEM_POCKET_EGG;
|
||||
bool hasItem = (gSaveContext.adultTradeItems & (1 << tradeIndex)) != 0;
|
||||
bool hasItem = (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) != 0;
|
||||
bool shouldHaveItem = hasItem;
|
||||
ImGui::Checkbox(("##adultTradeFlag" + std::to_string(itemID)).c_str(), &shouldHaveItem);
|
||||
if (hasItem != shouldHaveItem) {
|
||||
if (shouldHaveItem) {
|
||||
gSaveContext.adultTradeItems |= (1 << tradeIndex);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= (1 << tradeIndex);
|
||||
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_NONE) {
|
||||
INV_CONTENT(ITEM_TRADE_ADULT) = ITEM_POCKET_EGG + tradeIndex;
|
||||
}
|
||||
} else {
|
||||
gSaveContext.adultTradeItems &= ~(1 << tradeIndex);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~(1 << tradeIndex);
|
||||
Inventory_ReplaceItem(gPlayState, itemID, Randomizer_GetNextAdultTradeItem());
|
||||
}
|
||||
}
|
||||
@ -477,7 +477,7 @@ void DrawInventoryTab() {
|
||||
if (ImGui::Button("##itemNonePicker", ImVec2(32.0f, 32.0f))) {
|
||||
gSaveContext.inventory.items[selectedIndex] = ITEM_NONE;
|
||||
if (selectedIndex == SLOT_TRADE_ADULT) {
|
||||
gSaveContext.adultTradeItems = 0;
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems = 0;
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
@ -517,7 +517,7 @@ void DrawInventoryTab() {
|
||||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) &&
|
||||
selectedIndex == SLOT_TRADE_ADULT &&
|
||||
slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) {
|
||||
gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(slotEntry.id);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(slotEntry.id);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
@ -923,7 +923,7 @@ void DrawFlagsTab() {
|
||||
DrawFlagTableArray16(flagTable, j, gSaveContext.eventInf[j]);
|
||||
break;
|
||||
case RANDOMIZER_INF:
|
||||
DrawFlagTableArray16(flagTable, j, gSaveContext.randomizerInf[j]);
|
||||
DrawFlagTableArray16(flagTable, j, gSaveContext.ship.randomizerInf[j]);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -1305,7 +1305,7 @@ void DrawQuestStatusTab() {
|
||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), ImVec2(lineHeight, lineHeight));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, gSaveContext.inventory.dungeonKeys + dungeonItemsScene)) {
|
||||
gSaveContext.sohStats.dungeonKeys[dungeonItemsScene] = gSaveContext.inventory.dungeonKeys[dungeonItemsScene];
|
||||
gSaveContext.ship.stats.dungeonKeys[dungeonItemsScene] = gSaveContext.inventory.dungeonKeys[dungeonItemsScene];
|
||||
};
|
||||
} else {
|
||||
// dungeonItems is size 20 but dungeonKeys is size 19, so there are no keys for the last scene (Barinade's Lair)
|
||||
|
@ -305,7 +305,7 @@ EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) {
|
||||
GetSelectedEnemies();
|
||||
}
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
|
||||
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed() : gSaveContext.sohStats.fileCreatedAt);
|
||||
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
|
||||
Random_Init(finalSeed);
|
||||
uint32_t randomNumber = Random(0, RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE);
|
||||
return selectedEnemyList[randomNumber];
|
||||
|
@ -238,7 +238,12 @@ void GameInteractor::RawAction::SetFlag(int16_t flagType, int16_t flag) {
|
||||
gSaveContext.eventInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
break;
|
||||
case FlagType::FLAG_RANDOMIZER_INF:
|
||||
gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
if (!IS_RANDO) {
|
||||
LUSLOG_ERROR("Tried to set randomizerInf flag outside of rando (%d)", flag);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
gSaveContext.ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
break;
|
||||
case FlagType::FLAG_GS_TOKEN:
|
||||
SET_GS_FLAGS((flag & 0x1F00) >> 8, flag & 0xFF);
|
||||
@ -261,7 +266,12 @@ void GameInteractor::RawAction::UnsetFlag(int16_t flagType, int16_t flag) {
|
||||
gSaveContext.eventInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
break;
|
||||
case FlagType::FLAG_RANDOMIZER_INF:
|
||||
gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
if (!IS_RANDO) {
|
||||
LUSLOG_ERROR("Tried to unset randomizerInf flag outside of rando (%d)", flag);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
gSaveContext.ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -252,7 +252,7 @@ typedef struct {
|
||||
|
||||
// Timestamps are an array of structs, each with a name, time, and color
|
||||
// Names and colors are set up at the bottom of this file
|
||||
// Times are stored in gSaveContext.sohStats.itemTimestamp
|
||||
// Times are stored in gSaveContext.ship.stats.itemTimestamp
|
||||
TimestampInfo itemTimestampDisplay[TIMESTAMP_MAX];
|
||||
TimestampInfo sceneTimestampDisplay[8191];
|
||||
//std::vector<TimestampInfo> sceneTimestampDisplay;
|
||||
@ -287,25 +287,25 @@ extern "C" char* GameplayStats_GetCurrentTime() {
|
||||
}
|
||||
|
||||
void LoadStatsVersion1() {
|
||||
SaveManager::Instance->LoadCharArray("buildVersion", gSaveContext.sohStats.buildVersion,
|
||||
ARRAY_COUNT(gSaveContext.sohStats.buildVersion));
|
||||
SaveManager::Instance->LoadData("buildVersionMajor", gSaveContext.sohStats.buildVersionMajor);
|
||||
SaveManager::Instance->LoadData("buildVersionMinor", gSaveContext.sohStats.buildVersionMinor);
|
||||
SaveManager::Instance->LoadData("buildVersionPatch", gSaveContext.sohStats.buildVersionPatch);
|
||||
SaveManager::Instance->LoadCharArray("buildVersion", gSaveContext.ship.stats.buildVersion,
|
||||
ARRAY_COUNT(gSaveContext.ship.stats.buildVersion));
|
||||
SaveManager::Instance->LoadData("buildVersionMajor", gSaveContext.ship.stats.buildVersionMajor);
|
||||
SaveManager::Instance->LoadData("buildVersionMinor", gSaveContext.ship.stats.buildVersionMinor);
|
||||
SaveManager::Instance->LoadData("buildVersionPatch", gSaveContext.ship.stats.buildVersionPatch);
|
||||
|
||||
SaveManager::Instance->LoadData("heartPieces", gSaveContext.sohStats.heartPieces);
|
||||
SaveManager::Instance->LoadData("heartContainers", gSaveContext.sohStats.heartContainers);
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.dungeonKeys[i]);
|
||||
SaveManager::Instance->LoadData("heartPieces", gSaveContext.ship.stats.heartPieces);
|
||||
SaveManager::Instance->LoadData("heartContainers", gSaveContext.ship.stats.heartContainers);
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.ship.stats.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.sohStats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.sohStats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.sohStats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.sohStats.pauseTimer);
|
||||
SaveManager::Instance->LoadArray("itemTimestamps", ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.itemTimestamp[i]);
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.ship.stats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer);
|
||||
SaveManager::Instance->LoadArray("itemTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.itemTimestamp[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneTimestamps", ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps), [&](size_t i) {
|
||||
SaveManager::Instance->LoadArray("sceneTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.sceneTimestamps), [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
int scene, room, sceneTime, roomTime, isRoom;
|
||||
SaveManager::Instance->LoadData("scene", scene);
|
||||
@ -316,63 +316,63 @@ void LoadStatsVersion1() {
|
||||
if (scene == 0 && room == 0 && sceneTime == 0 && roomTime == 0 && isRoom == 0) {
|
||||
return;
|
||||
}
|
||||
gSaveContext.sohStats.sceneTimestamps[i].scene = scene;
|
||||
gSaveContext.sohStats.sceneTimestamps[i].room = room;
|
||||
gSaveContext.sohStats.sceneTimestamps[i].sceneTime = sceneTime;
|
||||
gSaveContext.sohStats.sceneTimestamps[i].roomTime = roomTime;
|
||||
gSaveContext.sohStats.sceneTimestamps[i].isRoom = isRoom;
|
||||
gSaveContext.ship.stats.sceneTimestamps[i].scene = scene;
|
||||
gSaveContext.ship.stats.sceneTimestamps[i].room = room;
|
||||
gSaveContext.ship.stats.sceneTimestamps[i].sceneTime = sceneTime;
|
||||
gSaveContext.ship.stats.sceneTimestamps[i].roomTime = roomTime;
|
||||
gSaveContext.ship.stats.sceneTimestamps[i].isRoom = isRoom;
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadData("tsIdx", gSaveContext.sohStats.tsIdx);
|
||||
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.sohStats.count), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.count[i]);
|
||||
SaveManager::Instance->LoadData("tsIdx", gSaveContext.ship.stats.tsIdx);
|
||||
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.ship.stats.count), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.count[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.scenesDiscovered[i]);
|
||||
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.scenesDiscovered[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.entrancesDiscovered[i]);
|
||||
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]);
|
||||
});
|
||||
}
|
||||
|
||||
void SaveStats(SaveContext* saveContext, int sectionID, bool fullSave) {
|
||||
SaveManager::Instance->SaveData("buildVersion", saveContext->sohStats.buildVersion);
|
||||
SaveManager::Instance->SaveData("buildVersionMajor", saveContext->sohStats.buildVersionMajor);
|
||||
SaveManager::Instance->SaveData("buildVersionMinor", saveContext->sohStats.buildVersionMinor);
|
||||
SaveManager::Instance->SaveData("buildVersionPatch", saveContext->sohStats.buildVersionPatch);
|
||||
SaveManager::Instance->SaveData("buildVersion", saveContext->ship.stats.buildVersion);
|
||||
SaveManager::Instance->SaveData("buildVersionMajor", saveContext->ship.stats.buildVersionMajor);
|
||||
SaveManager::Instance->SaveData("buildVersionMinor", saveContext->ship.stats.buildVersionMinor);
|
||||
SaveManager::Instance->SaveData("buildVersionPatch", saveContext->ship.stats.buildVersionPatch);
|
||||
|
||||
SaveManager::Instance->SaveData("heartPieces", saveContext->sohStats.heartPieces);
|
||||
SaveManager::Instance->SaveData("heartContainers", saveContext->sohStats.heartContainers);
|
||||
SaveManager::Instance->SaveArray("dungeonKeys", ARRAY_COUNT(saveContext->sohStats.dungeonKeys), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->sohStats.dungeonKeys[i]);
|
||||
SaveManager::Instance->SaveData("heartPieces", saveContext->ship.stats.heartPieces);
|
||||
SaveManager::Instance->SaveData("heartContainers", saveContext->ship.stats.heartContainers);
|
||||
SaveManager::Instance->SaveArray("dungeonKeys", ARRAY_COUNT(saveContext->ship.stats.dungeonKeys), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveData("rtaTiming", saveContext->sohStats.rtaTiming);
|
||||
SaveManager::Instance->SaveData("fileCreatedAt", saveContext->sohStats.fileCreatedAt);
|
||||
SaveManager::Instance->SaveData("playTimer", saveContext->sohStats.playTimer);
|
||||
SaveManager::Instance->SaveData("pauseTimer", saveContext->sohStats.pauseTimer);
|
||||
SaveManager::Instance->SaveArray("itemTimestamps", ARRAY_COUNT(saveContext->sohStats.itemTimestamp), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->sohStats.itemTimestamp[i]);
|
||||
SaveManager::Instance->SaveData("rtaTiming", saveContext->ship.stats.rtaTiming);
|
||||
SaveManager::Instance->SaveData("fileCreatedAt", saveContext->ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->SaveData("playTimer", saveContext->ship.stats.playTimer);
|
||||
SaveManager::Instance->SaveData("pauseTimer", saveContext->ship.stats.pauseTimer);
|
||||
SaveManager::Instance->SaveArray("itemTimestamps", ARRAY_COUNT(saveContext->ship.stats.itemTimestamp), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.stats.itemTimestamp[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveArray("sceneTimestamps", ARRAY_COUNT(saveContext->sohStats.sceneTimestamps), [&](size_t i) {
|
||||
if (saveContext->sohStats.sceneTimestamps[i].scene != 254 && saveContext->sohStats.sceneTimestamps[i].room != 254) {
|
||||
SaveManager::Instance->SaveArray("sceneTimestamps", ARRAY_COUNT(saveContext->ship.stats.sceneTimestamps), [&](size_t i) {
|
||||
if (saveContext->ship.stats.sceneTimestamps[i].scene != 254 && saveContext->ship.stats.sceneTimestamps[i].room != 254) {
|
||||
SaveManager::Instance->SaveStruct("", [&]() {
|
||||
SaveManager::Instance->SaveData("scene", saveContext->sohStats.sceneTimestamps[i].scene);
|
||||
SaveManager::Instance->SaveData("room", saveContext->sohStats.sceneTimestamps[i].room);
|
||||
SaveManager::Instance->SaveData("sceneTime", saveContext->sohStats.sceneTimestamps[i].sceneTime);
|
||||
SaveManager::Instance->SaveData("roomTime", saveContext->sohStats.sceneTimestamps[i].roomTime);
|
||||
SaveManager::Instance->SaveData("isRoom", saveContext->sohStats.sceneTimestamps[i].isRoom);
|
||||
SaveManager::Instance->SaveData("scene", saveContext->ship.stats.sceneTimestamps[i].scene);
|
||||
SaveManager::Instance->SaveData("room", saveContext->ship.stats.sceneTimestamps[i].room);
|
||||
SaveManager::Instance->SaveData("sceneTime", saveContext->ship.stats.sceneTimestamps[i].sceneTime);
|
||||
SaveManager::Instance->SaveData("roomTime", saveContext->ship.stats.sceneTimestamps[i].roomTime);
|
||||
SaveManager::Instance->SaveData("isRoom", saveContext->ship.stats.sceneTimestamps[i].isRoom);
|
||||
});
|
||||
}
|
||||
});
|
||||
SaveManager::Instance->SaveData("tsIdx", saveContext->sohStats.tsIdx);
|
||||
SaveManager::Instance->SaveArray("counts", ARRAY_COUNT(saveContext->sohStats.count), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->sohStats.count[i]);
|
||||
SaveManager::Instance->SaveData("tsIdx", saveContext->ship.stats.tsIdx);
|
||||
SaveManager::Instance->SaveArray("counts", ARRAY_COUNT(saveContext->ship.stats.count), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.stats.count[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveArray("scenesDiscovered", ARRAY_COUNT(saveContext->sohStats.scenesDiscovered), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->sohStats.scenesDiscovered[i]);
|
||||
SaveManager::Instance->SaveArray("scenesDiscovered", ARRAY_COUNT(saveContext->ship.stats.scenesDiscovered), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.stats.scenesDiscovered[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveArray("entrancesDiscovered", ARRAY_COUNT(saveContext->sohStats.entrancesDiscovered), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->sohStats.entrancesDiscovered[i]);
|
||||
SaveManager::Instance->SaveArray("entrancesDiscovered", ARRAY_COUNT(saveContext->ship.stats.entrancesDiscovered), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.stats.entrancesDiscovered[i]);
|
||||
});
|
||||
}
|
||||
|
||||
@ -443,16 +443,16 @@ void DrawGameplayStatsHeader() {
|
||||
} else {
|
||||
GameplayStatsRow("Build Version:", (char*)gBuildVersion);
|
||||
}
|
||||
if (gSaveContext.sohStats.rtaTiming) {
|
||||
GameplayStatsRow("Total Time (RTA):", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE);
|
||||
if (gSaveContext.ship.stats.rtaTiming) {
|
||||
GameplayStatsRow("Total Time (RTA):", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.ship.stats.gameComplete ? COLOR_GREEN : COLOR_WHITE);
|
||||
} else {
|
||||
GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE);
|
||||
GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.ship.stats.gameComplete ? COLOR_GREEN : COLOR_WHITE);
|
||||
}
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowAdditionalTimers"), 0)) { // !Only display total game time
|
||||
GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.sohStats.playTimer / 2), COLOR_GREY);
|
||||
GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.sohStats.pauseTimer / 3), COLOR_GREY);
|
||||
GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.sohStats.sceneTimer / 2), COLOR_LIGHT_BLUE);
|
||||
GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.sohStats.roomTimer / 2), COLOR_LIGHT_BLUE);
|
||||
GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.playTimer / 2), COLOR_GREY);
|
||||
GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.pauseTimer / 3), COLOR_GREY);
|
||||
GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.ship.stats.sceneTimer / 2), COLOR_LIGHT_BLUE);
|
||||
GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.ship.stats.roomTimer / 2), COLOR_LIGHT_BLUE);
|
||||
}
|
||||
if (gPlayState != NULL && CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowDebugInfo"), 0)) { // && display debug info
|
||||
GameplayStatsRow("play->sceneNum:", formatHexGameplayStat(gPlayState->sceneNum), COLOR_YELLOW);
|
||||
@ -468,7 +468,7 @@ void DrawGameplayStatsTimestampsTab() {
|
||||
// Set up the array of item timestamps and then sort it chronologically
|
||||
for (int i = 0; i < TIMESTAMP_MAX; i++) {
|
||||
strcpy(itemTimestampDisplay[i].name, itemTimestampDisplayName[i]);
|
||||
itemTimestampDisplay[i].time = gSaveContext.sohStats.itemTimestamp[i];
|
||||
itemTimestampDisplay[i].time = gSaveContext.ship.stats.itemTimestamp[i];
|
||||
itemTimestampDisplay[i].color = itemTimestampDisplayColor[i];
|
||||
}
|
||||
|
||||
@ -497,18 +497,18 @@ void DrawGameplayStatsCountsTab() {
|
||||
for (int i = COUNT_ENEMIES_DEFEATED_ANUBIS; i <= COUNT_ENEMIES_DEFEATED_WOLFOS; i++) {
|
||||
if (i == COUNT_ENEMIES_DEFEATED_FLOORMASTER) {
|
||||
// Special case: You must kill 3 mini Floormasters for it count as one defeated Floormaster
|
||||
enemiesDefeated += gSaveContext.sohStats.count[i] / 3;
|
||||
enemiesDefeated += gSaveContext.ship.stats.count[i] / 3;
|
||||
} else {
|
||||
enemiesDefeated += gSaveContext.sohStats.count[i];
|
||||
enemiesDefeated += gSaveContext.ship.stats.count[i];
|
||||
}
|
||||
}
|
||||
// Sum of all ammo used
|
||||
for (int i = COUNT_AMMO_USED_STICK; i <= COUNT_AMMO_USED_BEAN; i++) {
|
||||
ammoUsed += gSaveContext.sohStats.count[i];
|
||||
ammoUsed += gSaveContext.ship.stats.count[i];
|
||||
}
|
||||
// Sum of all button presses
|
||||
for (int i = COUNT_BUTTON_PRESSES_A; i <= COUNT_BUTTON_PRESSES_START; i++) {
|
||||
buttonPresses += gSaveContext.sohStats.count[i];
|
||||
buttonPresses += gSaveContext.ship.stats.count[i];
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f });
|
||||
@ -520,47 +520,47 @@ void DrawGameplayStatsCountsTab() {
|
||||
if (ImGui::TreeNodeEx("Enemy Details...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) {
|
||||
for (int i = COUNT_ENEMIES_DEFEATED_ANUBIS; i <= COUNT_ENEMIES_DEFEATED_WOLFOS; i++) {
|
||||
if (i == COUNT_ENEMIES_DEFEATED_FLOORMASTER) {
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i] / 3));
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.ship.stats.count[i] / 3));
|
||||
} else {
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i]));
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.ship.stats.count[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GameplayStatsRow("Rupees Collected:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_RUPEES_COLLECTED]));
|
||||
GameplayStatsRow("Rupees Collected:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_RUPEES_COLLECTED]));
|
||||
UIWidgets::Tooltip("Includes rupees collected with a full wallet.");
|
||||
GameplayStatsRow("Rupees Spent:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_RUPEES_SPENT]));
|
||||
GameplayStatsRow("Chests Opened:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_CHESTS_OPENED]));
|
||||
GameplayStatsRow("Rupees Spent:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_RUPEES_SPENT]));
|
||||
GameplayStatsRow("Chests Opened:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_CHESTS_OPENED]));
|
||||
GameplayStatsRow("Ammo Used:", formatIntGameplayStat(ammoUsed));
|
||||
if (ammoUsed > 0) {
|
||||
ImGui::TableNextRow(); ImGui::TableNextColumn();
|
||||
if (ImGui::TreeNodeEx("Ammo Details...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) {
|
||||
for (int i = COUNT_AMMO_USED_STICK; i <= COUNT_AMMO_USED_BEAN; i++) {
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i]));
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.ship.stats.count[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
GameplayStatsRow("Damage Taken:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_DAMAGE_TAKEN]));
|
||||
GameplayStatsRow("Sword Swings:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_SWORD_SWINGS]));
|
||||
GameplayStatsRow("Steps Taken:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_STEPS]));
|
||||
GameplayStatsRow("Damage Taken:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_DAMAGE_TAKEN]));
|
||||
GameplayStatsRow("Sword Swings:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_SWORD_SWINGS]));
|
||||
GameplayStatsRow("Steps Taken:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_STEPS]));
|
||||
// If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time)
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) {
|
||||
GameplayStatsRow("Bunny Hood Time:", formatTimestampGameplayStat(gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] / 2));
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD] > 0) {
|
||||
GameplayStatsRow("Bunny Hood Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD] / 2));
|
||||
}
|
||||
GameplayStatsRow("Rolls:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_ROLLS]));
|
||||
GameplayStatsRow("Bonks:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_BONKS]));
|
||||
GameplayStatsRow("Sidehops:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_SIDEHOPS]));
|
||||
GameplayStatsRow("Backflips:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_BACKFLIPS]));
|
||||
GameplayStatsRow("Ice Traps:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_ICE_TRAPS]));
|
||||
GameplayStatsRow("Pauses:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_PAUSES]));
|
||||
GameplayStatsRow("Pots Smashed:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_POTS_BROKEN]));
|
||||
GameplayStatsRow("Bushes Cut:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_BUSHES_CUT]));
|
||||
GameplayStatsRow("Rolls:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_ROLLS]));
|
||||
GameplayStatsRow("Bonks:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_BONKS]));
|
||||
GameplayStatsRow("Sidehops:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_SIDEHOPS]));
|
||||
GameplayStatsRow("Backflips:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_BACKFLIPS]));
|
||||
GameplayStatsRow("Ice Traps:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_ICE_TRAPS]));
|
||||
GameplayStatsRow("Pauses:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_PAUSES]));
|
||||
GameplayStatsRow("Pots Smashed:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_POTS_BROKEN]));
|
||||
GameplayStatsRow("Bushes Cut:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_BUSHES_CUT]));
|
||||
GameplayStatsRow("Buttons Pressed:", formatIntGameplayStat(buttonPresses));
|
||||
if (buttonPresses > 0) {
|
||||
ImGui::TableNextRow(); ImGui::TableNextColumn();
|
||||
if (ImGui::TreeNodeEx("Buttons...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) {
|
||||
for (int i = COUNT_BUTTON_PRESSES_A; i <= COUNT_BUTTON_PRESSES_START; i++) {
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.sohStats.count[i]));
|
||||
GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.ship.stats.count[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -569,25 +569,25 @@ void DrawGameplayStatsCountsTab() {
|
||||
}
|
||||
|
||||
void DrawGameplayStatsBreakdownTab() {
|
||||
for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) {
|
||||
std::string sceneName = ResolveSceneID(gSaveContext.sohStats.sceneTimestamps[i].scene, gSaveContext.sohStats.sceneTimestamps[i].room);
|
||||
for (int i = 0; i < gSaveContext.ship.stats.tsIdx; i++) {
|
||||
std::string sceneName = ResolveSceneID(gSaveContext.ship.stats.sceneTimestamps[i].scene, gSaveContext.ship.stats.sceneTimestamps[i].room);
|
||||
std::string name;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_GROTTOS) {
|
||||
name = fmt::format("{:s} Room {:d}", sceneName, gSaveContext.sohStats.sceneTimestamps[i].room);
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.ship.stats.sceneTimestamps[i].scene != SCENE_GROTTOS) {
|
||||
name = fmt::format("{:s} Room {:d}", sceneName, gSaveContext.ship.stats.sceneTimestamps[i].room);
|
||||
} else {
|
||||
name = sceneName;
|
||||
}
|
||||
strcpy(sceneTimestampDisplay[i].name, name.c_str());
|
||||
sceneTimestampDisplay[i].time = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ?
|
||||
gSaveContext.sohStats.sceneTimestamps[i].roomTime : gSaveContext.sohStats.sceneTimestamps[i].sceneTime;
|
||||
sceneTimestampDisplay[i].time = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ?
|
||||
gSaveContext.ship.stats.sceneTimestamps[i].roomTime : gSaveContext.ship.stats.sceneTimestamps[i].sceneTime;
|
||||
sceneTimestampDisplay[i].color = COLOR_GREY;
|
||||
sceneTimestampDisplay[i].isRoom = gSaveContext.sohStats.sceneTimestamps[i].isRoom;
|
||||
sceneTimestampDisplay[i].isRoom = gSaveContext.ship.stats.sceneTimestamps[i].isRoom;
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f });
|
||||
ImGui::BeginTable("gameplayStatsCounts", 1, ImGuiTableFlags_BordersOuter);
|
||||
ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch);
|
||||
for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) {
|
||||
for (int i = 0; i < gSaveContext.ship.stats.tsIdx; i++) {
|
||||
TimestampInfo tsInfo = sceneTimestampDisplay[i];
|
||||
bool canShow = !tsInfo.isRoom || CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0);
|
||||
if (tsInfo.time > 0 && strnlen(tsInfo.name, 40) > 1 && canShow) {
|
||||
@ -595,10 +595,10 @@ void DrawGameplayStatsBreakdownTab() {
|
||||
}
|
||||
}
|
||||
std::string toPass;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.sohStats.sceneNum != SCENE_GROTTOS) {
|
||||
toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum), gSaveContext.sohStats.roomNum);
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.ship.stats.sceneNum != SCENE_GROTTOS) {
|
||||
toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.ship.stats.sceneNum, gSaveContext.ship.stats.roomNum), gSaveContext.ship.stats.roomNum);
|
||||
} else {
|
||||
toPass = ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum);
|
||||
toPass = ResolveSceneID(gSaveContext.ship.stats.sceneNum, gSaveContext.ship.stats.roomNum);
|
||||
}
|
||||
GameplayStatsRow(toPass.c_str(), formatTimestampGameplayStat(CURRENT_MODE_TIMER / 2));
|
||||
ImGui::EndTable();
|
||||
@ -611,14 +611,14 @@ void DrawGameplayStatsOptionsTab() {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Show latest timestamps on top", CVAR_ENHANCEMENT("GameplayStats.ReverseTimestamps"), true, false);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), true, false);
|
||||
ImGui::SameLine();
|
||||
UIWidgets::InsertHelpHoverText("Allows a more in-depth perspective of time spent in a certain map.");
|
||||
UIWidgets::InsertHelpHoverText("Allows a more in-depth perspective of time spent in a certain map.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("RTA Timing on new files", CVAR_ENHANCEMENT("GameplayStats.RTATiming"), true, false);
|
||||
ImGui::SameLine();
|
||||
UIWidgets::InsertHelpHoverText(
|
||||
"Timestamps are relative to starting timestamp rather than in game time, usually necessary for races/speedruns.\n\n"
|
||||
"Starting timestamp is on first non-c-up input after intro cutscene.\n\n"
|
||||
"NOTE: THIS NEEDS TO BE SET BEFORE CREATING A FILE TO TAKE EFFECT"
|
||||
);
|
||||
);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Show additional detail timers", CVAR_ENHANCEMENT("GameplayStats.ShowAdditionalTimers"), true, false);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", CVAR_ENHANCEMENT("GameplayStats.ShowDebugInfo"));
|
||||
}
|
||||
@ -645,46 +645,46 @@ void GameplayStatsWindow::DrawElement() {
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
|
||||
ImGui::Text("Note: Gameplay stats are saved to the current file and will be\nlost if you quit without saving.");
|
||||
}
|
||||
void InitStats(bool isDebug) {
|
||||
gSaveContext.sohStats.heartPieces = isDebug ? 8 : 0;
|
||||
gSaveContext.sohStats.heartContainers = isDebug ? 8 : 0;
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) {
|
||||
gSaveContext.sohStats.dungeonKeys[dungeon] = isDebug ? 8 : 0;
|
||||
gSaveContext.ship.stats.heartPieces = isDebug ? 8 : 0;
|
||||
gSaveContext.ship.stats.heartContainers = isDebug ? 8 : 0;
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.ship.stats.dungeonKeys); dungeon++) {
|
||||
gSaveContext.ship.stats.dungeonKeys[dungeon] = isDebug ? 8 : 0;
|
||||
}
|
||||
gSaveContext.sohStats.rtaTiming = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RTATiming"), 0);
|
||||
gSaveContext.sohStats.fileCreatedAt = 0;
|
||||
gSaveContext.sohStats.playTimer = 0;
|
||||
gSaveContext.sohStats.pauseTimer = 0;
|
||||
for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp); timestamp++) {
|
||||
gSaveContext.sohStats.itemTimestamp[timestamp] = 0;
|
||||
gSaveContext.ship.stats.rtaTiming = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RTATiming"), 0);
|
||||
gSaveContext.ship.stats.fileCreatedAt = 0;
|
||||
gSaveContext.ship.stats.playTimer = 0;
|
||||
gSaveContext.ship.stats.pauseTimer = 0;
|
||||
for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp); timestamp++) {
|
||||
gSaveContext.ship.stats.itemTimestamp[timestamp] = 0;
|
||||
}
|
||||
for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps); timestamp++) {
|
||||
gSaveContext.sohStats.sceneTimestamps[timestamp].sceneTime = 0;
|
||||
gSaveContext.sohStats.sceneTimestamps[timestamp].roomTime = 0;
|
||||
gSaveContext.sohStats.sceneTimestamps[timestamp].scene = 254;
|
||||
gSaveContext.sohStats.sceneTimestamps[timestamp].room = 254;
|
||||
gSaveContext.sohStats.sceneTimestamps[timestamp].isRoom = 0;
|
||||
for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.ship.stats.sceneTimestamps); timestamp++) {
|
||||
gSaveContext.ship.stats.sceneTimestamps[timestamp].sceneTime = 0;
|
||||
gSaveContext.ship.stats.sceneTimestamps[timestamp].roomTime = 0;
|
||||
gSaveContext.ship.stats.sceneTimestamps[timestamp].scene = 254;
|
||||
gSaveContext.ship.stats.sceneTimestamps[timestamp].room = 254;
|
||||
gSaveContext.ship.stats.sceneTimestamps[timestamp].isRoom = 0;
|
||||
}
|
||||
gSaveContext.sohStats.tsIdx = 0;
|
||||
for (int count = 0; count < ARRAY_COUNT(gSaveContext.sohStats.count); count++) {
|
||||
gSaveContext.sohStats.count[count] = 0;
|
||||
gSaveContext.ship.stats.tsIdx = 0;
|
||||
for (int count = 0; count < ARRAY_COUNT(gSaveContext.ship.stats.count); count++) {
|
||||
gSaveContext.ship.stats.count[count] = 0;
|
||||
}
|
||||
gSaveContext.sohStats.gameComplete = false;
|
||||
for (int scenesIdx = 0; scenesIdx < ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered); scenesIdx++) {
|
||||
gSaveContext.sohStats.scenesDiscovered[scenesIdx] = 0;
|
||||
gSaveContext.ship.stats.gameComplete = false;
|
||||
for (int scenesIdx = 0; scenesIdx < ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered); scenesIdx++) {
|
||||
gSaveContext.ship.stats.scenesDiscovered[scenesIdx] = 0;
|
||||
}
|
||||
for (int entrancesIdx = 0; entrancesIdx < ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered); entrancesIdx++) {
|
||||
gSaveContext.sohStats.entrancesDiscovered[entrancesIdx] = 0;
|
||||
for (int entrancesIdx = 0; entrancesIdx < ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered); entrancesIdx++) {
|
||||
gSaveContext.ship.stats.entrancesDiscovered[entrancesIdx] = 0;
|
||||
}
|
||||
|
||||
SohUtils::CopyStringToCharArray(gSaveContext.sohStats.buildVersion, std::string((char*)gBuildVersion),
|
||||
ARRAY_COUNT(gSaveContext.sohStats.buildVersion));
|
||||
gSaveContext.sohStats.buildVersionMajor = gBuildVersionMajor;
|
||||
gSaveContext.sohStats.buildVersionMinor = gBuildVersionMinor;
|
||||
gSaveContext.sohStats.buildVersionPatch = gBuildVersionPatch;
|
||||
SohUtils::CopyStringToCharArray(gSaveContext.ship.stats.buildVersion, std::string((char*)gBuildVersion),
|
||||
ARRAY_COUNT(gSaveContext.ship.stats.buildVersion));
|
||||
gSaveContext.ship.stats.buildVersionMajor = gBuildVersionMajor;
|
||||
gSaveContext.ship.stats.buildVersionMinor = gBuildVersionMinor;
|
||||
gSaveContext.ship.stats.buildVersionPatch = gBuildVersionPatch;
|
||||
}
|
||||
|
||||
// Entries listed here will have a timestamp shown in the stat window
|
||||
|
@ -19,14 +19,14 @@ extern "C" {
|
||||
// Total gameplay time is tracked in tenths of seconds
|
||||
// I.E. game time counts frames at 20fps/2, pause time counts frames at 30fps/3
|
||||
// Frame counts in z_play.c and z_kaleido_scope_call.c
|
||||
#define GAMEPLAYSTAT_TOTAL_TIME (gSaveContext.sohStats.rtaTiming ?\
|
||||
(!gSaveContext.sohStats.gameComplete ?\
|
||||
(!gSaveContext.sohStats.fileCreatedAt ? 0 : ((GetUnixTimestamp() - gSaveContext.sohStats.fileCreatedAt) / 100)) :\
|
||||
(gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON])) :\
|
||||
(gSaveContext.sohStats.playTimer / 2 + gSaveContext.sohStats.pauseTimer / 3))
|
||||
#define GAMEPLAYSTAT_TOTAL_TIME (gSaveContext.ship.stats.rtaTiming ?\
|
||||
(!gSaveContext.ship.stats.gameComplete ?\
|
||||
(!gSaveContext.ship.stats.fileCreatedAt ? 0 : ((GetUnixTimestamp() - gSaveContext.ship.stats.fileCreatedAt) / 100)) :\
|
||||
(gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON])) :\
|
||||
(gSaveContext.ship.stats.playTimer / 2 + gSaveContext.ship.stats.pauseTimer / 3))
|
||||
#define CURRENT_MODE_TIMER (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ?\
|
||||
gSaveContext.sohStats.roomTimer :\
|
||||
gSaveContext.sohStats.sceneTimer)
|
||||
gSaveContext.ship.stats.roomTimer :\
|
||||
gSaveContext.ship.stats.sceneTimer)
|
||||
|
||||
void InitStatTracker();
|
||||
|
||||
|
@ -124,7 +124,7 @@ namespace Rando {
|
||||
mEntries.push_back(
|
||||
std::make_shared<KaleidoEntryIconCountRequired>(
|
||||
gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255,255,255,255 }, 0,
|
||||
yOffset, reinterpret_cast<int*>(&gSaveContext.triforcePiecesCollected),
|
||||
yOffset, reinterpret_cast<int*>(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected),
|
||||
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1,
|
||||
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).GetContextOptionIndex() + 1));
|
||||
yOffset += 18;
|
||||
|
@ -272,7 +272,7 @@ void AutoSave(GetItemEntry itemEntry) {
|
||||
// Don't autosave immediately after buying items from shops to prevent getting them for free!
|
||||
// Don't autosave in the Chamber of Sages since resuming from that map breaks the game
|
||||
// Don't autosave during the Ganon fight when picking up the Master Sword
|
||||
if ((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
|
||||
if ((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.ship.pendingSale == ITEM_NONE) &&
|
||||
(gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_BOSS) && (gPlayState->sceneNum != SCENE_CHAMBER_OF_THE_SAGES)) {
|
||||
if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_ALL_ITEMS)) && (item != ITEM_NONE)) {
|
||||
// Autosave for all items
|
||||
@ -409,8 +409,8 @@ void UpdatePermanentHeartLossState() {
|
||||
if (!GameInteractor::IsSaveLoaded()) return;
|
||||
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) && hasAffectedHealth) {
|
||||
uint8_t heartContainers = gSaveContext.sohStats.heartContainers; // each worth 16 health
|
||||
uint8_t heartPieces = gSaveContext.sohStats.heartPieces; // each worth 4 health, but only in groups of 4
|
||||
uint8_t heartContainers = gSaveContext.ship.stats.heartContainers; // each worth 16 health
|
||||
uint8_t heartPieces = gSaveContext.ship.stats.heartPieces; // each worth 4 health, but only in groups of 4
|
||||
uint8_t startingHealth = 16 * (IS_RANDO ? (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_HEARTS) + 1) : 3);
|
||||
|
||||
|
||||
@ -508,7 +508,7 @@ void RegisterDaytimeGoldSkultullas() {
|
||||
|
||||
bool IsHyperBossesActive() {
|
||||
return CVarGetInteger(CVAR_ENHANCEMENT("HyperBosses"), 0) ||
|
||||
(IS_BOSS_RUSH && gSaveContext.bossRushOptions[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES);
|
||||
(IS_BOSS_RUSH && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES);
|
||||
}
|
||||
|
||||
void UpdateHyperBossesState() {
|
||||
@ -667,7 +667,7 @@ void UpdateMirrorModeState(int32_t sceneNum) {
|
||||
|
||||
if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) {
|
||||
uint32_t seed = sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed()
|
||||
: gSaveContext.sohStats.fileCreatedAt);
|
||||
: gSaveContext.ship.stats.fileCreatedAt);
|
||||
Random_Init(seed);
|
||||
}
|
||||
|
||||
@ -849,60 +849,60 @@ void RegisterEnemyDefeatCounts() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnEnemyDefeat>([](void* refActor) {
|
||||
Actor* actor = static_cast<Actor*>(refActor);
|
||||
if (uniqueEnemyIdToStatCount.contains(actor->id)) {
|
||||
gSaveContext.sohStats.count[uniqueEnemyIdToStatCount[actor->id]]++;
|
||||
gSaveContext.ship.stats.count[uniqueEnemyIdToStatCount[actor->id]]++;
|
||||
} else {
|
||||
switch (actor->id) {
|
||||
case ACTOR_EN_BB:
|
||||
if (actor->params == ENBB_GREEN || actor->params == ENBB_GREEN_BIG) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_GREEN]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_GREEN]++;
|
||||
} else if (actor->params == ENBB_BLUE) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_BLUE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_BLUE]++;
|
||||
} else if (actor->params == ENBB_WHITE) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_WHITE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_WHITE]++;
|
||||
} else if (actor->params == ENBB_RED) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_RED]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_BUBBLE_RED]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_DEKUBABA:
|
||||
if (actor->params == DEKUBABA_BIG) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DEKU_BABA_BIG]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_DEKU_BABA_BIG]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DEKU_BABA]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_DEKU_BABA]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_ZF:
|
||||
if (actor->params == ENZF_TYPE_DINOLFOS) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_DINOLFOS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_DINOLFOS]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LIZALFOS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LIZALFOS]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_RD:
|
||||
if (actor->params >= -1) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_REDEAD]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_REDEAD]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_GIBDO]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_GIBDO]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_IK:
|
||||
if (actor->params == 0) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_IRON_KNUCKLE_NABOORU]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_IRON_KNUCKLE_NABOORU]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_IRON_KNUCKLE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_IRON_KNUCKLE]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_FIREFLY:
|
||||
if (actor->params == KEESE_NORMAL_FLY || actor->params == KEESE_NORMAL_PERCH) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_KEESE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_KEESE]++;
|
||||
} else if (actor->params == KEESE_FIRE_FLY || actor->params == KEESE_FIRE_PERCH) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_KEESE_FIRE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_KEESE_FIRE]++;
|
||||
} else if (actor->params == KEESE_ICE_FLY) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_KEESE_ICE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_KEESE_ICE]++;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -910,80 +910,80 @@ void RegisterEnemyDefeatCounts() {
|
||||
{
|
||||
EnReeba* reeba = (EnReeba*)actor;
|
||||
if (reeba->isBig) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LEEVER_BIG]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LEEVER_BIG]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_LEEVER]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LEEVER]++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_MB:
|
||||
if (actor->params == 0) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_MOBLIN_CLUB]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_MOBLIN_CLUB]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_MOBLIN]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_MOBLIN]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_PEEHAT:
|
||||
if (actor->params == PEAHAT_TYPE_LARVA) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_PEAHAT_LARVA]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_PEAHAT_LARVA]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_PEAHAT]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_PEAHAT]++;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ACTOR_EN_POH:
|
||||
if (actor->params == EN_POH_FLAT || actor->params == EN_POH_SHARP) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE_COMPOSER]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_POE_COMPOSER]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_POE]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_PO_FIELD:
|
||||
if (actor->params == EN_PO_FIELD_BIG) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE_BIG]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_POE_BIG]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_POE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_POE]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_ST:
|
||||
if (actor->params == 1) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA_BIG]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA_BIG]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_SW:
|
||||
if (((actor->params & 0xE000) >> 0xD) != 0) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA_GOLD]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_SKULLTULA_GOLD]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_SKULLWALLTULA]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_SKULLWALLTULA]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_TP:
|
||||
if (actor->params == TAILPASARAN_HEAD) { // Only count the head, otherwise each body segment will increment
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TAILPASARAN]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_TAILPASARAN]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_TITE:
|
||||
if (actor->params == TEKTITE_BLUE) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TEKTITE_BLUE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_TEKTITE_BLUE]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_TEKTITE_RED]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_TEKTITE_RED]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTOR_EN_WF:
|
||||
if (actor->params == WOLFOS_WHITE) {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_WOLFOS_WHITE]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_WOLFOS_WHITE]++;
|
||||
} else {
|
||||
gSaveContext.sohStats.count[COUNT_ENEMIES_DEFEATED_WOLFOS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_WOLFOS]++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -996,35 +996,35 @@ void RegisterBossDefeatTimestamps() {
|
||||
Actor* actor = static_cast<Actor*>(refActor);
|
||||
switch (actor->id) {
|
||||
case ACTOR_BOSS_DODONGO:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_FD2:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_GANON:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_GANON2:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.sohStats.gameComplete = true;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.gameComplete = true;
|
||||
break;
|
||||
case ACTOR_BOSS_GANONDROF:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_GOMA:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_MO:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_SST:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_TW:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case ACTOR_BOSS_VA:
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -1193,10 +1193,10 @@ void UpdateHurtContainerModeState(bool newState) {
|
||||
}
|
||||
|
||||
hurtEnabled = newState;
|
||||
uint16_t getHeartPieces = gSaveContext.sohStats.heartPieces / 4;
|
||||
uint16_t getHeartContainers = gSaveContext.sohStats.heartContainers;
|
||||
|
||||
if (hurtEnabled) {
|
||||
uint16_t getHeartPieces = gSaveContext.ship.stats.heartPieces / 4;
|
||||
uint16_t getHeartContainers = gSaveContext.ship.stats.heartContainers;
|
||||
|
||||
if (hurtEnabled) {
|
||||
gSaveContext.healthCapacity = 320 - ((getHeartPieces + getHeartContainers) * 16);
|
||||
} else {
|
||||
gSaveContext.healthCapacity = 48 + ((getHeartPieces + getHeartContainers) * 16);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "macros.h"
|
||||
|
||||
void Randomizer_ConsumeAdultTradeItem(PlayState* play, u8 itemId) {
|
||||
gSaveContext.adultTradeItems &= ~ADULT_TRADE_FLAG(itemId);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~ADULT_TRADE_FLAG(itemId);
|
||||
Inventory_ReplaceItem(play, itemId, Randomizer_GetNextAdultTradeItem());
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ u8 Randomizer_GetNextAdultTradeItem() {
|
||||
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
|
||||
for (int i = 0; i < numTradeItems; i++) {
|
||||
u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems;
|
||||
if (gSaveContext.adultTradeItems & (1 << tradeIndex)) {
|
||||
if (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) {
|
||||
return ITEM_POCKET_EGG + tradeIndex;
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@ u8 Randomizer_GetPrevAdultTradeItem() {
|
||||
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
|
||||
for (int i = 0; i < numTradeItems; i++) {
|
||||
u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems;
|
||||
if (gSaveContext.adultTradeItems & (1 << tradeIndex)) {
|
||||
if (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) {
|
||||
return ITEM_POCKET_EGG + tradeIndex;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <z64.h>
|
||||
|
||||
#define ADULT_TRADE_FLAG(itemId) (1 << (itemId - ITEM_POCKET_EGG))
|
||||
#define PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(itemID) (gSaveContext.adultTradeItems & ADULT_TRADE_FLAG(itemID))
|
||||
#define PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(itemID) (IS_RANDO && gSaveContext.ship.quest.data.randomizer.adultTradeItems & ADULT_TRADE_FLAG(itemID))
|
||||
|
||||
void Randomizer_ConsumeAdultTradeItem(PlayState* play, u8 itemId);
|
||||
u8 Randomizer_GetNextAdultTradeItem();
|
||||
|
@ -263,7 +263,7 @@ extern "C" void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getIt
|
||||
|
||||
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
|
||||
|
||||
uint8_t current = gSaveContext.triforcePiecesCollected;
|
||||
uint8_t current = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected;
|
||||
|
||||
Matrix_Scale(0.035f, 0.035f, 0.035f, MTXMODE_APPLY);
|
||||
|
||||
@ -287,7 +287,7 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
|
||||
|
||||
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
|
||||
|
||||
uint8_t current = gSaveContext.triforcePiecesCollected;
|
||||
uint8_t current = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected;
|
||||
uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1;
|
||||
|
||||
Matrix_Scale(triforcePieceScale, triforcePieceScale, triforcePieceScale, MTXMODE_APPLY);
|
||||
|
@ -1010,7 +1010,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
Item_Give(gPlayState, item00->itemEntry.itemId);
|
||||
} else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) {
|
||||
if (item00->itemEntry.getItemId == RG_ICE_TRAP) {
|
||||
gSaveContext.pendingIceTrapCount++;
|
||||
gSaveContext.ship.pendingIceTrapCount++;
|
||||
} else {
|
||||
Randomizer_Item_Give(gPlayState, item00->itemEntry);
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ void RegionTable_Init() {
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LINKS_POCKET, true),
|
||||
LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1;),
|
||||
LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->ship.quest.data.randomizer.triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1;),
|
||||
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
|
||||
}, {
|
||||
//Exits
|
||||
|
@ -1625,7 +1625,7 @@ namespace Rando {
|
||||
SetRandoInf(RandoGetToRandInf.at(randoGet), state);
|
||||
break;
|
||||
case RG_TRIFORCE_PIECE:
|
||||
mSaveContext->triforcePiecesCollected += (!state ? -1 : 1);
|
||||
mSaveContext->ship.quest.data.randomizer.triforcePiecesCollected += (!state ? -1 : 1);
|
||||
break;
|
||||
case RG_BOMBCHU_5:
|
||||
case RG_BOMBCHU_10:
|
||||
@ -1881,14 +1881,13 @@ namespace Rando {
|
||||
mSaveContext->sceneFlags[5].swch = 0x40000000;
|
||||
|
||||
// SoH specific
|
||||
mSaveContext->backupFW = mSaveContext->fw;
|
||||
mSaveContext->pendingSale = ITEM_NONE;
|
||||
mSaveContext->pendingSaleMod = MOD_NONE;
|
||||
mSaveContext->isBossRushPaused = 0;
|
||||
mSaveContext->pendingIceTrapCount = 0;
|
||||
mSaveContext->ship.backupFW = mSaveContext->fw;
|
||||
mSaveContext->ship.pendingSale = ITEM_NONE;
|
||||
mSaveContext->ship.pendingSaleMod = MOD_NONE;
|
||||
mSaveContext->ship.pendingIceTrapCount = 0;
|
||||
|
||||
// Init with normal quest unless only an MQ rom is provided
|
||||
mSaveContext->questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
|
||||
mSaveContext->ship.quest.id = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
|
||||
|
||||
//RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT)
|
||||
}
|
||||
@ -1937,16 +1936,16 @@ namespace Rando {
|
||||
|
||||
bool Logic::HasAdultTrade(uint32_t itemID) {
|
||||
int tradeIndex = itemID - ITEM_POCKET_EGG;
|
||||
return mSaveContext->adultTradeItems & (1 << tradeIndex);
|
||||
return mSaveContext->ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex);
|
||||
}
|
||||
|
||||
void Logic::SetAdultTrade(uint32_t itemID, bool state) {
|
||||
int tradeIndex = itemID - ITEM_POCKET_EGG;
|
||||
if (!state) {
|
||||
mSaveContext->adultTradeItems &= ~(1 << tradeIndex);
|
||||
mSaveContext->ship.quest.data.randomizer.adultTradeItems &= ~(1 << tradeIndex);
|
||||
}
|
||||
else {
|
||||
mSaveContext->adultTradeItems |= (1 << tradeIndex);
|
||||
mSaveContext->ship.quest.data.randomizer.adultTradeItems |= (1 << tradeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1981,15 +1980,15 @@ namespace Rando {
|
||||
}
|
||||
|
||||
bool Logic::CheckRandoInf(uint32_t flag) {
|
||||
return mSaveContext->randomizerInf[flag >> 4] & (1 << (flag & 0xF));
|
||||
return mSaveContext->ship.randomizerInf[flag >> 4] & (1 << (flag & 0xF));
|
||||
}
|
||||
|
||||
void Logic::SetRandoInf(uint32_t flag, bool state) {
|
||||
if (!state) {
|
||||
mSaveContext->randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
mSaveContext->ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
}
|
||||
else {
|
||||
mSaveContext->randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
mSaveContext->ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2787,7 +2787,7 @@ void CreateTriforcePieceMessages() {
|
||||
|
||||
CustomMessage Randomizer::GetTriforcePieceMessage() {
|
||||
// Item is only given after the textbox, so reflect that inside the textbox.
|
||||
uint8_t current = gSaveContext.triforcePiecesCollected + 1;
|
||||
uint8_t current = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected + 1;
|
||||
uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1;
|
||||
uint8_t remaining = required - current;
|
||||
float percentageCollected = (float)current / (float)required;
|
||||
@ -3330,7 +3330,7 @@ void CreateFireTempleGoronMessages() {
|
||||
CustomMessage Randomizer::GetGoronMessage(u16 index) {
|
||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, goronIDs[index]);
|
||||
messageEntry.Replace("[[days]]", std::to_string(gSaveContext.totalDays));
|
||||
messageEntry.Replace("[[a_btn]]", std::to_string(gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]));
|
||||
messageEntry.Replace("[[a_btn]]", std::to_string(gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_A]));
|
||||
messageEntry.Format();
|
||||
return messageEntry;
|
||||
}
|
||||
@ -3339,15 +3339,15 @@ void Randomizer::CreateCustomMessages() {
|
||||
// RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED
|
||||
// with GIMESSAGE(getItemID, itemID, english, german, french).
|
||||
const std::array<GetItemMessage, 85> getItemMessages = {{
|
||||
GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON,
|
||||
GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON,
|
||||
"You found %gGreg%w!",
|
||||
"%gGreg%w! Du hast ihn wirklich gefunden!",
|
||||
"Félicitation! Vous avez trouvé %gGreg%w!"),
|
||||
GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER,
|
||||
GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER,
|
||||
"You found the %gMaster Sword%w!",
|
||||
"Du erhältst das %gMaster-Schwert%w!",
|
||||
"Vous obtenez %gl'Épée de Légende%w!"),
|
||||
GIMESSAGE(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE,
|
||||
GIMESSAGE(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE,
|
||||
"You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!",
|
||||
"Du erhältst eine %rFlasche mit&blauem Feuer%w! Nutze es um&%rRotes Eis%w zu schmelzen!",
|
||||
"Vous obtenez une %rBouteille avec&une Flamme Bleue%w! Utilisez-la&pour faire fondre la %rGlace&Rouge%w!"),
|
||||
@ -3453,7 +3453,7 @@ void Randomizer::CreateCustomMessages() {
|
||||
"You found a %yGerudo Training &Grounds %wKeyring!",
|
||||
"Du erhältst ein %rSchlüsselbund%w&für die %yGerudo-Trainingsarena%w!",
|
||||
"Vous obtenez un trousseau de&clés du %yGymnase Gerudo%w!"),
|
||||
GIMESSAGE(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL,
|
||||
GIMESSAGE(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL,
|
||||
"You found a %rGanon's Castle &%wKeyring!",
|
||||
"Du erhältst ein %rSchlüsselbund%w&für %rGanons Schloß%w!",
|
||||
"Vous obtenez un trousseau de&clés du %rChâteau de Ganon%w!"),
|
||||
@ -3706,28 +3706,28 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
||||
|
||||
// Use ITEM_KEY_BOSS to timestamp Ganon's boss key
|
||||
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_KEY_BOSS] = time;
|
||||
gSaveContext.ship.stats.itemTimestamp[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.itemTimestamp[ITEM_BOTTLE] == 0) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] = time;
|
||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] == 0) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] = time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Count any bombchu pack as bombchus
|
||||
if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) {
|
||||
if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time;
|
||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = 0) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (item == RG_MAGIC_SINGLE) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
|
||||
}
|
||||
if (item == RG_DOUBLE_DEFENSE) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3920,7 +3920,7 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
|
||||
}
|
||||
|
||||
if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) {
|
||||
gSaveContext.sohStats.dungeonKeys[mapIndex]++;
|
||||
gSaveContext.ship.stats.dungeonKeys[mapIndex]++;
|
||||
if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) {
|
||||
gSaveContext.inventory.dungeonKeys[mapIndex] = 1;
|
||||
} else {
|
||||
@ -3930,7 +3930,7 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
|
||||
}
|
||||
|
||||
if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_GANONS_CASTLE_KEY_RING)) {
|
||||
gSaveContext.sohStats.dungeonKeys[mapIndex] = numOfKeysOnKeyring;
|
||||
gSaveContext.ship.stats.dungeonKeys[mapIndex] = numOfKeysOnKeyring;
|
||||
gSaveContext.inventory.dungeonKeys[mapIndex] = numOfKeysOnKeyring;
|
||||
return Return_Item_Entry(giEntry, RG_NONE);
|
||||
}
|
||||
@ -3989,16 +3989,16 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
|
||||
case RG_GREG_RUPEE:
|
||||
Rupees_ChangeBy(1);
|
||||
Flags_SetRandomizerInf(RAND_INF_GREG_FOUND);
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_FOUND_GREG] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_FOUND_GREG] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
break;
|
||||
case RG_TRIFORCE_PIECE:
|
||||
gSaveContext.triforcePiecesCollected++;
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected++;
|
||||
GameInteractor_SetTriforceHuntPieceGiven(true);
|
||||
|
||||
// Teleport to credits when goal is reached.
|
||||
if (gSaveContext.triforcePiecesCollected == (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) {
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.sohStats.gameComplete = 1;
|
||||
if (gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected == (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) {
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.gameComplete = 1;
|
||||
Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY);
|
||||
Play_PerformSave(play);
|
||||
GameInteractor_SetTriforceHuntCreditsWarpActive(true);
|
||||
|
@ -1360,7 +1360,7 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) {
|
||||
OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc)
|
||||
) || (loc->GetRCType() == RCTYPE_SHOP && showShops && !hideShopUnshuffledChecks);
|
||||
} else {
|
||||
return loc->IsVanillaCompletion() && (!loc->IsDungeon() || (loc->IsDungeon() && loc->GetQuest() == gSaveContext.questId));
|
||||
return loc->IsVanillaCompletion() && (!loc->IsDungeon() || (loc->IsDungeon() && loc->GetQuest() == gSaveContext.ship.quest.id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -740,7 +740,7 @@ u8 Entrance_GetIsSceneDiscovered(u8 sceneNum) {
|
||||
u32 idx = sceneNum / bitsPerIndex;
|
||||
if (idx < SAVEFILE_SCENES_DISCOVERED_IDX_COUNT) {
|
||||
u32 sceneBit = 1 << (sceneNum - (idx * bitsPerIndex));
|
||||
return (gSaveContext.sohStats.scenesDiscovered[idx] & sceneBit) != 0;
|
||||
return (gSaveContext.ship.stats.scenesDiscovered[idx] & sceneBit) != 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -754,7 +754,7 @@ void Entrance_SetSceneDiscovered(u8 sceneNum) {
|
||||
u32 idx = sceneNum / bitsPerIndex;
|
||||
if (idx < SAVEFILE_SCENES_DISCOVERED_IDX_COUNT) {
|
||||
u32 sceneBit = 1 << (sceneNum - (idx * bitsPerIndex));
|
||||
gSaveContext.sohStats.scenesDiscovered[idx] |= sceneBit;
|
||||
gSaveContext.ship.stats.scenesDiscovered[idx] |= sceneBit;
|
||||
}
|
||||
// Save scenesDiscovered
|
||||
Save_SaveSection(SECTION_ID_SCENES);
|
||||
@ -765,7 +765,7 @@ u8 Entrance_GetIsEntranceDiscovered(u16 entranceIndex) {
|
||||
u32 idx = entranceIndex / bitsPerIndex;
|
||||
if (idx < SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT) {
|
||||
u32 entranceBit = 1 << (entranceIndex - (idx * bitsPerIndex));
|
||||
return (gSaveContext.sohStats.entrancesDiscovered[idx] & entranceBit) != 0;
|
||||
return (gSaveContext.ship.stats.entrancesDiscovered[idx] & entranceBit) != 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -782,7 +782,7 @@ void Entrance_SetEntranceDiscovered(u16 entranceIndex, u8 isReversedEntrance) {
|
||||
u32 idx = entranceIndex / bitsPerIndex;
|
||||
if (idx < SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT) {
|
||||
u32 entranceBit = 1 << (entranceIndex - (idx * bitsPerIndex));
|
||||
gSaveContext.sohStats.entrancesDiscovered[idx] |= entranceBit;
|
||||
gSaveContext.ship.stats.entrancesDiscovered[idx] |= entranceBit;
|
||||
|
||||
// Set reverse entrance when not decoupled
|
||||
if (!Randomizer_GetSettingValue(RSK_DECOUPLED_ENTRANCES) && !isReversedEntrance) {
|
||||
|
@ -411,17 +411,17 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
|
||||
break;
|
||||
case ITEM_HEART_CONTAINER:
|
||||
result.maxCapacity = result.currentCapacity = 8;
|
||||
result.currentAmmo = gSaveContext.sohStats.heartContainers;
|
||||
result.currentAmmo = gSaveContext.ship.stats.heartContainers;
|
||||
break;
|
||||
case ITEM_HEART_PIECE:
|
||||
result.maxCapacity = result.currentCapacity = 36;
|
||||
result.currentAmmo = gSaveContext.sohStats.heartPieces;
|
||||
result.currentAmmo = gSaveContext.ship.stats.heartPieces;
|
||||
break;
|
||||
case ITEM_KEY_SMALL:
|
||||
// Though the ammo/capacity naming doesn't really make sense for keys, we are
|
||||
// hijacking the same system to display key counts as there are enough similarities
|
||||
result.currentAmmo = MAX(gSaveContext.inventory.dungeonKeys[item.data], 0);
|
||||
result.currentCapacity = gSaveContext.sohStats.dungeonKeys[item.data];
|
||||
result.currentCapacity = gSaveContext.ship.stats.dungeonKeys[item.data];
|
||||
switch (item.data) {
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
result.maxCapacity = FOREST_TEMPLE_SMALL_KEY_MAX;
|
||||
@ -582,11 +582,11 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) {
|
||||
std::string maxString = "";
|
||||
uint8_t piecesRequired = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1);
|
||||
uint8_t piecesTotal = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_TOTAL) + 1);
|
||||
ImU32 currentColor = gSaveContext.triforcePiecesCollected >= piecesRequired ? IM_COL_GREEN : IM_COL_WHITE;
|
||||
ImU32 currentColor = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >= piecesRequired ? IM_COL_GREEN : IM_COL_WHITE;
|
||||
ImU32 maxColor = IM_COL_GREEN;
|
||||
int32_t trackerTriforcePieceNumberDisplayMode = CVarGetInteger(CVAR_TRACKER_ITEM("TriforcePieceCounts"), TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX);
|
||||
|
||||
currentString += std::to_string(gSaveContext.triforcePiecesCollected);
|
||||
currentString += std::to_string(gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
currentString += "/";
|
||||
// gItemTrackerTriforcePieceTrack
|
||||
if (trackerTriforcePieceNumberDisplayMode == TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) {
|
||||
@ -651,11 +651,11 @@ void DrawItem(ItemTrackerItem item) {
|
||||
switch (item.id) {
|
||||
case ITEM_HEART_CONTAINER:
|
||||
actualItemId = item.id;
|
||||
hasItem = gSaveContext.sohStats.heartContainers > 0;
|
||||
hasItem = gSaveContext.ship.stats.heartContainers > 0;
|
||||
break;
|
||||
case ITEM_HEART_PIECE:
|
||||
actualItemId = item.id;
|
||||
hasItem = gSaveContext.sohStats.heartPieces > 0;
|
||||
hasItem = gSaveContext.ship.stats.heartPieces > 0;
|
||||
break;
|
||||
case ITEM_MAGIC_SMALL:
|
||||
case ITEM_MAGIC_LARGE:
|
||||
|
@ -25,7 +25,7 @@ void StartingItemGive(GetItemEntry getItemEntry, RandomizerCheck randomizerCheck
|
||||
Item_Give(NULL, getItemEntry.itemId);
|
||||
} else if (getItemEntry.modIndex == MOD_RANDOMIZER) {
|
||||
if (getItemEntry.getItemId == RG_ICE_TRAP) {
|
||||
gSaveContext.pendingIceTrapCount++;
|
||||
gSaveContext.ship.pendingIceTrapCount++;
|
||||
} else {
|
||||
Randomizer_Item_Give(NULL, getItemEntry);
|
||||
}
|
||||
@ -174,22 +174,22 @@ void SetStartingItems() {
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) {
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon
|
||||
} else if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_VANILLA) {
|
||||
// Logic cannot handle vanilla key layout in some dungeons
|
||||
// this is because vanilla expects the dungeon major item to be
|
||||
@ -198,7 +198,7 @@ void SetStartingItems() {
|
||||
if (ResourceMgr_IsSceneMasterQuest(SCENE_SPIRIT_TEMPLE)) {
|
||||
// MQ Spirit needs 3 keys
|
||||
gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] = 3;
|
||||
gSaveContext.sohStats.dungeonKeys[SCENE_SPIRIT_TEMPLE] = 3;
|
||||
gSaveContext.ship.stats.dungeonKeys[SCENE_SPIRIT_TEMPLE] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,10 +220,10 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
ctx->GetLogic()->SetSaveContext(&gSaveContext);
|
||||
|
||||
// Starts pending ice traps out at 0 before potentially incrementing them down the line.
|
||||
gSaveContext.pendingIceTrapCount = 0;
|
||||
gSaveContext.ship.pendingIceTrapCount = 0;
|
||||
|
||||
// Reset triforce pieces collected
|
||||
gSaveContext.triforcePiecesCollected = 0;
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected = 0;
|
||||
|
||||
// Set Cutscene flags and texts to skip them
|
||||
Flags_SetEventChkInf(EVENTCHKINF_FIRST_SPOKE_TO_MIDO);
|
||||
@ -262,7 +262,7 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
|
||||
// shuffle adult trade quest
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
gSaveContext.adultTradeItems = 0;
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems = 0;
|
||||
}
|
||||
|
||||
// remove One Time scrubs with scrubsanity off
|
||||
|
@ -345,8 +345,8 @@ void HandleDragAndDrop(std::vector<SplitObject>& objectList, int targetIndex, co
|
||||
}
|
||||
|
||||
void TimeSplitCompleteSplits() {
|
||||
gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.sohStats.gameComplete = true;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.gameComplete = true;
|
||||
}
|
||||
|
||||
void TimeSplitsSkipSplit(uint32_t index) {
|
||||
|
@ -2322,10 +2322,10 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId, MF_FORMATTED);
|
||||
} else if (textId == TEXT_HEART_CONTAINER && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"), 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER, MF_FORMATTED);
|
||||
messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.sohStats.heartContainers + 1));
|
||||
messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.ship.stats.heartContainers + 1));
|
||||
} else if (textId >= TEXT_HEART_PIECE && textId < TEXT_HEART_CONTAINER && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"), 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE, MF_FORMATTED);
|
||||
messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.sohStats.heartPieces + 1));
|
||||
messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.ship.stats.heartPieces + 1));
|
||||
} else if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger(CVAR_ENHANCEMENT("MarketSneak"), 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT, MF_FORMATTED);
|
||||
}
|
||||
|
@ -218,11 +218,11 @@ void SaveManager::LoadRandomizerVersion1() {
|
||||
}
|
||||
randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, {CustomMessage(ganonText)}));
|
||||
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems);
|
||||
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
|
||||
|
||||
|
||||
size_t merchantPricesSize = 0;
|
||||
@ -348,11 +348,11 @@ void SaveManager::LoadRandomizerVersion2() {
|
||||
SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText);
|
||||
randoContext->AddHint(RH_PRELUDE_WARP_LOC, Rando::Hint(RH_PRELUDE_WARP_LOC, {CustomMessage(warpPreludeText)}));
|
||||
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems);
|
||||
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
|
||||
|
||||
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
|
||||
|
||||
@ -445,11 +445,11 @@ void SaveManager::LoadRandomizerVersion3() {
|
||||
randoContext->AddHint(hint, Rando::Hint(hint, json));
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems);
|
||||
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
|
||||
|
||||
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
|
||||
|
||||
@ -473,7 +473,7 @@ void SaveManager::LoadRandomizerVersion3() {
|
||||
|
||||
void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool fullSave) {
|
||||
|
||||
if(saveContext->questId != QUEST_RANDOMIZER) return;
|
||||
if(saveContext->ship.quest.id != QUEST_RANDOMIZER) return;
|
||||
auto randoContext = Rando::Context::GetInstance();
|
||||
|
||||
SaveManager::Instance->SaveArray("itemLocations", RC_MAX, [&](size_t i) {
|
||||
@ -582,11 +582,11 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
|
||||
});
|
||||
});
|
||||
|
||||
SaveManager::Instance->SaveData("adultTradeItems", saveContext->adultTradeItems);
|
||||
SaveManager::Instance->SaveData("adultTradeItems", saveContext->ship.quest.data.randomizer.adultTradeItems);
|
||||
|
||||
SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext->triforcePiecesCollected);
|
||||
SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext->ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
|
||||
SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->pendingIceTrapCount);
|
||||
SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->ship.pendingIceTrapCount);
|
||||
|
||||
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
|
||||
|
||||
@ -701,10 +701,10 @@ void SaveManager::InitMeta(int fileNum) {
|
||||
// we don't actually require a vanilla OTR.
|
||||
fileMetaInfo[fileNum].requiresOriginal = !IS_MASTER_QUEST && (!IS_RANDO || randoContext->GetDungeons()->CountMQ() < 12);
|
||||
|
||||
fileMetaInfo[fileNum].buildVersionMajor = gSaveContext.sohStats.buildVersionMajor;
|
||||
fileMetaInfo[fileNum].buildVersionMinor = gSaveContext.sohStats.buildVersionMinor;
|
||||
fileMetaInfo[fileNum].buildVersionPatch = gSaveContext.sohStats.buildVersionPatch;
|
||||
SohUtils::CopyStringToCharArray(fileMetaInfo[fileNum].buildVersion, gSaveContext.sohStats.buildVersion,
|
||||
fileMetaInfo[fileNum].buildVersionMajor = gSaveContext.ship.stats.buildVersionMajor;
|
||||
fileMetaInfo[fileNum].buildVersionMinor = gSaveContext.ship.stats.buildVersionMinor;
|
||||
fileMetaInfo[fileNum].buildVersionPatch = gSaveContext.ship.stats.buildVersionPatch;
|
||||
SohUtils::CopyStringToCharArray(fileMetaInfo[fileNum].buildVersion, gSaveContext.ship.stats.buildVersion,
|
||||
ARRAY_COUNT(fileMetaInfo[fileNum].buildVersion));
|
||||
}
|
||||
|
||||
@ -821,8 +821,9 @@ void SaveManager::InitFileNormal() {
|
||||
for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.infTable); flag++) {
|
||||
gSaveContext.infTable[flag] = 0;
|
||||
}
|
||||
for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.randomizerInf); flag++) {
|
||||
gSaveContext.randomizerInf[flag] = 0;
|
||||
// Currently randomizer flags are accessible from all quests
|
||||
for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.ship.randomizerInf); flag++) {
|
||||
gSaveContext.ship.randomizerInf[flag] = 0;
|
||||
}
|
||||
gSaveContext.worldMapAreaData = 0;
|
||||
gSaveContext.scarecrowLongSongSet = 0;
|
||||
@ -856,15 +857,14 @@ void SaveManager::InitFileNormal() {
|
||||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
||||
|
||||
// SoH specific
|
||||
gSaveContext.backupFW = gSaveContext.fw;
|
||||
gSaveContext.pendingSale = ITEM_NONE;
|
||||
gSaveContext.pendingSaleMod = MOD_NONE;
|
||||
gSaveContext.isBossRushPaused = 0;
|
||||
gSaveContext.pendingIceTrapCount = 0;
|
||||
gSaveContext.maskMemory = PLAYER_MASK_NONE;
|
||||
gSaveContext.ship.backupFW = gSaveContext.fw;
|
||||
gSaveContext.ship.pendingSale = ITEM_NONE;
|
||||
gSaveContext.ship.pendingSaleMod = MOD_NONE;
|
||||
gSaveContext.ship.pendingIceTrapCount = 0;
|
||||
gSaveContext.ship.maskMemory = PLAYER_MASK_NONE;
|
||||
|
||||
// Init with normal quest unless only an MQ rom is provided
|
||||
gSaveContext.questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
|
||||
gSaveContext.ship.quest.id = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
|
||||
|
||||
//RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT)
|
||||
}
|
||||
@ -1436,7 +1436,7 @@ void SaveManager::LoadBaseVersion1() {
|
||||
int isRando = 0;
|
||||
SaveManager::Instance->LoadData("n64ddFlag", isRando);
|
||||
if (isRando) {
|
||||
gSaveContext.questId = QUEST_RANDOMIZER;
|
||||
gSaveContext.ship.quest.id = QUEST_RANDOMIZER;
|
||||
}
|
||||
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
|
||||
SaveManager::Instance->LoadData("health", gSaveContext.health);
|
||||
@ -1561,8 +1561,8 @@ void SaveManager::LoadBaseVersion1() {
|
||||
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.ship.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.randomizerInf[i]);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1581,7 +1581,7 @@ void SaveManager::LoadBaseVersion2() {
|
||||
int isRando = 0;
|
||||
SaveManager::Instance->LoadData("n64ddFlag", isRando);
|
||||
if (isRando) {
|
||||
gSaveContext.questId = QUEST_RANDOMIZER;
|
||||
gSaveContext.ship.quest.id = QUEST_RANDOMIZER;
|
||||
}
|
||||
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
|
||||
SaveManager::Instance->LoadData("health", gSaveContext.health);
|
||||
@ -1648,26 +1648,26 @@ void SaveManager::LoadBaseVersion2() {
|
||||
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("sohStats", []() {
|
||||
SaveManager::Instance->LoadData("heartPieces", gSaveContext.sohStats.heartPieces);
|
||||
SaveManager::Instance->LoadData("heartContainers", gSaveContext.sohStats.heartContainers);
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.dungeonKeys[i]);
|
||||
SaveManager::Instance->LoadData("heartPieces", gSaveContext.ship.stats.heartPieces);
|
||||
SaveManager::Instance->LoadData("heartContainers", gSaveContext.ship.stats.heartContainers);
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.ship.stats.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.sohStats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.sohStats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.sohStats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.sohStats.pauseTimer);
|
||||
SaveManager::Instance->LoadArray("timestamps", ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.itemTimestamp[i]);
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.ship.stats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer);
|
||||
SaveManager::Instance->LoadArray("timestamps", ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.itemTimestamp[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.sohStats.count), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.count[i]);
|
||||
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.ship.stats.count), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.count[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.scenesDiscovered[i]);
|
||||
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.scenesDiscovered[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.entrancesDiscovered[i]);
|
||||
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
@ -1745,13 +1745,13 @@ void SaveManager::LoadBaseVersion2() {
|
||||
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.ship.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.randomizerInf[i]);
|
||||
});
|
||||
int isMQ = 0;
|
||||
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
|
||||
if (isMQ) {
|
||||
gSaveContext.questId = QUEST_MASTER;
|
||||
gSaveContext.ship.quest.id = QUEST_MASTER;
|
||||
}
|
||||
|
||||
// Workaround for breaking save compatibility from 5.0.2 -> 5.1.0 in commit d7c35221421bf712b5ead56a360f81f624aca4bc
|
||||
@ -1797,7 +1797,7 @@ void SaveManager::LoadBaseVersion3() {
|
||||
int isRando = 0;
|
||||
SaveManager::Instance->LoadData("n64ddFlag", isRando);
|
||||
if (isRando) {
|
||||
gSaveContext.questId = QUEST_RANDOMIZER;
|
||||
gSaveContext.ship.quest.id = QUEST_RANDOMIZER;
|
||||
}
|
||||
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
|
||||
SaveManager::Instance->LoadData("health", gSaveContext.health);
|
||||
@ -1864,43 +1864,43 @@ void SaveManager::LoadBaseVersion3() {
|
||||
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("sohStats", []() {
|
||||
SaveManager::Instance->LoadCharArray("buildVersion", gSaveContext.sohStats.buildVersion,
|
||||
ARRAY_COUNT(gSaveContext.sohStats.buildVersion));
|
||||
SaveManager::Instance->LoadData("buildVersionMajor", gSaveContext.sohStats.buildVersionMajor);
|
||||
SaveManager::Instance->LoadData("buildVersionMinor", gSaveContext.sohStats.buildVersionMinor);
|
||||
SaveManager::Instance->LoadData("buildVersionPatch", gSaveContext.sohStats.buildVersionPatch);
|
||||
SaveManager::Instance->LoadCharArray("buildVersion", gSaveContext.ship.stats.buildVersion,
|
||||
ARRAY_COUNT(gSaveContext.ship.stats.buildVersion));
|
||||
SaveManager::Instance->LoadData("buildVersionMajor", gSaveContext.ship.stats.buildVersionMajor);
|
||||
SaveManager::Instance->LoadData("buildVersionMinor", gSaveContext.ship.stats.buildVersionMinor);
|
||||
SaveManager::Instance->LoadData("buildVersionPatch", gSaveContext.ship.stats.buildVersionPatch);
|
||||
|
||||
SaveManager::Instance->LoadData("heartPieces", gSaveContext.sohStats.heartPieces);
|
||||
SaveManager::Instance->LoadData("heartContainers", gSaveContext.sohStats.heartContainers);
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.dungeonKeys[i]);
|
||||
SaveManager::Instance->LoadData("heartPieces", gSaveContext.ship.stats.heartPieces);
|
||||
SaveManager::Instance->LoadData("heartContainers", gSaveContext.ship.stats.heartContainers);
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.ship.stats.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.sohStats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.sohStats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.sohStats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.sohStats.pauseTimer);
|
||||
SaveManager::Instance->LoadArray("itemTimestamps", ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.itemTimestamp[i]);
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.ship.stats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer);
|
||||
SaveManager::Instance->LoadArray("itemTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.itemTimestamp[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneTimestamps", ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("sceneTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.sceneTimestamps), [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("scene", gSaveContext.sohStats.sceneTimestamps[i].scene);
|
||||
SaveManager::Instance->LoadData("room", gSaveContext.sohStats.sceneTimestamps[i].room);
|
||||
SaveManager::Instance->LoadData("sceneTime", gSaveContext.sohStats.sceneTimestamps[i].sceneTime);
|
||||
SaveManager::Instance->LoadData("roomTime", gSaveContext.sohStats.sceneTimestamps[i].roomTime);
|
||||
SaveManager::Instance->LoadData("isRoom", gSaveContext.sohStats.sceneTimestamps[i].isRoom);
|
||||
SaveManager::Instance->LoadData("scene", gSaveContext.ship.stats.sceneTimestamps[i].scene);
|
||||
SaveManager::Instance->LoadData("room", gSaveContext.ship.stats.sceneTimestamps[i].room);
|
||||
SaveManager::Instance->LoadData("sceneTime", gSaveContext.ship.stats.sceneTimestamps[i].sceneTime);
|
||||
SaveManager::Instance->LoadData("roomTime", gSaveContext.ship.stats.sceneTimestamps[i].roomTime);
|
||||
SaveManager::Instance->LoadData("isRoom", gSaveContext.ship.stats.sceneTimestamps[i].isRoom);
|
||||
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadData("tsIdx", gSaveContext.sohStats.tsIdx);
|
||||
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.sohStats.count), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.count[i]);
|
||||
SaveManager::Instance->LoadData("tsIdx", gSaveContext.ship.stats.tsIdx);
|
||||
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.ship.stats.count), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.count[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.scenesDiscovered[i]);
|
||||
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.scenesDiscovered[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.sohStats.entrancesDiscovered[i]);
|
||||
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
@ -1978,27 +1978,27 @@ void SaveManager::LoadBaseVersion3() {
|
||||
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.ship.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.randomizerInf[i]);
|
||||
});
|
||||
int isMQ = 0;
|
||||
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
|
||||
if (isMQ) {
|
||||
gSaveContext.questId = QUEST_MASTER;
|
||||
gSaveContext.ship.quest.id = QUEST_MASTER;
|
||||
}
|
||||
SaveManager::Instance->LoadStruct("backupFW", []() {
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.backupFW.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.backupFW.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.backupFW.pos.z);
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.ship.backupFW.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.ship.backupFW.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.ship.backupFW.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.backupFW.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.backupFW.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.backupFW.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.backupFW.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.backupFW.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.backupFW.tempCollectFlags);
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.ship.backupFW.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.ship.backupFW.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.ship.backupFW.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.ship.backupFW.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.ship.backupFW.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.ship.backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.ship.backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
|
||||
}
|
||||
@ -2018,7 +2018,7 @@ void SaveManager::LoadBaseVersion4() {
|
||||
int isRando = 0;
|
||||
SaveManager::Instance->LoadData("n64ddFlag", isRando);
|
||||
if (isRando) {
|
||||
gSaveContext.questId = QUEST_RANDOMIZER;
|
||||
gSaveContext.ship.quest.id = QUEST_RANDOMIZER;
|
||||
}
|
||||
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
|
||||
SaveManager::Instance->LoadData("health", gSaveContext.health);
|
||||
@ -2159,30 +2159,30 @@ void SaveManager::LoadBaseVersion4() {
|
||||
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.ship.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.randomizerInf[i]);
|
||||
});
|
||||
int isMQ = 0;
|
||||
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
|
||||
if (isMQ) {
|
||||
gSaveContext.questId = QUEST_MASTER;
|
||||
gSaveContext.ship.quest.id = QUEST_MASTER;
|
||||
}
|
||||
SaveManager::Instance->LoadStruct("backupFW", []() {
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.backupFW.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.backupFW.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.backupFW.pos.z);
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.ship.backupFW.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.ship.backupFW.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.ship.backupFW.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.backupFW.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.backupFW.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.backupFW.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.backupFW.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.backupFW.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.backupFW.tempCollectFlags);
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.ship.backupFW.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.ship.backupFW.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.ship.backupFW.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.ship.backupFW.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.ship.backupFW.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.ship.backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.ship.backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
|
||||
SaveManager::Instance->LoadData("maskMemory", gSaveContext.maskMemory);
|
||||
SaveManager::Instance->LoadData("maskMemory", gSaveContext.ship.maskMemory);
|
||||
}
|
||||
|
||||
void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSave) {
|
||||
@ -2197,7 +2197,7 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
|
||||
SaveManager::Instance->SaveArray("playerName", ARRAY_COUNT(saveContext->playerName), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->playerName[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveData("n64ddFlag", saveContext->questId == QUEST_RANDOMIZER);
|
||||
SaveManager::Instance->SaveData("n64ddFlag", saveContext->ship.quest.id == QUEST_RANDOMIZER);
|
||||
SaveManager::Instance->SaveData("healthCapacity", saveContext->healthCapacity);
|
||||
SaveManager::Instance->SaveData("health", saveContext->health);
|
||||
SaveManager::Instance->SaveData("magicLevel", saveContext->magicLevel);
|
||||
@ -2333,26 +2333,26 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
|
||||
SaveManager::Instance->SaveData("angle", saveContext->horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->SaveArray("randomizerInf", ARRAY_COUNT(saveContext->randomizerInf), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->randomizerInf[i]);
|
||||
SaveManager::Instance->SaveArray("randomizerInf", ARRAY_COUNT(saveContext->ship.randomizerInf), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.randomizerInf[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveData("isMasterQuest", saveContext->questId == QUEST_MASTER);
|
||||
SaveManager::Instance->SaveData("isMasterQuest", saveContext->ship.quest.id == QUEST_MASTER);
|
||||
SaveManager::Instance->SaveStruct("backupFW", [&]() {
|
||||
SaveManager::Instance->SaveStruct("pos", [&]() {
|
||||
SaveManager::Instance->SaveData("x", saveContext->backupFW.pos.x);
|
||||
SaveManager::Instance->SaveData("y", saveContext->backupFW.pos.y);
|
||||
SaveManager::Instance->SaveData("z", saveContext->backupFW.pos.z);
|
||||
SaveManager::Instance->SaveData("x", saveContext->ship.backupFW.pos.x);
|
||||
SaveManager::Instance->SaveData("y", saveContext->ship.backupFW.pos.y);
|
||||
SaveManager::Instance->SaveData("z", saveContext->ship.backupFW.pos.z);
|
||||
});
|
||||
SaveManager::Instance->SaveData("yaw", saveContext->backupFW.yaw);
|
||||
SaveManager::Instance->SaveData("playerParams", saveContext->backupFW.playerParams);
|
||||
SaveManager::Instance->SaveData("entranceIndex", saveContext->backupFW.entranceIndex);
|
||||
SaveManager::Instance->SaveData("roomIndex", saveContext->backupFW.roomIndex);
|
||||
SaveManager::Instance->SaveData("set", saveContext->backupFW.set);
|
||||
SaveManager::Instance->SaveData("tempSwchFlags", saveContext->backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->SaveData("tempCollectFlags", saveContext->backupFW.tempCollectFlags);
|
||||
SaveManager::Instance->SaveData("yaw", saveContext->ship.backupFW.yaw);
|
||||
SaveManager::Instance->SaveData("playerParams", saveContext->ship.backupFW.playerParams);
|
||||
SaveManager::Instance->SaveData("entranceIndex", saveContext->ship.backupFW.entranceIndex);
|
||||
SaveManager::Instance->SaveData("roomIndex", saveContext->ship.backupFW.roomIndex);
|
||||
SaveManager::Instance->SaveData("set", saveContext->ship.backupFW.set);
|
||||
SaveManager::Instance->SaveData("tempSwchFlags", saveContext->ship.backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->SaveData("tempCollectFlags", saveContext->ship.backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->SaveData("dogParams", saveContext->dogParams);
|
||||
SaveManager::Instance->SaveData("maskMemory", saveContext->maskMemory);
|
||||
SaveManager::Instance->SaveData("maskMemory", saveContext->ship.maskMemory);
|
||||
}
|
||||
|
||||
// Load a string into a char array based on size and ensuring it is null terminated when overflowed
|
||||
|
@ -4982,15 +4982,33 @@ void Flags_UnsetEventInf(s32 flag) {
|
||||
* Tests if "randomizerInf" flag is set.
|
||||
*/
|
||||
s32 Flags_GetRandomizerInf(RandomizerInf flag) {
|
||||
return gSaveContext.randomizerInf[flag >> 4] & (1 << (flag & 0xF));
|
||||
// Randomizer flags are currently accessible from any quest (boss rush as an example)
|
||||
/*
|
||||
if (!IS_RANDO) {
|
||||
LUSLOG_ERROR("Tried to get randomizerInf flag \"%d\" outside of rando", flag);
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
return gSaveContext.ship.randomizerInf[flag >> 4] & (1 << (flag & 0xF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets "randomizerInf" flag.
|
||||
*/
|
||||
void Flags_SetRandomizerInf(RandomizerInf flag) {
|
||||
// Randomizer flags are currently accessible from any quest (boss rush as an example)
|
||||
/*
|
||||
if (!IS_RANDO) {
|
||||
LUSLOG_ERROR("Tried to set randomizerInf flag \"%d\" outside of rando", flag);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
s32 previouslyOff = !Flags_GetRandomizerInf(flag);
|
||||
gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
gSaveContext.ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
|
||||
if (previouslyOff) {
|
||||
LUSLOG_INFO("RandomizerInf Flag Set - %#x", flag);
|
||||
GameInteractor_ExecuteOnFlagSet(FLAG_RANDOMIZER_INF, flag);
|
||||
@ -5001,8 +5019,17 @@ void Flags_SetRandomizerInf(RandomizerInf flag) {
|
||||
* Unsets "randomizerInf" flag.
|
||||
*/
|
||||
void Flags_UnsetRandomizerInf(RandomizerInf flag) {
|
||||
// Randomizer flags are currently accessible from any quest (boss rush as an example)
|
||||
/*
|
||||
if (!IS_RANDO) {
|
||||
LUSLOG_ERROR("Tried to unset randomizerInf flag \"%d\" outside of rando", flag);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
s32 previouslyOn = Flags_GetRandomizerInf(flag);
|
||||
gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
gSaveContext.ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
|
||||
if (previouslyOn) {
|
||||
LUSLOG_INFO("RandomizerInf Flag Unset - %#x", flag);
|
||||
GameInteractor_ExecuteOnFlagUnset(FLAG_RANDOMIZER_INF, flag);
|
||||
|
@ -626,8 +626,8 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
|
||||
break;
|
||||
case 8:
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterFarore"), 0)) {
|
||||
FaroresWindData tempFW = gSaveContext.backupFW;
|
||||
gSaveContext.backupFW = gSaveContext.fw;
|
||||
FaroresWindData tempFW = gSaveContext.ship.backupFW;
|
||||
gSaveContext.ship.backupFW = gSaveContext.fw;
|
||||
gSaveContext.fw = tempFW;
|
||||
} else {
|
||||
gSaveContext.fw.set = 0;
|
||||
|
@ -1046,7 +1046,7 @@ void GetItem_DrawTriforcePiece(PlayState* play, s16 drawId) {
|
||||
|
||||
Matrix_Scale(0.035f, 0.035f, 0.035f, MTXMODE_APPLY);
|
||||
|
||||
uint8_t index = gSaveContext.triforcePiecesCollected % 3;
|
||||
uint8_t index = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected % 3;
|
||||
Gfx* triforcePieceDL;
|
||||
|
||||
switch (index) {
|
||||
|
@ -59,9 +59,9 @@ void KaleidoScopeCall_Update(PlayState* play) {
|
||||
|
||||
GameInteractor_ExecuteOnKaleidoUpdate();
|
||||
|
||||
if (!gSaveContext.sohStats.gameComplete &&
|
||||
(!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
|
||||
gSaveContext.sohStats.pauseTimer++;
|
||||
if (!gSaveContext.ship.stats.gameComplete &&
|
||||
(!IS_BOSS_RUSH || !gSaveContext.ship.quest.data.bossRush.isPaused)) {
|
||||
gSaveContext.ship.stats.pauseTimer++;
|
||||
}
|
||||
|
||||
if ((pauseCtx->state != 0) || (pauseCtx->debugState != 0)) {
|
||||
@ -73,7 +73,7 @@ void KaleidoScopeCall_Update(PlayState* play) {
|
||||
pauseCtx->unk_1E4 = 0;
|
||||
pauseCtx->unk_1EC = 0;
|
||||
pauseCtx->state = (pauseCtx->state & 0xFFFF) + 1;
|
||||
gSaveContext.sohStats.count[COUNT_PAUSES]++;
|
||||
gSaveContext.ship.stats.count[COUNT_PAUSES]++;
|
||||
}
|
||||
} else if (pauseCtx->state == 8) {
|
||||
HREG(80) = 7;
|
||||
|
@ -1812,7 +1812,7 @@ void func_80084BF4(PlayState* play, u16 flag) {
|
||||
void GameplayStats_SetTimestamp(PlayState* play, u8 item) {
|
||||
|
||||
// If we already have a timestamp for this item, do nothing
|
||||
if (gSaveContext.sohStats.itemTimestamp[item] != 0){
|
||||
if (gSaveContext.ship.stats.itemTimestamp[item] != 0){
|
||||
return;
|
||||
}
|
||||
// Use ITEM_KEY_BOSS only for Ganon's boss key - not any other boss keys
|
||||
@ -1831,20 +1831,20 @@ void GameplayStats_SetTimestamp(PlayState* play, u8 item) {
|
||||
|
||||
// Count any bottled item as a bottle
|
||||
if (item >= ITEM_BOTTLE && item <= ITEM_POE) {
|
||||
if (gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] == 0) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] = time;
|
||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] == 0) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] = time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Count any bombchu pack as bombchus
|
||||
if (item == ITEM_BOMBCHU || (item >= ITEM_BOMBCHUS_5 && item <= ITEM_BOMBCHUS_20)) {
|
||||
if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] == 0) {
|
||||
gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time;
|
||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] == 0) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
gSaveContext.sohStats.itemTimestamp[item] = time;
|
||||
gSaveContext.ship.stats.itemTimestamp[item] = time;
|
||||
GameInteractor_ExecuteOnTimestamp(item);
|
||||
}
|
||||
|
||||
@ -2338,7 +2338,7 @@ u8 Item_Give(PlayState* play, u8 item) {
|
||||
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
||||
} else if ((item == ITEM_HEART_PIECE_2) || (item == ITEM_HEART_PIECE)) {
|
||||
gSaveContext.inventory.questItems += 1 << (QUEST_HEART_PIECE + 4);
|
||||
gSaveContext.sohStats.heartPieces++;
|
||||
gSaveContext.ship.stats.heartPieces++;
|
||||
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
||||
} else if (item == ITEM_HEART_CONTAINER) {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("HurtContainer"), 0)) {
|
||||
@ -2348,7 +2348,7 @@ u8 Item_Give(PlayState* play, u8 item) {
|
||||
gSaveContext.healthCapacity -= 0x10;
|
||||
gSaveContext.health -= 0x10;
|
||||
}
|
||||
gSaveContext.sohStats.heartContainers++;
|
||||
gSaveContext.ship.stats.heartContainers++;
|
||||
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
||||
} else if (item == ITEM_HEART) {
|
||||
osSyncPrintf("回復ハート回復ハート回復ハート\n"); // "Recovery Heart"
|
||||
@ -2447,7 +2447,7 @@ u8 Item_Give(PlayState* play, u8 item) {
|
||||
}
|
||||
|
||||
if (item >= ITEM_POCKET_EGG) {
|
||||
gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(item);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(item);
|
||||
}
|
||||
|
||||
temp = INV_CONTENT(item);
|
||||
@ -2763,8 +2763,8 @@ bool Inventory_HatchPocketCucco(PlayState* play) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gSaveContext.adultTradeItems &= ~ADULT_TRADE_FLAG(ITEM_POCKET_EGG);
|
||||
gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(ITEM_POCKET_CUCCO);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~ADULT_TRADE_FLAG(ITEM_POCKET_EGG);
|
||||
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(ITEM_POCKET_CUCCO);
|
||||
Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO);
|
||||
return 1;
|
||||
}
|
||||
@ -2882,7 +2882,7 @@ s32 Health_ChangeBy(PlayState* play, s16 healthChange) {
|
||||
gSaveContext.healthCapacity);
|
||||
|
||||
if (healthChange < 0) {
|
||||
gSaveContext.sohStats.count[COUNT_DAMAGE_TAKEN] += -healthChange;
|
||||
gSaveContext.ship.stats.count[COUNT_DAMAGE_TAKEN] += -healthChange;
|
||||
}
|
||||
|
||||
// If one-hit ko mode is on, any damage kills you and you cannot gain health.
|
||||
@ -2952,10 +2952,10 @@ void Rupees_ChangeBy(s16 rupeeChange) {
|
||||
}
|
||||
|
||||
if (rupeeChange > 0) {
|
||||
gSaveContext.sohStats.count[COUNT_RUPEES_COLLECTED] += rupeeChange;
|
||||
gSaveContext.ship.stats.count[COUNT_RUPEES_COLLECTED] += rupeeChange;
|
||||
}
|
||||
if (rupeeChange < 0) {
|
||||
gSaveContext.sohStats.count[COUNT_RUPEES_SPENT] += -rupeeChange;
|
||||
gSaveContext.ship.stats.count[COUNT_RUPEES_SPENT] += -rupeeChange;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2963,25 +2963,25 @@ void GameplayStats_UpdateAmmoUsed(s16 item, s16 ammoUsed) {
|
||||
|
||||
switch (item) {
|
||||
case ITEM_STICK:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_STICK] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_STICK] += ammoUsed;
|
||||
break;
|
||||
case ITEM_NUT:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_NUT] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_NUT] += ammoUsed;
|
||||
break;
|
||||
case ITEM_BOMB:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_BOMB] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_BOMB] += ammoUsed;
|
||||
break;
|
||||
case ITEM_BOW:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_ARROW] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_ARROW] += ammoUsed;
|
||||
break;
|
||||
case ITEM_SLINGSHOT:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_SEED] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_SEED] += ammoUsed;
|
||||
break;
|
||||
case ITEM_BOMBCHU:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_BOMBCHU] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_BOMBCHU] += ammoUsed;
|
||||
break;
|
||||
case ITEM_BEAN:
|
||||
gSaveContext.sohStats.count[COUNT_AMMO_USED_BEAN] += ammoUsed;
|
||||
gSaveContext.ship.stats.count[COUNT_AMMO_USED_BEAN] += ammoUsed;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -6122,7 +6122,7 @@ void Interface_Draw(PlayState* play) {
|
||||
void Interface_DrawTotalGameplayTimer(PlayState* play) {
|
||||
// Draw timer based on the Gameplay Stats total time.
|
||||
|
||||
if ((IS_BOSS_RUSH && gSaveContext.bossRushOptions[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES) ||
|
||||
if ((IS_BOSS_RUSH && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES) ||
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum <= 2)) {
|
||||
|
||||
s32 X_Margins_Timer = 0;
|
||||
@ -6202,9 +6202,9 @@ void Interface_DrawTotalGameplayTimer(PlayState* play) {
|
||||
(rectTop + rectHeight) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
||||
|
||||
// Draw regular text. Change color based on if the timer is paused, running or the game is completed.
|
||||
if (gSaveContext.sohStats.gameComplete) {
|
||||
if (gSaveContext.ship.stats.gameComplete) {
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 255, 0, 255);
|
||||
} else if (gSaveContext.isBossRushPaused && !gSaveContext.sohStats.rtaTiming) {
|
||||
} else if (IS_BOSS_RUSH && gSaveContext.ship.quest.data.bossRush.isPaused && !gSaveContext.ship.stats.rtaTiming) {
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 150, 150, 150, 255);
|
||||
} else {
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255);
|
||||
@ -6429,11 +6429,11 @@ void Interface_Update(PlayState* play) {
|
||||
} else {
|
||||
gSaveContext.rupeeAccumulator = 0;
|
||||
}
|
||||
if (gSaveContext.rupeeAccumulator == 0 && gSaveContext.pendingSale != ITEM_NONE) {
|
||||
u16 tempSaleItem = gSaveContext.pendingSale;
|
||||
u16 tempSaleMod = gSaveContext.pendingSaleMod;
|
||||
gSaveContext.pendingSale = ITEM_NONE;
|
||||
gSaveContext.pendingSaleMod = MOD_NONE;
|
||||
if (gSaveContext.rupeeAccumulator == 0 && gSaveContext.ship.pendingSale != ITEM_NONE) {
|
||||
u16 tempSaleItem = gSaveContext.ship.pendingSale;
|
||||
u16 tempSaleMod = gSaveContext.ship.pendingSaleMod;
|
||||
gSaveContext.ship.pendingSale = ITEM_NONE;
|
||||
gSaveContext.ship.pendingSaleMod = MOD_NONE;
|
||||
if (tempSaleMod == MOD_NONE) {
|
||||
GetItemID getItemID = RetrieveGetItemIDFromItemID(tempSaleItem);
|
||||
RandomizerGet randomizerGet = RetrieveRandomizerGetFromItemID(tempSaleItem);
|
||||
|
@ -646,32 +646,32 @@ void Play_Init(GameState* thisx) {
|
||||
gSaveContext.respawnFlag = 0;
|
||||
|
||||
// #region SOH [Stats]
|
||||
if (gSaveContext.sohStats.sceneNum != gPlayState->sceneNum) {
|
||||
u16 idx = gSaveContext.sohStats.tsIdx;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].sceneTime = gSaveContext.sohStats.sceneTimer / 2;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].roomTime = gSaveContext.sohStats.roomTimer / 2;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].scene = gSaveContext.sohStats.sceneNum;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].room = gSaveContext.sohStats.roomNum;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].isRoom =
|
||||
gPlayState->sceneNum == gSaveContext.sohStats.sceneTimestamps[idx].scene &&
|
||||
gPlayState->roomCtx.curRoom.num != gSaveContext.sohStats.sceneTimestamps[idx].room;
|
||||
gSaveContext.sohStats.tsIdx++;
|
||||
gSaveContext.sohStats.sceneTimer = 0;
|
||||
gSaveContext.sohStats.roomTimer = 0;
|
||||
} else if (gSaveContext.sohStats.roomNum != gPlayState->roomCtx.curRoom.num) {
|
||||
u16 idx = gSaveContext.sohStats.tsIdx;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].roomTime = gSaveContext.sohStats.roomTimer / 2;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].scene = gSaveContext.sohStats.sceneNum;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].room = gSaveContext.sohStats.roomNum;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].isRoom =
|
||||
gPlayState->sceneNum == gSaveContext.sohStats.sceneTimestamps[idx].scene &&
|
||||
gPlayState->roomCtx.curRoom.num != gSaveContext.sohStats.sceneTimestamps[idx].room;
|
||||
gSaveContext.sohStats.tsIdx++;
|
||||
gSaveContext.sohStats.roomTimer = 0;
|
||||
if (gSaveContext.ship.stats.sceneNum != gPlayState->sceneNum) {
|
||||
u16 idx = gSaveContext.ship.stats.tsIdx;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].sceneTime = gSaveContext.ship.stats.sceneTimer / 2;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].roomTime = gSaveContext.ship.stats.roomTimer / 2;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].scene = gSaveContext.ship.stats.sceneNum;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].room = gSaveContext.ship.stats.roomNum;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].isRoom =
|
||||
gPlayState->sceneNum == gSaveContext.ship.stats.sceneTimestamps[idx].scene &&
|
||||
gPlayState->roomCtx.curRoom.num != gSaveContext.ship.stats.sceneTimestamps[idx].room;
|
||||
gSaveContext.ship.stats.tsIdx++;
|
||||
gSaveContext.ship.stats.sceneTimer = 0;
|
||||
gSaveContext.ship.stats.roomTimer = 0;
|
||||
} else if (gSaveContext.ship.stats.roomNum != gPlayState->roomCtx.curRoom.num) {
|
||||
u16 idx = gSaveContext.ship.stats.tsIdx;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].roomTime = gSaveContext.ship.stats.roomTimer / 2;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].scene = gSaveContext.ship.stats.sceneNum;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].room = gSaveContext.ship.stats.roomNum;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].isRoom =
|
||||
gPlayState->sceneNum == gSaveContext.ship.stats.sceneTimestamps[idx].scene &&
|
||||
gPlayState->roomCtx.curRoom.num != gSaveContext.ship.stats.sceneTimestamps[idx].room;
|
||||
gSaveContext.ship.stats.tsIdx++;
|
||||
gSaveContext.ship.stats.roomTimer = 0;
|
||||
}
|
||||
|
||||
gSaveContext.sohStats.sceneNum = gPlayState->sceneNum;
|
||||
gSaveContext.sohStats.roomNum = gPlayState->roomCtx.curRoom.num;
|
||||
gSaveContext.ship.stats.sceneNum = gPlayState->sceneNum;
|
||||
gSaveContext.ship.stats.roomNum = gPlayState->roomCtx.curRoom.num;
|
||||
// #endregion
|
||||
|
||||
#if 0
|
||||
@ -741,28 +741,28 @@ void Play_Update(PlayState* play) {
|
||||
}
|
||||
|
||||
// #region SOH [Stats] Gameplay stats: Count button presses
|
||||
if (!gSaveContext.sohStats.gameComplete) {
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_A)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_B)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_B]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CUP)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CUP]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CRIGHT)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CRIGHT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CLEFT)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CLEFT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CDOWN)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_CDOWN]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DUP)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DUP]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DRIGHT)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DRIGHT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DDOWN)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DDOWN]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DLEFT)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_DLEFT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_L)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_L]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_R)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_R]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_Z)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_Z]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_START)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_START]++;}
|
||||
if (!gSaveContext.ship.stats.gameComplete) {
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_A)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_A]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_B)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_B]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CUP)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_CUP]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CRIGHT)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_CRIGHT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CLEFT)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_CLEFT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_CDOWN)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_CDOWN]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DUP)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_DUP]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DRIGHT)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_DRIGHT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DDOWN)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_DDOWN]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_DLEFT)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_DLEFT]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_L)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_L]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_R)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_R]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_Z)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_Z]++;}
|
||||
if (CHECK_BTN_ALL(input[0].press.button, BTN_START)) {gSaveContext.ship.stats.count[COUNT_BUTTON_PRESSES_START]++;}
|
||||
|
||||
// Start RTA timing on first non-c-up input after intro cutscene
|
||||
if (
|
||||
!gSaveContext.sohStats.fileCreatedAt && !Player_InCsMode(play) &&
|
||||
!gSaveContext.ship.stats.fileCreatedAt && !Player_InCsMode(play) &&
|
||||
((input[0].press.button && input[0].press.button != 0x8) || input[0].rel.stick_x != 0 || input[0].rel.stick_y != 0)
|
||||
) {
|
||||
gSaveContext.sohStats.fileCreatedAt = GetUnixTimestamp();
|
||||
gSaveContext.ship.stats.fileCreatedAt = GetUnixTimestamp();
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
@ -1146,14 +1146,14 @@ void Play_Update(PlayState* play) {
|
||||
func_800AA178(true);
|
||||
|
||||
// Gameplay stat tracking
|
||||
if (!gSaveContext.sohStats.gameComplete &&
|
||||
(!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
|
||||
gSaveContext.sohStats.playTimer++;
|
||||
gSaveContext.sohStats.sceneTimer++;
|
||||
gSaveContext.sohStats.roomTimer++;
|
||||
if (!gSaveContext.ship.stats.gameComplete &&
|
||||
(!IS_BOSS_RUSH || !gSaveContext.ship.quest.data.bossRush.isPaused)) {
|
||||
gSaveContext.ship.stats.playTimer++;
|
||||
gSaveContext.ship.stats.sceneTimer++;
|
||||
gSaveContext.ship.stats.roomTimer++;
|
||||
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA && Player_GetMask(play) == PLAYER_MASK_BUNNY) {
|
||||
gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD]++;
|
||||
gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD]++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2220,7 +2220,7 @@ void Play_PerformSave(PlayState* play) {
|
||||
|
||||
uint8_t triforceHuntCompleted =
|
||||
IS_RANDO &&
|
||||
gSaveContext.triforcePiecesCollected == (Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1) &&
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected == (Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1) &&
|
||||
Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT);
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF || triforceHuntCompleted) {
|
||||
Overlay_DisplayText(3.0f, "Game Saved");
|
||||
|
@ -653,14 +653,14 @@ void func_80097534(PlayState* play, RoomContext* roomCtx) {
|
||||
Map_SavePlayerInitialInfo(play);
|
||||
}
|
||||
Audio_SetEnvReverb(play->roomCtx.curRoom.echo);
|
||||
u8 idx = gSaveContext.sohStats.tsIdx;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].scene = gSaveContext.sohStats.sceneNum;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].room = gSaveContext.sohStats.roomNum;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].roomTime = gSaveContext.sohStats.roomTimer / 2;
|
||||
gSaveContext.sohStats.sceneTimestamps[idx].isRoom =
|
||||
gPlayState->sceneNum == gSaveContext.sohStats.sceneTimestamps[idx].scene &&
|
||||
gPlayState->roomCtx.curRoom.num != gSaveContext.sohStats.sceneTimestamps[idx].room;
|
||||
gSaveContext.sohStats.tsIdx++;
|
||||
gSaveContext.sohStats.roomNum = roomCtx->curRoom.num;
|
||||
gSaveContext.sohStats.roomTimer = 0;
|
||||
u8 idx = gSaveContext.ship.stats.tsIdx;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].scene = gSaveContext.ship.stats.sceneNum;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].room = gSaveContext.ship.stats.roomNum;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].roomTime = gSaveContext.ship.stats.roomTimer / 2;
|
||||
gSaveContext.ship.stats.sceneTimestamps[idx].isRoom =
|
||||
gPlayState->sceneNum == gSaveContext.ship.stats.sceneTimestamps[idx].scene &&
|
||||
gPlayState->roomCtx.curRoom.num != gSaveContext.ship.stats.sceneTimestamps[idx].room;
|
||||
gSaveContext.ship.stats.tsIdx++;
|
||||
gSaveContext.ship.stats.roomNum = roomCtx->curRoom.num;
|
||||
gSaveContext.ship.stats.roomTimer = 0;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ void Sram_OpenSave() {
|
||||
}
|
||||
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
|
||||
gSaveContext.maskMemory = PLAYER_MASK_NONE;
|
||||
gSaveContext.ship.maskMemory = PLAYER_MASK_NONE;
|
||||
}
|
||||
|
||||
osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex);
|
||||
@ -252,11 +252,11 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
u8 currentQuest = fileChooseCtx->questType[fileChooseCtx->buttonIndex];
|
||||
|
||||
if (currentQuest == QUEST_RANDOMIZER && (Randomizer_IsSeedGenerated() || Randomizer_IsSpoilerLoaded())) {
|
||||
gSaveContext.questId = QUEST_RANDOMIZER;
|
||||
gSaveContext.ship.quest.id = QUEST_RANDOMIZER;
|
||||
|
||||
Randomizer_InitSaveFile();
|
||||
} else {
|
||||
gSaveContext.questId = currentQuest;
|
||||
gSaveContext.ship.quest.id = currentQuest;
|
||||
}
|
||||
|
||||
Save_SaveFile();
|
||||
|
@ -487,7 +487,7 @@ void EnBox_Open(EnBox* this, PlayState* play) {
|
||||
|
||||
if (Animation_OnFrame(&this->skelanime, 30.0f)) {
|
||||
sfxId = NA_SE_EV_TBOX_UNLOCK;
|
||||
gSaveContext.sohStats.count[COUNT_CHESTS_OPENED]++;
|
||||
gSaveContext.ship.stats.count[COUNT_CHESTS_OPENED]++;
|
||||
} else if (Animation_OnFrame(&this->skelanime, 90.0f)) {
|
||||
sfxId = NA_SE_EV_TBOX_OPEN;
|
||||
}
|
||||
|
@ -391,8 +391,8 @@ void func_809EFDD0(EnDns* this, PlayState* play) {
|
||||
pendingGetItemId = this->dnsItemEntry->getItemId;
|
||||
}
|
||||
GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId);
|
||||
gSaveContext.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.pendingSaleMod = itemEntry.modIndex;
|
||||
gSaveContext.ship.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = itemEntry.modIndex;
|
||||
Actor_OfferGetItem(&this->actor, play, pendingGetItemId, 130.0f, 100.0f);
|
||||
}
|
||||
|
||||
|
@ -206,8 +206,8 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) {
|
||||
if (GameInteractor_Should(VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) {
|
||||
GetItemEntry itemEntry = ItemTable_Retrieve(GI_POTION_BLUE);
|
||||
Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
|
||||
gSaveContext.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.pendingSaleMod = itemEntry.modIndex;
|
||||
gSaveContext.ship.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = itemEntry.modIndex;
|
||||
this->actionFunc = EnDs_GiveBluePotion;
|
||||
}
|
||||
|
||||
|
@ -880,16 +880,16 @@ s32 EnGirlA_CanBuy_Randomizer(PlayState* play, EnGirlA* this) {
|
||||
|
||||
void EnGirlA_ItemGive_Arrows(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Inventory_ChangeAmmo(ITEM_BOW, this->itemCount);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_Bombs(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
switch (this->itemCount) {
|
||||
case 5:
|
||||
Item_Give(play, ITEM_BOMBS_5);
|
||||
@ -909,8 +909,8 @@ void EnGirlA_ItemGive_Bombs(PlayState* play, EnGirlA* this) {
|
||||
|
||||
void EnGirlA_ItemGive_DekuNuts(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
switch (this->itemCount) {
|
||||
case 5:
|
||||
Item_Give(play, ITEM_NUTS_5);
|
||||
@ -924,16 +924,16 @@ void EnGirlA_ItemGive_DekuNuts(PlayState* play, EnGirlA* this) {
|
||||
|
||||
void EnGirlA_ItemGive_DekuSticks(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_STICK);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_Longsword(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
func_800849EC(play);
|
||||
gSaveContext.swordHealth = 8;
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
@ -941,86 +941,86 @@ void EnGirlA_ItemGive_Longsword(PlayState* play, EnGirlA* this) {
|
||||
|
||||
void EnGirlA_ItemGive_HylianShield(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_SHIELD_HYLIAN);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_DekuShield(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_SHIELD_DEKU);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_GoronTunic(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_TUNIC_GORON);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_ZoraTunic(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_TUNIC_ZORA);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_Health(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Health_ChangeBy(play, this->itemCount);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_MilkBottle(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_MILK_BOTTLE);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_WeirdEgg(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_WEIRD_EGG);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_Unk19(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_Unk20(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_DekuSeeds(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Item_Give(play, ITEM_SEEDS_30);
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_ItemGive_BottledItem(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
switch (this->actor.params) {
|
||||
case SI_FISH:
|
||||
Item_Give(play, ITEM_FISH);
|
||||
@ -1066,8 +1066,8 @@ void EnGirlA_ItemGive_Randomizer(PlayState* play, EnGirlA* this) {
|
||||
|
||||
void EnGirlA_BuyEvent_ShieldDiscount(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
if (this->actor.params == SI_HYLIAN_SHIELD) {
|
||||
if (Flags_GetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD)) {
|
||||
Rupees_ChangeBy(-(this->basePrice - sShieldDiscounts[(s32)Rand_ZeroFloat(7.9f)]));
|
||||
@ -1079,22 +1079,22 @@ void EnGirlA_BuyEvent_ShieldDiscount(PlayState* play, EnGirlA* this) {
|
||||
|
||||
void EnGirlA_BuyEvent_GoronTunic(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_BuyEvent_ZoraTunic(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
}
|
||||
|
||||
void EnGirlA_BuyEvent_ObtainBombchuPack(PlayState* play, EnGirlA* this) {
|
||||
GetItemEntry entry = ItemTable_Retrieve(this->getItemId);
|
||||
gSaveContext.pendingSale = entry.itemId;
|
||||
gSaveContext.pendingSaleMod = entry.modIndex;
|
||||
gSaveContext.ship.pendingSale = entry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = entry.modIndex;
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
|
||||
// Normally, buying a bombchu pack sets a flag indicating the pack is now sold out
|
||||
|
@ -135,8 +135,8 @@ void func_80A89160(EnJs* this, PlayState* play) {
|
||||
En_Js_SetupAction(this, func_80A8910C);
|
||||
} else {
|
||||
GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10);
|
||||
gSaveContext.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.pendingSaleMod = itemEntry.modIndex;
|
||||
gSaveContext.ship.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = itemEntry.modIndex;
|
||||
Actor_OfferGetItem(&this->actor, play, GI_BOMBCHUS_10, 10000.0f, 50.0f);
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ void EnKusa_Main(EnKusa* this, PlayState* play) {
|
||||
EnKusa_SpawnFragments(this, play);
|
||||
EnKusa_DropCollectible(this, play);
|
||||
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
|
||||
gSaveContext.sohStats.count[COUNT_BUSHES_CUT]++;
|
||||
gSaveContext.ship.stats.count[COUNT_BUSHES_CUT]++;
|
||||
|
||||
if ((this->actor.params >> 4) & 1) {
|
||||
EnKusa_SpawnBugs(this, play);
|
||||
@ -379,7 +379,7 @@ void EnKusa_Fall(EnKusa* this, PlayState* play) {
|
||||
if (this->actor.bgCheckFlags & 0xB) {
|
||||
if (!(this->actor.bgCheckFlags & 0x20)) {
|
||||
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
|
||||
gSaveContext.sohStats.count[COUNT_BUSHES_CUT]++;
|
||||
gSaveContext.ship.stats.count[COUNT_BUSHES_CUT]++;
|
||||
}
|
||||
EnKusa_SpawnFragments(this, play);
|
||||
EnKusa_DropCollectible(this, play);
|
||||
|
@ -917,8 +917,8 @@ void func_80B15FE8(EnTa* this, PlayState* play) {
|
||||
EnTa_SetupAction(this, EnTa_GiveItemInLonLonHouse, EnTa_AnimRunToEnd);
|
||||
Rupees_ChangeBy(-30);
|
||||
GetItemEntry itemEntry = ItemTable_Retrieve(GI_MILK);
|
||||
gSaveContext.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.pendingSaleMod = itemEntry.modIndex;
|
||||
gSaveContext.ship.pendingSale = itemEntry.itemId;
|
||||
gSaveContext.ship.pendingSaleMod = itemEntry.modIndex;
|
||||
Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 50.0f);
|
||||
break;
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ void ObjTsubo_AirBreak(ObjTsubo* this, PlayState* play) {
|
||||
sObjectIds[(this->actor.params >> 8) & 1], D_80BA1B8C[(this->actor.params >> 8) & 1]);
|
||||
}
|
||||
func_80033480(play, &this->actor.world.pos, 30.0f, 4, 20, 50, 1);
|
||||
gSaveContext.sohStats.count[COUNT_POTS_BROKEN]++;
|
||||
gSaveContext.ship.stats.count[COUNT_POTS_BROKEN]++;
|
||||
}
|
||||
|
||||
void ObjTsubo_WaterBreak(ObjTsubo* this, PlayState* play) {
|
||||
@ -218,7 +218,7 @@ void ObjTsubo_WaterBreak(ObjTsubo* this, PlayState* play) {
|
||||
(Rand_ZeroOne() * 95.0f) + 15.0f, 0, 32, 70, KAKERA_COLOR_NONE,
|
||||
sObjectIds[(this->actor.params >> 8) & 1], D_80BA1B8C[(this->actor.params >> 8) & 1]);
|
||||
}
|
||||
gSaveContext.sohStats.count[COUNT_POTS_BROKEN]++;
|
||||
gSaveContext.ship.stats.count[COUNT_POTS_BROKEN]++;
|
||||
}
|
||||
|
||||
void ObjTsubo_SetupWaitForObject(ObjTsubo* this) {
|
||||
|
@ -1789,9 +1789,9 @@ void Player_PlaySteppingSfx(Player* this, f32 pitchAdjustment) {
|
||||
func_800F4010(&this->actor.projectedPos, sfxId, pitchAdjustment);
|
||||
// Gameplay stats: Count footsteps
|
||||
// Only count while game isn't complete and don't count Link's idle animations or crawling in crawlspaces
|
||||
if (!gSaveContext.sohStats.gameComplete && !(this->stateFlags2 & PLAYER_STATE2_IDLE_FIDGET) &&
|
||||
if (!gSaveContext.ship.stats.gameComplete && !(this->stateFlags2 & PLAYER_STATE2_IDLE_FIDGET) &&
|
||||
!(this->stateFlags2 & PLAYER_STATE2_CRAWLING)) {
|
||||
gSaveContext.sohStats.count[COUNT_STEPS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_STEPS]++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2379,7 +2379,7 @@ void func_80833A20(Player* this, s32 newMeleeWeaponState) {
|
||||
}
|
||||
|
||||
if (this->heldItemAction >= PLAYER_IA_SWORD_MASTER && this->heldItemAction <= PLAYER_IA_SWORD_BIGGORON) {
|
||||
gSaveContext.sohStats.count[COUNT_SWORD_SWINGS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_SWORD_SWINGS]++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3484,7 +3484,7 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) {
|
||||
this->currentMask = itemAction - PLAYER_IA_MASK_KEATON + 1;
|
||||
}
|
||||
|
||||
gSaveContext.maskMemory = this->currentMask;
|
||||
gSaveContext.ship.maskMemory = this->currentMask;
|
||||
|
||||
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
||||
} else if (((itemAction >= PLAYER_IA_OCARINA_FAIRY) && (itemAction <= PLAYER_IA_OCARINA_OF_TIME)) ||
|
||||
@ -5538,7 +5538,7 @@ void func_8083A0F4(PlayState* play, Player* this) {
|
||||
Player_SetupAction(play, this, Player_Action_8084F608, 0);
|
||||
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0) || !CVarGetInteger(CVAR_ENHANCEMENT("AdultMasks"), 0)) {
|
||||
gSaveContext.maskMemory = PLAYER_MASK_NONE;
|
||||
gSaveContext.ship.maskMemory = PLAYER_MASK_NONE;
|
||||
}
|
||||
} else {
|
||||
LinkAnimationHeader* anim;
|
||||
@ -6267,7 +6267,7 @@ void Player_SetupRoll(Player* this, PlayState* play) {
|
||||
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime,
|
||||
GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType),
|
||||
1.25f * sWaterSpeedFactor);
|
||||
gSaveContext.sohStats.count[COUNT_ROLLS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ROLLS]++;
|
||||
}
|
||||
|
||||
s32 Player_TryRoll(Player* this, PlayState* play) {
|
||||
@ -6326,10 +6326,10 @@ s32 Player_ActionHandler_10(Player* this, PlayState* play) {
|
||||
func_8083BCD0(this, play, controlStickDirection);
|
||||
|
||||
if (controlStickDirection == 1 || controlStickDirection == 3) {
|
||||
gSaveContext.sohStats.count[COUNT_SIDEHOPS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_SIDEHOPS]++;
|
||||
}
|
||||
if (controlStickDirection == 2) {
|
||||
gSaveContext.sohStats.count[COUNT_BACKFLIPS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_BACKFLIPS]++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -7254,8 +7254,8 @@ void func_8083E4C4(PlayState* play, Player* this, GetItemEntry* giEntry) {
|
||||
s32 Player_ActionHandler_2(Player* this, PlayState* play) {
|
||||
Actor* interactedActor;
|
||||
|
||||
if(gSaveContext.pendingIceTrapCount) {
|
||||
gSaveContext.pendingIceTrapCount--;
|
||||
if(gSaveContext.ship.pendingIceTrapCount) {
|
||||
gSaveContext.ship.pendingIceTrapCount--;
|
||||
GameInteractor_ExecuteOnItemReceiveHooks(ItemTable_RetrieveEntry(MOD_RANDOMIZER, RG_ICE_TRAP));
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0)) {
|
||||
return 1;
|
||||
@ -7266,7 +7266,7 @@ s32 Player_ActionHandler_2(Player* this, PlayState* play) {
|
||||
this->getItemId = GI_NONE;
|
||||
this->getItemEntry = (GetItemEntry) GET_ITEM_NONE;
|
||||
// Gameplay stats: Increment Ice Trap count
|
||||
gSaveContext.sohStats.count[COUNT_ICE_TRAPS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_ICE_TRAPS]++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -7295,7 +7295,7 @@ s32 Player_ActionHandler_2(Player* this, PlayState* play) {
|
||||
Player_SetPendingFlag(this, play);
|
||||
Message_StartTextbox(play, 0xF8, NULL);
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
gSaveContext.pendingIceTrapCount++;
|
||||
gSaveContext.ship.pendingIceTrapCount++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -9513,7 +9513,7 @@ void func_80843AE8(PlayState* play, Player* this) {
|
||||
} else if (play->gameOverCtx.state == GAMEOVER_DEATH_WAIT_GROUND) {
|
||||
play->gameOverCtx.state = GAMEOVER_DEATH_DELAY_MENU;
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
|
||||
gSaveContext.maskMemory = PLAYER_MASK_NONE;
|
||||
gSaveContext.ship.maskMemory = PLAYER_MASK_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9818,7 +9818,7 @@ void Player_Action_Roll(Player* this, PlayState* play) {
|
||||
Player_PlayVoiceSfx(this, NA_SE_VO_LI_CLIMB_END);
|
||||
this->av2.bonked = 1;
|
||||
|
||||
gSaveContext.sohStats.count[COUNT_BONKS]++;
|
||||
gSaveContext.ship.stats.count[COUNT_BONKS]++;
|
||||
GameInteractor_ExecuteOnPlayerBonk();
|
||||
|
||||
return;
|
||||
@ -10806,9 +10806,9 @@ void Player_Init(Actor* thisx, PlayState* play2) {
|
||||
//keep masks thru loading zones
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
|
||||
if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_SOLD_OUT) {
|
||||
gSaveContext.maskMemory = PLAYER_MASK_NONE;
|
||||
gSaveContext.ship.maskMemory = PLAYER_MASK_NONE;
|
||||
}
|
||||
this->currentMask = gSaveContext.maskMemory;
|
||||
this->currentMask = gSaveContext.ship.maskMemory;
|
||||
}
|
||||
Player_InitCommon(this, play, gPlayerSkelHeaders[((void)0, gSaveContext.linkAge)]);
|
||||
// `giObjectSegment` is used for both "get item" objects and title cards. The maximum size for
|
||||
@ -14282,7 +14282,7 @@ s32 func_8084DFF4(PlayState* play, Player* this) {
|
||||
// #region SOH [Randomizer] TODO Better Ice trap handling?
|
||||
if (this->getItemEntry.itemId == RG_ICE_TRAP && this->getItemEntry.modIndex == MOD_RANDOMIZER) {
|
||||
this->unk_862 = 0;
|
||||
gSaveContext.pendingIceTrapCount++;
|
||||
gSaveContext.ship.pendingIceTrapCount++;
|
||||
Player_SetPendingFlag(this, play);
|
||||
}
|
||||
// #endregion
|
||||
@ -14460,7 +14460,7 @@ void Player_Action_8084E6D4(Player* this, PlayState* play) {
|
||||
this->actor.world.pos.y + 100.0f, this->actor.world.pos.z, 0, 0, 0, 0, true);
|
||||
func_8083C0E8(this, play);
|
||||
} else if (IS_RANDO) {
|
||||
gSaveContext.pendingIceTrapCount++;
|
||||
gSaveContext.ship.pendingIceTrapCount++;
|
||||
Player_SetPendingFlag(this, play);
|
||||
func_8083C0E8(this, play);
|
||||
} else {
|
||||
|
@ -989,7 +989,7 @@ void DrawSeedHashSprites(FileChooseContext* this) {
|
||||
this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_START_NAME_ENTRY ||
|
||||
this->configMode == CM_START_RANDOMIZER_SETTINGS_MENU) ||
|
||||
this->configMode == CM_RANDOMIZER_SETTINGS_MENU) &&
|
||||
gSaveContext.questId == QUEST_RANDOMIZER)) {
|
||||
gSaveContext.ship.quest.id == QUEST_RANDOMIZER)) {
|
||||
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
u16 xStart = 64;
|
||||
@ -1298,7 +1298,7 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
gSaveContext.questId = this->questType[this->buttonIndex];
|
||||
gSaveContext.ship.quest.id = this->questType[this->buttonIndex];
|
||||
|
||||
if (this->questType[this->buttonIndex] == QUEST_BOSSRUSH) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
@ -1393,17 +1393,17 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) {
|
||||
if (ABS(this->stickRelX) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
|
||||
if (this->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) {
|
||||
// If exceeding the amount of choices for the selected option, cycle back to the first.
|
||||
if ((gSaveContext.bossRushOptions[this->bossRushIndex] + 1) == BossRush_GetSettingOptionsAmount(this->bossRushIndex)) {
|
||||
gSaveContext.bossRushOptions[this->bossRushIndex] = 0;
|
||||
if ((gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] + 1) == BossRush_GetSettingOptionsAmount(this->bossRushIndex)) {
|
||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] = 0;
|
||||
} else {
|
||||
gSaveContext.bossRushOptions[this->bossRushIndex]++;
|
||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]++;
|
||||
}
|
||||
} else if (this->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) {
|
||||
// If cycling back when already at the first choice for the selected option, cycle back to the last choice.
|
||||
if ((gSaveContext.bossRushOptions[this->bossRushIndex] - 1) < 0) {
|
||||
gSaveContext.bossRushOptions[this->bossRushIndex] = BossRush_GetSettingOptionsAmount(this->bossRushIndex) - 1;
|
||||
if ((gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] - 1) < 0) {
|
||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] = BossRush_GetSettingOptionsAmount(this->bossRushIndex) - 1;
|
||||
} else {
|
||||
gSaveContext.bossRushOptions[this->bossRushIndex]--;
|
||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1411,10 +1411,10 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) {
|
||||
}
|
||||
|
||||
if (sLastBossRushOptionIndex != this->bossRushIndex ||
|
||||
sLastBossRushOptionValue != gSaveContext.bossRushOptions[this->bossRushIndex]) {
|
||||
GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(this->bossRushIndex, gSaveContext.bossRushOptions[this->bossRushIndex]);
|
||||
sLastBossRushOptionValue != gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]) {
|
||||
GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(this->bossRushIndex, gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]);
|
||||
sLastBossRushOptionIndex = this->bossRushIndex;
|
||||
sLastBossRushOptionValue = gSaveContext.bossRushOptions[this->bossRushIndex];
|
||||
sLastBossRushOptionValue = gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex];
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
@ -2408,7 +2408,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
||||
65, (87 + textYOffset), 255, 255, 80, textAlpha, 0.8f, true);
|
||||
|
||||
// Selected choice for option.
|
||||
uint16_t finalKerning = Interface_DrawTextLine(this->state.gfxCtx, BossRush_GetSettingChoiceName(i, gSaveContext.bossRushOptions[i], gSaveContext.language),
|
||||
uint16_t finalKerning = Interface_DrawTextLine(this->state.gfxCtx, BossRush_GetSettingChoiceName(i, gSaveContext.ship.quest.data.bossRush.options[i], gSaveContext.language),
|
||||
165, (87 + textYOffset), 255, 255, 255, textAlpha, 0.8f, true);
|
||||
|
||||
// Draw arrows around selected option.
|
||||
|
Loading…
Reference in New Issue
Block a user