From e4cfc8852d9e84fbfa29811896a0ea41c2cd21be Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:54:53 +0100 Subject: [PATCH 01/10] Add gRegEditEnabled (#3173) * Add gRegEditEnabled * Remove TCRF link --- soh/soh/SohMenuBar.cpp | 2 ++ soh/src/code/game.c | 2 +- soh/src/code/z_debug.c | 35 +++++++++++++++++++++++++++++------ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 018b05fe9a..0dd87bd82f 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1387,6 +1387,8 @@ void DrawDeveloperToolsMenu() { UIWidgets::EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled"); UIWidgets::Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen"); if (CVarGetInteger("gDebugEnabled", 0)) { + UIWidgets::EnhancementCheckbox("OoT Registry Editor", "gRegEditEnabled"); + UIWidgets::Tooltip("Enables the registry editor"); ImGui::Text("Debug Save File Mode:"); UIWidgets::EnhancementCombobox("gDebugSaveFileMode", DebugSaveFileModes, 1); UIWidgets::Tooltip( diff --git a/soh/src/code/game.c b/soh/src/code/game.c index 4167a5a961..b46aa4ebd8 100644 --- a/soh/src/code/game.c +++ b/soh/src/code/game.c @@ -93,7 +93,7 @@ void func_800C4344(GameState* gameState) { HREG(95) = CHECK_BTN_ALL(selectedInput->press.button, hReg82); } - if (gIsCtrlr2Valid) { + if (CVarGetInteger("gRegEditEnabled", 0) || gIsCtrlr2Valid) { func_8006390C(&gameState->input[1]); } diff --git a/soh/src/code/z_debug.c b/soh/src/code/z_debug.c index 8eb9de5a8c..267846eb42 100644 --- a/soh/src/code/z_debug.c +++ b/soh/src/code/z_debug.c @@ -24,12 +24,35 @@ Color_RGBA8 printTextColors[] = { }; InputCombo inputCombos[REG_GROUPS] = { - { BTN_L, BTN_CUP }, { BTN_L, BTN_CLEFT }, { BTN_L, BTN_CDOWN }, { BTN_L, BTN_A }, { BTN_R, BTN_CDOWN }, - { BTN_L, BTN_CRIGHT }, { BTN_L, BTN_R }, { BTN_L, BTN_DLEFT }, { BTN_L, BTN_DRIGHT }, { BTN_L, BTN_DUP }, - { BTN_L, BTN_B }, { BTN_L, BTN_Z }, { BTN_L, BTN_DDOWN }, { BTN_R, BTN_A }, { BTN_R, BTN_B }, - { BTN_R, BTN_Z }, { BTN_R, BTN_L }, { BTN_R, BTN_CUP }, { BTN_R, BTN_CRIGHT }, { BTN_R, BTN_DLEFT }, - { BTN_R, BTN_CLEFT }, { BTN_R, BTN_START }, { BTN_L, BTN_START }, { BTN_R, BTN_DRIGHT }, { BTN_R, BTN_DUP }, - { BTN_START, BTN_R }, { BTN_START, BTN_A }, { BTN_START, BTN_B }, { BTN_START, BTN_CRIGHT }, + { BTN_L, BTN_CUP }, //REG + { BTN_L, BTN_CLEFT }, //SREG + { BTN_L, BTN_CDOWN }, //OREG + { BTN_L, BTN_A }, //PREG + { BTN_R, BTN_CDOWN }, //QREG + { BTN_L, BTN_CRIGHT }, //MREG + { BTN_L, BTN_R }, //YREG + { BTN_L, BTN_DLEFT }, //DREG + { BTN_L, BTN_DRIGHT }, //UREG + { BTN_L, BTN_DUP }, //IREG + { BTN_L, BTN_B }, //ZREG + { BTN_L, BTN_Z }, //CREG + { BTN_L, BTN_DDOWN }, //NREG + { BTN_R, BTN_A }, //KREG + { BTN_R, BTN_B }, //XREG + { BTN_R, BTN_Z }, //cREG + { BTN_R, BTN_L }, //sREG + { BTN_R, BTN_CUP }, //iREG + { BTN_R, BTN_CRIGHT }, //WREG + { BTN_R, BTN_DLEFT }, //AREG + { BTN_R, BTN_CLEFT }, //VREG + { BTN_R, BTN_START }, //HREG + { BTN_L, BTN_START }, //GREG + { BTN_R, BTN_DRIGHT }, //mREG + { BTN_R, BTN_DUP }, //nREG + { BTN_START, BTN_R }, //BREG + { BTN_START, BTN_A }, //dREG + { BTN_START, BTN_B }, //kREG + { BTN_START, BTN_CRIGHT }, //bREG }; char regChar[] = " SOPQMYDUIZCNKXcsiWAVHGmnBdkb"; From dab070a8a138e3fb0b04dbd3ff81a7f4b7794d9b Mon Sep 17 00:00:00 2001 From: Andrew Van Caem Date: Tue, 31 Oct 2023 02:55:02 +1100 Subject: [PATCH 02/10] Added 'Fix enemies not spawning near water' checkbox to Fixes (#3179) --- soh/soh/Enhancements/presets.h | 3 +++ soh/soh/SohMenuBar.cpp | 3 +++ soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index ddbee3871f..b113c705a5 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -216,6 +216,7 @@ const std::vector enhancementsCvars = { "gBowReticle", "gFixTexturesOOB", "gIvanCoopModeEnabled", + "gEnemySpawnsOverWaterboxes", }; const std::vector cheatCvars = { @@ -523,6 +524,8 @@ const std::vector enhancedPresetEntries = { PRESET_ENTRY_S32("gNaviTextFix", 1), // Extend Silver Rupee Jingle PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), + // Fix enemies not spawning on ground over water + PRESET_ENTRY_S32("gEnemySpawnsOverWaterboxes", 1), // Red Ganon blood PRESET_ENTRY_S32("gRedGanonBlood", 1), diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 0dd87bd82f..2a52006a4d 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1042,6 +1042,9 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Fix Poacher's Saw Softlock", "gFixSawSoftlock", true, false, CVarGetInteger("gSkipText", 0), "This is disabled because it is forced on when Skip Text is enabled.", UIWidgets::CheckboxGraphics::Checkmark); UIWidgets::Tooltip("Prevents the Poacher's Saw softlock from mashing through the text, or with Skip Text enabled."); + UIWidgets::PaddedEnhancementCheckbox("Fix enemies not spawning near water", "gEnemySpawnsOverWaterboxes", true, false); + UIWidgets::Tooltip("Causes respawning enemies, like stalchildren, to appear on land near bodies of water. " + "Fixes an incorrect calculation that acted like water underneath ground was above it."); UIWidgets::PaddedEnhancementCheckbox("Fix Bush Item Drops", "gBushDropFix", true, false); UIWidgets::Tooltip("Fixes the bushes to drop items correctly rather than spawning undefined items."); diff --git a/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index 9cbd8b8cad..2d05c116cd 100644 --- a/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/soh/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -278,7 +278,7 @@ void EnEncount1_SpawnStalchildOrWolfos(EnEncount1* this, PlayState* play) { break; } if ((player->actor.yDistToWater != BGCHECK_Y_MIN) && - (floorY < (player->actor.world.pos.y - player->actor.yDistToWater))) { + (floorY < (player->actor.world.pos.y + player->actor.yDistToWater*(CVarGetInteger("gEnemySpawnsOverWaterboxes", 0) ? 1 : -1)))) { break; } spawnPos.y = floorY; From 671ce062d0eebeae7d02c126a82dd07dd7092c2a Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Mon, 30 Oct 2023 11:55:26 -0400 Subject: [PATCH 03/10] improve free camera reset (#3225) --- soh/src/code/z_camera.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 783731506e..a177e29e7b 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -2138,8 +2138,6 @@ s32 Camera_Parallel1(Camera* camera) { OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); - camera->play->manualCamera = false; - switch (camera->animState) { case 0: case 0xA: @@ -7888,6 +7886,15 @@ s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) { break; } } + + // Clear free camera if an action is performed that would move the camera (targeting, first person, talking) + if (CVarGetInteger("gFreeCamera", 0) && SetCameraManual(camera) == 1 && + ((mode >= CAM_MODE_TARGET && mode <= CAM_MODE_BATTLE) || + (mode >= CAM_MODE_FIRSTPERSON && mode <= CAM_MODE_CLIMBZ) || mode == CAM_MODE_HANGZ || + mode == CAM_MODE_FOLLOWBOOMERANG)) { + camera->play->manualCamera = false; + } + func_8005A02C(camera); camera->mode = mode; return 0x80000000 | mode; From a04ee354d4c786d9c6a568e8b6624997c55cbfea Mon Sep 17 00:00:00 2001 From: "Tina H. (sheepytina)" <99330992+sheepytina@users.noreply.github.com> Date: Tue, 31 Oct 2023 02:55:53 +1100 Subject: [PATCH 04/10] Add "Navi Targeting Colors" options to Controller LED Color (#3254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a (not yet functional) "Navi" option. * It works! * Slightly better name for this menu option. * Revert accidental commit of comments in z_en_elf.c * Renaming and tweaks. * Temporary fix(?) for compile error on non-Windows platforms. * … Just pretend this particular commit doesn't exist. :OHYEAH: * A more suitable fix. + Partial suggestions from review. In-progress implementation of Cosmetics Navi colours. * Convert relevant code to use Color_RGB8 sans alpha, matching the controller LED. Defaults are now labeled for clarity. * Revert back to Color_RGBA8. + Implement Cosmetics Navi colours. Add Color conversion functions. * Tidy comments. * Changed mind yet a third time. Uses Color_RGB8 sans alpha again. Uses CVarGetColor24 instead of CVarGetColor to drop alpha from cosmetics editor values, like how Tunic Colors does it. This of course does require me to go with the prior idea of storing the Navi colours without alpha channels. * Color type conversion functions removed as they're no longer needed. * Tidy up commented out code once more. * Fix a typo * Suggestion from code review. (Yeah nah you're totally right though.) * Correct indentation. * A minor goof in the comments was bothering me. --- soh/include/z64.h | 2 + .../controls/GameControlEditor.cpp | 5 +- soh/soh/OTRGlobals.cpp | 74 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/soh/include/z64.h b/soh/include/z64.h index 2172dcb74a..23ffcfb171 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -2245,6 +2245,8 @@ typedef enum { LED_SOURCE_TUNIC_ORIGINAL, LED_SOURCE_TUNIC_COSMETICS, LED_SOURCE_HEALTH, + LED_SOURCE_NAVI_ORIGINAL, + LED_SOURCE_NAVI_COSMETICS, LED_SOURCE_CUSTOM } LEDColorSource; diff --git a/soh/soh/Enhancements/controls/GameControlEditor.cpp b/soh/soh/Enhancements/controls/GameControlEditor.cpp index 3bd6506377..935935c480 100644 --- a/soh/soh/Enhancements/controls/GameControlEditor.cpp +++ b/soh/soh/Enhancements/controls/GameControlEditor.cpp @@ -331,13 +331,14 @@ namespace GameControlEditor { void DrawLEDControlPanel(GameControlEditorWindow* window) { window->BeginGroupPanelPublic("LED Colors", ImGui::GetContentRegionAvail()); - static const char* ledSources[4] = { "Original Tunic Colors", "Cosmetics Tunic Colors", "Health Colors", "Custom" }; + static const char* ledSources[] = { "Original Tunic Colors", "Cosmetics Tunic Colors", "Health Colors", + "Original Navi Targeting Colors", "Cosmetics Navi Targeting Colors", "Custom" }; UIWidgets::PaddedText("Source"); UIWidgets::EnhancementCombobox("gLedColorSource", ledSources, LED_SOURCE_TUNIC_ORIGINAL); DrawHelpIcon("Health\n- Red when health critical (13-20% depending on max health)\n- Yellow when health < 40%. Green otherwise.\n\n" \ "Tunics: colors will mirror currently equipped tunic, whether original or the current values in Cosmetics Editor.\n\n" \ "Custom: single, solid color"); - if (CVarGetInteger("gLedColorSource", 1) == 3) { + if (CVarGetInteger("gLedColorSource", 1) == LED_SOURCE_CUSTOM) { UIWidgets::Spacer(3); auto port1Color = CVarGetColor24("gLedPort1Color", { 255, 255, 255 }); ImVec4 colorVec = { port1Color.r / 255.0f, port1Color.g / 255.0f, port1Color.b / 255.0f, 1.0f }; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index eee6a622a9..553caef7e7 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -128,6 +128,34 @@ Color_RGB8 kokiriColor = { 0x1E, 0x69, 0x1B }; Color_RGB8 goronColor = { 0x64, 0x14, 0x00 }; Color_RGB8 zoraColor = { 0x00, 0xEC, 0x64 }; +// Same as NaviColor type from OoT src (z_actor.c), but modified to be sans alpha channel for Controller LED. +typedef struct { + Color_RGB8 inner; + Color_RGB8 outer; +} NaviColor_RGB8; + +static NaviColor_RGB8 defaultIdleColor = { { 255, 255, 255 }, { 0, 0, 255 } }; +static NaviColor_RGB8 defaultNPCColor = { { 150, 150, 255 }, { 150, 150, 255 } }; +static NaviColor_RGB8 defaultEnemyColor = { { 255, 255, 0 }, { 200, 155, 0 } }; +static NaviColor_RGB8 defaultPropsColor = { { 0, 255, 0 }, { 0, 255, 0 } }; + +// Labeled according to ActorCategory (included through ActorDB.h) +const NaviColor_RGB8 LEDColorDefaultNaviColorList[] = { + defaultPropsColor, // ACTORCAT_SWITCH Switch + defaultPropsColor, // ACTORCAT_BG Background (Prop type 1) + defaultIdleColor, // ACTORCAT_PLAYER Player + defaultPropsColor, // ACTORCAT_EXPLOSIVE Bomb + defaultNPCColor, // ACTORCAT_NPC NPC + defaultEnemyColor, // ACTORCAT_ENEMY Enemy + defaultPropsColor, // ACTORCAT_PROP Prop type 2 + defaultPropsColor, // ACTORCAT_ITEMACTION Item/Action + defaultPropsColor, // ACTORCAT_MISC Misc. + defaultEnemyColor, // ACTORCAT_BOSS Boss + defaultPropsColor, // ACTORCAT_DOOR Door + defaultPropsColor, // ACTORCAT_CHEST Chest + defaultPropsColor, // ACTORCAT_MAX +}; + // OTRTODO: A lot of these left in Japanese are used by the mempak manager. LUS does not currently support mempaks. Ignore unused ones. const char* constCameraStrings[] = { "INSUFFICIENT", @@ -1718,6 +1746,52 @@ Color_RGB8 GetColorForControllerLED() { break; } } + if (gPlayState && (source == LED_SOURCE_NAVI_ORIGINAL || source == LED_SOURCE_NAVI_COSMETICS)) { + Actor* arrowPointedActor = gPlayState->actorCtx.targetCtx.arrowPointedActor; + if (arrowPointedActor) { + ActorCategory category = (ActorCategory)arrowPointedActor->category; + switch (category) { + case ACTORCAT_PLAYER: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_IdlePrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_IdlePrimary.Value", defaultIdleColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + break; + case ACTORCAT_NPC: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_NPCPrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_NPCPrimary.Value", defaultNPCColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + break; + case ACTORCAT_ENEMY: + case ACTORCAT_BOSS: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_EnemyPrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_EnemyPrimary.Value", defaultEnemyColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + break; + default: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_PropsPrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_PropsPrimary.Value", defaultPropsColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + } + } else { // No target actor. + if (source == LED_SOURCE_NAVI_COSMETICS && CVarGetInteger("gCosmetics.Navi_IdlePrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_IdlePrimary.Value", defaultIdleColor.inner); + } else { + color = LEDColorDefaultNaviColorList[ACTORCAT_PLAYER].inner; + } + } + } if (source == LED_SOURCE_CUSTOM) { color = CVarGetColor24("gLedPort1Color", { 255, 255, 255 }); } From 5dd82f59e227da2ff2c6971a53212ebead4c9fb6 Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:56:36 +0000 Subject: [PATCH 05/10] Player Equip Docs (#3282) * hopefully everything * update docs for MS shuffle sections --- soh/include/z64item.h | 70 +++++++++++++- soh/soh/Enhancements/boss-rush/BossRush.cpp | 10 +- soh/soh/Enhancements/debugconsole.cpp | 6 +- .../Enhancements/debugger/debugSaveEditor.cpp | 30 +++--- .../game-interactor/GameInteractionEffect.cpp | 6 +- .../GameInteractor_RawAction.cpp | 14 +-- soh/soh/Enhancements/mods.cpp | 2 +- .../Enhancements/randomizer/randomizer.cpp | 20 ++-- soh/soh/OTRGlobals.cpp | 10 +- soh/soh/SaveManager.cpp | 8 +- soh/src/code/code_80097A00.c | 18 ++-- soh/src/code/z_demo.c | 4 +- soh/src/code/z_elf_message.c | 4 +- soh/src/code/z_message_PAL.c | 2 +- soh/src/code/z_parameter.c | 94 +++++++++++-------- soh/src/code/z_player_lib.c | 26 ++--- soh/src/code/z_sram.c | 9 +- .../actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c | 4 +- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 2 +- soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 2 +- .../overlays/actors/ovl_En_GirlA/z_en_girla.c | 11 ++- soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c | 4 +- soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 4 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 8 +- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 4 +- soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 3 +- soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c | 8 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 6 +- .../actors/ovl_player_actor/z_player.c | 32 +++---- .../ovl_file_choose/z_file_choose.c | 8 +- .../misc/ovl_kaleido_scope/z_kaleido_debug.c | 10 +- .../ovl_kaleido_scope/z_kaleido_equipment.c | 28 +++--- .../ovl_kaleido_scope/z_kaleido_scope_PAL.c | 4 +- 33 files changed, 275 insertions(+), 196 deletions(-) diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 2f0038872f..1fc919a45f 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -2,12 +2,74 @@ #define Z64ITEM_H typedef enum { - /* 0x00 */ EQUIP_SWORD, - /* 0x01 */ EQUIP_SHIELD, - /* 0x02 */ EQUIP_TUNIC, - /* 0x03 */ EQUIP_BOOTS + /* 0 */ EQUIP_TYPE_SWORD, + /* 1 */ EQUIP_TYPE_SHIELD, + /* 2 */ EQUIP_TYPE_TUNIC, + /* 3 */ EQUIP_TYPE_BOOTS, + /* 4 */ EQUIP_TYPE_MAX } EquipmentType; +// `EquipInv*` enums are for Inventory.equipment (for example used in the `CHECK_OWNED_EQUIP` macro) + +typedef enum { + /* 0 */ EQUIP_INV_SWORD_KOKIRI, + /* 1 */ EQUIP_INV_SWORD_MASTER, + /* 2 */ EQUIP_INV_SWORD_BIGGORON, + /* 3 */ EQUIP_INV_SWORD_BROKENGIANTKNIFE +} EquipInvSword; + +typedef enum { + /* 0 */ EQUIP_INV_SHIELD_DEKU, + /* 1 */ EQUIP_INV_SHIELD_HYLIAN, + /* 2 */ EQUIP_INV_SHIELD_MIRROR +} EquipInvShield; + +typedef enum { + /* 0 */ EQUIP_INV_TUNIC_KOKIRI, + /* 1 */ EQUIP_INV_TUNIC_GORON, + /* 2 */ EQUIP_INV_TUNIC_ZORA +} EquipInvTunic; + +typedef enum { + /* 0 */ EQUIP_INV_BOOTS_KOKIRI, + /* 1 */ EQUIP_INV_BOOTS_IRON, + /* 2 */ EQUIP_INV_BOOTS_HOVER +} EquipInvBoots; + +// `EquipValue*` enums are for ItemEquips.equipment (for example used in the `CUR_EQUIP_VALUE` macro) + +typedef enum { + /* 0 */ EQUIP_VALUE_SWORD_NONE, + /* 1 */ EQUIP_VALUE_SWORD_KOKIRI, + /* 2 */ EQUIP_VALUE_SWORD_MASTER, + /* 3 */ EQUIP_VALUE_SWORD_BIGGORON, + /* 4 */ EQUIP_VALUE_SWORD_MAX +} EquipValueSword; + +typedef enum { + /* 0 */ EQUIP_VALUE_SHIELD_NONE, + /* 1 */ EQUIP_VALUE_SHIELD_DEKU, + /* 2 */ EQUIP_VALUE_SHIELD_HYLIAN, + /* 3 */ EQUIP_VALUE_SHIELD_MIRROR, + /* 4 */ EQUIP_VALUE_SHIELD_MAX +} EquipValueShield; + +typedef enum { + /* 0 */ EQUIP_VALUE_TUNIC_NONE, + /* 1 */ EQUIP_VALUE_TUNIC_KOKIRI, + /* 2 */ EQUIP_VALUE_TUNIC_GORON, + /* 3 */ EQUIP_VALUE_TUNIC_ZORA, + /* 4 */ EQUIP_VALUE_TUNIC_MAX +} EquipValueTunic; + +typedef enum { + /* 0 */ EQUIP_VALUE_BOOTS_NONE, + /* 1 */ EQUIP_VALUE_BOOTS_KOKIRI, + /* 2 */ EQUIP_VALUE_BOOTS_IRON, + /* 3 */ EQUIP_VALUE_BOOTS_HOVER, + /* 4 */ EQUIP_VALUE_BOOTS_MAX +} EquipValueBoots; + typedef enum { /* 0x00 */ UPG_QUIVER, /* 0x01 */ UPG_BOMB_BAG, diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index d35b8825ea..9c5311922e 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -462,8 +462,8 @@ void BossRush_SetEquipment(uint8_t linkAge) { brCButtonSlots = { SLOT_STICK, SLOT_NUT, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI); - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_DEKU); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); // Set Adult equipment. } else { brButtonItems = { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_HAMMER, ITEM_BOMB, @@ -471,9 +471,9 @@ void BossRush_SetEquipment(uint8_t linkAge) { brCButtonSlots = { SLOT_BOW, SLOT_HAMMER, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_MASTER); - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_MIRROR); - Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_GORON + 1); // Game expects tunic + 1, don't ask me why. + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); } // Button Items diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index c94d5f8063..3e61505b28 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -1102,9 +1102,9 @@ static bool SpeedModifierHandler(std::shared_ptr Console, const st } const static std::map boots { - { "kokiri", PLAYER_BOOTS_KOKIRI }, - { "iron", PLAYER_BOOTS_IRON }, - { "hover", PLAYER_BOOTS_HOVER }, + { "kokiri", EQUIP_VALUE_BOOTS_KOKIRI }, + { "iron", EQUIP_VALUE_BOOTS_IRON }, + { "hover", EQUIP_VALUE_BOOTS_HOVER }, }; static bool BootsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index cb16a99151..9af4eadb7e 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1602,17 +1602,17 @@ void DrawPlayerTab() { if (ImGui::Selectable("None")) { player->currentSwordItemId = ITEM_NONE; gSaveContext.equips.buttonItems[0] = ITEM_NONE; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_NONE); } if (ImGui::Selectable("Kokiri Sword")) { player->currentSwordItemId = ITEM_SWORD_KOKIRI; gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); } if (ImGui::Selectable("Master Sword")) { player->currentSwordItemId = ITEM_SWORD_MASTER; gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_MASTER); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); } if (ImGui::Selectable("Biggoron's Sword")) { if (gSaveContext.bgsFlag) { @@ -1629,12 +1629,12 @@ void DrawPlayerTab() { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE; } - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_BIGGORON); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_BIGGORON); } if (ImGui::Selectable("Fishing Pole")) { player->currentSwordItemId = ITEM_FISHING_POLE; gSaveContext.equips.buttonItems[0] = ITEM_FISHING_POLE; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_MASTER); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); } ImGui::EndCombo(); @@ -1642,19 +1642,19 @@ void DrawPlayerTab() { if (ImGui::BeginCombo("Shield", curShield)) { if (ImGui::Selectable("None")) { player->currentShield = PLAYER_SHIELD_NONE; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_NONE); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_NONE); } if (ImGui::Selectable("Deku Shield")) { player->currentShield = PLAYER_SHIELD_DEKU; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_DEKU); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); } if (ImGui::Selectable("Hylian Shield")) { player->currentShield = PLAYER_SHIELD_HYLIAN; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_HYLIAN); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HYLIAN); } if (ImGui::Selectable("Mirror Shield")) { player->currentShield = PLAYER_SHIELD_MIRROR; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_MIRROR); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); } ImGui::EndCombo(); } @@ -1662,15 +1662,15 @@ void DrawPlayerTab() { if (ImGui::BeginCombo("Tunic", curTunic)) { if (ImGui::Selectable("Kokiri Tunic")) { player->currentTunic = PLAYER_TUNIC_KOKIRI; - Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_KOKIRI + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); } if (ImGui::Selectable("Goron Tunic")) { player->currentTunic = PLAYER_TUNIC_GORON; - Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_GORON + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); } if (ImGui::Selectable("Zora Tunic")) { player->currentTunic = PLAYER_TUNIC_ZORA; - Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_ZORA + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_ZORA); } ImGui::EndCombo(); } @@ -1678,15 +1678,15 @@ void DrawPlayerTab() { if (ImGui::BeginCombo("Boots", curBoots)) { if (ImGui::Selectable("Kokiri Boots")) { player->currentBoots = PLAYER_BOOTS_KOKIRI; - Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_KOKIRI + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); } if (ImGui::Selectable("Iron Boots")) { player->currentBoots = PLAYER_BOOTS_IRON; - Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_IRON + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_IRON); } if (ImGui::Selectable("Hover Boots")) { player->currentBoots = PLAYER_BOOTS_HOVER; - Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_HOVER + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_HOVER); } ImGui::EndCombo(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 8a8120e703..206b264262 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -373,7 +373,7 @@ namespace GameInteractionEffect { GameInteractor::RawAction::ForceEquipBoots(parameters[0]); } void ForceEquipBoots::_Remove() { - GameInteractor::RawAction::ForceEquipBoots(PLAYER_BOOTS_KOKIRI); + GameInteractor::RawAction::ForceEquipBoots(EQUIP_VALUE_BOOTS_KOKIRI); } // MARK: - ModifyRunSpeedModifier @@ -425,9 +425,9 @@ namespace GameInteractionEffect { GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) & + } else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & gSaveContext.inventory.equipment)) || - (parameters[0] < 0 && !((gBitFlags[(parameters[0] * -1) - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) & + (parameters[0] < 0 && !((gBitFlags[(parameters[0] * -1) - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & gSaveContext.inventory.equipment))) { return GameInteractionEffectQueryResult::NotPossible; } else { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index 1dedc3fa10..54a3b8e7bd 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -97,8 +97,8 @@ void GameInteractor::RawAction::SetWeatherStorm(bool active) { void GameInteractor::RawAction::ForceEquipBoots(int8_t boots) { Player* player = GET_PLAYER(gPlayState); - player->currentBoots = boots; - Inventory_ChangeEquipment(EQUIP_BOOTS, boots + 1); + player->currentBoots = BOOTS_EQUIP_TO_PLAYER(boots); + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, boots); Player_SetBootData(gPlayState, player); } @@ -274,24 +274,24 @@ void GameInteractor::RawAction::GiveOrTakeShield(int32_t shield) { break; } - gSaveContext.inventory.equipment &= ~(gBitFlags[shield - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]); + gSaveContext.inventory.equipment &= ~(gBitFlags[shield - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]); if (player->currentShield == shieldToCheck) { player->currentShield = PLAYER_SHIELD_NONE; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_NONE); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_NONE); } } else { Item_Give(gPlayState, shield); if (player->currentShield == PLAYER_SHIELD_NONE) { if (LINK_IS_CHILD && shield == ITEM_SHIELD_DEKU) { player->currentShield = PLAYER_SHIELD_DEKU; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_DEKU); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); } else if (LINK_IS_ADULT && shield == ITEM_SHIELD_MIRROR) { player->currentShield = PLAYER_SHIELD_MIRROR; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_MIRROR); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); } else if (shield == ITEM_SHIELD_HYLIAN) { player->currentShield = PLAYER_SHIELD_HYLIAN; - Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_HYLIAN); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HYLIAN); } } } diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 2cab1a754a..fa4b654708 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -236,7 +236,7 @@ void RegisterOcarinaTimeTravel() { Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f); Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f); Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f); - uint8_t hasMasterSword = (gBitFlags[ITEM_SWORD_MASTER - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]) & gSaveContext.inventory.equipment; + uint8_t hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); // If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range // TODO: Once Swordless Adult is fixed: Remove the Master Sword check diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 1a46b03907..a1f11bc103 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1637,29 +1637,29 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe // Equipment case RG_KOKIRI_SWORD: - return !CHECK_OWNED_EQUIP(EQUIP_SWORD, 0) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_MASTER_SWORD: - return !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_BIGGORON_SWORD: return !gSaveContext.bgsFlag ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_DEKU_SHIELD: case RG_BUY_DEKU_SHIELD: - return !CHECK_OWNED_EQUIP(EQUIP_SHIELD, 0) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_DEKU) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_HYLIAN_SHIELD: case RG_BUY_HYLIAN_SHIELD: - return !CHECK_OWNED_EQUIP(EQUIP_SHIELD, 1) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_HYLIAN) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_MIRROR_SHIELD: - return !CHECK_OWNED_EQUIP(EQUIP_SHIELD, 2) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_MIRROR) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_GORON_TUNIC: case RG_BUY_GORON_TUNIC: - return !CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_ZORA_TUNIC: case RG_BUY_ZORA_TUNIC: - return !CHECK_OWNED_EQUIP(EQUIP_TUNIC, 2) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_IRON_BOOTS: - return !CHECK_OWNED_EQUIP(EQUIP_BOOTS, 1) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_HOVER_BOOTS: - return !CHECK_OWNED_EQUIP(EQUIP_BOOTS, 2) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_HOVER) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; // Inventory Items case RG_PROGRESSIVE_STICK_UPGRADE: @@ -5311,7 +5311,7 @@ CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) { //If MS shuffle is on, Sheik will hint both MS and LA as long as Link doesn't have both, to prevent hint lockout. //Otherwise, she'll only give LA hint so only LA is required to move on. bool needRequirements = GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) ? - (!CHECK_OWNED_EQUIP(EQUIP_SWORD, 1) || INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) : + (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) || INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) : (INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT); if (needRequirements) { messageEntry.Replace("{{message}}", gSaveContext.sheikText, gSaveContext.sheikText, gSaveContext.sheikText); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 553caef7e7..7262a56e17 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1728,18 +1728,18 @@ Color_RGB8 GetColorForControllerLED() { LEDColorSource source = static_cast(CVarGetInteger("gLedColorSource", LED_SOURCE_TUNIC_ORIGINAL)); bool criticalOverride = CVarGetInteger("gLedCriticalOverride", 1); if (gPlayState && (source == LED_SOURCE_TUNIC_ORIGINAL || source == LED_SOURCE_TUNIC_COSMETICS)) { - switch (CUR_EQUIP_VALUE(EQUIP_TUNIC) - 1) { - case PLAYER_TUNIC_KOKIRI: + switch (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC)) { + case EQUIP_VALUE_TUNIC_KOKIRI: color = source == LED_SOURCE_TUNIC_COSMETICS ? CVarGetColor24("gCosmetics.Link_KokiriTunic.Value", kokiriColor) : kokiriColor; break; - case PLAYER_TUNIC_GORON: + case EQUIP_VALUE_TUNIC_GORON: color = source == LED_SOURCE_TUNIC_COSMETICS ? CVarGetColor24("gCosmetics.Link_GoronTunic.Value", goronColor) : goronColor; break; - case PLAYER_TUNIC_ZORA: + case EQUIP_VALUE_TUNIC_ZORA: color = source == LED_SOURCE_TUNIC_COSMETICS ? CVarGetColor24("gCosmetics.Link_ZoraTunic.Value", zoraColor) : zoraColor; @@ -2117,7 +2117,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { ? CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_ADULT) : CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_CHILD); } else if (textId == TEXT_GANONDORF) { - if ((INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) || + if ((INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) || !Randomizer_GetSettingValue(RSK_LIGHT_ARROWS_HINT)) { messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF_NOHINT); } else { diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index bf1144b458..235a7bd5f7 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -716,11 +716,11 @@ void SaveManager::InitFileDebug() { if (LINK_AGE_IN_YEARS == YEARS_CHILD) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, 1); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); if (gSaveContext.fileNum == 0xFF) { gSaveContext.equips.buttonItems[1] = ITEM_SLINGSHOT; gSaveContext.equips.cButtonSlots[0] = SLOT_SLINGSHOT; - Inventory_ChangeEquipment(EQUIP_SHIELD, 1); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); } } @@ -859,11 +859,11 @@ void SaveManager::InitFileMaxed() { if (LINK_AGE_IN_YEARS == YEARS_CHILD) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, 1); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); if (gSaveContext.fileNum == 0xFF) { gSaveContext.equips.buttonItems[1] = ITEM_SLINGSHOT; gSaveContext.equips.cButtonSlots[0] = SLOT_SLINGSHOT; - Inventory_ChangeEquipment(EQUIP_SHIELD, 1); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); } } diff --git a/soh/src/code/code_80097A00.c b/soh/src/code/code_80097A00.c index e2c8a61ef0..9e20d66aad 100644 --- a/soh/src/code/code_80097A00.c +++ b/soh/src/code/code_80097A00.c @@ -191,22 +191,22 @@ void Inventory_ChangeEquipment(s16 equipment, u16 value) { u8 Inventory_DeleteEquipment(PlayState* play, s16 equipment) { Player* player = GET_PLAYER(play); s32 pad; - u16 sp26 = gSaveContext.equips.equipment & gEquipMasks[equipment]; + u16 equipValue = gSaveContext.equips.equipment & gEquipMasks[equipment]; // "Erasing equipment item = %d zzz=%d" - osSyncPrintf("装備アイテム抹消 = %d zzz=%d\n", equipment, sp26); + osSyncPrintf("装備アイテム抹消 = %d zzz=%d\n", equipment, equipValue); - if (sp26) { - sp26 >>= gEquipShifts[equipment]; + if (equipValue) { + equipValue >>= gEquipShifts[equipment]; gSaveContext.equips.equipment &= gEquipNegMasks[equipment]; - gSaveContext.inventory.equipment ^= gBitFlags[sp26 - 1] << gEquipShifts[equipment]; + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG(equipment, equipValue - 1); - if (equipment == EQUIP_TUNIC) { - gSaveContext.equips.equipment |= 0x0100; + if (equipment == EQUIP_TYPE_TUNIC) { + gSaveContext.equips.equipment |= EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4); } - if (equipment == EQUIP_SWORD) { + if (equipment == EQUIP_TYPE_SWORD) { gSaveContext.equips.buttonItems[0] = ITEM_NONE; gSaveContext.infTable[29] = 1; } @@ -215,7 +215,7 @@ u8 Inventory_DeleteEquipment(PlayState* play, s16 equipment) { play->pauseCtx.cursorSpecialPos = PAUSE_CURSOR_PAGE_LEFT; } - return sp26; + return equipValue; } void Inventory_ChangeUpgrade(s16 upgrade, s16 value) { diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index e0b17fe720..1955a92355 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -994,9 +994,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.nextTransitionType = 2; break; case 71: - gSaveContext.equips.equipment |= 0x0100; + gSaveContext.equips.equipment |= EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4); Player_SetEquipmentData(play, player); - gSaveContext.equips.equipment |= 0x1000; + gSaveContext.equips.equipment |= EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4); Player_SetEquipmentData(play, player); play->linkAgeOnLoad = 1; play->nextEntranceIndex = 0x0053; diff --git a/soh/src/code/z_elf_message.c b/soh/src/code/z_elf_message.c index 6c5558fafd..e586c1bcce 100644 --- a/soh/src/code/z_elf_message.c +++ b/soh/src/code/z_elf_message.c @@ -46,8 +46,8 @@ u32 ElfMessage_CheckCondition(ElfMessage* msg) { return ((msg->byte0 & 1) == 1) == ((msg->byte1 & 0x0F) == CUR_UPG_VALUE(UPG_STRENGTH)); case (ELF_MSG_CONDITION_BOOTS << 4): return ((msg->byte0 & 1) == 1) == - (((gBitFlags[msg->byte3 - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]) & - gSaveContext.inventory.equipment) != 0); + (CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, + msg->byte3 - ITEM_BOOTS_KOKIRI + EQUIP_INV_BOOTS_KOKIRI) != 0); case (ELF_MSG_CONDITION_SONG << 4): return ((msg->byte0 & 1) == 1) == (CHECK_QUEST_ITEM(msg->byte3 - ITEM_SONG_MINUET + QUEST_SONG_MINUET) != 0); diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 78eac4ece4..da0f5f55fe 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -1617,7 +1617,7 @@ void Message_OpenText(PlayState* play, u16 textId) { // Increments text id based on piece of heart count, assumes the piece of heart text is all // in order and that you don't have more than the intended amount of heart pieces. textId += (gSaveContext.inventory.questItems & 0xF0000000 & 0xF0000000) >> 0x1C; - } else if (!IS_RANDO && (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_SWORD, 2))) { + } else if (!IS_RANDO && (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON))) { textId = 0xB; // Traded Giant's Knife for Biggoron Sword } else if (!IS_RANDO && (msgCtx->textId == 0xB4 && (Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_CURSED_MAN_IN_SKULL_HOUSE)))) { textId = 0xB5; // Destroyed Gold Skulltula diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index cf3192c3d6..ec25d20625 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1438,7 +1438,7 @@ Gfx* Gfx_TextureI8(Gfx* displayListHead, void* texture, s16 textureWidth, s16 te void Inventory_SwapAgeEquipment(void) { s16 i; - u16 temp; + u16 shieldEquipValue; if (LINK_AGE_IN_YEARS == YEARS_CHILD) { @@ -1483,8 +1483,15 @@ void Inventory_SwapAgeEquipment(void) { gSaveContext.equips.cButtonSlots[1] = SLOT_BOMB; gSaveContext.equips.cButtonSlots[2] = SLOT_OCARINA; - gSaveContext.equips.equipment = (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && - gSaveContext.equips.buttonItems[0] == ITEM_NONE) ? 0x1120 :0x1122; + gSaveContext.equips.equipment = (EQUIP_VALUE_SWORD_MASTER << (EQUIP_TYPE_SWORD * 4)) | + (EQUIP_VALUE_SHIELD_HYLIAN << (EQUIP_TYPE_SHIELD * 4)) | + (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) | + (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4)); + + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && + gSaveContext.equips.buttonItems[0] == ITEM_NONE) { + gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4)); + } // Set the dpad to nothing gSaveContext.equips.buttonItems[4] = ITEM_NONE; @@ -1518,13 +1525,13 @@ void Inventory_SwapAgeEquipment(void) { } else { // When becoming child, set swordless flag if player doesn't have kokiri sword // Only in rando to keep swordless link bugs in vanilla - if (IS_RANDO && (1 << 0 & gSaveContext.inventory.equipment) == 0) { + if (IS_RANDO && (EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment) == 0) { Flags_SetInfTable(INFTABLE_SWORDLESS); } // When using enhancements, set swordless flag if player doesn't have kokiri sword or hasn't equipped a sword yet. // Then set the child equips button items to item none to ensure kokiri sword is not equipped - if ((CVarGetInteger("gSwitchAge", 0) || CVarGetInteger("gSwitchTimeline", 0)) && ((1 << 0 & gSaveContext.inventory.equipment) == 0 || Flags_GetInfTable(INFTABLE_SWORDLESS))) { + if ((CVarGetInteger("gSwitchAge", 0) || CVarGetInteger("gSwitchTimeline", 0)) && ((EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment) == 0 || Flags_GetInfTable(INFTABLE_SWORDLESS))) { Flags_SetInfTable(INFTABLE_SWORDLESS); gSaveContext.childEquips.buttonItems[0] = ITEM_NONE; } @@ -1558,10 +1565,10 @@ void Inventory_SwapAgeEquipment(void) { } gSaveContext.equips.equipment = gSaveContext.childEquips.equipment; - gSaveContext.equips.equipment &= 0xFFF0; + gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4)); // Equips kokiri sword in the inventory screen only if kokiri sword exists in inventory and a sword has been equipped already - if (!((1 << 0 & gSaveContext.inventory.equipment) == 0) && !Flags_GetInfTable(INFTABLE_SWORDLESS)) { - gSaveContext.equips.equipment |= 0x0001; + if (!((EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment) == 0) && !Flags_GetInfTable(INFTABLE_SWORDLESS)) { + gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4); } } else if (gSaveContext.childEquips.buttonItems[0] != ITEM_NONE) { for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) { @@ -1582,15 +1589,15 @@ void Inventory_SwapAgeEquipment(void) { } gSaveContext.equips.equipment = gSaveContext.childEquips.equipment; - gSaveContext.equips.equipment &= 0xFFF0; - gSaveContext.equips.equipment |= 0x0001; + gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4)); + gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4); } else if (IS_RANDO && Randomizer_GetSettingValue(RSK_STARTING_AGE) == RO_AGE_ADULT) { /*If in rando and starting age is adult, childEquips is not initialized and buttonItems[0] will be ITEM_NONE. When changing age from adult -> child, reset equips to "default" (only kokiri tunic/boots equipped, no sword, no C-button items, no D-Pad items). When becoming child, set swordless flag if player doesn't have kokiri sword Only in rando to keep swordless link bugs in vanilla*/ - if (1 << 0 & gSaveContext.inventory.equipment == 0) { + if (EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment == 0) { Flags_SetInfTable(INFTABLE_SWORDLESS); } @@ -1601,7 +1608,10 @@ void Inventory_SwapAgeEquipment(void) { gSaveContext.equips.cButtonSlots[i-1] = ITEM_NONE; } } - gSaveContext.equips.equipment = 0x1111; + gSaveContext.equips.equipment = (EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4)) | + (EQUIP_VALUE_SHIELD_DEKU << (EQUIP_TYPE_SHIELD * 4)) | + (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) | + (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4)); } if ((CVarGetInteger("gSwitchAge", 0) || CVarGetInteger("gSwitchTimeline", 0)) && @@ -1609,17 +1619,18 @@ void Inventory_SwapAgeEquipment(void) { Flags_SetInfTable(INFTABLE_SWORDLESS); if (gSaveContext.childEquips.equipment == 0) { // force equip kokiri tunic and boots in scenario gSaveContext.childEquips.equipment is uninitialized - gSaveContext.equips.equipment &= 0xFFF0; - gSaveContext.equips.equipment |= 0x1100; + gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4)); + gSaveContext.equips.equipment |= (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) | + (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4)); } } } CVarSetInteger("gSwitchTimeline", 0); - temp = gEquipMasks[EQUIP_SHIELD] & gSaveContext.equips.equipment; - if (temp != 0) { - temp >>= gEquipShifts[EQUIP_SHIELD]; - if (!(gBitFlags[temp + 3] & gSaveContext.inventory.equipment)) { - gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_SHIELD]; + shieldEquipValue = gEquipMasks[EQUIP_TYPE_SHIELD] & gSaveContext.equips.equipment; + if (shieldEquipValue != 0) { + shieldEquipValue >>= gEquipShifts[EQUIP_TYPE_SHIELD]; + if (!CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, shieldEquipValue - 1)) { + gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_TYPE_SHIELD]; } } } @@ -1634,10 +1645,10 @@ void Interface_InitHorsebackArchery(PlayState* play) { } void func_800849EC(PlayState* play) { - gSaveContext.inventory.equipment |= gBitFlags[2] << gEquipShifts[EQUIP_SWORD]; - gSaveContext.inventory.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON); + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); - if (gBitFlags[3] & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE; } else { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; @@ -1882,17 +1893,21 @@ u8 Item_Give(PlayState* play, u8 item) { return Return_Item(item, MOD_NONE, ITEM_NONE); } else if ((item >= ITEM_SWORD_KOKIRI) && (item <= ITEM_SWORD_BGS)) { - gSaveContext.inventory.equipment |= gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SWORD, item - ITEM_SWORD_KOKIRI + EQUIP_INV_SWORD_KOKIRI); // Both Giant's Knife and Biggoron Sword have the same Item ID, so this part handles both of them if (item == ITEM_SWORD_BGS) { gSaveContext.swordHealth = 8; // In rando, when buying Giant's Knife, also check - // for 0xE in case we don't have Kokiri Sword - if (ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xF || (IS_RANDO && ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xE)) { + // without the Koriri Sword in case we don't have it + if (ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) == + ((1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) | + (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE)) || + (IS_RANDO && ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) == + ((1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE)))) { - gSaveContext.inventory.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; @@ -1904,8 +1919,8 @@ u8 Item_Give(PlayState* play, u8 item) { } else if (item == ITEM_SWORD_MASTER) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - gSaveContext.equips.equipment &= 0xFFF0; - gSaveContext.equips.equipment |= 0x0002; + gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4)); + gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_MASTER << (EQUIP_TYPE_SWORD * 4); if (play != NULL) { Interface_LoadItemIcon1(play, 0); } @@ -1913,13 +1928,13 @@ u8 Item_Give(PlayState* play, u8 item) { return Return_Item(item, MOD_NONE, ITEM_NONE); } else if ((item >= ITEM_SHIELD_DEKU) && (item <= ITEM_SHIELD_MIRROR)) { - gSaveContext.inventory.equipment |= (gBitFlags[item - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]); + gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SHIELD, item - ITEM_SHIELD_DEKU); return Return_Item(item, MOD_NONE, ITEM_NONE); } else if ((item >= ITEM_TUNIC_KOKIRI) && (item <= ITEM_TUNIC_ZORA)) { - gSaveContext.inventory.equipment |= (gBitFlags[item - ITEM_TUNIC_KOKIRI] << gEquipShifts[EQUIP_TUNIC]); + gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_TUNIC, item - ITEM_TUNIC_KOKIRI); return Return_Item(item, MOD_NONE, ITEM_NONE); } else if ((item >= ITEM_BOOTS_KOKIRI) && (item <= ITEM_BOOTS_HOVER)) { - gSaveContext.inventory.equipment |= (gBitFlags[item - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]); + gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_BOOTS, item - ITEM_BOOTS_KOKIRI); return Return_Item(item, MOD_NONE, ITEM_NONE); } else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) { gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; @@ -2610,8 +2625,8 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { } if (item == RG_MASTER_SWORD) { - if (!CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { - gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_SWORD]; + if (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { + gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_TYPE_SWORD]; } return Return_Item_Entry(giEntry, RG_NONE); } @@ -2651,26 +2666,25 @@ u8 Item_CheckObtainability(u8 item) { } else if ((item >= ITEM_SWORD_KOKIRI) && (item <= ITEM_SWORD_BGS)) { if (item == ITEM_SWORD_BGS) { return ITEM_NONE; - } else if ((gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]) & - gSaveContext.inventory.equipment) { + } else if (CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, item - ITEM_SWORD_KOKIRI + EQUIP_INV_SWORD_KOKIRI)) { return IS_RANDO ? ITEM_NONE : item; } else { return ITEM_NONE; } } else if ((item >= ITEM_SHIELD_DEKU) && (item <= ITEM_SHIELD_MIRROR)) { - if ((gBitFlags[item - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, item - ITEM_SHIELD_DEKU + EQUIP_INV_SHIELD_DEKU)) { return IS_RANDO ? ITEM_NONE : item; } else { return ITEM_NONE; } } else if ((item >= ITEM_TUNIC_KOKIRI) && (item <= ITEM_TUNIC_ZORA)) { - if ((gBitFlags[item - ITEM_TUNIC_KOKIRI] << gEquipShifts[EQUIP_TUNIC]) & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, item - ITEM_TUNIC_KOKIRI + EQUIP_INV_TUNIC_KOKIRI)) { return IS_RANDO ? ITEM_NONE : item; } else { return ITEM_NONE; } } else if ((item >= ITEM_BOOTS_KOKIRI) && (item <= ITEM_BOOTS_HOVER)) { - if ((gBitFlags[item - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]) & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, item - ITEM_BOOTS_KOKIRI + EQUIP_INV_BOOTS_KOKIRI)) { return IS_RANDO ? ITEM_NONE : item; } else { return ITEM_NONE; @@ -6489,11 +6503,11 @@ void Interface_Update(PlayState* play) { D_80125A58 = Player_GetEnvironmentalHazard(play); if (D_80125A58 == 1) { - if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == 2 || CVarGetInteger("gSuperTunic", 0) != 0) { + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == EQUIP_VALUE_TUNIC_GORON || CVarGetInteger("gSuperTunic", 0) != 0) { D_80125A58 = 0; } } else if ((Player_GetEnvironmentalHazard(play) >= 2) && (Player_GetEnvironmentalHazard(play) < 5)) { - if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == 3 || CVarGetInteger("gSuperTunic", 0) != 0) { + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == EQUIP_VALUE_TUNIC_ZORA || CVarGetInteger("gSuperTunic", 0) != 0) { D_80125A58 = 0; } } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index f4b71fc0ae..820f2c6726 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -669,9 +669,9 @@ void func_8008EC70(Player* this) { void Player_SetEquipmentData(PlayState* play, Player* this) { if (this->csMode != 0x56) { - this->currentShield = CUR_EQUIP_VALUE(EQUIP_SHIELD); - this->currentTunic = CUR_EQUIP_VALUE(EQUIP_TUNIC) - 1; - this->currentBoots = CUR_EQUIP_VALUE(EQUIP_BOOTS) - 1; + this->currentShield = SHIELD_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD)); + this->currentTunic = TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC)); + this->currentBoots = BOOTS_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS)); this->currentSwordItemId = B_BTN_ITEM; Player_SetModelGroup(this, Player_ActionToModelGroup(this, this->heldItemAction)); Player_SetBootData(play, this); @@ -2117,11 +2117,11 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* if (CVarGetInteger("gPauseLiveLink", 0) || CVarGetInteger("gPauseTriforce", 0)) { uintptr_t anim = 0; // Initialise anim - if (CUR_EQUIP_VALUE(EQUIP_SWORD) >= 3) { + if (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) >= EQUIP_VALUE_SWORD_BIGGORON) { EquipedStance = 1; - } else if (CUR_EQUIP_VALUE(EQUIP_SHIELD) == 0) { + } else if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SWORD_NONE) { EquipedStance = 2; - } else if (CUR_EQUIP_VALUE(EQUIP_SHIELD) == 2 && LINK_AGE_IN_YEARS == YEARS_CHILD) { + } else if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SWORD_MASTER && LINK_AGE_IN_YEARS == YEARS_CHILD) { EquipedStance = 3; } else { // Link is idle so revert to 0 @@ -2192,8 +2192,8 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* if (FrameCountSinceLastAnim >= SwitchAtFrame) { LastAnim = SelectedAnim; if (LastAnim==1) { - if ((CUR_EQUIP_VALUE(EQUIP_SWORD)!=PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)!= PLAYER_SHIELD_NONE)) { // if the player has a sword and shield equipped - if ((LINK_AGE_IN_YEARS == YEARS_ADULT) || (CUR_EQUIP_VALUE(EQUIP_SHIELD) == PLAYER_SHIELD_DEKU)) { // if he's an adult or a kid with the deku shield + if ((CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) != EQUIP_VALUE_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_NONE)) { // if the player has a sword and shield equipped + if ((LINK_AGE_IN_YEARS == YEARS_ADULT) || (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU)) { // if he's an adult or a kid with the deku shield SelectedAnim = (rand() % (6 - 2 + 1)) + 2; // select any 5 animations that aren't the default standing anim } else { //else if he's a child with a shield that isn't the deku shield s16 randval = (rand() % (5 - 2 + 1)) + 2; // 4 animations @@ -2203,15 +2203,15 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* SelectedAnim=randval; } } - } else if ((CUR_EQUIP_VALUE(EQUIP_SWORD) != PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)==PLAYER_SHIELD_NONE)) { // if the player has a sword equipped but no shield + } else if ((CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) != EQUIP_VALUE_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_NONE)) { // if the player has a sword equipped but no shield s16 randval = (rand() % (5 - 2 + 1)) + 2; // 4 animations if (randval==4) { //if its the shield anim SelectedAnim==6; // set to yawn anim } else { SelectedAnim=randval; } - } else if ((CUR_EQUIP_VALUE(EQUIP_SWORD) == PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)!=PLAYER_SHIELD_NONE)) { //if the player has a shield equipped but no sword - if ((LINK_AGE_IN_YEARS == YEARS_ADULT) || (CUR_EQUIP_VALUE(EQUIP_SHIELD) == PLAYER_SHIELD_DEKU)) {// if he's an adult or a kid with the deku shield + } else if ((CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_NONE)) { //if the player has a shield equipped but no sword + if ((LINK_AGE_IN_YEARS == YEARS_ADULT) || (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU)) {// if he's an adult or a kid with the deku shield s16 randval = (rand() % (5 - 2 + 1)) + 2; // 4 animations if (randval==5) { //if its the sword anim SelectedAnim==6; // set to yawn anim @@ -2226,7 +2226,7 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* SelectedAnim=randval; } } - } else if ((CUR_EQUIP_VALUE(EQUIP_SWORD) == PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)==PLAYER_SHIELD_NONE)) { // if the player has no sword or shield equipped + } else if ((CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_NONE)) { // if the player has no sword or shield equipped s16 randval = (rand() % (4 - 2 + 1)) + 2; // 3 animations if (randval==4) { //if its the shield anim SelectedAnim==6; // set to yawn anim @@ -2297,7 +2297,7 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* srcTable = gLinkPauseChildJointTable; } } else { - if (sword == 3) { + if (sword == PLAYER_SWORD_BIGGORON) { srcTable = gLinkPauseAdultBgsJointTable; } else if (shield != PLAYER_SHIELD_NONE) { srcTable = gLinkPauseAdultShieldJointTable; diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 225b29dc78..057460b625 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -168,13 +168,12 @@ void Sram_OpenSave() { } } - // check for owning kokiri sword.. to restore master sword? bug or debug feature? - if (LINK_AGE_IN_YEARS == YEARS_ADULT && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + if (LINK_AGE_IN_YEARS == YEARS_ADULT && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { - gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - gSaveContext.equips.equipment &= ~0xF; - gSaveContext.equips.equipment |= 2; + gSaveContext.equips.equipment &= ~(0xF << (EQUIP_TYPE_SWORD * 4)); + gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_MASTER << (EQUIP_TYPE_SWORD * 4); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index b4e62d0702..26a02aa96e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -91,7 +91,7 @@ void BgTokiSwd_Init(Actor* thisx, PlayState* play) { Player* player = GET_PLAYER(gPlayState); player->currentSwordItemId = ITEM_NONE; gSaveContext.equips.buttonItems[0] = ITEM_NONE; - Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_NONE); } } @@ -187,7 +187,7 @@ void BgTokiSwd_Draw(Actor* thisx, PlayState* play2) { s32 pad[3]; // Do not draw the Master Sword in the pedestal if the player has not found it yet - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index ea506ffbd5..cb00dbee83 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -179,7 +179,7 @@ void BossGanon2_Init(Actor* thisx, PlayState* play) { this->actor.gravity = 0.0f; hasFoundMasterSword = 1; - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { hasFoundMasterSword = 0; } } diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 85d47753a3..0dd33a8ac9 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -273,7 +273,7 @@ u32 func_809EF73C(EnDns* this) { } u32 func_809EF800(EnDns* this) { - if (gBitFlags[4] & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_DEKU)) { return 1; } if (gSaveContext.rupees < this->dnsItemEntry->itemPrice) { diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index bb9ee05c29..037b4b5943 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -565,7 +565,8 @@ s32 EnGirlA_CanBuy_BluePotion(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_Longsword(PlayState* play, EnGirlA* this) { - if ((gBitFlags[2] & gSaveContext.inventory.equipment) && !(gBitFlags[3] & gSaveContext.inventory.equipment)) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) && + !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { return CANBUY_RESULT_CANT_GET_NOW; } if (gSaveContext.rupees < this->basePrice) { @@ -578,7 +579,7 @@ s32 EnGirlA_CanBuy_Longsword(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_HylianShield(PlayState* play, EnGirlA* this) { - if (gBitFlags[5] & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_HYLIAN)) { return CANBUY_RESULT_CANT_GET_NOW; } if (gSaveContext.rupees < this->basePrice) { @@ -591,7 +592,7 @@ s32 EnGirlA_CanBuy_HylianShield(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_DekuShield(PlayState* play, EnGirlA* this) { - if (gBitFlags[4] & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_DEKU)) { return CANBUY_RESULT_CANT_GET_NOW; } if (gSaveContext.rupees < this->basePrice) { @@ -608,7 +609,7 @@ s32 EnGirlA_CanBuy_GoronTunic(PlayState* play, EnGirlA* this) { (!IS_RANDO || Randomizer_GetSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF)) { return CANBUY_RESULT_CANT_GET_NOW; } - if (gBitFlags[9] & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return CANBUY_RESULT_CANT_GET_NOW; } if (gSaveContext.rupees < this->basePrice) { @@ -625,7 +626,7 @@ s32 EnGirlA_CanBuy_ZoraTunic(PlayState* play, EnGirlA* this) { (!IS_RANDO || Randomizer_GetSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF)) { return CANBUY_RESULT_CANT_GET_NOW; } - if (gBitFlags[10] & gSaveContext.inventory.equipment) { + if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)) { return CANBUY_RESULT_CANT_GET_NOW; } if (gSaveContext.rupees < this->basePrice) { diff --git a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c index f461e781c9..4986f24f63 100644 --- a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -99,9 +99,9 @@ s32 func_80A3D7C8(void) { } else if ((IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF) && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) { return 1; - } else if (!(gBitFlags[2] & gSaveContext.inventory.equipment)) { // Don't have giant's knife + } else if (!CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)) { // Don't have giant's knife return 1; - } else if (gBitFlags[3] & gSaveContext.inventory.equipment) { // Have broken giant's knife + } else if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { // Have broken giant's knife return 2; } else { return 3; diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index ea9b135611..3094f21717 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -120,7 +120,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } else { return 0x3041; } - } else if (CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1) || (Flags_GetInfTable(INFTABLE_10D))) { + } else if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON) || (Flags_GetInfTable(INFTABLE_10D))) { if (Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK)) { return 0x3038; } else { @@ -651,7 +651,7 @@ void EnGo_Init(Actor* thisx, PlayState* play) { switch (this->actor.params & 0xF0) { case 0x00: Actor_SetScale(&this->actor, 0.008f); - if (CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) { + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo_SetMovedPos(this, play); EnGo_SetupAction(this, EnGo_CurledUp); } else { diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 87745131e5..a4aede2e5a 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -527,7 +527,7 @@ u16 EnGo2_GetTextIdGoronCityLink(PlayState* play, EnGo2* this) { if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { return Flags_GetInfTable(INFTABLE_10F) ? 0x3042 : 0x3041; - } else if (CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) { + } else if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return Flags_GetInfTable(INFTABLE_SPOKE_TO_GORON_LINK) ? 0x3038 : 0x3037; } else if (Flags_GetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING)) { this->unk_20C = 0; @@ -1221,7 +1221,7 @@ s32 EnGo2_IsCameraModified(EnGo2* this, PlayState* play) { return true; } else if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && - CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) { + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return true; } else { return false; @@ -1280,7 +1280,7 @@ void EnGo2_SelectGoronWakingUp(EnGo2* this) { case GORON_CITY_LINK: if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && - CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) { + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo2_WakingUp(this); break; } @@ -1642,7 +1642,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { this->actor.home.pos = this->actor.world.pos; if (((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) || (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE))) && - CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) { + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo2_GetItemAnimation(this, play); } else { this->actionFunc = EnGo2_CurledUp; diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 75b7479f33..ad3bd0ab50 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -95,7 +95,7 @@ u16 EnKz_GetTextNoMaskAdult(PlayState* play, EnKz* this) { if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_FROG) { if (!Flags_GetInfTable(INFTABLE_139)) { if (!IS_RANDO) { - return CHECK_OWNED_EQUIP(EQUIP_TUNIC, 2) ? 0x401F : 0x4012; + return CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? 0x401F : 0x4012; } else { return 0x4012; } @@ -272,7 +272,7 @@ void func_80A9CB18(EnKz* this, PlayState* play) { player->actor.textId = this->actor.textId; } else { if (!IS_RANDO) { - this->actor.textId = CHECK_OWNED_EQUIP(EQUIP_TUNIC, 2) ? 0x401F : 0x4012; + this->actor.textId = CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) ? 0x401F : 0x4012; } else { this->actor.textId = 0x4012; } diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index d757a5a020..14d9cbb7be 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -384,7 +384,8 @@ u16 EnMd_GetTextKokiriForest(PlayState* play, EnMd* this) { return 0x1034; } - if ((CUR_EQUIP_VALUE(EQUIP_SHIELD) == 1) && (CUR_EQUIP_VALUE(EQUIP_SWORD) == 1)) { + if ((CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) && + (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI)) { return 0x1033; } diff --git a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c index 49207d6436..a3265d724e 100644 --- a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -298,15 +298,15 @@ void EnRr_SetupReleasePlayer(EnRr* this, PlayState* play) { this->wobbleSizeTarget = 2048.0f; tunic = 0; shield = 0; - if (CUR_EQUIP_VALUE(EQUIP_SHIELD) != 3 /* Mirror shield */) { - shield = Inventory_DeleteEquipment(play, EQUIP_SHIELD); + if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { + shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); if (shield != 0) { this->eatenShield = shield; this->retreat = true; } } - if (CUR_EQUIP_VALUE(EQUIP_TUNIC) != 1 /* Kokiri tunic */ && !IS_RANDO /* Randomizer Save File */) { - tunic = Inventory_DeleteEquipment(play, EQUIP_TUNIC); + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { + tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); if (tunic != 0) { this->eatenTunic = tunic; this->retreat = true; diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index c72a82df69..83f7998776 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -376,7 +376,7 @@ void EnXc_SetupSerenadeAction(EnXc* this, PlayState* play) { } // Player is adult and does not have iron boots and has not learned Serenade - if ((!CHECK_OWNED_EQUIP(EQUIP_BOOTS, 1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT) { + if ((!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT) { this->action = SHEIK_ACTION_SERENADE; osSyncPrintf("水のセレナーデ シーク誕生!!!!!!!!!!!!!!!!!!\n"); } else { @@ -390,7 +390,7 @@ s32 EnXc_SerenadeCS(EnXc* this, PlayState* play) { Player* player = GET_PLAYER(play); s32 stateFlags = player->stateFlags1; - if (((CHECK_OWNED_EQUIP(EQUIP_BOOTS, 1) && !IS_RANDO) || + if (((CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !IS_RANDO) || (Flags_GetTreasure(play, 2) && IS_RANDO)) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !(stateFlags & 0x20000000) && !Play_InCsMode(play)) { @@ -2247,7 +2247,7 @@ void EnXc_SetupDialogueAction(EnXc* this, PlayState* play) { this->actor.textId = TEXT_SHEIK_HAVE_HOOK; } } else if (IS_RANDO && gPlayState->sceneNum == SCENE_INSIDE_GANONS_CASTLE) { - if (CHECK_OWNED_EQUIP(EQUIP_SWORD, 1) && INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && CUR_CAPACITY(UPG_QUIVER) >= 30 && gSaveContext.isMagicAcquired) { this->actor.textId = TEXT_SHEIK_HAVE_HOOK; } else { diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index b575a0084b..556b8ccd55 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -3857,7 +3857,7 @@ void func_8083819C(Player* this, PlayState* play) { if (this->currentShield == PLAYER_SHIELD_DEKU && (CVarGetInteger("gFireproofDekuShield", 0) == 0)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_SHIELD, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 1, true); - Inventory_DeleteEquipment(play, EQUIP_SHIELD); + Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); Message_StartTextbox(play, 0x305F, NULL); } } @@ -10591,20 +10591,20 @@ void Player_UseTunicBoots(Player* this, PlayState* play) { actionParam = Player_ItemToItemAction(item); if (actionParam >= PLAYER_IA_BOOTS_KOKIRI) { u16 bootsValue = actionParam - PLAYER_IA_BOOTS_KOKIRI + 1; - if (CUR_EQUIP_VALUE(EQUIP_BOOTS) == bootsValue) { - Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_KOKIRI + 1); + if (CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == bootsValue) { + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); } else { - Inventory_ChangeEquipment(EQUIP_BOOTS, bootsValue); + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue); } Player_SetEquipmentData(play, this); - func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_BOOTS) == PLAYER_BOOTS_IRON + 1 ? NA_SE_PL_WALK_HEAVYBOOTS + func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS); } else if (actionParam >= PLAYER_IA_TUNIC_KOKIRI) { u16 tunicValue = actionParam - PLAYER_IA_TUNIC_KOKIRI + 1; - if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == tunicValue) { - Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_KOKIRI + 1); + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) { + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); } else { - Inventory_ChangeEquipment(EQUIP_TUNIC, tunicValue); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, tunicValue); } Player_SetEquipmentData(play, this); func_808328EC(this, NA_SE_PL_CHANGE_ARMS); @@ -11254,7 +11254,7 @@ void Player_Draw(Actor* thisx, PlayState* play2) { pos.y = -130.0f; pos.z = -150.0f; scale = 0.046f; - } else if (CUR_EQUIP_VALUE(EQUIP_SWORD) != 2) { + } else if (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) != EQUIP_VALUE_SWORD_MASTER) { pos.x = 25.0f; pos.y = -228.0f; pos.z = 60.0f; @@ -12774,16 +12774,16 @@ s32 func_8084DFF4(PlayState* play, Player* this) { if (equipItem >= ITEM_SWORD_KOKIRI && equipItem <= ITEM_SWORD_BGS) { gSaveContext.equips.buttonItems[0] = equipItem; - Inventory_ChangeEquipment(EQUIP_SWORD, equipItem - ITEM_SWORD_KOKIRI + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, equipItem - ITEM_SWORD_KOKIRI + 1); func_808328EC(this, NA_SE_IT_SWORD_PUTAWAY); } else if (equipItem >= ITEM_SHIELD_DEKU && equipItem <= ITEM_SHIELD_MIRROR) { - Inventory_ChangeEquipment(EQUIP_SHIELD, equipItem - ITEM_SHIELD_DEKU + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, equipItem - ITEM_SHIELD_DEKU + 1); func_808328EC(&this->actor, NA_SE_IT_SHIELD_REMOVE); Player_SetEquipmentData(play, this); } else if (equipItem == ITEM_TUNIC_GORON || equipItem == ITEM_TUNIC_ZORA) { - Inventory_ChangeEquipment(EQUIP_TUNIC, equipItem - ITEM_TUNIC_KOKIRI + 1); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, equipItem - ITEM_TUNIC_KOKIRI + 1); func_808328EC(this, NA_SE_PL_CHANGE_ARMS); Player_SetEquipmentData(play, this); } @@ -14949,16 +14949,16 @@ void func_80852648(PlayState* play, Player* this, CsCmdActorAction* arg2) { // If MS sword is shuffled and not in the players inventory, then we need to unequip the current sword // and set swordless flag to mimic Link having his weapon knocked out of his hand in the Ganon fight - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { - Inventory_ChangeEquipment(EQUIP_SWORD, 0); + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_NONE); gSaveContext.equips.buttonItems[0] = ITEM_NONE; Flags_SetInfTable(INFTABLE_SWORDLESS); return; } - Inventory_ChangeEquipment(EQUIP_SWORD, 2); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - Inventory_DeleteEquipment(play, 0); + Inventory_DeleteEquipment(play, EQUIP_TYPE_SWORD); } } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index dac121a0e1..5de6df23dc 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -2939,7 +2939,7 @@ void FileChoose_FadeOut(GameState* thisx) { */ void FileChoose_LoadGame(GameState* thisx) { FileChooseContext* this = (FileChooseContext*)thisx; - u16 swordEquipMask; + u16 swordEquipValue; s32 pad; Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -3026,9 +3026,9 @@ void FileChoose_LoadGame(GameState* thisx) { (gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KNIFE)) { gSaveContext.equips.buttonItems[0] = ITEM_NONE; - swordEquipMask = BOMSWAP16(gEquipMasks[EQUIP_SWORD]) & gSaveContext.equips.equipment; - gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_SWORD]; - gSaveContext.inventory.equipment ^= (gBitFlags[swordEquipMask - 1] << BOMSWAP16(gEquipShifts[EQUIP_SWORD])); + swordEquipValue = (BOMSWAP16(gEquipMasks[EQUIP_TYPE_SWORD]) & gSaveContext.equips.equipment) >> (EQUIP_TYPE_SWORD * 4); + gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_TYPE_SWORD]; + gSaveContext.inventory.equipment ^= (gBitFlags[swordEquipValue - 1] << BOMSWAP16(gEquipShifts[EQUIP_TYPE_SWORD])); } } diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c index 5b55f41449..3aa4a25d67 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c @@ -576,18 +576,18 @@ void KaleidoScope_DrawDebugEditor(PlayState* play) { } } } else { - i = curSection - 0x34; + i = curSection - 0x34; // 0 <= i < 4 if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) { - gSaveContext.inventory.equipment ^= (1 << gEquipShifts[i]); + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(i, 0); } if (CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) { - gSaveContext.inventory.equipment ^= (2 << gEquipShifts[i]); + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(i, 1); } if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) { - gSaveContext.inventory.equipment ^= (4 << gEquipShifts[i]); + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(i, 2); } if (CHECK_BTN_ALL(input->press.button, BTN_CUP)) { - gSaveContext.inventory.equipment ^= (8 << gEquipShifts[i]); + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(i, 3); } } } else if (curSection < 0x44) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c index 23c531f15e..d255f40d24 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c @@ -108,7 +108,7 @@ void KaleidoScope_DrawPlayerWork(PlayState* play) { pos.y = -130.0f; pos.z = -150.0f; scale = 0.046f; - } else if (CUR_EQUIP_VALUE(EQUIP_SWORD) != 2 && !CVarGetInteger("gPauseTriforce", 0)) { + } else if (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) != EQUIP_VALUE_SWORD_MASTER && !CVarGetInteger("gPauseTriforce", 0)) { pos.x = 25.0f; pos.y = -228.0f; pos.z = 60.0f; @@ -153,8 +153,10 @@ void KaleidoScope_DrawPlayerWork(PlayState* play) { extern int fbTest; gsSPSetFB(play->state.gfxCtx->polyOpa.p++, fbTest); Player_DrawPause(play, pauseCtx->playerSegment, &pauseCtx->playerSkelAnime, &pos, &link_kaleido_rot, scale, - CUR_EQUIP_VALUE(EQUIP_SWORD), CUR_EQUIP_VALUE(EQUIP_TUNIC) - 1, CUR_EQUIP_VALUE(EQUIP_SHIELD), - CUR_EQUIP_VALUE(EQUIP_BOOTS) - 1); + SWORD_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD)), + TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC)), + SHIELD_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD)), + BOOTS_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS))); gsSPResetFB(play->state.gfxCtx->polyOpa.p++); } @@ -464,7 +466,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { if ((pauseCtx->cursorY[PAUSE_EQUIP] == 0) && (pauseCtx->cursorX[PAUSE_EQUIP] == 3)) { if (gSaveContext.bgsFlag != 0) { cursorItem = ITEM_HEART_PIECE_2; - } else if (gBitFlags[3] & gSaveContext.inventory.equipment) { + } else if (CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { cursorItem = ITEM_SWORD_KNIFE; } } @@ -523,28 +525,28 @@ void KaleidoScope_DrawEquipment(PlayState* play) { // If we're on the "swords" section of the equipment screen AND we're on a currently-equipped BGS/Giant's Knife if (pauseCtx->cursorY[PAUSE_EQUIP] == 0 && pauseCtx->cursorX[PAUSE_EQUIP] == 3 - && CUR_EQUIP_VALUE(EQUIP_SWORD) == 3 && CHECK_OWNED_EQUIP(0,1)){ // And we have the Master Sword - Inventory_ChangeEquipment(EQUIP_SWORD, 2); // "Unequip" it by equipping Master Sword + && CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_BIGGORON && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)){ // And we have the Master Sword + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); // "Unequip" it by equipping Master Sword gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; gSaveContext.infTable[29] = 0; goto RESUME_EQUIPMENT_SWORD; // Skip to here so we don't re-equip it } // If we're on the "shields" section of the equipment screen AND we're on a currently-equipped shield - if (pauseCtx->cursorY[PAUSE_EQUIP] == 1 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_SHIELD)) { - Inventory_ChangeEquipment(EQUIP_SHIELD, 0); // Unequip it + if (pauseCtx->cursorY[PAUSE_EQUIP] == 1 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD)) { + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_NONE); // Unequip it goto RESUME_EQUIPMENT; // Skip to here so we don't re-equip it } // If we're on the "tunics" section of the equipment screen AND we're on a currently-equipped tunic - if (pauseCtx->cursorY[PAUSE_EQUIP] == 2 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_TUNIC)) { - Inventory_ChangeEquipment(EQUIP_TUNIC, 1); // "Unequip" it (by equipping Kokiri Tunic) + if (pauseCtx->cursorY[PAUSE_EQUIP] == 2 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC)) { + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); // "Unequip" it (by equipping Kokiri Tunic) goto RESUME_EQUIPMENT; // Skip to here so we don't re-equip it } // If we're on the "boots" section of the equipment screen AND we're on currently-equipped boots - if (pauseCtx->cursorY[PAUSE_EQUIP] == 3 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_BOOTS)) { - Inventory_ChangeEquipment(EQUIP_BOOTS, 1); // "Unequip" it (by equipping Kokiri Boots) + if (pauseCtx->cursorY[PAUSE_EQUIP] == 3 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS)) { + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); // "Unequip" it (by equipping Kokiri Boots) goto RESUME_EQUIPMENT; // Skip to here so we don't re-equip it } } @@ -568,7 +570,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; } if ((gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS) && (gSaveContext.bgsFlag == 0) && - (gBitFlags[3] & gSaveContext.inventory.equipment)) { + CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE; } } diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 95c8f77406..87c4a99f56 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -3551,7 +3551,7 @@ void KaleidoScope_Update(PlayState* play) pauseCtx->worldMapPoints[3] = 1; } - if (CHECK_OWNED_EQUIP(EQUIP_BOOTS, 1)) { + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON)) { pauseCtx->worldMapPoints[3] = 2; } @@ -3705,7 +3705,7 @@ void KaleidoScope_Update(PlayState* play) pauseCtx->worldMapPoints[11] = 2; } - if (CHECK_OWNED_EQUIP(EQUIP_BOOTS, 1)) { + if (CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON)) { pauseCtx->worldMapPoints[11] = 1; } From 2810996475fc304edda86b3fb411b6e7f6e59f13 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:57:36 +0000 Subject: [PATCH 06/10] Fix Entrance hubs having no HintKey, causing hints to No Item (#3295) * Fix Entrance hubs having no HintKey, causing hints to No Item * Add castle grounds hint area to cover the OGC/HC to market entrence --- soh/soh/Enhancements/randomizer/3drando/hint_list.cpp | 5 +++++ .../3drando/location_access/locacc_castle_town.cpp | 4 ++-- .../3drando/location_access/locacc_death_mountain.cpp | 4 ++-- .../3drando/location_access/locacc_gerudo_valley.cpp | 4 ++-- .../3drando/location_access/locacc_hyrule_field.cpp | 2 +- .../randomizer/3drando/location_access/locacc_kakariko.cpp | 2 +- .../randomizer/3drando/location_access/locacc_lost_woods.cpp | 2 +- .../3drando/location_access/locacc_zoras_domain.cpp | 4 ++-- 8 files changed, 16 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index d9d94da200..a50de65022 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -1046,6 +1046,11 @@ void HintTable_Init() { Text{ "Temple of Time", /*french*/ "le Temple du Temps", /*spanish*/ "el Templo del Tiempo" }, }); + hintTable[CASTLE_GROUNDS] = HintText::Exclude({ + // obscure text + Text{ "the Castle Grounds", /*french*/ "le Château d'Hyrule", /*spanish*/ "" }, + }); + hintTable[HYRULE_CASTLE] = HintText::Exclude({ // obscure text Text{ "Hyrule Castle", /*french*/ "le Château d'Hyrule", /*spanish*/ "el Castillo de Hyrule" }, diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index d98096314f..24fdc8ccbe 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -71,7 +71,7 @@ void AreaTable_Init_CastleTown() { Entrance(TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[CASTLE_GROUNDS] = Area("Castle Grounds", "Castle Grounds", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[CASTLE_GROUNDS] = Area("Castle Grounds", "Castle Grounds", CASTLE_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(THE_MARKET, {[]{return true;}}), Entrance(HYRULE_CASTLE_GROUNDS, {[]{return IsChild;}}), @@ -157,7 +157,7 @@ void AreaTable_Init_CastleTown() { Entrance(GANONS_CASTLE_LEDGE, { [] { return IsAdult; }}), }); - areaTable[GANONS_CASTLE_LEDGE] = Area("Ganon's Castle Ledge", "OGC Ganon's Castle Ledge", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[GANONS_CASTLE_LEDGE] = Area("Ganon's Castle Ledge", "OGC Ganon's Castle Ledge", OUTSIDE_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits Entrance(GANONS_CASTLE_GROUNDS, {[]{return BuiltRainbowBridge;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp index bf1d061489..8988b045bd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp @@ -46,7 +46,7 @@ void AreaTable_Init_DeathMountain() { Entrance(DMT_GREAT_FAIRY_FOUNTAIN, {[]{return Here(DEATH_MOUNTAIN_SUMMIT, []{return CanBlastOrSmash;});}}), }); - areaTable[DMT_OWL_FLIGHT] = Area("DMT Owl Flight", "Death Mountain", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[DMT_OWL_FLIGHT] = Area("DMT Owl Flight", "Death Mountain", DEATH_MOUNTAIN_TRAIL, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(KAK_IMPAS_ROOFTOP, {[]{return true;}}), }); @@ -108,7 +108,7 @@ void AreaTable_Init_DeathMountain() { Entrance(GC_GROTTO_PLATFORM, {[]{return IsAdult && ((CanPlay(SongOfTime) && ((EffectiveHealth > 2) || CanUse(GORON_TUNIC) || CanUse(LONGSHOT) || CanUse(NAYRUS_LOVE))) || (EffectiveHealth > 1 && CanUse(GORON_TUNIC) && CanUse(HOOKSHOT)) || (CanUse(NAYRUS_LOVE) && CanUse(HOOKSHOT)) || (EffectiveHealth > 2 && CanUse(HOOKSHOT) && LogicGoronCityGrotto));}}), }); - areaTable[GC_WOODS_WARP] = Area("GC Woods Warp", "Goron City", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[GC_WOODS_WARP] = Area("GC Woods Warp", "Goron City", GORON_CITY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&GCWoodsWarpOpen, {[]{return GCWoodsWarpOpen || (CanBlastOrSmash || CanUse(DINS_FIRE));}}), }, {}, { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index f7b1c95afd..f11a74f3cf 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp @@ -119,7 +119,7 @@ void AreaTable_Init_GerudoValley() { Entrance(GF_STORMS_GROTTO, {[]{return IsAdult && CanOpenStormGrotto;}}), }); - areaTable[GF_OUTSIDE_GATE] = Area("GF Outside Gate", "Gerudo Fortress", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[GF_OUTSIDE_GATE] = Area("GF Outside Gate", "Gerudo Fortress", GERUDO_FORTRESS, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&GF_GateOpen, {[]{return IsAdult && GerudoToken && (ShuffleGerudoToken || ShuffleOverworldEntrances /*|| ShuffleSpecialIndoorEntrances*/);}}), }, {}, { @@ -157,7 +157,7 @@ void AreaTable_Init_GerudoValley() { Entrance(WASTELAND_NEAR_FORTRESS, {[]{return CanUse(HOVER_BOOTS) || CanUse(LONGSHOT) || LogicWastelandCrossing;}}), }); - areaTable[WASTELAND_NEAR_COLOSSUS] = Area("Wasteland Near Colossus", "Haunted Wasteland", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[WASTELAND_NEAR_COLOSSUS] = Area("Wasteland Near Colossus", "Haunted Wasteland", HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(DESERT_COLOSSUS, {[]{return true;}}), Entrance(HAUNTED_WASTELAND, {[]{return LogicReverseWasteland || false;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 50a0c340ea..5b3e34a4bd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp @@ -138,7 +138,7 @@ void AreaTable_Init_HyruleField() { Entrance(LH_FISHING_HOLE, {[]{return true;}}), }); - areaTable[LH_OWL_FLIGHT] = Area("LH Owl Flight", "Lake Hylia", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[LH_OWL_FLIGHT] = Area("LH Owl Flight", "Lake Hylia", LAKE_HYLIA, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(HYRULE_FIELD, {[]{return true;}}), }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp index 55af162085..5660104f7b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -278,7 +278,7 @@ void AreaTable_Init_Kakariko() { Entrance(SHADOW_TEMPLE_ENTRYWAY, {[]{return CanUse(DINS_FIRE) || (LogicShadowFireArrowEntry && IsAdult && CanUse(FIRE_ARROWS));}}), }); - areaTable[KAK_BEHIND_GATE] = Area("Kak Behind Gate", "Kakariko Village", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[KAK_BEHIND_GATE] = Area("Kak Behind Gate", "Kakariko Village", KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(KAKARIKO_VILLAGE, {[]{return IsAdult || LogicVisibleCollision || KakarikoVillageGateOpen || OpenKakariko.Is(OPENKAKARIKO_OPEN);}}), Entrance(DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp index c16468d24a..27d3cecbe0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp @@ -105,7 +105,7 @@ void AreaTable_Init_LostWoods() { Entrance(KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[LW_FOREST_EXIT] = Area("LW Forest Exit", "Lost Woods", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[LW_FOREST_EXIT] = Area("LW Forest Exit", "Lost Woods", THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(KOKIRI_FOREST, {[]{return true;}}) }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp index d9c91b876b..434095145f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp @@ -48,7 +48,7 @@ void AreaTable_Init_ZorasDomain() { Entrance(ZR_BEHIND_WATERFALL, {[]{return CanPlay(ZeldasLullaby) || (IsChild && LogicZoraWithCucco) || (IsAdult && CanUse(HOVER_BOOTS) && LogicZoraWithHovers);}}), }); - areaTable[ZR_BEHIND_WATERFALL] = Area("ZR Behind Waterfall", "Zora River", NONE, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[ZR_BEHIND_WATERFALL] = Area("ZR Behind Waterfall", "Zora River", ZORAS_RIVER, DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(ZORAS_RIVER, {[]{return true;}}), Entrance(ZORAS_DOMAIN, {[]{return true;}}), @@ -106,7 +106,7 @@ void AreaTable_Init_ZorasDomain() { Entrance(ZD_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), }); - areaTable[ZD_BEHIND_KING_ZORA] = Area("ZD Behind King Zora", "Zoras Domain", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[ZD_BEHIND_KING_ZORA] = Area("ZD Behind King Zora", "Zoras Domain", ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(ZORAS_DOMAIN, {[]{return DeliverLetter || ZorasFountain.Is(ZORASFOUNTAIN_OPEN) || (ZorasFountain.Is(ZORASFOUNTAIN_ADULT) && IsAdult);}}), Entrance(ZORAS_FOUNTAIN, {[]{return true;}}), From ff7fa7742707574fc19dd8d930367d09f2c61424 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 30 Oct 2023 12:00:24 -0400 Subject: [PATCH 07/10] Addresses Forest Temple Poes and NPC Dialogue issues. (#3334) --- soh/soh/Enhancements/mods.cpp | 15 +++++++++++---- .../overlays/actors/ovl_En_Wallmas/z_en_wallmas.c | 6 +++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index fa4b654708..c0bbb3806d 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -387,11 +387,18 @@ void RegisterShadowTag() { if (!CVarGetInteger("gShadowTag", 0)) { return; } - if (shouldSpawn && (delayTimer <= 0)) { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WALLMAS, 0, 0, 0, 0, 0, 0, 3, false); - shouldSpawn = false; + if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && // Forest Temple Scene + gPlayState->roomCtx.curRoom.num == 16 || // Green Poe Room + gPlayState->roomCtx.curRoom.num == 13 || // Blue Poe Room + gPlayState->roomCtx.curRoom.num == 12) { // Red Poe Room + return; } else { - delayTimer--; + if (shouldSpawn && (delayTimer <= 0)) { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WALLMAS, 0, 0, 0, 0, 0, 0, 3, false); + shouldSpawn = false; + } else { + delayTimer--; + } } }); GameInteractor::Instance->RegisterGameHook([]() { diff --git a/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index 9991f20ebc..69c33f5f58 100644 --- a/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -328,7 +328,11 @@ void EnWallmas_WaitToDrop(EnWallmas* this, PlayState* play) { } if (this->timer == 0) { - EnWallmas_SetupDrop(this, play); + if (this->actor.params == WMT_SHADOWTAG && (player->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE)) { + this->timer = 0x82; // Prevents Shadow Tag Hand from dropping when talking to an NPC or Signpost. + } else { + EnWallmas_SetupDrop(this, play); + } } } From 409f443ed0797239ebce6f185b417cc8becc2b5a Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 31 Oct 2023 18:35:02 -0400 Subject: [PATCH 08/10] Removal of Kakariko Center Tree, Bushes, and NPC's for both ages. --- soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c | 2 ++ soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 2 +- soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c | 7 ++++++- soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c | 2 +- soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c | 4 ++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c index 3f8e61481a..e2f16a6112 100644 --- a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c +++ b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c @@ -65,6 +65,8 @@ void EnHs2_Init(Actor* thisx, PlayState* play) { this->actionFunc = func_80A6F1A4; this->unk_2A8 = 0; this->actor.targetMode = 6; + + Actor_Kill(this); } void EnHs2_Destroy(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index e0ff7470d1..b790351e49 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -829,7 +829,7 @@ s32 EnHy_ShouldSpawn(EnHy* this, PlayState* play) { } else if ((this->actor.params & 0x7F) != ENHY_TYPE_BOJ_12 && IS_NIGHT) { return false; } else { - return true; + return false; } case SCENE_IMPAS_HOUSE: if ((this->actor.params & 0x7F) != ENHY_TYPE_BOJ_10) { diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index 75e54c140a..86e1f77652 100644 --- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -266,7 +266,12 @@ void EnKusa_Init(Actor* thisx, PlayState* play) { return; } - EnKusa_SetupWaitObject(this); + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) { + Actor_Kill(this); + } else { + EnKusa_SetupWaitObject(this); + } + } void EnKusa_Destroy(Actor* thisx, PlayState* play2) { diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index d52b82d8df..929028fddb 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -105,7 +105,7 @@ void EnToryo_Init(Actor* thisx, PlayState* play) { break; case SCENE_KAKARIKO_VILLAGE: if ((LINK_AGE_IN_YEARS == YEARS_CHILD) && IS_DAY) { - this->stateFlags |= 2; + Actor_Kill(this); } break; case SCENE_KAKARIKO_CENTER_GUEST_HOUSE: diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index 4adb7afe76..e41c0f1fd9 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -173,6 +173,10 @@ void EnWood02_Init(Actor* thisx, PlayState* play2) { f32 floorY; s16 extraRot; + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.params >= 0 || this->actor.params <= WOOD_TREE_KAKARIKO_ADULT) { + Actor_Kill(this); + } + // The tree in Kakariko's day scene does not have the same params to spawn the GS // as the night scene, For the always spawn GS enhancement we apply the needed // params to have the GS drop when bonking From e62fea9fcb9e9e5f37e4f90056520efffb016f3f Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 31 Oct 2023 19:36:49 -0400 Subject: [PATCH 09/10] Spawn Child Tree near Anju and fix Bushes that spawn near Graveyard entrance. --- soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c | 2 +- soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index 86e1f77652..9f8af9c7b9 100644 --- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -266,7 +266,7 @@ void EnKusa_Init(Actor* thisx, PlayState* play) { return; } - if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) { + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.world.pos.z < 600.0) { Actor_Kill(this); } else { EnKusa_SetupWaitObject(this); diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index e41c0f1fd9..e257a184d8 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -173,10 +173,16 @@ void EnWood02_Init(Actor* thisx, PlayState* play2) { f32 floorY; s16 extraRot; - if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.params >= 0 || this->actor.params <= WOOD_TREE_KAKARIKO_ADULT) { + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.params <= WOOD_TREE_KAKARIKO_ADULT) { Actor_Kill(this); } + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.params >= 0) { + this->actor.world.pos.x = 754.051; + this->actor.world.pos.y = 80.0; + this->actor.world.pos.z = 1429.908; + } + // The tree in Kakariko's day scene does not have the same params to spawn the GS // as the night scene, For the always spawn GS enhancement we apply the needed // params to have the GS drop when bonking From 160ce44ae30ebff3ce455f9f35c0e16546df7044 Mon Sep 17 00:00:00 2001 From: Caladius Date: Fri, 3 Nov 2023 13:25:28 -0400 Subject: [PATCH 10/10] Modifications to TH for The End --- soh/soh/Enhancements/mods.cpp | 57 +++++++++--- .../actors/ovl_End_Title/z_end_title.c | 87 +++++++++++++------ 2 files changed, 103 insertions(+), 41 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index c0bbb3806d..750ca54be0 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -641,16 +641,20 @@ void RegisterMirrorModeHandler() { f32 triforcePieceScale; void RegisterTriforceHunt() { + static int eventTimer = -1; GameInteractor::Instance->RegisterGameHook([]() { + Player* player = GET_PLAYER(gPlayState); + uint8_t currentPieces = gSaveContext.triforcePiecesCollected; + uint8_t requiredPieces = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED); + if (!GameInteractor::IsGameplayPaused() && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) { // Warp to credits if (GameInteractor::State::TriforceHuntCreditsWarpActive) { - gPlayState->nextEntranceIndex = 0x6B; - gSaveContext.nextCutsceneIndex = 0xFFF2; - gPlayState->sceneLoadFlag = 0x14; - gPlayState->fadeTransition = 3; + GetItemEntry getItemEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY); + GiveItemEntryWithoutActor(gPlayState, getItemEntry); + eventTimer = 1; GameInteractor::State::TriforceHuntCreditsWarpActive = 0; } @@ -663,17 +667,42 @@ void RegisterTriforceHunt() { triforcePieceScale = 0.0f; GameInteractor::State::TriforceHuntPieceGiven = 0; } - - uint8_t currentPieces = gSaveContext.triforcePiecesCollected; - uint8_t requiredPieces = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED); - - // Give Boss Key when player loads back into the savefile. - if (currentPieces >= requiredPieces && gPlayState->sceneLoadFlag != 0x14 && - (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) { - GetItemEntry getItemEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY); - GiveItemEntryWithoutActor(gPlayState, getItemEntry); - } } + + if (currentPieces >= requiredPieces && eventTimer >= 1 && eventTimer <= 30) { + eventTimer++; + } else if (eventTimer > 30 && eventTimer <= 31) { + gPlayState->nextEntranceIndex = 0xDB; + gSaveContext.nextCutsceneIndex = 0x8000; + gPlayState->sceneLoadFlag = 0x14; + gPlayState->fadeTransition = 3; + eventTimer = 32; + } + + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && eventTimer == 32) { + player->actor.world.pos.x = -1441.043; + player->actor.world.pos.y = 55.037; + player->actor.world.pos.z = 578.224; + player->actor.shape.rot.x = 0; + player->actor.shape.rot.y = 17681; + player->actor.shape.rot.z = 0; + + GameInteractor::State::NoUIActive = 1; + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_END_TITLE, 0, 0, 0, 0, 0, 0, 2, false); + eventTimer = 33; + } + + }); + + GameInteractor::Instance->RegisterGameHook([]() { + if (!gPlayState) { + return; + } + Player* player = GET_PLAYER(gPlayState); + if (eventTimer == 33) { + player->actor.freezeTimer = 60; + } + }); } diff --git a/soh/src/overlays/actors/ovl_End_Title/z_end_title.c b/soh/src/overlays/actors/ovl_End_Title/z_end_title.c index af13255a8b..1e21dad90c 100644 --- a/soh/src/overlays/actors/ovl_End_Title/z_end_title.c +++ b/soh/src/overlays/actors/ovl_End_Title/z_end_title.c @@ -38,6 +38,9 @@ void EndTitle_Init(Actor* thisx, PlayState* play) { if (this->actor.params == 1) { this->actor.draw = EndTitle_DrawNintendoLogo; } + if (this->actor.params == 2) { + EndTitle_DrawFull(thisx, play); + } } void EndTitle_Destroy(Actor* thisx, PlayState* play) { @@ -82,36 +85,66 @@ void EndTitle_DrawFull(Actor* thisx, PlayState* play) { if ((frameCount > 850) && (this->ootAlpha < 200)) { this->ootAlpha += 15; } - + OVERLAY_DISP = Gfx_SetupDL_64(OVERLAY_DISP); - if (D_801614B0.a > 0) + + if (this->actor.params == 2) { gSPGrayscale(OVERLAY_DISP++, false); - gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE); - gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0); - gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2); - gSPClearGeometryMode(OVERLAY_DISP++, - G_TEXTURE_ENABLE | G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); - gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, - COMBINED, 0, 0, 0, COMBINED); - gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->endAlpha); - gDPLoadTextureTile(OVERLAY_DISP++, sTheEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 80, 24, 0, 0, 80 - 1, 24 - 1, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); - gSPTextureRectangle(OVERLAY_DISP++, 120 << 2, 90 << 2, 200 << 2, 113 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); - gDPPipeSync(OVERLAY_DISP++); - gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->tlozAlpha); - gDPLoadTextureTile(OVERLAY_DISP++, sTheLegendOfZeldaTex, G_IM_FMT_IA, G_IM_SIZ_8b, 120, 24, 0, 0, 120 - 1, 24 - 1, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); - gSPTextureRectangle(OVERLAY_DISP++, 100 << 2, 160 << 2, 220 << 2, 183 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, - 1 << 10); - gDPPipeSync(OVERLAY_DISP++); - gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->ootAlpha); - gDPLoadTextureTile(OVERLAY_DISP++, sOcarinaOfTimeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 112, 16, 0, - 0, 112 - 1, 16 - 1, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); - gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, - 1 << 10); - if (D_801614B0.a > 0) + gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE); + gDPSetEnvColor(OVERLAY_DISP++, 0, 255, 0, 0); + gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2); + gSPClearGeometryMode(OVERLAY_DISP++, G_TEXTURE_ENABLE | G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); + gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED); + gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->endAlpha); + gDPLoadTextureTile(OVERLAY_DISP++, sTheEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 80, 24, 0, 0, 80 - 1, 24 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); + gSPTextureRectangle(OVERLAY_DISP++, 120 << 2, 90 << 2, 200 << 2, 113 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->tlozAlpha); + gDPLoadTextureTile(OVERLAY_DISP++, sTheLegendOfZeldaTex, G_IM_FMT_IA, G_IM_SIZ_8b, 120, 24, 0, 0, 120 - 1, 24 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); + gSPTextureRectangle(OVERLAY_DISP++, 100 << 2, 160 << 2, 220 << 2, 183 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->ootAlpha); + gDPLoadTextureTile(OVERLAY_DISP++, sOcarinaOfTimeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 112, 16, 0, 0, 112 - 1, 16 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); + gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + D_801614B0.a = 255; + D_801614B0.r = 205; + D_801614B0.g = 168; + D_801614B0.b = 130; + gSPGrayscale(OVERLAY_DISP++, true); + } else { + if (D_801614B0.a > 0) + + gSPGrayscale(OVERLAY_DISP++, false); + gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE); + gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0); + gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2); + gSPClearGeometryMode(OVERLAY_DISP++, G_TEXTURE_ENABLE | G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN | + G_TEXTURE_GEN_LINEAR); + gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, + COMBINED, 0, 0, 0, COMBINED); + gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->endAlpha); + gDPLoadTextureTile(OVERLAY_DISP++, sTheEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 80, 24, 0, 0, 80 - 1, 24 - 1, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); + gSPTextureRectangle(OVERLAY_DISP++, 120 << 2, 90 << 2, 200 << 2, 113 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, + 1 << 10); + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->tlozAlpha); + gDPLoadTextureTile(OVERLAY_DISP++, sTheLegendOfZeldaTex, G_IM_FMT_IA, G_IM_SIZ_8b, 120, 24, 0, 0, 120 - 1, + 24 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); + gSPTextureRectangle(OVERLAY_DISP++, 100 << 2, 160 << 2, 220 << 2, 183 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, + 1 << 10); + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->ootAlpha); + gDPLoadTextureTile(OVERLAY_DISP++, sOcarinaOfTimeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 112, 16, 0, 0, 112 - 1, 16 - 1, + 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); + gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, + 1 << 10); + if (D_801614B0.a > 0) + gSPGrayscale(OVERLAY_DISP++, true); + } + CLOSE_DISPS(play->state.gfxCtx); }