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/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/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/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 58e124b7a6..2762b5a1b0 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1607,17 +1607,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) { @@ -1634,12 +1634,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(); @@ -1647,19 +1647,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(); } @@ -1667,15 +1667,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(); } @@ -1683,15 +1683,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 849dbbb1d3..28383ccd5d 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 @@ -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([]() { @@ -634,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; } @@ -664,6 +675,41 @@ void RegisterTriforceHunt() { 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/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/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;}}), diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 664c5659b3..331aedc2f0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1638,29 +1638,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 26fecba815..5c7bdee722 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", @@ -1697,24 +1725,70 @@ 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; 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 }); } @@ -2042,7 +2116,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 a2b3189d22..478ab8d41f 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -722,11 +722,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); } } @@ -865,11 +865,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/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 018b05fe9a..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."); @@ -1387,6 +1390,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/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/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_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; 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"; 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 cbc317f14f..e972297f65 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]; @@ -2602,8 +2617,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); } @@ -2643,26 +2658,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; @@ -6481,11 +6495,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_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; 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_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..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,12 @@ void EnKusa_Init(Actor* thisx, PlayState* play) { return; } - EnKusa_SetupWaitObject(this); + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.world.pos.z < 600.0) { + Actor_Kill(this); + } else { + EnKusa_SetupWaitObject(this); + } + } void EnKusa_Destroy(Actor* thisx, PlayState* play2) { 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_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_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); + } } } 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..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,6 +173,16 @@ void EnWood02_Init(Actor* thisx, PlayState* play2) { f32 floorY; s16 extraRot; + 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 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_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); } 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; }