diff options
| author | Caladius <Caladius@users.noreply.github.com> | 2025-10-29 12:57:28 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-29 12:57:28 -0400 |
| commit | e5db91da04b507c194c25fce45d5c87cb992123c (patch) | |
| tree | f803c43f41d7a41778e74a7be8a9c8745b27ef08 | |
| parent | 83921dc012588c520efe0ed8c7ac1406806543c7 (diff) | |
[Rando] Enemy Drop Shuffle (#1282)
* Implement most of the Enemy Drops
* Fix Glitchless Generation
* Fix duplicate Logic Checks
* Add Slime Items and fix Linux Floating Point.
* Add Comment for Enemy Drops RC Sets
* Adds Leever and fixes Position Check issue.
* Adds GBC for Logic check
* Add Hiploop
* Adds Skullfish (Enemy only drops items inside GBT)
* Feedback Updates
* Updates
* Update to Switch for Actor Selection
* More Enemy Locations
* Fix Mini Baba and remove actors that dont drop items
* Update mm/2s2h/Rando/Logic/Logic.h
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Add case for ACTOR_BOSS_05 in Logic.h
* Update mm/2s2h/Rando/Types.h
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Clang format actor position
* Need swim for Bio Deku Baba
* Define RC_ENEMY_DROP_BIO_DEKU_BABA in checks
* GitHub spacing how dare you
* Update mm/2s2h/Rando/StaticData/Checks.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Types.h
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/StaticData/Checks.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Types.h
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/StaticData/Checks.cpp
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Update mm/2s2h/Rando/Types.h
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
* Apply suggestion from @Eblo
---------
Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
| -rw-r--r-- | mm/2s2h/GameInteractor/GameInteractor.h | 2 | ||||
| -rw-r--r-- | mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp | 1 | ||||
| -rw-r--r-- | mm/2s2h/Rando/ActorBehavior/ActorBehavior.h | 1 | ||||
| -rw-r--r-- | mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp | 151 | ||||
| -rw-r--r-- | mm/2s2h/Rando/CheckTracker/CheckTracker.cpp | 4 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Logic/Logic.cpp | 4 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Logic/Logic.h | 82 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp | 51 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Logic/Regions/TerminaField.cpp | 1 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Menu.cpp | 2 | ||||
| -rw-r--r-- | mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp | 5 | ||||
| -rw-r--r-- | mm/2s2h/Rando/StaticData/Checks.cpp | 37 | ||||
| -rw-r--r-- | mm/2s2h/Rando/StaticData/Options.cpp | 1 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Types.h | 40 | ||||
| -rw-r--r-- | mm/src/code/z_en_item00.c | 8 | ||||
| -rw-r--r-- | mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c | 12 |
16 files changed, 395 insertions, 7 deletions
diff --git a/mm/2s2h/GameInteractor/GameInteractor.h b/mm/2s2h/GameInteractor/GameInteractor.h index e27e7069b..8c44f5b5a 100644 --- a/mm/2s2h/GameInteractor/GameInteractor.h +++ b/mm/2s2h/GameInteractor/GameInteractor.h @@ -254,6 +254,8 @@ typedef enum { VB_SET_CAMERA_AT_EYE, VB_SET_CAMERA_FOV, VB_USE_ITEM_CONSIDER_ITEM_ACTION, + VB_ENEMY_DROP_COLLECTIBLE, + VB_DRAW_SLIME_RANDO_ITEM } GIVanillaBehavior; typedef enum { diff --git a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp index a0e9da23f..04600c8bd 100644 --- a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp +++ b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp @@ -78,6 +78,7 @@ void Rando::ActorBehavior::OnFileLoad() { Rando::ActorBehavior::InitEnDnhBehavior(); Rando::ActorBehavior::InitEnElfgrpBehavior(); Rando::ActorBehavior::InitEnElforgBehavior(); + Rando::ActorBehavior::InitEnemyDropBehavior(); Rando::ActorBehavior::InitEnFish2Behavior(); Rando::ActorBehavior::InitEnFsnBehavior(); Rando::ActorBehavior::InitEnFuBehavior(); diff --git a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h index f1ec06fe4..30b82dfda 100644 --- a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h +++ b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h @@ -35,6 +35,7 @@ void InitEnDnhBehavior(); void InitEnElfgrpBehavior(); void InitEnElforgBehavior(); void InitEnFish2Behavior(); +void InitEnemyDropBehavior(); void InitEnFsnBehavior(); void InitEnFuBehavior(); void InitEnGamelupyBehavior(); diff --git a/mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp b/mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp new file mode 100644 index 000000000..98ba30e5d --- /dev/null +++ b/mm/2s2h/Rando/ActorBehavior/EnemyDrops.cpp @@ -0,0 +1,151 @@ +#include "ActorBehavior.h" +#include <libultraship/bridge/consolevariablebridge.h> +#include "2s2h/CustomItem/CustomItem.h" + +extern "C" { +#include "variables.h" +#include "functions.h" + +#include "overlays/actors/ovl_En_Slime/z_en_slime.h" +#include "overlays/actors/ovl_En_Sw/z_en_sw.h" +} + +std::unordered_map<int16_t, RandoCheckId> actorIdToRandoCheckIdMap = { + { ACTOR_EN_AM, RC_ENEMY_DROP_ARMOS }, + { ACTOR_EN_VM, RC_ENEMY_DROP_BEAMOS }, + { ACTOR_BOSS_05, RC_ENEMY_DROP_BIO_DEKU_BABA }, + { ACTOR_EN_BB, RC_ENEMY_DROP_BLUE_BUBBLE }, + { ACTOR_EN_RAT, RC_ENEMY_DROP_BOMBCHU }, + { ACTOR_EN_SLIME, RC_ENEMY_DROP_CHU }, + { ACTOR_EN_FAMOS, RC_ENEMY_DROP_DEATH_ARMOS }, + { ACTOR_EN_DEKUBABA, RC_ENEMY_DROP_DEKU_BABA }, + { ACTOR_EN_DODONGO, RC_ENEMY_DROP_DODONGO }, + { ACTOR_EN_GRASSHOPPER, RC_ENEMY_DROP_DRAGONFLY }, + { ACTOR_EN_SNOWMAN, RC_ENEMY_DROP_EENO }, + { ACTOR_EN_TUBO_TRAP, RC_ENEMY_DROP_FLYING_POT }, + { ACTOR_EN_FLOORMAS, RC_ENEMY_DROP_FLOORMASTER }, + { ACTOR_EN_FZ, RC_ENEMY_DROP_FREEZARD }, + { ACTOR_EN_CROW, RC_ENEMY_DROP_GUAY }, + { ACTOR_EN_PP, RC_ENEMY_DROP_HIPLOOP }, + { ACTOR_EN_IK, RC_ENEMY_DROP_IRON_KNUCKLE }, + { ACTOR_EN_FIREFLY, RC_ENEMY_DROP_KEESE }, + { ACTOR_EN_NEO_REEBA, RC_ENEMY_DROP_LEEVER }, + { ACTOR_EN_RR, RC_ENEMY_DROP_LIKE_LIKE }, + { ACTOR_EN_DEKUNUTS, RC_ENEMY_DROP_MAD_SCRUB }, + { ACTOR_EN_KAREBABA, RC_ENEMY_DROP_MINI_BABA }, + { ACTOR_EN_BAGUO, RC_ENEMY_DROP_NEJIRON }, + { ACTOR_EN_OKUTA, RC_ENEMY_DROP_OCTOROK }, + { ACTOR_EN_PEEHAT, RC_ENEMY_DROP_PEAHAT }, + { ACTOR_EN_BBFALL, RC_ENEMY_DROP_RED_BUBBLE }, + { ACTOR_EN_RD, RC_ENEMY_DROP_REDEAD_GIBDO }, + { ACTOR_EN_SB, RC_ENEMY_DROP_SHELLBLADE }, + { ACTOR_EN_PR2, RC_ENEMY_DROP_SKULLFISH }, + { ACTOR_EN_ST, RC_ENEMY_DROP_SKULLTULA }, + { ACTOR_EN_SW, RC_ENEMY_DROP_SKULLWALLTULA }, + { ACTOR_EN_KAME, RC_ENEMY_DROP_SNAPPER }, + { ACTOR_EN_SKB, RC_ENEMY_DROP_STALCHILD }, + { ACTOR_EN_TITE, RC_ENEMY_DROP_TEKTITE }, + { ACTOR_EN_WF, RC_ENEMY_DROP_WOLFOS }, + { ACTOR_EN_WALLMAS, RC_ENEMY_DROP_WALLMASTER }, +}; + +RandoCheckId GetRandoCheckByActorId(int16_t actorId) { + for (auto& map : actorIdToRandoCheckIdMap) { + if (map.first == actorId) { + return map.second; + } + } + + return RC_UNKNOWN; +} + +Actor* FindActor(Vec3f position, ActorType actorType) { + ActorListEntry actorList = gPlayState->actorCtx.actorLists[actorType]; + + Actor* currentActor = actorList.first; + for (size_t i = 0; i < actorList.length; i++) { + if (currentActor->world.pos.x == position.x && currentActor->world.pos.y == position.y && + currentActor->world.pos.z == position.z) { + return currentActor; + } else { + currentActor = currentActor->next; + } + } + return nullptr; +} + +void SpawnEnemyDrop(Vec3f position, Actor* actor, RandoCheckId randoCheckId) { + CustomItem::Spawn( + position.x, position.y, position.z, 0, + CustomItem::KILL_ON_TOUCH | CustomItem::TOSS_ON_SPAWN | CustomItem::ABLE_TO_ZORA_RANG, randoCheckId, + [](Actor* actor, PlayState* play) { + RandoSaveCheck& randoSaveCheck = RANDO_SAVE_CHECKS[CUSTOM_ITEM_PARAM]; + randoSaveCheck.eligible = true; + }, + [](Actor* actor, PlayState* play) { + auto& randoSaveCheck = RANDO_SAVE_CHECKS[CUSTOM_ITEM_PARAM]; + RandoItemId randoItemId = Rando::ConvertItem(randoSaveCheck.randoItemId); + Matrix_Scale(30.0f, 30.0f, 30.0f, MTXMODE_APPLY); + Rando::DrawItem(Rando::ConvertItem(randoSaveCheck.randoItemId, (RandoCheckId)CUSTOM_ITEM_PARAM), actor); + }); +} + +void Rando::ActorBehavior::InitEnemyDropBehavior() { + COND_VB_SHOULD(VB_ENEMY_DROP_COLLECTIBLE, IS_RANDO, { + Vec3f position = va_arg(args, Vec3f); + + if (RANDO_SAVE_OPTIONS[RO_SHUFFLE_ENEMY_DROPS] == RO_GENERIC_OFF) { + return; + } + + Actor* foundActor = FindActor(position, ACTORCAT_ENEMY); + if (foundActor == nullptr || foundActor->category != ACTORCAT_ENEMY) { + return; + } + + int16_t actorId = foundActor->id; + + // Skullwalltulas need special handling because most of them drop tokens + if (actorId == ACTOR_EN_SW) { + return; + } + + RandoCheckId randoCheckId = GetRandoCheckByActorId(actorId); + if (randoCheckId == RC_UNKNOWN || RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) { + return; + } + + SpawnEnemyDrop(position, foundActor, randoCheckId); + *should = false; + }); + + COND_ID_HOOK(OnActorKill, ACTOR_EN_SW, IS_RANDO, [](Actor* actor) { + if (!ENSW_GET_3(actor)) { + RandoCheckId randoCheckId = GetRandoCheckByActorId(ACTOR_EN_SW); + if (RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) { + return; + } + + SpawnEnemyDrop(actor->world.pos, actor, randoCheckId); + } + }); + + COND_VB_SHOULD(VB_DRAW_SLIME_RANDO_ITEM, IS_RANDO, { + if (RANDO_SAVE_OPTIONS[RO_SHUFFLE_ENEMY_DROPS] == RO_GENERIC_OFF) { + return; + } + + EnSlime* slime = va_arg(args, EnSlime*); + RandoCheckId randoCheckId = GetRandoCheckByActorId(ACTOR_EN_SLIME); + if (RANDO_SAVE_CHECKS[randoCheckId].cycleObtained) { + return; + } + RandoItemId randoItemId = Rando::ConvertItem(RANDO_SAVE_CHECKS[randoCheckId].randoItemId); + + Matrix_RotateYS(slime->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(0.25f, 0.25f, 0.25f, MTXMODE_APPLY); + Rando::DrawItem(randoItemId); + + *should = false; + }); +} diff --git a/mm/2s2h/Rando/CheckTracker/CheckTracker.cpp b/mm/2s2h/Rando/CheckTracker/CheckTracker.cpp index b93807f88..48dfddb94 100644 --- a/mm/2s2h/Rando/CheckTracker/CheckTracker.cpp +++ b/mm/2s2h/Rando/CheckTracker/CheckTracker.cpp @@ -68,6 +68,7 @@ std::vector<const char*> checkTypeIconList = { /*RCTYPE_CHEST*/ gChestTrackerIcon, /*RCTYPE_COW*/ gItemIconRomaniMaskTex, /*RCTYPE_CRATE*/ gCrateTrackerIcon, + /*RCTYPE_ENEMY_DROP*/ gDungeonMapSkullTex, /*RCTYPE_FREESTANDING*/ gRupeeCounterIconTex, /*RCTYPE_FROG*/ gItemIconDonGeroMaskTex, /*RCTYPE_GRASS*/ gameplay_keep_Tex_053140, @@ -375,6 +376,9 @@ void CheckTrackerDrawNonLogicalList() { ImGui::Separator(); ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0, 0, 0, 0)); std::string headerText = Ship_GetSceneName(sceneId); + if (sceneId == SCENE_SPOT00) { + headerText = "Various Regions"; + } headerText += " (" + std::to_string(obtainedCheckSum) + "/" + std::to_string(unfilteredChecks.size()) + ")"; ImGui::PushStyleColor(ImGuiCol_Text, obtainedCheckSum == unfilteredChecks.size() diff --git a/mm/2s2h/Rando/Logic/Logic.cpp b/mm/2s2h/Rando/Logic/Logic.cpp index b76397557..11958e09b 100644 --- a/mm/2s2h/Rando/Logic/Logic.cpp +++ b/mm/2s2h/Rando/Logic/Logic.cpp @@ -72,6 +72,10 @@ static RegisterShipInitFunc initFunc([]() { EXIT(ENTRANCE(ZORA_CAPE, 6), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_ZORA_CAPE)), EXIT(ENTRANCE(IKANA_CANYON, 4), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_IKANA_CANYON)), EXIT(ENTRANCE(STONE_TOWER, 3), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_STONE_TOWER)), + EXIT(ENTRANCE(CUTSCENE, 0), ONE_WAY_EXIT, true), // Enemy Drop Region + }, + .connections = { + CONNECTION(RR_MISCELLANEOUS, true), // Enemy Drop Region }, }; }, {}); diff --git a/mm/2s2h/Rando/Logic/Logic.h b/mm/2s2h/Rando/Logic/Logic.h index adde65a4c..2c0ed8db3 100644 --- a/mm/2s2h/Rando/Logic/Logic.h +++ b/mm/2s2h/Rando/Logic/Logic.h @@ -119,6 +119,17 @@ extern std::map<RandoRegionId, RandoRegion> Regions; } \ } +inline bool CanReachRegions(std::vector<RandoRegionId> regionList) { + std::set<RandoRegionId> reachableRegions; + FindReachableRegions(GetRegionIdFromEntrance(gSaveContext.save.entrance), reachableRegions); + for (auto& target : regionList) { + if (reachableRegions.count(target) > 0) { + return true; + } + } + return false; +} + inline std::string LogicString(std::string condition) { if (condition == "true") return ""; @@ -214,7 +225,7 @@ inline bool CanKillEnemy(ActorId EnemyId) { return (HAS_ITEM(ITEM_BOW) && (CAN_BE_DEKU || CAN_USE_EXPLOSIVE || CAN_BE_GORON)); case ACTOR_EN_BIGSLIME: // Great Bay Gekko return (CAN_USE_MAGIC_ARROW(ICE)); - case ACTOR_EN_SW: // Gold Skulltula + case ACTOR_EN_SW: // Gold Skulltula & Skullwalltula return (CAN_USE_PROJECTILE || CAN_BE_DEKU || CAN_BE_GORON || CAN_USE_HUMAN_SWORD || CAN_USE_EXPLOSIVE); case ACTOR_EN_DINOFOS: // Dinofos return (CAN_USE_SWORD || CAN_BE_GORON || HAS_ITEM(ITEM_BOW) || (CAN_BE_DEKU && HAS_MAGIC)); @@ -244,6 +255,75 @@ inline bool CanKillEnemy(ActorId EnemyId) { CAN_USE_EXPLOSIVE || HAS_ITEM(ITEM_DEKU_STICK)); case ACTOR_OBJ_SNOWBALL: // Large Snowball return (CAN_USE_EXPLOSIVE || CAN_BE_GORON || CAN_USE_MAGIC_ARROW(FIRE)); + case ACTOR_EN_AM: // Armos + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_BE_DEKU || CAN_USE_EXPLOSIVE); + case ACTOR_EN_VM: // Beamos + return (CAN_USE_EXPLOSIVE); + case ACTOR_EN_BB: // Blue Bubble + case ACTOR_EN_BBFALL: // Red Bubble + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_RAT: // Real Bombchu + case ACTOR_EN_TUBO_TRAP: // Flying Pot + return true; + case ACTOR_EN_FAMOS: // Death Armos + return (CAN_USE_MAGIC_ARROW(LIGHT)); + case ACTOR_EN_DODONGO: // Dodongo + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC)); + case ACTOR_EN_FLOORMAS: // Floormaster + case ACTOR_EN_WALLMAS: // Wallmaster + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_FZ: // Freezard + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_USE_MAGIC_ARROW(FIRE) || + HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_CROW: // Guay (Generic, excludes the one circling Clock Town En_Ruppecrow) + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_BE_DEKU || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK) || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_FIREFLY: // Keese + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_BE_DEKU || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK) || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_RR: // Like Like + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_DEKUNUTS: // Mad Scrub + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_BE_DEKU || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK) || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_KAREBABA: // Wilted/Mini Babas + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_BE_DEKU); + case ACTOR_EN_PEEHAT: // Peahat + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || CAN_BE_DEKU || HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_RD: // Redead & Gibdos + return (CAN_USE_SWORD || CAN_BE_DEKU || CAN_BE_GORON || CAN_BE_ZORA || HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_SKB: // Stalchild + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK) || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_TITE: // Tektite + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW)); + case ACTOR_EN_SLIME: // Chuchus + return (CAN_USE_SWORD || CAN_BE_ZORA || CAN_BE_DEKU || HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_SNOWMAN: // Eeno + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK) || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_WDHAND: // Dexihand (Basic kill method, seems like a pain to require other things) + return (CAN_BE_ZORA && HAS_MAGIC); + case ACTOR_EN_KAME: // Snapper (non Gekko Miniboss) + return (CAN_BE_DEKU || CAN_USE_EXPLOSIVE || CAN_BE_GORON); + case ACTOR_EN_SB: // Shellblade + return (CAN_BE_ZORA && HAS_MAGIC); + case ACTOR_EN_OKUTA: // Octorok + return (CAN_USE_PROJECTILE); + case ACTOR_EN_BAGUO: // Nejiron + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_NEO_REEBA: // Leever + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK)); + case ACTOR_EN_PP: + return (CAN_USE_SWORD || CAN_BE_GORON || CAN_BE_ZORA || (CAN_BE_DEKU && HAS_MAGIC) || HAS_ITEM(ITEM_BOW) || + HAS_ITEM(ITEM_DEKU_STICK) || HAS_ITEM(ITEM_HOOKSHOT)); + case ACTOR_EN_PR2: + return (CAN_BE_ZORA && HAS_MAGIC); + case ACTOR_BOSS_05: // Bio Deku Baba + return CAN_BE_ZORA && CAN_USE_ABILITY(SWIM); default: // Incorrect actor ID inputed. assert(false); return false; diff --git a/mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp b/mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp new file mode 100644 index 000000000..80b187a72 --- /dev/null +++ b/mm/2s2h/Rando/Logic/Regions/Miscellaneous.cpp @@ -0,0 +1,51 @@ +#include "2s2h/GameInteractor/GameInteractor.h" +#include "2s2h/ShipInit.hpp" + +#include "2s2h/Rando/Logic/Logic.h" + +using namespace Rando::Logic; + +// clang-format off +static RegisterShipInitFunc initFunc([]() { + Regions[RR_MISCELLANEOUS] = RandoRegion{ .name = "Various Regions", .sceneId = SCENE_SPOT00, + .checks = { + CHECK(RC_ENEMY_DROP_ARMOS, CanKillEnemy(ACTOR_EN_AM) && CanReachRegions({ RR_STONE_TOWER_TEMPLE_ARMOS_ROOM })), + CHECK(RC_ENEMY_DROP_BEAMOS, CanKillEnemy(ACTOR_EN_VM) && CanReachRegions({ RR_STONE_TOWER_BOTTOM, RR_STONE_TOWER_MIDDLE, RR_STONE_TOWER_TEMPLE_SHALLOW_POOL_ROOM })), + CHECK(RC_ENEMY_DROP_BLUE_BUBBLE, CanKillEnemy(ACTOR_EN_BB) && CanReachRegions({ RR_TERMINA_FIELD, RR_ROAD_TO_IKANA_FIELD_SIDE, RR_ROAD_TO_IKANA_BELOW_LEDGE, RR_IKANA_CASTLE_BUBBLE_ROOM, RR_STONE_TOWER_TEMPLE_INVERTED_PATH_TO_GOMESS })), + CHECK(RC_ENEMY_DROP_BIO_DEKU_BABA, CanKillEnemy(ACTOR_BOSS_05) && CanReachRegions({ RR_TERMINA_FIELD_BIO_BABA_GROTTO, RR_STONE_TOWER_TEMPLE_DEEP_POOL_ROOM, RR_GREAT_BAY_TEMPLE_COMPASS_ROOM, RR_GREAT_BAY_TEMPLE_BABA_CHEST_ROOM })), + CHECK(RC_ENEMY_DROP_BOMBCHU, CanKillEnemy(ACTOR_EN_RAT) && CanReachRegions({ RR_TERMINA_FIELD, RR_ROAD_TO_IKANA_FIELD_SIDE, RR_ROAD_TO_IKANA_BELOW_LEDGE, RR_SNOWHEAD_TEMPLE_MAP_ROOM_LOWER, RR_STONE_TOWER_TEMPLE_LAVA_WIND_ROOM, RR_GREAT_BAY_TEMPLE_COMPASS_ROOM, RR_GREAT_BAY_TEMPLE_GREEN_PIPE_3 })), + CHECK(RC_ENEMY_DROP_CHU, CanKillEnemy(ACTOR_EN_SLIME) && CanReachRegions({ RR_TERMINA_FIELD, RR_ROAD_TO_SOUTHERN_SWAMP, RR_GREAT_BAY_TEMPLE_BEFORE_WART, RR_GREAT_BAY_TEMPLE_GREEN_PIPE_3, RR_STONE_TOWER_TEMPLE_INVERTED_BLOCK_FLIP_ROOM })), + CHECK(RC_ENEMY_DROP_DEATH_ARMOS, CanKillEnemy(ACTOR_EN_FAMOS) && CanReachRegions({ RR_STONE_TOWER_TEMPLE_INVERTED_SIDE_OF_ENTRANCE, RR_STONE_TOWER_TEMPLE_INVERTED_POE_ROOM })), + CHECK(RC_ENEMY_DROP_DEKU_BABA, CanKillEnemy(ACTOR_EN_DEKUBABA) && CanReachRegions({ RR_TERMINA_FIELD, RR_ROAD_TO_SOUTHERN_SWAMP, RR_SOUTHERN_SWAMP_SOUTH, RR_WOODFALL, RR_WOODFALL_TEMPLE_MAIN_ROOM, RR_WOODFALL_TEMPLE_MAZE_ROOM, RR_BENEATH_THE_WELL_BABA_AND_POTS_ROOM, RR_SAKON_HIDEOUT })), + CHECK(RC_ENEMY_DROP_DODONGO, CanKillEnemy(ACTOR_EN_DODONGO) && CanReachRegions({ RR_TERMINA_FIELD, RR_TERMINA_FIELD_DODONGO_GROTTO })), + CHECK(RC_ENEMY_DROP_DRAGONFLY, CanKillEnemy(ACTOR_EN_GRASSHOPPER) && CanReachRegions({ RR_SOUTHERN_SWAMP_SOUTH, RR_WOODFALL, RR_STONE_TOWER_TEMPLE_ENTRANCE, RR_STONE_TOWER_TEMPLE_OUTSIDE_SWITCH_ROOM, RR_WOODFALL_TEMPLE_PRE_BOSS_ROOM, RR_WOODFALL_TEMPLE_MAIN_ROOM_UPPER })), + CHECK(RC_ENEMY_DROP_EENO, CanKillEnemy(ACTOR_EN_SNOWMAN) && CanReachRegions({ RR_TERMINA_FIELD, RR_SNOWHEAD_TEMPLE_SNOW_ROOM })), + CHECK(RC_ENEMY_DROP_FLYING_POT, CanKillEnemy(ACTOR_EN_TUBO_TRAP) && CanReachRegions({ RR_STONE_TOWER_TEMPLE_INVERTED_UNDER_BRIDGE, RR_SNOWHEAD_TEMPLE_BLOCK_ROOM })), + CHECK(RC_ENEMY_DROP_FLOORMASTER, CanKillEnemy(ACTOR_EN_FLOORMAS) && CanReachRegions({ RR_IKANA_CASTLE_FLOORMASTER_ROOM })), + CHECK(RC_ENEMY_DROP_FREEZARD, CanKillEnemy(ACTOR_EN_FZ) && CanReachRegions({ RR_SNOWHEAD_TEMPLE_BRIDGE_ROOM_AFTER, RR_SNOWHEAD_TEMPLE_MAP_ROOM_UPPER, RR_SNOWHEAD_TEMPLE_PILLARS_ROOM_UPPER, RR_BENEATH_THE_WELL_FREEZARD_ROOM })), + CHECK(RC_ENEMY_DROP_GUAY, CanKillEnemy(ACTOR_EN_CROW) && CanReachRegions({ RR_IKANA_CANYON_UPPER, RR_IKANA_CASTLE_COURTYARD, RR_PATH_TO_GORON_VILLAGE, RR_IKANA_CASTLE_COURTYARD, RR_ZORA_CAPE }) || (CanReachRegions({ RR_MOUNTAIN_VILLAGE, RR_PATH_TO_GORON_VILLAGE }) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE])), + CHECK(RC_ENEMY_DROP_HIPLOOP, CanKillEnemy(ACTOR_EN_PP) && CanReachRegions({ RR_WOODFALL, RR_STONE_TOWER_TEMPLE_INVERTED_WIND_ROOM, RR_STONE_TOWER_TEMPLE_SPIKED_BAR_ROOM_UPPER })), + CHECK(RC_ENEMY_DROP_IRON_KNUCKLE, CanKillEnemy(ACTOR_EN_IK) && CanReachRegions({ RR_BENEATH_THE_GRAVEYARD_NIGHT_1_BOSS, RR_BENEATH_THE_GRAVEYARD_NIGHT_2_BOSS, RR_MOON_LINK_TRIAL })), + CHECK(RC_ENEMY_DROP_KEESE, CanKillEnemy(ACTOR_EN_FIREFLY) && CanReachRegions({ RR_TERMINA_FIELD, RR_STONE_TOWER_TOP, RR_STONE_TOWER_UPPER, RR_STONE_TOWER_MIDDLE, RR_BENEATH_THE_WELL_LEFT_FIRE_KEESE, RR_BENEATH_THE_WELL_RIGHT_FIRE_KEESE, RR_BENEATH_THE_WELL_FREEZARD_ROOM, RR_BENEATH_THE_GRAVEYARD_NIGHT_2_GRAVE_BEFORE_PIT, RR_SNOWHEAD_NEAR_TEMPLE, RR_PATH_TO_SNOWHEAD_LOWER, RR_PATH_TO_SNOWHEAD_MIDDLE })), + CHECK(RC_ENEMY_DROP_LEEVER, CanKillEnemy(ACTOR_EN_NEO_REEBA) && CanReachRegions({ RR_TERMINA_FIELD, RR_GREAT_BAY_COAST, RR_ZORA_CAPE })), + CHECK(RC_ENEMY_DROP_LIKE_LIKE, CanKillEnemy(ACTOR_EN_RR) && CanReachRegions({ RR_ZORA_CAPE, RR_GREAT_BAY_COAST })), + CHECK(RC_ENEMY_DROP_MAD_SCRUB, CanKillEnemy(ACTOR_EN_DEKUNUTS) && CanReachRegions({ RR_WOODFALL, RR_DEKU_PALACE_INSIDE })), + CHECK(RC_ENEMY_DROP_MINI_BABA, CanKillEnemy(ACTOR_EN_KAREBABA) && CanReachRegions({ RR_SOUTHERN_SWAMP_NORTH, RR_SOUTHERN_SWAMP_NEAR_WOODS, RR_BENEATH_THE_WELL_BABA_AND_POTS_ROOM })), + CHECK(RC_ENEMY_DROP_NEJIRON, CanKillEnemy(ACTOR_EN_BAGUO) && CanReachRegions({ RR_ROAD_TO_IKANA_ABOVE_LEDGE, RR_STONE_TOWER_TEMPLE_MIRROR_PILLAR_ROOM })), + CHECK(RC_ENEMY_DROP_OCTOROK, CanKillEnemy(ACTOR_EN_OKUTA) && CanReachRegions({ RR_SOUTHERN_SWAMP_NORTH, RR_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART, RR_IKANA_CANYON_LOWER })), + CHECK(RC_ENEMY_DROP_PEAHAT, CanKillEnemy(ACTOR_EN_PEEHAT) && CanReachRegions({ RR_TERMINA_FIELD_PEAHAT_GROTTO })), + CHECK(RC_ENEMY_DROP_RED_BUBBLE, CanKillEnemy(ACTOR_EN_BBFALL) && CanReachRegions({ RR_SNOWHEAD_TEMPLE_CENTRAL_ROOM_BOTTOM })), + CHECK(RC_ENEMY_DROP_REDEAD_GIBDO, CanKillEnemy(ACTOR_EN_RD) && CanReachRegions({ RR_IKANA_CANYON_UPPER, RR_IKANA_CASTLE_FRONT_ENTRANCE, RR_STONE_TOWER_UPPER, RR_BENEATH_THE_WELL_ENTRANCE, RR_BENEATH_THE_WELL_THREE_SPIKED_BARS, RR_BENEATH_THE_WELL_TWO_SPIKED_BARS, RR_BENEATH_THE_WELL_FREEZARD_ROOM, RR_BENEATH_THE_WELL_RIGHT_FIRE_KEESE, RR_BENEATH_THE_WELL_BABA_AND_POTS_ROOM, RR_BENEATH_THE_WELL_FOUR_SPIKED_BARS })), + CHECK(RC_ENEMY_DROP_SHELLBLADE, CanKillEnemy(ACTOR_EN_SB) && CanReachRegions({ RR_PIRATES_FORTRESS_LEFT_CLAM_EGG_ROOM, RR_PIRATES_FORTRESS_RIGHT_CLAM_EGG_ROOM, RR_PIRATES_FORTRESS_CAPTAIN_ROOM, RR_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART })), + CHECK(RC_ENEMY_DROP_SKULLFISH, CanKillEnemy(ACTOR_EN_PR2) && CanReachRegions({ RR_GREAT_BAY_TEMPLE_MAP_ROOM, RR_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART, })), + CHECK(RC_ENEMY_DROP_SKULLTULA, CanKillEnemy(ACTOR_EN_ST) && CanReachRegions({ RR_ASTRAL_OBSERVATORY_PASSAGE, RR_WOODFALL_TEMPLE_MAZE_ROOM, RR_OCEAN_SPIDER_HOUSE_MEETING_ROOM, RR_BENEATH_THE_WELL_SKULLTULA_ROOM, RR_BENEATH_THE_WELL_FOUR_SPIKED_BARS, RR_BENEATH_THE_GRAVEYARD_NIGHT_1_GRAVE, RR_GREAT_BAY_TEMPLE_WATER_WHEEL_ROOM, RR_IKANA_CASTLE_SKULLTULA_ROOM })), + CHECK(RC_ENEMY_DROP_SKULLWALLTULA, CanKillEnemy(ACTOR_EN_SW) && CanReachRegions({ RR_TERMINA_FIELD_GOSSIP_STONE_GROTTO_1, RR_LONE_PEAK_SHRINE })), + CHECK(RC_ENEMY_DROP_SNAPPER, CanKillEnemy(ACTOR_EN_KAME) && CanReachRegions({ RR_WOODS_OF_MYSTERY, RR_WOODFALL_TEMPLE_MAP_ROOM })), + CHECK(RC_ENEMY_DROP_STALCHILD, CanKillEnemy(ACTOR_EN_SKB) && CanReachRegions({ RR_IKANA_GRAVEYARD_LOWER, RR_OCEAN_SPIDER_HOUSE_LIBRARY_ROOM, RR_OCEAN_SPIDER_HOUSE_MEETING_ROOM })), + CHECK(RC_ENEMY_DROP_TEKTITE, CanKillEnemy(ACTOR_EN_TITE) && CanReachRegions({ RR_GORON_VILLAGE, RR_PATH_TO_MOUNTAIN_VILLAGE_LOWER, RR_PATH_TO_GORON_VILLAGE, RR_GREAT_BAY_TEMPLE_GREEN_PIPE_1 })), + CHECK(RC_ENEMY_DROP_WOLFOS, CanKillEnemy(ACTOR_EN_WF) && CanReachRegions({ RR_ROAD_TO_SOUTHERN_SWAMP, RR_PATH_TO_GORON_VILLAGE, RR_SNOWHEAD_TEMPLE_ENTRANCE_AFTER_BLOCK, RR_SNOWHEAD_NEAR_TEMPLE, RR_SNOWHEAD_TEMPLE_COMPASS_ROOM, RR_SAKON_HIDEOUT })), + CHECK(RC_ENEMY_DROP_WALLMASTER, CanKillEnemy(ACTOR_EN_WALLMAS) && CanReachRegions({ RR_BENEATH_THE_GRAVEYARD_DAMPE, RR_BENEATH_THE_WELL_FREEZARD_ROOM, RR_BENEATH_THE_WELL_LEFT_FIRE_KEESE, RR_BENEATH_THE_WELL_FOUR_SPIKED_BARS, RR_BENEATH_THE_WELL_TWO_SPIKED_BARS })), + }, + }; +}, {}); +// clang-format on
\ No newline at end of file diff --git a/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp b/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp index 53b4bcdfc..0eeb63bf6 100644 --- a/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp +++ b/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp @@ -487,7 +487,6 @@ static RegisterShipInitFunc initFunc([]() { CHECK(RC_TERMINA_FIELD_GRASS_214, true), CHECK(RC_TERMINA_FIELD_GRASS_215, true), CHECK(RC_TERMINA_FIELD_GRASS_216, true), - }, .exits = { // TO FROM EXIT(ENTRANCE(GROTTOS, 0), ENTRANCE(TERMINA_FIELD, 0), CAN_USE_EXPLOSIVE || CAN_BE_GORON), // TODO: Grotto mapping Gossip Stone #3 diff --git a/mm/2s2h/Rando/Menu.cpp b/mm/2s2h/Rando/Menu.cpp index 02554e8c5..4bc454904 100644 --- a/mm/2s2h/Rando/Menu.cpp +++ b/mm/2s2h/Rando/Menu.cpp @@ -323,6 +323,8 @@ static void DrawItemsTab() { "that must be found in order for their corresponding boss to spawn.", .disabled = IncompatibleWithLogicSetting(RO_SHUFFLE_BOSS_SOULS), .disabledTooltip = "Incompatible with current Logic Setting" } })); + CVarCheckbox("Enemy Drops", Rando::StaticData::Options[RO_SHUFFLE_ENEMY_DROPS].cvar, + CheckboxOptions({ { .tooltip = "Shuffles the first drop from a non Boss Enemy." } })); CVarCheckbox("Enemy Souls", "gPlaceholderBool", CheckboxOptions({ { .disabled = true, .disabledTooltip = "Coming Soon" } })); ImGui::EndChild(); diff --git a/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp b/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp index b87d7d01a..42e712ac5 100644 --- a/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp +++ b/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp @@ -183,6 +183,11 @@ void Rando::MiscBehavior::OnFileCreate(s16 fileNum) { continue; } + if (randoStaticCheck.randoCheckType == RCTYPE_ENEMY_DROP && + RANDO_SAVE_OPTIONS[RO_SHUFFLE_ENEMY_DROPS] == RO_GENERIC_NO) { + continue; + } + if (randoStaticCheck.randoCheckType == RCTYPE_TINGLE_SHOP && RANDO_SAVE_OPTIONS[RO_SHUFFLE_TINGLE_SHOPS] == RO_GENERIC_NO) { continue; diff --git a/mm/2s2h/Rando/StaticData/Checks.cpp b/mm/2s2h/Rando/StaticData/Checks.cpp index e6c7a9cee..4c2e84b80 100644 --- a/mm/2s2h/Rando/StaticData/Checks.cpp +++ b/mm/2s2h/Rando/StaticData/Checks.cpp @@ -2230,6 +2230,43 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = { RC(RC_ZORA_CAPE_GROTTO_GRASS_13, RCTYPE_GRASS, SCENE_KAKUSIANA, FLAG_NONE, 0x0, RI_JUNK), RC(RC_ZORA_CAPE_GROTTO_GRASS_14, RCTYPE_GRASS, SCENE_KAKUSIANA, FLAG_NONE, 0x0, RI_JUNK), + // Enemy Drops + RC(RC_ENEMY_DROP_ARMOS, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_BEAMOS, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_BIO_DEKU_BABA, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_BLUE_BUBBLE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_BOMBCHU, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_CHU, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_DEATH_ARMOS, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_DEKU_BABA, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_DODONGO, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_DRAGONFLY, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_EENO, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_FLYING_POT, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_FLOORMASTER, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_FREEZARD, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_GUAY, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_HIPLOOP, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_IRON_KNUCKLE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_KEESE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_LEEVER, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_LIKE_LIKE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_MAD_SCRUB, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_MINI_BABA, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_NEJIRON, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_OCTOROK, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_PEAHAT, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_RED_BUBBLE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_REDEAD_GIBDO, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_SHELLBLADE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_SKULLFISH, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_SKULLTULA, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_SKULLWALLTULA, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_SNAPPER, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_STALCHILD, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_TEKTITE, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_WOLFOS, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), + RC(RC_ENEMY_DROP_WALLMASTER, RCTYPE_ENEMY_DROP, SCENE_SPOT00, FLAG_NONE, 0x0, RI_JUNK), }; // clang-format on diff --git a/mm/2s2h/Rando/StaticData/Options.cpp b/mm/2s2h/Rando/StaticData/Options.cpp index 1f42b8930..b7d40747f 100644 --- a/mm/2s2h/Rando/StaticData/Options.cpp +++ b/mm/2s2h/Rando/StaticData/Options.cpp @@ -31,6 +31,7 @@ std::map<RandoOptionId, RandoStaticOption> Options = { RO(RO_SHUFFLE_BOSS_SOULS, RO_GENERIC_OFF), RO(RO_SHUFFLE_COWS, RO_GENERIC_OFF), RO(RO_SHUFFLE_CRATE_DROPS, RO_GENERIC_OFF), + RO(RO_SHUFFLE_ENEMY_DROPS, RO_GENERIC_OFF), RO(RO_SHUFFLE_FREESTANDING_ITEMS, RO_GENERIC_OFF), RO(RO_SHUFFLE_FROGS, RO_GENERIC_OFF), RO(RO_SHUFFLE_GOLD_SKULLTULAS, RO_GENERIC_OFF), diff --git a/mm/2s2h/Rando/Types.h b/mm/2s2h/Rando/Types.h index e236fbe02..8841137d7 100644 --- a/mm/2s2h/Rando/Types.h +++ b/mm/2s2h/Rando/Types.h @@ -7,6 +7,7 @@ typedef enum { RCTYPE_CHEST, RCTYPE_COW, RCTYPE_CRATE, + RCTYPE_ENEMY_DROP, RCTYPE_FREESTANDING, RCTYPE_FROG, RCTYPE_GRASS, @@ -2234,6 +2235,43 @@ typedef enum { RC_ZORA_CAPE_GROTTO_GRASS_13, RC_ZORA_CAPE_GROTTO_GRASS_14, + RC_ENEMY_DROP_ARMOS, + RC_ENEMY_DROP_BEAMOS, + RC_ENEMY_DROP_BIO_DEKU_BABA, + RC_ENEMY_DROP_BLUE_BUBBLE, + RC_ENEMY_DROP_BOMBCHU, + RC_ENEMY_DROP_CHU, + RC_ENEMY_DROP_DEATH_ARMOS, + RC_ENEMY_DROP_DEKU_BABA, + RC_ENEMY_DROP_DODONGO, + RC_ENEMY_DROP_DRAGONFLY, + RC_ENEMY_DROP_EENO, + RC_ENEMY_DROP_FLYING_POT, + RC_ENEMY_DROP_FLOORMASTER, + RC_ENEMY_DROP_FREEZARD, + RC_ENEMY_DROP_GUAY, + RC_ENEMY_DROP_HIPLOOP, + RC_ENEMY_DROP_IRON_KNUCKLE, + RC_ENEMY_DROP_KEESE, + RC_ENEMY_DROP_LEEVER, + RC_ENEMY_DROP_LIKE_LIKE, + RC_ENEMY_DROP_MAD_SCRUB, + RC_ENEMY_DROP_MINI_BABA, + RC_ENEMY_DROP_NEJIRON, + RC_ENEMY_DROP_OCTOROK, + RC_ENEMY_DROP_PEAHAT, + RC_ENEMY_DROP_RED_BUBBLE, + RC_ENEMY_DROP_REDEAD_GIBDO, + RC_ENEMY_DROP_SHELLBLADE, + RC_ENEMY_DROP_SKULLFISH, + RC_ENEMY_DROP_SKULLTULA, + RC_ENEMY_DROP_SKULLWALLTULA, + RC_ENEMY_DROP_SNAPPER, + RC_ENEMY_DROP_STALCHILD, + RC_ENEMY_DROP_TEKTITE, + RC_ENEMY_DROP_WOLFOS, + RC_ENEMY_DROP_WALLMASTER, + RC_MAX, } RandoCheckId; @@ -2537,6 +2575,7 @@ typedef enum { RR_MAGIC_HAGS_POTION_SHOP, RR_MARINE_RESEARCH_LAB, RR_MAYOR_RESIDENCE, + RR_MISCELLANEOUS, RR_MILK_BAR, RR_MILK_ROAD, RR_MOON_DEKU_TRIAL, @@ -2754,6 +2793,7 @@ typedef enum { RO_SHUFFLE_BOSS_SOULS, RO_SHUFFLE_COWS, RO_SHUFFLE_CRATE_DROPS, + RO_SHUFFLE_ENEMY_DROPS, RO_SHUFFLE_FREESTANDING_ITEMS, RO_SHUFFLE_FROGS, RO_SHUFFLE_GRASS_DROPS, diff --git a/mm/src/code/z_en_item00.c b/mm/src/code/z_en_item00.c index ec357c076..12233a36f 100644 --- a/mm/src/code/z_en_item00.c +++ b/mm/src/code/z_en_item00.c @@ -918,6 +918,10 @@ s16 func_800A7650(s16 dropId) { } Actor* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, u32 params) { + if (!(GameInteractor_Should(VB_ENEMY_DROP_COLLECTIBLE, true, *spawnPos))) { + return; + } + s32 pad; Actor* spawnedActor = NULL; s32 newParamFF; @@ -1333,6 +1337,10 @@ u8 sDropTableAmounts[DROP_TABLE_SIZE * DROP_TABLE_NUMBER] = { }; void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnPos, s16 params) { + if (!(GameInteractor_Should(VB_ENEMY_DROP_COLLECTIBLE, true, *spawnPos))) { + return; + } + EnItem00* spawnedActor; u8 dropId; s32 dropQuantity; diff --git a/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c b/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c index abe8498d8..eaa0a11e1 100644 --- a/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c +++ b/mm/src/overlays/actors/ovl_En_Slime/z_en_slime.c @@ -1245,12 +1245,14 @@ void EnSlime_Draw(Actor* thisx, PlayState* play) { Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + (2000.0f * this->actor.scale.y), this->actor.world.pos.z, MTXMODE_NEW); - if (GameInteractor_Should(VB_DRAW_SLIME_BODY_ITEM, true, this)) { - Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY); + if (GameInteractor_Should(VB_DRAW_SLIME_RANDO_ITEM, true, this)) { + if (GameInteractor_Should(VB_DRAW_SLIME_BODY_ITEM, true, this)) { + Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY); - gSPSegment(POLY_OPA_DISP++, 0x08, this->itemDropTex); - MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, gItemDropDL); + gSPSegment(POLY_OPA_DISP++, 8, (uintptr_t)this->itemDropTex); + MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, gItemDropDL); + } } } |
