diff options
author | lunarsoap5 <justindakotacarter@gmail.com> | 2021-11-07 21:24:49 -0600 |
---|---|---|
committer | lunarsoap5 <justindakotacarter@gmail.com> | 2021-11-07 21:24:49 -0600 |
commit | de4c80f6967f1b47f5c6deb17bc764050d0bc956 (patch) | |
tree | 46196ec2894a57ff460396f0c183a2187e4a19cb | |
parent | 5d87db08967bbfd200cef45325dd0ead771f3805 (diff) |
Update to 0.20b0.20b
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 |