summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlunarsoap5 <40438826+lunarsoap5@users.noreply.github.com>2020-06-20 17:31:13 -0500
committerGitHub <noreply@github.com>2020-06-20 17:31:13 -0500
commit67765f78e77c0d0ec9274d4566b92b084057db7c (patch)
tree9d9144ec491343f68e054ba59320819e10ab36f0
parentc240c41f0f095d71f8a325fca9136759af404ad7 (diff)
update to 0.16b0.16b
-rw-r--r--include/chestRando.h11
-rw-r--r--include/customChecks.h14
-rw-r--r--include/defines.h2
-rw-r--r--include/game_patches.h16
-rw-r--r--include/item.h3
-rw-r--r--include/itemChecks.h2
-rw-r--r--include/mod.h9
-rw-r--r--include/singleton.h3
-rw-r--r--include/stage.h4
-rw-r--r--include/tp.eu.lst1
-rw-r--r--include/tp.jp.lst1
-rw-r--r--include/tp.us.lst1
-rw-r--r--include/tp/d_com_inf_game.h2
-rw-r--r--include/tp/d_stage.h5
-rw-r--r--source/chestRando.cpp178
-rw-r--r--source/game_patches.cpp109
-rw-r--r--source/itemChecks.cpp19
-rw-r--r--source/mod.cpp84
-rw-r--r--source/singleton.cpp3
-rw-r--r--source/stage.cpp52
20 files changed, 407 insertions, 112 deletions
diff --git a/include/chestRando.h b/include/chestRando.h
index 79eaec0..4779813 100644
--- a/include/chestRando.h
+++ b/include/chestRando.h
@@ -74,8 +74,19 @@ namespace mod
/**
* checks if the stage is one of the 5 grotto stages
*/
+
+ bool isStageDungeon();
+
bool isStageGrotto();
+ bool isStageInterior();
+
+ bool isStageCave();
+
+ bool isStageSpecial();
+
+ bool isStageTOD();
+
private:
/**
diff --git a/include/customChecks.h b/include/customChecks.h
index f21cc7a..732bc3b 100644
--- a/include/customChecks.h
+++ b/include/customChecks.h
@@ -30,9 +30,9 @@ namespace mod
{
customCheck customChecks[37] = {
/*Ordon Shield*/
- {"F_SP103", 0, 0, 0x74, 0x2A, 0x456C12A0, 0x43390000, 0x44405C5E, 0x5FA0, []() { gameInfo.localAreaNodes.unk_0[0x8] |= 0x1;/*remove ordon shield*/ }, []() { return (gameInfo.scratchPad.eventBits[0x5] & 0x7A) != 0;/*have sewers been done*/ } },
+ {"F_SP103", 0, 0, 0x74, 0x2A, 0x456C12A0, 0x43390000, 0x44405C5E, 0x5FA0, []() { gameInfo.localAreaNodes.unk_0[0x8] |= 0x4;/*remove ordon shield*/ }, []() { return (gameInfo.scratchPad.eventBits[0x5] & 0x7A) != 0;/*have sewers been done*/ } },
/*Ordon Sword*/
- {"R_SP01", 4, 0, 0x70, 0x28, 0x439D0602, 0x0, 0xC26ABE99, 0xCC7D, []() { gameInfo.localAreaNodes.unk_0[0x8] |= 0x4;/*remove ordon sword*/ }, []() { return (gameInfo.scratchPad.eventBits[0x5] & 0x7A) != 0;/*have sewers been done*/ } },
+ {"R_SP01", 4, 0, 0x70, 0x28, 0x439D0602, 0x0, 0xC26ABE99, 0xCC7D, []() { gameInfo.localAreaNodes.unk_0[0x8] |= 0x1;/*got ordon sword*/ gameInfo.localAreaNodes.unk_0[0x1B] |= 0x8;/*remove ordon sword*/ }, []() { return (gameInfo.scratchPad.eventBits[0x5] & 0x7A) != 0;/*have sewers been done*/ } },
/*Fishing rod*/
{"F_SP103", 0, 1, 0x68, 0x4A, 0xC3FEB5F1, 0x42960000, 0x4514FB40, 0x883A, []() { gameInfo.scratchPad.eventBits[0x3] |= 0x5;/*brought Cradle to Uli and got fishing rod*/ gameInfo.scratchPad.eventBits[0x46] |= 0x1;/*took cradle from monkey*/ }, []() { return (gameInfo.localAreaNodes.unk_0[0xC] & 0x2) != 0;/*is goats 1 done*/ } },
/*Sera Bottle*/
@@ -56,7 +56,7 @@ namespace mod
/*Wooden Statue*/
{"F_SP122", 16, 1, 0x68, 0x82, 0xC7493734, 0xC5C3E9D7, 0x46F956C6, 0x7FE1, []() { gameInfo.scratchPad.eventBits[0x22] |= 0x80;/*Got Wooden Statue from wolves*/ }, []() { return tools::checkItemFlag(ItemFlags::Medicine_Scent); } },
/*Ilia's Charm*/
- {"F_SP128", 0, 1, 0x64, 0x83, 0x44F7650C, 0x42D20705, 0xC4A1A68B, 0x4226, nullptr /*Flag is set in game_patches to avoid interaction with vanilla check*/, []() { return (gameInfo.localAreaNodes.unk_0[0x9] & 0x2) != 0; /*All Bublins dead in HV*/ } },
+ {"F_SP128", 0, 1, 0x64, 0x83, 0x44F7650C, 0x42D20705, 0xC4A1A68B, 0x4226, nullptr /*Flag is set in game_patches to avoid interaction with vanilla check*/, []() { return true; } },
/*Horse Call*/
{"R_SP109", 0, 1, 0x74, 0x84, 0x43CDBCA1, 0x0, 0xC31EEBF3, 0xBDBE, []() { gameInfo.scratchPad.eventBits[0x23] |= 0x20;/*Got horse call from Illia*/ }, []() { return tools::checkItemFlag(ItemFlags::Ilias_Charm); } },
/*Fishing Hole Bottle*/
@@ -66,9 +66,9 @@ namespace mod
/*Gate Keys*/
{"F_SP121", 0xFF, 1, 0x7C, 0xF3, 0xC781DFDB, 0xC607B38E, 0x47897B50, 0xC0C9, nullptr, []() { return (gameInfo.scratchPad.eventBits[0x8] & 0x40) != 0;/*was escort started*/ } },
/*Camp Key*/
- {"F_SP118", 1, 0, 0x7C, 0x20, 0x457F816B, 0x43820000, 0xC572F680, 0x0000, nullptr, []() { return true; } },
+ {"F_SP118", 1, 0, 0x7C, 0x20, 0x457F816B, 0x43820000, 0xC572F680, 0x0000, []() { gameInfo.localAreaNodes.unk_0[0x4] |= 0x80;/*get camp key*/ }, []() { return true; } },
/*Jovani Poe*/
- {"R_SP160", 5, 0, 0x7C, 0xE0, 0x45906531, 0xC2960000, 0x45229AEB, 0xC3C9, []() { gameInfo.localAreaNodes.unk_0[0x8] |= 0x80;/*killed poe*/ gameInfo.localAreaNodes.unk_0[0xF] |= 0x7;/*cs + open path to sewers*/ }, []() { return true; } },
+ {"R_SP160", 5, 0, 0x7C, 0xE0, 0x45906531, 0xC2960000, 0x45229AEB, 0xC3C9, []() { gameInfo.localAreaNodes.unk_0[0x8] |= 0x80;/*killed poe*/ gameInfo.localAreaNodes.unk_0[0xF] |= 0x7;/*cs + open path to sewers*/ gameInfo.localAreaNodes.unk_0[0x17] |= 0x8; /*Gengle Free*/}, []() { return true; } },
/*Shadow Crystal*/
{"F_SP117", 1, 0, 0x7C, 0x32, 0xC36EB7DC, 0x44CB2000, 0xC5964574, 0x0000, []() { gameInfo.scratchPad.eventBits[0x10] |= 0x20;/*got master sword cs*/ }, []() { return true; } },
/*Master Sword*/
@@ -76,7 +76,7 @@ namespace mod
/*Powered Dominion Rod*/
{"R_SP209", 7, 1, 0x70, 0x4C, 0xC3DB30E9, 0xC4408000, 0xC523C471, 0x3CF0, nullptr, []() { return tools::checkItemFlag(ItemFlags::Ancient_Sky_Book_empty); } },
/*Light Master Sword*/
- {"F_SP125", 4, 1, 0x7C, 0x49, 0x44E0DBF7, 0x45898B09, 0xC6A4AAFA, 0x7DBC, nullptr, []() { return ((((gameInfo.scratchPad.eventBits[0x43] & 0x2) != 0) && ((gameInfo.scratchPad.eventBits[0x45] & 0x80) != 0)) || ((gameInfo.scratchPad.eventBits[0x44] & 0x28) != 0));/*both sols placed*/ } },
+ {"F_SP125", 4, 1, 0x74, 0x49, 0x44E0DBF7, 0x45898B09, 0xC6A4AAFA, 0x7DBC, nullptr, []() { return ((gameInfo.scratchPad.eventBits[0x26] & 0x40) != 0) && (gameInfo.scratchPad.eventBits[0x26] & 0x20) != 0;/*both sols outside of Palace*/ } },
/*Ending Blow*/
{"F_SP108", 6, 2, 0xF0, 0xE1, 0xC71A5B41, 0x44898000, 0xC6E08544, 0x0000, nullptr, []() { return gameInfo.scratchPad.clearedTwilights.Faron == 0b1; } },
/*Shield Bash*/
@@ -94,7 +94,7 @@ namespace mod
/*Youth's Scent*/
{"F_SP121", 0xFF, 0, 0x70, 0xB4, 0xC681A76B, 0xC5C99000, 0x4783ED29, 0xA6A9, []() { gameInfo.scratchPad.eventBits[0x22] |= 0x40;/*Got Youth's scent*/ gameInfo.localAreaNodes.unk_0[0x16] |= 0x4;/*Midna text after getting Youth's scent*/ gameInfo.localAreaNodes.unk_0[0x17] |= 0x40;/*got youth's scent cs*/ }, []() { return true; } },
/*Ilia's Scent*/
- {"F_SP121", 0xFF, 0, 0x6C, 0xB0, 0xC5DD1EF2, 0x4529ED9A, 0xC73F5AD1, 0x71A6, nullptr, []() { return true; } },
+ {"F_SP121", 0xFF, 0, 0x6C, 0xB0, 0xC5DD1EF2, 0x4529ED9A, 0xC73F5AD1, 0x71A6, []() { gameInfo.scratchPad.eventBits[0x22] |= 0x20;/*Got Ilia's scent*/ gameInfo.localAreaNodes.unk_0[0x16] |= 0x20;/*Midna text after getting Ilia's scent*/ gameInfo.localAreaNodes.unk_0[0x17] |= 0x80;/*got Ilia's scent cs*/ }, []() { return true; } },
/*Poe Scent*/
{"D_MN10", 0xFF, 0, 0x3C, 0xB2, 0xC1571A39, 0xC1200000, 0x4355109A, 0x0000, nullptr, []() { return true; } },
/*Reekfish Scent*/
diff --git a/include/defines.h b/include/defines.h
index c2c72d9..96898c7 100644
--- a/include/defines.h
+++ b/include/defines.h
@@ -39,7 +39,7 @@ union typeTransform {
// Mnemonics
#define AUTHOR "ZTPR"
-#define VERSION "v0.15.2a"
+#define VERSION "v0.16b"
#define RAND_SEED mod::tools::randomSeed
#define gameInfo tp::d_com_inf_game::dComIfG_gameInfo
#define getPlayerPos tp::d_map_path_dmap::getMapPlayerPos
diff --git a/include/game_patches.h b/include/game_patches.h
index d3f10ae..bc25d17 100644
--- a/include/game_patches.h
+++ b/include/game_patches.h
@@ -150,7 +150,7 @@ namespace mod::game_patch
/**
* give boss key to all dungeons
*/
- void unlockBossDoors();
+ void checkBossKeysey();
/**
* check wether to show hawkeye and hylian shield in malo mart
@@ -175,5 +175,19 @@ namespace mod::game_patch
/**
* skips the zant CS for MDH
*/
+ void skipMDHCS();
+
+ void fixFTBossMusic();
+
+ /**
+ * won't allow you to leave the forest if Faron escape is disabled until you beat Diababa
+ */
+ void allowFaronEscape();
+
+ /**
+ * set MDH skip after Lanayru Twilight
+ */
void skipMDH();
+
+ void setLanternFlag();
} \ No newline at end of file
diff --git a/include/item.h b/include/item.h
index 02de5da..e4dfc06 100644
--- a/include/item.h
+++ b/include/item.h
@@ -57,7 +57,8 @@ namespace mod::item
Bug = 10,
PoeSoul = 11,
Shop = 12,
- Skill = 13
+ Skill = 13,
+ Scent = 14
};
/**
diff --git a/include/itemChecks.h b/include/itemChecks.h
index dff2ea6..a45acfe 100644
--- a/include/itemChecks.h
+++ b/include/itemChecks.h
@@ -5,6 +5,6 @@
namespace mod::item
{
- extern ItemCheck checks[503];
+ extern ItemCheck checks[505];
extern u16 checkPriorityOrder[24];
} \ No newline at end of file
diff --git a/include/mod.h b/include/mod.h
index 245350b..32c755b 100644
--- a/include/mod.h
+++ b/include/mod.h
@@ -130,7 +130,10 @@ namespace mod
u8 LBTBossDoorTrickOn = 0;
u8 nbLBTKeys = 0;
-
+ u8 eventFlagToEdit = 0;
+ u8 newValueForEventFlag = 0;
+ u8 triggerEventFlagEdit = 0;
+
// Functions
private:
/**
@@ -218,7 +221,9 @@ namespace mod
void (*item_func_UTUWA_HEART_trampoline)() = nullptr;
- void(*actorCommonLayerInit_trampoline)(void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4) = nullptr;
+ bool (*actorCommonLayerInit_trampoline)(void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4) = nullptr;
+
+ void (*putSave_trampoline)(tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID) = nullptr;
// Item functions
s32 (*createItemForPresentDemo_trampoline)(const float pos[3], s32 item, u8 unk3, s32 unk4, s32 unk5, const float unk6[3], const float unk7[3]) = nullptr;
diff --git a/include/singleton.h b/include/singleton.h
index 8b41568..eabcd1b 100644
--- a/include/singleton.h
+++ b/include/singleton.h
@@ -28,6 +28,9 @@ namespace mod
u8 shuffledSkybook;
u8 isIntroSkipped;
u8 isTwilightSkipped;
+ u8 diababaMusicFixed;
+ u8 midnaTimeControl;
+ u8 hasActorCommonLayerRan;
private:
diff --git a/include/stage.h b/include/stage.h
index 166b5ff..53739d9 100644
--- a/include/stage.h
+++ b/include/stage.h
@@ -9,4 +9,8 @@ namespace mod::stage
extern const char* bossStages[8];
extern const char* shopStages[8];
extern const char* grottoStages[5];
+ extern const char* caveStages[6];
+ extern const char* interiorStages[8];
+ extern const char* specialStages[3];
+ extern const char* timeOfDayStages[19];
} \ No newline at end of file
diff --git a/include/tp.eu.lst b/include/tp.eu.lst
index 7a10dc1..87ac358 100644
--- a/include/tp.eu.lst
+++ b/include/tp.eu.lst
@@ -15,6 +15,7 @@
/ d_stage.o
80025914:actorCommonLayerInit
+80025AE0:actorInit
// data
803F8034:mStatus_roomControl
diff --git a/include/tp.jp.lst b/include/tp.jp.lst
index 03875f5..e261bb9 100644
--- a/include/tp.jp.lst
+++ b/include/tp.jp.lst
@@ -15,6 +15,7 @@
// d_stage.o
8002586C:actorCommonLayerInit
+80025A38:actorInit
// data
803F01D4:mStatus_roomControl
diff --git a/include/tp.us.lst b/include/tp.us.lst
index 2827ba9..954c3a9 100644
--- a/include/tp.us.lst
+++ b/include/tp.us.lst
@@ -15,6 +15,7 @@
// d_stage.o
8002586C:actorCommonLayerInit
+80025A38:actorInit
// data
803F6094:mStatus_roomControl
diff --git a/include/tp/d_com_inf_game.h b/include/tp/d_com_inf_game.h
index 59e3ec2..b18233b 100644
--- a/include/tp/d_com_inf_game.h
+++ b/include/tp/d_com_inf_game.h
@@ -253,7 +253,7 @@ namespace tp::d_com_inf_game
Null_D8 = 216,//now used for hawkeye check
Null_D9 = 217,//now used for malo hylian shield check
- Null_DA = 218,//now used for Barne's bomb bag check
+ Null_DA = 218,
Null_DB = 219,//now used for sky letter 5
Null_DC = 220,//now used for sky letter 4
Null_DD = 221,//now used for sky letter 3
diff --git a/include/tp/d_stage.h b/include/tp/d_stage.h
index a7a6c39..86b61d3 100644
--- a/include/tp/d_stage.h
+++ b/include/tp/d_stage.h
@@ -14,7 +14,7 @@ namespace tp::d_stage
{
extern "C"
{
- void* mStatus_roomControl;
+ extern void* mStatus_roomControl;
/**
* @brief Initialises Actors, can run multiple times per load
@@ -24,6 +24,7 @@ namespace tp::d_stage
* @param unk3 unknown
* @param unk4 unknown
*/
- void actorCommonLayerInit(void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4);
+ bool actorCommonLayerInit(void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4);
+ bool actorInit(void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4);
}
} // namespace tp::d_stage \ No newline at end of file
diff --git a/source/chestRando.cpp b/source/chestRando.cpp
index b7d48dd..1c5b7cc 100644
--- a/source/chestRando.cpp
+++ b/source/chestRando.cpp
@@ -14,6 +14,7 @@
#include <tp/d_com_inf_game.h>
#include <tp/d_item.h>
#include <tp/d_a_alink.h>
+#include <tp/d_kankyo.h>
#include <tp/JFWSystem.h>
#include <cstdio>
#include <cstring>
@@ -340,6 +341,10 @@ namespace mod
case item::ItemType::Skill:
result = true;
break;
+
+ case item::ItemType::Scent:
+ result = true;
+ break;
}
switch (check->itemID)
@@ -432,7 +437,7 @@ namespace mod
{//set flag for having talked to Bo
gameInfo.scratchPad.eventBits[0x1C] |= 0x20;
}
- else if (item == items::Item::Poe_Soul && gameInfo.scratchPad.poeCount >= 1)
+ else if (item == items::Item::Poe_Soul && gameInfo.scratchPad.poeCount >= 1 && !(tp::d_a_alink::checkStageName(stage::allStages[Stage_Castle_Town_Shops]) && tp::d_kankyo::env_light.currentRoom == 5))
{//decrease poe counter
gameInfo.scratchPad.poeCount--;
}
@@ -444,29 +449,35 @@ namespace mod
if (Singleton::getInstance()->isTwilightSkipped == 1)
{
//Set Faron Twilight Flags
- scratchPadPtr->clearedTwilights.Faron = 0b1; //Clear Faron Twilight
- tools::setItemFlag(ItemFlags::Vessel_Of_Light_Faron);
- scratchPadPtr->tearCounters.Faron = 16;
- eventBitsPtr[0x29] |= 0x4;//give ending blow
- eventBitsPtr[0x5] = 0xFF; //Ensure Epona is Stolen, give Midna Charge
- eventBitsPtr[0x6] |= 0x10; //Faron Twilight Progression flag
+ scratchPadPtr->clearedTwilights.Faron = 0b1; //Clear Faron Twilight
+ tools::setItemFlag(ItemFlags::Vessel_Of_Light_Faron);
+ scratchPadPtr->tearCounters.Faron = 16;
+ eventBitsPtr[0x5] = 0xFF; //Ensure Epona is Stolen, give Midna Charge
+ eventBitsPtr[0x6] |= 0x10; //Faron Twilight Progression flag
+ eventBitsPtr[0xC] |= 0x8; //Set Sword and Shield to not be on back
+ tools::setItemFlag(ItemFlags::Heros_Clothes);
- //Set Eldin Twilight Flags
- scratchPadPtr->clearedTwilights.Eldin = 0b1; // Clear Eldin Twilight
- tools::setItemFlag(ItemFlags::Vessel_Of_Light_Eldin);
- eventBitsPtr[0x6] |= 0x1; //tame Epona
- eventBitsPtr[0xA] |= 0x8; //Beat KB1
- eventBitsPtr[0x14] |= 0x10; //Put Bo Outside
- eventBitsPtr[0x7] = 0xD6; //skip Gor Coron Sumo and Enter Mines also Trigger KB1 and mark Post-KB1 CS as watched, Eldin Twilight Story Progression Flag
+ //Set Eldin Twilight Flags
+ scratchPadPtr->clearedTwilights.Eldin = 0b1; // Clear Eldin Twilight
+ tools::setItemFlag(ItemFlags::Vessel_Of_Light_Eldin);
+ scratchPadPtr->tearCounters.Eldin = 16;
+ eventBitsPtr[0x6] |= 0x1; //tame Epona
+ eventBitsPtr[0xA] |= 0x8; //Beat KB1
+ eventBitsPtr[0x14] |= 0x10; //Put Bo Outside
+ eventBitsPtr[0x7] = 0xDE; //skip Gor Coron Sumo and Enter Mines also Trigger KB1 and mark Post-KB1 CS as watched, Eldin Twilight Story Progression Flag
+ eventBitsPtr[0x41] |= 0x10; //Told Fado about the Kids
- //Set Lanayru Twilight Flags
- scratchPadPtr->clearedTwilights.Lanayru = 0b1; // Clear Lanayru Twilight
- tools::setItemFlag(ItemFlags::Vessel_Of_Light_Lanayru);
- allAreaNodesPtr->Hyrule_Field.unk_0[0xB] |= 0x80;//water on Field map
- allAreaNodesPtr->Hyrule_Field.unk_0[0xF] |= 0x10;//open south CT Shortcut to Faron
- eventBitsPtr[0x30] |= 0x40; //gave springwater to south CT goron
- eventBitsPtr[0x8] |= 0x80; //ZD Thawed
- eventBitsPtr[0xC] |= 0x2; //Lanayru Twilight Story Progression Flag
+ //Set Lanayru Twilight Flags
+ scratchPadPtr->clearedTwilights.Lanayru = 0b1; // Clear Lanayru Twilight
+ tools::setItemFlag(ItemFlags::Vessel_Of_Light_Lanayru);
+ scratchPadPtr->tearCounters.Lanayru = 16;
+ allAreaNodesPtr->Hyrule_Field.unk_0[0xB] |= 0x80;//water on Field map
+ allAreaNodesPtr->Hyrule_Field.unk_0[0xF] |= 0x10;//open south CT Shortcut to Faron
+ allAreaNodesPtr->Lanayru.unk_0[0xF] |= 0x1;//water on Map
+ eventBitsPtr[0x30] |= 0x40; //gave springwater to south CT goron
+ eventBitsPtr[0x8] |= 0x80; //ZD Thawed
+ eventBitsPtr[0xC] |= 0x2; //Lanayru Twilight Story Progression Flag
+ eventBitsPtr[0xA] |= 0x10; //Kagorok Howl at Lake
//Unlock Map Regions
scratchPadPtr->movingActors.exploredRegions.Snowpeak = 0b1;
@@ -488,8 +499,6 @@ namespace mod
allAreaNodesPtr->Lanayru.unk_0[0xB] |= 0x4; // give Zora's Domain Warp
allAreaNodesPtr->Lanayru.unk_0[0xA] |= 0x4;//give lake hylia warp
- tools::setItemFlag(ItemFlags::Heros_Clothes);
-
//Faron Escape
if (Singleton::getInstance()->isForestEscapeEnabled == 1)
{
@@ -500,6 +509,14 @@ namespace mod
eventBitsPtr[0x6] |= 0x24; //warp the kak bridge, give map warp
}
+ //Skip MDH?
+ if (Singleton::getInstance()->isMDHSkipEnabled == 1)
+ {
+ //set MDH flags
+ gameInfo.scratchPad.eventBits[0xC] |= 0x1; //MDH Started
+ gameInfo.scratchPad.eventBits[0x1E] |= 0x8; //MDH Completed
+ }
+
gameInfo.nextStageVars.triggerLoad |= 1;
return item;
}
@@ -514,10 +531,10 @@ namespace mod
{
eventBitsPtr[0x6] |= 0x24; //warp the kak bridge, give map warp
}
+ gameInfo.localAreaNodes.unk_0[0x9] = 0x10;//unlock N Faron gate
tools::setItemFlag(ItemFlags::Vessel_Of_Light_Faron);
return item;
}
- tools::setItemFlag(ItemFlags::Vessel_Of_Light_Faron);
return item;
}
else if (item == items::Item::Vessel_Of_Light_Eldin)
@@ -528,7 +545,7 @@ namespace mod
eventBitsPtr[0x6] |= 0x1; //tame Epona
eventBitsPtr[0xA] |= 0x8; //Beat KB1
eventBitsPtr[0x14] |= 0x10; //Put Bo Outside
- eventBitsPtr[0x7] = 0xD6; //skip Gor Coron Sumo and Enter Mines also Trigger KB1 and mark Post-KB1 CS as watched, Eldin Twilight Story Progression Flag
+ eventBitsPtr[0x7] = 0xD6; //skip Gor Coron Sumo and Enter Mines also Trigger KB1 and mark Post-KB1 CS as watched
return item;
}
else if (item == items::Item::Vessel_Of_Light_Lanayru)
@@ -536,10 +553,6 @@ namespace mod
tools::setItemFlag(ItemFlags::Vessel_Of_Light_Lanayru);
return item;
}
- else if (item == items::Item::Empty_Bomb_Bag)
- {//set flag for Barne's bomb bag check
- tools::setItemFlag(ItemFlags::Null_DA);
- }
else if (item == items::Item::Hylian_Shield && tp::d_a_alink::checkStageName("R_SP109"))
{//set flag for Malo's Hylian Shield check
tools::setItemFlag(ItemFlags::Null_D9);
@@ -758,13 +771,9 @@ namespace mod
else if (tools::checkItemFlag(ItemFlags::Null_DB))
{
gameInfo.scratchPad.eventBits[0x60] |= 0x4; //set shad to be back in the basement
- if (Singleton::getInstance()->isCannonRepaired == 0)
- {
- gameInfo.scratchPad.eventBits[0x25] |= 0x40; //Set the Owl Statue in Kak to be able to be moved
- gameInfo.scratchPad.eventBits[0x5F] |= 0x20; //Shad leaves so you can warp
- gameInfo.scratchPad.eventBits[0x3B] |= 0x8; //repairs Cannon at lake
- Singleton::getInstance()->isCannonRepaired = 1;
- }
+ gameInfo.scratchPad.eventBits[0x25] |= 0x40; //Set the Owl Statue in Kak to be able to be moved
+ gameInfo.scratchPad.eventBits[0x5F] |= 0x20; //Shad leaves so you can warp
+ gameInfo.scratchPad.eventBits[0x3B] |= 0x8; //repairs Cannon at lake
item = items::Item::Ancient_Sky_Book_completed;
}
}
@@ -802,13 +811,9 @@ namespace mod
else if (tools::checkItemFlag(ItemFlags::Null_DB))
{
gameInfo.scratchPad.eventBits[0x60] |= 0x4; //set shad to be back in the basement
- if (Singleton::getInstance()->isCannonRepaired == 0)
- {
- gameInfo.scratchPad.eventBits[0x25] |= 0x40; //Set the Owl Statue in Kak to be able to be moved
- gameInfo.scratchPad.eventBits[0x5F] |= 0x20; //Shad leaves so you can warp
- gameInfo.scratchPad.eventBits[0x3B] |= 0x8; //repairs Cannon at lake
- Singleton::getInstance()->isCannonRepaired = 1;
- }
+ gameInfo.scratchPad.eventBits[0x25] |= 0x40; //Set the Owl Statue in Kak to be able to be moved
+ gameInfo.scratchPad.eventBits[0x5F] |= 0x20; //Shad leaves so you can warp
+ gameInfo.scratchPad.eventBits[0x3B] |= 0x8; //repairs Cannon at lake
item = items::Item::Ancient_Sky_Book_completed;
}
}
@@ -940,7 +945,15 @@ namespace mod
}
else if (item == items::Item::Shadow_Crystal)
{//shadow crystal doesn't actually do anything so we have to do its functionnality ourselves
- game_patch::giveMidnaTransform();
+ game_patch::giveMidnaTransform();
+ if (Singleton::getInstance()->isMDHSkipEnabled == 1)
+ {
+ gameInfo.scratchPad.unk_1F[0x11] |= 0x8; //Midna on Back
+ }
+ }
+ else if (item == items::Item::Dominion_Rod_Uncharged)
+ {
+ gameInfo.scratchPad.eventBits[0x25] |= 0x80;//set flag to charge dominion rod
}
else if (item == items::Item::Ordon_Pumpkin)
{
@@ -948,6 +961,7 @@ namespace mod
gameInfo.scratchPad.eventBits[0x4] |= 0x80; //Told Yeta About Pumpkin
gameInfo.scratchPad.eventBits[0x0] |= 0x22; //Yeto took pumpkin and put it in soup
gameInfo.scratchPad.eventBits[0x14] |= 0x40; //Unlock Lobby Door
+ gameInfo.localAreaNodes.unk_0[0x9] |= 0x4;//unlock courtyard door
}
else if (item == items::Item::Ordon_Goat_Cheese)
{
@@ -955,6 +969,7 @@ namespace mod
gameInfo.scratchPad.eventBits[0x1] |= 0x20; //Told Yeta About Cheese
gameInfo.scratchPad.eventBits[0x0] |= 0x11; //Yeto took Cheese and put it in soup
gameInfo.scratchPad.eventBits[0x14] |= 0x20; //Unlock West Door
+ gameInfo.localAreaNodes.unk_0[0x9] |= 0x8;//unlock west wing door
}
else if (item == 0xE1)
{
@@ -984,6 +999,14 @@ namespace mod
{
gameInfo.scratchPad.eventBits[0x2A] |= 0x20;//give great spin
}
+ else if (item == items::Item::Reekfish_Scent)
+ {
+ gameInfo.scratchPad.eventBits[0x61] |= 0x20;//allow you to go to snowpeak
+ }
+ else if (item == items::Item::Medicine_Scent)
+ {
+ gameInfo.scratchPad.eventBits[0x2F] |= 0x4;//smelled Medicine Scent
+ }
else if (item == items::Item::Bed_Key)
{
gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.bigKeyGotten = 0b1; //unlock Blizzetta Door
@@ -1133,6 +1156,71 @@ namespace mod
return false;
}
+ bool ChestRandomizer::isStageDungeon()
+ {
+ u32 totalDungeonStages = sizeof(stage::dungeonStages) / sizeof(stage::dungeonStages[0]);
+ for (u32 i = 0; i < totalDungeonStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::dungeonStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ChestRandomizer::isStageInterior()
+ {
+ u32 totalInteriorStages = sizeof(stage::interiorStages) / sizeof(stage::interiorStages[0]);
+ for (u32 i = 0; i < totalInteriorStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::interiorStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ChestRandomizer::isStageCave()
+ {
+ u32 totalCaveStages = sizeof(stage::caveStages) / sizeof(stage::caveStages[0]);
+ for (u32 i = 0; i < totalCaveStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::caveStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ChestRandomizer::isStageSpecial()
+ {
+ u32 totalSpecialStages = sizeof(stage::specialStages) / sizeof(stage::specialStages[0]);
+ for (u32 i = 0; i < totalSpecialStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::specialStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ChestRandomizer::isStageTOD()
+ {
+ u32 totalTODStages = sizeof(stage::timeOfDayStages) / sizeof(stage::timeOfDayStages[0]);
+ for (u32 i = 0; i < totalTODStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::timeOfDayStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
void ChestRandomizer::handleKeysanity()
{
if (isKeysanityEnabled == 1)
diff --git a/source/game_patches.cpp b/source/game_patches.cpp
index 0c1d69d..0212ea0 100644
--- a/source/game_patches.cpp
+++ b/source/game_patches.cpp
@@ -133,7 +133,6 @@ namespace mod::game_patch
strcpy(sysConsolePtr->consoleLine[20].line, "-> Skipping Sewers");
// Set sewers flags
- giveMidna();
giveSense();
// We should be wolf
@@ -153,6 +152,7 @@ namespace mod::game_patch
// Load back to Ordon Spring
tools::triggerSaveLoad(stage::allStages[Stage_Ordon_Spring], 0x1, 0x3, 0x4);
}
+ giveMidna();
gameInfo.scratchPad.equipedItems.sword = 0x3F;
}
@@ -162,14 +162,6 @@ namespace mod::game_patch
{
gameInfo.unk_979[0x7] |= 0x6;//2 = lanyru gate 4 = eldin gorge gate
}
-
- //Skip MDH?
- if (Singleton::getInstance()->isMDHSkipEnabled == 1 && gameInfo.scratchPad.clearedTwilights.Lanayru == 0b1)
- {
- //set MDH flags
- gameInfo.scratchPad.eventBits[0xC] |= 0x1; //MDH Started
- gameInfo.scratchPad.eventBits[0x1E] |= 0x8; //MDH Completed
- }
}
void skipGoats()
@@ -206,7 +198,7 @@ namespace mod::game_patch
strcpy(sysConsolePtr->consoleLine[20].line, "state was not 1");
if (gameInfo.nextStageVars.nextRoom != 3)
{
- if (gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.bossBeaten == 0b1)
+ if ((gameInfo.scratchPad.eventBits[0xB] & 0x40) != 0)
{
strcpy(sysConsolePtr->consoleLine[20].line, "-> Setting Bublin State");
// reload bublin camp as state 3
@@ -284,7 +276,7 @@ namespace mod::game_patch
void earlyDesert()
{
- if (Singleton::getInstance()->isEarlyDesertEnabled == 1 && gameInfo.scratchPad.eventBits[0x26] < 0x80 && tools::checkItemFlag(ItemFlags::Shadow_Crystal))
+ if (Singleton::getInstance()->isEarlyDesertEnabled)
{
gameInfo.scratchPad.eventBits[0x26] |= 0x80; //Allow you to use the cannon in the desert
}
@@ -309,18 +301,18 @@ namespace mod::game_patch
{
if (Singleton::getInstance()->isCartEscortSkipEnabled == 1)
{
- gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x17] |= 0x40;//remove rock in graveyard
- gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x16] |= 0x40;//Barnes sells water bombs
gameInfo.scratchPad.eventBits[0x8] |= 0x40;//escort started
gameInfo.scratchPad.eventBits[0x8] |= 0x10;//escort finished
gameInfo.scratchPad.eventBits[0x8] |= 0x4;//got zora armor from Rutela
tools::triggerSaveLoad(stage::allStages[Stage_Kakariko_Interiors], 0x2, 0x3, 0xD);
}
+ gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x17] |= 0x40;//remove rock in graveyard
+ gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x16] |= 0x40;
}
void setEscortState()
{
- if ((gameInfo.scratchPad.eventBits[0x8] & 0x40) == 0 && tools::checkItemFlag(ItemFlags::Heros_Bow) && tools::checkItemFlag(ItemFlags::Boomerang) && gameInfo.scratchPad.clearedTwilights.Lanayru == 0b1)
+ if ((gameInfo.scratchPad.eventBits[0x8] & 0x40) == 0 && (Singleton::getInstance()->isCartEscortSkipEnabled == 1 || (tools::checkItemFlag(ItemFlags::Heros_Bow) && tools::checkItemFlag(ItemFlags::Boomerang))) && gameInfo.scratchPad.clearedTwilights.Lanayru == 0b1)
{
gameInfo.nextStageVars.nextState = 0x8;
gameInfo.nextStageVars.nextSpawnPoint = 0x14;
@@ -427,10 +419,9 @@ namespace mod::game_patch
maloLocalAreaNodesPtr->unk_0[0x13] &= ~0x40;//unset flag for hylian shield on counter
}
}
-
- //hawkeye check
+
//hawkeye check
- if ((gameInfo.scratchPad.eventBits[0xEF] & 0x8) != 0)//Bow mini-game PoH gotten
+ if ((gameInfo.scratchPad.eventBits[0x9] & 0x40) != 0)//Bow mini-game started
{
if (!tools::checkItemFlag(ItemFlags::Null_D8))
{
@@ -461,7 +452,28 @@ namespace mod::game_patch
}
}
- void skipMDH()
+ void allowFaronEscape()
+ {
+ if (Singleton::getInstance()->isForestEscapeEnabled == 0)
+ {
+ if (((gameInfo.scratchPad.eventBits[0x6] & 0x2) != 0) ||
+ (gameInfo.scratchPad.eventBits[0x6] & 0x10) == 0)
+ {
+ return;
+ }
+ else
+ {
+ gameInfo.nextStageVars.nextState = 0x0;
+ }
+ }
+ }
+
+ void setLanternFlag()
+ {
+ gameInfo.scratchPad.eventBits[0xF] |= 0x1;/*got lantern from Coro*/
+ }
+
+ void skipMDHCS()
{
if (Singleton::getInstance()->isMDHSkipEnabled == 1)
{
@@ -472,6 +484,25 @@ namespace mod::game_patch
}
}
+ void skipMDH()
+ {
+ if (Singleton::getInstance()->isMDHSkipEnabled == 1)
+ {
+ //set MDH flags
+ gameInfo.scratchPad.eventBits[0xC] |= 0x1; //MDH Started
+ gameInfo.scratchPad.eventBits[0x1E] |= 0x8; //MDH Completed
+ }
+ }
+
+ void fixFTBossMusic()
+ {
+ if (Singleton::getInstance()->isForestEscapeEnabled == 1 && gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.bossBeaten == 0b0 && Singleton::getInstance()->diababaMusicFixed == 0)
+ {
+ gameInfo.scratchPad.eventBits[0x6] &= ~0x2;
+ Singleton::getInstance()->diababaMusicFixed = 1;
+ }
+ }
+
void skipTextAndCS()
{
//Set Scratchpad Pointer
@@ -503,7 +534,6 @@ namespace mod::game_patch
eventBitsPtr[0x5] |= 0x10; //unchain wolf link
eventBitsPtr[0x6] |= 0xC0; //CS after beating Ordon Shadow, cs after entering Faron twilight
eventBitsPtr[0xB] |= 0x20; //Talked to Yeta First Time
- eventBitsPtr[0xC] |= 0x10; //Midna accompanies link
eventBitsPtr[0x10] |= 0x2; //Talked to Jaggle after climbing vines
eventBitsPtr[0x5E] |= 0x10; //Midna Text After Beating Forest Temple
eventBitsPtr[0x40] |= 0x8; //have been to desert (prevents cannon warp crash)
@@ -513,12 +543,14 @@ namespace mod::game_patch
eventBitsPtr[0x26] |= 0x2; //Talked to Yeto on Snowpeak
eventBitsPtr[0x37] |= 0x4; // Postman Twilight Text
eventBitsPtr[0x38] |= 0x6; //Enter Hena Cabin CS
+ eventBitsPtr[0x3A] |= 0x1; //Talked to Ralis
eventBitsPtr[0x42] |= 0x1; //Watched post ToT Ooccoo CS
eventBitsPtr[0x45] |= 0x8; //Postman Letters Text
eventBitsPtr[0x4A] |= 0x10; //Talo Cage CS
eventBitsPtr[0x3E] |= 0x2; //city OoCCoo CS watched
eventBitsPtr[0x59] |= 0x40; // Postman Met
eventBitsPtr[0x5D] |= 0x40; //Midna text after Kagorok FLight
+
//Set Area Node Flags
tp::d_com_inf_game::AllAreaNodes* allAreaNodesPtr = &scratchPadPtr->allAreaNodes;
@@ -526,7 +558,7 @@ namespace mod::game_patch
allAreaNodesPtr->Ordon.unk_0[0x9] |= 0xAA; //exit shield house CS watched, day 3 intro CS, bee nest CS, Ranch first time CS
allAreaNodesPtr->Ordon.unk_0[0xA] |= 0xF; //Ilia spring CS, Ordon Village CS
allAreaNodesPtr->Ordon.unk_0[0xD] |= 0x82; //Approach Faron Twilight CS, Shield house intro cs
- allAreaNodesPtr->Ordon.unk_0[0xE] |= 0x84; //Midna CS after watching Bo and Jaggle Talk about shield, midna text leaving spring
+ allAreaNodesPtr->Ordon.unk_0[0xE] |= 0x4; //Midna CS after watching Bo and Jaggle Talk about shield
allAreaNodesPtr->Ordon.unk_0[0xF] |= 0xC; //rusl talking to wife CS
allAreaNodesPtr->Ordon.unk_0[0x17] |= 0x80; //enter village as wolf CS
@@ -544,6 +576,7 @@ namespace mod::game_patch
allAreaNodesPtr->Lanayru.unk_0[0xB] |= 0x81;//Zora domain frozen CS, talked to reluta
allAreaNodesPtr->Lanayru.unk_0[0xC] |= 0x1;//midna text after jumping to lake from bridge
+ allAreaNodesPtr->Lanayru.unk_0[0xD] |= 0x10;//ZD exit CS
allAreaNodesPtr->Lanayru.unk_0[0xE] |= 0x20;//midna text after kagorok CS trigger
allAreaNodesPtr->Lanayru.unk_0[0x12] |= 0x40;//midna text after frozen zd
allAreaNodesPtr->Lanayru.unk_0[0x16] |= 0x80;//watched Ooccoo CiTS CS
@@ -553,7 +586,7 @@ namespace mod::game_patch
allAreaNodesPtr->Hyrule_Field.unk_0[0xF] |= 0xB; //cutscene for Gorge Bridge Watched, Ilia Scent CS, midna text after lanayru field cs
allAreaNodesPtr->Hyrule_Field.unk_0[0xE] |= 0x20; //cutscene for entering Field Watched
allAreaNodesPtr->Hyrule_Field.unk_0[0x8] |= 0x81; //Midna text for warping the bridge, lanayru field CS
- allAreaNodesPtr->Hyrule_Field.unk_0[0x9] |= 0x1; //cs before kak
+ allAreaNodesPtr->Hyrule_Field.unk_0[0x9] |= 0x9; //cs before kak, watched CS of Eldin Bridge returning
allAreaNodesPtr->Hyrule_Field.unk_0[0x16] |= 0x13; //midna text after entering eldin twilight, midna text after entering Lanayru twilight, midna text before eldin twilight, midna text after eldin twilight
allAreaNodesPtr->Hyrule_Field.unk_0[0x17] |= 0x10; //youth scent CS
@@ -630,11 +663,12 @@ namespace mod::game_patch
allAreaNodesPtr->Hyrule_Castle.unk_0[0x17] |= 0x80; //lone darknut room me torch watched
//Set Local Area Node flags
- allAreaNodesPtr->Faron.unk_0[0x8] = 0xFF;//give midna jumps in mist area
+ allAreaNodesPtr->Faron.unk_0[0x8] = 0xFB;//give midna jumps in mist area
allAreaNodesPtr->Faron.unk_0[0xC] |= 0x90;//set flag for midna to think you followed the monkey in the mist, trill lets you shop
allAreaNodesPtr->Faron.unk_0[0x12] |= 0x4;//mark read the midna text when you warp to N Faron for bridge
allAreaNodesPtr->Faron.unk_0[0xF] |= 0x8;//set flag for midna text after twilight
allAreaNodesPtr->Faron.unk_0[0xE] |= 0x9;//cs after entering Faron,spring cs with spirit
+ allAreaNodesPtr->Faron.unk_0[0x17] |= 0xC0;//kill bugs in Coro's House
//Apply Randomizer Options
checkBossKeysey();
@@ -660,13 +694,16 @@ namespace mod::game_patch
eventBitsPtr[0x4A] |= 0x60; //Day 1 done, sword training done
eventBitsPtr[0x2] |= 0x40; //Slingshot and Sword Training started
+ allAreaNodesPtr->Ordon.unk_0[0x8] |= 0x20; //Sword Training Started
eventBitsPtr[0x10] |= 0x1; //Cat got Fish
eventBitsPtr[0x16] |= 0x1; //Day 2 done
allAreaNodesPtr->Ordon.unk_0[0xE] |= 0x2;//set flag for Fado text before goats
allAreaNodesPtr->Ordon.unk_0[0x9] |= 0x60;//set flag for day 3 intro cs and goats 2 done
+ eventBitsPtr[0x15] |= 0x80; //Watched CS for goats 2 done
- tools::setItemFlag(ItemFlags::Heros_Clothes);
+ eventBitsPtr[0x1] |= 0x4; //Talked to Colin Day 3
+ eventBitsPtr[0x3] |= 0x2; //Gave Sword to Talo
@@ -687,24 +724,39 @@ namespace mod::game_patch
scratchPadPtr->tearCounters.Faron = 16;
eventBitsPtr[0x5] = 0xFF; //Ensure Epona is Stolen, give Midna Charge
eventBitsPtr[0x6] |= 0x10; //Faron Twilight Progression flag
+ eventBitsPtr[0xC] |= 0x8; //Set Sword and Shield to not be on back
tools::setItemFlag(ItemFlags::Heros_Clothes);
//Set Eldin Twilight Flags
scratchPadPtr->clearedTwilights.Eldin = 0b1; // Clear Eldin Twilight
tools::setItemFlag(ItemFlags::Vessel_Of_Light_Eldin);
+ scratchPadPtr->tearCounters.Eldin = 16;
eventBitsPtr[0x6] |= 0x1; //tame Epona
eventBitsPtr[0xA] |= 0x8; //Beat KB1
eventBitsPtr[0x14] |= 0x10; //Put Bo Outside
- eventBitsPtr[0x7] = 0xD6; //skip Gor Coron Sumo and Enter Mines also Trigger KB1 and mark Post-KB1 CS as watched, Eldin Twilight Story Progression Flag
+ eventBitsPtr[0x7] = 0xDE; //skip Gor Coron Sumo and Enter Mines also Trigger KB1 and mark Post-KB1 CS as watched, Eldin Twilight Story Progression Flag
+ eventBitsPtr[0x41] |= 0x10; //Told Fado about the Kids
//Set Lanayru Twilight Flags
scratchPadPtr->clearedTwilights.Lanayru = 0b1; // Clear Lanayru Twilight
tools::setItemFlag(ItemFlags::Vessel_Of_Light_Lanayru);
+ scratchPadPtr->tearCounters.Lanayru = 16;
allAreaNodesPtr->Hyrule_Field.unk_0[0xB] |= 0x80;//water on Field map
allAreaNodesPtr->Hyrule_Field.unk_0[0xF] |= 0x10;//open south CT Shortcut to Faron
+ allAreaNodesPtr->Lanayru.unk_0[0xF] |= 0x1;//water on Map
eventBitsPtr[0x30] |= 0x40; //gave springwater to south CT goron
eventBitsPtr[0x8] |= 0x80; //ZD Thawed
eventBitsPtr[0xC] |= 0x2; //Lanayru Twilight Story Progression Flag
+ eventBitsPtr[0xA] |= 0x10; //Kagorok Howl at Lake
+
+
+ //Skip MDH?
+ if (Singleton::getInstance()->isMDHSkipEnabled == 1)
+ {
+ //set MDH flags
+ gameInfo.scratchPad.eventBits[0xC] |= 0x1; //MDH Started
+ gameInfo.scratchPad.eventBits[0x1E] |= 0x8; //MDH Completed
+ }
// Set sewers flags
@@ -728,9 +780,9 @@ namespace mod::game_patch
allAreaNodesPtr->Faron.unk_0[0xB] = 0x4;//give N faron warp
allAreaNodesPtr->Eldin.unk_0[0x9] |= 0x20; // give Death Mountain Warp
allAreaNodesPtr->Eldin.unk_0[0x8] |= 0x80; // give Kakariko Warp
- allAreaNodesPtr->Hyrule_Field.unk_0[0x17] = 0x8; //give Bridge of Eldin Warp
allAreaNodesPtr->Hyrule_Field.unk_0[0xB] |= 0x8;//give castle town warp
allAreaNodesPtr->Hyrule_Field.unk_0[0x9] |= 0x20; //give Gorge Warp
+ allAreaNodesPtr->Hyrule_Field.unk_0[0x17] |= 0x8;//give Eldin warp
allAreaNodesPtr->Lanayru.unk_0[0xB] |= 0x4; // give Zora's Domain Warp
allAreaNodesPtr->Lanayru.unk_0[0xA] |= 0x4;//give lake hylia warp
}
@@ -740,6 +792,9 @@ namespace mod::game_patch
u16* secondTempAddress = reinterpret_cast<u16*>(&eventBitsPtr[0xF7]);
*secondTempAddress |= 0x1F4;//make it so you only have to donate 500 Rupees to Charlo
eventBitsPtr[0x20] |= 0x20; //MS Story Progression Flag
+ eventBitsPtr[0x1E] |= 0x80; //Gor Ebizo at Malo Mart
+ eventBitsPtr[0xA] |= 0x20; //Steal Eldin Bridge
+ eventBitsPtr[0xF] |= 0x8; //Put Eldin BRidge Back
//Faron Escape
@@ -756,6 +811,7 @@ namespace mod::game_patch
strncpy(gameInfo.nextStageVars.nextStage, stage::allStages[Stage_Ordon_Interiors], sizeof(gameInfo.nextStageVars.nextStage) - 1);
gameInfo.nextStageVars.nextRoom = 0x4;
gameInfo.nextStageVars.nextSpawnPoint = 0x4;
+ gameInfo.scratchPad.skyAngle = 180;
}
else
{
@@ -763,6 +819,9 @@ namespace mod::game_patch
u16* secondTempAddress = reinterpret_cast<u16*>(&eventBitsPtr[0xF7]);
*secondTempAddress |= 0x1F4;//make it so you only have to donate 500 Rupees to Charlo
eventBitsPtr[0x20] |= 0x20; //MS Story Progression Flag
+ eventBitsPtr[0x1E] |= 0x80; //Gor Ebizo at Malo Mart
+ eventBitsPtr[0xA] |= 0x20; //Steal Eldin Bridge
+ eventBitsPtr[0xF] |= 0x8; //Put Eldin BRidge Back
}
}
} \ No newline at end of file
diff --git a/source/itemChecks.cpp b/source/itemChecks.cpp
index cecf593..29417c5 100644
--- a/source/itemChecks.cpp
+++ b/source/itemChecks.cpp
@@ -6,7 +6,7 @@
namespace mod::item
{
- ItemCheck checks[503] = {
+ ItemCheck checks[505] = {
/* 0 */{0x3F, 1, stage::allStages[65], 4, 0x0, 0x0, 0b000000000000000000000, -1.6259740, 0.0000000, -207.4881290, nullptr, nullptr}, //Wooden Sword Chest
/* 1 */{0x03, 7, stage::allStages[40], 0, 0x1, 0xFF, 0b110000000000000000100, -3550.8691410, 4450.0000000, -694.8996580, nullptr, nullptr}, // South Faron Cave Small Chest
/* 2 */{0xEE, 8, stage::allStages[45], 14, 0x1, 0xFF, 0b000000000000000000100, 1221.9044190, 50.0000000, -7.9423170, nullptr, nullptr}, //North Faron Cave Key Chest
@@ -226,7 +226,7 @@ namespace mod::item
/* 216 */{ 0x06, 7, stage::allStages[59], 0, 0x13, 0xFF, 0b000000000000010000000, 16263.9707030, 989.6500240, 60708.4648440, nullptr, nullptr },
/* 217 */{ 0x18, 5, stage::allStages[12], 0, 0x14, 0xFF, 0b101000000010000000000, -1170.0834960, -755.0000000, 6670.0000000, nullptr, nullptr },
/* 218 */{ 0x04, 7, stage::allStages[12], 0, 0x14, 0xFF, 0b101000000010000000000, 1170.0000000, -755.0000000, 6670.0000000, nullptr, nullptr },
- /* 219 */{ 0x20, 8, stage::allStages[12], 10, 0x14, 0xFF, 0b100000000010100000000, -14514.4443360, 0.0000000, -12000.8310550, nullptr, nullptr },
+ /* 219 */{ 0x20, 8, stage::allStages[12], 10, 0x15, 0xFF, 0b100000000010100000000, -14514.4443360, 0.0000000, -12000.8310550, nullptr, nullptr },
/* 220 */{ 0x23, 2, stage::allStages[12], 5, 0x14, 0x14, 0b101000000010100000000, 17665.1347660, 0.0000000, -11924.1035160, nullptr, nullptr },
/* 221 */{ 0x03, 7, stage::allStages[12], 7, 0x14, 0xFF, 0b101000000010100000000, 15824.6093750, -110.0000000, -9750.6855470, nullptr, nullptr },
/* 222 */{ 0x04, 7, stage::allStages[12], 7, 0x14, 0xFF, 0b101000000010100000000, 17550.0000000, 1500.0000000, -7200.0000000, nullptr, nullptr },
@@ -549,17 +549,17 @@ namespace mod::item
//{0x68, 12, stage::allStages[20], 2, 0xFF, 0xFF, 0b000000000000000000000, -1334.620239, 1250.000000, -3007.779053, nullptr, nullptr},
//Yeto soup
//{0x7f, 12, stage::allStages[27], 2, 0x11, 0xFF, 0b000000000000000000000, 3154.522705, 144.729996, 340.811127, nullptr, nullptr},
-
+
//Custom Chests
//Shadow Crystal
- /*493*/{ 0x32, 0, stage::allStages[54], 1, 0x7, 0x7, 0b000000000000000000000, -235.256332, 1625.000000, -4709.996582, nullptr, nullptr },
+ /*493*/{ 0x32, 0, stage::allStages[54], 1, 0x6, 0x6, 0b000000000000000000000, -235.256332, 1625.000000, -4709.996582, nullptr, nullptr },
//Master Sword
/*494*/{ 0x29, 0, stage::allStages[54], 1, 0x7, 0x7, 0b000000000000000000000, 246.137573, 1625.000000, -4787.551270, nullptr, nullptr },
//Dominion Rod Uncharged
- /*495*/{ 0x4C, 0, stage::allStages[75], 7, 0x13, 0x13, 0b000000000000000000000, -339.546478, -770.000000, -2616.305908, nullptr, nullptr },
+ /*495*/{ 0x4C, 0, stage::allStages[75], 7, 0x12, 0x12, 0b000000000000000000000, -339.546478, -770.000000, -2616.305908, nullptr, nullptr },
//Light Sword
/*496*/ { 0x49, 0, stage::allStages[60], 1, 0x15, 0x15, 0b000000000000000000000, 1801.005249, 4413.458984, -21176.376953, nullptr, nullptr },
-
+
//Ending Blow
/*497*/ { 0xE1, 13, stage::allStages[45], 6, 0xFF, 0xFF, 0b000000000000000000000, -39511.792969, 1100.000000, -28626.875000, nullptr, nullptr },
//Shield Bash
@@ -573,7 +573,12 @@ namespace mod::item
//Jump Strike
/*502*/ { 0xE6, 13, stage::allStages[48], 0, 0xFF, 0xFF, 0b000000000000000000000, 16308.677734, 525.000000, -31.427549, nullptr, nullptr },
//Great Spin
- /*503*/ { 0xE7, 13, stage::allStages[53], 1, 0xFF, 0xFF, 0b000000000000000000000, 43.525406, 800.000000, -10109.346680, nullptr, nullptr }
+ /*503*/ { 0xE7, 13, stage::allStages[53], 1, 0xFF, 0xFF, 0b000000000000000000000, 43.525406, 800.000000, -10109.346680, nullptr, nullptr },
+
+ //Reekfish Scent
+ /*504*/ { 0xB3, 14, stage::allStages[50], 1, 0xFF, 0xFF, 0b000000000000000000000, 3673.396973, -5986.576172, 13185.018555, nullptr, nullptr },
+ //Medicine Scent
+ /*505*/ { 0xB5, 14, stage::allStages[73], 2, 0xFF, 0xFF, 0b000000000000000000000, 7454.945801, -190.000000, -1734.022095, nullptr, nullptr }
};
u16 checkPriorityOrder[24] = {
diff --git a/source/mod.cpp b/source/mod.cpp
index 15ad514..0458cdf 100644
--- a/source/mod.cpp
+++ b/source/mod.cpp
@@ -204,6 +204,7 @@ namespace mod
hudConsole->addOption(page, "No Shop Bottl?", &allowBottleItemsShopAnytime, 0x1);
hudConsole->addOption(page, "Fast transform?", &enableQuickTransform, 0x1);
hudConsole->addOption(page, "Skip Intro?", &Singleton::getInstance()->isIntroSkipped, 0x1);
+ //hudConsole->addOption(page, "Midna ToD Skip?", &Singleton::getInstance()->midnaTimeControl, 0x1);
//color
/*page = hudConsole->addPage("Tunic Color1");
@@ -252,7 +253,7 @@ namespace mod
//event info
page = hudConsole->addPage("Event Info");
- hudConsole->addOption(page, "Coords as hex?", &coordsAreInHex, 0x1);
+ //hudConsole->addOption(page, "Coords as hex?", &coordsAreInHex, 0x1);
hudConsole->addWatch(page, "CurrentEventID:", &gameInfo.eventSystem.currentEventID, 'x', WatchInterpretation::_u8);
hudConsole->addWatch(page, "NextEventID:", &gameInfo.eventSystem.nextEventID, 'x', WatchInterpretation::_u8);
@@ -449,7 +450,7 @@ namespace mod
eventListener->addLoadEvent(stage::allStages[Stage_Lake_Hylia], 0x0, 0x5, 0xE, 0xFF, game_patch::setLanayruWolf, event::LoadEventAccuracy::Stage_Room_Spawn);
//desert Access
- eventListener->addLoadEvent(stage::allStages[Stage_Gerudo_Desert], 0xFF, 0xFF, 0xFF, 0xFF, game_patch::accessDesert, event::LoadEventAccuracy::Stage_Room_Spawn);
+ eventListener->addLoadEvent(stage::allStages[Stage_Gerudo_Desert], 0x0, 0x0, 0xFF, 0xFF, game_patch::accessDesert, event::LoadEventAccuracy::Stage_Room_Spawn);
//Skip Midna Text and CS's
eventListener->addLoadEvent(stage::allStages[Stage_Faron_Woods], 0x1, 0x15, 0xFF, 0xFF, game_patch::skipTextAndCS, event::LoadEventAccuracy::Stage_Room_Spawn_State);
@@ -458,7 +459,20 @@ namespace mod
eventListener->addLoadEvent(stage::allStages[Stage_Castle_Town_Interiors], 0x5, 0xFF, 0xFF, 0xFF, game_patch::setEscortState, event::LoadEventAccuracy::Stage_Room_Spawn);
//Skip MDH Trigger
- eventListener->addLoadEvent(stage::allStages[Stage_Lake_Hylia], 0x1, 0x16, 0xFF, 0xFF, game_patch::skipMDH, event::LoadEventAccuracy::Stage_Room_Spawn);
+ eventListener->addLoadEvent(stage::allStages[Stage_Lake_Hylia], 0x1, 0x16, 0xFF, 0xFF, game_patch::skipMDHCS, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ //Fix FT Boss Music
+ eventListener->addLoadEvent(stage::allStages[Stage_Diababa], 0x32, 0x1, 0xFF, 0xFF, game_patch::fixFTBossMusic, event::LoadEventAccuracy::Stage);
+
+ // Allow Faron Escape
+ eventListener->addLoadEvent(stage::allStages[Stage_Faron_Woods], 0xFF, 0xFF, 0xFF, 0xFF, game_patch::allowFaronEscape, event::LoadEventAccuracy::Stage);
+
+ //Skip MDH After Lanayru
+ eventListener->addLoadEvent(stage::allStages[Stage_Lake_Hylia], 0x1, 0x14, 0xFF, 0xFF, game_patch::skipMDH, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ //Set Lantern gotten from Coro Flag
+ eventListener->addLoadEvent(stage::allStages[Stage_Faron_Woods], 0xFF, 0x0, 0xFF, 0xFF, game_patch::setLanternFlag, event::LoadEventAccuracy::Stage_Room_Spawn);
+
// =================
@@ -477,20 +491,37 @@ namespace mod
actorCommonLayerInit_trampoline = patch::hookFunction(tp::d_stage::actorCommonLayerInit,
[](void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4)
{
- // if unk4 is nullptr and unk3 is 0 it's probably ourselves calling this function
- // Thus don't call it again to avoid an infinite loop!
- if (unk3 != 0 && unk4)
+ if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Faron_Woods]))
+ {
+ if (Singleton::getInstance()->hasActorCommonLayerRan <= 4)
+ {
+ global::modPtr->doCustomTRESActor(mStatus_roomControl);
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Hyrule_Field]) && gameInfo.nextStageVars.nextSpawnPoint == 0xFC)
+ {
+ if (Singleton::getInstance()->hasActorCommonLayerRan <= 2)
+ {
+ global::modPtr->doCustomTRESActor(mStatus_roomControl);
+ }
+ }
+ else
{
- // doCustomTRESActor will call this function with unk3=0 and unk4=nullptr
- // So we only need to pass the status_roomControl (which should be static through LST anyway)
- // to maintain consistency
global::modPtr->doCustomTRESActor(mStatus_roomControl);
}
-
return global::modPtr->actorCommonLayerInit_trampoline(mStatus_roomControl, chunkTypeInfo, unk3, unk4);
}
);
+
+ putSave_trampoline = patch::hookFunction(tp::d_save::putSave,
+ [](tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID)
+ {
+ Singleton::getInstance()->hasActorCommonLayerRan = 0;
+ return global::modPtr->putSave_trampoline(gameInfoPtr, areaID);
+ }
+ );
+
checkTreasureRupeeReturn_trampoline = patch::hookFunction(tp::d_a_alink::checkTreasureRupeeReturn,
[](void* unk1, s32 item)
{
@@ -805,8 +836,8 @@ namespace mod
}
else if (tp::d_a_alink::linkStatus)
{
- if (enableQuickTransform == 1 && gameInfo.rButtonText == 0 && ((((gameInfo.aButtonText == 0x79 || gameInfo.aButtonText == 0x0 || gameInfo.aButtonText == 0x4) && gameInfo.eventSystem.eventFlag == 0) && tp::d_a_alink::linkStatus->status == 0x1) || gameInfo.aButtonText == 0x9) &&
- (gameInfo.scratchPad.eventBits[0xD] & 0x4) != 0 && controller::checkForButtonInputSingleFrame(controller::PadInputs::Button_R))
+ if (enableQuickTransform == 1 && gameInfo.rButtonText == 0 && ((((gameInfo.aButtonText == 0x24) && gameInfo.eventSystem.eventFlag == 0) && tp::d_a_alink::linkStatus->status == 0x1)) &&
+ (gameInfo.scratchPad.eventBits[0xD] & 0x4) != 0 && controller::checkForButtonInputSingleFrame(controller::PadInputs::Button_Z))
{
// Make sure Link is actually loaded
tp::d_com_inf_game::LinkMapVars* linkMapPtr = gameInfo.linkMapPtr;
@@ -819,6 +850,22 @@ namespace mod
}
}
}
+ /*else if (tp::d_a_alink::linkStatus->status == 0x5 && gameInfo.aButtonText == 0x23 && controller::checkForButtonInputSingleFrame(controller::PadInputs::Button_Z) && Singleton::getInstance()->midnaTimeControl == 1 &&
+ chestRandomizer->isStageTOD())
+ {
+ if (gameInfo.scratchPad.skyAngle >= 180 && gameInfo.scratchPad.skyAngle <= 359)
+ {
+ gameInfo.scratchPad.skyAngle = 0;
+ gameInfo.nextStageVars.nextSpawnPoint = 0x0;
+ gameInfo.nextStageVars.triggerLoad |= 1;
+ }
+ else if (gameInfo.scratchPad.skyAngle >= 0 && gameInfo.scratchPad.skyAngle <= 179)
+ {
+ gameInfo.scratchPad.skyAngle = 180;
+ gameInfo.nextStageVars.nextSpawnPoint = 0x0;
+ gameInfo.nextStageVars.triggerLoad |= 1;
+ }
+ }*/
}
if (sysConsolePtr->consoleEnabled)
@@ -1433,7 +1480,7 @@ namespace mod
shieldTrickOn = 1;
}
- if (!tools::checkItemFlag(ItemFlags::Null_DA) && bombBagTrickOn == 0 && tp::d_a_alink::checkStageName("R_SP109") && tp::d_kankyo::env_light.currentRoom == 1 &&
+ if ((gameInfo.scratchPad.eventBits[0x9] & 0x8) == 0/*didn't buy bomb bag yet*/ && bombBagTrickOn == 0 && tp::d_a_alink::checkStageName("R_SP109") && tp::d_kankyo::env_light.currentRoom == 1 &&
linkPos[2] > -600)
{
bombBag1Contents = gameInfo.scratchPad.itemWheel.Bomb_Bag_1;
@@ -1483,7 +1530,7 @@ namespace mod
bombBagTrickOn = 0;
}
}
- if (tools::checkItemFlag(ItemFlags::Null_DA) && bombBagTrickOn == 1)
+ if ((gameInfo.scratchPad.eventBits[0x9] & 0x8) != 0/*bought bomb bag*/ && bombBagTrickOn == 1)
{//bought bomb bag check
gameInfo.scratchPad.itemWheel.Bomb_Bag_1 = bombBag1Contents;
gameInfo.scratchPad.itemWheel.Bomb_Bag_2 = bombBag2Contents;
@@ -1786,7 +1833,7 @@ namespace mod
check.overrides();
}
- strcpy(TRES[i].actorName, "tboxA0\0");
+ strcpy(TRES[i].actorName, "tboxA0");
TRES[i].flags = 0xFF0FF000 | (check.chestType << 20) | (check.saveFlag << 4);
// Translate hex to float (1:1)
@@ -1804,11 +1851,10 @@ namespace mod
TRES[i].item = check.itemID;
}
- // Create the actors; last 2 params 0 and nullptr to avoid infinite loop! (identification for self-call inside the
- // hook)
- tp::d_stage::actorCommonLayerInit(mStatus_roomControl, &chunkInfo, 0, nullptr);
-
+ /// Create the actors
+ global::modPtr->actorCommonLayerInit_trampoline(mStatus_roomControl, &chunkInfo, 0, nullptr);
delete[] TRES;
+ Singleton::getInstance()->hasActorCommonLayerRan++;
}
delete[] checks;
diff --git a/source/singleton.cpp b/source/singleton.cpp
index 9a26fe8..56bd916 100644
--- a/source/singleton.cpp
+++ b/source/singleton.cpp
@@ -32,6 +32,9 @@ namespace mod
shuffledSkybook = 1;
isIntroSkipped = 1;
isTwilightSkipped = 1;
+ diababaMusicFixed = 0;
+ midnaTimeControl = 1;
+ hasActorCommonLayerRan = 0;
}
} \ No newline at end of file
diff --git a/source/stage.cpp b/source/stage.cpp
index e2a21c3..a61af8e 100644
--- a/source/stage.cpp
+++ b/source/stage.cpp
@@ -138,4 +138,56 @@ namespace mod::stage
allStages[Stage_Grotto_4],
allStages[Stage_Grotto_5]
};
+
+ const char* caveStages[6]
+ {
+ allStages[Stage_Lanayru_Ice_Puzzle_Cave],
+ allStages[Stage_Cave_of_Ordeals],
+ allStages[Stage_Eldin_Long_Cave],
+ allStages[Stage_Lake_Hylia_Long_Cave],
+ allStages[Stage_Eldin_Goron_Stockcave],
+ allStages[Stage_Faron_Woods_Cave]
+ };
+
+ const char* interiorStages[8]
+ {
+ allStages[Stage_Ordon_Interiors],
+ allStages[Stage_Kakariko_Interiors],
+ allStages[Stage_Castle_Town_Shops],
+ allStages[Stage_Sanctuary_Basement],
+ allStages[Stage_Impaz_House],
+ allStages[Stage_Henas_Cabin],
+ allStages[Stage_Castle_Town_Interiors],
+ allStages[Stage_Castle_Town]
+ };
+
+ const char* specialStages[3]
+ {
+ allStages[Stage_Title_Screen],
+ allStages[Stage_Bublin_2],
+ allStages[Stage_Hidden_Skill]
+ };
+
+ const char* timeOfDayStages[19]
+ {
+ allStages[Stage_Ordon_Village],
+ allStages[Stage_Ordon_Spring],
+ allStages[Stage_Ordon_Ranch],
+ allStages[Stage_Faron_Woods],
+ allStages[Stage_Death_Mountain],
+ allStages[Stage_Kakariko_Graveyard],
+ allStages[Stage_Zoras_River],
+ allStages[Stage_Zoras_Domain],
+ allStages[Stage_Upper_Zoras_River],
+ allStages[Stage_Snowpeak],
+ allStages[Stage_Ordon_Ranch],
+ allStages[Stage_Lake_Hylia],
+ allStages[Stage_Outside_Castle_Town],
+ allStages[Stage_Hyrule_Field],
+ allStages[Stage_Sacred_Grove],
+ allStages[Stage_Bublin_Camp],
+ allStages[Stage_Gerudo_Desert],
+ allStages[Stage_Hidden_Village],
+ allStages[Stage_Fishing_Pond]
+ };
} \ No newline at end of file