From 8b6c183776bddb511e7cec7a07d0018507ff101d Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:55:05 +0200 Subject: [PATCH] Rando: Skeleton key (#3997) * Initial Implementation * Add temporary model to the skeleton key --- .../Enhancements/debugger/debugSaveEditor.h | 4 +- soh/soh/Enhancements/mods.cpp | 23 ++- .../randomizer/3drando/item_pool.cpp | 4 + soh/soh/Enhancements/randomizer/draw.cpp | 50 ++++++ soh/soh/Enhancements/randomizer/draw.h | 1 + soh/soh/Enhancements/randomizer/item_list.cpp | 3 + soh/soh/Enhancements/randomizer/logic.cpp | 6 + soh/soh/Enhancements/randomizer/logic.h | 3 + .../randomizer/option_descriptions.cpp | 2 +- .../Enhancements/randomizer/randomizer.cpp | 3 +- .../Enhancements/randomizer/randomizerTypes.h | 3 + .../Enhancements/randomizer/randomizer_inf.h | 4 +- soh/soh/Enhancements/randomizer/settings.cpp | 7 +- soh/src/code/z_parameter.c | 159 +++++++++--------- .../overlays/actors/ovl_En_Door/z_en_door.h | 3 + 15 files changed, 194 insertions(+), 81 deletions(-) diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index e5086f5b8..661cf87be 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -596,11 +596,13 @@ const std::vector flagTables = { { RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" }, { RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }, + { RAND_INF_HAS_SKELETON_KEY, "RAND_INF_HAS_SKELETON_KEY" }, + { RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" }, { RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" }, { RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" }, { RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" }, - + { RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" }, { RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" }, { RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" }, diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 2efe6477e..098317bae 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -29,8 +29,10 @@ #include "src/overlays/actors/ovl_En_Tp/z_en_tp.h" #include "src/overlays/actors/ovl_En_Firefly/z_en_firefly.h" #include "src/overlays/actors/ovl_En_Xc/z_en_xc.h" -#include "src/overlays//actors/ovl_Fishing/z_fishing.h" +#include "src/overlays/actors/ovl_Fishing/z_fishing.h" #include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" +#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" @@ -1712,6 +1714,24 @@ void RegisterRandomizerCompasses() { }); } +void RegisterSkeletonKey() { + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + Actor* actor = static_cast(refActor); + + if (Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY)) { + if (actor->id == ACTOR_EN_DOOR) { + EnDoor* door = (EnDoor*)actor; + door->lockTimer = 0; + } else if (actor->id == ACTOR_DOOR_SHUTTER) { + DoorShutter* shutterDoor = (DoorShutter*)actor; + if (shutterDoor->doorType == SHUTTER_KEY_LOCKED) { + shutterDoor->unk_16E = 0; + } + } + } + }); +} + void InitMods() { RandomizerRegisterHooks(); TimeSaverRegisterHooks(); @@ -1760,4 +1780,5 @@ void InitMods() { RegisterPatchHandHandler(); RegisterHurtContainerModeHandler(); RegisterPauseMenuHooks(); + RegisterSkeletonKey(); } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index caf7c811e..6d2e44fbf 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -782,6 +782,10 @@ void GenerateItemPool() { ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_RIGHT_BUTTON); } + if (ctx->GetOption(RSK_SKELETON_KEY)) { + AddItemToMainPool(RG_SKELETON_KEY); + } + if (ctx->GetOption(RSK_SHUFFLE_SWIM)) { AddItemToMainPool(RG_PROGRESSIVE_SCALE); } diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index f35567b83..11e4a430b 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -541,5 +541,55 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI Matrix_Pop(); + CLOSE_DISPS(play->state.gfxCtx); +} + +int skeletonKeyHue = 0; + +// Runs every frame to update rainbow hue, taken from CosmeticsEditor.cpp. +Color_RGBA8 GetSkeletonKeyColor() { + float rainbowSpeed = 0.6f; + + float frequency = 2 * M_PI / (360 * rainbowSpeed); + Color_RGBA8 color; + color.r = sin(frequency * skeletonKeyHue + 0) * 127 + 128; + color.g = sin(frequency * skeletonKeyHue + (2 * M_PI / 3)) * 127 + 128; + color.b = sin(frequency * skeletonKeyHue + (4 * M_PI / 3)) * 127 + 128; + color.a = 255; + + skeletonKeyHue++; + if (skeletonKeyHue >= (360 * rainbowSpeed)) skeletonKeyHue = 0; + + return color; +} + +int test = 0; + +extern "C" void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Color_RGBA8 color = GetSkeletonKeyColor(); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + test += 1; + + if (test > 40) { + test -= 80; + } + + Matrix_RotateZ(M_PI / 40 * test, MTXMODE_APPLY); + Matrix_RotateY(M_PI / 40 * test, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gDPSetGrayscaleColor(POLY_OPA_DISP++, color.r, color.g, color.b, color.a); + gSPGrayscale(POLY_OPA_DISP++, true); + + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSmallKeyDL); + + gSPGrayscale(POLY_OPA_DISP++, false); + CLOSE_DISPS(play->state.gfxCtx); } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index ec390c002..d0ba3c747 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -21,6 +21,7 @@ void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry getItemEntry); #define GET_ITEM_MYSTERY \ diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 3bdd2709f..b9bd9be22 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -289,6 +289,9 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, &logic->ProgressiveWallet, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_SKELETON_KEY] = Item(RG_SKELETON_KEY, Text{ "Skeleton Key", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, &logic->SkeletonKey, RHT_SKELETON_KEY, RG_SKELETON_KEY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_SKELETON_KEY].SetCustomDrawFunc(Randomizer_DrawSkeletonKey); + itemTable[RG_DEKU_STICK_BAG] = Item(RG_DEKU_STICK_BAG, Text{ "Deku Stick Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, &logic->ProgressiveStickBag, RHT_NONE, RG_DEKU_STICK_BAG, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, &logic->ProgressiveNutBag, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index b1fa969d0..49f611f0e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -411,6 +411,9 @@ namespace Rando { } bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) { + if (SkeletonKey) { + return true; + } switch (dungeon) { case RR_FOREST_TEMPLE: /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotJump_Boots) >= static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHoverBoost) >= static_cast(GlitchDifficulty::NOVICE) || @@ -673,6 +676,9 @@ namespace Rando { //Triforce Pieces TriforcePieces = 0; + //Skeleton Key + SkeletonKey = false; + //Boss Souls CanSummonGohma = false; CanSummonKingDodongo = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 16213049d..799b8402a 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -171,6 +171,9 @@ class Logic { // Triforce Pieces uint8_t TriforcePieces = 0; + // Skeleton Key + bool SkeletonKey = false; + // Boss Keys bool BossKeyForestTemple = false; bool BossKeyFireTemple = false; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index ad5cd4e09..e5b0722f3 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -542,7 +542,6 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 50 tokens will tell you the reward"; mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 100 tokens will tell you the reward"; mOptionDescriptions[RSK_MASK_SHOP_HINT] = "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre."; - mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees."; mOptionDescriptions[RSK_BOMBCHUS_IN_LOGIC] = "Bombchus are properly considered in logic.\n" @@ -557,6 +556,7 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] = "Ice Arrows act like Blue Fire, making them able to melt red ice. " "Item placement logic will respect this option, so it might be required to use this to progress."; + mOptionDescriptions[RSK_SKELETON_KEY] = "Adds a new item called the \"Skeleton Key\", it unlocks every dungeon door locked by a small key."; mOptionDescriptions[RSK_SUNLIGHT_ARROWS] = "Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. " "Item placement logic will respect this option, so it might be required to use this to progress."; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 303a6bbfd..faac02d84 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2954,7 +2954,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = {{ + const std::array getItemMessages = {{ GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn wirklich gefunden!", @@ -3226,6 +3226,7 @@ void Randomizer::CreateCustomMessages() { "Vous trouvez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), GIMESSAGE_UNTRANSLATED(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!"), GIMESSAGE_UNTRANSLATED(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!"), + GIMESSAGE_UNTRANSLATED(RG_SKELETON_KEY, ITEM_KEY_SMALL, "You found the %rSkeleton Key%w!"), GIMESSAGE_UNTRANSLATED(RG_DEKU_STICK_BAG, ITEM_STICK, "You found the %rDeku Stick Bag%w!&You can now hold deku sticks!"), GIMESSAGE_UNTRANSLATED(RG_DEKU_NUT_BAG, ITEM_NUT, "You found the %rDeku Nut Bag%w!&You can now hold deku nuts!"), }}; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index d15d3d4a3..e89059ecd 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1979,6 +1979,7 @@ typedef enum { RG_OCARINA_C_DOWN_BUTTON, RG_OCARINA_C_LEFT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, + RG_SKELETON_KEY, RG_FISHING_POLE, RG_DEKU_STICK_BAG, RG_DEKU_NUT_BAG, @@ -3244,6 +3245,7 @@ typedef enum { RHT_OCARINA_C_RIGHT_BUTTON, RHT_BRONZE_SCALE, RHT_FISHING_POLE, + RHT_SKELETON_KEY, RHT_EPONA, RHT_HINT_MYSTERIOUS, RHT_MYSTERIOUS_ITEM, @@ -3713,6 +3715,7 @@ typedef enum { RSK_FISHSANITY_POND_COUNT, RSK_FISHSANITY_AGE_SPLIT, RSK_SHUFFLE_FISHING_POLE, + RSK_SKELETON_KEY, RSK_SHUFFLE_DEKU_STICK_BAG, RSK_SHUFFLE_DEKU_NUT_BAG, RSK_MAX diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index f1ae83121..72168f018 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -257,11 +257,13 @@ typedef enum { RAND_INF_ZD_FISH_4, RAND_INF_ZD_FISH_5, + RAND_INF_HAS_SKELETON_KEY, + RAND_INF_LINKS_POCKET, RAND_INF_LEARNED_EPONA_SONG, RAND_INF_DARUNIAS_JOY, RAND_INF_KING_ZORA_THAWED, - + RAND_INF_HC_GREAT_FAIRY_REWARD, RAND_INF_DMT_GREAT_FAIRY_REWARD, RAND_INF_DMC_GREAT_FAIRY_REWARD, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 80007b564..28f341631 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -184,6 +184,7 @@ void Settings::CreateOptions() { // TODO: Compasses show rewards/woth, maps show dungeon mode mOptions[RSK_BLUE_FIRE_ARROWS] = Option::Bool("Blue Fire Arrows", CVAR_RANDOMIZER_SETTING("BlueFireArrows"), mOptionDescriptions[RSK_BLUE_FIRE_ARROWS]); mOptions[RSK_SUNLIGHT_ARROWS] = Option::Bool("Sunlight Arrows", CVAR_RANDOMIZER_SETTING("SunlightArrows"), mOptionDescriptions[RSK_SUNLIGHT_ARROWS]); + mOptions[RSK_SKELETON_KEY] = Option::Bool("Skeleton Key", CVAR_RANDOMIZER_SETTING("SkeletonKey"), mOptionDescriptions[RSK_SKELETON_KEY]); mOptions[RSK_ITEM_POOL] = Option::U8("Item Pool", {"Plentiful", "Balanced", "Scarce", "Minimal"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ItemPool"), mOptionDescriptions[RSK_ITEM_POOL], WidgetType::Combobox, RO_ITEM_POOL_BALANCED); mOptions[RSK_ICE_TRAPS] = Option::U8("Ice Traps", {"Off", "Normal", "Extra", "Mayhem", "Onslaught"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("IceTraps"), mOptionDescriptions[RSK_ICE_TRAPS], WidgetType::Combobox, RO_ICE_TRAPS_NORMAL); // TODO: Remove Double Defense, Progressive Goron Sword @@ -764,7 +765,8 @@ void Settings::CreateOptions() { &mOptions[RSK_BOMBCHUS_IN_LOGIC], &mOptions[RSK_ENABLE_BOMBCHU_DROPS], &mOptions[RSK_BLUE_FIRE_ARROWS], - &mOptions[RSK_SUNLIGHT_ARROWS] + &mOptions[RSK_SUNLIGHT_ARROWS], + &mOptions[RSK_SKELETON_KEY], }, false, WidgetContainerType::COLUMN); mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE] = OptionGroup::SubGroup("Gameplay", { &mOptionGroups[RSG_TIMESAVERS_IMGUI], @@ -992,6 +994,7 @@ void Settings::CreateOptions() { &mOptions[RSK_DAMAGE_MULTIPLIER], &mOptions[RSK_BLUE_FIRE_ARROWS], &mOptions[RSK_SUNLIGHT_ARROWS], + &mOptions[RSK_SKELETON_KEY], }); mOptionGroups[RSG_ITEM_POOL] = OptionGroup("Item Pool Settings", std::initializer_list({ &mOptions[RSK_ITEM_POOL], @@ -1210,6 +1213,7 @@ void Settings::CreateOptions() { { "Miscellaneous Settings:Hint Distribution", RSK_HINT_DISTRIBUTION }, { "Miscellaneous Settings:Blue Fire Arrows", RSK_BLUE_FIRE_ARROWS }, { "Miscellaneous Settings:Sunlight Arrows", RSK_SUNLIGHT_ARROWS }, + { "Miscellaneous Settings:Skeleton Key", RSK_SKELETON_KEY }, { "Timesaver Settings:Skip Child Zelda", RSK_SKIP_CHILD_ZELDA }, { "Start with Consumables", RSK_STARTING_CONSUMABLES }, { "Full Wallets", RSK_FULL_WALLETS }, @@ -2359,6 +2363,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { case RSK_SKULLS_SUNS_SONG: case RSK_BLUE_FIRE_ARROWS: case RSK_SUNLIGHT_ARROWS: + case RSK_SKELETON_KEY: case RSK_BOMBCHUS_IN_LOGIC: case RSK_TOT_ALTAR_HINT: case RSK_GANONDORF_HINT: diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 2f39ade8c..a03a74c69 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2796,6 +2796,11 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { return Return_Item_Entry(giEntry, RG_NONE); } + if (item == RG_SKELETON_KEY) { + Flags_SetRandomizerInf(RAND_INF_HAS_SKELETON_KEY); + return Return_Item_Entry(giEntry, RG_NONE); + } + if (item == RG_DEKU_STICK_BAG) { Inventory_ChangeUpgrade(UPG_STICKS, 1); INV_CONTENT(ITEM_STICK) = ITEM_STICK; @@ -5370,83 +5375,87 @@ void Interface_Draw(PlayState* play) { } } - switch (play->sceneNum) { - case SCENE_FOREST_TEMPLE: - case SCENE_FIRE_TEMPLE: - case SCENE_WATER_TEMPLE: - case SCENE_SPIRIT_TEMPLE: - case SCENE_SHADOW_TEMPLE: - case SCENE_BOTTOM_OF_THE_WELL: - case SCENE_ICE_CAVERN: - case SCENE_GANONS_TOWER: - case SCENE_GERUDO_TRAINING_GROUND: - case SCENE_THIEVES_HIDEOUT: - case SCENE_INSIDE_GANONS_CASTLE: - case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: - case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: - case SCENE_TREASURE_BOX_SHOP: - if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] >= 0) { - s16 X_Margins_SKC; - s16 Y_Margins_SKC; - if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.UseMargins"), 0) != 0) { - if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 0) {X_Margins_SKC = Left_HUD_Margin;}; - Y_Margins_SKC = Bottom_HUD_Margin; - } else { - X_Margins_SKC = 0; - Y_Margins_SKC = 0; - } - s16 PosX_SKC_ori = OTRGetRectDimensionFromLeftEdge(26+X_Margins_SKC); - s16 PosY_SKC_ori = 190+Y_Margins_SKC; - s16 PosX_SKC; - s16 PosY_SKC; - if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) != 0) { - PosY_SKC = CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosY"), 0)+Y_Margins_SKC; - if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 1) {//Anchor Left - if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.UseMargins"), 0) != 0) {X_Margins_SKC = Left_HUD_Margin;}; - PosX_SKC = OTRGetDimensionFromLeftEdge(CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosX"), 0)+X_Margins_SKC); - } else if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 2) {//Anchor Right - if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.UseMargins"), 0) != 0) {X_Margins_SKC = Right_HUD_Margin;}; - PosX_SKC = OTRGetDimensionFromRightEdge(CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosX"), 0)+X_Margins_SKC); - } else if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 3) {//Anchor None - PosX_SKC = CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosX"), 0); - } else if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 4) {//Hidden - PosX_SKC = -9999; + //when having the skeleton key in rando, don't render the small key counter + if (!Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY)) { + switch (play->sceneNum) { + case SCENE_FOREST_TEMPLE: + case SCENE_FIRE_TEMPLE: + case SCENE_WATER_TEMPLE: + case SCENE_SPIRIT_TEMPLE: + case SCENE_SHADOW_TEMPLE: + case SCENE_BOTTOM_OF_THE_WELL: + case SCENE_ICE_CAVERN: + case SCENE_GANONS_TOWER: + case SCENE_GERUDO_TRAINING_GROUND: + case SCENE_THIEVES_HIDEOUT: + case SCENE_INSIDE_GANONS_CASTLE: + case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: + case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: + case SCENE_TREASURE_BOX_SHOP: + + if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] >= 0) { + s16 X_Margins_SKC; + s16 Y_Margins_SKC; + if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.UseMargins"), 0) != 0) { + if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 0) {X_Margins_SKC = Left_HUD_Margin;}; + Y_Margins_SKC = Bottom_HUD_Margin; + } else { + X_Margins_SKC = 0; + Y_Margins_SKC = 0; } - } else { - PosY_SKC = PosY_SKC_ori; - PosX_SKC = PosX_SKC_ori; + s16 PosX_SKC_ori = OTRGetRectDimensionFromLeftEdge(26+X_Margins_SKC); + s16 PosY_SKC_ori = 190+Y_Margins_SKC; + s16 PosX_SKC; + s16 PosY_SKC; + if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) != 0) { + PosY_SKC = CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosY"), 0)+Y_Margins_SKC; + if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 1) {//Anchor Left + if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.UseMargins"), 0) != 0) {X_Margins_SKC = Left_HUD_Margin;}; + PosX_SKC = OTRGetDimensionFromLeftEdge(CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosX"), 0)+X_Margins_SKC); + } else if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 2) {//Anchor Right + if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.UseMargins"), 0) != 0) {X_Margins_SKC = Right_HUD_Margin;}; + PosX_SKC = OTRGetDimensionFromRightEdge(CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosX"), 0)+X_Margins_SKC); + } else if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 3) {//Anchor None + PosX_SKC = CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosX"), 0); + } else if (CVarGetInteger(CVAR_COSMETIC("HUD.SmallKey.PosType"), 0) == 4) {//Hidden + PosX_SKC = -9999; + } + } else { + PosY_SKC = PosY_SKC_ori; + PosX_SKC = PosX_SKC_ori; + } + // Small Key Icon + gDPPipeSync(OVERLAY_DISP++); + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, keyCountColor.r,keyCountColor.g,keyCountColor.b, interfaceCtx->magicAlpha); + gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 20, 255); //We reset this here so it match user color :) + OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gSmallKeyCounterIconTex, 16, 16, PosX_SKC, PosY_SKC, 16, 16, + 1 << 10, 1 << 10); + + // Small Key Counter + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha); + gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, + TEXEL0, 0, PRIMITIVE, 0); + + interfaceCtx->counterDigits[2] = 0; + interfaceCtx->counterDigits[3] = gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]; + + while (interfaceCtx->counterDigits[3] >= 10) { + interfaceCtx->counterDigits[2]++; + interfaceCtx->counterDigits[3] -= 10; + } + + if (interfaceCtx->counterDigits[2] != 0) { + OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)((u8*)digitTextures[interfaceCtx->counterDigits[2]])), 8, 16, PosX_SKC+8, PosY_SKC, 8, 16, 1 << 10, 1 << 10); + } + + OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[3]]), 8, 16, PosX_SKC+16, PosY_SKC, 8, 16, 1 << 10, 1 << 10); } - // Small Key Icon - gDPPipeSync(OVERLAY_DISP++); - - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, keyCountColor.r,keyCountColor.g,keyCountColor.b, interfaceCtx->magicAlpha); - gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 20, 255); //We reset this here so it match user color :) - OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gSmallKeyCounterIconTex, 16, 16, PosX_SKC, PosY_SKC, 16, 16, - 1 << 10, 1 << 10); - - // Small Key Counter - gDPPipeSync(OVERLAY_DISP++); - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha); - gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, - TEXEL0, 0, PRIMITIVE, 0); - - interfaceCtx->counterDigits[2] = 0; - interfaceCtx->counterDigits[3] = gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]; - - while (interfaceCtx->counterDigits[3] >= 10) { - interfaceCtx->counterDigits[2]++; - interfaceCtx->counterDigits[3] -= 10; - } - - if (interfaceCtx->counterDigits[2] != 0) { - OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)((u8*)digitTextures[interfaceCtx->counterDigits[2]])), 8, 16, PosX_SKC+8, PosY_SKC, 8, 16, 1 << 10, 1 << 10); - } - - OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[3]]), 8, 16, PosX_SKC+16, PosY_SKC, 8, 16, 1 << 10, 1 << 10); - } - break; - default: - break; + break; + default: + break; + } } // Rupee Counter diff --git a/soh/src/overlays/actors/ovl_En_Door/z_en_door.h b/soh/src/overlays/actors/ovl_En_Door/z_en_door.h index 7389ac99a..4e7ef1279 100644 --- a/soh/src/overlays/actors/ovl_En_Door/z_en_door.h +++ b/soh/src/overlays/actors/ovl_En_Door/z_en_door.h @@ -57,6 +57,9 @@ typedef struct EnDoor { /* 0x01D4 */ EnDoorActionFunc actionFunc; } EnDoor; // size = 0x01D8 +#ifdef __cplusplus +extern "C" +#endif void EnDoor_SetupType(EnDoor* enDoor, PlayState* play); #endif