summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlunarsoap5 <40438826+lunarsoap5@users.noreply.github.com>2020-06-09 01:13:20 -0500
committerGitHub <noreply@github.com>2020-06-09 01:13:20 -0500
commit36705be9553d7df974d88230e1537f284d0f463d (patch)
treee2acf30bd207439104a8fb41ce64fe7e316befab
parentd3d7b5b07eb19c8900430c311baea43894c85646 (diff)
update code to 0.16
-rw-r--r--source/include/HUDConsole.h105
-rw-r--r--source/include/array.h19
-rw-r--r--source/include/chestRando.h134
-rw-r--r--source/include/controller.h36
-rw-r--r--source/include/customChecks.h106
-rw-r--r--source/include/defines.h126
-rw-r--r--source/include/eventListener.h60
-rw-r--r--source/include/game_patches.h179
-rw-r--r--source/include/gc/OSCache.h29
-rw-r--r--source/include/gc/OSModule.h19
-rw-r--r--source/include/global.h15
-rw-r--r--source/include/grottoChecks.h32
-rw-r--r--source/include/item.h84
-rw-r--r--source/include/itemChecks.h10
-rw-r--r--source/include/items.h266
-rw-r--r--source/include/keyPlacement.h67
-rw-r--r--source/include/memory.h12
-rw-r--r--source/include/mod.h234
-rw-r--r--source/include/patch.h31
-rw-r--r--source/include/singleton.h39
-rw-r--r--source/include/stage.h12
-rw-r--r--source/include/systemConsole.h12
-rw-r--r--source/include/tools.h77
-rw-r--r--source/include/tp.eu.lst170
-rw-r--r--source/include/tp.jp.lst170
-rw-r--r--source/include/tp.us.lst179
-rw-r--r--source/include/tp/DynamicLink.h24
-rw-r--r--source/include/tp/JFWSystem.h31
-rw-r--r--source/include/tp/JKRExpHeap.h12
-rw-r--r--source/include/tp/d_a_alink.h49
-rw-r--r--source/include/tp/d_com_inf_game.h954
-rw-r--r--source/include/tp/d_item.h13
-rw-r--r--source/include/tp/d_kankyo.h21
-rw-r--r--source/include/tp/d_map_path_dmap.h12
-rw-r--r--source/include/tp/d_menu_collect.h11
-rw-r--r--source/include/tp/d_msg_flow.h11
-rw-r--r--source/include/tp/d_save.h14
-rw-r--r--source/include/tp/d_stage.h29
-rw-r--r--source/include/tp/dzx.h47
-rw-r--r--source/include/tp/evt_control.h13
-rw-r--r--source/include/tp/f_ap_game.h11
-rw-r--r--source/include/tp/f_op_actor_mng.h17
-rw-r--r--source/include/tp/f_op_scene_req.h12
-rw-r--r--source/include/tp/m_Do_controller_pad.h22
-rw-r--r--source/include/tp/m_Do_ext.h11
-rw-r--r--source/source/HUDConsole.cpp259
-rw-r--r--source/source/array.cpp19
-rw-r--r--source/source/chestRando.cpp1844
-rw-r--r--source/source/controller.cpp25
-rw-r--r--source/source/cxx.cpp29
-rw-r--r--source/source/cxx.ld5
-rw-r--r--source/source/eventListener.cpp80
-rw-r--r--source/source/game_patches.cpp770
-rw-r--r--source/source/grottoChecks.cpp104
-rw-r--r--source/source/item.cpp118
-rw-r--r--source/source/itemChecks.cpp605
-rw-r--r--source/source/keyPlacement.cpp569
-rw-r--r--source/source/memory.cpp20
-rw-r--r--source/source/mod.cpp1814
-rw-r--r--source/source/patch.cpp30
-rw-r--r--source/source/rel.cpp42
-rw-r--r--source/source/runtime/restfpr_x.s42
-rw-r--r--source/source/runtime/restgpr_x.s42
-rw-r--r--source/source/singleton.cpp37
-rw-r--r--source/source/stage.cpp141
-rw-r--r--source/source/systemConsole.cpp24
-rw-r--r--source/source/tools.cpp112
67 files changed, 10268 insertions, 0 deletions
diff --git a/source/include/HUDConsole.h b/source/include/HUDConsole.h
new file mode 100644
index 0000000..ff5e361
--- /dev/null
+++ b/source/include/HUDConsole.h
@@ -0,0 +1,105 @@
+#pragma once
+
+#include <tp/JFWSystem.h>
+
+#include "defines.h"
+
+namespace mod
+{
+ struct Option
+ {
+ char Title[16];
+ u8* Target;
+ u32 Limit;
+ };
+
+ struct Watch
+ {
+ char Title[16];
+ void* Target;
+ char Format;
+ u8 Interpretation;
+ };
+
+ enum WatchInterpretation : u8
+ {
+ _u8 = 0,
+ _u16 = 1,
+ _u32 = 2,
+ _u64 = 3,
+ _s8 = 4,
+ _s16 = 5,
+ _s32 = 6,
+ _s64 = 7,
+ _str = 8
+ };
+
+ enum ConsoleActions : u8
+ {
+ Move_Up = 0,
+ Move_Down = 1,
+ Move_Left = 2,
+ Move_Right = 3,
+ Option_Increase = 4,
+ Option_Decrease = 5
+ };
+
+ class HUDConsole
+ {
+ public:
+ HUDConsole(const char firstPage[16], u32 RGBA = 0x000000FF);
+
+ /**
+ * Adds an option to the Console
+ *
+ * @param page Page index where the option should appear
+ * @param title Short description (limit 16)
+ * @param target The target value that can be set via the menu
+ * @param limit When target >= limit it will reset to 0
+ */
+ void addOption(u8 page, const char title[16], u8* target, u32 limit);
+
+ /**
+ * Adds a watch to the console
+ *
+ * @param page Page index where the watch should appear
+ * @param title Short description (limit 16)
+ * @param target Target value to be represented
+ * @param format Formatting char (s, d, u, x, ...)
+ * @param interpretation How to read from the target* (mod::WatchInterpretation)
+ */
+ void addWatch(u8 page, const char title[16], void* target, char format, u8 interpretation);
+
+ /**
+ * Adds a page to the Console (pages can be switched with R/L)
+ *
+ * @param title The name to appear when this page is opened
+ * @returns The index of the new page if successful otherwise -1
+ */
+ s8 addPage(const char title[16]);
+
+ /**
+ * Performs an action
+ *
+ * @param consoleAction A valid mod::ConsoleAction that's going to be performed
+ */
+ void performAction(u8 consoleAction, u8 amount = 1);
+
+ /**
+ * Draws the current page and it's options
+ */
+ void draw();
+
+ private:
+ u8 selectedOption; // Y Position
+ u8 selectedPage; // X Position
+
+ u8 numOptions[MAX_HUDCONSOLE_PAGES];
+ u8 numWatches[MAX_HUDCONSOLE_PAGES];
+ u8 numPages;
+
+ char pages[MAX_HUDCONSOLE_PAGES][16];
+ Option options[MAX_HUDCONSOLE_PAGES][10];
+ Watch watches[MAX_HUDCONSOLE_PAGES][10];
+ };
+} \ No newline at end of file
diff --git a/source/include/array.h b/source/include/array.h
new file mode 100644
index 0000000..37cb27c
--- /dev/null
+++ b/source/include/array.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::array
+{
+ extern "C"
+ {
+ /**
+ * Checks whether an array contains a value and returns it's index
+ *
+ * @param needle The value to be searched for
+ * @param haystack Pointer to the array
+ * @param count Number of elements within the array
+ * @returns If successful the index of needle inside the array, otherwise -1
+ */
+ s32 indexOf(u16 needle, u16* haystack, size_t count);
+ }
+} \ No newline at end of file
diff --git a/source/include/chestRando.h b/source/include/chestRando.h
new file mode 100644
index 0000000..79eaec0
--- /dev/null
+++ b/source/include/chestRando.h
@@ -0,0 +1,134 @@
+#pragma once
+
+#include "defines.h"
+#include "item.h"
+#include <tp/d_com_inf_game.h>
+
+namespace mod
+{
+ class ChestRandomizer
+ {
+ private:
+ u8* itemOrder = nullptr; // Used for checksum
+ u8 itemOrderIndex;
+
+ public:
+ // Conditions used by the generator to determine wether a check is already reachable
+ u32 currentPlayerConditions;
+
+ // Layer 0 conditions, basically
+ u32 startConditions = 0b100000000000000100010; // AND, small key, master sword (<-locked anyway)
+
+ // Debug values
+ char lastSourceInfo[50];
+ char lastDestInfo[50];
+
+ u64 currentSeed;
+ u16 checkSum;
+
+ u16 totalChecks;
+ u16 layerCheckCount;
+ u16 empty;
+ float rangeX = 400.0f;
+ float rangeY = 200.0f;
+ float rangeZ = 400.0f;
+
+ u8 isProgressiveEnabled = 1;
+ u8 isBugsanityEnabled = 1;
+ u8 isPoesanityEnabled = 1;
+ u8 isShopsanityEnabled = 1;
+ u8 areDungeonItemsRandomized = 1;
+ u8 isTwilightSkipEnabled = 1;
+ u8 isKeysanityEnabled = 1;
+
+ u8 itemThatReplacesHalfMilk = 0;
+ u8 itemThatReplacesSlingShot = 0;
+
+ tp::d_com_inf_game::ItemSlots* itemWheel;
+
+ public:
+ /**
+ * Generates a new set of chest replacements based
+ * on current RAND_SEED
+ */
+ void generate();
+
+ /**
+ * Returns the item replacement if found, otherwise
+ * the item that's passed via argument
+ *
+ * @param pos The cXyz of the chest
+ * @param item Internal Item ID of the item
+ */
+ s32 getItemReplacement(const float pos[3], s32 item);
+
+
+ /**
+ * Checks if the stage given is a boss room
+ * to know if we can spawn a HC
+ *
+ * excludes hyrule castle since boss doesn't spawn heart container
+ */
+ bool isStageBoss();
+
+ /**
+ * checks if the stage is one of the 5 grotto stages
+ */
+ bool isStageGrotto();
+
+
+ private:
+ /**
+ * Finds a random source within a specified layer range
+ */
+ item::ItemCheck* findSource(u8 maxLayer, u8 minLayer = 0, item::ItemCheck* destCheck = nullptr);
+
+ /**
+ * Places dest into source and sets the flags necessary
+ */
+ void placeCheck(item::ItemCheck* sourceCheck, item::ItemCheck* destCheck);
+
+ /**
+ * Checks if the player with their current conditions can access the chest
+ */
+ bool checkCondition(item::ItemCheck* sourceCheck, item::ItemCheck* destCheck);
+
+ /**
+ * Checks if the item should be locked in place
+ */
+ bool isLocked(item::ItemCheck* check);
+
+ /**
+ * Checks if the stage given is a dungeon
+ * to prevent heart containers to spawn there so boss heart containers can spawn (doesn't fix it entirely based on Zephiles)
+ *
+ *includes miniboss rooms but not boss rooms
+ *excludes hyrule castle since boss doesn't spawn heart container
+ */
+ bool isStageADungeon(char* stage);
+
+ /**
+ * checks if item given is a type of bombs
+ * to prevent problems with the game changing bomb type based on type of bombs in inventory
+ *
+ * excludes bomb bag+bombs
+ */
+ bool isItemBombs(u8 itemID);
+
+ /**
+ * checks if item given is a bottle content without a bottle
+ */
+ bool isItemBottleFill(u8 itemID);
+
+ /**
+ *
+ * places the key checks correctly
+ */
+ void handleKeysanity();
+
+ /**
+ * check if the check gotten in a grotto is the right one
+ */
+ bool isGrottoCheckOk(u16 checkID);
+ };
+} \ No newline at end of file
diff --git a/source/include/controller.h b/source/include/controller.h
new file mode 100644
index 0000000..5fc660c
--- /dev/null
+++ b/source/include/controller.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::controller
+{
+ enum PadInputs : u32
+ {
+ Button_DPad_Left = 0x00000001,
+ Button_DPad_Right = 0x00000002,
+ Button_DPad_Down = 0x00000004,
+ Button_DPad_Up = 0x00000008,
+ Button_Z = 0x00000010,
+ Button_R = 0x00000020,
+ Button_L = 0x00000040,
+ Button_A = 0x00000100,
+ Button_B = 0x00000200,
+ Button_X = 0x00000400,
+ Button_Y = 0x00000800,
+ Button_Start = 0x00001000,
+ Stick_C_Left = 0x00010000,
+ Stick_C_Right = 0x00020000,
+ Stick_C_Down = 0x00040000,
+ Stick_C_Up = 0x00080000,
+ Stick_Left = 0x01000000,
+ Stick_Right = 0x02000000,
+ Stick_Down = 0x04000000,
+ Stick_Up = 0x08000000
+ };
+
+ extern "C"
+ {
+ bool checkForButtonInput(u32 buttonCombo);
+ bool checkForButtonInputSingleFrame(u32 buttonCombo);
+ }
+} \ No newline at end of file
diff --git a/source/include/customChecks.h b/source/include/customChecks.h
new file mode 100644
index 0000000..0f881cd
--- /dev/null
+++ b/source/include/customChecks.h
@@ -0,0 +1,106 @@
+#pragma once
+#include "defines.h"
+#include "tools.h"
+
+#include <tp/dzx.h>
+#include <tp/d_com_inf_game.h>
+
+struct customCheck
+{
+ char stage[8];
+ u8 room;
+
+ u8 chestType;
+
+ u8 saveFlag;
+ u8 itemID;
+
+ u32 X;
+ u32 Y;
+ u32 Z;
+
+ s32 Angle;
+
+ void(*overrides)();
+
+ bool(*requirement)();
+};
+
+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*/ } },
+ /*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*/ } },
+ /*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*/
+ {"F_SP103", 0, 1, 0x7C, 0x65, 0x444C8DC3, 0x42AF0000, 0xC4CB2577, 0xA3E7, []() { gameInfo.scratchPad.eventBits[0x12] |= 0x8;/*can shop at Sera's shop*/ gameInfo.scratchPad.eventBits[0x14] |= 0x8;/*Sera Bottle gotten*/ }, []() { return (gameInfo.localAreaNodes.unk_0[0xC] & 0x2) != 0;/*is goats 1 done*/ } },
+ /*Slingshot*/
+ {"F_SP103", 0, 0, 0x78, 0x4B, 0xC3EDF8A9, 0x44CD922E, 0x45F31BF5, 0x7881, nullptr /*Flag is set in game_patches to avoid interaction with vanilla check*/, []() { return gameInfo.scratchPad.counters.rupees >= 30 && (gameInfo.localAreaNodes.unk_0[0xC] & 0x2) != 0;/*is goats 1 done*/ } },
+ /*Lantern*/
+ {"F_SP108", 0xFF, 1, 0xF8, 0x48, 0xC66D4C1B, 0x41C19A25, 0xC65D2696, 0x36EC, nullptr, []() { return true; } },
+ /*Zora Armor*/
+ {"F_SP111", 0, 1, 0x7C, 0x31, 0x46A85A96, 0x43FA0000, 0x43944190, 0xC270, []() { gameInfo.scratchPad.eventBits[0x8] |= 0x4;/*got zora armor from Rutela*/ }, []() { return true; } },
+ /*Coral Earring*/
+ {"F_SP111", 0, 1, 0x78, 0x3D, 0x46A81087, 0x43FA57D9, 0xC3BCEFAC, 0xC270, []() { gameInfo.scratchPad.eventBits[0x3B] |= 0x80;/*Got Coral Earring from Ralis*/ }, []() { return tools::checkItemFlag(ItemFlags::Asheis_Sketch); } },
+ /*Auru's Memo*/
+ {"F_SP115", 0, 1, 0x7C, 0x90, 0xC7E2E398, 0xC6770800, 0x47656746, 0x143D, []() { gameInfo.scratchPad.eventBits[0x25] |= 0x30;/*Auru Cutscene Complete + Auru's Memo gotten*/ }, []() { return gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.bossBeaten == 0b1; } },
+ /*Ashei's Sketch*/
+ {"F_SP114", 0, 1, 0x7C, 0x91, 0x46F71891, 0xC6502A32, 0xC6348FA6, 0x86E6, []() { gameInfo.scratchPad.eventBits[0x29] |= 0x40;/*Got Ashei's Sketch from Ashei*/ }, []() { return true; } },
+ /*Renardo's Letter*/
+ {"R_SP109", 0, 1, 0x68, 0x80, 0x43D3A702, 0x0, 0x43D5A60B, 0xC1FD, []() { gameInfo.scratchPad.eventBits[0xF] |= 0x80;/*Got Renardo's Letter from Renardo*/ }, []() { return gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.bossBeaten == 0b1; } },
+ /*Invoice*/
+ {"R_SP116", 5, 1, 0x70, 0x81, 0x45282E22, 0xC48FC000, 0x453BED7D, 0x0000, []() { gameInfo.scratchPad.eventBits[0x21] |= 0x80;/*Got Invoice from Telma*/ }, []() { return tools::checkItemFlag(ItemFlags::Renardos_Letter); } },
+ /*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*/ } },
+ /*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*/
+ {"F_SP127", 0, 1, 0x7C, 0x60, 0x45B27147, 0x420C0000, 0x450F716A, 0x62E5, []() { gameInfo.scratchPad.eventBits[0x39] |= 0x8;/*Got fishing hole bottle*/ }, []() { return true; } },
+ /*Coro Key*/
+ {"F_SP108", 0xFF, 0, 0xF4, 0xFE, 0xC64BA600, 0x403DA884, 0xC663BC8E, 0x7A11, [](){ gameInfo.scratchPad.eventBits[0x1A] |= 0x10;/*Talked to Coro after Faron Twilight*/ gameInfo.localAreaNodes.unk_0[0xD] |= 0x4;/*got Coro key*/ }, [](){ return gameInfo.scratchPad.clearedTwilights.Faron == 0b1; } },
+ /*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; } },
+ /*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; } },
+ /*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*/
+ {"F_SP117", 1, 2, 0x78, 0x29, 0x4372ACFB, 0x44CB2000, 0xC5991A55, 0x0000, []() { gameInfo.scratchPad.eventBits[0x10] |= 0x20;/*got master sword cs*/ }, []() { return true; } },
+ /*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*/ } },
+ /*Ending Blow*/
+ {"F_SP108", 6, 2, 0xF0, 0xE1, 0xC71A5B41, 0x44898000, 0xC6E08544, 0x0000, nullptr, []() { return gameInfo.scratchPad.clearedTwilights.Faron == 0b1; } },
+ /*Shield Bash*/
+ {"F_SP104", 1, 2, 0x6C, 0xE2, 0xC4BB1F1C, 0x438C0000, 0xC613CAAA, 0x4138, []() { gameInfo.scratchPad.eventBits[0x3C] |= 0x8;/*Got skill from Ordon Wolf*/ }, []() { return (gameInfo.scratchPad.eventBits[0x3A] & 0x80) != 0;/*DMT howling stone done*/ } },
+ /*Back Slice*/
+ {"F_SP122", 8, 2, 0x78, 0xE3, 0xC78590C8, 0xC4834000, 0x45B7BC37, 0xC15B, []() { gameInfo.scratchPad.eventBits[0x3C] |= 0x4;/*Got skill from West CT Wolf*/ }, []() { return (gameInfo.scratchPad.eventBits[0x3A] & 0x40) != 0;/*UZR howling stone done*/ } },
+ /*Helm Splitter*/
+ {"F_SP122", 16, 2, 0x74, 0xE4, 0xC75990D6, 0xC5BEA000, 0x46C3B269, 0x0000, []() { gameInfo.scratchPad.eventBits[0x3C] |= 0x2;/*Got skill from South CT Wolf*/ }, []() { return (gameInfo.scratchPad.eventBits[0x3A] & 0x20) != 0;/*Faron howling stone done*/ } },
+ /*Mortal Draw*/
+ {"F_SP124", 0, 2, 0x78, 0xE5, 0xC53E0B78, 0x41C428F6, 0x46318C93, 0x4565, []() { gameInfo.scratchPad.eventBits[0x3C] |= 0x1;/*Got skill from Bublin Camp Wolf*/ }, []() { return (gameInfo.scratchPad.eventBits[0x3A] & 0x10) != 0;/*Lake Hylia howling stone done*/ } },
+ /*Jump Strike*/
+ {"F_SP111", 0, 2, 0x6C, 0xE6, 0x467D1395, 0x44034000, 0xC1F855A7, 0x3EE7, []() { gameInfo.scratchPad.eventBits[0x3D] |= 0x80;/*Got skill from Graveyard Wolf*/ }, []() { return (gameInfo.scratchPad.eventBits[0x3A] & 0x8) != 0;/*Snowpeak howling stone done*/ } },
+ /*Great Spin*/
+ {"F_SP116", 1, 2, 0x78, 0xE7, 0x42204113, 0x44480000, 0xC61FB41E, 0x0000, []() { gameInfo.scratchPad.eventBits[0x3D] |= 0x40;/*Got skill from Barrier Wolf*/ }, []() { return (gameInfo.scratchPad.eventBits[0x3A] & 0x4) != 0;/*Hidden Village howling stone done*/ } },
+ /*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; } },
+ /*Poe Scent*/
+ {"D_MN10", 0xFF, 0, 0x3C, 0xB2, 0xC1571A39, 0xC1200000, 0x4355109A, 0x0000, nullptr, []() { return true; } },
+ /*Reekfish Scent*/
+ {"F_SP113", 1, 0, 0x64, 0xB3, 0x456A7496, 0xC5BB109B, 0x464D4470, 0xD6E8, nullptr, []() { return tools::checkItemFlag(ItemFlags::Coral_Earring); } },
+ /*Medicine Scent*/
+ {"R_SP160", 2, 0, 0x74, 0xB5, 0x45EC0BF6, 0xC33E0000, 0xC4D9EA4C, 0xC26D, nullptr, []() { return true; } },
+ /*Snowpeak Map*/
+ {"D_MN11", 0xFF, 0, 0x74, 0x23, 0x447AF8E0, 0x00000000, 0xC42C93A9, 0xFEED, nullptr, []() { return true; } } };
+}; \ No newline at end of file
diff --git a/source/include/defines.h b/source/include/defines.h
new file mode 100644
index 0000000..c2c72d9
--- /dev/null
+++ b/source/include/defines.h
@@ -0,0 +1,126 @@
+#pragma once
+
+#include <cstddef>
+
+using std::size_t;
+
+// Data types
+typedef unsigned long long u64;
+typedef signed long long s64;
+typedef unsigned int u32;
+typedef signed int s32;
+typedef unsigned short u16;
+typedef signed short s16;
+typedef unsigned char u8;
+typedef signed char s8;
+
+// Helper
+#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
+#define BYTE_TO_BINARY(byte) \
+ (byte & 0b10000000 ? '1' : '0'), \
+ (byte & 0b01000000 ? '1' : '0'), \
+ (byte & 0b00100000 ? '1' : '0'), \
+ (byte & 0b00010000 ? '1' : '0'), \
+ (byte & 0b00001000 ? '1' : '0'), \
+ (byte & 0b00000100 ? '1' : '0'), \
+ (byte & 0b00000010 ? '1' : '0'), \
+ (byte & 0b00000001 ? '1' : '0')
+
+// Allows to transform data as bytes 1:1 from A<-->B and vice versa
+template <typename A, typename B>
+union typeTransform {
+ A a;
+ B b;
+};
+
+// Array modification
+#define MAX_LOAD_EVENTS 20 // eventListener
+#define MAX_HUDCONSOLE_PAGES 12 // HUDConsole
+
+// Mnemonics
+#define AUTHOR "ZTPR"
+#define VERSION "v0.15.2a"
+#define RAND_SEED mod::tools::randomSeed
+#define gameInfo tp::d_com_inf_game::dComIfG_gameInfo
+#define getPlayerPos tp::d_map_path_dmap::getMapPlayerPos
+#define sysConsolePtr tp::jfw_system::systemConsole
+#define isLoading tp::f_op_scene_req::isUsingOfOverlap
+#define ItemFlags tp::d_com_inf_game::ItemFlagBits
+
+// Stage translations for mod::stage::allStages[]
+#define Stage_Lakebed_Temple 0
+#define Stage_Morpheel 1
+#define Stage_Deku_Toad 2
+#define Stage_Goron_Mines 3
+#define Stage_Fyrus 4
+#define Stage_Dangoro 5
+#define Stage_Forest_Temple 6
+#define Stage_Diababa 7
+#define Stage_Ook 8
+#define Stage_Temple_of_Time 9
+#define Stage_Armogohma 10
+#define Stage_Darknut 11
+#define Stage_City_in_the_Sky 12
+#define Stage_Argorok 13
+#define Stage_Aeralfos 14
+#define Stage_Palace_of_Twilight 15
+#define Stage_Zant_Main 16
+#define Stage_Phantom_Zant_1 17
+#define Stage_Phantom_Zant_2 18
+#define Stage_Zant_Fight 19
+#define Stage_Hyrule_Castle 20
+#define Stage_Ganondorf_Castle 21
+#define Stage_Ganondorf_Field 22
+#define Stage_Ganondorf_Defeated 23
+#define Stage_Arbiters_Grounds 24
+#define Stage_Stallord 25
+#define Stage_Death_Sword 26
+#define Stage_Snowpeak_Ruins 27
+#define Stage_Blizzeta 28
+#define Stage_Darkhammer 29
+#define Stage_Lanayru_Ice_Puzzle_Cave 30
+#define Stage_Cave_of_Ordeals 31
+#define Stage_Eldin_Long_Cave 32
+#define Stage_Lake_Hylia_Long_Cave 33
+#define Stage_Eldin_Goron_Stockcave 34
+#define Stage_Grotto_1 35
+#define Stage_Grotto_2 36
+#define Stage_Grotto_3 37
+#define Stage_Grotto_4 38
+#define Stage_Grotto_5 39
+#define Stage_Faron_Woods_Cave 40
+#define Stage_Ordon_Ranch 41
+#define Stage_Title_Screen 42
+#define Stage_Ordon_Village 43
+#define Stage_Ordon_Spring 44
+#define Stage_Faron_Woods 45
+#define Stage_Kakariko_Village 46
+#define Stage_Death_Mountain 47
+#define Stage_Kakariko_Graveyard 48
+#define Stage_Zoras_River 49
+#define Stage_Zoras_Domain 50
+#define Stage_Snowpeak 51
+#define Stage_Lake_Hylia 52
+#define Stage_Castle_Town 53
+#define Stage_Sacred_Grove 54
+#define Stage_Bublin_Camp 55
+#define Stage_Hyrule_Field 56
+#define Stage_Outside_Castle_Town 57
+#define Stage_Bublin_2 58
+#define Stage_Gerudo_Desert 59
+#define Stage_Mirror_Chamber 60
+#define Stage_Upper_Zoras_River 61
+#define Stage_Fishing_Pond 62
+#define Stage_Hidden_Village 63
+#define Stage_Hidden_Skill 64
+#define Stage_Ordon_Interiors 65
+#define Stage_Hyrule_Castle_Sewers 66
+#define Stage_Coros_Lantern_Shop 67
+#define Stage_Kakariko_Interiors 68
+#define Stage_Death_Mountain_Sumo_Hall 69
+#define Stage_Castle_Town_Interiors 70
+#define Stage_Henas_Cabin 71
+#define Stage_Impaz_House 72
+#define Stage_Castle_Town_Shops 73
+#define Stage_Star_Game 74
+#define Stage_Sanctuary_Basement 75 \ No newline at end of file
diff --git a/source/include/eventListener.h b/source/include/eventListener.h
new file mode 100644
index 0000000..f1d176a
--- /dev/null
+++ b/source/include/eventListener.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::event
+{
+ /**
+ * Runs when the according event triggers
+ */
+ typedef void (*EventFunction)();
+
+ enum LoadEventAccuracy : u8
+ {
+ All = 0,
+ Stage = 1,
+ Stage_Room = 2,
+ Stage_Room_Spawn = 3,
+ Stage_Room_Spawn_State = 4
+ };
+
+ struct LoadEvent
+ {
+ char* Stage;
+ u8 Room;
+ u8 Spawn;
+ u8 State;
+ u8 Eventid; // Cutscene event id
+ EventFunction Trigger;
+ LoadEventAccuracy Accuracy;
+ };
+
+ class EventListener
+ {
+ private:
+ u8 loadEventIndex;
+ LoadEvent loadEvents[MAX_LOAD_EVENTS];
+
+ public:
+
+ EventListener();
+
+ /**
+ * Runs a loop that triggers the according event if it's conditions match
+ */
+ void checkLoadEvents();
+
+ /**
+ * Executes a function when certain load conditions match
+ *
+ * @param stage The stage identifier (internal id)
+ * @param room The room identifier (internal room id)
+ * @param spawn The spawnpoint identifier (internal spawn id)
+ * @param state The state (internal state id)
+ * @param csevent If it's a CS this is the id
+ * @param trigger The (void) function(void) to be executed when the event occurs
+ * @param accuracy Defines which of the identifiers have to match for the event to trigger
+ */
+ void addLoadEvent(char* stage, u8 room, u8 spawn, u8 state, u8 eventid, EventFunction trigger, LoadEventAccuracy accuracy = LoadEventAccuracy::All);
+ };
+} \ No newline at end of file
diff --git a/source/include/game_patches.h b/source/include/game_patches.h
new file mode 100644
index 0000000..d3f10ae
--- /dev/null
+++ b/source/include/game_patches.h
@@ -0,0 +1,179 @@
+#pragma once
+
+#include "defines.h"
+#include <tp/d_com_inf_game.h>
+
+
+
+/**
+ * Contains functions that fix certain cutscenes
+ * those functions should only run when the CS
+ * is currently playing and tried to be skipped by the user
+ */
+namespace mod::cutscene_skip
+{
+ /**
+ * Runs when master sword CS is skipped
+ */
+ s32 onMasterSwordSkip(void* unk, s32 unk2);
+}
+
+/**
+ * Contains patch functions that take no parameters
+ * and immediately perfom the described action
+ */
+namespace mod::game_patch
+{
+ /**
+ * Enables the debug screen without
+ * active debug mode; It triggers
+ * automatically when crashing
+ */
+ void assemblyOverwrites();
+
+ /**
+ * Kills spider at links house
+ */
+ void killLinkHouseSpider();
+
+ /**
+ * Increasees Links climbing speed
+ */
+ void increaseClimbSpeed();
+
+ /**
+ * Removes the movementspeed limit
+ * when wearing IB
+ */
+ void removeIBLimit();
+
+ /**
+ * Changes the max rupee amounts for each
+ * of the wallets
+ */
+ void increaseWalletSize();
+
+ /**
+ * Skips sewers immediately
+ * triggers the load to Ordon Spring
+ * and sets the flags accordingly
+ */
+ void skipSewers();
+
+ /**
+ * Adds the chests that disappear after KB3
+ * changes the state of faron from 1 to 3
+ */
+ void setBublinState();
+
+ /**
+ * Sets the flag after Ilia CS
+ * which tells the game that you started
+ * with sewers
+ */
+ void setFirstTimeWolf();
+
+ /**
+ * Sets form to human
+ */
+ void setHuman();
+
+ /**
+ * Sets form to wolf
+ */
+ void setWolf();
+
+
+ /**
+ * Activates the sense button (X)
+ * for Wolf Link
+ */
+ void giveSense();
+
+ /**
+ * Tames Epona
+ */
+ void giveEpona();
+
+ /**
+ * Gives Master Sword and equips it
+ */
+ void giveMasterSword();
+
+ /**
+ * Gives Midna and sets the according sewers flag
+ * Makes her appear on Z
+ */
+ void giveMidna();
+
+ /**
+ * Gives Midna Text that allows transformation
+ */
+ void giveMidnaTransform();
+
+ /**
+ * Removes the locks from the 2 bulblin gates in HF
+ * change doesn't get saved so set it evry time you load into HF
+ */
+ void setFieldBits();
+
+ /**
+ * when spawning in goats 2, will warp you to Illia taking Epona CS
+ */
+ void skipGoats();
+
+ /**
+ * opens the door the the master sword in sacred grove
+ */
+ void setGroveFlags();
+
+ /**
+ * when you spawn into the Cart Escort, game will spawn you in Kakariko Afterwards
+ */
+ void skipCartEscort();
+
+ /**
+ * warps player to Lanayru twilight gate if they don't have MS
+ */
+ void setLanayruWolf();
+
+ /**
+ * Fixes the cannon and puts it at lake hylia
+ */
+ void earlyCiTS();
+
+ /**
+ * Fyer will let you go to the desert if you have MS
+ */
+ void earlyDesert();
+
+ /**
+ * give boss key to all dungeons
+ */
+ void unlockBossDoors();
+
+ /**
+ * check wether to show hawkeye and hylian shield in malo mart
+ */
+ void handleMaloShop();
+
+ /**
+ * check whether you have MS before being allowed to enter the desert
+ */
+ void accessDesert();
+
+ /**
+ * skips midna text and story CS
+ */
+ void skipTextAndCS();
+
+ /**
+ * escort avalable at any time
+ */
+ void setEscortState();
+
+ /**
+ * skips the zant CS for MDH
+ */
+ void skipMDH();
+} \ No newline at end of file
diff --git a/source/include/gc/OSCache.h b/source/include/gc/OSCache.h
new file mode 100644
index 0000000..6a08f2e
--- /dev/null
+++ b/source/include/gc/OSCache.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "defines.h"
+
+namespace gc::os_cache
+{
+ extern "C"
+ {
+ // DCEnable
+ // DCInvalidateRange
+ void DCFlushRange(void* startAddr, u32 nBytes);
+ // DCStoreRange
+ // DCFlushRangeNoSync
+ // DCStoreRangeNoSync
+ // DCZeroRange
+ void ICInvalidateRange(void* startAddr, u32 nBytes);
+ // ICFlashInvalidate
+ // ICEnable
+ // __LCEnable
+ // LCEnable
+ // LCDisable
+ // LCStoreBlocks
+ // LCStoreData
+ // LCQueueWait
+ // L2GlobalInvalidate
+ // DMAErrorHandler
+ // __OSCacheInit
+ }
+} \ No newline at end of file
diff --git a/source/include/gc/OSModule.h b/source/include/gc/OSModule.h
new file mode 100644
index 0000000..27cfdc3
--- /dev/null
+++ b/source/include/gc/OSModule.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "defines.h"
+
+namespace gc::OSModule {
+
+struct OSModuleInfo
+{
+ u32 id;
+ OSModuleInfo* next;
+ OSModuleInfo* prev;
+ u32 numSections;
+ u32 sectionInfoOffset;
+ u32 nameOffset;
+ u32 nameSize;
+ u32 version;
+} __attribute__((__packed__));
+
+} \ No newline at end of file
diff --git a/source/include/global.h b/source/include/global.h
new file mode 100644
index 0000000..5992199
--- /dev/null
+++ b/source/include/global.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "mod.h"
+#include "chestRando.h"
+#include "eventListener.h"
+#include "HUDConsole.h"
+#include "game_patches.h"
+
+namespace mod::global
+{
+ extern mod::Mod* modPtr;
+ extern mod::ChestRandomizer* chestRandoPtr;
+ extern mod::event::EventListener* eventListenerPtr;
+ extern mod::HUDConsole* hudConsolePtr;
+} \ No newline at end of file
diff --git a/source/include/grottoChecks.h b/source/include/grottoChecks.h
new file mode 100644
index 0000000..23d8415
--- /dev/null
+++ b/source/include/grottoChecks.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::grottoChecks
+{
+ extern u16 g1_0[1];//Lanayru2
+ extern u16 g1_1[2];//Eldin2
+ extern u16 g1_2[1];//Ordon
+ extern u16 g1_3[2];//Lanayru3
+
+ extern u16 g2_0[3];//Eldin4
+ extern u16 g2_1[3];//Faron1
+ extern u16 g2_2[1];//Sacred
+ //extern u16 g2_3[0];//Eldin1
+
+ extern u16 g3_0[3];//Gerudo3
+ //extern u16 g3_1[0];//Gerudo2
+ //extern u16 g3_2[0];//Snowpeak2
+ //extern u16 g3_3[0];//Lanayru5
+
+ extern u16 g4_0[1];//Lanayru6
+ extern u16 g4_1[1];//Gerudo1
+ extern u16 g4_2[1];//Snowpeak1
+ extern u16 g4_3[1];//Lanayru4
+
+ extern u16 g5_0[1];//Lanayru1
+ //extern u16 g5_1[0];//Faron2
+ extern u16 g5_2[1];//Lake2
+ extern u16 g5_3[1];//Eldin3
+ extern u16 g5_4[1];//Lake1
+} \ No newline at end of file
diff --git a/source/include/item.h b/source/include/item.h
new file mode 100644
index 0000000..02de5da
--- /dev/null
+++ b/source/include/item.h
@@ -0,0 +1,84 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::item
+{
+
+ /**
+ * Returns the flag(s) to an item under certain conditions
+ *
+ * @param item Internal item ID
+ * @param currentPlayerConditions Current conditions of the player
+ */
+ u32 getFlags(u8 item, u32 currentPlayerConditions);
+
+ /**
+ * Bitwise conditions for ItemCheck
+ */
+ enum Condition : u32
+ {
+ OR = 0b000000000000000000000,
+ AND = 0b100000000000000000000,
+ Lantern = 0b010000000000000000000,//0x48
+ Iron_Boots = 0b001000000000000000000,//0x45
+ Boomerang = 0b000100000000000000000,//0x40
+ Slingshot = 0b000010000000000000000,//0x4B
+ Bow = 0b000001000000000000000,//0x43
+ Bombs = 0b000000100000000000000,//0x70 0x51
+ Water_Bombs = 0b000000010000000000000,//0x70 0x51
+ Bomb_Arrows = 0b000000001000000000000,//0x43 0x70 0x51
+ Ball_And_Chain = 0b000000000100000000000,//0x42
+ Clawshot = 0b000000000010000000000,//0x44
+ Double_Clawshot = 0b000000000001000000000,//0x47
+ Spinner = 0b000000000000100000000,//0x41
+ Dominion_Rod = 0b000000000000010000000,//0x46
+ Zora_Armor = 0b000000000000001000000,//0x31
+ Small_Key = 0b000000000000000100000,//locked
+ Coral_Earring = 0b000000000000000010000,//0x3D
+ Wooden_Sword = 0b000000000000000001000,//0x3F
+ Ordon_Sword = 0b000000000000000000100,//0x28
+ Master_Sword = 0b000000000000000000010,//0x29 locked not randomized yet (implies transformation too)
+ Shield = 0b000000000000000000001,//0x2C
+ };
+
+ enum ItemType : u8
+ {
+ Equip = 0,
+ Gear = 1,
+ Dungeon = 2,
+ HeartPiece = 3,
+ Story = 4,
+ Ammo = 5,
+ Misc = 6,
+ Rupee = 7,
+ Key = 8,
+ Bottle = 9,
+ Bug = 10,
+ PoeSoul = 11,
+ Shop = 12,
+ Skill = 13
+ };
+
+ /**
+ * Contains item check info
+ */
+ struct ItemCheck
+ {
+ u8 itemID;
+ u8 type;
+ char* stage;
+ u8 room;
+ u8 sourceLayer;
+ u8 destLayer;
+ u32 condition;
+ float position[3];
+ ItemCheck* source;
+ ItemCheck* destination;
+ };
+
+ /**
+ * Contains the values for the flags to be set to skip the animations of first getting specific items
+ */
+ extern u8 itemGetAnimationFlags[10];
+} \ No newline at end of file
diff --git a/source/include/itemChecks.h b/source/include/itemChecks.h
new file mode 100644
index 0000000..dff2ea6
--- /dev/null
+++ b/source/include/itemChecks.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "defines.h"
+#include "item.h"
+
+namespace mod::item
+{
+ extern ItemCheck checks[503];
+ extern u16 checkPriorityOrder[24];
+} \ No newline at end of file
diff --git a/source/include/items.h b/source/include/items.h
new file mode 100644
index 0000000..85f9608
--- /dev/null
+++ b/source/include/items.h
@@ -0,0 +1,266 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::items
+{
+ enum Item : u8
+ {
+ Recovery_Heart = 0x00,
+ Green_Rupee = 0x01,
+ Blue_Rupee = 0x02,
+ Yellow_Rupee = 0x03,
+ Red_Rupee = 0x04,
+ Purple_Rupee = 0x05,
+ Orange_Rupee = 0x06,
+ Silver_Rupee = 0x07,
+ /*Borrow_Bomb_Bag? = 0x08,*/
+ /*Bomb_Bag_And_Bombs? = 0x09,*/
+ Bombs_5 = 0x0A,
+ Bombs_10 = 0x0B,
+ Bombs_20 = 0x0C,
+ Bombs_30 = 0x0D,
+ Arrows_10 = 0x0E,
+ Arrows_20 = 0x0F,
+ Arrows_30 = 0x10,
+ Arrows_1 = 0x11,
+ Seeds_50 = 0x12,
+ /*? = 0x13,*/
+ /*? = 0x14,*/
+ /*? = 0x15,*/
+ Water_Bombs_5 = 0x16,
+ Water_Bombs_10 = 0x17,
+ Water_Bombs_15 = 0x18,
+ Water_Bombs_3 = 0x19,
+ Bomblings_5 = 0x1A,
+ Bomblings_10 = 0x1B,
+ Bomblings_3 = 0x1C,
+ Bombling_1 = 0x1D,
+ Fairy = 0x1E,
+ Recovery_Heart_x3 = 0x1F,
+ Small_Key = 0x20,
+ Piece_of_Heart = 0x21,
+ Heart_Container = 0x22,
+ Dungeon_Map = 0x23,
+ Compass = 0x24,
+ Ooccoo_FT = 0x25,
+ Big_Key = 0x26,
+ Ooccoo_Jr = 0x27,
+ Ordon_Sword = 0x28,
+ Master_Sword = 0x29,
+ Ordon_Shield = 0x2A,
+ Wooden_Shield = 0x2B,
+ Hylian_Shield = 0x2C,
+ Ooccoos_Note = 0x2D,
+ Ordon_Clothing = 0x2E,
+ Heros_Clothes = 0x2F,
+ Magic_Armor = 0x30,
+ Zora_Armor = 0x31,
+ /*does notting*/Shadow_Crystal = 0x32,
+ Ooccoo_Dungeon = 0x33,
+ /*unused*/Small_Wallet = 0x34,
+ Big_Wallet = 0x35,
+ Giant_Wallet = 0x36,
+ /*Piece_of_Heart_2? = 0x37,*/
+ /*Piece_of_Heart_3? = 0x38,*/
+ /*Piece_of_Heart_4? = 0x39,*/
+ /*Piece_of_Heart_5? = 0x3A,*/
+ /*sword? = 0x3B,*/
+ /*? = 0x3C,*/
+ Coral_Earring = 0x3D,
+ Hawkeye = 0x3E,
+ Wooden_Sword = 0x3F,
+ Boomerang = 0x40,
+ Spinner = 0x41,
+ Ball_and_Chain = 0x42,
+ Heros_Bow = 0x43,
+ Clawshot = 0x44,
+ Iron_Boots = 0x45,
+ Dominion_Rod = 0x46,
+ Clawshots = 0x47,
+ Lantern = 0x48,
+ Master_Sword_Light = 0x49,
+ Fishing_Rod = 0x4A,
+ Slingshot = 0x4B,
+ Dominion_Rod_Uncharged = 0x4C,
+ /*? = 0x4D,*/
+ /*? = 0x4E,*/
+ Giant_Bomb_Bag = 0x4F,
+ Empty_Bomb_Bag = 0x50,
+ Goron_Bomb_Bag = 0x51,
+ /*Giant_Bomb_Bag? = 0x52,*/
+ /*? = 0x53,*/
+ /*unused*/Small_Quiver = 0x54,
+ Big_Quiver = 0x55,
+ Giant_Quiver = 0x56,
+ /*? = 0x57,*/
+ Fishing_Rod_Lure = 0x58,
+ Bow_Bombs = 0x59,
+ Bow_Hawkeye = 0x5A,
+ Fishing_Rod_Bee_Larva = 0x5B,
+ Fishing_Rod_Coral_Earring = 0x5C,
+ Fishing_Rod_Worm = 0x5D,
+ Fishing_Rod_Earring_Bee_Larva = 0x5E,
+ Fishing_Rod_Earring_Worm = 0x5F,
+ Empty_Bottle = 0x60,
+ Red_Potion_Shop = 0x61,
+ Green_Potion = 0x62,
+ Blue_Potion = 0x63,
+ Milk = 0x64,
+ Sera_Bottle = 0x65,
+ Lantern_Oil_Shop = 0x66,
+ Water = 0x67,
+ Lantern_Oil_Scooped = 0x68,
+ Red_Potion_Scooped = 0x69,
+ Nasty_soup = 0x6A,
+ Hot_spring_water_Scooped = 0x6B,
+ Fairy_Bottle = 0x6C,
+ Hot_Spring_Water_Shop = 0x6D,
+ Lantern_Refill_Scooped = 0x6E,
+ Lantern_Refill_Shop = 0x6F,
+ Bomb_Bag_Regular_Bombs = 0x70,
+ Bomb_Bag_Water_Bombs = 0x71,
+ Bomb_Bag_Bomblings = 0x72,
+ Fairy_Tears = 0x73,
+ Worm = 0x74,
+ Jovani_Bottle = 0x75,
+ Bee_Larva_Scooped = 0x76,
+ Rare_Chu_Jelly = 0x77,
+ Red_Chu_Jelly = 0x78,
+ Blue_Chu_Jelly = 0x79,
+ Green_Chu_Jelly = 0x7A,
+ Yellow_Chu_Jelly = 0x7B,
+ Purple_Chu_Jelly = 0x7C,
+ Simple_Soup = 0x7D,
+ Good_Soup = 0x7E,
+ Superb_Soup = 0x7F,
+ Renardos_Letter = 0x80,
+ Invoice = 0x81,
+ Wooden_Statue = 0x82,
+ Ilias_Charm = 0x83,
+ Horse_Call = 0x84,
+ /*? = 0x85,*/
+ /*? = 0x86,*/
+ /*? = 0x87,*/
+ /*? = 0x88,*/
+ /*? = 0x89,*/
+ /*? = 0x8A,*/
+ /*? = 0x8B,*/
+ /*? = 0x8C,*/
+ /*? = 0x8D,*/
+ /*? = 0x8E,*/
+ /*? = 0x8F,*/
+ Aurus_Memo = 0x90,
+ Asheis_Sketch = 0x91,
+ /*? = 0x92,*/
+ /*? = 0x93,*/
+ /*? = 0x94,*/
+ /*? = 0x95,*/
+ /*? = 0x96,*/
+ /*? = 0x97,*/
+ /*? = 0x98,*/
+ /*? = 0x99,*/
+ /*? = 0x9A,*/
+ /*? = 0x9B,*/
+ Lantern_Yellow_Chu_Chu = 0x9C,
+ Coro_Bottle = 0x9D,
+ Bee_Larva_Shop = 0x9E,
+ Black_Chu_Jelly = 0x9F,
+ /*unused*/Tear_Of_Light = 0xA0,
+ Vessel_Of_Light_Faron = 0xA1,
+ Vessel_Of_Light_Eldin = 0xA2,
+ Vessel_Of_Light_Lanayru = 0xA3,
+ /*unused*/Vessel_Of_Light_Full = 0xA4,
+ /*? = 0xA5,*/
+ /*? = 0xA6,*/
+ /*? = 0xA7,*/
+ /*? = 0xA8,*/
+ /*? = 0xA9,*/
+ /*? = 0xAA,*/
+ /*? = 0xAB,*/
+ /*? = 0xAC,*/
+ /*? = 0xAD,*/
+ /*? = 0xAE,*/
+ /*? = 0xAF,*/
+ Ilias_Scent = 0xB0,
+ /*Unused_Scent? = 0xB1,*/
+ Poe_Scent = 0xB2,
+ Reekfish_Scent = 0xB3,
+ Youths_Scent = 0xB4,
+ Medicine_Scent = 0xB5,
+ /*? = 0xB6,*/
+ /*? = 0xB7,*/
+ /*? = 0xB8,*/
+ /*? = 0xB9,*/
+ /*? = 0xBA,*/
+ /*? = 0xBB,*/
+ /*? = 0xBC,*/
+ /*? = 0xBD,*/
+ /*? = 0xBE,*/
+ /*Bottle_Insides? = 0xBF,*/
+ Male_Beetle = 0xC0,
+ Female_Beetle = 0xC1,
+ Male_Butterfly = 0xC2,
+ Female_Butterfly = 0xC3,
+ Male_Stag_Beetle = 0xC4,
+ Female_Stag_Beetle = 0xC5,
+ Male_Grasshopper = 0xC6,
+ Female_Grasshopper = 0xC7,
+ Male_Phasmid = 0xC8,
+ Female_Phasmid = 0xC9,
+ Male_Pill_Bug = 0xCA,
+ Female_Pill_Bug = 0xCB,
+ Male_Mantis = 0xCC,
+ Female_Mantis = 0xCD,
+ Male_Ladybug = 0xCE,
+ Female_Ladybug = 0xCF,
+ Male_Snail = 0xD0,
+ Female_Snail = 0xD1,
+ Male_Dragonfly = 0xD2,
+ Female_Dragonfly = 0xD3,
+ Male_Ant = 0xD4,
+ Female_Ant = 0xD5,
+ Male_Dayfly = 0xD6,
+ Female_Dayfly = 0xD7,
+ /*? = 0xD8,*/
+ /*? = 0xD9,*/
+ /*? = 0xDA,*/
+ /*? = 0xDB,*/
+ /*? = 0xDC,*/
+ /*? = 0xDD,*/
+ /*? = 0xDE,*/
+ /*? = 0xDF,*/
+ Poe_Soul = 0xE0,
+ /*? = 0xE1,*/
+ /*? = 0xE2,*/
+ /*? = 0xE3,*/
+ /*? = 0xE4,*/
+ /*? = 0xE5,*/
+ /*? = 0xE6,*/
+ /*? = 0xE7,*/
+ /*? = 0xE8,*/
+ Ancient_Sky_Book_empty = 0xE9,
+ Ancient_Sky_Book_partly_filled = 0xEA,
+ Ancient_Sky_Book_completed = 0xEB,
+ Ooccoo_CitS = 0xEC,
+ Purple_Rupee_Links_house = 0xED,
+ Small_Key_N_Faron_Gate = 0xEE,
+ /*Blue_Fire? = 0xEF,*/
+ /*Blue_Fire? = 0xF0,*/
+ /*Blue_Fire? = 0xF1,*/
+ /*Blue_Fire? = 0xF2,*/
+ Gate_Keys = 0xF3,
+ Ordon_Pumpkin = 0xF4,
+ Ordon_Goat_Cheese = 0xF5,
+ Bed_Key = 0xF6,
+ /*Shield? = 0xF7,*/
+ Got_Lantern_Back = 0xF8,
+ Key_Shard_1 = 0xF9,
+ Key_Shard_2 = 0xFA,
+ Key_Shard_3 = 0xFB,
+ /*Key? = 0xFC,*/
+ Big_Key_Goron_Mines = 0xFD,
+ Coro_Key = 0xFE,
+ /*Gives_Vanilla*/NullItem = 0xFF
+ };
+} \ No newline at end of file
diff --git a/source/include/keyPlacement.h b/source/include/keyPlacement.h
new file mode 100644
index 0000000..9ea0017
--- /dev/null
+++ b/source/include/keyPlacement.h
@@ -0,0 +1,67 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::keyPlacement
+{
+ extern u16 FT_keys[4];
+ extern u16 FT_1[5];
+ extern u16 FT_2[5];
+ extern u16 FT_3[9];
+ extern u16 FT_4[9];
+
+ extern u16 GM_keys[3];
+ extern u16 GM_1[2];
+ extern u16 GM_2[10];
+ extern u16 GM_3[12];
+
+ extern u16 LBT_keys[3];
+ extern u16 LBT_1[7];
+ extern u16 LBT_2[9];
+ extern u16 LBT_3[11];
+
+ extern u16 AG_keys[5];
+ extern u16 AG_1[1];
+ extern u16 AG_2[7];
+ extern u16 AG_3[9];
+ extern u16 AG_4[11];
+ extern u16 AG_5[16];
+
+ extern u16 SPR_keys[6];
+ extern u16 SPR_1[5];
+ extern u16 SPR_2[6];
+ extern u16 SPR_3[10];
+ extern u16 SPR_4[13];
+ extern u16 SPR_5[19];
+ extern u16 SPR_6[22];
+
+ extern u16 ToT_keys[3];
+ extern u16 ToT_1[2];
+ extern u16 ToT_2[8];
+ extern u16 ToT_3[16];
+
+ extern u16 CitS_keys[1];
+ extern u16 CitS_1[7];
+
+ extern u16 PoT_keys[7];
+ extern u16 PoT_1[1];
+ extern u16 PoT_2[4];
+ extern u16 PoT_3[6];
+ extern u16 PoT_4[10];
+ extern u16 PoT_5[14];
+ extern u16 PoT_6[16];
+ extern u16 PoT_7[17];
+
+ extern u16 HC_keys[3];
+ extern u16 HC_1[9];
+ extern u16 HC_2[15];
+ extern u16 HC_3[15];
+
+ extern u16 F_keys[2];
+ extern u16 F_1[4];
+ extern u16 F_2[2];
+
+ extern u16 GD_keys[1];
+ extern u16 GD_1[21];
+
+} \ No newline at end of file
diff --git a/source/include/memory.h b/source/include/memory.h
new file mode 100644
index 0000000..26beaf4
--- /dev/null
+++ b/source/include/memory.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::memory
+{
+ extern "C"
+ {
+ void* clearMemory(void* ptr, size_t size);
+ void clear_DC_IC_Cache(void* ptr, u32 size);
+ }
+} \ No newline at end of file
diff --git a/source/include/mod.h b/source/include/mod.h
new file mode 100644
index 0000000..245350b
--- /dev/null
+++ b/source/include/mod.h
@@ -0,0 +1,234 @@
+#pragma once
+
+#include "defines.h"
+#include <tp/d_com_inf_game.h>
+#include <tp/DynamicLink.h>
+#include <tp/dzx.h>
+#include "eventListener.h"
+#include "chestRando.h"
+#include "HUDConsole.h"
+
+namespace mod
+{
+ class Mod
+ {
+ public:
+ Mod();
+ /**
+ * Init this and other stuff in order for all
+ * modifications to work
+ */
+ void init();
+
+ /**
+ * Custom event listener that can
+ * schedule function calls
+ */
+ event::EventListener* eventListener;
+ ChestRandomizer* chestRandomizer;
+ HUDConsole* hudConsole;
+
+ // Options
+ u8 customSeed; // Use custom seed?
+ u8 randoEnabled; // Randomize chests?
+ u8 truePause; // Disable controls during console?
+ u8 inputBuffering; // En/Disable buffering
+
+ //item search
+ u8 lastItemSearchID;
+ u8 itemSearchID;
+
+ u8 lastItemReverseSearchID;
+ u8 itemReverseSearchID;
+ char itemSearchResults[30];
+ char itemReverseSearchResults[30];
+
+ //check search
+ u8 checkSearchID1;
+ u8 checkSearchID2;
+
+ u8 checkReverseSearchID1;
+ u8 checkReverseSearchID2;
+
+ u16 lastCheckSearchID;
+ u16 checkSearchID;
+
+ u16 lastCheckReverseSearchID;
+ u16 checkReverseSearchID;
+ char checkSearchResults[30];
+ char checkReverseSearchResults[30];
+
+ // Debug info
+ char lastItemFunc[32]; // Last called item create function
+ char lastItemDataID[5];
+ char lastItemDataX[30];
+ char lastItemDataY[30];
+ char lastItemDataZ[30];
+
+ char currentPosX[30];
+ char currentPosY[30];
+ char currentPosZ[30];
+
+ char linkAngle[30];
+
+ u8 coordsAreInHex = 0;
+
+ // Replacment handler
+ s32 procItemCreateFunc(const float pos[3], s32 item, const char funcIdentifier[32]);
+
+ u8 enableNormalTime = 1;
+ u8 setDay = 1;
+
+ u32 skyAngle;
+
+ u8 enableQuickTransform = 1;
+
+ u8 stage = 0;
+ u8 room = 0;
+ u8 spawn = 0;
+ u8 state = 0;
+ u8 trigerLoadSave = 0;
+
+ u8 dungeonFlagsView1;
+ u8 dungeonFlagsView2;
+ u8 dungeonFlagsView3;
+ u8 dungeonFlagsView4;
+ u8 dungeonFlagsView5;
+ u8 dungeonFlagsView6;
+ u8 dungeonFlagsView7;
+ u8 dungeonFlagsView8;
+ u8 dungeonFlagsViewEdit;
+
+ u16 colorResult;
+
+ u8 topToggle = 1;
+ u8 redTop = 0;
+ u8 greenTop = 0;
+ u8 blueTop = 0;
+ u8 bottomToggle = 1;
+ u8 redBottom = 0;
+ u8 greenBottom = 0;
+ u8 blueBottom = 0;
+
+ u8 bottle4Contents;
+ u8 bottleTrickOn = 0;
+ u8 allowBottleItemsShopAnytime = 1;
+ u8 shieldTrickOn = 0;
+ u8 hadHShield;
+ u8 hadOShield;
+ u8 hadWShield;
+ u8 bombBagTrickOn = 0;
+ u8 bombBag1Contents;
+ u8 bombBag2Contents;
+ u8 bombBag3Contents;
+ u8 bombBag1Ammo;
+ u8 bombBag2Ammo;
+ u8 bombBag3Ammo;
+
+ u8 yetaTrickOn = 0;
+
+ u8 LBTBossDoorTrickOn = 0;
+ u8 nbLBTKeys = 0;
+
+
+ // Functions
+ private:
+ /**
+ * Runs once each frame
+ */
+ void procNewFrame();
+
+ /**
+ * Runs when checking if the treasure chest content
+ * should be returned or can be obtained
+ */
+ bool procCheckTreasureRupeeReturn(void* unk1, s32 item);
+
+ s32 procEvtSkipper(void* evtPtr);
+
+ bool proc_query022(void* unk1, void* unk2, s32 unk3);
+
+ bool procDoLink(tp::dynamic_link::DynamicModuleControl* dmc);
+
+ void procItem_func_UTUWA_HEART();
+
+ /**
+ * gives the unlocked scent that can be seen in the current area (defaults to most advanced one obtained)
+ */
+ void giveAllStoryItems();
+
+ /**
+ * order the item wheel correctly
+ */
+ void reorderItemWheel();
+
+ /**
+ * Allows Yeta to always be in the living room even with the BK
+ * Allows Yeto to always be in the kitchen even with the BK
+ */
+ void fixYetaAndYeto();
+
+ /**
+ * fix problem where opening LBT boss door removes a key
+ */
+ void fixLBTBossDoor();
+
+ /**
+ * removes the empty skybook if you are in the sanctuary basement
+ */
+ void preventPoweringUpDomRod();
+
+ /**
+ * gives the unlocked scent that can be seen in the current area (defaults to most advanced one obtained)
+ */
+ void giveAllScents();
+
+ /**
+ * renders all shop items buyable no matter what you have in you inv
+ * only works for bottle items for now
+ */
+ void allowShopItemsAnytime();
+
+ /**
+ * checks if the current stage contains a shop
+ */
+ bool isStageShop();
+
+ /**
+ * Inserts custom TRES Boxes if applicable to this stage+room
+ */
+ void doCustomTRESActor(void* mStatus_roomControl);
+
+
+ // Private members
+ //private:
+
+
+ // Hook trampolines
+ private:
+ void (*fapGm_Execute_trampoline)() = nullptr;
+
+ s32 (*evt_control_Skipper_trampoline)(void* eventPtr) = nullptr;
+
+ bool (*query022_trampoline)(void* unk1, void* unk2, s32 unk3) = nullptr;
+
+ bool (*do_link_trampoline)(tp::dynamic_link::DynamicModuleControl* dmc) = nullptr;
+
+ bool (*checkTreasureRupeeReturn_trampoline)(void* unk1, s32 item) = nullptr;
+
+ void (*item_func_UTUWA_HEART_trampoline)() = nullptr;
+
+ void(*actorCommonLayerInit_trampoline)(void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4) = 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;
+ s32 (*createItemForTrBoxDemo_trampoline)(const float pos[3], s32 item, s32 unk3, s32 unk4, const float unk5[3], const float unk6[3]) = nullptr;
+ s32 (*createItemForBoss_trampoline)(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7, s32 unk8) = nullptr;
+ s32 (*createItemForMidBoss_trampoline)(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], s32 unk6, s32 unk7) = nullptr;
+ s32 (*createItemForDirectGet_trampoline)(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7) = nullptr;
+ s32(*createItemForSimpleDemo_trampoline)(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7) = nullptr;
+ s32(*createItem_trampoline)(const float pos[3], s32 item, s32 unk3, s32 unk4, const float unk5[3], const float unk6[3], s32 unk7) = nullptr;
+
+ void(*setItemBombNumCount_trampoline)(u32 unk1, u8 bagNb, short amount) = nullptr;
+ };
+} \ No newline at end of file
diff --git a/source/include/patch.h b/source/include/patch.h
new file mode 100644
index 0000000..6273c60
--- /dev/null
+++ b/source/include/patch.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "defines.h"
+#include "memory.h"
+
+namespace mod::patch
+{
+ void writeBranch(void* ptr, void* destination);
+ void writeBranchLR(void* ptr, void* destination);
+ void writeBranchMain(void* ptr, void* destination, u32 branch);
+
+ template<typename Func, typename Dest>
+ Func hookFunction(Func function, Dest destination)
+ {
+ u32* instructions = reinterpret_cast<u32*>(function);
+
+ u32* trampoline = new u32[2];
+
+ // Original instruction
+ trampoline[0] = instructions[0];
+ memory::clear_DC_IC_Cache(&trampoline[0], sizeof(u32));
+
+ // Branch to original function past hook
+ writeBranch(&trampoline[1], &instructions[1]);
+
+ // Write actual hook
+ writeBranch(&instructions[0], reinterpret_cast<void*>(static_cast<Func>(destination)));
+
+ return reinterpret_cast<Func>(trampoline);
+ }
+} \ No newline at end of file
diff --git a/source/include/singleton.h b/source/include/singleton.h
new file mode 100644
index 0000000..8b41568
--- /dev/null
+++ b/source/include/singleton.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "defines.h"
+
+
+/**
+ * Contains variables that can be edited and read by everyone
+ */
+namespace mod
+{
+ class Singleton
+ {
+ public:
+
+ static Singleton* getInstance();
+
+ u8 isMDHSkipEnabled;
+ u8 isForestEscapeEnabled;
+ u8 isGateUnlockEnabled;
+ u8 isGoatSkipEnabled;
+ u8 isMSPuzzleSkipEnabled;
+ u8 isCartEscortSkipEnabled;
+ u8 isEarlyCiTSEnabled;
+ u8 isCannonRepaired;
+ u8 isEarlyDesertEnabled;
+ u8 isBossKeyseyEnabled;
+ u8 isSewerSkipEnabled;
+ u8 shuffledSkybook;
+ u8 isIntroSkipped;
+ u8 isTwilightSkipped;
+
+ private:
+
+ static Singleton* instance;
+
+ Singleton();
+
+ };
+} \ No newline at end of file
diff --git a/source/include/stage.h b/source/include/stage.h
new file mode 100644
index 0000000..166b5ff
--- /dev/null
+++ b/source/include/stage.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::stage
+{
+ extern char allStages[76][8];
+ extern const char* dungeonStages[18];
+ extern const char* bossStages[8];
+ extern const char* shopStages[8];
+ extern const char* grottoStages[5];
+} \ No newline at end of file
diff --git a/source/include/systemConsole.h b/source/include/systemConsole.h
new file mode 100644
index 0000000..c2aac6a
--- /dev/null
+++ b/source/include/systemConsole.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace mod::system_console
+{
+ extern "C"
+ {
+ void setBackgroundColor(u32 rgba);
+ void setState(bool activeFlag, u32 totalLines);
+ }
+} \ No newline at end of file
diff --git a/source/include/tools.h b/source/include/tools.h
new file mode 100644
index 0000000..7162985
--- /dev/null
+++ b/source/include/tools.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "defines.h"
+
+#include <tp/evt_control.h>
+#include <tp/d_com_inf_game.h>
+
+namespace mod::tools
+{
+ extern "C"
+ {
+ extern u64 randomSeed;
+
+ /**
+ * Generates a simple random number (not perfectly random but good enough for most purposes)
+ * Note: It's best to use with a clock that advances randomSeed
+ * (C) http://xoshiro.di.unimi.it/splitmix64.c
+ *
+ * @param max The maximum number to return
+ * @returns A random integer between 0 and max, excluding max
+ */
+ u32 getRandom(u32 max);
+
+ /**
+ * Triggers the generator function which is a member function
+ * (This is a wrapper)
+ */
+ void triggerRandomGenerator();
+
+ /**
+ * Triggers a load savely by setting some important
+ * variables for the game to handle it properly
+ */
+ void triggerSaveLoad(char* stage, u8 room, u8 spawn, u8 state = 0xFF, u8 event = 0xFF);
+
+ /**
+ * Sets whether the cutscene can be skipped
+ *
+ * Unskippable cutscenes sometimes set flags so take care of them
+ * in the function that calls this if needed
+ *
+ * @param skippable If true the user can skip, otherwise unskippable
+ * @param fade If true the skip action will smoothly transition
+ * @param onSkip The tp::evt_control::csFunc that runs when trying to skip
+ */
+ void setCutscene(bool skippable, bool fade = true, tp::evt_control::csFunc onSkip = tp::evt_control::defaultSkipStb);
+
+ /**
+ * Compares two floats and returns their difference
+ */
+ float fCompare(const float f1, const float f2);
+
+ /**
+ * Generates a simple u32 checksum
+ *
+ * @param data The data you need a checksum for
+ * @param count The number of bytes
+ */
+ u16 fletcher16(u8* data, s32 count);
+
+ /**
+ * Sets a specific bit/flag in the itemFlags variable in tp::d_com_inf_game::gameInfo.scratchPad.itemFlags
+ */
+ void setItemFlag(ItemFlags flag);
+
+ /**
+ * Unsets a specific bit/flag in the itemFlags variable in tp::d_com_inf_game::gameInfo.scratchPad.itemFlags
+ */
+ void clearItemFlag(ItemFlags flag);
+
+
+ /**
+ * Checks if a specific bit/flag in the itemFlags variable in tp::d_com_inf_game::gameInfo.scratchPad.itemFlags is set
+ */
+ bool checkItemFlag(ItemFlags flag);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp.eu.lst b/source/include/tp.eu.lst
new file mode 100644
index 0000000..7a10dc1
--- /dev/null
+++ b/source/include/tp.eu.lst
@@ -0,0 +1,170 @@
+// memory
+80003458:memset
+80003540:memcpy
+
+// m_Do_ext.o
+// text
+8000EDA8:getArchiveHeapPtr
+// data
+80452BF4:archiveHeap
+
+// d_save.o
+80032B50:getRupeeMax
+800351EC:getSave
+80035220:putSave
+
+/ d_stage.o
+80025914:actorCommonLayerInit
+// data
+803F8034:mStatus_roomControl
+
+// d_event.o
+800428A8:defaultSkipStb
+80042B04:skipper
+
+// f_op_scene_req.o
+// data
+804525D4:freezeActors
+80452CA0:isUsingOfOverlap
+
+// f_ap_game.o
+80018B14:fapGm_Execute
+
+// f_op_actor_mng.o
+8001BC90:createItemForPresentDemo
+8001BD1C:createItemForTrBoxDemo
+8001C120:createDemoItem
+8001C17C:createItemForBoss
+8001C21C:createItemForMidBoss
+8001C260:createItemForDirectGet
+8001C2A4:createItemForSimpleDemo
+
+// d_map_path_dmap.o
+8003EF8C:getMapPlayerPos
+8003F050:getMapPlayerAngleY
+
+// d_item.o
+80097FBC:execItemGet
+80098010:checkItemGet
+800983E4:item_func_UTUWA_HEART
+
+// d_a_alink.h
+8009DC6C:checkStageName
+800B2928:setStickData
+800BB6C4:checkHeavyStateOn
+800C7A00:procCoMetamorphoseInit
+8011A908:checkTreasureRupeeReturn
+803DEDF4:linkStatus
+// data
+8039038C:ladderVars
+
+// d_menu_collect.o
+801B3598:setWalletMaxNum
+
+// d_msg_flow.o
+8024BF88:query022
+
+// DynamicLink.o
+80263A5C:do_link
+
+// JKRExpHeap.o
+802CFF28:do_alloc_JKRExpHeap
+802D05AC:do_free_JKRExpHeap
+
+// OSCache.o
+// 8033C36C:DCEnable
+// 8033C380:DCInvalidateRange
+8033C3AC:DCFlushRange
+// 8033C3DC:DCStoreRange
+// 8033C40C:DCFlushRangeNoSync
+// 8033C438:DCStoreRangeNoSync
+// 8033C464:DCZeroRange
+8033C490:ICInvalidateRange
+// 8033C4C4:ICFlashInvalidate
+// 8033C4D4:ICEnable
+// 8033C4E8:__LCEnable
+// 8033C5B4:LCEnable
+// 8033C5EC:LCDisable
+// 8033C614:LCStoreBlocks
+// 8033C638:LCStoreData
+// 8033C6E4:LCQueueWait
+// 8033C6F8:L2GlobalInvalidate
+// 8033C790:DMAErrorHandler
+// 8033C8F0:__OSCacheInit
+
+// runtime.o
+80362F38:_savefpr_14
+80362F3C:_savefpr_15
+80362F40:_savefpr_16
+80362F44:_savefpr_17
+80362F48:_savefpr_18
+80362F4C:_savefpr_19
+80362F50:_savefpr_20
+80362F54:_savefpr_21
+80362F58:_savefpr_22
+80362F5C:_savefpr_23
+80362F60:_savefpr_24
+80362F64:_savefpr_25
+80362F68:_savefpr_26
+80362F6C:_savefpr_27
+80362F70:_savefpr_28
+80362F74:_savefpr_29
+80362F78:_savefpr_30
+80362F7C:_savefpr_31
+80362FD0:_savegpr_14
+80362FD4:_savegpr_15
+80362FD8:_savegpr_16
+80362FDC:_savegpr_17
+80362FE0:_savegpr_18
+80362FE4:_savegpr_19
+80362FE8:_savegpr_20
+80362FEC:_savegpr_21
+80362FF0:_savegpr_22
+80362FF4:_savegpr_23
+80362FF8:_savegpr_24
+80362FFC:_savegpr_25
+80363000:_savegpr_26
+80363004:_savegpr_27
+80363008:_savegpr_28
+8036300C:_savegpr_29
+80363010:_savegpr_30
+80363014:_savegpr_31
+8036328C:__umoddi3
+
+// mem.o
+80366EBC:memcmp
+
+// printf.o
+8036730C:sprintf
+803673EC:snprintf
+
+// string.o
+803697C4:strcmp
+8036995C:strcpy
+80369918:strncpy
+
+//currentState
+803A8393:current_state
+
+// m_Do_controller_pad.o
+// data
+803DF288:cpadInfo
+
+// d_com_inf_game.o
+// data
+80408160:dComIfG_gameInfo
+8002B414:setItemBombNumCount
+
+// d_kankyo.o
+// data
+8042EA14:env_light
+
+// JFWSystem.o
+// data
+80453180:systemConsole
+
+//currentState
+803A8393:current_state
+
+//canWarp
+80408956:can_warp
diff --git a/source/include/tp.jp.lst b/source/include/tp.jp.lst
new file mode 100644
index 0000000..03875f5
--- /dev/null
+++ b/source/include/tp.jp.lst
@@ -0,0 +1,170 @@
+// memory
+80003458:memset
+80003540:memcpy
+
+// m_Do_ext.o
+// text
+8000EDF4:getArchiveHeapPtr
+// data
+8044AD74:archiveHeap
+
+// d_save.o
+80032AA8:getRupeeMax
+800350BC:getSave
+800350F0:putSave
+
+// d_stage.o
+8002586C:actorCommonLayerInit
+// data
+803F01D4:mStatus_roomControl
+
+// d_event.o
+80042778:defaultSkipStb
+800429D4:skipper
+
+// f_op_scene_req.o
+// data
+8044A754:freezeActors
+8044AE20:isUsingOfOverlap
+
+// f_ap_game.o
+80018A6C:fapGm_Execute
+
+// f_op_actor_mng.o
+8001BBE8:createItemForPresentDemo
+8001BC74:createItemForTrBoxDemo
+8001c078:createDemoItem
+8001C0D4:createItemForBoss
+8001C174:createItemForMidBoss
+8001C1B8:createItemForDirectGet
+8001C1FC:createItemForSimpleDemo
+
+// d_map_path_dmap.o
+8003EE5C:getMapPlayerPos
+8003EF20:getMapPlayerAngleY
+
+// d_item.o
+80097ECC:execItemGet
+80097F20:checkItemGet
+800982F4:item_func_UTUWA_HEART
+
+// d_a_alink.h
+8009DA98:checkStageName
+800B2754:setStickData
+800BB4F0:checkHeavyStateOn
+800C782C:procCoMetamorphoseInit
+8011A734:checkTreasureRupeeReturn
+803D6F94:linkStatus
+// data
+80388C0C:ladderVars
+
+// d_menu_collect.o
+801B3300:setWalletMaxNum
+
+// d_msg_flow.o
+8024D24C:query022
+
+// DynamicLink.o
+8026508C:do_link
+
+// JKRExpHeap.o
+802D15C4:do_alloc_JKRExpHeap
+802D1C48:do_free_JKRExpHeap
+
+// OSCache.o
+// 8033DA08:DCEnable
+// 8033DA1C:DCInvalidateRange
+8033DA48:DCFlushRange
+// 8033DA78:DCStoreRange
+// 8033DAA8:DCFlushRangeNoSync
+// 8033DAD4:DCStoreRangeNoSync
+// 8033DB00:DCZeroRange
+8033DB2C:ICInvalidateRange
+// 8033DB60:ICFlashInvalidate
+// 8033DB70:ICEnable
+// 8033DB84:__LCEnable
+// 8033DC50:LCEnable
+// 8033DC88:LCDisable
+// 8033DCB0:LCStoreBlocks
+// 8033DCD4:LCStoreData
+// 8033DD80:LCQueueWait
+// 8033DD94:L2GlobalInvalidate
+// 8033DE2C:DMAErrorHandler
+// 8033DF8C:__OSCacheInit
+
+// runtime.o
+803645A4:_savefpr_14
+803645A8:_savefpr_15
+803645AC:_savefpr_16
+803645B0:_savefpr_17
+803645B4:_savefpr_18
+803645B8:_savefpr_19
+803645BC:_savefpr_20
+803645C0:_savefpr_21
+803645C4:_savefpr_22
+803645C8:_savefpr_23
+803645CC:_savefpr_24
+803645D0:_savefpr_25
+803645D4:_savefpr_26
+803645D8:_savefpr_27
+803645DC:_savefpr_28
+803645E0:_savefpr_29
+803645E4:_savefpr_30
+803645E8:_savefpr_31
+8036463C:_savegpr_14
+80364640:_savegpr_15
+80364644:_savegpr_16
+80364648:_savegpr_17
+8036464C:_savegpr_18
+80364650:_savegpr_19
+80364654:_savegpr_20
+80364658:_savegpr_21
+8036465C:_savegpr_22
+80364660:_savegpr_23
+80364664:_savegpr_24
+80364668:_savegpr_25
+8036466C:_savegpr_26
+80364670:_savegpr_27
+80364674:_savegpr_28
+80364678:_savegpr_29
+8036467C:_savegpr_30
+80364680:_savegpr_31
+803648F8:__umoddi3
+
+// mem.o
+80368528:memcmp
+
+// printf.o
+80368978:sprintf
+80368A58:snprintf
+
+// string.o
+8036AE30:strcmp
+8036AFC8:strcpy
+8036AF84:strncpy
+
+//currentState
+803B8000:current_state
+
+// m_Do_controller_pad.o
+// data
+803D7428:cpadInfo
+
+// d_com_inf_game.o
+// data
+80400300:dComIfG_gameInfo
+8002B36C:setItemBombNumCount
+
+// d_kankyo.o
+// data
+80426B94:env_light
+
+// JFWSystem.o
+// data
+8044B2F8:systemConsole
+
+//currentState
+803B8000:current_state
+
+//canWarp
+80400AF6:can_warp \ No newline at end of file
diff --git a/source/include/tp.us.lst b/source/include/tp.us.lst
new file mode 100644
index 0000000..2827ba9
--- /dev/null
+++ b/source/include/tp.us.lst
@@ -0,0 +1,179 @@
+// memory
+80003458:memset
+80003540:memcpy
+
+// m_Do_ext.o
+// text
+8000EDF4:getArchiveHeapPtr
+// data
+80450C34:archiveHeap
+
+// d_save.o
+80032AA8:getRupeeMax
+800350BC:getSave
+800350F0:putSave
+
+// d_stage.o
+8002586C:actorCommonLayerInit
+// data
+803F6094:mStatus_roomControl
+
+// d_event.o
+80042778:defaultSkipStb
+800429D4:skipper
+
+// f_op_scene_req.o
+// data
+80450614:freezeActors
+80450CE0:isUsingOfOverlap
+
+// f_ap_game.o
+80018A6C:fapGm_Execute
+
+// f_op_actor_mng.o
+8001BBE8:createItemForPresentDemo
+8001BC74:createItemForTrBoxDemo
+8001C078:createDemoItem
+8001C0D4:createItemForBoss
+8001C174:createItemForMidBoss
+8001C1B8:createItemForDirectGet
+8001C1FC:createItemForSimpleDemo
+
+// d_map_path_dmap.o
+8003EE5C:getMapPlayerPos
+8003EF20:getMapPlayerAngleY
+
+// d_item.o
+80097E8C:execItemGet
+80097EE0:checkItemGet
+800982B4:item_func_UTUWA_HEART
+
+// d_a_alink.h
+8009DA60:checkStageName
+800B271C:setStickData
+800BB4B8:checkHeavyStateOn
+800C77F4:procCoMetamorphoseInit
+8011A6FC:checkTreasureRupeeReturn
+803DCE54:linkStatus
+// data
+8038EB8C:ladderVars
+
+// d_menu_collect.o
+801B3340:setWalletMaxNum
+
+// d_msg_flow.o
+8024B8E4:query022
+
+// DynamicLink.o
+80262C5C:do_link
+
+// JKRExpHeap.o
+802CF128:do_alloc_JKRExpHeap
+802CF7AC:do_free_JKRExpHeap
+
+// OSCache.o
+// 8033B56C:DCEnable
+// 8033B580:DCInvalidateRange
+8033B5AC:DCFlushRange
+// 8033B5DC:DCStoreRange
+// 8033B60C:DCFlushRangeNoSync
+// 8033B638:DCStoreRangeNoSync
+// 8033B664:DCZeroRange
+8033B690:ICInvalidateRange
+// 8033B6C4:ICFlashInvalidate
+// 8033B6D4:ICEnable
+// 8033B6E8:__LCEnable
+// 8033B7B4:LCEnable
+// 8033B7EC:LCDisable
+// 8033B814:LCStoreBlocks
+// 8033B838:LCStoreData
+// 8033B8E4:LCQueueWait
+// 8033B8F8:L2GlobalInvalidate
+// 8033B990:DMAErrorHandler
+// 8033BAF0:__OSCacheInit
+
+// runtime.o
+80362108:_savefpr_14
+8036210C:_savefpr_15
+80362110:_savefpr_16
+80362114:_savefpr_17
+80362118:_savefpr_18
+8036211C:_savefpr_19
+80362120:_savefpr_20
+80362124:_savefpr_21
+80362128:_savefpr_22
+8036212C:_savefpr_23
+80362130:_savefpr_24
+80362134:_savefpr_25
+80362138:_savefpr_26
+8036213C:_savefpr_27
+80362140:_savefpr_28
+80362144:_savefpr_29
+80362148:_savefpr_30
+8036214C:_savefpr_31
+803621A0:_savegpr_14
+803621A4:_savegpr_15
+803621A8:_savegpr_16
+803621AC:_savegpr_17
+803621B0:_savegpr_18
+803621B4:_savegpr_19
+803621B8:_savegpr_20
+803621BC:_savegpr_21
+803621C0:_savegpr_22
+803621C4:_savegpr_23
+803621C8:_savegpr_24
+803621CC:_savegpr_25
+803621D0:_savegpr_26
+803621D4:_savegpr_27
+803621D8:_savegpr_28
+803621DC:_savegpr_29
+803621E0:_savegpr_30
+803621E4:_savegpr_31
+8036245C:__umoddi3
+
+// mem.o
+8036608C:memcmp
+
+// printf.o
+803664DC:sprintf
+803665BC:snprintf
+
+// string.o
+80368994:strcmp
+80368B2C:strcpy
+80368AE8:strncpy
+
+//currentState
+803A66B3:current_state
+
+// m_Do_controller_pad.o
+// data
+803DD2E8:cpadInfo
+
+// d_com_inf_game.o
+// data
+804061C0:dComIfG_gameInfo
+8002B36C:setItemBombNumCount
+
+// d_kankyo.o
+// data
+8042CA54:env_light
+
+// JFWSystem.o
+// data
+804511B8:systemConsole
+
+//currentState
+803A66B3:current_state
+
+//walletText
+80bbc749:wallet_text
+
+//walletdescription
+80BBD835:wallet_description
+
+//canwarp
+804069B6:can_warp
+
+//resource.o
+802a9490:parseCharacter_1Byte \ No newline at end of file
diff --git a/source/include/tp/DynamicLink.h b/source/include/tp/DynamicLink.h
new file mode 100644
index 0000000..50ea632
--- /dev/null
+++ b/source/include/tp/DynamicLink.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "defines.h"
+
+#include <gc/OSModule.h>
+
+namespace tp::dynamic_link
+{
+ // Should try to fill in the variables at some point
+ struct DynamicModuleControl
+ {
+ u8 unk_0[0x10];
+ gc::OSModule::OSModuleInfo* moduleInfo;
+ u8 unk_10[0x18];
+ } __attribute__((__packed__));
+
+ // This size may not be correct
+ static_assert(sizeof(DynamicModuleControl) == 0x2C);
+
+ extern "C"
+ {
+ bool do_link(DynamicModuleControl* dmc);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/JFWSystem.h b/source/include/tp/JFWSystem.h
new file mode 100644
index 0000000..59add62
--- /dev/null
+++ b/source/include/tp/JFWSystem.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::jfw_system
+{
+ struct ConsoleLine
+ {
+ bool showLine;
+ char line[61];
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+ // Need to also get the exact size of this struct
+ struct SystemConsole
+ {
+ u8 unk_0[0x60];
+ u8 consoleColor[4]; // rgba
+ u8 unk_64[0x4];
+ bool consoleEnabled;
+ u8 unk_69[3];
+ ConsoleLine consoleLine[25]; // Should figure out the total amount of lines at some point
+ } __attribute__((__packed__));
+
+ static_assert(sizeof(ConsoleLine) == 0x3E);
+
+ extern "C"
+ {
+ extern SystemConsole* systemConsole;
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/JKRExpHeap.h b/source/include/tp/JKRExpHeap.h
new file mode 100644
index 0000000..60afb7c
--- /dev/null
+++ b/source/include/tp/JKRExpHeap.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::jkr_exp_heap
+{
+ extern "C"
+ {
+ void* do_alloc_JKRExpHeap(void* heap, u32 size, s32 unk3);
+ void do_free_JKRExpHeap(void* heap, void* ptr);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_a_alink.h b/source/include/tp/d_a_alink.h
new file mode 100644
index 0000000..7f687ad
--- /dev/null
+++ b/source/include/tp/d_a_alink.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "defines.h"
+#include "d_com_inf_game.h"
+
+namespace tp::d_a_alink
+{
+ // Should try to fill in the variables at some point
+ struct LadderVars
+ {
+ u8 unk_0[0x28];
+ float ladderClimbInitSpeed;
+ u8 unk_2c[0x4];
+ float ladderReachTopClimbUpSpeed;
+ u8 unk_30[0x4];
+ float ladderTopStartClimbDownSpeed;
+ u8 unk_34[0x4];
+ float ladderBottomGetOffSpeed;
+ u8 unk_38[0x8];
+ float ladderClimbSpeed;
+ u8 unk_40[0x10];
+ float wallClimbHorizontalSpeed;
+ u8 unk_58[0x4];
+ float wallClimbVerticalSpeed;
+ u8 unk_5c[0x4];
+ } __attribute__((__packed__));
+
+
+ static_assert(sizeof(LadderVars) == 0x70);
+
+ struct LinkStatus
+ {
+ u8 unk_0[0xA2];
+ u8 status;
+ } __attribute__((__packed__));
+
+ extern "C"
+ {
+ bool checkStageName(const char* name); // Checks if dComIfG_gameInfo.currentStage is equal to name
+ void setStickData();
+ bool checkHeavyStateOn(s32 unk1, s32 unk2);
+ bool procCoMetamorphoseInit(tp::d_com_inf_game::LinkMapVars* linkMapPtr);
+ bool checkTreasureRupeeReturn(void* unk1, s32 item);
+
+ // Variables
+ extern LadderVars ladderVars;
+ extern LinkStatus* linkStatus;
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_com_inf_game.h b/source/include/tp/d_com_inf_game.h
new file mode 100644
index 0000000..59e3ec2
--- /dev/null
+++ b/source/include/tp/d_com_inf_game.h
@@ -0,0 +1,954 @@
+#pragma once
+
+#include "defines.h"
+
+#include <tp/evt_control.h>
+
+namespace tp::d_com_inf_game
+{
+ enum class ItemFlagBits : u32
+ {
+ Recovery_Heart = 0,
+ Green_Rupee = 1,
+ Blue_Rupee = 2,
+ Yellow_Rupee = 3,
+ Red_Rupee = 4,
+ Purple_Rupee = 5,
+ Orange_Rupee = 6,
+ Silver_Rupee = 7,
+
+ Null_8 = 8,
+ Null_9 = 9,
+ Bombs_5 = 10,
+ Bombs_10 = 11,
+ Bombs_20 = 12,
+ Bombs_30 = 13,
+ Arrows_10 = 14,
+ Arrows_20 = 15,
+
+ Arrows_30 = 16,
+ Arrows_1 = 17,
+ Seeds_50 = 18,
+ Null_13 = 19,
+ Null_14 = 20,
+ Null_15 = 21,
+ Water_Bombs_5 = 22,
+ Water_Bombs_10 = 23,
+
+ Water_Bombs_15 = 24,
+ Water_Bombs_3 = 25,
+ Bomblings_5 = 26,
+ Bomblings_10 = 27,
+ Bomblings_3 = 28,
+ Bombling_1 = 29,
+ Fairy = 30,
+ Recovery_Heart_x3 = 31,
+
+ Small_Key = 32,
+ Piece_of_Heart = 33,
+ Heart_Container = 34,
+ Dungeon_Map = 35,
+ Compass = 36,
+ Ooccoo_FT = 37,
+ Big_Key = 38,
+ Ooccoo_Jr = 39,//never set in normal game
+
+ Ordon_Sword = 40,
+ Master_Sword = 41,
+ Ordon_Shield = 42,
+ Wooden_Shield = 43,
+ Hylian_Shield = 44,
+ Ooccoos_Note = 45,//never set in normal game
+ Ordon_Clothing = 46,//never set in normal game
+ Heros_Clothes = 47,
+
+ Magic_Armor = 48,
+ Zora_Armor = 49,
+ Shadow_Crystal = 50,//never set in normal game
+ Ooccoo_Dungeon = 51,
+ Small_Wallet = 52,//never set in normal game
+ Big_Wallet = 53,
+ Giant_Wallet = 54,
+ Null_37 = 55,
+
+ Null_38 = 56,
+ Null_39 = 57,
+ Null_3A = 58,
+ Null_3B = 59,
+ Null_3C = 60,
+ Coral_Earring = 61,
+ Hawkeye = 62,
+ Wooden_Sword = 63,
+
+ Boomerang = 64,
+ Spinner = 65,
+ Ball_and_Chain = 66,
+ Heros_Bow = 67,
+ Clawshot = 68,
+ Iron_Boots = 69,
+ Dominion_Rod = 70,
+ Clawshots = 71,
+
+ Lantern = 72,
+ Master_Sword_Light = 73,
+ Fishing_Rod = 74,
+ Slingshot = 75,
+ Dominion_Rod_Uncharged = 76,//never set in normal game
+ Null_4D = 77,
+ Null_4E = 78,
+ Giant_Bomb_Bag = 79,
+
+ Empty_Bomb_Bag = 80,//never set in normal game
+ Goron_Bomb_Bag = 81,
+ Null_52 = 82,
+ Null_53 = 83,
+ Small_Quiver = 84,//never set in normal game
+ Big_Quiver = 85,
+ Giant_Quiver = 86,
+ Null_57 = 87,
+
+ Fishing_Rod_Lure = 88,
+ Bow_Bombs = 89,
+ Bow_Hawkeye = 90,
+ Fishing_Rod_Bee_Larva = 91,
+ Fishing_Rod_Coral_Earring = 92,
+ Fishing_Rod_Worm = 93,
+ Fishing_Rod_Earring_Bee_Larva = 94,
+ Fishing_Rod_Earring_Worm = 95,
+
+ Empty_Bottle = 96,
+ Red_Potion_Shop = 97,
+ Green_Potion = 98,
+ Blue_Potion = 99,
+ Milk = 100,
+ Sera_Bottle = 101,
+ Lantern_Oil_Shop = 102,
+ Water = 103,
+
+ Lantern_Oil_Scooped = 104,
+ Red_Potion_Scooped = 105,
+ Nasty_soup = 106,
+ Hot_spring_water_Scooped = 107,
+ Fairy_Bottle = 108,
+ Hot_Spring_Water_Shop = 109,
+ Lantern_Refill_Scooped = 110,
+ Lantern_Refill_Shop = 111,
+
+ Bomb_Bag_Regular_Bombs = 112,
+ Bomb_Bag_Water_Bombs = 113,
+ Bomb_Bag_Bomblings = 114,
+ Fairy_Tears = 115,
+ Worm = 116,
+ Jovani_Bottle = 117,
+ Bee_Larva_Scooped = 118,
+ Rare_Chu_Jelly = 119,
+
+ Red_Chu_Jelly = 120,
+ Blue_Chu_Jelly = 121,
+ Green_Chu_Jelly = 122,
+ Yellow_Chu_Jelly = 123,
+ Purple_Chu_Jelly = 124,
+ Simple_Soup = 125,
+ Good_Soup = 126,
+ Superb_Soup = 127,
+
+ Renardos_Letter = 128,
+ Invoice = 129,
+ Wooden_Statue = 130,
+ Ilias_Charm = 131,
+ Horse_Call = 132,
+ Null_85 = 133,
+ Null_86 = 134,
+ Null_87 = 135,
+
+ Null_88 = 136,
+ Null_89 = 137,
+ Null_8A = 138,
+ Null_8B = 139,
+ Null_8C = 140,
+ Null_8D = 141,
+ Null_8E = 142,
+ Null_8F = 143,
+
+ Aurus_Memo = 144,
+ Asheis_Sketch = 145,
+ Null_92 = 146,
+ Null_93 = 147,
+ Null_94 = 148,
+ Null_95 = 149,
+ Null_96 = 150,
+ Null_97 = 151,
+
+ Null_98 = 152,
+ Null_99 = 153,
+ Null_9A = 154,
+ Null_9B = 155,
+ Lantern_Yellow_Chu_Chu = 156,
+ Coro_Bottle = 157,
+ Bee_Larva_Shop = 158,
+ Black_Chu_Jelly = 159,
+
+ Tear_Of_Light = 160,//never set in normal game
+ Vessel_Of_Light_Faron = 161,
+ Vessel_Of_Light_Eldin = 162,
+ Vessel_Of_Light_Lanayru = 163,
+ Vessel_Of_Light_Full = 164,//never set in normal game
+ Null_A5 = 165,
+ Null_A6 = 166,
+ Null_A7 = 167,
+
+ Null_A8 = 168,
+ Null_A9 = 169,
+ Null_AA = 170,
+ Null_AB = 171,
+ Null_AC = 172,
+ Null_AD = 173,
+ Null_AE = 174,
+ Null_AF = 175,
+
+ Ilias_Scent = 176,
+ Null_B1 = 177,
+ Poe_Scent = 178,
+ Reekfish_Scent = 179,
+ Youths_Scent = 180,
+ Medicine_Scent = 181,
+ Null_B6 = 182,
+ Null_B7 = 183,
+
+ Null_B8 = 184,
+ Null_B9 = 185,
+ Null_BA = 186,
+ Null_BB = 187,
+ Null_BC = 188,
+ Null_BD = 189,
+ Null_BE = 190,
+ Null_BF = 191,
+
+ Male_Beetle = 192,
+ Female_Beetle = 193,
+ Male_Butterfly = 194,
+ Female_Butterfly = 195,
+ Male_Stag_Beetle = 196,
+ Female_Stag_Beetle = 197,
+ Male_Grasshopper = 198,
+ Female_Grasshopper = 199,
+
+ Male_Phasmid = 200,
+ Female_Phasmid = 201,
+ Male_Pill_Bug = 202,
+ Female_Pill_Bug = 203,
+ Male_Mantis = 204,
+ Female_Mantis = 205,
+ Male_Ladybug = 206,
+ Female_Ladybug = 207,
+
+ Male_Snail = 208,
+ Female_Snail = 209,
+ Male_Dragonfly = 210,
+ Female_Dragonfly = 211,
+ Male_Ant = 212,
+ Female_Ant = 213,
+ Male_Dayfly = 214,
+ Female_Dayfly = 215,
+
+ 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_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
+ Null_DE = 222,//now used for sky letter 2
+ Null_DF = 223,//now used for sky letter 1
+
+ Poe_Soul = 224,
+ Null_E1 = 225,//now used for ending blow
+ Null_E2 = 226,//now used for shield bash
+ Null_E3 = 227,//now used for back slice
+ Null_E4 = 228,//now used for helm splitter
+ Null_E5 = 229,//now used for mortal draw
+ Null_E6 = 230,//now used for jump strike
+ Null_E7 = 231,//now used for great spin
+
+ Null_E8 = 232,
+ Ancient_Sky_Book_empty = 233,
+ Ancient_Sky_Book_partly_filled = 234,
+ Ancient_Sky_Book_completed = 235,
+ Ooccoo_CitS = 236,
+ Purple_Rupee_Links_house = 237,
+ Small_Key_N_Faron_Gate = 238,
+ Null_EF = 239,
+
+ Null_F0 = 240,
+ Null_F1 = 241,
+ Null_F2 = 242,
+ Gate_Keys = 243,
+ Ordon_Pumpkin = 244,
+ Ordon_Goat_Cheese = 245,
+ Bed_Key = 246,
+ Null_F7 = 247,
+
+ Got_Lantern_Back = 248,
+ Key_Shard_1 = 249,
+ Key_Shard_2 = 250,
+ Key_Shard_3 = 251,
+ Null_FC = 252,
+ Big_Key_Goron_Mines = 253,
+ Coro_Key = 254,
+ NullItem = 255,
+ };
+
+ struct Counters
+ {
+ u16 max_health;
+ u16 health;
+ u16 rupees;
+ u16 max_lantern_oil;//constant
+ u16 lantern_oil;//divide by max to get %
+
+ } __attribute__((__packed__));
+
+ struct EquipedItems
+ {
+ u8 unk;
+ u8 item_X;
+ u8 item_Y;
+ u8 item_unk3;
+ u8 item_unk4;
+ u8 item_combo_X;//bow goes here, bombs/hawkeye go in main slot
+ u8 item_combo_Y;//bow goes here, bombs/hawkeye go in main slot
+ u8 item_combo_unk3;//bow goes here, bombs/hawkeye go in main slot
+ u8 item_combo_unk4;//bow goes here, bombs/hawkeye go in main slot
+ u8 clothes;
+ u8 sword;
+ u8 shield;
+ u8 scent;
+
+ } __attribute__((__packed__));
+
+ struct ClearedTwilights
+ {
+ u8 unk_0 : 1,
+ unk_1 : 1,
+ unk_2 : 1,
+ unk_3 : 1,
+ unk_4 : 1,
+ Lanayru : 1,
+ Eldin : 1,
+ Faron : 1;
+
+ } __attribute__((__packed__));
+
+ struct Epona
+ {
+ float position_X;
+ float position_Y;
+ float position_Z;
+ u16 angle;
+ char stage[8];
+ u8 spawn;//unused
+ u8 room;
+ } __attribute__((__packed__));//size 0x18
+
+ struct Link
+ {
+ char stage[8];
+ u8 spawn;
+ u8 room;
+ u8 unk_62[0x2];
+ float previous_position_X;
+ float previous_position_Y;
+ float previous_position_Z;
+ u16 previous_angle;
+ char previous_stage[8];
+
+ } __attribute__((__packed__));//size 0x22
+
+ struct ExploredRegions
+ {
+ u8 unk_0 : 1,
+ Snowpeak : 1,
+ Desert : 1,
+ Lanayru : 1,
+ Eldin : 1,
+ Faron : 1,
+ Ordon : 1,
+ unk_8 : 1;
+
+ } __attribute__((__packed__));
+
+ struct Ooccoo
+ {
+ float position_X;
+ float position_Y;
+ float position_Z;
+ u16 angle;
+ char stage[8];// 7th byte will be 37 by default, rest 00. No clue why
+ u8 spawn;//unused
+ u8 room;
+ u8 dungeon;
+
+ } __attribute__((__packed__));//size 0x19
+
+ struct MovingActors
+ {
+ Epona epona;
+ Link link;
+ u8 unk_7A[0x3];
+ ExploredRegions exploredRegions;
+ u8 unk_7E[0x2];
+ Ooccoo ooccoo;
+
+ } __attribute__((__packed__));//size 0x59
+
+ struct ItemSlots
+ {
+ u8 Boomerang;
+ u8 Lantern;
+ u8 Spinner;
+ u8 Iron_Boots;
+ u8 Bow;
+ u8 Hawkeye;
+ u8 Ball_and_Chain;
+ u8 Item_Slot;
+ u8 Dominion_Rod;
+ u8 Clawshot;
+ u8 Double_Clawshot;
+ u8 Bottle_1;
+ u8 Bottle_2;
+ u8 Bottle_3;
+ u8 Bottle_4;
+ u8 Bomb_Bag_1;
+ u8 Bomb_Bag_2;
+ u8 Bomb_Bag_3;
+ u8 Ooccoo;
+ u8 Story;
+ u8 Fishing_Rod;
+ u8 Horse_Call;
+ u8 Sky_Book;
+ u8 Slingshot;
+ } __attribute__((__packed__));
+
+ struct Ammo
+ {
+ u8 arrows;
+ u8 bombs1;
+ u8 bombs2;
+ u8 bombs3;
+ u8 unk_F0;
+ u8 unk_F1;
+ u8 unk_F2;
+ u8 unk_F3;
+ u8 seeds;
+ u8 unk_F5;
+ u8 unk_F6;
+ u8 unk_F7;
+ u8 max_arrows;//30,60,100
+ u8 max_normal_bombs;//const (giant bomb bag just does this value x2)
+ u8 max_water_bombs;//const (giant bomb bag just does this value x2)
+ u8 max_bomblings;//const (giant bomb bag just does this value x2)
+
+ } __attribute__((__packed__));//size 0x10
+
+ struct DungeonRewards
+ {
+ u16 unk_0 : 1,
+ unk_1 : 1,
+ unk_2 : 1,
+ unk_3 : 1,
+ Palace_of_Twilight : 1,
+ Lakebed_Temple : 1,
+ Goron_Mines : 1,
+ Forest_Temple : 1,
+
+ unk_8 : 1,
+ unk_9 : 1,
+ unk_10 : 1,
+ unk_11 : 1,
+ City_in_the_Sky : 1,
+ Temple_of_Time : 1,
+ Snowpeak_Ruins : 1,
+ Arbiters_Grounds : 1;
+
+ } __attribute__((__packed__));
+
+ struct TearsOfLightCounters
+ {
+ u8 Faron;
+ u8 Eldin;
+ u8 Lanayru;
+
+ } __attribute__((__packed__));
+
+ struct Letters
+ {
+ u16 From_Wife_of_Yeto : 1,
+ Update : 1,
+ Now_open_for_business : 1,
+ Agithas_Dream : 1,
+ Hey_kid : 1,
+ Challenge_for_you : 1,
+ They_came_so_quickly : 1,
+ Heroes_come_together : 1,
+
+ URGENT_Bomb_arrows : 1,
+ Rare_item_in_stock : 1,
+ Good_stuff_inside : 1,
+ URGENT_NOTICE : 1,
+ Post_office_notice : 1,
+ Dear_Adventurer_1 : 1,
+ Dear_Adventurer_2 : 1,
+ About_Ilias_memory : 1;
+
+ } __attribute__((__packed__));
+
+ struct NumberOfFish
+ {
+ u16 Hyrule_Bass;
+ u16 Hylian_Loach;
+ u16 Hylian_Pike;
+ u16 Ordon_Catfish;
+ u16 Reekfish;
+ u16 Greengill;
+ } __attribute__((__packed__));
+
+ struct LargestFishes
+ {
+ u8 Hyrule_Bass;
+ u8 Hylian_Loach;
+ u8 Hylian_Pike;
+ u8 Ordon_Catfish;
+ u8 Reekfish;
+ u8 Greengill;
+ } __attribute__((__packed__));
+
+ struct FishingJournal
+ {
+ NumberOfFish numbers;//size 0xC
+ u8 unk_178[0x14];//offset 0xC
+ LargestFishes largest;//size 0x6 offset 0x20
+
+ } __attribute__((__packed__));
+
+ struct Settings
+ {
+ u8 sound;// Mono=0 / Stereo = 1 / Surround = 2
+ u8 targettingType;// Hold = 0 / Switch = 1
+ u8 rumble;// Off = 0 / On = 1
+
+ } __attribute__((__packed__));
+
+ struct DungeonFlags
+ {
+ u8 miniBossBeaten : 1,
+ ooccooGotten : 1,
+ bitSix : 1,
+ containerGotten : 1,
+ bossBeaten : 1,
+ bigKeyGotten : 1,
+ compassGotten : 1,
+ mapGotten : 1;
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+ struct AreaNodes
+ {
+ u8 unk_0[0x1C];
+ u8 nbKeys;
+ DungeonFlags dungeon;
+ u8 unk_1E[0x2];
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+ struct AllAreaNodes
+ {
+ AreaNodes Ordon;//00
+ AreaNodes Sewers;//20
+ AreaNodes Faron;//40
+ AreaNodes Eldin;//60
+ AreaNodes Lanayru;//80
+ AreaNodes Null_5;//A0
+ AreaNodes Hyrule_Field;//C0
+ AreaNodes Sacred_Grove;//E0
+ AreaNodes Snowpeak;//100
+ AreaNodes Castle_Town;//120
+ AreaNodes Gerudo_Desert;//140
+ AreaNodes Fishing_Pond;//160
+ AreaNodes Null_C;
+ AreaNodes Null_D;
+ AreaNodes Null_E;
+ AreaNodes Null_F;
+ AreaNodes Forest_Temple;
+ AreaNodes Goron_Mines;
+ AreaNodes Lakebed_Temple;
+ AreaNodes Arbiters_Grounds;
+ AreaNodes Snowpeak_Ruins;
+ AreaNodes Temple_of_Time;
+ AreaNodes City_in_the_Sky;
+ AreaNodes Palace_of_Twilight;
+ AreaNodes Hyrule_Castle;
+ AreaNodes Cave_of_Ordeals;//includes Gorge Cave and Ice Block Cave
+ AreaNodes Lake_Hylia_Cave;//includes Goron Stockcave
+ AreaNodes Grottos;
+ AreaNodes Null_1C;
+ AreaNodes Null_1D;
+ AreaNodes Null_1E;
+ AreaNodes Null_1F;
+ } __attribute__((__packed__));
+
+ struct StageRooms
+ {
+ u64 room_31 : 1,
+ room_30 : 1,
+ room_29 : 1,
+ room_28 : 1,
+ room_27 : 1,
+ room_26 : 1,
+ room_25 : 1,
+ room_24 : 1,
+
+ room_23 : 1,
+ room_22 : 1,
+ room_21 : 1,
+ room_20 : 1,
+ room_19 : 1,
+ room_18 : 1,
+ room_17 : 1,
+ room_16 : 1,
+
+ room_15 : 1,
+ room_14 : 1,
+ room_13 : 1,
+ room_12 : 1,
+ room_11 : 1,
+ room_10 : 1,
+ room_09 : 1,
+ room_08 : 1,
+
+ room_07 : 1,
+ room_06 : 1,
+ room_05 : 1,
+ room_04 : 1,
+ room_03 : 1,
+ room_02 : 1,
+ room_01 : 1,
+ room_00 : 1,
+
+ room_63 : 1,
+ room_62 : 1,
+ room_61 : 1,
+ room_60 : 1,
+ room_59 : 1,
+ room_58 : 1,
+ room_57 : 1,
+ room_56 : 1,
+
+ room_55 : 1,
+ room_54 : 1,
+ room_53 : 1,
+ room_52 : 1,
+ room_51 : 1,
+ room_50 : 1,
+ room_49 : 1,
+ room_48 : 1,
+
+ room_47 : 1,
+ room_46 : 1,
+ room_45 : 1,
+ room_44 : 1,
+ room_43 : 1,
+ room_42 : 1,
+ room_41 : 1,
+ room_40 : 1,
+
+ room_39 : 1,
+ room_38 : 1,
+ room_37 : 1,
+ room_36 : 1,
+ room_35 : 1,
+ room_34 : 1,
+ room_33 : 1,
+ room_32 : 1;
+
+ } __attribute__((__packed__));
+
+ struct ExploredStagesMap
+ {
+ StageRooms F_SP00;
+ StageRooms F_SP103;
+ StageRooms F_SP104;
+ StageRooms R_SP01;
+ StageRooms unk_4;
+ StageRooms R_SP107;
+ StageRooms F_SP108;
+ StageRooms R_SP108;
+ StageRooms F_SP117;
+ StageRooms F_SP109;
+ StageRooms F_SP110;
+ StageRooms F_SP111;
+ StageRooms R_SP109_R_SP209;
+ StageRooms F_SP112_F_SP126;
+ StageRooms F_SP113;
+ StageRooms F_SP114;
+ StageRooms F_SP115;
+ StageRooms F_SP116;
+ StageRooms F_SP118_F_SP124_F_SP125;
+ StageRooms unk_19;
+ StageRooms unk_20;
+ StageRooms F_SP121_F_SP122;
+ StageRooms D_MN05;
+ StageRooms D_MN04;
+ StageRooms D_MN01;
+ StageRooms D_MN10;
+ StageRooms D_MN11;
+ StageRooms D_MN06;
+ StageRooms D_MN07;
+ StageRooms D_MN08;
+ StageRooms D_MN09;
+ StageRooms R_SP110;
+ StageRooms R_SP116_R_SP161;
+ StageRooms F_SP127;
+ StageRooms F_SP128;
+ StageRooms R_SP128;
+ StageRooms R_SP300;
+ StageRooms R_SP301;
+ StageRooms F_SP200;
+ StageRooms R_SP127;
+ StageRooms D_SB00;
+ StageRooms D_SB01;
+ StageRooms D_SB02;
+ StageRooms D_SB03;
+ StageRooms D_SB04;
+ StageRooms D_SB05_6_7_8_9;
+ StageRooms unk_46;
+ StageRooms unk_47;
+ StageRooms unk_48;
+ StageRooms unk_49;
+ StageRooms D_SB10;
+ StageRooms unk_51;
+ StageRooms unk_52;
+ StageRooms unk_53;
+ StageRooms unk_54;
+ StageRooms unk_55;
+ StageRooms unk_56;
+ StageRooms unk_57;
+ StageRooms unk_58;
+ StageRooms unk_59;
+ StageRooms unk_60;
+ StageRooms unk_61;
+ StageRooms unk_62;
+ StageRooms unk_63;
+
+ } __attribute__((__packed__));
+
+ // Should try to fill in the variables at some point
+ struct ScratchPad
+ {
+ Counters counters;//size: 0xA offset: 0x0
+ EquipedItems equipedItems;//size: 0xD offset: 0xA
+ u8 unk_17[0x2];//offset: 0x17
+ u8 equippedWallet;//offset: 0x19 (0 = small, 1 = big, 2 = giant)
+ u8 unk_1A[0x4];//offset: 0x1A
+ u8 form;//offset: 0x1E (0 = human, 1 = wolf)
+ u8 unk_1F[0x12];//offset: 0x1F
+ ClearedTwilights clearedTwilights;//offset: 0x31
+ u8 unk_32[0x2];//offset: 0x32
+ float skyAngle;//offset: 0x34 Impacts time of day poes and towns
+ u8 unk_38[0x8];//offset: 0x38
+ MovingActors movingActors;//size:0x59 offset: 0x40
+ u8 unk_99[0x3];//offset: 0x99
+ ItemSlots itemWheel;//size:0x18 offset 0x9C
+ u8 itemSlotsOrder[0x18];//offset 0xB4
+ u32 itemFlags[8];//size:0x20 offset 0xCC
+ Ammo ammo;//size:0x10 offset: 0xEC
+ u8 unk_FC[0xD];//offset 0xFC
+ DungeonRewards dungeonRewards;//size: 0x2 offset: 0x109
+ u8 unk_10B;
+ u8 poeCount;//offset 0x10C
+ u8 unk_10D[0x7];//offset 0x10D
+ TearsOfLightCounters tearCounters;//size 0x3 offset: 0x114
+ u8 unk_115[0x7];//offset: 0x115
+ Letters recivedLetters;//size: 0x2 offset: 0x11E
+ u8 unk_120[0x6];//offset: 0x120
+ Letters readLetters;//size: 0x2 offset: 0x126
+ u8 unk_128[0x44];//offset 0x128
+ FishingJournal fishingJournal; //size: 0x26 offset: 0x16C
+ u8 unk_192[0x22];//offset 0x192
+ char linkName[16];//offset 0x1B4
+ u8 unk_1C4;
+ char eponaName[16];//offset 0x1C5
+ u8 unk_1D5[0xC];//offset 0x1D5
+ Settings optionsSettings;//size: 0x3 offset 0x1E1
+ u8 unk_1E4[0xC];//offset 1E4
+ AllAreaNodes allAreaNodes;//size: 0x400 offset 0x1F0
+ ExploredStagesMap exploredMap;//size: 0x200 offset 0x5F0
+ u8 eventBits[0x150]; // Bitfield (QuestLogOffset - 7F0)
+ u8 miniGameBits[0x18]; // Bitfield
+ } __attribute__((__packed__));
+
+ struct RespawnValues
+ {
+ u8 room;//0xDB4
+ u8 unk_DB5[0x5];//0xDB5
+ u8 spawnPoint;//0xDB9
+ u16 angle;//0xDBA
+ float position_X;//0xDBC
+ float position_Y;//0xDC0
+ float position_Z;//0xDC4
+ u8 respawnCutscene; //0xDC8
+ u8 unk_DC9[0x7];//0xDC9
+ u8 lastItem;//0xDD0
+ u8 voidedAsWolf;//0xDD1
+ u8 unk_DD2;//0xDD2
+ u8 respawnAnimation;//0xDD3
+
+ } __attribute__((__packed__));
+
+
+ // Should try to fill in the missing variables at some point
+ // Need to also get the exact size of this struct
+ struct CurrentStageVars
+ {
+ char currentStage[8];
+ s16 currentSpawnPoint;
+ u8 unknown[4];
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+ // Need to also get the exact size of this struct
+ struct NextStageVars
+ {
+ char nextStage[8];
+ u8 isVoidorWarp;
+ u8 nextSpawnPoint;
+ u8 nextRoom;
+ u8 nextState;
+ u8 unk1;
+ u8 unk2;
+ u8 triggerLoad;
+ u8 fadeType;
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+
+ struct EventSystem
+ {
+ u8 unk00[0x13]; // 4ec8 - 4eda
+ u16 immediateControl; // 4edb - 4edc
+ u8 unk_00[0x4]; // 4edd - 4EE0
+ u8 nextEventID; // 4EE1
+ u8 unk1A[0xCB];
+ u8 eventFlag;
+ u8 unkE7[0x5];
+ u8 currentEventID;
+ u8 unk_ec[0x14];
+ tp::evt_control::csFunc* onSkip; // if != 0 the function stored here will run, otherwise unskippable
+ u8 unk_104[0xC];
+ u32 fadeOnSkip; // if != 0 this will fade out the screen when skipping
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+ // Need to also get the exact size of this struct
+ struct LinkMapVars
+ {
+ u8 unk_0[0x4D0];
+ float pos[3];
+ u8 unk_4DC[0x94];
+ u32 isTargeting;//570 at 0x400000 link is targeting
+ } __attribute__((__packed__));
+
+ struct TunicColor
+ {
+ u8 unk_0[0x32A0];
+ u8 redTopToggle;//0x4 disables red
+ u8 redTop;
+ u8 greenTopToggle;//0x4 disables green
+ u8 greenTop;
+ u8 blueTopToggle;//0x4 disables blue
+ u8 blueTop;
+ u8 unk_32A6[0x2];
+ u8 redBottomToggle;//0x4 disables red
+ u8 redBottom;
+ u8 greenBottomToggle;//0x4 disables green
+ u8 greenBottom;
+ u8 blueBottomToggle;//0x4 disables blue
+ u8 blueBottom;
+ } __attribute__((__packed__));
+
+ // Should try to fill in the missing variables at some point
+ struct GameInfo
+ {
+ ScratchPad scratchPad; // 0 - 957
+ AreaNodes localAreaNodes; // 958 - 978 holds flags about the current area
+ u8 unk_979[0x43B]; // 979 - DB3
+ RespawnValues respawnValues;// DB4 - DD3
+ u8 unkdd4[0x402C]; // dd4 - 4DFF
+ char currentStage[8]; // 4E00 - 4E07
+ u8 unk_4e08; // 4E08
+ u8 currentSpawnID;// 4E09
+ u8 unk_4e0A[4]; // 4E0A - 4E0D
+ NextStageVars nextStageVars; // 4E0E - 4E1D
+ u8 unk_4e1E[0xAA]; // 4E1E - 4EC7
+ EventSystem eventSystem; // 4EC8 - 4FDB
+ u8 unk_4fdc[0xDD0]; // 4FDC - 5DAB
+ LinkMapVars* linkMapPtr; // 5DAC - 5DAF
+ u8 unk_5db0[0x4];
+ TunicColor* ColorPtr;// 5DB4 - 5DB7
+ u8 unk_5db8[0x2A];//5DB8 - 5DE1
+ u16 airMeter; //5DE2 - 5DE3 max = 258
+ u8 unk_5de4[0x38];//5DE4 - 5E1B
+ u8 rButtonText;//5E1C - 51EC
+ u8 bButtonText;//5E1D - 51ED
+ u8 unk_5E1E[0x6];//5E1E - 5E23
+ u8 aButtonText; //5E24 - 5E24
+ u8 unk_5e25;//5E25 - 5E25
+ u8 stickButtonText;//5E26 - 5E26
+ u8 unk_5e27[0xB];//5E27 - 5E5B
+ u8 startButtonText;//5E32 - 5E32
+ u8 unk_5e33[0xC];//5E33 - 5E3E
+ u8 cButtonText;//5E3F - 5E3F
+ u8 unk_5e40[0x1C];//5E40 - 5E5B
+ u8 xButtonText;//5E5C - 5E5C set to sense and doesn't unset
+ u8 unk_5e5D[0x3];//5E5D - 5E5F
+ u8 yButtonText;//5E60 - 5E60 set to dig and doesn't unset
+ u8 unk_5e61[0xB];//5E61 - 5E6B
+ u8 xItem;//5E6C - 5E6C
+ u8 yItem;//5E6D - 5E6D
+ u8 unk_5E6E[0x22];//5E6E - 5E8F
+ u8 bottomPromptShown;//5E90 set to 0x8 when button promt apprears on bottom of screen
+ u8 topPromptShown;//5E91 set to 0x8 when button promt apprears on top of screen
+ u8 unk_5e92[0x25];//5E92 - 5EB6
+ u8 airTimerDepleted; //5EB7 - 5EB7
+ u8 unk_5eb8[0x17F58];
+
+
+ } __attribute__((__packed__));
+
+ static_assert(sizeof(AreaNodes) == 0x20);
+ static_assert(sizeof(ScratchPad) == 0x958);
+ static_assert(sizeof(GameInfo) == 0x1DE10);
+ static_assert(sizeof(DungeonFlags) == 0x1);
+ static_assert(sizeof(FishingJournal) == 0x26);
+ static_assert(sizeof(ExploredStagesMap) == 0x200);
+ static_assert(sizeof(Epona) == 0x18);
+ static_assert(sizeof(Link) == 0x22);
+ static_assert(sizeof(Ooccoo) == 0x19);
+ static_assert(sizeof(MovingActors) == 0x59);
+ static_assert(sizeof(Ammo) == 0x10);
+ static_assert(sizeof(RespawnValues) == 0x21);
+ static_assert(sizeof(LinkMapVars*) == 0x4);
+ static_assert(sizeof(EventSystem) == 0x114);
+ static_assert(sizeof(NextStageVars) == 0x10);
+
+
+ extern "C"
+ {
+ extern GameInfo dComIfG_gameInfo;
+ extern u8 current_state;
+ extern void setItemBombNumCount(u32 unk1, u8 bagNb, short amout);//amount will be the og (ex: if you can only have 5 more bombs and buy 10, it'll still ahow 10)
+ extern u8 next_state;
+ //extern char wallet_text[13];
+ //extern char wallet_description[96];
+ extern u8 can_warp;
+
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_item.h b/source/include/tp/d_item.h
new file mode 100644
index 0000000..030b210
--- /dev/null
+++ b/source/include/tp/d_item.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::d_item
+{
+ extern "C"
+ {
+ s32 execItemGet(u8 item);
+ s32 checkItemGet(u8 item, s32 defaultValue);
+ void item_func_UTUWA_HEART();
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_kankyo.h b/source/include/tp/d_kankyo.h
new file mode 100644
index 0000000..4121959
--- /dev/null
+++ b/source/include/tp/d_kankyo.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::d_kankyo
+{
+ // Should try to fill in the missing variables at some point
+ struct EnvLight
+ {
+ u8 unk_0[0x98C];
+ u8 currentRoom;
+ u8 unk_98d[0x983];
+ } __attribute__((__packed__));
+
+ static_assert(sizeof(EnvLight) == 0x1310);
+
+ extern "C"
+ {
+ extern EnvLight env_light;
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_map_path_dmap.h b/source/include/tp/d_map_path_dmap.h
new file mode 100644
index 0000000..779a94f
--- /dev/null
+++ b/source/include/tp/d_map_path_dmap.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::d_map_path_dmap
+{
+ extern "C"
+ {
+ void getMapPlayerPos(float posOut[3]);
+ u32 getMapPlayerAngleY();
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_menu_collect.h b/source/include/tp/d_menu_collect.h
new file mode 100644
index 0000000..8768ac4
--- /dev/null
+++ b/source/include/tp/d_menu_collect.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::d_menu_collect
+{
+ extern "C"
+ {
+ void setWalletMaxNum();
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_msg_flow.h b/source/include/tp/d_msg_flow.h
new file mode 100644
index 0000000..9a3c4f3
--- /dev/null
+++ b/source/include/tp/d_msg_flow.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::d_msg_flow
+{
+ extern "C"
+ {
+ bool query022(void* unk1, void* unk2, s32 unk3);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_save.h b/source/include/tp/d_save.h
new file mode 100644
index 0000000..132a564
--- /dev/null
+++ b/source/include/tp/d_save.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "defines.h"
+#include <tp/d_com_inf_game.h>
+
+namespace tp::d_save
+{
+ extern "C"
+ {
+ u16 getRupeeMax();
+ void getSave(tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID);
+ void putSave(tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/d_stage.h b/source/include/tp/d_stage.h
new file mode 100644
index 0000000..a7a6c39
--- /dev/null
+++ b/source/include/tp/d_stage.h
@@ -0,0 +1,29 @@
+/** @file d_stage.h
+ * @brief Stage related functions and fields
+ *
+ * @author AECX
+ * @bug No known bugs.
+ */
+
+#pragma once
+
+#include "../defines.h"
+#include "dzx.h"
+
+namespace tp::d_stage
+{
+ extern "C"
+ {
+ void* mStatus_roomControl;
+
+ /**
+ * @brief Initialises Actors, can run multiple times per load
+ *
+ * @param mStatus_roomControl Pointer to roomControl data (unknown)
+ * @param chunkTypeInfo Pointer to dzxHeader
+ * @param unk3 unknown
+ * @param unk4 unknown
+ */
+ void actorCommonLayerInit(void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4);
+ }
+} // namespace tp::d_stage \ No newline at end of file
diff --git a/source/include/tp/dzx.h b/source/include/tp/dzx.h
new file mode 100644
index 0000000..6bf3fc2
--- /dev/null
+++ b/source/include/tp/dzx.h
@@ -0,0 +1,47 @@
+/** @file dzx.h
+ * @brief dzx related definitions
+ *
+ * @author AECX
+ * @bug No known bugs.
+ */
+#pragma once
+#include <string.h>
+
+#include "../defines.h"
+
+namespace tp::d_stage
+{
+ /**
+ * @brief Holds information about the given dzx Chunktype
+ *
+ * Example:
+ * TRES
+ * 0001
+ * 80401234 = 1 TRES Chunk at this address
+ */
+ struct dzxChunkTypeInfo
+ {
+ char tag[4];
+ u32 numChunks;
+ void* chunkDataPtr;
+ } __attribute__((__packed__));
+
+ struct TRES
+ {
+ char actorName[8];
+ u32 flags;
+
+ float X;
+ float Y;
+ float Z;
+
+ s32 angle;
+
+ u8 item;
+ u8 unk2[3]; // Seems to always be 0xFF
+
+ TRES() { memset(this, 0xFF, sizeof(TRES)); }
+ } __attribute__((__packed__));
+ static_assert(sizeof(TRES) == 0x20);
+
+} // namespace tp \ No newline at end of file
diff --git a/source/include/tp/evt_control.h b/source/include/tp/evt_control.h
new file mode 100644
index 0000000..32301da
--- /dev/null
+++ b/source/include/tp/evt_control.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::evt_control
+{
+ typedef s32 (csFunc)(void* unk, s32 unk2);
+ extern "C"
+ {
+ s32 skipper(void* eventPtr);
+ s32 defaultSkipStb(void* unk, s32 unk2);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/f_ap_game.h b/source/include/tp/f_ap_game.h
new file mode 100644
index 0000000..e362a86
--- /dev/null
+++ b/source/include/tp/f_ap_game.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::f_ap_game
+{
+ extern "C"
+ {
+ void fapGm_Execute();
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/f_op_actor_mng.h b/source/include/tp/f_op_actor_mng.h
new file mode 100644
index 0000000..d0ca47c
--- /dev/null
+++ b/source/include/tp/f_op_actor_mng.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::f_op_actor_mng
+{
+ extern "C"
+ {
+ s32 createItemForPresentDemo(const float pos[3], s32 item, u8 unk3, s32 unk4, s32 unk5, const float unk6[3], const float unk7[3]);
+ s32 createItemForTrBoxDemo(const float pos[3], s32 item, s32 unk3, s32 unk4, const float unk5[3], const float unk6[3]);
+ s32 createDemoItem(const float pos[3], s32 item, s32 unk3, const float unk4[3], s32 unk5, const float unk6[3], u8 unk7);
+ s32 createItemForBoss(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7, s32 unk8);
+ s32 createItemForMidBoss(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], s32 unk6, s32 unk7);
+ s32 createItemForDirectGet(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7);
+ s32 createItemForSimpleDemo(const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7);
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/f_op_scene_req.h b/source/include/tp/f_op_scene_req.h
new file mode 100644
index 0000000..a650dc3
--- /dev/null
+++ b/source/include/tp/f_op_scene_req.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::f_op_scene_req
+{
+ extern "C"
+ {
+ extern u8 freezeActors;
+ extern s32 isUsingOfOverlap;
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/m_Do_controller_pad.h b/source/include/tp/m_Do_controller_pad.h
new file mode 100644
index 0000000..af38ac6
--- /dev/null
+++ b/source/include/tp/m_Do_controller_pad.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::m_do_controller_pad
+{
+ // Should try to fill in the missing variables at some point
+ struct CPadInfo
+ {
+ u8 unk_0[0x30];
+ u32 buttonInput;
+ u32 buttonInputTrg;
+ u8 unk_38[0xC8];
+ } __attribute__((__packed__));
+
+ static_assert(sizeof(CPadInfo) == 0x100);
+
+ extern "C"
+ {
+ extern CPadInfo cpadInfo;
+ }
+} \ No newline at end of file
diff --git a/source/include/tp/m_Do_ext.h b/source/include/tp/m_Do_ext.h
new file mode 100644
index 0000000..9c6b664
--- /dev/null
+++ b/source/include/tp/m_Do_ext.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::m_Do_ext
+{
+ extern "C"
+ {
+ extern void* archiveHeap;
+ }
+} \ No newline at end of file
diff --git a/source/source/HUDConsole.cpp b/source/source/HUDConsole.cpp
new file mode 100644
index 0000000..8e78484
--- /dev/null
+++ b/source/source/HUDConsole.cpp
@@ -0,0 +1,259 @@
+#include "HUDConsole.h"
+#include "defines.h"
+#include "systemConsole.h"
+
+#include <cstdio>
+#include <cstring>
+
+namespace mod
+{
+ HUDConsole::HUDConsole(const char firstPage[16], u32 RGBA)
+ {
+ strcpy(pages[0], firstPage);
+ numPages = 1;
+
+ // Set the visibility flags for all lines but disable the console
+ system_console::setState(true, 25);
+ system_console::setState(false, 0);
+
+ system_console::setBackgroundColor(RGBA);
+ }
+
+ void HUDConsole::addOption(u8 page, const char title[16], u8* target, u32 limit)
+ {
+ // Page is 0-based index, numPages the absolute counter
+ if(page < numPages)
+ {
+ // Find the option struct
+ u8 optionIndex = numOptions[page];
+
+ if(optionIndex < 10)
+ {
+ strcpy(options[page][optionIndex].Title, title);
+ options[page][optionIndex].Target = target;
+ options[page][optionIndex].Limit = limit;
+
+ // Incrase the counter
+ numOptions[page]++;
+ }
+ }
+ }
+
+ void HUDConsole::addWatch(u8 page, const char title[16], void* target, char format, u8 interpretation)
+ {
+ // Page is 0-based index, numPages the absolute counter
+ if(page < numPages)
+ {
+ // Find the watch struct
+ u8 watchIndex = numWatches[page];
+
+ if(watchIndex < 10)
+ {
+ strcpy(watches[page][watchIndex].Title, title);
+ watches[page][watchIndex].Target = target;
+ watches[page][watchIndex].Format = format;
+ watches[page][watchIndex].Interpretation = interpretation;
+
+ // Increase the counter
+ numWatches[page]++;
+ }
+ }
+ }
+
+ s8 HUDConsole::addPage(const char title[16])
+ {
+ if(numPages < MAX_HUDCONSOLE_PAGES)
+ {
+ sprintf(pages[numPages], title);
+ numPages++;
+
+ return (numPages - 1);
+ }
+ return -1;
+ }
+
+ void HUDConsole::performAction(u8 consoleAction, u8 amount)
+ {
+ Option* o = &options[selectedPage][selectedOption];
+ switch(consoleAction)
+ {
+ case ConsoleActions::Move_Up:
+ // Y movement (Caret)
+ if(selectedOption > 0)
+ {
+ selectedOption--;
+ }
+ else
+ {
+ // Go to last option
+ selectedOption = numOptions[selectedPage] - 1;
+ }
+ break;
+
+ case ConsoleActions::Move_Down:
+ // Y movement (Caret)
+ if(selectedOption < numOptions[selectedPage] - 1)
+ {
+ selectedOption++;
+ }
+ else
+ {
+ // Reset position
+ selectedOption = 0;
+ }
+ break;
+
+ case ConsoleActions::Move_Left:
+ selectedOption = 0;
+ // X Movement (Page)
+ if(selectedPage > 0)
+ {
+ selectedPage--;
+ }
+ else
+ {
+ // Go to last page
+ selectedPage = numPages - 1;
+ }
+ break;
+
+ case ConsoleActions::Move_Right:
+ selectedOption = 0;
+ // X Movement (Page)
+ if(selectedPage < numPages - 1)
+ {
+ selectedPage++;
+ }
+ else
+ {
+ // Go to first page
+ selectedPage = 0;
+ }
+ break;
+
+ case ConsoleActions::Option_Increase:
+ if(numOptions[selectedPage] < 1) return;
+ if(*o->Target + amount <= o->Limit)
+ {
+ *o->Target = *o->Target + amount;
+ }
+ else
+ {
+ // Loop back
+ *o->Target = 0;
+ }
+ break;
+
+ case ConsoleActions::Option_Decrease:
+ if(numOptions[selectedPage] < 1) return;
+ else if(*o->Target - amount >= 0)
+ {
+ *o->Target = *o->Target - amount;
+ }
+ else
+ {
+ // Loop back
+ *o->Target = static_cast<u8>(o->Limit);
+ }
+ break;
+ }
+ }
+
+ void HUDConsole::draw()
+ {
+ // Current line index
+ u8 i = 0;
+
+ tp::jfw_system::SystemConsole* console = sysConsolePtr;
+
+ // Print heading
+ sprintf(console->consoleLine[i].line, "[%d/%d][%-18s] %s (C) %s", selectedPage + 1, numPages, pages[selectedPage], VERSION, AUTHOR);
+
+ // Print options
+ for(i = 1; i <= numOptions[selectedPage]; i++)
+ {
+ // Template:
+ // [>] [title] (padding) [value]
+ u8 optionindex = i - 1; // Option[0] is line 1
+ Option o = options[selectedPage][optionindex];
+
+ if(o.Limit == 1)
+ {
+ sprintf(console->consoleLine[i].line, "%c%-25s %s", (optionindex == selectedOption ? '>' : ' '), o.Title, (*o.Target ? "Yes" : "No"));
+ }
+ else
+ {
+ sprintf(console->consoleLine[i].line, "%c%-25s %02x", (optionindex == selectedOption ? '>' : ' '), o.Title, *o.Target);
+ }
+ }
+
+ for(i = i; i < 11; i++)
+ {
+ console->consoleLine[i].line[0] = '\0';
+ }
+
+ for(i = i; (i - 11) < numWatches[selectedPage]; i++)
+ {
+ u8 watchIndex = i - 11;
+ // Print the watch to this line
+ Watch w = watches[selectedPage][watchIndex];
+
+ char format[12];
+ sprintf(format, "%s%c", "%-15s %", w.Format);
+
+ if(w.Interpretation == WatchInterpretation::_s64 || w.Interpretation == WatchInterpretation::_u64)
+ {
+ sprintf(format, "%s%c", "%-15s %ll", w.Format);
+ }
+
+ switch(w.Interpretation)
+ {
+ case WatchInterpretation::_u8:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<u8*>(w.Target));
+ break;
+
+ case WatchInterpretation::_u16:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<u16*>(w.Target));
+ break;
+
+ case WatchInterpretation::_u32:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<u32*>(w.Target));
+ break;
+
+ case WatchInterpretation::_u64:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<u64*>(w.Target));
+ break;
+
+ case WatchInterpretation::_s8:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<s8*>(w.Target));
+ break;
+
+ case WatchInterpretation::_s16:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<s16*>(w.Target));
+ break;
+
+ case WatchInterpretation::_s32:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<s32*>(w.Target));
+ break;
+
+ case WatchInterpretation::_s64:
+ sprintf(console->consoleLine[i].line, format, w.Title, *reinterpret_cast<s64*>(w.Target));
+ break;
+
+ case WatchInterpretation::_str:
+ sprintf(console->consoleLine[i].line, format, w.Title, reinterpret_cast<char*>(w.Target));
+ break;
+
+ default:
+ strcpy(console->consoleLine[i].line, "Error parsing watch");
+ break;
+ }
+ }
+
+ for(i = i; i < 20; i++)
+ {
+ console->consoleLine[i].line[0] = '\0';
+ }
+
+ }
+} \ No newline at end of file
diff --git a/source/source/array.cpp b/source/source/array.cpp
new file mode 100644
index 0000000..76cbebe
--- /dev/null
+++ b/source/source/array.cpp
@@ -0,0 +1,19 @@
+#include "array.h"
+#include "memory.h"
+
+#include <cstring>
+
+namespace mod::array
+{
+ s32 indexOf(u16 needle, u16* haystack, size_t count)
+ {
+ for (u32 i = 0; i < count; i++)
+ {
+ if (haystack[i] == needle)
+ {
+ return static_cast<s32>(i);
+ }
+ }
+ return -1;
+ }
+} \ No newline at end of file
diff --git a/source/source/chestRando.cpp b/source/source/chestRando.cpp
new file mode 100644
index 0000000..bd2c06a
--- /dev/null
+++ b/source/source/chestRando.cpp
@@ -0,0 +1,1844 @@
+#include "chestRando.h"
+#include "defines.h"
+#include "item.h"
+#include "items.h"
+#include "itemChecks.h"
+#include "tools.h"
+#include "array.h"
+#include "stage.h"
+#include "keyPlacement.h"
+#include "singleton.h"
+#include "grottoChecks.h"
+#include "game_patches.h"
+
+#include <tp/d_com_inf_game.h>
+#include <tp/d_item.h>
+#include <tp/d_a_alink.h>
+#include <tp/JFWSystem.h>
+#include <cstdio>
+#include <cstring>
+
+namespace mod
+{
+ void ChestRandomizer::generate()
+ {
+ // Reset
+
+ itemWheel = &gameInfo.scratchPad.itemWheel;
+
+ currentPlayerConditions = startConditions;
+ currentSeed = tools::randomSeed;
+
+ totalChecks = sizeof(item::checks) / sizeof(item::ItemCheck);
+ empty = 0;
+ layerCheckCount = 0;
+
+ itemOrderIndex = 0;
+
+ // Set up arrays
+ itemOrder = new u8[totalChecks];
+
+ item::ItemCheck* sourceCheck;
+ item::ItemCheck* destCheck;
+
+ // Reset randomization
+ for (u16 i = 0; i < totalChecks; i++)
+ {
+ item::checks[i].destination = nullptr;
+ item::checks[i].source = nullptr;
+ }
+
+ // Lock some checks
+ for (u16 i = 0; i < totalChecks; i++)
+ {
+ if (isLocked(&item::checks[i]))
+ {
+ placeCheck(&item::checks[i], &item::checks[i]);
+ }
+ }
+
+ handleKeysanity();
+
+ //do needed items in order
+ for (u16 i = 0; i < sizeof(item::checkPriorityOrder) / sizeof(u16); i++)
+ {
+ destCheck = &item::checks[item::checkPriorityOrder[i]];
+ if (!destCheck->source)
+ {
+ if (destCheck->itemID == items::Item::Ordon_Sword)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x1, destCheck);//to prevent woodensword from being overwritten before losing it
+ }
+ else if (destCheck->itemID == items::Item::Ordon_Shield || destCheck->itemID == items::Item::Wooden_Shield || destCheck->itemID == items::Item::Hylian_Shield)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x2, destCheck);//to prevent softlocking the game when you try to get ordon shield check
+ }
+ else if (destCheck->itemID == items::Item::Zora_Armor || destCheck->itemID == items::Item::Magic_Armor)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x2, destCheck);//to prevent softlocking the game when you try to get ordon shield check
+ }
+ else if (isProgressiveEnabled == 0 && destCheck->itemID == items::Item::Clawshots)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x7, destCheck);//to prevent Clawshots from being overwritten by Clawshot
+ }
+ else
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x0, destCheck);
+ }
+ placeCheck(sourceCheck, destCheck);
+ //layerCheckCount++;
+ }
+ }
+
+ // Place items that unlock other locations before caring about remaining items
+ //useless
+ /*for(u16 i = 0; i < totalChecks; i++)
+ {
+ destCheck = &item::checks[i];
+ if(!destCheck->source)
+ {
+ // Free slot
+ if(item::getFlags(destCheck->itemID, 0) != 0)
+ {
+ // This would unlock new checks, so place it
+ if (destCheck->itemID == items::Item::Ordon_Shield || destCheck->itemID == items::Item::Wooden_Shield || destCheck->itemID == items::Item::Hylian_Shield)
+ {
+ sourceCheck = findSource(0xFF, 0x2, destCheck);//to prevent softlocking the game when you try to get ordon shield check
+ }
+ else
+ {
+ sourceCheck = findSource(0xFF, 0, destCheck);
+ }
+ placeCheck(sourceCheck, destCheck);
+ }
+ }
+ }*/
+
+ //do dungeon items
+ for (u16 i = 0; i <= totalChecks; i++)
+ {
+ destCheck = &item::checks[i];
+ if (!destCheck->source && destCheck->type == item::ItemType::Dungeon)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x0, destCheck);
+ placeCheck(sourceCheck, destCheck);
+ //layerCheckCount++;
+ }
+ }
+
+ // Place layer checks
+ for (u16 i = 0; i < totalChecks; i++)
+ {
+ destCheck = &item::checks[i];
+
+ if (!destCheck->source)
+ {
+ // Free slot
+ if (destCheck->destLayer != 0xFF)
+ {
+ // Layer check
+ if (destCheck->itemID == items::Item::Ordon_Sword)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x1, destCheck);//to prevent woodensword from being overwritten before losing it
+ }
+ else if (destCheck->itemID == items::Item::Ordon_Shield || destCheck->itemID == items::Item::Wooden_Shield || destCheck->itemID == items::Item::Hylian_Shield)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x2, destCheck);//to prevent softlocking the game when you try to get ordon shield check
+ }
+ else if (destCheck->itemID == items::Item::Zora_Armor || destCheck->itemID == items::Item::Magic_Armor)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x2, destCheck);//to prevent softlocking the game when you try to get ordon shield check
+ }
+ else if (isProgressiveEnabled == 0)
+ {
+ if (destCheck->itemID == items::Item::Clawshots)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x7, destCheck);//to prevent Clawshots from being overwritten by Clawshot
+ }
+ else if (destCheck->itemID == items::Item::Big_Quiver)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x4, destCheck);//to prevent bow from being overwritten
+ }
+ else if (destCheck->itemID == items::Item::Giant_Quiver)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x8, destCheck);//to prevent bow from being overwritten
+ }
+ else if (destCheck->itemID == items::Item::Giant_Wallet)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x7, destCheck);//to prevent overwriting giant wallet with big wallet
+ }
+ else if (destCheck->itemID == items::Item::Giant_Bomb_Bag)
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x6, destCheck);//to prevent getting a 4th bag and possibly crashing the game
+ }
+ else
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x0, destCheck);
+ }
+ }
+ else
+ {
+ sourceCheck = findSource(destCheck->destLayer, 0x0, destCheck);
+ }
+ placeCheck(sourceCheck, destCheck);
+ layerCheckCount++;
+ }
+ }
+ }
+
+
+
+ // Place remaining
+ for (u16 i = 0; i < totalChecks; i++)
+ {
+ destCheck = &item::checks[i];
+
+ if (!destCheck->source)
+ {
+ if (destCheck->itemID == items::Item::Ordon_Shield || destCheck->itemID == items::Item::Wooden_Shield || destCheck->itemID == items::Item::Hylian_Shield)
+ {
+ sourceCheck = findSource(0xFF, 0x2, destCheck);//to prevent softlocking the game when you try to get ordon shield check
+ }
+ else
+ {
+ sourceCheck = findSource(0xFF, 0, destCheck);
+ }
+ placeCheck(sourceCheck, destCheck);
+ }
+ }
+
+ // Count empty
+ for (u16 i = 0; i < totalChecks; i++)
+ {
+ if (!item::checks[i].destination)
+ {
+ empty++;
+ }
+ }
+
+ // Done
+ checkSum = tools::fletcher16(itemOrder, sizeof(itemOrder));
+
+ delete[] itemOrder;
+
+ // Reset seed if the player wanted to lock it (otherwise it advances anyways)
+ tools::randomSeed = currentSeed;
+ }
+
+ void ChestRandomizer::placeCheck(item::ItemCheck* sourceCheck, item::ItemCheck* destCheck)
+ {
+ // Add source item to the itemOrder array
+ itemOrder[itemOrderIndex] = sourceCheck->itemID;
+ itemOrderIndex++;
+
+ // Place without asking
+ sourceCheck->destination = destCheck;
+ destCheck->source = sourceCheck;
+
+ // Update player conditions!
+ currentPlayerConditions = item::getFlags(destCheck->itemID, currentPlayerConditions);
+ }
+
+ item::ItemCheck* ChestRandomizer::findSource(u8 maxLayer, u8 minLayer, item::ItemCheck* destCheck)
+ {
+ if (minLayer == 0xFF)
+ {
+ minLayer = 0x0;
+ }
+
+ item::ItemCheck* sourceCheck;
+ u16 index;
+ do
+ {
+ index = tools::getRandom(totalChecks);
+ sourceCheck = &item::checks[index];
+ } while (!checkCondition(sourceCheck, destCheck) || sourceCheck->destination || sourceCheck->sourceLayer > maxLayer || sourceCheck->sourceLayer < minLayer ||
+ (destCheck->type == item::ItemType::Bug && 0 == strcmp("R_SP160", sourceCheck->stage) && sourceCheck->room == 3) || //agitha can't give bugs
+ (areDungeonItemsRandomized == 1 && destCheck->type == item::ItemType::Dungeon && 0 != strcmp(destCheck->stage, sourceCheck->stage)) || //dungeon items only in their own dungeon
+ (areDungeonItemsRandomized == 1 && destCheck->type == item::ItemType::Dungeon && index == 115)); //dont place dungeon items at clawshot goron mines check
+
+ return sourceCheck;
+ }
+
+ bool ChestRandomizer::checkCondition(item::ItemCheck* sourceCheck, item::ItemCheck* destCheck)
+ {
+ if ((sourceCheck->condition & item::Condition::AND) == item::Condition::AND)
+ {
+ if ((sourceCheck->condition & currentPlayerConditions) == sourceCheck->condition)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if ((sourceCheck->condition & currentPlayerConditions) != 0)
+ {
+ return true;
+ }
+ }
+ // If the destination item (which you'll receive) isn't required for this source and you don't require anything in this layer, it can be placed though
+ if ((item::getFlags(destCheck->itemID, 0) & sourceCheck->condition) == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool ChestRandomizer::isLocked(item::ItemCheck* check)
+ {
+ bool result = false;
+
+ switch (check->type)
+ {
+ case item::ItemType::Key:
+ // Small Keys + ordon pumpkin and cheese
+ if (isKeysanityEnabled == 0 || (Singleton::getInstance()->isForestEscapeEnabled == 1 && isKeysanityEnabled == 1 && check->itemID == items::Item::Coro_Key))
+ {
+ result = true;
+ }
+ break;
+
+ case item::ItemType::Dungeon:
+ // Map, compass, big key
+ if (areDungeonItemsRandomized == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case item::ItemType::Story:
+ if (check->itemID != items::Item::Aurus_Memo && check->itemID != items::Item::Asheis_Sketch)
+ {
+ result = true;
+ }
+ break;
+
+ case item::ItemType::Bug:
+ if (isBugsanityEnabled == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case item::ItemType::PoeSoul:
+ if (isPoesanityEnabled == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case item::ItemType::Shop:
+ if (isShopsanityEnabled == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case item::ItemType::Skill:
+ result = true;
+ break;
+ }
+
+ switch (check->itemID)
+ {
+ /*case items::Item::Iron_Boots:
+ result = true;
+ break;*/
+ case items::Item::Shadow_Crystal:
+ if (Singleton::getInstance()->isMDHSkipEnabled == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case items::Item::Fishing_Rod:
+ result = true;
+ break;
+
+ case items::Item::Ancient_Sky_Book_empty:
+ if (isProgressiveEnabled == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case items::Item::Ancient_Sky_Book_partly_filled:
+ if (Singleton::getInstance()->shuffledSkybook == 0)
+ {
+ result = true;
+ }
+ break;
+
+ case items::Item::Ancient_Sky_Book_completed:
+ if (Singleton::getInstance()->shuffledSkybook == 0)
+ {
+ result = true;
+ }
+ break;
+
+
+ }
+
+ return result;
+ }
+
+ s32 ChestRandomizer::getItemReplacement(const float pos[3], s32 item)
+ {
+ item::ItemCheck* sourceCheck;
+ snprintf(lastSourceInfo, 50, "%s %4.0f %4.0f %4.0f", gameInfo.currentStage, pos[0], pos[1], pos[2]);
+ snprintf(lastDestInfo, 50, "No Replacement found for this source");
+
+ /*if (item == items::Item::Sera_Bottle)
+ { //for testing only
+ item = itemThatReplacesHalfMilk;
+ if (item == items::Item::Dominion_Rod)
+ {
+ gameInfo.scratchPad.eventBits[0x25] |= 0x80;
+ }
+ else if (item == items::Item::Poe_Soul)
+ {//increase poe counter
+ gameInfo.scratchPad.poeCount++;
+ }
+ return item;
+ }
+ else if (item == items::Item::Slingshot)
+ { //for testing only
+ item = itemThatReplacesSlingShot;
+ if (item == items::Item::Dominion_Rod)
+ {
+ item = items::Item::Dominion_Rod;
+ gameInfo.scratchPad.eventBits[0x25] |= 0x80;
+ }
+ else if (item == items::Item::Poe_Soul)
+ {//increase poe counter
+ gameInfo.scratchPad.poeCount++;
+ }
+ return item;
+ }*/
+
+
+ if (item == items::Item::Heart_Container && isStageBoss())
+ {//set flag for HC gotten
+ gameInfo.localAreaNodes.dungeon.containerGotten = 0b1;
+ if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Fyrus]))
+ {
+ gameInfo.localAreaNodes.unk_0[0xA] |= 0x40; //open doors to mini boss to prevent softlocks
+ }
+ }
+ else if (item == items::Item::Iron_Boots)
+ {//set flag for having talked to Bo
+ gameInfo.scratchPad.eventBits[0x1C] |= 0x20;
+ }
+ else if (item == items::Item::Poe_Soul && gameInfo.scratchPad.poeCount >= 1)
+ {//decrease poe counter
+ gameInfo.scratchPad.poeCount--;
+ }
+ else if (item == items::Item::Vessel_Of_Light_Faron)
+ {
+ tp::d_com_inf_game::ScratchPad* scratchPadPtr = &gameInfo.scratchPad;
+ u8* eventBitsPtr = &scratchPadPtr->eventBits[0];
+ tp::d_com_inf_game::AllAreaNodes* allAreaNodesPtr = &scratchPadPtr->allAreaNodes;
+ 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
+
+ //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 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
+
+ //Unlock Map Regions
+ scratchPadPtr->movingActors.exploredRegions.Snowpeak = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Desert = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Lanayru = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Eldin = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Faron = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Ordon = 0b1;
+
+ //Unlock Warps
+ allAreaNodesPtr->Ordon.unk_0[0xD] = 0x10; // give Ordon Spring Warp
+ gameInfo.localAreaNodes.unk_0[0x13] = 0x80;//give S faron warp
+ gameInfo.localAreaNodes.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->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)
+ {
+ eventBitsPtr[0x6] |= 0x26; //warp the kak bridge, give map warp, set Forest Temple Story Flag
+ }
+ else
+ {
+ eventBitsPtr[0x6] |= 0x24; //warp the kak bridge, give map warp
+ }
+
+ gameInfo.nextStageVars.triggerLoad |= 1;
+ return item;
+ }
+ else
+ {
+ //Faron Escape
+ if (Singleton::getInstance()->isForestEscapeEnabled == 1)
+ {
+ eventBitsPtr[0x6] |= 0x26; //warp the kak bridge, give map warp, set Forest Temple Story Flag
+ }
+ else
+ {
+ eventBitsPtr[0x6] |= 0x24; //warp the kak bridge, give map warp
+ }
+ 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)
+ {
+ tp::d_com_inf_game::ScratchPad* scratchPadPtr = &gameInfo.scratchPad;
+ u8* eventBitsPtr = &scratchPadPtr->eventBits[0];
+ 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
+ return item;
+ }
+ else if (item == items::Item::Vessel_Of_Light_Lanayru)
+ {
+ 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);
+ }
+ else if (item == items::Item::Hawkeye)
+ {//set flag for Hawkeye check
+ tools::setItemFlag(ItemFlags::Null_D8);
+ }
+ else if (item == items::Item::Dungeon_Map && tp::d_a_alink::checkStageName("D_MN11"))
+ {//set flag to be able to enter kitchen
+ gameInfo.localAreaNodes.unk_0[0x10] |= 0x20;
+ }
+
+ for (u16 i = 0; i < totalChecks; i++)
+ {
+ sourceCheck = &item::checks[i];
+
+ if (tp::d_a_alink::checkStageName(sourceCheck->stage) || (tp::d_a_alink::checkStageName("F_SP128") && 0 == strcmp(sourceCheck->stage, "R_SP128")))
+ {
+
+ if (isGrottoCheckOk(i))
+ {
+
+ if (isProgressiveEnabled == 1 && item == items::Item::Ancient_Sky_Book_completed)
+ {
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ }
+ // Correct stage
+ if (sourceCheck->itemID == item || (isItemBombs(item) && isItemBombs(sourceCheck->itemID)) ||
+ (item == items::Item::Red_Rupee && sourceCheck->itemID == items::Item::Giant_Bomb_Bag) ||
+ (item == items::Item::Ooccoo_FT && sourceCheck->itemID == items::Item::Ooccoo_Dungeon) ||
+ (item == items::Item::Lantern_Refill_Shop && sourceCheck->itemID == items::Item::Lantern_Oil_Shop) ||
+ (item == items::Item::Lantern_Refill_Scooped && sourceCheck->itemID == items::Item::Lantern_Oil_Scooped) ||
+ (sourceCheck->itemID == items::Item::Superb_Soup && (item == items::Item::Simple_Soup || item == items::Item::Good_Soup)))
+ {
+ bool isOk = false;
+
+ if (sourceCheck->type == item::ItemType::Bug || sourceCheck->type == item::ItemType::Dungeon || sourceCheck->itemID == items::Item::Heart_Container ||
+ sourceCheck->itemID == items::Item::Ball_and_Chain || sourceCheck->itemID == items::Item::Ancient_Sky_Book_empty)
+ {//bugs have unique itemids so position doesn't matter
+ //dungeon items are unique in their dungeon
+ //there can only be one heart container per stage in vanilla, so position doesn't matter (also each one can be at 2 locations: if gotten after boss or if coming back)
+ //BaC can be anywhere in the room so don't check the position
+ //empty sky book can be outside the house or inside the house so don't check coords
+ isOk = true;
+ }
+ else if (sourceCheck->itemID == items::Item::Piece_of_Heart && (0 == strcmp("F_SP127", sourceCheck->stage)))
+ {//fishing hole freestanding PoH
+ //it's alone in the fishing hole so it can only be that one
+ isOk = true;
+ }
+ else
+ {
+ if (sourceCheck->type == item::ItemType::PoeSoul)
+ {//poes can move a lot so give them more range
+ //poe range= ~1400
+ rangeX = 2800.0f;
+ rangeY = 1400.0f;
+ rangeZ = 2800.0f;
+ }
+ else if (sourceCheck->itemID == items::Item::Piece_of_Heart && ((0 == strcmp("F_SP121", sourceCheck->stage) && sourceCheck->room == 6) ||
+ (0 == strcmp("F_SP109", sourceCheck->stage) && sourceCheck->room == 0) || (0 == strcmp("F_SP121", sourceCheck->stage) && sourceCheck->room == 3) ||
+ (0 == strcmp("F_SP121", sourceCheck->stage) && sourceCheck->room == 0) || (0 == strcmp("F_SP128", sourceCheck->stage) && sourceCheck->room == 0)))
+ {//freestanding PoH
+ // they can be moved by boomerang and clawshot, so give them more range
+ // clawshot and boomrang targetting range ~2000
+ rangeX = 3000.0f;
+ rangeY = 3000.0f;
+ rangeZ = 3000.0f;
+ }
+ else if (sourceCheck->itemID == items::Item::Small_Key && 0 == strcmp("D_MN05", sourceCheck->stage) && sourceCheck->room == 5)
+ {//totem chest in FT (it can be knocked down both ways so more range is required)
+ rangeX = 500.0f;
+ rangeY = 500.0f;
+ rangeZ = 800.0f;
+ }
+ if (tools::fCompare(sourceCheck->position[0], pos[0]) < rangeX)
+ {
+ if (tools::fCompare(sourceCheck->position[1], pos[1]) < rangeY)
+ {
+ if (tools::fCompare(sourceCheck->position[2], pos[2]) < rangeZ)
+ {
+ isOk = true;
+ }
+ }
+ }
+ }
+ if (isOk)
+ {
+ snprintf(lastSourceInfo, 50, "%s->%d->%x", sourceCheck->stage, sourceCheck->room, sourceCheck->itemID);
+ if (sourceCheck->destination)
+ {
+ snprintf(lastDestInfo, 50, "%s->%d->%x", sourceCheck->destination->stage, sourceCheck->destination->room, sourceCheck->destination->itemID);
+ item = sourceCheck->destination->itemID;
+ if (sourceCheck->type == item::ItemType::Bug || sourceCheck->itemID == items::Item::Heart_Container)
+ {
+ sourceCheck->destination = &item::checks[263];//green rupee
+ }
+ else if (sourceCheck->type == item::ItemType::Shop)
+ {
+ sourceCheck->destination = &item::checks[i];
+ }
+ else if (sourceCheck->itemID != items::Item::Big_Quiver && sourceCheck->itemID != items::Item::Giant_Quiver && // quiver checks called twice somehow
+ sourceCheck->type != item::ItemType::Dungeon && sourceCheck->type != item::ItemType::Gear && sourceCheck->type != item::ItemType::Equip) // some checks are called twice i don't wanna list them all, but dungeon items, gear, and equipable items only have one check each intheir stage
+ {
+ // Unset this check
+ sourceCheck->destination = nullptr;
+ }
+ //progressive checks (doesn't work if you already have items when generating seed)
+ if (isProgressiveEnabled == 1)
+ {
+ if (item == items::Item::Wooden_Sword && tools::checkItemFlag(ItemFlags::Wooden_Sword))
+ {
+ item = items::Item::Ordon_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x28;
+ }
+ else if (item == items::Item::Ordon_Sword && !tools::checkItemFlag(ItemFlags::Wooden_Sword))
+ {
+ item = items::Item::Wooden_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x3F;
+ }
+ else if (item == items::Item::Master_Sword && tools::checkItemFlag(ItemFlags::Master_Sword))
+ {//for when MS and light Ms are implemented
+ item = items::Item::Master_Sword_Light;
+ gameInfo.scratchPad.equipedItems.sword = 0x49;
+ }
+ else if (item == items::Item::Master_Sword_Light && !tools::checkItemFlag(ItemFlags::Master_Sword))
+ {//for when MS and light Ms are implemented
+ item = items::Item::Master_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x29;
+ }
+ else if (item == items::Item::Clawshot && tools::checkItemFlag(ItemFlags::Clawshot))
+ {
+ item = items::Item::Clawshots;
+ }
+ else if (item == items::Item::Clawshots && !tools::checkItemFlag(ItemFlags::Clawshot))
+ {
+ item = items::Item::Clawshot;
+ }
+ else if (item == items::Item::Heros_Bow)
+ {
+ if (tools::checkItemFlag(ItemFlags::Heros_Bow) &&
+ !tools::checkItemFlag(ItemFlags::Big_Quiver))
+ {
+ item = items::Item::Big_Quiver;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Heros_Bow) &&
+ tools::checkItemFlag(ItemFlags::Big_Quiver))
+ {
+ item = items::Item::Giant_Quiver;
+ }
+ }
+ else if (item == items::Item::Big_Quiver)
+ {
+ if (!tools::checkItemFlag(ItemFlags::Heros_Bow))
+ {
+ item = items::Item::Heros_Bow;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Big_Quiver))
+ {
+ item = items::Item::Giant_Quiver;
+ }
+ }
+ else if (item == items::Item::Giant_Quiver)
+ {
+ if (!tools::checkItemFlag(ItemFlags::Heros_Bow))
+ {
+ item = items::Item::Heros_Bow;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Big_Quiver))
+ {
+ item = items::Item::Big_Quiver;
+ }
+ }
+ else if (item == items::Item::Big_Wallet &&
+ tools::checkItemFlag(ItemFlags::Big_Wallet))
+ {
+ item = items::Item::Giant_Wallet;
+ }
+ else if (item == items::Item::Giant_Wallet &&
+ !tools::checkItemFlag(ItemFlags::Big_Wallet))
+ {
+ item = items::Item::Big_Wallet;
+ }
+ else if (item == items::Item::Ancient_Sky_Book_empty)
+ {
+ if (!tools::checkItemFlag(ItemFlags::Ancient_Sky_Book_empty))
+ {
+ item = items::Item::Ancient_Sky_Book_empty;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DF))
+ {//letter 1
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DF);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DE))
+ {//letter 2
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DE);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DD))
+ {//letter 3
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DD);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DC))
+ {//letter 4
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DC);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DB))
+ {//letter 5
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DB);
+ }
+ 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;
+ }
+ item = items::Item::Ancient_Sky_Book_completed;
+ }
+ }
+ else if (item == items::Item::Ancient_Sky_Book_partly_filled)
+ {
+ if (!tools::checkItemFlag(ItemFlags::Ancient_Sky_Book_empty))
+ {
+ item = items::Item::Ancient_Sky_Book_empty;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DF))
+ {//letter 1
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DF);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DE))
+ {//letter 2
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DE);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DD))
+ {//letter 3
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DD);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DC))
+ {//letter 4
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DC);
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Null_DB))
+ {//letter 5
+ item = items::Item::Ancient_Sky_Book_partly_filled;
+ tools::setItemFlag(ItemFlags::Null_DB);
+ }
+ 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;
+ }
+ item = items::Item::Ancient_Sky_Book_completed;
+ }
+ }
+ else if (item == items::Item::Empty_Bomb_Bag)
+ {
+ if (itemWheel->Bomb_Bag_1 == 0xFF)
+ {
+ item = items::Item::Bomb_Bag_Regular_Bombs;
+ }
+ else if (itemWheel->Bomb_Bag_2 == 0xFF)
+ {
+ item = items::Item::Goron_Bomb_Bag;
+ }
+ else if (itemWheel->Bomb_Bag_3 == 0xFF)
+ {
+ item = items::Item::Goron_Bomb_Bag;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Giant_Bomb_Bag))
+ {
+ item = items::Item::Giant_Bomb_Bag;
+ }
+ else
+ {
+ item = items::Item::Bombs_30;
+ }
+ }
+ else if (item == items::Item::Goron_Bomb_Bag)
+ {
+ if (itemWheel->Bomb_Bag_1 == 0xFF)
+ {
+ item = items::Item::Bomb_Bag_Regular_Bombs;
+ }
+ else if (itemWheel->Bomb_Bag_2 == 0xFF)
+ {
+ item = items::Item::Goron_Bomb_Bag;
+ }
+ else if (itemWheel->Bomb_Bag_3 == 0xFF)
+ {
+ item = items::Item::Goron_Bomb_Bag;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Giant_Bomb_Bag))
+ {
+ item = items::Item::Giant_Bomb_Bag;
+ }
+ else
+ {
+ item = items::Item::Bombs_30;
+ }
+ }
+ else if (item == items::Item::Giant_Bomb_Bag)
+ {
+ if (itemWheel->Bomb_Bag_1 == 0xFF)
+ {
+ item = items::Item::Bomb_Bag_Regular_Bombs;
+ }
+ else if (itemWheel->Bomb_Bag_2 == 0xFF)
+ {
+ item = items::Item::Goron_Bomb_Bag;
+ }
+ else if (itemWheel->Bomb_Bag_3 == 0xFF)
+ {
+ item = items::Item::Goron_Bomb_Bag;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Giant_Bomb_Bag))
+ {
+ item = items::Item::Giant_Bomb_Bag;
+ }
+ else
+ {
+ item = items::Item::Bombs_30;
+ }
+ }
+ else if (item == items::Item::Key_Shard_1)
+ {
+ if (tools::checkItemFlag(ItemFlags::Key_Shard_1) &&
+ !tools::checkItemFlag(ItemFlags::Key_Shard_2))
+ {
+ item = items::Item::Key_Shard_2;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Key_Shard_1) &&
+ tools::checkItemFlag(ItemFlags::Key_Shard_2))
+ {
+ item = items::Item::Big_Key_Goron_Mines;
+ tools::setItemFlag(ItemFlags::Key_Shard_3);//set this flag to show full key on the map
+ }
+ }
+ else if (item == items::Item::Key_Shard_2)
+ {
+ if (!tools::checkItemFlag(ItemFlags::Key_Shard_1))
+ {
+ item = items::Item::Key_Shard_1;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Key_Shard_1) &&
+ tools::checkItemFlag(ItemFlags::Key_Shard_2))
+ {
+ item = items::Item::Big_Key_Goron_Mines;
+ tools::setItemFlag(ItemFlags::Key_Shard_3);//set this flag to show full key on the map
+ }
+ }
+ else if (item == items::Item::Big_Key_Goron_Mines)
+ {
+ if (!tools::checkItemFlag(ItemFlags::Key_Shard_1))
+ {
+ item = items::Item::Key_Shard_1;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Key_Shard_1) &&
+ !tools::checkItemFlag(ItemFlags::Key_Shard_2))
+ {
+ item = items::Item::Key_Shard_2;
+ }
+ else
+ {
+ tools::setItemFlag(ItemFlags::Key_Shard_3);//set this flag to show full key on the map
+ }
+ }
+ else if (item == items::Item::Dominion_Rod && tools::checkItemFlag(ItemFlags::Dominion_Rod))
+ {//for when powered dominion rod is implemented
+ item = items::Item::Dominion_Rod_Uncharged;
+ }
+ else if (item == items::Item::Dominion_Rod_Uncharged && !tools::checkItemFlag(ItemFlags::Dominion_Rod))
+ {//for when MS and light Ms are implemented
+ item = items::Item::Dominion_Rod;
+ }
+ }
+ if (item == items::Item::Dominion_Rod_Uncharged)
+ {//giving Dominion_Rod_Uncharged is the same as giving Dominion_Rod but there's no text (yet)
+ gameInfo.scratchPad.eventBits[0x25] |= 0x80;//set flag to charge dominion rod
+ } //will be changed once we implement custom chests
+ else if (item == items::Item::Poe_Soul && gameInfo.scratchPad.poeCount < 60)
+ {//increase poe counter
+ gameInfo.scratchPad.poeCount++;
+ }
+ 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();
+ }
+ else if (item == items::Item::Ordon_Pumpkin)
+ {
+ gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.unk_0[0x9] |= 0x4; //Unlock Lobby Courtyard Door
+ gameInfo.scratchPad.eventBits[0x4] |= 0x80; //Told Yeta About Pumpkin
+ gameInfo.scratchPad.eventBits[0x0] |= 0x22; //Yeto took pumpkin and put it in soup
+ }
+ else if (item == items::Item::Ordon_Goat_Cheese)
+ {
+ gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.unk_0[0x9] |= 0x8; //Unlock West Wing Door
+ gameInfo.scratchPad.eventBits[0x1] |= 0x20; //Told Yeta About Cheese
+ gameInfo.scratchPad.eventBits[0x0] |= 0x11; //Yeto took Cheese and put it in soup
+ }
+ else if (item == 0xE1)
+ {
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;//give ending blow
+ }
+ else if (item == 0xE2)
+ {
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;//give shield attack
+ }
+ else if (item == 0xE3)
+ {
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;//give back slice
+ }
+ else if (item == 0xE4)
+ {
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;//give helm splitter
+ }
+ else if (item == 0xE5)
+ {
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;//give mortal draw
+ }
+ else if (item == 0xE6)
+ {
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;//give jump strike
+ }
+ else if (item == 0xE7)
+ {
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;//give great spin
+ }
+ else if (item == items::Item::Bed_Key)
+ {
+ gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.bigKeyGotten = 0b1; //unlock Blizzetta Door
+ if (Singleton::getInstance()->isBossKeyseyEnabled == 1)
+ {
+ item = items::Item::Red_Rupee;
+ }
+ }
+ else if (item == items::Item::Big_Key && Singleton::getInstance()->isBossKeyseyEnabled == 1)
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Slingshot) &&
+ (item == items::Item::Seeds_50))
+ {
+ item = items::Item::Blue_Rupee;
+ }
+ else if (!tools::checkItemFlag(ItemFlags::Heros_Bow) &&
+ (item == items::Item::Arrows_10 ||
+ item == items::Item::Arrows_20 ||
+ item == items::Item::Arrows_30 ||
+ item == items::Item::Arrows_1))
+ {
+ item = items::Item::Blue_Rupee;
+ }
+ else if (gameInfo.scratchPad.itemWheel.Bomb_Bag_1 == 0xFF && isItemBombs(item))
+ {
+ item = items::Item::Blue_Rupee;
+ }
+ else if (gameInfo.scratchPad.itemWheel.Bottle_1 == 0xFF && isItemBottleFill(item))
+ {
+ if (tools::checkItemFlag(ItemFlags::Lantern))
+ {
+ if (item == items::Item::Lantern_Oil_Shop)
+ {
+ item = items::Item::Lantern_Refill_Shop;
+ gameInfo.scratchPad.counters.lantern_oil = gameInfo.scratchPad.counters.max_lantern_oil;
+ }
+ else if (item == items::Item::Lantern_Oil_Scooped)
+ {
+ item = items::Item::Lantern_Refill_Scooped;
+ gameInfo.scratchPad.counters.lantern_oil = gameInfo.scratchPad.counters.max_lantern_oil;
+ }
+ else if (item == items::Item::Yellow_Chu_Jelly)
+ {
+ item = items::Item::Lantern_Yellow_Chu_Chu;
+ gameInfo.scratchPad.counters.lantern_oil = gameInfo.scratchPad.counters.max_lantern_oil;
+ }
+ else
+ {
+ item = items::Item::Blue_Rupee;
+ }
+ }
+ else
+ {
+ item = items::Item::Blue_Rupee;
+ }
+ }
+ /*if (item == items::Item::Blue_Rupee)
+ {//somehow the blue rupee item get don't work normally
+ tp::d_item::execItemGet(items::Item::Blue_Rupee);
+ }*/
+ return item;
+ }
+ else
+ {
+ snprintf(lastDestInfo, 50, "No replacement here.");
+ //no return in the case where 2 items are close enough to be considered the same (bug rewards for example)
+ }
+ }
+ }
+ }
+ }
+ }
+ return item;
+ }
+
+
+ bool ChestRandomizer::isStageADungeon(char* stage)
+ {
+ u32 totalDungeonStages = sizeof(stage::dungeonStages) / sizeof(stage::dungeonStages[0]);
+ for (u32 i = 0; i < totalDungeonStages; i++)
+ {
+ if (0 == strcmp(stage, stage::dungeonStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ChestRandomizer::isItemBombs(u8 itemID)
+ {
+ if (itemID == items::Item::Bombs_5 || itemID == items::Item::Bombs_10 || itemID == items::Item::Bombs_20 || itemID == items::Item::Bombs_30 ||
+ itemID == items::Item::Water_Bombs_5 || itemID == items::Item::Water_Bombs_10 || itemID == items::Item::Water_Bombs_15 ||
+ itemID == items::Item::Bomblings_5 || itemID == items::Item::Bomblings_10)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool ChestRandomizer::isItemBottleFill(u8 itemID)
+ {
+ if (itemID == items::Item::Red_Potion_Shop || itemID == items::Item::Green_Potion || itemID == items::Item::Blue_Potion || itemID == items::Item::Milk ||
+ itemID == items::Item::Lantern_Oil_Shop || itemID == items::Item::Water || itemID == items::Item::Lantern_Oil_Scooped || itemID == items::Item::Red_Potion_Scooped ||
+ itemID == items::Item::Nasty_soup || itemID == items::Item::Hot_spring_water_Scooped || itemID == items::Item::Fairy_Bottle || itemID == items::Item::Hot_Spring_Water_Shop ||
+ itemID == items::Item::Fairy_Tears || itemID == items::Item::Worm || itemID == items::Item::Bee_Larva_Scooped || itemID == items::Item::Rare_Chu_Jelly ||
+ itemID == items::Item::Red_Chu_Jelly || itemID == items::Item::Blue_Chu_Jelly || itemID == items::Item::Green_Chu_Jelly || itemID == items::Item::Yellow_Chu_Jelly ||
+ itemID == items::Item::Purple_Chu_Jelly || itemID == items::Item::Simple_Soup || itemID == items::Item::Good_Soup || itemID == items::Item::Superb_Soup ||
+ itemID == items::Item::Bee_Larva_Shop || itemID == items::Item::Black_Chu_Jelly)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool ChestRandomizer::isStageBoss()
+ {
+ u32 totalBossStages = sizeof(stage::bossStages) / sizeof(stage::bossStages[0]);
+ for (u32 i = 0; i < totalBossStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::bossStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ChestRandomizer::isStageGrotto()
+ {
+ u32 totalGrottoStages = sizeof(stage::grottoStages) / sizeof(stage::grottoStages[0]);
+ for (u32 i = 0; i < totalGrottoStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::grottoStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void ChestRandomizer::handleKeysanity()
+ {
+ if (isKeysanityEnabled == 1)
+ {
+ item::ItemCheck* sourceCheck;
+ item::ItemCheck* destCheck;
+ u32 length;
+ u16 index;
+ //do FT_1
+ length = sizeof(keyPlacement::FT_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::FT_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::FT_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do FT_2
+ length = sizeof(keyPlacement::FT_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::FT_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::FT_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do FT_3
+ length = sizeof(keyPlacement::FT_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::FT_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::FT_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do FT_4
+ length = sizeof(keyPlacement::FT_4) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::FT_keys[3]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::FT_4[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do GM_1
+ length = sizeof(keyPlacement::GM_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::GM_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::GM_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do GM_2
+ length = sizeof(keyPlacement::GM_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::GM_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::GM_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do GM_3
+ length = sizeof(keyPlacement::GM_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::GM_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::GM_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do LBT_1
+ length = sizeof(keyPlacement::LBT_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::LBT_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::LBT_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do LBT_2
+ length = sizeof(keyPlacement::LBT_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::LBT_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::LBT_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do LBT_3
+ length = sizeof(keyPlacement::LBT_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::LBT_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::LBT_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do AG_1
+ length = sizeof(keyPlacement::AG_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::AG_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::AG_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do AG_2
+ length = sizeof(keyPlacement::AG_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::AG_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::AG_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do AG_3
+ length = sizeof(keyPlacement::AG_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::AG_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::AG_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do AG_4
+ length = sizeof(keyPlacement::AG_4) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::AG_keys[3]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::AG_4[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do AG_5
+ length = sizeof(keyPlacement::AG_5) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::AG_keys[4]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::AG_5[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do SPR_1
+ length = sizeof(keyPlacement::SPR_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::SPR_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::SPR_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do SPR_2
+ length = sizeof(keyPlacement::SPR_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::SPR_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::SPR_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do SPR_3
+ length = sizeof(keyPlacement::SPR_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::SPR_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::SPR_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do SPR_4
+ length = sizeof(keyPlacement::SPR_4) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::SPR_keys[3]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::SPR_4[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do SPR_5
+ length = sizeof(keyPlacement::SPR_5) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::SPR_keys[4]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::SPR_5[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do SPR_6
+ length = sizeof(keyPlacement::SPR_6) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::SPR_keys[5]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::SPR_6[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do ToT_1
+ length = sizeof(keyPlacement::ToT_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::ToT_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::ToT_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do ToT_2
+ length = sizeof(keyPlacement::ToT_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::ToT_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::ToT_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do ToT_3
+ length = sizeof(keyPlacement::ToT_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::ToT_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::ToT_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do CitS_1
+ length = sizeof(keyPlacement::CitS_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::CitS_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::CitS_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do PoT_1
+ length = sizeof(keyPlacement::PoT_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do PoT_2
+ length = sizeof(keyPlacement::PoT_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do PoT_3
+ length = sizeof(keyPlacement::PoT_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do PoT_4
+ length = sizeof(keyPlacement::PoT_4) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[3]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_4[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do PoT_5
+ length = sizeof(keyPlacement::PoT_5) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[4]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_5[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do PoT_6
+ length = sizeof(keyPlacement::PoT_6) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[5]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_6[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do PoT_7
+ length = sizeof(keyPlacement::PoT_7) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::PoT_keys[6]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::PoT_7[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do HC_1
+ length = sizeof(keyPlacement::HC_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::HC_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::HC_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do HC_2
+ length = sizeof(keyPlacement::HC_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::HC_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::HC_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ //do HC_3
+ length = sizeof(keyPlacement::HC_3) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::HC_keys[2]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::HC_3[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+
+ //do F_1
+ length = sizeof(keyPlacement::F_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::F_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::F_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ if (Singleton::getInstance()->isForestEscapeEnabled == 0)
+ {
+ //do F_2
+ length = sizeof(keyPlacement::F_2) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::F_keys[1]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::F_2[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ }
+
+ //do GD_1
+ length = sizeof(keyPlacement::GD_1) / sizeof(u16);
+ destCheck = &item::checks[keyPlacement::GD_keys[0]];
+ do
+ {
+ index = tools::getRandom(length);
+ sourceCheck = &item::checks[keyPlacement::GD_1[index]];
+ } while (sourceCheck->destination || (sourceCheck->type == item::ItemType::PoeSoul && isPoesanityEnabled == 0) ||
+ (sourceCheck->type == item::ItemType::Bug && isBugsanityEnabled == 0) || (sourceCheck->type == item::ItemType::Shop && isShopsanityEnabled == 0));
+ placeCheck(sourceCheck, destCheck);
+ }
+ }
+
+ bool ChestRandomizer::isGrottoCheckOk(u16 checkID)
+ {
+ if (isStageGrotto())
+ {
+ u8 state = tp::d_com_inf_game::current_state;
+ if (tp::d_a_alink::checkStageName(stage::grottoStages[0]))
+ {
+ if (state == '0')
+ {
+ u32 length = sizeof(grottoChecks::g1_0) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g1_0[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '1')
+ {
+ u32 length = sizeof(grottoChecks::g1_1) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g1_1[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '2')
+ {
+ u32 length = sizeof(grottoChecks::g1_2) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g1_2[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '3')
+ {
+ u32 length = sizeof(grottoChecks::g1_3) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g1_3[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::grottoStages[1]))
+ {
+ if (state == '0')
+ {
+ u32 length = sizeof(grottoChecks::g2_0) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g2_0[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '1')
+ {
+ u32 length = sizeof(grottoChecks::g2_1) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g2_1[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '2')
+ {
+ u32 length = sizeof(grottoChecks::g2_2) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g2_2[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ /*else if (state == '3')
+ {
+ u32 length = sizeof(grottoChecks::g2_3) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g2_3[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }*/
+ else
+ {
+ return true;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::grottoStages[2]))
+ {
+ if (state == '0')
+ {
+ u32 length = sizeof(grottoChecks::g3_0) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g3_0[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ /*else if (state == '1')
+ {
+ u32 length = sizeof(grottoChecks::g3_1) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g3_1[i])
+ {
+ return true;
+ }
+ }
+ return false;
+
+ }*/
+ /*else if (state == '2')
+ {
+ u32 length = sizeof(grottoChecks::g3_2) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g3_2[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }*/
+ /*else if (state == '3')
+ {
+ u32 length = sizeof(grottoChecks::g3_3) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g3_3[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }*/
+ else
+ {
+ return true;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::grottoStages[3]))
+ {
+ if (state == '0')
+ {
+ u32 length = sizeof(grottoChecks::g4_0) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g4_0[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '1')
+ {
+ u32 length = sizeof(grottoChecks::g4_1) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g4_1[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '2')
+ {
+ u32 length = sizeof(grottoChecks::g4_2) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g4_2[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '3')
+ {
+ u32 length = sizeof(grottoChecks::g4_3) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g4_3[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::grottoStages[4]))
+ {
+ if (state == '0')
+ {
+ u32 length = sizeof(grottoChecks::g5_0) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g5_0[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ /*else if (state == '1')
+ {
+ u32 length = sizeof(grottoChecks::g5_1) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g5_1[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }*/
+ else if (state == '2')
+ {
+ u32 length = sizeof(grottoChecks::g5_2) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g5_2[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '3')
+ {
+ u32 length = sizeof(grottoChecks::g5_3) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g5_3[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (state == '4')
+ {
+ u32 length = sizeof(grottoChecks::g5_4) / sizeof(u16);
+ for (u16 i = 0; i < length; i++)
+ {
+ if (checkID == grottoChecks::g5_4[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/source/source/controller.cpp b/source/source/controller.cpp
new file mode 100644
index 0000000..51b4d4e
--- /dev/null
+++ b/source/source/controller.cpp
@@ -0,0 +1,25 @@
+#include "controller.h"
+#include "defines.h"
+
+#include <tp/m_Do_controller_pad.h>
+
+namespace mod::controller
+{
+ bool checkForButtonInput(u32 buttonCombo)
+ {
+ return (tp::m_do_controller_pad::cpadInfo.buttonInput & buttonCombo) == buttonCombo;
+ }
+
+ bool checkForButtonInputSingleFrame(u32 buttonCombo)
+ {
+ tp::m_do_controller_pad::CPadInfo* PadInfo = &tp::m_do_controller_pad::cpadInfo;
+ if ((PadInfo->buttonInput & buttonCombo) == buttonCombo)
+ {
+ if (PadInfo->buttonInputTrg & buttonCombo)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/source/source/cxx.cpp b/source/source/cxx.cpp
new file mode 100644
index 0000000..e3e05cb
--- /dev/null
+++ b/source/source/cxx.cpp
@@ -0,0 +1,29 @@
+#include "defines.h"
+
+#include <tp/m_Do_ext.h>
+#include <tp/JKRExpHeap.h>
+
+#include <cstring>
+
+void* operator new(size_t size)
+{
+ void* ArchiveHeapPtr = tp::m_Do_ext::archiveHeap;
+ void* NewPtr = tp::jkr_exp_heap::do_alloc_JKRExpHeap(ArchiveHeapPtr, size, 0x20);
+ return memset(NewPtr, 0, size);
+}
+void* operator new[](size_t size)
+{
+ void* ArchiveHeapPtr = tp::m_Do_ext::archiveHeap;
+ void* NewPtr = tp::jkr_exp_heap::do_alloc_JKRExpHeap(ArchiveHeapPtr, size, 0x20);
+ return memset(NewPtr, 0, size);
+}
+void operator delete(void* ptr)
+{
+ void* ArchiveHeapPtr = tp::m_Do_ext::archiveHeap;
+ return tp::jkr_exp_heap::do_free_JKRExpHeap(ArchiveHeapPtr, ptr);
+}
+void operator delete[](void* ptr)
+{
+ void* ArchiveHeapPtr = tp::m_Do_ext::archiveHeap;
+ return tp::jkr_exp_heap::do_free_JKRExpHeap(ArchiveHeapPtr, ptr);
+} \ No newline at end of file
diff --git a/source/source/cxx.ld b/source/source/cxx.ld
new file mode 100644
index 0000000..e81ef87
--- /dev/null
+++ b/source/source/cxx.ld
@@ -0,0 +1,5 @@
+/* Symbols for us to be able to call global constructors and destructors */
+_ctors_start = ADDR(.ctors);
+_ctors_end = _ctors_start + SIZEOF(.ctors);
+_dtors_start = ADDR(.dtors);
+_dtors_end = _dtors_start + SIZEOF(.dtors); \ No newline at end of file
diff --git a/source/source/eventListener.cpp b/source/source/eventListener.cpp
new file mode 100644
index 0000000..74ae241
--- /dev/null
+++ b/source/source/eventListener.cpp
@@ -0,0 +1,80 @@
+#include "defines.h"
+#include "eventListener.h"
+
+#include <tp/d_com_inf_game.h>
+#include <tp/d_kankyo.h>
+#include <tp/JFWSystem.h>
+
+#include <cstdio>
+#include <cstring>
+
+namespace mod::event
+{
+ EventListener::EventListener()
+ {
+ sprintf(sysConsolePtr->consoleLine[20].line, "Event Listener Initialized.");
+ }
+
+ void EventListener::addLoadEvent(char* stage, u8 room, u8 spawn, u8 state, u8 eventid, EventFunction trigger, LoadEventAccuracy accuracy)
+ {
+ if(loadEventIndex < MAX_LOAD_EVENTS)
+ {
+ // Add the event to the array
+ loadEvents[loadEventIndex] = {stage, room, spawn, state, eventid, trigger, accuracy};
+
+ loadEventIndex++;
+ }
+ }
+
+ void EventListener::checkLoadEvents()
+ {
+ char* stage = gameInfo.nextStageVars.nextStage;
+ u8 room = gameInfo.nextStageVars.nextRoom;
+ u8 spawn = static_cast<u8>(gameInfo.nextStageVars.nextSpawnPoint);
+ u8 state = gameInfo.nextStageVars.nextState;
+ u8 eventid = gameInfo.eventSystem.currentEventID;
+
+ for(u8 i = 0; i < loadEventIndex; i++)
+ {
+ LoadEvent e = loadEvents[i];
+ if(strcmp(stage, e.Stage) == 0)
+ {
+ // Stage is minimum requirement
+ if(e.Accuracy == LoadEventAccuracy::Stage)
+ {
+ e.Trigger();
+ }
+
+ if(room == e.Room || e.Room == 0xFF)
+ {
+ if(e.Accuracy == LoadEventAccuracy::Stage_Room)
+ {
+ e.Trigger();
+ }
+
+ if(spawn == e.Spawn || e.Spawn == 0xFF)
+ {
+ if(e.Accuracy == LoadEventAccuracy::Stage_Room_Spawn)
+ {
+ e.Trigger();
+ }
+
+ if(state == e.State || e.State == 0xFF)
+ {
+ if(e.Accuracy == LoadEventAccuracy::Stage_Room_Spawn_State)
+ {
+ e.Trigger();
+ }
+
+ if(eventid == e.Eventid)
+ {
+ // No accuracy check since it's already ::All
+ e.Trigger();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/source/source/game_patches.cpp b/source/source/game_patches.cpp
new file mode 100644
index 0000000..8afc1c6
--- /dev/null
+++ b/source/source/game_patches.cpp
@@ -0,0 +1,770 @@
+#include "game_patches.h"
+#include "defines.h"
+#include "stage.h"
+#include "tools.h"
+#include "singleton.h"
+
+#include <tp/d_menu_collect.h>
+#include <tp/d_a_alink.h>
+#include <tp/d_save.h>
+#include <tp/d_item.h>
+#include <tp/JFWSystem.h>
+#include <tp/d_com_inf_game.h>
+#include <tp/evt_control.h>
+#include <cstring>
+#include <cstdio>
+
+
+namespace mod::cutscene_skip
+{
+ /**
+ * Runs when master sword CS is skipped
+ */
+ s32 onMasterSwordSkip(void* unk, s32 unk2)
+ {
+ game_patch::giveMasterSword();
+ game_patch::giveMidna();
+ game_patch::giveMidnaTransform();
+
+ gameInfo.nextStageVars.nextSpawnPoint = 0x96;
+
+ tools::triggerSaveLoad(stage::allStages[Stage_Sacred_Grove], 0x1, 0x96);
+
+ // Call actual skip function
+ return tp::evt_control::defaultSkipStb(unk, unk2);
+ }
+}
+
+namespace mod::game_patch
+{
+
+ void assemblyOverwrites()
+ {
+ // Default to US/JP
+ u32* enableCrashScreen = reinterpret_cast<u32*>(0x8000B8A4);
+
+ // Get the addresses to overwrite
+ #ifdef TP_US
+ enableCrashScreen = reinterpret_cast<u32*>(0x8000B8A4);
+ #elif defined TP_EU
+ enableCrashScreen = reinterpret_cast<u32*>(0x8000B878);
+ #elif defined TP_JP
+ enableCrashScreen = reinterpret_cast<u32*>(0x8000B8A4);
+ #endif
+
+ // Perform the overwrites
+
+ /* If the address is loaded into the cache before the overwrite is made,
+ then the cache will need to be cleared after the overwrite */
+
+ // Enable the crash screen
+ *enableCrashScreen = 0x48000014; // b 0x14
+ }
+
+ void killLinkHouseSpider()
+ {
+ // Kill Skulltula at Link's house
+ gameInfo.localAreaNodes.unk_0[0xA] |= 0x1;
+ }
+
+ void increaseClimbSpeed()
+ {
+ // Adjust Link's climbing speeds
+ tp::d_a_alink::LadderVars* LadderVars = &tp::d_a_alink::ladderVars;
+ LadderVars->ladderClimbInitSpeed = 1.8;
+ LadderVars->ladderReachTopClimbUpSpeed = 1.765;
+ LadderVars->ladderTopStartClimbDownSpeed = 1.8;
+ LadderVars->ladderBottomGetOffSpeed = 1.8;
+ LadderVars->ladderClimbSpeed = 1.575;
+ LadderVars->wallClimbHorizontalSpeed = 2.0;
+ LadderVars->wallClimbVerticalSpeed = 1.875;
+ }
+
+ void removeIBLimit()
+ {
+ if (!tp::d_a_alink::checkStageName("D_MN07A"))
+ {
+ // li 0
+ u32 li = 0x38600000;
+ // b +4C
+ u32 b = 0x4800004C;
+
+ // CheckHeavyState overwrite
+ u32 checkHeavyStateOnAddress = reinterpret_cast<u32>(&tp::d_a_alink::checkHeavyStateOn);
+ *reinterpret_cast<u32*>(checkHeavyStateOnAddress + 0x84) = li;
+
+ u32 setStickDataAddress = reinterpret_cast<u32>(&tp::d_a_alink::setStickData);
+ *reinterpret_cast<u32*>(setStickDataAddress + 0x5FC) = b;
+ }
+ }
+
+ void increaseWalletSize()
+ {
+ // li
+ u32 li = 0x38600000;
+ u32 cmpwi = 0x2c000000;
+
+ u32 getRupeeMaxAddress = reinterpret_cast<u32>(&tp::d_save::getRupeeMax);
+ u32 setWalletMaxNumAddress = reinterpret_cast<u32>(&tp::d_menu_collect::setWalletMaxNum);
+
+ // 300 -> 1000
+ *reinterpret_cast<u32*>(getRupeeMaxAddress + 0x30) = li | 0x000003E8;
+
+ // 600 -> 5000
+ *reinterpret_cast<u32*>(getRupeeMaxAddress + 0x38) = li | 0x00001388;
+
+ // 1000 -> 9999 (> 4 digit not good)
+ *reinterpret_cast<u32*>(getRupeeMaxAddress + 0x40) = li | 0x0000270F;
+
+ // 600 -> 5000
+ *reinterpret_cast<u32*>(setWalletMaxNumAddress + 0x18) = cmpwi | 0x00001388;
+
+ // 300 -> 1000
+ *reinterpret_cast<u32*>(setWalletMaxNumAddress + 0x24) = cmpwi | 0x000003E8;
+
+ // 1000 -> 9999
+ *reinterpret_cast<u32*>(setWalletMaxNumAddress + 0x30) = cmpwi | 0x0000270F;
+ }
+
+ void skipSewers()
+ {
+ if (Singleton::getInstance()->isSewerSkipEnabled == 1)
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Skipping Sewers");
+
+ // Set sewers flags
+ giveMidna();
+ giveSense();
+
+ // We should be wolf
+ setFirstTimeWolf();
+
+ // Set sewers flags (escaped cell cs, Midna intro cs, unchained wolf link, zelda cutscene, First trip to Sewers Done)
+ gameInfo.scratchPad.eventBits[0x05] |= 0x7A;
+
+ // Set more sewers flags (talk to midna after escaping cell in sewers, listened to first guard in sewers)
+ gameInfo.scratchPad.eventBits[0x1A] |= 0x82;
+
+ // Set more sewers flags (spawned into sewers twilight as wolf)
+ gameInfo.scratchPad.eventBits[0x4D] |= 0x8;
+
+ gameInfo.scratchPad.equipedItems.sword = 0x3F;
+
+ // Load back to Ordon Spring
+ tools::triggerSaveLoad(stage::allStages[Stage_Ordon_Spring], 0x1, 0x3, 0x4);
+ }
+ gameInfo.scratchPad.equipedItems.sword = 0x3F;
+ }
+
+ void setFieldBits()
+ {
+ if ((Singleton::getInstance()->isGateUnlockEnabled == 1 && (gameInfo.localAreaNodes.unk_0[0x8] & 0x10) == 0) || tools::checkItemFlag(ItemFlags::Gate_Keys))
+ {
+ 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()
+ {
+ if (tp::d_com_inf_game::current_state == 0x63)
+ {//goats 1
+ if (Singleton::getInstance()->isGoatSkipEnabled == 1)
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Skipping Goats 1");
+
+ // Load back to Ordon ranch after goats 1
+ tools::triggerSaveLoad(stage::allStages[Stage_Ordon_Ranch], 0x0, 0x4, 0x7);
+ }
+ }
+ else if (tp::d_com_inf_game::current_state == 0x39)
+ {//goats 2
+ if (Singleton::getInstance()->isGoatSkipEnabled == 1)
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Skipping Goats 2");
+
+ gameInfo.localAreaNodes.unk_0[0xE] |= 0x2;//set flag for Fado text before goats
+ gameInfo.localAreaNodes.unk_0[0x9] |= 0x60;//set flag for day 3 intro cs and goats 2 done
+ //gameInfo.localAreaNodes.unk_0[0x9] |= 0x40;//set flag for day 3 intro cs and goats 2 done
+
+
+ // Load back to Ordon village
+ tools::triggerSaveLoad(stage::allStages[Stage_Ordon_Village], 0x0, 0x19, 0x8);
+ }
+ }
+ }
+
+ void setBublinState()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "state was not 1");
+ if (gameInfo.nextStageVars.nextRoom != 3)
+ {
+ if (gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.bossBeaten == 0b1)
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Setting Bublin State");
+ // reload bublin camp as state 3
+ //tools::triggerSaveLoad(gameInfo.nextStageVars.nextStage, gameInfo.nextStageVars.nextRoom, gameInfo.nextStageVars.nextSpawnPoint, a);
+ gameInfo.nextStageVars.nextState = 0x3;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ void setGroveFlags()
+ {
+ if (Singleton::getInstance()->isMSPuzzleSkipEnabled == 1 && (gameInfo.localAreaNodes.unk_0[0xB] & 0x4) == 0)
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "Skipping MS Puzzle");
+ gameInfo.localAreaNodes.unk_0[0xB] |= 0x4;//skip Sacred Grove Puzzle
+ }
+ }
+
+ void checkBossKeysey()
+ {
+ if (Singleton::getInstance()->isBossKeyseyEnabled == 1)
+ {
+ tp::d_com_inf_game::AllAreaNodes* dungeonAreaNodesPtr = &gameInfo.scratchPad.allAreaNodes;
+ dungeonAreaNodesPtr->Forest_Temple.dungeon.bigKeyGotten = 0b1; //unlock Diababa Door
+ dungeonAreaNodesPtr->Goron_Mines.dungeon.bigKeyGotten = 0b1; //unlock Fryus Door
+ dungeonAreaNodesPtr->Lakebed_Temple.dungeon.bigKeyGotten = 0b1; //unlock Morpheel Door
+ dungeonAreaNodesPtr->Arbiters_Grounds.dungeon.bigKeyGotten = 0b1; //unlock Stallord Door
+ dungeonAreaNodesPtr->Snowpeak_Ruins.dungeon.bigKeyGotten = 0b1; //unlock Blizzetta Door
+ dungeonAreaNodesPtr->Temple_of_Time.dungeon.bigKeyGotten = 0b1; //unlock Armaghoma Door
+ dungeonAreaNodesPtr->City_in_the_Sky.dungeon.bigKeyGotten = 0b1; //unlock Argorok Door
+ dungeonAreaNodesPtr->Palace_of_Twilight.dungeon.bigKeyGotten = 0b1; //unlock Zant Door
+ dungeonAreaNodesPtr->Hyrule_Castle.dungeon.bigKeyGotten = 0b1; //unlock Ganon Door
+ }
+ }
+
+ /* Still in the works
+ void unlockDungeonDoors()
+ {
+ if (Singleton::getInstance()->isMSPuzzleSkipEnabled == 1 && (gameInfo.localAreaNodes.unk_0[0xB] & 0x4) == 0)
+ {
+ //Forest Temple
+ allAreaNodesPtr->Forest_Temple.unk_0[0xA] |= 0x8; //unlock Second Monkey Door
+ allAreaNodesPtr->Forest_Temple.unk_0[0xB] |= 0x80; //unlock Gale Puzzle Monkey Door
+
+ //Goron Mines
+
+
+ //Lakebed Temple
+
+ //Arbiter's Grounds
+
+ //Snowpeak Ruins
+
+ //Temple of Time
+
+ //City in the Sky
+
+ //Palace of Twilight
+
+ //Hyrule Castle
+ }
+ }*/
+
+ void earlyCiTS()
+ {
+ if (Singleton::getInstance()->isEarlyCiTSEnabled == 1)
+ {
+ gameInfo.scratchPad.eventBits[0x3B] |= 0x8; //repairs Cannon at lake
+ }
+ }
+
+ void earlyDesert()
+ {
+ if (Singleton::getInstance()->isEarlyDesertEnabled == 1 && gameInfo.scratchPad.eventBits[0x26] < 0x80 && tools::checkItemFlag(ItemFlags::Shadow_Crystal))
+ {
+ gameInfo.scratchPad.eventBits[0x26] |= 0x80; //Allow you to use the cannon in the desert
+ }
+ }
+
+ void accessDesert()
+ {
+ if (tools::checkItemFlag(ItemFlags::Shadow_Crystal))
+ {
+ return;
+ }
+ else
+ {
+ strncpy(gameInfo.nextStageVars.nextStage, stage::allStages[Stage_Lake_Hylia], sizeof(gameInfo.nextStageVars.nextStage) - 1);
+ gameInfo.nextStageVars.nextRoom = 0x0;
+ gameInfo.nextStageVars.nextSpawnPoint = 0x4D;
+ tp::d_item::execItemGet(0x2);
+ }
+ }
+
+ void skipCartEscort()
+ {
+ 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);
+ }
+ }
+
+ void setEscortState()
+ {
+ if ((gameInfo.scratchPad.eventBits[0x8] & 0x40) == 0 && tools::checkItemFlag(ItemFlags::Heros_Bow) && tools::checkItemFlag(ItemFlags::Boomerang) && gameInfo.scratchPad.clearedTwilights.Lanayru == 0b1)
+ {
+ gameInfo.nextStageVars.nextState = 0x8;
+ gameInfo.nextStageVars.nextSpawnPoint = 0x14;
+ }
+ }
+
+ void setFirstTimeWolf()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Set first time wolf");
+
+ gameInfo.scratchPad.unk_1F[0x11] |= 1;
+ }
+
+ void setLanayruWolf()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Set wolf");
+
+ if (gameInfo.scratchPad.form == 0 && !tools::checkItemFlag(ItemFlags::Shadow_Crystal) && !tools::checkItemFlag(ItemFlags::Vessel_Of_Light_Lanayru))
+ {
+
+ strncpy(gameInfo.nextStageVars.nextStage, stage::allStages[Stage_Hyrule_Field], sizeof(gameInfo.nextStageVars.nextStage) - 1);
+ gameInfo.nextStageVars.nextRoom = 0x9;
+ gameInfo.nextStageVars.nextSpawnPoint = 0xA;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ void setHuman()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Set human");
+
+ gameInfo.scratchPad.form = 0;
+ }
+
+ void setWolf()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Set wolf");
+
+ gameInfo.scratchPad.form = 1;
+ }
+
+ void giveSense()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Give Senses");
+
+ // Set the Sense (sewers) flag
+ gameInfo.scratchPad.eventBits[0x43] |= 0x8;
+ }
+
+ void giveEpona()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Give Epona");
+
+ // Set Epona tamed
+ gameInfo.scratchPad.eventBits[0x6] |= 0x1;
+ }
+
+ void giveMasterSword()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Give MasterSword");
+
+ // Set Master sword inventory flag
+ tools::setItemFlag(ItemFlags::Master_Sword);
+
+ // Equip Master sword (0x49 / 73)
+ gameInfo.scratchPad.equipedItems.sword = 0x49;
+ }
+
+ void giveMidna()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Give Midna (sewers)");
+
+ // Set Midna sewers flag
+ gameInfo.scratchPad.eventBits[0xC] |= 0x10;
+ }
+
+ void giveMidnaTransform()
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> Give Midna Transform");
+
+ // Set Midna Transform flag (gets set at Master Sword)
+ gameInfo.scratchPad.eventBits[0xD] |= 0x4;
+ }
+
+ void handleMaloShop()
+ {
+ tp::d_com_inf_game::AreaNodes* maloLocalAreaNodesPtr = &gameInfo.localAreaNodes;
+ //hylian shield check
+ if ((gameInfo.scratchPad.eventBits[0xA] & 0x8) != 0)//KB1 done
+ {
+ if (!tools::checkItemFlag(ItemFlags::Null_D9))
+ {
+ strcpy(sysConsolePtr->consoleLine[20].line, "-> selling hylian shield");
+ maloLocalAreaNodesPtr->unk_0[0xC] &= ~0x2;//unset flag for hylian shield bought
+ maloLocalAreaNodesPtr->unk_0[0x13] |= 0x40;//set flag for hylian shield on counter
+ maloLocalAreaNodesPtr->unk_0[0x15] &= ~0x40;//unset flag for red potion on right
+ }
+ else
+ {
+ maloLocalAreaNodesPtr->unk_0[0xC] |= 0x2;//set flag for hylian shield bought
+ 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 (!tools::checkItemFlag(ItemFlags::Null_D8))
+ {
+ maloLocalAreaNodesPtr->unk_0[0xC] |= 0x40;//set flag for hawkeye on counter
+ maloLocalAreaNodesPtr->unk_0[0xC] &= ~0x20;//unset flag for arrows on counter (else causes crash)
+ maloLocalAreaNodesPtr->unk_0[0xD] &= ~0x8;//unset flag for hawkeye sold out
+ maloLocalAreaNodesPtr->unk_0[0x15] &= ~0x10;//unset flag for red potion on left
+ }
+ else
+ {
+ maloLocalAreaNodesPtr->unk_0[0xC] &= ~0x40;//unset flag for hawkeye on counter
+ if (tools::checkItemFlag(ItemFlags::Null_D9))
+ {
+ maloLocalAreaNodesPtr->unk_0[0xC] |= 0x20;//set flag for arrows on counter
+ maloLocalAreaNodesPtr->unk_0[0x15] |= 0x40;//set flag for red potion on right
+ maloLocalAreaNodesPtr->unk_0[0x15] &= ~0x10;//unset flag for red potion on left
+ maloLocalAreaNodesPtr->unk_0[0xD] |= 0x8;//set flag for hawkeye sold out
+ }
+ else
+ {
+ maloLocalAreaNodesPtr->unk_0[0xC] &= ~0x20;//unset flag for arrows on counter
+ maloLocalAreaNodesPtr->unk_0[0x15] &= ~0x40;//unset flag for red potion on right
+ maloLocalAreaNodesPtr->unk_0[0x15] |= 0x10;//set flag for red potion on left
+ maloLocalAreaNodesPtr->unk_0[0xD] &= ~0x8;//unset flag for hawkeye sold out
+
+ }
+ }
+ }
+ }
+
+ void skipMDH()
+ {
+ if (Singleton::getInstance()->isMDHSkipEnabled == 1)
+ {
+ strncpy(gameInfo.nextStageVars.nextStage, stage::allStages[Stage_Lake_Hylia], sizeof(gameInfo.nextStageVars.nextStage) - 1);
+ gameInfo.nextStageVars.nextSpawnPoint = 0x7;
+ gameInfo.nextStageVars.nextRoom = 0x0;
+
+ }
+ }
+
+ void skipTextAndCS()
+ {
+ //Set Scratchpad Pointer
+ tp::d_com_inf_game::ScratchPad* scratchPadPtr = &gameInfo.scratchPad;
+
+ //Set Letters Pointer
+ tp::d_com_inf_game::Letters* LettersPtr = &scratchPadPtr->recivedLetters;
+ LettersPtr->From_Wife_of_Yeto = 0b1;
+ LettersPtr->Update = 0b1;
+ LettersPtr->Now_open_for_business = 0b1;
+ LettersPtr->Agithas_Dream = 0b1;
+ LettersPtr->Hey_kid = 0b1;
+ LettersPtr->Challenge_for_you = 0b1;
+ LettersPtr->They_came_so_quickly = 0b1;
+ LettersPtr->Heroes_come_together = 0b1;
+ LettersPtr->URGENT_Bomb_arrows = 0b1;
+ LettersPtr->Rare_item_in_stock = 0b1;
+ LettersPtr->Good_stuff_inside = 0b1;
+ LettersPtr->URGENT_NOTICE = 0b1;
+ LettersPtr->Post_office_notice = 0b1;
+ LettersPtr->Dear_Adventurer_1 = 0b1;
+ LettersPtr->Dear_Adventurer_2 = 0b1;
+ LettersPtr->About_Ilias_memory = 0b1;
+
+ //Set Event Bits
+ u8* eventBitsPtr = &scratchPadPtr->eventBits[0];
+ eventBitsPtr[0x1] |= 0x40; //talked to Yeto First Time
+ eventBitsPtr[0x3] |= 0x90; //Jaggle Calls out to link, talked to squirrel as wolf in Ordon
+ 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)
+ eventBitsPtr[0x1B] |= 0x78; //skip the monkey escort
+ eventBitsPtr[0x1D] = 0x40; //fight bublin after Fyer
+ eventBitsPtr[0x22] |= 0x1; //Plumm initial CS watched
+ eventBitsPtr[0x26] |= 0x2; //Talked to Yeto on Snowpeak
+ eventBitsPtr[0x37] |= 0x4; // Postman Twilight Text
+ eventBitsPtr[0x38] |= 0x6; //Enter Hena Cabin CS
+ 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;
+
+ 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[0xF] |= 0xC; //rusl talking to wife CS
+ allAreaNodesPtr->Ordon.unk_0[0x17] |= 0x80; //enter village as wolf CS
+
+ allAreaNodesPtr->Sewers.unk_0[0x8] |= 0x38; //wake up in Jail CS, text after first gate, text after rooftops
+ allAreaNodesPtr->Sewers.unk_0[0x9] |= 0x18; //midna cs after digging out, midna intro cs
+ allAreaNodesPtr->Sewers.unk_0[0xA] |= 0x41; //zelda tower intro cs, outside top door intro cs
+ allAreaNodesPtr->Sewers.unk_0[0xB] |= 0x38; //other side of fence cs, top of stairway cs watched, stairway intro cs
+ allAreaNodesPtr->Sewers.unk_0[0xF] |= 0x11; //midna cs after digging out watched, midna text when approaching first rooftop guard
+
+ allAreaNodesPtr->Eldin.unk_0[0x9] |= 0x40;//goron mines DM cs
+ allAreaNodesPtr->Eldin.unk_0[0x14] |= 1;//give midna jumps for top of sanctuary
+ allAreaNodesPtr->Eldin.unk_0[0x10] |= 0x10;//skip Graveyard CS
+ allAreaNodesPtr->Eldin.unk_0[0x11] |= 0x8;//midna text after meteor
+ allAreaNodesPtr->Eldin.unk_0[0x13] |= 0x20;//skip Kak CS
+
+ 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[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
+
+ allAreaNodesPtr->Hyrule_Field.unk_0[0xB] |= 0x60; //cutscene before eldin twilight and Lanayru twilight
+ allAreaNodesPtr->Hyrule_Field.unk_0[0xD] |= 0x80; //midna text after warping gorge bridge
+ 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[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
+
+ allAreaNodesPtr->Sacred_Grove.unk_0[0x8] |= 0x38; //lost woods intro cs, human block cs, midna text after human block
+
+ allAreaNodesPtr->Snowpeak.unk_0[0x8] |= 0x4; //Mountiain top CS
+ allAreaNodesPtr->Snowpeak.unk_0[0xB] |= 0x3; //Snowpeak Entrance CS, midna text in front of SPR
+
+ allAreaNodesPtr->Castle_Town.unk_0[0xA] |= 0x4; //STAR Tent CS
+ allAreaNodesPtr->Castle_Town.unk_0[0xF] |= 0x4; //Jovani House CS
+
+ allAreaNodesPtr->Gerudo_Desert.unk_0[0x13] |= 0x40;//watched the CS when entering the desert
+ allAreaNodesPtr->Gerudo_Desert.unk_0[0xA] |= 0x10;//Mirror Chamber Intro CS
+
+ allAreaNodesPtr->Forest_Temple.unk_0[0x8] |= 0x61; //set Midna Text for Ook Bridge Broken, Boomerang, and freeing first monkey
+ allAreaNodesPtr->Forest_Temple.unk_0[0x9] |= 0x40; //Ook Bridge Broken
+ allAreaNodesPtr->Forest_Temple.unk_0[0xA] |= 0x3; //Boko bridge CS, one bridge CS
+ allAreaNodesPtr->Forest_Temple.unk_0[0xE] |= 0x22; //Diababa CS, Worm Bridge CS, second monkey CS
+ allAreaNodesPtr->Forest_Temple.unk_0[0xF] |= 0xE; //Midna text for pre-diababa room and open room monkey, Big Baba CS
+ allAreaNodesPtr->Forest_Temple.unk_0[0x10] |= 0x14; //Midna text for compass, eat open area bridge CS
+ allAreaNodesPtr->Forest_Temple.unk_0[0x14] |= 0x1; //Ook Miniboss CS
+ allAreaNodesPtr->Forest_Temple.unk_0[0x16] |= 0x2; //Entrance CS watched
+
+ allAreaNodesPtr->Goron_Mines.unk_0[0x8] |= 0x1F; //upper magnet CS, first room switch 3 cs, first room switch 2 cs, outside bridge cs, crystal switch bridge cs
+ allAreaNodesPtr->Goron_Mines.unk_0[0x9] |= 0x20; // bottom magnet cs
+ allAreaNodesPtr->Goron_Mines.unk_0[0xD] |= 0x80; //outside magnet cs
+ allAreaNodesPtr->Goron_Mines.unk_0[0xE] |= 0x30; //enter tall room cs
+ allAreaNodesPtr->Goron_Mines.unk_0[0xF] |= 0x20; //open room CS
+ allAreaNodesPtr->Goron_Mines.unk_0[0x10] |= 0xCC; //lava slug room cs, outside area beamos wall cs, second magnet in crystal switch cs, crystal switch room gate
+ allAreaNodesPtr->Goron_Mines.unk_0[0x11] |= 0xB8; //opening cs, first room gate cs, first room switch 1 cs, water room magnet cs
+ allAreaNodesPtr->Goron_Mines.unk_0[0x17] |= 0xF; //lava slug room cs watched, lava slug room flag, tall room CS flags
+
+ allAreaNodesPtr->Lakebed_Temple.unk_0[0x8] |= 0x2; //stalactite midna text
+ allAreaNodesPtr->Lakebed_Temple.unk_0[0xF] |= 0x3; //one gear room spinning cs, two gear room spinning cs
+ allAreaNodesPtr->Lakebed_Temple.unk_0[0x14] |= 0x7; //main room cs, front bridge cs, opening cs
+ allAreaNodesPtr->Lakebed_Temple.unk_0[0x15] |= 0x20; //staircase turn CS
+ allAreaNodesPtr->Lakebed_Temple.unk_0[0x16] |= 0x8; // chu worm cs watched
+
+ allAreaNodesPtr->Arbiters_Grounds.unk_0[0xB] |= 0x20; //spinner wall cs
+ allAreaNodesPtr->Arbiters_Grounds.unk_0[0xE] |= 0x10; //opening CS
+ allAreaNodesPtr->Arbiters_Grounds.unk_0[0x12] |= 0x8; //cs after raising rails
+
+ allAreaNodesPtr->Snowpeak_Ruins.unk_0[0x10] |= 0x30; //enter cannonball room cs, unlock door to yeto
+ allAreaNodesPtr->Snowpeak_Ruins.unk_0[0x14] |= 0x41; //entrance cs, midna text after bedroom key
+ allAreaNodesPtr->Snowpeak_Ruins.unk_0[0x15] |= 0x2A; //freezard tower cs, enter NE room cs watched, East Courtyard Dig CS
+ allAreaNodesPtr->Snowpeak_Ruins.unk_0[0x16] |= 0x28; //midna text after cheese and pumpkin
+
+ allAreaNodesPtr->Temple_of_Time.unk_0[0x8] |= 0x80; //Midna text about missing statue
+ allAreaNodesPtr->Temple_of_Time.unk_0[0x9] |= 0x3C; //scales cs, entrance cs, scales move cs
+ allAreaNodesPtr->Temple_of_Time.unk_0[0xA] |= 0x8; //statue move cs watched
+ allAreaNodesPtr->Temple_of_Time.unk_0[0xF] |= 0x8; //gate outside darknut cs
+ allAreaNodesPtr->Temple_of_Time.unk_0[0x12] |= 0xEE; //first room switch cs, 8f hall switch cs, before darknut gate open cs, elevator room switches cs, 3F hall switch cs, 2F hall switch cs
+ allAreaNodesPtr->Temple_of_Time.unk_0[0x14] |= 0x4; //darknut room gate open cs
+
+ allAreaNodesPtr->City_in_the_Sky.unk_0[0xC] |= 0xF; //fan tower cs, room before aerolfos, first room exit cs, entrance cs
+ allAreaNodesPtr->City_in_the_Sky.unk_0[0xD] |= 0x6; // west bridge extended cs, east bridge extended cs
+
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0x9] |= 0x4; //Phantom zant 1 cs watched
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0xB] |= 0x2; //Entrance CS watched
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0xC] |= 0x82; //Midna Text when west hand seals sol, Light Sword CS
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0xD] |= 0x1; //Midna text after forced transform
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0xE] |= 0xB0; //Midna text after west hand drops sol, midna text about transformed twili, midna text after post zant save
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0xF] |= 0xC0; //Midna text after light sword, midna text after west sol in slot
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0x12] |= 0x4; // midna text after re-entering west after sol stolen
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0x13] |= 0x2; //midna text after entrance cs
+ allAreaNodesPtr->Palace_of_Twilight.unk_0[0x16] |= 0x10; //watched EW 2nd room stairs CS
+
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x9] |= 0x1; //graveyard entrance cs
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x11] |= 0xC; //east wing cs
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0xe] |= 0x1; //midna text after outside gale
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x10] |= 0x24; //entrance cs, chandelier room east cs watched
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x13] |= 0x40; // Darknuts room CS
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x14] |= 0xB; //Midna text post KB4, lizalfos Room CS, midna text after graveyard SK
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x16] |= 0x1; //lone darknut room se torch cs
+ allAreaNodesPtr->Hyrule_Castle.unk_0[0x17] |= 0x80; //lone darknut room me torch watched
+
+ //Set Local Area Node flags
+ tp::d_com_inf_game::AreaNodes* csLocalAreaNodesPtr = &gameInfo.localAreaNodes;
+ csLocalAreaNodesPtr->unk_0[0x8] = 0xFF;//give midna jumps in mist area
+ csLocalAreaNodesPtr->unk_0[0xC] |= 0x80;//set flag for midna to think you followed the monkey in the mist
+ csLocalAreaNodesPtr->unk_0[0x12] |= 0x4;//mark read the midna text when you warp to N Faron for bridge
+ csLocalAreaNodesPtr->unk_0[0xF] |= 0x8;//set flag for midna text after twilight
+ csLocalAreaNodesPtr->unk_0[0xE] |= 0x9;//cs after entering Faron,spring cs with spirit
+
+ //Apply Randomizer Options
+ checkBossKeysey();
+ earlyCiTS();
+ earlyDesert();
+
+ //Apply Overrides for custom chests
+ gameInfo.scratchPad.eventBits[0x22] |= 0x4;/*Got Ilia's Charm from Impaz*/
+ gameInfo.scratchPad.eventBits[0x49] |= 0x2;/*Bought Slingshot from Sera*/
+
+ if (Singleton::getInstance()->isIntroSkipped == 1)
+ {
+ //set Ordon Days 1,2, and 3 Flags
+ allAreaNodesPtr->Ordon.unk_0[0x3] |= 0x1; //Gave cradle to Uli, got Fishing Rod from uli
+ eventBitsPtr[0x4] |= 0x4; //Talked to Uli Day 1
+ allAreaNodesPtr->Ordon.unk_0[0x9] |= 0x40; //Goats 2 done
+ allAreaNodesPtr->Ordon.unk_0[0xC] |= 0x1A; //Day 2 CS watched, Goats 1 done, spawn wooden sword chest
+ eventBitsPtr[0x45] |= 0x10; //Saved Talo
+ eventBitsPtr[0x46] |= 0x11; //Came Back to Links House with Epona Day 1, took cradle from monkey
+ eventBitsPtr[0x47] |= 0x2F; //Called Epona and Talked to everyone
+ eventBitsPtr[0x48] |= 0x10; //Talked to Sera
+ eventBitsPtr[0x62] |= 0x80; //Talked to Colin Day 1
+ eventBitsPtr[0x4A] |= 0x60; //Day 1 done, sword training done
+
+ eventBitsPtr[0x2] |= 0x40; //Slingshot and 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
+
+ tools::setItemFlag(ItemFlags::Heros_Clothes);
+
+
+
+ if (Singleton::getInstance()->isSewerSkipEnabled == 1)
+ {
+ // Set sewers flags (escaped cell cs, Midna intro cs, unchained wolf link, zelda cutscene, First trip to Sewers Done)
+ // Set more sewers flags (talk to midna after escaping cell in sewers, listened to first guard in sewers)
+ gameInfo.scratchPad.eventBits[0x1A] |= 0x82;
+
+ // Set more sewers flags (spawned into sewers twilight as wolf)
+ gameInfo.scratchPad.eventBits[0x4D] |= 0x8;
+
+ 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[0x5] = 0xFF; //Ensure Epona is Stolen, give Midna Charge
+ eventBitsPtr[0x6] |= 0x10; //Faron Twilight Progression flag
+ 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 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 sewers flags
+ giveMidna();
+ giveSense();
+
+ // Set sewers flags (zelda cutscenes, unchained wolf link, bla)
+ eventBitsPtr[0x05] |= 0x7A;
+
+ //Unlock Map Regions
+ scratchPadPtr->movingActors.exploredRegions.Snowpeak = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Desert = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Lanayru = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Eldin = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Faron = 0b1;
+ scratchPadPtr->movingActors.exploredRegions.Ordon = 0b1;
+
+ //Unlock Warps
+ allAreaNodesPtr->Ordon.unk_0[0xD] = 0x10; // give Ordon Spring Warp
+ gameInfo.localAreaNodes.unk_0[0x13] = 0x80;//give S faron warp
+ gameInfo.localAreaNodes.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->Lanayru.unk_0[0xB] |= 0x4; // give Zora's Domain Warp
+ allAreaNodesPtr->Lanayru.unk_0[0xA] |= 0x4;//give lake hylia warp
+ }
+ }
+
+ //Set Other Flags
+ 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
+
+
+ //Faron Escape
+ if (Singleton::getInstance()->isForestEscapeEnabled == 1)
+ {
+ eventBitsPtr[0x6] |= 0x26; //warp the kak bridge, give map warp, set Forest Temple Story Flag
+ }
+ else
+ {
+ eventBitsPtr[0x6] |= 0x24; //warp the kak bridge, give map warp
+ }
+
+ //Start Link in His House
+ strncpy(gameInfo.nextStageVars.nextStage, stage::allStages[Stage_Ordon_Interiors], sizeof(gameInfo.nextStageVars.nextStage) - 1);
+ gameInfo.nextStageVars.nextRoom = 0x4;
+ gameInfo.nextStageVars.nextSpawnPoint = 0x4;
+ }
+ else
+ {
+ //Set Other Flags
+ 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
+ }
+ }
+} \ No newline at end of file
diff --git a/source/source/grottoChecks.cpp b/source/source/grottoChecks.cpp
new file mode 100644
index 0000000..7b5cf37
--- /dev/null
+++ b/source/source/grottoChecks.cpp
@@ -0,0 +1,104 @@
+#include "grottoChecks.h"
+#include "defines.h"
+
+
+namespace mod::grottoChecks
+{
+ u16 g1_0[1]//Lanayru2
+ {
+ 73
+ };
+ u16 g1_1[2]//Eldin2
+ {
+ 121,
+ 122
+ };
+ u16 g1_2[1]//Ordon
+ {
+ 167
+ };
+ u16 g1_3[2]//Lanayru3
+ {
+ 434,//poe 30
+ 435//poe 31
+ };
+
+ u16 g2_0[3]//Eldin4
+ {
+ 163,
+ 164,
+ 165
+ };
+ u16 g2_1[3]//Faron1
+ {
+ 111,
+ 112,
+ 113
+ };
+ u16 g2_2[1]//Sacred
+ {
+ 72
+ };
+ /*u16 g2_3[0]//Eldin1
+ {
+
+ };*/
+
+ u16 g3_0[3]//Gerudo3
+ {
+ 132,
+ 420,//poe 16
+ 421//poe 17
+ };
+ /*u16 g3_1[0]//Gerudo2
+ {
+
+ };*/
+ /*u16 g3_2[0]//Snowpeak2
+ {
+
+ };*/
+ /*u16 g3_3[0]//Lanayru5
+ {
+
+ };*/
+
+ u16 g4_0[1]//Lanayru6
+ {
+ 108
+ };
+ u16 g4_1[1]//Gerudo1
+ {
+ 124
+ };
+ u16 g4_2[1]//Snowpeak1
+ {
+ 189
+ };
+ u16 g4_3[1]//Lanayru4
+ {
+ 105
+ };
+
+ u16 g5_0[1]//Lanayru1
+ {
+ 120
+ };
+ /*u16 g5_1[0]//Faron2
+ {
+
+ };*/
+ u16 g5_2[1]//Lake2
+ {
+ 89
+ };
+ u16 g5_3[1]//Eldin3
+ {
+ 123
+ };
+ u16 g5_4[1]//Lake1
+ {
+ 102
+ };
+
+} \ No newline at end of file
diff --git a/source/source/item.cpp b/source/source/item.cpp
new file mode 100644
index 0000000..98a273d
--- /dev/null
+++ b/source/source/item.cpp
@@ -0,0 +1,118 @@
+#include "item.h"
+#include "items.h"
+#include "defines.h"
+#include <tp/d_com_inf_game.h>
+
+namespace mod::item
+{
+ u8 itemGetAnimationFlags[10] =
+ {
+ static_cast<u8>(ItemFlags::Blue_Rupee),
+ static_cast<u8>(ItemFlags::Yellow_Rupee),
+ static_cast<u8>(ItemFlags::Red_Rupee),
+ static_cast<u8>(ItemFlags::Purple_Rupee),
+ static_cast<u8>(ItemFlags::Orange_Rupee),
+ static_cast<u8>(ItemFlags::Seeds_50),
+ static_cast<u8>(ItemFlags::Arrows_30),
+ static_cast<u8>(ItemFlags::Arrows_20),
+ static_cast<u8>(ItemFlags::Arrows_10),
+ static_cast<u8>(ItemFlags::Arrows_1),
+ };
+ u32 getFlags(u8 item, u32 currentPlayerConditions)
+ {
+ u32 flags = currentPlayerConditions;
+ switch(item)
+ {
+ case items::Item::Lantern:
+ flags |= item::Condition::Lantern;
+ break;
+
+ case items::Item::Iron_Boots:
+ flags |= item::Condition::Iron_Boots;
+ break;
+
+ case items::Item::Boomerang:
+ flags |= item::Condition::Boomerang;
+ break;
+
+ case items::Item::Slingshot:
+ flags |= item::Condition::Slingshot;
+ break;
+
+ case items::Item::Heros_Bow:
+ flags |= item::Condition::Bow;
+ break;
+
+ case items::Item::Goron_Bomb_Bag:
+ flags |= item::Condition::Bombs;
+ flags |= item::Condition::Water_Bombs;
+ break;
+
+ case items::Item::Bomb_Bag_Regular_Bombs:
+ flags |= item::Condition::Bombs;
+ flags |= item::Condition::Water_Bombs;
+ break;
+
+ case items::Item::Ball_and_Chain:
+ flags |= item::Condition::Ball_And_Chain;
+ break;
+
+ case items::Item::Clawshot:
+ flags |= item::Condition::Clawshot;
+ break;
+
+ case items::Item::Clawshots:
+ flags |= item::Condition::Double_Clawshot;
+ break;
+
+ case items::Item::Spinner:
+ flags |= item::Condition::Spinner;
+ break;
+
+ case items::Item::Dominion_Rod_Uncharged:
+ flags |= item::Condition::Dominion_Rod;
+ break;
+
+ case items::Item::Zora_Armor:
+ flags |= item::Condition::Zora_Armor;
+ break;
+
+ case items::Item::Coral_Earring:
+ flags |= item::Condition::Coral_Earring;
+ break;
+
+ case items::Item::Wooden_Sword:
+ flags |= item::Condition::Wooden_Sword;
+ break;
+
+ case items::Item::Ordon_Sword:
+ flags |= item::Condition::Ordon_Sword;
+ break;
+
+ case items::Item::Master_Sword:
+ flags |= item::Condition::Master_Sword;
+ break;
+
+ case items::Item::Ordon_Shield:
+ flags |= item::Condition::Shield;
+ break;
+
+ case items::Item::Wooden_Shield:
+ flags |= item::Condition::Shield;
+ break;
+
+ case items::Item::Hylian_Shield:
+ flags |= item::Condition::Shield;
+ break;
+
+ }
+
+ if ((flags & item::Condition::Bow) && ((flags & item::Condition::Bombs) || (flags & item::Condition::Water_Bombs)))
+ {
+ // We have bow && (bombs || waterbombs) = bombarrows
+ flags |= item::Condition::Bomb_Arrows;
+ }
+
+ return flags;
+ }
+} \ No newline at end of file
diff --git a/source/source/itemChecks.cpp b/source/source/itemChecks.cpp
new file mode 100644
index 0000000..fa2c181
--- /dev/null
+++ b/source/source/itemChecks.cpp
@@ -0,0 +1,605 @@
+#include "item.h"
+#include "itemChecks.h"
+#include "stage.h"
+#include "defines.h"
+
+
+namespace mod::item
+{
+ ItemCheck checks[503] = {
+ /* 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
+ /* 3 */{0x21, 3, stage::allStages[45], 14, 0x1, 0xFF, 0b110000000000000000100, 1528.0000000, 250.0000000, -22.0000000, nullptr, nullptr}, //North Faron Cave Heart Piece Chest
+ /* 4 */{0x03, 7, stage::allStages[45], 6, 0x1, 0xFF, 0b000000000000000000100, -38292.5312500, 400.0000000, -23129.9550780, nullptr, nullptr}, //Small Chest North of Trill
+ /* 5 */{0xED, 7, stage::allStages[65], 7, 0x0, 0xFF, 0b110010000000000001000, 128.7043760, -1077.0000000, -607.5000000, nullptr, nullptr}, //Link's Basement Chest
+ /* 6 */{0x03, 7, stage::allStages[6], 22, 0x1, 0xFF, 0b000000000000000000000, 900.0000000, 3110.0000000, 15825.0000000, nullptr, nullptr}, //FT Entrance Vine Chest
+ /* 7 */{0x04, 7, stage::allStages[6], 0, 0x1, 0xFF, 0b100100000000000000000, 0.0000000, 2700.0000000, 5550.0000000, nullptr, nullptr}, //FT Central Chest Behind Stairs
+ /* 8 */{0x23, 2, stage::allStages[6], 0, 0x1, 0x1, 0b110000000000000000000, 550.0000000, 3301.0095210, 5325.0000000, nullptr, nullptr}, //FT Map Chest
+ /* 9 */{0x20, 8, stage::allStages[6], 9, 0x1, 0xFF, 0b110000000000000000000, 6908.0000000, 3580.2719730, -3305.0000000, nullptr, nullptr}, //FT Windless Bridge Chest
+ /* 10 */{0x03, 7, stage::allStages[6], 2, 0x1, 0xFF, 0b110000000000000100000, 11559.7548830, 3152.0000000, 3761.2187500, nullptr, nullptr}, //FT Second Monkey Under Bridge Chest
+ /* 11 */{0x20, 8, stage::allStages[6], 5, 0x1, 0xFF, 0b100000000000000100000, -9108.924805, 3302.0000000, 5547.310059, nullptr, nullptr}, //FT Totem Pole Chest
+ /* 12 */{0x04, 7, stage::allStages[6], 5, 0x1, 0xFF, 0b100000000000000100000, -11721.1455080, 3750.0000000, 4717.8212890, nullptr, nullptr}, //FT West Tile Worm Small Chest
+ /* 13 */{0x21, 3, stage::allStages[6], 3, 0x1, 0xFF, 0b110000000000000000000, -4000.0000000, 2955.5900880, 9075.0000000, nullptr, nullptr}, //FT Deku Like Heart Piece Chest
+ /* 14 */{0x21, 3, stage::allStages[6], 5, 0x1, 0xFF, 0b110100000000000100000, -14275.0000000, 3402.7832030, 6150.0000000, nullptr, nullptr}, //FT West Tile Worm Heart Piece Chest
+ /* 15 */{0x24, 2, stage::allStages[6], 0, 0x1, 0x1, 0b100100000000000000000, 0.0000000, 3150.0000000, 7125.0000000, nullptr, nullptr}, //FT Compass Chest
+ /* 16 */{0x26, 2, stage::allStages[6], 1, 0x1, 0x1, 0b100100000000000000000, 9225.0009770, 3471.9599610, 8465.1347660, nullptr, nullptr}, //FT Big Key Chest
+ /* 17 */{0x03, 7, stage::allStages[6], 1, 0x1, 0xFF, 0b000000000000000000000, 10261.0000000, 3175.0000000, 8295.0000000, nullptr, nullptr}, //FT East Water Cave Chest
+ /* 18 */{0x20, 8, stage::allStages[6], 10, 0x2, 0xFF, 0b000100000010000000000, 1174.2510990, 5002.3901370, -9219.0937500, nullptr, nullptr}, //FT North Deku Like Chest
+ /* 19 */{0x04, 7, stage::allStages[6], 11, 0x2, 0xFF, 0b100100000000000100000, 11183.0000000, 3806.5500490, -6305.0000000, nullptr, nullptr}, //FT East Tile Worm Chest
+ /* 20 */{0x04, 7, stage::allStages[68], 2, 0x2, 0xFF, 0b000000000000000000000, -70.0000000, -6.0440000, -670.0000000, nullptr, nullptr}, //Kakariko Inn Small Chest
+ /* 21 */{0x45, 0, stage::allStages[65], 0, 0x2, 0x2, 0b000000000000000000000, 320.8111880, 9.7100000, 1017.9390870, nullptr, nullptr}, //Iron Boots Chest
+ /* 22 */{0x04, 7, stage::allStages[3], 1, 0x3, 0xFF, 0b001000000000000000000, 1050.0000000, -258.1840820, 13750.0000000, nullptr, nullptr}, //GM Entrance Small Chest
+ /* 23 */{0x20, 8, stage::allStages[3], 3, 0x3, 0xFF, 0b001000000000000000000, 2700.0000000, -1378.3521730, 5175.0000000, nullptr, nullptr}, //GM Main Magnet Room Bottom Chest
+ /* 24 */{0x23, 2, stage::allStages[3], 14, 0x3, 0x3, 0b001000000000000100000, -15984.1562500, -710.5994260, 1504.4143070, nullptr, nullptr}, //GM Map Chest
+ /* 25 */{0x04, 7, stage::allStages[3], 14, 0x3, 0xFF, 0b001000000000000000000, -16176.0000000, -561.3822020, 895.0000000, nullptr, nullptr}, //GM Gor Amato Small Chest
+ /* 26 */{0x21, 3, stage::allStages[3], 4, 0x3, 0xFF, 0b001000000000000000000, -5625.0000000, 448.7841190, 75.0000000, nullptr, nullptr}, //GM Magnet Maze Heart Piece Chest
+ /* 27 */{0x20, 8, stage::allStages[3], 6, 0x3, 0xFF, 0b001000000000000000000, 1125.0000000, 600.0000000, -4725.0000000, nullptr, nullptr}, //GM Switch Room Underwater Chest
+ /* 28 */{0x04, 7, stage::allStages[3], 6, 0x3, 0xFF, 0b001000000000000000000, 1000.0000000, 1650.0000000, -5650.0000000, nullptr, nullptr}, //GM Switch Room Small Chest
+ /* 29 */{0x21, 3, stage::allStages[3], 6, 0x3, 0xFF, 0b001000000000000000000, -1350.0000000, 2350.0000000, -6200.0000000, nullptr, nullptr}, //GM After Switch Room Heart Piece Chest
+ /* 30 */{0x20, 8, stage::allStages[3], 7, 0x3, 0xFF, 0b101000000000000100000, -1050.0000000, 2425.0000000, -14825.0000000, nullptr, nullptr}, //GM Outside Bemos Chest
+ /* 31 */{0x03, 7, stage::allStages[3], 17, 0x3, 0xFF, 0b101000000000000100000, 13900.0000000, 2997.0900880, -17175.0000000, nullptr, nullptr}, //GM Gor Ebizo Small Chest
+ /* 32 */{0x03, 7, stage::allStages[3], 9, 0x3, 0xFF, 0b101000000000000100000, 9950.0000000, 2475.0000000, -15375.0000000, nullptr, nullptr}, //GM Small Chest Before Dangoro
+ /* 33 */{0x43, 0, stage::allStages[3], 11, 0x3, 0x3, 0b001000000000000000000, 7997.9995120, 2640.0000000, -5355.0000000, nullptr, nullptr}, //GM Bow Chest
+ /* 34 */{0x24, 2, stage::allStages[3], 11, 0x4, 0x4, 0b101001000000000000000, 6488.3676760, 2640.0000000, -1673.5349120, nullptr, nullptr}, //GM Compass Chest
+ /* 35 */{0x05, 7, stage::allStages[3], 16, 0x4, 0xFF, 0b101001000000000000000, 13975.0000000, 2476.4899900, -1675.0000000, nullptr, nullptr}, //GM Gor Liggs Small Chest
+ /* 36 */{0x05, 7, stage::allStages[3], 3, 0x4, 0xFF, 0b101001000000000000000, 3625.0000000, 2637.8999020, 4050.0000000, nullptr, nullptr}, //GM Main Magnet Room Top Chest
+ /* 37 */{0x05, 7, stage::allStages[3], 7, 0x4, 0xFF, 0b001000000000000000000, 2325.0000000, 1100.0000000, -17400.0000000, nullptr, nullptr}, //GM Outside Underwater Chest
+ /* 38 */{0x21, 3, stage::allStages[46], 0, 0x5, 0xFF, 0b101000100000000000000, 1300.0000000, -1600.0000000, 16700.0000000, nullptr, nullptr}, //Eldin Spring Heart Piece Chest
+ /* 39 */{0x05, 7, stage::allStages[48], 0, 0x2, 0xFF, 0b010000000000000000000, 16050.0000000, 200.0000000, 725.0000000, nullptr, nullptr}, //Kakariko Graveyard Lanturn Chest
+ /* 40 */{0x05, 7, stage::allStages[68], 4, 0x3, 0xFF, 0b000000000000000000000, -887.4350590, 1000.0000000, -173.2907710, nullptr, nullptr}, //Kakariko Watchtower Chest
+ /* 41 */{0x06, 7, stage::allStages[46], 0, 0x5, 0xFF, 0b000000101100000000000, -4027.7336430, 3200.0000000, -8970.9990230, nullptr, nullptr}, //Kakariko Watchtower Alcove Chest
+ /* 42 */{0x21, 3, stage::allStages[56], 0, 0x5, 0xFF, 0b000000001000000000000, 11550.0000000, 2700.0000000, 24090.0000000, nullptr, nullptr}, //Eldin Bomb Rock Ledge Heart Piece Chest
+ /* 43 */{0x03, 7, stage::allStages[50], 1, 0x5, 0xFF, 0b000000000000000000000, 2784.3178710, -4587.8901370, 10773.4140620, nullptr, nullptr}, //ZD Small Chest By Mother and Child Isles
+ /* 44 */{0x04, 7, stage::allStages[50], 1, 0xFF, 0xFF, 0b000000000000000000000, 3810.8435060, -3535.5300290, 11344.8876950, nullptr, nullptr}, //ZD Small Chest Under Waterfall
+ /* 45 */{0x06, 7, stage::allStages[52], 0, 0x5, 0xFF, 0b001000000000000000000, -97123.5468750, -19490.0000000, 58585.6992190, nullptr, nullptr}, //Lake Hylia Underwater Chest
+ /* 46 */{0x0F, 5, stage::allStages[0], 0, 0x6, 0xFF, 0b000000000000001000000, -1707.6793210, 1250.0000000, 15388.9882810, nullptr, nullptr}, //LBT Lobby Left Chest
+ /* 47 */{0x17, 5, stage::allStages[0], 0, 0x6, 0xFF, 0b000000000000001000000, -144.6737980, 1250.0000000, 16525.8710940, nullptr, nullptr}, //LBT Lobby Rear Chest
+ /* 48 */{0x17, 5, stage::allStages[0], 1, 0x6, 0xFF, 0b100000001000001000000, 1417.5971680, 1813.6099850, 7807.2255860, nullptr, nullptr}, //LBT Stalactite Room Small Chest
+ /* 49 */{0x0F, 5, stage::allStages[0], 3, 0x6, 0xFF, 0b000000000000001000000, 1629.5045170, 0.0000000, 2049.6350100, nullptr, nullptr}, //LBT Central Room Small Chest
+ /* 50 */{0x23, 2, stage::allStages[0], 3, 0x6, 0x6, 0b000000000000001000000, 2010.5773930, 0.0000000, -1656.3415530, nullptr, nullptr}, //LBT Map Chest
+ /* 51 */{0x20, 8, stage::allStages[0], 8, 0x6, 0xFF, 0b100000001000001000000, 12900.0000000, -600.0000000, 1850.0000000, nullptr, nullptr}, //LBT East Stalactite Room Chest
+ /* 52 */{0x16, 5, stage::allStages[0], 7, 0x6, 0xFF, 0b000000000000001100000, 8779.1152340, 1500.0000000, 1667.6258540, nullptr, nullptr}, //LBT East Second Floor Southwest Chest
+ /* 53 */{0x20, 8, stage::allStages[0], 7, 0x6, 0xFF, 0b100000001000001100000, 11550.8037110, 1500.0000000, 2866.6462400, nullptr, nullptr}, //LBT East Second Floor Southeast Chest
+ /* 54 */{0x17, 5, stage::allStages[0], 10, 0x6, 0xFF, 0b000000000000001100000, 18228.3320310, 3995.0000000, -466.3260800, nullptr, nullptr}, //LBT East Water Supply Small Chest
+ /* 55 */{0x20, 8, stage::allStages[0], 9, 0x6, 0xFF, 0b000000000000001000000, 13550.0000000, 10.0000000, -2500.0000000, nullptr, nullptr}, //LBT Before Deku Toad Chest
+ /* 56 */{0x04, 7, stage::allStages[0], 9, 0x6, 0xFF, 0b101000000000001100000, 13193.2910160, -1189.3100590, -2433.4060060, nullptr, nullptr}, //LBT Before Deku Toad Underwater Left Chest
+ /* 57 */{0x16, 5, stage::allStages[0], 9, 0x6, 0xFF, 0b101000000000001100000, 13757.0000000, -1275.3310550, -4783.1503910, nullptr, nullptr}, //LBT Before Deku Toad Underwater Right Chest
+ /* 58 */{0x44, 0, stage::allStages[2], 51, 0x6, 0x6, 0b000000000000001000000, 0.0000000, 0.0000000, 0.0000000, nullptr, nullptr}, //LBT Clawshot Chest
+ /* 59 */{0x21, 3, stage::allStages[0], 3, 0x7, 0xFF, 0b100000000010001000000, -0.8691990, 2100.0000000, 2.1099050, nullptr, nullptr}, //LBT Chandelier Heart Piece Chest
+ /* 60 */{0x05, 7, stage::allStages[0], 10, 0x7, 0xFF, 0b100000000010001100000, 21000.0000000, 4170.0000000, 85.0000000, nullptr, nullptr}, //LBT Eas Water Supply Clawshot Chest
+ /* 61 */{0x04, 7, stage::allStages[0], 3, 0x7, 0xFF, 0b000000000000001000000, 0.0000000, -940.0000000, -315.5000000, nullptr, nullptr}, //LBT Central Room Center Spire Chest
+ /* 62 */{0x17, 5, stage::allStages[0], 12, 0x7, 0xFF, 0b000000000010001000000, -10687.0947270, -299.3999940, -1161.5905760, nullptr, nullptr}, //LBT West Lower Small Chest
+ /* 63 */{0x17, 5, stage::allStages[0], 13, 0x7, 0xFF, 0b100000000010001000000, -20310.0000000, 4015.0000000, 460.0000000, nullptr, nullptr}, //LBT West Water Supply Small Chest
+ /* 64 */{0x24, 2, stage::allStages[0], 13, 0x7, 0x7, 0b100000000010001000000, -23100.0000000, 4200.0000000, -85.0000000, nullptr, nullptr}, //LBT Compass Chest
+ /* 65 */{0x04, 7, stage::allStages[0], 11, 0x7, 0xFF, 0b101000000000001000000, -14158.2880860, 700.0000000, 2868.1103520, nullptr, nullptr}, //LBT West Second Floor Southwest Underwater Chest
+ /* 66 */{0x04, 7, stage::allStages[0], 12, 0x7, 0xFF, 0b100000000010001000000, -10180.6718750, 1500.0000000, -1939.7305910, nullptr, nullptr}, //LBT West Second Floor Central Small Chest
+ /* 67 */{0x04, 7, stage::allStages[0], 11, 0x7, 0xFF, 0b000000000000001000000, -10950.0000000, 1450.0000000, 2590.0000000, nullptr, nullptr}, //LBT West Second Floor Northeast Chest
+ /* 68 */{0x18, 5, stage::allStages[0], 11, 0x7, 0xFF, 0b100000000010001000000, -9270.0000000, 1450.0000000, -2100.0000000, nullptr, nullptr}, //LBT West Second Floor Southeast Chest
+ /* 69 */{0x26, 2, stage::allStages[0], 6, 0x7, 0x7, 0b101000001010001000000, -16549.8789060, -1345.7093510, 2820.3918460, nullptr, nullptr}, //LBT Big Key Chest
+ /* 70 */{0x16, 5, stage::allStages[0], 5, 0x7, 0xFF, 0b101000000010001000000, -18544.2207030, -200.0000000, 475.5745850, nullptr, nullptr}, //LBT Underwater Maze Small Chest
+ /* 71 */{0x21, 3, stage::allStages[0], 8, 0x7, 0xFF, 0b100000000010001000000, 11356.2246090, -550.0000000, 4896.6640620, nullptr, nullptr}, //LBT East Stalactite Heart Piece Chest
+ /* 72 */{0x21, 3, stage::allStages[36], 1, 0x12, 0xFF, 0b100000100000000000010, -211.8681490, -61.3470460, -2693.1110840, nullptr, nullptr}, // Grotto - Deku Baba Heart Piece Chest
+ /* 73 */{0x06, 7, stage::allStages[35], 0, 0x8, 0xFF, 0b100000000010000000010, 28.7614960, 2.9684250, -455.4558110, nullptr, nullptr}, //Grotto - Helmasaur Chest
+ /* 74 */{0x1A, 5, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, -655.6493530, 1069.5000000, -4819.0908200, nullptr, nullptr}, //Lake Lanturn Cave First Chest
+ /* 75 */{0x03, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 682.1680300, 1069.5000000, -6179.2060550, nullptr, nullptr}, //Lake Lanturn Cave Second Chest
+ /* 76 */{0x04, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 2067.4831540, 966.9400020, -7130.3203120, nullptr, nullptr}, //Lake Lanturn Cave Third Chest
+ /* 77 */{0x0E, 5, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 9980.4072270, 353.3800050, -7188.2241210, nullptr, nullptr}, //Lake Lanturn Cave Fourth Chest
+ /* 78 */{0x04, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 8154.4853520, -721.9500120, -16215.0576170, nullptr, nullptr}, //Lake Lanturn Cave Fifth Chest
+ /* 79 */{0x06, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 1585.2146000, -1584.6899410, -14877.4931640, nullptr, nullptr}, //Lake Lanturn Cave Sixth Chest
+ /* 80 */{0x04, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 1678.4635010, -1586.6899410, -16192.1738280, nullptr, nullptr}, //Lake Lanturn Cave Seventh Chest
+ /* 81 */{0x1A, 5, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, -642.0394290, -1703.1999510, -18994.8613280, nullptr, nullptr}, //Lake Lanturn Cave Eighth Chest
+ /* 82 */{0x0E, 5, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, -7978.3588870, -2572.7099610, -16192.1738280, nullptr, nullptr}, //Lake Lanturn Cave Ninth Chest
+ /* 83 */{0x05, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, -9292.6113280, -2572.7099610, -17523.3867190, nullptr, nullptr}, //Lake Lanturn Cave Tenth Chest
+ /* 84 */{0x1B, 5, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 2974.3283690, -4197.5800780, -20501.6816410, nullptr, nullptr}, //Lake Lanturn Cave Eleventh Chest
+ /* 85 */{0x05, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 1675.3985600, -4197.5800780, -21755.7343750, nullptr, nullptr}, //Lake Lanturn Cave Twelfth Chest
+ /* 86 */{0x12, 5, stage::allStages[33], 0, 0x5, 0xFF, 0b000000001100000000000, 3981.5319820, -4081.0800780, -19125.3964840, nullptr, nullptr}, //Lake Lanturn Cave Thirtennth Chest
+ /* 87 */{0x06, 7, stage::allStages[33], 0, 0x5, 0xFF, 0b110000001000000000000, 8324.2236330, -4070.1899410, -17814.0156250, nullptr, nullptr}, //Lake Lanturn Cave Fourteenth Chest
+ /* 88 */{0x21, 3, stage::allStages[33], 0, 0x5, 0xFF, 0b110000001000000000000, 6582.5747070, -5144.5200200, -10032.9658200, nullptr, nullptr}, //Lake Lanturn Cave Heart Piece Chest
+ /* 89 */{0x06, 7, stage::allStages[39], 4, 0x8, 0xFF, 0b000000000000000000010, -312.1882930, -27.1700000, -1501.0155030, nullptr, nullptr}, //Grotto - Water Toadpoli Chest
+ /* 90 */{0x05, 7, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000010000000000, -91673.9453120, -16547.1699220, 49208.8203120, nullptr, nullptr}, //Outside Lanayru Spring - Left Statue Small Chest
+ /* 91 */{0x06, 7, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000010000000000, -88884.070312, -16939.031250, 49405.648438, nullptr, nullptr}, //Outside Lanayru Spring - Right Statue Chest
+ /* 92 */{0x02, 7, stage::allStages[52], 1, 0x5, 0xFF, 0b001000000000000000000, 593.5773930, -1276.7792970, 128.1360020, nullptr, nullptr}, //Lanayru Spring Underwater Left Chest
+ /* 93 */{0x03, 7, stage::allStages[52], 1, 0x5, 0xFF, 0b001000000000000000000, -1262.2436520, -1380.8292240, 68.6994780, nullptr, nullptr}, //Lanayru Spring Underwater Right Chest
+ /* 94 */{0x02, 7, stage::allStages[52], 1, 0x6, 0xFF, 0b000000000010000000000, -33.7100300, 1406.5571290, 4875.7338870, nullptr, nullptr}, //Lanayru Spring Southern Room Left Chest
+ /* 95 */{0x0A, 5, stage::allStages[52], 1, 0x6, 0xFF, 0b000000000010000000000, 486.2900090, 1406.5479740, 4875.7338870, nullptr, nullptr}, //Lanayru Spring Southern Room Right Chest
+ /* 96 */{0x21, 3, stage::allStages[52], 1, 0x6, 0xFF, 0b110000000010000000000, 224.6442720, 1406.5999760, 4862.4682620, nullptr, nullptr}, //Lanayru Spring Heart Piece Chest
+ /* 97 */{0x06, 7, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000000000000000, -102601.6640620, -16650.6562500, 43399.9570310, nullptr, nullptr}, //Isle of Riches Top Platform
+ /* 98 */{0x21, 3, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000000000000000, -102682.2031250, -17271.6835940, 43179.0781250, nullptr, nullptr}, //Isle of Riches 2nd Level
+ /* 99 */{0x05, 7, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000000000000000, -102990.2421880, -17760.8300780, 42850.2382810, nullptr, nullptr}, //Isle of Riches 3rd Level
+ /* 100 */{0x04, 7, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000000000000000, -103540.7812500, -18170.2578120, 42296.2421880, nullptr, nullptr}, //Isle of Riches 4th Level
+ /* 101 */{0x03, 7, stage::allStages[52], 0, 0x6, 0xFF, 0b001000000000000000000, -104351.7031250, -18485.7714840, 41482.6367190, nullptr, nullptr}, //Isle of Riches 5th Level
+ /* 102 */{ 0x06, 7, stage::allStages[39], 4, 0x8, 0xFF, 0b101000000000000000010, -371.4389950, -27.1700000, -1627.2565920, nullptr, nullptr }, //Grotto - Shell Blade Chest
+ /* 103 */{0x05, 7, stage::allStages[50], 0, 0x6, 0xFF, 0b010000000000000000000, 200.0000000, -349.6226810, -1900.0000000, nullptr, nullptr}, //ZD Underwater Right Chest
+ /* 104 */{0x05, 7, stage::allStages[50], 0, 0x6, 0xFF, 0b111100000000000000000, -200.0000000, -349.4964290, -1900.0000000, nullptr, nullptr}, //ZD Underwater Left Chest
+ /* 105 */{ 0x05, 7, stage::allStages[38], 3, 0x8, 0xFF, 0b110000000000000000010, -1125.7841800, -133.9226530, -3012.3530270, nullptr, nullptr }, //Grotto - Skulltula Chest
+ /* 106 */{0x06, 7, stage::allStages[56], 10, 0x6, 0xFF, 0b001000000000000000000, -46800.0000000, -4800.0000000, -22650.0000000, nullptr, nullptr}, //Behind Gate Underwater Chest
+ /* 107 */{0x06, 7, stage::allStages[56], 13, 0x7, 0xFF, 0b000000000010000000000, -94100.0000000, -4420.0000000, 30009.9199220, nullptr, nullptr}, //Bridge Vines Chest
+ /* 108 */{ 0x06, 7, stage::allStages[38], 3, 0x8, 0xFF, 0b110000000010000000010, -1061.2969970, -132.2552490, -3053.6071780, nullptr, nullptr }, //Grotto - Bubble Chest
+ /* 109 */{0x05, 7, stage::allStages[56], 13, 0x7, 0xFF, 0b100000001010000000000, -80910.0000000, -6000.0000000, 64780.0000000, nullptr, nullptr}, //Outside Bubble Grotto Chest
+ /* 110 */{0x06, 7, stage::allStages[56], 6, 0x7, 0xFF, 0b000000000010000000000, -46040.0000000, -9100.0000000, 80025.0000000, nullptr, nullptr}, //Faron Under Bridge Chest
+ /* 111 */{ 0x04, 7, stage::allStages[36], 1, 0x8, 0xFF, 0b000000000000000000010, 578.9967040, -266.3237300, -2138.4619140, nullptr, nullptr }, //Grotto - Chu, Baba, and Keese Right Chest
+ /* 112 */{ 0x03, 7, stage::allStages[36], 1, 0x8, 0xFF, 0b000000000000000000010, -281.6463620, -300.0000000, 910.2941280, nullptr, nullptr }, //Grotto - Chu, Baba, and Keese Rear Chest
+ /* 113 */{ 0x04, 7, stage::allStages[36], 1, 0x8, 0xFF, 0b000000000000000000010, -754.0296020, -256.7704770, -3001.7814940, nullptr, nullptr }, //Grotto - Chu, Babe, and Keese Left Chest
+ /* 114 */{0x21, 3, stage::allStages[47], 0, 0x4, 0xFF, 0b000000000000000000000, -1646.0109860, 379.2999880, 8487.9677730, nullptr, nullptr}, //Death Mountain Alcove Heart Piece Chest
+ /* 115 */{0x05, 7, stage::allStages[3], 7, 0x7, 0xFF, 0b101000000010000000000, 2700.0000000, 4275.0000000, -19550.0000000, nullptr, nullptr}, //GM Outside Clawshot Chest
+ /* 116 */{0x04, 7, stage::allStages[32], 0, 0x5, 0xFF, 0b000000001100000000000, -1056.4636230, 3145.5432130, -4376.8500980, nullptr, nullptr}, //Eldin Lantern Cave First Chest
+ /* 117 */{0x21, 3, stage::allStages[32], 0, 0x5, 0xFF, 0b000000001100000000000, 6452.6201170, 4447.9018550, -6947.8505860, nullptr, nullptr}, //Eldin Lantern Cave Heart Piece Chest
+ /* 118 */{0x05, 7, stage::allStages[32], 0, 0x5, 0xFF, 0b000000001100000000000, 7333.7602540, 4152.1391600, 1235.8031010, nullptr, nullptr}, //Eldin Lantern Cave Second Chest
+ /* 119 */{ 0x06, 7, stage::allStages[57], 16, 0x8, 0xFF, 0b100000000010000000010, -53600.0000000, -3592.9699710, 23830.0000000, nullptr, nullptr }, //Castle Pillar Chest
+ /* 120 */{ 0x06, 7, stage::allStages[39], 4, 0x8, 0xFF, 0b000000000000000000010, -240.3374330, -27.1700000, -1660.1081540, nullptr, nullptr }, //Grotto - Tetike Chest
+ /* 121 */{ 0x05, 7, stage::allStages[35], 0, 0x8, 0xFF, 0b110000000000000000010, -1037.5682370, 1.0515240, -536.6557620, nullptr, nullptr }, //Grotto - Bombling Left Chest
+ /* 122 */{ 0x05, 7, stage::allStages[35], 0, 0x8, 0xFF, 0b110000000000000000010, -193.2892910, 150.0000000, -1135.5745850, nullptr, nullptr }, //Grotto - Bombling Right Chest
+ /* 123 */{ 0x05, 7, stage::allStages[39], 4, 0x8, 0xFF, 0b000000000000000000010, -251.5004430, -27.1700000, -1691.9121090, nullptr, nullptr }, //Grotto - Water Bomb Fish Chest
+ /* 124 */{ 0x06, 7, stage::allStages[38], 3, 0x9, 0xFF, 0b000000000000000000010, -1066.0302730, -132.1377870, -3046.8808590, nullptr, nullptr }, //Grotto - Desert Skulltula Chest
+ /* 125 */{ 0x04, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000010000000000, 51585.6210940, 1536.1500240, 58741.2500000, nullptr, nullptr }, //Desert Peahat Chest
+ /* 126 */{ 0x04, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 51813.6796880, 171.0510250, 46656.2773440, nullptr, nullptr }, //East Canyon Chest
+ /* 127 */{ 0x0E, 5, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 30472.5644530, 778.0640260, 50140.5703120, nullptr, nullptr }, //Desert Lone Small Chest
+ /* 128 */{0x04, 7, stage::allStages[34], 10, 0x7, 0xFF, 0b000000000010000000000, 13825.0000000, 137.5000000, -34250.0000000, nullptr, nullptr}, //Eldin Stockcave Small Chest
+ /* 129 */{0x06, 7, stage::allStages[34], 10, 0x7, 0xFF, 0b111000000010000000000, 9577.0000000, -2833.8898930, -33492.0000000, nullptr, nullptr}, //Eldin Stockcave Lanturn Chest
+ /* 130 */{0x21, 3, stage::allStages[34], 10, 0x7, 0xFF, 0b101000000010000000000, 9515.7099610, -2850.0000000, -31912.3808590, nullptr, nullptr}, //Eldin Stockcave Heart Piece Chest
+ /* 131 */{ 0x05, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000010000000000, -6940.8110350, 441.2112430, 48305.4023440, nullptr, nullptr },
+ /* 132 */{ 0x06, 7, stage::allStages[37], 2, 0x9, 0xFF, 0b110000100010000000010, -128.8401180, 150.0000000, -1330.3356930, nullptr, nullptr },
+ /* 133 */{ 0x04, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 9889.4482420, -732.8599850, 17813.8398440, nullptr, nullptr },
+ /* 134 */{ 0x06, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 32741.2617190, 158.3099980, 68606.5468750, nullptr, nullptr },
+ /* 135 */{ 0x04, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 3104.9711910, -732.8599850, 24575.0351560, nullptr, nullptr },
+ /* 136 */{ 0x05, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 4945.0000000, -732.8599850, 25572.0000000, nullptr, nullptr },
+ /* 137 */{ 0x0E, 5, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 1845.0000000, -732.8599850, 26130.0000000, nullptr, nullptr },
+ /* 138 */{ 0x04, 7, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, -6532.4062500, -732.8599850, 20852.4121090, nullptr, nullptr },
+ /* 139 */{ 0x0E, 5, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 4681.0947270, -162.9400020, 12575.7626950, nullptr, nullptr },
+ /* 140 */{ 0x0F, 5, stage::allStages[55], 1, 0x9, 0xFF, 0b000000000000000000000, 4761.6406250, 0.0000000, 1580.5701900, nullptr, nullptr },
+ /* 141 */{ 0x05, 7, stage::allStages[55], 1, 0x9, 0xFF, 0b000000000000000000000, 2389.0454100, 260.0000000, -1473.3872070, nullptr, nullptr },
+ /* 142 */{ 0x05, 7, stage::allStages[55], 3, 0x9, 0xFF, 0b010000000000000000000, 3633.6201170, 840.0000000, -12457.7001950, nullptr, nullptr },
+ /* 143 */{ 0x20, 8, stage::allStages[24], 0, 0x9, 0xFF, 0b000000000000000000000, -3000.0000000, -19.0000000, 5600.0000000, nullptr, nullptr },
+ /* 144 */{ 0x20, 8, stage::allStages[24], 15, 0x9, 0xFF, 0b000000000000000000000, 4125.0000000, -741.5800170, -2250.0000000, nullptr, nullptr },
+ /* 145 */{ 0x21, 3, stage::allStages[24], 2, 0x9, 0xFF, 0b000000000000000000000, 1300.0000000, 62.5000000, -3012.5000000, nullptr, nullptr },
+ /* 146 */{ 0x23, 2, stage::allStages[24], 2, 0x9, 0x9, 0b000000000000000000000, -1300.0000000, 50.0000000, -3012.5000000, nullptr, nullptr },
+ /* 147 */{ 0x24, 2, stage::allStages[24], 4, 0x9, 0x9, 0b000000000000000100000, 9400.0000000, 990.0599980, 6100.0000000, nullptr, nullptr },
+ /* 148 */{ 0x20, 8, stage::allStages[24], 4, 0x9, 0xFF, 0b000000000000000100000, 12275.0000000, 980.0000000, 4537.5000000, nullptr, nullptr },
+ /* 149 */{ 0x20, 8, stage::allStages[24], 14, 0x9, 0xFF, 0b000000000000000100000, 4150.0000000, 825.0000000, 775.0000000, nullptr, nullptr },
+ /* 150 */{ 0x04, 7, stage::allStages[24], 6, 0x9, 0xFF, 0b000000000000000000000, -4065.0000000, 150.0000000, -2660.0000000, nullptr, nullptr },
+ /* 151 */{ 0x04, 7, stage::allStages[24], 6, 0x9, 0xFF, 0b000000000000000000000, -4450.0000000, 400.0000000, 1150.0000000, nullptr, nullptr },
+ /* 152 */{ 0x0A, 5, stage::allStages[24], 7, 0x9, 0xFF, 0b000000100100000000000, -9975.0000000, 500.0000000, -600.0000000, nullptr, nullptr },
+ /* 153 */{ 0x0A, 5, stage::allStages[24], 7, 0x9, 0xFF, 0b000000100100000000000, -8113.0000000, 500.0000000, -1382.0000000, nullptr, nullptr },
+ /* 154 */{ 0x20, 8, stage::allStages[24], 16, 0x9, 0xFF, 0b000000000000000000000, 3970.0000000, -1050.0000000, -6080.0000000, nullptr, nullptr },
+ /* 155 */{ 0x41, 0, stage::allStages[26], 51, 0x9, 0x9, 0b000100000010000000000, 0.0000000, 50.0000000, -6200.0000000, nullptr, nullptr },
+ /* 156 */{ 0x0B, 5, stage::allStages[24], 13, 0x10, 0xFF, 0b000000000000100000000, -8331.4091800, -1800.0000000, -3677.7468260, nullptr, nullptr },
+ /* 157 */{ 0x04, 7, stage::allStages[24], 13, 0x10, 0xFF, 0b000000000000100000000, -10212.5000000, -1840.0000000, -3725.0000000, nullptr, nullptr },
+ /* 158 */{ 0x03, 7, stage::allStages[24], 13, 0x10, 0xFF, 0b000000000000100000000, -10812.5000000, -1825.0000000, -5712.5000000, nullptr, nullptr },
+ /* 159 */{ 0x21, 3, stage::allStages[24], 13, 0x10, 0xFF, 0b000000000000100000000, -5475.0000000, -1325.0000000, -4875.0000000, nullptr, nullptr },
+ /* 160 */{ 0x03, 7, stage::allStages[24], 13, 0x10, 0xFF, 0b000000000000100000000, -6225.0000000, -1125.0000000, -7275.0000000, nullptr, nullptr },
+ /* 161 */{ 0x26, 2, stage::allStages[24], 9, 0x10, 0x10, 0b000000000000100000000, -3675.0000000, 500.0000000, -7250.0000000, nullptr, nullptr },
+ /* 162 */{ 0x21, 3, stage::allStages[56], 11, 0x10, 0xFF, 0b000000000000100000000, -88260.0000000, 2950.0000000, -8150.0000000, nullptr, nullptr },
+ /* 163 */{ 0x0A, 5, stage::allStages[36], 1, 0x10, 0xFF, 0b100000000000100000010, 464.9176030, -262.3106380, -709.6952510, nullptr, nullptr },
+ /* 164 */{ 0x0A, 5, stage::allStages[36], 1, 0x10, 0xFF, 0b100000000000100000010, -1153.7760010, -255.8396450, -980.6660160, nullptr, nullptr },
+ /* 165 */{ 0x21, 3, stage::allStages[36], 1, 0x10, 0xFF, 0b100000100000100000010, -211.8499450, -60.9387400, -2691.0991210, nullptr, nullptr },
+ /* 166 */{ 0x06, 7, stage::allStages[57], 16, 0x10, 0xFF, 0b100000000010100000000, -51500.0000000, -5180.0000000, 25970.0000000, nullptr, nullptr },
+ /* 167 */{ 0x05, 7, stage::allStages[35], 0, 0x8, 0xFF, 0b110000000000000000010, -277.2709660, 150.0000000, -1096.2886960, nullptr, nullptr },
+ /* 168 */{0x04, 7, stage::allStages[45], 5, 0x1, 0xFF, 0b000000000000000000000, -25790.1093750, 330.0000000, -19842.9355470, nullptr, nullptr}, //Faron Mist Stump Chest
+ /* 169 */{0x03, 7, stage::allStages[45], 5, 0x1, 0xFF, 0b000000000000000000000, -24845.1308590, -100.0000000, -26998.7226560, nullptr, nullptr}, //Faron Mist North Small Chest
+ /* 170 */{0x05, 7, stage::allStages[45], 5, 0x1, 0xFF, 0b000000000000000000000, -25966.7851560, -83.1305240, -16071.9599610, nullptr, nullptr}, //Faron Mist East Chest
+ /* 171 */{ 0x20, 8, stage::allStages[27], 4, 0x11, 0xFF, 0b000000000000000000000, -1500.0000000, -60.0000000, -4458.0000000, nullptr, nullptr },
+ /* 172 */{ 0x04, 7, stage::allStages[27], 4, 0x11, 0xFF, 0b000000000000000000000, 1350.0000000, 50.0000000, -1400.0000000, nullptr, nullptr },
+ /* 173 */{ 0xF4, 8, stage::allStages[27], 5, 0x11, 0x11, 0b000000000000000100000, 5300.0000000, 0.0000000, -5100.0000000, nullptr, nullptr },
+ /* 174 */{ 0x20, 8, stage::allStages[27], 4, 0x11, 0xFF, 0b000000000000000000000, 1350.0000000, -40.0000000, -4150.0000000, nullptr, nullptr },
+ /* 175 */{ 0x04, 7, stage::allStages[27], 8, 0x11, 0xFF, 0b000000100100000000000, -4355.0000000, 0.0000000, -2160.0000000, nullptr, nullptr },
+ /* 176 */{ 0x24, 2, stage::allStages[27], 8, 0x11, 0x11, 0b000000100100000000000, -3510.0000000, 0.0000000, -1350.0000000, nullptr, nullptr },
+ /* 177 */{ 0x0A, 5, stage::allStages[27], 4, 0x11, 0xFF, 0b000000100100000000000, 0.0000000, 0.0000000, -1250.0000000, nullptr, nullptr },
+ /* 178 */{ 0xF5, 8, stage::allStages[29], 51, 0x12, 0x12, 0b000000000100000000000, 0.0000000, 0.0000000, -3196.0000000, nullptr, nullptr },
+ /* 179 */{ 0x21, 3, stage::allStages[27], 7, 0x12, 0xFF, 0b000000000100000000000, -3600.0000000, 0.0000000, 1600.0000000, nullptr, nullptr },
+ /* 180 */{ 0x20, 8, stage::allStages[27], 8, 0x12, 0xFF, 0b000000000100000000000, -4350.0000000, 950.0000000, -3850.0000000, nullptr, nullptr },
+ /* 181 */{ 0x21, 3, stage::allStages[27], 0, 0x12, 0xFF, 0b000000000100000000000, 0.0000000, 1118.3201900, 4690.0000000, nullptr, nullptr },
+ /* 182 */{ 0x04, 7, stage::allStages[27], 0, 0x12, 0xFF, 0b000000000100000000000, -900.0000000, -50.0000000, 5950.0000000, nullptr, nullptr },
+ /* 183 */{ 0x03, 7, stage::allStages[27], 0, 0x12, 0xFF, 0b000000000100000000000, 930.0000000, -50.0000000, 5350.0000000, nullptr, nullptr },
+ /* 184 */{ 0x20, 8, stage::allStages[27], 5, 0x12, 0xFF, 0b100000000110000000000, 4350.0000000, 953.0000000, -4900.0000000, nullptr, nullptr },
+ /* 185 */{ 0x04, 7, stage::allStages[27], 9, 0x12, 0xFF, 0b000000000100000000000, -5347.3071290, -50.0000000, -6500.8867190, nullptr, nullptr },
+ /* 186 */{ 0x0A, 5, stage::allStages[27], 9, 0x12, 0xFF, 0b000000100100000000000, -1818.3217770, 0.0000000, -7562.9838870, nullptr, nullptr },
+ /* 187 */{ 0xF6, 2, stage::allStages[27], 11, 0x12, 0x12, 0b100000100100000000000, -4350.0000000, 1050.0000000, -8560.5742190, nullptr, nullptr },
+ /* 188 */{ 0x06, 7, stage::allStages[51], 2, 0x12, 0xFF, 0b110000000100000000010, -6233.2583010, -1800.0000000, -9865.0205080, nullptr, nullptr },
+ /* 189 */{ 0x06, 7, stage::allStages[38], 3, 0x12, 0xFF, 0b100000000100000000010, -810.7105710, -300.0000000, -2101.0502930, nullptr, nullptr },
+ /* 190 */{ 0x21, 3, stage::allStages[30], 0, 0x12, 0xFF, 0b000000000100000000000, 0.0000000, 0.0000000, -7900.0000000, nullptr, nullptr },
+ /* 191 */{ 0x0D, 5, stage::allStages[54], 3, 0x12, 0xFF, 0b110100000000000000000, -15394.4238280, 2300.0000000, 2483.9230960, nullptr, nullptr },
+ /* 192 */{ 0x06, 7, stage::allStages[54], 3, 0x12, 0xFF, 0b000000000000100000000, -6840.3515620, 2000.0000000, 6329.0605470, nullptr, nullptr },
+ /* 193 */{ 0x20, 8, stage::allStages[9], 0, 0x12, 0xFF, 0b110001000000000000000, 2500.0000000, 56.2500000, 368.7500000, nullptr, nullptr },
+ /* 194 */{ 0x10, 5, stage::allStages[9], 1, 0x12, 0xFF, 0b000001000000000000000, -12.5000000, 1100.0000000, 8362.5000000, nullptr, nullptr },
+ /* 195 */{ 0x04, 7, stage::allStages[9], 1, 0x12, 0xFF, 0b000001000000000000000, 5795.0000000, 2505.0000000, 4210.0000000, nullptr, nullptr },
+ /* 196 */{ 0x23, 2, stage::allStages[9], 1, 0x12, 0x12, 0b000001000000000000000, 6925.0000000, 2325.0000000, 3400.0000000, nullptr, nullptr },
+ /* 197 */{ 0x20, 8, stage::allStages[9], 3, 0x12, 0xFF, 0b100001000000100000000, -1737.5000000, 4500.0000000, 5812.5000000, nullptr, nullptr },
+ /* 198 */{ 0x24, 2, stage::allStages[9], 4, 0x12, 0x12, 0b100001000000100000000, -3450.0000000, 4450.0000000, -5510.0000000, nullptr, nullptr },
+ /* 199 */{ 0x05, 7, stage::allStages[9], 5, 0x12, 0xFF, 0b100001000000100000000, -30.0000000, 5750.0000000, -1515.0000000, nullptr, nullptr },
+ /* 200 */{ 0x20, 8, stage::allStages[9], 7, 0x12, 0xFF, 0b100001000000100000000, 5319.0000000, 7550.0000000, 8592.7500000, nullptr, nullptr },
+ /* 201 */{ 0x05, 7, stage::allStages[9], 7, 0x12, 0xFF, 0b100001000000100000000, 5300.0000000, 8100.0000000, -800.0000000, nullptr, nullptr },
+ /* 202 */{ 0x46, 0, stage::allStages[11], 51, 0x12, 0x12, 0b100001000000100100000, 0.0000000, -350.0000000, -2400.0000000, nullptr, nullptr },
+ /* 203 */{ 0x04, 7, stage::allStages[9], 5, 0x12, 0xFF, 0b100001000010100000000, 1195.0000000, 7400.0000000, 2350.0000000, nullptr, nullptr },
+ /* 204 */{ 0x04, 7, stage::allStages[9], 6, 0x12, 0xFF, 0b100001000010100000000, 6135.0000000, 8000.0000000, 0.0000000, nullptr, nullptr },
+ /* 205 */{ 0x26, 2, stage::allStages[9], 6, 0x12, 0x12, 0b100001000010100000000, 5350.0000000, 7400.0000000, 0.0000000, nullptr, nullptr },
+ /* 206 */{ 0x21, 3, stage::allStages[9], 4, 0x13, 0xFF, 0b100001000000110000000, -8740.0000000, 5100.0000000, -4515.0000000, nullptr, nullptr },
+ /* 207 */{ 0x04, 7, stage::allStages[9], 3, 0x12, 0xFF, 0b100001000000100000000, 0.0000000, 4850.0000000, 9200.0000000, nullptr, nullptr },
+ /* 208 */{ 0x21, 3, stage::allStages[9], 3, 0x13, 0xFF, 0b100001000000110000000, 1740.0000000, 4500.0000000, 5815.0000000, nullptr, nullptr },
+ /* 209 */{ 0x21, 3, stage::allStages[54], 2, 0x13, 0xFF, 0b100001000000010000000, 606.7956540, 1005.0000000, 8005.3901370, nullptr, nullptr },
+ /* 210 */{ 0x04, 7, stage::allStages[53], 4, 0x13, 0xFF, 0b000000000000000000000, 6500.0000000, 426.0000000, -977.0000000, nullptr, nullptr },
+ /* 211 */{ 0x21, 3, stage::allStages[56], 0, 0x13, 0xFF, 0b000000000000010000000, 31257.5957030, 900.0000000, -16115.4990230, nullptr, nullptr },
+ /* 212 */{ 0x06, 7, stage::allStages[56], 3, 0x13, 0xFF, 0b000000000000010000000, -10245.4765620, -4400.0000000, 42817.0467500, nullptr, nullptr },
+ /* 213 */{ 0x06, 7, stage::allStages[57], 8, 0x13, 0xFF, 0b000000000000010000000, -79819.4140620, -1301.2399900, 22400.6718750, nullptr, nullptr },
+ /* 214 */{ 0x06, 7, stage::allStages[56], 13, 0x13, 0xFF, 0b100000000010010000000, -93284.5703120, -5000.0000000, 18235.7246090, nullptr, nullptr },
+ /* 215 */{ 0x21, 3, stage::allStages[45], 5, 0x13, 0xFF, 0b100000100000010000000, -21012.1542970, 1350.0000000, -20630.3222660, nullptr, nullptr },
+ /* 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 },
+ /* 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 },
+ /* 223 */{ 0x05, 7, stage::allStages[12], 7, 0x14, 0xFF, 0b101000000010100000000, 13470.0000000, 1500.0000000, -7925.0000000, nullptr, nullptr },
+ /* 224 */{ 0x47, 0, stage::allStages[14], 51, 0x14, 0x14, 0b101000000010100000000, -0.3629600, 600.0000000, 2279.7690430, nullptr, nullptr },
+ /* 225 */{ 0x24, 2, stage::allStages[12], 4, 0x15, 0x15, 0b101000000001100000000, 10800.0000000, -1775.0000000, -11850.0000000, nullptr, nullptr },
+ /* 226 */{ 0x0F, 5, stage::allStages[12], 10, 0x15, 0xFF, 0b100000000001100000000, -11099.1240230, -1500.0000000, -15658.8515620, nullptr, nullptr },
+ /* 227 */{ 0x04, 7, stage::allStages[12], 10, 0x15, 0xFF, 0b100000000001100000000, -13458.7949220, 0.0000000, -13410.5566410, nullptr, nullptr },
+ /* 228 */{ 0x0B, 5, stage::allStages[12], 10, 0x15, 0xFF, 0b100000000001100000000, -10742.9599610, 0.0000000, -15156.7197270, nullptr, nullptr },
+ /* 229 */{ 0x03, 7, stage::allStages[12], 11, 0x15, 0xFF, 0b100000000001100000000, -15654.8398440, 2840.2299800, -18906.7890620, nullptr, nullptr },
+ /* 230 */{ 0x0F, 5, stage::allStages[12], 11, 0x15, 0xFF, 0b100000000001100000000, -12630.1699220, 2430.8999020, -19611.4316410, nullptr, nullptr },
+ /* 231 */{ 0x21, 3, stage::allStages[12], 11, 0x15, 0xFF, 0b100000000001100000000, -14567.1093750, 2281.0000000, -16989.0351560, nullptr, nullptr },
+ /* 232 */{ 0x04, 7, stage::allStages[12], 12, 0x15, 0xFF, 0b100000000001100000000, -15782.7958980, 2980.0000000, -11466.6982420, nullptr, nullptr },
+ /* 233 */{ 0x05, 7, stage::allStages[12], 12, 0x15, 0xFF, 0b100000000001100000000, -14270.5380860, 1982.1999510, -7411.9101560, nullptr, nullptr },
+ /* 234 */{ 0x0A, 5, stage::allStages[12], 12, 0x15, 0xFF, 0b100000000001100000000, -12592.9677730, 2400.0000000, -13712.7675780, nullptr, nullptr },
+ /* 235 */{ 0x21, 3, stage::allStages[12], 12, 0x15, 0xFF, 0b100000000001100000000, -11494.3183590, 3000.0000000, -9888.6738280, nullptr, nullptr },
+ /* 236 */{ 0x04, 7, stage::allStages[12], 13, 0x15, 0xFF, 0b100000000001100000000, 75.2376170, 4500.0000000, -10853.4550780, nullptr, nullptr },
+ /* 237 */{ 0x05, 7, stage::allStages[12], 13, 0x15, 0xFF, 0b100000000001100000000, 4010.3149410, 4500.0000000, -12451.9033200, nullptr, nullptr },
+ /* 238 */{ 0x26, 2, stage::allStages[12], 2, 0x15, 0x15, 0b100000000001100000000, -1090.9830320, 4500.0000000, -12411.7617190, nullptr, nullptr },
+ /* 239 */{ 0x04, 7, stage::allStages[12], 2, 0x15, 0xFF, 0b100000000001100000000, 11.8030090, 3000.0000000, -13501.7851560, nullptr, nullptr },
+ /* 240 */{ 0x05, 7, stage::allStages[12], 14, 0x15, 0xFF, 0b100000000001100000000, 0.0000000, 894.4799800, -23853.0000000, nullptr, nullptr },
+ /* 241 */{ 0x21, 3, stage::allStages[56], 3, 0x15, 0xFF, 0b000000000001000000000, -22100.0000000, -7176.0297850, 52140.0000000, nullptr, nullptr },
+ /* 242 */{ 0x06, 7, stage::allStages[52], 1, 0x15, 0xFF, 0b000000000001000000000, -2816.4138180, 1305.0787350, -1395.7875980, nullptr, nullptr },
+ /* 243 */{ 0x06, 7, stage::allStages[52], 1, 0x15, 0xFF, 0b000000000001000000000, 2798.9057620, 1322.1817720, -987.1356810, nullptr, nullptr },
+ /* 244 */{ 0x06, 7, stage::allStages[57], 16, 0x15, 0xFF, 0b000000000001000000000, -57374.0820310, -9100.0000000, 29237.9062500, nullptr, nullptr },
+ /* 245 */{ 0x20, 8, stage::allStages[15], 1, 0x15, 0xFF, 0b000000000000000000000, -3950.0000000, -1071.0000000, 1375.0000000, nullptr, nullptr },
+ /* 246 */{ 0x20, 8, stage::allStages[15], 2, 0x15, 0xFF, 0b000000000010000100000, -3950.0000000, -1200.0000000, -5075.0000000, nullptr, nullptr },
+ /* 247 */{ 0x24, 2, stage::allStages[15], 2, 0x15, 0x15, 0b000000000010000100000, -2700.0000000, -1196.0000000, -1661.0000000, nullptr, nullptr },
+ /* 248 */{ 0x06, 7, stage::allStages[15], 2, 0x15, 0xFF, 0b000000000001000100000, -2400.0000000, -21.2500000, -1550.0000000, nullptr, nullptr },
+ /* 249 */{ 0x21, 3, stage::allStages[15], 1, 0x15, 0xFF, 0b000000000010000000000, -6850.0000000, -771.2500000, 3200.0000000, nullptr, nullptr },
+ /* 250 */{ 0x05, 7, stage::allStages[15], 4, 0x15, 0xFF, 0b000000000010000000000, 3250.0000000, -696.2500000, 1235.0000000, nullptr, nullptr },
+ /* 251 */{ 0x20, 8, stage::allStages[15], 4, 0x15, 0xFF, 0b000000000010000000000, 4650.0000000, -696.2500000, 1235.0000000, nullptr, nullptr },
+ /* 252 */{ 0x05, 7, stage::allStages[15], 5, 0x15, 0xFF, 0b000000000001000100000, 5700.0000000, 3.7500000, -4350.0000000, nullptr, nullptr },
+ /* 253 */{ 0x05, 7, stage::allStages[15], 5, 0x15, 0xFF, 0b000000000001000100000, 2200.0000000, 3.7500000, -5100.0000000, nullptr, nullptr },
+ /* 254 */{ 0x23, 2, stage::allStages[15], 5, 0x15, 0x15, 0b000000000001000100000, 2300.0000000, -396.2500000, -3300.0000000, nullptr, nullptr },
+ /* 255 */{ 0x20, 8, stage::allStages[15], 5, 0x15, 0xFF, 0b000000000001000100000, 5600.0000000, -296.2500000, -3300.0000000, nullptr, nullptr },
+ /* 256 */{ 0x21, 3, stage::allStages[15], 4, 0x15, 0xFF, 0b000000000001000000000, 5352.5000000, -171.2500000, 3500.0000000, nullptr, nullptr },
+ /* 257 */{ 0x05, 7, stage::allStages[15], 4, 0x15, 0xFF, 0b000000000001000000000, 2547.5000000, -171.2500000, 3500.0000000, nullptr, nullptr },
+ /* 258 */{0x20, 8, stage::allStages[15], 7, 0xFF, 0xFF, 0b000000000001000000000, 1500.0000000, 128.7500000, 6250.0000000, nullptr, nullptr}, //PoT Central First Room Chest
+ /* 259 */{0x26, 2, stage::allStages[15], 11, 0xFF, 0xFF, 0b000000000001000100000, 0.0000000, 3130.0000000, -3600.0000000, nullptr, nullptr}, //PoT Big Key Chest
+ /* 260 */{0x20, 8, stage::allStages[15], 11, 0xFF, 0xFF, 0b000000000001000100000, -2900.0000000, -71.2500000, -2055.0000000, nullptr, nullptr}, //PoT Central Outdoor Chest
+ /* 261 */{0x20, 8, stage::allStages[15], 8, 0xFF, 0xFF, 0b000000000001000100000, -800.0000000, 1130.0000000, 1200.0000000, nullptr, nullptr}, //PoT Central Tower Chest
+ /* 262 */{0x06, 7, stage::allStages[20], 9, 0xFF, 0xFF, 0b000000100000000000000, 4025.0000000, 152.0000000, -11735.0000000, nullptr, nullptr}, //HC Graveyard Grave Switch Room Right Chest
+ /* 263 */{0x01, 7, stage::allStages[20], 9, 0xFF, 0xFF, 0b000000100000000000000, 3850.0000000, 152.0000000, -12725.0000000, nullptr, nullptr}, //HC Graveyard Grave Switch Room Front Left Small Chest
+ /* 264 */{0x04, 7, stage::allStages[20], 9, 0xFF, 0xFF, 0b000000100000000000000, 4075.0000000, 150.0000000, -12725.0000000, nullptr, nullptr}, //HC Graveyard Grave Switch Room Back Left Small Chest
+ /* 265 */{0x20, 8, stage::allStages[20], 9, 0xFF, 0xFF, 0b110000100000010000000, 375.0000000, 600.0000000, -6900.0000000, nullptr, nullptr}, //HC Graveyard Owl Statue Chest
+ /* 266 */{0x23, 2, stage::allStages[20], 14, 0xFF, 0xFF, 0b000100000000000000000, 1210.0000000, 0.0000000, -7002.0000000, nullptr, nullptr}, //HC Map Chest
+ /* 267 */{0x03, 7, stage::allStages[20], 14, 0xFF, 0xFF, 0b000100000000000000000, 4775.0000000, 1200.0000000, 3875.0000000, nullptr, nullptr}, //HC East Castle Balcony Chest
+ /* 268 */{0x04, 7, stage::allStages[20], 13, 0xFF, 0xFF, 0b000000000000000000000, -6420.0000000, 30.0000000, -8017.8183590, nullptr, nullptr}, //HC West Courtyard Northern Small Chest
+ /* 269 */{0x04, 7, stage::allStages[20], 13, 0xFF, 0xFF, 0b000000000000000000000, -6400.0000000, 350.0000000, 125.0000000, nullptr, nullptr}, //HC West Courtyard Central Small Chest
+ /* 270 */{0x24, 2, stage::allStages[20], 1, 0xFF, 0xFF, 0b000000000010000100000, 2400.0000000, 1250.0000000, -875.0000000, nullptr, nullptr}, //HC Compass Chest
+ /* 271 */{0x05, 7, stage::allStages[20], 2, 0xFF, 0xFF, 0b100100000010000000000, 25.0000000, 1875.0000000, -4975.0000000, nullptr, nullptr}, //HC Lantern Staircase Chest
+ /* 272 */{0x05, 7, stage::allStages[20], 1, 0xFF, 0xFF, 0b100001000010000100000, -1225.0000000, 2000.0000000, 2125.0000000, nullptr, nullptr}, //HC Main Hall Southwest Chest
+ /* 273 */{0x07, 7, stage::allStages[20], 1, 0xFF, 0xFF, 0b100001000010000100000, -2375.0000000, 1250.0000000, -900.0000000, nullptr, nullptr}, //HC Main Hall Northwest Chest
+ /* 274 */{0x20, 8, stage::allStages[20], 15, 0xFF, 0xFF, 0b100100000010000000000, 8685.0000000, 2000.0000000, 8690.0000000, nullptr, nullptr}, //HC Southeast Balcony Tower Chest
+ /* 275 */{0x26, 2, stage::allStages[20], 15, 0xFF, 0xFF, 0b100100000010000000000, -8700.0000000, 2000.0000000, 8700.0000000, nullptr, nullptr}, //HC Big Key Chest
+ /* 276 */{0x02, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3350.0000000, 6150.0000000, 3675.0000000, nullptr, nullptr}, //HC Treasure Room First Chest
+ /* 277 */{0x03, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3475.0000000, 6150.0000000, 3550.0000000, nullptr, nullptr}, //HC Treasure Room Second Chest
+ /* 278 */{0x04, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3600.0000000, 6150.0000000, 3425.0000000, nullptr, nullptr}, //HC Treasure Room Third Chest
+ /* 279 */{0x18, 5, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3700.0000000, 6150.0000000, 3250.0000000, nullptr, nullptr}, //HC Treasure Room Fourth Chest
+ /* 280 */{0x0F, 5, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3700.0000000, 6150.0000000, 3075.0000000, nullptr, nullptr}, //HC Treasure Room Fifth Chest
+ /* 281 */{0x0C, 5, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3700.0000000, 6150.0000000, 2750.0000000, nullptr, nullptr}, //HC Treasure Room First Small Chest
+ /* 282 */{0x01, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3700.0000000, 6150.0000000, 2525.0000000, nullptr, nullptr}, //HC Treasure Room Second Small Chest
+ /* 283 */{0x10, 5, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 3700.0000000, 6150.0000000, 2300.0000000, nullptr, nullptr}, //HC Treasure Room Third Small Chest
+ /* 284 */{0x05, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 2650.0000000, 6150.0000000, 2125.0000000, nullptr, nullptr}, //HC Treasure Room Fourth Small Chest
+ /* 285 */{0x1B, 5, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 2550.0000000, 6150.0000000, 2225.0000000, nullptr, nullptr}, //HC Treasure Room Fifth Small Chest
+ /* 286 */{0x07, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 2450.0000000, 6150.0000000, 2325.0000000, nullptr, nullptr}, //HC Treasure Room Sixth Small Chest
+ /* 287 */{0x12, 5, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 2350.0000000, 6150.0000000, 2425.0000000, nullptr, nullptr}, //HC Treasure Room Seventh Small Chest
+ /* 288 */{0x06, 7, stage::allStages[20], 8, 0xFF, 0xFF, 0b100100000001100100000, 2250.0000000, 6150.0000000, 2525.0000000, nullptr, nullptr}, //HC Treasure Room Eighth Small Chest
+ /* 289 */{0x40, 0, stage::allStages[8], 2, 0x1, 0x1, 0b000000000000000000000, 205.3669740, 3901.0000000, -6120.5043950, nullptr, nullptr}, //FT Boomerang
+ /* 290 */{ 0x42, 0, stage::allStages[29], 51, 0x11, 0x11, 0b000000100100000000000, -0.0000460, 47.0000000, -473.7650150, nullptr, nullptr }, //SPR Ball and Chain
+ /* 291 */{0x2A, 1, stage::allStages[43], 0, 0x1, 0x2, 0b000000000000000000100, 3845.178467, 185.000000, 697.817505, nullptr, nullptr}, //Ordon Shield
+ /* 292 */{ 0x28, 1, stage::allStages[65], 4, 0x1, 0x7, 0b000000000000000000000, 266.211700, 0.000000, -55.204613, nullptr, nullptr }, //Ordon Sword
+ /* 293 */{0x4A, 0, stage::allStages[43], 0, 0x0, 0x0, 0b000000000000000000000, -532.611450, 75.000000, 2287.597412, nullptr, nullptr}, //Fishing Rod
+ /* 294 */{0x65, 9, stage::allStages[43], 0, 0x0, 0xFF, 0b000000000000000000000, 739.763489, 87.500000, -1685.456421, nullptr, nullptr}, //Sera Bottle
+ /* 295 */{0x4B, 12, stage::allStages[43], 0, 0x0, 0x0, 0b000000000000000000000, -461.078217, 1618.401978, 7681.837891, nullptr, nullptr}, //Slingshot
+ /* 296 */{0x48, 0, stage::allStages[45], 4, 0x0, 0x0, 0b100010000000000001000, -15089.815430, 26.508539, -14135.130859, nullptr, nullptr}, //Lantern
+ /* 297 */{0x2C, 12, stage::allStages[68], 3, 0x2, 0x2, 0b001000000000000000000, -500.0000000, 320.0000000, -695.0000000, nullptr, nullptr}, //Hylian Shield (Malo)
+ /* 298 */{0x2B, 12, stage::allStages[68], 3, 0x2, 0xFF, 0b001000000000000000000, -500.0000000, 320.0000000, -695.0000000, nullptr, nullptr}, //Wooden Shield (Malo)
+ /* 299 */{0x55, 1, stage::allStages[74], 7, 0x7, 0x7, 0b111111100010000000000, -4400.0000000, 0.0000000, 2500.0000000, nullptr, nullptr}, //Big Quiver
+ /* 300 */{ 0x56, 1, stage::allStages[74], 7, 0x15, 0x15, 0b111111100001000000000, -4400.0000000, 0.0000000, 2500.0000000, nullptr, nullptr }, //Giant Quiver
+ /* 301 */{0x2C, 12, stage::allStages[73], 4, 0x5, 0xFF, 0b111111100000000000000, -494.7930300, 100.0000000, 3701.0000000, nullptr, nullptr}, //Hylian Shield (Goron)
+ /* 302 */{0x21, 3, stage::allStages[46], 0, 0x2, 0xFF, 0b111111100000000000000, -2010.0000000, 151.0000000, 7897.0000000, nullptr, nullptr}, //Kakariko Bomb Rock Spire Heart Piece
+ /* 303 */{0x21, 3, stage::allStages[56], 6, 0x2, 0xFF, 0b110110000000000000000, -46688.0000000, -7953.0000000, 86307.0000000, nullptr, nullptr}, //Faron Tree Heart Piece
+ /* 304 */{0x21, 3, stage::allStages[56], 3, 0x2, 0xFF, 0b110110000000000000000, -21270.0000000, -5620.0000000, 55553.0000000, nullptr, nullptr}, //Kakariko Gorge Spire Heart Piece
+ /* 305 */{0x22, 3, stage::allStages[7], 50, 0x2, 0xFF, 0b110110000000000000000, 50.0000000, 3.0000000, 1703.0000000, nullptr, nullptr}, //Diababa Heart Container
+ /* 306 */{0x21, 3, stage::allStages[41], 0, 0x2, 0xFF, 0b001000000000000000000, -4358.0000000, 15307.0000000, -19476.0000000, nullptr, nullptr}, //Herding Goats Heart Piece
+ /* 307 */{0x22, 3, stage::allStages[4], 50, 0x4, 0xFF, 0b111111000000000000000, 203.0000000, 0.0000000, 830.0000000, nullptr, nullptr}, //Fyrus Heart Container
+ /* 308 */{0x22, 3, stage::allStages[1], 50, 0x7, 0xFF, 0b111111010010001000000, -915.0000000, -23960.0000000, 8916.0000000, nullptr, nullptr}, //Morpheel Heart Container
+ /* 309 */{ 0x22, 3, stage::allStages[25], 50, 0x10, 0xFF, 0b111111010010101000000, 85.0000000, 1799.0000000, -1264.0000000, nullptr, nullptr },
+ /* 310 */{ 0x22, 3, stage::allStages[28], 50, 0x12, 0xFF, 0b111111010110101000000, 279.0000000, 43.0000000, -865.0000000, nullptr, nullptr },
+ /* 311 */{ 0x22, 3, stage::allStages[10], 50, 0x13, 0xFF, 0b111111010110111000000, 900.0000000, 0.0000000, 0.0000000, nullptr, nullptr },
+ /* 312 */{ 0x22, 3, stage::allStages[13], 50, 0x15, 0xFF, 0b111111010101111000000, 317.0000000, 0.0000000, 764.0000000, nullptr, nullptr },
+ /* 313 */{0x22, 3, stage::allStages[16], 10, 0xFF, 0xFF, 0b111111010101111000000, -3.0000000, 2525.0000000, -14603.0000000, nullptr, nullptr}, //Zant Heart Container
+ /* 314 */{0x31, 1, stage::allStages[48], 0, 0x5, 0x5, 0b111111100000000000000, 21450.962891, 500.000000, 305.869934, nullptr, nullptr}, //Zora Armor
+ /* 315 */{ 0x30, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr }, //Magic Armor
+ /* 316 */{0x4F, 1, stage::allStages[52], 0, 0x5, 0xFF, 0b111111110000000000000, -77679.9375000, -18765.0000000, 40764.0000000, nullptr, nullptr}, //Giant Bomb Bag
+ /* 317 */{ 0x3D, 0, stage::allStages[48], 0, 0x10, 0x10, 0b111111010010101000000, 21413.962891, 500.681793, -368.516510, nullptr, nullptr },
+ /* 318 */{ 0x3E, 12, stage::allStages[68], 3, 0x4, 0x12, 0b111111000000000000000, -500.0000000, 320.0000000, -695.0000000, nullptr, nullptr }, //Hawkeye
+ /* 319 */{0x51, 0, stage::allStages[50], 0, 0x5, 0xFF, 0b111111010000000000000, 44.0000000, -3854.0000000, -2626.0000000, nullptr, nullptr}, //Goron Bomb Bag
+ /* 320 */{0x50, 0, stage::allStages[68], 1, 0x4, 0x4, 0b111111000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr}, //Barnes Bomb Bag
+ /* 321 */{0x51, 0, stage::allStages[52], 0, 0x5, 0xFF, 0b111111100000000000000, -77680.0000000, -18765.0000000, 40764.0000000, nullptr, nullptr},//Iza Bomb Bag
+ /* 322 */{ 0x90, 4, stage::allStages[52], 0, 0x8, 0x8, 0b111111010010001000000, -116117.015625, -15810.000000, 58812.617188, nullptr, nullptr }, //Auru's Memo
+ /* 323 */{ 0x91, 4, stage::allStages[51], 0, 0x10, 0x10, 0b000000000000000000000, 31608.291016, -13330.000000, -11652.610352, nullptr, nullptr }, //Aeshi's Sketch
+ /* 324 */{ 0x80, 4, stage::allStages[46], 0, 0xFF, 0x13, 0b000000000000000000000, -324.903625, 0.000000, 435.528595, nullptr, nullptr }, //Renardo's Letter
+ /* 325 */{ 0x81, 4, stage::allStages[53], 5, 0xFF, 0x13, 0b000000000000000000000, 2694.345215, -1150.000000, 3105.746826, nullptr, nullptr }, //Invoice
+ /* 326 */{ 0x82, 4, stage::allStages[57], 16, 0xFF, 0x13, 0b000000000000000000000, -51514.375000, -6269.229980, 31816.427734, nullptr, nullptr }, //Wooden Statue
+ /* 327 */{ 0x83, 4, stage::allStages[63], 0, 0xFF, 0x13, 0b000000000000000000000, 2077.769775, 104.958275, -1301.828491, nullptr, nullptr }, //Ilia's Charm
+ /* 328 */{ 0x84, 4, stage::allStages[68], 0, 0xFF, 0x13, 0b000000000000000000000, 312.675079, 0.000000, -160.984177, nullptr, nullptr }, //Horse Call
+ /* 329 */{0x9d, 9, stage::allStages[45], 4, 0x1, 0xFF, 0b000000000000000000000, -13659.433594, -0.454284, -14367.083008, nullptr, nullptr}, //Coro Bottle
+ /* 330 */{0x75, 9, stage::allStages[73], 5, 0xFF, 0xFF, 0b000000000000000000000, 4250.363281, 134.492020, 1813.639648, nullptr, nullptr}, //Jovani Bottle
+ /* 331 */{ 0x60, 9, stage::allStages[62], 0, 0x5, 0x5, 0b000000000000000000000, 5772.262695, 35.000000, 2218.249512, nullptr, nullptr }, //Fishing Hole Bottle
+ /* 332 */{0x2B, 12, stage::allStages[47], 3, 0x3, 0xFF, 0b001000000000000000000, -6545.0000000, -125.0000000, -2275.0000000, nullptr, nullptr}, //Wooden Shield (Goron)
+ /* 333 */{0x21, 3, stage::allStages[46], 0, 0x4, 0xFF, 0b000001000000000000000, -900.000000, 0.780221, 6600.000000, nullptr, nullptr}, //Bow Shooting Game Heart Piece
+ /* 334 */{0x21, 3, stage::allStages[53], 2, 0x5, 0xFF, 0b000000000000000000000, -4142.703125, 0.000000, -569.375000, nullptr, nullptr}, //Donation Heart Piece
+ /* 335 */{ 0x21, 3, stage::allStages[62], 0, 0xFF, 0xFF, 0b101000000010000000000, -2678.128906, -167.094162, 2246.794186, nullptr, nullptr },
+ /* 336 */{ 0x21, 3, stage::allStages[56], 0, 0x8, 0xFF, 0b000000000000000000000, -25148.583984, -200.000000, 9814.881836, nullptr, nullptr },
+ /* 337 */{ 0x21, 3, stage::allStages[61], 0, 0x8, 0xFF, 0b000000000000000000000, 3618.216797, 232.476608, 541.905518, nullptr, nullptr },
+ /* 338 */{ 0x21, 3, stage::allStages[55], 1, 0x8, 0xFF, 0b000000000000000000000, 4708.924805, 260.000000, -3120.967529, nullptr, nullptr },
+ /* 339 */{ 0x23, 2, stage::allStages[27], 1, 0xFF, 0x11, 0b000000000000000000000, 293.920288, 0.000000, -337.167480, nullptr, nullptr }, // Yeta Map
+ /* 340 */{ 0x21, 3, stage::allStages[51], 1, 0x12, 0xFF, 0b000000000000000000000, -71795.539062, -54450.000000, 56396.738281, nullptr, nullptr },
+ /* 341 */{ 0x21, 3, stage::allStages[63], 0, 0x13, 0xFF, 0b000000000000000000010, 2200.000000, 104.574730, -1200.000000, nullptr, nullptr },
+ /* 342 */{0x20, 8, stage::allStages[20], 13, 0xFF, 0xFF, 0b000000000000000000000, -7625.000000, 52.000000, -5525.000000, nullptr, nullptr}, //
+ /* 343 */{0x20, 8, stage::allStages[6], 7, 0x1, 0xFF, 0b000000000000000000000, -5703.254883, 4372.640137, 11664.798828, nullptr, nullptr},
+
+
+ //Ooccoo
+ /* 344 */{ 0x33, 2, stage::allStages[6], 1, 0x1, 0x1, 0b000000000000000000000, 3775.943604, 3167.790039, 5428.488281, nullptr, nullptr },
+ /* 345 */{ 0x33, 2, stage::allStages[3], 14, 0x3, 0x3, 0b000000000000000000000, -14154.718750, 190.286682, 2185.947510, nullptr, nullptr },
+ /* 346 */{ 0x33, 2, stage::allStages[0], 2, 0x6, 0x6, 0b000000000000000000000, 2045.683228, 1500.000000, 1642.919189, nullptr, nullptr },
+ /* 347 */{ 0x33, 2, stage::allStages[24], 10, 0x9, 0x9, 0b000000000000000000000, -667.577815, -2100.000000, 4029.893311, nullptr, nullptr },
+ /* 348 */{ 0x33, 2, stage::allStages[27], 2, 0x11, 0x11, 0b000000000000000000000, 3742.823975, 0.000000, 1621.097900, nullptr, nullptr },
+ /* 349 */{ 0x33, 2, stage::allStages[9], 0, 0x12, 0x12, 0b000000000000000000000, -28.417549, 725.000000, 3091.288574, nullptr, nullptr },
+ /* 350 */{ 0x33, 2, stage::allStages[12], 16, 0x14, 0x14, 0b000000000000000000000, 6082.295898, 0.000000, 5896.656738, nullptr, nullptr },
+ //overworld keys
+ /* 351 */{ 0xfe, 8, stage::allStages[45], 4, 0xFF, 0xFF, 0b000000000000000000000, -13022.520508, -3.070827, -14673.488281, nullptr, nullptr },
+ /* 352 */{ 0xf3, 4, stage::allStages[58], 13, 0x5, 0xFF, 0b000000000000000000000, -93334.218750, -5725.979980, 44504.023438, nullptr, nullptr },
+ /* 353 */{ 0x20, 8, stage::allStages[55], 1, 0x9, 0xFF, 0b000000000000000000000, 4087.104248, 260.000000, -3795.968262, nullptr, nullptr },
+ //goron mines key shards
+ /* 354 */{ 0xf9, 2, stage::allStages[3], 14, 0x3, 0x3, 0b000000000000000000000, -15375.557617, -636.630005, 1595.673462, nullptr, nullptr },
+ /* 355 */{ 0xfa, 2, stage::allStages[3], 17, 0x3, 0x3, 0b000000000000000000000, 13007.017578, 2924.530029, -17705.732422, nullptr, nullptr },
+ /* 356 */{ 0xfd, 2, stage::allStages[3], 16, 0x4, 0x3, 0b000000000000000000000, 13055.647461, 2400.500000, -1660.316895, nullptr, nullptr },
+ //bugs
+ /* 357 */{ 0xc0, 10, stage::allStages[56], 6, 0x2, 0xFF, 0b000000000000000000000, -50212.730469, -8840.560547, 86352.757812, nullptr, nullptr },
+ /* 358 */{ 0xc1, 10, stage::allStages[56], 6, 0x2, 0xFF, 0b000100000010000000000, -38651.949219, -9189.901367, 73707.671875, nullptr, nullptr },
+ /* 359 */{ 0xca, 10, stage::allStages[56], 3, 0x2, 0xFF, 0b000000000000000000000, -9730.929688, -7200.000000, 57526.199219, nullptr, nullptr },
+ /* 360 */{ 0xcb, 10, stage::allStages[56], 3, 0x2, 0xFF, 0b000000000000000000000, 562.488159, -6092.589844, 61677.734375, nullptr, nullptr },
+ /* 361 */{ 0xd4, 10, stage::allStages[48], 0, 0x2, 0xFF, 0b000000000000000000000, 17085.654297, 557.072510, -850.370605, nullptr, nullptr },
+ /* 362 */{ 0xd5, 10, stage::allStages[68], 6, 0x2, 0xFF, 0b000000000000000000000, 205.938171, 17.797655, 4.593423, nullptr, nullptr },
+ /* 363 */{ 0xc6, 10, stage::allStages[56], 0, 0x2, 0xFF, 0b000000000000000000000, 19503.787109, 662.713684, 13563.345703, nullptr, nullptr },
+ /* 364 */{ 0xc7, 10, stage::allStages[56], 0, 0x2, 0xFF, 0b000000000000000000000, -10765.343750, 80.466759, -9151.101562, nullptr, nullptr },
+ /* 365 */{ 0xc8, 10, stage::allStages[56], 0, 0x2, 0xFF, 0b000100000010000000000, 34607.441406, -260.000000, -14273.162109, nullptr, nullptr },
+ /* 366 */{ 0xc9, 10, stage::allStages[56], 0, 0x2, 0xFF, 0b000100000010000000000, 37897.406250, -260.000000, -40525.894531, nullptr, nullptr },
+ /* 367 */{ 0xcc, 10, stage::allStages[56], 13, 0x5, 0xFF, 0b000100000010000000000, -93754.703125, -5925.377441, 31642.708984, nullptr, nullptr },
+ /* 368 */{ 0xcd, 10, stage::allStages[56], 13, 0x5, 0xFF, 0b000100000010000000000, -88147.609375, -6854.451660, 58998.777344, nullptr, nullptr },
+ /* 369 */{ 0xc2, 10, stage::allStages[57], 8, 0x5, 0xFF, 0b000000000000000000000, -75074.406250, -384.115967, 16053.256836, nullptr, nullptr },
+ /* 370 */{ 0xc3, 10, stage::allStages[57], 8, 0x5, 0xFF, 0b000100000010000000000, -78787.265625, -1472.352661, 2016.588013, nullptr, nullptr },
+ /* 371 */{ 0xce, 10, stage::allStages[57], 16, 0x5, 0xFF, 0b000000000000000000000, -45085.273438, 6042.771484, 29910.453125, nullptr, nullptr },
+ /* 372 */{ 0xcf, 10, stage::allStages[57], 16, 0x5, 0xFF, 0b000000000000000000000, -54377.070312, -5460.576660, 27647.970703, nullptr, nullptr },
+ /* 373 */{ 0xc4, 10, stage::allStages[56], 10, 0x5, 0xFF, 0b000000000000000000000, -62781.214844, -1350.003052, -33241.687500, nullptr, nullptr },
+ /* 374 */{ 0xc5, 10, stage::allStages[56], 10, 0x5, 0xFF, 0b000000000000000000000, -48976.765625, -677.295044, -50834.683594, nullptr, nullptr },
+ /* 375 */{ 0xd2, 10, stage::allStages[50], 1, 0x5, 0xFF, 0b000000000000000000000, 3540.047363, -5150.441895, 15789.274414, nullptr, nullptr },
+ /* 376 */{ 0xd3, 10, stage::allStages[61], 1, 0x5, 0xFF, 0b000000000000000000000, 6013.379395, 445.474884, -224.899765, nullptr, nullptr },
+ /* 377 */{ 0xd6, 10, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 28767.958984, 524.933899, 58604.546875, nullptr, nullptr },
+ /* 378 */{ 0xd7, 10, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000000, 11790.147461, 340.034332, 55725.250000, nullptr, nullptr },
+ /* 379 */{ 0xd0, 10, stage::allStages[54], 1, 0x12, 0xFF, 0b000000000000000000000, 1304.371826, 1005.000000, 7306.179688, nullptr, nullptr },
+ /* 380 */{ 0xd1, 10, stage::allStages[54], 2, 0x12, 0xFF, 0b000100000010000000000, 521.038208, 1000.000000, 5867.415527, nullptr, nullptr },
+ //bug rewards
+ /* 381 */{ 0x35, 1, stage::allStages[73], 3, 0xFF, 0x5, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 382 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 383 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 384 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 385 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 386 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 387 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 388 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 389 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 390 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 391 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 392 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 393 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 394 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 395 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 396 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 397 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 398 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 399 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 400 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 401 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 402 */{ 0x06, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 403 */{ 0x05, 7, stage::allStages[73], 3, 0xFF, 0xFF, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ /* 404 */{ 0x36, 1, stage::allStages[73], 3, 0xFF, 0x12, 0b000000000000000000000, -123.609940, 40.000000, 305.168640, nullptr, nullptr },
+ //poes
+ /*#1*/{ 0xe0, 11, stage::allStages[24], 2, 0x9, 0xFF, 0b000000000000000000010, 105.801384, -19.549999, -741.391968, nullptr, nullptr },
+ /*#2*/{ 0xe0, 11, stage::allStages[24], 3, 0x9, 0xFF, 0b100000000010000000010, 3606.844482, 150.030182, -5323.249512, nullptr, nullptr },
+ /*#3*/{ 0xe0, 11, stage::allStages[24], 5, 0x9, 0xFF, 0b000000000000000000010, 5712.277344, 1050.019775, 4526.544922, nullptr, nullptr },
+ /*#4*/{ 0xe0, 11, stage::allStages[24], 8, 0x9, 0xFF, 0b000000000000000000010, -4197.771973, 1040.154663, 4983.674805, nullptr, nullptr },
+ /*#5*/{ 0xe0, 11, stage::allStages[73], 5, 0x8, 0xFF, 0b000000000000000000010, 4529.513672, -75.000000, 2609.175049, nullptr, nullptr },
+ /*#6*/{ 0xe0, 11, stage::allStages[31], 16, 0x10, 0xFF, 0b100000000000100000010, 126.849854, -20000.000000, -337.206903, nullptr, nullptr },
+ /*#7*/{ 0xe0, 11, stage::allStages[31], 32, 0x13, 0xFF, 0b100000000100110000010, 231.875824, -40000.000000, -216.2944296, nullptr, nullptr },
+ /*#8*/{ 0xe0, 11, stage::allStages[31], 43, 0x15, 0xFF, 0b100000000101110000010, -4560.734375, -53750.000000, -825.646851, nullptr, nullptr },
+ /*#9*/{ 0xe0, 11, stage::allStages[12], 12, 0x15, 0xFF, 0b100000000001000000010, -12660.987305, 1982.199951, -7632.476074, nullptr, nullptr },
+ /*#10*/{ 0xe0, 11, stage::allStages[12], 13, 0x15, 0xFF, 0b100000000001000000010, 3916.892090, 4496.779785, -12149.609375, nullptr, nullptr },
+ /*#11*/{ 0xe0, 11, stage::allStages[47], 0, 0x8, 0xFF, 0b000000000000000000010, -2502.529785, -1533.660522, 18041.601562, nullptr, nullptr },
+ /*#12*/{ 0xe0, 11, stage::allStages[45], 11, 0x8, 0xFF, 0b000000000000000000010, -25786.427734, 300.000000, -20456.810547, nullptr, nullptr },
+ /*#13*/{ 0xe0, 11, stage::allStages[59], 0, 0x9, 0xFF, 0b000000000000000000010, 66240.039062, 143.258804, 56904.339844, nullptr, nullptr },
+ /*#14*/{ 0xe0, 11, stage::allStages[59], 0, 0x9, 0xFF, 0b100000000010000000010, -816.907959, 2496.226562, 57933.289062, nullptr, nullptr },
+ /*#15*/{ 0xe0, 11, stage::allStages[59], 0, 0x9, 0xFF, 0b100000000010000000010, 26747.324219, -46.507732, 26175.406250, nullptr, nullptr },
+ /*#16*/{ 0xe0, 11, stage::allStages[37], 2, 0x9, 0xFF, 0b100000000010000000010, -1026.819824, 1.152117, -161.420013, nullptr, nullptr },
+ /*#17*/{ 0xe0, 11, stage::allStages[37], 2, 0x9, 0xFF, 0b100000000010000000010, -286.849121, 3.514773, -895.548218, nullptr, nullptr },
+ /*#18*/{ 0xe0, 11, stage::allStages[59], 0, 0x9, 0xFF, 0b100000000010000000010, -2024.554443, 16.013172, 11583.281250, nullptr, nullptr },
+ /*#19*/{ 0xe0, 11, stage::allStages[55], 1, 0x9, 0xFF, 0b000000000000000000010, 1812.931274, 0.000000, 1155.415161, nullptr, nullptr },
+ /*#20*/{ 0xe0, 11, stage::allStages[55], 3, 0x9, 0xFF, 0b000000000000000000010, 283.265228, 840.000000, -12366.407227, nullptr, nullptr },
+ /*#21*/{ 0xe0, 11, stage::allStages[48], 0, 0x8, 0xFF, 0b000000000000000000010, 12836.060547, 100.000000, 178.608246, nullptr, nullptr },
+ /*#22*/{ 0xe0, 11, stage::allStages[48], 0, 0x8, 0xFF, 0b000000000000000000010, 14444.615234, 256.835815, -527.642578, nullptr, nullptr },
+ /*#24*/{ 0xe0, 11, stage::allStages[63], 0, 0x13, 0xFF, 0b100000000000010000010, 1683.054077, 480.000000, -6715.406250, nullptr, nullptr },
+ /*#24*/{ 0xe0, 11, stage::allStages[57], 8, 0x8, 0xFF, 0b000000000000000000010, -81042.460938, -1650.079956, 21720.513672, nullptr, nullptr },
+ /*#25*/{ 0xe0, 11, stage::allStages[57], 17, 0x8, 0xFF, 0b000000000000000000010, -42291.773438, -1400.000000, 10844.620117, nullptr, nullptr },
+ /*#26*/{ 0xe0, 11, stage::allStages[56], 3, 0x8, 0xFF, 0b000000000000000000010, -10858.849609, -5700.000000, 55509.773438, nullptr, nullptr },
+ /*#27*/{ 0xe0, 11, stage::allStages[32], 0, 0x8, 0xFF, 0b110000000000000000010, 4567.875977, 5027.688477, -5207.911621, nullptr, nullptr },
+ /*#28*/{ 0xe0, 11, stage::allStages[56], 6, 0x8, 0xFF, 0b000000000000000000010, -45153.691406, -8909.261719, 74205.156250, nullptr, nullptr },
+ /*#29*/{ 0xe0, 11, stage::allStages[56], 10, 0x8, 0xFF, 0b110000000000000000010, -45192.148438, -2474.139893, -32984.613281, nullptr, nullptr },
+ /*#30*/{ 0xe0, 11, stage::allStages[35], 0, 0x8, 0xFF, 0b110000000000000000010, 269.485474, 22.380699, -981.643372, nullptr, nullptr },
+ /*#31*/{ 0xe0, 11, stage::allStages[35], 0, 0x8, 0xFF, 0b110000000000000000010, -236.254684, 150.000000, -1036.175781, nullptr, nullptr },
+ /*#32*/{ 0xe0, 11, stage::allStages[57], 16, 0x8, 0xFF, 0b000000000000000000010, -53146.578125, -5153.850098, 25666.673828, nullptr, nullptr },
+ /*#33*/{ 0xe0, 11, stage::allStages[56], 13, 0x8, 0xFF, 0b100000001010000000010, -81177.609375, -6000.000000, 65960.148438, nullptr, nullptr },
+ /*#34*/{ 0xe0, 11, stage::allStages[46], 0, 0x8, 0xFF, 0b000000000000000000010, 3372.341553, 2300.000000, -3018.808594, nullptr, nullptr },
+ /*#35*/{ 0xe0, 11, stage::allStages[46], 0, 0x8, 0xFF, 0b000000000000000000010, -1487.586548, 3848.365234, -5915.137207, nullptr, nullptr },
+ /*#36*/{ 0xe0, 11, stage::allStages[52], 0, 0x8, 0xFF, 0b000000000000000000010, -74531.953125, -18336.878906, 47025.640625, nullptr, nullptr },
+ /*#37*/{ 0xe0, 11, stage::allStages[52], 0, 0x8, 0xFF, 0b000000000000000000010, -96335.820312, -17510.320312, 62149.574219, nullptr, nullptr },
+ /*#38*/{ 0xe0, 11, stage::allStages[52], 0, 0x8, 0xFF, 0b000000000000000000010, -115949.156250, -15840.000000, 59894.671875, nullptr, nullptr },
+ /*#39*/{ 0xe0, 11, stage::allStages[52], 0, 0x8, 0xFF, 0b101000000000000000010, -104251.976562, -18469.791016, 42262.726562, nullptr, nullptr },
+ /*#40*/{ 0xe0, 11, stage::allStages[52], 0, 0x8, 0xFF, 0b101000000000000000010, -115114.968750, -14096.000000, 25330.574219, nullptr, nullptr },
+ /*#41*/{ 0xe0, 11, stage::allStages[33], 0, 0x8, 0xFF, 0b100000100000000000010, 8918.118164, 355.380005, -6922.565430, nullptr, nullptr },
+ /*#42*/{ 0xe0, 11, stage::allStages[33], 0, 0x8, 0xFF, 0b110000000000000000010, 801.443970, -4197.580078, -20497.589844, nullptr, nullptr },
+ /*#43*/{ 0xe0, 11, stage::allStages[33], 0, 0x8, 0xFF, 0b110000000000000000010, 6740.693848, -5139.174805, -10953.290039, nullptr, nullptr },
+ /*#44*/{ 0xe0, 11, stage::allStages[54], 3, 0x12, 0xFF, 0b100000100000000000010, -5483.465332, 500.000000, 5302.014648, nullptr, nullptr },
+ /*#45*/{ 0xe0, 11, stage::allStages[54], 1, 0x12, 0xFF, 0b000000000000000000010, 1214.411987, 1639.093384, -3631.436035, nullptr, nullptr },
+ /*#46*/{ 0xe0, 11, stage::allStages[54], 3, 0x12, 0xFF, 0b000000000000000000010, -21789.335936, 2200.000000, 10000.409180, nullptr, nullptr },
+ /*#47*/{ 0xe0, 11, stage::allStages[51], 0, 0x11, 0xFF, 0b100000000000000010010, 843.887695, -9361.725586, -21468.560547, nullptr, nullptr },
+ /*#48*/{ 0xe0, 11, stage::allStages[51], 0, 0x11, 0xFF, 0b100000000000000010010, 7834.021484, -8356.457031, -18110.230469, nullptr, nullptr },
+ /*#49*/{ 0xe0, 11, stage::allStages[51], 0, 0x11, 0xFF, 0b100000000000000010010, -4954.811035, -4714.479980, -18838.253906, nullptr, nullptr },
+ /*#50*/{ 0xe0, 11, stage::allStages[51], 2, 0x12, 0xFF, 0b100000000100000000010, -6137.537598, -1800.000000, -10043.368164, nullptr, nullptr },
+ /*#51*/{ 0xe0, 11, stage::allStages[51], 1, 0x11, 0xFF, 0b100000000000000010010, -69507.492188, -52429.000000, 62508.425781, nullptr, nullptr },
+ /*#52*/{ 0xe0, 11, stage::allStages[27], 0, 0x11, 0xFF, 0b000000000000000000010, -238.949356, -2.310000, 2920.424072, nullptr, nullptr },
+ /*#53*/{ 0xe0, 11, stage::allStages[27], 0, 0x12, 0xFF, 0b100000000100000000010, 533.658569, -84.440002, 5910.784180, nullptr, nullptr },
+ /*#54*/{ 0xe0, 11, stage::allStages[27], 6, 0x12, 0xFF, 0b100000000100000000010, 4784.004395, 950.000000, 331.876648, nullptr, nullptr },
+ /*#55*/{ 0xe0, 11, stage::allStages[9], 2, 0x13, 0xFF, 0b100000000000010000010, -3295.982178, 2750.000000, 11.354874, nullptr, nullptr },
+ /*#56*/{ 0xe0, 11, stage::allStages[9], 5, 0x12, 0xFF, 0b100000000010100000010, 1861.281128, 7400.000000, -358.31518, nullptr, nullptr },
+ /*#57*/{ 0xe0, 11, stage::allStages[54], 2, 0x13, 0xFF, 0b100000000000010000010, -1086.470947, 925.000000, 6306.895020, nullptr, nullptr },
+ /*#58*/{ 0xe0, 11, stage::allStages[61], 0, 0x8, 0xFF, 0b000000000000000000010, 942.983948, 817.438049, 3387.270996, nullptr, nullptr },
+ /*#59*/{ 0xe0, 11, stage::allStages[50], 0, 0x8, 0xFF, 0b000000000000000000010, 3444.790039, -4658.747559, 11720.103516, nullptr, nullptr },
+ /*#60*/{ 0xe0, 11, stage::allStages[50], 0, 0x8, 0xFF, 0b000000000000000000010, 297.160065, -4608.964844, 7384.047852, nullptr, nullptr },
+ /*60 poe reward*/{ 0x07, 7, stage::allStages[73], 5, 0x15, 0xFF, 0b000000000000000000000, 4250.363281, 134.492020, 1813.639648, nullptr, nullptr },
+ //sky book quest
+ /*empty*/{ 0xe9, 0, stage::allStages[72], 0, 0x13, 0x13, 0b000000000000010000000, -532.266479, 1.500000, -343.810791, nullptr, nullptr },
+ /*faron*/{ 0xea, 0, stage::allStages[45], 8, 0x13, 0x13, 0b000000000000010000000, -17500.000000, -310.000000, -20950.000000, nullptr, nullptr },
+ /*eldin gorge*/{ 0xea, 0, stage::allStages[56], 3, 0x13, 0x13, 0b000000000000010000000, -10195.000000, -4760.000000, 39363.000000, nullptr, nullptr },
+ /*edin bridge*/{ 0xea, 0, stage::allStages[56], 0, 0x13, 0x13, 0b000000000000010000000, 33650.000000, -80.000000, -35970.000000, nullptr, nullptr },
+ /*west castle*/{ 0xea, 0, stage::allStages[57], 8, 0x13, 0x13, 0b000000000000010000000, -81950.000000, -1300.000000, 20650.000000, nullptr, nullptr },
+ /*hylia bridge*/{ 0xea, 0, stage::allStages[56], 13, 0x13, 0x13, 0b000000000000010000000, -94664.000000, -5040.000000, 18311.000000, nullptr, nullptr },
+ /*desert*/{ 0xea, 0, stage::allStages[59], 0, 0x13, 0x13, 0b000000000000010000000, 15120.000000, 952.169983, 59670.000000, nullptr, nullptr },
+ //shop items
+ //Ordon
+ {0x64, 12, stage::allStages[65], 1, 0x5, 0xFF, 0b000000000000000000000, -55.0000000, 0.0000000, -156.0000000, nullptr, nullptr},
+ {0x66, 12, stage::allStages[65], 1, 0x1, 0xFF, 0b000000000000000000000, -55.0000000, 0.0000000, -156.0000000, nullptr, nullptr},
+ {0x9e, 12, stage::allStages[65], 1, 0x5, 0xFF, 0b000000000000000000000, -55.0000000, 0.0000000, -156.0000000, nullptr, nullptr},
+ //Coro
+ /*auto gotten*///{0x66, 12, stage::allStages[45], 4, 0x1, 0xFF, 0b000000000000000000000, -13659.433594, -0.454284, -14367.083008, nullptr, nullptr},
+ //Malo Kakariko
+ /*auto gotten*///{0x0e, 12, stage::allStages[68], 3, 0x5, 0xFF, 0b001000000000000000000, -500.0000000, 320.0000000, -695.0000000, nullptr, nullptr},
+ {0x61, 12, stage::allStages[68], 3, 0x5, 0xFF, 0b001000000000000000000, -500.0000000, 320.0000000, -695.0000000, nullptr, nullptr},
+ //Goron Shop Death Mountain
+ /*auto gotten*///{0x0e, 12, stage::allStages[47], 3, 0x5, 0xFF, 0b001000000000000000000, -6545.0000000, -125.0000000, -2275.0000000, nullptr, nullptr},
+ {0x66, 12, stage::allStages[47], 3, 0x3, 0xFF, 0b001000000000000000000, -6545.0000000, -125.0000000, -2275.0000000, nullptr, nullptr},
+ {0x64, 12, stage::allStages[47], 3, 0x5, 0xFF, 0b001000000000000000000, -6545.0000000, -125.0000000, -2275.0000000, nullptr, nullptr},
+ //Barnes
+ /*auto gotten*///{0x0b, 12, stage::allStages[68], 1, 0x4, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x0c, 12, stage::allStages[68], 1, 0x4, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x0d, 12, stage::allStages[68], 1, 0x4, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x16, 12, stage::allStages[68], 1, 0x5, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x17, 12, stage::allStages[68], 1, 0x5, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x18, 12, stage::allStages[68], 1, 0x5, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x1d, 12, stage::allStages[68], 1, 0x8, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x1a, 12, stage::allStages[68], 1, 0x8, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x1b, 12, stage::allStages[68], 1, 0x8, 0xFF, 0b000000000000000000000, 800.0000000, 0.0000000, -300.0000000, nullptr, nullptr},
+ //Goron Night Kakariko
+ {0x63, 12, stage::allStages[46], 0, 0x5, 0xFF, 0b001000000000000000000, -1350.000000, 0.000000, -3070.000000, nullptr, nullptr},
+ {0x61, 12, stage::allStages[46], 0, 0x5, 0xFF, 0b001000000000000000000, -1350.000000, 0.000000, -3070.000000, nullptr, nullptr},
+ {0x66, 12, stage::allStages[46], 0, 0x4, 0xFF, 0b001000000000000000000, -1350.000000, 0.000000, -3070.000000, nullptr, nullptr},
+ //Goron Merchants Castle Town
+ {0x61, 12, stage::allStages[73], 4, 0x5, 0xFF, 0b111111100000000000000, -685.106323, 100.000000, 3819.986572, nullptr, nullptr},
+ {0x66, 12, stage::allStages[73], 4, 0x5, 0xFF, 0b111111100000000000000, -801.576233, 1000.000000, 4318.003906, nullptr, nullptr},
+ {0x10, 12, stage::allStages[53], 0, 0x5, 0xFF, 0b111111100000000000000, -169.985306, 1120.000000, 3406.518799, nullptr, nullptr},
+ { 0x6d, 12, stage::allStages[53], 3, 0x8, 0xFF, 0b111111100000000000000, 511.206268, -200.000000, 7069.889160, nullptr, nullptr },
+ //Malo Castle Town
+ /*auto gotten*///{0x0d, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x18, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x1b, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr},
+ /*auto gotten*///{0x0e, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr},
+ { 0x61, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr },
+ { 0x63, 12, stage::allStages[73], 0, 0x8, 0xFF, 0b111111100000000000000, 1557.0000000, -200.0000000, 3491.0000000, nullptr, nullptr },
+ //City In The Sky
+ /*auto gotten*///{0x10, 12, stage::allStages[12], 16, 0x14, 0xFF, 0b111111100000000000000, -187.485748, 140.000000, -327.944885, nullptr, nullptr},
+ /*auto gotten*///{0x0d, 12, stage::allStages[12], 16, 0x14, 0xFF, 0b111111100000000000000, -187.485748, 140.000000, -327.944885, nullptr, nullptr},
+ { 0x66, 12, stage::allStages[12], 16, 0x14, 0xFF, 0b111111100000000000000, -187.485748, 140.000000, -327.944885, nullptr, nullptr },
+ { 0x61, 12, stage::allStages[12], 16, 0x14, 0xFF, 0b111111100000000000000, -187.485748, 140.000000, -327.944885, nullptr, nullptr },
+ { 0x63, 12, stage::allStages[12], 16, 0x14, 0xFF, 0b111111100000000000000, -187.485748, 140.000000, -327.944885, nullptr, nullptr },
+ //Fairy Tear Cave Of Ordeals (includes spring warps)
+ { 0x73, 12, stage::allStages[31], 49, 0x15, 0xFF, 0b100000000101110000010, -7.837189, -61250.000000, -3557.497070, nullptr, nullptr },//,
+ //Scoopables
+ //Nasty Soup
+ //{0x6a, 12, stage::allStages[45], 4, 0x5, 0xFF, 0b010000000000000000000, -13961.199219, 0.000000, -14341.190430, nullptr, nullptr},
+ //Trill
+ //{0x69, 12, stage::allStages[45], 6, 0x5, 0xFF, 0b000000000000000000000, -37251.628906, 350.000000, -19399.669922, nullptr, nullptr},
+ //{0x68, 12, stage::allStages[45], 6, 0x1, 0xFF, 0b000000000000000000000, -37285.023438, 350.000000, -19244.654297, nullptr, nullptr},
+ //Oil pots
+ //{0x68, 12, stage::allStages[24], 0, 0x9, 0xFF, 0b000000000000000000000, 852.599731, 1.000000, 5601.884766, nullptr, nullptr},
+ //{0x68, 12, stage::allStages[20], 9, 0xFF, 0xFF, 0b000000000000000000000, 4335.721191, 152.000000, -11863.983398, nullptr, nullptr},
+ //{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 },
+ //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[76], 1, 0x13, 0x13, 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
+ /*498*/ { 0xE2, 13, stage::allStages[44], 1, 0xFF, 0xFF, 0b000000000000000000000, -1385.184692, 280.000000, -9465.467773, nullptr, nullptr },
+ //Back Slice
+ /*499*/ { 0xE3, 13, stage::allStages[57], 8, 0xFF, 0xFF, 0b000000000000000000000, -68497.195312, -1050.000000, 5886.681152, nullptr, nullptr },
+ //Helm Splitter
+ /*500*/ { 0xE4, 13, stage::allStages[57], 16, 0xFF, 0xFF, 0b000000000000000000000, -55693.375000, -6100.000000, 25161.146484, nullptr, nullptr },
+ //Mortal Draw
+ /*501*/ { 0xE5, 13, stage::allStages[59], 0, 0xFF, 0xFF, 0b000000000000000000000, -2930.295898, 24.520000, 11344.983398, nullptr, nullptr },
+ //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 }
+ };
+
+ u16 checkPriorityOrder[24] = {
+ 293, //fishing rod
+ 0, //wooden sword
+ 295, //slingshot
+ 296, //lantern
+ 292, //ordon sword
+ 298, //boomerang
+ 21, //iron boots
+ 291, //ordon shield
+ 297, //hylian shield
+ 33, //bow
+ 320, //bomb bag
+ 314, //zora armor
+ 58, //clawshot
+ 493, //Shadow Crystal
+ 494, //Master Sword
+ 322, //Auru memo
+ 155, //spinner
+ 323, //Ashei sketch
+ 317, //coral earring
+ 290, //ball and chain
+ 202, //doninion rod
+ 495, //Charged Dominion Rod
+ 224, //double clawshot
+ 496 //Light Sword
+ };
+} \ No newline at end of file
diff --git a/source/source/keyPlacement.cpp b/source/source/keyPlacement.cpp
new file mode 100644
index 0000000..114be0f
--- /dev/null
+++ b/source/source/keyPlacement.cpp
@@ -0,0 +1,569 @@
+#include "keyPlacement.h"
+#include "defines.h"
+
+
+namespace mod::keyPlacement
+{
+ u16 FT_keys[4]
+ {
+ 9,//Windless Bridge Chest
+ 11,//totem key
+ 343,//big baba
+ 18//North Deku like chest
+ };
+ u16 FT_1[5]
+ {
+ 6,//entry
+ 8,//map
+ 9,//Windless Bridge Chest
+ 344,//ooccoo
+ 17//Water Cave Chest
+ };
+ u16 FT_2[5]
+ {
+ 6,//entry
+ 8,//map
+ 9,//Windless Bridge Chest
+ 344,//ooccoo
+ 17//Water Cave Chest
+ };
+ u16 FT_3[9]
+ {
+ 6,//entry
+ 8,//map
+ 9,//Windless Bridge Chest
+ 344,//ooccoo
+ 17,//Water Cave Chest
+ 13,//PoH deku ike
+ 11,//totem key
+ 12,//Small Chest West Tile
+ 343//big baba
+ };
+ u16 FT_4[9]
+ {
+ 6,//entry
+ 8,//map
+ 9,//Windless Bridge Chest
+ 344,//ooccoo
+ 17,//Water Cave Chest
+ 13,//PoH deku ike
+ 11,//totem key
+ 12,//Small Chest West Tile
+ 343//big baba
+ };
+
+ u16 GM_keys[3]
+ {
+ 23,//Hub Bottom Chest
+ 27,//Chest under water
+ 30//Outside Bemos Chest
+ };
+ u16 GM_1[2]
+ {
+ 22,//Entry Chest
+ 23//Hub Bottom Chest
+ };
+ u16 GM_2[10]
+ {
+ 22,//Entry Chest
+ 23,//Hub Bottom Chest
+ 24,//map
+ 25,//Gor Amato Small Chest
+ 354,//key shard 1
+ 345,//ooccoo
+ 26,//POH Chest
+ 28,//Small chest in water room
+ 27,//Chest under water
+ 29//POH Chest 2
+ };
+ u16 GM_3[12]
+ {
+ 22,//Entry Chest
+ 23,//Hub Bottom Chest
+ 24,//map
+ 25,//Gor Amato Small Chest
+ 354,//key shard 1
+ 345,//ooccoo
+ 26,//POH Chest
+ 28,//Small chest in water room
+ 27,//Chest under water
+ 29,//POH Chest 2
+ 30,//Outside Bemos Chest
+ 37//Outside Underwater
+ };
+
+ u16 LBT_keys[3]
+ {
+ 51,//Water Bridge Chest
+ 53,//2nd Floor East SE Chest
+ 55//Pre Deku Toad Chest
+ };
+ u16 LBT_1[7]
+ {
+ 46,//Entry Chest 1
+ 47,//Entry Chest 2
+ 48,//Stalactie Small Chest
+ 49,//Hub Small Chest
+ 346,//ooccoo
+ 50,//map
+ 51//Water Bridge Chest
+ };
+ u16 LBT_2[9]
+ {
+ 46,//Entry Chest 1
+ 47,//Entry Chest 2
+ 48,//Stalactie Small Chest
+ 49,//Hub Small Chest
+ 346,//ooccoo
+ 50,//map
+ 51,//Water Bridge Chest
+ 52,//2nd Floor East SW Chest
+ 53//2nd Floor East SE Chest
+ };
+ u16 LBT_3[11]
+ {
+ 46,//Entry Chest 1
+ 47,//Entry Chest 2
+ 48,//Stalactie Small Chest
+ 49,//Hub Small Chest
+ 346,//ooccoo
+ 50,//map
+ 51,//Water Bridge Chest
+ 52,//2nd Floor East SW Chest
+ 53,//2nd Floor East SE Chest
+ 54,//East Water Small Chest
+ 55//Pre Deku Toad Chest
+ };
+
+ u16 AG_keys[5]
+ {
+ 143,//Entry Chest
+ 144,//East Redead Small Chest
+ 148,//East Upper Redead Chest
+ 149,//Ghoul Rat Small Chest
+ 154//North Turn Room Chest
+ };
+ u16 AG_1[1]
+ {
+ 143//Entry Chest
+ };
+ u16 AG_2[7]
+ {
+ 143,//Entry Chest
+ 146,//map
+ 145,//Poe Hub POH
+ 405,//poe 1
+ 144,//East Redead Small Chest
+ 406,//poe 2
+ 150//West Small Chest
+ };
+ u16 AG_3[9]
+ {
+ 143,//Entry Chest
+ 146,//map
+ 145,//Poe Hub POH
+ 405,//poe 1
+ 144,//East Redead Small Chest
+ 406,//poe 2
+ 150,//West Small Chest
+ 147,//compass
+ 148//East Upper Redead Chest
+ };
+ u16 AG_4[11]
+ {
+ 143,//Entry Chest
+ 146,//map
+ 145,//Poe Hub POH
+ 405,//poe 1
+ 144,//East Redead Small Chest
+ 406,//poe 2
+ 150,//West Small Chest
+ 147,//compass
+ 148,//East Upper Redead Chest
+ 407,//poe 3
+ 149//Ghoul Rat Small Chest
+ };
+ u16 AG_5[16]
+ {
+ 143,//Entry Chest
+ 146,//map
+ 145,//Poe Hub POH
+ 405,//poe 1
+ 144,//East Redead Small Chest
+ 406,//poe 2
+ 150,//West Small Chest
+ 147,//compass
+ 148,//East Upper Redead Chest
+ 407,//poe 3
+ 149,//Ghoul Rat Small Chest
+ 151,//West Chandelier Chest
+ 152,//Stalfos Chest 1
+ 153,//Stalfos Chest 2
+ 408,//poe 4
+ 154//North Turn Room Chest
+ };
+
+ u16 SPR_keys[6]
+ {
+ 174,//CY Partially Buried Chest
+ 173,//pumpkin
+ 171,//Buried Chest
+ 178,//cheese
+ 180,//Wooden Beam C. Chest
+ 184//Chilfos Small Chest
+ };
+ u16 SPR_1[5]
+ {
+ 456,//poe 1
+ 339,//map
+ 348,//ooccoo
+ 172,//Courtyard Open Chest
+ 174//CY Partially Buried Chest
+ };
+ u16 SPR_2[6]
+ {
+ 456,//poe 1
+ 339,//map
+ 348,//ooccoo
+ 172,//Courtyard Open Chest
+ 174,//CY Partially Buried Chest
+ 173//pumpkin
+ };
+ u16 SPR_3[10]
+ {
+ 456,//poe 1
+ 339,//map
+ 348,//ooccoo
+ 172,//Courtyard Open Chest
+ 174,//CY Partially Buried Chest
+ 173,//pumpkin
+ 185,//Storage Chest Right
+ 175,//Small Beams Chest
+ 176,//compass
+ 171//Buried Chest
+ };
+ u16 SPR_4[13]
+ {
+ 456,//poe 1
+ 339,//map
+ 348,//ooccoo
+ 172,//Courtyard Open Chest
+ 174,//CY Partially Buried Chest
+ 173,//pumpkin
+ 185,//Storage Chest Right
+ 175,//Small Beams Chest
+ 176,//compass
+ 171,//Buried Chest
+ 177,//Courtyard South Chest
+ 290,//BaC
+ 178//cheese
+ };
+ u16 SPR_5[19]
+ {
+ 456,//poe 1
+ 339,//map
+ 348,//ooccoo
+ 172,//Courtyard Open Chest
+ 174,//CY Partially Buried Chest
+ 173,//pumpkin
+ 185,//Storage Chest Right
+ 175,//Small Beams Chest
+ 176,//compass
+ 171,//Buried Chest
+ 177,//Courtyard South Chest
+ 290,//BaC
+ 178,//cheese
+ 179,//Breakable Floor POH
+ 180,//Wooden Beam C. Chest
+ 457,//poe 2
+ 182,//Entry Chest Left
+ 183,//Entry Chest Right
+ 186//Storage Chest Left
+ };
+ u16 SPR_6[22]
+ {
+ 456,//poe 1
+ 339,//map
+ 348,//ooccoo
+ 172,//Courtyard Open Chest
+ 174,//CY Partially Buried Chest
+ 173,//pumpkin
+ 185,//Storage Chest Right
+ 175,//Small Beams Chest
+ 176,//compass
+ 171,//Buried Chest
+ 177,//Courtyard South Chest
+ 290,//BaC
+ 178,//cheese
+ 179,//Breakable Floor POH
+ 180,//Wooden Beam C. Chest
+ 457,//poe 2
+ 182,//Entry Chest Left
+ 183,//Entry Chest Right
+ 186,//Storage Chest Left
+ 181,//Entry POH Chest
+ 458,//poe 3
+ 184//Chilfos Small Chest
+ };
+
+ u16 ToT_keys[3]
+ {
+ 193,//Entry Chest
+ 197,//Armos Room Left Chest
+ 200//Third Stair Window Chest
+ };
+ u16 ToT_1[2]
+ {
+ 193,//Entry Chest
+ 349//ooccoo
+ };
+ u16 ToT_2[8]
+ {
+ 193,//Entry Chest
+ 349,//ooccoo
+ 194,//First Stair Small Chest pots
+ 195,//First Stair Small Chest
+ 196,//map
+ 459,//poe 1
+ 207,//Armos Room Small Chest
+ 197//Armos Room Left Chest
+ };
+ u16 ToT_3[16]
+ {
+ 193,//Entry Chest
+ 349,//ooccoo
+ 194,//First Stair Small Chest pots
+ 195,//First Stair Small Chest
+ 196,//map
+ 459,//poe 1
+ 207,//Armos Room Small Chest
+ 197,//Armos Room Left Chest
+ 198,//compass
+ 199,//Scale Room Spider Chest
+ 460,//poe 2
+ 203,//Small Chest Scale Room
+ 204,//Helmasaur Small Chest
+ 205,//boss key
+ 200,//Third Stair Window Chest
+ 201//Gilloutine Chest
+ };
+
+ u16 CitS_keys[1]
+ {
+ 219//West Wing Chest 1
+ };
+ u16 CitS_1[7]
+ {
+ 217,//Underwater Chest 1
+ 218,//Underwater Chest 2
+ 219,//West Wing Chest 1
+ 350,//ooccoo
+ 488,//Lantern_Oil
+ 489,//Red_Potion
+ 490//Blue_Potion
+ };
+
+ u16 PoT_keys[7]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 251,//East 1st North Chest
+ 255,//East 2nd SE Chest
+ 258,//Central Room 1st Chest
+ 260,//Central Outdoor Chest
+ 261//Central Tower Chest
+ };
+ u16 PoT_1[1]
+ {
+ 245//West 1st Central Chest
+ };
+ u16 PoT_2[4]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 247,//compass
+ 248//West 2nd SE Chest
+ };
+ u16 PoT_3[6]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 247,//compass
+ 248,//West 2nd SE Chest
+ 250,//East 1st Small Chest
+ 251//East 1st North Chest
+ };
+ u16 PoT_4[10]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 247,//compass
+ 248,//West 2nd SE Chest
+ 250,//East 1st Small Chest
+ 251,//East 1st North Chest
+ 252,//East 2nd NE Chest
+ 253,//East 2nd NW Chest
+ 254,//map
+ 255//East 2nd SE Chest
+ };
+ u16 PoT_5[14]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 247,//compass
+ 248,//West 2nd SE Chest
+ 250,//East 1st Small Chest
+ 251,//East 1st North Chest
+ 252,//East 2nd NE Chest
+ 253,//East 2nd NW Chest
+ 254,//map
+ 255,//East 2nd SE Chest
+ 249,//West 1st POH Chest
+ 256,//East 1st POH Chest
+ 257,//East 1st West Chest
+ 258//Central Room 1st Chest
+ };
+ u16 PoT_6[16]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 247,//compass
+ 248,//West 2nd SE Chest
+ 250,//East 1st Small Chest
+ 251,//East 1st North Chest
+ 252,//East 2nd NE Chest
+ 253,//East 2nd NW Chest
+ 254,//map
+ 255,//East 2nd SE Chest
+ 249,//West 1st POH Chest
+ 256,//East 1st POH Chest
+ 257,//East 1st West Chest
+ 258,//Central Room 1st Chest
+ 259,//big key
+ 260//Central Outdoor Chest
+ };
+ u16 PoT_7[17]
+ {
+ 245,//West 1st Central Chest
+ 246,//West 2nd Central Chest
+ 247,//compass
+ 248,//West 2nd SE Chest
+ 250,//East 1st Small Chest
+ 251,//East 1st North Chest
+ 252,//East 2nd NE Chest
+ 253,//East 2nd NW Chest
+ 254,//map
+ 255,//East 2nd SE Chest
+ 249,//West 1st POH Chest
+ 256,//East 1st POH Chest
+ 257,//East 1st West Chest
+ 258,//Central Room 1st Chest
+ 259,//big key
+ 260,//Central Outdoor Chest
+ 261//Central Tower Chest
+ };
+
+ u16 HC_keys[3]
+ {
+ 342,//king bulblin key
+ 265,//Grave Owl Chest
+ 274//SE Balcony Tower Chest
+ };
+ u16 HC_1[9]
+ {
+ 262,//Grave Switch Right Chest
+ 263,//Grave Switch Left Chest 1
+ 264,//Grave Switch Left Chest 2
+ 265,//Grave Owl Chest
+ 266,//map
+ 267,//East Castle Balcony
+ 268,//West CY North Chest
+ 269,//West CY Central Chest
+ 342//king bulblin key
+ };
+ u16 HC_2[15]
+ {
+ 262,//Grave Switch Right Chest
+ 263,//Grave Switch Left Chest 1
+ 264,//Grave Switch Left Chest 2
+ 265,//Grave Owl Chest
+ 266,//map
+ 267,//East Castle Balcony
+ 268,//West CY North Chest
+ 269,//West CY Central Chest
+ 342,//king bulblin key
+ 270,//compass
+ 271,//Lantern Staircase
+ 272,//HUB SW Chest
+ 273,//HUB NW Chest
+ 274,//SE Balcony Tower Chest
+ 275//big key
+ };
+ u16 HC_3[15]
+ {
+ 262,//Grave Switch Right Chest
+ 263,//Grave Switch Left Chest 1
+ 264,//Grave Switch Left Chest 2
+ 265,//Grave Owl Chest
+ 266,//map
+ 267,//East Castle Balcony
+ 268,//West CY North Chest
+ 269,//West CY Central Chest
+ 342,//king bulblin key
+ 270,//compass
+ 271,//Lantern Staircase
+ 272,//HUB SW Chest
+ 273,//HUB NW Chest
+ 274,//SE Balcony Tower Chest
+ 275//big key
+ };
+
+ u16 F_keys[2]
+ {
+ 2,//North Cave Key
+ 351//coro key
+ };
+ u16 F_1[4]
+ {
+ 296,//lantern
+ 2,//North Cave Key
+ 3,//PoH key cave
+ 1//transition cave
+ };
+ u16 F_2[2]
+ {
+ 329,//coro bottle
+ 351//coro key
+ };
+
+ u16 GD_keys[1]
+ {
+ 353//camp key
+ };
+
+ u16 GD_1[21]
+ {
+ 125,//desert chest
+ 126,//desert chest
+ 127,//desert chest
+ 131,//desert chest
+ 133,//desert chest
+ 134,//desert chest
+ 135,//desert chest
+ 136,//desert chest
+ 137,//desert chest
+ 138,//desert chest
+ 139,//desert chest
+ 140,//camp small chest 1
+ 141,//camp small chest 2
+ 338,//camp PoH
+ 353,//camp key
+ 377,//Male Dayfly
+ 378,//Female Dayfly
+ 417,//poe 13
+ 418,//poe 14
+ 419,//poe 15
+ 422//poe 18
+ };
+
+} \ No newline at end of file
diff --git a/source/source/memory.cpp b/source/source/memory.cpp
new file mode 100644
index 0000000..9812336
--- /dev/null
+++ b/source/source/memory.cpp
@@ -0,0 +1,20 @@
+#include "memory.h"
+#include "defines.h"
+
+#include <gc/OSCache.h>
+
+#include <cstring>
+
+namespace mod::memory
+{
+ void* clearMemory(void* ptr, size_t size)
+ {
+ return memset(ptr, 0, size);
+ }
+
+ void clear_DC_IC_Cache(void* ptr, u32 size)
+ {
+ gc::os_cache::DCFlushRange(ptr, size);
+ gc::os_cache::ICInvalidateRange(ptr, size);
+ }
+} \ No newline at end of file
diff --git a/source/source/mod.cpp b/source/source/mod.cpp
new file mode 100644
index 0000000..4a80465
--- /dev/null
+++ b/source/source/mod.cpp
@@ -0,0 +1,1814 @@
+#include "defines.h"
+#include "mod.h"
+#include "global.h"
+#include "systemConsole.h"
+#include "patch.h"
+#include "controller.h"
+#include "customChecks.h"
+#include "tools.h"
+#include "array.h"
+#include "eventListener.h"
+#include "stage.h"
+#include "game_patches.h"
+#include "chestRando.h"
+#include "itemChecks.h"
+#include "HUDConsole.h"
+#include "items.h"
+#include "singleton.h"
+
+#include <tp/f_op_scene_req.h>
+#include <tp/m_Do_controller_pad.h>
+#include <tp/d_map_path_dmap.h>
+#include <tp/evt_control.h>
+#include <tp/f_op_scene_req.h>
+#include <tp/d_com_inf_game.h>
+#include <tp/f_ap_game.h>
+#include <tp/f_op_actor_mng.h>
+#include <tp/d_a_alink.h>
+#include <tp/d_save.h>
+#include <tp/d_stage.h>
+#include <tp/dzx.h>
+#include <tp/JFWSystem.h>
+#include <tp/d_kankyo.h>
+#include <tp/d_msg_flow.h>
+#include <tp/DynamicLink.h>
+#include <tp/d_item.h>
+#include <cstdio>
+#include <cstring>
+
+
+
+namespace mod
+{
+ Mod* global::modPtr = nullptr;
+ ChestRandomizer* global::chestRandoPtr = nullptr;
+ event::EventListener* global::eventListenerPtr = nullptr;
+ mod::HUDConsole* global::hudConsolePtr = nullptr;
+ int num_frames = 120;
+ int frame_counter = 0;
+
+ void main()
+ {
+ Mod* mod = new Mod();
+ mod->init();
+ }
+
+ Mod::Mod()
+ {
+ eventListener = new event::EventListener();
+ chestRandomizer = new ChestRandomizer();
+ hudConsole = new HUDConsole("Settings", 0x80);
+ global::modPtr = this;
+ global::chestRandoPtr = this->chestRandomizer;
+ global::eventListenerPtr = this->eventListener;
+ global::hudConsolePtr = this->hudConsole;
+ }
+
+ void Mod::init()
+ {
+ // Perform any necessary assembly overwrites
+ game_patch::assemblyOverwrites();
+ game_patch::increaseWalletSize();
+ game_patch::increaseClimbSpeed();
+ /*
+ * Causes issues right now (argarok cannot be beaten)
+ * game_patch::removeIBLimit();
+ */
+
+ // Init rando
+ tools::randomSeed = 0x9e3779b97f4a7c15;
+ randoEnabled = 1;
+ truePause = 1;
+ inputBuffering = 0;
+
+ // Print controls
+ strcpy(sysConsolePtr->consoleLine[20].line, "D-Pad Nav: Up/Down Left/Right");
+ strcpy(sysConsolePtr->consoleLine[21].line, "+/- Value: A/B/X/Y Console : R + Z");
+ strcpy(sysConsolePtr->consoleLine[22].line, " Generate: R + Start (auto on new file)");
+ strcpy(sysConsolePtr->consoleLine[23].line, "Bring up the console to use commands");
+ strcpy(sysConsolePtr->consoleLine[24].line, "rando.tpspeed.run | Twitter: @ztprandomizer");
+
+ u8 page = 0;
+
+ // General settings
+ hudConsole->addOption(page, "Red:", &reinterpret_cast<u8*>(&sysConsolePtr->consoleColor)[0], 0xFF);
+ hudConsole->addOption(page, "Green:", &reinterpret_cast<u8*>(&sysConsolePtr->consoleColor)[1], 0xFF);
+ hudConsole->addOption(page, "Blue:", &reinterpret_cast<u8*>(&sysConsolePtr->consoleColor)[2], 0xFF);
+ hudConsole->addOption(page, "Alpha:", &reinterpret_cast<u8*>(&sysConsolePtr->consoleColor)[3], 0xFF);
+ hudConsole->addOption(page, "True Pause:", &truePause, 0x1);
+ hudConsole->addOption(page, "Input Buffer:", &inputBuffering, 0x1);
+
+
+ // Seed settings
+ page = hudConsole->addPage("Seed");
+
+ hudConsole->addOption(page, "Rando enabled?", &randoEnabled, 0x1);
+ hudConsole->addOption(page, "Custom Seed?", &customSeed, 0x1);
+ hudConsole->addOption(page, "Seed 1:", &reinterpret_cast<u8*>(&tools::randomSeed)[0], 0xFF);
+ hudConsole->addOption(page, "Seed 2:", &reinterpret_cast<u8*>(&tools::randomSeed)[1], 0xFF);
+ hudConsole->addOption(page, "Seed 3:", &reinterpret_cast<u8*>(&tools::randomSeed)[2], 0xFF);
+ hudConsole->addOption(page, "Seed 4:", &reinterpret_cast<u8*>(&tools::randomSeed)[3], 0xFF);
+
+ hudConsole->addOption(page, "Seed 5:", &reinterpret_cast<u8*>(&tools::randomSeed)[4], 0xFF);
+ hudConsole->addOption(page, "Seed 6:", &reinterpret_cast<u8*>(&tools::randomSeed)[5], 0xFF);
+ hudConsole->addOption(page, "Seed 7:", &reinterpret_cast<u8*>(&tools::randomSeed)[6], 0xFF);
+ hudConsole->addOption(page, "Seed 8:", &reinterpret_cast<u8*>(&tools::randomSeed)[7], 0xFF);
+
+ hudConsole->addWatch(page, "Resulting Seed", &tools::randomSeed, 'x', WatchInterpretation::_u64);
+
+ // Debug
+ page = hudConsole->addPage("Debug Info");
+
+ hudConsole->addOption(page, "Bugsanity?", &chestRandomizer->isBugsanityEnabled, 0x1);
+ hudConsole->addOption(page, "Poesanity?", &chestRandomizer->isPoesanityEnabled, 0x1);
+ hudConsole->addOption(page, "Shopsanity?", &chestRandomizer->isShopsanityEnabled, 0x1);
+ hudConsole->addOption(page, "Dungeon Items?", &chestRandomizer->areDungeonItemsRandomized, 0x1);
+ hudConsole->addOption(page, "Key Shuffle?", &chestRandomizer->isKeysanityEnabled, 0x1);
+ hudConsole->addOption(page, "Skybooksanity?", &Singleton::getInstance()->shuffledSkybook, 0x1);
+
+
+
+ hudConsole->addWatch(page, "Function:", &lastItemFunc, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, " Source:", &chestRandomizer->lastSourceInfo, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, " Dest:", &chestRandomizer->lastDestInfo, 's', WatchInterpretation::_str);
+
+ hudConsole->addWatch(page, "Total Checks:", &chestRandomizer->totalChecks, 'u', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "Layer Checks:", &chestRandomizer->layerCheckCount, 'u', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "Empty:", &chestRandomizer->empty, 'u', WatchInterpretation::_u16);
+
+ hudConsole->addWatch(page, "Active Seed:", &chestRandomizer->currentSeed, 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, " Checksum:", &chestRandomizer->checkSum, 'x', WatchInterpretation::_u16);
+
+
+ // Item search
+ page = hudConsole->addPage("Item Search");
+
+ hudConsole->addOption(page, "Search ID:", &itemSearchID, 0xFF);
+ hudConsole->addOption(page, "Reverse ID:", &itemReverseSearchID, 0xFF);
+
+ hudConsole->addWatch(page, "Search Result:", &itemSearchResults, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "Reverse Result:", &itemReverseSearchResults, 's', WatchInterpretation::_str);
+
+ hudConsole->addWatch(page, "MetadataID:", &lastItemDataID, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "MetadataX:", &lastItemDataX, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "MetadataY:", &lastItemDataY, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "MetadataZ:", &lastItemDataZ, 's', WatchInterpretation::_str);
+
+ // Check search
+ page = hudConsole->addPage("Check Search");
+
+ hudConsole->addOption(page, "Search ID1:", &checkSearchID1, 0xFF);
+ hudConsole->addOption(page, "Search ID2:", &checkSearchID2, 0xFF);
+ hudConsole->addOption(page, "Reverse ID1:", &checkReverseSearchID1, 0xFF);
+ hudConsole->addOption(page, "Reverse ID2:", &checkReverseSearchID2, 0xFF);
+
+ hudConsole->addWatch(page, "Search ID:", &checkSearchID, 'd', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "Reverse ID:", &checkReverseSearchID, 'd', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "Search Result:", &checkSearchResults, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "Reverse Result:", &checkReverseSearchResults, 's', WatchInterpretation::_str);
+
+ // Game info 1
+ page = hudConsole->addPage("Skips 1");
+
+ hudConsole->addOption(page, "MDH Skip?", &Singleton::getInstance()->isMDHSkipEnabled, 0x1);
+ hudConsole->addOption(page, "Faron Escape?", &Singleton::getInstance()->isForestEscapeEnabled, 0x1);
+ hudConsole->addOption(page, "Open HF gates?", &Singleton::getInstance()->isGateUnlockEnabled, 0x1);
+ hudConsole->addOption(page, "Skip Twilight?", &Singleton::getInstance()->isTwilightSkipped, 0x1);
+ hudConsole->addOption(page, "Skip Goats?", &Singleton::getInstance()->isGoatSkipEnabled, 0x1);
+ hudConsole->addOption(page, "Skip MS Puzzle?", &Singleton::getInstance()->isMSPuzzleSkipEnabled, 0x1);
+ hudConsole->addOption(page, "Skip Escort?", &Singleton::getInstance()->isCartEscortSkipEnabled, 0x1);
+ hudConsole->addOption(page, "Skip Sewers?", &Singleton::getInstance()->isSewerSkipEnabled, 0x1);
+
+
+
+ /*hudConsole->addOption(page, "Item half milk", &chestRandomizer->itemThatReplacesHalfMilk, 0xFF); //for testing only
+ hudConsole->addOption(page, "Item slingshot", &chestRandomizer->itemThatReplacesSlingShot, 0xFF); //for testing only
+ hudConsole->addOption(page, "Normal Time:", &enableNormalTime, 0x1); //for testing only
+ hudConsole->addOption(page, "Set Day:", &setDay, 0x1); //for testing only*/
+
+ hudConsole->addWatch(page, "CurrentStage:", &gameInfo.currentStage, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "CurrentRoom:", &tp::d_kankyo::env_light.currentRoom, 'd', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "CurrentState:", &tp::d_com_inf_game::current_state, 'x', WatchInterpretation::_u8);
+
+ hudConsole->addWatch(page, "CurrentPosX:", &currentPosX, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "CurrentPosY:", &currentPosY, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "CurrentPosZ:", &currentPosZ, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "CurrentAngle:", &linkAngle, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "Sky Angle:", &skyAngle, 's', WatchInterpretation::_str);
+
+ //Game info 2
+ page = hudConsole->addPage("Skips 2");
+ hudConsole->addOption(page, "Early CiTS?", &Singleton::getInstance()->isEarlyCiTSEnabled, 0x1);
+ hudConsole->addOption(page, "Early Desert?", &Singleton::getInstance()->isEarlyDesertEnabled, 0x1);
+ hudConsole->addOption(page, "Boss Keysey?", &Singleton::getInstance()->isBossKeyseyEnabled, 0x1);
+ hudConsole->addOption(page, "No Shop Bottl?", &allowBottleItemsShopAnytime, 0x1);
+ hudConsole->addOption(page, "Fast transform?", &enableQuickTransform, 0x1);
+ hudConsole->addOption(page, "Skip Intro?", &Singleton::getInstance()->isIntroSkipped, 0x1);
+ //color
+ /*page = hudConsole->addPage("Tunic Color1");
+
+ hudConsole->addOption(page, "Top toggle:", &topToggle, 0x1);
+ hudConsole->addOption(page, "Red top:", &redTop, 0xFF);
+ hudConsole->addOption(page, "Green top:", &greenTop, 0xFF);
+ hudConsole->addOption(page, "Blue top:", &blueTop, 0xFF);
+ hudConsole->addOption(page, "Bottom toggle:", &bottomToggle, 0x1);
+ hudConsole->addOption(page, "Red bottom:", &redBottom, 0xFF);
+ hudConsole->addOption(page, "Green bottom:", &greenBottom, 0xFF);
+ hudConsole->addOption(page, "Blue bottom:", &blueBottom, 0xFF); */
+
+ //buttons
+ /*page = hudConsole->addPage("Button texts");
+
+ hudConsole->addOption(page, "A button:", &gameInfo.aButtonText, 0xFF);
+ hudConsole->addOption(page, "Y button:", &gameInfo.yButtonText, 0xFF);
+ hudConsole->addOption(page, "X button:", &gameInfo.xButtonText, 0xFF);
+ hudConsole->addOption(page, "B button:", &gameInfo.bButtonText, 0xFF);
+ hudConsole->addOption(page, "R button:", &gameInfo.rButtonText, 0xFF);
+ hudConsole->addOption(page, "stick button:", &gameInfo.stickButtonText, 0xFF);
+ hudConsole->addOption(page, "start button:", &gameInfo.startButtonText, 0xFF);
+ hudConsole->addOption(page, "C button:", &gameInfo.cButtonText, 0xFF);
+ hudConsole->addOption(page, "X item:", &gameInfo.xItem, 0xFF);
+ hudConsole->addOption(page, "Y item:", &gameInfo.yItem, 0xFF);
+ hudConsole->addWatch(page, "A button:", &gameInfo.aButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "Y button:", &gameInfo.yButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "X button:", &gameInfo.xButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "B button:", &gameInfo.bButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "R button:", &gameInfo.rButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "stick:", &gameInfo.stickButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "start button:", &gameInfo.startButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "C button:", &gameInfo.cButtonText, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "scoop:", &scoopResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "check:", &checkResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "items:", &itemsResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "map:", &mapResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "equip:", &equipResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "back:", &backResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "zoom in:", &zoomInResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "zoom out:", &zoomOutResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "move:", &moveResult, 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u16);*/
+
+
+
+ //event info
+ page = hudConsole->addPage("Event Info");
+ 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);
+ hudConsole->addWatch(page, "NextStage:", &gameInfo.nextStageVars.nextStage, 's', WatchInterpretation::_str);
+ hudConsole->addWatch(page, "NextRoom:", &gameInfo.nextStageVars.nextRoom, 'd', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "NextSpawnPoint:", &gameInfo.nextStageVars.nextSpawnPoint, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "NextSate:", &gameInfo.nextStageVars.nextState, 'x', WatchInterpretation::_u8);
+
+ //local area
+ /*page = hudConsole->addPage("Local Area 1");
+ hudConsole->addWatch(page, "AreaNodes0:", &gameInfo.localAreaNodes.unk_0[0], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes1:", &gameInfo.localAreaNodes.unk_0[1], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes2:", &gameInfo.localAreaNodes.unk_0[2], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes3:", &gameInfo.localAreaNodes.unk_0[3], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes4:", &gameInfo.localAreaNodes.unk_0[4], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes5:", &gameInfo.localAreaNodes.unk_0[5], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes6:", &gameInfo.localAreaNodes.unk_0[6], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes7:", &gameInfo.localAreaNodes.unk_0[7], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes8:", &gameInfo.localAreaNodes.unk_0[8], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes9:", &gameInfo.localAreaNodes.unk_0[9], 'x', WatchInterpretation::_u8);
+ page = hudConsole->addPage("Local Area 2");
+ hudConsole->addWatch(page, "AreaNodes10:", &gameInfo.localAreaNodes.unk_0[10], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes11:", &gameInfo.localAreaNodes.unk_0[11], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes12:", &gameInfo.localAreaNodes.unk_0[12], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes13:", &gameInfo.localAreaNodes.unk_0[13], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes14:", &gameInfo.localAreaNodes.unk_0[14], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes15:", &gameInfo.localAreaNodes.unk_0[15], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes16:", &gameInfo.localAreaNodes.unk_0[16], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes17:", &gameInfo.localAreaNodes.unk_0[17], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes18:", &gameInfo.localAreaNodes.unk_0[18], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes19:", &gameInfo.localAreaNodes.unk_0[19], 'x', WatchInterpretation::_u8);
+ page = hudConsole->addPage("Local Area 3");
+ hudConsole->addWatch(page, "AreaNodes20:", &gameInfo.localAreaNodes.unk_0[20], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes21:", &gameInfo.localAreaNodes.unk_0[21], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes22:", &gameInfo.localAreaNodes.unk_0[22], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes23:", &gameInfo.localAreaNodes.unk_0[23], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes24:", &gameInfo.localAreaNodes.unk_0[24], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes25:", &gameInfo.localAreaNodes.unk_0[25], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes26:", &gameInfo.localAreaNodes.unk_0[26], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes27:", &gameInfo.localAreaNodes.unk_0[27], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "NbKeys:", &gameInfo.localAreaNodes.nbKeys, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "Dungeon flags:", &gameInfo.localAreaNodes.dungeon, 'x', WatchInterpretation::_u8);
+ page = hudConsole->addPage("Local Area 4");
+ hudConsole->addWatch(page, "AreaNodes30:", &gameInfo.localAreaNodes.unk_1E[0], 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "AreaNodes31:", &gameInfo.localAreaNodes.unk_1E[1], 'x', WatchInterpretation::_u8);*/
+
+ //item slots
+ /*page = hudConsole->addPage("Item slots 1");
+ hudConsole->addWatch(page, "Boomerang:", &gameInfo.scratchPad.itemWeel.Boomerang, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "Slot 1:", &gameInfo.scratchPad.itemSlots[0x1], 'x', WatchInterpretation::_u8);
+
+ hudConsole->addWatch(page, "flags1:", &gameInfo.scratchPad.itemFlags.itemFlags1, 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "flags2:", &gameInfo.scratchPad.itemFlags.itemFlags2, 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "flags3:", &gameInfo.scratchPad.itemFlags.itemFlags3, 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "falgs4:", &gameInfo.scratchPad.itemFlags.itemFlags4, 'x', WatchInterpretation::_u64);*/
+
+ /*page = hudConsole->addPage("Warps 1");
+ hudConsole->addOption(page, "Mirror Chamber:", &gameInfo.scratchPad.allAreaNodes.Gerudo_Desert.unk_0[0xE], 0xFF);
+ hudConsole->addOption(page, "Gerudo Mesa:", &gameInfo.scratchPad.allAreaNodes.Gerudo_Desert.unk_0[0x9], 0xFF);
+ hudConsole->addOption(page, "Snowpeak Top:", &gameInfo.scratchPad.allAreaNodes.Snowpeak.unk_0[0x9], 0xFF);
+ hudConsole->addOption(page, "Sacred Grove:", &gameInfo.scratchPad.allAreaNodes.Sacred_Grove.unk_0[0x17], 0xFF);
+ hudConsole->addOption(page, "Eldin Bridge:", &gameInfo.scratchPad.allAreaNodes.Hyrule_Field.unk_0[0x17], 0xFF);
+ hudConsole->addOption(page, "Castle Town:", &gameInfo.scratchPad.allAreaNodes.Hyrule_Field.unk_0[0xB], 0xFF);
+ hudConsole->addOption(page, "Kakariko Gorge:", &gameInfo.scratchPad.allAreaNodes.Hyrule_Field.unk_0[0x9], 0xFF);
+ hudConsole->addOption(page, "Zoras Domain:", &gameInfo.scratchPad.allAreaNodes.Lanyru.unk_0[0xB], 0xFF);
+ hudConsole->addOption(page, "Lake Hylia:", &gameInfo.scratchPad.allAreaNodes.Lanyru.unk_0[0xA], 0xFF);
+ hudConsole->addOption(page, "Zora River:", &gameInfo.scratchPad.allAreaNodes.Lanyru.unk_0[0x9], 0xFF);
+
+ hudConsole->addWatch(page, "Mirror Chamber:", &gameInfo.scratchPad.allAreaNodes.Gerudo_Desert.unk_0[0xE], 'x', WatchInterpretation::_u8);//1
+ hudConsole->addWatch(page, "Gerudo Mesa:", &gameInfo.scratchPad.allAreaNodes.Gerudo_Desert.unk_0[0x9], 'x', WatchInterpretation::_u8);//32
+ hudConsole->addWatch(page, "Snowpeak Top:", &gameInfo.scratchPad.allAreaNodes.Snowpeak.unk_0[0x9], 'x', WatchInterpretation::_u8);//32
+ hudConsole->addWatch(page, "Sacred Grove:", &gameInfo.scratchPad.allAreaNodes.Sacred_Grove.unk_0[0x17], 'x', WatchInterpretation::_u8);//16
+ hudConsole->addWatch(page, "Eldin Bridge:", &gameInfo.scratchPad.allAreaNodes.Hyrule_Field.unk_0[0x17], 'x', WatchInterpretation::_u8);//8
+ hudConsole->addWatch(page, "Castle Town:", &gameInfo.scratchPad.allAreaNodes.Hyrule_Field.unk_0[0xB], 'x', WatchInterpretation::_u8);//8
+ hudConsole->addWatch(page, "Kakariko Gorge:", &gameInfo.scratchPad.allAreaNodes.Hyrule_Field.unk_0[0x9], 'x', WatchInterpretation::_u8);//32
+ hudConsole->addWatch(page, "Zoras Domain:", &gameInfo.scratchPad.allAreaNodes.Lanyru.unk_0[0xB], 'x', WatchInterpretation::_u8);//4
+ hudConsole->addWatch(page, "Lake Hylia:", &gameInfo.scratchPad.allAreaNodes.Lanyru.unk_0[0xA], 'x', WatchInterpretation::_u8);//4
+ hudConsole->addWatch(page, "Zora River:", &gameInfo.scratchPad.allAreaNodes.Lanyru.unk_0[0x9], 'x', WatchInterpretation::_u8);//32
+ page = hudConsole->addPage("Warps 2");
+ hudConsole->addOption(page, "Death Mountain:", &gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x9], 0xFF);
+ hudConsole->addOption(page, "Kakariko:", &gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x8], 0xFF);
+ hudConsole->addOption(page, "South Faron:", &gameInfo.scratchPad.allAreaNodes.Faron.unk_0[0x13], 0xFF);
+ hudConsole->addOption(page, "North Faron:", &gameInfo.scratchPad.allAreaNodes.Faron.unk_0[0xB], 0xFF);
+ hudConsole->addOption(page, "Ordon Spring:", &gameInfo.scratchPad.allAreaNodes.Ordon.unk_0[0xD], 0xFF);
+
+ hudConsole->addWatch(page, "Death Mountain:", &gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x9], 'x', WatchInterpretation::_u8);//32
+ hudConsole->addWatch(page, "Kakariko:", &gameInfo.scratchPad.allAreaNodes.Eldin.unk_0[0x8], 'x', WatchInterpretation::_u8);//128
+ hudConsole->addWatch(page, "South Faron:", &gameInfo.scratchPad.allAreaNodes.Faron.unk_0[0x13], 'x', WatchInterpretation::_u8);//128
+ hudConsole->addWatch(page, "North Faron:", &gameInfo.scratchPad.allAreaNodes.Faron.unk_0[0xB], 'x', WatchInterpretation::_u8);//4
+ hudConsole->addWatch(page, "Ordon Spring:", &gameInfo.scratchPad.allAreaNodes.Ordon.unk_0[0xD], 'x', WatchInterpretation::_u8);//16*/
+
+
+ // save load
+ /*page = hudConsole->addPage("Save load");
+
+ hudConsole->addOption(page, "stage:", &stage, 78); //for testing only
+ hudConsole->addOption(page, "room:", &room, 60); //for testing only
+ hudConsole->addOption(page, "spawn:", &spawn, 0xFF); //for testing only
+ hudConsole->addOption(page, "state:", &state, 0xFF); //for testing only
+ hudConsole->addOption(page, "trigger:", &trigerLoadSave, 0x1); //for testing only*/
+
+ /*page = hudConsole->addPage("testing adr1");
+
+
+ hudConsole->addWatch(page, "D:", &gameInfo.scratchPad.equipedItems.unk, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "17:", &gameInfo.scratchPad.unk_17[0x0], 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "1A:", &gameInfo.scratchPad.unk_1A[0x0], 'x', WatchInterpretation::_u32);
+ hudConsole->addWatch(page, "1F:", &gameInfo.scratchPad.unk_1F[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "27:", &gameInfo.scratchPad.unk_1F[0x8], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "2F:", &gameInfo.scratchPad.unk_1F[0x10], 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "32:", &gameInfo.scratchPad.unk_32[0x0], 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "38:", &gameInfo.scratchPad.unk_38[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "62:", &gameInfo.scratchPad.movingActors.link.unk_62[0x0], 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "7A:", &gameInfo.scratchPad.movingActors.unk_7A[0x0], 'x', WatchInterpretation::_u32);//actual size:0x3
+
+ page = hudConsole->addPage("testing adr2");
+
+ hudConsole->addWatch(page, "7E:", &gameInfo.scratchPad.movingActors.unk_7E[0x0], 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "99:", &gameInfo.scratchPad.unk_99[0x0], 'x', WatchInterpretation::_u32);//actual size:0x3
+ hudConsole->addWatch(page, "F0:", &gameInfo.scratchPad.ammo.unk_F0, 'x', WatchInterpretation::_u32);
+ hudConsole->addWatch(page, "F5:", &gameInfo.scratchPad.ammo.unk_F5, 'x', WatchInterpretation::_u32);//actual size:0x3
+ hudConsole->addWatch(page, "FC:", &gameInfo.scratchPad.unk_FC[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "104:", &gameInfo.scratchPad.unk_FC[0x8], 'x', WatchInterpretation::_u64);//actual size:0x5
+ hudConsole->addWatch(page, "10B:", &gameInfo.scratchPad.unk_10B, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "10D:", &gameInfo.scratchPad.unk_10D[0x0], 'x', WatchInterpretation::_u64);//actual size:0x7
+ hudConsole->addWatch(page, "115:", &gameInfo.scratchPad.unk_115[0x0], 'x', WatchInterpretation::_u64);//actual size:0x7
+ hudConsole->addWatch(page, "120:", &gameInfo.scratchPad.unk_120[0x0], 'x', WatchInterpretation::_u64);//actual size:0x6
+
+ page = hudConsole->addPage("testing adr2");
+
+ hudConsole->addWatch(page, "128:", &gameInfo.scratchPad.unk_128[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "130:", &gameInfo.scratchPad.unk_128[0x8], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "138:", &gameInfo.scratchPad.unk_128[0x10], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "140:", &gameInfo.scratchPad.unk_128[0x18], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "148:", &gameInfo.scratchPad.unk_128[0x20], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "150:", &gameInfo.scratchPad.unk_128[0x28], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "158:", &gameInfo.scratchPad.unk_128[0x30], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "160:", &gameInfo.scratchPad.unk_128[0x38], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "168:", &gameInfo.scratchPad.unk_128[0x40], 'x', WatchInterpretation::_u32);
+ hudConsole->addWatch(page, "178:", &gameInfo.scratchPad.fishingJournal.unk_178[0x0], 'x', WatchInterpretation::_u64);
+
+ page = hudConsole->addPage("testing adr3");
+
+ hudConsole->addWatch(page, "180:", &gameInfo.scratchPad.fishingJournal.unk_178[0x8], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "188:", &gameInfo.scratchPad.fishingJournal.unk_178[0x10], 'x', WatchInterpretation::_u32);
+ hudConsole->addWatch(page, "192:", &gameInfo.scratchPad.unk_192[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "19A:", &gameInfo.scratchPad.unk_192[0x8], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "1A2:", &gameInfo.scratchPad.unk_192[0x10], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "1AA:", &gameInfo.scratchPad.unk_192[0x18], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "1B2:", &gameInfo.scratchPad.unk_192[0x20], 'x', WatchInterpretation::_u16);
+ hudConsole->addWatch(page, "1C4:", &gameInfo.scratchPad.unk_1C4, 'x', WatchInterpretation::_u8);
+ hudConsole->addWatch(page, "1D5:", &gameInfo.scratchPad.unk_1D5[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "1DD:", &gameInfo.scratchPad.unk_1D5[0x8], 'x', WatchInterpretation::_u32);
+ hudConsole->addWatch(page, "1E4:", &gameInfo.scratchPad.unk_1E4[0x0], 'x', WatchInterpretation::_u64);
+ hudConsole->addWatch(page, "1EC:", &gameInfo.scratchPad.unk_1E4[0x8], 'x', WatchInterpretation::_u32);*/
+
+
+ // Print
+ hudConsole->draw();
+ system_console::setState(true, 0);
+
+ // =================
+ // | Custom events |
+ // =================
+
+ // Generate random data when a new game starts
+ eventListener->addLoadEvent(stage::allStages[Stage_Faron_Woods], 0x1, 0x15, 0xFF, 0xFF, tools::triggerRandomGenerator, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ // Skip sewers when the load happens
+ eventListener->addLoadEvent(stage::allStages[Stage_Hyrule_Castle_Sewers], 0x0, 0x18, 0xFF, 0xFF, game_patch::skipSewers, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ // Fix BiTE
+ //eventListener->addLoadEvent(stage::allStages[Stage_Title_Screen], 0x0, 0x17, 0xFF, 0xFF, game_patch::giveEpona, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ // Kill spider at Link's house
+ eventListener->addLoadEvent(stage::allStages[Stage_Ordon_Village], 0x1, 0xFF, 0xFF, 0xFF, game_patch::killLinkHouseSpider, event::LoadEventAccuracy::Stage_Room);
+
+ //Set Bublin Camp State
+ eventListener->addLoadEvent(stage::allStages[Stage_Bublin_Camp], 0xFF, 0xFF, 0x1, 0xFF, game_patch::setBublinState, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ //unlock HF gates and check for MDH
+ eventListener->addLoadEvent(stage::allStages[Stage_Hyrule_Field], 0xFF, 0xFF, 0xFF, 0xFF, game_patch::setFieldBits, event::LoadEventAccuracy::Stage);
+
+ //skip goats 2
+ eventListener->addLoadEvent(stage::allStages[Stage_Ordon_Ranch], 0x0, 0x3, 0xFF, 0xFF, game_patch::skipGoats, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ //skip MS Puzzle
+ eventListener->addLoadEvent(stage::allStages[Stage_Sacred_Grove], 0xFF, 0xFF, 0xFF, 0xFF, game_patch::setGroveFlags, event::LoadEventAccuracy::Stage);
+
+ //skip Cart Escort
+ eventListener->addLoadEvent(stage::allStages[Stage_Hyrule_Field], 0xC, 0x2, 0xFF, 0xFF, game_patch::skipCartEscort, event::LoadEventAccuracy::Stage_Room_Spawn);
+
+ //Fix Lanayru Softlock
+ 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);
+
+ //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);
+
+ //Allow Escort Any Time
+ 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);
+
+
+ // =================
+ // | Function Hooks |
+ // =================
+
+ fapGm_Execute_trampoline = patch::hookFunction(tp::f_ap_game::fapGm_Execute,
+ []()
+ {
+ global::modPtr->procNewFrame();
+ }
+ );
+
+ // Hook actor init function to use as a timing for placing custom chests as this function only creates actors at
+ // specific times
+ 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)
+ {
+ // 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);
+ }
+ );
+
+ checkTreasureRupeeReturn_trampoline = patch::hookFunction(tp::d_a_alink::checkTreasureRupeeReturn,
+ [](void* unk1, s32 item)
+ {
+ return global::modPtr->procCheckTreasureRupeeReturn(unk1, item);
+ }
+ );
+
+ createItemForPresentDemo_trampoline = patch::hookFunction(tp::f_op_actor_mng::createItemForPresentDemo,
+ [](const float pos[3], s32 item, u8 unk3, s32 unk4, s32 unk5, const float unk6[3], const float unk7[3])
+ {
+ // Call replacement function
+ /*char txt[50];
+ snprintf(txt, 50, "0 = %f 1 = %f 2 = %f", pos[0], pos[1], pos[2]);
+ strcpy(sysConsolePtr->consoleLine[20].line, txt);*/
+
+ item = global::modPtr->procItemCreateFunc(pos, item, "createItemForPresentDemo");
+
+ return global::modPtr->createItemForPresentDemo_trampoline(pos, item, unk3, unk4, unk5, unk6, unk7);
+ }
+ );
+
+
+ createItemForTrBoxDemo_trampoline = patch::hookFunction(tp::f_op_actor_mng::createItemForTrBoxDemo,
+ [](const float pos[3], s32 item, s32 unk3, s32 unk4, const float unk5[3], const float unk6[3])
+ {
+ // Call replacement function
+ item = global::modPtr->procItemCreateFunc(pos, item, "createItemForTrBoxDemo");
+
+ return global::modPtr->createItemForTrBoxDemo_trampoline(pos, item, unk3, unk4, unk5, unk6);
+ }
+ );
+ //this function is called when the heart spawns, not when link gets it
+ //createItemForTrBoxDemo is called when heart container is gotten
+ createItemForBoss_trampoline = patch::hookFunction(tp::f_op_actor_mng::createItemForBoss,
+ [](const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7, s32 unk8)
+ {
+ // Call replacement function
+ item = global::modPtr->procItemCreateFunc(pos, item, "createItemForBoss");
+
+ return global::modPtr->createItemForBoss_trampoline(pos, item, unk3, unk4, unk5, unk6, unk7, unk8);
+ }
+ );
+
+ createItemForMidBoss_trampoline = patch::hookFunction(tp::f_op_actor_mng::createItemForMidBoss,
+ [](const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], s32 unk6, s32 unk7)
+ {
+ // Call replacement function
+ item = global::modPtr->procItemCreateFunc(pos, item, "createItemForMidBoss");
+
+ return global::modPtr->createItemForMidBoss_trampoline(pos, item, unk3, unk4, unk5, unk6, unk7);
+ }
+ );
+
+ createItemForDirectGet_trampoline = patch::hookFunction(tp::f_op_actor_mng::createItemForDirectGet,
+ [](const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7)
+ {
+ // Call replacement function
+ item = global::modPtr->procItemCreateFunc(pos, item, "createItemForDirectGet");
+
+ return global::modPtr->createItemForDirectGet_trampoline(pos, item, unk3, unk4, unk5, unk6, unk7);
+ }
+ );
+
+ createItemForSimpleDemo_trampoline = patch::hookFunction(tp::f_op_actor_mng::createItemForSimpleDemo,
+ [](const float pos[3], s32 item, s32 unk3, const float unk4[3], const float unk5[3], float unk6, float unk7)
+ {
+ // Call replacement function
+ item = global::modPtr->procItemCreateFunc(pos, item, "createItemForSimpleDemo");
+
+ return global::modPtr->createItemForSimpleDemo_trampoline(pos, item, unk3, unk4, unk5, unk6, unk7);
+ }
+ );
+
+
+ evt_control_Skipper_trampoline = patch::hookFunction(tp::evt_control::skipper,
+ [](void* evtPtr)
+ {
+ return global::modPtr->procEvtSkipper(evtPtr);
+ }
+ );
+
+ query022_trampoline = patch::hookFunction(tp::d_msg_flow::query022,
+ [](void* unk1, void* unk2, s32 unk3)
+ {
+ return global::modPtr->proc_query022(unk1, unk2, unk3);
+ }
+ );
+
+ do_link_trampoline = patch::hookFunction(tp::dynamic_link::do_link,
+ [](tp::dynamic_link::DynamicModuleControl* dmc)
+ {
+ return global::modPtr->procDoLink(dmc);
+ }
+ );
+
+ item_func_UTUWA_HEART_trampoline = patch::hookFunction(tp::d_item::item_func_UTUWA_HEART,
+ []()
+ {
+ return global::modPtr->procItem_func_UTUWA_HEART();
+ }
+ );
+
+ setItemBombNumCount_trampoline = patch::hookFunction(tp::d_com_inf_game::setItemBombNumCount,
+ [](u32 unk1, u8 bagNb, short amount)
+ {
+ u8 bombtype = 0;
+ if (bagNb == 0)
+ {
+ bombtype = gameInfo.scratchPad.itemWheel.Bomb_Bag_1;
+ }
+ else if (bagNb == 1)
+ {
+ bombtype = gameInfo.scratchPad.itemWheel.Bomb_Bag_2;
+ }
+ else if (bagNb == 2)
+ {
+ bombtype = gameInfo.scratchPad.itemWheel.Bomb_Bag_3;
+ }
+ char txt[50];
+ snprintf(txt, 50, "bag = %x amount = %d type = %x", bagNb, amount, bombtype);
+ strcpy(sysConsolePtr->consoleLine[20].line, txt);
+
+ /*u8 itemID = 0x0;
+ if (bombtype == items::Item::Bomb_Bag_Regular_Bombs)
+ {
+ if (amount == 5)
+ {
+ itemID = items::Item::Bombs_5;
+ }
+ else if (amount == 10)
+ {
+ itemID = items::Item::Bombs_10;
+ }
+ else if (amount == 20)
+ {
+ itemID = items::Item::Bombs_20;
+ }
+ else if (amount == 30)
+ {
+ itemID = items::Item::Bombs_30;
+ }
+ }
+ else if (bombtype == items::Item::Bomb_Bag_Water_Bombs)
+ {
+ if (amount == 3)
+ {
+ itemID = items::Item::Water_Bombs_3;
+ }
+ else if (amount == 5)
+ {
+ itemID = items::Item::Water_Bombs_5;
+ }
+ else if (amount == 10)
+ {
+ itemID = items::Item::Water_Bombs_10;
+ }
+ else if (amount == 15)
+ {
+ itemID = items::Item::Water_Bombs_15;
+ }
+ }
+ else if (bombtype == items::Item::Bomb_Bag_Bomblings)
+ {
+ if (amount == 1)
+ {
+ itemID = items::Item::Bombling_1;
+ }
+ else if (amount == 3)
+ {
+ itemID = items::Item::Bomblings_3;
+ }
+ else if (amount == 5)
+ {
+ itemID = items::Item::Bomblings_5;
+ }
+ else if (amount == 10)
+ {
+ itemID = items::Item::Bomblings_10;
+ }
+ }
+
+
+ float linkPos[3];
+ getPlayerPos(linkPos);
+
+ const float zero[3] = {0.0f,0.0f,0.0f};
+
+ amount = 0;
+
+ tp::f_op_actor_mng::createItemForPresentDemo(linkPos, itemID, 0, -1, -1, zero, zero);*/
+
+ return global::modPtr->setItemBombNumCount_trampoline(unk1, bagNb, amount);
+ }
+ );
+ }
+
+ void Mod::procNewFrame()
+ {
+ float linkPos[3];
+ getPlayerPos(linkPos);
+
+ if (coordsAreInHex == 1)
+ {
+ typeTransform<float, u32> x = { linkPos[0] };
+ typeTransform<float, u32> y = { linkPos[1] };
+ typeTransform<float, u32> z = { linkPos[2] };
+
+ snprintf(currentPosX, 30, "%04x", x.b);
+ snprintf(currentPosY, 30, "%04x", y.b);
+ snprintf(currentPosZ, 30, "%04x", z.b);
+
+ snprintf(linkAngle, 30, "%02x", static_cast<u16>(tp::d_map_path_dmap::getMapPlayerAngleY()));
+ }
+ else
+ {
+ snprintf(currentPosX, 30, "%f", linkPos[0]);
+ snprintf(currentPosY, 30, "%f", linkPos[1]);
+ snprintf(currentPosZ, 30, "%f", linkPos[2]);
+
+ snprintf(linkAngle, 30, "%d", static_cast<u16>(tp::d_map_path_dmap::getMapPlayerAngleY()));
+ }
+
+
+ if (gameInfo.ColorPtr != nullptr)
+ {
+ if (topToggle == 0)
+ {
+ gameInfo.ColorPtr->redTopToggle = 0x4;
+ gameInfo.ColorPtr->greenTopToggle = 0x4;
+ gameInfo.ColorPtr->blueTopToggle = 0x4;
+ }
+ else
+ {
+ gameInfo.ColorPtr->redTopToggle = 0x0;
+ gameInfo.ColorPtr->greenTopToggle = 0x0;
+ gameInfo.ColorPtr->blueTopToggle = 0x0;
+ }
+ gameInfo.ColorPtr->redTop = redTop;
+ gameInfo.ColorPtr->greenTop = greenTop;
+ gameInfo.ColorPtr->blueTop = blueTop;
+ if (bottomToggle == 0)
+ {
+ gameInfo.ColorPtr->redBottomToggle = 0x4;
+ gameInfo.ColorPtr->greenBottomToggle = 0x4;
+ gameInfo.ColorPtr->blueBottomToggle = 0x4;
+ }
+ else
+ {
+ gameInfo.ColorPtr->redBottomToggle = 0x0;
+ gameInfo.ColorPtr->greenBottomToggle = 0x0;
+ gameInfo.ColorPtr->blueBottomToggle = 0x0;
+ }
+ gameInfo.ColorPtr->redBottom = redBottom;
+ gameInfo.ColorPtr->greenBottom = greenBottom;
+ gameInfo.ColorPtr->blueBottom = blueBottom;
+ /*u16 last14 = 0;
+ for(colorResult = 0x0; colorResult < 0x6000; colorResult++)
+ {
+
+ if (gameInfo.ColorPtr->unk_0[colorResult] == 0x14)
+ {
+ if (colorResult - last14 == 8)
+ {
+ break;
+ }
+ else
+ {
+ last14 = colorResult;
+ }
+ }
+ }*/
+ }
+
+ if (trigerLoadSave == 1) {
+ trigerLoadSave = 0;
+ tools::triggerSaveLoad(stage::allStages[stage], room, spawn, state);
+ }
+
+ if (!tools::checkItemFlag(ItemFlags::Orange_Rupee))
+ {//remove the item get animations for floor pickups (except silver rupee)
+ u32 loopAmount = sizeof(item::itemGetAnimationFlags) / sizeof(item::itemGetAnimationFlags[0]);
+ for (u32 i = 0; i < loopAmount; i++)
+ {
+ tools::setItemFlag(static_cast<ItemFlags>(item::itemGetAnimationFlags[i]));
+ }
+ }
+
+ if (enableNormalTime == 0 && setDay == 0)
+ {//set night
+ gameInfo.scratchPad.skyAngle = 0;
+ }
+ else if (enableNormalTime == 0 && setDay == 1)
+ {//set day
+ gameInfo.scratchPad.skyAngle = 180;
+ }
+ // Increment seed
+ if (!customSeed)
+ {
+ tools::getRandom(0);
+ }
+
+ // If loading has started check for LoadEvents
+ if (isLoading)
+ {
+ eventListener->checkLoadEvents();
+ }
+
+ if (controller::checkForButtonInputSingleFrame((controller::PadInputs::Button_R | controller::PadInputs::Button_Z)))
+ {
+ // Toggle console
+ system_console::setState(!sysConsolePtr->consoleEnabled, 0);
+ }
+ else 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))
+ {
+ // Make sure Link is actually loaded
+ tp::d_com_inf_game::LinkMapVars* linkMapPtr = gameInfo.linkMapPtr;
+ if (linkMapPtr)
+ {
+ if (!((linkMapPtr->isTargeting & 0x400000) != 0 && gameInfo.scratchPad.form == 0))
+ {
+ // Transform
+ tp::d_a_alink::procCoMetamorphoseInit(linkMapPtr);
+ }
+ }
+ }
+
+ if (sysConsolePtr->consoleEnabled)
+ {
+ if (controller::checkForButtonInputSingleFrame((controller::PadInputs::Button_R | controller::PadInputs::Button_Start)))
+ {
+ chestRandomizer->generate();
+ }
+
+ // Parse inputs of this frame
+ switch (tp::m_do_controller_pad::cpadInfo.buttonInputTrg)
+ {
+ case controller::PadInputs::Button_A:
+ hudConsole->performAction(ConsoleActions::Option_Increase);
+ break;
+
+ case controller::PadInputs::Button_X:
+ hudConsole->performAction(ConsoleActions::Option_Increase, 0x10);
+ break;
+
+ case controller::PadInputs::Button_B:
+ hudConsole->performAction(ConsoleActions::Option_Decrease);
+ break;
+
+ case controller::PadInputs::Button_Y:
+ hudConsole->performAction(ConsoleActions::Option_Decrease, 0x10);
+ break;
+
+ case controller::PadInputs::Button_DPad_Up:
+ hudConsole->performAction(ConsoleActions::Move_Up);
+ break;
+
+ case controller::PadInputs::Button_DPad_Down:
+ hudConsole->performAction(ConsoleActions::Move_Down);
+ break;
+
+ case controller::PadInputs::Button_DPad_Left:
+ hudConsole->performAction(ConsoleActions::Move_Left);
+ break;
+
+ case controller::PadInputs::Button_DPad_Right:
+ hudConsole->performAction(ConsoleActions::Move_Right);
+ break;
+ }
+ hudConsole->draw();
+ }
+
+ if (truePause && sysConsolePtr->consoleEnabled)
+ {
+ // Inputs handled, don't pass onto the game
+ tp::f_op_scene_req::freezeActors = 1;
+ tp::m_do_controller_pad::cpadInfo.buttonInputTrg = 0;
+ tp::m_do_controller_pad::cpadInfo.buttonInput = 0;
+ }
+ else
+ {
+ tp::f_op_scene_req::freezeActors = 0;
+ }
+
+ if (itemSearchID != lastItemSearchID)
+ {
+ lastItemSearchID = itemSearchID;
+
+ strcpy(itemSearchResults, "404");
+
+ for (u16 i = 0; i < chestRandomizer->totalChecks; i++)
+ {
+ item::ItemCheck* check = &item::checks[i];
+ if (check->destination)
+ {
+ if (check->destination->itemID == itemSearchID)
+ {
+ // Found the source
+ snprintf(itemSearchResults, 40, "ID: %x Stage: %s Room: %d", check->itemID, check->stage, check->room);
+ }
+ }
+ }
+ }
+ else if (itemReverseSearchID != lastItemReverseSearchID)
+ {
+ lastItemReverseSearchID = itemReverseSearchID;
+
+ strcpy(itemReverseSearchResults, "404");
+
+ for (u16 i = 0; i < chestRandomizer->totalChecks; i++)
+ {
+ item::ItemCheck* check = &item::checks[i];
+ if (check->source)
+ {
+ if (check->source->itemID == itemReverseSearchID)
+ {
+ // Found the source
+ snprintf(itemReverseSearchResults, 40, "ID: %x Stage: %s Room: %d", check->itemID, check->stage, check->room);
+ }
+ }
+ }
+ }
+
+ if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Faron_Woods]))
+ {
+ if (0xB == gameInfo.eventSystem.currentEventID)
+ {
+ tools::setCutscene(false, false);
+ if (frame_counter == num_frames)
+ {
+ tools::setItemFlag(ItemFlags::Vessel_Of_Light_Faron);//set flag for vessel since we'll skip it by reloading
+ gameInfo.scratchPad.movingActors.exploredRegions.Eldin = 0b1; // Set Eldin Map Unlocked so we can warp there
+ tools::setCutscene(true, false);
+ }
+ else
+ {
+ frame_counter++;
+ }
+ }
+ else
+ {
+ frame_counter = 0;
+ }
+ }
+
+ checkSearchID = (checkSearchID2 * 0x100) + checkSearchID1;
+ checkReverseSearchID = (checkReverseSearchID2 * 0x100) + checkReverseSearchID1;
+ if (checkSearchID != lastCheckSearchID)
+ {
+ lastCheckSearchID = checkSearchID;
+
+ strcpy(checkSearchResults, "404");
+ if (checkSearchID < chestRandomizer->totalChecks)
+ {
+ item::ItemCheck* check = &item::checks[checkSearchID];
+ if (check->source)
+ {
+ snprintf(checkSearchResults, 40, "ID: %x Stage: %s Room: %d", check->source->itemID, check->source->stage, check->source->room);
+ }
+ }
+ }
+ else if (checkReverseSearchID != lastCheckReverseSearchID)
+ {
+ lastCheckReverseSearchID = checkReverseSearchID;
+
+ strcpy(checkReverseSearchResults, "404");
+
+ if (checkReverseSearchID < chestRandomizer->totalChecks)
+ {
+ item::ItemCheck* check = &item::checks[checkReverseSearchID];
+ if (check->destination)
+ {
+ snprintf(checkReverseSearchResults, 40, "ID: %x Stage: %s Room: %d", check->destination->itemID, check->destination->stage, check->destination->room);
+ }
+ }
+ }
+
+
+ /*if (gameInfo.scratchPad.unk_0[0x019] == 0)
+ {
+ const char* walletText = "Wallet";
+ strncpy(tp::d_com_inf_game::wallet_text, walletText, sizeof(tp::d_com_inf_game::wallet_text) - 1);
+
+ const char* walletDescription = "A wallet from your childhood. It holds up to 1,000 Rupees.";
+ strncpy(tp::d_com_inf_game::wallet_description, walletDescription, sizeof(tp::d_com_inf_game::wallet_description) - 1);
+ }
+ else if (gameInfo.scratchPad.unk_0[0x019] == 1)
+ {
+ const char* walletText = "Big Wallet";
+ strncpy(tp::d_com_inf_game::wallet_text, walletText, sizeof(tp::d_com_inf_game::wallet_text) - 1);
+
+ const char* walletDescription = "A wallet given to you by Agitha, princess of the insect kingdom. It can hold 5,000 Rupees.";
+ strncpy(tp::d_com_inf_game::wallet_description, walletDescription, sizeof(tp::d_com_inf_game::wallet_description) - 1);
+ }
+ else if (gameInfo.scratchPad.unk_0[0x019] == 2)
+ {
+ const char* walletText = "Giant Wallet";
+ strncpy(tp::d_com_inf_game::wallet_text, walletText, sizeof(tp::d_com_inf_game::wallet_text) - 1);
+
+ const char* walletDescription = "The wallet given by Agitha to benefactors of the insect kingdom. It can hold up to 9,999 Rupees.";
+ strncpy(tp::d_com_inf_game::wallet_description, walletDescription, sizeof(tp::d_com_inf_game::wallet_description) - 1);
+ }*/
+
+
+ if(inputBuffering)
+ {
+ tp::m_do_controller_pad::cpadInfo.buttonInputTrg = tp::m_do_controller_pad::cpadInfo.buttonInput;
+ }
+
+ giveAllStoryItems();
+
+ reorderItemWheel();
+
+ allowShopItemsAnytime();
+
+ giveAllScents();
+
+ fixYetaAndYeto();
+
+ fixLBTBossDoor();
+
+ preventPoweringUpDomRod();
+
+ // Call original function
+ fapGm_Execute_trampoline();
+ }
+
+ s32 Mod::procItemCreateFunc(const float pos[3], s32 item, const char funcIdentifier[32])
+ {
+ strcpy(lastItemFunc, funcIdentifier);
+ snprintf(lastItemDataID, 5, "0x%02x", item);
+ snprintf(lastItemDataX, 30, "%f", pos[0]);
+ snprintf(lastItemDataY, 30, "%f", pos[1]);
+ snprintf(lastItemDataZ, 30, "%f", pos[2]);
+ // Runs once when Link picks up an item with text and is holding it towards the camera
+ if (randoEnabled && strcmp(funcIdentifier, "createItemForDirectGet") != 0 && strcmp(funcIdentifier, "createItemForBoss") != 0 &&
+ strcmp(funcIdentifier, "createItemForMidBoss") != 0 && strcmp(funcIdentifier, "createItemForSimpleDemo") != 0)
+ {
+ item = chestRandomizer->getItemReplacement(pos, item);
+ }
+
+ return item;
+ }
+
+ bool Mod::procCheckTreasureRupeeReturn(void* unk1, s32 item)
+ {
+ // Allow to open
+ return false;
+ }
+
+ s32 Mod::procEvtSkipper(void* evtPtr)
+ {
+ // Runs when the user tries to skip a Cutscene
+ if(tp::d_a_alink::checkStageName(stage::allStages[Stage_Sacred_Grove]))
+ {
+ // We're at sacred grove
+ if(0x2 == gameInfo.eventSystem.currentEventID)
+ {
+ // Master Sword cutscene
+ tools::setCutscene(true, false, cutscene_skip::onMasterSwordSkip);
+ }
+ }
+
+
+ // Call original function
+ return evt_control_Skipper_trampoline(evtPtr);
+ }
+
+ bool Mod::proc_query022(void* unk1, void* unk2, s32 unk3)
+ {
+ // Check to see if currently in one of the Ordon interiors
+ if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Ordon_Interiors]))
+ {
+ // Check to see if ckecking for the Iron Boots
+ u16 item = *reinterpret_cast<u16*>(reinterpret_cast<u32>(unk2) + 0x4);
+
+ if (item == items::Item::Iron_Boots)
+ {
+ // Return false so that the door in Bo's house can be opened without having the Iron Boots
+ return false;
+ }
+ }
+
+ // Call original function
+ return query022_trampoline(unk1, unk2, unk3);
+ }
+
+ bool Mod::procDoLink(tp::dynamic_link::DynamicModuleControl* dmc)
+ {
+ // Call the original function immediately, as the REL file needs to be linked before applying patches
+ const bool result = do_link_trampoline(dmc);
+
+ // Get the pointer to the current REL file
+ gc::OSModule::OSModuleInfo* moduleInfo = dmc->moduleInfo;
+
+ // Make sure a REL file is actually loaded, as do_link will clear the pointer if something goes wrong
+ if (!moduleInfo)
+ {
+ return result;
+ }
+
+ // Get the REL pointer as a raw u32, to use for overwrites
+ u32 relPtrRaw = reinterpret_cast<u32>(moduleInfo);
+
+ // Modify the current REL file
+ switch (moduleInfo->id) // May want to set up enums or defines for the module ids
+ {
+ case 0x121: // d_a_npc_bouS.rel - Inside Bo's house
+ {
+ // Prevent Bo from talking after the chest has been opened
+ *reinterpret_cast<u32*>(relPtrRaw + 0x1A44) = 0x48000028; // b 0x28
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ void Mod::procItem_func_UTUWA_HEART()
+ {
+ /* Call the original function immediately, as the heart container flag
+ for the current area needs to be set before making any adjustments */
+ item_func_UTUWA_HEART_trampoline();
+
+ // Clear the heart container flag if not currently in a boss room
+ if (!chestRandomizer->isStageBoss())
+ {
+ gameInfo.localAreaNodes.dungeon.containerGotten = 0b0;
+ }
+ }
+
+ void Mod::giveAllScents()
+ {
+ //code to have all scents at once you need to unlock them tho
+ if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Hyrule_Field]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Youths_Scent) && tp::d_kankyo::env_light.currentRoom == 3)
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Youths_Scent;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Ilias_Scent) &&
+ (tp::d_kankyo::env_light.currentRoom == 9 || tp::d_kankyo::env_light.currentRoom == 10))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Ilias_Scent;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Kakariko_Village]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Youths_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Youths_Scent;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Outside_Castle_Town]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Ilias_Scent) && tp::d_kankyo::env_light.currentRoom == 8)
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Ilias_Scent;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Castle_Town]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Medicine_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Medicine_Scent;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Ilias_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Ilias_Scent;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Zoras_Domain]) || tp::d_a_alink::checkStageName(stage::allStages[Stage_Snowpeak]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Reekfish_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Reekfish_Scent;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Arbiters_Grounds]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Poe_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Poe_Scent;
+ }
+ }
+ else
+ {
+ if (tools::checkItemFlag(ItemFlags::Medicine_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Medicine_Scent;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Reekfish_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Reekfish_Scent;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Poe_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Poe_Scent;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Ilias_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Ilias_Scent;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Youths_Scent))
+ {
+ gameInfo.scratchPad.equipedItems.scent = items::Item::Youths_Scent;
+ }
+ }
+ }
+
+ void Mod::giveAllStoryItems()
+ {
+ if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Lake_Hylia]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Aurus_Memo))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Aurus_Memo;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Snowpeak]) || tp::d_a_alink::checkStageName(stage::allStages[Stage_Kakariko_Graveyard]) ||
+ tp::d_a_alink::checkStageName(stage::allStages[Stage_Zoras_Domain]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Asheis_Sketch))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Asheis_Sketch;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Kakariko_Interiors]) && tp::d_kankyo::env_light.currentRoom == 0)
+ {
+ if (tools::checkItemFlag(ItemFlags::Ilias_Charm))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Ilias_Charm;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Wooden_Statue))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Wooden_Statue;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Renardos_Letter))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Renardos_Letter;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Outside_Castle_Town]) && tp::d_kankyo::env_light.currentRoom == 3)
+ {
+ if (tools::checkItemFlag(ItemFlags::Wooden_Statue))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Wooden_Statue;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Castle_Town_Shops]) && tp::d_kankyo::env_light.currentRoom == 2)
+ {
+ if (tools::checkItemFlag(ItemFlags::Invoice))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Invoice;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Castle_Town_Interiors]) && tp::d_kankyo::env_light.currentRoom == 5)
+ {
+ if (tools::checkItemFlag(ItemFlags::Invoice))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Invoice;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Renardos_Letter))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Renardos_Letter;
+ }
+ }
+ else if (tp::d_a_alink::checkStageName(stage::allStages[Stage_Hidden_Village]) || tp::d_a_alink::checkStageName(stage::allStages[Stage_Impaz_House]))
+ {
+ if (tools::checkItemFlag(ItemFlags::Ilias_Charm))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Ilias_Charm;
+ }
+ }
+ else
+ {
+ if (tools::checkItemFlag(ItemFlags::Horse_Call))
+ {//finished Ilia Quest
+ gameInfo.scratchPad.itemWheel.Story = items::Item::NullItem;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Ilias_Charm))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Ilias_Charm;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Wooden_Statue))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Wooden_Statue;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Invoice))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Invoice;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Renardos_Letter))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Renardos_Letter;
+ }
+
+ if (tools::checkItemFlag(ItemFlags::Coral_Earring))
+ {//given sketch
+ gameInfo.scratchPad.itemWheel.Story = items::Item::NullItem;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Asheis_Sketch))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Asheis_Sketch;
+ }
+
+ if (gameInfo.scratchPad.movingActors.exploredRegions.Desert == 0b1)
+ {//given memo
+ gameInfo.scratchPad.itemWheel.Story = items::Item::NullItem;
+ }
+ else if (tools::checkItemFlag(ItemFlags::Aurus_Memo))
+ {
+ gameInfo.scratchPad.itemWheel.Story = items::Item::Aurus_Memo;
+ }
+
+ }
+ }
+
+ void Mod::allowShopItemsAnytime()
+ {
+ float linkPos[3];
+ getPlayerPos(linkPos);
+
+ u8 hasEmptyBottleAlready = 1;
+ if (gameInfo.scratchPad.itemWheel.Bottle_1 != items::Item::Empty_Bottle && gameInfo.scratchPad.itemWheel.Bottle_2 != items::Item::Empty_Bottle &&
+ gameInfo.scratchPad.itemWheel.Bottle_3 != items::Item::Empty_Bottle && gameInfo.scratchPad.itemWheel.Bottle_4 != items::Item::Empty_Bottle)
+ {
+ hasEmptyBottleAlready = 0;
+ }
+
+ if (tp::d_a_alink::checkStageName("R_SP109") && tp::d_kankyo::env_light.currentRoom == 3)
+ {
+ game_patch::handleMaloShop();
+ }
+
+ if (isStageShop())
+ {
+ if ((tp::d_a_alink::checkStageName("R_SP160") && tp::d_kankyo::env_light.currentRoom == 4) ||
+ (tp::d_a_alink::checkStageName("F_SP108") && tp::d_kankyo::env_light.currentRoom == 4) ||
+ (tp::d_a_alink::checkStageName("F_SP116") && (tp::d_kankyo::env_light.currentRoom == 0 || tp::d_kankyo::env_light.currentRoom == 3)))
+ {//Coro shop/castle goron shop
+ if (gameInfo.aButtonText == 0x1C)
+ {//about to speak to merchant
+ if (allowBottleItemsShopAnytime == 1 && hasEmptyBottleAlready == 0)
+ {
+ if (gameInfo.scratchPad.itemWheel.Bottle_4 != items::Item::Empty_Bottle)
+ {
+ bottle4Contents = gameInfo.scratchPad.itemWheel.Bottle_4;
+ }
+ gameInfo.scratchPad.itemWheel.Bottle_4 = items::Item::Empty_Bottle;
+ bottleTrickOn = 1;
+ }
+ if (tools::checkItemFlag(ItemFlags::Hylian_Shield))
+ {
+ hadHShield = 1;
+ tools::clearItemFlag(ItemFlags::Hylian_Shield);
+ shieldTrickOn = 1;
+ }
+ }
+ if (gameInfo.aButtonText == 0x22)
+ {//selecting if you wanna buy or not
+ if (bottleTrickOn == 1)
+ {
+ bottleTrickOn = 2;
+ }
+ if (shieldTrickOn == 1)
+ {
+ shieldTrickOn = 2;
+ }
+ }
+ if (gameInfo.aButtonText == 0x23)
+ {
+ if (bottleTrickOn == 2)
+ {
+ gameInfo.scratchPad.itemWheel.Bottle_4 = bottle4Contents;
+ bottleTrickOn = 0;
+ }
+ if (shieldTrickOn == 2)
+ {
+ if (hadHShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Hylian_Shield);
+ }
+ shieldTrickOn = 0;
+ }
+ }
+ if (gameInfo.aButtonText == 0x6 || gameInfo.aButtonText == 0x79)
+ {//leaving
+ if (bottleTrickOn >= 1)
+ {
+ gameInfo.scratchPad.itemWheel.Bottle_4 = bottle4Contents;
+ bottleTrickOn = 0;
+ }
+ if (shieldTrickOn >= 1)
+ {
+ if (hadHShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Hylian_Shield);
+ }
+ shieldTrickOn = 0;
+ }
+ }
+ }
+ else
+ {//normal shops
+ if (gameInfo.bButtonText == 0x2A)
+ {//is in shop and is selecting an item
+ if (allowBottleItemsShopAnytime == 1 && hasEmptyBottleAlready == 0)
+ {
+ if (gameInfo.scratchPad.itemWheel.Bottle_4 != items::Item::Empty_Bottle)
+ {
+ bottle4Contents = gameInfo.scratchPad.itemWheel.Bottle_4;
+ }
+ gameInfo.scratchPad.itemWheel.Bottle_4 = items::Item::Empty_Bottle;
+ bottleTrickOn = 1;
+ }
+ if (tools::checkItemFlag(ItemFlags::Hylian_Shield))
+ {
+ hadHShield = 1;
+ tools::clearItemFlag(ItemFlags::Hylian_Shield);
+ shieldTrickOn = 1;
+ }
+ if (tools::checkItemFlag(ItemFlags::Wooden_Shield))
+ {
+ hadWShield = 1;
+ tools::clearItemFlag(ItemFlags::Wooden_Shield);
+ shieldTrickOn = 1;
+ }
+ if (tools::checkItemFlag(ItemFlags::Ordon_Shield))
+ {
+ hadOShield = 1;
+ tools::clearItemFlag(ItemFlags::Ordon_Shield);
+ shieldTrickOn = 1;
+ }
+
+ if (!tools::checkItemFlag(ItemFlags::Null_DA) && 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;
+ bombBag2Contents = gameInfo.scratchPad.itemWheel.Bomb_Bag_2;
+ bombBag3Contents = gameInfo.scratchPad.itemWheel.Bomb_Bag_3;
+ bombBag1Ammo = gameInfo.scratchPad.ammo.bombs1;
+ bombBag2Ammo = gameInfo.scratchPad.ammo.bombs2;
+ bombBag3Ammo = gameInfo.scratchPad.ammo.bombs3;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_1 = 0xFF;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_2 = 0xFF;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_3 = 0xFF;
+ bombBagTrickOn = 1;
+ }
+
+ }
+ else if (gameInfo.aButtonText == 0x23)
+ {//is in shop and is exiting the item select mode
+ if (bottleTrickOn == 1)
+ {
+ gameInfo.scratchPad.itemWheel.Bottle_4 = bottle4Contents;
+ bottleTrickOn = 0;
+ }
+ if (shieldTrickOn == 1)
+ {
+ if (hadHShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Hylian_Shield);
+ }
+ if (hadWShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Wooden_Shield);
+ }
+ if (hadOShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Ordon_Shield);
+ }
+ shieldTrickOn = 0;
+ }
+ if (bombBagTrickOn == 1)
+ {
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_1 = bombBag1Contents;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_2 = bombBag2Contents;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_3 = bombBag3Contents;
+ gameInfo.scratchPad.ammo.bombs1 = bombBag1Ammo;
+ gameInfo.scratchPad.ammo.bombs2 = bombBag2Ammo;
+ gameInfo.scratchPad.ammo.bombs3 = bombBag3Ammo;
+ bombBagTrickOn = 0;
+ }
+ }
+ if (tools::checkItemFlag(ItemFlags::Null_DA) && bombBagTrickOn == 1)
+ {//bought bomb bag check
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_1 = bombBag1Contents;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_2 = bombBag2Contents;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_3 = bombBag3Contents;
+ gameInfo.scratchPad.ammo.bombs1 = bombBag1Ammo;
+ gameInfo.scratchPad.ammo.bombs2 = bombBag2Ammo;
+ gameInfo.scratchPad.ammo.bombs3 = bombBag3Ammo;
+ bombBagTrickOn = 0;
+ }
+ }
+ }
+ else
+ {
+ if (bottleTrickOn >= 1)
+ {
+ gameInfo.scratchPad.itemWheel.Bottle_4 = bottle4Contents;
+ bottleTrickOn = 0;
+ }
+ if (shieldTrickOn >= 1)
+ {
+ if (hadHShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Hylian_Shield);
+ }
+ if (hadWShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Wooden_Shield);
+ }
+ if (hadOShield == 1)
+ {
+ tools::setItemFlag(ItemFlags::Ordon_Shield);
+ }
+ shieldTrickOn = 0;
+ }
+ if (bombBagTrickOn >= 1)
+ {
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_1 = bombBag1Contents;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_2 = bombBag2Contents;
+ gameInfo.scratchPad.itemWheel.Bomb_Bag_3 = bombBag3Contents;
+ gameInfo.scratchPad.ammo.bombs1 = bombBag1Ammo;
+ gameInfo.scratchPad.ammo.bombs2 = bombBag2Ammo;
+ gameInfo.scratchPad.ammo.bombs3 = bombBag3Ammo;
+ bombBagTrickOn = 0;
+ }
+ }
+ }
+
+
+ void Mod::reorderItemWheel()
+ {
+ u8 currentSlot = 0x0;
+ if (tools::checkItemFlag(ItemFlags::Clawshots))
+ {
+ gameInfo.scratchPad.itemWheel.Double_Clawshot = items::Item::Clawshots;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xA;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Dominion_Rod))
+ {
+ gameInfo.scratchPad.itemWheel.Dominion_Rod = items::Item::Dominion_Rod;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x8;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Ball_and_Chain))
+ {
+ gameInfo.scratchPad.itemWheel.Ball_and_Chain = items::Item::Ball_and_Chain;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x6;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Spinner))
+ {
+ gameInfo.scratchPad.itemWheel.Spinner = items::Item::Spinner;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x2;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Clawshot))
+ {
+ gameInfo.scratchPad.itemWheel.Clawshot = items::Item::Clawshot;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x9;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Heros_Bow))
+ {
+ gameInfo.scratchPad.itemWheel.Bow = items::Item::Heros_Bow;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x4;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Iron_Boots))
+ {
+ gameInfo.scratchPad.itemWheel.Iron_Boots = items::Item::Iron_Boots;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x3;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Boomerang))
+ {
+ gameInfo.scratchPad.itemWheel.Boomerang = items::Item::Boomerang;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x0;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Lantern))
+ {
+ gameInfo.scratchPad.itemWheel.Lantern = items::Item::Lantern;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x1;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Slingshot))
+ {
+ gameInfo.scratchPad.itemWheel.Slingshot = items::Item::Slingshot;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x17;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Fishing_Rod != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x14;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Hawkeye))
+ {
+ gameInfo.scratchPad.itemWheel.Hawkeye = items::Item::Hawkeye;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x5;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bomb_Bag_1 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xF;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bomb_Bag_2 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x10;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bomb_Bag_3 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x11;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bottle_1 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xB;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bottle_2 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xC;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bottle_3 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xD;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Bottle_4 != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xE;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Story != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x13;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Ooccoo != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x12;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Sky_Book != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x16;
+ currentSlot++;
+ }
+ if (tools::checkItemFlag(ItemFlags::Horse_Call))
+ {
+ gameInfo.scratchPad.itemWheel.Horse_Call = items::Item::Horse_Call;
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x15;
+ currentSlot++;
+ }
+ if (gameInfo.scratchPad.itemWheel.Item_Slot != 0xFF)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0x7;
+ currentSlot++;
+ }
+
+ for (u16 i = currentSlot; i < sizeof(gameInfo.scratchPad.itemSlotsOrder) / sizeof(u8); i++)
+ {
+ gameInfo.scratchPad.itemSlotsOrder[currentSlot] = 0xFF;
+ }
+ }
+
+ void Mod::fixYetaAndYeto()
+ {
+ if (tools::checkItemFlag(ItemFlags::Bed_Key) && tp::d_a_alink::checkStageName("D_MN11"))
+ {
+ float linkPos[3];
+ getPlayerPos(linkPos);
+
+ if (gameInfo.aButtonText == 0x6 && (tp::d_kankyo::env_light.currentRoom == 0 || tp::d_kankyo::env_light.currentRoom == 1 ||
+ tp::d_kankyo::env_light.currentRoom == 2 || tp::d_kankyo::env_light.currentRoom == 3 || tp::d_kankyo::env_light.currentRoom == 4 ||
+ tp::d_kankyo::env_light.currentRoom == 7) && linkPos[1] == 0)
+ {
+ gameInfo.localAreaNodes.dungeon.bigKeyGotten = 0b0;
+ yetaTrickOn = 1;
+ }
+ if (gameInfo.aButtonText == 0x79 && yetaTrickOn == 1)
+ {
+ gameInfo.localAreaNodes.dungeon.bigKeyGotten = 0b1;
+ yetaTrickOn = 0;
+ }
+ }
+ }
+
+ void Mod::fixLBTBossDoor()
+ {
+ if (tp::d_a_alink::checkStageName("D_MN01") && tp::d_kankyo::env_light.currentRoom == 3)
+ {
+ float linkPos[3];
+ getPlayerPos(linkPos);
+ if (gameInfo.aButtonText == 0x6 && linkPos[1] >= -340 && linkPos[1] <= -320)
+ {
+ nbLBTKeys = gameInfo.localAreaNodes.nbKeys;
+ LBTBossDoorTrickOn = 1;
+ }
+ if (gameInfo.aButtonText == 0x79 && LBTBossDoorTrickOn == 1)
+ {
+ gameInfo.localAreaNodes.nbKeys = nbLBTKeys;
+ LBTBossDoorTrickOn = 0;
+ }
+ }
+ }
+
+ void Mod::preventPoweringUpDomRod()
+ {
+ if (gameInfo.scratchPad.itemWheel.Sky_Book == 0xFF && tools::checkItemFlag(ItemFlags::Ancient_Sky_Book_empty) && !tools::checkItemFlag(ItemFlags::Ancient_Sky_Book_partly_filled))
+ {
+ gameInfo.scratchPad.itemWheel.Sky_Book = items::Item::Ancient_Sky_Book_empty;
+ }
+ if (tp::d_a_alink::checkStageName("R_SP209"))
+ {
+ if (gameInfo.scratchPad.itemWheel.Sky_Book == items::Item::Ancient_Sky_Book_empty)
+ {
+ gameInfo.scratchPad.itemWheel.Sky_Book = 0xFF;
+ }
+ }
+ }
+
+ bool Mod::isStageShop()
+ {
+ u8 totalShopStages = sizeof(stage::shopStages) / sizeof(stage::shopStages[0]);
+ for (u8 i = 0; i < totalShopStages; i++)
+ {
+ if (tp::d_a_alink::checkStageName(stage::shopStages[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void Mod::doCustomTRESActor(void* mStatus_roomControl)
+ {
+ tp::d_com_inf_game::GameInfo* pGameInfo = &tp::d_com_inf_game::dComIfG_gameInfo;
+
+ u32 numChecks = sizeof(customChecks) / sizeof(customChecks[0]);
+
+ // Count and temp array for the checks for this stage+room
+ u32 checkCount = 0;
+ customCheck* checks = new customCheck[5]; // Assume there's never more than 5 custom checks per stage+room
+
+ // Loop through checks and place if correct room and stage
+ for (u32 i = 0; i < numChecks; i++)
+ {
+ customCheck* check = &customChecks[i];
+
+ if (0 == strcmp(pGameInfo->nextStageVars.nextStage, check->stage) &&
+ (0xFF == check->room || pGameInfo->nextStageVars.nextRoom == check->room) && // 0xFF = no need to check for room
+ check->requirement())
+ {
+ checks[checkCount] = *check;
+ checkCount++;
+ }
+ }
+
+ if (checkCount > 0)
+ {
+ // Create required structs
+ tp::d_stage::TRES* TRES = new tp::d_stage::TRES[checkCount];
+ tp::d_stage::dzxChunkTypeInfo chunkInfo;
+ strcpy(chunkInfo.tag, "ACTR"); // has to be ACTR for the function we use
+ chunkInfo.numChunks = checkCount;
+ chunkInfo.chunkDataPtr = TRES;
+
+ // Populate TRES array with data
+ for (u32 i = 0; i < checkCount; i++)
+ {
+ customCheck check = checks[i];
+
+ if (check.overrides != nullptr)
+ {
+ check.overrides();
+ }
+
+ strcpy(TRES[i].actorName, "tboxA0\0");
+ TRES[i].flags = 0xFF0FF000 | (check.chestType << 20) | (check.saveFlag << 4);
+
+ // Translate hex to float (1:1)
+ typeTransform<u32, float> X, Y, Z;
+ X.a = check.X;
+ Y.a = check.Y;
+ Z.a = check.Z;
+
+ TRES[i].X = X.b;
+ TRES[i].Y = Y.b;
+ TRES[i].Z = Z.b;
+
+ TRES[i].angle = check.Angle;
+
+ 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);
+
+ delete[] TRES;
+ }
+
+ delete[] checks;
+ return;
+ }
+} // namespace mod \ No newline at end of file
diff --git a/source/source/patch.cpp b/source/source/patch.cpp
new file mode 100644
index 0000000..7a51a11
--- /dev/null
+++ b/source/source/patch.cpp
@@ -0,0 +1,30 @@
+#include "patch.h"
+#include "defines.h"
+#include "memory.h"
+
+namespace mod::patch
+{
+ void writeBranch(void* ptr, void* destination)
+ {
+ u32 branch = 0x48000000; // b
+ writeBranchMain(ptr, destination, branch);
+ }
+
+ void writeBranchLR(void* ptr, void* destination)
+ {
+ u32 branch = 0x48000001; // bl
+ writeBranchMain(ptr, destination, branch);
+ }
+
+ void writeBranchMain(void* ptr, void* destination, u32 branch)
+ {
+ u32 delta = reinterpret_cast<u32>(destination) - reinterpret_cast<u32>(ptr);
+
+ branch |= (delta & 0x03FFFFFC);
+
+ u32* p = reinterpret_cast<u32*>(ptr);
+ *p = branch;
+
+ memory::clear_DC_IC_Cache(ptr, sizeof(u32));
+ }
+} \ No newline at end of file
diff --git a/source/source/rel.cpp b/source/source/rel.cpp
new file mode 100644
index 0000000..623944e
--- /dev/null
+++ b/source/source/rel.cpp
@@ -0,0 +1,42 @@
+extern "C"
+{
+ typedef void (*PFN_voidfunc)();
+ __attribute__((section (".ctors"))) extern PFN_voidfunc _ctors_start[];
+ __attribute__((section (".ctors"))) extern PFN_voidfunc _ctors_end[];
+ __attribute__((section (".dtors"))) extern PFN_voidfunc _dtors_start[];
+ __attribute__((section (".dtors"))) extern PFN_voidfunc _dtors_end[];
+
+ void _prolog();
+ void _epilog();
+ void _unresolved();
+}
+
+namespace mod
+{
+ extern void main();
+}
+
+void _prolog()
+{
+ // Run global constructors
+ for (PFN_voidfunc *ctor = _ctors_start; ctor != _ctors_end && *ctor; ++ctor)
+ {
+ (*ctor)();
+ }
+ // Run mod main
+ mod::main();
+}
+
+void _epilog()
+{
+ // In the unlikely event we ever get here, run the global destructors
+ for (PFN_voidfunc *dtor = _dtors_start; dtor != _dtors_end && *dtor; ++dtor)
+ {
+ (*dtor)();
+ }
+}
+
+void _unresolved(void)
+{
+
+} \ No newline at end of file
diff --git a/source/source/runtime/restfpr_x.s b/source/source/runtime/restfpr_x.s
new file mode 100644
index 0000000..d2c533a
--- /dev/null
+++ b/source/source/runtime/restfpr_x.s
@@ -0,0 +1,42 @@
+.global _restfpr_14_x
+.global _restfpr_15_x
+.global _restfpr_16_x
+.global _restfpr_17_x
+.global _restfpr_18_x
+.global _restfpr_19_x
+.global _restfpr_20_x
+.global _restfpr_21_x
+.global _restfpr_22_x
+.global _restfpr_23_x
+.global _restfpr_24_x
+.global _restfpr_25_x
+.global _restfpr_26_x
+.global _restfpr_27_x
+.global _restfpr_28_x
+.global _restfpr_29_x
+.global _restfpr_30_x
+.global _restfpr_31_x
+
+_restfpr_14_x: lfd %f14,-0x90(%r11)
+_restfpr_15_x: lfd %f15,-0x88(%r11)
+_restfpr_16_x: lfd %f16,-0x80(%r11)
+_restfpr_17_x: lfd %f17,-0x78(%r11)
+_restfpr_18_x: lfd %f18,-0x70(%r11)
+_restfpr_19_x: lfd %f19,-0x68(%r11)
+_restfpr_20_x: lfd %f20,-0x60(%r11)
+_restfpr_21_x: lfd %f21,-0x58(%r11)
+_restfpr_22_x: lfd %f22,-0x50(%r11)
+_restfpr_23_x: lfd %f23,-0x48(%r11)
+_restfpr_24_x: lfd %f24,-0x40(%r11)
+_restfpr_25_x: lfd %f25,-0x38(%r11)
+_restfpr_26_x: lfd %f26,-0x30(%r11)
+_restfpr_27_x: lfd %f27,-0x28(%r11)
+_restfpr_28_x: lfd %f28,-0x20(%r11)
+_restfpr_29_x: lfd %f29,-0x18(%r11)
+_restfpr_30_x: lfd %f30,-0x10(%r11)
+_restfpr_31_x:
+lwz %r0,0x4(%r11)
+lfd %f31,-0x8(%r11)
+mtlr %r0
+mr %sp,%r11
+blr \ No newline at end of file
diff --git a/source/source/runtime/restgpr_x.s b/source/source/runtime/restgpr_x.s
new file mode 100644
index 0000000..16723ce
--- /dev/null
+++ b/source/source/runtime/restgpr_x.s
@@ -0,0 +1,42 @@
+.global _restgpr_14_x
+.global _restgpr_15_x
+.global _restgpr_16_x
+.global _restgpr_17_x
+.global _restgpr_18_x
+.global _restgpr_19_x
+.global _restgpr_20_x
+.global _restgpr_21_x
+.global _restgpr_22_x
+.global _restgpr_23_x
+.global _restgpr_24_x
+.global _restgpr_25_x
+.global _restgpr_26_x
+.global _restgpr_27_x
+.global _restgpr_28_x
+.global _restgpr_29_x
+.global _restgpr_30_x
+.global _restgpr_31_x
+
+_restgpr_14_x: lwz %r14,-0x48(%r11)
+_restgpr_15_x: lwz %r15,-0x44(%r11)
+_restgpr_16_x: lwz %r16,-0x40(%r11)
+_restgpr_17_x: lwz %r17,-0x3C(%r11)
+_restgpr_18_x: lwz %r18,-0x38(%r11)
+_restgpr_19_x: lwz %r19,-0x34(%r11)
+_restgpr_20_x: lwz %r20,-0x30(%r11)
+_restgpr_21_x: lwz %r21,-0x2C(%r11)
+_restgpr_22_x: lwz %r22,-0x28(%r11)
+_restgpr_23_x: lwz %r23,-0x24(%r11)
+_restgpr_24_x: lwz %r24,-0x20(%r11)
+_restgpr_25_x: lwz %r25,-0x1C(%r11)
+_restgpr_26_x: lwz %r26,-0x18(%r11)
+_restgpr_27_x: lwz %r27,-0x14(%r11)
+_restgpr_28_x: lwz %r28,-0x10(%r11)
+_restgpr_29_x: lwz %r29,-0xC(%r11)
+_restgpr_30_x: lwz %r30,-0x8(%r11)
+_restgpr_31_x:
+lwz %r0,0x4(%r11)
+lwz %r31,-0x4(%r11)
+mtlr %r0
+mr %sp,%r11
+blr \ No newline at end of file
diff --git a/source/source/singleton.cpp b/source/source/singleton.cpp
new file mode 100644
index 0000000..9a26fe8
--- /dev/null
+++ b/source/source/singleton.cpp
@@ -0,0 +1,37 @@
+#include "singleton.h"
+#include "defines.h"
+
+
+namespace mod
+{
+
+ Singleton* Singleton::instance = 0;
+
+ Singleton* Singleton::getInstance()
+ {
+ if (instance == 0)
+ {
+ instance = new Singleton();
+ }
+ return instance;
+ }
+
+ Singleton::Singleton()
+ {
+ isMDHSkipEnabled = 1;
+ isForestEscapeEnabled = 1;
+ isGateUnlockEnabled = 1;
+ isGoatSkipEnabled = 1;
+ isMSPuzzleSkipEnabled = 1;
+ isCartEscortSkipEnabled = 1;
+ isEarlyCiTSEnabled = 0;
+ isCannonRepaired = 0;
+ isEarlyDesertEnabled = 0;
+ isBossKeyseyEnabled = 0;
+ isSewerSkipEnabled = 1;
+ shuffledSkybook = 1;
+ isIntroSkipped = 1;
+ isTwilightSkipped = 1;
+ }
+
+} \ No newline at end of file
diff --git a/source/source/stage.cpp b/source/source/stage.cpp
new file mode 100644
index 0000000..e2a21c3
--- /dev/null
+++ b/source/source/stage.cpp
@@ -0,0 +1,141 @@
+#include "stage.h"
+#include "defines.h"
+
+
+namespace mod::stage
+{
+ char allStages[76][8] =
+ {
+ "D_MN01",
+ "D_MN01A",
+ "D_MN01B",
+ "D_MN04",
+ "D_MN04A",
+ "D_MN04B",
+ "D_MN05",
+ "D_MN05A",
+ "D_MN05B",
+ "D_MN06",
+ "D_MN06A",
+ "D_MN06B",
+ "D_MN07",
+ "D_MN07A",
+ "D_MN07B",
+ "D_MN08",
+ "D_MN08A",
+ "D_MN08B",
+ "D_MN08C",
+ "D_MN08D",
+ "D_MN09",
+ "D_MN09A",
+ "D_MN09B",
+ "D_MN09C",
+ "D_MN10",
+ "D_MN10A",
+ "D_MN10B",
+ "D_MN11",
+ "D_MN11A",
+ "D_MN11B",
+ "D_SB00",
+ "D_SB01",
+ "D_SB02",
+ "D_SB03",
+ "D_SB04",
+ "D_SB05",
+ "D_SB06",
+ "D_SB07",
+ "D_SB08",
+ "D_SB09",
+ "D_SB10",
+ "F_SP00",
+ "F_SP102",
+ "F_SP103",
+ "F_SP104",
+ "F_SP108",
+ "F_SP109",
+ "F_SP110",
+ "F_SP111",
+ "F_SP112",
+ "F_SP113",
+ "F_SP114",
+ "F_SP115",
+ "F_SP116",
+ "F_SP117",
+ "F_SP118",
+ "F_SP121",
+ "F_SP122",
+ "F_SP123",
+ "F_SP124",
+ "F_SP125",
+ "F_SP126",
+ "F_SP127",
+ "F_SP128",
+ "F_SP200",
+ "R_SP01",
+ "R_SP107",
+ "R_SP108",
+ "R_SP109",
+ "R_SP110",
+ "R_SP116",
+ "R_SP127",
+ "R_SP128",
+ "R_SP160",
+ "R_SP161",
+ "R_SP209"
+ };
+
+ const char* dungeonStages[18]
+ {
+ allStages[Stage_Lakebed_Temple],
+ allStages[Stage_Deku_Toad],
+ allStages[Stage_Goron_Mines],
+ allStages[Stage_Dangoro],
+ allStages[Stage_Forest_Temple],
+ allStages[Stage_Ook],
+ allStages[Stage_Temple_of_Time],
+ allStages[Stage_Darknut],
+ allStages[Stage_City_in_the_Sky],
+ allStages[Stage_Aeralfos],
+ allStages[Stage_Palace_of_Twilight],
+ allStages[Stage_Phantom_Zant_1],
+ allStages[Stage_Phantom_Zant_2],
+ allStages[Stage_Hyrule_Castle],
+ allStages[Stage_Arbiters_Grounds],
+ allStages[Stage_Death_Sword],
+ allStages[Stage_Snowpeak_Ruins],
+ allStages[Stage_Darkhammer],
+ };
+
+ const char* bossStages[8]
+ {
+ allStages[Stage_Morpheel],
+ allStages[Stage_Fyrus],
+ allStages[Stage_Diababa],
+ allStages[Stage_Armogohma],
+ allStages[Stage_Argorok],
+ allStages[Stage_Zant_Main],
+ allStages[Stage_Stallord],
+ allStages[Stage_Blizzeta]
+ };
+
+ const char* shopStages[8]
+ {
+ allStages[Stage_Ordon_Interiors],
+ allStages[Stage_Faron_Woods],
+ allStages[Stage_Kakariko_Interiors],
+ allStages[Stage_Death_Mountain],
+ allStages[Stage_Kakariko_Village],
+ allStages[Stage_Castle_Town_Shops],
+ allStages[Stage_Castle_Town],
+ allStages[Stage_City_in_the_Sky]
+ };
+
+ const char* grottoStages[5]
+ {
+ allStages[Stage_Grotto_1],
+ allStages[Stage_Grotto_2],
+ allStages[Stage_Grotto_3],
+ allStages[Stage_Grotto_4],
+ allStages[Stage_Grotto_5]
+ };
+} \ No newline at end of file
diff --git a/source/source/systemConsole.cpp b/source/source/systemConsole.cpp
new file mode 100644
index 0000000..7c88a1f
--- /dev/null
+++ b/source/source/systemConsole.cpp
@@ -0,0 +1,24 @@
+#include "systemConsole.h"
+#include "defines.h"
+
+#include <tp/JFWSystem.h>
+
+namespace mod::system_console
+{
+ void setBackgroundColor(u32 rgba)
+ {
+ u32* ConsoleColor = reinterpret_cast<u32*>(sysConsolePtr->consoleColor);
+ *ConsoleColor = rgba;
+ }
+
+ void setState(bool activeFlag, u32 totalLines)
+ {
+ tp::jfw_system::SystemConsole* Console = sysConsolePtr;
+ Console->consoleEnabled = activeFlag;
+
+ for (u32 i = 0; i < totalLines; i++)
+ {
+ Console->consoleLine[i].showLine = activeFlag;
+ }
+ }
+} \ No newline at end of file
diff --git a/source/source/tools.cpp b/source/source/tools.cpp
new file mode 100644
index 0000000..8b30184
--- /dev/null
+++ b/source/source/tools.cpp
@@ -0,0 +1,112 @@
+#include "defines.h"
+#include "tools.h"
+#include "global.h"
+
+#include <tp/evt_control.h>
+#include <tp/d_com_inf_game.h>
+#include <tp/JFWSystem.h>
+#include <cstring>
+#include <cstdio>
+
+namespace mod::tools
+{
+ u64 randomSeed = 0x9e3779b97f4a7c15;
+
+ u32 getRandom(u32 max)
+ {
+ u64 z = (randomSeed += 0x9e3779b97f4a7c15);
+ z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+ z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+
+ return (z % max);
+ }
+
+ void triggerRandomGenerator()
+ {
+ sprintf(sysConsolePtr->consoleLine[12].line, "New rando");
+ global::chestRandoPtr->generate();
+ }
+
+ void triggerSaveLoad(char* stage, u8 room, u8 spawn, u8 state, u8 event)
+ {
+ strcpy(gameInfo.nextStageVars.nextStage, stage);
+ gameInfo.nextStageVars.nextRoom = room;
+ gameInfo.nextStageVars.nextSpawnPoint = spawn;
+ gameInfo.nextStageVars.nextState = state;
+
+ gameInfo.eventSystem.nextEventID = event;
+ gameInfo.respawnValues.respawnAnimation = 0;
+ gameInfo.nextStageVars.isVoidorWarp = 0;
+ gameInfo.respawnValues.respawnCutscene = 0;
+ gameInfo.eventSystem.immediateControl = 0xFFFF;
+ gameInfo.nextStageVars.fadeType = 0x13;
+
+ gameInfo.nextStageVars.triggerLoad = true;
+ }
+
+ void setCutscene(bool skippable, bool fade, tp::evt_control::csFunc onSkip)
+ {
+ gameInfo.eventSystem.fadeOnSkip = fade;
+ if(skippable)
+ {
+ gameInfo.eventSystem.onSkip = onSkip;
+ }
+ else
+ {
+ gameInfo.eventSystem.onSkip = nullptr;
+ }
+ }
+
+ float fCompare(const float f1, const float f2)
+ {
+ if(f1 > f2)
+ {
+ return (f1 - f2);
+ }
+ else
+ {
+ return (f2 - f1);
+ }
+ }
+
+ u16 fletcher16(u8* data, s32 count)
+ {
+ u16 sum1 = 0;
+ u16 sum2 = 0;
+
+ for(s32 index = 0; index < count; ++index )
+ {
+ sum1 = (sum1 + data[index]) % 0xFF;
+ sum2 = (sum2 + sum1) % 0xFF;
+ }
+
+ return (sum2 << 8) | sum1;
+ }
+
+ void setItemFlag(ItemFlags flag)
+ {
+ u32 flagsPerVar = sizeof(u32) * 8;
+ u32 tempFlagVar = static_cast<u32>(flag);
+
+ u32* tempItemFlagsArray = gameInfo.scratchPad.itemFlags;
+ tempItemFlagsArray[tempFlagVar / flagsPerVar] |= 1 << (tempFlagVar % flagsPerVar);
+ }
+
+ void clearItemFlag(ItemFlags flag)
+ {
+ u32 flagsPerVar = sizeof(u32) * 8;
+ u32 tempFlagVar = static_cast<u32>(flag);
+
+ u32* tempItemFlagsArray = gameInfo.scratchPad.itemFlags;
+ tempItemFlagsArray[tempFlagVar / flagsPerVar] &= ~(1 << (tempFlagVar % flagsPerVar));
+ }
+
+ bool checkItemFlag(ItemFlags flag)
+ {
+ u32 flagsPerVar = sizeof(u32) * 8;
+ u32 tempFlagVar = static_cast<u32>(flag);
+
+ u32* tempItemFlagsArray = gameInfo.scratchPad.itemFlags;
+ return tempItemFlagsArray[tempFlagVar / flagsPerVar] & (1 << (tempFlagVar % flagsPerVar));
+ }
+} \ No newline at end of file