Compare commits

...

58 Commits

Author SHA1 Message Date
David Chavez 32ad0ab4b8 Bump version 2023-01-18 19:21:38 +01:00
aMannus a5f7478b99 Fix CC connection bugs (#2367) 2023-01-18 16:56:32 +01:00
briaguya 750ae907c2 sdl windowed fullscreen (#2351) 2023-01-17 22:14:45 -05:00
briaguya f665326a67 workaround for vanilla save check tracker crash (#2359)
Co-authored-by: briaguya <briaguya@alice>
2023-01-17 21:40:02 -05:00
briaguya 418d0f8e6c fix: default cvar values before applying presets (#2357) 2023-01-17 17:57:02 -05:00
UltraHDR 13b8f26435 Set LSApplicationCategoryType to games 2023-01-17 17:19:35 -05:00
AltoXorg ba5d5c25d1 changes to the asset extraction script (#2068)
- fixes exiting with Ctrl+C on linux
- chooseROM returns Z64Rom object in addition to speed
- adds simple verbosity for inspecting roms
2023-01-17 17:05:24 -05:00
briaguya 1fe862515d fix top left dungeon entrance icon in graveyard (#2303)
Co-authored-by: briaguya <briaguya>
2023-01-17 15:42:09 -05:00
Adam Bird 6eef813e5d fix wrong entrances in epona check handler (#2352) 2023-01-17 15:20:21 -05:00
Adam Bird 76c9895432 add missing medigoron hint text (#2339) 2023-01-17 15:19:22 -05:00
Adam Bird 048207eb7d Fix exiting courtyard at night not taking link to castle grounds in dungeon entrance randomizer (#2316) 2023-01-17 15:18:59 -05:00
Amaro Martínez 170b9c1224 Disable BEL char by default when terminal attached (#2306) 2023-01-17 15:18:13 -05:00
Adam Bird 1e7cf8858f fix one-way entrances making some entrances disappear from the overrides (#2318) 2023-01-17 21:07:58 +01:00
Adam Bird 4b10a887a6 Fix: Remove MQ Spirit Temple silver block for child to guarantee access to the chest (#2342) 2023-01-17 21:05:19 +01:00
Adam Bird ff3548a1b6 Rando: Adjust locked door logic for temples and give starting keys for MQ Spirit (#2343) 2023-01-17 21:03:08 +01:00
Adam Bird fda198db76 Fix: Reset waterbox collisions in Lake Hylia and Morphas room (#2346) 2023-01-17 21:01:45 +01:00
Andrew Van Caem 7f06087cef Altered save flag docs concerning events in Mido's house (#2311) 2023-01-17 14:46:42 -05:00
Garrett Cox 6ae28273d1 Fix Ganon Boss Key for MQ only otrs (#2295) 2023-01-17 14:23:00 -05:00
Amaro Martínez 5b2a50cac2 Remove repeated preset entries (#2294) 2023-01-17 14:01:45 -05:00
briaguya 1e258318a1 fix: properly randomize mirror shield and silver gaunts chests when using only an mq otr (#2291) 2023-01-17 13:17:00 -05:00
PurpleHato 156de816fb FIX: Equip now message (#2286) 2023-01-17 12:40:05 -05:00
briaguya ecb10e6ac2 chore: bump sdl version in appimage (#2288)
Co-authored-by: briaguya <briaguya@alice>
2022-12-27 19:33:40 -05:00
briaguya f42f86e3ef fix: make fisherman rumble text work (#2279)
we weren't correctly setting the pakType in padMgr because
the depreciated `gRumbleEnabled` cvar was being checked
2022-12-26 06:37:40 -05:00
briaguya 85bccab1bb bump lus version (#2269)
* bump lus version

* Fixed StringHelper issues caused by the latest lus version

Co-authored-by: KiritoDv <kiritodev01@gmail.com>
2022-12-24 17:49:54 -05:00
briaguya 7768869251 bump version 2022-12-24 00:58:15 -05:00
briaguya 013244560e hi mom (#2261)
Co-authored-by: aMannus <mannusmenting@gmail.com>
2022-12-24 00:45:02 -05:00
Adam Bird 9529cc1217 SFX: Support replaying the current BGM when changed (#2150)
* add support for reloading the current bgm when changing it in the sfx editor

* clarify audio command with comment

* fix wrong seq type after merge
2022-12-23 23:50:39 -05:00
briaguya 0017bf1fcc fix: correct item ordering in kak potion shop (#2256)
Co-authored-by: briaguya <briaguya>
2022-12-23 22:27:19 -05:00
aMannus f6a7f3d13c Fix enemy rando flags (#2253) 2022-12-23 22:27:01 -05:00
aMannus 99367ebb53 Fix silver rupee room in GtG (#2252) 2022-12-23 22:26:26 -05:00
Adam Bird d215c76eba fix shopsanity spawning objects for actors (#2247) 2022-12-23 22:26:01 -05:00
aMannus 07bae6b84c Fix common enemy rando crashes (#2242) 2022-12-23 22:25:38 -05:00
briaguya 6eaf51c2bd version bump (#2232) 2022-12-21 14:11:19 -05:00
aMannus 565775a3dc Fix ice trap particles (#2229) 2022-12-21 11:14:00 -05:00
aMannus 9eb190e734 Fix particle regression (#2228) 2022-12-21 10:40:23 -05:00
Garrett Cox 0e7a89d117 Fix crash on mac with custom sequences (#2226) 2022-12-21 03:04:11 -05:00
briaguya 73873a6dbc fix: no longer leak memory, invalidate textures properly (#2223)
* Revert "Fix Ganondorf boss battle ending (MQ only) (#2072)"

This reverts commit 52b896271c.

* yolo this should work

* finish comment

* see if this doesn't lag switches!

* formatting

* formatting

Co-authored-by: briaguya <briaguya@alice>
2022-12-21 01:26:13 -05:00
aMannus e03ef85f3b Enemy Rando Hyrule Field crash hotfix (#2222) 2022-12-21 01:03:05 -05:00
Christopher Leggett 8c8111c7b8 Small improvement to sfx randomize button. (#2219)
Should result in less allocations.
2022-12-21 00:31:51 -05:00
GaryOderNichts 1a10d8f627 Fix AdpcmBook allocations (#2214) 2022-12-21 00:15:05 -05:00
aMannus a1a6c07549 Rando - Fix ice traps & get item logic (#2210)
* Fix ice traps & get item logic

* Fix shop keepers & more draw logic cleanup
2022-12-20 23:32:01 -05:00
Adam Bird 6f7361e1a4 only save authentic sequence cvars (#2216) 2022-12-20 17:09:12 -05:00
Garrett Cox 95f1ba7202 Fix cosmetic oob hacks (#2211) 2022-12-20 16:21:00 -05:00
GaryOderNichts 4eee417520 WiiU: Don't invalidate tex cache for dodongo (#2220) 2022-12-20 15:52:13 -05:00
GaryOderNichts 0f3c2d7c78 Fix gfx patching on 32-bit platforms (#2213) 2022-12-20 14:19:25 -05:00
Christopher Leggett 56ac27b8f4 Fixes crash during randomization of individual sound effects. (#2203)
* Fixes randomization of individual sound effects.

* Re-adds the mistakenly removed const specifier.

* Implements new randomization syntax that actually fixes the crash.

* Increases default width of sfx editor menu.

The default width was cutting off a lot of the text in the dropdowns due to the added Randomize button.
2022-12-19 05:12:36 -05:00
PurpleHato 4999df5395 TWEAK: Rando Text (French / German) (#2204)
* TWEAK: Some Rando Text

French and German tweaks (German made by Timmy_GamerNepgear on Discord)

Tweak: water control level style to fits Navi's style textboxes

* TWEAK: %c instead of %w
2022-12-18 21:07:05 -05:00
Adam Bird 51f3e37010 fix medi goron not selling randomized item and continuously selling knifes (#2206) 2022-12-18 20:07:35 -05:00
Adam Bird c4b077d83b fix warp song hints not being set if gossip stones are turned off (#2197) 2022-12-17 20:06:23 -05:00
Garrett Cox be38b41644 [#361] Fix ganon boss offset on retail rom (#2190) 2022-12-17 19:51:52 -05:00
Garrett Cox d3f2da2a8f [#1803] Fix hookshot target offset on retail rom (#2189) 2022-12-17 19:21:00 -05:00
KiritoDev 166a6691fc Fixed nintendo switch debug flags (#2202) 2022-12-17 19:08:32 -05:00
briaguya a05bc1e29f bump version (#2185)
Co-authored-by: briaguya <briaguya@alice>
2022-12-13 23:48:54 -05:00
briaguya 2720292b08 bump lus verison (#2184)
Co-authored-by: briaguya <briaguya@alice>
2022-12-13 23:47:12 -05:00
Christopher Leggett 8a69f1f020 Fixes receiving the wrong item when picking up ammo drops near a chest. (#2183)
* Fixes receiving the wrong item when picking up ammo drops near a chest.

Still shows the wrong model above links head but does give the right
item and shows the right text.

* Fixes get item model during first time pickup anim near chest.
2022-12-13 23:27:51 -05:00
briaguya e71583d47c fix: populate merchant prices table with expensive scrub prices (#2181)
* fix: populate merchant prices with vanilla scrub prices

* temporary expensive scrub workaround

Co-authored-by: briaguya <briaguya@alice>
2022-12-13 21:57:59 -05:00
Garrett Cox 5965cdb193 Fix save compatibility issue from renames (#2177)
* Revert json key changes in save v1 and v2

* Introduce save v3

* Add workaround for breaking save compatibility in 5.1.0

* Handle scarecrow long song a bit differently since the array is never empty
2022-12-13 19:18:18 -05:00
Christopher Leggett 7718e74d73 Always use authentic cache policy for replaced seqs (#2176) 2022-12-13 14:55:00 -05:00
69 changed files with 885 additions and 398 deletions
+3 -3
View File
@@ -101,9 +101,9 @@ jobs:
- name: Install latest SDL
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
wget https://www.libsdl.org/release/SDL2-2.24.1.tar.gz
tar -xzf SDL2-2.24.1.tar.gz
cd SDL2-2.24.1
wget https://www.libsdl.org/release/SDL2-2.26.1.tar.gz
tar -xzf SDL2-2.26.1.tar.gz
cd SDL2-2.26.1
./configure
make -j 10
sudo make install
+4 -4
View File
@@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE)
project(Ship LANGUAGES C CXX
VERSION 5.1.0)
set(PROJECT_BUILD_NAME "BRADLEY ALFA" CACHE STRING "")
VERSION 5.1.4)
set(PROJECT_BUILD_NAME "BRADLEY ECHO" CACHE STRING "")
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)
@@ -49,8 +49,8 @@ endif()
# Global configuration types
################################################################################
if (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
set(CMAKE_C_FLAGS_DEBUG "-O3 -ffast-math")
set(CMAKE_CXX_FLAGS_DEBUG "-O3 -ffast-math")
set(CMAKE_C_FLAGS_DEBUG "-g -ffast-math -DDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-g -ffast-math -DDEBUG")
set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG")
else()
+4 -5
View File
@@ -32,17 +32,16 @@ def main():
parser.add_argument("-z", "--zapd", help="Path to ZAPD executable", dest="zapd_exe", type=str)
parser.add_argument("rom", help="Path to the rom", type=str, nargs="?")
parser.add_argument("--non-interactive", help="Runs the script non-interactively for use in build scripts.", dest="non_interactive", action="store_true")
parser.add_argument("-v", "--verbose", help="Display rom's header checksums and their corresponding xml folder", dest="verbose", action="store_true")
args = parser.parse_args()
rom_paths = [ args.rom ] if args.rom else rom_chooser.chooseROM(args.non_interactive)
for rom_path in rom_paths:
rom = Z64Rom(rom_path)
roms = [ Z64Rom(args.rom) ] if args.rom else rom_chooser.chooseROM(args.verbose, args.non_interactive)
for rom in roms:
if (os.path.exists("Extract")):
shutil.rmtree("Extract")
BuildOTR("../soh/assets/xml/" + rom.version.xml_ver + "/", rom_path, zapd_exe=args.zapd_exe)
BuildOTR("../soh/assets/xml/" + rom.version.xml_ver + "/", rom.file_path, zapd_exe=args.zapd_exe)
if __name__ == "__main__":
main()
+14 -8
View File
@@ -2,12 +2,13 @@ import os, sys, glob
from rom_info import Z64Rom
def chooseROM(non_interactive=False):
def chooseROM(verbose=False, non_interactive=False):
roms = []
for file in glob.glob("*.z64"):
if Z64Rom.isValidRom(file):
roms.append(file)
rom = Z64Rom(file)
if rom.is_valid:
roms.append(rom)
if not (roms):
print("Error: No roms located, place one in the OTRExporter directory", file=os.sys.stderr)
@@ -21,23 +22,28 @@ def chooseROM(non_interactive=False):
foundMq = False
foundOot = False
for rom in roms:
isMq = Z64Rom.isMqRom(rom)
if isMq and not foundMq:
if rom.isMq and not foundMq:
romsToExtract.append(rom)
foundMq = True
elif not isMq and not foundOot:
elif not rom.isMq and not foundOot:
romsToExtract.append(rom)
foundOot = True
return romsToExtract
print(str(len(roms))+ " roms found, please select one by pressing 1-"+str(len(roms)))
print(f"{len(roms)} roms found, please select one by pressing 1-{len(roms)}")
print()
for i in range(len(roms)):
print(str(i+1)+ ". " + roms[i])
print(f"[{i+1:>2d}] {roms[i].file_path}")
if verbose:
print(f" Checksum: {roms[i].checksum.value}, Version XML: {roms[i].version.xml_ver}")
print()
while(1):
try:
selection = int(input())
except KeyboardInterrupt:
sys.exit(1)
except:
print("Bad input. Try again with the number keys.")
continue
+3 -3
View File
@@ -221,7 +221,7 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
// Check for repeated attributes.
if (offsetXml != nullptr)
{
rawDataIndex = strtol(StringHelper::Split(offsetXml, "0x")[1].c_str(), NULL, 16);
rawDataIndex = strtol(StringHelper::Split(std::string(offsetXml), "0x")[1].c_str(), NULL, 16);
if (offsetSet.find(offsetXml) != offsetSet.end())
{
@@ -831,7 +831,7 @@ void ZFile::GenerateSourceHeaderFiles()
xmlPath = StringHelper::Replace(xmlPath, "\\", "/");
auto pathList = StringHelper::Split(xmlPath, "/");
std::string outPath = "";
for (int i = 0; i < 3; i++)
outPath += pathList[i] + "/";
@@ -1192,7 +1192,7 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] const std::strin
if (declarations.find(currentOffset) != declarations.end())
declarations.at(currentOffset)->size = currentTex->GetRawDataSize();
currentTex->DeclareVar(GetName(), "");
}
else
@@ -1,7 +1,7 @@
<Root>
<File Name="object_d_hsblock" Segment="6">
<Collision Name="gHookshotPostCol" Offset="0x578"/>
<Collision Name="gHookshotTargetCol" Offset="0x730"/>
<Collision Name="gHookshotTargetCol" Offset="0x578"/>
<Collision Name="gHookshotPostCol" Offset="0x730"/>
<DList Name="gHookshotPostDL" Offset="0x210"/>
<DList Name="gHookshotTargetDL" Offset="0x470"/>
<Texture Name="gHookshotTargetTex" OutName="hookshot_target" Format="i4" Width="64" Height="64" Offset="0x760"/>
@@ -21,7 +21,7 @@
<Array Name="ovl_Boss_Ganon2_Vtx_00CC98" Count="4" Offset="0x00C958">
<Vtx/>
</Array>
<DList Name="ovl_Boss_Ganon2_DL_00CCD8" Offset="0x00CA98"/>
<DList Name="ovl_Boss_Ganon2_DL_00CCD8" Offset="0x00C998"/>
<Texture Name="ovl_Boss_Ganon2_Tex_00CD58" OutName="tex_0000CD58" Format="i4" Width="32" Height="160" Offset="0x00CA18"/>
<Array Name="ovl_Boss_Ganon2_Vtx_00D758" Count="4" Offset="0x00D418">
<Vtx/>
+1
View File
@@ -168,6 +168,7 @@ extern "C"
extern s32 __osPfsLastChannel;
extern u8 gWalkSpeedToggle1;
extern u8 gWalkSpeedToggle2;
extern f32 iceTrapScale;
extern const s16 D_8014A6C0[];
#define gTatumsPerBeat (D_8014A6C0[1])
+7
View File
@@ -32,4 +32,11 @@
#define VT_RST VT_SGR("")
#define VT_CLS VT_ED(2)
#ifdef USE_BELL
// ASCII BEL character, plays an alert tone
#define BEL '\a'
#else
#define BEL '\0'
#endif
#endif
+3 -1
View File
@@ -26,6 +26,8 @@
extern char* fontMap[256];
#define MAX_AUTHENTIC_SEQID 110
typedef enum {
/* 0 */ ADSR_STATE_DISABLED,
/* 1 */ ADSR_STATE_INITIAL,
@@ -125,7 +127,7 @@ typedef struct {
typedef struct {
/* 0x00 */ s32 order;
/* 0x04 */ s32 npredictors;
/* 0x08 */ s16 book[1]; // size 8 * order * npredictors. 8-byte aligned
/* 0x08 */ s16 book[]; // size 8 * order * npredictors. 8-byte aligned
} AdpcmBook; // size >= 0x8
typedef struct
+2
View File
@@ -29,6 +29,8 @@
<string>@CMAKE_PROJECT_VERSION@</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright 2022 HarbourMasters.</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
</dict>
+135 -135
View File
@@ -193,11 +193,11 @@ static std::map<std::string, CosmeticOption> cosmeticOptions = {
COSMETIC_OPTION("MirrorShield_Emblem", "Emblem", GROUP_MIRRORSHIELD, ImVec4(205, 225, 255, 255), false, true, true),
COSMETIC_OPTION("Swords_KokiriBlade", "Kokiri Sword Blade", GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Swords_KokiriHilt", "Kokiri Sword Hilt", GROUP_SWORDS, ImVec4(160, 100, 15, 255), false, true, true),
// COSMETIC_OPTION("Swords_KokiriHilt", "Kokiri Sword Hilt", GROUP_SWORDS, ImVec4(160, 100, 15, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
COSMETIC_OPTION("Swords_MasterBlade", "Master Sword Blade", GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Swords_MasterHilt", "Master Sword Hilt", GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true),
// COSMETIC_OPTION("Swords_MasterHilt", "Master Sword Hilt", GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
COSMETIC_OPTION("Swords_BiggoronBlade", "Biggoron Sword Blade", GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Swords_BiggoronHilt", "Biggoron Sword Hilt", GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true),
// COSMETIC_OPTION("Swords_BiggoronHilt", "Biggoron Sword Hilt", GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
COSMETIC_OPTION("Gloves_GoronBracelet", "Goron Bracelet", GROUP_GLOVES, ImVec4(255, 255, 170, 255), false, true, false),
COSMETIC_OPTION("Gloves_SilverGauntlets", "Silver Gauntlets", GROUP_GLOVES, ImVec4(255, 255, 255, 255), false, true, false),
@@ -206,7 +206,7 @@ static std::map<std::string, CosmeticOption> cosmeticOptions = {
COSMETIC_OPTION("Equipment_BoomerangBody", "Boomerang Body", GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, false),
COSMETIC_OPTION("Equipment_BoomerangGem", "Boomerang Gem", GROUP_EQUIPMENT, ImVec4(255, 50, 150, 255), false, true, true),
COSMETIC_OPTION("Equipment_SlingshotBody", "Slingshot Body", GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, true),
// COSMETIC_OPTION("Equipment_SlingshotBody", "Slingshot Body", GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
COSMETIC_OPTION("Equipment_SlingshotString", "Slingshot String", GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true),
COSMETIC_OPTION("Equipment_HammerHead", "Hammer Head", GROUP_EQUIPMENT, ImVec4(155, 192, 201, 255), false, true, false),
COSMETIC_OPTION("Equipment_HammerHandle", "Hammer Handle", GROUP_EQUIPMENT, ImVec4(110, 60, 0, 255), false, true, true),
@@ -593,47 +593,47 @@ void ApplyOrResetCustomGfxPatches(bool manualChange = true) {
PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade3", swordsKokiriBlade.changedCvar, 10, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade4", swordsKokiriBlade.changedCvar, 12, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255));
}
static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords_KokiriHilt");
if (manualChange || CVar_GetS32(swordsKokiriHilt.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {swordsKokiriHilt.defaultColor.x, swordsKokiriHilt.defaultColor.y, swordsKokiriHilt.defaultColor.z, swordsKokiriHilt.defaultColor.w};
Color_RGBA8 color = CVar_GetRGBA(swordsKokiriHilt.cvar, defaultColor);
PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt1", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt2", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt3", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt4", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt5", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt6", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt7", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt8", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt9", swordsKokiriHilt.changedCvar, 64, gsDPSetPrimColor(0, 0, MAX(color.r - 50, 0), MAX(color.g - 50, 0), MAX(color.b - 50, 0), 255));
PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt10", swordsKokiriHilt.changedCvar, 66, gsDPSetEnvColor(MAX(color.r - 50, 0) / 3, MAX(color.g - 50, 0) / 3, MAX(color.b - 50, 0) / 3, 255));
PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt11", swordsKokiriHilt.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt12", swordsKokiriHilt.changedCvar, 164, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
// static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords_KokiriHilt");
// if (manualChange || CVar_GetS32(swordsKokiriHilt.rainbowCvar, 0)) {
// static Color_RGBA8 defaultColor = {swordsKokiriHilt.defaultColor.x, swordsKokiriHilt.defaultColor.y, swordsKokiriHilt.defaultColor.z, swordsKokiriHilt.defaultColor.w};
// Color_RGBA8 color = CVar_GetRGBA(swordsKokiriHilt.cvar, defaultColor);
// PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt1", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt2", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt3", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt4", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt5", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt6", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt7", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt8", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt9", swordsKokiriHilt.changedCvar, 64, gsDPSetPrimColor(0, 0, MAX(color.r - 50, 0), MAX(color.g - 50, 0), MAX(color.b - 50, 0), 255));
// PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt10", swordsKokiriHilt.changedCvar, 66, gsDPSetEnvColor(MAX(color.r - 50, 0) / 3, MAX(color.g - 50, 0) / 3, MAX(color.b - 50, 0) / 3, 255));
// PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt11", swordsKokiriHilt.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
// PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt12", swordsKokiriHilt.changedCvar, 164, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
if (manualChange) {
PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt13", swordsKokiriHilt.changedCvar, 108, gsSPGrayscale(true));
PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt14", swordsKokiriHilt.changedCvar, 134, gsSPGrayscale(false));
PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt15", swordsKokiriHilt.changedCvar, 106, gsSPGrayscale(true));
PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt16", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false));
PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt17", swordsKokiriHilt.changedCvar, 100, gsSPGrayscale(true));
PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt18", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false));
PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt19", swordsKokiriHilt.changedCvar, 128, gsSPEndDisplayList());
PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt20", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true));
PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt21", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false));
PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt22", swordsKokiriHilt.changedCvar, 120, gsSPEndDisplayList());
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt23", swordsKokiriHilt.changedCvar, 166, gsSPGrayscale(true));
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt24", swordsKokiriHilt.changedCvar, 192, gsSPGrayscale(false));
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt25", swordsKokiriHilt.changedCvar, 194, gsSPEndDisplayList());
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt26", swordsKokiriHilt.changedCvar, 156, gsSPGrayscale(true));
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt27", swordsKokiriHilt.changedCvar, 176, gsSPGrayscale(false));
PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt28", swordsKokiriHilt.changedCvar, 178, gsSPEndDisplayList());
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt29", swordsKokiriHilt.changedCvar, 162, gsSPGrayscale(true));
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt30", swordsKokiriHilt.changedCvar, 188, gsSPGrayscale(false));
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt31", swordsKokiriHilt.changedCvar, 190, gsSPEndDisplayList());
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt32", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true));
PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false));
}
}
// if (manualChange) {
// PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt13", swordsKokiriHilt.changedCvar, 108, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt14", swordsKokiriHilt.changedCvar, 134, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt15", swordsKokiriHilt.changedCvar, 106, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt16", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt17", swordsKokiriHilt.changedCvar, 100, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt18", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt19", swordsKokiriHilt.changedCvar, 128, gsSPEndDisplayList());
// PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt20", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt21", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt22", swordsKokiriHilt.changedCvar, 120, gsSPEndDisplayList());
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt23", swordsKokiriHilt.changedCvar, 166, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt24", swordsKokiriHilt.changedCvar, 192, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt25", swordsKokiriHilt.changedCvar, 194, gsSPEndDisplayList());
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt26", swordsKokiriHilt.changedCvar, 156, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt27", swordsKokiriHilt.changedCvar, 176, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt28", swordsKokiriHilt.changedCvar, 178, gsSPEndDisplayList());
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt29", swordsKokiriHilt.changedCvar, 162, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt30", swordsKokiriHilt.changedCvar, 188, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt31", swordsKokiriHilt.changedCvar, 190, gsSPEndDisplayList());
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt32", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false));
// }
// }
static CosmeticOption& swordsMasterBlade = cosmeticOptions.at("Swords_MasterBlade");
if (manualChange || CVar_GetS32(swordsMasterBlade.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {swordsMasterBlade.defaultColor.x, swordsMasterBlade.defaultColor.y, swordsMasterBlade.defaultColor.z, swordsMasterBlade.defaultColor.w};
@@ -645,53 +645,53 @@ void ApplyOrResetCustomGfxPatches(bool manualChange = true) {
PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterBlade5", swordsMasterBlade.changedCvar, 26, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterBlade6", swordsMasterBlade.changedCvar, 28, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255));
}
static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords_MasterHilt");
if (manualChange || CVar_GetS32(swordsMasterHilt.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {swordsMasterHilt.defaultColor.x, swordsMasterHilt.defaultColor.y, swordsMasterHilt.defaultColor.z, swordsMasterHilt.defaultColor.w};
Color_RGBA8 color = CVar_GetRGBA(swordsMasterHilt.cvar, defaultColor);
PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt1", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt2", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt3", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt4", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt5", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt6", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt7", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt8", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt9", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt10", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords_MasterHilt");
// if (manualChange || CVar_GetS32(swordsMasterHilt.rainbowCvar, 0)) {
// static Color_RGBA8 defaultColor = {swordsMasterHilt.defaultColor.x, swordsMasterHilt.defaultColor.y, swordsMasterHilt.defaultColor.z, swordsMasterHilt.defaultColor.w};
// Color_RGBA8 color = CVar_GetRGBA(swordsMasterHilt.cvar, defaultColor);
// PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt1", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt2", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt3", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt4", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt5", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt6", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt7", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt8", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt9", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt10", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
if (manualChange) {
PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt11", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt12", swordsMasterHilt.changedCvar, 64, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt13", swordsMasterHilt.changedCvar, 106, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt14", swordsMasterHilt.changedCvar, 120, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt15", swordsMasterHilt.changedCvar, 104, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt16", swordsMasterHilt.changedCvar, 182, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt17", swordsMasterHilt.changedCvar, 184, gsSPEndDisplayList());
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt18", swordsMasterHilt.changedCvar, 80, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt19", swordsMasterHilt.changedCvar, 94, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt20", swordsMasterHilt.changedCvar, 162, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt21", swordsMasterHilt.changedCvar, 180, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt22", swordsMasterHilt.changedCvar, 154, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt23", swordsMasterHilt.changedCvar, 232, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt24", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt25", swordsMasterHilt.changedCvar, 130, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt26", swordsMasterHilt.changedCvar, 172, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt27", swordsMasterHilt.changedCvar, 186, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt28", swordsMasterHilt.changedCvar, 220, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt29", swordsMasterHilt.changedCvar, 298, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt30", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt31", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt32", swordsMasterHilt.changedCvar, 86, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt33", swordsMasterHilt.changedCvar, 208, gsSPGrayscale(false));
PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt34", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true));
PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt35", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false));
PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt36", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList());
PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt37", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true));
PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt38", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false));
PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList());
}
}
// if (manualChange) {
// PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt11", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt12", swordsMasterHilt.changedCvar, 64, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt13", swordsMasterHilt.changedCvar, 106, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt14", swordsMasterHilt.changedCvar, 120, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt15", swordsMasterHilt.changedCvar, 104, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt16", swordsMasterHilt.changedCvar, 182, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt17", swordsMasterHilt.changedCvar, 184, gsSPEndDisplayList());
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt18", swordsMasterHilt.changedCvar, 80, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt19", swordsMasterHilt.changedCvar, 94, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt20", swordsMasterHilt.changedCvar, 162, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt21", swordsMasterHilt.changedCvar, 180, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt22", swordsMasterHilt.changedCvar, 154, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt23", swordsMasterHilt.changedCvar, 232, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt24", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt25", swordsMasterHilt.changedCvar, 130, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt26", swordsMasterHilt.changedCvar, 172, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt27", swordsMasterHilt.changedCvar, 186, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt28", swordsMasterHilt.changedCvar, 220, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt29", swordsMasterHilt.changedCvar, 298, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt30", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt31", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt32", swordsMasterHilt.changedCvar, 86, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt33", swordsMasterHilt.changedCvar, 208, gsSPGrayscale(false));
// PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt34", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true));
// PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt35", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false));
// PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt36", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList());
// PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt37", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true));
// PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt38", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false));
// PATCH_GFX(ovl_Boss_Ganon2_DL_0103A8, "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList());
// }
// }
static CosmeticOption& swordsBiggoronBlade = cosmeticOptions.at("Swords_BiggoronBlade");
if (manualChange || CVar_GetS32(swordsBiggoronBlade.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {swordsBiggoronBlade.defaultColor.x, swordsBiggoronBlade.defaultColor.y, swordsBiggoronBlade.defaultColor.z, swordsBiggoronBlade.defaultColor.w};
@@ -701,25 +701,25 @@ void ApplyOrResetCustomGfxPatches(bool manualChange = true) {
PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade3", swordsBiggoronBlade.changedCvar, 10, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade4", swordsBiggoronBlade.changedCvar, 12, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
}
static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords_BiggoronHilt");
if (manualChange || CVar_GetS32(swordsBiggoronHilt.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {swordsBiggoronHilt.defaultColor.x, swordsBiggoronHilt.defaultColor.y, swordsBiggoronHilt.defaultColor.z, swordsBiggoronHilt.defaultColor.w};
Color_RGBA8 color = CVar_GetRGBA(swordsBiggoronHilt.cvar, defaultColor);
PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt1", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt2", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt3", swordsBiggoronHilt.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt4", swordsBiggoronHilt.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt5", swordsBiggoronHilt.changedCvar, 154, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt6", swordsBiggoronHilt.changedCvar, 156, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
// static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords_BiggoronHilt");
// if (manualChange || CVar_GetS32(swordsBiggoronHilt.rainbowCvar, 0)) {
// static Color_RGBA8 defaultColor = {swordsBiggoronHilt.defaultColor.x, swordsBiggoronHilt.defaultColor.y, swordsBiggoronHilt.defaultColor.z, swordsBiggoronHilt.defaultColor.w};
// Color_RGBA8 color = CVar_GetRGBA(swordsBiggoronHilt.cvar, defaultColor);
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt1", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt2", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt3", swordsBiggoronHilt.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
// PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt4", swordsBiggoronHilt.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
// PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt5", swordsBiggoronHilt.changedCvar, 154, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
// PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt6", swordsBiggoronHilt.changedCvar, 156, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
if (manualChange) {
PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt7", swordsBiggoronHilt.changedCvar, 278, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt8", swordsBiggoronHilt.changedCvar, 332, gsSPGrayscale(false));
PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt9", swordsBiggoronHilt.changedCvar, 334, gsSPEndDisplayList());
PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt10", swordsBiggoronHilt.changedCvar, 38, gsSPGrayscale(true));
PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt11", swordsBiggoronHilt.changedCvar, 118, gsSPGrayscale(false));
}
}
// if (manualChange) {
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt7", swordsBiggoronHilt.changedCvar, 278, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt8", swordsBiggoronHilt.changedCvar, 332, gsSPGrayscale(false));
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt9", swordsBiggoronHilt.changedCvar, 334, gsSPEndDisplayList());
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt10", swordsBiggoronHilt.changedCvar, 38, gsSPGrayscale(true));
// PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt11", swordsBiggoronHilt.changedCvar, 118, gsSPGrayscale(false));
// }
// }
static CosmeticOption& glovesGoronBracelet = cosmeticOptions.at("Gloves_GoronBracelet");
if (manualChange || CVar_GetS32(glovesGoronBracelet.rainbowCvar, 0)) {
@@ -782,30 +782,30 @@ void ApplyOrResetCustomGfxPatches(bool manualChange = true) {
// PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangGem5", equipmentBoomerangGem.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
}
static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment_SlingshotBody");
if (manualChange || CVar_GetS32(equipmentSlingshotBody.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {equipmentSlingshotBody.defaultColor.x, equipmentSlingshotBody.defaultColor.y, equipmentSlingshotBody.defaultColor.z, equipmentSlingshotBody.defaultColor.w};
Color_RGBA8 color = CVar_GetRGBA(equipmentSlingshotBody.cvar, defaultColor);
PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody1", equipmentSlingshotBody.changedCvar, 10, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255));
PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody2", equipmentSlingshotBody.changedCvar, 12, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255));
PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody3", equipmentSlingshotBody.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody4", equipmentSlingshotBody.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody5", equipmentSlingshotBody.changedCvar, 128, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255));
PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody6", equipmentSlingshotBody.changedCvar, 130, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255));
PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody7", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody8", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody9", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment_SlingshotBody");
// if (manualChange || CVar_GetS32(equipmentSlingshotBody.rainbowCvar, 0)) {
// static Color_RGBA8 defaultColor = {equipmentSlingshotBody.defaultColor.x, equipmentSlingshotBody.defaultColor.y, equipmentSlingshotBody.defaultColor.z, equipmentSlingshotBody.defaultColor.w};
// Color_RGBA8 color = CVar_GetRGBA(equipmentSlingshotBody.cvar, defaultColor);
// PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody1", equipmentSlingshotBody.changedCvar, 10, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255));
// PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody2", equipmentSlingshotBody.changedCvar, 12, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255));
// PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody3", equipmentSlingshotBody.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
// PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody4", equipmentSlingshotBody.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255));
// PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody5", equipmentSlingshotBody.changedCvar, 128, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255));
// PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody6", equipmentSlingshotBody.changedCvar, 130, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255));
// PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody7", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody8", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody9", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
if (manualChange) {
PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody10",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true));
PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody11",equipmentSlingshotBody.changedCvar, 74, gsSPGrayscale(false));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody12",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody13",equipmentSlingshotBody.changedCvar, 66, gsSPGrayscale(false));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody14",equipmentSlingshotBody.changedCvar, 96, gsSPGrayscale(true));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody15",equipmentSlingshotBody.changedCvar, 136, gsSPGrayscale(false));
PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList());
}
}
// if (manualChange) {
// PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody10",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody11",equipmentSlingshotBody.changedCvar, 74, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody12",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody13",equipmentSlingshotBody.changedCvar, 66, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody14",equipmentSlingshotBody.changedCvar, 96, gsSPGrayscale(true));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody15",equipmentSlingshotBody.changedCvar, 136, gsSPGrayscale(false));
// PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList());
// }
// }
static CosmeticOption& equipmentSlingshotString = cosmeticOptions.at("Equipment_SlingshotString");
if (manualChange || CVar_GetS32(equipmentSlingshotString.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {equipmentSlingshotString.defaultColor.x, equipmentSlingshotString.defaultColor.y, equipmentSlingshotString.defaultColor.z, equipmentSlingshotString.defaultColor.w};
@@ -949,10 +949,10 @@ void ApplyOrResetCustomGfxPatches(bool manualChange = true) {
if (manualChange || CVar_GetS32(consumableHearts.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {consumableHearts.defaultColor.x, consumableHearts.defaultColor.y, consumableHearts.defaultColor.z, consumableHearts.defaultColor.w};
Color_RGBA8 color = CVar_GetRGBA(consumableHearts.cvar, defaultColor);
PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts1", consumableHearts.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts2", consumableHearts.changedCvar, 26, gsSPGrayscale(true));
PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts3", consumableHearts.changedCvar, 72, gsSPGrayscale(false));
PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts4", consumableHearts.changedCvar, 74, gsSPEndDisplayList());
// PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts1", consumableHearts.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255));
// PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts2", consumableHearts.changedCvar, 26, gsSPGrayscale(true));
// PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts3", consumableHearts.changedCvar, 72, gsSPGrayscale(false));
// PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts4", consumableHearts.changedCvar, 74, gsSPEndDisplayList());
PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts5", consumableHearts.changedCvar, 4, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts6", consumableHearts.changedCvar, 12, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255));
PATCH_GFX(gGiHeartContainerDL, "Consumable_Hearts7", consumableHearts.changedCvar, 4, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
@@ -101,7 +101,7 @@ void CrowdControl::Disable() {
void CrowdControl::ListenToServer() {
while (isEnabled) {
while (!connected) {
while (!connected && isEnabled) {
SPDLOG_TRACE("[CrowdControl] Attempting to make connection to server...");
tcpsock = SDLNet_TCP_Open(&ip);
@@ -112,8 +112,10 @@ void CrowdControl::ListenToServer() {
}
}
auto socketSet = SDLNet_AllocSocketSet(1);
SDLNet_TCP_AddSocket(socketSet, tcpsock);
SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1);
if (tcpsock) {
SDLNet_TCP_AddSocket(socketSet, tcpsock);
}
// Listen to socket messages
while (connected && tcpsock && isEnabled) {
@@ -36,6 +36,7 @@ const std::vector<FlagTable> flagTables = {
{ 0x09, "Used Deku Tree Blue Warp" },
{ 0x0A, "Played Saria's Song for Mido as Adult" },
{ 0x0C, "Met Deku Tree" },
{ 0x0F, "Spoke to Mido about Saria's whereabouts" },
{ 0x10, "Spoke to Child Malon at Castle or Market" },
{ 0x11, "Spoke to Ingo at Ranch before Talon returns" },
{ 0x12, "Obtained Pocket Egg" },
@@ -219,7 +220,7 @@ const std::vector<FlagTable> flagTables = {
{ 0x24, "Spoke to Kokiri Boy Cutting Grass" },
{ 0x26, "Spoke to Kokiri Girl on Shop Awning" },
{ 0x28, "Spoke to Kokiri Girl About Training Center" },
{ 0x31, "Spoke to Kokiri Boy on Bed in Mido's House" },
{ 0x41, "Spoke to Kokiri Boy on Bed in Mido's House" },
{ 0x51, "Spoke to Kokiri Girl in Saria's House" },
{ 0x59, "Spoke to Know-It-All Bro. About Temple" },
{ 0x61, "Spoke to Know-It-All Bro. About Saria" },
+4
View File
@@ -259,6 +259,10 @@ bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId,
// Only randomize the initial deku scrub actor (single and triple attack), not the flower they spawn.
case ACTOR_EN_DEKUNUTS:
return (params == -256 || params == 768);
// Don't randomize the OoB wallmaster in the silver rupee room because it's only there to
// not trigger unlocking the door after killing the other wallmaster in authentic gameplay.
case ACTOR_EN_WALLMAS:
return (!(!isMQ && sceneNum == SCENE_MEN && roomNum == 2 && posX == -2345));
// Only randomize initial floormaster actor (it can split and does some spawning on init).
case ACTOR_EN_FLOORMAS:
return (params == 0 || params == -32768);
@@ -23,7 +23,10 @@ bool ItemTableManager::AddItemEntry(uint16_t tableID, uint16_t getItemID, GetIte
GetItemEntry ItemTableManager::RetrieveItemEntry(uint16_t tableID, uint16_t itemID) {
try {
ItemTable* itemTable = RetrieveItemTable(tableID);
return itemTable->at(itemID);
GetItemEntry getItemEntry = itemTable->at(itemID);
getItemEntry.drawItemId = getItemEntry.itemId;
getItemEntry.drawModIndex = getItemEntry.modIndex;
return getItemEntry;
} catch (std::out_of_range& oor) { return GET_ITEM_NONE; }
}
@@ -52,5 +52,7 @@ typedef struct GetItemEntry {
/* 0x0C */ uint16_t collectable; // determines whether the item can be collected on the overworld. Will be true in most cases.
/* 0x0E */ GetItemFrom getItemFrom;
/* 0x0F */ GetItemCategory getItemCategory; // Primarily made and used for chest size/texture matches contents
/* 0x10 */ uint16_t drawItemId; // Will be a copy of itemId unless the item is an ice trap. Needed for particles to function on ice traps.
/* 0x11 */ uint16_t drawModIndex; // Will be a copy of modIndex unless the item is an ice trap. Needed for particles to function on ice traps.
CustomDrawFunc drawFunc;
}; // size = 0x0F
}; // size = 0x11
+2 -3
View File
@@ -55,9 +55,8 @@ void DrawPresetSelector(PresetType presetTypeId) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f));
if (ImGui::Button(("Apply Preset##" + presetTypeCvar).c_str())) {
if (selectedPresetId == 0) {
clearCvars(presetTypeDef.cvarsToClear);
} else {
clearCvars(presetTypeDef.cvarsToClear);
if (selectedPresetId != 0) {
applyPreset(selectedPresetDef.entries);
}
SohImGui::RequestCvarSaveOnNextTick();
+2 -9
View File
@@ -350,7 +350,7 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
// Text Speed (1 to 5)
PRESET_ENTRY_S32("gTextSpeed", 5),
// King Zora Speed (1 to 5)
PRESET_ENTRY_S32("gMweepSpeed", 2),
PRESET_ENTRY_S32("gMweepSpeed", 5),
// Faster Block Push (+0 to +5)
PRESET_ENTRY_S32("gFasterBlockPush", 5),
// Better Owl
@@ -394,8 +394,6 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
PRESET_ENTRY_S32("gBombchusOOB", 1),
// Skip save confirmation
PRESET_ENTRY_S32("gSkipSaveConfirmation", 1),
// King Zora Speed (1 to 5)
PRESET_ENTRY_S32("gMweepSpeed", 5),
// Biggoron Forge Time (0 to 3)
PRESET_ENTRY_S32("gForgeTime", 0),
// Vine/Ladder Climb speed (+0 to +12)
@@ -467,7 +465,7 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
// Text Speed (1 to 5)
PRESET_ENTRY_S32("gTextSpeed", 5),
// King Zora Speed (1 to 5)
PRESET_ENTRY_S32("gMweepSpeed", 2),
PRESET_ENTRY_S32("gMweepSpeed", 5),
// Faster Block Push (+0 to +5)
PRESET_ENTRY_S32("gFasterBlockPush", 5),
// Better Owl
@@ -480,9 +478,6 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
// Inject Item Counts in messages
PRESET_ENTRY_S32("gInjectItemCounts", 1),
// Pause link animation (0 to 16)
PRESET_ENTRY_S32("gPauseLiveLink", 1),
// Dynamic Wallet Icon
PRESET_ENTRY_S32("gDynamicWalletIcon", 1),
// Always show dungeon entrances
@@ -511,8 +506,6 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
PRESET_ENTRY_S32("gBombchusOOB", 1),
// Skip save confirmation
PRESET_ENTRY_S32("gSkipSaveConfirmation", 1),
// King Zora Speed (1 to 5)
PRESET_ENTRY_S32("gMweepSpeed", 5),
// Biggoron Forge Time (0 to 3)
PRESET_ENTRY_S32("gForgeTime", 0),
// Vine/Ladder Climb speed (+0 to +12)
@@ -295,8 +295,8 @@ std::vector<uint32_t> GetAccessibleLocations(const std::vector<uint32_t>& allowe
if (mode == SearchMode::GeneratePlaythrough && exit.IsShuffled() && !exit.IsAddedToPool() && !noRandomEntrances) {
entranceSphere.push_back(&exit);
exit.AddToPool();
// Don't list a coupled entrance from both directions
if (exit.GetReplacement()->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
// Don't list a two-way coupled entrance from both directions
if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !Settings::DecoupleEntrances) {
exit.GetReplacement()->GetReverse()->AddToPool();
}
}
@@ -909,6 +909,9 @@ void VanillaFill() {
CreateItemOverrides();
CreateEntranceOverrides();
CreateAlwaysIncludedMessages();
if (ShuffleWarpSongs) {
CreateWarpSongTexts();
}
}
void ClearProgress() {
@@ -1071,6 +1074,9 @@ int Fill() {
if (ShuffleMerchants.Is(SHUFFLEMERCHANTS_HINTS)) {
CreateMerchantsHints();
}
if (ShuffleWarpSongs) {
CreateWarpSongTexts();
}
return 1;
}
//Unsuccessful placement
@@ -418,6 +418,10 @@ void HintTable_Init_Exclude_Overworld() {
Text{"a #carpet guru# sells", /*french*/"#un marchand du désert# vend", /*spanish*/"el #genio de una alfombra# vende"},
});
hintTable[GC_MEDIGORON] = HintText::Exclude({
//obscure text
Text{"#Medigoron# sells", /*french*/"#Medigoron# vend", /*spanish*/"#Medigoron# vende"},
});
hintTable[KAK_IMPAS_HOUSE_FREESTANDING_POH] = HintText::Exclude({
//obscure text
@@ -779,7 +779,6 @@ void CreateAllHints() {
CreateGanonText();
CreateAltarText();
CreateWarpSongTexts();
SPDLOG_DEBUG("\nNOW CREATING HINTS\n");
const HintSetting& hintSetting = hintSettingTable[Settings::HintDistribution.Value<uint8_t>()];
@@ -220,6 +220,7 @@ extern std::array<ConditionalAlwaysHint, 9> conditionalAlwaysHints;
extern uint32_t GetHintRegionHintKey(const uint32_t area);
extern void CreateAllHints();
extern void CreateMerchantsHints();
extern void CreateWarpSongTexts();
Text& GetChildAltarText();
Text& GetAdultAltarText();
@@ -286,6 +286,11 @@ Item& ItemFromGIID(const int giid) {
}
index++;
}
// there are vanilla items that don't exist in the item table we're reading from here
// if we made it this far, it means we didn't find an item in the table
// if we don't return anything, the game will crash, so, as a workaround, return greg
return itemTable[GREEN_RUPEE];
}
//This function should only be used to place items containing hint text
@@ -807,14 +807,14 @@ void LocationTable_Init() {
locationTable[KF_SHOP_ITEM_7] = ItemLocation::Base(RC_KF_SHOP_ITEM_7, 0x2D, 0x36, "KF Shop Item 7", KF_SHOP_ITEM_7, BUY_ARROWS_30, {Category::cKokiriForest, Category::cForest, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x2D, 6), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST);
locationTable[KF_SHOP_ITEM_8] = ItemLocation::Base(RC_KF_SHOP_ITEM_8, 0x2D, 0x37, "KF Shop Item 8", KF_SHOP_ITEM_8, BUY_HEART, {Category::cKokiriForest, Category::cForest, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x2D, 7), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST);
locationTable[KAK_POTION_SHOP_ITEM_1] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_1, 0x30, 0x30, "Kak Potion Shop Item 1", KAK_POTION_SHOP_ITEM_1, BUY_DEKU_NUT_5, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_2] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_2, 0x30, 0x31, "Kak Potion Shop Item 2", KAK_POTION_SHOP_ITEM_2, BUY_FISH, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_1] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_1, 0x30, 0x30, "Kak Potion Shop Item 1", KAK_POTION_SHOP_ITEM_1, BUY_GREEN_POTION, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_2] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_2, 0x30, 0x31, "Kak Potion Shop Item 2", KAK_POTION_SHOP_ITEM_2, BUY_BLUE_FIRE, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_3] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_3, 0x30, 0x32, "Kak Potion Shop Item 3", KAK_POTION_SHOP_ITEM_3, BUY_RED_POTION_30, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_4] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_4, 0x30, 0x33, "Kak Potion Shop Item 4", KAK_POTION_SHOP_ITEM_4, BUY_GREEN_POTION, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_5] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_5, 0x30, 0x34, "Kak Potion Shop Item 5", KAK_POTION_SHOP_ITEM_5, BUY_BLUE_FIRE, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_4] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_4, 0x30, 0x33, "Kak Potion Shop Item 4", KAK_POTION_SHOP_ITEM_4, BUY_FAIRYS_SPIRIT, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_5] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_5, 0x30, 0x34, "Kak Potion Shop Item 5", KAK_POTION_SHOP_ITEM_5, BUY_DEKU_NUT_5, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_6] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_6, 0x30, 0x35, "Kak Potion Shop Item 6", KAK_POTION_SHOP_ITEM_6, BUY_BOTTLE_BUG, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_7] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_7, 0x30, 0x36, "Kak Potion Shop Item 7", KAK_POTION_SHOP_ITEM_7, BUY_POE, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_8] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_8, 0x30, 0x37, "Kak Potion Shop Item 8", KAK_POTION_SHOP_ITEM_8, BUY_FAIRYS_SPIRIT, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_POTION_SHOP_ITEM_8] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_8, 0x30, 0x37, "Kak Potion Shop Item 8", KAK_POTION_SHOP_ITEM_8, BUY_FISH, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[MARKET_BOMBCHU_SHOP_ITEM_1] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, 0x32, 0x30, "MK Bombchu Shop Item 1", MARKET_BOMBCHU_SHOP_ITEM_1, BUY_BOMBCHU_10, {Category::cInnerMarket, Category::cMarket, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[MARKET_BOMBCHU_SHOP_ITEM_2] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, 0x32, 0x31, "MK Bombchu Shop Item 2", MARKET_BOMBCHU_SHOP_ITEM_2, BUY_BOMBCHU_10, {Category::cInnerMarket, Category::cMarket, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
+18 -32
View File
@@ -12,7 +12,7 @@
extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s8 isColoredKeysEnabled = CVar_GetS32("gRandoMatchKeyColors", 0);
s16 color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_SMALL_KEY;
s16 colors[9][3] = {
{ 4, 195, 46 }, // Forest Temple
@@ -33,18 +33,23 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gDPSetGrayscaleColor(POLY_OPA_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
gSPGrayscale(POLY_OPA_DISP++, true);
if (isColoredKeysEnabled) {
gDPSetGrayscaleColor(POLY_OPA_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
gSPGrayscale(POLY_OPA_DISP++, true);
}
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSmallKeyDL);
gSPGrayscale(POLY_OPA_DISP++, false);
if (isColoredKeysEnabled) {
gSPGrayscale(POLY_OPA_DISP++, false);
}
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s8 isColoredKeysEnabled = CVar_GetS32("gRandoMatchKeyColors", 0);
s16 color_slot;
color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_BOSS_KEY;
s16 colors[6][3] = {
@@ -63,14 +68,14 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
if (color_slot == 5) { // Ganon's Boss Key
if (color_slot == 5 && isColoredKeysEnabled) { // Ganon's Boss Key
gDPSetGrayscaleColor(POLY_OPA_DISP++, 80, 80, 80, 255);
gSPGrayscale(POLY_OPA_DISP++, true);
}
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiBossKeyDL);
if (color_slot == 5) { // Ganon's Boss Key
if (color_slot == 5 && isColoredKeysEnabled) { // Ganon's Boss Key
gSPGrayscale(POLY_OPA_DISP++, false);
}
@@ -79,13 +84,16 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gDPSetGrayscaleColor(POLY_XLU_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2],
255);
gSPGrayscale(POLY_XLU_DISP++, true);
if (isColoredKeysEnabled) {
gDPSetGrayscaleColor(POLY_XLU_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
gSPGrayscale(POLY_XLU_DISP++, true);
}
gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBossKeyGemDL);
gSPGrayscale(POLY_XLU_DISP++, false);
if (isColoredKeysEnabled) {
gSPGrayscale(POLY_XLU_DISP++, false);
}
CLOSE_DISPS(play->state.gfxCtx);
}
@@ -157,25 +165,3 @@ extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getIt
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawIceTrap(PlayState* play, GetItemEntry getItemEntry) {
s32 pad;
OPEN_DISPS(play->state.gfxCtx);
if (CVar_GetS32("gLetItSnow", 0)) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
gDPSetGrayscaleColor(POLY_OPA_DISP++, 100, 100, 100, 255);
gSPGrayscale(POLY_OPA_DISP++, true);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL);
gSPGrayscale(POLY_OPA_DISP++, false);
}
CLOSE_DISPS(play->state.gfxCtx);
}
+80 -16
View File
@@ -342,20 +342,20 @@ void Randomizer::LoadHintLocations(const char* spoilerFileName) {
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_WARP_RANDOM_REPLACED_TEXT,
{ TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM,
"Warp to&{{location}}?\x1B&%gOK&No%w\x02",
"Warp to&{{location}}?\x1B&%gOK&No%w\x02", // TODO: German translation
"Zu {{location}}?\x1B&%gOK&No%w\x02",
"Se téléporter vers&{{location}}?\x1B&%gOK!&Non%w\x02" });
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN,
{ TEXTBOX_TYPE_WOODEN, TEXTBOX_POS_BOTTOM,
"Water level control system.&Keep away!",
"Wasserstand Kontrollsystem&Finger weg!",
"Contrôle du niveau de l'eau.&Ne pas toucher!"
"Système de contrôle du niveau&d'eau.&Ne pas toucher!"
});
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI,
{ TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM,
"This switch is rustier than you think.^Something must be wrong with the&pipe system in the Water Temple.",
"Dieser Schalter scheint rostiger zu&sein als er aussieht.^Etwas muss mit dem Leitungssystem&im Wassertempel nicht stimmen.",
"Cet interrupteur est très rouillé.^Quelque chose ne va pas avec&la tuyauterie du Temple de l'Eau."
{ TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM,
"%cThis switch is rustier than you think.^%cSomething must be wrong with the&pipe system in the %bWater Temple%c.",
"%cDieser Schalter scheint rostiger zu&sein als er aussieht.^%cEtwas muss mit dem Leitungssystem&im %bWassertempel%c nicht stimmen.",
"%cCet interrupteur est très rouillé.^%cIl doit y avoir un problème avec&la tuyauterie du %bTemple de l'Eau%c."
});
}
@@ -471,9 +471,9 @@ void Randomizer::LoadMerchantMessages(const char* spoilerFileName) {
{
TEXTBOX_TYPE_BLACK,
TEXTBOX_POS_TOP,
"Finally! Now I can go back to being &an %rarms dealer!%w",
"Finally! Now I can go back to being &an %rarms dealer%w!",
"Endlich! Schon bald kann ich wieder &%rKrabbelminen-Händler%w sein!",
"Squalala! Je vais enfin pouvoir &%rprendre des vacances!%w"
"Squalala! Je vais enfin pouvoir &%rprendre des vacances%w!"
}
);
@@ -1162,6 +1162,65 @@ void Randomizer::ParseMasterQuestDungeonsFile(const char* spoilerFileName) {
}
}
int16_t Randomizer::GetVanillaMerchantPrice(RandomizerCheck check) {
switch (check) {
case RC_HF_DEKU_SCRUB_GROTTO:
return 10;
case RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT:
case RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS:
case RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR:
return 15;
case RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT:
case RC_LH_DEKU_SCRUB_GROTTO_LEFT:
case RC_GC_DEKU_SCRUB_GROTTO_LEFT:
case RC_DMC_DEKU_SCRUB_GROTTO_LEFT:
case RC_LLR_DEKU_SCRUB_GROTTO_LEFT:
case RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT:
case RC_JABU_JABUS_BELLY_DEKU_SCRUB:
case RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT:
return 20;
case RC_LW_DEKU_SCRUB_NEAR_BRIDGE:
case RC_LW_DEKU_SCRUB_GROTTO_REAR:
case RC_LW_DEKU_SCRUB_GROTTO_FRONT:
case RC_SFM_DEKU_SCRUB_GROTTO_REAR:
case RC_SFM_DEKU_SCRUB_GROTTO_FRONT:
case RC_LH_DEKU_SCRUB_GROTTO_RIGHT:
case RC_LH_DEKU_SCRUB_GROTTO_CENTER:
case RC_GV_DEKU_SCRUB_GROTTO_REAR:
case RC_GV_DEKU_SCRUB_GROTTO_FRONT:
case RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR:
case RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT:
case RC_GC_DEKU_SCRUB_GROTTO_RIGHT:
case RC_GC_DEKU_SCRUB_GROTTO_CENTER:
case RC_DMC_DEKU_SCRUB:
case RC_DMC_DEKU_SCRUB_GROTTO_RIGHT:
case RC_DMC_DEKU_SCRUB_GROTTO_CENTER:
case RC_ZR_DEKU_SCRUB_GROTTO_REAR:
case RC_ZR_DEKU_SCRUB_GROTTO_FRONT:
case RC_LLR_DEKU_SCRUB_GROTTO_RIGHT:
case RC_LLR_DEKU_SCRUB_GROTTO_CENTER:
case RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT:
case RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT:
case RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS:
case RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT:
case RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT:
case RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT:
case RC_GANONS_CASTLE_DEKU_SCRUB_LEFT:
case RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT:
case RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER:
case RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT:
case RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT:
return 40;
case RC_DEKU_TREE_MQ_DEKU_SCRUB:
case RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY:
case RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE:
return 50;
default:
// we check for -1 when calling this to know if we don't have a price
return -1;
}
}
void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent) {
std::ifstream spoilerFileStream(sanitize(spoilerFileName));
if (!spoilerFileStream)
@@ -1186,7 +1245,6 @@ void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent
if (it->is_structured()) {
json itemJson = *it;
for (auto itemit = itemJson.begin(); itemit != itemJson.end(); ++itemit) {
// todo handle prices
if (itemit.key() == "item") {
gSaveContext.itemLocations[randomizerCheck].check = randomizerCheck;
gSaveContext.itemLocations[randomizerCheck].get.rgID = SpoilerfileGetNameToEnum[itemit.value()];
@@ -1204,6 +1262,10 @@ void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent
gSaveContext.itemLocations[randomizerCheck].check = SpoilerfileCheckNameToEnum[it.key()];
gSaveContext.itemLocations[randomizerCheck].get.rgID = SpoilerfileGetNameToEnum[it.value()];
gSaveContext.itemLocations[randomizerCheck].get.fakeRgID = RG_NONE;
int16_t price = GetVanillaMerchantPrice(randomizerCheck);
if (price != -1) {
merchantPrices[gSaveContext.itemLocations[randomizerCheck].check] = price;
}
}
}
@@ -2546,6 +2608,8 @@ GetItemEntry Randomizer::GetItemEntryFromRGData(RandomizerGetData rgData, GetIte
GetItemEntry fakeGiEntry = ItemTableManager::Instance->RetrieveItemEntry(modIndex, GetItemIdFromRandomizerGet(rgData.fakeRgID, ogItemId));
giEntry.gid = fakeGiEntry.gid;
giEntry.gi = fakeGiEntry.gi;
giEntry.drawItemId = fakeGiEntry.drawItemId;
giEntry.drawModIndex = fakeGiEntry.drawModIndex;
giEntry.drawFunc = fakeGiEntry.drawFunc;
}
return giEntry;
@@ -3491,9 +3555,11 @@ void DrawRandoEditor(bool& open) {
UIWidgets::InsertHelpHoverText(
"Start with - You will start with all Small Keys from all dungeons.\n"
"\n"
"Vanilla - Small Keys will appear in their vanilla locations.\n"
"Vanilla - Small Keys will appear in their vanilla locations. "
"You start with 3 keys in Spirit Temple MQ because the vanilla key layout is not beatable in logic.\n"
"\n"
"Own dungeon - Small Keys can only appear in their respective dungeon.\n"
"Own dungeon - Small Keys can only appear in their respective dungeon. "
"If Fire Temple is not a Master Quest dungeon, the door to the Boss Key chest will be unlocked.\n"
"\n"
"Any dungeon - Small Keys can only appear inside of any dungon.\n"
"\n"
@@ -4141,7 +4207,7 @@ CustomMessageEntry Randomizer::GetWarpSongMessage(u16 textId, bool mysterious) {
if (mysterious) {
std::vector<std::string> locationName ={
"a mysterious place",
"a mysterious place", // TODO: German translation
"ein mysteriöser Ort",
"un endroit mystérieux",
};
@@ -4506,8 +4572,8 @@ void CreateIceTrapRandoMessages() {
// We only use this ice trap message for christmas, so we don't want it in the normal ice trap messages rotation
customMessageManager->CreateMessage(Randomizer::IceTrapRandoMessageTableID, NUM_ICE_TRAP_MESSAGES + 1,
{ TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM,
"This year for Christmas, all&you get is %BCOAL",
"This year for Christmas, all&you get is %BCOAL",
"This year for Christmas, all&you get is %BCOAL%w!",
"This year for Christmas, all&you get is %BCOAL%w!",
"Pour Noël, cette année, tu&n'auras que du %BCHARBON!&%rJoyeux Noël%w!" });
}
@@ -4866,8 +4932,6 @@ void InitRandoItemTable() {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey;
} else if (randoGetItemTable[i].itemId == RG_DOUBLE_DEFENSE) {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawDoubleDefense;
} else if (randoGetItemTable[i].itemId == RG_ICE_TRAP) {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawIceTrap;
}
ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, randoGetItemTable[i].itemId, randoGetItemTable[i]);
}
@@ -31,6 +31,7 @@ class Randomizer {
void ParseEntranceDataFile(const char* spoilerFileName, bool silent);
bool IsItemVanilla(RandomizerGet randoGet);
GetItemEntry GetItemEntryFromRGData(RandomizerGetData rgData, GetItemID ogItemId, bool checkObtainability = true);
int16_t GetVanillaMerchantPrice(RandomizerCheck check);
public:
Randomizer();
@@ -587,8 +587,8 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = {
RC_OBJECT(RC_WATER_TEMPLE_MORPHA_HEART, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_MIZUSIN_BS, 0x00, GI_HEART_CONTAINER, "Morpha Heart Container", "Water Temple Morpha Heart Container"),
RC_OBJECT(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPOT11, 1707, GI_GAUNTLETS_SILVER, "Silver Gauntlets Chest", "Spirit Temple Silver Gauntlets Chest"),
RC_OBJECT(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPOT11, 13673, GI_SHIELD_MIRROR, "Mirror Shield Chest", "Spirit Temple Mirror Shield Chest"),
RC_OBJECT(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPOT11, 1707, GI_GAUNTLETS_SILVER, "Silver Gauntlets Chest", "Spirit Temple Silver Gauntlets Chest"),
RC_OBJECT(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPOT11, 13673, GI_SHIELD_MIRROR, "Mirror Shield Chest", "Spirit Temple Mirror Shield Chest"),
RC_OBJECT(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_JYASINZOU, 21800, GI_SHIELD_DEKU, "Child Bridge Chest", "Spirit Temple Child Bridge Chest"),
RC_OBJECT(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_JYASINZOU, -30656, GI_KEY_SMALL, "Child Early Torches Chest", "Spirit Temple Child Early Torches Chest"),
RC_OBJECT(RC_SPIRIT_TEMPLE_COMPASS_CHEST, RCVORMQ_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_JYASINZOU, 14340, GI_COMPASS, "Compass Chest", "Spirit Temple Compass Chest"),
@@ -776,7 +776,7 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = {
RC_OBJECT(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RCVORMQ_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_MEN, 31394, GI_RUPEE_PURPLE, "MQ Heavy Block Chest", "Gerudo Training Grounds MQ Heavy Block Chest"),
RC_OBJECT(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANON, 10219, GI_KEY_BOSS, "Boss Key Chest", "Ganon's Tower Boss Key Chest"),
RC_OBJECT(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANON, 10219, GI_KEY_BOSS, "Boss Key Chest", "Ganon's Tower Boss Key Chest"),
RC_OBJECT(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONTIKA, 30857, GI_MAGIC_LARGE, "Forest Trial Chest", "Ganon's Castle Forest Trial Chest"),
RC_OBJECT(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONTIKA, 24455, GI_ICE_TRAP, "Water Trial Left Chest", "Ganon's Castle Water Trial Left Chest"),
RC_OBJECT(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RCVORMQ_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONTIKA, 22790, GI_HEART, "Water Trial Right Chest", "Ganon's Castle Water Trial Right Chest"),
@@ -198,8 +198,8 @@ s16 Entrance_OverrideNextIndex(s16 nextEntranceIndex) {
}
// Exiting through the crawl space from Hyrule Castle courtyard is the same exit as leaving Ganon's castle
// If we came from the Castle courtyard, then don't override the entrance to keep Link in Hyrule Castle area
if (gPlayState != NULL && gPlayState->sceneNum == 69 && nextEntranceIndex == 0x023D) {
// Don't override the entrance if we came from the Castle courtyard (day and night scenes)
if (gPlayState != NULL && (gPlayState->sceneNum == 69 || gPlayState->sceneNum == 70) && nextEntranceIndex == 0x023D) {
return nextEntranceIndex;
}
@@ -433,6 +433,10 @@ void Entrance_HandleEponaState(void) {
//If Link is riding Epona but he's about to go through an entrance where she can't spawn,
//unset the Epona flag to avoid Master glitch, and restore temp B.
if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES) && (player->stateFlags1 & PLAYER_STATE1_23)) {
// Allow Master glitch to be performed on the Thieves Hideout entrance
if (entrance == Entrance_GetOverride(0x0496)) { // Gerudo Fortress -> Theives Hideout
return;
}
static const s16 validEponaEntrances[] = {
0x0102, // Hyrule Field -> Lake Hylia
@@ -444,12 +448,11 @@ void Entrance_HandleEponaState(void) {
0x0157, // Hyrule Field -> Lon Lon Ranch
0x01F9, // Lon Lon Ranch -> Hyrule Field
0x01FD, // Market Entrance -> Hyrule Field
0x00EA, // ZR Front -> Hyrule Field
0x0181, // LW Bridge -> Hyrule Field
0x0181, // ZR Front -> Hyrule Field
0x0185, // LW Bridge -> Hyrule Field
0x0129, // GV Fortress Side -> Gerudo Fortress
0x022D, // Gerudo Fortress -> GV Fortress Side
0x03D0, // GV Carpenter Tent -> GV Fortress Side
0x0496, // Gerudo Fortress -> Thieves Hideout
0x042F, // LLR Stables -> Lon Lon Ranch
0x05D4, // LLR Tower -> Lon Lon Ranch
0x0378, // LLR Talons House -> Lon Lon Ranch
+49 -15
View File
@@ -181,6 +181,28 @@ std::map<u16, std::tuple<std::string, std::string, SeqType>> sfxEditorSequenceMa
{NA_SE_EV_CHICKEN_CRY_A, {"Chicken Cry", "NA_SE_EV_CHICKEN_CRY_A", SEQ_SFX}},
};
// Grabs the current BGM sequence ID and replays it
// which will lookup the proper override, or reset back to vanilla
void ReplayCurrentBGM() {
u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
// TODO: replace with Audio_StartSeq when the macro is shared
// The fade time and audio player flags will always be 0 in the case of replaying the BGM, so they are not set here
Audio_QueueSeqCmd(0x00000000 | curSeqId);
}
// Attempt to update the BGM if it matches the current sequence that is being played
// The seqKey that is passed in should be the vanilla ID, not the override ID
void UpdateCurrentBGM(u16 seqKey, SeqType seqType) {
if (seqType != SEQ_BGM_WORLD) {
return;
}
u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
if (curSeqId == seqKey) {
ReplayCurrentBGM();
}
}
void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::string, std::string, SeqType>>& map, SeqType type) {
const std::string hiddenTabId = "##" + tabId;
const std::string resetAllButton = "Reset All" + hiddenTabId;
@@ -189,11 +211,18 @@ void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::s
for (const auto& [defaultValue, seqData] : map) {
const auto& [name, sfxKey, seqType] = seqData;
if (seqType == type) {
// Only save authentic sequence CVars
if (seqType == SEQ_FANFARE && defaultValue >= MAX_AUTHENTIC_SEQID) {
continue;
}
const std::string cvarKey = "gSfxEditor_" + sfxKey;
CVar_SetS32(cvarKey.c_str(), defaultValue);
}
}
SohImGui::RequestCvarSaveOnNextTick();
if (type == SEQ_BGM_WORLD) {
ReplayCurrentBGM();
}
}
ImGui::SameLine();
if (ImGui::Button(randomizeAllButton.c_str())) {
@@ -208,7 +237,8 @@ void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::s
const auto& [name, sfxKey, seqType] = seqData;
const std::string cvarKey = "gSfxEditor_" + sfxKey;
if (seqType & type) {
if (((seqType & SEQ_BGM_CUSTOM) || seqType == SEQ_FANFARE) && defaultValue > MAX_AUTHENTIC_SEQID) {
// Only save authentic sequence CVars
if (((seqType & SEQ_BGM_CUSTOM) || seqType == SEQ_FANFARE) && defaultValue >= MAX_AUTHENTIC_SEQID) {
continue;
}
const int randomValue = values.back();
@@ -217,6 +247,9 @@ void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::s
}
}
SohImGui::RequestCvarSaveOnNextTick();
if (type == SEQ_BGM_WORLD) {
ReplayCurrentBGM();
}
}
ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit);
@@ -229,6 +262,7 @@ void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::s
if (~(seqType) & type) {
continue;
}
// Do not display custom sequences in the list
if (((seqType & SEQ_BGM_CUSTOM) || seqType == SEQ_FANFARE) && defaultValue >= MAX_AUTHENTIC_SEQID) {
continue;
}
@@ -257,6 +291,7 @@ void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::s
if (ImGui::Selectable(std::get<0>(seqData).c_str())) {
CVar_SetS32(cvarKey.c_str(), value);
SohImGui::RequestCvarSaveOnNextTick();
UpdateCurrentBGM(defaultValue, type);
}
}
@@ -293,23 +328,22 @@ void Draw_SfxTab(const std::string& tabId, const std::map<u16, std::tuple<std::s
if (ImGui::Button(resetButton.c_str())) {
CVar_SetS32(cvarKey.c_str(), defaultValue);
SohImGui::RequestCvarSaveOnNextTick();
UpdateCurrentBGM(defaultValue, seqType);
}
ImGui::SameLine();
ImGui::PushItemWidth(-FLT_MIN);
if (ImGui::Button(randomizeButton.c_str())) {
bool valid = false;
uint32_t value;
while (!valid) {
value = Random(2, map.size());
if (map.contains(value)) {
auto [name, sfxKey, seqType] = map.at(value);
if (seqType & type) {
valid = true;
}
auto it = map.begin();
while (true) {
const auto& [value, seqData] = *std::next(it, rand() % map.size());
const auto& [name, sfxKey, seqType] = seqData;
if (seqType & type) {
CVar_SetS32(cvarKey.c_str(), value);
SohImGui::RequestCvarSaveOnNextTick();
UpdateCurrentBGM(defaultValue, type);
break;
}
}
CVar_SetS32(cvarKey.c_str(), value);
SohImGui::RequestCvarSaveOnNextTick();
}
}
ImGui::EndTable();
@@ -324,7 +358,7 @@ extern "C" u16 SfxEditor_GetReplacementSeq(u16 seqId) {
seqId = NA_BGM_FIELD_LOGIC;
}
}
if (sfxEditorSequenceMap.find(seqId) == sfxEditorSequenceMap.end()) {
return seqId;
}
@@ -355,7 +389,7 @@ void DrawSfxEditor(bool& open) {
CVar_SetS32("gSfxEditor", 0);
return;
}
ImGui::SetNextWindowSize(ImVec2(465, 630), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(900, 630), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("SFX Editor", &open)) {
ImGui::End();
return;
@@ -426,7 +460,7 @@ void InitSfxEditor() {
}
extern "C" void SfxEditor_AddSequence(char *otrPath, uint16_t seqNum) {
std::vector<std::string> splitName = StringHelper::Split(otrPath, "/");
std::vector<std::string> splitName = StringHelper::Split(std::string(otrPath), "/");
std::string fileName = splitName[splitName.size() - 1];
std::vector<std::string> splitFileName = StringHelper::Split(fileName, "_");
std::string sequenceName = splitFileName[0];
@@ -7,7 +7,6 @@ void SfxEditor_AddSequence(char *otrPath, uint16_t seqNum);
#endif
#define INSTRUMENT_OFFSET 0x81
#define MAX_AUTHENTIC_SEQID 110
enum SeqType {
SEQ_NOSHUFFLE = 0,
+4
View File
@@ -271,6 +271,10 @@ namespace GameMenuBar {
ImGui::PopStyleVar(1);
}
if (SohImGui::supportsWindowedFullscreen()) {
UIWidgets::PaddedEnhancementCheckbox("Windowed fullscreen", "gSdlWindowedFullscreen", true, false);
}
if (SohImGui::supportsViewports()) {
UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false);
UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a reload to take effect.");
+6 -3
View File
@@ -83,9 +83,12 @@ extern "C" void gSPVertex(Gfx* pkt, uintptr_t v, int n, int v0) {
extern "C" void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr)
{
char* imgData = (char*)texAddr;
if (texAddr != 0 && ResourceMgr_OTRSigCheck(imgData))
texAddr = (uintptr_t)ResourceMgr_LoadTexByName(imgData);
if (texAddr != 0 && ResourceMgr_OTRSigCheck(imgData)) {
// Temporary solution to the mq/nonmq issue, this will be
// handled better with LUS 1.0
texAddr = (uintptr_t)ResourceMgr_LoadTexOrDListByName(imgData);
}
__gSPInvalidateTexCache(pkt, texAddr);
}
+35 -27
View File
@@ -461,6 +461,11 @@ extern "C" void InitOTR() {
#ifdef ENABLE_CROWD_CONTROL
CrowdControl::Instance = new CrowdControl();
CrowdControl::Instance->Init();
if (CVar_GetS32("gCrowdControl", 0)) {
CrowdControl::Instance->Enable();
} else {
CrowdControl::Instance->Disable();
}
#endif
}
@@ -724,29 +729,19 @@ extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize)
return result;
}
std::string GetName(const char* path) {
std::string Path = path;
if (IsGameMasterQuest()) {
size_t pos = 0;
if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) {
Path.replace(pos, 7, "/mq/");
}
}
return Path;
}
extern "C" const char* ResourceMgr_GetName(const char* path) {
auto s = new std::string(GetName(path));
const char* name = s->c_str();
return name;
}
extern "C" void ResourceMgr_LoadFile(const char* resName) {
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName);
}
std::shared_ptr<Ship::Resource> ResourceMgr_LoadResource(const char* path) {
return OTRGlobals::Instance->context->GetResourceManager()->LoadResource(ResourceMgr_GetName(path));
std::string Path = path;
if (ResourceMgr_IsGameMasterQuest()) {
size_t pos = 0;
if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) {
Path.replace(pos, 7, "/mq/");
}
}
return OTRGlobals::Instance->context->GetResourceManager()->LoadResource(Path.c_str());
}
extern "C" char* ResourceMgr_LoadFileRaw(const char* resName) {
@@ -821,7 +816,14 @@ extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) {
else if (res->ResType == Ship::ResourceType::Array)
return (char*)(std::static_pointer_cast<Ship::Array>(res))->vertices.data();
else {
return ResourceMgr_LoadTexByName(ResourceMgr_GetName(filePath));
std::string Path = filePath;
if (ResourceMgr_IsGameMasterQuest()) {
size_t pos = 0;
if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) {
Path.replace(pos, 7, "/mq/");
}
}
return ResourceMgr_LoadTexByName(Path.c_str());
}
}
@@ -867,6 +869,11 @@ extern "C" void ResourceMgr_PatchGfxByName(const char* path, const char* patchNa
}
}*/
// Index refers to individual gfx words, which are half the size on 32-bit
if (sizeof(uintptr_t) < 8) {
index /= 2;
}
Gfx* gfx = (Gfx*)&res->instructions[index];
if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) {
@@ -1132,7 +1139,7 @@ extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(const char* path)
sampleC->unk_bit26 = sample->unk_bit26;
sampleC->unk_bit25 = sample->unk_bit25;
sampleC->book = new AdpcmBook[sample->book.books.size() * sizeof(int16_t)];
sampleC->book = (AdpcmBook*) malloc(sizeof(AdpcmBook) + sample->book.books.size() * sizeof(int16_t));
sampleC->book->npredictors = sample->book.npredictors;
sampleC->book->order = sample->book.order;
@@ -1755,12 +1762,13 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) {
}
}
extern "C" int Controller_ShouldRumble(size_t i) {
extern "C" int Controller_ShouldRumble(size_t slot) {
auto controlDeck = Ship::Window::GetInstance()->GetControlDeck();
for (int i = 0; i < controlDeck->GetNumVirtualDevices(); ++i) {
auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(i);
if (physicalDevice->CanRumble()) {
if (slot < controlDeck->GetNumVirtualDevices()) {
auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(slot);
if (physicalDevice->getProfile(slot)->UseRumble && physicalDevice->CanRumble()) {
return 1;
}
}
@@ -1793,11 +1801,11 @@ extern "C" int GetEquipNowMessage(char* buffer, char* src, const int maxBufferSi
std::string postfix;
if (gSaveContext.language == LANGUAGE_FRA) {
postfix = "\x04\x1A\x08" "sirez-vous l'équiper maintenant?" "\x09&&"
postfix = "\x04\x1A\x08" "D\x96sirez-vous l'\x96quiper maintenant?" "\x09&&"
"\x1B%g" "Oui" "&"
"Non" "%w\x02";
} else if (gSaveContext.language == LANGUAGE_GER) {
postfix = "\x04\x1A\x08" "chtest Du es jetzt ausrüsten?" "\x09&&"
postfix = "\x04\x1A\x08" "M""\x9A""chtest Du es jetzt ausr\x9Esten?" "\x09&&"
"\x1B%g" "Ja!" "&"
"Nein!" "%w\x02";
} else {
+1 -3
View File
@@ -37,7 +37,6 @@ private:
};
uint32_t IsGameMasterQuest();
std::string GetName(const char* path);
#endif
#ifndef __cplusplus
@@ -60,7 +59,6 @@ uint32_t ResourceMgr_GetNumGameVersions();
uint32_t ResourceMgr_GetGameVersion(int index);
void ResourceMgr_CacheDirectory(const char* resName);
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
const char* ResourceMgr_GetName(const char* path);
void ResourceMgr_LoadFile(const char* resName);
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
char* ResourceMgr_LoadJPEG(char* data, int dataSize);
@@ -106,7 +104,7 @@ int AudioPlayer_Buffered(void);
int AudioPlayer_GetDesiredBuffered(void);
void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
int Controller_ShouldRumble(size_t i);
int Controller_ShouldRumble(size_t slot);
void Controller_BlockGameInput();
void Controller_UnblockGameInput();
void Hooks_ExecuteAudioInit();
+213 -6
View File
@@ -24,7 +24,8 @@ std::filesystem::path SaveManager::GetFileName(int fileNum) {
SaveManager::SaveManager() {
AddLoadFunction("base", 1, LoadBaseVersion1);
AddLoadFunction("base", 2, LoadBaseVersion2);
AddSaveFunction("base", 2, SaveBase);
AddLoadFunction("base", 3, LoadBaseVersion3);
AddSaveFunction("base", 3, SaveBase);
AddLoadFunction("randomizer", 1, LoadRandomizerVersion1);
AddLoadFunction("randomizer", 2, LoadRandomizerVersion2);
@@ -825,9 +826,9 @@ void SaveManager::LoadBaseVersion1() {
SaveManager::Instance->LoadData("rupees", gSaveContext.rupees);
SaveManager::Instance->LoadData("swordHealth", gSaveContext.swordHealth);
SaveManager::Instance->LoadData("naviTimer", gSaveContext.naviTimer);
SaveManager::Instance->LoadData("isMagicAcquired", gSaveContext.isMagicAcquired);
SaveManager::Instance->LoadData("isDoubleMagicAcquired", gSaveContext.isDoubleMagicAcquired);
SaveManager::Instance->LoadData("isDoubleDefenseAcquired", gSaveContext.isDoubleDefenseAcquired);
SaveManager::Instance->LoadData("magicAcquired", gSaveContext.isMagicAcquired);
SaveManager::Instance->LoadData("doubleMagic", gSaveContext.isDoubleMagicAcquired);
SaveManager::Instance->LoadData("doubleDefense", gSaveContext.isDoubleDefenseAcquired);
SaveManager::Instance->LoadData("bgsFlag", gSaveContext.bgsFlag);
SaveManager::Instance->LoadData("ocarinaGameRoundNum", gSaveContext.ocarinaGameRoundNum);
SaveManager::Instance->LoadStruct("childEquips", []() {
@@ -923,8 +924,8 @@ void SaveManager::LoadBaseVersion1() {
SaveManager::Instance->LoadData("", gSaveContext.infTable[i]);
});
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
SaveManager::Instance->LoadData("scarecrowLongSongSet", gSaveContext.scarecrowLongSongSet);
SaveManager::Instance->LoadArray("scarecrowLongSong", sizeof(gSaveContext.scarecrowLongSong), [](size_t i) {
SaveManager::Instance->LoadData("scarecrowCustomSongSet", gSaveContext.scarecrowLongSongSet);
SaveManager::Instance->LoadArray("scarecrowCustomSong", sizeof(gSaveContext.scarecrowLongSong), [](size_t i) {
SaveManager::Instance->LoadData("", ((u8*)&gSaveContext.scarecrowLongSong)[i]);
});
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
@@ -947,6 +948,212 @@ void SaveManager::LoadBaseVersion1() {
}
void SaveManager::LoadBaseVersion2() {
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.entranceIndex);
SaveManager::Instance->LoadData("linkAge", gSaveContext.linkAge);
SaveManager::Instance->LoadData("cutsceneIndex", gSaveContext.cutsceneIndex);
SaveManager::Instance->LoadData("dayTime", gSaveContext.dayTime);
SaveManager::Instance->LoadData("nightFlag", gSaveContext.nightFlag);
SaveManager::Instance->LoadData("totalDays", gSaveContext.totalDays);
SaveManager::Instance->LoadData("bgsDayCount", gSaveContext.bgsDayCount);
SaveManager::Instance->LoadData("deaths", gSaveContext.deaths);
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
});
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag);
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
SaveManager::Instance->LoadData("health", gSaveContext.health);
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
SaveManager::Instance->LoadData("magic", gSaveContext.magic);
SaveManager::Instance->LoadData("rupees", gSaveContext.rupees);
SaveManager::Instance->LoadData("swordHealth", gSaveContext.swordHealth);
SaveManager::Instance->LoadData("naviTimer", gSaveContext.naviTimer);
SaveManager::Instance->LoadData("magicAcquired", gSaveContext.isMagicAcquired);
SaveManager::Instance->LoadData("doubleMagic", gSaveContext.isDoubleMagicAcquired);
SaveManager::Instance->LoadData("doubleDefense", gSaveContext.isDoubleDefenseAcquired);
SaveManager::Instance->LoadData("bgsFlag", gSaveContext.bgsFlag);
SaveManager::Instance->LoadData("ocarinaGameRoundNum", gSaveContext.ocarinaGameRoundNum);
SaveManager::Instance->LoadStruct("childEquips", []() {
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.childEquips.buttonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.childEquips.buttonItems[i],
static_cast<uint8_t>(ITEM_NONE));
});
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.childEquips.cButtonSlots), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.childEquips.cButtonSlots[i],
static_cast<uint8_t>(SLOT_NONE));
});
SaveManager::Instance->LoadData("equipment", gSaveContext.childEquips.equipment);
});
SaveManager::Instance->LoadStruct("adultEquips", []() {
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.adultEquips.buttonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.buttonItems[i],
static_cast<uint8_t>(ITEM_NONE));
});
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.adultEquips.cButtonSlots), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.cButtonSlots[i],
static_cast<uint8_t>(SLOT_NONE));
});
SaveManager::Instance->LoadData("equipment", gSaveContext.adultEquips.equipment);
});
SaveManager::Instance->LoadData("unk_54", gSaveContext.unk_54);
SaveManager::Instance->LoadData("savedSceneNum", gSaveContext.savedSceneNum);
SaveManager::Instance->LoadStruct("equips", []() {
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.equips.buttonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.equips.buttonItems[i], static_cast<uint8_t>(ITEM_NONE));
});
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.equips.cButtonSlots), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.equips.cButtonSlots[i], static_cast<uint8_t>(SLOT_NONE));
});
SaveManager::Instance->LoadData("equipment", gSaveContext.equips.equipment);
});
SaveManager::Instance->LoadStruct("inventory", []() {
SaveManager::Instance->LoadArray("items", ARRAY_COUNT(gSaveContext.inventory.items), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.items[i]);
});
SaveManager::Instance->LoadArray("ammo", ARRAY_COUNT(gSaveContext.inventory.ammo), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.ammo[i]);
});
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
SaveManager::Instance->LoadArray("dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
});
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
});
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
});
SaveManager::Instance->LoadStruct("sohStats", []() {
SaveManager::Instance->LoadData("heartPieces", gSaveContext.sohStats.heartPieces);
SaveManager::Instance->LoadData("heartContainers", gSaveContext.sohStats.heartContainers);
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.sohStats.dungeonKeys[i]);
});
SaveManager::Instance->LoadData("playTimer", gSaveContext.sohStats.playTimer);
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.sohStats.pauseTimer);
SaveManager::Instance->LoadArray("timestamps", ARRAY_COUNT(gSaveContext.sohStats.timestamp), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.sohStats.timestamp[i]);
});
SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.sohStats.count), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.sohStats.count[i]);
});
SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.sohStats.scenesDiscovered[i]);
});
SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.sohStats.entrancesDiscovered[i]);
});
});
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
SaveManager::Instance->LoadData("clear", gSaveContext.sceneFlags[i].clear);
SaveManager::Instance->LoadData("collect", gSaveContext.sceneFlags[i].collect);
SaveManager::Instance->LoadData("unk", gSaveContext.sceneFlags[i].unk);
SaveManager::Instance->LoadData("rooms", gSaveContext.sceneFlags[i].rooms);
SaveManager::Instance->LoadData("floors", gSaveContext.sceneFlags[i].floors);
});
});
SaveManager::Instance->LoadStruct("fw", []() {
SaveManager::Instance->LoadStruct("pos", []() {
SaveManager::Instance->LoadData("x", gSaveContext.fw.pos.x);
SaveManager::Instance->LoadData("y", gSaveContext.fw.pos.y);
SaveManager::Instance->LoadData("z", gSaveContext.fw.pos.z);
});
SaveManager::Instance->LoadData("yaw", gSaveContext.fw.yaw);
SaveManager::Instance->LoadData("playerParams", gSaveContext.fw.playerParams);
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.fw.entranceIndex);
SaveManager::Instance->LoadData("roomIndex", gSaveContext.fw.roomIndex);
SaveManager::Instance->LoadData("set", gSaveContext.fw.set);
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.fw.tempSwchFlags);
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.fw.tempCollectFlags);
});
SaveManager::Instance->LoadArray("gsFlags", ARRAY_COUNT(gSaveContext.gsFlags), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.gsFlags[i]);
});
SaveManager::Instance->LoadArray("highScores", ARRAY_COUNT(gSaveContext.highScores), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.highScores[i]);
});
SaveManager::Instance->LoadArray("eventChkInf", ARRAY_COUNT(gSaveContext.eventChkInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.eventChkInf[i]);
});
SaveManager::Instance->LoadArray("itemGetInf", ARRAY_COUNT(gSaveContext.itemGetInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.itemGetInf[i]);
});
SaveManager::Instance->LoadArray("infTable", ARRAY_COUNT(gSaveContext.infTable), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.infTable[i]);
});
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
SaveManager::Instance->LoadData("scarecrowCustomSongSet", gSaveContext.scarecrowLongSongSet);
SaveManager::Instance->LoadArray("scarecrowCustomSong", ARRAY_COUNT(gSaveContext.scarecrowLongSong), [](size_t i) {
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowLongSong[i].noteIdx);
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowLongSong[i].unk_01);
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowLongSong[i].unk_02);
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowLongSong[i].volume);
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowLongSong[i].vibrato);
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowLongSong[i].tone);
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowLongSong[i].semitone);
});
});
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
SaveManager::Instance->LoadArray("scarecrowSpawnSong", ARRAY_COUNT(gSaveContext.scarecrowSpawnSong), [](size_t i) {
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowSpawnSong[i].noteIdx);
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowSpawnSong[i].unk_01);
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowSpawnSong[i].unk_02);
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowSpawnSong[i].volume);
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowSpawnSong[i].vibrato);
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowSpawnSong[i].tone);
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowSpawnSong[i].semitone);
});
});
SaveManager::Instance->LoadStruct("horseData", []() {
SaveManager::Instance->LoadData("scene", gSaveContext.horseData.scene);
SaveManager::Instance->LoadStruct("pos", []() {
SaveManager::Instance->LoadData("x", gSaveContext.horseData.pos.x);
SaveManager::Instance->LoadData("y", gSaveContext.horseData.pos.y);
SaveManager::Instance->LoadData("z", gSaveContext.horseData.pos.z);
});
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
});
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
});
SaveManager::Instance->LoadData("isMasterQuest", gSaveContext.isMasterQuest);
// Workaround for breaking save compatibility from 5.0.2 -> 5.1.0 in commit d7c35221421bf712b5ead56a360f81f624aca4bc
if (!gSaveContext.isMagicAcquired) {
SaveManager::Instance->LoadData("isMagicAcquired", gSaveContext.isMagicAcquired);
}
if (!gSaveContext.isDoubleMagicAcquired) {
SaveManager::Instance->LoadData("isDoubleMagicAcquired", gSaveContext.isDoubleMagicAcquired);
}
if (!gSaveContext.isDoubleDefenseAcquired) {
SaveManager::Instance->LoadData("isDoubleDefenseAcquired", gSaveContext.isDoubleDefenseAcquired);
}
if (!gSaveContext.scarecrowLongSongSet) {
SaveManager::Instance->LoadData("scarecrowLongSongSet", gSaveContext.scarecrowLongSongSet);
if (gSaveContext.scarecrowLongSongSet) {
SaveManager::Instance->LoadArray("scarecrowLongSong", ARRAY_COUNT(gSaveContext.scarecrowLongSong), [](size_t i) {
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowLongSong[i].noteIdx);
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowLongSong[i].unk_01);
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowLongSong[i].unk_02);
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowLongSong[i].volume);
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowLongSong[i].vibrato);
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowLongSong[i].tone);
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowLongSong[i].semitone);
});
});
}
}
}
void SaveManager::LoadBaseVersion3() {
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.entranceIndex);
SaveManager::Instance->LoadData("linkAge", gSaveContext.linkAge);
SaveManager::Instance->LoadData("cutsceneIndex", gSaveContext.cutsceneIndex);
+1
View File
@@ -122,6 +122,7 @@ public:
static void LoadBaseVersion1();
static void LoadBaseVersion2();
static void LoadBaseVersion3();
static void SaveBase();
std::vector<InitFunc> initFuncs;
+6 -6
View File
@@ -95,7 +95,7 @@ extern "C" void OTRMessage_Init()
{
TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM,
"You got a %rGold Skulltula Token%w!&You've collected %r{{gsCount}}%w tokens&in total!\x0E\x3C",
"Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r{{gsCount}}%w symbol gesammelt!\x0E\x3C",
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r{{gsCount}}%w Golende&Skulltula-Symbole gesammelt!\x0E\x3C",
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r{{gsCount}}%w symboles en tout!\x0E\x3C"
}
);
@@ -104,7 +104,7 @@ extern "C" void OTRMessage_Init()
{
TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM,
"You got a %rGold Skulltula Token%w!&You've collected %r{{gsCount}}%w tokens&in total!",
"Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r{{gsCount}}%w symbol gesammelt!",
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r{{gsCount}}%w Golende&Skulltula-Symbole gesammelt!",
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r{{gsCount}}%w symboles en tout!"
}
);
@@ -131,7 +131,7 @@ extern "C" void OTRMessage_Init()
{
TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM,
"You got a %rHeart Container%w!&You've collected %r{{heartContainerCount}}%w containers&in total!",
"Du erhältst ein %rHerzgefäß%w! Du&hast insgesamt %r{{heartContainerCount}}%w Gefäße&gesammelt!",
"Ein %rHerzcontainer%w!&Du hast nun insgesamt %r{{heartContainerCount}}%w&Herzcontainer gesammelt!",
"Vous obtenez un %rCoeur&d'Energie%w! Vous en avez&collecté %r{{heartContainerCount}}%w en tout!"
}
);
@@ -140,7 +140,7 @@ extern "C" void OTRMessage_Init()
{
TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM,
"You got a %rHeart Piece%w!&You've collected %r{{heartPieceCount}}%w pieces&in total!",
"Du erhältst ein %rHerzteil%w! Du hast&insgesamt %r{{heartPieceCount}}%w Teile&gesammelt!",
"Ein %rHerzteil%w!&Du hast nun insgesamt %r{{heartPieceCount}}%w&Herteile gesammelt!",
"Vous obtenez un %rQuart de&Coeur%w! Vous en avez collecté&%r{{heartPieceCount}}%w en tout!"
}
);
@@ -149,8 +149,8 @@ extern "C" void OTRMessage_Init()
{
TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM,
"You look bored. Wanna go out for a&walk?\x1B&%gYes&No%w",
"Du siehst gelangweilt aus.&Willst du einen Spaziergang machen?\x1B&%gJa&Nein%w", //TODO: AI translated, replace with actual translation
"Tu as l'air de t'ennuyer. Tu veux&aller faire une promenade?\x1B&%gOui&Non%w", //TODO: AI translated, replace with actual translation
"Du siehst gelangweilt aus.&Willst du einen Spaziergang machen?\x1B&%gJa&Nein%w",
"Tu as l'air de t'ennuyer. Tu veux&aller faire un tour?\x1B&%gOui&Non%w",
}
);
}
+2 -2
View File
@@ -168,7 +168,7 @@ void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorName, cons
char buff1[80];
char buff2[80];
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
osSyncPrintf(VT_FGCOL(RED));
osSyncPrintf("DMA致命的エラー(%s)\nROM:%X RAM:%X SIZE:%X %s\n",
errorDesc != NULL ? errorDesc : (errorName != NULL ? errorName : "???"), vrom, ram, size,
@@ -348,7 +348,7 @@ s32 DmaMgr_SendRequestImpl(DmaRequest* req, uintptr_t ram, uintptr_t vrom, size_
if (1) {
if ((sDmaMgrQueueFullLogged == 0) && (sDmaMgrMsgQueue.validCount >= sDmaMgrMsgQueue.msgCount)) {
sDmaMgrQueueFullLogged++;
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
osSyncPrintf(VT_FGCOL(RED));
osSyncPrintf("dmaEntryMsgQが一杯です。キューサイズの再検討をおすすめします。");
LOG_NUM("(sizeof(dmaEntryMsgBufs) / sizeof(dmaEntryMsgBufs[0]))", ARRAY_COUNT(sDmaMgrMsgs));
+8
View File
@@ -78,6 +78,8 @@ void* sUnusedHandler = NULL;
s32 gAudioContextInitalized = false;
char* sequenceMap[MAX_SEQUENCES];
// A map of authentic sequence IDs to their cache policies, for use with sequence swapping.
u8 seqCachePolicyMap[MAX_AUTHENTIC_SEQID];
char* fontMap[256];
uintptr_t fontStart;
@@ -569,15 +571,20 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
s32 index;
s32 numFonts;
s32 fontId;
s8 authCachePolicy = -1; // since 0 is a valid cache policy value
AudioSeq_SequencePlayerDisable(seqPlayer);
fontId = 0xFF;
if (gAudioContext.seqReplaced[playerIdx]) {
authCachePolicy = seqCachePolicyMap[seqId];
seqId = gAudioContext.seqToPlay[playerIdx];
}
SequenceData seqData2 = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
if (authCachePolicy != -1) {
seqData2.cachePolicy = authCachePolicy;
}
for (int i = 0; i < seqData2.numFonts; i++)
{
@@ -1316,6 +1323,7 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
strcpy(str, seqList[i]);
sequenceMap[sDat.seqNumber] = str;
seqCachePolicyMap[sDat.seqNumber] = sDat.cachePolicy;
}
free(seqList);
+8 -6
View File
@@ -8,6 +8,8 @@ typedef struct {
u8 unk_1; // importance?
} Struct_8016E320;
#define GET_PLAYER_IDX(cmd) (cmd & 0xF000000) >> 24
Struct_8016E320 D_8016E320[4][5];
u8 D_8016E348[4];
u32 sAudioSeqCmds[0x100];
@@ -122,7 +124,7 @@ void Audio_ProcessSeqCmd(u32 cmd) {
}
op = cmd >> 28;
playerIdx = (cmd & 0xF000000) >> 24;
playerIdx = GET_PLAYER_IDX(cmd);
switch (op) {
case 0x0:
@@ -371,12 +373,12 @@ void Audio_QueueSeqCmd(u32 cmd)
u8 op = cmd >> 28;
if (op == 0 || op == 2 || op == 12) {
u8 seqId = cmd & 0xFF;
u8 playerIdx = (cmd >> 24) & 0xFF;
u8 playerIdx = GET_PLAYER_IDX(cmd);
u16 newSeqId = SfxEditor_GetReplacementSeq(seqId);
gAudioContext.seqReplaced[playerIdx] = (seqId != newSeqId);
gAudioContext.seqToPlay[playerIdx] = newSeqId;
cmd |= (seqId & 0xFF);
}
gAudioContext.seqReplaced[playerIdx] = (seqId != newSeqId);
gAudioContext.seqToPlay[playerIdx] = newSeqId;
cmd |= (seqId & 0xFF);
}
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
}
+1 -1
View File
@@ -491,7 +491,7 @@ void GameState_Realloc(GameState* gameState, size_t size) {
osSyncPrintf("ハイラル一時解放!!\n"); // "Hyrule temporarily released!!"
SystemArena_GetSizes(&systemMaxFree, &systemFree, &systemAlloc);
if ((systemMaxFree - 0x10) < size) {
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
osSyncPrintf(VT_FGCOL(RED));
// "Not enough memory. Change the hyral size to the largest possible value"
+5 -5
View File
@@ -337,14 +337,14 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
if (pool->headMagic != GFXPOOL_HEAD_MAGIC) {
//! @bug (?) : "problem = true;" may be missing
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
// "Dynamic area head is destroyed"
osSyncPrintf(VT_COL(RED, WHITE) "ダイナミック領域先頭が破壊されています\n" VT_RST);
Fault_AddHungupAndCrash(__FILE__, __LINE__);
}
if (pool->tailMagic != GFXPOOL_TAIL_MAGIC) {
problem = true;
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
// "Dynamic region tail is destroyed"
osSyncPrintf(VT_COL(RED, WHITE) "ダイナミック領域末尾が破壊されています\n" VT_RST);
Fault_AddHungupAndCrash(__FILE__, __LINE__);
@@ -353,19 +353,19 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
if (THGA_IsCrash(&gfxCtx->polyOpa)) {
problem = true;
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
// "Zelda 0 is dead"
osSyncPrintf(VT_COL(RED, WHITE) "ゼルダ0は死んでしまった(graph_alloc is empty)\n" VT_RST);
}
if (THGA_IsCrash(&gfxCtx->polyXlu)) {
problem = true;
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
// "Zelda 1 is dead"
osSyncPrintf(VT_COL(RED, WHITE) "ゼルダ1は死んでしまった(graph_alloc is empty)\n" VT_RST);
}
if (THGA_IsCrash(&gfxCtx->overlay)) {
problem = true;
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
// "Zelda 4 is dead"
osSyncPrintf(VT_COL(RED, WHITE) "ゼルダ4は死んでしまった(graph_alloc is empty)\n" VT_RST);
}
+1 -1
View File
@@ -116,7 +116,7 @@ void IrqMgr_CheckStack() {
if (StackCheck_Check(NULL) == 0) {
osSyncPrintf("スタックは大丈夫みたいです\n"); // "The stack looks ok"
} else {
osSyncPrintf("%c", 7);
osSyncPrintf("%c", BEL);
osSyncPrintf(VT_FGCOL(RED));
// "Stack overflow or dangerous"
osSyncPrintf("スタックがオーバーフローしたか危険な状態です\n");
+1 -1
View File
@@ -331,7 +331,7 @@ void PadMgr_HandleRetraceMsg(PadMgr* padMgr) {
osContGetReadData(padMgr->pads);
for (i = 0; i < __osMaxControllers; i++) {
padMgr->padStatus[i].status = CVar_GetS32("gRumbleEnabled", 0) && Controller_ShouldRumble(i);
padMgr->padStatus[i].status = Controller_ShouldRumble(i);
}
if (padMgr->preNMIShutdown) {
+13
View File
@@ -78,6 +78,9 @@
static CollisionPoly* sCurCeilingPoly;
static s32 sCurCeilingBgId;
// Used for animating the ice trap on the "Get Item" model.
f32 iceTrapScale;
void ActorShape_Init(ActorShape* shape, f32 yOffset, ActorShadowFunc shadowDraw, f32 shadowScale) {
shape->yOffset = yOffset;
shape->shadowDraw = shadowDraw;
@@ -2030,6 +2033,7 @@ s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEn
s32 absYawDiff = ABS(yawDiff);
if ((getItemEntry.getItemId != GI_NONE) || (player->getItemDirection < absYawDiff)) {
iceTrapScale = 0.0f;
player->getItemEntry = getItemEntry;
player->getItemId = getItemEntry.getItemId;
player->interactRangeActor = actor;
@@ -3322,6 +3326,15 @@ Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, PlayState* play
return NULL;
}
// The following enemies break when the parent actor isn't the same as what would happen in authentic gameplay.
// As such, don't assign a parent to them at all when spawned with Enemy Randomizer.
// Gohma (z_boss_goma.c), the Stalchildren spawner (z_en_encount1.c) and the falling platform spawning Stalfos in
// Forest Temple (z_bg_mori_bigst.c) that normally rely on this behaviour are changed when
// Enemy Rando is on so they still work properly even without assigning a parent.
if (CVar_GetS32("gRandomizedEnemies", 0) && (spawnedActor->id == ACTOR_EN_FLOORMAS || spawnedActor->id == ACTOR_EN_PEEHAT)) {
return spawnedActor;
}
parent->child = spawnedActor;
spawnedActor->parent = parent;
+9 -4
View File
@@ -400,9 +400,7 @@ void GetItem_Draw(PlayState* play, s16 drawId) {
* Uses the Custom Draw Function if it exists, or just calls `GetItem_Draw`
*/
void GetItemEntry_Draw(PlayState* play, GetItemEntry getItemEntry) {
// RANDOTODO: Make this more flexible for easier toggling of individual item recolors in the future.
if (getItemEntry.drawFunc != NULL &&
(CVar_GetS32("gRandoMatchKeyColors", 0) || getItemEntry.getItemId == RG_DOUBLE_DEFENSE)) {
if (getItemEntry.drawFunc != NULL) {
getItemEntry.drawFunc(play, &getItemEntry);
} else {
GetItem_Draw(play, getItemEntry.gid);
@@ -759,8 +757,15 @@ void GetItem_DrawRecoveryHeart(PlayState* play, s16 drawId) {
1 * -(play->state.frames * 2), 32, 32));
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_MODELVIEW | G_MTX_LOAD);
if (CVar_GetS32("gCosmetics.Consumable_Hearts.Changed", 0)) {
Color_RGB8 color = CVar_GetRGB("gCosmetics.Consumable_Hearts.Value", (Color_RGB8) { 255, 70, 50 });
gDPSetGrayscaleColor(POLY_XLU_DISP++, color.r, color.g, color.b, 255);
gSPGrayscale(POLY_XLU_DISP++, true);
}
gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
if (CVar_GetS32("gCosmetics.Consumable_Hearts.Changed", 0)) {
gSPGrayscale(POLY_XLU_DISP++, false);
}
CLOSE_DISPS(play->state.gfxCtx);
}
+15 -14
View File
@@ -1264,9 +1264,9 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry) {
s16 color_slot;
switch (giEntry.modIndex) {
switch (giEntry.drawModIndex) {
case MOD_NONE:
switch (giEntry.itemId) {
switch (giEntry.drawItemId) {
case ITEM_SONG_MINUET:
color_slot = 0;
break;
@@ -1298,7 +1298,7 @@ void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry
}
break;
case MOD_RANDOMIZER:
switch (giEntry.itemId) {
switch (giEntry.drawItemId) {
case RG_MAGIC_SINGLE:
case RG_MAGIC_DOUBLE:
case RG_MAGIC_BEAN_PACK:
@@ -1339,25 +1339,26 @@ void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry
{ 154, 154, 154 } // White Color placeholder
};
static Vec3f velocity = { 0.0f, 0.2f, 0.0f };
static Vec3f accel = { 0.0f, 0.05f, 0.0f };
static Vec3f velocity = { 0.0f, 0.0f, 0.0f };
static Vec3f accel = { 0.0f, 0.0f, 0.0f };
Color_RGBA8 primColor = { colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 0 };
Color_RGBA8 envColor = { colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 0 };
Vec3f pos;
velocity.y = -0.00f;
accel.y = -0.0f;
pos.x = Rand_CenteredFloat(15.0f) + Parent->world.pos.x;
// Shop items are rendered at a different height than the rest, so a different y offset is required
// Make particles more compact for shop items and use a different height offset for them.
if (Parent->id == ACTOR_EN_GIRLA) {
pos.x = Rand_CenteredFloat(15.0f) + Parent->world.pos.x;
pos.y = (Rand_ZeroOne() * 10.0f) + Parent->world.pos.y + 3;
pos.z = Rand_CenteredFloat(15.0f) + Parent->world.pos.z;
EffectSsKiraKira_SpawnFocused(play, &pos, &velocity, &accel, &primColor, &envColor, 1000, 30);
} else {
pos.y = (Rand_ZeroOne() * 10.0f) + Parent->world.pos.y + 25;
pos.x = Rand_CenteredFloat(32.0f) + Parent->world.pos.x;
pos.y = (Rand_ZeroOne() * 6.0f) + Parent->world.pos.y + 25;
pos.z = Rand_CenteredFloat(32.0f) + Parent->world.pos.z;
velocity.y = -0.05f;
accel.y = -0.025f;
EffectSsKiraKira_SpawnDispersed(play, &pos, &velocity, &accel, &primColor, &envColor, 1000, 30);
}
pos.z = Rand_CenteredFloat(15.0f) + Parent->world.pos.z;
EffectSsKiraKira_SpawnFocused(play, &pos, &velocity, &accel, &primColor, &envColor, 1000, 30);
}
/**
+5 -9
View File
@@ -897,21 +897,17 @@ void Minimap_Draw(PlayState* play) {
//No idea why and how Original value work but this does actually fix them all.
PosY = PosY+1024;
}
if ((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) ||
((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) &&
(gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]]))) {
if (((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) ||
((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) &&
(gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]])
)) || CVar_GetS32("gAlwaysShowDungeonMinimapIcon", 0)) {
if (!Map0 || !CVar_GetS32("gFixDungeonMinimapIcon", 0)) {
gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b,
IconSize, IconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(OVERLAY_DISP++, TopLeftX, TopLeftY, TopLeftW, TopLeftH, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
} else if (CVar_GetS32("gAlwaysShowDungeonMinimapIcon", 0) != 0){ //Ability to show entrance Before beating the dungeon itself
gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b,
IconSize, IconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(OVERLAY_DISP++, TopLeftX, TopLeftY, TopLeftW, TopLeftH, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
}
}
s16 entranceX = OTRGetRectDimensionFromRightEdge(270 + X_Margins_Minimap);
+47 -3
View File
@@ -1,5 +1,6 @@
#include "global.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "objects/object_link_boy/object_link_boy.h"
#include "objects/object_link_child/object_link_child.h"
#include "objects/object_triforce_spot/object_triforce_spot.h"
@@ -1172,6 +1173,49 @@ void func_800906D4(PlayState* play, Player* this, Vec3f* newTipPos) {
}
}
void Player_DrawGetItemIceTrap(PlayState* play, Player* this, Vec3f* refPos, s32 drawIdPlusOne, f32 height) {
OPEN_DISPS(play->state.gfxCtx);
if (CVar_GetS32("gLetItSnow", 0)) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
gDPSetGrayscaleColor(POLY_OPA_DISP++, 75, 75, 75, 255);
gSPGrayscale(POLY_OPA_DISP++, true);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL);
gSPGrayscale(POLY_OPA_DISP++, false);
} else {
if (iceTrapScale < 0.01) {
iceTrapScale += 0.001f;
} else if (iceTrapScale < 0.8f) {
iceTrapScale += 0.2f;
}
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, (0 - play->gameplayFrames) % 128, 32, 32, 1, 0,
(play->gameplayFrames * -2) % 128, 32, 32));
Matrix_Translate(0.0f, -40.0f, 0.0f, MTXMODE_APPLY);
Matrix_Scale(iceTrapScale, iceTrapScale, iceTrapScale, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, 255);
gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL);
// Reset matrix for the fake item model because we're animating the size of the ice block around it before this.
Matrix_Translate(refPos->x + (3.3f * Math_SinS(this->actor.shape.rot.y)), refPos->y + height,
refPos->z + ((3.3f + (IREG(90) / 10.0f)) * Math_CosS(this->actor.shape.rot.y)), MTXMODE_NEW);
Matrix_RotateZYX(0, play->gameplayFrames * 1000, 0, MTXMODE_APPLY);
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
// Draw fake item model.
GetItem_Draw(play, drawIdPlusOne - 1);
}
CLOSE_DISPS(play->state.gfxCtx);
}
void Player_DrawGetItemImpl(PlayState* play, Player* this, Vec3f* refPos, s32 drawIdPlusOne) {
f32 height = (this->exchangeItemId != EXCH_ITEM_NONE) ? 6.0f : 14.0f;
@@ -1187,9 +1231,9 @@ void Player_DrawGetItemImpl(PlayState* play, Player* this, Vec3f* refPos, s32 dr
Matrix_RotateZYX(0, play->gameplayFrames * 1000, 0, MTXMODE_APPLY);
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
// RANDOTODO: Make this more flexible for easier toggling of individual item recolors in the future.
if (this->getItemEntry.drawFunc != NULL &&
(CVar_GetS32("gRandoMatchKeyColors", 0) || this->getItemEntry.getItemId == RG_DOUBLE_DEFENSE || this->getItemEntry.getItemId == RG_ICE_TRAP)) {
if (this->getItemEntry.modIndex == MOD_RANDOMIZER && this->getItemEntry.getItemId == RG_ICE_TRAP) {
Player_DrawGetItemIceTrap(play, this, refPos, drawIdPlusOne, height);
} else if (this->getItemEntry.drawFunc != NULL) {
this->getItemEntry.drawFunc(play, &this->getItemEntry);
} else {
GetItem_Draw(play, drawIdPlusOne - 1);
+25 -5
View File
@@ -470,8 +470,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
GiveLinkRupees(9001);
}
if(Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) {
// TODO: If master quest there are different key counts
if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) {
gSaveContext.inventory.dungeonKeys[SCENE_BMORI1] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest
gSaveContext.sohStats.dungeonKeys[SCENE_BMORI1] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest
gSaveContext.inventory.dungeonKeys[SCENE_HIDAN] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire
@@ -488,6 +487,16 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
gSaveContext.sohStats.dungeonKeys[SCENE_MEN] = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; // GTG
gSaveContext.inventory.dungeonKeys[SCENE_GANONTIKA] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon
gSaveContext.sohStats.dungeonKeys[SCENE_GANONTIKA] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon
} else if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_VANILLA) {
// Logic cannot handle vanilla key layout in some dungeons
// this is because vanilla expects the dungeon major item to be
// locked behind the keys, which is not always true in rando.
// We can resolve this by starting with some extra keys
if (ResourceMgr_IsSceneMasterQuest(SCENE_JYASINZOU)) {
// MQ Spirit needs 3 keys
gSaveContext.inventory.dungeonKeys[SCENE_JYASINZOU] = 3;
gSaveContext.sohStats.dungeonKeys[SCENE_JYASINZOU] = 3;
}
}
if(Randomizer_GetSettingValue(RSK_BOSS_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) {
@@ -516,12 +525,23 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
gSaveContext.infTable[20] |= 4;
// Go away ruto (water temple first cutscene)
gSaveContext.sceneFlags[05].swch |= (1 << 0x10);
gSaveContext.sceneFlags[SCENE_MIZUSIN].swch |= (1 << 0x10);
// Opens locked Water Temple door to prevent softlocks
// Open lowest Vanilla Fire Temple locked door (to prevent key logic lockouts)
// Not done on keysanity since this lockout is a non issue when Fire keys can be found outside the temple
u8 keysanity = Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANYWHERE ||
Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_OVERWORLD ||
Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANY_DUNGEON;
if (!ResourceMgr_IsSceneMasterQuest(SCENE_HIDAN) && !keysanity) {
gSaveContext.sceneFlags[SCENE_HIDAN].swch |= (1 << 0x17);
}
// Opens locked Water Temple door in vanilla to prevent softlocks
// West door on the middle level that leads to the water raising thing
// Happens in 3DS rando and N64 rando as well
gSaveContext.sceneFlags[05].swch |= (1 << 0x15);
if (!ResourceMgr_IsSceneMasterQuest(SCENE_MIZUSIN)) {
gSaveContext.sceneFlags[SCENE_MIZUSIN].swch |= (1 << 0x15);
}
// Skip intro cutscene when bombing mud wall in Dodongo's cavern
// this also makes the lower jaw render, and the eyes react to explosives
@@ -113,9 +113,17 @@ void func_8087B938(BgHaka* this, PlayState* play) {
actor = actor->next;
}
player->stateFlags2 &= ~0x10;
if (this->dyna.actor.params == 1) {
func_80078884(NA_SE_SY_CORRECT_CHIME);
} else if (play->sceneNum == SCENE_SPOT02 && allPulled) {
} else if (!IS_DAY && play->sceneNum == SCENE_SPOT02) {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_POH, this->dyna.actor.home.pos.x,
this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, this->dyna.actor.shape.rot.y, 0,
1, true);
}
// un tss un tss
if (play->sceneNum == SCENE_SPOT02 && allPulled) {
func_80078884(NA_SE_SY_CORRECT_CHIME);
func_800F5ACC(NA_BGM_STAFF_2);
Actor* actor2 = play->actorCtx.actorLists[ACTORCAT_BG].head;
@@ -126,11 +134,8 @@ void func_8087B938(BgHaka* this, PlayState* play) {
}
actor2 = actor2->next;
}
} else if (!IS_DAY && play->sceneNum == SCENE_SPOT02) {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_POH, this->dyna.actor.home.pos.x,
this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, this->dyna.actor.shape.rot.y, 0,
1, true);
}
this->actionFunc = func_8087BAAC;
}
func_8002F974(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG);
@@ -30,6 +30,8 @@ typedef enum {
#define WATER_LEVEL_LOWERED (WATER_LEVEL_RAISED - 680)
#define WATER_LEVEL_RIVER_LOWERED (WATER_LEVEL_RIVER_RAISED - 80)
#define WATER_LEVEL_RIVER_LOWER_Z 2203
void BgSpot06Objects_Init(Actor* thisx, PlayState* play);
void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play);
void BgSpot06Objects_Update(Actor* thisx, PlayState* play);
@@ -210,6 +212,9 @@ void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play) {
break;
}
// Due to Ships resource caching, the water box collisions for the river have to be manually reset
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z;
if (gSaveContext.n64ddFlag && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
// For randomizer when leaving lake hylia while the water level is lowered,
// reset the "raise lake hylia water" flag back to on if the water temple is cleared
@@ -591,6 +596,8 @@ void BgSpot06Objects_WaterPlaneCutsceneRise(BgSpot06Objects* this, PlayState* pl
// On rando, this is used with the water control system switch to finalize raising the water
if (gSaveContext.n64ddFlag) {
this->lakeHyliaWaterLevel = 0;
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_RAISED;
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z;
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); // Set the "raise lake hylia water" flag
play->roomCtx.unk_74[0] = 0; // Apply the moving under water texture to lake hylia ground
}
@@ -620,12 +627,14 @@ void BgSpot06Objects_WaterPlaneCutsceneLower(BgSpot06Objects* this, PlayState* p
play->roomCtx.unk_74[0] = 87; // Remove the moving under water texture from lake hylia ground
if (this->lakeHyliaWaterLevel <= -681.0f) {
this->lakeHyliaWaterLevel = -681.0f;
this->dyna.actor.world.pos.y = WATER_LEVEL_RAISED;
this->actionFunc = BgSpot06Objects_DoNothing;
} else {
// Go slightly beyond -681 so the smoothing doesn't slow down too much (matches the reverse of water rise func)
Math_SmoothStepToF(&this->lakeHyliaWaterLevel, -682.0f, 0.1f, 1.0f, 0.001f);
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_LOWERED;
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z - 50;
play->colCtx.colHeader->waterBoxes[LHWB_MAIN_1].ySurface = yPos;
play->colCtx.colHeader->waterBoxes[LHWB_MAIN_2].ySurface = yPos;
}
@@ -1703,10 +1703,7 @@ void BossDodongo_DrawEffects(PlayState* play) {
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
unkMtx = &play->billboardMtxF;
// OTRTODO: This call causes the whole texture cache to be cleaned up, which causes an important slowdown on switch so we need to find a way to avoid it.
#ifndef __SWITCH__
gSPInvalidateTexCache(POLY_XLU_DISP++, 0);
#endif
gSPInvalidateTexCache(POLY_XLU_DISP++, gDodongosCavernBossLavaFloorTex);
for (i = 0; i < 80; i++, eff++) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
@@ -1197,8 +1197,10 @@ void BossGanon_SetupTowerCutscene(BossGanon* this, PlayState* play) {
void BossGanon_ShatterWindows(u8 windowShatterState) {
s16 i;
u8* tex1 = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(ResourceMgr_GetName(ganon_boss_sceneTex_006C18)));
u8* tex2 = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(ResourceMgr_GetName(ganon_boss_sceneTex_007418)));
// Temporary solution: using LoadTexOrDList to ensure we actually have the texture available
// based on mq/nonmq. This will be handled properly with LUS 1.0
u8* tex1 = ResourceMgr_LoadTexOrDListByName(SEGMENTED_TO_VIRTUAL(ganon_boss_sceneTex_006C18));
u8* tex2 = ResourceMgr_LoadTexOrDListByName(SEGMENTED_TO_VIRTUAL(ganon_boss_sceneTex_007418));
u8* templateTex = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(gGanondorfWindowShatterTemplateTex));
for (i = 0; i < 2048; i++) {
@@ -3820,8 +3822,8 @@ void BossGanon_Draw(Actor* thisx, PlayState* play) {
// Invalidate textures if they have changed
if (this->windowShatterState != GDF_WINDOW_SHATTER_OFF) {
gSPInvalidateTexCache(POLY_OPA_DISP++, ResourceMgr_GetName(ganon_boss_sceneTex_006C18));
gSPInvalidateTexCache(POLY_OPA_DISP++, ResourceMgr_GetName(ganon_boss_sceneTex_007418));
gSPInvalidateTexCache(POLY_OPA_DISP++, ganon_boss_sceneTex_006C18);
gSPInvalidateTexCache(POLY_OPA_DISP++, ganon_boss_sceneTex_007418);
}
Gfx_SetupDL_25Opa(play->state.gfxCtx);
@@ -18,6 +18,8 @@
#define MO_WATER_LEVEL(play) play->colCtx.colHeader->waterBoxes[0].ySurface
#define MO_STARTING_WATER_LEVEL (-60)
#define HAS_LINK(tent) \
((tent != NULL) && \
((tent->work[MO_TENT_ACTION_STATE] == MO_TENT_GRAB) || (tent->work[MO_TENT_ACTION_STATE] == MO_TENT_SHAKE)))
@@ -338,6 +340,10 @@ void BossMo_Init(Actor* thisx, PlayState* play2) {
BossMo* this = (BossMo*)thisx;
u16 i;
// Due to Ships resource caching, the water level for Morpha needs to be reset
// to ensure subsequent re-fights in the same running instance start with the correct level
MO_WATER_LEVEL(play) = MO_STARTING_WATER_LEVEL;
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
if (this->actor.params != BOSSMO_TENTACLE) {
@@ -178,6 +178,13 @@ void EnDns_Init(Actor* thisx, PlayState* play) {
this->dnsItemEntry->itemPrice = this->scrubIdentity.itemPrice;
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_EXPENSIVE) {
// temporary workaround: always use 40 rupees as price instead of 70
if (this->actor.params == 0x0006) {
this->dnsItemEntry->itemPrice = 40;
}
}
if (this->scrubIdentity.isShuffled) {
this->dnsItemEntry->getItemId = this->scrubIdentity.getItemId;
this->dnsItemEntry->purchaseableCheck = EnDns_RandomizerPurchaseableCheck;
@@ -159,13 +159,6 @@ void EnDoor_SetupType(EnDoor* this, PlayState* play) {
}
this->actor.world.rot.y = 0x0000;
if (doorType == DOOR_LOCKED) {
// unlock the door behind the hammer blocks
// in the fire temple entryway when rando'd
if (gSaveContext.n64ddFlag && play->sceneNum == 4) {
// RANDOTODO don't do this when keysanity is enabled
Flags_SetSwitch(play, 0x17);
}
if (!Flags_GetSwitch(play, this->actor.params & 0x3F)) {
this->lockTimer = 10;
}
@@ -239,10 +239,14 @@ void EnEncount1_SpawnStalchildOrWolfos(EnEncount1* this, PlayState* play) {
spawnPos = this->actor.world.pos;
// In authentic gameplay, the game checks how many Stalchildren were spawned and only spawns new ones
// when the old ones are despawned and a timer is reached.
// With Enemy Randomizer on, this will keep spawning enemies solely on the timer because it's much
// more difficult tracking how many enemies have been spawned/killed. It's also fun. :)
if ((this->curNumSpawn < this->maxCurSpawns && this->totalNumSpawn < this->maxTotalSpawns) || CVar_GetS32("gRandomizedEnemies", 0)) {
while ((this->curNumSpawn < this->maxCurSpawns && this->totalNumSpawn < this->maxTotalSpawns) || CVar_GetS32("gRandomizedEnemies", 0)) {
// With Enemy Randomizer on, this will keep spawning enemies based on the timer and the total amount of existing
// enemies because it's much more difficult tracking how many enemies specifically spawned by this spawner have
// been spawned and/or killed.
int8_t enemyCount = play->actorCtx.actorLists[ACTORCAT_ENEMY].length;
if ((this->curNumSpawn < this->maxCurSpawns && this->totalNumSpawn < this->maxTotalSpawns) ||
(CVar_GetS32("gRandomizedEnemies", 0) && enemyCount < 15)) {
while ((this->curNumSpawn < this->maxCurSpawns && this->totalNumSpawn < this->maxTotalSpawns) ||
(CVar_GetS32("gRandomizedEnemies", 0) && enemyCount < 15)) {
if (play->sceneNum == SCENE_SPOT00) {
if ((player->unk_89E == 0) || (player->actor.floorBgId != BGCHECK_SCENE) ||
!(player->actor.bgCheckFlags & 1) || (player->stateFlags1 & 0x08000000)) {
@@ -422,10 +422,10 @@ void EnGirlA_InitItem(EnGirlA* this, PlayState* play) {
objectId = getItemEntry.objectId;
}
// Weird edge case here, sold out object reports as loaded for Kokiri shop but doesn't render so we force it to load here
if (Object_IsLoaded(&play->objectCtx, objectId) && (params != SI_SOLD_OUT && play->sceneNum == SCENE_KOKIRI_SHOP)) {
this->objBankIndex = Object_GetIndex(&play->objectCtx, objectId);
} else {
this->objBankIndex = Object_GetIndex(&play->objectCtx, objectId);
// If the object isn't normally spawned by the shop scene, then spawn it now
if (this->objBankIndex < 0) {
this->objBankIndex = Object_Spawn(&play->objectCtx, objectId);
}
}
+10 -8
View File
@@ -93,13 +93,13 @@ void EnGm_Destroy(Actor* thisx, PlayState* play) {
s32 func_80A3D7C8(void) {
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
return 0;
} else if (!(gBitFlags[2] & gSaveContext.inventory.equipment)) {
return 1;
} else if (gBitFlags[3] & gSaveContext.inventory.equipment) {
return 2;
} else if ((gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF) &&
(gBitFlags[2] & gSaveContext.inventory.equipment)) {
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) {
return 1;
} else if (!(gBitFlags[2] & gSaveContext.inventory.equipment)) { // Don't have giant's knife
return 1;
} else if (gBitFlags[3] & gSaveContext.inventory.equipment) { // Have broken giant's knife
return 2;
} else {
return 3;
}
@@ -256,7 +256,6 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE);
gSaveContext.pendingSale = itemEntry.itemId;
GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f);
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON);
gSaveContext.infTable[11] |= 2;
this->actionFunc = func_80A3DF00;
} else {
@@ -276,6 +275,11 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) {
void func_80A3DF00(EnGm* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) {
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON);
}
this->actor.parent = NULL;
this->actionFunc = func_80A3DF60;
} else {
@@ -284,14 +288,12 @@ void func_80A3DF00(EnGm* this, PlayState* play) {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE);
gSaveContext.pendingSale = itemEntry.itemId;
GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f);
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON);
gSaveContext.infTable[11] |= 2;
}
else {
gSaveContext.pendingSale = ItemTable_Retrieve(GI_SWORD_KNIFE).itemId;
func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f);
}
}
}
+3 -1
View File
@@ -656,7 +656,9 @@ void func_80A75A38(EnIk* this, PlayState* play) {
}
if (this->unk_2F9 == 0) {
Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xB0);
if (this->switchFlags != 0xFF) {
// Don't set flag when Iron Knuckle is spawned by Enemy Rando.
// Instead Iron Knuckles rely on the "clear room" flag when Enemy Rando is on.
if (this->switchFlags != 0xFF && !CVar_GetS32("gRandomizedEnemies",0)) {
Flags_SetSwitch(play, this->switchFlags);
}
Actor_Kill(&this->actor);
+2 -1
View File
@@ -663,7 +663,8 @@ void func_80AE3C98(EnRd* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
if (this->unk_30C == 0) {
if (!Flags_GetSwitch(play, this->unk_312 & 0x7F)) {
// Don't set this flag in Enemy Rando as it can overlap with other objects using the same flag.
if (!Flags_GetSwitch(play, this->unk_312 & 0x7F) && !CVar_GetS32("gRandomizedEnemies", 0)) {
Flags_SetSwitch(play, this->unk_312 & 0x7F);
}
if (this->unk_314 != 0) {
@@ -272,6 +272,15 @@ void ObjOshihiki_Init(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
ObjOshihiki* this = (ObjOshihiki*)thisx;
// In MQ Spirit, remove the large silver block in the hole as child so the chest in the silver block hallway
// can be guaranteed accessible
if (gSaveContext.n64ddFlag && LINK_IS_CHILD && ResourceMgr_IsGameMasterQuest() &&
play->sceneNum == SCENE_JYASINZOU && thisx->room == 6 && // Spirit Temple silver block hallway
thisx->params == 0x9C7) { // Silver block that is marked as in the hole
Actor_Kill(thisx);
return;
}
ObjOshihiki_CheckType(this, play);
if ((((this->dyna.actor.params >> 8) & 0xFF) >= 0) && (((this->dyna.actor.params >> 8) & 0xFF) <= 0x3F)) {
@@ -1710,7 +1710,7 @@ s32 func_808332E4(Player* this) {
void func_808332F4(Player* this, PlayState* play) {
GetItemEntry giEntry;
if (this->getItemEntry.objectId == OBJECT_INVALID) {
if (this->getItemEntry.objectId == OBJECT_INVALID || (this->getItemId != this->getItemEntry.getItemId)) {
giEntry = ItemTable_Retrieve(this->getItemId);
} else {
giEntry = this->getItemEntry;
@@ -12576,7 +12576,7 @@ s32 func_8084DFF4(PlayState* play, Player* this) {
}
if (this->unk_84F == 0) {
if (this->getItemEntry.objectId == OBJECT_INVALID) {
if (this->getItemEntry.objectId == OBJECT_INVALID || (this->getItemId != this->getItemEntry.getItemId)) {
giEntry = ItemTable_Retrieve(this->getItemId);
} else {
giEntry = this->getItemEntry;
@@ -1295,7 +1295,7 @@ void Select_Main(GameState* thisx) {
}
void Select_Destroy(GameState* thisx) {
osSyncPrintf("%c", '\a'); // ASCII BEL character, plays an alert tone
osSyncPrintf("%c", BEL);
// "view_cleanup will hang, so it won't be called"
osSyncPrintf("*** view_cleanupはハングアップするので、呼ばない ***\n");
}
@@ -9,6 +9,7 @@
#include "global.h"
#include "alloca.h"
#include "textures/nintendo_rogo_static/nintendo_rogo_static.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include <soh/Enhancements/bootcommands.h>
#include <GameVersions.h>
#include <soh/SaveManager.h>
@@ -234,6 +235,22 @@ void Title_Draw(TitleContext* this) {
gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
// Draw ice cube around N64 logo.
if (CVar_GetS32("gLetItSnow", 0)) {
f32 scale = 0.4f;
gSPSegment(POLY_OPA_DISP++, 0x08,
Gfx_TwoTexScroll(this->state.gfxCtx, 0, 0, (0 - 1) % 128, 32, 32, 1,
0, (1 * -2) % 128, 32, 32));
Matrix_Translate(0.0f, -10.0f, 0.0f, MTXMODE_APPLY);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(this->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 50, 100, 255);
gSPDisplayList(POLY_OPA_DISP++, gEffIceFragment3DL);
}
Environment_FillScreen(this->state.gfxCtx, 0, 0, 0, (s16)this->coverAlpha, FILL_SCREEN_XLU);
sTitleRotY += (300 * CVar_GetFloat("gCosmetics.N64Logo_SpinSpeed", 1.0f));