summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlunarsoap5 <justindakotacarter@gmail.com>2021-11-07 21:24:49 -0600
committerlunarsoap5 <justindakotacarter@gmail.com>2021-11-07 21:24:49 -0600
commitde4c80f6967f1b47f5c6deb17bc764050d0bc956 (patch)
tree46196ec2894a57ff460396f0c183a2187e4a19cb
parent5d87db08967bbfd200cef45325dd0ead771f3805 (diff)
Update to 0.20b0.20b
-rw-r--r--include/customChecks.h211
-rw-r--r--include/customMessage.h590
-rw-r--r--include/defines.h2
-rw-r--r--include/game_patches.h42
-rw-r--r--include/gc/bmgres.h47
-rw-r--r--include/item.h15
-rw-r--r--include/itemChecks.h2
-rw-r--r--include/items.h102
-rw-r--r--include/mod.h84
-rw-r--r--include/musicRando.h3
-rw-r--r--include/singleton.h9
-rw-r--r--include/stage.h2
-rw-r--r--include/tp.eu.lst33
-rw-r--r--include/tp.jp.lst32
-rw-r--r--include/tp.us.lst30
-rw-r--r--include/tp/DynamicLink.h2
-rw-r--r--include/tp/control.h28
-rw-r--r--include/tp/d_a_alink.h3
-rw-r--r--include/tp/d_com_inf_game.h40
-rw-r--r--include/tp/d_item.h5
-rw-r--r--include/tp/d_item_data.h12
-rw-r--r--include/tp/d_msg_class.h12
-rw-r--r--include/tp/d_msg_flow.h7
-rw-r--r--include/tp/d_save.h3
-rw-r--r--include/tp/d_stage.h1
-rw-r--r--include/tp/processor.h11
-rw-r--r--include/tp/resource.h44
-rw-r--r--source/chestRando.cpp507
-rw-r--r--source/game_patches.cpp871
-rw-r--r--source/item.cpp47
-rw-r--r--source/itemChecks.cpp169
-rw-r--r--source/mod.cpp1656
-rw-r--r--source/musicRando.cpp88
-rw-r--r--source/singleton.cpp10
-rw-r--r--source/stage.cpp37
35 files changed, 3072 insertions, 1685 deletions
diff --git a/include/customChecks.h b/include/customChecks.h
index 34f3e23..05fe084 100644
--- a/include/customChecks.h
+++ b/include/customChecks.h
@@ -28,7 +28,7 @@ struct customCheck
namespace mod
{
- customCheck customChecks[37] = {
+ customCheck customChecks[30] = {
/*Ordon Shield*/
{ "F_SP103",
0,
@@ -39,12 +39,10 @@ namespace mod
0x43390000,
0x44405C5E,
0x5FA0,
- []()
- {
+ []() {
gameInfo.localAreaNodes.unk_0[0x8] |= 0x4; /*remove ordon shield*/
},
- []()
- {
+ []() {
return ( gameInfo.scratchPad.eventBits[0x5] & 0x7A ) != 0; /*have sewers been done*/
} },
/*Ordon Sword*/
@@ -57,13 +55,11 @@ namespace mod
0x0,
0xC26ABE99,
0xCC7D,
- []()
- {
+ []() {
gameInfo.localAreaNodes.unk_0[0x8] |= 0x1; /*got ordon sword*/
gameInfo.localAreaNodes.unk_0[0x1B] |= 0x8; /*remove ordon sword*/
},
- []()
- {
+ []() {
return ( gameInfo.scratchPad.eventBits[0x5] & 0x7A ) != 0; /*have sewers been done*/
} },
/*Fishing rod*/
@@ -76,13 +72,11 @@ namespace mod
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*/
@@ -95,13 +89,11 @@ namespace mod
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*/
@@ -115,8 +107,7 @@ namespace mod
0x45F31BF5,
0x7881,
nullptr /*Flag is set in game_patches to avoid interaction with vanilla check*/,
- []()
- {
+ []() {
return ( gameInfo.localAreaNodes.unk_0[0xC] & 0x2 ) != 0; /*is goats 1 done*/
} },
/*Lantern*/
@@ -131,8 +122,7 @@ namespace mod
0x43FA0000,
0x43944190,
0xC270,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x8] |= 0x4; /*got zora armor from Rutela*/
},
[]() { return true; } },
@@ -146,8 +136,7 @@ namespace mod
0x43FA57D9,
0xC3BCEFAC,
0xC270,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x3B] |= 0x80; /*Got Coral Earring from Ralis*/
},
[]() { return tools::checkItemFlag( ItemFlags::Asheis_Sketch ); } },
@@ -161,8 +150,7 @@ namespace mod
0xC6770800,
0x47656746,
0x143D,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x25] |= 0x30; /*Auru Cutscene Complete + Auru's Memo gotten*/
},
[]() { return gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.bossBeaten == 0b1; } },
@@ -176,8 +164,7 @@ namespace mod
0xC6502A32,
0xC6348FA6,
0x86E6,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x29] |= 0x40; /*Got Ashei's Sketch from Ashei*/
},
[]() { return true; } },
@@ -191,8 +178,7 @@ namespace mod
0x0,
0x43D5A60B,
0xC1FD,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0xF] |= 0x80; /*Got Renardo's Letter from Renardo*/
},
[]() { return gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.bossBeaten == 0b1; } },
@@ -206,8 +192,7 @@ namespace mod
0xC48FC000,
0x453BED7D,
0x0000,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x21] |= 0x80; /*Got Invoice from Telma*/
},
[]() { return tools::checkItemFlag( ItemFlags::Renardos_Letter ); } },
@@ -221,23 +206,10 @@ namespace mod
0xC5C3E9D7,
0x46F956C6,
0x7FE1,
- []()
- {
- gameInfo.scratchPad.eventBits[0x22] |= 0x80; /*Got Wooden Statue from wolves*/
+ []() {
+ gameInfo.scratchPad.eventBits[0x22] |= 0x4; /*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 true; } },
+ []() { return ( ( gameInfo.scratchPad.eventBits[0x2F] & 0x4 ) != 0 ); } },
/*Horse Call*/
{ "R_SP109",
0,
@@ -248,9 +220,8 @@ namespace mod
0x0,
0xC31EEBF3,
0xBDBE,
- []()
- {
- gameInfo.scratchPad.eventBits[0x23] |= 0x20; /*Got horse call from Illia*/
+ []() {
+ gameInfo.scratchPad.eventBits[0x23] |= 0x20; /*Got horse call from Ilia*/
},
[]() { return tools::checkItemFlag( ItemFlags::Ilias_Charm ); } },
/*Fishing Hole Bottle*/
@@ -263,8 +234,7 @@ namespace mod
0x420C0000,
0x450F716A,
0x62E5,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x39] |= 0x8; /*Got fishing hole bottle*/
},
[]() { return true; } },
@@ -278,27 +248,11 @@ namespace mod
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,
@@ -309,8 +263,7 @@ namespace mod
0x43820000,
0xC572F680,
0x0000,
- []()
- {
+ []() {
gameInfo.localAreaNodes.unk_0[0x4] |= 0x80; /*get camp key*/
},
[]() { return true; } },
@@ -324,8 +277,7 @@ namespace mod
0xC2960000,
0x45229AEB,
0xC3C9,
- []()
- {
+ []() {
gameInfo.localAreaNodes.unk_0[0x8] |= 0x80; /*killed poe*/
gameInfo.localAreaNodes.unk_0[0xF] |= 0x7; /*cs + open path to sewers*/
gameInfo.localAreaNodes.unk_0[0x17] |= 0x8; /*Gengle Free*/
@@ -341,8 +293,7 @@ namespace mod
0x44CB2000,
0xC5964574,
0x0000,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x10] |= 0x20; /*got master sword cs*/
},
[]() { return true; } },
@@ -356,8 +307,7 @@ namespace mod
0x44CB2000,
0xC5991A55,
0x0000,
- []()
- {
+ []() {
gameInfo.scratchPad.eventBits[0x10] |= 0x20; /*got master sword cs*/
},
[]() { return true; } },
@@ -373,22 +323,6 @@ namespace mod
0x3CF0,
nullptr,
[]() { return tools::checkItemFlag( ItemFlags::Ancient_Sky_Book_empty ); } },
- /*Light Master Sword*/
- { "F_SP125",
- 4,
- 1,
- 0x74,
- 0x49,
- 0x44E0DBF7,
- 0x45898B09,
- 0xC6A4AAFA,
- 0x7DBC,
- nullptr,
- []()
- {
- return ( ( gameInfo.scratchPad.eventBits[0x26] & 0x40 ) != 0 ) &&
- ( gameInfo.scratchPad.eventBits[0x26] & 0x20 ) != 0; /*both sols outside of Palace*/
- } },
/*Ending Blow*/
{ "F_SP108",
6,
@@ -411,12 +345,10 @@ namespace mod
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*/
@@ -429,12 +361,10 @@ namespace mod
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*/
@@ -447,12 +377,10 @@ namespace mod
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*/
@@ -465,12 +393,10 @@ namespace mod
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*/
@@ -483,12 +409,10 @@ namespace mod
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*/
@@ -501,76 +425,23 @@ namespace mod
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,
- []()
- {
- gameInfo.scratchPad.eventBits[0x22] |= 0x20; /*Got Ilia's scent*/
- gameInfo.localAreaNodes.unk_0[0x16] |= 0x20; /*Midna text after getting Ilia's scent*/
- gameInfo.localAreaNodes.unk_0[0x17] |= 0x80; /*got Ilia's scent cs*/
- },
- []() { return true; } },
- /*Poe Scent*/
- { "D_MN10", 0xFF, 0, 0x3C, 0xB2, 0xC1571A39, 0xC1200000, 0x4355109A, 0x0000, nullptr, []() { return true; } },
- /*Reekfish Scent*/
- { "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,
+ 0xBA,
0x447AF8E0,
0x00000000,
0xC42C93A9,
0xFEED,
- []()
- {
+ []() {
gameInfo.localAreaNodes.unk_0[0xA] |= 0x10; /*got map from Yeta*/
gameInfo.scratchPad.eventBits[0xB] |= 0x20; /*Talked to Yeta in SPR first time*/
gameInfo.localAreaNodes.unk_0[0x10] |= 0x20; /*Yeta lets you open kitchen door*/
diff --git a/include/customMessage.h b/include/customMessage.h
new file mode 100644
index 0000000..8c41358
--- /dev/null
+++ b/include/customMessage.h
@@ -0,0 +1,590 @@
+#pragma once
+
+#include <tp/resource.h>
+
+#include "defines.h"
+
+namespace mod::customMessage
+{
+ MSG_BEGIN( customForestSKText )
+ MSG_SPEED( MSG_SPEED_FAST )
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_GREEN)
+ "Forest Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customMinesSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_RED)
+ "Goron Mines"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customLakebedSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_BLUE)
+ "Lakebed Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customArbitersSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_ORANGE)
+ "Arbiter's Grounds"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customSnowpeakSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_LIGHT_BLUE)
+ "Snowpeak Ruins"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customToTSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_DARK_GREEN)
+ "Temple of Time"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCitySKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_YELLOW)
+ "City in The Sky"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customPalaceSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_PURPLE)
+ "Palace of Twilight"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCastleSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_SILVER)
+ "Hyrule Castle"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customBublinSKText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "small key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_ORANGE)
+ "Bulblin Camp"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCrystalText)
+ MSG_SPEED(MSG_SPEED_SLOW)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Shadow Crystal"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nThis is a dark manifestation\nof "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Zant's "
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "power that allows\nyou to transform at will!\nHold "
+ MSG_ICON(MSG_ICON_R)
+ MSG_COLOR(MSG_COLOR_WHITE)
+ " then "
+ MSG_ICON(MSG_ICON_Y)
+ MSG_COLOR(MSG_COLOR_WHITE)
+ " at the same\ntime to quickly transform.\nWhile talking to "
+ MSG_COLOR(MSG_COLOR_LIGHT_BLUE)
+ "Midna"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ ", hold\n"
+ MSG_ICON(MSG_ICON_R)
+ MSG_COLOR(MSG_COLOR_WHITE)
+ " then "
+ MSG_ICON(MSG_ICON_Y)
+ MSG_COLOR(MSG_COLOR_WHITE)
+ " to change time."
+ MSG_END()
+
+ MSG_BEGIN(customForestMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_GREEN)
+ "Forest Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customMinesMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_RED)
+ "Goron Mines"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customLakebedMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_BLUE)
+ "Lakebed Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customArbitersMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_ORANGE)
+ "Arbiter's Grounds"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customSnowpeakMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_LIGHT_BLUE)
+ "Snowpeak Ruins"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customToTMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_DARK_GREEN)
+ "Temple of Time"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCityMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_YELLOW)
+ "City in The Sky"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customPalaceMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_PURPLE)
+ "Palace of Twilight"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCastleMapText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "dungeon map"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_SILVER)
+ "Hyrule Castle"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customForestCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_GREEN)
+ "Forest Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customMinesCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_RED)
+ "Goron Mines"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customLakebedCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_BLUE)
+ "Lakebed Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customArbitersCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_ORANGE)
+ "Arbiter's Grounds"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customSnowpeakCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_LIGHT_BLUE)
+ "Snowpeak Ruins"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customToTCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_DARK_GREEN)
+ "Temple of Time"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCityCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_YELLOW)
+ "City in The Sky"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customPalaceCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_PURPLE)
+ "Palace of Twilight"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCastleCompassText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "compass"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_SILVER)
+ "Hyrule Castle"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customForestBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_GREEN)
+ "Forest Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customMinesBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_RED)
+ "Goron Mines"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customLakebedBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_BLUE)
+ "Lakebed Temple"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customArbitersBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_ORANGE)
+ "Arbiter's Grounds"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customSnowpeakBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(MSG_COLOR_LIGHT_BLUE)
+ "Snowpeak Ruins"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customToTBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_DARK_GREEN)
+ "Temple of Time"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCityBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_YELLOW)
+ "City in The Sky"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customPalaceBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in the\n"
+ MSG_COLOR(MSG_COLOR_PURPLE)
+ "Palace of Twilight"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(customCastleBigKeyText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got a "
+ MSG_COLOR(MSG_COLOR_RED)
+ "big key"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!\nIt can be used in\n"
+ MSG_COLOR(CUSTOM_MSG_COLOR_SILVER)
+ "Hyrule Castle"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "."
+ MSG_END()
+
+ MSG_BEGIN(endingBlowText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Ending Blow"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(shieldAttackText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Shield Attack"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(backSliceText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Back Slice"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(helmSplitterText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Helm Splitter"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(mortalDrawText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Mortal Draw"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(jumpStrikeText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Jump Strike"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(greatSpinText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "You got the "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Great Spin"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "!"
+ MSG_END()
+
+ MSG_BEGIN(customPoweredRodText)
+ MSG_SPEED(MSG_SPEED_FAST)
+ "Power has been restored to\nthe "
+ MSG_COLOR(MSG_COLOR_RED)
+ "Dominion Rod"
+ MSG_COLOR(MSG_COLOR_WHITE)
+ "! Now it can\nbe used to imbude statues\nwith life in the present!"
+ MSG_END()
+} // namespace mod::customMessage \ No newline at end of file
diff --git a/include/defines.h b/include/defines.h
index a49f786..a4a46b5 100644
--- a/include/defines.h
+++ b/include/defines.h
@@ -35,7 +35,7 @@ union typeTransform
// Mnemonics
#define AUTHOR "ZTPR"
-#define VERSION "v0.17.0b"
+#define VERSION "v0.20b"
#define RAND_SEED mod::tools::randomSeed
#define gameInfo tp::d_com_inf_game::dComIfG_gameInfo
#define getPlayerPos tp::d_map_path_dmap::getMapPlayerPos
diff --git a/include/game_patches.h b/include/game_patches.h
index 66b86bb..25ba0f9 100644
--- a/include/game_patches.h
+++ b/include/game_patches.h
@@ -1,6 +1,7 @@
#pragma once
#include <tp/d_com_inf_game.h>
+#include <tp/d_stage.h>
#include "defines.h"
@@ -151,11 +152,6 @@ namespace mod::game_patch
void checkBossKeysey();
/**
- * 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();
@@ -175,8 +171,6 @@ namespace mod::game_patch
*/
void skipMDHCS();
- void fixFTBossMusic();
-
/**
* won't allow you to leave the forest if Faron escape is disabled until you beat Diababa
*/
@@ -194,32 +188,10 @@ namespace mod::game_patch
void breakBarrier();
- /**
- * unset the story flag and boss flag when re-entering a dungeon
- */
- void fixFTState();
- void fixGMState();
- void fixLBTState();
- void fixAGState();
- void fixSPRState();
- void fixToTState();
- void fixCiTSState();
-
- /**
- * reset the flags for a dungeon if it has been beaten or if a skip is active
- */
- void setFTDungeonFlag();
- void setFTBossFlag();
- void setGMDungeonFlag();
- void setGMBossFlag();
- void setLakeDungeonFlags();
- void setLBTBossFlag();
- void setAGDungeonFlag();
- void setAGBossFlag();
- void setSPRDungeonFlag();
- void setSPRBossFlag();
- void setToTDungeonFlag();
- void setToTBossFlag();
- void setCiTSDungeonFlag();
- void setCiTSBossFlag();
+ void setCustomItemData();
+
+ void setCustomItemFunctions();
+
+ extern u16 dungeonStoryFlags[8];
+
} // namespace mod::game_patch \ No newline at end of file
diff --git a/include/gc/bmgres.h b/include/gc/bmgres.h
new file mode 100644
index 0000000..fe1d240
--- /dev/null
+++ b/include/gc/bmgres.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "defines.h"
+
+namespace gc::bmgres
+{
+ struct FileHeader
+ {
+ u8 misc[0x100]; // Very start of the file; Should define at some point
+ } __attribute__((__packed__));
+
+ struct BMGHeader
+ {
+ char signature[4];
+ char identifier[4];
+ u32 dataSize;
+ u32 numBlocks;
+ u8 charset;
+ u8 unk_11;
+ u16 unk_12;
+ s32 unk_14[2];
+ s32 unk_1c;
+ } __attribute__((__packed__));
+
+ struct MessageEntry
+ {
+ u32 offsetToMessage;
+ u16 messageId;
+ u8 unk[0xE];
+ } __attribute__((__packed__));
+
+ struct TextIndexTable
+ {
+ char kind[4]; // Should be INF1 in ASCII
+ u32 size;
+ u16 numEntries;
+ u16 entrySize;
+ u16 groupId;
+ u8 defaultColor;
+ u8 unk;
+ MessageEntry entry[]; // Amount of entries is numEntries
+ } __attribute__((__packed__));
+
+ static_assert(sizeof(FileHeader) == 0x100);
+ static_assert(sizeof(BMGHeader) == 0x20);
+ static_assert(sizeof(MessageEntry) == 0x14);
+}
diff --git a/include/item.h b/include/item.h
index 03594fe..e8b96a1 100644
--- a/include/item.h
+++ b/include/item.h
@@ -77,9 +77,22 @@ namespace mod::item
ItemCheck* destination;
};
+ enum class NodeDungeonItemType : u8
+ {
+ Small_Key,
+ Dungeon_Map,
+ Compass,
+ Big_Key
+ };
+
/**
* Contains the values for the flags to be set to skip the animations of first getting specific items
*/
extern u8 itemGetAnimationFlags[10];
- extern u8 itemsWithNoFieldModel[2];
+
+ extern u8 customSmallKeyItemIDs[10];
+ extern u8 customBigKeyItemIDs[7];
+ extern u8 customDungeonMapItemIDs[9];
+ extern u8 customCompassItemIDs[9];
+ extern u8 customHiddenSkillItemIDs[7];
} // namespace mod::item \ No newline at end of file
diff --git a/include/itemChecks.h b/include/itemChecks.h
index 93c9a56..d911063 100644
--- a/include/itemChecks.h
+++ b/include/itemChecks.h
@@ -5,6 +5,6 @@
namespace mod::item
{
- extern ItemCheck checks[505];
+ extern ItemCheck checks[503];
extern u16 checkPriorityOrder[24];
} // namespace mod::item \ No newline at end of file
diff --git a/include/items.h b/include/items.h
index d16bd13..15500d1 100644
--- a/include/items.h
+++ b/include/items.h
@@ -14,8 +14,8 @@ namespace mod::items
Purple_Rupee = 0x05,
Orange_Rupee = 0x06,
Silver_Rupee = 0x07,
- /*Borrow_Bomb_Bag? = 0x08,*/
- /*Bomb_Bag_And_Bombs? = 0x09,*/
+ /*Small Magic = 0x08,*/
+ /*Large Magic = 0x09,*/
Bombs_5 = 0x0A,
Bombs_10 = 0x0B,
Bombs_20 = 0x0C,
@@ -56,9 +56,9 @@ namespace mod::items
Heros_Clothes = 0x2F,
Magic_Armor = 0x30,
Zora_Armor = 0x31,
- /*does notting*/ Shadow_Crystal = 0x32,
+ Shadow_Crystal = 0x32, // Does nothing in Vanilla. Is used to handle the transformation flag in the Randomizer.
Ooccoo_Dungeon = 0x33,
- /*unused*/ Small_Wallet = 0x34,
+ Small_Wallet = 0x34, // Unused
Big_Wallet = 0x35,
Giant_Wallet = 0x36,
/*Piece_of_Heart_2? = 0x37,*/
@@ -90,7 +90,7 @@ namespace mod::items
Goron_Bomb_Bag = 0x51,
/*Giant_Bomb_Bag? = 0x52,*/
/*? = 0x53,*/
- /*unused*/ Small_Quiver = 0x54,
+ Small_Quiver = 0x54, // Unused
Big_Quiver = 0x55,
Giant_Quiver = 0x56,
/*? = 0x57,*/
@@ -139,29 +139,29 @@ namespace mod::items
Wooden_Statue = 0x82,
Ilias_Charm = 0x83,
Horse_Call = 0x84,
- /*? = 0x85,*/
- /*? = 0x86,*/
- /*? = 0x87,*/
- /*? = 0x88,*/
- /*? = 0x89,*/
- /*? = 0x8A,*/
- /*? = 0x8B,*/
- /*? = 0x8C,*/
- /*? = 0x8D,*/
- /*? = 0x8E,*/
- /*? = 0x8F,*/
+ Forest_Temple_Small_Key = 0x85, // Custom Item added for the Randomizer.
+ Goron_Mines_Small_Key = 0x86, // Custom Item added for the Randomizer.
+ Lakebed_Temple_Small_Key = 0x87, // Custom Item added for the Randomizer.
+ Arbiters_Grounds_Small_Key = 0x88, // Custom Item added for the Randomizer.
+ Snowpeak_Ruins_Small_Key = 0x89, // Custom Item added for the Randomizer.
+ Temple_of_Time_Small_Key = 0x8A, // Custom Item added for the Randomizer.
+ City_in_The_Sky_Small_Key = 0x8B, // Custom Item added for the Randomizer.
+ Palace_of_Twilight_Small_Key = 0x8C, // Custom Item added for the Randomizer.
+ Hyrule_Castle_Small_Key = 0x8D, // Custom Item added for the Randomizer.
+ Bublin_Camp_Key = 0x8E, // Custom Item added for the Randomizer.
+ Foolish_Item = 0x8F, // Custom Item added for the Randomizer.
Aurus_Memo = 0x90,
Asheis_Sketch = 0x91,
- /*? = 0x92,*/
- /*? = 0x93,*/
- /*? = 0x94,*/
- /*? = 0x95,*/
- /*? = 0x96,*/
- /*? = 0x97,*/
- /*? = 0x98,*/
- /*? = 0x99,*/
- /*? = 0x9A,*/
- /*? = 0x9B,*/
+ Forest_Temple_Big_Key = 0x92, // Custom Item added for the Randomizer.
+ Lakebed_Temple_Big_Key = 0x93, // Custom Item added for the Randomizer.
+ Arbiters_Grounds_Big_Key = 0x94, // Custom Item added for the Randomizer.
+ Temple_of_Time_Big_Key = 0x95, // Custom Item added for the Randomizer.
+ City_in_The_Sky_Big_Key = 0x96, // Custom Item added for the Randomizer.
+ Palace_of_Twilight_Big_Key = 0x97, // Custom Item added for the Randomizer.
+ Hyrule_Castle_Big_Key = 0x98, // Custom Item added for the Randomizer.
+ Forest_Temple_Compass = 0x99, // Custom Item added for the Randomizer.
+ Goron_Mines_Compass = 0x9A, // Custom Item added for the Randomizer.
+ Lakebed_Temple_Compass = 0x9B, // Custom Item added for the Randomizer.
Lantern_Yellow_Chu_Chu = 0x9C,
Coro_Bottle = 0x9D,
Bee_Larva_Shop = 0x9E,
@@ -171,15 +171,15 @@ namespace mod::items
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,*/
+ /*unused*/ Mirror_Piece_2 = 0xA5,
+ /*unused*/ Mirror_Piece_3 = 0xA6,
+ /*unused*/ Mirror_Piece_4 = 0xA7,
+ Arbiters_Grounds_Compass = 0xA8, // Custom Item added for the Randomizer.
+ Snowpeak_Ruins_Compass = 0xA9, // Custom Item added for the Randomizer.
+ Temple_of_Time_Compass = 0xAA, // Custom Item added for the Randomizer.
+ City_in_The_Sky_Compass = 0xAB, // Custom Item added for the Randomizer.
+ Palace_of_Twilight_Compass = 0xAC, // Custom Item added for the Randomizer.
+ Hyrule_Castle_Compass = 0xAD, // Custom Item added for the Randomizer.
/*? = 0xAE,*/
/*? = 0xAF,*/
Ilias_Scent = 0xB0,
@@ -188,15 +188,15 @@ namespace mod::items
Reekfish_Scent = 0xB3,
Youths_Scent = 0xB4,
Medicine_Scent = 0xB5,
- /*? = 0xB6,*/
- /*? = 0xB7,*/
- /*? = 0xB8,*/
- /*? = 0xB9,*/
- /*? = 0xBA,*/
- /*? = 0xBB,*/
- /*? = 0xBC,*/
- /*? = 0xBD,*/
- /*? = 0xBE,*/
+ Forest_Temple_Dungeon_Map = 0xB6, // Custom Item added for the Randomizer.
+ Goron_Mines_Dungeon_Map = 0xB7, // Custom Item added for the Randomizer.
+ Lakebed_Temple_Dungeon_Map = 0xB8, // Custom Item added for the Randomizer.
+ Arbiters_Grounds_Dungeon_Map = 0xB9, // Custom Item added for the Randomizer.
+ Snowpeak_Ruins_Dungeon_Map = 0xBA, // Custom Item added for the Randomizer.
+ Temple_of_Time_Dungeon_Map = 0xBB, // Custom Item added for the Randomizer.
+ City_in_The_Sky_Dungeon_Map = 0xBC, // Custom Item added for the Randomizer.
+ Palace_of_Twilight_Dungeon_Map = 0xBD, // Custom Item added for the Randomizer.
+ Hyrule_Castle_Dungeon_Map = 0xBE, // Custom Item added for the Randomizer.
/*Bottle_Insides? = 0xBF,*/
Male_Beetle = 0xC0,
Female_Beetle = 0xC1,
@@ -231,13 +231,13 @@ namespace mod::items
/*? = 0xDE,*/
/*? = 0xDF,*/
Poe_Soul = 0xE0,
- /*? = 0xE1,*/
- /*? = 0xE2,*/
- /*? = 0xE3,*/
- /*? = 0xE4,*/
- /*? = 0xE5,*/
- /*? = 0xE6,*/
- /*? = 0xE7,*/
+ Ending_Blow = 0xE1, // Custom Item added for the Randomizer.
+ Shield_Attack = 0xE2, // Custom Item added for the Randomizer.
+ Back_Slice = 0xE3, // Custom Item added for the Randomizer.
+ Helm_Splitter = 0xE4, // Custom Item added for the Randomizer.
+ Mortal_Draw = 0xE5, // Custom Item added for the Randomizer.
+ Jump_Strike = 0xE6, // Custom Item added for the Randomizer.
+ Great_Spin = 0xE7, // Custom Item added for the Randomizer.
/*? = 0xE8,*/
Ancient_Sky_Book_empty = 0xE9,
Ancient_Sky_Book_partly_filled = 0xEA,
diff --git a/include/mod.h b/include/mod.h
index b335856..d76f63c 100644
--- a/include/mod.h
+++ b/include/mod.h
@@ -1,6 +1,7 @@
#pragma once
#include <tp/DynamicLink.h>
+#include <tp/control.h>
#include <tp/d_com_inf_game.h>
#include <tp/dzx.h>
@@ -113,8 +114,6 @@ namespace mod
u8 greenBottom = 0;
u8 blueBottom = 0;
- u8 bottle4Contents;
- u8 bottleTrickOn = 0;
u8 allowBottleItemsShopAnytime = 1;
u8 shieldTrickOn = 0;
u8 hadHShield;
@@ -131,9 +130,6 @@ namespace mod
u8 yetaTrickOn = 0;
- u8 LBTBossDoorTrickOn = 0;
- u8 nbLBTKeys = 0;
-
u8 eventFlagToEdit = 0;
u8 newValueForEventFlag = 0;
u8 triggerEventFlagEdit = 0;
@@ -164,6 +160,14 @@ namespace mod
bool proc_query022( void* unk1, void* unk2, s32 unk3 );
+ bool proc_query023( void* unk1, void* unk2, s32 unk3 );
+
+ bool proc_query024( void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused );
+
+ bool proc_query025( void* unk1, void* unk2, s32 unk3 );
+
+ bool proc_isDungeonItem( void* memBitPtr, const int param_1 );
+
bool procDoLink( tp::dynamic_link::DynamicModuleControl* dmc );
void procItem_func_UTUWA_HEART();
@@ -172,6 +176,18 @@ namespace mod
bool canChangeToD();
+ s32 getMsgIndex( const void* TProcessor, u16 unk2, u32 msgId );
+
+ s32 getItemMsgIndex( const void* TProcessor, u16 unk2, u32 itemId );
+
+ s32 getItemIdFromMsgId( const void* TProcessor, u16 unk3, u32 msgId );
+
+ u32 getCustomMsgColor( u8 colorId );
+
+ s32 proc_checkItemGet( u8 item, s32 defaultValue );
+
+ bool proc_isEventBit( u8* eventSystem, u16 indexNumber );
+
/**
* gives the unlocked scent that can be seen in the current area (defaults to most advanced one obtained)
*/
@@ -189,11 +205,6 @@ namespace mod
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();
@@ -204,12 +215,6 @@ namespace mod
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();
@@ -221,12 +226,6 @@ namespace mod
void changeLanternColor();
- void fixFTTotemMonkey();
-
- // void setFieldModels();
-
- // bool procActorCommonLayerInit(void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, s32 unk3,
- // void* unk4);
// Private members
// private:
@@ -237,9 +236,15 @@ namespace mod
s32 ( *evt_control_Skipper_trampoline )( void* eventPtr ) = nullptr;
bool ( *query022_trampoline )( void* unk1, void* unk2, s32 unk3 ) = nullptr;
-
- // Used in MsgFlow "Can buy arrows?" checks
- bool (*query024_trampoline)(void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused) = nullptr;
+
+ bool ( *query023_trampoline )( void* unk1, void* unk2, s32 unk3 ) = nullptr;
+
+ bool ( *query024_trampoline )( void* dMsgFlow_cPtr,
+ void* mesg_flow_node_branchPtr,
+ void* fopAc_ac_cPtr,
+ int unused ) = nullptr;
+
+ bool ( *query025_trampoline )( void* unk1, void* unk2, s32 unk3 ) = nullptr;
bool ( *do_link_trampoline )( tp::dynamic_link::DynamicModuleControl* dmc ) = nullptr;
@@ -252,6 +257,11 @@ namespace mod
int unk3,
void* unk4 ) = nullptr;
+ bool ( *actorInit_always_trampoline )( void* mStatus_roomControl,
+ tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo,
+ int unk3,
+ void* unk4 ) = nullptr;
+
void ( *putSave_trampoline )( tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID ) = nullptr;
// Item functions
@@ -306,5 +316,27 @@ namespace mod
s32 unk7 ) = nullptr;
void ( *setItemBombNumCount_trampoline )( u32 unk1, u8 bagNb, short amount ) = nullptr;
+
+ bool ( *isDungeonItem_trampoline )( void* memBitPtr, int param_1 ) = nullptr;
+
+ int ( *getLayerNo_common_common_trampoline )( const char* stageName, int roomId, int layerOverride ) = nullptr;
+
+ bool ( *setMessageCode_inSequence_trampoline )( tp::control::TControl* control,
+ const void* TProcessor,
+ u16 unk3,
+ u16 msgId ) = nullptr;
+
+ u32 ( *getFontCCColorTable_trampoline )( u8 colorId, u8 unk ) = nullptr;
+ u32 ( *getFontGCColorTable_trampoline )( u8 colorId, u8 unk ) = nullptr;
+
+ s32 ( *checkItemGet_trampoline )( u8 item, s32 defaultValue ) = nullptr;
+
+ char ( *parseCharacter1Byte_trampoline )( const char** text ) = nullptr;
+
+ bool ( *isEventBit_trampoline )( u8* eventSystem, u16 indexNumber ) = nullptr;
+
+ void ( *onEventBit_trampoline )( u8* eventSystem, u16 indexNumber ) = nullptr;
+
+ void ( *setGetItemFace_trampoline )( void* daAlink_c, u16 itemId ) = nullptr;
};
-} // namespace mod
+} // namespace mod \ No newline at end of file
diff --git a/include/musicRando.h b/include/musicRando.h
index 9595b4a..81b2cf7 100644
--- a/include/musicRando.h
+++ b/include/musicRando.h
@@ -4,6 +4,7 @@
namespace mod::musicrando
{
extern u8 musicRandoEnabled;
- extern u8 enemyBgmEnabled;
+ extern u8 enemyBgmDisabled;
+ extern u8 fanfareRandoEnabled;
void initMusicRando();
} // namespace mod::musicrando \ No newline at end of file
diff --git a/include/singleton.h b/include/singleton.h
index 43e2e30..f63fb8f 100644
--- a/include/singleton.h
+++ b/include/singleton.h
@@ -34,15 +34,8 @@ namespace mod
u8 isGMStoryPatch;
u8 isEarlyHCEnabled;
u8 startWithCrystal;
+ u8 shuffleHiddenSkills;
- // dungeon flags
- u8 hasFTBeenBeaten;
- u8 hasGMBeenBeaten;
- u8 hasLBTBeenBeaten;
- u8 hasAGBeenBeaten;
- u8 hasSPRBeenBeaten;
- u8 hasToTBeenBeaten;
- u8 hasCiTSBeenBeaten;
u8 hasCiTSOoccoo;
private:
diff --git a/include/stage.h b/include/stage.h
index 4aa0c05..04f974b 100644
--- a/include/stage.h
+++ b/include/stage.h
@@ -13,4 +13,6 @@ namespace mod::stage
extern const char* interiorStages[8];
extern const char* specialStages[3];
extern const char* timeOfDayStages[18];
+ extern const char* mainDungeonStages[9];
+ extern const char* allDungeonStages[26];
} // namespace mod::stage \ No newline at end of file
diff --git a/include/tp.eu.lst b/include/tp.eu.lst
index 6e536b9..753a7dc 100644
--- a/include/tp.eu.lst
+++ b/include/tp.eu.lst
@@ -12,10 +12,15 @@
80032B50:getRupeeMax
800351EC:getSave
80035220:putSave
+80034aec:isEventBit
+80034abc:onEventBit
+80034a64:isDungeonItem
/ d_stage.o
80025914:actorCommonLayerInit
80025AE0:actorInit
+80025bcc:actorInit_always
+
// data
803F8034:mStatus_roomControl
@@ -48,6 +53,9 @@
80097FBC:execItemGet
80098010:checkItemGet
800983E4:item_func_UTUWA_HEART
+803b0a58:item_info
+803b0e58:item_func_ptr
+803ae280:item_resource
// d_a_alink.h
8009DC6C:checkStageName
@@ -63,6 +71,8 @@
800CF490:checkHorseRide
800CF4D4:checkSpinnerRide
800CF4C0:checkBoarRide
+8039325C:getSeType
+801183ac:setGetItemFace
// data
8039038C:ladderVars
@@ -71,7 +81,9 @@
// d_msg_flow.o
8024BF88:query022
-8024BFF8:query024
+8024bfbc:query023
+8024bff8:query024
+8024c018:query025
// DynamicLink.o
80263A5C:do_link
@@ -151,6 +163,8 @@
803697C4:strcmp
8036995C:strcpy
80369918:strncpy
+80369784:strncmp
+80369a14:strlen
//currentState
803A8393:current_state
@@ -163,6 +177,9 @@
// data
80408160:dComIfG_gameInfo
8002B414:setItemBombNumCount
+8002f8b8:dComIfGs_Wolf_Change_Check
+801415a8:dComIfGs_isEventBit
+8002b4dc:getLayerNo_common_common
// d_kankyo.o
// data
@@ -187,3 +204,17 @@
//Z2SeqMgr
802B5CB0:startBattleBgm
802B029C:subBgmStart
+802AACE8:startSound
+
+//control.o
+802a8820:setMessageCode_inSequence
+
+//d_msg_class.o
+80228bc0:getFontCCColorTable
+80228c6c:getFontGCColorTable
+
+//resource.o
+802aa290:parseCharacter_1Byte
+
+//processor.o
+802a8a54:getResource_groupID \ No newline at end of file
diff --git a/include/tp.jp.lst b/include/tp.jp.lst
index 730d994..ae685f7 100644
--- a/include/tp.jp.lst
+++ b/include/tp.jp.lst
@@ -12,10 +12,14 @@
80032AA8:getRupeeMax
800350BC:getSave
800350F0:putSave
+800349bc:isEventBit
+8003498c:onEventBit
+80034934:isDungeonItem
// d_stage.o
8002586C:actorCommonLayerInit
80025A38:actorInit
+80025b24:actorInit_always
// data
803F01D4:mStatus_roomControl
@@ -48,6 +52,9 @@
80097ECC:execItemGet
80097F20:checkItemGet
800982F4:item_func_UTUWA_HEART
+803a8ed8:item_info
+803a6700:item_resource
+803a92d8:item_func_ptr
// d_a_alink.h
8009DA98:checkStageName
@@ -63,6 +70,9 @@
800CF2bC:checkHorseRide
800CF300:checkSpinnerRide
800CF2EC:checkBoarRide
+8038badC:getSeType
+801413e8:dComIfGs_isEventBit
+801181d8:setGetItemFace
// data
80388C0C:ladderVars
@@ -72,7 +82,9 @@
// d_msg_flow.o
8024D24C:query022
-8024D2BC:query024
+8024d280:query023
+8024d2bc:query024
+8024d2dc:query025
// DynamicLink.o
8026508C:do_link
@@ -152,6 +164,8 @@
8036AE30:strcmp
8036AFC8:strcpy
8036AF84:strncpy
+8036adf0:strncmp
+8036b080:strlen
//currentState
803B8000:current_state
@@ -164,6 +178,8 @@
// data
80400300:dComIfG_gameInfo
8002B36C:setItemBombNumCount
+8002f810:dComIfGs_Wolf_Change_Check
+8002b434:getLayerNo_common_common
// d_kankyo.o
// data
@@ -188,3 +204,17 @@
//Z2SeqMgr
802B72F0:startBattleBgm
802B18DC:subBgmStart
+802AC328:startSound
+
+//control.o
+802a9e60:setMessageCode_inSequence
+
+//d_msg_class.o
+80229048:getFontCCColorTable
+802290f4:getFontGCColorTable
+
+//resource.o
+802ab8d0:parseCharacter_1Byte
+
+//processor.o
+802aa094:getResource_groupID \ No newline at end of file
diff --git a/include/tp.us.lst b/include/tp.us.lst
index 5425902..ac985b9 100644
--- a/include/tp.us.lst
+++ b/include/tp.us.lst
@@ -12,10 +12,15 @@
80032AA8:getRupeeMax
800350BC:getSave
800350F0:putSave
+80034934:isDungeonItem
+800349bc:isEventBit
+8003498c:onEventBit
// d_stage.o
8002586C:actorCommonLayerInit
80025A38:actorInit
+80025b24:actorInit_always
+
// data
803F6094:mStatus_roomControl
@@ -48,6 +53,8 @@
80097E8C:execItemGet
80097EE0:checkItemGet
800982B4:item_func_UTUWA_HEART
+803AF178:item_func_ptr
+803AF578:item_getcheck_func_ptr
// d_a_alink.h
8009DA60:checkStageName
@@ -63,6 +70,9 @@
800cf284:checkHorseRide
800cf2c8:checkSpinnerRide
800cf2b4:checkBoarRide
+8014139c:dComIfGs_isEventBit
+80391A5C:getSeType
+801181a0:setGetItemFace
// data
8038EB8C:ladderVars
@@ -72,7 +82,13 @@
// d_msg_flow.o
8024B8E4:query022
+8024b918:query023
8024B954:query024
+8024b974:query025
+
+// d_msg_class.o
+802288fc:getFontCCColorTable
+802289a8:getFontGCColorTable
// DynamicLink.o
80262C5C:do_link
@@ -152,6 +168,8 @@
80368994:strcmp
80368B2C:strcpy
80368AE8:strncpy
+80368954:strncmp
+80368be4:strlen
//currentState
803A66B3:current_state
@@ -164,6 +182,8 @@
// data
804061C0:dComIfG_gameInfo
8002B36C:setItemBombNumCount
+8002b434:getLayerNo_common_common
+8002f810:dComIfGs_Wolf_Change_Check
// d_kankyo.o
// data
@@ -202,3 +222,13 @@
//Z2SeqMgr
802B4EB0:startBattleBgm
802AF49C:subBgmStart
+802A9EE8:startSound
+
+//processor.o
+802A7C54:getResource_groupID
+
+//control.o
+802A7A20:setMessageCode_inSequence
+
+//resource.o
+802a9490:parseCharacter_1Byte \ No newline at end of file
diff --git a/include/tp/DynamicLink.h b/include/tp/DynamicLink.h
index b56cdd3..e76d5bc 100644
--- a/include/tp/DynamicLink.h
+++ b/include/tp/DynamicLink.h
@@ -20,5 +20,7 @@ namespace tp::dynamic_link
extern "C"
{
bool do_link( DynamicModuleControl* dmc );
+
+#define SET_LOAD_IMMEDIATE( register, value ) ( 0x38000000 + ( register * 0x200000 ) ) | static_cast<int16_t>( value )
}
} // namespace tp::dynamic_link \ No newline at end of file
diff --git a/include/tp/control.h b/include/tp/control.h
new file mode 100644
index 0000000..cd8fe54
--- /dev/null
+++ b/include/tp/control.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <gc/bmgres.h>
+
+#include "defines.h"
+
+namespace tp::control
+{
+ struct TControl
+ {
+ void* unk_0;
+ void* unk_4;
+ void* unk_8;
+ u16 unk_E; // unk3 in setMessageCode_inSequence
+ u16 msgId;
+ void* unk_10;
+ gc::bmgres::MessageEntry* msgEntry;
+ const char* msg;
+ u8 unk_1C[0x4];
+ const char* wMsgRender;
+ u32 unk_24;
+ } __attribute__( ( __packed__ ) );
+
+ extern "C"
+ {
+ bool setMessageCode_inSequence( TControl* control, const void* TProcessor, u16 unk3, u16 msgId );
+ }
+} // namespace tp::control \ No newline at end of file
diff --git a/include/tp/d_a_alink.h b/include/tp/d_a_alink.h
index dbbfa5b..63aa9bb 100644
--- a/include/tp/d_a_alink.h
+++ b/include/tp/d_a_alink.h
@@ -47,6 +47,9 @@ namespace tp::d_a_alink
bool checkHorseRide( tp::d_com_inf_game::LinkMapVars* linkMapPtr );
bool checkBoarRide( tp::d_com_inf_game::LinkMapVars* linkMapPtr );
bool checkSpinnerRide( tp::d_com_inf_game::LinkMapVars* linkMapPtr );
+ bool dComIfGs_isEventBit( u16 flag );
+ void setGetItemFace( void* daAlink_c, u16 itemId );
+ extern u8 getSeType[0x100];
// Variables
extern LadderVars ladderVars;
diff --git a/include/tp/d_com_inf_game.h b/include/tp/d_com_inf_game.h
index dc997fc..70497de 100644
--- a/include/tp/d_com_inf_game.h
+++ b/include/tp/d_com_inf_game.h
@@ -777,6 +777,42 @@ namespace tp::d_com_inf_game
u8 blueBottom;
} __attribute__( ( __packed__ ) );
+ enum class AreaNodesID : u32
+ {
+ Ordon = 0,
+ Sewers,
+ Faron,
+ Eldin,
+ Lanayru,
+ Unk_5,
+ Hyrule_Field,
+ Sacred_Grove,
+ Snowpeak,
+ Castle_Town,
+ Gerudo_Desert,
+ Fishing_Pond,
+ Unk_C,
+ Unk_D,
+ Unk_E,
+ Unk_F,
+ Forest_Temple,
+ Goron_Mines,
+ Lakebed_Temple,
+ Arbiters_Grounds,
+ Snowpeak_Ruins,
+ Temple_of_Time,
+ City_in_the_Sky,
+ Palace_of_Twilight,
+ Hyrule_Castle,
+ Cave_of_Ordeals, // Includes Gorge Cave and Ice Block Cave
+ Lake_Hylia_Cave, // Includes Goron Stockcave
+ Grottos,
+ Unk_1C,
+ Unk_1D,
+ Unk_1E,
+ Unk_1F,
+ };
+
// Should try to fill in the missing variables at some point
struct GameInfo
{
@@ -850,8 +886,10 @@ namespace tp::d_com_inf_game
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 izaBoatSignText[100];
// extern char wallet_description[96];
extern u8 can_warp;
+ int getLayerNo_common_common( const char* stageName, int roomId, int layerOverride );
+
+ void dComIfGs_Wolf_Change_Check();
}
} // namespace tp::d_com_inf_game \ No newline at end of file
diff --git a/include/tp/d_item.h b/include/tp/d_item.h
index d2b16ac..011cb64 100644
--- a/include/tp/d_item.h
+++ b/include/tp/d_item.h
@@ -4,10 +4,15 @@
namespace tp::d_item
{
+ typedef void ( *ItemFunc )();
+ typedef s32 ( *ItemGetCheckFunc )();
+
extern "C"
{
s32 execItemGet( u8 item );
s32 checkItemGet( u8 item, s32 defaultValue );
void item_func_UTUWA_HEART();
+ extern ItemFunc item_func_ptr[0x100];
+ extern ItemGetCheckFunc item_getcheck_func_ptr[0x100];
}
} // namespace tp::d_item \ No newline at end of file
diff --git a/include/tp/d_item_data.h b/include/tp/d_item_data.h
index c18f488..26023d2 100644
--- a/include/tp/d_item_data.h
+++ b/include/tp/d_item_data.h
@@ -8,7 +8,7 @@ namespace tp::d_item_data
{
struct ItemResource // d_item_data.h
{
- char* arcName;
+ const char* arcName;
s16 modelResIdx;
s16 btkResIdx;
s16 bckResIdx;
@@ -16,13 +16,13 @@ namespace tp::d_item_data
s16 btpResIdx;
u8 tevFrm;
u8 btpFrm;
- s16 ringTexResIdx;
+ s16 ringTexResIdx; // The icon displayed next to the text shown when you get an item.
s16 unk_12[3];
} __attribute__( ( __packed__ ) );
struct FieldItemRes // d_item_data.h
{
- char* arcName;
+ const char* arcName;
s16 modelResIdx;
s16 bckAnmResIdx;
s16 brkAnmResIdx;
@@ -45,8 +45,8 @@ namespace tp::d_item_data
extern "C"
{
- extern ItemResource item_resource[255]; // 0x803AC5A0 in US
- extern FieldItemRes field_item_res[255]; // 0x803ADD88 in US
- extern ItemInfo item_info[255]; // 0x803AED78 in US
+ extern ItemResource item_resource[255];
+ extern FieldItemRes field_item_res[255];
+ extern ItemInfo item_info[255];
}
} // namespace tp::d_item_data \ No newline at end of file
diff --git a/include/tp/d_msg_class.h b/include/tp/d_msg_class.h
new file mode 100644
index 0000000..242f153
--- /dev/null
+++ b/include/tp/d_msg_class.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::d_msg_class
+{
+ extern "C"
+ {
+ u32 getFontCCColorTable( u8 colorId, u8 unk );
+ u32 getFontGCColorTable( u8 colorId, u8 unk );
+ }
+} // namespace tp::d_msg_class \ No newline at end of file
diff --git a/include/tp/d_msg_flow.h b/include/tp/d_msg_flow.h
index 079427c..0377a4b 100644
--- a/include/tp/d_msg_flow.h
+++ b/include/tp/d_msg_flow.h
@@ -7,7 +7,8 @@ namespace tp::d_msg_flow
extern "C"
{
bool query022( void* unk1, void* unk2, s32 unk3 );
- // Used in MsgFlow "Can buy arrows?" checks
- bool query024(void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused);
+ bool query023( void* unk1, void* unk2, s32 unk3 );
+ bool query024( void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused );
+ bool query025( void* unk1, void* unk2, s32 unk3 );
}
-} // namespace tp::d_msg_flow
+} // namespace tp::d_msg_flow \ No newline at end of file
diff --git a/include/tp/d_save.h b/include/tp/d_save.h
index c27a25e..e1b4cec 100644
--- a/include/tp/d_save.h
+++ b/include/tp/d_save.h
@@ -11,5 +11,8 @@ namespace tp::d_save
u16 getRupeeMax();
void getSave( tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID );
void putSave( tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID );
+ bool isDungeonItem( void* memBitPtr, const int param_1 );
+ bool isEventBit( u8* eventSystem, u16 indexNumber );
+ void onEventBit( u8* eventSystem, u16 indexNumber );
}
} // namespace tp::d_save \ No newline at end of file
diff --git a/include/tp/d_stage.h b/include/tp/d_stage.h
index 573fbf2..6df0373 100644
--- a/include/tp/d_stage.h
+++ b/include/tp/d_stage.h
@@ -40,5 +40,6 @@ namespace tp::d_stage
*/
bool actorCommonLayerInit( void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4 );
bool actorInit( void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4 );
+ bool actorInit_always( void* mStatus_roomControl, dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4 );
}
} // namespace tp::d_stage \ No newline at end of file
diff --git a/include/tp/processor.h b/include/tp/processor.h
new file mode 100644
index 0000000..bf1233f
--- /dev/null
+++ b/include/tp/processor.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "defines.h"
+
+namespace tp::processor
+{
+ extern "C"
+ {
+ void* getResource_groupID( const void* TProcessor, u16 unk2 );
+ }
+} // namespace tp::processor \ No newline at end of file
diff --git a/include/tp/resource.h b/include/tp/resource.h
index 57d83ea..ba4c818 100644
--- a/include/tp/resource.h
+++ b/include/tp/resource.h
@@ -4,8 +4,50 @@
namespace tp::resource
{
+// Message commands
+#define MSG_BEGIN( name ) const char* name =
+
+#define MSG_END() ;
+
+// Message Speeds
+#define MSG_SPEED( speed ) "\x1A\x05\x00\x00" speed
+
+#define MSG_SPEED_FAST "\x01"
+#define MSG_SPEED_SLOW "\x02"
+
+#define MSG_COLOR( id ) "\x1A\x06\xFF\x00\x00" id
+
+// Message Icons
+#define MSG_ICON( icon ) "\x1A\x05\x00\x00" icon
+
+// Message colors
+#define MSG_COLOR_WHITE "\x00"
+#define MSG_COLOR_RED "\x01"
+#define MSG_COLOR_GREEN "\x02"
+#define MSG_COLOR_LIGHT_BLUE "\x03"
+#define MSG_COLOR_YELLOW "\x04"
+#define MSG_COLOR_PURPLE "\x06"
+#define MSG_COLOR_ORANGE "\x08"
+
+// Custom message colors
+#define CUSTOM_MSG_COLOR_DARK_GREEN "\x09"
+#define CUSTOM_MSG_COLOR_BLUE "\x0A"
+#define CUSTOM_MSG_COLOR_SILVER "\x0B"
+
+// Standard hex values for custom message colors
+// Needed for the getFontCCColorTable and getFontGCColorTable hooks
+#define CUSTOM_MSG_COLOR_DARK_GREEN_HEX 0x9
+#define CUSTOM_MSG_COLOR_BLUE_HEX 0xA
+#define CUSTOM_MSG_COLOR_SILVER_HEX 0xB
+
+// Message Icon Values
+#define MSG_ICON_R "\x0E"
+#define MSG_ICON_A "\x0A"
+#define MSG_ICON_X "\x0F"
+#define MSG_ICON_Y "\x10"
+
extern "C"
{
- extern void* parseCharacter_1Byte( const char** text );
+ char parseCharacter_1Byte( const char** text );
}
} // namespace tp::resource \ No newline at end of file
diff --git a/source/chestRando.cpp b/source/chestRando.cpp
index 2fa8fcf..a8bca7e 100644
--- a/source/chestRando.cpp
+++ b/source/chestRando.cpp
@@ -12,12 +12,12 @@
#include "array.h"
#include "defines.h"
-#include "game_patches.h"
#include "grottoChecks.h"
#include "item.h"
#include "itemChecks.h"
#include "items.h"
#include "keyPlacement.h"
+#include "musicRando.h"
#include "singleton.h"
#include "stage.h"
#include "tools.h"
@@ -387,7 +387,10 @@ namespace mod
break;
case item::ItemType::Skill:
- result = true;
+ if ( Singleton::getInstance()->shuffleHiddenSkills == 0x0 )
+ {
+ result = true;
+ }
break;
case item::ItemType::Scent:
@@ -397,22 +400,12 @@ namespace mod
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 )
+ if ( Singleton::getInstance()->shuffledSkybook == 0 )
{
result = true;
}
@@ -620,6 +613,164 @@ namespace mod
gameInfo.localAreaNodes.unk_0[0x10] |= 0x20;
}
+ else if ( item == items::Small_Key )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Forest_Temple] ) )
+ {
+ item = items::Forest_Temple_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Goron_Mines] ) )
+ {
+ item = items::Goron_Mines_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Lakebed_Temple] ) )
+ {
+ item = items::Lakebed_Temple_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Arbiters_Grounds] ) )
+ {
+ item = items::Arbiters_Grounds_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Snowpeak_Ruins] ) )
+ {
+ item = items::Snowpeak_Ruins_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Temple_of_Time] ) )
+ {
+ item = items::Temple_of_Time_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_City_in_the_Sky] ) )
+ {
+ item = items::City_in_The_Sky_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Palace_of_Twilight] ) )
+ {
+ item = items::Palace_of_Twilight_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Hyrule_Castle] ) )
+ {
+ item = items::Hyrule_Castle_Small_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Bublin_Camp] ) )
+ {
+ item = items::Bublin_Camp_Key;
+ }
+ }
+ else if ( item == items::Compass )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Forest_Temple] ) )
+ {
+ item = items::Forest_Temple_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Goron_Mines] ) )
+ {
+ item = items::Goron_Mines_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Lakebed_Temple] ) )
+ {
+ item = items::Lakebed_Temple_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Arbiters_Grounds] ) )
+ {
+ item = items::Arbiters_Grounds_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Snowpeak_Ruins] ) )
+ {
+ item = items::Snowpeak_Ruins_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Temple_of_Time] ) )
+ {
+ item = items::Temple_of_Time_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_City_in_the_Sky] ) )
+ {
+ item = items::City_in_The_Sky_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Palace_of_Twilight] ) )
+ {
+ item = items::Palace_of_Twilight_Compass;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Hyrule_Castle] ) )
+ {
+ item = items::Hyrule_Castle_Compass;
+ }
+ }
+ else if ( item == items::Dungeon_Map )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Forest_Temple] ) )
+ {
+ item = items::Forest_Temple_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Goron_Mines] ) )
+ {
+ item = items::Goron_Mines_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Lakebed_Temple] ) )
+ {
+ item = items::Lakebed_Temple_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Arbiters_Grounds] ) )
+ {
+ item = items::Arbiters_Grounds_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Snowpeak_Ruins] ) )
+ {
+ item = items::Snowpeak_Ruins_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Temple_of_Time] ) )
+ {
+ item = items::Temple_of_Time_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_City_in_the_Sky] ) )
+ {
+ item = items::City_in_The_Sky_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Palace_of_Twilight] ) )
+ {
+ item = items::Palace_of_Twilight_Dungeon_Map;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Hyrule_Castle] ) )
+ {
+ item = items::Hyrule_Castle_Dungeon_Map;
+ }
+ }
+ else if ( item == items::Big_Key )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Forest_Temple] ) )
+ {
+ item = items::Forest_Temple_Big_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Lakebed_Temple] ) )
+ {
+ item = items::Lakebed_Temple_Big_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Arbiters_Grounds] ) )
+ {
+ item = items::Arbiters_Grounds_Big_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Temple_of_Time] ) )
+ {
+ item = items::Temple_of_Time_Big_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_City_in_the_Sky] ) )
+ {
+ item = items::City_in_The_Sky_Big_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Palace_of_Twilight] ) )
+ {
+ item = items::Palace_of_Twilight_Big_Key;
+ }
+ else if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Hyrule_Castle] ) )
+ {
+ item = items::Hyrule_Castle_Big_Key;
+ }
+
+ if ( Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ }
+
for ( u16 i = 0; i < totalChecks; i++ )
{
sourceCheck = &item::checks[i];
@@ -745,28 +896,121 @@ namespace mod
// 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 ) )
+ if ( item == items::Item::Wooden_Sword )
{
- item = items::Item::Ordon_Sword;
- gameInfo.scratchPad.equipedItems.sword = 0x28;
+ if ( tools::checkItemFlag( ItemFlags::Wooden_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Ordon_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Master_Sword ) )
+ {
+ item = items::Item::Master_Sword_Light;
+ gameInfo.scratchPad.equipedItems.sword = 0x49;
+ }
+ else
+ {
+ item = items::Item::Master_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x29;
+ }
+ }
+ else
+ {
+ item = items::Item::Ordon_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x28;
+ }
+ }
+ else
+ {
+ item = items::Item::Wooden_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x3F;
+ }
}
- else if ( item == items::Item::Ordon_Sword &&
- !tools::checkItemFlag( ItemFlags::Wooden_Sword ) )
+ else if ( item == items::Item::Ordon_Sword )
{
- item = items::Item::Wooden_Sword;
- gameInfo.scratchPad.equipedItems.sword = 0x3F;
+ if ( tools::checkItemFlag( ItemFlags::Wooden_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Ordon_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Master_Sword ) )
+ {
+ item = items::Item::Master_Sword_Light;
+ gameInfo.scratchPad.equipedItems.sword = 0x49;
+ }
+ else
+ {
+ item = items::Item::Master_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x29;
+ }
+ }
+ else
+ {
+ item = items::Item::Ordon_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x28;
+ }
+ }
+ else
+ {
+ 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 )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Wooden_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Ordon_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Master_Sword ) )
+ {
+ item = items::Item::Master_Sword_Light;
+ gameInfo.scratchPad.equipedItems.sword = 0x49;
+ }
+ else
+ {
+ item = items::Item::Master_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x29;
+ }
+ }
+ else
+ {
+ item = items::Item::Ordon_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x28;
+ }
+ }
+ else
+ {
+ item = items::Item::Wooden_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x3F;
+ }
}
- 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::Master_Sword_Light )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Wooden_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Ordon_Sword ) )
+ {
+ if ( tools::checkItemFlag( ItemFlags::Master_Sword ) )
+ {
+ item = items::Item::Master_Sword_Light;
+ gameInfo.scratchPad.equipedItems.sword = 0x49;
+ }
+ else
+ {
+ item = items::Item::Master_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x29;
+ }
+ }
+ else
+ {
+ item = items::Item::Ordon_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x28;
+ }
+ }
+ else
+ {
+ item = items::Item::Wooden_Sword;
+ gameInfo.scratchPad.equipedItems.sword = 0x3F;
+ }
}
else if ( item == items::Item::Clawshot && tools::checkItemFlag( ItemFlags::Clawshot ) )
{
@@ -776,6 +1020,17 @@ namespace mod
{
item = items::Item::Clawshot;
}
+
+ else if ( item == items::Item::Fishing_Rod &&
+ tools::checkItemFlag( ItemFlags::Fishing_Rod ) )
+ {
+ item = items::Item::Coral_Earring;
+ }
+ else if ( item == items::Item::Coral_Earring &&
+ !tools::checkItemFlag( ItemFlags::Fishing_Rod ) )
+ {
+ item = items::Item::Fishing_Rod;
+ }
else if ( item == items::Item::Heros_Bow )
{
if ( tools::checkItemFlag( ItemFlags::Heros_Bow ) &&
@@ -1044,7 +1299,7 @@ namespace mod
}
else
{
- game_patch::giveMidnaTransform();
+ gameInfo.scratchPad.eventBits[0xD] |= 0x4;
if ( Singleton::getInstance()->isMDHSkipEnabled == 1 )
{
gameInfo.scratchPad.unk_1F[0x11] |= 0x8; // Midna on Back
@@ -1089,38 +1344,45 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == 0xE2 )
@@ -1139,38 +1401,43 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
- {
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
- }
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == 0xE3 )
@@ -1189,38 +1456,43 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
- {
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
- }
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == 0xE4 )
@@ -1239,38 +1511,45 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == 0xE5 )
@@ -1289,38 +1568,45 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == 0xE6 )
@@ -1339,38 +1625,45 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == 0xE7 )
@@ -1389,38 +1682,45 @@ namespace mod
if ( ( gameInfo.scratchPad.eventBits[0x2A] & 0x40 ) !=
0 ) /*have jump strike*/
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x20; // give great spin
+ item = items::Great_Spin; // give great spin
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x20;
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x40; // give jumpstrike
+ item = items::Jump_Strike; // give jumpstrike
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x40;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x2A] |= 0x80; // give mortal draw
+ item = items::Mortal_Draw; // give mortal draw
+ gameInfo.scratchPad.eventBits[0x2A] |= 0x80;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x1; // give helm splitter
+ item = items::Helm_Splitter; // give helm splitter
+ gameInfo.scratchPad.eventBits[0x29] |= 0x1;
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x2; // give back slice
+ item = items::Back_Slice; // give back slice
+ gameInfo.scratchPad.eventBits[0x29] |= 0x2;
}
}
else
{
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x8; // give shield attack
+ item = items::Shield_Attack; // give shield attack
+ gameInfo.scratchPad.eventBits[0x29] |= 0x8;
}
}
}
else
{
- gameInfo.scratchPad.eventBits[0x29] |= 0x4; // give ending blow
+ item = items::Ending_Blow; // give ending blow
+ gameInfo.scratchPad.eventBits[0x29] |= 0x4;
}
}
else if ( item == items::Item::Reekfish_Scent )
@@ -1444,6 +1744,41 @@ namespace mod
{
item = items::Item::Red_Rupee;
}
+ else if ( item == items::Item::Forest_Temple_Big_Key &&
+ Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if ( item == items::Item::Lakebed_Temple_Big_Key &&
+ Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if ( item == items::Item::Arbiters_Grounds_Big_Key &&
+ Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if ( item == items::Item::Temple_of_Time_Big_Key &&
+ Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if ( item == items::Item::City_in_The_Sky_Big_Key &&
+ Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if ( item == items::Item::Palace_of_Twilight_Big_Key &&
+ Singleton::getInstance()->isBossKeyseyEnabled == 1 )
+ {
+ item = items::Item::Red_Rupee;
+ }
+ else if ( item == items::Item::Hyrule_Castle_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;
@@ -1490,10 +1825,6 @@ namespace mod
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
diff --git a/source/game_patches.cpp b/source/game_patches.cpp
index 437bd95..4797e61 100644
--- a/source/game_patches.cpp
+++ b/source/game_patches.cpp
@@ -15,6 +15,7 @@
#include <cstring>
#include "defines.h"
+#include "item.h"
#include "itemChecks.h"
#include "items.h"
#include "singleton.h"
@@ -64,6 +65,10 @@ namespace mod::game_patch
// Enable the crash screen
*enableCrashScreen = 0x48000014; // b 0x14
+
+ // Modify dComIfGs_Wolf_Change_Check to return true when checking to see if mdh is complete
+ u32 wolfChangeCheckAddress = reinterpret_cast<u32>( &tp::d_com_inf_game::dComIfGs_Wolf_Change_Check );
+ *reinterpret_cast<u32*>( wolfChangeCheckAddress + 0x108 ) = 0x3be00000; // Previous 0x3be00001
}
void killLinkHouseSpider()
@@ -196,273 +201,6 @@ namespace mod::game_patch
}
}
- void fixFTState()
- {
- if ( Singleton::getInstance()->hasFTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x6] &= ~0x2; // unset story flag
- if ( ( gameInfo.scratchPad.allAreaNodes.Forest_Temple.unk_0[0x12] & 0x10 ) == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.ooccooGotten = 0b0;
- }
- }
- }
-
- void fixGMState()
- {
- if ( Singleton::getInstance()->hasGMBeenBeaten == 1 || Singleton::getInstance()->isGMStoryPatch == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Goron_Mines.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x7] &= ~0x1; // unset story flag
- if ( ( gameInfo.scratchPad.allAreaNodes.Goron_Mines.unk_0[0xE] & 0x2 ) == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.Goron_Mines.dungeon.ooccooGotten = 0b0;
- }
- }
- }
-
- void fixLBTState()
- {
- if ( Singleton::getInstance()->hasLBTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x9] &= ~0x4; // unset story flag
- if ( ( gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.unk_0[0x11] & 0x80 ) == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.ooccooGotten = 0b0;
- }
- }
- }
-
- void fixAGState()
- {
- if ( Singleton::getInstance()->hasAGBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x20] &= ~0x10; // unset story flag
- if ( ( gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.unk_0[0x17] & 0x20 ) == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.ooccooGotten = 0b0;
- }
- }
- }
-
- void fixSPRState()
- {
- if ( Singleton::getInstance()->hasSPRBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x20] &= ~0x8; // unset story flag
- if ( ( gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.unk_0[0x1] & 0x1 ) == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.ooccooGotten = 0b0;
- }
- }
- }
-
- void fixToTState()
- {
- if ( Singleton::getInstance()->hasToTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x20] &= ~0x4; // unset story flag
- if ( ( gameInfo.scratchPad.allAreaNodes.Temple_of_Time.unk_0[0x4] & 0x80 ) == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.ooccooGotten = 0b0;
- }
- }
- }
-
- void fixCiTSState()
- {
- if ( Singleton::getInstance()->hasCiTSBeenBeaten == 1 || Singleton::getInstance()->isEarlyPoTEnabled == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.City_in_the_Sky.dungeon.bossBeaten = 0b0; // unset boss flag
- gameInfo.scratchPad.eventBits[0x20] &= ~0x2; // unset story flag
- }
- if ( Singleton::getInstance()->hasCiTSOoccoo == 0 )
- {
- gameInfo.scratchPad.allAreaNodes.City_in_the_Sky.dungeon.ooccooGotten = 0b0;
- }
- }
-
- void setFTDungeonFlag()
- {
- if ( Singleton::getInstance()->hasFTBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasFTBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasFTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x6] |= 0x2; // set story flag
- }
- }
-
- void setGMDungeonFlag()
- {
- if ( Singleton::getInstance()->hasGMBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.Goron_Mines.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasGMBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasGMBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Goron_Mines.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x7] |= 0x1; // set story flag
- }
- else if ( Singleton::getInstance()->isGMStoryPatch == 1 )
- {
- gameInfo.scratchPad.eventBits[0x7] |= 0x1; // set story flag
- }
- }
-
- void setGMBossFlag()
- {
- if ( Singleton::getInstance()->hasGMBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Goron_Mines.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
- void setLakeDungeonFlags()
- {
- if ( Singleton::getInstance()->hasLBTBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasLBTBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasLBTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x9] |= 0x4; // set story flag
- }
-
- if ( Singleton::getInstance()->hasCiTSBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.City_in_the_Sky.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasCiTSBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasCiTSBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.City_in_the_Sky.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x20] |= 0x2; // set story flag
- }
- else if ( Singleton::getInstance()->isEarlyPoTEnabled == 1 )
- {
- gameInfo.scratchPad.eventBits[0x20] |= 0x2; // set story flag
- }
- }
-
- void setLBTBossFlag()
- {
- if ( Singleton::getInstance()->hasLBTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Lakebed_Temple.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
- void setAGDungeonFlag()
- {
- if ( Singleton::getInstance()->hasAGBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasAGBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasAGBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x20] |= 0x10; // set story flag
- }
- }
-
- void setAGBossFlag()
- {
- if ( Singleton::getInstance()->hasAGBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Arbiters_Grounds.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
- void setSPRDungeonFlag()
- {
- if ( Singleton::getInstance()->hasSPRBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasSPRBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasSPRBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x20] |= 0x8; // set story flag
- }
- }
-
- void setSPRBossFlag()
- {
- if ( Singleton::getInstance()->hasSPRBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Snowpeak_Ruins.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
- void setToTDungeonFlag()
- {
- if ( Singleton::getInstance()->hasToTBeenBeaten == 0 &&
- gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.bossBeaten == 0b1 )
- {
- Singleton::getInstance()->hasToTBeenBeaten = 1;
- }
- else if ( Singleton::getInstance()->hasToTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.bossBeaten = 0b1; // set boss flag
- gameInfo.scratchPad.eventBits[0x20] |= 0x4; // set story flag
- }
-
- if ( Singleton::getInstance()->isEarlyToTEnabled == 1 )
- {
- gameInfo.nextStageVars.nextState = 0x2;
- }
- }
-
- void setToTBossFlag()
- {
- if ( Singleton::getInstance()->hasToTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Temple_of_Time.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
- void setCiTSBossFlag()
- {
- if ( Singleton::getInstance()->hasCiTSBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.City_in_the_Sky.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
- void setBublinState()
- {
- strcpy( sysConsolePtr->consoleLine[20].line, "state was not 1" );
- if ( gameInfo.nextStageVars.nextRoom != 3 )
- {
- if ( ( gameInfo.scratchPad.eventBits[0xB] & 0x40 ) != 0 )
- {
- 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 )
@@ -556,13 +294,21 @@ namespace mod::game_patch
{
gameInfo.scratchPad.eventBits[0x42] |= 0x8;
}
+ else if ( Singleton::getInstance()->isEarlyHCEnabled == 0 && ( ( gameInfo.scratchPad.eventBits[0x1E] & 0x8 ) != 0 ) &&
+ ( ( gameInfo.scratchPad.allAreaNodes.Palace_of_Twilight.dungeon.bossBeaten != 0 ) ) )
+ {
+ gameInfo.scratchPad.eventBits[0x42] |= 0x8;
+ }
}
void setEscortState()
{
- if ( ( gameInfo.scratchPad.eventBits[0x8] & 0x40 ) == 0 && Singleton::getInstance()->isCartEscortSkipEnabled == 0 &&
- tools::checkItemFlag( ItemFlags::Heros_Bow ) && tools::checkItemFlag( ItemFlags::Boomerang ) &&
- gameInfo.scratchPad.clearedTwilights.Lanayru == 0b1 )
+ if ( ( ( gameInfo.scratchPad.eventBits[0x8] & 0x40 ) == 0 ) &&
+ ( Singleton::getInstance()->isCartEscortSkipEnabled == 0 ) && tools::checkItemFlag( ItemFlags::Heros_Bow ) &&
+ tools::checkItemFlag( ItemFlags::Boomerang ) && gameInfo.scratchPad.clearedTwilights.Lanayru == 0b1 &&
+ ( ( Singleton::getInstance()->isMDHSkipEnabled == 1 ) ||
+ ( !tp::d_a_alink::dComIfGs_isEventBit( 0xC1 ) ||
+ ( tp::d_a_alink::dComIfGs_isEventBit( 0xC1 ) && tp::d_a_alink::dComIfGs_isEventBit( 0x1E08 ) ) ) ) )
{
gameInfo.nextStageVars.nextState = 0x8;
gameInfo.nextStageVars.nextSpawnPoint = 0x14;
@@ -652,57 +398,6 @@ namespace mod::game_patch
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
- if ( ( gameInfo.scratchPad.eventBits[0x9] & 0x40 ) != 0 ) // Bow mini-game started
- {
- 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 allowFaronEscape()
{
if ( Singleton::getInstance()->isForestEscapeEnabled == 0 )
@@ -742,22 +437,6 @@ namespace mod::game_patch
}
}
- void fixFTBossMusic()
- {
- if ( Singleton::getInstance()->isForestEscapeEnabled == 1 &&
- gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.bossBeaten == 0b0 &&
- Singleton::getInstance()->diababaMusicFixed == 0 )
- {
- gameInfo.scratchPad.eventBits[0x6] &= ~0x2;
- Singleton::getInstance()->diababaMusicFixed = 1;
- }
-
- if ( Singleton::getInstance()->hasFTBeenBeaten == 1 )
- {
- gameInfo.scratchPad.allAreaNodes.Forest_Temple.dungeon.bossBeaten = 0b1; // set boss flag
- }
- }
-
void skipTextAndCS()
{
// Set Scratchpad Pointer
@@ -791,22 +470,26 @@ namespace mod::game_patch
eventBitsPtr[0x7] |= 0x20; // Talked to Bo outside his house
eventBitsPtr[0xB] |= 0x20; // Talked to Yeta First Time
eventBitsPtr[0x10] |= 0x2; // Talked to Jaggle after climbing vines
+ eventBitsPtr[0xF] |= 0x40; // Talked to Doctor for the first time
eventBitsPtr[0x5E] |= 0x10; // Midna Text After Beating Forest Temple
- eventBitsPtr[0x40] |= 0x8; // have been to desert (prevents cannon warp crash)
+ eventBitsPtr[0x40] |= 0x88; // have been to desert (prevents cannon warp crash) saved monkey from puppets
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[0x2C] |= 0x10; // Mirror Rose
eventBitsPtr[0x28] |= 0x40; // Used Ooccoo for the First Time
eventBitsPtr[0x37] |= 0x4; // Postman Twilight Text
eventBitsPtr[0x38] |= 0x6; // Enter Hena Cabin CS
eventBitsPtr[0x3A] |= 0x1; // Talked to Ralis
- eventBitsPtr[0x42] |= 0x1; // Watched post ToT Ooccoo CS
+ eventBitsPtr[0x40] |= 0x2; // Agreed to help Rusl after snowpeak
+ eventBitsPtr[0x42] |= 0x3; // Watched post ToT Ooccoo CS and triggered monkey puppet 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
+ eventBitsPtr[0x54] |= 0x10; // PoT story flag
// Set Area Node Flags
tp::d_com_inf_game::AllAreaNodes* allAreaNodesPtr = &scratchPadPtr->allAreaNodes;
@@ -826,11 +509,13 @@ namespace mod::game_patch
allAreaNodesPtr->Sewers.unk_0[0xF] |=
0x11; // midna cs after digging out watched, midna text when approaching first rooftop guard
+ allAreaNodesPtr->Faron.unk_0[0x9] |= 0x2; // Saved monkey from puppets
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->Eldin.unk_0[0x16] |= 0x10; // Watched Colin saved 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
@@ -917,7 +602,7 @@ namespace mod::game_patch
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[0xC] |= 0x2; // Midna Text when west hand seals sol
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
@@ -947,7 +632,6 @@ namespace mod::game_patch
allAreaNodesPtr->Faron.unk_0[0x17] |= 0xC0; // kill bugs in Coro's House
// 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*/
// Apply Randomizer Options
@@ -994,14 +678,6 @@ namespace mod::game_patch
}
}
- Singleton::getInstance()->hasFTBeenBeaten = 0;
- Singleton::getInstance()->hasGMBeenBeaten = 0;
- Singleton::getInstance()->hasLBTBeenBeaten = 0;
- Singleton::getInstance()->hasAGBeenBeaten = 0;
- Singleton::getInstance()->hasSPRBeenBeaten = 0;
- Singleton::getInstance()->hasToTBeenBeaten = 0;
- Singleton::getInstance()->hasCiTSBeenBeaten = 0;
-
if ( Singleton::getInstance()->isIntroSkipped == 1 )
{
// set Ordon Days 1,2, and 3 Flags
@@ -1043,7 +719,8 @@ namespace mod::game_patch
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[0x5] |= 0xFF; // Ensure Epona is Stolen, give Midna Charge, finished sewers, midna text for
+ // entering Faron Twilight, Met zelda in sewers
eventBitsPtr[0x6] |= 0x10; // Faron Twilight Progression flag
eventBitsPtr[0xC] |= 0x8; // Set Sword and Shield to not be on back
tools::setItemFlag( ItemFlags::Heros_Clothes );
@@ -1111,7 +788,7 @@ namespace mod::game_patch
// 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
+ eventBitsPtr[0x20] |= 0x24; // MS Story Progression Flag and ToT flag
eventBitsPtr[0x1E] |= 0x80; // Gor Ebizo at Malo Mart
eventBitsPtr[0xA] |= 0x20; // Steal Eldin Bridge
eventBitsPtr[0xF] |= 0x8; // Put Eldin BRidge Back
@@ -1139,100 +816,448 @@ namespace mod::game_patch
// 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
+ eventBitsPtr[0x20] |= 0x24; // MS Story Progression Flag and ToT Flag
eventBitsPtr[0x1E] |= 0x80; // Gor Ebizo at Malo Mart
eventBitsPtr[0xA] |= 0x20; // Steal Eldin Bridge
eventBitsPtr[0xF] |= 0x8; // Put Eldin BRidge Back
}
}
- /*void setFieldModels()
+ void setCustomItemData()
{
- tp::d_item_data::ItemResource* itemResPtr = &tp::d_item_data::item_resource[0];
- tp::d_item_data::FieldItemRes* fieldItemResPtr = &tp::d_item_data::field_item_res[0];
+ // Generic item variables
+ tp::d_item_data::ItemResource* itemResourcePtr = &tp::d_item_data::item_resource[0];
+ tp::d_item_data::ItemInfo* itemInfoPtr = &tp::d_item_data::item_info[0];
+ u8* getSeTypePtr = &tp::d_a_alink::getSeType[0];
+
+ // Vanilla Small Key variables
+ tp::d_item_data::ItemResource* smallKeyItemResourcePtr = &itemResourcePtr[items::Small_Key];
+ u32 smallKeyItemInfo = *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[items::Small_Key] ) );
+ u8 smallKeySeType = getSeTypePtr[items::Small_Key];
+
+ // Vanilla Big Key variables
+ tp::d_item_data::ItemResource* bigKeyItemResourcePtr = &itemResourcePtr[items::Big_Key];
+ u32 bigKeyItemInfo = *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[items::Big_Key] ) );
+ u8 bigKeySeType = getSeTypePtr[items::Big_Key];
+
+ // Vanilla Dungeon Map variables
+ tp::d_item_data::ItemResource* dungeonMapItemResourcePtr = &itemResourcePtr[items::Dungeon_Map];
+ u32 dungeonMapItemInfo = *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[items::Dungeon_Map] ) );
+ u8 dungeonMapSeType = getSeTypePtr[items::Dungeon_Map];
+
+ // Vanilla Compass variables
+ tp::d_item_data::ItemResource* compassItemResourcePtr = &itemResourcePtr[items::Compass];
+ u32 compassItemInfo = *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[items::Compass] ) );
+ u8 compassSeType = getSeTypePtr[items::Compass];
+
+ // Set the item info for the custom small keys to that of the current Small Key
+ for ( u32 i = 0; i < sizeof( item::customSmallKeyItemIDs ) / sizeof( item::customSmallKeyItemIDs[0] ); i++ )
+ {
+ *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[item::customSmallKeyItemIDs[i]] ) ) = smallKeyItemInfo;
+
+ getSeTypePtr[item::customSmallKeyItemIDs[i]] = smallKeySeType;
+
+ memcpy( &itemResourcePtr[item::customSmallKeyItemIDs[i]],
+ smallKeyItemResourcePtr,
+ sizeof( tp::d_item_data::ItemResource ) );
+ }
- u32 loopCount = sizeof(item::itemsWithNoFieldModel) / sizeof(item::itemsWithNoFieldModel[0]);
- for (u32 i = 0; i < loopCount; i++)
+ // Set the item info for the custom big keys to that of the current Big Key
+ for ( u32 i = 0; i < sizeof( item::customBigKeyItemIDs ) / sizeof( item::customBigKeyItemIDs[0] ); i++ )
{
- u32 item = item::itemsWithNoFieldModel[i]; // Retrieve as u32 to prevent rlwinm shenanigans
- fieldItemResPtr[item].arcName = itemResPtr[item].arcName;
- fieldItemResPtr[item].modelResIdx = itemResPtr[item].modelResIdx;
+ *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[item::customBigKeyItemIDs[i]] ) ) = bigKeyItemInfo;
+
+ getSeTypePtr[item::customBigKeyItemIDs[i]] = bigKeySeType;
+
+ memcpy( &itemResourcePtr[item::customBigKeyItemIDs[i]],
+ bigKeyItemResourcePtr,
+ sizeof( tp::d_item_data::ItemResource ) );
}
- // For items that dont have a field model, use rupee item info to allow the item to be collected and whatnot
- // Using the yellow rupee because thats what i used in testing
- tp::d_item_data::ItemInfo* itemInfoPtr = &tp::d_item_data::item_info[0];
- tp::d_item_data::ItemInfo* yellowRupeeInfoPtr = &tp::d_item_data::item_info[items::Yellow_Rupee];
+ // Set the item info for the custom dungeon map to that of the current Dungeon Map
+ for ( u32 i = 0; i < sizeof( item::customDungeonMapItemIDs ) / sizeof( item::customDungeonMapItemIDs[0] ); i++ )
+ {
+ *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[item::customDungeonMapItemIDs[i]] ) ) =
+ dungeonMapItemInfo;
+
+ getSeTypePtr[item::customDungeonMapItemIDs[i]] = dungeonMapSeType;
- loopCount = sizeof(item::itemsWithNoFieldModel) / sizeof(item::itemsWithNoFieldModel[0]);
- for (u32 i = 0; i < loopCount; i++)
+ memcpy( &itemResourcePtr[item::customDungeonMapItemIDs[i]],
+ dungeonMapItemResourcePtr,
+ sizeof( tp::d_item_data::ItemResource ) );
+ }
+
+ // Set the item info for the custom compass to that of the current compass
+ for ( u32 i = 0; i < sizeof( item::customCompassItemIDs ) / sizeof( item::customCompassItemIDs[0] ); i++ )
{
- u32 item = item::itemsWithNoFieldModel[i]; // Retrieve as u32 to prevent rlwinm shenanigans
- itemInfoPtr[item].mShadowSize = yellowRupeeInfoPtr->mShadowSize;
- itemInfoPtr[item].mCollisionH = yellowRupeeInfoPtr->mCollisionH;
- itemInfoPtr[item].mCollisionR = yellowRupeeInfoPtr->mCollisionR;
- itemInfoPtr[item].mFlags = yellowRupeeInfoPtr->mFlags;
+ *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[item::customCompassItemIDs[i]] ) ) = compassItemInfo;
+
+ getSeTypePtr[item::customCompassItemIDs[i]] = compassSeType;
+
+ memcpy( &itemResourcePtr[item::customCompassItemIDs[i]],
+ compassItemResourcePtr,
+ sizeof( tp::d_item_data::ItemResource ) );
}
- // Modify a branch in itemGetNextExecute to allow the item get cutscene to play with items past 0x40
- // If you already have the item it gives you, then itll act like a rupee and appear over your head. This could be
- changed though. u32 address_US = 0x8015CF64; *reinterpret_cast<u32*>(address_US) = 0x48000018; // b 0x18
+ // Set the item info for the custom hidden skill items
+ // Set the item info for the custom compass to that of the current compass
+ for ( u32 i = 0; i < sizeof( item::customHiddenSkillItemIDs ) / sizeof( item::customHiddenSkillItemIDs[0] ); i++ )
+ {
+ itemResourcePtr[item::customHiddenSkillItemIDs[i]].arcName = "O_gD_memo";
+ itemResourcePtr[item::customHiddenSkillItemIDs[i]].ringTexResIdx = 0x003D;
+ itemResourcePtr[item::customHiddenSkillItemIDs[i]].modelResIdx = 0x0003;
+ itemResourcePtr[item::customHiddenSkillItemIDs[i]].brkResIdx = 0xFFFF;
+ itemResourcePtr[item::customHiddenSkillItemIDs[i]].tevFrm = 0x00;
+ getSeTypePtr[item::customHiddenSkillItemIDs[i]] = 0x2;
+ }
+
+ // Set the Model and SeType for the Master/Light Swords. We will use the Ordon Sword for now.
+ memcpy( &itemResourcePtr[items::Master_Sword],
+ &itemResourcePtr[items::Ordon_Sword],
+ sizeof( tp::d_item_data::ItemResource ) );
+ itemResourcePtr[items::Master_Sword].ringTexResIdx = 0x0042;
+ getSeTypePtr[items::Master_Sword] = getSeTypePtr[items::Clawshot];
+
+ memcpy( &itemResourcePtr[items::Master_Sword_Light],
+ &itemResourcePtr[items::Ordon_Sword],
+ sizeof( tp::d_item_data::ItemResource ) );
+ itemResourcePtr[items::Master_Sword_Light].ringTexResIdx = 0x0042;
+ getSeTypePtr[items::Master_Sword_Light] = getSeTypePtr[items::Clawshot];
+
+ // Set the model and SeType for all other items that need it.
+
+ itemResourcePtr[items::Shadow_Crystal].ringTexResIdx = 0x002E;
+ getSeTypePtr[items::Shadow_Crystal] = getSeTypePtr[items::Clawshot];
+
+ itemResourcePtr[items::Bomb_Bag_Regular_Bombs].arcName = itemResourcePtr[items::Goron_Bomb_Bag].arcName;
+ itemResourcePtr[items::Bomb_Bag_Regular_Bombs].modelResIdx = itemResourcePtr[items::Goron_Bomb_Bag].modelResIdx;
+ itemResourcePtr[items::Bomb_Bag_Regular_Bombs].brkResIdx = 0xFFFF;
+ itemResourcePtr[items::Bomb_Bag_Regular_Bombs].tevFrm = 0x00;
+ getSeTypePtr[items::Bomb_Bag_Regular_Bombs] = getSeTypePtr[items::Goron_Bomb_Bag];
+
+ memcpy( &itemResourcePtr[items::Horse_Call],
+ &itemResourcePtr[items::Ilias_Charm],
+ sizeof( tp::d_item_data::ItemResource ) );
+ getSeTypePtr[items::Horse_Call] = getSeTypePtr[items::Clawshot];
+
+ *reinterpret_cast<u32*>( reinterpret_cast<u32>( &itemInfoPtr[items::Bublin_Camp_Key] ) ) = smallKeyItemInfo;
+ getSeTypePtr[items::Bublin_Camp_Key] = smallKeySeType;
+ memcpy( &itemResourcePtr[items::Bublin_Camp_Key], smallKeyItemResourcePtr, sizeof( tp::d_item_data::ItemResource ) );
+ }
+
+ void giveNodeDungeonItems( const tp::d_com_inf_game::AreaNodesID nodeId,
+ const char* stage,
+ const item::NodeDungeonItemType type )
+ {
+ tp::d_com_inf_game::GameInfo* gameInfoPtr = &gameInfo;
- // Hook dStage_actorCommonLayerInit to search for field items (probably only rupees) to replace based on object name
- bool procActorCommonLayerInit(void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, s32 unk3, void*
- unk4)
+ // If the key is for the current area, then update the local node
+ // Only check the first 4 characters, since those are what determine each area
+ if ( strncmp( gameInfoPtr->currentStage, stage, 4 ) == 0 )
{
- Actr* actrPtr = chunkTypeInfo->chunkDataPtr;
- u32 numChunks = chunkTypeInfo->numChunks;
- for (u32 i = 0; i < numChunks; i++)
+ switch ( type )
{
- // Check for "item", as that seems to be whats used for rupees
- // Would check for chests and whatnot as well when changing the contents of those
- if (strncmp(actrPtr->objectName, "item", sizeof(Actr.objectName)))
- {
- // Change the item id
- u8* tempParamBytes = reinterpret_cast<u8*>(&actrPtr->parameters);
- tempParamBytes[3] = newItemId;
-
- // Changing the parameters probably isnt necessary for "item", but I'll add them anyway
- // Refer to Winditor for what the parameters do
- tempParamBytes[0] = 0xF3;
- tempParamBytes[1] = 0xFF;
- tempParamBytes[2] = 0x80;
- actrPtr->rot[2] = 0x3F;
- }
+ case item::NodeDungeonItemType::Small_Key:
+ gameInfoPtr->localAreaNodes.nbKeys++;
+ break;
+ case item::NodeDungeonItemType::Dungeon_Map:
+ gameInfoPtr->localAreaNodes.dungeon.mapGotten = 0b1;
+ break;
+ case item::NodeDungeonItemType::Compass:
+ gameInfoPtr->localAreaNodes.dungeon.compassGotten = 0b1;
+ break;
+ case item::NodeDungeonItemType::Big_Key:
+ gameInfoPtr->localAreaNodes.dungeon.bigKeyGotten = 0b1;
+ break;
+
+ default:
+ break;
}
}
-
- // hook dStage_actorInit to search for field items (probably only heart containers) to replace based on object name
- // Not sure what is passed into dStage_actorInit, but r4 seems to be the same as dStage_actorCommonLayerInit
- bool procActorCommonLayerInit(void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, s32 unk3, void*
- unk4)
+ else // Key is not for the current area, so update the appropriate node
{
- Actr* actrPtr = chunkTypeInfo->chunkDataPtr;
- u32 numChunks = chunkTypeInfo->numChunks;
- for (u32 i = 0; i < numChunks; i++)
+ tp::d_com_inf_game::AreaNodes* node =
+ reinterpret_cast<tp::d_com_inf_game::AreaNodes*>( &gameInfoPtr->scratchPad.allAreaNodes.Ordon );
+
+ switch ( type )
{
- // Check for "htPiece", as that seems to be whats used for heart pieces
- // Not sure what name heart containers use
- if (strncmp(actrPtr->objectName, "htPiece", sizeof(Actr.objectName)))
- {
- // Change the object name to "item"
- strncpy(actrPtr->objectName, "item", sizeof(Actr.objectName));
-
- // Change the item id
- u8* tempParamBytes = reinterpret_cast<u8*>(&actrPtr->parameters);
- tempParamBytes[3] = newItemId;
-
- // Changing the parameters is necessary for this, as its being changed to use rupee parameters
- // Currently allows the item to respawn, so need to look into what handles that
- // Refer to Winditor for what the parameters do
- tempParamBytes[0] = 0xF3;
- tempParamBytes[1] = 0xFF;
- tempParamBytes[2] = 0x80;
- actrPtr->rot[2] = 0x3F;
- }
+ case item::NodeDungeonItemType::Small_Key:
+ node[static_cast<u32>( nodeId )].nbKeys++;
+ break;
+ case item::NodeDungeonItemType::Dungeon_Map:
+ node[static_cast<u32>( nodeId )].dungeon.mapGotten = 0b1;
+ break;
+ case item::NodeDungeonItemType::Compass:
+ node[static_cast<u32>( nodeId )].dungeon.compassGotten = 0b1;
+ break;
+ case item::NodeDungeonItemType::Big_Key:
+ node[static_cast<u32>( nodeId )].dungeon.bigKeyGotten = 0b1;
+ break;
+ default:
+ break;
}
}
- }*/
+ }
+
+ void setCustomItemFunctions()
+ {
+ tp::d_item::ItemFunc* itemFuncPtr = &tp::d_item::item_func_ptr[0];
+
+ // Forest Temple
+ tp::d_item::ItemFunc onGetForestTempleSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Forest_Temple;
+ const char* stage = stage::allStages[Stage_Forest_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Forest_Temple_Small_Key] = onGetForestTempleSmallKey;
+
+ tp::d_item::ItemFunc onGetForestTempleDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Forest_Temple;
+ const char* stage = stage::allStages[Stage_Forest_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Forest_Temple_Dungeon_Map] = onGetForestTempleDungeonMap;
+
+ tp::d_item::ItemFunc onGetForestTempleCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Forest_Temple;
+ const char* stage = stage::allStages[Stage_Forest_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Forest_Temple_Compass] = onGetForestTempleCompass;
+
+ tp::d_item::ItemFunc onGetForestTempleBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Forest_Temple;
+ const char* stage = stage::allStages[Stage_Forest_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::Forest_Temple_Big_Key] = onGetForestTempleBigKey;
+
+ // Goron Mines
+ tp::d_item::ItemFunc onGetGoronMinesSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Goron_Mines;
+ const char* stage = stage::allStages[Stage_Goron_Mines];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Goron_Mines_Small_Key] = onGetGoronMinesSmallKey;
+
+ tp::d_item::ItemFunc onGetGoronMinesDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Goron_Mines;
+ const char* stage = stage::allStages[Stage_Goron_Mines];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Goron_Mines_Dungeon_Map] = onGetGoronMinesDungeonMap;
+
+ tp::d_item::ItemFunc onGetGoronMinesCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Goron_Mines;
+ const char* stage = stage::allStages[Stage_Goron_Mines];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Goron_Mines_Compass] = onGetGoronMinesCompass;
+
+ // Lakebed Temple
+ tp::d_item::ItemFunc onGetLakebedTempleSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Lakebed_Temple;
+ const char* stage = stage::allStages[Stage_Lakebed_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Lakebed_Temple_Small_Key] = onGetLakebedTempleSmallKey;
+
+ tp::d_item::ItemFunc onGetLakebedTempleDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Lakebed_Temple;
+ const char* stage = stage::allStages[Stage_Lakebed_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Lakebed_Temple_Dungeon_Map] = onGetLakebedTempleDungeonMap;
+
+ tp::d_item::ItemFunc onGetLakebedTempleCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Lakebed_Temple;
+ const char* stage = stage::allStages[Stage_Lakebed_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Lakebed_Temple_Compass] = onGetLakebedTempleCompass;
+
+ tp::d_item::ItemFunc onGetLakebedTempleBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Lakebed_Temple;
+ const char* stage = stage::allStages[Stage_Lakebed_Temple];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::Lakebed_Temple_Big_Key] = onGetLakebedTempleBigKey;
+
+ // Arbiters Grounds
+ tp::d_item::ItemFunc onGetArbitersGroundsSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Arbiters_Grounds;
+ const char* stage = stage::allStages[Stage_Arbiters_Grounds];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Arbiters_Grounds_Small_Key] = onGetArbitersGroundsSmallKey;
+
+ tp::d_item::ItemFunc onGetArbitersGroundsDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Arbiters_Grounds;
+ const char* stage = stage::allStages[Stage_Arbiters_Grounds];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Arbiters_Grounds_Dungeon_Map] = onGetArbitersGroundsDungeonMap;
+
+ tp::d_item::ItemFunc onGetArbitersGroundsCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Arbiters_Grounds;
+ const char* stage = stage::allStages[Stage_Arbiters_Grounds];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Arbiters_Grounds_Compass] = onGetArbitersGroundsCompass;
+
+ tp::d_item::ItemFunc onGetArbitersGroundsBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Arbiters_Grounds;
+ const char* stage = stage::allStages[Stage_Arbiters_Grounds];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::Arbiters_Grounds_Big_Key] = onGetArbitersGroundsBigKey;
+
+ // Snowpeak Ruins
+ tp::d_item::ItemFunc onGetSnowpeakRuinsSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Snowpeak_Ruins;
+ const char* stage = stage::allStages[Stage_Snowpeak_Ruins];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Snowpeak_Ruins_Small_Key] = onGetSnowpeakRuinsSmallKey;
+
+ tp::d_item::ItemFunc onGetSnowpeakRuinsDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Snowpeak_Ruins;
+ const char* stage = stage::allStages[Stage_Snowpeak_Ruins];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Snowpeak_Ruins_Dungeon_Map] = onGetSnowpeakRuinsDungeonMap;
+
+ tp::d_item::ItemFunc onGetSnowpeakRuinsCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Snowpeak_Ruins;
+ const char* stage = stage::allStages[Stage_Snowpeak_Ruins];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Snowpeak_Ruins_Compass] = onGetSnowpeakRuinsCompass;
+
+ // Temple of Time
+ tp::d_item::ItemFunc onGetTempleofTimeSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Temple_of_Time;
+ const char* stage = stage::allStages[Stage_Temple_of_Time];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Temple_of_Time_Small_Key] = onGetTempleofTimeSmallKey;
+
+ tp::d_item::ItemFunc onGetTempleofTimeDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Temple_of_Time;
+ const char* stage = stage::allStages[Stage_Temple_of_Time];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Temple_of_Time_Dungeon_Map] = onGetTempleofTimeDungeonMap;
+
+ tp::d_item::ItemFunc onGetTempleofTimeCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Temple_of_Time;
+ const char* stage = stage::allStages[Stage_Temple_of_Time];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Temple_of_Time_Compass] = onGetTempleofTimeCompass;
+
+ tp::d_item::ItemFunc onGetTempleofTimeBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Temple_of_Time;
+ const char* stage = stage::allStages[Stage_Temple_of_Time];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::Temple_of_Time_Big_Key] = onGetTempleofTimeBigKey;
+
+ // City in The Sky
+ tp::d_item::ItemFunc onGetCityinTheSkySmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::City_in_the_Sky;
+ const char* stage = stage::allStages[Stage_City_in_the_Sky];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::City_in_The_Sky_Small_Key] = onGetCityinTheSkySmallKey;
+
+ tp::d_item::ItemFunc onGetCityinTheSkyDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::City_in_the_Sky;
+ const char* stage = stage::allStages[Stage_City_in_the_Sky];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::City_in_The_Sky_Dungeon_Map] = onGetCityinTheSkyDungeonMap;
+
+ tp::d_item::ItemFunc onGetCityinTheSkyCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::City_in_the_Sky;
+ const char* stage = stage::allStages[Stage_City_in_the_Sky];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::City_in_The_Sky_Compass] = onGetCityinTheSkyCompass;
+
+ tp::d_item::ItemFunc onGetCityinTheSkyBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::City_in_the_Sky;
+ const char* stage = stage::allStages[Stage_City_in_the_Sky];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::City_in_The_Sky_Big_Key] = onGetCityinTheSkyBigKey;
+
+ // Palace of Twilight
+ tp::d_item::ItemFunc onGetPalaceofTwilightSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Palace_of_Twilight;
+ const char* stage = stage::allStages[Stage_Palace_of_Twilight];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Palace_of_Twilight_Small_Key] = onGetPalaceofTwilightSmallKey;
+
+ tp::d_item::ItemFunc onGetPalaceofTwilightDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Palace_of_Twilight;
+ const char* stage = stage::allStages[Stage_Palace_of_Twilight];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Palace_of_Twilight_Dungeon_Map] = onGetPalaceofTwilightDungeonMap;
+
+ tp::d_item::ItemFunc onGetPalaceofTwilightCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Palace_of_Twilight;
+ const char* stage = stage::allStages[Stage_Palace_of_Twilight];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Palace_of_Twilight_Compass] = onGetPalaceofTwilightCompass;
+
+ tp::d_item::ItemFunc onGetPalaceofTwilightBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Palace_of_Twilight;
+ const char* stage = stage::allStages[Stage_Palace_of_Twilight];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::Palace_of_Twilight_Big_Key] = onGetPalaceofTwilightBigKey;
+
+ // Hyrule Castle
+ tp::d_item::ItemFunc onGetHyruleCastleSmallKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Hyrule_Castle;
+ const char* stage = stage::allStages[Stage_Hyrule_Castle];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Hyrule_Castle_Small_Key] = onGetHyruleCastleSmallKey;
+
+ tp::d_item::ItemFunc onGetHyruleCastleDungeonMap = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Hyrule_Castle;
+ const char* stage = stage::allStages[Stage_Hyrule_Castle];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Dungeon_Map );
+ };
+ itemFuncPtr[items::Hyrule_Castle_Dungeon_Map] = onGetHyruleCastleDungeonMap;
+
+ tp::d_item::ItemFunc onGetHyruleCastleCompass = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Hyrule_Castle;
+ const char* stage = stage::allStages[Stage_Hyrule_Castle];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Compass );
+ };
+ itemFuncPtr[items::Hyrule_Castle_Compass] = onGetHyruleCastleCompass;
+
+ tp::d_item::ItemFunc onGetHyruleCastleBigKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Hyrule_Castle;
+ const char* stage = stage::allStages[Stage_Hyrule_Castle];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Big_Key );
+ };
+ itemFuncPtr[items::Hyrule_Castle_Big_Key] = onGetHyruleCastleBigKey;
+
+ // Bublin Camp
+ tp::d_item::ItemFunc onGetBublinCampKey = []() {
+ const tp::d_com_inf_game::AreaNodesID nodeId = tp::d_com_inf_game::AreaNodesID::Gerudo_Desert;
+ const char* stage = stage::allStages[Stage_Bublin_Camp];
+ giveNodeDungeonItems( nodeId, stage, item::NodeDungeonItemType::Small_Key );
+ };
+ itemFuncPtr[items::Bublin_Camp_Key] = onGetBublinCampKey;
+ }
+
+ u16 dungeonStoryFlags[8] = { 0x602, 0x701, 0x904, 0x2010, 0x2008, 0x2004, 0x2002, 0x5410 };
} // namespace mod::game_patch \ No newline at end of file
diff --git a/source/item.cpp b/source/item.cpp
index 411bae3..c0cde13 100644
--- a/source/item.cpp
+++ b/source/item.cpp
@@ -117,5 +117,50 @@ namespace mod::item
return flags;
}
- u8 itemsWithNoFieldModel[2] = { 0x32, 0x40 };
+ u8 customSmallKeyItemIDs[10] = { items::Forest_Temple_Small_Key,
+ items::Goron_Mines_Small_Key,
+ items::Lakebed_Temple_Small_Key,
+ items::Arbiters_Grounds_Small_Key,
+ items::Snowpeak_Ruins_Small_Key,
+ items::Temple_of_Time_Small_Key,
+ items::City_in_The_Sky_Small_Key,
+ items::Palace_of_Twilight_Small_Key,
+ items::Hyrule_Castle_Small_Key,
+ items::Bublin_Camp_Key };
+
+ u8 customBigKeyItemIDs[7] = { items::Forest_Temple_Big_Key,
+ items::Lakebed_Temple_Big_Key,
+ items::Arbiters_Grounds_Big_Key,
+ items::Temple_of_Time_Big_Key,
+ items::City_in_The_Sky_Big_Key,
+ items::Palace_of_Twilight_Big_Key,
+ items::Hyrule_Castle_Big_Key };
+
+ u8 customDungeonMapItemIDs[9] = { items::Forest_Temple_Dungeon_Map,
+ items::Goron_Mines_Dungeon_Map,
+ items::Lakebed_Temple_Dungeon_Map,
+ items::Arbiters_Grounds_Dungeon_Map,
+ items::Snowpeak_Ruins_Dungeon_Map,
+ items::Temple_of_Time_Dungeon_Map,
+ items::City_in_The_Sky_Dungeon_Map,
+ items::Palace_of_Twilight_Dungeon_Map,
+ items::Hyrule_Castle_Dungeon_Map };
+
+ u8 customCompassItemIDs[9] = { items::Forest_Temple_Compass,
+ items::Goron_Mines_Compass,
+ items::Lakebed_Temple_Compass,
+ items::Arbiters_Grounds_Compass,
+ items::Snowpeak_Ruins_Compass,
+ items::Temple_of_Time_Compass,
+ items::City_in_The_Sky_Compass,
+ items::Palace_of_Twilight_Compass,
+ items::Hyrule_Castle_Compass };
+
+ u8 customHiddenSkillItemIDs[7] = { items::Ending_Blow,
+ items::Shield_Attack,
+ items::Back_Slice,
+ items::Helm_Splitter,
+ items::Mortal_Draw,
+ items::Jump_Strike,
+ items::Great_Spin };
} // namespace mod::item \ No newline at end of file
diff --git a/source/itemChecks.cpp b/source/itemChecks.cpp
index f45ff9a..cc9092d 100644
--- a/source/itemChecks.cpp
+++ b/source/itemChecks.cpp
@@ -6,7 +6,7 @@
namespace mod::item
{
- ItemCheck checks[505] = {
+ ItemCheck checks[503] = {
/* 0 */ { 0x3F,
1,
stage::allStages[65],
@@ -111,7 +111,7 @@ namespace mod::item
nullptr,
nullptr }, // FT Central Chest Behind Stairs
/* 8 */
- { 0x23,
+ { 0xB6,
2,
stage::allStages[6],
0,
@@ -124,7 +124,7 @@ namespace mod::item
nullptr,
nullptr }, // FT Map Chest
/* 9 */
- { 0x20,
+ { 0x85,
8,
stage::allStages[6],
9,
@@ -150,7 +150,7 @@ namespace mod::item
nullptr,
nullptr }, // FT Second Monkey Under Bridge Chest
/* 11 */
- { 0x20,
+ { 0x85,
8,
stage::allStages[6],
5,
@@ -202,7 +202,7 @@ namespace mod::item
nullptr,
nullptr }, // FT West Tile Worm Heart Piece Chest
/* 15 */
- { 0x24,
+ { 0x99,
2,
stage::allStages[6],
0,
@@ -215,7 +215,7 @@ namespace mod::item
nullptr,
nullptr }, // FT Compass Chest
/* 16 */
- { 0x26,
+ { 0x92,
2,
stage::allStages[6],
1,
@@ -241,7 +241,7 @@ namespace mod::item
nullptr,
nullptr }, // FT East Water Cave Chest
/* 18 */
- { 0x20,
+ { 0x85,
8,
stage::allStages[6],
10,
@@ -306,7 +306,7 @@ namespace mod::item
nullptr,
nullptr }, // GM Entrance Small Chest
/* 23 */
- { 0x20,
+ { 0x86,
8,
stage::allStages[3],
3,
@@ -319,7 +319,7 @@ namespace mod::item
nullptr,
nullptr }, // GM Main Magnet Room Bottom Chest
/* 24 */
- { 0x23,
+ { 0xB7,
2,
stage::allStages[3],
14,
@@ -358,7 +358,7 @@ namespace mod::item
nullptr,
nullptr }, // GM Magnet Maze Heart Piece Chest
/* 27 */
- { 0x20,
+ { 0x86,
8,
stage::allStages[3],
6,
@@ -397,7 +397,7 @@ namespace mod::item
nullptr,
nullptr }, // GM After Switch Room Heart Piece Chest
/* 30 */
- { 0x20,
+ { 0x86,
8,
stage::allStages[3],
7,
@@ -449,7 +449,7 @@ namespace mod::item
nullptr,
nullptr }, // GM Bow Chest
/* 34 */
- { 0x24,
+ { 0x9A,
2,
stage::allStages[3],
11,
@@ -657,7 +657,7 @@ namespace mod::item
nullptr,
nullptr }, // LBT Central Room Small Chest
/* 50 */
- { 0x23,
+ { 0xB8,
2,
stage::allStages[0],
3,
@@ -670,7 +670,7 @@ namespace mod::item
nullptr,
nullptr }, // LBT Map Chest
/* 51 */
- { 0x20,
+ { 0x87,
8,
stage::allStages[0],
8,
@@ -696,7 +696,7 @@ namespace mod::item
nullptr,
nullptr }, // LBT East Second Floor Southwest Chest
/* 53 */
- { 0x20,
+ { 0x87,
8,
stage::allStages[0],
7,
@@ -722,7 +722,7 @@ namespace mod::item
nullptr,
nullptr }, // LBT East Water Supply Small Chest
/* 55 */
- { 0x20,
+ { 0x87,
8,
stage::allStages[0],
9,
@@ -839,7 +839,7 @@ namespace mod::item
nullptr,
nullptr }, // LBT West Water Supply Small Chest
/* 64 */
- { 0x24,
+ { 0x9B,
2,
stage::allStages[0],
13,
@@ -904,7 +904,7 @@ namespace mod::item
nullptr,
nullptr }, // LBT West Second Floor Southeast Chest
/* 69 */
- { 0x26,
+ { 0x93,
2,
stage::allStages[0],
6,
@@ -1866,7 +1866,7 @@ namespace mod::item
nullptr,
nullptr },
/* 143 */
- { 0x20,
+ { 0x88,
8,
stage::allStages[24],
0,
@@ -1879,7 +1879,7 @@ namespace mod::item
nullptr,
nullptr },
/* 144 */
- { 0x20,
+ { 0x88,
8,
stage::allStages[24],
15,
@@ -1905,7 +1905,7 @@ namespace mod::item
nullptr,
nullptr },
/* 146 */
- { 0x23,
+ { 0xB9,
2,
stage::allStages[24],
2,
@@ -1918,7 +1918,7 @@ namespace mod::item
nullptr,
nullptr },
/* 147 */
- { 0x24,
+ { 0xA8,
2,
stage::allStages[24],
4,
@@ -1931,7 +1931,7 @@ namespace mod::item
nullptr,
nullptr },
/* 148 */
- { 0x20,
+ { 0x88,
8,
stage::allStages[24],
4,
@@ -1944,7 +1944,7 @@ namespace mod::item
nullptr,
nullptr },
/* 149 */
- { 0x20,
+ { 0x88,
8,
stage::allStages[24],
14,
@@ -2009,7 +2009,7 @@ namespace mod::item
nullptr,
nullptr },
/* 154 */
- { 0x20,
+ { 0x88,
8,
stage::allStages[24],
16,
@@ -2100,7 +2100,7 @@ namespace mod::item
nullptr,
nullptr },
/* 161 */
- { 0x26,
+ { 0x94,
2,
stage::allStages[24],
9,
@@ -2230,7 +2230,7 @@ namespace mod::item
nullptr,
nullptr }, // Faron Mist East Chest
/* 171 */
- { 0x20,
+ { 0x89,
8,
stage::allStages[27],
4,
@@ -2269,7 +2269,7 @@ namespace mod::item
nullptr,
nullptr },
/* 174 */
- { 0x20,
+ { 0x89,
8,
stage::allStages[27],
4,
@@ -2295,7 +2295,7 @@ namespace mod::item
nullptr,
nullptr },
/* 176 */
- { 0x24,
+ { 0xA9,
2,
stage::allStages[27],
8,
@@ -2347,7 +2347,7 @@ namespace mod::item
nullptr,
nullptr },
/* 180 */
- { 0x20,
+ { 0x89,
8,
stage::allStages[27],
8,
@@ -2399,7 +2399,7 @@ namespace mod::item
nullptr,
nullptr },
/* 184 */
- { 0x20,
+ { 0x89,
8,
stage::allStages[27],
5,
@@ -2516,7 +2516,7 @@ namespace mod::item
nullptr,
nullptr },
/* 193 */
- { 0x20,
+ { 0x8A,
8,
stage::allStages[9],
0,
@@ -2555,7 +2555,7 @@ namespace mod::item
nullptr,
nullptr },
/* 196 */
- { 0x23,
+ { 0xBB,
2,
stage::allStages[9],
1,
@@ -2568,7 +2568,7 @@ namespace mod::item
nullptr,
nullptr },
/* 197 */
- { 0x20,
+ { 0x8A,
8,
stage::allStages[9],
3,
@@ -2581,7 +2581,7 @@ namespace mod::item
nullptr,
nullptr },
/* 198 */
- { 0x24,
+ { 0xAA,
2,
stage::allStages[9],
4,
@@ -2607,7 +2607,7 @@ namespace mod::item
nullptr,
nullptr },
/* 200 */
- { 0x20,
+ { 0x8A,
8,
stage::allStages[9],
7,
@@ -2672,7 +2672,7 @@ namespace mod::item
nullptr,
nullptr },
/* 205 */
- { 0x26,
+ { 0x95,
2,
stage::allStages[9],
6,
@@ -2854,7 +2854,7 @@ namespace mod::item
nullptr,
nullptr },
/* 219 */
- { 0x20,
+ { 0x8B,
8,
stage::allStages[12],
10,
@@ -2867,7 +2867,7 @@ namespace mod::item
nullptr,
nullptr },
/* 220 */
- { 0x23,
+ { 0xBC,
2,
stage::allStages[12],
5,
@@ -2932,7 +2932,7 @@ namespace mod::item
nullptr,
nullptr },
/* 225 */
- { 0x24,
+ { 0xAB,
2,
stage::allStages[12],
4,
@@ -3101,7 +3101,7 @@ namespace mod::item
nullptr,
nullptr },
/* 238 */
- { 0x26,
+ { 0x96,
2,
stage::allStages[12],
2,
@@ -3192,7 +3192,7 @@ namespace mod::item
nullptr,
nullptr },
/* 245 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
1,
@@ -3205,7 +3205,7 @@ namespace mod::item
nullptr,
nullptr },
/* 246 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
2,
@@ -3218,7 +3218,7 @@ namespace mod::item
nullptr,
nullptr },
/* 247 */
- { 0x24,
+ { 0xAC,
2,
stage::allStages[15],
2,
@@ -3270,7 +3270,7 @@ namespace mod::item
nullptr,
nullptr },
/* 251 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
4,
@@ -3309,7 +3309,7 @@ namespace mod::item
nullptr,
nullptr },
/* 254 */
- { 0x23,
+ { 0xBD,
2,
stage::allStages[15],
5,
@@ -3322,7 +3322,7 @@ namespace mod::item
nullptr,
nullptr },
/* 255 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
5,
@@ -3361,7 +3361,7 @@ namespace mod::item
nullptr,
nullptr },
/* 258 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
7,
@@ -3374,7 +3374,7 @@ namespace mod::item
nullptr,
nullptr }, // PoT Central First Room Chest
/* 259 */
- { 0x26,
+ { 0x97,
2,
stage::allStages[15],
11,
@@ -3387,7 +3387,7 @@ namespace mod::item
nullptr,
nullptr }, // PoT Big Key Chest
/* 260 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
11,
@@ -3400,7 +3400,7 @@ namespace mod::item
nullptr,
nullptr }, // PoT Central Outdoor Chest
/* 261 */
- { 0x20,
+ { 0x8C,
8,
stage::allStages[15],
8,
@@ -3452,7 +3452,7 @@ namespace mod::item
nullptr,
nullptr }, // HC Graveyard Grave Switch Room Back Left Small Chest
/* 265 */
- { 0x20,
+ { 0x8D,
8,
stage::allStages[20],
9,
@@ -3465,7 +3465,7 @@ namespace mod::item
nullptr,
nullptr }, // HC Graveyard Owl Statue Chest
/* 266 */
- { 0x23,
+ { 0xBE,
2,
stage::allStages[20],
14,
@@ -3517,7 +3517,7 @@ namespace mod::item
nullptr,
nullptr }, // HC West Courtyard Central Small Chest
/* 270 */
- { 0x24,
+ { 0xAD,
2,
stage::allStages[20],
1,
@@ -3569,7 +3569,7 @@ namespace mod::item
nullptr,
nullptr }, // HC Main Hall Northwest Chest
/* 274 */
- { 0x20,
+ { 0x8D,
8,
stage::allStages[20],
15,
@@ -3582,7 +3582,7 @@ namespace mod::item
nullptr,
nullptr }, // HC Southeast Balcony Tower Chest
/* 275 */
- { 0x26,
+ { 0x98,
2,
stage::allStages[20],
15,
@@ -4414,7 +4414,7 @@ namespace mod::item
nullptr,
nullptr }, // camp HP
/* 339 */
- { 0x23,
+ { 0xBA,
2,
stage::allStages[27],
1,
@@ -4453,7 +4453,7 @@ namespace mod::item
nullptr,
nullptr },
/* 342 */
- { 0x20,
+ { 0x8D,
8,
stage::allStages[20],
13,
@@ -4466,7 +4466,7 @@ namespace mod::item
nullptr,
nullptr }, //
/* 343 */
- { 0x20,
+ { 0x85,
8,
stage::allStages[6],
7,
@@ -4599,7 +4599,7 @@ namespace mod::item
nullptr,
nullptr },
/* 353 */
- { 0x20,
+ { 0x8E,
8,
stage::allStages[55],
1,
@@ -6457,7 +6457,7 @@ namespace mod::item
0,
stage::allStages[54],
1,
- 0x6,
+ 0x7,
0x6,
0b000000000000000000000,
-235.256332,
@@ -6514,8 +6514,8 @@ namespace mod::item
13,
stage::allStages[45],
6,
- 0xFF,
- 0xFF,
+ 0x1,
+ 0x15,
0b000000000000000000000,
-39511.792969,
1100.000000,
@@ -6528,7 +6528,7 @@ namespace mod::item
13,
stage::allStages[44],
1,
- 0xFF,
+ 0x3,
0xFF,
0b000000000000000000000,
-1385.184692,
@@ -6542,7 +6542,7 @@ namespace mod::item
13,
stage::allStages[57],
8,
- 0xFF,
+ 0x5,
0xFF,
0b000000000000000000000,
-68497.195312,
@@ -6556,7 +6556,7 @@ namespace mod::item
13,
stage::allStages[57],
16,
- 0xFF,
+ 0x7,
0xFF,
0b000000000000000000000,
-55693.375000,
@@ -6570,7 +6570,7 @@ namespace mod::item
13,
stage::allStages[59],
0,
- 0xFF,
+ 0x9,
0xFF,
0b000000000000000000000,
-2930.295898,
@@ -6584,7 +6584,7 @@ namespace mod::item
13,
stage::allStages[48],
0,
- 0xFF,
+ 0x11,
0xFF,
0b000000000000000000000,
16308.677734,
@@ -6598,43 +6598,16 @@ namespace mod::item
13,
stage::allStages[53],
1,
- 0xFF,
+ 0x13,
0xFF,
0b000000000000000000000,
43.525406,
800.000000,
-10109.346680,
nullptr,
- nullptr },
+ nullptr }
- // Reekfish Scent
- /*504*/
- { 0xB3,
- 14,
- stage::allStages[50],
- 1,
- 0xFF,
- 0xFF,
- 0b000000000000000000000,
- 3673.396973,
- -5986.576172,
- 13185.018555,
- nullptr,
- nullptr },
- // Medicine Scent
- /*505*/
- { 0xB5,
- 14,
- stage::allStages[73],
- 2,
- 0xFF,
- 0xFF,
- 0b000000000000000000000,
- 7454.945801,
- -190.000000,
- -1734.022095,
- nullptr,
- nullptr } };
+ };
u16 checkPriorityOrder[24] = {
293, // fishing rod
diff --git a/source/mod.cpp b/source/mod.cpp
index ec990c3..2d28095 100644
--- a/source/mod.cpp
+++ b/source/mod.cpp
@@ -9,6 +9,7 @@
#include <tp/d_kankyo.h>
#include <tp/d_map_path_dmap.h>
#include <tp/d_meter2_info.h>
+#include <tp/d_msg_class.h>
#include <tp/d_msg_flow.h>
#include <tp/d_save.h>
#include <tp/d_stage.h>
@@ -18,6 +19,8 @@
#include <tp/f_op_actor_mng.h>
#include <tp/f_op_scene_req.h>
#include <tp/m_Do_controller_pad.h>
+#include <tp/processor.h>
+#include <tp/resource.h>
#include <cstdio>
#include <cstring>
@@ -27,6 +30,7 @@
#include "chestRando.h"
#include "controller.h"
#include "customChecks.h"
+#include "customMessage.h"
#include "defines.h"
#include "eventListener.h"
#include "game_patches.h"
@@ -51,6 +55,8 @@ namespace mod
int num_frames = 120;
int frame_counter = 0;
+ tp::d_stage::Actr EponaActr = { "Horse", 0x00000F0D, 0.f, 0.f, 0.f, 0, -180, 0, 0xFFFF };
+
void main()
{
Mod* mod = new Mod();
@@ -74,6 +80,8 @@ namespace mod
game_patch::assemblyOverwrites();
game_patch::increaseWalletSize();
game_patch::increaseClimbSpeed();
+ game_patch::setCustomItemData();
+ game_patch::setCustomItemFunctions();
// Causes issues right now (argarok cannot be beaten)
// game_patch::removeIBLimit();
@@ -185,11 +193,6 @@ namespace mod
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 );
@@ -212,17 +215,6 @@ namespace mod
hudConsole->addOption( page, "Early ToT?", &Singleton::getInstance()->isEarlyToTEnabled, 0x1 );
hudConsole->addOption( page, "Early PoT?", &Singleton::getInstance()->isEarlyPoTEnabled, 0x1 );
hudConsole->addOption( page, "Open HC?", &Singleton::getInstance()->isEarlyHCEnabled, 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");
@@ -261,6 +253,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
// hudConsole->addOption(page, "Coords as hex?", &coordsAreInHex, 0x1);
hudConsole->addOption( page, "GM Story Flag?", &Singleton::getInstance()->isGMStoryPatch, 0x1 );
hudConsole->addOption( page, "Start w/ Crstl?", &Singleton::getInstance()->startWithCrystal, 0x1 );
+ hudConsole->addOption( page, "Hidden Skills?", &Singleton::getInstance()->shuffleHiddenSkills, 0x1 );
hudConsole->addWatch( page, "CurrentEventID:", &gameInfo.eventSystem.currentEventID, 'x', WatchInterpretation::_u8 );
hudConsole->addWatch( page, "NextEventID:", &gameInfo.eventSystem.nextEventID, 'x', WatchInterpretation::_u8 );
@@ -281,161 +274,8 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
// Bgm Options
page = hudConsole->addPage( "BGM" );
hudConsole->addOption( page, "BGM Rando: ", &musicrando::musicRandoEnabled, 0x1 );
- hudConsole->addOption( page, "Enemy BGM: ", &musicrando::enemyBgmEnabled, 0x1 );
-
- // 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);*/
+ hudConsole->addOption( page, "No Enemy BGM?: ", &musicrando::enemyBgmDisabled, 0x1 );
+ hudConsole->addOption( page, "Item Fanfares: ", &musicrando::fanfareRandoEnabled, 0x1 );
// Print
hudConsole->draw();
@@ -476,15 +316,6 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
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,
@@ -557,15 +388,6 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
game_patch::skipMDHCS,
event::LoadEventAccuracy::Stage_Room_Spawn );
- // Fix FT Boss Music
- eventListener->addLoadEvent( stage::allStages[Stage_Diababa],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixFTBossMusic,
- event::LoadEventAccuracy::Stage );
-
// Allow Faron Escape
eventListener->addLoadEvent( stage::allStages[Stage_Faron_Woods],
0xFF,
@@ -593,163 +415,6 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
game_patch::setLanternFlag,
event::LoadEventAccuracy::Stage_Room_Spawn );
- // unset dungeon flags after beating dungeon
- eventListener->addLoadEvent( stage::allStages[Stage_Forest_Temple],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixFTState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Goron_Mines],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixGMState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Lakebed_Temple],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixLBTState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Arbiters_Grounds],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixAGState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Snowpeak_Ruins],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixSPRState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Temple_of_Time],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixToTState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_City_in_the_Sky],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::fixCiTSState,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- // set dungeon and boss flags
- eventListener->addLoadEvent( stage::allStages[Stage_Faron_Woods],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setFTDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- eventListener->addLoadEvent( stage::allStages[Stage_Death_Mountain_Sumo_Hall],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setGMDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Kakariko_Village],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setGMDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Fyrus],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setGMBossFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- eventListener->addLoadEvent( stage::allStages[Stage_Lake_Hylia],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setLakeDungeonFlags,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Morpheel],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setLBTBossFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- eventListener->addLoadEvent( stage::allStages[Stage_Bublin_Camp],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setAGDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Mirror_Chamber],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setAGDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Stallord],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setAGBossFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- eventListener->addLoadEvent( stage::allStages[Stage_Snowpeak],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setSPRDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Blizzeta],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setSPRBossFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- eventListener->addLoadEvent( stage::allStages[Stage_Sacred_Grove],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setToTDungeonFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
- eventListener->addLoadEvent( stage::allStages[Stage_Armogohma],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setToTBossFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
- eventListener->addLoadEvent( stage::allStages[Stage_Argorok],
- 0xFF,
- 0xFF,
- 0xFF,
- 0xFF,
- game_patch::setCiTSBossFlag,
- event::LoadEventAccuracy::Stage_Room_Spawn );
-
// Break Barrier
eventListener->addLoadEvent( stage::allStages[Stage_Castle_Town],
0xFF,
@@ -769,8 +434,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
// specific times
actorCommonLayerInit_trampoline = patch::hookFunction(
tp::d_stage::actorCommonLayerInit,
- []( void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4 )
- {
+ []( void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4 ) {
if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Faron_Woods] ) )
{
if ( Singleton::getInstance()->hasActorCommonLayerRan <= 4 )
@@ -793,12 +457,36 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
return global::modPtr->actorCommonLayerInit_trampoline( mStatus_roomControl, chunkTypeInfo, unk3, unk4 );
} );
- putSave_trampoline = patch::hookFunction( tp::d_save::putSave,
- []( tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID )
- {
- Singleton::getInstance()->hasActorCommonLayerRan = 0;
- return global::modPtr->putSave_trampoline( gameInfoPtr, areaID );
- } );
+ actorInit_always_trampoline = patch::hookFunction(
+ tp::d_stage::actorInit_always,
+ []( void* mStatus_roomControl, tp::d_stage::dzxChunkTypeInfo* chunkTypeInfo, int unk3, void* unk4 ) {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Faron_Woods] ) )
+ {
+ // Add Epona to the global Actor list
+ tp::d_stage::Actr* EponaActrPtr = &EponaActr;
+ tp::d_stage::dzxChunkTypeInfo chunkInfo;
+ strcpy( chunkInfo.tag, "ACTR" );
+ chunkInfo.numChunks = 0x1;
+ typeTransform<u32, float> X, Y, Z;
+ X.a = 0x0;
+ Y.a = 0x0;
+ Z.a = 0x0;
+ EponaActrPtr->pos[0] = X.b;
+ EponaActrPtr->pos[1] = Y.b;
+ EponaActrPtr->pos[2] = Z.b;
+ chunkInfo.chunkDataPtr = EponaActrPtr;
+ // Add the actor to the actor list
+ global::modPtr->actorInit_always_trampoline( mStatus_roomControl, &chunkInfo, 0, nullptr );
+ }
+
+ return global::modPtr->actorCommonLayerInit_trampoline( mStatus_roomControl, chunkTypeInfo, unk3, unk4 );
+ } );
+
+ putSave_trampoline =
+ patch::hookFunction( tp::d_save::putSave, []( tp::d_com_inf_game::GameInfo* gameInfoPtr, s32 areaID ) {
+ Singleton::getInstance()->hasActorCommonLayerRan = 0;
+ return global::modPtr->putSave_trampoline( gameInfoPtr, areaID );
+ } );
checkTreasureRupeeReturn_trampoline = patch::hookFunction(
tp::d_a_alink::checkTreasureRupeeReturn,
@@ -806,8 +494,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
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] )
- {
+ []( 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]);
@@ -820,8 +507,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
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] )
- {
+ []( 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" );
@@ -838,8 +524,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
const float unk5[3],
float unk6,
float unk7,
- s32 unk8 )
- {
+ s32 unk8 ) {
// Call replacement function
item = global::modPtr->procItemCreateFunc( pos, item, "createItemForBoss" );
@@ -848,8 +533,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
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 )
- {
+ []( 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" );
@@ -858,8 +542,7 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
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 )
- {
+ []( 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" );
@@ -868,127 +551,558 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
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 )
- {
+ []( 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 ); } );
+ 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 ); } );
+ query022_trampoline = patch::hookFunction( tp::d_msg_flow::query022, []( void* unk1, void* unk2, s32 unk3 ) {
+ return global::modPtr->proc_query022( unk1, unk2, unk3 );
+ } );
+ query023_trampoline = patch::hookFunction( tp::d_msg_flow::query023, []( void* unk1, void* unk2, s32 unk3 ) {
+ return global::modPtr->proc_query023( unk1, unk2, unk3 );
+ } );
- // Always allow to buy arrows
- query024_trampoline = patch::hookFunction(tp::d_msg_flow::query024, [](void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused) {
- return true;
- });
+ query024_trampoline = patch::hookFunction(
+ tp::d_msg_flow::query024,
+ []( void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused ) {
+ return global::modPtr->proc_query024( dMsgFlow_cPtr, mesg_flow_node_branchPtr, fopAc_ac_cPtr, unused );
+ } );
- do_link_trampoline = patch::hookFunction( tp::dynamic_link::do_link,
- []( tp::dynamic_link::DynamicModuleControl* dmc )
- { return global::modPtr->procDoLink( dmc ); } );
+ query025_trampoline = patch::hookFunction( tp::d_msg_flow::query025, []( void* unk1, void* unk2, s32 unk3 ) {
+ return global::modPtr->proc_query025( unk1, unk2, unk3 );
+ } );
+
+ isEventBit_trampoline = patch::hookFunction( tp::d_save::isEventBit, []( u8* eventSystem, u16 indexNumber ) {
+ return global::modPtr->proc_isEventBit( eventSystem, indexNumber );
+ } );
+
+ onEventBit_trampoline = patch::hookFunction( tp::d_save::onEventBit, []( u8* eventSystem, u16 indexNumber ) {
+ if ( indexNumber == 0x1E08 && ( gameInfo.scratchPad.form == 1 ) )
+ {
+ gameInfo.scratchPad.form = 0;
+ }
+ return global::modPtr->onEventBit_trampoline( eventSystem, indexNumber );
+ } );
+
+ setGetItemFace_trampoline = patch::hookFunction( tp::d_a_alink::setGetItemFace, []( void* daAlink_c, u16 itemId ) {
+ switch ( itemId )
+ {
+ case items::Shadow_Crystal:
+ {
+ itemId = items::Clawshot;
+ break;
+ }
+ case items::Master_Sword:
+ {
+ itemId = items::Clawshot;
+ break;
+ }
+ case items::Master_Sword_Light:
+ {
+ itemId = items::Clawshot;
+ break;
+ }
+ default:
+ {
+ return global::modPtr->setGetItemFace_trampoline( daAlink_c, itemId );
+ }
+ }
+ return global::modPtr->setGetItemFace_trampoline( daAlink_c, itemId );
+ } );
+
+ 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 );
- } );
+ 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 );
+ return global::modPtr->setItemBombNumCount_trampoline( unk1, bagNb, amount );
+ } );
+ isDungeonItem_trampoline = patch::hookFunction( tp::d_save::isDungeonItem, []( void* memBitPtr, const int param_1 ) {
+ return global::modPtr->proc_isDungeonItem( memBitPtr, param_1 );
+ } );
+
+ getLayerNo_common_common_trampoline = patch::hookFunction(
+ tp::d_com_inf_game::getLayerNo_common_common,
+ []( const char* stageName, int roomId, int layerOverride ) {
+ int chosenLayer;
+ bool condition;
+ // Bublin Camp
+ bool stageComparison = strcmp( stageName, "F_SP118" );
+ if ( stageComparison == 0 )
+ {
+ condition = tp::d_a_alink::dComIfGs_isEventBit( 0xb40 ); // Escaped Burning Tent in Bublin Camp
+ if ( condition != false )
+ {
+ if ( ( gameInfo.localAreaNodes.unk_0[0xB] & 0x10 ) == 0 )
+ {
+ chosenLayer = 0x1;
+ }
+ else
+ {
+ chosenLayer = 0x3;
+ }
+ }
+ else
+ {
+ chosenLayer = 0x0;
+ }
+ return chosenLayer;
+ }
+ stageComparison = strcmp( stageName, "F_SP117" );
+ if ( ( stageComparison == 0 ) && ( Singleton::getInstance()->isEarlyToTEnabled == 1 ) )
+ {
+ chosenLayer = 0x2;
+ return chosenLayer;
+ }
+ return global::modPtr->getLayerNo_common_common_trampoline( stageName, roomId, layerOverride );
+ } );
+
+ setMessageCode_inSequence_trampoline = patch::hookFunction(
+ tp::control::setMessageCode_inSequence,
+ []( tp::control::TControl* control, const void* TProcessor, u16 unk3, u16 msgId ) {
+ // Call the original function immediately, as a lot of stuff needs to be set before our code runs
+ const bool ret = global::modPtr->setMessageCode_inSequence_trampoline( control, TProcessor, unk3, msgId );
+
+ // Make sure the function ran successfully
+ if ( !ret )
+ {
+ return ret;
+ }
+
+ // Check if the current text is for an item
+ s32 index = global::modPtr->getItemIdFromMsgId( TProcessor, unk3, msgId );
+ // The current text is for an item
+ switch ( static_cast<u32>( index ) )
+ {
+ const char* replacementText;
+ case items::Forest_Temple_Small_Key:
+ {
+ replacementText = customMessage::customForestSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Forest_Temple_Dungeon_Map:
+ {
+ replacementText = customMessage::customForestMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Forest_Temple_Compass:
+ {
+ replacementText = customMessage::customForestCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Forest_Temple_Big_Key:
+ {
+ replacementText = customMessage::customForestBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Goron_Mines_Small_Key:
+ {
+ replacementText = customMessage::customMinesSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Goron_Mines_Dungeon_Map:
+ {
+ replacementText = customMessage::customMinesMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Goron_Mines_Compass:
+ {
+ replacementText = customMessage::customMinesCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Lakebed_Temple_Small_Key:
+ {
+ replacementText = customMessage::customLakebedSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Lakebed_Temple_Dungeon_Map:
+ {
+ replacementText = customMessage::customLakebedMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Lakebed_Temple_Compass:
+ {
+ replacementText = customMessage::customLakebedCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Lakebed_Temple_Big_Key:
+ {
+ replacementText = customMessage::customLakebedBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Arbiters_Grounds_Small_Key:
+ {
+ replacementText = customMessage::customArbitersSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Arbiters_Grounds_Dungeon_Map:
+ {
+ replacementText = customMessage::customArbitersMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Arbiters_Grounds_Compass:
+ {
+ replacementText = customMessage::customArbitersCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Arbiters_Grounds_Big_Key:
+ {
+ replacementText = customMessage::customArbitersBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Snowpeak_Ruins_Small_Key:
+ {
+ replacementText = customMessage::customSnowpeakSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Snowpeak_Ruins_Dungeon_Map:
+ {
+ replacementText = customMessage::customSnowpeakMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Snowpeak_Ruins_Compass:
+ {
+ replacementText = customMessage::customSnowpeakCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Temple_of_Time_Small_Key:
+ {
+ replacementText = customMessage::customToTSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Temple_of_Time_Dungeon_Map:
+ {
+ replacementText = customMessage::customToTMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Temple_of_Time_Compass:
+ {
+ replacementText = customMessage::customToTCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Temple_of_Time_Big_Key:
+ {
+ replacementText = customMessage::customToTBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::City_in_The_Sky_Small_Key:
+ {
+ replacementText = customMessage::customCitySKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::City_in_The_Sky_Dungeon_Map:
+ {
+ replacementText = customMessage::customCityMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::City_in_The_Sky_Compass:
+ {
+ replacementText = customMessage::customCityCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::City_in_The_Sky_Big_Key:
+ {
+ replacementText = customMessage::customCityBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Palace_of_Twilight_Small_Key:
+ {
+ replacementText = customMessage::customPalaceSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Palace_of_Twilight_Dungeon_Map:
+ {
+ replacementText = customMessage::customPalaceMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Palace_of_Twilight_Compass:
+ {
+ replacementText = customMessage::customPalaceCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Palace_of_Twilight_Big_Key:
+ {
+ replacementText = customMessage::customPalaceBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Hyrule_Castle_Small_Key:
+ {
+ replacementText = customMessage::customCastleSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Hyrule_Castle_Dungeon_Map:
+ {
+ replacementText = customMessage::customCastleMapText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Hyrule_Castle_Compass:
+ {
+ replacementText = customMessage::customCastleCompassText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Hyrule_Castle_Big_Key:
+ {
+ replacementText = customMessage::customCastleBigKeyText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Shadow_Crystal:
+ {
+ replacementText = customMessage::customCrystalText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Ending_Blow:
+ {
+ replacementText = customMessage::endingBlowText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Shield_Attack:
+ {
+ replacementText = customMessage::shieldAttackText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Back_Slice:
+ {
+ replacementText = customMessage::backSliceText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Helm_Splitter:
+ {
+ replacementText = customMessage::helmSplitterText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Mortal_Draw:
+ {
+ replacementText = customMessage::mortalDrawText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Jump_Strike:
+ {
+ replacementText = customMessage::jumpStrikeText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+ case items::Great_Spin:
+ {
+ replacementText = customMessage::greatSpinText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Item::Bublin_Camp_Key:
+ {
+ replacementText = customMessage::customBublinSKText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ case items::Dominion_Rod_Uncharged:
+ {
+ replacementText = customMessage::customPoweredRodText;
+ control->msg = replacementText;
+ control->wMsgRender = replacementText;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ return ret;
+ } );
+
+ getFontCCColorTable_trampoline = patch::hookFunction( tp::d_msg_class::getFontCCColorTable, []( u8 colorId, u8 unk ) {
+ if ( colorId >= 0x9 )
+ {
+ return global::modPtr->getCustomMsgColor( colorId );
+ }
+ else
+ {
+ return global::modPtr->getFontCCColorTable_trampoline( colorId, unk );
+ }
+ } );
+
+ getFontGCColorTable_trampoline = patch::hookFunction( tp::d_msg_class::getFontGCColorTable, []( u8 colorId, u8 unk ) {
+ if ( colorId >= 0x9 )
+ {
+ return global::modPtr->getCustomMsgColor( colorId );
+ }
+ else
+ {
+ return global::modPtr->getFontGCColorTable_trampoline( colorId, unk );
+ }
+ } );
+
+ checkItemGet_trampoline = patch::hookFunction( tp::d_item::checkItemGet, []( u8 item, s32 defaultValue ) {
+ return global::modPtr->proc_checkItemGet( item, defaultValue );
+ } );
+
+ parseCharacter1Byte_trampoline = patch::hookFunction( tp::resource::parseCharacter_1Byte, []( const char** text ) {
+ const char* bigWalletRupeeText = { "600 Rupees" MSG_COLOR( MSG_COLOR_WHITE ) "!" };
+ const char* giantWalletRupeeText = { "1,000 Rupees" MSG_COLOR( MSG_COLOR_WHITE ) "!" };
+ const char* pauseWalletRupeeText = { "1,000 Rupees." };
+
+ if ( strncmp( *text, bigWalletRupeeText, strlen( bigWalletRupeeText ) ) == 0 )
+ {
+ // Replacement text
+ const char* replacementText = { "5,000 Rupees" MSG_COLOR( MSG_COLOR_WHITE ) "!" };
+ *text = replacementText;
+ }
+ if ( strncmp( *text, giantWalletRupeeText, strlen( giantWalletRupeeText ) ) == 0 )
+ {
+ // Replacement text
+ const char* replacementText = { "9,999 Rupees" MSG_COLOR( MSG_COLOR_WHITE ) "!" };
+ *text = replacementText;
+ }
+ else if ( strncmp( *text, pauseWalletRupeeText, strlen( pauseWalletRupeeText ) ) == 0 )
+ {
+ // Replacement text
+ switch ( gameInfo.scratchPad.equippedWallet )
+ {
+ case 0x0:
+ {
+ const char* replacementText = { "1,000 Rupees." };
+ *text = replacementText;
+ break;
+ }
+ case 0x1:
+ {
+ const char* replacementText = { "5,000 Rupees." };
+ *text = replacementText;
+ break;
+ }
+ case 0x2:
+ {
+ const char* replacementText = { "9,999 Rupees." };
+ *text = replacementText;
+ break;
+ }
+ }
+ }
+
+ return global::modPtr->parseCharacter1Byte_trampoline( text );
+ } );
}
void Mod::procNewFrame()
@@ -1107,9 +1221,9 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
eventListener->checkLoadEvents();
// Check if there's a random seed in the current save data
- if ( *global::seedInSaveFile > 0 && *global::seedInSaveFile != tools::randomSeed )
+ if ( ( *global::seedInSaveFile > 0 ) && ( *global::seedInSaveFile != tools::randomSeed ) )
{
- customSeed = true;
+ customSeed = 1;
tools::randomSeed = *global::seedInSaveFile;
chestRandomizer->generate();
musicrando::initMusicRando();
@@ -1163,7 +1277,8 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
// Check if we have a seed sitting in our save file somewhere and if so, apply this automatically (unless custom
// seed is turned on)
- if ( !customSeed && *global::seedInSaveFile > 0 )
+ if ( !customSeed && ( *global::seedInSaveFile > 0 ) &&
+ !tp::d_a_alink::checkStageName( stage::allStages[Stage_Title_Screen] ) )
{
tools::randomSeed = *global::seedInSaveFile;
}
@@ -1376,22 +1491,16 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
reorderItemWheel();
- allowShopItemsAnytime();
-
giveAllScents();
fixYetaAndYeto();
- fixLBTBossDoor();
-
preventPoweringUpDomRod();
// Call original function
fapGm_Execute_trampoline();
changeLanternColor();
- // setFieldModels();
- fixFTTotemMonkey();
}
s32 Mod::procItemCreateFunc( const float pos[3], s32 item, const char funcIdentifier[32] )
@@ -1454,6 +1563,116 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
return query022_trampoline( unk1, unk2, unk3 );
}
+ bool Mod::proc_query023( void* unk1, void* unk2, s32 unk3 )
+ {
+ // Check to see if currently in the Kakariko Interiors. Specifically in Barnes' Bomb Shop
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Kakariko_Interiors] ) &&
+ tp::d_kankyo::env_light.currentRoom == 1 )
+ {
+ // If player has not bought Barnes' Bomb Bag, we want to allow them to be able to get the check.
+ if ( ( !tp::d_a_alink::dComIfGs_isEventBit( 0x908 ) ) )
+ {
+ return false;
+ }
+ // If the player has bought the bomb bag check, we won't allow them to get the check, regardless of if they have
+ // bombs or not
+ else
+ {
+ return true;
+ }
+ }
+
+ // Call original function if the conditions aren't met.
+ return query023_trampoline( unk1, unk2, unk3 );
+ }
+
+ bool Mod::proc_query024( void* dMsgFlow_cPtr, void* mesg_flow_node_branchPtr, void* fopAc_ac_cPtr, int unused )
+ {
+ // Check to see if currently in the Castle Town. Specifically in the central square
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Castle_Town] ) && tp::d_kankyo::env_light.currentRoom == 0 )
+ {
+ return true; // Allow the player to buy arrows, even if the quiver is full
+ }
+ // Call original function if the conditions aren't met.
+ return query024_trampoline( dMsgFlow_cPtr, mesg_flow_node_branchPtr, fopAc_ac_cPtr, unused );
+ }
+
+ bool Mod::proc_query025( void* unk1, void* unk2, s32 unk3 )
+ {
+ // Check to see if currently in a shop and that we have the bottle requirement enabled
+ if ( isStageShop() && ( allowBottleItemsShopAnytime == 1 ) )
+ {
+ // Tell the game that we have an empty bottle, even if we don't
+ return false;
+ }
+ // Call original function if the conditions aren't met.
+ return query025_trampoline( unk1, unk2, unk3 );
+ }
+
+ bool Mod::proc_isDungeonItem( void* memBitPtr, const int param_1 )
+ {
+ u32 totalMainDungeonStages = sizeof( stage::mainDungeonStages ) / sizeof( stage::mainDungeonStages[0] );
+ for ( u32 i = 0; i < totalMainDungeonStages; i++ )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::mainDungeonStages[i] ) && ( param_1 == 3 ) )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Forest_Temple] ) && ( param_1 == 7 ) &&
+ ( ( tp::d_kankyo::env_light.currentRoom == 3 ) || ( tp::d_kankyo::env_light.currentRoom == 1 ) ) )
+ {
+ return false;
+ }
+ return false;
+ }
+ }
+
+ // Call original function
+ return isDungeonItem_trampoline( memBitPtr, param_1 );
+ }
+
+ bool Mod::proc_isEventBit( u8* eventSystem, u16 indexNumber )
+ {
+ if ( ( ( indexNumber == 0x2280 ) || ( indexNumber == 0x2320 ) || ( indexNumber == 0x3E02 ) ) &&
+ tp::d_a_alink::checkStageName( stage::allStages[Stage_Hidden_Village] ) )
+ {
+ if ( ( ( gameInfo.scratchPad.eventBits[0x22] & 0x80 ) == 0 ) )
+ {
+ return false;
+ }
+ }
+ else if ( Singleton::getInstance()->isEarlyHCEnabled == 0 && ( indexNumber == 0x5410 ) &&
+ ( ( gameInfo.scratchPad.allAreaNodes.Palace_of_Twilight.dungeon.bossBeaten == 0 ) ) )
+ {
+ return false;
+ }
+
+ else
+ {
+ u32 totalAllDungeonStages = sizeof( stage::allDungeonStages ) / sizeof( stage::allDungeonStages[0] );
+ u32 totalStageFlags = sizeof( game_patch::dungeonStoryFlags ) / sizeof( game_patch::dungeonStoryFlags[0] );
+ for ( u32 i = 0; i < totalAllDungeonStages; i++ )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allDungeonStages[i] ) )
+ {
+ for ( u32 j = 0; j < totalStageFlags; j++ )
+ {
+ if ( indexNumber == game_patch::dungeonStoryFlags[j] )
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Zant_Main] ) &&
+ ( gameInfo.localAreaNodes.dungeon.bossBeaten != 0 ) )
+ {
+ return isEventBit_trampoline( eventSystem, indexNumber );
+ }
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ // Call original function
+ return isEventBit_trampoline( eventSystem, indexNumber );
+ }
+
bool Mod::procDoLink( tp::dynamic_link::DynamicModuleControl* dmc )
{
// Call the original function immediately, as the REL file needs to be linked before applying patches
@@ -1480,6 +1699,48 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
*reinterpret_cast<u32*>( relPtrRaw + 0x1A44 ) = 0x48000028; // b 0x28
break;
}
+ case 0x280: // d_a_obj_swBallC.rel - Light Sword Cutscene
+ {
+ item::ItemCheck* itemCheck = &item::checks[495]; // Light Sword Item
+ // Check if the item has a replacement
+ if ( itemCheck->destination )
+ {
+ // Replace Item given
+ *reinterpret_cast<u32*>( relPtrRaw + 0xC10 ) =
+ SET_LOAD_IMMEDIATE( 3, itemCheck->destination->itemID ); // 38600000 + item ID
+ // Replace Item Get text
+ *reinterpret_cast<u32*>( relPtrRaw + 0xCD8 ) = SET_LOAD_IMMEDIATE(
+ 3,
+ ( itemCheck->destination->itemID + 0x65 ) ); // 38600000 + item index (item ID + 0x65)
+ }
+
+ // The cutscene gives link the MS during the cutscene by default, so we just nop out the link to the function.
+ *reinterpret_cast<u32*>( relPtrRaw + 0xB50 ) = 0x60000000;
+ break;
+ }
+ case 0x1FA: // d_a_obj_kshutter.rel - Doors that do not cause a cutscene after opened
+ {
+ if ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Lakebed_Temple] ) &&
+ ( tp::d_kankyo::env_light.currentRoom == 3 ) )
+ {
+ // Set it to not remove a small key from the inventory when opening the boss door
+ *reinterpret_cast<u32*>( relPtrRaw + 0x1198 ) = 0x60000000; // Previous: 0x3803ffff
+ }
+ break;
+ }
+ case 0x13F: // d_a_npc_impal.rel - Impaz
+ {
+ item::ItemCheck* itemCheck1 = &item::checks[327]; // Ilia's Charm Item
+ item::ItemCheck* itemCheck2 = &item::checks[466]; // Empty Skybook Item
+ // Replace the Ilias Charm item
+ *reinterpret_cast<u32*>( relPtrRaw + 0x2D98 ) =
+ SET_LOAD_IMMEDIATE( 4, itemCheck1->destination->itemID ); // 38800000 + item ID
+ // Replace the Ancient Skybook Item
+ *reinterpret_cast<u32*>( relPtrRaw + 0x3240 ) =
+ SET_LOAD_IMMEDIATE( 4, itemCheck2->destination->itemID ); // 38800000 + item ID
+
+ break;
+ }
default:
{
break;
@@ -1502,6 +1763,82 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
}
}
+ s32 Mod::proc_checkItemGet( u8 item, s32 defaultValue )
+ {
+ // Check to see if currently in one of the Ordon interiors
+ switch ( item )
+ {
+ case items::Hylian_Shield:
+ {
+ // Check if we are at Kakariko Malo mart and verify that we have not bought the shield.
+ if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Kakariko_Interiors] ) &&
+ tp::d_kankyo::env_light.currentRoom == 3 ) &&
+ ( ( gameInfo.localAreaNodes.unk_0[0xC] & 0x2 ) == 0 ) )
+ {
+ // Return false so we can buy the shield.
+ return 0;
+ }
+ // Check if we are at Castle Town Goron Shops and verify that we have not bought the shield.
+ // Since there is not a flag for this, we will just check if the randomizer has set a nullptr for the check.
+ else if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Castle_Town_Shops] ) &&
+ tp::d_kankyo::env_light.currentRoom == 4 ) )
+ {
+ // Return false so we can buy the shield.
+ return 0;
+ }
+ }
+ case items::Hawkeye:
+ {
+ // Check if we are at Kakariko Village and that the hawkeye is currently not for sale.
+ if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Kakariko_Village] ) &&
+ ( ( gameInfo.localAreaNodes.unk_0[0xC] & 0x40 ) == 0 ) ) )
+ {
+ // Return false so we can buy the hawkeye.
+ return 0;
+ }
+ }
+ case items::Ordon_Shield:
+ {
+ // Check if we are at Kakariko Malo mart.
+ if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Kakariko_Interiors] ) &&
+ tp::d_kankyo::env_light.currentRoom == 3 ) )
+ {
+ // Return false so we can buy the wooden shield.
+ return 0;
+ }
+ // Check if we are at the Death Mountain Goron Shop.
+ else if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Death_Mountain] ) &&
+ tp::d_kankyo::env_light.currentRoom == 3 ) )
+ {
+ // Return false so we can buy the shield.
+ return 0;
+ }
+ }
+ case items::Wooden_Shield:
+ {
+ // Check if we are at Kakariko Malo mart.
+ if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Kakariko_Interiors] ) &&
+ tp::d_kankyo::env_light.currentRoom == 3 ) )
+ {
+ // Return false so we can buy the wooden shield.
+ return 0;
+ }
+ // Check if we are at the Death Mountain Goron Shop.
+ else if ( ( tp::d_a_alink::checkStageName( stage::allStages[Stage_Death_Mountain] ) &&
+ tp::d_kankyo::env_light.currentRoom == 3 ) )
+ {
+ // Return false so we can buy the shield.
+ return 0;
+ }
+ }
+ default:
+ {
+ // Call original function if the conditions are not met.
+ return global::modPtr->checkItemGet_trampoline( item, defaultValue );
+ }
+ }
+ }
+
void Mod::giveAllScents()
{
// code to have all scents at once you need to unlock them tho
@@ -1701,224 +2038,6 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
}
}
- 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 ( ( gameInfo.scratchPad.eventBits[0x9] & 0x8 ) == 0 /*didn't buy bomb bag yet*/ && bombBagTrickOn == 0 &&
- tp::d_a_alink::checkStageName( "R_SP109" ) && tp::d_kankyo::env_light.currentRoom == 1 &&
- linkPos[2] > -600 )
- {
- bombBag1Contents = gameInfo.scratchPad.itemWheel.Bomb_Bag_1;
- 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 ( ( gameInfo.scratchPad.eventBits[0x9] & 0x8 ) != 0 /*bought bomb bag*/ && bombBagTrickOn == 1 )
- { // bought bomb bag check
- gameInfo.scratchPad.itemWheel.Bomb_Bag_1 = bombBag1Contents;
- gameInfo.scratchPad.itemWheel.Bomb_Bag_2 = bombBag2Contents;
- 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;
@@ -2085,36 +2204,6 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
}
}
- 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::fixFTTotemMonkey()
- {
- if ( tp::d_a_alink::checkStageName( "D_MN05" ) && tp::d_kankyo::env_light.currentRoom == 12 )
- {
- if ( ( gameInfo.localAreaNodes.unk_0[0xA] & 0x4 ) != 0 )
- {
- gameInfo.localAreaNodes.unk_0[0x12] |= 0x1;
- }
- }
- }
-
void Mod::preventPoweringUpDomRod()
{
if ( gameInfo.scratchPad.itemWheel.Sky_Book == 0xFF && tools::checkItemFlag( ItemFlags::Ancient_Sky_Book_empty ) &&
@@ -2293,35 +2382,30 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
// Check to see if link is riding a snowboard
if ( tp::d_a_alink::checkBoardRide( linkMapPtr ) )
{
- strcpy( sysConsolePtr->consoleLine[20].line, "-> on board" );
return false;
}
// Check to see if link is riding the canoe
if ( tp::d_a_alink::checkCanoeRide( linkMapPtr ) )
{
- strcpy( sysConsolePtr->consoleLine[20].line, "-> on canoe" );
return false;
}
// Check to see if link is riding Epona
if ( tp::d_a_alink::checkHorseRide( linkMapPtr ) )
{
- strcpy( sysConsolePtr->consoleLine[20].line, "-> on horse" );
return false;
}
// Check to see if link is riding a boar
if ( tp::d_a_alink::checkBoarRide( linkMapPtr ) )
{
- strcpy( sysConsolePtr->consoleLine[20].line, "-> on boar" );
return false;
}
// Check to see if link is riding the spinner
if ( tp::d_a_alink::checkSpinnerRide( linkMapPtr ) )
{
- strcpy( sysConsolePtr->consoleLine[20].line, "-> on spinner" );
return false;
}
@@ -2330,7 +2414,6 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
return false;
}
- strcpy( sysConsolePtr->consoleLine[20].line, "-> Can Transform" );
return true;
}
@@ -2363,4 +2446,111 @@ hudConsole->addWatch(page, "throw:", &throwResult, 'x', WatchInterpretation::_u1
return true;
}
+ s32 Mod::getMsgIndex( const void* TProcessor, u16 unk2, u32 msgId )
+ {
+ void* unk = tp::processor::getResource_groupID( TProcessor, unk2 );
+ if ( !unk )
+ {
+ return -1;
+ }
+
+ gc::bmgres::TextIndexTable* textIndexTable =
+ *reinterpret_cast<gc::bmgres::TextIndexTable**>( reinterpret_cast<u32>( unk ) + 0xC );
+
+ gc::bmgres::MessageEntry* entry = &textIndexTable->entry[0];
+ u32 loopCount = textIndexTable->numEntries;
+
+ for ( u32 i = 0; i < loopCount; i++ )
+ {
+ if ( entry->messageId == msgId )
+ {
+ return static_cast<s32>( i );
+ }
+ entry++;
+ }
+
+ // Didn't find the index
+ return -1;
+ }
+
+ s32 Mod::getItemMsgIndex( const void* TProcessor, u16 unk2, u32 itemId )
+ {
+ // Increment itemId to be at the start of the table entries for items
+ u32 msgId = itemId + 0x65;
+ return getMsgIndex( TProcessor, unk2, msgId );
+ }
+
+ s32 Mod::getItemIdFromMsgId( const void* TProcessor, u16 unk3, u32 msgId )
+ {
+ void* unk = tp::processor::getResource_groupID( TProcessor, unk3 );
+ if ( !unk )
+ {
+ return -1;
+ }
+
+ gc::bmgres::TextIndexTable* textIndexTable =
+ *reinterpret_cast<gc::bmgres::TextIndexTable**>( reinterpret_cast<u32>( unk ) + 0xC );
+
+ gc::bmgres::MessageEntry* entry = &textIndexTable->entry[0];
+ u32 loopCount = textIndexTable->numEntries;
+
+ // Loop through the item IDs until msgId is found
+ u32 itemId = items::Item::Recovery_Heart;
+ for ( u32 i = 0; i < loopCount; i++ )
+ {
+ u16 entryMessageId = entry->messageId;
+ if ( entryMessageId == ( itemId + 0x64 ) )
+ {
+ if ( entryMessageId == msgId )
+ {
+ return static_cast<s32>( itemId );
+ }
+ else
+ {
+ itemId++;
+
+ // Make sure itemId is valid
+ if ( itemId > items::Item::NullItem )
+ {
+ break;
+ }
+ }
+ }
+ entry++;
+ }
+
+ // Didn't find the index
+ return -1;
+ }
+
+ u32 Mod::getCustomMsgColor( u8 colorId )
+ {
+ u32 newColorCode; // RGBA
+ switch ( colorId )
+ {
+ case CUSTOM_MSG_COLOR_DARK_GREEN_HEX:
+ {
+ newColorCode = 0x4BBE4BFF;
+ break;
+ }
+ case CUSTOM_MSG_COLOR_BLUE_HEX:
+ {
+ newColorCode = 0x4B96D7FF;
+ break;
+ }
+ case CUSTOM_MSG_COLOR_SILVER_HEX:
+ {
+ newColorCode = 0xBFBFBFFF;
+ break;
+ }
+ default:
+ {
+ // Return the color white if there is not a match
+ newColorCode = 0xFFFFFFFF;
+ break;
+ }
+ }
+ return newColorCode;
+ }
+
} // namespace mod \ No newline at end of file
diff --git a/source/musicRando.cpp b/source/musicRando.cpp
index 1f225b5..9015ebf 100644
--- a/source/musicRando.cpp
+++ b/source/musicRando.cpp
@@ -30,7 +30,8 @@ static const BGM bgmSource[] = {
// Some fanfares can't be played using the current method as when subStartBgm is called it includes additional logic on some,
// such as stopping the main music track
-static const u8 fanfareSrc[] = { 0x0a, 0x0b, 0x12, 0x14, 0x1c, 0x43, 0x44, 0x45, 0x46, 0x81, 0x82, 0x83, 0x9c, 0x9d, 0xa0 };
+static const u8 fanfareSrc[] =
+ { 0x0a, 0x0b, 0x14, 0x1c, 0x43, 0x44, 0x45, 0x46, 0x81, 0x82, 0x83, 0x98, 0x99, 0x9c, 0x9d, 0xa0, 0xa3, 0xa4 };
static const u8 bgmSource_length = sizeof( bgmSource ) / sizeof( BGM );
@@ -49,7 +50,10 @@ void ( *sceneChange_trampoline )( Z2SceneMgr* sceneMgr,
u8 DemoWave,
bool param_7 ) = nullptr;
void ( *startBattleBgm_trampoline )( Z2SeqMgr* seqMgr, bool param_1 ) = nullptr;
-void ( *subBgmStart_trampoline )( Z2SeqMgr* seqMgr, u32 id ) = nullptr;
+void ( *startSound_trampoline )( struct Z2SoundMgr* soundMgr,
+ JAISoundID soundId,
+ struct JAISoundHandle* soundHandle,
+ struct TVec3* pos ) = nullptr;
static void sceneChangeHook( Z2SceneMgr* sceneMgr,
JAISoundID BGMId,
@@ -107,47 +111,72 @@ static void sceneChangeHook( Z2SceneMgr* sceneMgr,
}
}
-static void subBgmStartHook( Z2SeqMgr* seqMgr, u32 id )
+extern "C"
{
- id = id - 0x1000000;
- u8 index = 0;
- bool found = false;
- for ( u8 i = 0; i < fanfareSourceLength; i++ )
+ void startSound( struct Z2SoundMgr* soundMgr, JAISoundID soundId, struct JAISoundHandle* soundHandle, struct TVec3* pos );
+}
+
+void startSoundHook( struct Z2SoundMgr* soundMgr, JAISoundID soundId, struct JAISoundHandle* soundHandle, struct TVec3* pos )
+{
+ u32 id = soundId.id;
+ if ( mod::musicrando::fanfareRandoEnabled && id >= 0x1000000 && id < 0x2000000)
{
- if ( randomizedFanfares[i] == id )
+ u32 id = soundId.id;
+ id = id - 0x1000000;
+ u8 index = 0;
+ bool found = false;
+ for ( u8 i = 0; i < fanfareSourceLength; i++ )
{
- index = i;
- found = true;
- break;
+ if ( randomizedFanfares[i] == id )
+ {
+ index = i;
+ found = true;
+ break;
+ }
+ }
+ if ( found )
+ {
+ u32 newId = fanfareSrc[index] + 0x1000000;
+ JAISoundID newIdSound;
+ newIdSound.id = newId;
+ startSound_trampoline( soundMgr, newIdSound, soundHandle, pos );
+ }
+ else
+ {
+ startSound_trampoline( soundMgr, soundId, soundHandle, pos );
}
- }
- if ( found )
- {
- u32 newId = fanfareSrc[index] + 0x1000000;
- subBgmStart_trampoline( seqMgr, newId );
}
else
{
- subBgmStart_trampoline( seqMgr, id );
+ startSound_trampoline( soundMgr, soundId, soundHandle, pos );
}
}
static void startBattleBgmHook( Z2SeqMgr* seqMgr, bool param_1 )
{
- if ( mod::musicrando::enemyBgmEnabled )
+ if ( !mod::musicrando::enemyBgmDisabled )
{
startBattleBgm_trampoline( seqMgr, param_1 );
}
}
+static u32 getRandomWithSeedReference( u32 max, u64* seed )
+{
+ u64 z = ( *seed += 0x9e3779b97f4a7c15 );
+ z = ( z ^ ( z >> 30 ) ) * 0xbf58476d1ce4e5b9;
+ z = ( z ^ ( z >> 27 ) ) * 0x94d049bb133111eb;
+ return ( z % max );
+}
+
static void randomizeTable( void* srcTable, u8 destTable[], size_t srcTableElementSize, size_t tableSize )
{
+ u64 seedCopy = mod::tools::randomSeed;
for ( u8 i = 0; i < tableSize; i++ )
{ // Fills in the array with random ids
bool gotUnique = false;
while ( !gotUnique )
{ // Depends on randomness to shuffle the original array; needs a better method
- u8 random = mod::tools::getRandom( tableSize );
+ u8 random = getRandomWithSeedReference( tableSize, &seedCopy );
u8 idGot = *( (u8*) srcTable + ( random * srcTableElementSize ) );
bool valueExists = false;
for ( u8 j = 0; j < i; j++ )
@@ -174,16 +203,23 @@ static void randomizeTable( void* srcTable, u8 destTable[], size_t srcTableEleme
trampoline = mod::patch::hookFunction( origin, hook ); \
}
+static bool musicRandoInit = false;
+
namespace mod::musicrando
{
u8 musicRandoEnabled = 0;
- u8 enemyBgmEnabled = 1;
+ u8 enemyBgmDisabled = 0;
+ u8 fanfareRandoEnabled = 0;
void initMusicRando()
{
- randomizeTable( (void*) &bgmSource, randomizedBGMs, sizeof( BGM ), bgmSource_length );
- randomizeTable( (void*) &fanfareSrc, randomizedFanfares, sizeof( u8 ), fanfareSourceLength );
- HookTrampoline( sceneChange_trampoline, tp::Z2AudioLib::SceneMgr::sceneChange, sceneChangeHook );
- HookTrampoline( startBattleBgm_trampoline, tp::Z2AudioLib::SeqMgr::startBattleBgm, startBattleBgmHook );
- HookTrampoline( subBgmStart_trampoline, tp::Z2AudioLib::SeqMgr::subBgmStart, subBgmStartHook );
+ if ( musicRandoInit == false )
+ {
+ musicRandoInit = true;
+ randomizeTable( (void*) &bgmSource, randomizedBGMs, sizeof( BGM ), bgmSource_length );
+ randomizeTable( (void*) &fanfareSrc, randomizedFanfares, sizeof( u8 ), fanfareSourceLength );
+ HookTrampoline( sceneChange_trampoline, tp::Z2AudioLib::SceneMgr::sceneChange, sceneChangeHook );
+ HookTrampoline( startBattleBgm_trampoline, tp::Z2AudioLib::SeqMgr::startBattleBgm, startBattleBgmHook );
+ HookTrampoline( startSound_trampoline, startSound, startSoundHook );
+ }
}
-} // namespace mod::musicrando
+} // namespace mod::musicrando \ No newline at end of file
diff --git a/source/singleton.cpp b/source/singleton.cpp
index c05bd90..811d57a 100644
--- a/source/singleton.cpp
+++ b/source/singleton.cpp
@@ -39,15 +39,7 @@ namespace mod
isGMStoryPatch = 0;
isEarlyHCEnabled = 0;
startWithCrystal = 0;
-
- // dungeon fixes
- hasFTBeenBeaten = 0;
- hasGMBeenBeaten = 0;
- hasLBTBeenBeaten = 0;
- hasAGBeenBeaten = 0;
- hasSPRBeenBeaten = 0;
- hasToTBeenBeaten = 0;
- hasCiTSBeenBeaten = 0;
+ shuffleHiddenSkills = 0;
hasCiTSOoccoo = 0;
}
diff --git a/source/stage.cpp b/source/stage.cpp
index 5588646..73a7841 100644
--- a/source/stage.cpp
+++ b/source/stage.cpp
@@ -94,4 +94,41 @@ namespace mod::stage
allStages[Stage_Gerudo_Desert],
allStages[Stage_Hidden_Village],
allStages[Stage_Fishing_Pond] };
+
+ const char* mainDungeonStages[9] { allStages[Stage_Lakebed_Temple],
+ allStages[Stage_Goron_Mines],
+ allStages[Stage_Forest_Temple],
+ allStages[Stage_Temple_of_Time],
+ allStages[Stage_City_in_the_Sky],
+ allStages[Stage_Palace_of_Twilight],
+ allStages[Stage_Hyrule_Castle],
+ allStages[Stage_Arbiters_Grounds],
+ allStages[Stage_Snowpeak_Ruins] };
+
+ const char* allDungeonStages[26] { 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],
+ 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] };
} // namespace mod::stage \ No newline at end of file