summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaladius <Caladius@users.noreply.github.com>2025-10-15 12:39:07 -0400
committerGitHub <noreply@github.com>2025-10-15 12:39:07 -0400
commitda767c966d1102fa2dfe8f78627400ab23f4634c (patch)
treeaf78ae7191c499b00f4808d86c7d318b724db46b
parentf2ae53313b2ca4046743d0d6befa09a325129888 (diff)
[Rando] Shuffle Swim (#1087)
* Shuffle Swim + Central Logic * East Logic * Great Bay Temple (hopefully) * North Logic * Pirates Logic (Hopefully) * South Logic * West Logic * Fix Termina Field Logic * Fix Great Bay Temple Logic * Feedback Changes * Split Southern Swamp North * Update Swamp and GBC logic * missed one * Feedback Updates * fix syntax * Split Marine Lab Exterior from GBC * replace Bronze Scale wording in Menu. * Additional logic pass for swim ability * Mimic Deku hop failure event when touching water Separate Woodfall owl statue platform into own region * Import Model * Add to 2ship.o2r * Add Model Selector * Update Model * Clean remove model for replacement * Import new model extract from Dana * Testing * pathing change * Pushing for someone to look at the model crash issue. * Enable DrawAbilityItem to take in multiple items when more get added. This is ready to go. * Feedback Changes * clang * Revert "clang" This reverts commit e09482f8b83c39f4678a9c349ed9061f2e002251. * Undo clang for once lol * Do not skip pushing Mikau if no swim ability * How did I mess that up * Fix changes * clang bullsh*t --------- Co-authored-by: Eblo <7004497+Eblo@users.noreply.github.com>
-rw-r--r--mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipPushingMikau.cpp6
-rw-r--r--mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp1
-rw-r--r--mm/2s2h/Rando/ActorBehavior/ActorBehavior.h1
-rw-r--r--mm/2s2h/Rando/ActorBehavior/Player.cpp33
-rw-r--r--mm/2s2h/Rando/ConvertItem.cpp1
-rw-r--r--mm/2s2h/Rando/DrawItem.cpp20
-rw-r--r--mm/2s2h/Rando/GiveItem.cpp3
-rw-r--r--mm/2s2h/Rando/Logic/Logic.cpp1
-rw-r--r--mm/2s2h/Rando/Logic/Logic.h1
-rw-r--r--mm/2s2h/Rando/Logic/Regions/Central.cpp6
-rw-r--r--mm/2s2h/Rando/Logic/Regions/East.cpp18
-rw-r--r--mm/2s2h/Rando/Logic/Regions/GreatBayTemple.cpp88
-rw-r--r--mm/2s2h/Rando/Logic/Regions/North.cpp12
-rw-r--r--mm/2s2h/Rando/Logic/Regions/PiratesFortress.cpp48
-rw-r--r--mm/2s2h/Rando/Logic/Regions/South.cpp125
-rw-r--r--mm/2s2h/Rando/Logic/Regions/TerminaField.cpp4
-rw-r--r--mm/2s2h/Rando/Logic/Regions/West.cpp89
-rw-r--r--mm/2s2h/Rando/Menu.cpp5
-rw-r--r--mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp4
-rw-r--r--mm/2s2h/Rando/StaticData/Items.cpp1
-rw-r--r--mm/2s2h/Rando/StaticData/Options.cpp1
-rw-r--r--mm/2s2h/Rando/Types.h9
-rw-r--r--mm/assets/2s2h_assets.h3
-rw-r--r--mm/assets/custom/objects/object_ability_swim/flippersbin0 -> 604 bytes
-rw-r--r--mm/assets/custom/objects/object_ability_swim/flippers2bin0 -> 604 bytes
-rw-r--r--mm/assets/custom/objects/object_ability_swim/gGiFlippersDL13
-rw-r--r--mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_0171
-rw-r--r--mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_141
-rw-r--r--mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_0233
-rw-r--r--mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_173
-rw-r--r--mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers21
-rw-r--r--mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers221
32 files changed, 900 insertions, 153 deletions
diff --git a/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipPushingMikau.cpp b/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipPushingMikau.cpp
index 8c2c7d4c9..1eb1cd16f 100644
--- a/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipPushingMikau.cpp
+++ b/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipPushingMikau.cpp
@@ -1,6 +1,8 @@
#include "public/bridge/consolevariablebridge.h"
#include "2s2h/GameInteractor/GameInteractor.h"
#include "2s2h/ShipInit.hpp"
+#include "2s2h/Rando/Rando.h"
+#include "2s2h/Rando/Logic/Logic.h"
extern "C" {
#include "functions.h"
@@ -11,6 +13,10 @@ extern "C" {
void RegisterSkipPushingMikau() {
COND_ID_HOOK(ShouldActorInit, ACTOR_EN_ZOG, CVAR, [](Actor* actor, bool* should) {
+ if (IS_RANDO && !CAN_USE_ABILITY(SWIM)) {
+ // This skip would circumvent logical requirements if the player cannot swim yet
+ return;
+ }
Flags_SetWeekEventReg(WEEKEVENTREG_88_10);
Flags_SetWeekEventReg(WEEKEVENTREG_29_20);
Flags_SetWeekEventReg(WEEKEVENTREG_91_01);
diff --git a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
index 6aa041370..75af9964f 100644
--- a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
+++ b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
@@ -139,6 +139,7 @@ void Rando::ActorBehavior::OnFileLoad() {
Rando::ActorBehavior::InitObjTaruBehavior();
Rando::ActorBehavior::InitObjTsuboBehavior();
Rando::ActorBehavior::InitObjWarpstoneBehavior();
+ Rando::ActorBehavior::InitPlayerBehavior();
Rando::ActorBehavior::InitSoulsBehavior();
COND_HOOK(ShouldVanillaBehavior, IS_RANDO, MiscVanillaBehaviorHandler);
diff --git a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
index 3d0727cbc..f1ec06fe4 100644
--- a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
+++ b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
@@ -95,6 +95,7 @@ void InitObjSnowballBehavior();
void InitObjTaruBehavior();
void InitObjTsuboBehavior();
void InitObjWarpstoneBehavior();
+void InitPlayerBehavior();
void InitSoulsBehavior();
} // namespace ActorBehavior
diff --git a/mm/2s2h/Rando/ActorBehavior/Player.cpp b/mm/2s2h/Rando/ActorBehavior/Player.cpp
new file mode 100644
index 000000000..b08bb384c
--- /dev/null
+++ b/mm/2s2h/Rando/ActorBehavior/Player.cpp
@@ -0,0 +1,33 @@
+#include "ActorBehavior.h"
+#include "public/bridge/consolevariablebridge.h"
+
+extern "C" {
+#include "variables.h"
+#include "functions.h"
+
+#include "include/z64player.h"
+extern s32 Player_SetAction(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 arg3);
+extern void Player_Action_1(Player* player, PlayState* play);
+}
+
+void RespawnOnWaterTouch(Player* player) {
+ // This is Honey & Darlings Shop, touching the water ends the minigame as its vanilla behavior.
+ // No reason to handle it a second time here.
+ if (gPlayState->sceneId == SCENE_BOWLING) {
+ return;
+ }
+
+ if (player->stateFlags1 & PLAYER_STATE1_8000000) {
+ // Mimic Deku Hop failure behavior
+ Player_SetAction(gPlayState, player, Player_Action_1, 0);
+ player->stateFlags1 |= PLAYER_STATE1_20000000;
+ }
+}
+
+void Rando::ActorBehavior::InitPlayerBehavior() {
+ COND_ID_HOOK(OnActorUpdate, ACTOR_PLAYER, IS_RANDO && RANDO_SAVE_OPTIONS[RO_SHUFFLE_SWIM], [](Actor* actor) {
+ if (!Flags_GetRandoInf(RANDO_INF_OBTAINED_SWIM)) {
+ RespawnOnWaterTouch(GET_PLAYER(gPlayState));
+ }
+ });
+}
diff --git a/mm/2s2h/Rando/ConvertItem.cpp b/mm/2s2h/Rando/ConvertItem.cpp
index 0c635b518..f2d7142fb 100644
--- a/mm/2s2h/Rando/ConvertItem.cpp
+++ b/mm/2s2h/Rando/ConvertItem.cpp
@@ -238,6 +238,7 @@ bool Rando::IsItemObtainable(RandoItemId randoItemId, RandoCheckId randoCheckId)
case RI_FROG_CYAN:
case RI_FROG_PINK:
case RI_FROG_WHITE:
+ case RI_ABILITY_SWIM:
if (hasObtainedCheck) {
return false;
}
diff --git a/mm/2s2h/Rando/DrawItem.cpp b/mm/2s2h/Rando/DrawItem.cpp
index 684e724a4..5fcfd13f5 100644
--- a/mm/2s2h/Rando/DrawItem.cpp
+++ b/mm/2s2h/Rando/DrawItem.cpp
@@ -2,6 +2,7 @@
#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
#include "2s2h/ShipInit.hpp"
#include "2s2h/Rando/DrawFuncs.h"
+#include "2s2h_assets.h"
extern "C" {
#include "variables.h"
@@ -296,6 +297,21 @@ void DrawSkulltulaToken(RandoItemId randoItemId, Actor* actor) {
CLOSE_DISPS(gPlayState->state.gfxCtx);
}
+void DrawAbilityItem(RandoItemId randoItemId, Actor* actor) {
+ Gfx* abilityItemModel[1] = {
+ (Gfx*)gGiFlippersDL,
+ };
+
+ OPEN_DISPS(gPlayState->state.gfxCtx);
+
+ Gfx_SetupDL25_Xlu(gPlayState->state.gfxCtx);
+
+ MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, gPlayState->state.gfxCtx);
+ gSPDisplayList(POLY_XLU_DISP++, (Gfx*)abilityItemModel[randoItemId - RI_ABILITY_SWIM]);
+
+ CLOSE_DISPS(gPlayState->state.gfxCtx);
+}
+
void DrawSparkles(RandoItemId randoItemId, Actor* actor) {
if (actor == NULL) {
return;
@@ -421,6 +437,9 @@ void Rando::DrawItem(RandoItemId randoItemId, Actor* actor) {
case RI_FROG_WHITE:
DrawMinifrog(randoItemId, actor);
break;
+ case RI_ABILITY_SWIM:
+ DrawAbilityItem(randoItemId, actor);
+ break;
case RI_NONE:
case RI_UNKNOWN:
break;
@@ -431,6 +450,7 @@ void Rando::DrawItem(RandoItemId randoItemId, Actor* actor) {
switch (randoItemId) {
case RI_NONE:
+ case RI_ABILITY_SWIM:
case RI_PROGRESSIVE_MAGIC:
case RI_SINGLE_MAGIC:
case RI_DOUBLE_MAGIC:
diff --git a/mm/2s2h/Rando/GiveItem.cpp b/mm/2s2h/Rando/GiveItem.cpp
index 8e0dfd3c7..44863637d 100644
--- a/mm/2s2h/Rando/GiveItem.cpp
+++ b/mm/2s2h/Rando/GiveItem.cpp
@@ -269,6 +269,9 @@ void Rando::GiveItem(RandoItemId randoItemId) {
case RI_FROG_WHITE:
SET_WEEKEVENTREG(WEEKEVENTREG_33_02);
break;
+ case RI_ABILITY_SWIM:
+ Flags_SetRandoInf(RANDO_INF_OBTAINED_SWIM);
+ break;
case RI_JUNK:
case RI_NONE:
break;
diff --git a/mm/2s2h/Rando/Logic/Logic.cpp b/mm/2s2h/Rando/Logic/Logic.cpp
index 005d98e34..80f10ff03 100644
--- a/mm/2s2h/Rando/Logic/Logic.cpp
+++ b/mm/2s2h/Rando/Logic/Logic.cpp
@@ -64,6 +64,7 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(SOUTH_CLOCK_TOWN, 0), ONE_WAY_EXIT, true), // Save warp
EXIT(ENTRANCE(SOUTH_CLOCK_TOWN, 9), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_CLOCK_TOWN)),
EXIT(ENTRANCE(SOUTHERN_SWAMP_POISONED, 10), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_SOUTHERN_SWAMP)),
+ EXIT(ENTRANCE(WOODFALL, 4), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_WOODFALL)),
EXIT(ENTRANCE(MILK_ROAD, 4), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_MILK_ROAD)),
EXIT(ENTRANCE(MOUNTAIN_VILLAGE_WINTER, 8), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_MOUNTAIN_VILLAGE)),
EXIT(ENTRANCE(SNOWHEAD, 3), ONE_WAY_EXIT, CAN_PLAY_SONG(SOARING) && CAN_OWL_WARP(OWL_WARP_SNOWHEAD)),
diff --git a/mm/2s2h/Rando/Logic/Logic.h b/mm/2s2h/Rando/Logic/Logic.h
index 617c3c961..f759cd51b 100644
--- a/mm/2s2h/Rando/Logic/Logic.h
+++ b/mm/2s2h/Rando/Logic/Logic.h
@@ -98,6 +98,7 @@ extern std::unordered_map<RandoRegionId, RandoRegion> Regions;
#define FOUND_ALL_FROGS \
(CHECK_WEEKEVENTREG(WEEKEVENTREG_33_01) && CHECK_WEEKEVENTREG(WEEKEVENTREG_32_40) && \
CHECK_WEEKEVENTREG(WEEKEVENTREG_32_80) && CHECK_WEEKEVENTREG(WEEKEVENTREG_33_02))
+#define CAN_USE_ABILITY(ability) (Flags_GetRandoInf(RI_ABILITY_##ability - RI_ABILITY_SWIM + RANDO_INF_OBTAINED_SWIM))
#define EVENT(randoEvent, condition) \
{ \
diff --git a/mm/2s2h/Rando/Logic/Regions/Central.cpp b/mm/2s2h/Rando/Logic/Regions/Central.cpp
index 54131e04d..6edd31d71 100644
--- a/mm/2s2h/Rando/Logic/Regions/Central.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/Central.cpp
@@ -120,9 +120,9 @@ static RegisterShipInitFunc initFunc([]() {
Regions[RR_CLOCK_TOWN_LAUNDRY] = RandoRegion{ .sceneId = SCENE_ALLEY,
.checks = {
CHECK(RC_CLOCK_TOWN_STRAY_FAIRY, true),
- CHECK(RC_CLOCK_TOWN_LAUNDRY_FREESTANDING_RUPEE_01, true),
- CHECK(RC_CLOCK_TOWN_LAUNDRY_FREESTANDING_RUPEE_02, true),
- CHECK(RC_CLOCK_TOWN_LAUNDRY_FREESTANDING_RUPEE_03, true),
+ CHECK(RC_CLOCK_TOWN_LAUNDRY_FREESTANDING_RUPEE_01, CAN_USE_ABILITY(SWIM) || CAN_BE_ZORA),
+ CHECK(RC_CLOCK_TOWN_LAUNDRY_FREESTANDING_RUPEE_02, CAN_USE_ABILITY(SWIM) || CAN_BE_ZORA),
+ CHECK(RC_CLOCK_TOWN_LAUNDRY_FREESTANDING_RUPEE_03, CAN_USE_ABILITY(SWIM) || CAN_BE_ZORA),
CHECK(RC_CLOCK_TOWN_LAUNDRY_FROG, HAS_ITEM(ITEM_MASK_DON_GERO)),
CHECK(RC_CLOCK_TOWN_LAUNDRY_GURU_GURU, true),
CHECK(RC_CLOCK_TOWN_LAUNDRY_SMALL_CRATE, true),
diff --git a/mm/2s2h/Rando/Logic/Regions/East.cpp b/mm/2s2h/Rando/Logic/Regions/East.cpp
index 3f5a1031e..465b0d0da 100644
--- a/mm/2s2h/Rando/Logic/Regions/East.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/East.cpp
@@ -146,12 +146,12 @@ static RegisterShipInitFunc initFunc([]() {
Must have delivered the Letter to Kafei and met Kafei.(Sakon just does not show up otherwise, as odd as that may sound.)
*/
EXIT(ENTRANCE(SAKONS_HIDEOUT, 0), ENTRANCE(IKANA_CANYON, 6), Flags_GetRandoInf(RANDO_INF_OBTAINED_LETTER_TO_KAFEI)),
- EXIT(ENTRANCE(SECRET_SHRINE, 0), ENTRANCE(IKANA_CANYON, 12), true),
- EXIT(ENTRANCE(SOUTHERN_SWAMP_POISONED, 9), ONE_WAY_EXIT, true),
+ EXIT(ENTRANCE(SECRET_SHRINE, 0), ENTRANCE(IKANA_CANYON, 12), CAN_USE_ABILITY(SWIM)),
+ EXIT(ENTRANCE(SOUTHERN_SWAMP_POISONED, 9), ONE_WAY_EXIT, CAN_USE_ABILITY(SWIM)),
},
.connections = {
CONNECTION(RR_IKANA_CANYON_UPPER, HAS_ITEM(ITEM_HOOKSHOT) && CAN_USE_MAGIC_ARROW(ICE)),
- CONNECTION(RR_IKANA_CANYON_GROTTO, true), // TODO: Grotto mapping
+ CONNECTION(RR_IKANA_CANYON_GROTTO, CAN_USE_ABILITY(SWIM)), // TODO: Grotto mapping
},
.events = {
EVENT(RE_ACCESS_BLUE_POTION_REFILL, CUR_UPG_VALUE(UPG_WALLET) >= 1),
@@ -363,12 +363,12 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_SECRET_SHRINE_WART_CHEST, RANDO_EVENTS[RE_SECRET_SHRINE_WART]),
CHECK(RC_SECRET_SHRINE_GARO_MASTER_CHEST, RANDO_EVENTS[RE_SECRET_SHRINE_GARO_MASTER]),
CHECK(RC_SECRET_SHRINE_PIECE_OF_HEART_CHEST, RANDO_EVENTS[RE_SECRET_SHRINE_DINALFOS] && RANDO_EVENTS[RE_SECRET_SHRINE_WIZZROBE] && RANDO_EVENTS[RE_SECRET_SHRINE_WART] && RANDO_EVENTS[RE_SECRET_SHRINE_GARO_MASTER]),
- CHECK(RC_SECRET_SHRINE_POT_04, CAN_BE_ZORA),
- CHECK(RC_SECRET_SHRINE_POT_05, CAN_BE_ZORA),
- CHECK(RC_SECRET_SHRINE_POT_06, CAN_BE_ZORA),
- CHECK(RC_SECRET_SHRINE_POT_07, CAN_BE_ZORA),
- CHECK(RC_SECRET_SHRINE_POT_08, CAN_BE_ZORA),
- CHECK(RC_SECRET_SHRINE_POT_09, CAN_BE_ZORA),
+ CHECK(RC_SECRET_SHRINE_POT_04, (CAN_USE_PROJECTILE && CAN_USE_ABILITY(SWIM)) || CAN_BE_ZORA),
+ CHECK(RC_SECRET_SHRINE_POT_05, (CAN_USE_PROJECTILE && CAN_USE_ABILITY(SWIM)) || CAN_BE_ZORA),
+ CHECK(RC_SECRET_SHRINE_POT_06, (CAN_USE_PROJECTILE && CAN_USE_ABILITY(SWIM)) || CAN_BE_ZORA),
+ CHECK(RC_SECRET_SHRINE_POT_07, (CAN_USE_PROJECTILE && CAN_USE_ABILITY(SWIM)) || CAN_BE_ZORA),
+ CHECK(RC_SECRET_SHRINE_POT_08, (CAN_USE_PROJECTILE && CAN_USE_ABILITY(SWIM)) || CAN_BE_ZORA),
+ CHECK(RC_SECRET_SHRINE_POT_09, (CAN_USE_PROJECTILE && CAN_USE_ABILITY(SWIM)) || CAN_BE_ZORA),
},
.connections = {
CONNECTION(RR_SECRET_SHRINE_ENTRANCE, true),
diff --git a/mm/2s2h/Rando/Logic/Regions/GreatBayTemple.cpp b/mm/2s2h/Rando/Logic/Regions/GreatBayTemple.cpp
index 975840f38..685c3fad9 100644
--- a/mm/2s2h/Rando/Logic/Regions/GreatBayTemple.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/GreatBayTemple.cpp
@@ -45,10 +45,10 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_BOSS_POT_02, true),
CHECK(RC_GREAT_BAY_TEMPLE_BOSS_POT_03, true),
CHECK(RC_GREAT_BAY_TEMPLE_BOSS_POT_04, true),
- CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_01, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_02, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_03, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_04, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_BOSS_UNDERWATER_POT_04, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_GIANTS_CHAMBER_OATH_TO_ORDER, CanKillEnemy(ACTOR_BOSS_03)),
},
.exits = { // TO FROM
@@ -66,14 +66,14 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_SF_CENTRAL_ROOM_BARREL, true),
CHECK(RC_GREAT_BAY_TEMPLE_CENTRAL_ROOM_POT_01, true),
CHECK(RC_GREAT_BAY_TEMPLE_CENTRAL_ROOM_POT_02, true),
- CHECK(RC_GREAT_BAY_TEMPLE_SF_CENTRAL_ROOM_UNDERWATER_POT, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_SF_CENTRAL_ROOM_UNDERWATER_POT, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM_TUNNEL, CAN_BE_ZORA && GBT_CAN_REVERSE_WATER_FLOW),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM_TUNNEL, CAN_BE_ZORA && GBT_CAN_REVERSE_WATER_FLOW && CAN_USE_ABILITY(SWIM)),
CONNECTION(RR_GREAT_BAY_TEMPLE_GREEN_PIPE_1, CAN_USE_MAGIC_ARROW(ICE)),
- CONNECTION(RR_GREAT_BAY_TEMPLE_MAP_ROOM, CAN_BE_ZORA),
- CONNECTION(RR_GREAT_BAY_TEMPLE_PRE_BOSS_ROOM, CAN_BE_ZORA && GBT_CAN_REVERSE_WATER_FLOW),
- CONNECTION(RR_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART, CAN_BE_ZORA),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_MAP_ROOM, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_PRE_BOSS_ROOM, CAN_BE_ZORA && GBT_CAN_REVERSE_WATER_FLOW && CAN_USE_ABILITY(SWIM)),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CONNECTION(RR_GREAT_BAY_TEMPLE_WATER_WHEEL_ROOM, true)
},
};
@@ -94,27 +94,27 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_TUNNEL_FREESTANDING_RUPEE_02, CAN_BE_ZORA),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA),
- CONNECTION(RR_GREAT_BAY_TEMPLE_GREEN_PIPE_2, GBT_CAN_REVERSE_WATER_FLOW),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_GREEN_PIPE_2, GBT_CAN_REVERSE_WATER_FLOW && CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_GREAT_BAY_TEMPLE_COMPASS_ROOM] = RandoRegion{ .sceneId = SCENE_SEA,
.checks = {
CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_CHEST, true),
- CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_UNDERWATER, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_UNDERWATER, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_SURFACE_POT_01, true),
CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_SURFACE_POT_02, true),
CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_SURFACE_POT_03, true),
CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_SURFACE_POT_04, true),
- CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_WATER_POT_01, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_WATER_POT_02, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_WATER_POT_03, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_WATER_POT_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_WATER_POT_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_COMPASS_ROOM_WATER_POT_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.connections = {
CONNECTION(RR_GREAT_BAY_TEMPLE_BABA_CHEST_ROOM, true),
CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM_WITH_BOSS_KEY_CHEST, CAN_BE_ZORA && CAN_USE_MAGIC_ARROW(ICE)), // TODO : Decide if this should be considered a trick
CONNECTION(RR_GREAT_BAY_TEMPLE_GEKKO, CAN_USE_MAGIC_ARROW(ICE) && CAN_USE_MAGIC_ARROW(FIRE)),
- CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM_TUNNEL, true)
+ CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM_TUNNEL, CAN_USE_ABILITY(SWIM))
},
};
Regions[RR_GREAT_BAY_TEMPLE_ENTRANCE] = RandoRegion{ .sceneId = SCENE_SEA,
@@ -174,7 +174,7 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_1_BARREL_03, HAS_ITEM(ITEM_HOOKSHOT)),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, true),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_USE_ABILITY(SWIM)),
},
.events = {
EVENT(RE_GREAT_BAY_GREEN_SWITCH_1, CAN_USE_MAGIC_ARROW(ICE)),
@@ -186,17 +186,17 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_BARREL_02, true),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_LOWER_CHEST, HAS_ITEM(ITEM_HOOKSHOT)),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_UPPER_CHEST, (HAS_ITEM(ITEM_HOOKSHOT) && CAN_USE_MAGIC_ARROW(ICE))),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_01, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_02, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_03, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_04, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_05, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_06, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_07, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_08, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_04, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_05, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_06, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_07, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_POT_08, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM, CAN_BE_ZORA),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_COMPASS_ROOM, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CONNECTION(RR_GREAT_BAY_TEMPLE_GREEN_PIPE_3, CAN_USE_MAGIC_ARROW(ICE)),
},
};
@@ -206,7 +206,7 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_LOWER_POT, true),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_UPPER_POT_01, CAN_USE_MAGIC_ARROW(FIRE)),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_UPPER_POT_02, CAN_USE_MAGIC_ARROW(FIRE)),
- CHECK(RC_GREAT_BAY_TEMPLE_SF_GREEN_PIPE_3_BARREL, CAN_BE_ZORA && CAN_USE_MAGIC_ARROW(FIRE)),
+ CHECK(RC_GREAT_BAY_TEMPLE_SF_GREEN_PIPE_3_BARREL, CAN_BE_ZORA && CAN_USE_MAGIC_ARROW(FIRE) && CAN_USE_ABILITY(SWIM)),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_LARGE_CRATE_01, true),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_LARGE_CRATE_02, true),
CHECK(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_LARGE_CRATE_03, true),
@@ -229,14 +229,14 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_SURFACE_POT_01, true),
CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_SURFACE_POT_02, true),
CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_SURFACE_POT_03, CAN_BE_ZORA || CAN_USE_MAGIC_ARROW(ICE)),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_01, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_02, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_03, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_04, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_05, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_06, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_07, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_08, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_04, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_05, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_06, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_07, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_MAP_ROOM_WATER_POT_08, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_GREAT_BAY_TEMPLE_SF_MAP_ROOM_POT, CAN_BE_ZORA || CAN_USE_MAGIC_ARROW(ICE)),
},
.connections = {
@@ -256,13 +256,13 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_PRE_BOSS_POT_07, CAN_BE_ZORA),
CHECK(RC_GREAT_BAY_TEMPLE_PRE_BOSS_POT_08, CAN_BE_ZORA),
CHECK(RC_GREAT_BAY_TEMPLE_SF_PRE_BOSS_ABOVE_WATER, CAN_USE_PROJECTILE && HAS_ITEM(ITEM_MASK_GREAT_FAIRY)),
- CHECK(RC_GREAT_BAY_TEMPLE_SF_PRE_BOSS_UNDERWATER, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_SF_PRE_BOSS_UNDERWATER, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.exits = { // TO FROM
EXIT(ENTRANCE(GYORGS_LAIR, 0), ONE_WAY_EXIT, CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, DUNGEON_SCENE_INDEX_GREAT_BAY_TEMPLE) && GBT_GREEN_SWITCH_FLOW),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.events = {
EVENT(RE_GREAT_BAY_GREEN_SWITCH_3, true),
@@ -270,13 +270,13 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART] = RandoRegion{ .sceneId = SCENE_SEA,
.checks = {
- CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_01, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_02, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_03, CAN_BE_ZORA),
- CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_04, CAN_BE_ZORA),
+ CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_GREAT_BAY_TEMPLE_RED_PIPE_BEFORE_WART_POT_04, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CONNECTION(RR_GREAT_BAY_TEMPLE_BEFORE_WART, KEY_COUNT(GREAT_BAY_TEMPLE) >= 1),
},
.events = {
@@ -321,7 +321,7 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_GREAT_BAY_TEMPLE_WATER_WHEEL_ROOM] = RandoRegion{ .sceneId = SCENE_SEA,
.checks = {
- CHECK(RC_GREAT_BAY_TEMPLE_SF_WATER_WHEEL_PLATFORM, CAN_BE_ZORA || (HAS_ITEM(ITEM_BOW) && (HAS_ITEM(ITEM_MASK_GREAT_FAIRY)))),
+ CHECK(RC_GREAT_BAY_TEMPLE_SF_WATER_WHEEL_PLATFORM, (CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)) || (HAS_ITEM(ITEM_BOW) && HAS_ITEM(ITEM_MASK_GREAT_FAIRY))),
CHECK(RC_GREAT_BAY_TEMPLE_SF_WATER_WHEEL_SKULLTULA, true),
CHECK(RC_GREAT_BAY_TEMPLE_WATER_WHEEL_FREESTANDING_RUPEE_01, true),
CHECK(RC_GREAT_BAY_TEMPLE_WATER_WHEEL_FREESTANDING_RUPEE_02, true),
@@ -330,7 +330,7 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_TEMPLE_WATER_WHEEL_FREESTANDING_RUPEE_05, true),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA),
+ CONNECTION(RR_GREAT_BAY_TEMPLE_CENTRAL_ROOM, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CONNECTION(RR_GREAT_BAY_TEMPLE_ENTRANCE, true),
}
};
diff --git a/mm/2s2h/Rando/Logic/Regions/North.cpp b/mm/2s2h/Rando/Logic/Regions/North.cpp
index 72d334eae..6cc57fef7 100644
--- a/mm/2s2h/Rando/Logic/Regions/North.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/North.cpp
@@ -318,12 +318,12 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_PATH_TO_GORON_VILLAGE_LULLABY_INTRO, CAN_BE_GORON && (CAN_USE_MAGIC_ARROW(FIRE) || (CAN_ACCESS(HOT_SPRING_WATER) && HAS_BOTTLE))),
CHECK(RC_TWIN_ISLANDS_TINGLE_MAP_01, CAN_USE_PROJECTILE && CAN_AFFORD(RC_TWIN_ISLANDS_TINGLE_MAP_01)),
CHECK(RC_TWIN_ISLANDS_TINGLE_MAP_02, CAN_USE_PROJECTILE && CAN_AFFORD(RC_TWIN_ISLANDS_TINGLE_MAP_02)),
- CHECK(RC_TWIN_ISLANDS_UNDERWATER_CHEST_01, CAN_BE_ZORA && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
- CHECK(RC_TWIN_ISLANDS_UNDERWATER_CHEST_02, CAN_BE_ZORA && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
- CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_01, CAN_BE_ZORA && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
- CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_02, CAN_BE_ZORA && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
- CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_03, CAN_BE_ZORA && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
- CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_04, CAN_BE_ZORA && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
+ CHECK(RC_TWIN_ISLANDS_UNDERWATER_CHEST_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
+ CHECK(RC_TWIN_ISLANDS_UNDERWATER_CHEST_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
+ CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
+ CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
+ CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
+ CHECK(RC_TWIN_ISLANDS_FREESTANDING_RUPEE_04, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
CHECK(RC_TWIN_ISLANDS_SPRING_GRASS_01, RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
CHECK(RC_TWIN_ISLANDS_SPRING_GRASS_02, RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
CHECK(RC_TWIN_ISLANDS_SPRING_GRASS_03, RANDO_EVENTS[RE_CLEARED_SNOWHEAD_TEMPLE]),
diff --git a/mm/2s2h/Rando/Logic/Regions/PiratesFortress.cpp b/mm/2s2h/Rando/Logic/Regions/PiratesFortress.cpp
index f5fc49213..82d738220 100644
--- a/mm/2s2h/Rando/Logic/Regions/PiratesFortress.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/PiratesFortress.cpp
@@ -31,7 +31,7 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(PIRATES_FORTRESS, 1), ENTRANCE(PIRATES_FORTRESS_INTERIOR, 0), true),
},
.events = {
- EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA),
+ EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_PIRATES_FORTRESS_INSIDE_3_GUARD_ROOM] = RandoRegion{ .name = "3 Guard Room", .sceneId = SCENE_PIRATE,
@@ -50,7 +50,7 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_PIRATES_FORTRESS_INSIDE_CHEST_EGG_ROOM] = RandoRegion{ .name = "Chest Egg Room", .sceneId = SCENE_PIRATE,
.checks = {
- CHECK(RC_PIRATE_FORTRESS_INTERIOR_AQUARIUM_CHEST, HAS_ITEM(ITEM_HOOKSHOT) && CAN_BE_ZORA),
+ CHECK(RC_PIRATE_FORTRESS_INTERIOR_AQUARIUM_CHEST, HAS_ITEM(ITEM_HOOKSHOT) && CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_PIRATE_FORTRESS_INTERIOR_CHEST_AQUARIUM_POT_01, true),
CHECK(RC_PIRATE_FORTRESS_INTERIOR_CHEST_AQUARIUM_POT_02, true),
CHECK(RC_PIRATE_FORTRESS_INTERIOR_CHEST_AQUARIUM_POT_03, true),
@@ -62,7 +62,7 @@ static RegisterShipInitFunc initFunc([]() {
CONNECTION(RR_PIRATES_FORTRESS_INSIDE_ORANGE_GUARD, true),
},
.events = {
- EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA),
+ EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_PIRATES_FORTRESS_INSIDE_GREEN_GUARD] = RandoRegion{ .name = "Green Guard Room", .sceneId = SCENE_PIRATE,
@@ -121,7 +121,7 @@ static RegisterShipInitFunc initFunc([]() {
CONNECTION(RR_PIRATES_FORTRESS_LEFT_CLAM_EGG_ROOM, true),
},
.events = {
- EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA),
+ EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_PIRATES_FORTRESS_LEFT_PLATFORM] = RandoRegion{ .name = "Left Platform", .sceneId = SCENE_KAIZOKU,
@@ -135,11 +135,11 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_PIRATES_FORTRESS_MOAT_HIGHER] = RandoRegion{ .name = "Higher", .sceneId = SCENE_TORIDE,
.exits = { // TO FROM
- EXIT(ENTRANCE(PIRATES_FORTRESS, 0), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 1), true),
- EXIT(ENTRANCE(PIRATES_FORTRESS_INTERIOR, 10), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 6), true),
+ EXIT(ENTRANCE(PIRATES_FORTRESS, 0), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 1), CAN_USE_ABILITY(SWIM)),
+ EXIT(ENTRANCE(PIRATES_FORTRESS_INTERIOR, 10), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 6), CAN_USE_ABILITY(SWIM)),
},
.connections = {
- CONNECTION(RR_PIRATES_FORTRESS_MOAT_LOWER, true),
+ CONNECTION(RR_PIRATES_FORTRESS_MOAT_LOWER, CAN_USE_ABILITY(SWIM)),
},
.oneWayEntrances = {
ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 4), // From being captured in the inner part of Pirate Fortress
@@ -147,16 +147,16 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_PIRATES_FORTRESS_MOAT_LOWER] = RandoRegion{ .name = "Lower", .sceneId = SCENE_TORIDE,
.checks = {
- CHECK(RC_PIRATE_FORTRESS_ENTRANCE_CHEST_01, CAN_BE_ZORA),
- CHECK(RC_PIRATE_FORTRESS_ENTRANCE_CHEST_02, CAN_BE_ZORA),
- CHECK(RC_PIRATE_FORTRESS_ENTRANCE_CHEST_03, CAN_BE_ZORA),
+ CHECK(RC_PIRATE_FORTRESS_ENTRANCE_CHEST_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_PIRATE_FORTRESS_ENTRANCE_CHEST_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_PIRATE_FORTRESS_ENTRANCE_CHEST_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.exits = { // TO FROM
- EXIT(ENTRANCE(GREAT_BAY_COAST, 5), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 0), CAN_BE_ZORA),
- EXIT(ENTRANCE(PIRATES_FORTRESS_INTERIOR, 9), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 2), CAN_BE_ZORA && CAN_BE_GORON),
+ EXIT(ENTRANCE(GREAT_BAY_COAST, 5), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 0), CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ EXIT(ENTRANCE(PIRATES_FORTRESS_INTERIOR, 9), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 2), CAN_BE_ZORA && CAN_USE_ABILITY(SWIM) && CAN_BE_GORON),
},
.connections = {
- CONNECTION(RR_PIRATES_FORTRESS_MOAT_HIGHER, HAS_ITEM(ITEM_HOOKSHOT)),
+ CONNECTION(RR_PIRATES_FORTRESS_MOAT_HIGHER, HAS_ITEM(ITEM_HOOKSHOT) && CAN_USE_ABILITY(SWIM)),
},
.events = {
EVENT(RE_ACCESS_PIRATE_PICTURE, true),
@@ -173,7 +173,7 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(PIRATES_FORTRESS, 12), ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 5), true),
},
.connections = {
- CONNECTION(RR_PIRATES_FORTRESS_MOAT_LOWER, true),
+ CONNECTION(RR_PIRATES_FORTRESS_MOAT_LOWER, CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_PIRATES_FORTRESS_PLAZA_LEFT_EXIT] = RandoRegion{ .name = "Left Side Exit", .sceneId = SCENE_KAIZOKU,
@@ -283,29 +283,29 @@ static RegisterShipInitFunc initFunc([]() {
CONNECTION(RR_PIRATES_FORTRESS_INSIDE_MAZE_GUARD, true),
},
.events = {
- EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA),
+ EVENT(RE_ACCESS_ZORA_EGG, HAS_ITEM(ITEM_HOOKSHOT) && HAS_BOTTLE && CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_PIRATES_FORTRESS_SEWERS_POSTGATE] = RandoRegion{ .name = "Sewers Postgate", .sceneId = SCENE_PIRATE,
.checks = {
- CHECK(RC_PIRATE_FORTRESS_SEWERS_WATERWAY_POT_01, true),
- CHECK(RC_PIRATE_FORTRESS_SEWERS_WATERWAY_POT_02, true),
+ CHECK(RC_PIRATE_FORTRESS_SEWERS_WATERWAY_POT_01, CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_PIRATE_FORTRESS_SEWERS_WATERWAY_POT_02, CAN_USE_ABILITY(SWIM)),
},
.exits = { // TO FROM
- EXIT(ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 3), ONE_WAY_EXIT, true)
+ EXIT(ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 3), ONE_WAY_EXIT, CAN_USE_ABILITY(SWIM))
},
.connections = {
- CONNECTION(RR_PIRATES_FORTRESS_TELESCOPE_ROOM, HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT) || CAN_BE_ZORA)
+ CONNECTION(RR_PIRATES_FORTRESS_TELESCOPE_ROOM, (HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT) || CAN_BE_ZORA) && CAN_USE_ABILITY(SWIM))
}
};
Regions[RR_PIRATES_FORTRESS_SEWERS_PREGATE] = RandoRegion{ .name = "Sewers Pregate", .sceneId = SCENE_PIRATE,
.checks = {
- CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_CHEST_01, CAN_BE_ZORA),
- CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_CHEST_02, CAN_BE_ZORA),
- CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_CHEST_03, CAN_BE_ZORA),
+ CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_CHEST_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_CHEST_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_CHEST_03, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_POT_01, true),
CHECK(RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_POT_02, true),
- CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_PIECE_OF_HEART, true),
+ CHECK(RC_PIRATE_FORTRESS_INTERIOR_SEWERS_PIECE_OF_HEART, true),
CHECK(RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_01, true),
CHECK(RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_02, true),
CHECK(RC_PIRATE_FORTRESS_SEWERS_HEART_PIECE_ROOM_BARREL_03, true),
@@ -355,7 +355,7 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 6), ENTRANCE(PIRATES_FORTRESS_INTERIOR, 10), CAN_USE_PROJECTILE)
},
.connections = {
- CONNECTION(RR_PIRATES_FORTRESS_SEWERS_POSTGATE, true)
+ CONNECTION(RR_PIRATES_FORTRESS_SEWERS_POSTGATE, CAN_USE_ABILITY(SWIM))
}
};
}, {});
diff --git a/mm/2s2h/Rando/Logic/Regions/South.cpp b/mm/2s2h/Rando/Logic/Regions/South.cpp
index 3f35c4473..9a21cda50 100644
--- a/mm/2s2h/Rando/Logic/Regions/South.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/South.cpp
@@ -5,6 +5,31 @@
using namespace Rando::Logic;
+inline bool CanGetPastBigOcto() {
+ // Boat ride. This takes Link to a landing in the next region and thus has no additional requirements.
+ if (RANDO_EVENTS[RE_SOUTHERN_SWAMP_RIDE_BOAT]) {
+ return true;
+ }
+ /*
+ * Kill the Big Octo. This means the water is still in a poison state, so swimming is not logically considered due
+ * to the damage boost method not being logically considered. This piece may need expanded as tricks and glitches
+ * are logically introduced.
+ */
+ if (RANDO_EVENTS[RE_SOUTHERN_SWAMP_KILL_OCTOROK] && CAN_BE_DEKU) {
+ return true;
+ }
+ /*
+ * The water is clear in this state, so swimming comes into question. Either Link uses the swim ability, he hops
+ * over the water as Deku, or he uses one of the forms tall enough to walk through the water. This may also be
+ * expanded if FD is ever logically considered.
+ */
+ if (RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE] &&
+ (CAN_USE_ABILITY(SWIM) || CAN_BE_DEKU || CAN_BE_ZORA || CAN_BE_GORON)) {
+ return true;
+ }
+ return false;
+}
+
// clang-format off
static RegisterShipInitFunc initFunc([]() {
Regions[RR_DEKU_KINGS_CHAMBER_HOLDING_CELL] = RandoRegion{ .name = "Holding Cell", .sceneId = SCENE_DEKU_KING,
@@ -241,19 +266,12 @@ static RegisterShipInitFunc initFunc([]() {
CONNECTION(RR_SOUTHERN_SWAMP_SOUTH, true), // TODO: Grotto mapping
},
};
- Regions[RR_SOUTHERN_SWAMP_NORTH] = RandoRegion{ .name = "North Section", .sceneId = SCENE_20SICHITAI,
+ Regions[RR_SOUTHERN_SWAMP_NORTH] = RandoRegion{ .name = "North Tourist Section", .sceneId = SCENE_20SICHITAI,
.checks = {
- CHECK(RC_SOUTHERN_SWAMP_FROG, HAS_ITEM(ITEM_MASK_DON_GERO)),
CHECK(RC_SOUTHERN_SWAMP_PIECE_OF_HEART, CAN_BE_DEKU && Flags_GetRandoInf(RANDO_INF_OBTAINED_DEED_LAND)),
CHECK(RC_SOUTHERN_SWAMP_SCRUB_DEED, Flags_GetRandoInf(RANDO_INF_OBTAINED_DEED_LAND)),
CHECK(RC_SOUTHERN_SWAMP_SCRUB_BEANS, CAN_BE_DEKU),
CHECK(RC_SOUTHERN_SWAMP_OWL_STATUE, CAN_USE_SWORD),
- CHECK(RC_SOUTHERN_SWAMP_POISON_POT_01, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_POT_02, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_POT_03, true),
- CHECK(RC_SOUTHERN_SWAMP_CLEAR_POT_01, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
- CHECK(RC_SOUTHERN_SWAMP_CLEAR_POT_02, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
- CHECK(RC_SOUTHERN_SWAMP_CLEAR_POT_03, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_FREESTANDING_RUPEE_01, CAN_BE_DEKU || CAN_BE_ZORA),
CHECK(RC_SOUTHERN_SWAMP_FREESTANDING_RUPEE_02, CAN_BE_DEKU || CAN_BE_ZORA),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_01, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
@@ -268,6 +286,48 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_10, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_11, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_12, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_01, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_02, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_03, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_04, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_05, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_06, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_07, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_08, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_09, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_10, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_11, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_12, true),
+ },
+ .exits = { // TO FROM
+ EXIT(ENTRANCE(ROAD_TO_SOUTHERN_SWAMP, 1), ENTRANCE(SOUTHERN_SWAMP_POISONED, 0), true),
+ EXIT(ENTRANCE(TOURIST_INFORMATION, 0), ENTRANCE(SOUTHERN_SWAMP_POISONED, 1), true),
+ },
+ .connections = {
+ CONNECTION(RR_SOUTHERN_SWAMP_SOUTH, CanGetPastBigOcto()),
+ CONNECTION(RR_SOUTHERN_SWAMP_NEAR_WOODS, (CAN_BE_HUMAN && CAN_USE_ABILITY(SWIM)) || (CAN_BE_DEKU || CAN_BE_ZORA || CAN_BE_GORON)),
+ },
+ .events = {
+ EVENT(RE_ACCESS_SPRING_WATER, true),
+ EVENT(RE_ACCESS_BEANS_REFILL, CAN_BE_DEKU && HAS_ITEM(ITEM_MAGIC_BEANS)),
+ EVENT(RE_SOUTHERN_SWAMP_KILL_OCTOROK, (HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT) || CAN_BE_ZORA)),
+ EVENT(RE_ACCESS_PICTOGRAPH_SWAMP_GENERIC, HAS_ITEM(ITEM_PICTOGRAPH_BOX)),
+ },
+ .oneWayEntrances = {
+ ENTRANCE(SOUTHERN_SWAMP_POISONED, 10), // From Song of Soaring
+ }
+ };
+ Regions[RR_SOUTHERN_SWAMP_NEAR_WOODS] = RandoRegion{ .name = "North Woods Section", .sceneId = SCENE_20SICHITAI,
+ .checks = {
+ CHECK(RC_SOUTHERN_SWAMP_FROG, HAS_ITEM(ITEM_MASK_DON_GERO)),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_POT_01, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_POT_02, true),
+ CHECK(RC_SOUTHERN_SWAMP_POISON_POT_03, true),
+ CHECK(RC_SOUTHERN_SWAMP_CLEAR_POT_01, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
+ CHECK(RC_SOUTHERN_SWAMP_CLEAR_POT_02, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
+ CHECK(RC_SOUTHERN_SWAMP_CLEAR_POT_03, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
+ CHECK(RC_SOUTHERN_SWAMP_FREESTANDING_RUPEE_01, CAN_BE_DEKU || CAN_BE_ZORA),
+ CHECK(RC_SOUTHERN_SWAMP_FREESTANDING_RUPEE_02, CAN_BE_DEKU || CAN_BE_ZORA),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_13, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_14, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_15, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
@@ -286,18 +346,6 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_28, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_29, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
CHECK(RC_SOUTHERN_SWAMP_CLEARED_GRASS_30, RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_01, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_02, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_03, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_04, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_05, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_06, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_07, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_08, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_09, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_10, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_11, true),
- CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_12, true),
CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_13, true),
CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_14, true),
CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_15, true),
@@ -318,13 +366,12 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_SOUTHERN_SWAMP_POISON_GRASS_30, true),
},
.exits = { // TO FROM
- EXIT(ENTRANCE(ROAD_TO_SOUTHERN_SWAMP, 1), ENTRANCE(SOUTHERN_SWAMP_POISONED, 0), true),
- EXIT(ENTRANCE(TOURIST_INFORMATION, 0), ENTRANCE(SOUTHERN_SWAMP_POISONED, 1), true),
EXIT(ENTRANCE(MAGIC_HAGS_POTION_SHOP, 0), ENTRANCE(SOUTHERN_SWAMP_POISONED, 5), true),
EXIT(ENTRANCE(WOODS_OF_MYSTERY, 0), ENTRANCE(SOUTHERN_SWAMP_POISONED, 7), true),
},
.connections = {
- CONNECTION(RR_SOUTHERN_SWAMP_SOUTH, (RANDO_EVENTS[RE_SOUTHERN_SWAMP_KILL_OCTOROK] || RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE])),
+ CONNECTION(RR_SOUTHERN_SWAMP_SOUTH, CanGetPastBigOcto()),
+ CONNECTION(RR_SOUTHERN_SWAMP_NORTH, (CAN_BE_HUMAN && CAN_USE_ABILITY(SWIM)) || (CAN_BE_DEKU || CAN_BE_ZORA || CAN_BE_GORON)),
},
.events = {
EVENT(RE_ACCESS_SPRING_WATER, true),
@@ -334,7 +381,6 @@ static RegisterShipInitFunc initFunc([]() {
},
.oneWayEntrances = {
ENTRANCE(SOUTHERN_SWAMP_POISONED, 9), // From river in Ikana
- ENTRANCE(SOUTHERN_SWAMP_POISONED, 10), // From Song of Soaring
}
};
Regions[RR_SOUTHERN_SWAMP_SOUTH] = RandoRegion{ .name = "South Section", .sceneId = SCENE_20SICHITAI,
@@ -348,7 +394,8 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(SWAMP_SPIDER_HOUSE, 0), ENTRANCE(SOUTHERN_SWAMP_POISONED, 8), CAN_LIGHT_TORCH_NEAR_ANOTHER && (CAN_BE_DEKU || RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE])),
},
.connections = {
- CONNECTION(RR_SOUTHERN_SWAMP_NORTH, (RANDO_EVENTS[RE_SOUTHERN_SWAMP_KILL_OCTOROK] || RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE])),
+ CONNECTION(RR_SOUTHERN_SWAMP_NORTH, CanGetPastBigOcto()),
+ CONNECTION(RR_SOUTHERN_SWAMP_NEAR_WOODS, CanGetPastBigOcto()),
CONNECTION(RR_SOUTHERN_SWAMP_GROTTO, CAN_BE_DEKU), // TODO: Grotto mapping
},
.events = {
@@ -375,7 +422,7 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(SOUTHERN_SWAMP_POISONED, 1), ENTRANCE(TOURIST_INFORMATION, 0), true),
},
.events = {
- EVENT(RE_SOUTHERN_SWAMP_KILL_OCTOROK, RANDO_EVENTS[RE_SAVED_KOUME] || CAN_ACCESS(PICTOGRAPH_SWAMP_GENERIC)),
+ EVENT(RE_SOUTHERN_SWAMP_RIDE_BOAT, RANDO_EVENTS[RE_SAVED_KOUME] || CAN_ACCESS(PICTOGRAPH_SWAMP_GENERIC)),
},
};
Regions[RR_WOODFALL_GREAT_FAIRY_FOUNTAIN] = RandoRegion{ .name = "Woodfall", .sceneId = SCENE_YOUSEI_IZUMI,
@@ -388,13 +435,8 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_WOODFALL] = RandoRegion{ .sceneId = SCENE_21MITURINMAE,
.checks = {
- CHECK(RC_WOODFALL_ENTRANCE_CHEST, CAN_BE_DEKU || RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
+ CHECK(RC_WOODFALL_ENTRANCE_CHEST, CAN_BE_DEKU || (RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE] && (CAN_BE_ZORA || CAN_BE_GORON || CAN_USE_ABILITY(SWIM)))),
CHECK(RC_WOODFALL_PIECE_OF_HEART_CHEST, CAN_BE_DEKU),
- CHECK(RC_WOODFALL_OWL_STATUE, CAN_USE_SWORD),
- CHECK(RC_WOODFALL_NEAR_OWL_CHEST, CAN_BE_DEKU),
- CHECK(RC_WOODFALL_POT_01, CAN_BE_DEKU || CAN_OWL_WARP(OWL_WARP_WOODFALL)),
- CHECK(RC_WOODFALL_POT_02, CAN_BE_DEKU || CAN_OWL_WARP(OWL_WARP_WOODFALL)),
- CHECK(RC_WOODFALL_POT_03, CAN_BE_DEKU || CAN_OWL_WARP(OWL_WARP_WOODFALL)),
CHECK(RC_WOODFALL_FREESTANDING_RUPEE, CAN_BE_DEKU),
CHECK(RC_WOODFALL_GRASS_01, true),
CHECK(RC_WOODFALL_GRASS_02, true),
@@ -405,10 +447,27 @@ static RegisterShipInitFunc initFunc([]() {
},
.exits = { // TO FROM
EXIT(ENTRANCE(SOUTHERN_SWAMP_POISONED, 2), ENTRANCE(WOODFALL, 0), true),
- EXIT(ENTRANCE(WOODFALL_TEMPLE, 0), ENTRANCE(WOODFALL, 1), CanAccessDungeon(DUNGEON_SCENE_INDEX_WOODFALL_TEMPLE)),
EXIT(ENTRANCE(FAIRY_FOUNTAIN, 1), ENTRANCE(WOODFALL, 2), CAN_BE_DEKU),
EXIT(ENTRANCE(WOODFALL_TEMPLE, 2), ENTRANCE(WOODFALL, 3), RANDO_EVENTS[RE_CLEARED_WOODFALL_TEMPLE]),
},
+ .connections = {
+ CONNECTION(RR_WOODFALL_OWL_STATUE_PLATFORM, CAN_BE_DEKU),
+ },
+ };
+ Regions[RR_WOODFALL_OWL_STATUE_PLATFORM] = RandoRegion{ .name = "Owl Statue Platform", .sceneId = SCENE_21MITURINMAE,
+ .checks = {
+ CHECK(RC_WOODFALL_OWL_STATUE, CAN_USE_SWORD),
+ CHECK(RC_WOODFALL_NEAR_OWL_CHEST, CAN_BE_DEKU),
+ CHECK(RC_WOODFALL_POT_01, true),
+ CHECK(RC_WOODFALL_POT_02, true),
+ CHECK(RC_WOODFALL_POT_03, true),
+ },
+ .exits = { // TO FROM
+ EXIT(ENTRANCE(WOODFALL_TEMPLE, 0), ENTRANCE(WOODFALL, 1), CAN_BE_DEKU && CanAccessDungeon(DUNGEON_SCENE_INDEX_WOODFALL_TEMPLE)),
+ },
+ .connections = {
+ CONNECTION(RR_WOODFALL, CAN_BE_DEKU),
+ },
};
Regions[RR_WOODS_OF_MYSTERY_GROTTO] = RandoRegion{ .name = "Woods of Mystery Grotto", .sceneId = SCENE_KAKUSIANA,
.checks = {
diff --git a/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp b/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp
index bb1b83a35..53b4bcdfc 100644
--- a/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/TerminaField.cpp
@@ -25,7 +25,7 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_TERMINA_FIELD_BIO_BABA_GROTTO] = RandoRegion{ .name = "Termina Field Bio Baba", .sceneId = SCENE_KAKUSIANA,
.checks = {
- CHECK(RC_TERMINA_FIELD_BIO_BABA_GROTTO, CAN_BE_ZORA),
+ CHECK(RC_TERMINA_FIELD_BIO_BABA_GROTTO, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_TERMINA_FIELD_BIO_BABA_GROTTO_GRASS_01, true),
CHECK(RC_TERMINA_FIELD_BIO_BABA_GROTTO_GRASS_02, true),
},
@@ -249,7 +249,7 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_TERMINA_FIELD_POT, CAN_GROW_BEAN_PLANT),
CHECK(RC_TERMINA_FIELD_TALL_GRASS_CHEST, true),
CHECK(RC_TERMINA_FIELD_TREE_STUMP_CHEST, CAN_GROW_BEAN_PLANT || HAS_ITEM(ITEM_HOOKSHOT)),
- CHECK(RC_TERMINA_FIELD_WATER_CHEST, CAN_BE_ZORA),
+ CHECK(RC_TERMINA_FIELD_WATER_CHEST, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_TERMINA_FIELD_FREESTANDING_RUPEE_01, true), // TODO: Fix duplicate item get...
CHECK(RC_TERMINA_FIELD_GUAY_RUPEE_DROP_01, CAN_PLAY_SONG(SONATA) || CAN_PLAY_SONG(LULLABY) || CAN_PLAY_SONG(BOSSA_NOVA)),
CHECK(RC_TERMINA_FIELD_GUAY_RUPEE_DROP_02, CAN_PLAY_SONG(SONATA) || CAN_PLAY_SONG(LULLABY) || CAN_PLAY_SONG(BOSSA_NOVA)),
diff --git a/mm/2s2h/Rando/Logic/Regions/West.cpp b/mm/2s2h/Rando/Logic/Regions/West.cpp
index fad9b3255..c91a17915 100644
--- a/mm/2s2h/Rando/Logic/Regions/West.cpp
+++ b/mm/2s2h/Rando/Logic/Regions/West.cpp
@@ -94,7 +94,7 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_GREAT_BAY_COAST_COW_GROTTO_GRASS_72, true),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_COAST, true), // TODO: Grotto mapping
+ CONNECTION(RR_GREAT_BAY_COAST_CLIFFSIDE, true), // TODO: Grotto mapping
},
};
Regions[RR_GREAT_BAY_COAST_FISHERMAN_GROTTO] = RandoRegion{ .name = "Great Bay Coast Fisherman Grotto", .sceneId = SCENE_KAKUSIANA,
@@ -122,26 +122,9 @@ static RegisterShipInitFunc initFunc([]() {
Regions[RR_GREAT_BAY_COAST] = RandoRegion{ .sceneId = SCENE_30GYOSON,
.checks = {
CHECK(RC_GREAT_BAY_COAST_FISHERMAN_MINIGAME, RANDO_EVENTS[RE_CLEARED_GREAT_BAY_TEMPLE] && (HAS_ITEM(ITEM_HOOKSHOT) || CAN_USE_MAGIC_ARROW(ICE))),
- CHECK(RC_GREAT_BAY_COAST_OWL_STATUE, CAN_USE_SWORD),
- CHECK(RC_GREAT_BAY_COAST_MIKAU, CAN_PLAY_SONG(HEALING)),
- CHECK(RC_GREAT_BAY_COAST_PIECE_OF_HEART, CAN_HOOK_SCARECROW && CAN_GROW_BEAN_PLANT),
- CHECK(RC_GREAT_BAY_COAST_POT_01, true),
- CHECK(RC_GREAT_BAY_COAST_POT_02, true),
+ CHECK(RC_GREAT_BAY_COAST_MIKAU, CAN_USE_ABILITY(SWIM) && CAN_PLAY_SONG(HEALING)),
CHECK(RC_GREAT_BAY_COAST_POT_03, true),
CHECK(RC_GREAT_BAY_COAST_POT_04, true),
- CHECK(RC_GREAT_BAY_COAST_POT_05, true),
- CHECK(RC_GREAT_BAY_COAST_POT_06, true),
- CHECK(RC_GREAT_BAY_COAST_POT_07, true),
- CHECK(RC_GREAT_BAY_COAST_POT_08, true),
- CHECK(RC_GREAT_BAY_COAST_POT_09, true),
- CHECK(RC_GREAT_BAY_COAST_POT_10, true),
- CHECK(RC_GREAT_BAY_COAST_POT_11, true),
- CHECK(RC_GREAT_BAY_COAST_POT_12, true),
- CHECK(RC_GREAT_BAY_COAST_LEDGE_POT_01, HAS_ITEM(ITEM_HOOKSHOT)),
- CHECK(RC_GREAT_BAY_COAST_LEDGE_POT_02, HAS_ITEM(ITEM_HOOKSHOT)),
- CHECK(RC_GREAT_BAY_COAST_LEDGE_POT_03, HAS_ITEM(ITEM_HOOKSHOT)),
- CHECK(RC_GREAT_BAY_COAST_TINGLE_MAP_01, (HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT)) && CAN_AFFORD(RC_GREAT_BAY_COAST_TINGLE_MAP_01)),
- CHECK(RC_GREAT_BAY_COAST_TINGLE_MAP_02, (HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT)) && CAN_AFFORD(RC_GREAT_BAY_COAST_TINGLE_MAP_02)),
CHECK(RC_GREAT_BAY_COAST_GRASS_01, true),
CHECK(RC_GREAT_BAY_COAST_GRASS_02, true),
CHECK(RC_GREAT_BAY_COAST_GRASS_03, true),
@@ -151,22 +134,55 @@ static RegisterShipInitFunc initFunc([]() {
.exits = { // TO FROM
EXIT(ENTRANCE(TERMINA_FIELD, 2), ENTRANCE(GREAT_BAY_COAST, 0), true),
EXIT(ENTRANCE(ZORA_CAPE, 0), ENTRANCE(GREAT_BAY_COAST, 1), true),
- EXIT(ENTRANCE(PINNACLE_ROCK, 0), ENTRANCE(GREAT_BAY_COAST, 3), true),
+ EXIT(ENTRANCE(PINNACLE_ROCK, 0), ENTRANCE(GREAT_BAY_COAST, 3), CAN_USE_ABILITY(SWIM)),
EXIT(ENTRANCE(FISHERMANS_HUT, 0), ENTRANCE(GREAT_BAY_COAST, 4), true),
- EXIT(ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 0), ENTRANCE(GREAT_BAY_COAST, 5), CAN_BE_ZORA),
- EXIT(ENTRANCE(MARINE_RESEARCH_LAB, 0), ENTRANCE(GREAT_BAY_COAST, 7), true),
+ EXIT(ENTRANCE(PIRATES_FORTRESS_EXTERIOR, 0), ENTRANCE(GREAT_BAY_COAST, 5), CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
EXIT(ENTRANCE(OCEANSIDE_SPIDER_HOUSE, 0), ENTRANCE(GREAT_BAY_COAST, 8), true),
},
.connections = {
- CONNECTION(RR_GREAT_BAY_COAST_COW_GROTTO, CAN_HOOK_SCARECROW && CAN_GROW_BEAN_PLANT), // TODO: Grotto mapping
+ CONNECTION(RR_GREAT_BAY_COAST_CLIFFSIDE, CAN_USE_ABILITY(SWIM)), // TODO: Grotto mapping
CONNECTION(RR_GREAT_BAY_COAST_FISHERMAN_GROTTO, true), // TODO: Grotto mapping
+ CONNECTION(RR_GREAT_BAY_COAST_MARINE_LAB_EXTERIOR, CAN_USE_ABILITY(SWIM)),
+ CONNECTION(RR_GREAT_BAY_COAST_PIRATE_LEDGE, CAN_USE_ABILITY(SWIM)),
+ },
+ };
+ Regions[RR_GREAT_BAY_COAST_MARINE_LAB_EXTERIOR] = RandoRegion{ .sceneId = SCENE_30GYOSON,
+ .checks = {
+ CHECK(RC_GREAT_BAY_COAST_OWL_STATUE, CAN_USE_SWORD),
+ CHECK(RC_GREAT_BAY_COAST_POT_09, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_10, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_11, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_12, true),
+ CHECK(RC_GREAT_BAY_COAST_TINGLE_MAP_01, (HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT)) && CAN_AFFORD(RC_GREAT_BAY_COAST_TINGLE_MAP_01)),
+ CHECK(RC_GREAT_BAY_COAST_TINGLE_MAP_02, (HAS_ITEM(ITEM_BOW) || HAS_ITEM(ITEM_HOOKSHOT)) && CAN_AFFORD(RC_GREAT_BAY_COAST_TINGLE_MAP_02)),
+ },
+ .exits = { // TO FROM
+ EXIT(ENTRANCE(MARINE_RESEARCH_LAB, 0), ENTRANCE(GREAT_BAY_COAST, 7), true),
+ },
+ .connections = {
+ CONNECTION(RR_GREAT_BAY_COAST, CAN_USE_ABILITY(SWIM)),
},
.events = {
EVENT(RE_ACCESS_PICTOGRAPH_TINGLE, HAS_ITEM(ITEM_PICTOGRAPH_BOX)),
},
.oneWayEntrances = {
ENTRANCE(GREAT_BAY_COAST, 11), // From Song of Soaring
- ENTRANCE(GREAT_BAY_COAST, 12), // From being captured in Pirate Fortress Moat
+ },
+ };
+ Regions[RR_GREAT_BAY_COAST_CLIFFSIDE] = RandoRegion{ .sceneId = SCENE_30GYOSON,
+ .checks = {
+ CHECK(RC_GREAT_BAY_COAST_PIECE_OF_HEART, CAN_HOOK_SCARECROW && CAN_GROW_BEAN_PLANT),
+ CHECK(RC_GREAT_BAY_COAST_POT_05, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_06, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_07, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_08, true),
+ CHECK(RC_GREAT_BAY_COAST_LEDGE_POT_01, HAS_ITEM(ITEM_HOOKSHOT)),
+ CHECK(RC_GREAT_BAY_COAST_LEDGE_POT_02, HAS_ITEM(ITEM_HOOKSHOT)),
+ CHECK(RC_GREAT_BAY_COAST_LEDGE_POT_03, HAS_ITEM(ITEM_HOOKSHOT)),
+ },
+ .connections = {
+ CONNECTION(RR_GREAT_BAY_COAST_COW_GROTTO, CAN_HOOK_SCARECROW && CAN_GROW_BEAN_PLANT), // TODO: Grotto mapping
+ CONNECTION(RR_GREAT_BAY_COAST, CAN_USE_ABILITY(SWIM)),
},
};
Regions[RR_GREAT_BAY_GREAT_FAIRY_FOUNTAIN] = RandoRegion{ .sceneId = SCENE_YOUSEI_IZUMI,
@@ -177,6 +193,19 @@ static RegisterShipInitFunc initFunc([]() {
EXIT(ENTRANCE(ZORA_CAPE, 5), ENTRANCE(FAIRY_FOUNTAIN, 3), true),
},
};
+ Regions[RR_GREAT_BAY_COAST_PIRATE_LEDGE] = RandoRegion{ .sceneId = SCENE_30GYOSON,
+ .checks = {
+ CHECK(RC_GREAT_BAY_COAST_POT_01, true),
+ CHECK(RC_GREAT_BAY_COAST_POT_02, true),
+ },
+ .connections = {
+ CONNECTION(RR_GREAT_BAY_COAST, CAN_USE_ABILITY(SWIM)),
+ },
+ .oneWayEntrances = {
+ // This region can feel like overkill now, but this one-way entrance will be significant for entrance rando.
+ ENTRANCE(GREAT_BAY_COAST, 12), // From being captured in Pirate Fortress Moat
+ },
+ };
Regions[RR_MARINE_RESEARCH_LAB] = RandoRegion{ .sceneId = SCENE_LABO,
.checks = {
CHECK(RC_GREAT_BAY_COAST_NEW_WAVE_BOSSA_NOVA, CAN_BE_ZORA && HAS_ITEM(ITEM_OCARINA_OF_TIME) && RANDO_EVENTS[RE_ACCESS_ZORA_EGG] >= 7),
@@ -212,7 +241,7 @@ static RegisterShipInitFunc initFunc([]() {
CHECK(RC_PINNACLE_ROCK_REUNITE_SEAHORSE, CAN_BE_ZORA && HAS_MAGIC && RANDO_EVENTS[RE_ACCESS_SEAHORSE]),
},
.connections = {
- CONNECTION(RR_PINNACLE_ROCK_ENTRANCE, true)
+ CONNECTION(RR_PINNACLE_ROCK_ENTRANCE, CAN_USE_ABILITY(SWIM))
},
.events = {
EVENT(RE_ACCESS_ZORA_EGG, HAS_MAGIC && HAS_BOTTLE && CAN_BE_ZORA),
@@ -222,8 +251,8 @@ static RegisterShipInitFunc initFunc([]() {
};
Regions[RR_WATERFALL_RAPIDS] = RandoRegion{ .sceneId = SCENE_35TAKI,
.checks = {
- CHECK(RC_WATERFALL_RAPIDS_BEAVER_RACE_01, CAN_BE_ZORA),
- CHECK(RC_WATERFALL_RAPIDS_BEAVER_RACE_02, CAN_BE_ZORA),
+ CHECK(RC_WATERFALL_RAPIDS_BEAVER_RACE_01, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_WATERFALL_RAPIDS_BEAVER_RACE_02, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
},
.exits = { // TO FROM
EXIT(ENTRANCE(ZORA_CAPE, 4), ENTRANCE(WATERFALL_RAPIDS, 0), true),
@@ -275,14 +304,14 @@ static RegisterShipInitFunc initFunc([]() {
.checks = {
CHECK(RC_ZORA_CAPE_LEDGE_CHEST_01, HAS_ITEM(ITEM_HOOKSHOT)),
CHECK(RC_ZORA_CAPE_LEDGE_CHEST_02, HAS_ITEM(ITEM_HOOKSHOT)),
- CHECK(RC_ZORA_CAPE_UNDERWATER_CHEST, CAN_BE_ZORA),
- CHECK(RC_ZORA_CAPE_WATERFALL_PIECE_OF_HEART, CAN_BE_ZORA),
+ CHECK(RC_ZORA_CAPE_UNDERWATER_CHEST, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
+ CHECK(RC_ZORA_CAPE_WATERFALL_PIECE_OF_HEART, CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
CHECK(RC_ZORA_CAPE_NEAR_BEAVERS_POT_01, true),
CHECK(RC_ZORA_CAPE_NEAR_BEAVERS_POT_02, true),
},
.exits = { // TO FROM
EXIT(ENTRANCE(GREAT_BAY_COAST, 1), ENTRANCE(ZORA_CAPE, 0), true),
- EXIT(ENTRANCE(ZORA_HALL, 0), ENTRANCE(ZORA_CAPE, 1), CAN_BE_ZORA),
+ EXIT(ENTRANCE(ZORA_HALL, 0), ENTRANCE(ZORA_CAPE, 1), CAN_BE_ZORA && CAN_USE_ABILITY(SWIM)),
EXIT(ENTRANCE(WATERFALL_RAPIDS, 0), ENTRANCE(ZORA_CAPE, 4), HAS_ITEM(ITEM_HOOKSHOT)),
EXIT(ENTRANCE(FAIRY_FOUNTAIN, 3), ENTRANCE(ZORA_CAPE, 5), HAS_ITEM(ITEM_HOOKSHOT) && CAN_USE_EXPLOSIVE),
},
diff --git a/mm/2s2h/Rando/Menu.cpp b/mm/2s2h/Rando/Menu.cpp
index 3cbf76f23..e7fa06f78 100644
--- a/mm/2s2h/Rando/Menu.cpp
+++ b/mm/2s2h/Rando/Menu.cpp
@@ -270,8 +270,9 @@ static void DrawItemsTab() {
f32 columnWidth = ImGui::GetContentRegionAvail().x / 3 - (ImGui::GetStyle().ItemSpacing.x * 2);
f32 halfHeight = ImGui::GetContentRegionAvail().y / 3 - (ImGui::GetStyle().ItemSpacing.y * 2);
ImGui::BeginChild("randoItemsColumn1", ImVec2(columnWidth, halfHeight));
- CVarCheckbox("Bronze Scale", "gPlaceholderBool",
- CheckboxOptions({ { .disabled = true, .disabledTooltip = "Coming Soon" } }));
+ CVarCheckbox("Shuffle Swim", Rando::StaticData::Options[RO_SHUFFLE_SWIM].cvar,
+ CheckboxOptions({ { .tooltip = "Shuffles the ability to Swim, entering the Swim state or submerging\n"
+ "into deep water will respawn Link." } }));
CVarCheckbox("Deku Stick Bag", "gPlaceholderBool",
CheckboxOptions({ { .disabled = true, .disabledTooltip = "Coming Soon" } }));
CVarCheckbox("Deku Nut Bag", "gPlaceholderBool",
diff --git a/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp b/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp
index 668f5e7ba..93b9621bd 100644
--- a/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp
+++ b/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp
@@ -245,6 +245,10 @@ void Rando::MiscBehavior::OnFileCreate(s16 fileNum) {
}
}
+ if (RANDO_SAVE_OPTIONS[RO_SHUFFLE_SWIM] == RO_GENERIC_YES) {
+ itemPool.push_back(RI_ABILITY_SWIM);
+ }
+
// Remove starting items from the pool (but only one per entry in startingItems)
for (RandoItemId startingItem : startingItems) {
auto it = std::find(itemPool.begin(), itemPool.end(), startingItem);
diff --git a/mm/2s2h/Rando/StaticData/Items.cpp b/mm/2s2h/Rando/StaticData/Items.cpp
index b0243aaf7..a2a127a97 100644
--- a/mm/2s2h/Rando/StaticData/Items.cpp
+++ b/mm/2s2h/Rando/StaticData/Items.cpp
@@ -22,6 +22,7 @@ namespace StaticData {
// clang-format off
std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_UNKNOWN, "", "Unknown", RITYPE_JUNK, ITEM_NONE, GI_NONE, GID_NONE),
+ RI(RI_ABILITY_SWIM, "the", "Ability to Swim", RITYPE_MAJOR, ITEM_NONE, GI_NONE, GID_NONE),
RI(RI_ARROW_FIRE, "", "Fire Arrows", RITYPE_MAJOR, ITEM_ARROW_FIRE, GI_ARROW_FIRE, GID_ARROW_FIRE),
RI(RI_ARROW_ICE, "", "Ice Arrows", RITYPE_MAJOR, ITEM_ARROW_ICE, GI_ARROW_ICE, GID_ARROW_ICE),
RI(RI_ARROW_LIGHT, "", "Light Arrows", RITYPE_MAJOR, ITEM_ARROW_LIGHT, GI_ARROW_LIGHT, GID_ARROW_LIGHT),
diff --git a/mm/2s2h/Rando/StaticData/Options.cpp b/mm/2s2h/Rando/StaticData/Options.cpp
index 66879099c..38a35e459 100644
--- a/mm/2s2h/Rando/StaticData/Options.cpp
+++ b/mm/2s2h/Rando/StaticData/Options.cpp
@@ -39,6 +39,7 @@ std::map<RandoOptionId, RandoStaticOption> Options = {
RO(RO_SHUFFLE_POT_DROPS, RO_GENERIC_OFF),
RO(RO_SHUFFLE_SHOPS, RO_GENERIC_OFF),
RO(RO_SHUFFLE_SNOWBALL_DROPS, RO_GENERIC_OFF),
+ RO(RO_SHUFFLE_SWIM, RO_GENERIC_OFF),
RO(RO_SHUFFLE_TINGLE_SHOPS, RO_GENERIC_OFF),
RO(RO_STARTING_CONSUMABLES, RO_GENERIC_OFF),
RO(RO_STARTING_HEALTH, 3),
diff --git a/mm/2s2h/Rando/Types.h b/mm/2s2h/Rando/Types.h
index 73fd2913a..ef9725be7 100644
--- a/mm/2s2h/Rando/Types.h
+++ b/mm/2s2h/Rando/Types.h
@@ -2252,6 +2252,7 @@ typedef enum {
typedef enum {
RI_UNKNOWN,
+ RI_ABILITY_SWIM,
RI_ARROW_FIRE,
RI_ARROW_ICE,
RI_ARROW_LIGHT,
@@ -2480,9 +2481,12 @@ typedef enum {
RR_GORON_SHOP,
RR_GORON_SHRINE,
RR_GORON_VILLAGE,
+ RR_GREAT_BAY_COAST_CLIFFSIDE,
RR_GREAT_BAY_COAST_COW_GROTTO,
RR_GREAT_BAY_COAST_FISHERMAN_GROTTO,
RR_GREAT_BAY_COAST,
+ RR_GREAT_BAY_COAST_MARINE_LAB_EXTERIOR,
+ RR_GREAT_BAY_COAST_PIRATE_LEDGE,
RR_GREAT_BAY_GREAT_FAIRY_FOUNTAIN,
RR_GREAT_BAY_TEMPLE_BABA_CHEST_ROOM,
RR_GREAT_BAY_TEMPLE_BEFORE_WART,
@@ -2628,6 +2632,7 @@ typedef enum {
RR_SNOWHEAD_TEMPLE_SNOW_ROOM,
RR_SNOWHEAD_TEMPLE_UPPER_WIZZROBE_ROOM,
RR_SOUTHERN_SWAMP_GROTTO,
+ RR_SOUTHERN_SWAMP_NEAR_WOODS,
RR_SOUTHERN_SWAMP_NORTH,
RR_SOUTHERN_SWAMP_SOUTH,
RR_STONE_TOWER_BOTTOM,
@@ -2698,6 +2703,7 @@ typedef enum {
RR_TREASURE_SHOP,
RR_WATERFALL_RAPIDS,
RR_WOODFALL_GREAT_FAIRY_FOUNTAIN,
+ RR_WOODFALL_OWL_STATUE_PLATFORM,
RR_WOODFALL_TEMPLE_BOSS_KEY_ROOM,
RR_WOODFALL_TEMPLE_BOSS_ROOM,
RR_WOODFALL_TEMPLE_BOW_ROOM,
@@ -2754,6 +2760,7 @@ typedef enum {
RO_SHUFFLE_POT_DROPS,
RO_SHUFFLE_SHOPS,
RO_SHUFFLE_SNOWBALL_DROPS,
+ RO_SHUFFLE_SWIM,
RO_SHUFFLE_TINGLE_SHOPS,
RO_STARTING_CONSUMABLES,
RO_STARTING_HEALTH,
@@ -2817,6 +2824,7 @@ typedef enum {
RANDO_INF_OBTAINED_SOUL_OF_MAJORA,
RANDO_INF_OBTAINED_SOUL_OF_ODOLWA,
RANDO_INF_OBTAINED_SOUL_OF_TWINMOLD,
+ RANDO_INF_OBTAINED_SWIM,
RANDO_INF_MAX,
} RandoInf;
@@ -2857,6 +2865,7 @@ typedef enum {
RE_SECRET_SHRINE_WART,
RE_SECRET_SHRINE_GARO_MASTER,
RE_SOUTHERN_SWAMP_KILL_OCTOROK,
+ RE_SOUTHERN_SWAMP_RIDE_BOAT,
RE_SWAMP_SPIDER_HOUSE_GOLD_ROOM_LADDER,
RE_IKANA_CASTLE_MAIN_SUNLIGHT,
RE_IKANA_CASTLE_RIGHT_SUNLIGHT,
diff --git a/mm/assets/2s2h_assets.h b/mm/assets/2s2h_assets.h
index 61e7effbd..5581dad87 100644
--- a/mm/assets/2s2h_assets.h
+++ b/mm/assets/2s2h_assets.h
@@ -370,3 +370,6 @@ static const ALIGN_ASSET(2) char gCrateTrackerIcon[] = dgCrateTrackerIcon;
#define dgBarrelTrackerIcon "__OTR__textures/icons/gBarrelTrackerIcon"
static const ALIGN_ASSET(2) char gBarrelTrackerIcon[] = dgBarrelTrackerIcon;
+
+#define dgGiFlippersDL "__OTR__objects/object_ability_swim/gGiFlippersDL"
+static const ALIGN_ASSET(2) char gGiFlippersDL[] = dgGiFlippersDL;
diff --git a/mm/assets/custom/objects/object_ability_swim/flippers b/mm/assets/custom/objects/object_ability_swim/flippers
new file mode 100644
index 000000000..c133124a3
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/flippers
Binary files differ
diff --git a/mm/assets/custom/objects/object_ability_swim/flippers2 b/mm/assets/custom/objects/object_ability_swim/flippers2
new file mode 100644
index 000000000..0958ba4ed
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/flippers2
Binary files differ
diff --git a/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL
new file mode 100644
index 000000000..cdf042fe9
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL
@@ -0,0 +1,13 @@
+<DisplayList Version="0">
+ <CallDisplayList Path="objects/object_ability_swim/mat_gGiFlippersDL_flippers2"/>
+ <CallDisplayList Path="objects/object_ability_swim/gGiFlippersDL_tri_0"/>
+ <CallDisplayList Path="objects/object_ability_swim/mat_gGiFlippersDL_flippers"/>
+ <CallDisplayList Path="objects/object_ability_swim/gGiFlippersDL_tri_1"/>
+ <PipeSync/>
+ <SetGeometryMode G_LIGHTING="1" />
+ <ClearGeometryMode G_TEXTURE_GEN="1" />
+ <SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
+ <Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
+ <EndDisplayList/>
+</DisplayList>
+
diff --git a/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_0 b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_0
new file mode 100644
index 000000000..b687b1624
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_0
@@ -0,0 +1,171 @@
+<DisplayList Version="0">
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="15"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="7" V02="8"/>
+ <Triangle1 V00="9" V01="10" V02="11"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="15" Count="15"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="7" V02="8"/>
+ <Triangle1 V00="9" V01="10" V02="11"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="30" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="7" V02="8"/>
+ <Triangle1 V00="7" V01="9" V02="8"/>
+ <Triangle1 V00="10" V01="9" V02="7"/>
+ <Triangle1 V00="11" V01="10" V02="7"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <Triangle1 V00="14" V01="15" V02="12"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="46" Count="15"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="4" V02="3"/>
+ <Triangle1 V00="7" V01="6" V02="3"/>
+ <Triangle1 V00="3" V01="8" V02="7"/>
+ <Triangle1 V00="9" V01="7" V02="8"/>
+ <Triangle1 V00="9" V01="8" V02="10"/>
+ <Triangle1 V00="10" V01="8" V02="11"/>
+ <Triangle1 V00="11" V01="12" V02="10"/>
+ <Triangle1 V00="11" V01="13" V02="12"/>
+ <Triangle1 V00="11" V01="14" V02="13"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="61" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="3" V02="1"/>
+ <Triangle1 V00="4" V01="3" V02="0"/>
+ <Triangle1 V00="4" V01="5" V02="3"/>
+ <Triangle1 V00="4" V01="6" V02="5"/>
+ <Triangle1 V00="4" V01="7" V02="6"/>
+ <Triangle1 V00="6" V01="7" V02="8"/>
+ <Triangle1 V00="6" V01="8" V02="9"/>
+ <Triangle1 V00="10" V01="11" V02="12"/>
+ <Triangle1 V00="12" V01="11" V02="13"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <Triangle1 V00="13" V01="15" V02="14"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="77" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="2" V02="1"/>
+ <Triangle1 V00="3" V01="4" V02="2"/>
+ <Triangle1 V00="5" V01="4" V02="3"/>
+ <Triangle1 V00="5" V01="6" V02="4"/>
+ <Triangle1 V00="7" V01="6" V02="5"/>
+ <Triangle1 V00="8" V01="9" V02="10"/>
+ <Triangle1 V00="8" V01="11" V02="9"/>
+ <Triangle1 V00="11" V01="8" V02="12"/>
+ <Triangle1 V00="11" V01="12" V02="13"/>
+ <Triangle1 V00="14" V01="13" V02="12"/>
+ <Triangle1 V00="14" V01="12" V02="15"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="93" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="2" V02="3"/>
+ <Triangle1 V00="4" V01="0" V02="3"/>
+ <Triangle1 V00="4" V01="3" V02="5"/>
+ <Triangle1 V00="6" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="5" V02="7"/>
+ <Triangle1 V00="8" V01="4" V02="6"/>
+ <Triangle1 V00="8" V01="0" V02="4"/>
+ <Triangle1 V00="9" V01="10" V02="11"/>
+ <Triangle1 V00="9" V01="11" V02="12"/>
+ <Triangle1 V00="12" V01="11" V02="13"/>
+ <Triangle1 V00="11" V01="14" V02="13"/>
+ <Triangle1 V00="11" V01="15" V02="14"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="109" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="2" V02="3"/>
+ <Triangle1 V00="4" V01="5" V02="6"/>
+ <Triangle1 V00="7" V01="8" V02="1"/>
+ <Triangle1 V00="1" V01="9" V02="7"/>
+ <Triangle1 V00="9" V01="10" V02="7"/>
+ <Triangle1 V00="11" V01="12" V02="13"/>
+ <Triangle1 V00="11" V01="14" V02="12"/>
+ <Triangle1 V00="15" V01="12" V02="14"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="125" Count="14"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="4" V01="6" V02="5"/>
+ <Triangle1 V00="7" V01="6" V02="4"/>
+ <Triangle1 V00="8" V01="7" V02="4"/>
+ <Triangle1 V00="9" V01="10" V02="11"/>
+ <Triangle1 V00="11" V01="12" V02="9"/>
+ <Triangle1 V00="11" V01="13" V02="12"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="139" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="1" V02="0"/>
+ <Triangle1 V00="4" V01="3" V02="0"/>
+ <Triangle1 V00="0" V01="5" V02="4"/>
+ <Triangle1 V00="6" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="5" V02="7"/>
+ <Triangle1 V00="7" V01="5" V02="8"/>
+ <Triangle1 V00="8" V01="9" V02="7"/>
+ <Triangle1 V00="8" V01="10" V02="9"/>
+ <Triangle1 V00="8" V01="11" V02="10"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <Triangle1 V00="12" V01="15" V02="13"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="155" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="3" V02="1"/>
+ <Triangle1 V00="0" V01="4" V02="3"/>
+ <Triangle1 V00="0" V01="5" V02="4"/>
+ <Triangle1 V00="4" V01="5" V02="6"/>
+ <Triangle1 V00="4" V01="6" V02="7"/>
+ <Triangle1 V00="8" V01="9" V02="10"/>
+ <Triangle1 V00="10" V01="9" V02="11"/>
+ <Triangle1 V00="10" V01="11" V02="12"/>
+ <Triangle1 V00="11" V01="13" V02="12"/>
+ <Triangle1 V00="11" V01="14" V02="13"/>
+ <Triangle1 V00="15" V01="13" V02="14"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="171" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="1" V02="0"/>
+ <Triangle1 V00="3" V01="4" V02="1"/>
+ <Triangle1 V00="5" V01="4" V02="3"/>
+ <Triangle1 V00="6" V01="7" V02="8"/>
+ <Triangle1 V00="6" V01="9" V02="7"/>
+ <Triangle1 V00="9" V01="6" V02="10"/>
+ <Triangle1 V00="9" V01="10" V02="11"/>
+ <Triangle1 V00="12" V01="11" V02="10"/>
+ <Triangle1 V00="12" V01="10" V02="13"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <Triangle1 V00="12" V01="14" V02="15"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="187" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="2" V02="3"/>
+ <Triangle1 V00="4" V01="0" V02="3"/>
+ <Triangle1 V00="4" V01="3" V02="5"/>
+ <Triangle1 V00="6" V01="0" V02="4"/>
+ <Triangle1 V00="6" V01="1" V02="0"/>
+ <Triangle1 V00="7" V01="8" V02="9"/>
+ <Triangle1 V00="7" V01="9" V02="10"/>
+ <Triangle1 V00="10" V01="9" V02="11"/>
+ <Triangle1 V00="9" V01="12" V02="11"/>
+ <Triangle1 V00="9" V01="13" V02="12"/>
+ <Triangle1 V00="14" V01="13" V02="9"/>
+ <Triangle1 V00="14" V01="9" V02="15"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="203" Count="14"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="5" V01="6" V02="3"/>
+ <Triangle1 V00="6" V01="7" V02="3"/>
+ <Triangle1 V00="8" V01="9" V02="10"/>
+ <Triangle1 V00="8" V01="11" V02="9"/>
+ <Triangle1 V00="12" V01="9" V02="11"/>
+ <Triangle1 V00="12" V01="13" V02="9"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_0" VertexBufferIndex="0" VertexOffset="217" Count="14"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="1" V01="0" V02="3"/>
+ <Triangle1 V00="1" V01="3" V02="4"/>
+ <Triangle1 V00="1" V01="4" V02="5"/>
+ <Triangle1 V00="1" V01="5" V02="6"/>
+ <Triangle1 V00="6" V01="2" V02="1"/>
+ <Triangle1 V00="7" V01="8" V02="9"/>
+ <Triangle1 V00="8" V01="7" V02="10"/>
+ <Triangle1 V00="8" V01="10" V02="11"/>
+ <Triangle1 V00="8" V01="11" V02="12"/>
+ <Triangle1 V00="8" V01="12" V02="13"/>
+ <Triangle1 V00="13" V01="9" V02="8"/>
+ <EndDisplayList/>
+</DisplayList>
+
diff --git a/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_1 b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_1
new file mode 100644
index 000000000..6b5b57c0a
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_tri_1
@@ -0,0 +1,41 @@
+<DisplayList Version="0">
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="2"/>
+ <Triangle1 V00="5" V01="6" V02="7"/>
+ <Triangle1 V00="8" V01="6" V02="9"/>
+ <Triangle1 V00="10" V01="11" V02="1"/>
+ <Triangle1 V00="12" V01="11" V02="13"/>
+ <Triangle1 V00="14" V01="7" V02="15"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_1" VertexBufferIndex="0" VertexOffset="16" Count="15"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="7" V02="5"/>
+ <Triangle1 V00="8" V01="9" V02="10"/>
+ <Triangle1 V00="11" V01="9" V02="12"/>
+ <Triangle1 V00="13" V01="14" V02="4"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_1" VertexBufferIndex="0" VertexOffset="31" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="3" V01="4" V02="5"/>
+ <Triangle1 V00="6" V01="7" V02="5"/>
+ <Triangle1 V00="8" V01="9" V02="10"/>
+ <Triangle1 V00="8" V01="10" V02="11"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <Triangle1 V00="12" V01="14" V02="15"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_1" VertexBufferIndex="0" VertexOffset="47" Count="16"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="2" V02="3"/>
+ <Triangle1 V00="4" V01="5" V02="6"/>
+ <Triangle1 V00="4" V01="6" V02="7"/>
+ <Triangle1 V00="8" V01="9" V02="10"/>
+ <Triangle1 V00="8" V01="10" V02="11"/>
+ <Triangle1 V00="12" V01="13" V02="14"/>
+ <Triangle1 V00="12" V01="14" V02="15"/>
+ <LoadVertices Path="objects/object_ability_swim/gGiFlippersDL_vtx_1" VertexBufferIndex="0" VertexOffset="63" Count="8"/>
+ <Triangle1 V00="0" V01="1" V02="2"/>
+ <Triangle1 V00="0" V01="2" V02="3"/>
+ <Triangle1 V00="4" V01="5" V02="6"/>
+ <Triangle1 V00="4" V01="6" V02="7"/>
+ <EndDisplayList/>
+</DisplayList>
+
diff --git a/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_0 b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_0
new file mode 100644
index 000000000..e8e529aef
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_0
@@ -0,0 +1,233 @@
+<Vertex Version="0">
+ <Vtx X="-1" Y="8" Z="-5" S="95" T="819" R="166" G="176" B="215" A="255"/>
+ <Vtx X="-1" Y="5" Z="-9" S="27" T="853" R="134" G="30" B="21" A="255"/>
+ <Vtx X="9" Y="7" Z="-3" S="-1" T="765" R="23" G="159" B="79" A="255"/>
+ <Vtx X="9" Y="7" Z="-3" S="21" T="759" R="23" G="159" B="79" A="255"/>
+ <Vtx X="0" Y="8" Z="2" S="197" T="779" R="33" G="141" B="43" A="255"/>
+ <Vtx X="-1" Y="8" Z="-5" S="117" T="813" R="166" G="176" B="215" A="255"/>
+ <Vtx X="0" Y="8" Z="2" S="203" T="782" R="33" G="141" B="43" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="202" T="838" R="237" G="245" B="131" A="255"/>
+ <Vtx X="-1" Y="8" Z="-5" S="124" T="815" R="166" G="176" B="215" A="255"/>
+ <Vtx X="9" Y="5" Z="-14" S="95" T="819" R="188" G="169" B="193" A="255"/>
+ <Vtx X="11" Y="6" Z="-5" S="-1" T="765" R="44" G="152" B="58" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="27" T="853" R="26" G="238" B="133" A="255"/>
+ <Vtx X="11" Y="6" Z="-5" S="21" T="759" R="44" G="152" B="58" A="255"/>
+ <Vtx X="9" Y="5" Z="-14" S="117" T="813" R="188" G="169" B="193" A="255"/>
+ <Vtx X="15" Y="3" Z="-12" S="197" T="779" R="5" G="150" B="70" A="255"/>
+ <Vtx X="15" Y="3" Z="-12" S="203" T="782" R="5" G="150" B="70" A="255"/>
+ <Vtx X="9" Y="5" Z="-14" S="124" T="815" R="188" G="169" B="193" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="202" T="838" R="133" G="22" B="233" A="255"/>
+ <Vtx X="5" Y="-4" Z="23" S="95" T="819" R="159" G="182" B="37" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="27" T="853" R="222" G="4" B="122" A="255"/>
+ <Vtx X="11" Y="-5" Z="16" S="-1" T="765" R="56" G="143" B="242" A="255"/>
+ <Vtx X="11" Y="-5" Z="16" S="21" T="759" R="56" G="143" B="242" A="255"/>
+ <Vtx X="12" Y="-7" Z="26" S="197" T="779" R="27" G="139" B="214" A="255"/>
+ <Vtx X="5" Y="-4" Z="23" S="117" T="813" R="159" G="182" B="37" A="255"/>
+ <Vtx X="12" Y="-7" Z="26" S="203" T="782" R="27" G="139" B="214" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="202" T="838" R="138" G="27" B="217" A="255"/>
+ <Vtx X="5" Y="-4" Z="23" S="124" T="815" R="159" G="182" B="37" A="255"/>
+ <Vtx X="1" Y="-3" Z="11" S="95" T="819" R="150" G="186" B="6" A="255"/>
+ <Vtx X="10" Y="-4" Z="13" S="-1" T="765" R="47" G="146" B="213" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="27" T="853" R="161" G="27" B="176" A="255"/>
+ <Vtx X="10" Y="-4" Z="13" S="21" T="759" R="47" G="146" B="213" A="255"/>
+ <Vtx X="1" Y="-3" Z="11" S="117" T="813" R="150" G="186" B="6" A="255"/>
+ <Vtx X="5" Y="-5" Z="5" S="197" T="779" R="38" G="135" B="251" A="255"/>
+ <Vtx X="5" Y="-5" Z="5" S="203" T="782" R="38" G="135" B="251" A="255"/>
+ <Vtx X="1" Y="-3" Z="11" S="124" T="815" R="150" G="186" B="6" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="202" T="838" R="181" G="11" B="102" A="255"/>
+ <Vtx X="-1" Y="5" Z="-9" S="28" T="858" R="134" G="30" B="21" A="255"/>
+ <Vtx X="-24" Y="-23" Z="-28" S="-16" T="1183" R="209" G="89" B="178" A="255"/>
+ <Vtx X="9" Y="7" Z="-3" S="-22" T="775" R="23" G="159" B="79" A="255"/>
+ <Vtx X="20" Y="20" Z="2" S="-16" T="671" R="45" G="165" B="77" A="255"/>
+ <Vtx X="11" Y="6" Z="-5" S="-22" T="775" R="44" G="152" B="58" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="28" T="858" R="26" G="238" B="133" A="255"/>
+ <Vtx X="5" Y="15" Z="4" S="189" T="723" R="240" G="226" B="122" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="496" T="1174" R="46" G="147" B="47" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="496" T="1174" R="48" G="139" B="8" A="255"/>
+ <Vtx X="0" Y="8" Z="2" S="231" T="791" R="33" G="141" B="43" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="496" T="1174" R="48" G="139" B="8" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="203" T="845" R="237" G="245" B="131" A="255"/>
+ <Vtx X="0" Y="8" Z="2" S="231" T="791" R="33" G="141" B="43" A="255"/>
+ <Vtx X="2" Y="21" Z="0" S="233" T="-16" R="149" G="68" B="13" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="119" T="259" R="237" G="245" B="131" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="-218" T="496" R="46" G="147" B="47" A="255"/>
+ <Vtx X="-1" Y="8" Z="-5" S="141" T="259" R="166" G="176" B="215" A="255"/>
+ <Vtx X="-1" Y="5" Z="-9" S="107" T="259" R="134" G="30" B="21" A="255"/>
+ <Vtx X="4" Y="13" Z="-12" S="193" T="-16" R="184" G="51" B="165" A="255"/>
+ <Vtx X="-24" Y="-23" Z="-28" S="-226" T="496" R="201" G="79" B="173" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="107" T="259" R="26" G="238" B="133" A="255"/>
+ <Vtx X="17" Y="16" Z="-15" S="233" T="-16" R="30" G="22" B="135" A="255"/>
+ <Vtx X="9" Y="5" Z="-14" S="141" T="259" R="188" G="169" B="193" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="119" T="259" R="133" G="22" B="233" A="255"/>
+ <Vtx X="-5" Y="-29" Z="-46" S="-218" T="496" R="11" G="159" B="81" A="255"/>
+ <Vtx X="17" Y="16" Z="-15" S="240" T="-17" R="30" G="22" B="135" A="255"/>
+ <Vtx X="22" Y="30" Z="-9" S="87" T="304" R="43" G="88" B="176" A="255"/>
+ <Vtx X="26" Y="25" Z="-9" S="240" T="-17" R="98" G="39" B="186" A="255"/>
+ <Vtx X="19" Y="27" Z="-11" S="87" T="304" R="252" G="61" B="145" A="255"/>
+ <Vtx X="4" Y="13" Z="-12" S="240" T="-17" R="184" G="51" B="165" A="255"/>
+ <Vtx X="11" Y="25" Z="-9" S="240" T="304" R="191" G="65" B="168" A="255"/>
+ <Vtx X="10" Y="30" Z="-2" S="87" T="304" R="170" G="88" B="225" A="255"/>
+ <Vtx X="2" Y="21" Z="0" S="240" T="-17" R="149" G="68" B="13" A="255"/>
+ <Vtx X="11" Y="30" Z="6" S="240" T="-17" R="205" G="89" B="75" A="255"/>
+ <Vtx X="13" Y="33" Z="0" S="87" T="304" R="210" G="118" B="7" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="-218" T="496" R="46" G="147" B="47" A="255"/>
+ <Vtx X="5" Y="15" Z="4" S="233" T="496" R="240" G="226" B="122" A="255"/>
+ <Vtx X="2" Y="21" Z="0" S="233" T="-16" R="149" G="68" B="13" A="255"/>
+ <Vtx X="14" Y="24" Z="11" S="233" T="496" R="253" G="251" B="127" A="255"/>
+ <Vtx X="11" Y="30" Z="6" S="233" T="-16" R="205" G="89" B="75" A="255"/>
+ <Vtx X="23" Y="32" Z="1" S="286" T="-16" R="71" G="98" B="39" A="255"/>
+ <Vtx X="14" Y="24" Z="11" S="233" T="496" R="253" G="251" B="127" A="255"/>
+ <Vtx X="25" Y="26" Z="6" S="286" T="496" R="90" G="6" B="90" A="255"/>
+ <Vtx X="23" Y="32" Z="1" S="286" T="-16" R="71" G="98" B="39" A="255"/>
+ <Vtx X="29" Y="19" Z="-4" S="233" T="496" R="118" G="210" B="8" A="255"/>
+ <Vtx X="26" Y="25" Z="-9" S="233" T="-16" R="98" G="39" B="186" A="255"/>
+ <Vtx X="20" Y="10" Z="-10" S="233" T="496" R="106" G="185" B="2" A="255"/>
+ <Vtx X="17" Y="16" Z="-15" S="233" T="-16" R="30" G="22" B="135" A="255"/>
+ <Vtx X="-5" Y="-29" Z="-46" S="-218" T="496" R="11" G="159" B="81" A="255"/>
+ <Vtx X="19" Y="27" Z="-11" S="87" T="304" R="252" G="61" B="145" A="255"/>
+ <Vtx X="19" Y="31" Z="-7" S="165" T="144" R="213" G="101" B="192" A="255"/>
+ <Vtx X="22" Y="30" Z="-9" S="87" T="304" R="43" G="88" B="176" A="255"/>
+ <Vtx X="17" Y="29" Z="-9" S="165" T="144" R="206" G="97" B="191" A="255"/>
+ <Vtx X="11" Y="25" Z="-9" S="240" T="304" R="191" G="65" B="168" A="255"/>
+ <Vtx X="13" Y="28" Z="-8" S="240" T="144" R="218" G="98" B="184" A="255"/>
+ <Vtx X="12" Y="30" Z="-4" S="165" T="144" R="224" G="91" B="174" A="255"/>
+ <Vtx X="10" Y="30" Z="-2" S="87" T="304" R="170" G="88" B="225" A="255"/>
+ <Vtx X="12" Y="30" Z="-4" S="165" T="144" R="224" G="91" B="174" A="255"/>
+ <Vtx X="10" Y="30" Z="-2" S="87" T="304" R="170" G="88" B="225" A="255"/>
+ <Vtx X="13" Y="33" Z="0" S="87" T="304" R="210" G="118" B="7" A="255"/>
+ <Vtx X="15" Y="33" Z="-3" S="165" T="144" R="226" G="97" B="179" A="255"/>
+ <Vtx X="15" Y="28" Z="-5" S="240" T="514" R="240" G="113" B="201" A="255"/>
+ <Vtx X="18" Y="31" Z="-3" S="240" T="514" R="186" G="55" B="165" A="255"/>
+ <Vtx X="17" Y="29" Z="-9" S="165" T="144" R="206" G="97" B="191" A="255"/>
+ <Vtx X="19" Y="31" Z="-7" S="165" T="144" R="213" G="101" B="192" A="255"/>
+ <Vtx X="13" Y="28" Z="-8" S="240" T="144" R="218" G="98" B="184" A="255"/>
+ <Vtx X="0" Y="8" Z="2" S="193" T="793" R="33" G="141" B="43" A="255"/>
+ <Vtx X="9" Y="7" Z="-3" S="18" T="772" R="23" G="159" B="79" A="255"/>
+ <Vtx X="20" Y="20" Z="2" S="-16" T="671" R="45" G="165" B="77" A="255"/>
+ <Vtx X="5" Y="15" Z="4" S="189" T="723" R="240" G="226" B="122" A="255"/>
+ <Vtx X="25" Y="26" Z="6" S="-16" T="671" R="90" G="6" B="90" A="255"/>
+ <Vtx X="29" Y="19" Z="-4" S="189" T="723" R="118" G="210" B="8" A="255"/>
+ <Vtx X="20" Y="10" Z="-10" S="189" T="723" R="106" G="185" B="2" A="255"/>
+ <Vtx X="15" Y="3" Z="-12" S="193" T="793" R="5" G="150" B="70" A="255"/>
+ <Vtx X="20" Y="10" Z="-10" S="189" T="723" R="106" G="185" B="2" A="255"/>
+ <Vtx X="20" Y="20" Z="2" S="-16" T="671" R="45" G="165" B="77" A="255"/>
+ <Vtx X="11" Y="6" Z="-5" S="18" T="772" R="44" G="152" B="58" A="255"/>
+ <Vtx X="5" Y="15" Z="4" S="189" T="723" R="240" G="226" B="122" A="255"/>
+ <Vtx X="25" Y="26" Z="6" S="-16" T="671" R="90" G="6" B="90" A="255"/>
+ <Vtx X="14" Y="24" Z="11" S="189" T="723" R="253" G="251" B="127" A="255"/>
+ <Vtx X="-5" Y="-29" Z="-46" S="496" T="1174" R="229" G="163" B="83" A="255"/>
+ <Vtx X="-5" Y="-29" Z="-46" S="496" T="1174" R="11" G="159" B="81" A="255"/>
+ <Vtx X="15" Y="3" Z="-12" S="231" T="791" R="5" G="150" B="70" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="203" T="845" R="133" G="22" B="233" A="255"/>
+ <Vtx X="11" Y="30" Z="6" S="240" T="-17" R="205" G="89" B="75" A="255"/>
+ <Vtx X="20" Y="34" Z="-3" S="240" T="304" R="30" G="123" B="246" A="255"/>
+ <Vtx X="13" Y="33" Z="0" S="87" T="304" R="210" G="118" B="7" A="255"/>
+ <Vtx X="23" Y="32" Z="1" S="240" T="-17" R="71" G="98" B="39" A="255"/>
+ <Vtx X="26" Y="25" Z="-9" S="240" T="-17" R="98" G="39" B="186" A="255"/>
+ <Vtx X="26" Y="25" Z="-9" S="240" T="-17" R="98" G="39" B="186" A="255"/>
+ <Vtx X="22" Y="30" Z="-9" S="87" T="304" R="43" G="88" B="176" A="255"/>
+ <Vtx X="20" Y="34" Z="-3" S="240" T="304" R="30" G="123" B="246" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="28" T="858" R="222" G="4" B="122" A="255"/>
+ <Vtx X="-33" Y="-29" Z="25" S="-16" T="1183" R="187" G="102" B="32" A="255"/>
+ <Vtx X="11" Y="-5" Z="16" S="-22" T="775" R="56" G="143" B="242" A="255"/>
+ <Vtx X="24" Y="8" Z="12" S="-16" T="671" R="67" G="153" B="224" A="255"/>
+ <Vtx X="10" Y="-4" Z="13" S="-22" T="775" R="47" G="146" B="213" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="28" T="858" R="161" G="27" B="176" A="255"/>
+ <Vtx X="17" Y="0" Z="25" S="189" T="723" R="88" G="184" B="57" A="255"/>
+ <Vtx X="-25" Y="-32" Z="51" S="496" T="1174" R="38" G="145" B="206" A="255"/>
+ <Vtx X="-25" Y="-32" Z="51" S="496" T="1174" R="4" G="151" B="185" A="255"/>
+ <Vtx X="12" Y="-7" Z="26" S="231" T="791" R="27" G="139" B="214" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="203" T="845" R="138" G="27" B="217" A="255"/>
+ <Vtx X="13" Y="7" Z="27" S="233" T="-16" R="231" G="44" B="117" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="119" T="259" R="138" G="27" B="217" A="255"/>
+ <Vtx X="-25" Y="-32" Z="51" S="-218" T="496" R="38" G="145" B="206" A="255"/>
+ <Vtx X="5" Y="-4" Z="23" S="141" T="259" R="159" G="182" B="37" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="107" T="259" R="222" G="4" B="122" A="255"/>
+ <Vtx X="3" Y="4" Z="18" S="193" T="-16" R="155" G="68" B="38" A="255"/>
+ <Vtx X="-33" Y="-29" Z="25" S="-226" T="496" R="177" G="94" B="34" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="107" T="259" R="161" G="27" B="176" A="255"/>
+ <Vtx X="7" Y="9" Z="6" S="233" T="-16" R="174" G="66" B="185" A="255"/>
+ <Vtx X="1" Y="-3" Z="11" S="141" T="259" R="150" G="186" B="6" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="119" T="259" R="181" G="11" B="102" A="255"/>
+ <Vtx X="-40" Y="-26" Z="-1" S="-218" T="496" R="52" G="140" B="254" A="255"/>
+ <Vtx X="7" Y="9" Z="6" S="240" T="-17" R="174" G="66" B="185" A="255"/>
+ <Vtx X="18" Y="21" Z="9" S="87" T="304" R="230" G="116" B="210" A="255"/>
+ <Vtx X="19" Y="17" Z="3" S="240" T="-17" R="254" G="74" B="153" A="255"/>
+ <Vtx X="14" Y="18" Z="10" S="87" T="304" R="174" G="94" B="230" A="255"/>
+ <Vtx X="3" Y="4" Z="18" S="240" T="-17" R="155" G="68" B="38" A="255"/>
+ <Vtx X="14" Y="18" Z="10" S="87" T="304" R="174" G="94" B="230" A="255"/>
+ <Vtx X="7" Y="9" Z="6" S="240" T="-17" R="174" G="66" B="185" A="255"/>
+ <Vtx X="11" Y="15" Z="17" S="240" T="304" R="165" G="81" B="36" A="255"/>
+ <Vtx X="18" Y="17" Z="22" S="87" T="304" R="207" G="80" B="86" A="255"/>
+ <Vtx X="13" Y="7" Z="27" S="240" T="-17" R="231" G="44" B="117" A="255"/>
+ <Vtx X="25" Y="15" Z="24" S="240" T="-17" R="59" G="50" B="101" A="255"/>
+ <Vtx X="21" Y="19" Z="21" S="87" T="304" R="10" G="101" B="77" A="255"/>
+ <Vtx X="-25" Y="-32" Z="51" S="-218" T="496" R="38" G="145" B="206" A="255"/>
+ <Vtx X="17" Y="0" Z="25" S="233" T="496" R="88" G="184" B="57" A="255"/>
+ <Vtx X="13" Y="7" Z="27" S="233" T="-16" R="231" G="44" B="117" A="255"/>
+ <Vtx X="29" Y="8" Z="22" S="233" T="496" R="104" G="208" B="55" A="255"/>
+ <Vtx X="25" Y="15" Z="24" S="233" T="-16" R="59" G="50" B="101" A="255"/>
+ <Vtx X="27" Y="19" Z="13" S="286" T="-16" R="90" G="89" B="240" A="255"/>
+ <Vtx X="31" Y="12" Z="11" S="286" T="496" R="121" G="245" B="219" A="255"/>
+ <Vtx X="23" Y="10" Z="1" S="233" T="496" R="54" G="228" B="144" A="255"/>
+ <Vtx X="23" Y="10" Z="1" S="233" T="496" R="54" G="228" B="144" A="255"/>
+ <Vtx X="19" Y="17" Z="3" S="233" T="-16" R="254" G="74" B="153" A="255"/>
+ <Vtx X="27" Y="19" Z="13" S="286" T="-16" R="90" G="89" B="240" A="255"/>
+ <Vtx X="11" Y="3" Z="4" S="233" T="496" R="38" G="204" B="146" A="255"/>
+ <Vtx X="7" Y="9" Z="6" S="233" T="-16" R="174" G="66" B="185" A="255"/>
+ <Vtx X="-40" Y="-26" Z="-1" S="-218" T="496" R="52" G="140" B="254" A="255"/>
+ <Vtx X="14" Y="18" Z="10" S="87" T="304" R="174" G="94" B="230" A="255"/>
+ <Vtx X="18" Y="21" Z="12" S="165" T="144" R="204" G="109" B="38" A="255"/>
+ <Vtx X="18" Y="21" Z="9" S="87" T="304" R="230" G="116" B="210" A="255"/>
+ <Vtx X="15" Y="19" Z="13" S="165" T="144" R="199" G="105" B="43" A="255"/>
+ <Vtx X="11" Y="15" Z="17" S="240" T="304" R="165" G="81" B="36" A="255"/>
+ <Vtx X="14" Y="17" Z="16" S="240" T="144" R="199" G="110" B="30" A="255"/>
+ <Vtx X="17" Y="18" Z="19" S="165" T="144" R="192" G="108" B="18" A="255"/>
+ <Vtx X="18" Y="17" Z="22" S="87" T="304" R="207" G="80" B="86" A="255"/>
+ <Vtx X="21" Y="19" Z="21" S="87" T="304" R="10" G="101" B="77" A="255"/>
+ <Vtx X="20" Y="20" Z="18" S="165" T="144" R="198" G="111" B="20" A="255"/>
+ <Vtx X="17" Y="17" Z="15" S="240" T="514" R="227" G="122" B="23" A="255"/>
+ <Vtx X="17" Y="18" Z="19" S="165" T="144" R="192" G="108" B="18" A="255"/>
+ <Vtx X="20" Y="20" Z="18" S="165" T="144" R="198" G="111" B="20" A="255"/>
+ <Vtx X="20" Y="19" Z="15" S="240" T="514" R="158" G="72" B="38" A="255"/>
+ <Vtx X="15" Y="19" Z="13" S="165" T="144" R="199" G="105" B="43" A="255"/>
+ <Vtx X="18" Y="21" Z="12" S="165" T="144" R="204" G="109" B="38" A="255"/>
+ <Vtx X="14" Y="17" Z="16" S="240" T="144" R="199" G="110" B="30" A="255"/>
+ <Vtx X="12" Y="-7" Z="26" S="193" T="793" R="27" G="139" B="214" A="255"/>
+ <Vtx X="11" Y="-5" Z="16" S="18" T="772" R="56" G="143" B="242" A="255"/>
+ <Vtx X="24" Y="8" Z="12" S="-16" T="671" R="67" G="153" B="224" A="255"/>
+ <Vtx X="17" Y="0" Z="25" S="189" T="723" R="88" G="184" B="57" A="255"/>
+ <Vtx X="31" Y="12" Z="11" S="-16" T="671" R="121" G="245" B="219" A="255"/>
+ <Vtx X="23" Y="10" Z="1" S="189" T="723" R="54" G="228" B="144" A="255"/>
+ <Vtx X="11" Y="3" Z="4" S="189" T="723" R="38" G="204" B="146" A="255"/>
+ <Vtx X="5" Y="-5" Z="5" S="193" T="793" R="38" G="135" B="251" A="255"/>
+ <Vtx X="10" Y="-4" Z="13" S="18" T="772" R="47" G="146" B="213" A="255"/>
+ <Vtx X="17" Y="0" Z="25" S="189" T="723" R="88" G="184" B="57" A="255"/>
+ <Vtx X="31" Y="12" Z="11" S="-16" T="671" R="121" G="245" B="219" A="255"/>
+ <Vtx X="29" Y="8" Z="22" S="189" T="723" R="104" G="208" B="55" A="255"/>
+ <Vtx X="-40" Y="-26" Z="-1" S="496" T="1174" R="35" G="138" B="32" A="255"/>
+ <Vtx X="-40" Y="-26" Z="-1" S="496" T="1174" R="52" G="140" B="254" A="255"/>
+ <Vtx X="11" Y="3" Z="4" S="189" T="723" R="38" G="204" B="146" A="255"/>
+ <Vtx X="5" Y="-5" Z="5" S="231" T="791" R="38" G="135" B="251" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="203" T="845" R="181" G="11" B="102" A="255"/>
+ <Vtx X="25" Y="15" Z="24" S="240" T="-17" R="59" G="50" B="101" A="255"/>
+ <Vtx X="23" Y="22" Z="14" S="240" T="304" R="34" G="122" B="4" A="255"/>
+ <Vtx X="21" Y="19" Z="21" S="87" T="304" R="10" G="101" B="77" A="255"/>
+ <Vtx X="27" Y="19" Z="13" S="240" T="-17" R="90" G="89" B="240" A="255"/>
+ <Vtx X="19" Y="17" Z="3" S="240" T="-17" R="254" G="74" B="153" A="255"/>
+ <Vtx X="18" Y="21" Z="9" S="87" T="304" R="230" G="116" B="210" A="255"/>
+ <Vtx X="15" Y="33" Z="-3" S="165" T="144" R="226" G="97" B="179" A="255"/>
+ <Vtx X="18" Y="33" Z="-4" S="240" T="144" R="208" G="88" B="177" A="255"/>
+ <Vtx X="18" Y="31" Z="-3" S="240" T="514" R="186" G="55" B="165" A="255"/>
+ <Vtx X="13" Y="33" Z="0" S="87" T="304" R="210" G="118" B="7" A="255"/>
+ <Vtx X="20" Y="34" Z="-3" S="240" T="304" R="30" G="123" B="246" A="255"/>
+ <Vtx X="22" Y="30" Z="-9" S="87" T="304" R="43" G="88" B="176" A="255"/>
+ <Vtx X="19" Y="31" Z="-7" S="165" T="144" R="213" G="101" B="192" A="255"/>
+ <Vtx X="20" Y="20" Z="18" S="165" T="144" R="198" G="111" B="20" A="255"/>
+ <Vtx X="21" Y="22" Z="15" S="240" T="144" R="186" G="101" B="32" A="255"/>
+ <Vtx X="20" Y="19" Z="15" S="240" T="514" R="158" G="72" B="38" A="255"/>
+ <Vtx X="21" Y="19" Z="21" S="87" T="304" R="10" G="101" B="77" A="255"/>
+ <Vtx X="23" Y="22" Z="14" S="240" T="304" R="34" G="122" B="4" A="255"/>
+ <Vtx X="18" Y="21" Z="9" S="87" T="304" R="230" G="116" B="210" A="255"/>
+ <Vtx X="18" Y="21" Z="12" S="165" T="144" R="204" G="109" B="38" A="255"/>
+</Vertex>
diff --git a/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_1 b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_1
new file mode 100644
index 000000000..85dcede42
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/gGiFlippersDL_vtx_1
@@ -0,0 +1,73 @@
+<Vertex Version="0">
+ <Vtx X="-1" Y="5" Z="-9" S="-1033" T="-1030" R="134" G="30" B="21" A="255"/>
+ <Vtx X="-24" Y="-23" Z="-28" S="-1092" T="-580" R="209" G="89" B="178" A="255"/>
+ <Vtx X="-27" Y="-16" Z="-18" S="-891" T="-665" R="209" G="90" B="179" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="-580" T="-592" R="48" G="139" B="8" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="-890" T="-1046" R="237" G="245" B="131" A="255"/>
+ <Vtx X="-1" Y="5" Z="-9" S="-1033" T="-1030" R="47" G="166" B="76" A="255"/>
+ <Vtx X="-27" Y="-16" Z="-18" S="-891" T="-665" R="47" G="166" B="77" A="255"/>
+ <Vtx X="-24" Y="-23" Z="-28" S="-1092" T="-580" R="46" G="166" B="77" A="255"/>
+ <Vtx X="-43" Y="-16" Z="-9" S="-580" T="-592" R="44" G="168" B="80" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="-890" T="-1046" R="47" G="166" B="77" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="-1033" T="-1030" R="26" G="238" B="133" A="255"/>
+ <Vtx X="-12" Y="-21" Z="-32" S="-891" T="-665" R="211" G="89" B="178" A="255"/>
+ <Vtx X="-5" Y="-29" Z="-46" S="-580" T="-592" R="229" G="163" B="83" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="-890" T="-1046" R="133" G="22" B="233" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="-1033" T="-1030" R="45" G="167" B="79" A="255"/>
+ <Vtx X="-12" Y="-21" Z="-32" S="-891" T="-665" R="45" G="167" B="78" A="255"/>
+ <Vtx X="-5" Y="-29" Z="-46" S="-580" T="-592" R="49" G="166" B="76" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="-890" T="-1046" R="46" G="167" B="78" A="255"/>
+ <Vtx X="-12" Y="-21" Z="-32" S="-891" T="-665" R="45" G="167" B="78" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="-1033" T="-1030" R="222" G="4" B="122" A="255"/>
+ <Vtx X="-33" Y="-29" Z="25" S="-1092" T="-580" R="187" G="102" B="32" A="255"/>
+ <Vtx X="-24" Y="-26" Z="34" S="-891" T="-665" R="188" G="102" B="33" A="255"/>
+ <Vtx X="-25" Y="-32" Z="51" S="-580" T="-592" R="4" G="151" B="185" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="-890" T="-1046" R="138" G="27" B="217" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="-1033" T="-1030" R="67" G="153" B="222" A="255"/>
+ <Vtx X="-24" Y="-26" Z="34" S="-891" T="-665" R="68" G="154" B="223" A="255"/>
+ <Vtx X="-33" Y="-29" Z="25" S="-1092" T="-580" R="67" G="153" B="224" A="255"/>
+ <Vtx X="-25" Y="-32" Z="51" S="-580" T="-592" R="69" G="153" B="227" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="-890" T="-1046" R="67" G="153" B="223" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="-1033" T="-1030" R="161" G="27" B="176" A="255"/>
+ <Vtx X="-30" Y="-24" Z="13" S="-891" T="-665" R="188" G="103" B="31" A="255"/>
+ <Vtx X="-40" Y="-26" Z="-1" S="-580" T="-592" R="35" G="138" B="32" A="255"/>
+ <Vtx X="-30" Y="-24" Z="13" S="-891" T="-665" R="188" G="103" B="31" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="-890" T="-1046" R="181" G="11" B="102" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="-1033" T="-1030" R="68" G="153" B="226" A="255"/>
+ <Vtx X="-33" Y="-29" Z="25" S="-1092" T="-580" R="67" G="153" B="224" A="255"/>
+ <Vtx X="-30" Y="-24" Z="13" S="-891" T="-665" R="68" G="153" B="225" A="255"/>
+ <Vtx X="-40" Y="-26" Z="-1" S="-580" T="-592" R="67" G="154" B="221" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="-890" T="-1046" R="68" G="153" B="225" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="-888" T="-1046" R="237" G="245" B="131" A="255"/>
+ <Vtx X="-1" Y="8" Z="-5" S="-966" T="-1078" R="166" G="176" B="215" A="255"/>
+ <Vtx X="-1" Y="5" Z="-9" S="-1034" T="-1030" R="134" G="30" B="21" A="255"/>
+ <Vtx X="-27" Y="-16" Z="-18" S="-891" T="-665" R="209" G="90" B="179" A="255"/>
+ <Vtx X="-5" Y="8" Z="-3" S="-888" T="-1046" R="47" G="166" B="77" A="255"/>
+ <Vtx X="-27" Y="-16" Z="-18" S="-891" T="-665" R="47" G="166" B="77" A="255"/>
+ <Vtx X="-1" Y="5" Z="-9" S="-1034" T="-1030" R="47" G="166" B="76" A="255"/>
+ <Vtx X="-1" Y="8" Z="-5" S="-966" T="-1078" R="47" G="166" B="77" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="-888" T="-1046" R="133" G="22" B="233" A="255"/>
+ <Vtx X="-12" Y="-21" Z="-32" S="-891" T="-665" R="211" G="89" B="178" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="-1034" T="-1030" R="26" G="238" B="133" A="255"/>
+ <Vtx X="9" Y="5" Z="-14" S="-966" T="-1078" R="188" G="169" B="193" A="255"/>
+ <Vtx X="10" Y="3" Z="-18" S="-888" T="-1046" R="46" G="167" B="78" A="255"/>
+ <Vtx X="9" Y="5" Z="-14" S="-966" T="-1078" R="45" G="167" B="78" A="255"/>
+ <Vtx X="3" Y="3" Z="-14" S="-1034" T="-1030" R="45" G="167" B="79" A="255"/>
+ <Vtx X="-12" Y="-21" Z="-32" S="-891" T="-665" R="45" G="167" B="78" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="-888" T="-1046" R="138" G="27" B="217" A="255"/>
+ <Vtx X="5" Y="-4" Z="23" S="-966" T="-1078" R="159" G="182" B="37" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="-1034" T="-1030" R="222" G="4" B="122" A="255"/>
+ <Vtx X="-24" Y="-26" Z="34" S="-891" T="-665" R="188" G="102" B="33" A="255"/>
+ <Vtx X="4" Y="-6" Z="28" S="-888" T="-1046" R="67" G="153" B="223" A="255"/>
+ <Vtx X="-24" Y="-26" Z="34" S="-891" T="-665" R="68" G="154" B="223" A="255"/>
+ <Vtx X="0" Y="-6" Z="21" S="-1034" T="-1030" R="67" G="153" B="222" A="255"/>
+ <Vtx X="5" Y="-4" Z="23" S="-966" T="-1078" R="67" G="153" B="223" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="-888" T="-1046" R="181" G="11" B="102" A="255"/>
+ <Vtx X="-30" Y="-24" Z="13" S="-891" T="-665" R="188" G="103" B="31" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="-1034" T="-1030" R="161" G="27" B="176" A="255"/>
+ <Vtx X="1" Y="-3" Z="11" S="-966" T="-1078" R="150" G="186" B="6" A="255"/>
+ <Vtx X="-2" Y="-4" Z="7" S="-888" T="-1046" R="68" G="153" B="225" A="255"/>
+ <Vtx X="1" Y="-3" Z="11" S="-966" T="-1078" R="68" G="153" B="225" A="255"/>
+ <Vtx X="-1" Y="-5" Z="15" S="-1034" T="-1030" R="68" G="153" B="226" A="255"/>
+ <Vtx X="-30" Y="-24" Z="13" S="-891" T="-665" R="68" G="153" B="225" A="255"/>
+</Vertex>
diff --git a/mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers b/mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers
new file mode 100644
index 000000000..b456d6367
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers
@@ -0,0 +1,21 @@
+<DisplayList Version="0">
+ <PipeSync/>
+ <SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_SHADE" D0="G_CCMUX_0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
+ <SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_TEXTURE_GEN="1" G_SHADING_SMOOTH="1" />
+ <ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN_LINEAR="1" />
+ <SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" />
+ <SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_FOG_SHADE_A="1" G_RM_AA_ZB_OPA_SURF2="1" />
+ <Texture S="960" T="960" Level="0" Tile="0" On="1"/>
+ <SetTextureLUT Mode="G_TT_NONE"/>
+ <TileSync/>
+ <SetTextureImage Path="objects/object_ability_swim/flippers" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
+ <SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Line="0" TMem="0" Tile="7" Palette="0" Cms0="G_TX_CLAMP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_CLAMP" Cmt1="G_TX_NOMIRROR" MaskS="4" ShiftS="0" MaskT="4" ShiftT="0"/>
+ <LoadSync/>
+ <LoadBlock Tile="7" Uls="0" Ult="0" Lrs="255" Dxt="512"/>
+ <PipeSync/>
+ <SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" Line="4" TMem="0" Tile="0" Palette="0" Cms0="G_TX_CLAMP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_CLAMP" Cmt1="G_TX_NOMIRROR" MaskS="4" ShiftS="0" MaskT="4" ShiftT="0"/>
+ <SetTileSize T="0" Uls="0" Ult="0" Lrs="60" Lrt="60"/>
+ <SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255"/>
+ <EndDisplayList/>
+</DisplayList>
+
diff --git a/mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers2 b/mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers2
new file mode 100644
index 000000000..b3d6c1821
--- /dev/null
+++ b/mm/assets/custom/objects/object_ability_swim/mat_gGiFlippersDL_flippers2
@@ -0,0 +1,21 @@
+<DisplayList Version="0">
+ <PipeSync/>
+ <SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_SHADE" D0="G_CCMUX_0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
+ <SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_SHADING_SMOOTH="1" />
+ <ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN="1" G_TEXTURE_GEN_LINEAR="1" />
+ <SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" />
+ <SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_FOG_SHADE_A="1" G_RM_AA_ZB_OPA_SURF2="1" />
+ <Texture S="65535" T="65535" Level="0" Tile="0" On="1"/>
+ <SetTextureLUT Mode="G_TT_NONE"/>
+ <TileSync/>
+ <SetTextureImage Path="objects/object_ability_swim/flippers2" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
+ <SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Line="0" TMem="0" Tile="7" Palette="0" Cms0="G_TX_CLAMP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_CLAMP" Cmt1="G_TX_NOMIRROR" MaskS="4" ShiftS="0" MaskT="4" ShiftT="0"/>
+ <LoadSync/>
+ <LoadBlock Tile="7" Uls="0" Ult="0" Lrs="255" Dxt="512"/>
+ <PipeSync/>
+ <SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" Line="4" TMem="0" Tile="0" Palette="0" Cms0="G_TX_CLAMP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_CLAMP" Cmt1="G_TX_NOMIRROR" MaskS="4" ShiftS="0" MaskT="4" ShiftT="0"/>
+ <SetTileSize T="0" Uls="0" Ult="0" Lrs="60" Lrt="60"/>
+ <SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255"/>
+ <EndDisplayList/>
+</DisplayList>
+