summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2024-12-14 08:58:39 -0600
committerGarrett Cox <garrettjcox@gmail.com>2024-12-14 08:58:39 -0600
commitbaa926d9487501aa42a9e39418b56fc4532f21ea (patch)
tree578e09122127a2318cd1fbe38964335319551961
parentb4af8ab7687d4419680f99b94c51f6a847c1db35 (diff)
Tingle checks
Co-authored-by: Caladius <Caladius@users.noreply.github.com>
-rw-r--r--mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp1
-rw-r--r--mm/2s2h/Enhancements/Cutscenes/Cutscenes.h1
-rw-r--r--mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipTingleTime.cpp15
-rw-r--r--mm/2s2h/GameInteractor/GameInteractor.h2
-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/EnBal.cpp73
-rw-r--r--mm/2s2h/Rando/ConvertItem.cpp8
-rw-r--r--mm/2s2h/Rando/GiveItem.cpp32
-rw-r--r--mm/2s2h/Rando/Logic/Regions.cpp21
-rw-r--r--mm/2s2h/Rando/RemoveItem.cpp8
-rw-r--r--mm/2s2h/Rando/StaticData/Checks.cpp22
-rw-r--r--mm/2s2h/Rando/StaticData/Items.cpp14
-rw-r--r--mm/2s2h/Rando/Types.h19
-rw-r--r--mm/src/overlays/actors/ovl_En_Bal/z_en_bal.c15
15 files changed, 206 insertions, 27 deletions
diff --git a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp
index 4f4c4ca73..e4d73464c 100644
--- a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp
+++ b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp
@@ -11,6 +11,7 @@ void RegisterCutscenes() {
RegisterSkipMayorsOfficeCutscene();
RegisterSkipPushingMikau();
RegisterSkipKamaroTeachDance();
+ RegisterSkipTingleTime();
// StoryCutscenes
RegisterSkipClockTowerOpen();
diff --git a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h
index e1270b86a..b463432a7 100644
--- a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h
+++ b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h
@@ -13,6 +13,7 @@ void RegisterSkipTatlInterrupts();
void RegisterSkipMayorsOfficeCutscene();
void RegisterSkipPushingMikau();
void RegisterSkipKamaroTeachDance();
+void RegisterSkipTingleTime();
// StoryCutscenes
void RegisterSkipClockTowerOpen();
diff --git a/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipTingleTime.cpp b/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipTingleTime.cpp
new file mode 100644
index 000000000..b0929dd5d
--- /dev/null
+++ b/mm/2s2h/Enhancements/Cutscenes/MiscInteractions/SkipTingleTime.cpp
@@ -0,0 +1,15 @@
+#include <libultraship/bridge.h>
+#include "2s2h/GameInteractor/GameInteractor.h"
+
+extern "C" {
+#include "functions.h"
+}
+
+void RegisterSkipTingleTime() {
+ GameInteractor::Instance->RegisterGameHookForID<GameInteractor::ShouldActorInit>(
+ ACTOR_EN_BAL, [](Actor* actor, bool* should) {
+ if (CVarGetInteger("gEnhancements.Cutscenes.SkipMiscInteractions", 0)) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_TINGLE);
+ }
+ });
+}
diff --git a/mm/2s2h/GameInteractor/GameInteractor.h b/mm/2s2h/GameInteractor/GameInteractor.h
index b7cd406fc..ce0a7cd22 100644
--- a/mm/2s2h/GameInteractor/GameInteractor.h
+++ b/mm/2s2h/GameInteractor/GameInteractor.h
@@ -147,6 +147,8 @@ typedef enum {
VB_PASS_SECOND_BANK_THRESHOLD,
VB_PASS_SECOND_BANK_THRESHOLD_ALT,
VB_CLEAR_B_BUTTON_FOR_HORSEBACK,
+ VB_ALREADY_HAVE_TINGLE_MAP,
+ VB_TINGLE_GIVE_MAP_UNLOCK,
VB_OWL_STATUE_ACTIVATE,
} GIVanillaBehavior;
diff --git a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
index 741a3385e..3f0618bef 100644
--- a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
+++ b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
@@ -47,6 +47,7 @@ void Rando::ActorBehavior::OnFileLoad() {
Rando::ActorBehavior::InitEnSiBehavior();
Rando::ActorBehavior::InitEnStoneheishiBehavior();
Rando::ActorBehavior::InitEnBabaBehavior();
+ Rando::ActorBehavior::InitEnBalBehavior();
Rando::ActorBehavior::InitEnYbBehavior();
Rando::ActorBehavior::InitEnRzBehavior();
Rando::ActorBehavior::InitEnMnkBehavior();
diff --git a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
index 76ae17602..c9fcb7350 100644
--- a/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
+++ b/mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
@@ -33,6 +33,7 @@ void InitEnSellnutsBehavior();
void InitEnSiBehavior();
void InitEnStoneheishiBehavior();
void InitEnBabaBehavior();
+void InitEnBalBehavior();
void InitEnYbBehavior();
void InitEnRzBehavior();
void InitEnMnkBehavior();
diff --git a/mm/2s2h/Rando/ActorBehavior/EnBal.cpp b/mm/2s2h/Rando/ActorBehavior/EnBal.cpp
new file mode 100644
index 000000000..7f33aeadf
--- /dev/null
+++ b/mm/2s2h/Rando/ActorBehavior/EnBal.cpp
@@ -0,0 +1,73 @@
+#include "ActorBehavior.h"
+#include <libultraship/libultraship.h>
+
+extern "C" {
+#include "variables.h"
+#include "overlays/actors/ovl_En_Bal/z_en_bal.h"
+void EnBal_SetupTalk(EnBal* enBal);
+}
+
+std::map<int16_t, std::vector<RandoCheckId>> tingleMap = {
+ { SCENE_BACKTOWN, { RC_CLOCK_TOWN_NORTH_TINGLE_MAP_1, RC_CLOCK_TOWN_NORTH_TINGLE_MAP_2 } },
+ { SCENE_24KEMONOMITI, { RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_1, RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_2 } },
+ { SCENE_17SETUGEN, { RC_TWIN_ISLANDS_TINGLE_MAP_1, RC_TWIN_ISLANDS_TINGLE_MAP_2 } },
+ { SCENE_ROMANYMAE, { RC_MILK_ROAD_TINGLE_MAP_1, RC_MILK_ROAD_TINGLE_MAP_2 } },
+ { SCENE_30GYOSON, { RC_GREAT_BAY_COAST_TINGLE_MAP_1, RC_GREAT_BAY_COAST_TINGLE_MAP_2 } },
+ { SCENE_IKANA, { RC_IKANA_CANYON_TINGLE_MAP_1, RC_IKANA_CANYON_TINGLE_MAP_2 } }
+};
+
+void OnOpenText(u16* textId, bool* loadFromMessageTable) {
+ RandoItemId randoItemId1 = RANDO_SAVE_CHECKS[tingleMap[gPlayState->sceneId][0]].randoItemId;
+ RandoItemId randoItemId2 = RANDO_SAVE_CHECKS[tingleMap[gPlayState->sceneId][1]].randoItemId;
+
+ randoItemId1 = Rando::ConvertItem(randoItemId1, tingleMap[gPlayState->sceneId][0]);
+ randoItemId2 = Rando::ConvertItem(randoItemId2, tingleMap[gPlayState->sceneId][1]);
+
+ auto entry = CustomMessage::LoadVanillaMessageTableEntry(*textId);
+ entry.autoFormat = false;
+
+ entry.msg = "\x02\xC3{item1}\x01 20 Rupees\x11"
+ "\x02{item2}\x01 40 Rupees\x11"
+ "\x02No thanks";
+
+ CustomMessage::Replace(&entry.msg, "{item1}", Rando::StaticData::Items[randoItemId1].name);
+ CustomMessage::Replace(&entry.msg, "{item2}", Rando::StaticData::Items[randoItemId2].name);
+ CustomMessage::EnsureMessageEnd(&entry.msg);
+ CustomMessage::LoadCustomMessageIntoFont(entry);
+ *loadFromMessageTable = false;
+};
+
+void Rando::ActorBehavior::InitEnBalBehavior() {
+ COND_VB_SHOULD(VB_ALREADY_HAVE_TINGLE_MAP, IS_RANDO, {
+ EnBal* enBal = va_arg(args, EnBal*);
+ s32* price = va_arg(args, s32*);
+ // TODO: Allow randomization of price
+ if (gPlayState->msgCtx.choiceIndex == 0) {
+ *price = 20;
+ } else {
+ *price = 40;
+ }
+
+ if (RANDO_SAVE_CHECKS[tingleMap[gPlayState->sceneId][gPlayState->msgCtx.choiceIndex]].obtained) {
+ *should = true;
+ } else {
+ *should = false;
+ }
+ });
+
+ COND_VB_SHOULD(VB_TINGLE_GIVE_MAP_UNLOCK, IS_RANDO, {
+ EnBal* enBal = va_arg(args, EnBal*);
+ RANDO_SAVE_CHECKS[tingleMap[gPlayState->sceneId][gPlayState->msgCtx.choiceIndex]].eligible = true;
+ Message_StartTextbox(gPlayState, 0x1D17, &enBal->picto.actor);
+ enBal->textId = 0x1D17;
+ EnBal_SetupTalk(enBal);
+ *should = false;
+ });
+
+ COND_ID_HOOK(OnOpenText, 0x1D11, IS_RANDO, OnOpenText);
+ COND_ID_HOOK(OnOpenText, 0x1D12, IS_RANDO, OnOpenText);
+ COND_ID_HOOK(OnOpenText, 0x1D13, IS_RANDO, OnOpenText);
+ COND_ID_HOOK(OnOpenText, 0x1D14, IS_RANDO, OnOpenText);
+ COND_ID_HOOK(OnOpenText, 0x1D15, IS_RANDO, OnOpenText);
+ COND_ID_HOOK(OnOpenText, 0x1D16, IS_RANDO, OnOpenText);
+}
diff --git a/mm/2s2h/Rando/ConvertItem.cpp b/mm/2s2h/Rando/ConvertItem.cpp
index 954e280d7..b541d5b5d 100644
--- a/mm/2s2h/Rando/ConvertItem.cpp
+++ b/mm/2s2h/Rando/ConvertItem.cpp
@@ -285,25 +285,25 @@ bool Rando::IsItemObtainable(RandoItemId randoItemId, RandoCheckId randoCheckId)
return !CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, DUNGEON_INDEX_WOODFALL_TEMPLE);
case RI_WOODFALL_COMPASS:
return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, DUNGEON_INDEX_WOODFALL_TEMPLE);
- case RI_WOODFALL_MAP:
+ case RI_WOODFALL_TEMPLE_MAP:
return !CHECK_DUNGEON_ITEM(DUNGEON_MAP, DUNGEON_INDEX_WOODFALL_TEMPLE);
case RI_SNOWHEAD_BOSS_KEY:
return !CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, DUNGEON_INDEX_SNOWHEAD_TEMPLE);
case RI_SNOWHEAD_COMPASS:
return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, DUNGEON_INDEX_SNOWHEAD_TEMPLE);
- case RI_SNOWHEAD_MAP:
+ case RI_SNOWHEAD_TEMPLE_MAP:
return !CHECK_DUNGEON_ITEM(DUNGEON_MAP, DUNGEON_INDEX_SNOWHEAD_TEMPLE);
case RI_GREAT_BAY_BOSS_KEY:
return !CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, DUNGEON_INDEX_GREAT_BAY_TEMPLE);
case RI_GREAT_BAY_COMPASS:
return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, DUNGEON_INDEX_GREAT_BAY_TEMPLE);
- case RI_GREAT_BAY_MAP:
+ case RI_GREAT_BAY_TEMPLE_MAP:
return !CHECK_DUNGEON_ITEM(DUNGEON_MAP, DUNGEON_INDEX_GREAT_BAY_TEMPLE);
case RI_STONE_TOWER_BOSS_KEY:
return !CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, DUNGEON_INDEX_STONE_TOWER_TEMPLE);
case RI_STONE_TOWER_COMPASS:
return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, DUNGEON_INDEX_STONE_TOWER_TEMPLE);
- case RI_STONE_TOWER_MAP:
+ case RI_STONE_TOWER_TEMPLE_MAP:
return !CHECK_DUNGEON_ITEM(DUNGEON_MAP, DUNGEON_INDEX_STONE_TOWER_TEMPLE);
// These items are technically fine to receive again because they don't do anything, but we'll convert them to
// ensure it's clear to the player something didn't go wrong.
diff --git a/mm/2s2h/Rando/GiveItem.cpp b/mm/2s2h/Rando/GiveItem.cpp
index 881d71315..361ab162f 100644
--- a/mm/2s2h/Rando/GiveItem.cpp
+++ b/mm/2s2h/Rando/GiveItem.cpp
@@ -44,7 +44,7 @@ void Rando::GiveItem(RandoItemId randoItemId) {
// Don't love this because it doesn't hit GameInteractor_ExecuteOnItemGive()
// but not sure how else to account for collecting outside of dungeon
case RI_WOODFALL_BOSS_KEY:
- case RI_WOODFALL_MAP:
+ case RI_WOODFALL_TEMPLE_MAP:
case RI_WOODFALL_COMPASS:
SET_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_WOODFALL_TEMPLE);
@@ -59,7 +59,7 @@ void Rando::GiveItem(RandoItemId randoItemId) {
}
break;
case RI_SNOWHEAD_BOSS_KEY:
- case RI_SNOWHEAD_MAP:
+ case RI_SNOWHEAD_TEMPLE_MAP:
case RI_SNOWHEAD_COMPASS:
SET_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_SNOWHEAD_TEMPLE);
@@ -74,7 +74,7 @@ void Rando::GiveItem(RandoItemId randoItemId) {
}
break;
case RI_GREAT_BAY_BOSS_KEY:
- case RI_GREAT_BAY_MAP:
+ case RI_GREAT_BAY_TEMPLE_MAP:
case RI_GREAT_BAY_COMPASS:
SET_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_GREAT_BAY_TEMPLE);
@@ -89,7 +89,7 @@ void Rando::GiveItem(RandoItemId randoItemId) {
}
break;
case RI_STONE_TOWER_BOSS_KEY:
- case RI_STONE_TOWER_MAP:
+ case RI_STONE_TOWER_TEMPLE_MAP:
case RI_STONE_TOWER_COMPASS:
SET_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_STONE_TOWER_TEMPLE);
@@ -172,6 +172,30 @@ void Rando::GiveItem(RandoItemId randoItemId) {
Item_Give(gPlayState, Rando::StaticData::Items[randoItemId].itemId);
break;
+ case RI_CLOCK_TOWN_MAP:
+ Inventory_SetWorldMapCloudVisibility(TINGLE_MAP_CLOCK_TOWN);
+ SET_WEEKEVENTREG(WEEKEVENTREG_TINGLE_MAP_BOUGHT_CLOCK_TOWN);
+ break;
+ case RI_WOODFALL_MAP:
+ Inventory_SetWorldMapCloudVisibility(TINGLE_MAP_WOODFALL);
+ SET_WEEKEVENTREG(WEEKEVENTREG_TINGLE_MAP_BOUGHT_WOODFALL);
+ break;
+ case RI_GREAT_BAY_MAP:
+ Inventory_SetWorldMapCloudVisibility(TINGLE_MAP_SNOWHEAD);
+ SET_WEEKEVENTREG(WEEKEVENTREG_TINGLE_MAP_BOUGHT_SNOWHEAD);
+ break;
+ case RI_ROMANI_RANCH_MAP:
+ Inventory_SetWorldMapCloudVisibility(TINGLE_MAP_ROMANI_RANCH);
+ SET_WEEKEVENTREG(WEEKEVENTREG_TINGLE_MAP_BOUGHT_ROMANI_RANCH);
+ break;
+ case RI_SNOWHEAD_MAP:
+ Inventory_SetWorldMapCloudVisibility(TINGLE_MAP_GREAT_BAY);
+ SET_WEEKEVENTREG(WEEKEVENTREG_TINGLE_MAP_BOUGHT_GREAT_BAY);
+ break;
+ case RI_STONE_TOWER_MAP:
+ Inventory_SetWorldMapCloudVisibility(TINGLE_MAP_STONE_TOWER);
+ SET_WEEKEVENTREG(WEEKEVENTREG_TINGLE_MAP_BOUGHT_STONE_TOWER);
+ break;
case RI_OWL_CLOCK_TOWN_SOUTH:
Sram_ActivateOwl(OWL_WARP_CLOCK_TOWN);
break;
diff --git a/mm/2s2h/Rando/Logic/Regions.cpp b/mm/2s2h/Rando/Logic/Regions.cpp
index 35aedf393..24ad8ffc9 100644
--- a/mm/2s2h/Rando/Logic/Regions.cpp
+++ b/mm/2s2h/Rando/Logic/Regions.cpp
@@ -317,6 +317,8 @@ std::unordered_map<RandoRegionId, RandoRegion> Regions = {
} },
{ RR_CLOCK_TOWN_NORTH, RandoRegion{ .sceneId = SCENE_BACKTOWN,
.checks = {
+ CHECK(RC_CLOCK_TOWN_NORTH_TINGLE_MAP_1, CAN_USE_PROJECTILE),
+ CHECK(RC_CLOCK_TOWN_NORTH_TINGLE_MAP_2, CAN_USE_PROJECTILE),
CHECK(RC_CLOCK_TOWN_NORTH_TREE_HP, true),
CHECK(RC_CLOCK_TOWN_NORTH_BOMB_LADY, CAN_USE_SWORD || CAN_BE_ZORA || CAN_BE_GORON),
},
@@ -487,6 +489,8 @@ std::unordered_map<RandoRegionId, RandoRegion> Regions = {
CHECK(RC_GREAT_BAY_COAST_POT_LEDGE_1, HAS_ITEM(ITEM_HOOKSHOT)),
CHECK(RC_GREAT_BAY_COAST_POT_LEDGE_2, HAS_ITEM(ITEM_HOOKSHOT)),
CHECK(RC_GREAT_BAY_COAST_POT_LEDGE_3, HAS_ITEM(ITEM_HOOKSHOT)),
+ CHECK(RC_GREAT_BAY_COAST_TINGLE_MAP_1, CAN_USE_PROJECTILE),
+ CHECK(RC_GREAT_BAY_COAST_TINGLE_MAP_2, CAN_USE_PROJECTILE),
},
.exits = { // TO FROM
EXIT(ENTRANCE(TERMINA_FIELD, 2), ENTRANCE(GREAT_BAY_COAST, 0), true),
@@ -552,6 +556,8 @@ std::unordered_map<RandoRegionId, RandoRegion> Regions = {
{ RR_IKANA_CANYON_UPPER, RandoRegion{ .name = "Upper", .sceneId = SCENE_IKANA,
.checks = {
CHECK(RC_IKANA_CANYON_OWL_STATUE, CAN_USE_SWORD),
+ CHECK(RC_IKANA_CANYON_TINGLE_MAP_1, CAN_USE_PROJECTILE),
+ CHECK(RC_IKANA_CANYON_TINGLE_MAP_2, CAN_USE_PROJECTILE),
},
.exits = { // TO FROM
EXIT(ENTRANCE(GHOST_HUT, 0), ENTRANCE(IKANA_CANYON, 1), true),
@@ -671,6 +677,8 @@ std::unordered_map<RandoRegionId, RandoRegion> Regions = {
{ RR_MILK_ROAD, RandoRegion{ .sceneId = SCENE_ROMANYMAE,
.checks = {
CHECK(RC_MILK_ROAD_OWL_STATUE, CAN_USE_SWORD),
+ CHECK(RC_MILK_ROAD_TINGLE_MAP_1, CAN_USE_PROJECTILE),
+ CHECK(RC_MILK_ROAD_TINGLE_MAP_2, CAN_USE_PROJECTILE),
},
.exits = { // TO FROM
EXIT(ENTRANCE(TERMINA_FIELD, 5), ENTRANCE(MILK_ROAD, 0), true),
@@ -719,6 +727,17 @@ std::unordered_map<RandoRegionId, RandoRegion> Regions = {
EXIT(ENTRANCE(IKANA_CANYON, 2), ENTRANCE(MUSIC_BOX_HOUSE, 0), true),
},
} },
+ { RR_PATH_TO_GORON_VILLAGE, RandoRegion{ .sceneId = SCENE_17SETUGEN,
+ .checks = {
+ CHECK(RC_TWIN_ISLANDS_TINGLE_MAP_1, CAN_USE_PROJECTILE),
+ CHECK(RC_TWIN_ISLANDS_TINGLE_MAP_2, CAN_USE_PROJECTILE),
+ },
+ .exits = { // TO FROM
+ EXIT(ENTRANCE(MOUNTAIN_VILLAGE_WINTER, 2), ENTRANCE(PATH_TO_GORON_VILLAGE_WINTER, 0), true),
+ EXIT(ENTRANCE(GORON_VILLAGE_WINTER, 0), ENTRANCE(PATH_TO_GORON_VILLAGE_WINTER, 1), true),
+ EXIT(ENTRANCE(GORON_RACETRACK, 0), ENTRANCE(PATH_TO_GORON_VILLAGE_WINTER, 2), HAS_ITEM(ITEM_POWDER_KEG) && CAN_BE_GORON),
+ },
+ } },
{ RR_PATH_TO_MOUNTAIN_VILLAGE, RandoRegion{ .sceneId = SCENE_13HUBUKINOMITI,
.exits = { // TO FROM
EXIT(ENTRANCE(TERMINA_FIELD, 3), ENTRANCE(PATH_TO_MOUNTAIN_VILLAGE, 0), true),
@@ -1104,6 +1123,8 @@ std::unordered_map<RandoRegionId, RandoRegion> Regions = {
{ RR_ROAD_TO_SOUTHERN_SWAMP, RandoRegion{ .sceneId = SCENE_24KEMONOMITI,
.checks = {
CHECK(RC_ROAD_TO_SOUTHERN_SWAMP_HP, true),
+ CHECK(RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_1, CAN_USE_PROJECTILE),
+ CHECK(RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_2, CAN_USE_PROJECTILE),
},
.exits = { // TO FROM
EXIT(ENTRANCE(TERMINA_FIELD, 1), ENTRANCE(ROAD_TO_SOUTHERN_SWAMP, 0), true),
diff --git a/mm/2s2h/Rando/RemoveItem.cpp b/mm/2s2h/Rando/RemoveItem.cpp
index 1de95e2ad..782429545 100644
--- a/mm/2s2h/Rando/RemoveItem.cpp
+++ b/mm/2s2h/Rando/RemoveItem.cpp
@@ -37,7 +37,7 @@ void Rando::RemoveItem(RandoItemId randoItemId) {
gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired = false;
break;
case RI_WOODFALL_BOSS_KEY:
- case RI_WOODFALL_MAP:
+ case RI_WOODFALL_TEMPLE_MAP:
case RI_WOODFALL_COMPASS:
REMOVE_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_WOODFALL_TEMPLE);
@@ -47,7 +47,7 @@ void Rando::RemoveItem(RandoItemId randoItemId) {
gSaveContext.save.shipSaveInfo.rando.foundDungeonKeys[DUNGEON_INDEX_WOODFALL_TEMPLE]--;
break;
case RI_SNOWHEAD_BOSS_KEY:
- case RI_SNOWHEAD_MAP:
+ case RI_SNOWHEAD_TEMPLE_MAP:
case RI_SNOWHEAD_COMPASS:
REMOVE_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_SNOWHEAD_TEMPLE);
@@ -57,7 +57,7 @@ void Rando::RemoveItem(RandoItemId randoItemId) {
gSaveContext.save.shipSaveInfo.rando.foundDungeonKeys[DUNGEON_INDEX_WOODFALL_TEMPLE]--;
break;
case RI_GREAT_BAY_BOSS_KEY:
- case RI_GREAT_BAY_MAP:
+ case RI_GREAT_BAY_TEMPLE_MAP:
case RI_GREAT_BAY_COMPASS:
REMOVE_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_GREAT_BAY_TEMPLE);
@@ -67,7 +67,7 @@ void Rando::RemoveItem(RandoItemId randoItemId) {
gSaveContext.save.shipSaveInfo.rando.foundDungeonKeys[DUNGEON_INDEX_WOODFALL_TEMPLE]--;
break;
case RI_STONE_TOWER_BOSS_KEY:
- case RI_STONE_TOWER_MAP:
+ case RI_STONE_TOWER_TEMPLE_MAP:
case RI_STONE_TOWER_COMPASS:
REMOVE_DUNGEON_ITEM(Rando::StaticData::Items[randoItemId].itemId - ITEM_KEY_BOSS,
DUNGEON_INDEX_STONE_TOWER_TEMPLE);
diff --git a/mm/2s2h/Rando/StaticData/Checks.cpp b/mm/2s2h/Rando/StaticData/Checks.cpp
index 24b56c0d2..37a1dee84 100644
--- a/mm/2s2h/Rando/StaticData/Checks.cpp
+++ b/mm/2s2h/Rando/StaticData/Checks.cpp
@@ -42,6 +42,8 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_CLOCK_TOWN_GREAT_FAIRY, RCTYPE_NPC, SCENE_YOUSEI_IZUMI, FLAG_NONE, 0x00, RI_PROGRESSIVE_MAGIC),
RC(RC_CLOCK_TOWN_LAUNDRY_GURU_GURU, RCTYPE_NPC, SCENE_ALLEY, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_38_40, RI_MASK_BREMEN),
RC(RC_CLOCK_TOWN_NORTH_BOMB_LADY, RCTYPE_NPC, SCENE_BACKTOWN, FLAG_CYCL_SCENE_COLLECTIBLE, WEEKEVENTREG_BOMBERS_NOTEBOOK_EVENT_RECEIVED_BLAST_MASK, RI_MASK_BLAST),
+ RC(RC_CLOCK_TOWN_NORTH_TINGLE_MAP_1, RCTYPE_NPC, SCENE_BACKTOWN, FLAG_NONE, 0x00, RI_CLOCK_TOWN_MAP),
+ RC(RC_CLOCK_TOWN_NORTH_TINGLE_MAP_2, RCTYPE_NPC, SCENE_BACKTOWN, FLAG_NONE, 0x00, RI_WOODFALL_MAP),
RC(RC_CLOCK_TOWN_NORTH_TREE_HP, RCTYPE_FREESTANDING, SCENE_BACKTOWN, FLAG_CYCL_SCENE_COLLECTIBLE, 0x0A, RI_HEART_PIECE),
RC(RC_CLOCK_TOWN_SCRUB_DEED, RCTYPE_NPC, SCENE_CLOCKTOWER, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_17_80, RI_DEED_LAND),
RC(RC_CLOCK_TOWN_SOUTH_CHEST_LOWER, RCTYPE_CHEST, SCENE_CLOCKTOWER, FLAG_CYCL_SCENE_CHEST, 0x00, RI_RUPEE_RED),
@@ -73,6 +75,8 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_GREAT_BAY_COAST_HP, RCTYPE_FREESTANDING, SCENE_30GYOSON, FLAG_CYCL_SCENE_COLLECTIBLE, 0x05, RI_HEART_PIECE),
RC(RC_GREAT_BAY_COAST_MIKAU, RCTYPE_NPC, SCENE_30GYOSON, FLAG_NONE, 0x00, RI_MASK_ZORA),
RC(RC_GREAT_BAY_COAST_OWL_STATUE, RCTYPE_OWL, SCENE_30GYOSON, FLAG_NONE, 0x00, RI_OWL_GREAT_BAY_COAST),
+ RC(RC_GREAT_BAY_COAST_TINGLE_MAP_1, RCTYPE_NPC, SCENE_30GYOSON, FLAG_NONE, 0x00, RI_GREAT_BAY_MAP),
+ RC(RC_GREAT_BAY_COAST_TINGLE_MAP_2, RCTYPE_NPC, SCENE_30GYOSON, FLAG_NONE, 0x00, RI_STONE_TOWER_MAP),
RC(RC_GREAT_BAY_GREAT_FAIRY, RCTYPE_NPC, SCENE_YOUSEI_IZUMI, FLAG_NONE, 0x00, RI_DOUBLE_DEFENSE),
RC(RC_GREAT_BAY_TEMPLE_BABA_CHEST, RCTYPE_CHEST, SCENE_SEA, FLAG_CYCL_SCENE_CHEST, 0x19, RI_GREAT_BAY_STRAY_FAIRY),
RC(RC_GREAT_BAY_TEMPLE_BOSS_HC, RCTYPE_FREESTANDING, SCENE_SEA_BS, FLAG_CYCL_SCENE_COLLECTIBLE, 0x1f, RI_HEART_CONTAINER),
@@ -86,7 +90,7 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_2_UPPER_CHEST, RCTYPE_CHEST, SCENE_SEA, FLAG_CYCL_SCENE_CHEST, 0x14, RI_GREAT_BAY_STRAY_FAIRY),
RC(RC_GREAT_BAY_TEMPLE_GREEN_PIPE_3_CHEST, RCTYPE_CHEST, SCENE_SEA, FLAG_CYCL_SCENE_CHEST, 0x16, RI_GREAT_BAY_STRAY_FAIRY),
RC(RC_GREAT_BAY_TEMPLE_ICE_ARROW, RCTYPE_CHEST, SCENE_SEA, FLAG_CYCL_SCENE_CHEST, 0x1B, RI_ARROW_ICE),
- RC(RC_GREAT_BAY_TEMPLE_MAP, RCTYPE_CHEST, SCENE_SEA, FLAG_CYCL_SCENE_CHEST, 0x1D, RI_GREAT_BAY_MAP),
+ RC(RC_GREAT_BAY_TEMPLE_MAP, RCTYPE_CHEST, SCENE_SEA, FLAG_CYCL_SCENE_CHEST, 0x1D, RI_GREAT_BAY_TEMPLE_MAP),
RC(RC_GREAT_BAY_TEMPLE_SF_CENTRAL_ROOM_BARREL, RCTYPE_STRAY_FAIRY, SCENE_SEA, FLAG_CYCL_SCENE_COLLECTIBLE, 0x1C, RI_GREAT_BAY_STRAY_FAIRY),
RC(RC_GREAT_BAY_TEMPLE_SF_CENTRAL_ROOM_UNDERWATER_POT, RCTYPE_STRAY_FAIRY, SCENE_SEA, FLAG_CYCL_SCENE_COLLECTIBLE, 0x1B, RI_GREAT_BAY_STRAY_FAIRY),
RC(RC_GREAT_BAY_TEMPLE_SF_COMPASS_ROOM_POT, RCTYPE_STRAY_FAIRY, SCENE_SEA, FLAG_CYCL_SCENE_COLLECTIBLE, 0x1D, RI_GREAT_BAY_STRAY_FAIRY),
@@ -104,6 +108,8 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_IKANA_CANYON_SCRUB_HP, RCTYPE_FREESTANDING, SCENE_IKANA, FLAG_CYCL_SCENE_COLLECTIBLE, 0x1e, RI_HEART_PIECE),
RC(RC_IKANA_CANYON_SCRUB_HUGE_RUPEE, RCTYPE_NPC, SCENE_IKANA, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_62_20, RI_RUPEE_HUGE),
RC(RC_IKANA_CANYON_SCRUB_POTION_REFILL, RCTYPE_NPC, SCENE_IKANA, FLAG_RANDO_INF, RANDO_INF_PURCHASED_POTION_FROM_IKANA_CANYON_SCRUB, RI_BLUE_POTION_REFILL),
+ RC(RC_IKANA_CANYON_TINGLE_MAP_1, RCTYPE_NPC, SCENE_IKANA, FLAG_NONE, 0x00, RI_STONE_TOWER_MAP),
+ RC(RC_IKANA_CANYON_TINGLE_MAP_2, RCTYPE_NPC, SCENE_IKANA, FLAG_NONE, 0x00, RI_CLOCK_TOWN_MAP),
RC(RC_IKANA_GRAVEYARD_CAPTAIN_MASK, RCTYPE_CHEST, SCENE_BOTI, FLAG_CYCL_SCENE_CHEST, 0x00, RI_MASK_CAPTAIN),
RC(RC_IKANA_GRAVEYARD_GROTTO, RCTYPE_CHEST, SCENE_KAKUSIANA, FLAG_CYCL_SCENE_CHEST, 0x18, RI_BOMBCHU_5),
RC(RC_IKANA_GREAT_FAIRY, RCTYPE_NPC, SCENE_YOUSEI_IZUMI, FLAG_NONE, 0x00, RI_GREAT_FAIRY_SWORD),
@@ -114,6 +120,8 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_MAYORS_OFFICE_HP, RCTYPE_NPC, SCENE_SONCHONOIE, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_BOMBERS_NOTEBOOK_EVENT_RECEIVED_MAYOR_HP, RI_HEART_PIECE),
RC(RC_MAYORS_OFFICE_KAFEIS_MASK, RCTYPE_NPC, SCENE_SONCHONOIE, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_BOMBERS_NOTEBOOK_EVENT_RECEIVED_KAFEIS_MASK, RI_MASK_KAFEIS_MASK),
RC(RC_MILK_ROAD_OWL_STATUE, RCTYPE_OWL, SCENE_ROMANYMAE, FLAG_NONE, 0x00, RI_OWL_MILK_ROAD),
+ RC(RC_MILK_ROAD_TINGLE_MAP_1, RCTYPE_NPC, SCENE_ROMANYMAE, FLAG_NONE, 0x00, RI_ROMANI_RANCH_MAP),
+ RC(RC_MILK_ROAD_TINGLE_MAP_2, RCTYPE_NPC, SCENE_ROMANYMAE, FLAG_NONE, 0x00, RI_GREAT_BAY_MAP),
RC(RC_MOON_TRIAL_DEKU_HP, RCTYPE_FREESTANDING, SCENE_LAST_DEKU, FLAG_CYCL_SCENE_COLLECTIBLE, 0x01, RI_HEART_PIECE),
RC(RC_MOON_TRIAL_GORON_HP, RCTYPE_FREESTANDING, SCENE_LAST_GORON, FLAG_CYCL_SCENE_COLLECTIBLE, 0x01, RI_HEART_PIECE),
RC(RC_MOON_TRIAL_LINK_GARO_MASTER_CHEST, RCTYPE_CHEST, SCENE_LAST_LINK, FLAG_CYCL_SCENE_CHEST, 0x01, RI_ARROWS_30),
@@ -180,6 +188,8 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_ROAD_TO_IKANA_STONE_MASK, RCTYPE_NPC, SCENE_KAKUSIANA, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_41_40, RI_MASK_STONE),
RC(RC_ROAD_TO_SOUTHERN_SWAMP_GROTTO, RCTYPE_CHEST, SCENE_KAKUSIANA, FLAG_CYCL_SCENE_CHEST, 0x1e, RI_RUPEE_RED),
RC(RC_ROAD_TO_SOUTHERN_SWAMP_HP, RCTYPE_FREESTANDING, SCENE_24KEMONOMITI, FLAG_CYCL_SCENE_COLLECTIBLE, 0x01, RI_HEART_PIECE),
+ RC(RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_1, RCTYPE_NPC, SCENE_24KEMONOMITI, FLAG_NONE, 0x00, RI_WOODFALL_MAP),
+ RC(RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_2, RCTYPE_NPC, SCENE_24KEMONOMITI, FLAG_NONE, 0x00, RI_SNOWHEAD_MAP),
RC(RC_ROMANI_RANCH_BARN_COW_LEFT, RCTYPE_COW, SCENE_OMOYA, FLAG_NONE, 0x12, RI_MILK_REFILL),
RC(RC_ROMANI_RANCH_BARN_COW_MIDDLE, RCTYPE_COW, SCENE_OMOYA, FLAG_NONE, 0x10, RI_MILK_REFILL),
RC(RC_ROMANI_RANCH_BARN_COW_RIGHT, RCTYPE_COW, SCENE_OMOYA, FLAG_NONE, 0x11, RI_MILK_REFILL),
@@ -208,7 +218,7 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_SNOWHEAD_TEMPLE_ICICLE_ROOM_ALCOVE_CHEST, RCTYPE_CHEST, SCENE_HAKUGIN, FLAG_CYCL_SCENE_CHEST, 0x16, RI_SNOWHEAD_STRAY_FAIRY),
RC(RC_SNOWHEAD_TEMPLE_ICICLE_ROOM, RCTYPE_CHEST, SCENE_HAKUGIN, FLAG_CYCL_SCENE_CHEST, 0x04, RI_SNOWHEAD_SMALL_KEY),
RC(RC_SNOWHEAD_TEMPLE_MAP_ALCOVE_CHEST, RCTYPE_CHEST, SCENE_HAKUGIN, FLAG_CYCL_SCENE_CHEST, 0x13, RI_SNOWHEAD_STRAY_FAIRY),
- RC(RC_SNOWHEAD_TEMPLE_MAP, RCTYPE_CHEST, SCENE_HAKUGIN, FLAG_CYCL_SCENE_CHEST, 0x1D, RI_SNOWHEAD_MAP),
+ RC(RC_SNOWHEAD_TEMPLE_MAP, RCTYPE_CHEST, SCENE_HAKUGIN, FLAG_CYCL_SCENE_CHEST, 0x1D, RI_SNOWHEAD_TEMPLE_MAP),
RC(RC_SNOWHEAD_TEMPLE_PILLARS_ROOM_CHEST, RCTYPE_CHEST, SCENE_HAKUGIN, FLAG_CYCL_SCENE_CHEST, 0x18, RI_SNOWHEAD_STRAY_FAIRY),
RC(RC_SNOWHEAD_TEMPLE_SF_BRIDGE_PILLAR, RCTYPE_STRAY_FAIRY, SCENE_HAKUGIN, FLAG_CYCL_SCENE_SWITCH, 0x30, RI_SNOWHEAD_STRAY_FAIRY),
RC(RC_SNOWHEAD_TEMPLE_SF_BRIDGE_UNDER_PLATFORM, RCTYPE_STRAY_FAIRY, SCENE_HAKUGIN, FLAG_CYCL_SCENE_SWITCH, 0x2F, RI_SNOWHEAD_STRAY_FAIRY),
@@ -251,7 +261,7 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_STONE_TOWER_TEMPLE_INVERTED_GIANT_MASK, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x1a, RI_MASK_GIANT),
RC(RC_STONE_TOWER_TEMPLE_INVERTED_WIZZROBE_CHEST, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x11, RI_STONE_TOWER_STRAY_FAIRY),
RC(RC_STONE_TOWER_TEMPLE_LIGHT_ARROW, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x1b, RI_ARROW_LIGHT),
- RC(RC_STONE_TOWER_TEMPLE_MAP, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x1d, RI_STONE_TOWER_MAP),
+ RC(RC_STONE_TOWER_TEMPLE_MAP, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x1d, RI_STONE_TOWER_TEMPLE_MAP),
RC(RC_STONE_TOWER_TEMPLE_MIRRORS_ROOM_CENTER_CHEST, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x0f, RI_STONE_TOWER_STRAY_FAIRY),
RC(RC_STONE_TOWER_TEMPLE_MIRRORS_ROOM_RIGHT_CHEST, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x0b, RI_STONE_TOWER_STRAY_FAIRY),
RC(RC_STONE_TOWER_TEMPLE_UNDER_WEST_GARDEN_LAVA_CHEST, RCTYPE_CHEST, SCENE_INISIE_N, FLAG_CYCL_SCENE_CHEST, 0x02, RI_STONE_TOWER_SMALL_KEY),
@@ -312,6 +322,8 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_TRADING_POST_SHOP_ITEM_8, RCTYPE_SHOP, SCENE_8ITEMSHOP, FLAG_NONE, 0x00, RI_ARROWS_50),
RC(RC_TWIN_ISLANDS_FROZEN_GROTTO_CHEST, RCTYPE_CHEST, SCENE_KAKUSIANA, FLAG_CYCL_SCENE_CHEST, 0x02, RI_RUPEE_RED),
RC(RC_TWIN_ISLANDS_RAMP_GROTTO_CHEST, RCTYPE_CHEST, SCENE_KAKUSIANA, FLAG_CYCL_SCENE_CHEST, 0x19, RI_BOMBCHU),
+ RC(RC_TWIN_ISLANDS_TINGLE_MAP_1, RCTYPE_NPC, SCENE_17SETUGEN, FLAG_NONE, 0x00, RI_SNOWHEAD_MAP),
+ RC(RC_TWIN_ISLANDS_TINGLE_MAP_2, RCTYPE_NPC, SCENE_17SETUGEN, FLAG_NONE, 0x00, RI_ROMANI_RANCH_MAP),
RC(RC_TWIN_ISLANDS_UNDERWATER_CHEST_1, RCTYPE_CHEST, SCENE_17SETUGEN, FLAG_CYCL_SCENE_CHEST, 0x06, RI_HEART_PIECE),
RC(RC_TWIN_ISLANDS_UNDERWATER_CHEST_2, RCTYPE_CHEST, SCENE_17SETUGEN, FLAG_CYCL_SCENE_CHEST, 0x00, RI_RUPEE_RED),
RC(RC_WOODFALL_ENTRANCE_CHEST, RCTYPE_CHEST, SCENE_21MITURINMAE, FLAG_CYCL_SCENE_CHEST, 0x00, RI_RUPEE_RED),
@@ -327,7 +339,7 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_WOODFALL_TEMPLE_COMPASS, RCTYPE_CHEST, SCENE_MITURIN, FLAG_CYCL_SCENE_CHEST, 0x1c, RI_WOODFALL_COMPASS),
RC(RC_WOODFALL_TEMPLE_DARK_CHEST, RCTYPE_CHEST, SCENE_MITURIN, FLAG_CYCL_SCENE_CHEST, 0x19, RI_WOODFALL_STRAY_FAIRY),
RC(RC_WOODFALL_TEMPLE_ENTRANCE_CHEST, RCTYPE_CHEST, SCENE_MITURIN, FLAG_CYCL_SCENE_CHEST, 0x18, RI_WOODFALL_STRAY_FAIRY),
- RC(RC_WOODFALL_TEMPLE_MAP, RCTYPE_CHEST, SCENE_MITURIN, FLAG_CYCL_SCENE_CHEST, 0x1d, RI_WOODFALL_MAP),
+ RC(RC_WOODFALL_TEMPLE_MAP, RCTYPE_CHEST, SCENE_MITURIN, FLAG_CYCL_SCENE_CHEST, 0x1d, RI_WOODFALL_TEMPLE_MAP),
RC(RC_WOODFALL_TEMPLE_SF_ENTRANCE, RCTYPE_STRAY_FAIRY, SCENE_MITURIN, FLAG_CYCL_SCENE_SWITCH, 0x2B, RI_WOODFALL_STRAY_FAIRY),
RC(RC_WOODFALL_TEMPLE_SF_MAIN_BUBBLE, RCTYPE_STRAY_FAIRY, SCENE_MITURIN, FLAG_CYCL_SCENE_SWITCH, 0x30, RI_WOODFALL_STRAY_FAIRY),
RC(RC_WOODFALL_TEMPLE_SF_MAIN_DEKU_BABA, RCTYPE_STRAY_FAIRY, SCENE_MITURIN, FLAG_CYCL_SCENE_SWITCH, 0x2E, RI_WOODFALL_STRAY_FAIRY),
@@ -345,12 +357,12 @@ std::map<RandoCheckId, RandoStaticCheck> Checks = {
RC(RC_ZORA_CAPE_GROTTO, RCTYPE_CHEST, SCENE_KAKUSIANA, FLAG_CYCL_SCENE_CHEST, 0x15, RI_BOMBCHU),
RC(RC_ZORA_CAPE_LEDGE_CHEST_1, RCTYPE_CHEST, SCENE_31MISAKI, FLAG_CYCL_SCENE_CHEST, 0x01, RI_RUPEE_RED),
RC(RC_ZORA_CAPE_LEDGE_CHEST_2, RCTYPE_CHEST, SCENE_31MISAKI, FLAG_CYCL_SCENE_CHEST, 0x02, RI_RUPEE_RED),
+ RC(RC_ZORA_CAPE_OWL_STATUE, RCTYPE_OWL, SCENE_31MISAKI, FLAG_NONE, 0x00, RI_OWL_ZORA_CAPE),
RC(RC_ZORA_CAPE_UNDERWATER_CHEST, RCTYPE_CHEST, SCENE_31MISAKI, FLAG_CYCL_SCENE_CHEST, 0x00, RI_RUPEE_PURPLE),
RC(RC_ZORA_CAPE_WATERFALL_HP, RCTYPE_FREESTANDING, SCENE_31MISAKI, FLAG_CYCL_SCENE_COLLECTIBLE, 0x07, RI_HEART_PIECE),
RC(RC_ZORA_HALL_SCRUB_DEED, RCTYPE_NPC, SCENE_BANDROOM, FLAG_WEEK_EVENT_REG, WEEKEVENTREG_62_04, RI_DEED_OCEAN),
RC(RC_ZORA_HALL_SCRUB_HP, RCTYPE_FREESTANDING, SCENE_BANDROOM, FLAG_CYCL_SCENE_COLLECTIBLE, 0x1E, RI_HEART_PIECE),
RC(RC_ZORA_HALL_SCRUB_POTION_REFILL, RCTYPE_NPC, SCENE_BANDROOM, FLAG_RANDO_INF, RANDO_INF_PURCHASED_POTION_FROM_ZORA_HALL_SCRUB, RI_GREEN_POTION_REFILL),
- RC(RC_ZORA_CAPE_OWL_STATUE, RCTYPE_OWL, SCENE_31MISAKI, FLAG_NONE, 0x00, RI_OWL_ZORA_CAPE),
RC(RC_ZORA_SHOP_ITEM_1, RCTYPE_SHOP, SCENE_BANDROOM, FLAG_NONE, 0x00, RI_SHIELD_HERO),
RC(RC_ZORA_SHOP_ITEM_2, RCTYPE_SHOP, SCENE_BANDROOM, FLAG_NONE, 0x00, RI_ARROWS_10),
RC(RC_ZORA_SHOP_ITEM_3, RCTYPE_SHOP, SCENE_BANDROOM, FLAG_NONE, 0x00, RI_RED_POTION_REFILL),
diff --git a/mm/2s2h/Rando/StaticData/Items.cpp b/mm/2s2h/Rando/StaticData/Items.cpp
index 5c379cac8..415ba3757 100644
--- a/mm/2s2h/Rando/StaticData/Items.cpp
+++ b/mm/2s2h/Rando/StaticData/Items.cpp
@@ -31,6 +31,7 @@ std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_BOMBS_5, "", "5 Bombs", ITEM_BOMBS_5, GI_BOMBS_5, GID_BOMB),
RI(RI_BOTTLE_EMPTY, "an", "Empty Bottle", ITEM_BOTTLE, GI_BOTTLE, GID_BOTTLE),
RI(RI_BOW, "a", "Bow", ITEM_BOW, GI_QUIVER_30, GID_BOW),
+ RI(RI_CLOCK_TOWN_MAP, "the", "Map of Clock Town", ITEM_TINGLE_MAP, GI_TINGLE_MAP_CLOCK_TOWN, GID_TINGLE_MAP),
RI(RI_CLOCK_TOWN_STRAY_FAIRY, "a", "Clock Town Stray Fairy", ITEM_STRAY_FAIRIES, GI_STRAY_FAIRY, GID_NONE),
RI(RI_DEED_LAND, "the", "Land Title Deed", ITEM_DEED_LAND, GI_DEED_LAND, GID_DEED_LAND),
RI(RI_DEED_MOUNTAIN, "the", "Mountain Title Deed", ITEM_DEED_MOUNTAIN, GI_DEED_MOUNTAIN, GID_DEED_MOUNTAIN),
@@ -45,9 +46,10 @@ std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_FAIRY_REFILL, "a", "Fairy", ITEM_FAIRY, GI_FAIRY, GID_FAIRY_2),
RI(RI_GREAT_BAY_BOSS_KEY, "the", "Great Bay Boss Key", ITEM_KEY_BOSS, GI_KEY_BOSS, GID_KEY_BOSS),
RI(RI_GREAT_BAY_COMPASS, "the", "Great Bay Compass", ITEM_COMPASS, GI_COMPASS, GID_COMPASS),
- RI(RI_GREAT_BAY_MAP, "the", "Great Bay Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
+ RI(RI_GREAT_BAY_MAP, "the", "Map of Great Bay", ITEM_TINGLE_MAP, GI_TINGLE_MAP_GREAT_BAY, GID_TINGLE_MAP),
RI(RI_GREAT_BAY_SMALL_KEY, "a", "Great Bay Small Key", ITEM_KEY_SMALL, GI_KEY_SMALL, GID_KEY_SMALL),
RI(RI_GREAT_BAY_STRAY_FAIRY, "a", "Great Bay Stray Fairy", ITEM_STRAY_FAIRIES, GI_STRAY_FAIRY, GID_NONE),
+ RI(RI_GREAT_BAY_TEMPLE_MAP, "the", "Great Bay Temple Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
RI(RI_GREAT_FAIRY_SWORD, "the", "Great Fairy's Sword", ITEM_SWORD_GREAT_FAIRY, GI_SWORD_GREAT_FAIRY, GID_SWORD_GREAT_FAIRY),
RI(RI_GREAT_SPIN_ATTACK, "the", "Great Spin Attack", ITEM_NONE, GI_NONE, GID_SWORD_KOKIRI),
RI(RI_GREEN_POTION_REFILL, "a", "Green Potion Refill", ITEM_POTION_GREEN, GI_POTION_GREEN, GID_POTION_GREEN),
@@ -107,6 +109,7 @@ std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_REMAINS_GYORG, "", "Gyorg's Remains", ITEM_REMAINS_GYORG, GI_REMAINS_GYORG, GID_REMAINS_GYORG),
RI(RI_REMAINS_ODOLWA, "", "Odolwa's Remains", ITEM_REMAINS_ODOLWA, GI_REMAINS_ODOLWA, GID_REMAINS_ODOLWA),
RI(RI_REMAINS_TWINMOLD, "", "Twinmold's Remains", ITEM_REMAINS_TWINMOLD, GI_REMAINS_TWINMOLD, GID_REMAINS_TWINMOLD),
+ RI(RI_ROMANI_RANCH_MAP, "the", "Map of Romani Ranch", ITEM_TINGLE_MAP, GI_TINGLE_MAP_ROMANI_RANCH, GID_TINGLE_MAP),
RI(RI_ROOM_KEY, "the", "Room Key", ITEM_ROOM_KEY, GI_ROOM_KEY, GID_ROOM_KEY),
RI(RI_RUPEE_BLUE, "a", "Blue Rupee", ITEM_RUPEE_BLUE, GI_RUPEE_BLUE, GID_RUPEE_BLUE),
RI(RI_RUPEE_GREEN, "a", "Green Rupee", ITEM_RUPEE_GREEN, GI_RUPEE_GREEN, GID_RUPEE_GREEN),
@@ -119,9 +122,10 @@ std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_SINGLE_MAGIC, "the", "Power of Magic", ITEM_NONE, GI_NONE, GID_MAGIC_JAR_SMALL),
RI(RI_SNOWHEAD_BOSS_KEY, "the", "Snowhead Boss Key", ITEM_KEY_BOSS, GI_KEY_BOSS, GID_KEY_BOSS),
RI(RI_SNOWHEAD_COMPASS, "the", "Snowhead Compass", ITEM_COMPASS, GI_COMPASS, GID_COMPASS),
- RI(RI_SNOWHEAD_MAP, "the", "Snowhead Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
+ RI(RI_SNOWHEAD_MAP, "the", "Map of Snowhead", ITEM_TINGLE_MAP, GI_TINGLE_MAP_SNOWHEAD, GID_TINGLE_MAP),
RI(RI_SNOWHEAD_SMALL_KEY, "a", "Snowhead Small Key", ITEM_KEY_SMALL, GI_KEY_SMALL, GID_KEY_SMALL),
RI(RI_SNOWHEAD_STRAY_FAIRY, "a", "Snowhead Stray Fairy", ITEM_STRAY_FAIRIES, GI_STRAY_FAIRY, GID_NONE),
+ RI(RI_SNOWHEAD_TEMPLE_MAP, "the", "Snowhead Temple Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
RI(RI_SONG_BOSSA_NOVA, "the", "New Wave Bossa Nova", ITEM_SONG_NOVA, GI_NONE, GID_NONE),
RI(RI_SONG_ELEGY, "the", "Elegy of Emptiness", ITEM_SONG_ELEGY, GI_NONE, GID_NONE),
RI(RI_SONG_EPONA, "", "Epona's Song", ITEM_SONG_EPONA, GI_NONE, GID_NONE),
@@ -134,9 +138,10 @@ std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_SONG_TIME, "the", "Song of Time", ITEM_SONG_TIME, GI_NONE, GID_NONE),
RI(RI_STONE_TOWER_BOSS_KEY, "the", "Stone Tower Boss Key", ITEM_KEY_BOSS, GI_KEY_BOSS, GID_KEY_BOSS),
RI(RI_STONE_TOWER_COMPASS, "the", "Stone Tower Compass", ITEM_COMPASS, GI_COMPASS, GID_COMPASS),
- RI(RI_STONE_TOWER_MAP, "the", "Stone Tower Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
+ RI(RI_STONE_TOWER_MAP, "the", "Map of Stone Tower", ITEM_TINGLE_MAP, GI_TINGLE_MAP_STONE_TOWER, GID_TINGLE_MAP),
RI(RI_STONE_TOWER_SMALL_KEY, "a", "Stone Tower Small Key", ITEM_KEY_SMALL, GI_KEY_SMALL, GID_KEY_SMALL),
RI(RI_STONE_TOWER_STRAY_FAIRY, "a", "Stone Tower Stray Fairy", ITEM_STRAY_FAIRIES, GI_STRAY_FAIRY, GID_NONE),
+ RI(RI_STONE_TOWER_TEMPLE_MAP, "the", "Stone Tower Temple Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
RI(RI_SWORD_GILDED, "the", "Gilded Sword", ITEM_SWORD_GILDED, GI_SWORD_GILDED, GID_SWORD_GILDED),
RI(RI_SWORD_KOKIRI, "the", "Kokiri Sword", ITEM_SWORD_KOKIRI, GI_SWORD_KOKIRI, GID_SWORD_KOKIRI),
RI(RI_SWORD_RAZOR, "the", "Razor Sword", ITEM_SWORD_RAZOR, GI_SWORD_RAZOR, GID_SWORD_RAZOR),
@@ -144,9 +149,10 @@ std::map<RandoItemId, RandoStaticItem> Items = {
RI(RI_WALLET_GIANT, "the", "Giant's Wallet", ITEM_WALLET_GIANT, GI_WALLET_GIANT, GID_WALLET_GIANT),
RI(RI_WOODFALL_BOSS_KEY, "the", "Woodfall Boss Key", ITEM_KEY_BOSS, GI_KEY_BOSS, GID_KEY_BOSS),
RI(RI_WOODFALL_COMPASS, "the", "Woodfall Compass", ITEM_COMPASS, GI_COMPASS, GID_COMPASS),
- RI(RI_WOODFALL_MAP, "the", "Woodfall Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
+ RI(RI_WOODFALL_MAP, "the", "Map of Woodfall", ITEM_TINGLE_MAP, GI_TINGLE_MAP_WOODFALL, GID_TINGLE_MAP),
RI(RI_WOODFALL_SMALL_KEY, "a", "Woodfall Small Key", ITEM_KEY_SMALL, GI_KEY_SMALL, GID_KEY_SMALL),
RI(RI_WOODFALL_STRAY_FAIRY, "a", "Woodfall Stray Fairy", ITEM_STRAY_FAIRIES, GI_STRAY_FAIRY, GID_NONE),
+ RI(RI_WOODFALL_TEMPLE_MAP, "the", "Woodfall Temple Map", ITEM_DUNGEON_MAP, GI_MAP, GID_DUNGEON_MAP),
};
RandoItemId GetItemIdFromName(const char* name) {
diff --git a/mm/2s2h/Rando/Types.h b/mm/2s2h/Rando/Types.h
index 4cd797018..7506f9b2c 100644
--- a/mm/2s2h/Rando/Types.h
+++ b/mm/2s2h/Rando/Types.h
@@ -42,6 +42,8 @@ typedef enum {
RC_CLOCK_TOWN_GREAT_FAIRY,
RC_CLOCK_TOWN_LAUNDRY_GURU_GURU,
RC_CLOCK_TOWN_NORTH_BOMB_LADY,
+ RC_CLOCK_TOWN_NORTH_TINGLE_MAP_1,
+ RC_CLOCK_TOWN_NORTH_TINGLE_MAP_2,
RC_CLOCK_TOWN_NORTH_TREE_HP,
RC_CLOCK_TOWN_SCRUB_DEED,
RC_CLOCK_TOWN_SOUTH_CHEST_LOWER,
@@ -73,6 +75,8 @@ typedef enum {
RC_GREAT_BAY_COAST_HP,
RC_GREAT_BAY_COAST_MIKAU,
RC_GREAT_BAY_COAST_OWL_STATUE,
+ RC_GREAT_BAY_COAST_TINGLE_MAP_1,
+ RC_GREAT_BAY_COAST_TINGLE_MAP_2,
RC_GREAT_BAY_GREAT_FAIRY,
RC_GREAT_BAY_TEMPLE_BABA_CHEST,
RC_GREAT_BAY_TEMPLE_BOSS_HC,
@@ -103,6 +107,8 @@ typedef enum {
RC_IKANA_CANYON_SCRUB_HP,
RC_IKANA_CANYON_SCRUB_HUGE_RUPEE,
RC_IKANA_CANYON_SCRUB_POTION_REFILL,
+ RC_IKANA_CANYON_TINGLE_MAP_1,
+ RC_IKANA_CANYON_TINGLE_MAP_2,
RC_IKANA_GRAVEYARD_CAPTAIN_MASK,
RC_IKANA_GRAVEYARD_GROTTO,
RC_IKANA_GREAT_FAIRY,
@@ -113,6 +119,8 @@ typedef enum {
RC_MAYORS_OFFICE_HP,
RC_MAYORS_OFFICE_KAFEIS_MASK,
RC_MILK_ROAD_OWL_STATUE,
+ RC_MILK_ROAD_TINGLE_MAP_1,
+ RC_MILK_ROAD_TINGLE_MAP_2,
RC_MOON_TRIAL_DEKU_HP,
RC_MOON_TRIAL_GORON_HP,
RC_MOON_TRIAL_LINK_GARO_MASTER_CHEST,
@@ -179,6 +187,8 @@ typedef enum {
RC_ROAD_TO_IKANA_STONE_MASK,
RC_ROAD_TO_SOUTHERN_SWAMP_GROTTO,
RC_ROAD_TO_SOUTHERN_SWAMP_HP,
+ RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_1,
+ RC_ROAD_TO_SOUTHERN_SWAMP_TINGLE_MAP_2,
RC_ROMANI_RANCH_BARN_COW_LEFT,
RC_ROMANI_RANCH_BARN_COW_MIDDLE,
RC_ROMANI_RANCH_BARN_COW_RIGHT,
@@ -310,6 +320,8 @@ typedef enum {
RC_TRADING_POST_SHOP_ITEM_8,
RC_TWIN_ISLANDS_FROZEN_GROTTO_CHEST,
RC_TWIN_ISLANDS_RAMP_GROTTO_CHEST,
+ RC_TWIN_ISLANDS_TINGLE_MAP_1,
+ RC_TWIN_ISLANDS_TINGLE_MAP_2,
RC_TWIN_ISLANDS_UNDERWATER_CHEST_1,
RC_TWIN_ISLANDS_UNDERWATER_CHEST_2,
RC_WOODFALL_ENTRANCE_CHEST,
@@ -892,6 +904,7 @@ typedef enum {
RI_BOMBS_5,
RI_BOTTLE_EMPTY,
RI_BOW,
+ RI_CLOCK_TOWN_MAP,
RI_CLOCK_TOWN_STRAY_FAIRY,
RI_DEED_LAND,
RI_DEED_MOUNTAIN,
@@ -909,6 +922,7 @@ typedef enum {
RI_GREAT_BAY_MAP,
RI_GREAT_BAY_SMALL_KEY,
RI_GREAT_BAY_STRAY_FAIRY,
+ RI_GREAT_BAY_TEMPLE_MAP,
RI_GREAT_FAIRY_SWORD,
RI_GREAT_SPIN_ATTACK,
RI_GREEN_POTION_REFILL,
@@ -968,6 +982,7 @@ typedef enum {
RI_REMAINS_GYORG,
RI_REMAINS_ODOLWA,
RI_REMAINS_TWINMOLD,
+ RI_ROMANI_RANCH_MAP,
RI_ROOM_KEY,
RI_RUPEE_BLUE,
RI_RUPEE_GREEN,
@@ -983,6 +998,7 @@ typedef enum {
RI_SNOWHEAD_MAP,
RI_SNOWHEAD_SMALL_KEY,
RI_SNOWHEAD_STRAY_FAIRY,
+ RI_SNOWHEAD_TEMPLE_MAP,
RI_SONG_BOSSA_NOVA,
RI_SONG_ELEGY,
RI_SONG_EPONA,
@@ -1001,6 +1017,7 @@ typedef enum {
RI_STONE_TOWER_MAP,
RI_STONE_TOWER_SMALL_KEY,
RI_STONE_TOWER_STRAY_FAIRY,
+ RI_STONE_TOWER_TEMPLE_MAP,
RI_SWORD_GILDED,
RI_SWORD_KOKIRI,
RI_SWORD_RAZOR,
@@ -1011,6 +1028,7 @@ typedef enum {
RI_WOODFALL_MAP,
RI_WOODFALL_SMALL_KEY,
RI_WOODFALL_STRAY_FAIRY,
+ RI_WOODFALL_TEMPLE_MAP,
RI_MAX,
} RandoItemId;
@@ -1067,6 +1085,7 @@ typedef enum {
RR_MOUNTAIN_SMITHY,
RR_MOUNTAIN_VILLAGE,
RR_MUSIC_BOX_HOUSE,
+ RR_PATH_TO_GORON_VILLAGE,
RR_PATH_TO_MOUNTAIN_VILLAGE,
RR_PATH_TO_SNOWHEAD_LOWER,
RR_PATH_TO_SNOWHEAD_MIDDLE,
diff --git a/mm/src/overlays/actors/ovl_En_Bal/z_en_bal.c b/mm/src/overlays/actors/ovl_En_Bal/z_en_bal.c
index 7678a3ccd..b1620b45d 100644
--- a/mm/src/overlays/actors/ovl_En_Bal/z_en_bal.c
+++ b/mm/src/overlays/actors/ovl_En_Bal/z_en_bal.c
@@ -6,6 +6,7 @@
#include "z_en_bal.h"
#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
+#include "GameInteractor/GameInteractor.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10)
@@ -834,7 +835,7 @@ void EnBal_TryPurchaseMap(EnBal* this, PlayState* play) {
Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, TINGLE_ANIM_TALK);
Message_StartTextbox(play, 0x1D0A, &this->picto.actor);
this->textId = 0x1D0A;
- } else if (EnBal_CheckIfMapUnlocked(this, play)) {
+ } else if ((GameInteractor_Should(VB_ALREADY_HAVE_TINGLE_MAP, EnBal_CheckIfMapUnlocked(this, play), this, &price))) {
// Can't buy map because player already has it
Audio_PlaySfx(NA_SE_SY_ERROR);
Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, TINGLE_ANIM_TALK);
@@ -846,11 +847,13 @@ void EnBal_TryPurchaseMap(EnBal* this, PlayState* play) {
Rupees_ChangeBy(-price);
Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, TINGLE_ANIM_MAGIC_REVERSE);
this->forceEyesShut = true;
- Message_StartTextbox(play, 0x1D0B, &this->picto.actor);
- this->textId = 0x1D0B;
- EnBal_UnlockSelectedAreaMap(this);
- player->stateFlags1 |= PLAYER_STATE1_20;
- EnBal_SetupOfferGetItem(this);
+ if (GameInteractor_Should(VB_TINGLE_GIVE_MAP_UNLOCK, true, this)) {
+ Message_StartTextbox(play, 0x1D0B, &this->picto.actor);
+ this->textId = 0x1D0B;
+ EnBal_UnlockSelectedAreaMap(this);
+ player->stateFlags1 |= PLAYER_STATE1_20;
+ EnBal_SetupOfferGetItem(this);
+ }
}
} else {
// Cancel