From 0b58acb27e80cb485a7b9d49790a8f315eaa29a2 Mon Sep 17 00:00:00 2001 From: Alchav Date: Wed, 22 Apr 2026 19:42:56 -0400 Subject: [PATCH 01/53] Key rings --- LTTP_RND_GeneralBugfixes.asm | 6 +++--- dialog.asm | 11 ++++++++++- inventory.asm | 4 ++++ itemtext.asm | 7 +++++++ newitems.asm | 31 ++++++++++++++++++++++++++++--- stats.asm | 18 ++++++++++++++---- tables.asm | 23 ++++++++++++++++++++++- utilities.asm | 13 +++++++++---- 8 files changed, 97 insertions(+), 16 deletions(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index 762e743f..d46229ff 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -149,9 +149,6 @@ incsrc msu.asm incsrc dialog.asm incsrc entrances.asm incsrc clock.asm -incsrc accessability.asm -incsrc heartbeep.asm -incsrc capacityupgrades.asm print "End of Coda Bank $20: ", pc warnpc $A18000 @@ -179,6 +176,9 @@ org $A1FF00 ; static mapping area incsrc init.asm org $A48000 ; code bank - PUT NEW CODE HERE +incsrc accessability.asm +incsrc heartbeep.asm +incsrc capacityupgrades.asm incsrc timer.asm incsrc doorframefixes.asm incsrc music.asm diff --git a/dialog.asm b/dialog.asm index 3216fe09..98d152ba 100644 --- a/dialog.asm +++ b/dialog.asm @@ -177,7 +177,7 @@ FreeDungeonItemNotice: + : LDA.l FreeItemText : AND.b #$08 : CMP.b #$08 : BNE + ; show message for dungeon big key LDA !ITEM_TEMPORARY : AND.b #$F0 : CMP.b #$90 : BNE + ; big key of... %CopyDialog(Notice_BigKeyOf) - BRA .dungeon + BRL .dungeon + : LDA.l FreeItemText : AND.b #$01 : CMP.b #$01 : BNE + ; show message for dungeon small key LDA !ITEM_TEMPORARY : AND.b #$F0 : CMP.b #$A0 : BNE + ; small key of... LDA !ITEM_TEMPORARY : CMP.b #$AF : BNE ++ : BRL .skip : ++ @@ -185,6 +185,15 @@ FreeDungeonItemNotice: PLA : AND.b #$0F : STA $7F5020 : LDA.b #$0F : !SUB $7F5020 : PHA LDA #$01 : STA $7F5010 ; set up a flip for small keys BRA .dungeon + + : LDA.l FreeItemText : AND.b #$01 : CMP.b #$01 : BNE + ; show message for dungeon key ring + LDA !ITEM_TEMPORARY : AND.b #$F0 : CMP.b #$C0 : BNE + ; key ring of... + LDA !ITEM_TEMPORARY : CMP.b #$CE : !BLT .keyRingNotice + BRL .skip + .keyRingNotice + %CopyDialog(Notice_KeyRingOf) + PLA : AND.b #$0F : STA $7F5020 : LDA.b #$0F : !SUB $7F5020 : PHA + LDA #$01 : STA $7F5010 ; set up a flip for key rings + BRA .dungeon + BRL .skip ; it's not something we are going to give a notice for diff --git a/inventory.asm b/inventory.asm index 28368ef7..f04b66eb 100644 --- a/inventory.asm +++ b/inventory.asm @@ -544,6 +544,10 @@ AddInventory: CPY.b #$B0 : !BGE + JSR .incrementKey BRL .done + + CPY.b #$C0 : !BLT + ; Items $C0 - $CD - Key Rings + CPY.b #$CE : !BGE + + JSR .incrementKey + BRL .done + .done PLP : PLX : PLA diff --git a/itemtext.asm b/itemtext.asm index f4d32c17..83ade1e6 100644 --- a/itemtext.asm +++ b/itemtext.asm @@ -27,6 +27,13 @@ Notice_SmallKeyOf: db $75, $00, $BC, $00, $B6, $00, $AA, $00, $B5, $00, $B5, $00, $FF, $00, $B4, $00, $AE, $00, $C2, $00, $FF, $00, $BD, $00, $B8 dw #$7F7F +; this is a +; key ring to +Notice_KeyRingOf: + db $74, $00, $BD, $00, $B1, $00, $B2, $00, $BC, $00, $FF, $00, $B2, $00, $BC, $00, $FF, $00, $AA + db $75, $00, $B4, $00, $AE, $00, $C2, $00, $FF, $00, $BB, $00, $B2, $00, $B7, $00, $B0, $00, $FF, $00, $BD, $00, $B8 + dw #$7F7F + ; light world Notice_LightWorld: db $76, $00, $B5, $00, $B2, $00, $B0, $00, $B1, $00, $BD, $00, $FF, $00, $C0, $00, $B8, $00, $BB, $00, $B5, $00, $AD diff --git a/newitems.asm b/newitems.asm index 9bee8f4c..4cfec50e 100755 --- a/newitems.asm +++ b/newitems.asm @@ -40,6 +40,7 @@ ; #$90 - Big Keys ; #$A0 - Small Keys ; #$B0 - Bee Trap +; #$C0 - Key Rings ; #$FE - Server Request (Asychronous Chest) ; #$FF - Null Chest ;-------------------------------------------------------------------------------- @@ -407,6 +408,30 @@ AddReceivedItemExpandedGetItem: LDA $7EF36F : INC : STA $7EF36F ++ BRL .done + + CMP.b #$C0 : !BLT + : CMP.b #$D0 : !BGE + ; Key Ring + AND #$0F : TAX + LDA.l KeyRingQuantities, X : BEQ .keyRingDone + PHA + CLC : ADC $7EF37C, X : STA $7EF37C, X + + CPX.b #$00 : BNE ++ + STA $7EF37D ; copy HC to sewers + ++ : CPX.b #$01 : BNE ++ + STA $7EF37C ; copy sewers to HC + ++ + + LDA.l GenericKeys : BEQ .keyRingDungeon + PLA : CLC : ADC $7EF36F : STA $7EF36F + BRL .done + .keyRingDungeon + TXA : ASL : CMP $040C : BNE .keyRingDiscard + PLA : CLC : ADC $7EF36F : STA $7EF36F + BRL .done + .keyRingDiscard + PLA + BRL .done + .keyRingDone + BRL .done + CMP.b #$B0 : BNE + ; Bee Trap LDA.b #$79 : JSL Sprite_SpawnDynamically : BMI + ; DashBeeHive_SpawnBee LDA $22 : STA $0D10, Y : LDA $23 : STA $0D30, Y ; from enemizer's Spawn_Bees @@ -671,7 +696,7 @@ AddReceivedItemExpanded: db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Small Key db 0 ; Bee Trap db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused - db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused + db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Key Ring db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused @@ -718,7 +743,7 @@ AddReceivedItemExpanded: db $47 ; Bee Trap db $47, $2C, $47, $47 ; Fae, Bee, Jar, Apple db $47, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused - db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused + db $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F ; Key Ring db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused @@ -759,7 +784,7 @@ AddReceivedItemExpanded: db $02 ; Bee Trap db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused - db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; Key Ring db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused diff --git a/stats.asm b/stats.asm index e839b763..980d7515 100644 --- a/stats.asm +++ b/stats.asm @@ -265,8 +265,12 @@ CountChestKey: ; called by neighbor functions PHA : PHX LDA !MULTIWORLD_ITEM_PLAYER_ID : bne .end CPY #$24 : BEQ + ; small key for this dungeon - use $040C - CPY #$A0 : !BLT .end ; Ignore most items - CPY #$AE : !BGE .end ; Ignore reserved key and generic key + CPY #$A0 : !BLT .checkKeyRing ; Ignore most items + CPY #$AE : !BLT .dungeonKey ; Count dungeon small keys + .checkKeyRing + CPY #$C0 : !BLT .end + CPY #$CE : !BGE .end ; Ignore reserved key ring slots + .dungeonKey TYA : AND.B #$0F : BNE ++ ; If this is a sewers key, instead count it as an HC key INC ++ TAX : BRA .count ; use Key id instead of $040C (Keysanity) @@ -288,7 +292,13 @@ CountBonkItem: ; called from GetBonkItem in bookofmudora.asm %GetPossiblyEncryptedItem(BonkKey_GTower, HeartPieceIndoorValues) : BRA ++ + LDA.B #$24 ; default to small key ++ - CMP #$24 : BNE + + CMP #$24 : BEQ .count + CMP #$A0 : !BLT .checkKeyRing + CMP #$AE : !BLT .count + .checkKeyRing + CMP #$C0 : !BLT + + CMP #$CE : !BGE + + .count PHY TAY : JSR CountChestKey PLY @@ -513,4 +523,4 @@ NoEGtoTriforce: ; If it is not possible to beat ganon, then make it impossible t JML $02B797 .no_triforce - JML $02B7A1 \ No newline at end of file + JML $02B7A1 diff --git a/tables.asm b/tables.asm index e03de986..d344620f 100644 --- a/tables.asm +++ b/tables.asm @@ -1401,6 +1401,22 @@ db $04 ;AD - Small Key of Ganon's Tower ;AE - Reserved ;AF - Generic Small Key +;C0 - Small Key Ring of Sewers +;C1 - Small Key Ring of Hyrule Castle +;C2 - Small Key Ring of Eastern Palace +;C3 - Small Key Ring of Desert Palace +;C4 - Small Key Ring of Agahnim's Tower +;C5 - Small Key Ring of Swamp Palace +;C6 - Small Key Ring of Dark Palace +;C7 - Small Key Ring of Misery Mire +;C8 - Small Key Ring of Skull Woods +;C9 - Small Key Ring of Ice Palace +;CA - Small Key Ring of Tower of Hera +;CB - Small Key Ring of Thieves' Town +;CC - Small Key Ring of Turtle Rock +;CD - Small Key Ring of Ganon's Tower +;CE - Reserved +;CF - Reserved ;================================================================================ ;;Residual Portal ;org $0283E0 ; PC 0x103E0 (Bank02.asm:816) (BNE) @@ -1917,8 +1933,13 @@ db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00 db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00 +; 0x186380 - 18638F +org $30E380 ; PC 0x186380 +KeyRingQuantities: +db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00 + ;-------------------------------------------------------------------------------- -; 0x186380 - 187FFF (unused) +; 0x186390 - 187FFF (unused) ;-------------------------------------------------------------------------------- org $30EFFF ; PC 0x186FFF diff --git a/utilities.asm b/utilities.asm index ae3ce088..a6a9285a 100644 --- a/utilities.asm +++ b/utilities.asm @@ -168,10 +168,13 @@ RTL ;Ax db $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F ; Free Small Key + ;Bx db $2C ; Bee Trap db $2B, $2C, $32, $31 ; Fae, Bee, Jar, Apple db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused - db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused + + ;Cx + db $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F ; Key Ring db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Reserved @@ -308,7 +311,7 @@ RTL db $04 ; Bee Trap db $08, $02, $08, $02 ; Fae, Bee, Jar, Apple db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused - db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused + db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Key Ring db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused @@ -379,7 +382,7 @@ IsNarrowSprite: LDX.b #$00 ; set index counter to 0 ;---- - - CPX.b #$24 : !BGE .false ; finish if we've done the whole list + CPX.b #$34 : !BGE .false ; finish if we've done the whole list CMP.l .smallSprites, X : BNE + ; skip to next if we don't match ;-- SEC ; set true state @@ -402,7 +405,9 @@ RTL db $15, $18, $24, $2A, $34, $35, $36, $42 db $43, $45, $59, $A0, $A1, $A2, $A3, $A4 db $A5, $A6, $A7, $A8, $A9, $AA, $AB, $AC - db $AD, $AE, $AF, $B3, $FF, $FF, $FF, $FF + db $AD, $AE, $AF, $B3, $C0, $C1, $C2, $C3 + db $C4, $C5, $C6, $C7, $C8, $C9, $CA, $CB + db $CC, $CD, $CE, $CF } ;-------------------------------------------------------------------------------- From 5b94507f3e458bfdf09662bebce48e1b09928d7c Mon Sep 17 00:00:00 2001 From: Alchav Date: Wed, 22 Apr 2026 23:22:50 -0400 Subject: [PATCH 02/53] Supress errors --- build.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/build.py b/build.py index 06a0eab2..718f187a 100644 --- a/build.py +++ b/build.py @@ -7,6 +7,8 @@ getprints as asar_prints, getwarnings as asar_warnings JAP10HASH = '03a63945398191337e896e5771f77173' +MAX_ERRORS_TO_PRINT = 100 +MAX_WARNINGS_TO_PRINT = 50 def int16_as_bytes(value): @@ -48,6 +50,19 @@ def local_path(path): def generate_patch(baserombytes: bytes, rom: bytes) -> bytes: return bsdiff4.diff(bytes(baserombytes), rom) + +def print_messages(label, messages, limit): + print(f"\n{label}: {len(messages)}") + for message in messages[:limit]: + print(message) + remaining = len(messages) - limit + if remaining > 0: + print(f"... omitted {remaining} additional {label.lower()}") + + +def is_deprecation_warning(message): + return "DEPRECATION NOTIFICATION" in message + if __name__ == '__main__': try: asar_init() @@ -85,13 +100,10 @@ def generate_patch(baserombytes: bytes, rom: bytes) -> bytes: f.write(generate_patch(old_rom_data, new_rom_data)) else: errors = asar_errors() - print("\nErrors: " + str(len(errors))) - for error in errors: - print(error) - warnings = asar_warnings() - print("\nWarnings: " + str(len(warnings))) - for w in warnings: - print(w) + print_messages("Errors", errors, MAX_ERRORS_TO_PRINT) + warnings = [warning for warning in asar_warnings() if not is_deprecation_warning(warning)] + if warnings: + print_messages("Warnings", warnings, MAX_WARNINGS_TO_PRINT) asar_close() except: From 235c3a62bd69dff6c6544aa4552aea760db800fc Mon Sep 17 00:00:00 2001 From: Alchav Date: Wed, 22 Apr 2026 23:24:45 -0400 Subject: [PATCH 03/53] Graphics compressor --- gfx_compress.py | 203 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 gfx_compress.py diff --git a/gfx_compress.py b/gfx_compress.py new file mode 100644 index 00000000..93952358 --- /dev/null +++ b/gfx_compress.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 +"""Compress raw graphics into ALTTP graphics-pack format. + +This intentionally uses only the simpler command types: +0 = literal bytes +1 = repeated byte +2 = alternating 2-byte word +3 = incrementing byte sequence + +That is enough to produce valid .gfx files for the paired assets in this repo +while staying inside the existing reserved ROM slots. +""" + +from __future__ import annotations + +import argparse +from pathlib import Path + + +MAX_CHUNK_LEN = 32 +TERMINATOR = 0xFF + + +def emit_command(out: bytearray, command: int, length: int, payload: bytes) -> None: + if not 1 <= length <= MAX_CHUNK_LEN: + raise ValueError(f"invalid command length {length}") + out.append((command << 5) | (length - 1)) + out.extend(payload) + + +def compress(data: bytes) -> bytes: + out = bytearray() + literal = bytearray() + index = 0 + + def flush_literal() -> None: + nonlocal literal + while literal: + chunk = bytes(literal[:MAX_CHUNK_LEN]) + del literal[:MAX_CHUNK_LEN] + emit_command(out, 0, len(chunk), chunk) + + while index < len(data): + best_kind = None + best_len = 0 + + repeated_len = 1 + while ( + index + repeated_len < len(data) + and repeated_len < MAX_CHUNK_LEN + and data[index + repeated_len] == data[index] + ): + repeated_len += 1 + if repeated_len >= 2: + best_kind = "repeat" + best_len = repeated_len + + if index + 1 < len(data): + first = data[index] + second = data[index + 1] + alternating_len = 0 + while index + alternating_len < len(data) and alternating_len < MAX_CHUNK_LEN: + expected = first if alternating_len % 2 == 0 else second + if data[index + alternating_len] != expected: + break + alternating_len += 1 + if alternating_len >= 4 and alternating_len > best_len: + best_kind = "alternating" + best_len = alternating_len + + incrementing_len = 1 + start_value = data[index] + while ( + index + incrementing_len < len(data) + and incrementing_len < MAX_CHUNK_LEN + and data[index + incrementing_len] == ((start_value + incrementing_len) & 0xFF) + ): + incrementing_len += 1 + if incrementing_len >= 3 and incrementing_len > best_len: + best_kind = "incrementing" + best_len = incrementing_len + + if best_kind is None: + literal.append(data[index]) + index += 1 + if len(literal) == MAX_CHUNK_LEN: + flush_literal() + continue + + flush_literal() + + if best_kind == "repeat": + emit_command(out, 1, best_len, bytes([data[index]])) + elif best_kind == "alternating": + emit_command(out, 2, best_len, data[index:index + 2]) + else: + emit_command(out, 3, best_len, bytes([data[index]])) + + index += best_len + + flush_literal() + out.append(TERMINATOR) + return bytes(out) + + +def decompress(data: bytes) -> bytes: + out = bytearray() + index = 0 + + while True: + command_byte = data[index] + index += 1 + + if command_byte == TERMINATOR: + return bytes(out) + + if (command_byte & 0xE0) == 0xE0: + command = (command_byte >> 2) & 0x07 + length = (((command_byte & 0x03) << 8) | data[index]) + 1 + index += 1 + else: + command = (command_byte >> 5) & 0x07 + length = (command_byte & 0x1F) + 1 + + if command == 0: + out.extend(data[index:index + length]) + index += length + continue + + if command == 1: + out.extend([data[index]] * length) + index += 1 + continue + + if command == 2: + first = data[index] + second = data[index + 1] + index += 2 + for offset in range(length): + out.append(first if offset % 2 == 0 else second) + continue + + if command == 3: + value = data[index] + index += 1 + for _ in range(length): + out.append(value) + value = (value + 1) & 0xFF + continue + + raise ValueError(f"unsupported command {command}; this script only emits 0-3") + + +def parse_max_size(value: str) -> int: + return int(value, 0) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("input", type=Path, help="raw decompressed graphics file, usually .bin") + parser.add_argument( + "output", + type=Path, + nargs="?", + help="output .gfx path; defaults to input path with .gfx suffix", + ) + parser.add_argument( + "--max-size", + type=parse_max_size, + help="fail if compressed size exceeds this value (accepts hex like 0x800)", + ) + parser.add_argument( + "--no-verify", + action="store_true", + help="skip decompressing the result to verify round-trip correctness", + ) + args = parser.parse_args() + + input_path = args.input + output_path = args.output or input_path.with_suffix(".gfx") + + raw = input_path.read_bytes() + compressed = compress(raw) + + if not args.no_verify and decompress(compressed) != raw: + raise RuntimeError("round-trip verification failed") + + if args.max_size is not None and len(compressed) > args.max_size: + raise RuntimeError( + f"compressed output is {len(compressed)} bytes, exceeds limit {args.max_size}" + ) + + output_path.write_bytes(compressed) + print( + f"{input_path.name}: {len(raw)} -> {len(compressed)} bytes " + f"({len(raw) - len(compressed)} saved)" + ) + print(f"wrote {output_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 0f690380ffb72e813f64e0b5d4f30c41ddf215c9 Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 23 Apr 2026 17:03:32 -0400 Subject: [PATCH 04/53] Key Ring graphic --- 2026items.bin | Bin 0 -> 1536 bytes 2026items.gfx | Bin 0 -> 1340 bytes LTTP_RND_GeneralBugfixes.asm | 3 ++- newitems.asm | 6 +++--- utilities.asm | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 2026items.bin create mode 100644 2026items.gfx mode change 100755 => 100644 newitems.asm diff --git a/2026items.bin b/2026items.bin new file mode 100644 index 0000000000000000000000000000000000000000..5742d0c0a2725dcf2f309f79a87b48209f70cc62 GIT binary patch literal 1536 zcmbtUU1%It6#gbNaff9)vkCK%?hbp$ZIn`iZX{_p?sV>Uk!mdsrIg}>Y(fzqq)2=) zyO8P3_C;D)w9S)3R0tx}Co2RjH0xSH`cP8w$wG+>B8p&~isD$79nalK0zyk0dJbpq zxpTic^PQg=AQl<=0Na(-#7@>36YDG%aT7r~{QS$~VqXrzA5@rldc;%>Qj>huc-}Nk z!w~297Y{$3{%78UJu;D=NW=T^f;T!g28c*DnNWwe#;9Q!*IeH)Q;&RG6lUp)#5CV#c& zc`r-A5_)}Yp+yzN(&;yT`)t|tFmFed$or=9%j=$P!}C_pt$t9keX6;G9GOjK;*gWi zNPzb+oUp|vmrkKr2Y%161FAM&h=a^3XpZV^`*>#IDC`4t!|L*+w*}H23 z&$B$uz$87!mxi(e|K`Q5Y$FK#mC2QrE0phk_3h+LUgUd(nrAvQHP08GhL5pM6}m+$ zjjeX+)cCPW+9uxeEg#2X{K8uc!kgZ%W<)-w`|+oD+Aj*UEfTVuzLXJ;m}eIu0(8V~ z^o8?ji=1tdz^P9{Bu59+N}1aJjWc&%34@@m4?T5c@e{QWpU2n7!1I3mT+P{V@6`M8 z8TWhLFrarsmJ$P`7#v6rLXs0CdVm|jUusfGDph6Uu&Oq#ABohL0*z& zvBuIs18q{0Mx)&pumqlvO!?m6pSvmtr2%Cy`}2D~oub?*Hwx`{=iYIfbr3f2dfore zGgXaO=RNNzp})l+)G=XIq|i8gdGhk=i4@I^$`qdQi}ivimNC40^u?D7M4(C2+`>n6 zch9|tAqh}fe(TU1*Klu6A3){I6 zVKJ;k>TfSiyl{If!pnBnP7x4JjR=MS4cB8?Qo)eIbEg=3ju~Vwsx7b2 z?Yk2;^58jS$G~wJ=0|2Mv=G2Y&p=Eo)GnrS4?y5xbBCaCmI|VjGmT?A&)j-EpuXHy zhY!uJyd@X!6lCvK(i_%J>sE8G60yBOKk#YvJAtc7yo4B^h_R!Sm*T3A8~!h{lMv;) zxbxV}rXTdF!q*4=F*qC?Hdo02<=B9waX4)_U9k5y?cU3(K|-9Eigv~;HEGcRNsk;XJbJQ-E;`V$i8t74v#4}N)>cNSuG`3p!%A87@H-p!0`kMD z@tI4P7rO0L1`li4Bp!2VWp(YV_uf8X?FYYS4}Tp4e7GCzszBws^YI6yYT6(oQS5!{ zcbFJ$lMzBzKZ$Np4E00DK<<+M_-Vg#I8$oRk{RlZUicsmZKqM_{$p aM9E+56?-NB)x}oHWFMFhXu!8jgnt6FB31wZ literal 0 HcmV?d00001 diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index d46229ff..75b61cde 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -264,8 +264,9 @@ warnpc $31A800 org $31A800 GFX_New_Items: -incbin newitems.gfx +;incbin newitems.gfx ;incbin eventitems.gfx ; *EVENT* +incbin 2026items.gfx warnpc $31B000 org $31B000 diff --git a/newitems.asm b/newitems.asm old mode 100755 new mode 100644 index 4cfec50e..33f10a41 --- a/newitems.asm +++ b/newitems.asm @@ -696,7 +696,7 @@ AddReceivedItemExpanded: db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Small Key db 0 ; Bee Trap db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused - db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Key Ring + db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Key Ring db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; Unused @@ -743,7 +743,7 @@ AddReceivedItemExpanded: db $47 ; Bee Trap db $47, $2C, $47, $47 ; Fae, Bee, Jar, Apple db $47, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused - db $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F ; Key Ring + db $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47 ; Key Ring db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused @@ -784,7 +784,7 @@ AddReceivedItemExpanded: db $02 ; Bee Trap db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused - db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; Key Ring + db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Key Ring db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 ; Unused diff --git a/utilities.asm b/utilities.asm index a6a9285a..2e7f80e5 100644 --- a/utilities.asm +++ b/utilities.asm @@ -174,7 +174,7 @@ RTL db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused ;Cx - db $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F ; Key Ring + db $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47 ; Key Ring db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Reserved From f92142119e70cbc0f804e6a5704f5716e4b777d9 Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 23 Apr 2026 18:30:31 -0400 Subject: [PATCH 05/53] Shuffle Prizes --- LTTP_RND_GeneralBugfixes.asm | 2 +- dungeondrops.asm | 264 ++++++++++++++++++++++++++++++++++- events.asm | 2 + hooks.asm | 6 +- inventory.asm | 3 + newitems.asm | 16 ++- tables.asm | 60 +++++++- utilities.asm | 4 +- 8 files changed, 346 insertions(+), 11 deletions(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index 75b61cde..6df0bf91 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -138,7 +138,6 @@ incsrc maidencrystals.asm incsrc zoraking.asm incsrc catfish.asm incsrc flute.asm -incsrc dungeondrops.asm incsrc halfmagicbat.asm incsrc newitems.asm incsrc mantle.asm @@ -217,6 +216,7 @@ incsrc darkroomitems.asm incsrc multiworld.asm incsrc terrorpin.asm incsrc RandSprite.asm +incsrc dungeondrops.asm print "End of Coda Bank $24: ", pc warnpc $A58000 diff --git a/dungeondrops.asm b/dungeondrops.asm index ac40e11d..ca301a02 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -1,9 +1,271 @@ ;================================================================================ ; Dungeon & Boss Drop Fixes ;-------------------------------------------------------------------------------- +!BOSS_PRIZE_ACTIVE = "$7F5047" +!BOSS_PRIZE_ROOM = "$7F5048" + DropSafeDungeon: LDA $040C : CMP #$08 : BEQ + LDA $01C6FC, X : JSL Sprite_SpawnFallingItem + RTL -;-------------------------------------------------------------------------------- \ No newline at end of file +;-------------------------------------------------------------------------------- +BossPrizeRoomTag: + LDA BossPrizeShuffle : BEQ .vanilla + JSL.l CheckIfBossRoom : BCC .vanilla + + LDA $0403 : AND.b #$80 : BEQ .heartContainerStillExists + LDA $0403 : AND.b #$40 : BNE .criticalItemAlreadyObtained + + JSL.l LoadBossPrizeRoomValue + JSL.l Sprite_SpawnFallingItem + JSL.l SetBossPrizeContext + BRA .clearTagFlag + +.vanilla + LDA $0403 : AND.b #$80 : BEQ .heartContainerStillExists + + LDA $040C : LSR A : TAX + LDA $7EF3CA : BNE .inDarkWorld + LDA $7EF374 : AND.l CrystalPendantFlags, X : BNE .criticalItemAlreadyObtained + BRA .giveCriticalItem + +.inDarkWorld + LDA $7EF37A : AND.l CrystalPendantFlags, X : BNE .criticalItemAlreadyObtained + +.giveCriticalItem + LDA.b #$80 : STA $04C2 + LDA $0E : PHA + LDA $040C : LSR A : TAX + JSL.l DropSafeDungeon + PLA : STA $0E + BRA .clearTagFlag + +.criticalItemAlreadyObtained + JSL.l ClearBossPrizeContext + +.clearTagFlag + LDX $0E + STZ $AE, X + +.heartContainerStillExists +RTL +;-------------------------------------------------------------------------------- +SetBossPrizeContext: + LDA.b #$01 : STA !BOSS_PRIZE_ACTIVE + PHP + REP #$20 + LDA $A0 : STA !BOSS_PRIZE_ROOM + PLP +RTL +;-------------------------------------------------------------------------------- +ClearBossPrizeContext: + LDA.b #$00 + STA !BOSS_PRIZE_ACTIVE + STA !BOSS_PRIZE_ROOM + STA !BOSS_PRIZE_ROOM+1 +RTL +;-------------------------------------------------------------------------------- +BossPrizeContextMatchesRoom: + LDA BossPrizeShuffle : BEQ .mismatch + LDA !BOSS_PRIZE_ACTIVE : BEQ .mismatch + LDA $1B : BEQ .mismatch + + PHP + REP #$20 + LDA !BOSS_PRIZE_ROOM : CMP $A0 : BNE .notCurrentRoom + PLP + SEC + RTL + +.notCurrentRoom + PLP + +.mismatch + CLC +RTL +;-------------------------------------------------------------------------------- +BossPrizeApplyItemPlayer: + JSL.l BossPrizeContextMatchesRoom : BCC .done + JSL.l BossPrizeGetPlayer : STA !MULTIWORLD_ITEM_PLAYER_ID +.done +RTL +;-------------------------------------------------------------------------------- +MaybeCollectBossPrize: + JSL.l BossPrizeContextMatchesRoom : BCC .done + + LDA $0403 : ORA.b #$40 : STA $0403 + JSL.l MarkBossPrizeDungeonCompletion + JSL.l ClearBossPrizeContext + JSL.l PrepDungeonExit + +.done +RTL +;-------------------------------------------------------------------------------- +MarkBossPrizeDungeonCompletion: + LDA $040C + CMP #$FF : BEQ .done + LSR : AND #$0F : CMP #$08 : !BGE + + JSR .valueShift + ORA $7EF46B : STA $7EF46B + BRA .done + + + !SUB #$08 + JSR .valueShift + BIT.b #$C0 : BEQ ++ : LDA.b #$C0 : ++ ; Make Hyrule Castle / Sewers Count for Both + ORA $7EF46C : STA $7EF46C +.done +RTL + +.valueShift + PHX + TAX : LDA.b #$01 + - + CPX #$00 : BEQ + + ASL + DEX + BRA - + + + PLX +RTS +;-------------------------------------------------------------------------------- +MaybeSetOrdinaryBossPrizeBits: + CMP.b #$B6 : BNE + + LDA $7EF374 : ORA.b #$04 : STA $7EF374 + SEC : RTL + + CMP.b #$B7 : BNE + + LDA $7EF374 : ORA.b #$02 : STA $7EF374 + SEC : RTL + + CMP.b #$B8 : BNE + + LDA $7EF374 : ORA.b #$01 : STA $7EF374 + SEC : RTL + + CMP.b #$B9 : BNE + + LDA $7EF37A : ORA.b #$02 : STA $7EF37A + SEC : RTL + + CMP.b #$BA : BNE + + LDA $7EF37A : ORA.b #$10 : STA $7EF37A + SEC : RTL + + CMP.b #$BB : BNE + + LDA $7EF37A : ORA.b #$40 : STA $7EF37A + SEC : RTL + + CMP.b #$BC : BNE + + LDA $7EF37A : ORA.b #$20 : STA $7EF37A + SEC : RTL + + CMP.b #$BD : BNE + + LDA $7EF37A : ORA.b #$04 : STA $7EF37A + SEC : RTL + + CMP.b #$BE : BNE + + LDA $7EF37A : ORA.b #$01 : STA $7EF37A + SEC : RTL + + CMP.b #$BF : BNE + + LDA $7EF37A : ORA.b #$08 : STA $7EF37A + SEC : RTL + + + CLC +RTL +;-------------------------------------------------------------------------------- +MaybeIncrementOrdinaryBossPrizeCounts: + CPY.b #$B6 : BCC .miss + CPY.b #$B9 : BCS .checkCrystals + LDA $7EF429 : INC : AND #$03 : TAX + LDA $7EF429 : AND #$FC : STA $7EF429 + TXA : ORA $7EF429 : STA $7EF429 + SEC + RTL + +.checkCrystals + CPY.b #$C0 : BCS .miss + LDA $7EF422 : INC : AND #$07 : TAX + LDA $7EF422 : AND #$F8 : STA $7EF422 + TXA : ORA $7EF422 : STA $7EF422 + SEC + RTL + +.miss + CLC +RTL +;-------------------------------------------------------------------------------- +LoadBossPrizeRoomValue: + PHP + REP #$20 ; set 16-bit accumulator + LDA $A0 ; these are all decimal because i got them that way + CMP.w #200 : BNE + + %GetPossiblyEncryptedItem(BossPrize_ArmosKnights, BossPrizeValues) + BRL .done + + CMP.w #51 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Lanmolas, BossPrizeValues) + BRL .done + + CMP.w #7 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Moldorm, BossPrizeValues) + BRL .done + + CMP.w #90 : BNE + + %GetPossiblyEncryptedItem(BossPrize_HelmasaurKing, BossPrizeValues) + BRL .done + + CMP.w #6 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Arrghus, BossPrizeValues) + BRL .done + + CMP.w #41 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Mothula, BossPrizeValues) + BRL .done + + CMP.w #172 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Blind, BossPrizeValues) + BRL .done + + CMP.w #222 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Kholdstare, BossPrizeValues) + BRL .done + + CMP.w #144 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Vitreous, BossPrizeValues) + BRL .done + + CMP.w #164 : BNE + + %GetPossiblyEncryptedItem(BossPrize_Trinexx, BossPrizeValues) + BRL .done + + + LDA.w #$0000 + +.done + AND.w #$00FF + PLP +RTL +;-------------------------------------------------------------------------------- +BossPrizeGetPlayer: + PHP + REP #$20 ; set 16-bit accumulator + LDA $A0 ; these are all decimal because i got them that way + CMP.w #200 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_ArmosKnights_Player) + BRL .done + + CMP.w #51 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Lanmolas_Player) + BRL .done + + CMP.w #7 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Moldorm_Player) + BRL .done + + CMP.w #90 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_HelmasaurKing_Player) + BRL .done + + CMP.w #6 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Arrghus_Player) + BRL .done + + CMP.w #41 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Mothula_Player) + BRL .done + + CMP.w #172 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Blind_Player) + BRL .done + + CMP.w #222 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Kholdstare_Player) + BRL .done + + CMP.w #144 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Vitreous_Player) + BRL .done + + CMP.w #164 : BNE + + %GetPossiblyEncryptedPlayerID(BossPrize_Trinexx_Player) + BRL .done + + + LDA.w #$0000 + +.done + AND.w #$00FF + PLP +RTL +;-------------------------------------------------------------------------------- diff --git a/events.asm b/events.asm index 13d9d437..77b1527a 100644 --- a/events.asm +++ b/events.asm @@ -251,6 +251,8 @@ PostItemAnimation: LDA $0403 : STA !MULTIWORLD_ROOMDATA + + JSL.l MaybeCollectBossPrize + LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + STZ $02E9 LDA #$00 : STA !MULTIWORLD_ITEM_PLAYER_ID diff --git a/hooks.asm b/hooks.asm index 93a9f2fd..feac3bdf 100755 --- a/hooks.asm +++ b/hooks.asm @@ -1002,6 +1002,11 @@ org $1BBCC1 ; <- DBCC1 - Bank1B.asm : 223 (LDA $0F8004, X : AND.w #$01FF : STA $ Overworld_Entrance_BRANCH_EPSILON: ; go here to lock doors ;-------------------------------------------------------------------------------- ; -- HOOK THIS LATER TO FUCK WITH BOSS DROPS -- +org $01C709 ; <- C709 - Bank01.asm : 10347 +JSL.l BossPrizeRoomTag +RTS +NOP #48 +;-------------------------------------------------------------------------------- org $01C73E ; <- C73E - Bank01.asm : 10377 (LDA $01C6FC, X : JSL Sprite_SpawnFallingItem) JSL.l DropSafeDungeon NOP #4 @@ -2679,4 +2684,3 @@ org $1BEE1B JSL Palette_ArmorAndGlovesRandSprite_part_two RTL ;-------------------------------------------------------------------------------- - diff --git a/inventory.asm b/inventory.asm index f04b66eb..14be8b73 100644 --- a/inventory.asm +++ b/inventory.asm @@ -466,6 +466,9 @@ AddInventory: JSR .incrementPendant JSR .setDungeonCompletion BRL .done + + JSL.l MaybeIncrementOrdinaryBossPrizeCounts : BCC + + BRL .done + + + CPY.b #$3A : !BLT + ; Items $3A - $3B - Bow & Silver Arrows CPY.b #$3C : !BGE + JSR .incrementBow diff --git a/newitems.asm b/newitems.asm index 33f10a41..c3520197 100644 --- a/newitems.asm +++ b/newitems.asm @@ -40,6 +40,16 @@ ; #$90 - Big Keys ; #$A0 - Small Keys ; #$B0 - Bee Trap +; #$B6 - Green Pendant +; #$B7 - Blue Pendant +; #$B8 - Red Pendant +; #$B9 - Crystal 1 +; #$BA - Crystal 2 +; #$BB - Crystal 3 +; #$BC - Crystal 4 +; #$BD - Crystal 5 +; #$BE - Crystal 6 +; #$BF - Crystal 7 ; #$C0 - Key Rings ; #$FE - Server Request (Asychronous Chest) ; #$FF - Null Chest @@ -463,6 +473,7 @@ AddReceivedItemExpandedGetItem: LDA.b #$1F : STA $0E00, Y LDA.b #$03 : STA $0E40, Y + + JSL.l MaybeSetOrdinaryBossPrizeBits : BCS .done .done PLX LDA $02E9 : CMP.b #$01 ; thing we wrote over @@ -489,6 +500,7 @@ RTL AddReceivedItemExpanded: { PHA : PHX + JSL.l BossPrizeApplyItemPlayer LDA RemoteItems : BEQ + : LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + LDA $02E9 : BEQ ++ : CMP #$03 : BNE +++ : ++ ; fromTextOrObject @@ -742,7 +754,7 @@ AddReceivedItemExpanded: db $47 ; Bee Trap db $47, $2C, $47, $47 ; Fae, Bee, Jar, Apple - db $47, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused + db $47, $23, $23, $23, $28, $28, $28, $28, $28, $28, $28 ; Unused, Pendants, Crystals db $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47 ; Key Ring db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused @@ -824,7 +836,7 @@ AddReceivedItemExpanded: db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Big Key db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Small Key db 1 ; Bee Trap - db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused + db 4, 4, 4, 4, 4, 4, 2, 1, 6, 6, 6, 6, 6, 6, 6 ; Unused, Pendants, Crystals db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused diff --git a/tables.asm b/tables.asm index d344620f..f5e7d52b 100644 --- a/tables.asm +++ b/tables.asm @@ -941,7 +941,11 @@ db #$00 RainDeathRefillArrows_Mantle: db #$00 ;================================================================================ -; 0x18018E - 0x18018F (unused) +org $30818E ; PC 0x18018E +BossPrizeShuffle: +db #$00 ; #$00 = vanilla boss prizes (default) - #$01 = shuffled boss prizes use ordinary item IDs and warp after collection +;================================================================================ +; 0x18018F (unused) ;================================================================================ org $308190 ; PC 0x180190 - 0x180192 TimerStyle: @@ -959,7 +963,30 @@ org $308194 ; PC 0x180194 TurnInGoalItems: db #$01 ; #$00 = Instant win if last goal item collected. $01 = (Default) must turn in goal items ;-------------------------------------------------------------------------------- -; 0x180195 - 0x1801FF (unused) +org $308195 ; PC 0x180195 - 0x18019E [encrypted] +BossPrizeValues: +BossPrize_ArmosKnights: + db #$B6 ; Green Pendant +BossPrize_Lanmolas: + db #$B7 ; Blue Pendant +BossPrize_Moldorm: + db #$B8 ; Red Pendant +BossPrize_HelmasaurKing: + db #$B9 ; Crystal 1 +BossPrize_Arrghus: + db #$BA ; Crystal 2 +BossPrize_Mothula: + db #$BB ; Crystal 3 +BossPrize_Blind: + db #$BC ; Crystal 4 +BossPrize_Kholdstare: + db #$BD ; Crystal 5 +BossPrize_Vitreous: + db #$BE ; Crystal 6 +BossPrize_Trinexx: + db #$BF ; Crystal 7 +;-------------------------------------------------------------------------------- +; 0x18019F - 0x1801FF (unused) ;================================================================================ org $308200 ; PC 0x180200 - 0x18020F RedClockAmount: @@ -1517,7 +1544,9 @@ dw #9999 ; Rupee Limit ; $7F5042 - Tile Upload Offset Override (Low) ; $7F5043 - Tile Upload Offset Override (High) ; $7F5044 - $7F5046 - NMI Auxiliary Function -; $7F5047 - $7F504E - Unused +; $7F5047 - Boss Prize Active Flag +; $7F5048 - $7F5049 - Boss Prize Room ID +; $7F504A - $7F504E - Unused ; $7F504F - $7F506F - Shop Block ; $7F5070 - Reserved for OneMind ; $7F5071 - Reserved for OneMind @@ -1939,7 +1968,30 @@ KeyRingQuantities: db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00 ;-------------------------------------------------------------------------------- -; 0x186390 - 187FFF (unused) +org $30E390 ; PC 0x186390 - 0x186399 +BossPrize_ArmosKnights_Player: +db #$00 +BossPrize_Lanmolas_Player: +db #$00 +BossPrize_Moldorm_Player: +db #$00 +BossPrize_HelmasaurKing_Player: +db #$00 +BossPrize_Arrghus_Player: +db #$00 +BossPrize_Mothula_Player: +db #$00 +BossPrize_Blind_Player: +db #$00 +BossPrize_Kholdstare_Player: +db #$00 +BossPrize_Vitreous_Player: +db #$00 +BossPrize_Trinexx_Player: +db #$00 + +;-------------------------------------------------------------------------------- +; 0x18639A - 187FFF (unused) ;-------------------------------------------------------------------------------- org $30EFFF ; PC 0x186FFF diff --git a/utilities.asm b/utilities.asm index 2e7f80e5..89d92b8b 100644 --- a/utilities.asm +++ b/utilities.asm @@ -171,7 +171,7 @@ RTL ;Bx db $2C ; Bee Trap db $2B, $2C, $32, $31 ; Fae, Bee, Jar, Apple - db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused + db $49, $23, $23, $23, $28, $28, $28, $28, $28, $28, $28 ; Unused, Pendants, Crystals ;Cx db $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47, $47 ; Key Ring @@ -310,7 +310,7 @@ RTL db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Free Small Key db $04 ; Bee Trap db $08, $02, $08, $02 ; Fae, Bee, Jar, Apple - db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused + db $08, $08, $04, $02, $0A, $0A, $0A, $0A, $0A, $0A, $0A ; Unused, Pendants, Crystals db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Key Ring db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused From 89a6cb08e0cfaf1c4c7e058d0ac840122ffd7a78 Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 23 Apr 2026 18:57:30 -0400 Subject: [PATCH 06/53] Fix Crystal palette --- darkroomitems.asm | 55 +++++++++++++++++++++++++++++++------------ inventory.asm | 4 ++-- multiworld.asm | 37 +++++++++++++++++------------ pendantcrystalhud.asm | 20 ++++++++-------- utilities.asm | 14 +++++++---- 5 files changed, 83 insertions(+), 47 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index a2d14741..098a4de8 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -1,15 +1,27 @@ -CheckReceivedItemPropertiesBeforeLoad: - LDA $A0 : BEQ .normalCode - LDA $7EC005 : BNE .lightOff - .normalCode - LDA.l AddReceivedItemExpanded_properties, X ;Restore Rando Code - RTL - -.lightOff - PHX : PHY : PHB - LDA.l AddReceivedItemExpanded_properties, X ; get palette - - REP #$30 +CheckReceivedItemPropertiesBeforeLoad: + TXA + CMP.b #$20 : BEQ .loadCrystalPalette + CMP.b #$B9 : BCC .normalLightCheck + CMP.b #$C0 : BCC .loadCrystalPalette + +.normalLightCheck + LDA $A0 : BEQ .normalCode + LDA $7EC005 : BNE .lightOff + .normalCode + LDA.l AddReceivedItemExpanded_properties, X ;Restore Rando Code + RTL + +.loadCrystalPalette + PHX + JSL.l LoadCrystalItemPalette + PLX + BRA .normalLightCheck + +.lightOff + PHX : PHY : PHB + LDA.l AddReceivedItemExpanded_properties, X ; get palette + + REP #$30 AND #$0007 ; mask out palette ASL #5 ; multiply by 32 ADC #$C610 ; offset to latter half @@ -22,6 +34,19 @@ CheckReceivedItemPropertiesBeforeLoad: SEP #$30 PLB : PLY : PLX - INC $15 - LDA #$00 - RTL + INC $15 + LDA #$00 + RTL + +LoadCrystalItemPalette: + PHP + PHX + + LDA.b #$04 : STA $0AB1 + LDA.b #$02 : STA $0AA9 + JSL.l $0DED72 ; Palette_MiscSpr.justSP6 + + PLX + PLP + LDA.b #$0C +RTL diff --git a/inventory.asm b/inventory.asm index 14be8b73..7c799c94 100644 --- a/inventory.asm +++ b/inventory.asm @@ -1182,14 +1182,14 @@ SpawnShovelItem: LDX.b #$00 LDA $2F : CMP.b #$04 : BEQ + : INX : + - LDA.l .x_speeds, X : STA $0D50, Y + LDA.w .x_speeds, X : STA $0D50, Y LDA.b #$00 : STA $0D40, Y LDA.b #$18 : STA $0F80, Y LDA.b #$FF : STA $0B58, Y LDA.b #$30 : STA $0F10, Y - LDA $22 : !ADD.l .x_offsets, X + LDA $22 : !ADD.w .x_offsets, X AND.b #$F0 : STA $0D10, Y LDA $23 : ADC.b #$00 : STA $0D30, Y diff --git a/multiworld.asm b/multiworld.asm index 0f6b2ea2..6a5f73e2 100644 --- a/multiworld.asm +++ b/multiworld.asm @@ -136,34 +136,41 @@ GetMultiworldItem: + PLA + BRA .checkCurrentDungeonKey + .thisdungeon_near + BRL .thisdungeon + .keyend_near + BRL .keyend + .checkCurrentDungeonKey + ; Check if we have a key for the dungeon we are currently in LDX $040C ; Escape CMP #$A0 : BNE + : CPX #$00 : BEQ ++ : CPX #$02 : BEQ ++ : BRL .keyend : ++ : BRL .thisdungeon : + ; Eastern - CMP #$A2 : BNE + : CPX #$04 : BEQ .thisdungeon : BRA .keyend : + + CMP #$A2 : BNE + : CPX #$04 : BEQ .thisdungeon_near : BRA .keyend_near : + ; Desert - CMP #$A3 : BNE + : CPX #$06 : BEQ .thisdungeon : BRA .keyend : + + CMP #$A3 : BNE + : CPX #$06 : BEQ .thisdungeon_near : BRA .keyend_near : + ; Hera - CMP #$AA : BNE + : CPX #$14 : BEQ .thisdungeon : BRA .keyend : + + CMP #$AA : BNE + : CPX #$14 : BEQ .thisdungeon_near : BRA .keyend_near : + ; Aga - CMP #$A4 : BNE + : CPX #$08 : BEQ .thisdungeon : BRA .keyend : + + CMP #$A4 : BNE + : CPX #$08 : BEQ .thisdungeon_near : BRA .keyend_near : + ; PoD - CMP #$A6 : BNE + : CPX #$0C : BEQ .thisdungeon : BRA .keyend : + + CMP #$A6 : BNE + : CPX #$0C : BEQ .thisdungeon_near : BRA .keyend_near : + ; Swamp - CMP #$A5 : BNE + : CPX #$0A : BEQ .thisdungeon : BRA .keyend : + + CMP #$A5 : BNE + : CPX #$0A : BEQ .thisdungeon_near : BRA .keyend_near : + ; SW - CMP #$A8 : BNE + : CPX #$10 : BEQ .thisdungeon : BRA .keyend : + + CMP #$A8 : BNE + : CPX #$10 : BEQ .thisdungeon_near : BRA .keyend_near : + ; TT - CMP #$AB : BNE + : CPX #$16 : BEQ .thisdungeon : BRA .keyend : + + CMP #$AB : BNE + : CPX #$16 : BEQ .thisdungeon_near : BRA .keyend_near : + ; Ice - CMP #$A9 : BNE + : CPX #$12 : BEQ .thisdungeon : BRA .keyend : + + CMP #$A9 : BNE + : CPX #$12 : BEQ .thisdungeon_near : BRA .keyend_near : + ; Mire - CMP #$A7 : BNE + : CPX #$0E : BEQ .thisdungeon : BRA .keyend : + + CMP #$A7 : BNE + : CPX #$0E : BEQ .thisdungeon_near : BRA .keyend_near : + ; TR - CMP #$AC : BNE + : CPX #$18 : BEQ .thisdungeon : BRA .keyend : + + CMP #$AC : BNE + : CPX #$18 : BNE ++ : BRL .thisdungeon : ++ : BRL .keyend : + ; GT - CMP #$AD : BNE + : CPX #$1A : BEQ .thisdungeon : BRA .keyend : + + CMP #$AD : BNE + : CPX #$1A : BNE ++ : BRL .thisdungeon : ++ : BRL .keyend : + ; GT BK CMP #$92 : BNE .keyend : CPX #$1A : BNE .keyend : LDA #$32 : BRA .keyend .thisdungeon @@ -264,15 +271,15 @@ Multiworld_AddReceivedItem_notCrystal: { TYA : STA $02E4 : PHX ; things we wrote over - LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + + LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE + + JML.l AddReceivedItem_notCrystal+5 + + PHY : LDY $02D8 : JSL AddInventory : PLY %Print_Text(HUD_SentTo, #$0010, !MULTIWORLD_ITEM_PLAYER_ID) LDA #$33 : STA $012F JML.l AddReceivedItem_gfxHandling - + - JML.l AddReceivedItem_notCrystal+5 } Multiworld_Ancilla_ReceiveItem_stillInMotion: diff --git a/pendantcrystalhud.asm b/pendantcrystalhud.asm index 9d01296b..c6e75c64 100644 --- a/pendantcrystalhud.asm +++ b/pendantcrystalhud.asm @@ -462,15 +462,15 @@ DrawPendantCrystalDiagram: REP #$30 ; Set 16-bit accumulator & index registers LDX.w #$0000 ; Paint entire box black & draw empty pendants and crystals - - LDA.l .row0, X : STA $12EA, X - LDA.l .row1, X : STA $132A, X - LDA.l .row2, X : STA $136A, X - LDA.l .row3, X : STA $13AA, X - LDA.l .row4, X : STA $13EA, X - LDA.l .row5, X : STA $142A, X - LDA.l .row6, X : STA $146A, X - LDA.l .row7, X : STA $14AA, X - LDA.l .row8, X : STA $14EA, X + LDA.w .row0, X : STA $12EA, X + LDA.w .row1, X : STA $132A, X + LDA.w .row2, X : STA $136A, X + LDA.w .row3, X : STA $13AA, X + LDA.w .row4, X : STA $13EA, X + LDA.w .row5, X : STA $142A, X + LDA.w .row6, X : STA $146A, X + LDA.w .row7, X : STA $14AA, X + LDA.w .row8, X : STA $14EA, X INX #2 : CPX.w #$0014 : BCC - ;pendants @@ -588,4 +588,4 @@ dw $A8FB, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $E8FB ;0x1A - Ganon's Tower ;0x1C - ??? possibly unused. (Were they planning two extra dungeons perhaps?) ;0x1E - ??? possibly unused. -;================================================================================ \ No newline at end of file +;================================================================================ diff --git a/utilities.asm b/utilities.asm index 89d92b8b..978b2dd4 100644 --- a/utilities.asm +++ b/utilities.asm @@ -49,7 +49,7 @@ GetSpriteID: PHX PHB : PHK : PLB ;-------- - TAX : LDA.l .gfxSlots, X ; look up item gfx + TAX : LDA.w .gfxSlots, X ; look up item gfx PLB : PLX CMP.b #$F8 : !BGE .specialHandling RTL @@ -213,11 +213,15 @@ GetSpritePalette: PHX PHB : PHK : PLB ;-------- - TAX : LDA.l .gfxPalettes, X ; look up item gfx + TAX : LDA.w .gfxPalettes, X ; look up item gfx PLB : PLX CMP.b #$F8 : !BGE .specialHandling RTL .specialHandling + CMP.b #$F9 : BNE ++ ; Crystal palette + JSL.l LoadCrystalItemPalette + RTL + ++ CMP.b #$FD : BNE ++ ; Progressive Sword LDA $7EF359 CMP.l ProgressiveSwordLimit : !BLT + ; Progressive Sword Limit @@ -279,7 +283,7 @@ RTL db $08, $08, $02, $02, $04, $02, $02, $02 db $04, $02, $04, $02, $08, $08, $04, $02 - db $0A, $02, $04, $02, $04, $04, $00, $04 + db $F9, $02, $04, $02, $04, $04, $00, $04 db $04, $08, $02, $02, $08, $04, $02, $08 db $04, $04, $08, $08, $08, $04, $02, $08 @@ -310,7 +314,7 @@ RTL db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Free Small Key db $04 ; Bee Trap db $08, $02, $08, $02 ; Fae, Bee, Jar, Apple - db $08, $08, $04, $02, $0A, $0A, $0A, $0A, $0A, $0A, $0A ; Unused, Pendants, Crystals + db $08, $08, $04, $02, $F9, $F9, $F9, $F9, $F9, $F9, $F9 ; Unused, Pendants, Crystals db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Key Ring db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused @@ -383,7 +387,7 @@ IsNarrowSprite: ;---- - CPX.b #$34 : !BGE .false ; finish if we've done the whole list - CMP.l .smallSprites, X : BNE + ; skip to next if we don't match + CMP.w .smallSprites, X : BNE + ; skip to next if we don't match ;-- SEC ; set true state BRA .done ; we're done From 9c3237c928026f02ec1a1f28b5bca587b6ba7b9c Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 24 Apr 2026 20:54:11 -0400 Subject: [PATCH 07/53] Stabilize shuffled boss prize item flow, hooks, and palettes --- darkroomitems.asm | 29 ++--- dungeondrops.asm | 271 ++++++++++++++++++++++++++++++++++++++++++++-- events.asm | 3 +- heartpieces.asm | 31 +++--- hooks.asm | 40 +++++++ newitems.asm | 5 + tablets.asm | 2 +- utilities.asm | 8 +- 8 files changed, 330 insertions(+), 59 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index 098a4de8..1e3034d3 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -1,22 +1,10 @@ CheckReceivedItemPropertiesBeforeLoad: - TXA - CMP.b #$20 : BEQ .loadCrystalPalette - CMP.b #$B9 : BCC .normalLightCheck - CMP.b #$C0 : BCC .loadCrystalPalette - -.normalLightCheck LDA $A0 : BEQ .normalCode LDA $7EC005 : BNE .lightOff .normalCode LDA.l AddReceivedItemExpanded_properties, X ;Restore Rando Code RTL -.loadCrystalPalette - PHX - JSL.l LoadCrystalItemPalette - PLX - BRA .normalLightCheck - .lightOff PHX : PHY : PHB LDA.l AddReceivedItemExpanded_properties, X ; get palette @@ -38,15 +26,12 @@ CheckReceivedItemPropertiesBeforeLoad: LDA #$00 RTL -LoadCrystalItemPalette: - PHP - PHX +CrystalItemBehaviorCheck: + LDA $0C5E, X : CMP.b #$20 : BNE .ordinaryItem + LDA $0C54, X : CMP.b #$03 : BEQ .bossPrizeCrystal - LDA.b #$04 : STA $0AB1 - LDA.b #$02 : STA $0AA9 - JSL.l $0DED72 ; Palette_MiscSpr.justSP6 +.ordinaryItem + JML.l CrystalFanfareContinue - PLX - PLP - LDA.b #$0C -RTL +.bossPrizeCrystal + JML.l CrystalSpecialBehaviorContinue diff --git a/dungeondrops.asm b/dungeondrops.asm index ca301a02..4db9a2ec 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -3,6 +3,8 @@ ;-------------------------------------------------------------------------------- !BOSS_PRIZE_ACTIVE = "$7F5047" !BOSS_PRIZE_ROOM = "$7F5048" +!BOSS_PRIZE_SLOT = "$7F504A" +!ITEM_BUSY = "$7F5091" DropSafeDungeon: LDA $040C : CMP #$08 : BEQ + @@ -15,11 +17,18 @@ BossPrizeRoomTag: JSL.l CheckIfBossRoom : BCC .vanilla LDA $0403 : AND.b #$80 : BEQ .heartContainerStillExists - LDA $0403 : AND.b #$40 : BNE .criticalItemAlreadyObtained + JSL.l BossPrizeDungeonCompletionMatches : BCS .criticalItemAlreadyObtained + LDA !ITEM_BUSY : BNE .heartContainerStillExists + JSL.l BossPrizeSpawnReady : BCC .heartContainerStillExists + LDA $0E : PHA JSL.l LoadBossPrizeRoomValue - JSL.l Sprite_SpawnFallingItem + JSL.l SpawnBossPrizeFallingItem : BCC + + PLA : STA $0E + BRA .heartContainerStillExists + + JSL.l SetBossPrizeContext + PLA : STA $0E BRA .clearTagFlag .vanilla @@ -64,6 +73,83 @@ ClearBossPrizeContext: STA !BOSS_PRIZE_ACTIVE STA !BOSS_PRIZE_ROOM STA !BOSS_PRIZE_ROOM+1 + LDA.b #$FF : STA !BOSS_PRIZE_SLOT +RTL +;-------------------------------------------------------------------------------- +SpawnBossPrizeFallingItem: + JSL.l BossPrizeResolveItem + PHA + + LDY.b #$04 + LDA.b #$29 + JSL.l AddAncillaLong : BCC .spawned + PLA + SEC + RTL + + .spawned + PLA : STA $0C5E, X : TAY + + PHX : PHB + LDA.b #AddReceivedItemExpanded_item_graphics_indices>>16 : PHA : PLB + LDA.w AddReceivedItemExpanded_item_graphics_indices, Y : STA $72 + CMP.b #$FF : BEQ .invalidItem + CMP.b #$20 : BNE .getItemTiles + JSL.l DecompShieldGfx + LDA $72 + BRA .getItemTiles + + .invalidItem + LDA.b #$00 + + .getItemTiles + JSL.l GetAnimatedSpriteTile_variable + + LDA $72 : CMP.b #$06 : BNE .notFighterSword + JSL.l DecompSwordGfx + .notFighterSword + PLB : PLX + + LDA.b #$D0 : STA $0294, X + STZ $0C22, X + STZ $0C2C, X + STZ $0C54, X + LDA.b #$80 : STA $029E, X + LDA.b #$09 : STA $03B1, X + STZ $03A4, X + LDA.b #$05 : STA $0BF0, X + STZ $039F, X + STZ $0385, X + STZ $0394, X + + LDA $0C5E, X : STA $02D8 + + LDA $040C : CMP.b #$14 : BNE .normalCoords + LDA $21 : AND.b #$FE : INC A : STA $01 + STZ $00 + LDA $23 : AND.b #$FE : INC A : STA $03 + STZ $02 + BRA .setCoords + + .normalCoords + REP #$20 + LDA $E8 : !ADD.w #$0078 : STA $00 + LDA $E2 : !ADD.w #$0078 : STA $02 + SEP #$20 + + .setCoords + LDY $0C5E, X + LDA.w AddReceivedItemExpanded_wide_item_flag, Y : BNE + + REP #$20 + LDA $02 : !ADD.w #$0008 : STA $02 + SEP #$20 + + + LDA $00 : STA $0BFA, X + LDA $01 : STA $0C0E, X + LDA $02 : STA $0C04, X + LDA $03 : STA $0C18, X + TXA : STA !BOSS_PRIZE_SLOT + CLC RTL ;-------------------------------------------------------------------------------- BossPrizeContextMatchesRoom: @@ -81,43 +167,133 @@ BossPrizeContextMatchesRoom: .notCurrentRoom PLP +.mismatch + CLC +RTL +;-------------------------------------------------------------------------------- +BossPrizeContextMatchesSlot: + LDA !BOSS_PRIZE_SLOT : CMP.b #$FF : BEQ .mismatch + TXA : CMP !BOSS_PRIZE_SLOT : BNE .mismatch + SEC + RTL + +.mismatch + CLC +RTL +;-------------------------------------------------------------------------------- +BossPrizeReceiveContextMatches: + LDA $02E9 : CMP.b #$03 : BNE .mismatch + JSL.l BossPrizeContextMatchesRoom : BCC .mismatch + JSL.l BossPrizeContextMatchesSlot : BCC .mismatch + SEC + RTL + +.mismatch + CLC +RTL +;-------------------------------------------------------------------------------- +BossPrizeObjectContextMatches: + LDA $0C54, X : CMP.b #$03 : BNE .mismatch + JSL.l BossPrizeContextMatchesRoom : BCC .mismatch + JSL.l BossPrizeContextMatchesSlot : BCC .mismatch + SEC + RTL + .mismatch CLC RTL ;-------------------------------------------------------------------------------- BossPrizeApplyItemPlayer: - JSL.l BossPrizeContextMatchesRoom : BCC .done + JSL.l BossPrizeReceiveContextMatches : BCC .done JSL.l BossPrizeGetPlayer : STA !MULTIWORLD_ITEM_PLAYER_ID .done RTL ;-------------------------------------------------------------------------------- -MaybeCollectBossPrize: - JSL.l BossPrizeContextMatchesRoom : BCC .done +BossPrizeItemNeedsVictoryFanfare: + JSL.l BossPrizeObjectContextMatches : BCC .noFanfare + SEC + RTL + +.noFanfare + CLC +RTL +;-------------------------------------------------------------------------------- +BossPrizePendantWaitCheck: + LDA $0C5E, X : CMP.b #$37 : BEQ .waitForMusic + CMP.b #$38 : BEQ .waitForMusic + CMP.b #$39 : BEQ .waitForMusic - LDA $0403 : ORA.b #$40 : STA $0403 + JSL.l BossPrizeItemNeedsVictoryFanfare : BCC .dontWaitForMusic + +.waitForMusic + JML.l PendantFanfareWait + +.dontWaitForMusic + JML.l PendantFanfareDone +;-------------------------------------------------------------------------------- +HandleBossPrizeObjectFinished: + JSL.l BossPrizeObjectContextMatches : BCC .normalObjectFinished JSL.l MarkBossPrizeDungeonCompletion JSL.l ClearBossPrizeContext + + LDA $7F509F : BEQ + + LDA.b #$04 : STA $0C54, X + STZ $1CF0 : STZ $1CF1 + JSL.l Main_ShowTextMessage_Alt + LDA.b #$00 : STA $7F509F + JML.l Ancilla_ReceiveItem_return + + + + STZ $0C4A, X + STZ $0FC1 + LDA $0C54, X : PHA : PHX JSL.l PrepDungeonExit + PLX : PLA -.done -RTL + JML.l Ancilla_ReceiveItem_objectFinished+44 + +.normalObjectFinished + STZ $0C4A, X + STZ $0FC1 + JML.l Ancilla_ReceiveItem_objectFinished+6 ;-------------------------------------------------------------------------------- MarkBossPrizeDungeonCompletion: LDA $040C CMP #$FF : BEQ .done LSR : AND #$0F : CMP #$08 : !BGE + - JSR .valueShift + JSR BossPrizeValueShift ORA $7EF46B : STA $7EF46B BRA .done + !SUB #$08 - JSR .valueShift + JSR BossPrizeValueShift BIT.b #$C0 : BEQ ++ : LDA.b #$C0 : ++ ; Make Hyrule Castle / Sewers Count for Both ORA $7EF46C : STA $7EF46C .done RTL -.valueShift +BossPrizeDungeonCompletionMatches: + LDA $040C + CMP #$FF : BEQ .mismatch + LSR : AND #$0F : CMP #$08 : !BGE + + JSR BossPrizeValueShift + AND.l $7EF46B : BNE .match + BRA .mismatch + + + !SUB #$08 + JSR BossPrizeValueShift + BIT.b #$C0 : BEQ ++ : LDA.b #$C0 : ++ + AND.l $7EF46C : BNE .match + +.mismatch + CLC +RTL + +.match + SEC +RTL + +BossPrizeValueShift: PHX TAX : LDA.b #$01 - @@ -129,6 +305,79 @@ RTL PLX RTS ;-------------------------------------------------------------------------------- +BossPrizeResolveItem: + PHA + JSL.l BossPrizeGetPlayer : CMP.b #$00 : BNE .remote + PLA + JSL.l AttemptItemSubstitutionLong + RTL + +.remote + PLA +RTL +;-------------------------------------------------------------------------------- +BossPrizeDrawPrep: + REP #$20 + LDA $00 : CLC : ADC.w #$0008 : STA $08 + SEP #$20 + PHX + LDA $0BF0, X : STA $74 + JML.l BossPrizeDrawContinue +;-------------------------------------------------------------------------------- +BossPrizeMasterSwordSourceCheck: + LDA $02E9 : CMP.b #$02 : BEQ .spriteSource + JSL.l BossPrizeReceiveContextMatches : BCS .spriteSource + JML.l BossPrizeMasterSwordSourceNormal + +.spriteSource + JML.l BossPrizeMasterSwordFromSprite +;-------------------------------------------------------------------------------- +BossPrizeQueueFreeItemNotice: + JSL.l BossPrizeReceiveContextMatches : BCC .done + JSL.l BossPrizeGetPlayer : CMP.b #$00 : BNE .done + LDA $02D8 : JSL.l FreeDungeonItemNotice +.done +RTL +;-------------------------------------------------------------------------------- +BossPrizeSpawnReady: + LDX.b #$09 + +.nextAncilla + LDA $0C4A, X : CMP.b #$22 : BEQ .blocked + DEX : BPL .nextAncilla + SEC + RTL + +.blocked + CLC + RTL +;-------------------------------------------------------------------------------- +BossPrizeReceiveDispatch: + LDA $0C54, X : BEQ .fromTextOrObject + CMP.b #$03 : BEQ .fromTextOrObject + CMP.b #$04 : BEQ .waitForTextClose + JML.l Ancilla_ReceiveItem_fromChestOrSprite + +.fromTextOrObject + JML.l Ancilla_ReceiveItem_fromTextOrObject + +.waitForTextClose + LDA $10 : CMP.b #$0E : BEQ .keepWaiting + LDA $11 : BNE .keepWaiting + LDA $1CD8 : BNE .keepWaiting + + STZ $0C4A, X + STZ $0FC1 + LDA $0C54, X : PHA : PHX + JSL.l PrepDungeonExit + PLX : PLA + JML.l Ancilla_ReceiveItem_objectFinished+44 + +.keepWaiting + LDA.b #$01 : STA $02E4 + LDA.b #$01 : STA $0FC1 + JML.l Ancilla_ReceiveItem_return +;-------------------------------------------------------------------------------- MaybeSetOrdinaryBossPrizeBits: CMP.b #$B6 : BNE + LDA $7EF374 : ORA.b #$04 : STA $7EF374 diff --git a/events.asm b/events.asm index 77b1527a..bba44780 100644 --- a/events.asm +++ b/events.asm @@ -241,6 +241,7 @@ PostItemAnimation: LDA.b #$00 : STA !ITEM_BUSY ; mark item as finished LDA $7F509F : BEQ + + JSL.l BossPrizeReceiveContextMatches : BCS + STZ $1CF0 : STZ $1CF1 ; reset decompression buffer JSL.l Main_ShowTextMessage_Alt LDA.b #$00 : STA $7F509F @@ -251,8 +252,6 @@ PostItemAnimation: LDA $0403 : STA !MULTIWORLD_ROOMDATA + - JSL.l MaybeCollectBossPrize - LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + STZ $02E9 LDA #$00 : STA !MULTIWORLD_ITEM_PLAYER_ID diff --git a/heartpieces.asm b/heartpieces.asm index ce753580..58834ea6 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -94,14 +94,9 @@ DrawHeartContainerGFX: BRA DrawHeartPieceGFX_skipLoad ;-------------------------------------------------------------------------------- HeartContainerSound: - LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE + - CPY.b #$20 : BEQ + ; Skip for Crystal - CPY.b #$37 : BEQ + ; Skip for Pendants - CPY.b #$38 : BEQ + - CPY.b #$39 : BEQ + - JSL.l CheckIfBossRoom : BCC + ; Skip if not in a boss room - LDA.b #$2E - SEC + CPY.b #$3E : BNE + + LDA.b #$2E + SEC RTL + CLC @@ -114,18 +109,20 @@ NormalItemSkipSound: + LDA $0C5E, X ; thing we wrote over - - CPY.b #$20 : BEQ + ; Skip for Crystal - CPY.b #$37 : BEQ + ; Skip for Pendants - CPY.b #$38 : BEQ + - CPY.b #$39 : BEQ + - PHA - JSL.l CheckIfBossRoom - PLA -RTL + JSL.l BossPrizeItemNeedsVictoryFanfare : BCC + + PLA + JSL Sound_SetSfxPanWithPlayerCoords + ORA.b #$13 : STA $012C + SEC + RTL + + PLA + CMP.b #$3E : BEQ + CLC + RTL + + + SEC RTL ;-------------------------------------------------------------------------------- HeartUpgradeSpawnDecision: ; this should return #$00 to make the hp spawn diff --git a/hooks.asm b/hooks.asm index feac3bdf..59add069 100755 --- a/hooks.asm +++ b/hooks.asm @@ -900,6 +900,9 @@ LDA.w AddReceivedItemExpanded_item_masks, X org $098769 ; 48769 - ancilla_init.asm:1005 (LDA .item_graphics_indices, Y) LDA.w AddReceivedItemExpanded_item_graphics_indices, Y +org $09878C ; 4878C - ancilla_init.asm:1028 (JSL GetAnimatedSpriteTile.variable) +JSL.l GetAnimatedSpriteTile_variable + org $09884D ; 4884D - ancilla_init.asm:1137 (LDA $836C, Y) LDA.w AddReceivedItemExpanded_y_offsets, Y org $09885B ; 4885B - ancilla_init.asm:1139 (LDA .x_offsets, X) - I think the disassembly is wrong here, should have been LDA .x_offsets, Y @@ -916,6 +919,20 @@ LDA.w AddReceivedItemExpanded_x_offsets, Y org $08C6C8 ; 446C8 - ancilla_receive_item.asm:538 (LDA AddReceiveItem.properties, X) JSL CheckReceivedItemPropertiesBeforeLoad +org $08C6B4 ; 446B4 - ancilla_receive_item.asm:520 alternate draw entry (PHX : LDA $0BF0, X : STA $74) +JML.l BossPrizeDrawPrep +NOP #2 +org $08C6BA +BossPrizeDrawContinue: + +org $0987BB ; 487BB - ancilla_init.asm (LDA $02E9 : CMP.b #$02 : BEQ .masterSwordFromSprite) +JML.l BossPrizeMasterSwordSourceCheck +NOP #3 +org $0987C2 +BossPrizeMasterSwordSourceNormal: +org $0987E2 +BossPrizeMasterSwordFromSprite: + org $08C6DE ; 446DE - ancilla_receive_item.asm:550 (LDA .wide_item_flag, X) LDA.l AddReceivedItemExpanded_wide_item_flag, X @@ -1556,9 +1573,18 @@ org $08C421 ; <- AD4021 F005 - ancilla_receive_item.asm:108 (LDA $2140 : BEQ .wa JML PendantFanfareWait : NOP PendantFanfareContinue: +org $08C412 ; <- BD5E0C C937 F008 - ancilla_receive_item.asm:101 (LDA $0C5E, X : CMP.b #$37 : BEQ .isPendant) +JML.l BossPrizePendantWaitCheck +NOP #11 + org $08C42B PendantFanfareDone: +org $08C61D ; <- BD5E0C C920 - ancilla_receive_item.asm:435 (LDA $0C5E, X : CMP.b #$20) +JML.l CrystalItemBehaviorCheck +NOP +CrystalSpecialBehaviorContinue: + org $08C62A ; <- AD4021 D008 - ancilla_receive_item.asm:442 (LDA $2140 : BNE .waitForSilence) JML CrystalFanfareWait : NOP CrystalFanfareDone: @@ -2026,6 +2052,20 @@ org $08C45F ; <- 4445F - ancilla_recieve_item.asm:157 (STZ $02E9 : LDA $0C5E, X) Ancilla_ReceiveItem_optimus: JML.l PostItemAnimation : NOP #2 +org $08C3D0 ; <- 443D0 - ancilla_receive_item.asm:62 (LDA $0C54, X) +JML.l BossPrizeReceiveDispatch +NOP #8 +org $08C3DC +Ancilla_ReceiveItem_fromTextOrObject: +org $08C538 +Ancilla_ReceiveItem_return: +org $08C539 +Ancilla_ReceiveItem_fromChestOrSprite: + +org $08C505 ; <- 44505 - ancilla_receive_item.asm:256 (STZ $0C4A, X : STZ $0FC1) +JML.l HandleBossPrizeObjectFinished +NOP #2 + org $08C548 ; <- 44548 - ancilla_recieve_item.asm:297 (CMP.b #$28 : BNE .dontGiveRupees) JML.l Multiworld_Ancilla_ReceiveItem_stillInMotion Ancilla_ReceiveItem_stillInMotion_moveon: diff --git a/newitems.asm b/newitems.asm index c3520197..f27d131e 100644 --- a/newitems.asm +++ b/newitems.asm @@ -522,6 +522,7 @@ AddReceivedItemExpanded: JSR IncrementItemCounters + + JSL.l BossPrizeQueueFreeItemNotice LDA $02D8 ; Item Value CMP.b #$16 : BEQ .bottle ; Bottle @@ -1217,6 +1218,10 @@ AttemptItemSubstitution: PLA : PLX RTS ;-------------------------------------------------------------------------------- +AttemptItemSubstitutionLong: + JSR AttemptItemSubstitution +RTL +;-------------------------------------------------------------------------------- CountBottles: PHX LDX.b #$00 diff --git a/tablets.asm b/tablets.asm index 338bef70..576723b9 100644 --- a/tablets.asm +++ b/tablets.asm @@ -132,4 +132,4 @@ DrawNarrowDroppedObject: PLY .large_sprite RTL -;-------------------------------------------------------------------------------- \ No newline at end of file +;-------------------------------------------------------------------------------- diff --git a/utilities.asm b/utilities.asm index 978b2dd4..d0d76adf 100644 --- a/utilities.asm +++ b/utilities.asm @@ -218,10 +218,6 @@ GetSpritePalette: CMP.b #$F8 : !BGE .specialHandling RTL .specialHandling - CMP.b #$F9 : BNE ++ ; Crystal palette - JSL.l LoadCrystalItemPalette - RTL - ++ CMP.b #$FD : BNE ++ ; Progressive Sword LDA $7EF359 CMP.l ProgressiveSwordLimit : !BLT + ; Progressive Sword Limit @@ -283,7 +279,7 @@ RTL db $08, $08, $02, $02, $04, $02, $02, $02 db $04, $02, $04, $02, $08, $08, $04, $02 - db $F9, $02, $04, $02, $04, $04, $00, $04 + db $0C, $02, $04, $02, $04, $04, $00, $04 db $04, $08, $02, $02, $08, $04, $02, $08 db $04, $04, $08, $08, $08, $04, $02, $08 @@ -314,7 +310,7 @@ RTL db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Free Small Key db $04 ; Bee Trap db $08, $02, $08, $02 ; Fae, Bee, Jar, Apple - db $08, $08, $04, $02, $F9, $F9, $F9, $F9, $F9, $F9, $F9 ; Unused, Pendants, Crystals + db $08, $08, $04, $02, $0C, $0C, $0C, $0C, $0C, $0C, $0C ; Unused, Pendants, Crystals db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Key Ring db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused From 59a36e306d3c4a1a5760c7cdc56b27d8bac2dfd4 Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 24 Apr 2026 21:24:00 -0400 Subject: [PATCH 08/53] Hide boss prize item during deferred textbox --- dungeondrops.asm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dungeondrops.asm b/dungeondrops.asm index 4db9a2ec..285e2595 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -238,6 +238,7 @@ HandleBossPrizeObjectFinished: LDA $7F509F : BEQ + LDA.b #$04 : STA $0C54, X + JSL.l HideBossPrizeItemVisual STZ $1CF0 : STZ $1CF1 JSL.l Main_ShowTextMessage_Alt LDA.b #$00 : STA $7F509F @@ -257,6 +258,24 @@ HandleBossPrizeObjectFinished: STZ $0FC1 JML.l Ancilla_ReceiveItem_objectFinished+6 ;-------------------------------------------------------------------------------- +HideBossPrizeItemVisual: + PHP + REP #$20 + LDA $E8 : SEC : SBC.w #$0018 + SEP #$20 + STA $0BFA, X + XBA + STA $0C0E, X + + REP #$20 + LDA $E2 : SEC : SBC.w #$0018 + SEP #$20 + STA $0C04, X + XBA + STA $0C18, X + PLP +RTL +;-------------------------------------------------------------------------------- MarkBossPrizeDungeonCompletion: LDA $040C CMP #$FF : BEQ .done From c21dab7441a293a8015016fd9b2ef9afbebded73 Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 16:47:37 -0400 Subject: [PATCH 09/53] Full width progressive items showing correctly as prizes --- darkroomitems.asm | 15 ++++-- dungeondrops.asm | 128 +++++++++++++++++++++++++++++++++++++++++++--- hooks.asm | 4 ++ tablets.asm | 5 ++ 4 files changed, 139 insertions(+), 13 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index 1e3034d3..b5c20dd2 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -1,16 +1,21 @@ CheckReceivedItemPropertiesBeforeLoad: + PHX + LDA $7F504C : BEQ + + LDA $7F504D : TAX + + LDA $A0 : BEQ .normalCode LDA $7EC005 : BNE .lightOff .normalCode LDA.l AddReceivedItemExpanded_properties, X ;Restore Rando Code + PLX RTL .lightOff - PHX : PHY : PHB + PHY : PHB LDA.l AddReceivedItemExpanded_properties, X ; get palette REP #$30 - AND #$0007 ; mask out palette + AND #$0007 ; mask out palette ASL #5 ; multiply by 32 ADC #$C610 ; offset to latter half @@ -19,9 +24,9 @@ CheckReceivedItemPropertiesBeforeLoad: LDA #$000F ; 16 bytes MVN $7E, $7E ; move palette - - SEP #$30 - PLB : PLY : PLX + + SEP #$30 + PLB : PLY : PLX INC $15 LDA #$00 RTL diff --git a/dungeondrops.asm b/dungeondrops.asm index 285e2595..5e482b86 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -4,6 +4,9 @@ !BOSS_PRIZE_ACTIVE = "$7F5047" !BOSS_PRIZE_ROOM = "$7F5048" !BOSS_PRIZE_SLOT = "$7F504A" +!BOSS_PRIZE_NARROW_SHADOW = "$7F504B" +!BOSS_PRIZE_DRAW_ACTIVE = "$7F504C" +!BOSS_PRIZE_DISPLAY_ITEM = "$7F504D" !ITEM_BUSY = "$7F5091" DropSafeDungeon: @@ -74,21 +77,28 @@ ClearBossPrizeContext: STA !BOSS_PRIZE_ROOM STA !BOSS_PRIZE_ROOM+1 LDA.b #$FF : STA !BOSS_PRIZE_SLOT + LDA.b #$00 + STA !BOSS_PRIZE_NARROW_SHADOW + STA !BOSS_PRIZE_DRAW_ACTIVE + STA !BOSS_PRIZE_DISPLAY_ITEM RTL ;-------------------------------------------------------------------------------- SpawnBossPrizeFallingItem: - JSL.l BossPrizeResolveItem PHA + JSL.l BossPrizeResolveItem + STA !BOSS_PRIZE_DISPLAY_ITEM + PLA : PHA LDY.b #$04 LDA.b #$29 JSL.l AddAncillaLong : BCC .spawned PLA SEC - RTL + RTL .spawned - PLA : STA $0C5E, X : TAY + PLA : STA $0C5E, X + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY PHX : PHB LDA.b #AddReceivedItemExpanded_item_graphics_indices>>16 : PHA : PLB @@ -138,7 +148,7 @@ SpawnBossPrizeFallingItem: SEP #$20 .setCoords - LDY $0C5E, X + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY LDA.w AddReceivedItemExpanded_wide_item_flag, Y : BNE + REP #$20 LDA $02 : !ADD.w #$0008 : STA $02 @@ -326,16 +336,103 @@ RTS ;-------------------------------------------------------------------------------- BossPrizeResolveItem: PHA - JSL.l BossPrizeGetPlayer : CMP.b #$00 : BNE .remote + JSL.l BossPrizeGetPlayer : CMP.b #$00 : BEQ .local + +.remote PLA - JSL.l AttemptItemSubstitutionLong RTL -.remote +.local PLA -RTL + JSL.l AttemptItemSubstitutionLong + CMP.b #$4E : BNE .notProgressiveMagic + +.progressiveMagic + LDA $7EF37B : BNE + + RTL + + + LDA.b #$4F + RTL + +.notProgressiveMagic + CMP.b #$5E : BNE .notProgressiveSword + +.progressiveSword + LDA $7EF359 : CMP.l ProgressiveSwordLimit : !BLT + + LDA.l ProgressiveSwordReplacement : RTL + + + LDA $7EF359 : CMP.b #$FF : BNE + + LDA.b #$49 : RTL + + : CMP.b #$00 : BNE + + LDA.b #$49 : RTL + + : CMP.b #$01 : BNE + + LDA.b #$50 : RTL + + : CMP.b #$02 : BNE + + LDA.b #$02 : RTL + + LDA.b #$03 : RTL + +.notProgressiveSword + CMP.b #$5F : BNE .notProgressiveShield + +.progressiveShield + LDA !PROGRESSIVE_SHIELD : LSR #6 : CMP.l ProgressiveShieldLimit : !BLT + + LDA.l ProgressiveShieldReplacement : RTL + + + LDA !PROGRESSIVE_SHIELD : AND.b #$C0 : BNE + + LDA.b #$04 : RTL + + : CMP.b #$40 : BNE + + LDA.b #$05 : RTL + + LDA.b #$06 : RTL + +.notProgressiveShield + CMP.b #$60 : BNE .notProgressiveArmor + +.progressiveArmor + LDA $7EF35B : CMP.l ProgressiveArmorLimit : !BLT + + LDA.l ProgressiveArmorReplacement : RTL + + + LDA $7EF35B : CMP.b #$00 : BNE + + LDA.b #$22 : RTL + + LDA.b #$23 : RTL + +.notProgressiveArmor + CMP.b #$61 : BNE .notProgressiveGlove + +.progressiveGlove + LDA $7EF354 : BNE + + LDA.b #$1B : RTL + + LDA.b #$1C : RTL + +.notProgressiveGlove + CMP.b #$64 : BEQ .progressiveBow + CMP.b #$65 : BNE .displayResolved + +.progressiveBow + LDA $7EF340 : INC : LSR : CMP.l ProgressiveBowLimit : !BLT + + LDA.l ProgressiveBowReplacement : RTL + + + LDA $7EF340 : INC : LSR : CMP.b #$00 : BNE + + LDA.b #$3A : RTL + + LDA.b #$3B : RTL + +.displayResolved + RTL ;-------------------------------------------------------------------------------- BossPrizeDrawPrep: + LDA.b #$00 + STA !BOSS_PRIZE_NARROW_SHADOW + STA !BOSS_PRIZE_DRAW_ACTIVE + JSL.l BossPrizeContextMatchesRoom : BCC .restore + JSL.l BossPrizeContextMatchesSlot : BCC .restore + LDA.b #$01 : STA !BOSS_PRIZE_DRAW_ACTIVE + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY + LDA.w AddReceivedItemExpanded_wide_item_flag, Y : BNE .restore + LDA.b #$01 : STA !BOSS_PRIZE_NARROW_SHADOW + REP #$20 + LDA $02 : CLC : ADC.w #$0008 : STA $02 + SEP #$20 + +.restore REP #$20 LDA $00 : CLC : ADC.w #$0008 : STA $08 SEP #$20 @@ -343,6 +440,21 @@ BossPrizeDrawPrep: LDA $0BF0, X : STA $74 JML.l BossPrizeDrawContinue ;-------------------------------------------------------------------------------- +BossPrizeMilestoneShadowPrep: + SEP #$20 + LDA !BOSS_PRIZE_NARROW_SHADOW : BEQ .prepShadowY + LDX.b #$02 + REP #$20 + LDA $02 : SEC : SBC.w #$0004 : STA $02 + BRA .shadowYReady + +.prepShadowY + REP #$20 + +.shadowYReady + LDA $06 : CLC : ADC.w #$000C : STA $00 +RTL +;-------------------------------------------------------------------------------- BossPrizeMasterSwordSourceCheck: LDA $02E9 : CMP.b #$02 : BEQ .spriteSource JSL.l BossPrizeReceiveContextMatches : BCS .spriteSource diff --git a/hooks.asm b/hooks.asm index 59add069..0b66fd06 100755 --- a/hooks.asm +++ b/hooks.asm @@ -942,6 +942,10 @@ JSL CheckReceivedItemPropertiesBeforeLoad org $08C70F ; 4470F - ancilla_receive_item.asm : 582 - (LDA.b #$00 : STA ($92), Y) JSL.l LoadNarrowObject +org $08CDF3 ; 44DF3 - ancilla_milestone_item.asm:239 (REP #$20 : LDA $06 : ADD.w #$000C : STA $00) +JSL.l BossPrizeMilestoneShadowPrep +NOP #6 + ;org $0985ED ; 485ED - ancilla_init.asm:693 (LDA $02E9 : CMP.b #$01) ;JSL.l AddReceivedItemExpandedGetItem ;NOP diff --git a/tablets.asm b/tablets.asm index 576723b9..75c8c801 100644 --- a/tablets.asm +++ b/tablets.asm @@ -95,7 +95,12 @@ IsMedallion: RTL ;-------------------------------------------------------------------------------- LoadNarrowObject: + PHX + LDA $7F504C : BEQ + + LDA $7F504D : TAX + + LDA.l AddReceivedItemExpanded_wide_item_flag, X : STA ($92), Y ; AddReceiveItem.wide_item_flag? + PLX RTL ;-------------------------------------------------------------------------------- DrawNarrowDroppedObject: From 3aae5dd862eb7274e56f77d77ae359255c815c79 Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 19:46:02 -0400 Subject: [PATCH 10/53] Half-width prizes fixed --- dungeondrops.asm | 39 ++++++++++++++++++++++++++++++++++++++- hooks.asm | 2 +- tablets.asm | 7 +------ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index 5e482b86..2c6f231c 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -445,7 +445,7 @@ BossPrizeMilestoneShadowPrep: LDA !BOSS_PRIZE_NARROW_SHADOW : BEQ .prepShadowY LDX.b #$02 REP #$20 - LDA $02 : SEC : SBC.w #$0004 : STA $02 + LDA $02 : SEC : SBC.w #$0008 : STA $02 BRA .shadowYReady .prepShadowY @@ -455,6 +455,43 @@ BossPrizeMilestoneShadowPrep: LDA $06 : CLC : ADC.w #$000C : STA $00 RTL ;-------------------------------------------------------------------------------- +BossPrizeShiftUpperItemTileAndLoadWideItemFlag: + PHX : PHY + LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .normalItem + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAX + LDA.l AddReceivedItemExpanded_wide_item_flag, X : CMP.b #$02 : BEQ .loadWideFlag + + TYA : ASL #2 : TAY + LDA ($90), Y : CLC : ADC.b #$04 : STA ($90), Y + BRA .loadWideFlag + +.normalItem +.loadWideFlag + LDA.l AddReceivedItemExpanded_wide_item_flag, X + PLY : PLX +RTL +;-------------------------------------------------------------------------------- +BossPrizeLoadNarrowObject: + PHX : PHY + LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .normalItem + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAX + BRA .loadWideFlag + +.normalItem + TXA + +.loadWideFlag + LDA.l AddReceivedItemExpanded_wide_item_flag, X : STA ($92), Y + CMP.b #$02 : BEQ .done + LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .done + + TYA : ASL #2 : TAY + LDA ($90), Y : CLC : ADC.b #$04 : STA ($90), Y + +.done + PLY : PLX +RTL +;-------------------------------------------------------------------------------- BossPrizeMasterSwordSourceCheck: LDA $02E9 : CMP.b #$02 : BEQ .spriteSource JSL.l BossPrizeReceiveContextMatches : BCS .spriteSource diff --git a/hooks.asm b/hooks.asm index 0b66fd06..408d7c50 100755 --- a/hooks.asm +++ b/hooks.asm @@ -934,7 +934,7 @@ org $0987E2 BossPrizeMasterSwordFromSprite: org $08C6DE ; 446DE - ancilla_receive_item.asm:550 (LDA .wide_item_flag, X) -LDA.l AddReceivedItemExpanded_wide_item_flag, X +JSL.l BossPrizeShiftUpperItemTileAndLoadWideItemFlag org $08C6F9 ; 446F9 - ancilla_receive_item.asm:570 (LDA AddReceiveItem.properties, X) JSL CheckReceivedItemPropertiesBeforeLoad diff --git a/tablets.asm b/tablets.asm index 75c8c801..8218c641 100644 --- a/tablets.asm +++ b/tablets.asm @@ -95,12 +95,7 @@ IsMedallion: RTL ;-------------------------------------------------------------------------------- LoadNarrowObject: - PHX - LDA $7F504C : BEQ + - LDA $7F504D : TAX - + - LDA.l AddReceivedItemExpanded_wide_item_flag, X : STA ($92), Y ; AddReceiveItem.wide_item_flag? - PLX + JSL.l BossPrizeLoadNarrowObject RTL ;-------------------------------------------------------------------------------- DrawNarrowDroppedObject: From 631a0c962e69022a1cd5871f88574527c0be5153 Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 20:31:09 -0400 Subject: [PATCH 11/53] Fix Progressive Sword/Shield on prize locations --- darkroomitems.asm | 30 +++++++++++++++++++++++---- dungeondrops.asm | 52 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index b5c20dd2..f6bb5db5 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -6,17 +6,17 @@ CheckReceivedItemPropertiesBeforeLoad: LDA $A0 : BEQ .normalCode LDA $7EC005 : BNE .lightOff .normalCode - LDA.l AddReceivedItemExpanded_properties, X ;Restore Rando Code + JSR .loadProperty PLX RTL -.lightOff + .lightOff PHY : PHB - LDA.l AddReceivedItemExpanded_properties, X ; get palette + JSR .loadProperty REP #$30 AND #$0007 ; mask out palette - ASL #5 ; multiply by 32 + ASL #5 ; multiply by 32 ADC #$C610 ; offset to latter half TAX ; give to destination @@ -31,6 +31,28 @@ CheckReceivedItemPropertiesBeforeLoad: LDA #$00 RTL + .loadProperty + LDA $7F504C : BEQ .normalProperty + TXA : CMP.b #$04 : BEQ .blueShield + CMP.b #$05 : BEQ .redShield + CMP.b #$06 : BEQ .mirrorShield + + .normalProperty + LDA.l AddReceivedItemExpanded_properties, X ; Restore Rando Code + RTS + + .blueShield + LDA.b #$02 + RTS + + .redShield + LDA.b #$01 + RTS + + .mirrorShield + LDA.b #$04 + RTS + CrystalItemBehaviorCheck: LDA $0C5E, X : CMP.b #$20 : BNE .ordinaryItem LDA $0C54, X : CMP.b #$03 : BEQ .bossPrizeCrystal diff --git a/dungeondrops.asm b/dungeondrops.asm index 2c6f231c..17542297 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -104,9 +104,13 @@ SpawnBossPrizeFallingItem: LDA.b #AddReceivedItemExpanded_item_graphics_indices>>16 : PHA : PLB LDA.w AddReceivedItemExpanded_item_graphics_indices, Y : STA $72 CMP.b #$FF : BEQ .invalidItem - CMP.b #$20 : BNE .getItemTiles - JSL.l DecompShieldGfx - LDA $72 + CMP.b #$20 : BEQ .shieldItem + CMP.b #$2D : BEQ .shieldItem + CMP.b #$2E : BNE .getItemTiles + .shieldItem + TYA + JSL.l GetSpriteID + STA $72 BRA .getItemTiles .invalidItem @@ -115,9 +119,11 @@ SpawnBossPrizeFallingItem: .getItemTiles JSL.l GetAnimatedSpriteTile_variable - LDA $72 : CMP.b #$06 : BNE .notFighterSword - JSL.l DecompSwordGfx - .notFighterSword + LDA $72 : CMP.b #$06 : BEQ .swordItem + CMP.b #$18 : BNE .notSwordItem + .swordItem + JSL.l BossPrizeDecompResolvedSwordGfx + .notSwordItem PLB : PLX LDA.b #$D0 : STA $0294, X @@ -162,6 +168,34 @@ SpawnBossPrizeFallingItem: CLC RTL ;-------------------------------------------------------------------------------- +BossPrizeDecompResolvedSwordGfx: + PHP + SEP #$20 + LDA $7EF359 : PHA + LDA !BOSS_PRIZE_DISPLAY_ITEM + CMP.b #$49 : BEQ .fighterSword + CMP.b #$01 : BEQ .masterSword + CMP.b #$50 : BEQ .masterSword + CMP.b #$02 : BEQ .temperedSword + LDA.b #$04 : BRA .loadSword + +.fighterSword + LDA.b #$01 : BRA .loadSword + +.masterSword + LDA.b #$02 : BRA .loadSword + +.temperedSword + LDA.b #$03 + +.loadSword + STA $7EF359 + JSL.l DecompSwordGfx + JSL.l Palette_Sword + PLA : STA $7EF359 + PLP +RTL +;-------------------------------------------------------------------------------- BossPrizeContextMatchesRoom: LDA BossPrizeShuffle : BEQ .mismatch LDA !BOSS_PRIZE_ACTIVE : BEQ .mismatch @@ -407,7 +441,7 @@ BossPrizeResolveItem: CMP.b #$64 : BEQ .progressiveBow CMP.b #$65 : BNE .displayResolved -.progressiveBow + .progressiveBow LDA $7EF340 : INC : LSR : CMP.l ProgressiveBowLimit : !BLT + LDA.l ProgressiveBowReplacement : RTL + @@ -415,8 +449,8 @@ BossPrizeResolveItem: LDA.b #$3A : RTL + LDA.b #$3B : RTL -.displayResolved - RTL + .displayResolved + RTL ;-------------------------------------------------------------------------------- BossPrizeDrawPrep: LDA.b #$00 From 7e77526083fe08919b35a2538d4b947911a065cd Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 20:59:40 -0400 Subject: [PATCH 12/53] Restrict boss prize draw offsets to milestone ancilla --- dungeondrops.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/dungeondrops.asm b/dungeondrops.asm index 17542297..77dfae03 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -456,6 +456,7 @@ BossPrizeDrawPrep: LDA.b #$00 STA !BOSS_PRIZE_NARROW_SHADOW STA !BOSS_PRIZE_DRAW_ACTIVE + LDA $0C4A, X : CMP.b #$29 : BNE .restore JSL.l BossPrizeContextMatchesRoom : BCC .restore JSL.l BossPrizeContextMatchesSlot : BCC .restore LDA.b #$01 : STA !BOSS_PRIZE_DRAW_ACTIVE From 6807eff7b95bfb856687e89f9e8d339f99aeec69 Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 21:32:55 -0400 Subject: [PATCH 13/53] Remove stored boss prize X shift from narrow items --- dungeondrops.asm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index 77dfae03..264682c1 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -154,12 +154,6 @@ SpawnBossPrizeFallingItem: SEP #$20 .setCoords - LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY - LDA.w AddReceivedItemExpanded_wide_item_flag, Y : BNE + - REP #$20 - LDA $02 : !ADD.w #$0008 : STA $02 - SEP #$20 - + LDA $00 : STA $0BFA, X LDA $01 : STA $0C0E, X LDA $02 : STA $0C04, X From f23b23b4466f1b533cbeb1eb0c506063a07bb4d9 Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 21:42:59 -0400 Subject: [PATCH 14/53] Document WRAM usage --- tables.asm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tables.asm b/tables.asm index f5e7d52b..68b1ef55 100644 --- a/tables.asm +++ b/tables.asm @@ -1546,7 +1546,11 @@ dw #9999 ; Rupee Limit ; $7F5044 - $7F5046 - NMI Auxiliary Function ; $7F5047 - Boss Prize Active Flag ; $7F5048 - $7F5049 - Boss Prize Room ID -; $7F504A - $7F504E - Unused +; $7F504A - Boss Prize Ancilla Slot +; $7F504B - Boss Prize Narrow Shadow Flag +; $7F504C - Boss Prize Draw Active Flag +; $7F504D - Boss Prize Display Item +; $7F504E - Unused ; $7F504F - $7F506F - Shop Block ; $7F5070 - Reserved for OneMind ; $7F5071 - Reserved for OneMind From 38a150311f91f0a263ce5861bcc5c64a35509734 Mon Sep 17 00:00:00 2001 From: Alchav Date: Mon, 27 Apr 2026 22:04:52 -0400 Subject: [PATCH 15/53] Fix Crystal palettes --- darkroomitems.asm | 18 ++++++++++++++++++ utilities.asm | 14 ++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index f6bb5db5..b435d341 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -62,3 +62,21 @@ CrystalItemBehaviorCheck: .bossPrizeCrystal JML.l CrystalSpecialBehaviorContinue + +MaybeLoadCrystalSpritePalette: + PHA + CMP.b #$20 : BEQ .loadPalette + CMP.b #$B9 : BCC .done + CMP.b #$C0 : BCS .done + +.loadPalette + PHX + LDA.b #$04 : STA $0AB1 + LDA.b #$02 : STA $0AA9 + JSL.l $1BED72 ; Palette_MiscSpr.justSP6 + INC $15 + PLX + +.done + PLA +RTL diff --git a/utilities.asm b/utilities.asm index d0d76adf..5bb76a71 100644 --- a/utilities.asm +++ b/utilities.asm @@ -490,9 +490,10 @@ RTS !SKIP_EOR = "$7F5008" ;-------------------------------------------------------------------------------- DrawDynamicTile: - JSR PrepDrawRemoteItemSprite + JSR PrepDrawRemoteItemSprite + JSL.l MaybeLoadCrystalSpritePalette - JSL.l IsNarrowSprite : BCS .narrow + JSL.l IsNarrowSprite : BCS .narrow .full LDA.b #$01 : STA $06 @@ -521,9 +522,10 @@ DrawDynamicTile: RTL ;-------------------------------------------------------------------------------- DrawDynamicTileNoShadow: - JSR PrepDrawRemoteItemSprite + JSR PrepDrawRemoteItemSprite + JSL.l MaybeLoadCrystalSpritePalette - JSL.l IsNarrowSprite : BCS .narrow + JSL.l IsNarrowSprite : BCS .narrow .full LDA.b #$01 : STA $06 @@ -551,8 +553,8 @@ RTL ;-------------------------------------------------------------------------------- PrepDrawRemoteItemSprite: - PHA - LDA RemoteItems : BEQ + + PHA + LDA RemoteItems : BEQ + PLA CMP !MULTIWORLD_SCOUTREPLY_LOCATION : BNE ++ LDA !MULTIWORLD_SCOUT_LOCATION : BEQ +++ From 1028c2786d450e5a6cf7376a0212dda4b802a79b Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 30 Apr 2026 18:01:03 -0400 Subject: [PATCH 16/53] Merge key-rings-2 into shuffle-prizes --- LTTP_RND_GeneralBugfixes.asm | 38 ++++++++- capacityupgrades.asm | 2 + heartpieces.asm | 3 + hooks.asm | 4 + inventory.asm | 13 +++- keydropshuffle.asm | 6 ++ newitems.asm | 147 ++++++++++++++++++----------------- shopkeeper.asm | 15 ++-- stats.asm | 1 + tables.asm | 10 +-- utilities.asm | 8 +- 11 files changed, 158 insertions(+), 89 deletions(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index 6df0bf91..cdd3110d 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -147,7 +147,6 @@ incsrc map.asm incsrc msu.asm incsrc dialog.asm incsrc entrances.asm -incsrc clock.asm print "End of Coda Bank $20: ", pc warnpc $A18000 @@ -175,6 +174,43 @@ org $A1FF00 ; static mapping area incsrc init.asm org $A48000 ; code bank - PUT NEW CODE HERE + +Link_ReceiveItem_HandleCurrentDungeonKeyRing: + CPY.b #$CE : BNE .normalReceive + LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE .normalReceive + JSL.l ReceiveCurrentDungeonKeyRingQuiet + JSL.l Player_HaltDashAttackLong + CLC + PLB + RTL + + .normalReceive + LDA $02E9 + BEQ .fromTextOrObject + CMP.b #$03 : BNE .fromChestOrSprite + .fromChestOrSprite + JML $0799F2 + .fromTextOrObject + JML $0799C8 + +ReceiveCurrentDungeonKeyRingQuiet: + PHX : PHY + LDA $040C : CMP.b #$FF : BEQ .cleanup + LSR : TAX + LDA.l KeyRingQuantities, X : BEQ .cleanup + CLC : ADC $7EF36F : STA $7EF36F + JSL.l UpdateKeys + LDY.b #$CE + JSL.l FullInventoryExternal + JSL.l CountChestKeyLong + JSL.l HUD_RebuildLong + .cleanup + STZ $02D8 : STZ $02D9 : STZ $02E9 + STZ $02DA : STZ $037B : STZ $02E4 + PLY : PLX +RTL + +incsrc clock.asm incsrc accessability.asm incsrc heartbeep.asm incsrc capacityupgrades.asm diff --git a/capacityupgrades.asm b/capacityupgrades.asm index 59e46939..d12a4a03 100644 --- a/capacityupgrades.asm +++ b/capacityupgrades.asm @@ -8,6 +8,8 @@ IncrementBombs: LDA !BOMB_UPGRADES ; get bomb upgrades !ADD.l StartingMaxBombs : DEC + CMP.b #$FF : BEQ + ; if max bombs is 0, it underflows to $FF. Don't add bombs + CMP !BOMB_CURRENT !BLT + diff --git a/heartpieces.asm b/heartpieces.asm index 58834ea6..80baa865 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -108,6 +108,8 @@ NormalItemSkipSound: RTL + + CPY.b #$CE : BEQ .skipSound ; Skip the current-dungeon key ring pickup fanfare + LDA $0C5E, X ; thing we wrote over PHA JSL.l BossPrizeItemNeedsVictoryFanfare : BCC + @@ -122,6 +124,7 @@ NormalItemSkipSound: CLC RTL + +.skipSound SEC RTL ;-------------------------------------------------------------------------------- diff --git a/hooks.asm b/hooks.asm index 408d7c50..2bcd63d0 100755 --- a/hooks.asm +++ b/hooks.asm @@ -2239,6 +2239,10 @@ BCC Link_ReceiveItem_notHeartContainer org $0799BA ; 399BA - Bank07.asm:4070 (LDA.b #$60 : STA $02D9) Link_ReceiveItem_notHeartContainer: ;-------------------------------------------------------------------------------- +org $0799BF ; 399BF - Bank07.asm:4072 (LDA $02E9 : BEQ .fromTextOrObject) +JML.l Link_ReceiveItem_HandleCurrentDungeonKeyRing +NOP #5 +;-------------------------------------------------------------------------------- org $09887F ; <- 4887F - ancilla_init.asm : 1163 (LDA $0C5E, X : CMP.b #$3E : BEQ .doneWithSoundEffects) JSL NormalItemSkipSound NOP diff --git a/inventory.asm b/inventory.asm index 7c799c94..9907262b 100644 --- a/inventory.asm +++ b/inventory.asm @@ -547,8 +547,8 @@ AddInventory: CPY.b #$B0 : !BGE + JSR .incrementKey BRL .done - + CPY.b #$C0 : !BLT + ; Items $C0 - $CD - Key Rings - CPY.b #$CE : !BGE + + + CPY.b #$C0 : !BLT + ; Items $C0 - $CE - Key Rings + CPY.b #$CF : !BGE + JSR .incrementKey BRL .done + @@ -763,6 +763,10 @@ RTS ; Link_ReceiveItem_HUDRefresh: ;-------------------------------------------------------------------------------- Link_ReceiveItem_HUDRefresh: + LDA $7EF370 ; get bomb upgrades + !ADD.l StartingMaxBombs + CMP.b #0 : BEQ + ; do not add bombs if you can't carry any + LDA $7EF343 : BNE + ; skip if we have bombs LDA $7EF375 : BEQ + ; skip if we are filling no bombs DEC : STA $7EF375 ; decrease bomb fill count @@ -780,6 +784,11 @@ RTL HandleBombAbsorbtion: STA $7EF375 ; thing we wrote over LDA $0303 : BNE + ; skip if we already have some item selected + + LDA $7EF370 ; get bomb upgrades + !ADD.l StartingMaxBombs + CMP.b #0 : BEQ + ; do not switch to bombs if you can't carry any + LDA.b #$04 : STA $0202 ; set selected item to bombs LDA.b #$01 : STA $0303 ; set selected item to bombs JSL.l HUD_RebuildLong diff --git a/keydropshuffle.asm b/keydropshuffle.asm index 403ff707..acea84cd 100644 --- a/keydropshuffle.asm +++ b/keydropshuffle.asm @@ -160,6 +160,12 @@ KeyGet: - JSL.l FullInventoryExternal : jsl CountChestKeyLong : plx : pla : rtl + cmp #$af : beq - ; universal key cmp #$24 : beq - ; small key for this dungeon + cmp #$CE : bne + ; small key ring for this dungeon + lda.l KeyRingQuantities, x : beq - + clc : adc $02, S : dec + sta $02, S + bra - + + plx .receive jsl.l $0791b3 ; Player_HaltDashAttackLong diff --git a/newitems.asm b/newitems.asm index f27d131e..d8060ebf 100644 --- a/newitems.asm +++ b/newitems.asm @@ -51,6 +51,7 @@ ; #$BE - Crystal 6 ; #$BF - Crystal 7 ; #$C0 - Key Rings +; #$CE - Small Key Ring of Current Dungeon ; #$FE - Server Request (Asychronous Chest) ; #$FF - Null Chest ;-------------------------------------------------------------------------------- @@ -235,38 +236,38 @@ AddReceivedItemExpandedGetItem: ++ LDA.b #$04 ; bow with arrow +++ - STA $7EF340 - .noequip - LDA !INVENTORY_SWAP_2 : ORA #$40 : STA !INVENTORY_SWAP_2 ; mark silver bow on y-toggle - BRL .done + STA $7EF340 + .noequip + LDA !INVENTORY_SWAP_2 : ORA #$40 : STA !INVENTORY_SWAP_2 ; mark silver bow on y-toggle + BRL .done + CMP.b #$4C : BNE + ; 50 bombs - ;LDA.b #$07 : STA $7EF370 ; upgrade bombs - LDA.b #50 : !SUB.l StartingMaxBombs : STA $7EF370 ; upgrade bombs - LDA.b #50 : STA $7EF375 ; fill bombs - BRL .done + ;LDA.b #$07 : STA $7EF370 ; upgrade bombs + LDA.b #50 : !SUB.l StartingMaxBombs : STA $7EF370 ; upgrade bombs + LDA.b #50 : STA $7EF375 ; fill bombs + BRL .done + CMP.b #$4D : BNE + ; 70 arrows - ;LDA #$07 : STA $7EF371 ; upgrade arrows - LDA.b #70 : !SUB.l StartingMaxArrows : STA $7EF371 ; upgrade arrows - LDA.b #70 : STA $7EF376 ; fill arrows - BRL .done + ;LDA #$07 : STA $7EF371 ; upgrade arrows + LDA.b #70 : !SUB.l StartingMaxArrows : STA $7EF371 ; upgrade arrows + LDA.b #70 : STA $7EF376 ; fill arrows + BRL .done + CMP.b #$4E : BNE + ; 1/2 magic - LDA $7EF37B : CMP #$02 : !BGE ++ - INC : STA $7EF37B ; upgrade magic - ++ - LDA.b #$80 : STA $7EF373 ; fill magic - BRL .done + LDA $7EF37B : CMP #$02 : !BGE ++ + INC : STA $7EF37B ; upgrade magic + ++ + LDA.b #$80 : STA $7EF373 ; fill magic + BRL .done + CMP.b #$4F : BNE + ; 1/4 magic - LDA.b #$02 : STA $7EF37B ; upgrade magic - LDA.b #$80 : STA $7EF373 ; fill magic - BRL .done + LDA.b #$02 : STA $7EF37B ; upgrade magic + LDA.b #$80 : STA $7EF373 ; fill magic + BRL .done + CMP.b #$50 : BNE + ; Master Sword (Safe) - LDA $7EF359 : CMP.b #$02 : !BGE + ; skip if we have a better sword - LDA.b #$02 : STA $7EF359 ; set master sword - BRL .done + LDA $7EF359 : CMP.b #$02 : !BGE + ; skip if we have a better sword + LDA.b #$02 : STA $7EF359 ; set master sword + BRL .done + CMP.b #$51 : BNE + ; +5 Bombs - LDA $7EF370 : !ADD.b #$05 : STA $7EF370 ; upgrade bombs +5 - LDA.l Upgrade5BombsRefill : STA $7EF375 ; fill bombs - BRL .done + LDA $7EF370 : !ADD.b #$05 : STA $7EF370 ; upgrade bombs +5 + LDA.l Upgrade5BombsRefill : STA $7EF375 ; fill bombs + BRL .done + CMP.b #$52 : BNE + ; +10 Bombs LDA $7EF370 : !ADD.b #$0A : STA $7EF370 ; upgrade bombs +10 LDA.l Upgrade10BombsRefill : STA $7EF375 ; fill bombs @@ -342,63 +343,63 @@ AddReceivedItemExpandedGetItem: BRL .done + CMP.b #$6B : BNE + ; Goal Collectable (Multi/Power Star) BRA .multi_collect - + CMP.b #$6C : BNE + ; Goal Collectable (Multi/Power Star) Alternate Graphic - .multi_collect - REP #$20 - LDA GoalItemRequirement : BEQ ++ - LDA !GOAL_COUNTER : INC : STA !GOAL_COUNTER + + CMP.b #$6C : BNE + ; Goal Collectable (Multi/Power Star) Alternate Graphic + .multi_collect + REP #$20 + LDA GoalItemRequirement : BEQ ++ + LDA !GOAL_COUNTER : INC : STA !GOAL_COUNTER CMP GoalItemRequirement : !BLT ++ SEP #$20 LDA TurnInGoalItems : BNE ++ JSL.l ActivateGoal - ++ - SEP #$20 - BRL .done - + CMP.b #$6D : BNE + ; Server Request F0 - JSL.l ItemGetServiceRequest_F0 - BRL .done - + CMP.b #$6E : BNE + ; Server Request F1 - JSL.l ItemGetServiceRequest_F1 - BRL .done - + CMP.b #$6F : BNE + ; Server Request F2 - JSL.l ItemGetServiceRequest_F2 - BRL .done + ++ + SEP #$20 + BRL .done + + CMP.b #$6D : BNE + ; Server Request F0 + JSL.l ItemGetServiceRequest_F0 + BRL .done + + CMP.b #$6E : BNE + ; Server Request F1 + JSL.l ItemGetServiceRequest_F1 + BRL .done + + CMP.b #$6F : BNE + ; Server Request F2 + JSL.l ItemGetServiceRequest_F2 + BRL .done ;+ CMP.b #$FE : BNE + ; Server Request (Null Chest) ; JSL.l ItemGetServiceRequest ; BRL .done - + CMP.b #$70 : !BLT + : CMP.b #$80 : !BGE + ; Free Map - AND #$0F : CMP #$08 : !BGE ++ - %ValueShift() - ORA $7EF368 : STA $7EF368 ; Map 1 - BRL .done + + CMP.b #$70 : !BLT + : CMP.b #$80 : !BGE + ; Free Map + AND #$0F : CMP #$08 : !BGE ++ + %ValueShift() + ORA $7EF368 : STA $7EF368 ; Map 1 + BRL .done ++ - !SUB #$08 - %ValueShift() - BIT.b #$C0 : BEQ +++ : LDA.b #$C0 : +++ ; Make Hyrule Castle / Sewers Count for Both - ORA $7EF369 : STA $7EF369 ; Map 2 - BRL .done - + CMP.b #$80 : !BLT + : CMP.b #$90 : !BGE + ; Free Compass - AND #$0F : CMP #$08 : !BGE ++ - %ValueShift() - ORA $7EF364 : STA $7EF364 ; Compass 1 + !SUB #$08 + %ValueShift() + BIT.b #$C0 : BEQ +++ : LDA.b #$C0 : +++ ; Make Hyrule Castle / Sewers Count for Both + ORA $7EF369 : STA $7EF369 ; Map 2 BRL .done + + CMP.b #$80 : !BLT + : CMP.b #$90 : !BGE + ; Free Compass + AND #$0F : CMP #$08 : !BGE ++ + %ValueShift() + ORA $7EF364 : STA $7EF364 ; Compass 1 + BRL .done ++ - !SUB #$08 - %ValueShift() - BIT.b #$C0 : BEQ +++ : LDA.b #$C0 : +++ ; Make Hyrule Castle / Sewers Count for Both - ORA $7EF365 : STA $7EF365 ; Compass 2 - BRL .done - + CMP.b #$90 : !BLT + : CMP.b #$A0 : !BGE + ; Free Big Key - AND #$0F : CMP #$08 : !BGE ++ - %ValueShift() - ORA $7EF366 : STA $7EF366 ; Big Key 1 + !SUB #$08 + %ValueShift() + BIT.b #$C0 : BEQ +++ : LDA.b #$C0 : +++ ; Make Hyrule Castle / Sewers Count for Both + ORA $7EF365 : STA $7EF365 ; Compass 2 BRL .done + + CMP.b #$90 : !BLT + : CMP.b #$A0 : !BGE + ; Free Big Key + AND #$0F : CMP #$08 : !BGE ++ + %ValueShift() + ORA $7EF366 : STA $7EF366 ; Big Key 1 + BRL .done ++ - !SUB #$08 - %ValueShift() - BIT.b #$C0 : BEQ +++ : LDA.b #$C0 : +++ ; Make Hyrule Castle / Sewers Count for Both - ORA $7EF367 : STA $7EF367 ; Big Key 2 - BRL .done + !SUB #$08 + %ValueShift() + BIT.b #$C0 : BEQ +++ : LDA.b #$C0 : +++ ; Make Hyrule Castle / Sewers Count for Both + ORA $7EF367 : STA $7EF367 ; Big Key 2 + BRL .done + CMP.b #$A0 : !BLT + : CMP.b #$B0 : !BGE + ; Free Small Key AND #$0F : TAX LDA $7EF37C, X : INC : STA $7EF37C, X ; Increment Key Count @@ -418,8 +419,12 @@ AddReceivedItemExpandedGetItem: LDA $7EF36F : INC : STA $7EF36F ++ BRL .done + + CMP.b #$CE : BNE + ; Small Key Ring (Current Dungeon) + LDA $040C : LSR : TAX + BRA .keyRingCount + CMP.b #$C0 : !BLT + : CMP.b #$D0 : !BGE + ; Key Ring AND #$0F : TAX + .keyRingCount LDA.l KeyRingQuantities, X : BEQ .keyRingDone PHA CLC : ADC $7EF37C, X : STA $7EF37C, X diff --git a/shopkeeper.asm b/shopkeeper.asm index 2c6b81c2..680235d9 100644 --- a/shopkeeper.asm +++ b/shopkeeper.asm @@ -682,8 +682,10 @@ Shopkeeper_BuyItem: LDA !SHOP_TYPE : AND.b #$80 : BEQ + : BRL .buy : + ; don't charge if this is a take-any .custom_price - LDA !SHOP_INVENTORY+2, X : AND.b #$80 : BEQ .price_is_rupees ; i honestly can't think of a better way to do this block because i haven't done asm in like 8 months - LDA !SHOP_INVENTORY+2, X : AND.b #$7F : CMP.b #$09 : BNE + ; 09 specifically is item + LDA !SHOP_INVENTORY+2, X : AND.b #$80 : BNE .price_is_not_rupees ; i honestly can't think of a better way to do this block because i haven't done asm in like 8 months + JMP .price_is_rupees + .price_is_not_rupees + LDA !SHOP_INVENTORY+2, X : AND.b #$7F : CMP.b #$09 : BNE + ; 09 specifically is item LDA !SHOP_INVENTORY+1, X : CMP.b $0303 : BNE .gotItem BRL .cant_afford .gotItem ; hand it over?? not logic friendly @@ -698,14 +700,17 @@ Shopkeeper_BuyItem: LDA !SHOP_INVENTORY+2, X : AND.b #$07 ; if bit 80, it's custom, if numbers 0-7, custom resource ; store shop index, get resource offset (X), load val, pop shop index, cmp val to shop_price... PHX : TAX : LDA ResourceOffset, X : TAX : TAY : LDA $7EF300, X ; fumble around with our resource value and price, sub value then put back into RAM - PLX : CMP !SHOP_INVENTORY+1,X : BMI + ; if resource is less than value, skip + PLX : CMP !SHOP_INVENTORY+1,X : BCC + ; if resource is less than value, skip + ; If hearts, ensure hearts are greater than the price + BNE .notEqual : CPY #$6D : BEQ .cant_afford + .notEqual ; subtract and store, store (x), store val back to address ; if X is heart containers, set ordinary hearts - !SUB !SHOP_INVENTORY+1,X : PHX : TYX : STA $7EF300, X + !SUB !SHOP_INVENTORY+1,X : PHX : TYX : STA $7EF300, X CPX #$6C : BNE .notHeartContainers CMP $7EF36D : !BGE .notHeartContainers : STA $7EF36D .notHeartContainers - PLX : BRL .buy_real + PLX : BRL .buy_real + BRL .cant_afford .price_is_rupees diff --git a/stats.asm b/stats.asm index 980d7515..1e8dec4e 100644 --- a/stats.asm +++ b/stats.asm @@ -265,6 +265,7 @@ CountChestKey: ; called by neighbor functions PHA : PHX LDA !MULTIWORLD_ITEM_PLAYER_ID : bne .end CPY #$24 : BEQ + ; small key for this dungeon - use $040C + CPY #$CE : BEQ + ; small key ring for this dungeon - use $040C CPY #$A0 : !BLT .checkKeyRing ; Ignore most items CPY #$AE : !BLT .dungeonKey ; Count dungeon small keys .checkKeyRing diff --git a/tables.asm b/tables.asm index 68b1ef55..f9e2f0b3 100644 --- a/tables.asm +++ b/tables.asm @@ -1442,7 +1442,7 @@ db $04 ;CB - Small Key Ring of Thieves' Town ;CC - Small Key Ring of Turtle Rock ;CD - Small Key Ring of Ganon's Tower -;CE - Reserved +;CE - Small Key Ring of Current Dungeon ;CF - Reserved ;================================================================================ ;;Residual Portal @@ -1966,13 +1966,13 @@ db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00 db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00 -; 0x186380 - 18638F -org $30E380 ; PC 0x186380 +; 0x186390 - 18639F +org $30E390 ; PC 0x186390 KeyRingQuantities: db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00 ;-------------------------------------------------------------------------------- -org $30E390 ; PC 0x186390 - 0x186399 +org $30E3A0 ; PC 0x1863A0 - 0x1863A9 BossPrize_ArmosKnights_Player: db #$00 BossPrize_Lanmolas_Player: @@ -1995,7 +1995,7 @@ BossPrize_Trinexx_Player: db #$00 ;-------------------------------------------------------------------------------- -; 0x18639A - 187FFF (unused) +; 0x1863AA - 187FFF (unused) ;-------------------------------------------------------------------------------- org $30EFFF ; PC 0x186FFF diff --git a/utilities.asm b/utilities.asm index 5bb76a71..21bc91ca 100644 --- a/utilities.asm +++ b/utilities.asm @@ -382,8 +382,8 @@ IsNarrowSprite: LDX.b #$00 ; set index counter to 0 ;---- - - CPX.b #$34 : !BGE .false ; finish if we've done the whole list - CMP.w .smallSprites, X : BNE + ; skip to next if we don't match + CPX.b #$24 : !BGE .false ; finish if we've done the whole list + CMP.l .smallSprites, X : BNE + ; skip to next if we don't match ;-- SEC ; set true state BRA .done ; we're done @@ -405,9 +405,7 @@ RTL db $15, $18, $24, $2A, $34, $35, $36, $42 db $43, $45, $59, $A0, $A1, $A2, $A3, $A4 db $A5, $A6, $A7, $A8, $A9, $AA, $AB, $AC - db $AD, $AE, $AF, $B3, $C0, $C1, $C2, $C3 - db $C4, $C5, $C6, $C7, $C8, $C9, $CA, $CB - db $CC, $CD, $CE, $CF + db $AD, $AE, $AF, $B3 } ;-------------------------------------------------------------------------------- From 80f98c83abc5848cd04bc4763e318c9e41ea67b2 Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 30 Apr 2026 22:46:36 -0400 Subject: [PATCH 17/53] Fix Crystal Palettes! --- darkroomitems.asm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/darkroomitems.asm b/darkroomitems.asm index b435d341..7e302995 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -3,11 +3,16 @@ CheckReceivedItemPropertiesBeforeLoad: LDA $7F504C : BEQ + LDA $7F504D : TAX + + TXA + PHY + JSL.l MaybeLoadCrystalSpritePalette + PLY LDA $A0 : BEQ .normalCode LDA $7EC005 : BNE .lightOff .normalCode JSR .loadProperty PLX + CMP.b #$00 ; preserve vanilla BPL behavior by setting flags from the loaded property, not restored X RTL .lightOff From deb7f30a7d424b018dd8f1d4a3a37c9f61c3fb33 Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 30 Apr 2026 23:33:24 -0400 Subject: [PATCH 18/53] Fix Crystal shadow on Prize locations --- darkroomitems.asm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index 7e302995..96037827 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -75,11 +75,22 @@ MaybeLoadCrystalSpritePalette: CMP.b #$C0 : BCS .done .loadPalette - PHX + PHX : PHY + REP #$20 + LDA $00 : PHA + LDA $02 : PHA + SEP #$20 + LDA.b #$04 : STA $0AB1 LDA.b #$02 : STA $0AA9 JSL.l $1BED72 ; Palette_MiscSpr.justSP6 INC $15 + + REP #$20 + PLA : STA $02 + PLA : STA $00 + SEP #$20 + PLY PLX .done From 256e75eafef41c8b272c5c205a30ef3f229c6775 Mon Sep 17 00:00:00 2001 From: Alchav Date: Thu, 30 Apr 2026 23:38:39 -0400 Subject: [PATCH 19/53] Link once again holds items up --- LTTP_RND_GeneralBugfixes.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index cdd3110d..6cabfac3 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -187,7 +187,7 @@ Link_ReceiveItem_HandleCurrentDungeonKeyRing: .normalReceive LDA $02E9 BEQ .fromTextOrObject - CMP.b #$03 : BNE .fromChestOrSprite + CMP.b #$03 : BEQ .fromTextOrObject .fromChestOrSprite JML $0799F2 .fromTextOrObject From 7d0bb571164ec72b89e7899b38f7e26ff765e62e Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 15:40:10 -0400 Subject: [PATCH 20/53] Fix remaining prize x position issues --- darkroomitems.asm | 2 +- dungeondrops.asm | 120 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 106 insertions(+), 16 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index 96037827..59d15762 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -39,7 +39,7 @@ CheckReceivedItemPropertiesBeforeLoad: .loadProperty LDA $7F504C : BEQ .normalProperty TXA : CMP.b #$04 : BEQ .blueShield - CMP.b #$05 : BEQ .redShield + CMP.b #$05 : BEQ .blueShield CMP.b #$06 : BEQ .mirrorShield .normalProperty diff --git a/dungeondrops.asm b/dungeondrops.asm index 264682c1..6fe7b119 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -7,6 +7,7 @@ !BOSS_PRIZE_NARROW_SHADOW = "$7F504B" !BOSS_PRIZE_DRAW_ACTIVE = "$7F504C" !BOSS_PRIZE_DISPLAY_ITEM = "$7F504D" +!BOSS_PRIZE_X_OFFSET_APPLIED = "$7F504E" !ITEM_BUSY = "$7F5091" DropSafeDungeon: @@ -81,6 +82,7 @@ ClearBossPrizeContext: STA !BOSS_PRIZE_NARROW_SHADOW STA !BOSS_PRIZE_DRAW_ACTIVE STA !BOSS_PRIZE_DISPLAY_ITEM + STA !BOSS_PRIZE_X_OFFSET_APPLIED RTL ;-------------------------------------------------------------------------------- SpawnBossPrizeFallingItem: @@ -104,10 +106,19 @@ SpawnBossPrizeFallingItem: LDA.b #AddReceivedItemExpanded_item_graphics_indices>>16 : PHA : PLB LDA.w AddReceivedItemExpanded_item_graphics_indices, Y : STA $72 CMP.b #$FF : BEQ .invalidItem + TYA + CMP.b #$49 : BEQ .freestandingSwordItem + CMP.b #$01 : BEQ .freestandingSwordItem + CMP.b #$50 : BEQ .freestandingSwordItem + CMP.b #$02 : BEQ .freestandingSwordItem + CMP.b #$03 : BEQ .freestandingSwordItem + LDA $72 CMP.b #$20 : BEQ .shieldItem CMP.b #$2D : BEQ .shieldItem CMP.b #$2E : BNE .getItemTiles - .shieldItem + + .shieldItem + .freestandingSwordItem TYA JSL.l GetSpriteID STA $72 @@ -121,7 +132,7 @@ SpawnBossPrizeFallingItem: LDA $72 : CMP.b #$06 : BEQ .swordItem CMP.b #$18 : BNE .notSwordItem - .swordItem + .swordItem JSL.l BossPrizeDecompResolvedSwordGfx .notSwordItem PLB : PLX @@ -450,16 +461,21 @@ BossPrizeDrawPrep: LDA.b #$00 STA !BOSS_PRIZE_NARROW_SHADOW STA !BOSS_PRIZE_DRAW_ACTIVE + STA !BOSS_PRIZE_X_OFFSET_APPLIED LDA $0C4A, X : CMP.b #$29 : BNE .restore JSL.l BossPrizeContextMatchesRoom : BCC .restore JSL.l BossPrizeContextMatchesSlot : BCC .restore LDA.b #$01 : STA !BOSS_PRIZE_DRAW_ACTIVE - LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY - LDA.w AddReceivedItemExpanded_wide_item_flag, Y : BNE .restore + PHX + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAX + JSR.w BossPrizeLoadDisplayWideItemFlag + PLX + CMP.b #$00 : BEQ .narrowItem + JSR.w BossPrizeApplyDisplayXOffset + BRA .restore + +.narrowItem LDA.b #$01 : STA !BOSS_PRIZE_NARROW_SHADOW - REP #$20 - LDA $02 : CLC : ADC.w #$0008 : STA $02 - SEP #$20 .restore REP #$20 @@ -471,11 +487,13 @@ BossPrizeDrawPrep: ;-------------------------------------------------------------------------------- BossPrizeMilestoneShadowPrep: SEP #$20 + LDA !BOSS_PRIZE_X_OFFSET_APPLIED : BEQ .drawShadow + JSR.w BossPrizeUndoDisplayXOffset + +.drawShadow LDA !BOSS_PRIZE_NARROW_SHADOW : BEQ .prepShadowY LDX.b #$02 - REP #$20 - LDA $02 : SEC : SBC.w #$0008 : STA $02 - BRA .shadowYReady + BRA .prepShadowY .prepShadowY REP #$20 @@ -484,19 +502,90 @@ BossPrizeMilestoneShadowPrep: LDA $06 : CLC : ADC.w #$000C : STA $00 RTL ;-------------------------------------------------------------------------------- +BossPrizeApplyDisplayXOffset: + PHX : PHY + JSR.w BossPrizeLoadDisplayXOffset + BEQ .shiftRight + BRA .done + +.shiftRight + LDA.b #$01 : STA !BOSS_PRIZE_X_OFFSET_APPLIED + REP #$20 + LDA $02 : CLC : ADC.w #$0001 : STA $02 + SEP #$20 + +.done + PLY : PLX +RTS +;-------------------------------------------------------------------------------- +BossPrizeUndoDisplayXOffset: + PHX : PHY + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY + JSR.w BossPrizeLoadDisplayXOffset + BEQ .shiftLeft + BRA .done + +.shiftLeft + REP #$20 + LDA $02 : SEC : SBC.w #$0001 : STA $02 + SEP #$20 + +.done + PLY : PLX +RTS +;-------------------------------------------------------------------------------- +BossPrizeLoadDisplayWideItemFlag: + TXA + CMP.b #$49 : BEQ .wideSword + CMP.b #$01 : BEQ .wideSword + CMP.b #$50 : BEQ .wideSword + CMP.b #$02 : BEQ .wideSword + CMP.b #$03 : BEQ .wideSword + LDA.l AddReceivedItemExpanded_wide_item_flag, X + RTS + +.wideSword + LDA.b #$02 +RTS +;-------------------------------------------------------------------------------- +BossPrizeLoadDisplayXOffset: + TYA + CMP.b #$20 : BEQ .ignore + CMP.b #$04 : BCC .load + CMP.b #$07 : BCC .ignore + CMP.b #$37 : BCC .load + CMP.b #$3A : BCC .ignore + CMP.b #$B6 : BCC .load + CMP.b #$C0 : BCC .ignore + +.load + TAX + JSR.w BossPrizeLoadDisplayWideItemFlag : BEQ .ignore + LDA.l AddReceivedItemExpanded_x_offsets, X + RTS + +.ignore + LDA.b #$04 +RTS +;-------------------------------------------------------------------------------- BossPrizeShiftUpperItemTileAndLoadWideItemFlag: PHX : PHY LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .normalItem LDA !BOSS_PRIZE_DISPLAY_ITEM : TAX - LDA.l AddReceivedItemExpanded_wide_item_flag, X : CMP.b #$02 : BEQ .loadWideFlag + JSR.w BossPrizeLoadDisplayWideItemFlag : CMP.b #$02 : BEQ .done + .narrowItem TYA : ASL #2 : TAY LDA ($90), Y : CLC : ADC.b #$04 : STA ($90), Y + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAX BRA .loadWideFlag .normalItem .loadWideFlag LDA.l AddReceivedItemExpanded_wide_item_flag, X + BRA .done + +.done PLY : PLX RTL ;-------------------------------------------------------------------------------- @@ -504,13 +593,14 @@ BossPrizeLoadNarrowObject: PHX : PHY LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .normalItem LDA !BOSS_PRIZE_DISPLAY_ITEM : TAX - BRA .loadWideFlag + JSR.w BossPrizeLoadDisplayWideItemFlag + BRA .storeWideFlag .normalItem - TXA + LDA.l AddReceivedItemExpanded_wide_item_flag, X -.loadWideFlag - LDA.l AddReceivedItemExpanded_wide_item_flag, X : STA ($92), Y +.storeWideFlag + STA ($92), Y CMP.b #$02 : BEQ .done LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .done From daa5d16b9d07df48adca36f5dc517eaa25eec82d Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 15:53:19 -0400 Subject: [PATCH 21/53] Fix prize shield palettes --- darkroomitems.asm | 20 ++++++++++++++------ dungeondrops.asm | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/darkroomitems.asm b/darkroomitems.asm index 59d15762..32194c4a 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -38,26 +38,34 @@ CheckReceivedItemPropertiesBeforeLoad: .loadProperty LDA $7F504C : BEQ .normalProperty - TXA : CMP.b #$04 : BEQ .blueShield - CMP.b #$05 : BEQ .blueShield - CMP.b #$06 : BEQ .mirrorShield + TXA : CMP.b #$49 : BEQ .masterSword + CMP.b #$01 : BEQ .masterSword + CMP.b #$50 : BEQ .masterSword + CMP.b #$02 : BEQ .temperedSword + CMP.b #$03 : BEQ .goldenSword + CMP.b #$04 : BCC .normalProperty + CMP.b #$07 : BCC .shield .normalProperty LDA.l AddReceivedItemExpanded_properties, X ; Restore Rando Code RTS - .blueShield + .masterSword LDA.b #$02 RTS - .redShield + .temperedSword LDA.b #$01 RTS - .mirrorShield + .goldenSword LDA.b #$04 RTS + .shield + LDA.b #$05 + RTS + CrystalItemBehaviorCheck: LDA $0C5E, X : CMP.b #$20 : BNE .ordinaryItem LDA $0C54, X : CMP.b #$03 : BEQ .bossPrizeCrystal diff --git a/dungeondrops.asm b/dungeondrops.asm index 6fe7b119..42abdc17 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -118,6 +118,13 @@ SpawnBossPrizeFallingItem: CMP.b #$2E : BNE .getItemTiles .shieldItem + TYA + JSL.l GetSpriteID + STA $72 + JSL.l BossPrizeDecompResolvedShieldGfx + LDA $72 + BRA .getItemTiles + .freestandingSwordItem TYA JSL.l GetSpriteID @@ -201,6 +208,29 @@ BossPrizeDecompResolvedSwordGfx: PLP RTL ;-------------------------------------------------------------------------------- +BossPrizeDecompResolvedShieldGfx: + PHP + SEP #$20 + LDA $7EF35A : PHA + LDA !BOSS_PRIZE_DISPLAY_ITEM + CMP.b #$04 : BEQ .fighterShield + CMP.b #$05 : BEQ .redShield + LDA.b #$03 : BRA .loadShield + +.fighterShield + LDA.b #$01 : BRA .loadShield + +.redShield + LDA.b #$02 + +.loadShield + STA $7EF35A + JSL.l DecompShieldGfx + JSL.l Palette_Shield + PLA : STA $7EF35A + PLP +RTL +;-------------------------------------------------------------------------------- BossPrizeContextMatchesRoom: LDA BossPrizeShuffle : BEQ .mismatch LDA !BOSS_PRIZE_ACTIVE : BEQ .mismatch From 4be33d74f5dd59797676b517fbb46d41118c53b6 Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 16:15:23 -0400 Subject: [PATCH 22/53] The real x pos fix --- dungeondrops.asm | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index 42abdc17..7284d48d 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -534,6 +534,7 @@ RTL ;-------------------------------------------------------------------------------- BossPrizeApplyDisplayXOffset: PHX : PHY + LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY JSR.w BossPrizeLoadDisplayXOffset BEQ .shiftRight BRA .done @@ -580,15 +581,6 @@ RTS ;-------------------------------------------------------------------------------- BossPrizeLoadDisplayXOffset: TYA - CMP.b #$20 : BEQ .ignore - CMP.b #$04 : BCC .load - CMP.b #$07 : BCC .ignore - CMP.b #$37 : BCC .load - CMP.b #$3A : BCC .ignore - CMP.b #$B6 : BCC .load - CMP.b #$C0 : BCC .ignore - -.load TAX JSR.w BossPrizeLoadDisplayWideItemFlag : BEQ .ignore LDA.l AddReceivedItemExpanded_x_offsets, X From 08559d15e083f0823dd516a1f2da2c7af1b94c4b Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 17:12:59 -0400 Subject: [PATCH 23/53] Silver Arrows just use single arrow graphic, key rings take the silver arrows slot --- 2026items.bin | Bin 1536 -> 1536 bytes 2026items.gfx | Bin 1340 -> 1273 bytes newitems.asm | 13 +++++++++---- utilities.asm | 17 +++++++++++------ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/2026items.bin b/2026items.bin index 5742d0c0a2725dcf2f309f79a87b48209f70cc62..1e78f4ce097f3f6c9138dc0092e4b2d0a5e6d8c8 100644 GIT binary patch delta 58 zcmZqRY2aDFJoy8&`DAnE-IJA>B_|s&^FT4nWObIv$px$ilQ*y&n5@Vw4Hf5_ypS~> E0Q(0JqW}N^ delta 85 zcmZqRY2aDFJkh{t5)0R48|H13nV3x{tFuHJh;W#5lyk%@)N9mpcr!3C$k@k~)zx`3 nG%y@vc+c=3jN=%17#iGGny%a%#4~vV%Yn%aEC!PouqFTi`XL$( diff --git a/2026items.gfx b/2026items.gfx index 9657ccaec720f9d293c9a00c03b544146fc7cc54..a62c2105c280b4b3b85881f51eefd10cc42119d0 100644 GIT binary patch delta 79 zcmV-V0I>hO3i%1Ji~<7zu}+gW126$AlcxfZ13v&ZlV}4?1rG3j{``}!1T6;(ARho9 l2p^O21F9Dhz5xCJ{{TJ!3;@84lA_YVG7LWeFaVR?1YZnB8aDs{ delta 145 zcmey#xrb{*50f; Date: Fri, 1 May 2026 17:22:55 -0400 Subject: [PATCH 24/53] Add comments --- LTTP_RND_GeneralBugfixes.asm | 5 +++++ darkroomitems.asm | 8 +++++++ dialog.asm | 1 + dungeondrops.asm | 42 ++++++++++++++++++++++++++++++++++++ events.asm | 2 ++ heartpieces.asm | 2 ++ hooks.asm | 11 +++++++++- inventory.asm | 2 ++ keydropshuffle.asm | 2 ++ multiworld.asm | 2 ++ newitems.asm | 9 ++++++++ shopkeeper.asm | 2 ++ stats.asm | 2 ++ tables.asm | 2 ++ utilities.asm | 5 +++++ 15 files changed, 96 insertions(+), 1 deletion(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index 6cabfac3..b0851e31 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -175,6 +175,8 @@ incsrc init.asm org $A48000 ; code bank - PUT NEW CODE HERE +; Current-dungeon key rings are inventory-only rewards. They should add the +; dungeon's key quantity and update HUD/stats without the normal item fanfare. Link_ReceiveItem_HandleCurrentDungeonKeyRing: CPY.b #$CE : BNE .normalReceive LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE .normalReceive @@ -193,6 +195,8 @@ Link_ReceiveItem_HandleCurrentDungeonKeyRing: .fromTextOrObject JML $0799C8 +; Grant the current dungeon's key ring directly because the generic receive-item +; path only handles one concrete item ID at a time. ReceiveCurrentDungeonKeyRingQuiet: PHX : PHY LDA $040C : CMP.b #$FF : BEQ .cleanup @@ -302,6 +306,7 @@ org $31A800 GFX_New_Items: ;incbin newitems.gfx ;incbin eventitems.gfx ; *EVENT* +; 2026 item graphics include the key ring art and keep within the original slot. incbin 2026items.gfx warnpc $31B000 diff --git a/darkroomitems.asm b/darkroomitems.asm index 32194c4a..5c01ee59 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -1,3 +1,5 @@ +; Load received-item palette properties, using the boss-prize display item when +; the receive animation is showing a substituted/progressive prize. CheckReceivedItemPropertiesBeforeLoad: PHX LDA $7F504C : BEQ + @@ -36,6 +38,8 @@ CheckReceivedItemPropertiesBeforeLoad: LDA #$00 RTL + ; Swords and shields use inventory-dependent palette properties, so boss + ; prizes need the resolved display item rather than the original item ID. .loadProperty LDA $7F504C : BEQ .normalProperty TXA : CMP.b #$49 : BEQ .masterSword @@ -66,6 +70,8 @@ CheckReceivedItemPropertiesBeforeLoad: LDA.b #$05 RTS +; Boss-prize crystals are spawned as ordinary receive-item objects, but still +; need the crystal-specific fanfare/state path once they are collected. CrystalItemBehaviorCheck: LDA $0C5E, X : CMP.b #$20 : BNE .ordinaryItem LDA $0C54, X : CMP.b #$03 : BEQ .bossPrizeCrystal @@ -76,6 +82,8 @@ CrystalItemBehaviorCheck: .bossPrizeCrystal JML.l CrystalSpecialBehaviorContinue +; Dynamic/freestanding crystals need SP6 loaded before draw, unlike most items +; whose palettes are already present in the normal received-item path. MaybeLoadCrystalSpritePalette: PHA CMP.b #$20 : BEQ .loadPalette diff --git a/dialog.asm b/dialog.asm index 98d152ba..3dbe4b1f 100644 --- a/dialog.asm +++ b/dialog.asm @@ -185,6 +185,7 @@ FreeDungeonItemNotice: PLA : AND.b #$0F : STA $7F5020 : LDA.b #$0F : !SUB $7F5020 : PHA LDA #$01 : STA $7F5010 ; set up a flip for small keys BRA .dungeon + ; Key rings share the small-key notice flag but use their own text prefix. + : LDA.l FreeItemText : AND.b #$01 : CMP.b #$01 : BNE + ; show message for dungeon key ring LDA !ITEM_TEMPORARY : AND.b #$F0 : CMP.b #$C0 : BNE + ; key ring of... LDA !ITEM_TEMPORARY : CMP.b #$CE : !BLT .keyRingNotice diff --git a/dungeondrops.asm b/dungeondrops.asm index 7284d48d..2233941e 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -10,12 +10,16 @@ !BOSS_PRIZE_X_OFFSET_APPLIED = "$7F504E" !ITEM_BUSY = "$7F5091" +; Boss prize shuffle tracks one spawned receive-item ancilla so the normal +; receive-item draw and collection code can identify the shuffled prize path. DropSafeDungeon: LDA $040C : CMP #$08 : BEQ + LDA $01C6FC, X : JSL Sprite_SpawnFallingItem + RTL ;-------------------------------------------------------------------------------- +; Replace the vanilla boss room tag handler. In shuffle mode this spawns the +; configured item as a falling receive-item object instead of the vanilla prize. BossPrizeRoomTag: LDA BossPrizeShuffle : BEQ .vanilla JSL.l CheckIfBossRoom : BCC .vanilla @@ -64,6 +68,7 @@ BossPrizeRoomTag: .heartContainerStillExists RTL ;-------------------------------------------------------------------------------- +; Mark the current room as owning an active shuffled boss prize. SetBossPrizeContext: LDA.b #$01 : STA !BOSS_PRIZE_ACTIVE PHP @@ -72,6 +77,7 @@ SetBossPrizeContext: PLP RTL ;-------------------------------------------------------------------------------- +; Clear all state used to recognize and draw the shuffled boss prize ancilla. ClearBossPrizeContext: LDA.b #$00 STA !BOSS_PRIZE_ACTIVE @@ -85,6 +91,8 @@ ClearBossPrizeContext: STA !BOSS_PRIZE_X_OFFSET_APPLIED RTL ;-------------------------------------------------------------------------------- +; Spawn the shuffled prize with vanilla receive-item behavior and preload the +; display graphics for the resolved item that Link will actually show. SpawnBossPrizeFallingItem: PHA JSL.l BossPrizeResolveItem @@ -102,6 +110,8 @@ SpawnBossPrizeFallingItem: PLA : STA $0C5E, X LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY + ; Swords and shields need their freestanding/decompressed graphics, while + ; other items can use the normal received-item graphics index directly. PHX : PHB LDA.b #AddReceivedItemExpanded_item_graphics_indices>>16 : PHA : PLB LDA.w AddReceivedItemExpanded_item_graphics_indices, Y : STA $72 @@ -180,6 +190,7 @@ SpawnBossPrizeFallingItem: CLC RTL ;-------------------------------------------------------------------------------- +; Temporarily present the resolved sword level to the vanilla sword decompressor. BossPrizeDecompResolvedSwordGfx: PHP SEP #$20 @@ -208,6 +219,7 @@ BossPrizeDecompResolvedSwordGfx: PLP RTL ;-------------------------------------------------------------------------------- +; Temporarily present the resolved shield level to the vanilla shield decompressor. BossPrizeDecompResolvedShieldGfx: PHP SEP #$20 @@ -231,6 +243,7 @@ BossPrizeDecompResolvedShieldGfx: PLP RTL ;-------------------------------------------------------------------------------- +; True when the current room is the room that spawned the active shuffled prize. BossPrizeContextMatchesRoom: LDA BossPrizeShuffle : BEQ .mismatch LDA !BOSS_PRIZE_ACTIVE : BEQ .mismatch @@ -250,6 +263,7 @@ BossPrizeContextMatchesRoom: CLC RTL ;-------------------------------------------------------------------------------- +; True when X is the receive-item ancilla slot used by the shuffled prize. BossPrizeContextMatchesSlot: LDA !BOSS_PRIZE_SLOT : CMP.b #$FF : BEQ .mismatch TXA : CMP !BOSS_PRIZE_SLOT : BNE .mismatch @@ -260,6 +274,7 @@ BossPrizeContextMatchesSlot: CLC RTL ;-------------------------------------------------------------------------------- +; True while Link is receiving the tracked shuffled boss prize. BossPrizeReceiveContextMatches: LDA $02E9 : CMP.b #$03 : BNE .mismatch JSL.l BossPrizeContextMatchesRoom : BCC .mismatch @@ -271,6 +286,7 @@ BossPrizeReceiveContextMatches: CLC RTL ;-------------------------------------------------------------------------------- +; True while the tracked boss-prize ancilla is still being animated. BossPrizeObjectContextMatches: LDA $0C54, X : CMP.b #$03 : BNE .mismatch JSL.l BossPrizeContextMatchesRoom : BCC .mismatch @@ -282,12 +298,14 @@ BossPrizeObjectContextMatches: CLC RTL ;-------------------------------------------------------------------------------- +; Apply the configured multiworld recipient before the item is granted. BossPrizeApplyItemPlayer: JSL.l BossPrizeReceiveContextMatches : BCC .done JSL.l BossPrizeGetPlayer : STA !MULTIWORLD_ITEM_PLAYER_ID .done RTL ;-------------------------------------------------------------------------------- +; Non-pendant shuffled prizes still need the victory fanfare before warping out. BossPrizeItemNeedsVictoryFanfare: JSL.l BossPrizeObjectContextMatches : BCC .noFanfare SEC @@ -297,6 +315,7 @@ BossPrizeItemNeedsVictoryFanfare: CLC RTL ;-------------------------------------------------------------------------------- +; Extend the pendant music wait to any shuffled boss prize that uses the victory fanfare. BossPrizePendantWaitCheck: LDA $0C5E, X : CMP.b #$37 : BEQ .waitForMusic CMP.b #$38 : BEQ .waitForMusic @@ -310,6 +329,8 @@ BossPrizePendantWaitCheck: .dontWaitForMusic JML.l PendantFanfareDone ;-------------------------------------------------------------------------------- +; Finish a shuffled boss prize by marking dungeon completion, showing deferred +; text if needed, then routing to the dungeon-exit path. HandleBossPrizeObjectFinished: JSL.l BossPrizeObjectContextMatches : BCC .normalObjectFinished JSL.l MarkBossPrizeDungeonCompletion @@ -337,6 +358,7 @@ HandleBossPrizeObjectFinished: STZ $0FC1 JML.l Ancilla_ReceiveItem_objectFinished+6 ;-------------------------------------------------------------------------------- +; Move the item object offscreen while deferred text owns the receive-item state. HideBossPrizeItemVisual: PHP REP #$20 @@ -355,6 +377,7 @@ HideBossPrizeItemVisual: PLP RTL ;-------------------------------------------------------------------------------- +; Record shuffled boss-prize completion separately from vanilla pendant/crystal bits. MarkBossPrizeDungeonCompletion: LDA $040C CMP #$FF : BEQ .done @@ -370,6 +393,7 @@ MarkBossPrizeDungeonCompletion: .done RTL +; Check the shuffled boss-prize completion bit for the current dungeon. BossPrizeDungeonCompletionMatches: LDA $040C CMP #$FF : BEQ .mismatch @@ -391,6 +415,7 @@ RTL SEC RTL +; Convert a dungeon index into a single-bit mask for completion storage. BossPrizeValueShift: PHX TAX : LDA.b #$01 @@ -403,6 +428,7 @@ BossPrizeValueShift: PLX RTS ;-------------------------------------------------------------------------------- +; Resolve progressive/substituted local prizes for display before the item is granted. BossPrizeResolveItem: PHA JSL.l BossPrizeGetPlayer : CMP.b #$00 : BEQ .local @@ -487,6 +513,7 @@ BossPrizeResolveItem: .displayResolved RTL ;-------------------------------------------------------------------------------- +; Prepare receive-item drawing to use the resolved boss-prize display item. BossPrizeDrawPrep: LDA.b #$00 STA !BOSS_PRIZE_NARROW_SHADOW @@ -515,6 +542,7 @@ BossPrizeDrawPrep: LDA $0BF0, X : STA $74 JML.l BossPrizeDrawContinue ;-------------------------------------------------------------------------------- +; Undo any boss-prize X adjustment before the milestone-item shadow is drawn. BossPrizeMilestoneShadowPrep: SEP #$20 LDA !BOSS_PRIZE_X_OFFSET_APPLIED : BEQ .drawShadow @@ -532,6 +560,7 @@ BossPrizeMilestoneShadowPrep: LDA $06 : CLC : ADC.w #$000C : STA $00 RTL ;-------------------------------------------------------------------------------- +; Match vanilla receive-item X centering for the resolved boss-prize item. BossPrizeApplyDisplayXOffset: PHX : PHY LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY @@ -549,6 +578,7 @@ BossPrizeApplyDisplayXOffset: PLY : PLX RTS ;-------------------------------------------------------------------------------- +; Restore the draw X position after the boss-prize item body is drawn. BossPrizeUndoDisplayXOffset: PHX : PHY LDA !BOSS_PRIZE_DISPLAY_ITEM : TAY @@ -565,6 +595,7 @@ BossPrizeUndoDisplayXOffset: PLY : PLX RTS ;-------------------------------------------------------------------------------- +; Treat freestanding swords as wide sprites even though their item IDs bypass the table. BossPrizeLoadDisplayWideItemFlag: TXA CMP.b #$49 : BEQ .wideSword @@ -579,6 +610,7 @@ BossPrizeLoadDisplayWideItemFlag: LDA.b #$02 RTS ;-------------------------------------------------------------------------------- +; Load the display item's X offset, ignoring offsets for narrow item layouts. BossPrizeLoadDisplayXOffset: TYA TAX @@ -590,6 +622,7 @@ BossPrizeLoadDisplayXOffset: LDA.b #$04 RTS ;-------------------------------------------------------------------------------- +; Use the resolved display item when the upper tile of a boss-prize object is drawn. BossPrizeShiftUpperItemTileAndLoadWideItemFlag: PHX : PHY LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .normalItem @@ -611,6 +644,7 @@ BossPrizeShiftUpperItemTileAndLoadWideItemFlag: PLY : PLX RTL ;-------------------------------------------------------------------------------- +; Store the resolved display item's narrow/wide flag into the OAM size buffer. BossPrizeLoadNarrowObject: PHX : PHY LDA !BOSS_PRIZE_DRAW_ACTIVE : BEQ .normalItem @@ -633,6 +667,7 @@ BossPrizeLoadNarrowObject: PLY : PLX RTL ;-------------------------------------------------------------------------------- +; Boss-prize swords should use the sprite/freestanding source path, not the held-up source. BossPrizeMasterSwordSourceCheck: LDA $02E9 : CMP.b #$02 : BEQ .spriteSource JSL.l BossPrizeReceiveContextMatches : BCS .spriteSource @@ -641,6 +676,7 @@ BossPrizeMasterSwordSourceCheck: .spriteSource JML.l BossPrizeMasterSwordFromSprite ;-------------------------------------------------------------------------------- +; Show "free dungeon item" text for local shuffled boss prizes after substitution. BossPrizeQueueFreeItemNotice: JSL.l BossPrizeReceiveContextMatches : BCC .done JSL.l BossPrizeGetPlayer : CMP.b #$00 : BNE .done @@ -648,6 +684,7 @@ BossPrizeQueueFreeItemNotice: .done RTL ;-------------------------------------------------------------------------------- +; Avoid spawning the prize while another receive-item ancilla is still active. BossPrizeSpawnReady: LDX.b #$09 @@ -661,6 +698,7 @@ BossPrizeSpawnReady: CLC RTL ;-------------------------------------------------------------------------------- +; Route boss-prize receive states through object/text handling and wait for text close. BossPrizeReceiveDispatch: LDA $0C54, X : BEQ .fromTextOrObject CMP.b #$03 : BEQ .fromTextOrObject @@ -687,6 +725,7 @@ BossPrizeReceiveDispatch: LDA.b #$01 : STA $0FC1 JML.l Ancilla_ReceiveItem_return ;-------------------------------------------------------------------------------- +; Ordinary pendant/crystal item IDs collected outside boss rooms still set vanilla bits. MaybeSetOrdinaryBossPrizeBits: CMP.b #$B6 : BNE + LDA $7EF374 : ORA.b #$04 : STA $7EF374 @@ -722,6 +761,7 @@ MaybeSetOrdinaryBossPrizeBits: CLC RTL ;-------------------------------------------------------------------------------- +; Count ordinary pendant/crystal item IDs for inventory and stats displays. MaybeIncrementOrdinaryBossPrizeCounts: CPY.b #$B6 : BCC .miss CPY.b #$B9 : BCS .checkCrystals @@ -743,6 +783,7 @@ MaybeIncrementOrdinaryBossPrizeCounts: CLC RTL ;-------------------------------------------------------------------------------- +; Map the current boss room to its configured shuffled prize item. LoadBossPrizeRoomValue: PHP REP #$20 ; set 16-bit accumulator @@ -785,6 +826,7 @@ LoadBossPrizeRoomValue: PLP RTL ;-------------------------------------------------------------------------------- +; Map the current boss room to the configured multiworld recipient. BossPrizeGetPlayer: PHP REP #$20 ; set 16-bit accumulator diff --git a/events.asm b/events.asm index bba44780..a0d4de91 100644 --- a/events.asm +++ b/events.asm @@ -241,6 +241,8 @@ PostItemAnimation: LDA.b #$00 : STA !ITEM_BUSY ; mark item as finished LDA $7F509F : BEQ + + ; Boss-prize collection may defer text until its custom finish path, so + ; leave the message queued while the boss-prize receive context is active. JSL.l BossPrizeReceiveContextMatches : BCS + STZ $1CF0 : STZ $1CF1 ; reset decompression buffer JSL.l Main_ShowTextMessage_Alt diff --git a/heartpieces.asm b/heartpieces.asm index 80baa865..6f0651e9 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -112,6 +112,8 @@ NormalItemSkipSound: LDA $0C5E, X ; thing we wrote over PHA + ; Shuffled boss prizes keep the victory fanfare even when the prize is not + ; one of the vanilla pendant/crystal item IDs. JSL.l BossPrizeItemNeedsVictoryFanfare : BCC + PLA JSL Sound_SetSfxPanWithPlayerCoords diff --git a/hooks.asm b/hooks.asm index 2bcd63d0..aea60f9d 100755 --- a/hooks.asm +++ b/hooks.asm @@ -900,6 +900,7 @@ LDA.w AddReceivedItemExpanded_item_masks, X org $098769 ; 48769 - ancilla_init.asm:1005 (LDA .item_graphics_indices, Y) LDA.w AddReceivedItemExpanded_item_graphics_indices, Y +; Let expanded graphics IDs use the variable animated-sprite tile loader. org $09878C ; 4878C - ancilla_init.asm:1028 (JSL GetAnimatedSpriteTile.variable) JSL.l GetAnimatedSpriteTile_variable @@ -919,12 +920,14 @@ LDA.w AddReceivedItemExpanded_x_offsets, Y org $08C6C8 ; 446C8 - ancilla_receive_item.asm:538 (LDA AddReceiveItem.properties, X) JSL CheckReceivedItemPropertiesBeforeLoad +; Boss-prize items draw with the resolved display item, not always the stored item ID. org $08C6B4 ; 446B4 - ancilla_receive_item.asm:520 alternate draw entry (PHX : LDA $0BF0, X : STA $74) JML.l BossPrizeDrawPrep NOP #2 org $08C6BA BossPrizeDrawContinue: +; Route shuffled boss-prize swords through the freestanding/sprite source path. org $0987BB ; 487BB - ancilla_init.asm (LDA $02E9 : CMP.b #$02 : BEQ .masterSwordFromSprite) JML.l BossPrizeMasterSwordSourceCheck NOP #3 @@ -942,6 +945,7 @@ JSL CheckReceivedItemPropertiesBeforeLoad org $08C70F ; 4470F - ancilla_receive_item.asm : 582 - (LDA.b #$00 : STA ($92), Y) JSL.l LoadNarrowObject +; Boss-prize narrow items need the shadow position adjusted after the item body. org $08CDF3 ; 44DF3 - ancilla_milestone_item.asm:239 (REP #$20 : LDA $06 : ADD.w #$000C : STA $00) JSL.l BossPrizeMilestoneShadowPrep NOP #6 @@ -1022,7 +1026,7 @@ JSL.l LockAgahnimDoors : BNE Overworld_Entrance_BRANCH_EPSILON : NOP #6 org $1BBCC1 ; <- DBCC1 - Bank1B.asm : 223 (LDA $0F8004, X : AND.w #$01FF : STA $00) Overworld_Entrance_BRANCH_EPSILON: ; go here to lock doors ;-------------------------------------------------------------------------------- -; -- HOOK THIS LATER TO FUCK WITH BOSS DROPS -- +; Replace the boss-room tag so shuffled prizes can spawn ordinary item IDs. org $01C709 ; <- C709 - Bank01.asm : 10347 JSL.l BossPrizeRoomTag RTS @@ -1577,6 +1581,7 @@ org $08C421 ; <- AD4021 F005 - ancilla_receive_item.asm:108 (LDA $2140 : BEQ .wa JML PendantFanfareWait : NOP PendantFanfareContinue: +; Non-pendant shuffled boss prizes still wait for victory music before finishing. org $08C412 ; <- BD5E0C C937 F008 - ancilla_receive_item.asm:101 (LDA $0C5E, X : CMP.b #$37 : BEQ .isPendant) JML.l BossPrizePendantWaitCheck NOP #11 @@ -1584,6 +1589,7 @@ NOP #11 org $08C42B PendantFanfareDone: +; Crystals spawned by boss-prize shuffle should use the crystal-special branch. org $08C61D ; <- BD5E0C C920 - ancilla_receive_item.asm:435 (LDA $0C5E, X : CMP.b #$20) JML.l CrystalItemBehaviorCheck NOP @@ -2056,6 +2062,7 @@ org $08C45F ; <- 4445F - ancilla_recieve_item.asm:157 (STZ $02E9 : LDA $0C5E, X) Ancilla_ReceiveItem_optimus: JML.l PostItemAnimation : NOP #2 +; Split receive-item dispatch so boss-prize text/object states can be handled. org $08C3D0 ; <- 443D0 - ancilla_receive_item.asm:62 (LDA $0C54, X) JML.l BossPrizeReceiveDispatch NOP #8 @@ -2066,6 +2073,7 @@ Ancilla_ReceiveItem_return: org $08C539 Ancilla_ReceiveItem_fromChestOrSprite: +; Finish shuffled boss prizes by marking completion and starting the dungeon exit. org $08C505 ; <- 44505 - ancilla_receive_item.asm:256 (STZ $0C4A, X : STZ $0FC1) JML.l HandleBossPrizeObjectFinished NOP #2 @@ -2239,6 +2247,7 @@ BCC Link_ReceiveItem_notHeartContainer org $0799BA ; 399BA - Bank07.asm:4070 (LDA.b #$60 : STA $02D9) Link_ReceiveItem_notHeartContainer: ;-------------------------------------------------------------------------------- +; Current-dungeon key rings are granted quietly by a custom receive-item branch. org $0799BF ; 399BF - Bank07.asm:4072 (LDA $02E9 : BEQ .fromTextOrObject) JML.l Link_ReceiveItem_HandleCurrentDungeonKeyRing NOP #5 diff --git a/inventory.asm b/inventory.asm index 9907262b..c37eef7c 100644 --- a/inventory.asm +++ b/inventory.asm @@ -466,6 +466,7 @@ AddInventory: JSR .incrementPendant JSR .setDungeonCompletion BRL .done + ; Shuffled boss prizes use ordinary item IDs and still need pendant/crystal counts. + JSL.l MaybeIncrementOrdinaryBossPrizeCounts : BCC + BRL .done + @@ -547,6 +548,7 @@ AddInventory: CPY.b #$B0 : !BGE + JSR .incrementKey BRL .done + ; Key rings count as key inventory checks for the owning dungeon. + CPY.b #$C0 : !BLT + ; Items $C0 - $CE - Key Rings CPY.b #$CF : !BGE + JSR .incrementKey diff --git a/keydropshuffle.asm b/keydropshuffle.asm index acea84cd..9edd66e8 100644 --- a/keydropshuffle.asm +++ b/keydropshuffle.asm @@ -161,6 +161,8 @@ KeyGet: + cmp #$af : beq - ; universal key cmp #$24 : beq - ; small key for this dungeon cmp #$CE : bne + ; small key ring for this dungeon + ; Current-dungeon key rings add the configured quantity to the + ; saved key count before the normal key pickup returns. lda.l KeyRingQuantities, x : beq - clc : adc $02, S : dec sta $02, S diff --git a/multiworld.asm b/multiworld.asm index 6a5f73e2..446c32f7 100644 --- a/multiworld.asm +++ b/multiworld.asm @@ -136,6 +136,8 @@ GetMultiworldItem: + PLA + ; The added current-dungeon key ring cases make some branches exceed 8-bit + ; range, so near labels trampoline to the original key handling blocks. BRA .checkCurrentDungeonKey .thisdungeon_near BRL .thisdungeon diff --git a/newitems.asm b/newitems.asm index ea266de4..7af81afb 100644 --- a/newitems.asm +++ b/newitems.asm @@ -425,6 +425,8 @@ AddReceivedItemExpandedGetItem: + CMP.b #$C0 : !BLT + : CMP.b #$D0 : !BGE + ; Key Ring AND #$0F : TAX .keyRingCount + ; Key rings add the configured quantity for their dungeon and mirror the + ; HC/Sewers shared key count behavior used by single keys. LDA.l KeyRingQuantities, X : BEQ .keyRingDone PHA CLC : ADC $7EF37C, X : STA $7EF37C, X @@ -496,6 +498,8 @@ RTL !SINGLE_INDEX_BITMASK_TEMP = "$7F5022" !LOCK_IN = "$7F5090" !ITEM_BUSY = "$7F5091" +; Received-item graphics IDs are separate from dynamic ground-sprite IDs. +; Key rings reuse the former Silver Arrow slot; Silver Arrows use single-arrow art. !SINGLE_ARROW_RECEIVED_ITEM_GFX = $33 !KEY_RING_RECEIVED_ITEM_GFX = $41 ;2B:Bottle Already Filled w/ Red Potion @@ -507,6 +511,8 @@ RTL AddReceivedItemExpanded: { PHA : PHX + ; Boss prizes may be remote items, so set the recipient before normal + ; local/remote inventory handling runs. JSL.l BossPrizeApplyItemPlayer LDA RemoteItems : BEQ + : LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + LDA $02E9 : BEQ ++ : CMP #$03 : BNE +++ : ++ @@ -529,6 +535,8 @@ AddReceivedItemExpanded: JSR IncrementItemCounters + + ; Boss-prize display items are resolved before collection, so queue any + ; free-dungeon-item notice after substitution. JSL.l BossPrizeQueueFreeItemNotice LDA $02D8 ; Item Value @@ -1228,6 +1236,7 @@ AttemptItemSubstitution: PLA : PLX RTS ;-------------------------------------------------------------------------------- +; Long-call wrapper for boss-prize code that lives outside this bank. AttemptItemSubstitutionLong: JSR AttemptItemSubstitution RTL diff --git a/shopkeeper.asm b/shopkeeper.asm index 680235d9..99b08af6 100644 --- a/shopkeeper.asm +++ b/shopkeeper.asm @@ -682,6 +682,8 @@ Shopkeeper_BuyItem: LDA !SHOP_TYPE : AND.b #$80 : BEQ + : BRL .buy : + ; don't charge if this is a take-any .custom_price + ; High bit marks non-rupee prices; split that path so rupee prices keep + ; the vanilla 16-bit rupee comparison below. LDA !SHOP_INVENTORY+2, X : AND.b #$80 : BNE .price_is_not_rupees ; i honestly can't think of a better way to do this block because i haven't done asm in like 8 months JMP .price_is_rupees .price_is_not_rupees diff --git a/stats.asm b/stats.asm index 1e8dec4e..a87593ba 100644 --- a/stats.asm +++ b/stats.asm @@ -269,6 +269,7 @@ CountChestKey: ; called by neighbor functions CPY #$A0 : !BLT .checkKeyRing ; Ignore most items CPY #$AE : !BLT .dungeonKey ; Count dungeon small keys .checkKeyRing + ; Dungeon-specific key rings count as key checks for the owning dungeon. CPY #$C0 : !BLT .end CPY #$CE : !BGE .end ; Ignore reserved key ring slots .dungeonKey @@ -297,6 +298,7 @@ CountBonkItem: ; called from GetBonkItem in bookofmudora.asm CMP #$A0 : !BLT .checkKeyRing CMP #$AE : !BLT .count .checkKeyRing + ; Bonk/dig style key drops can also resolve to key rings. CMP #$C0 : !BLT + CMP #$CE : !BGE + .count diff --git a/tables.asm b/tables.asm index f9e2f0b3..4230cba1 100644 --- a/tables.asm +++ b/tables.asm @@ -1968,11 +1968,13 @@ db #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, #$00, ; 0x186390 - 18639F org $30E390 ; PC 0x186390 +; Number of small keys awarded by each dungeon key ring, indexed by dungeon ID. KeyRingQuantities: db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00 ;-------------------------------------------------------------------------------- org $30E3A0 ; PC 0x1863A0 - 0x1863A9 +; Multiworld player IDs for each shuffled boss prize, indexed in boss-room order. BossPrize_ArmosKnights_Player: db #$00 BossPrize_Lanmolas_Player: diff --git a/utilities.asm b/utilities.asm index 47cf2bc2..72e95238 100644 --- a/utilities.asm +++ b/utilities.asm @@ -3,6 +3,8 @@ ;================================================================================ !PROGRESSIVE_SHIELD = "$7EF416" ; ss-- ---- !BEE_TRAP_DISGUISE = "$7EF4DA" +; Dynamic ground-sprite graphics IDs. This table is not the same ID space as +; received/held-up item graphics. !SINGLE_ARROW_SPRITE_GFX = $33 !KEY_RING_SPRITE_GFX = $41 ;-------------------------------------------------------------------------------- @@ -176,6 +178,7 @@ RTL db $49, $23, $23, $23, $28, $28, $28, $28, $28, $28, $28 ; Unused, Pendants, Crystals ;Cx + ; Key rings use the dynamic slot where the Silver Arrow graphic is stored. db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX ; Key Ring db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX @@ -494,6 +497,7 @@ RTS ;-------------------------------------------------------------------------------- DrawDynamicTile: JSR PrepDrawRemoteItemSprite + ; Crystals can appear as ordinary ground sprites when boss prizes shuffle. JSL.l MaybeLoadCrystalSpritePalette JSL.l IsNarrowSprite : BCS .narrow @@ -526,6 +530,7 @@ RTL ;-------------------------------------------------------------------------------- DrawDynamicTileNoShadow: JSR PrepDrawRemoteItemSprite + ; Shadowless dynamic draws need the same crystal palette preload. JSL.l MaybeLoadCrystalSpritePalette JSL.l IsNarrowSprite : BCS .narrow From 0fcae34a056ab23f6d4549c66d8e2d8b43d970b1 Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 17:24:53 -0400 Subject: [PATCH 25/53] Revert build.py for now --- build.py | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/build.py b/build.py index 718f187a..06a0eab2 100644 --- a/build.py +++ b/build.py @@ -7,8 +7,6 @@ getprints as asar_prints, getwarnings as asar_warnings JAP10HASH = '03a63945398191337e896e5771f77173' -MAX_ERRORS_TO_PRINT = 100 -MAX_WARNINGS_TO_PRINT = 50 def int16_as_bytes(value): @@ -50,19 +48,6 @@ def local_path(path): def generate_patch(baserombytes: bytes, rom: bytes) -> bytes: return bsdiff4.diff(bytes(baserombytes), rom) - -def print_messages(label, messages, limit): - print(f"\n{label}: {len(messages)}") - for message in messages[:limit]: - print(message) - remaining = len(messages) - limit - if remaining > 0: - print(f"... omitted {remaining} additional {label.lower()}") - - -def is_deprecation_warning(message): - return "DEPRECATION NOTIFICATION" in message - if __name__ == '__main__': try: asar_init() @@ -100,10 +85,13 @@ def is_deprecation_warning(message): f.write(generate_patch(old_rom_data, new_rom_data)) else: errors = asar_errors() - print_messages("Errors", errors, MAX_ERRORS_TO_PRINT) - warnings = [warning for warning in asar_warnings() if not is_deprecation_warning(warning)] - if warnings: - print_messages("Warnings", warnings, MAX_WARNINGS_TO_PRINT) + print("\nErrors: " + str(len(errors))) + for error in errors: + print(error) + warnings = asar_warnings() + print("\nWarnings: " + str(len(warnings))) + for w in warnings: + print(w) asar_close() except: From 022baf93711572d88f8661a3a9f74d440d65bc06 Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 17:47:10 -0400 Subject: [PATCH 26/53] Fix trap item graphics on prize location --- dungeondrops.asm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dungeondrops.asm b/dungeondrops.asm index 2233941e..58754260 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -96,6 +96,7 @@ RTL SpawnBossPrizeFallingItem: PHA JSL.l BossPrizeResolveItem + JSL.l BossPrizeResolvePrizeLocationDisplayItem STA !BOSS_PRIZE_DISPLAY_ITEM PLA : PHA @@ -513,6 +514,24 @@ BossPrizeResolveItem: .displayResolved RTL ;-------------------------------------------------------------------------------- +; Boss-prize Null/trap items use the blank received-item graphic. Show a random +; ordinary item graphic at the prize location while keeping the real item ID. +BossPrizeResolvePrizeLocationDisplayItem: + PHA : PHY : PHB + TAY + LDA.b #AddReceivedItemExpanded_item_graphics_indices>>16 : PHA : PLB + LDA.w AddReceivedItemExpanded_item_graphics_indices, Y + CMP.b #$47 : BEQ .randomDisguise + PLB : PLY : PLA +RTL + +.randomDisguise + PLB : PLY : PLA + JSL.l GetRandomInt : AND.b #$3F + BNE + : LDA.b #$49 : + + CMP.b #$26 : BNE + : LDA.b #$6A : + +RTL +;-------------------------------------------------------------------------------- ; Prepare receive-item drawing to use the resolved boss-prize display item. BossPrizeDrawPrep: LDA.b #$00 From 5ac052893329d497f23629e67db44366368b44c6 Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 18:58:14 -0400 Subject: [PATCH 27/53] Fix Small Key Ring for Current Dungeon on prize location --- LTTP_RND_GeneralBugfixes.asm | 1 + heartpieces.asm | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index b0851e31..ceaeb9f8 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -180,6 +180,7 @@ org $A48000 ; code bank - PUT NEW CODE HERE Link_ReceiveItem_HandleCurrentDungeonKeyRing: CPY.b #$CE : BNE .normalReceive LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE .normalReceive + JSL.l BossPrizeReceiveContextMatches : BCS .normalReceive JSL.l ReceiveCurrentDungeonKeyRingQuiet JSL.l Player_HaltDashAttackLong CLC diff --git a/heartpieces.asm b/heartpieces.asm index 6f0651e9..1f815b77 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -108,8 +108,6 @@ NormalItemSkipSound: RTL + - CPY.b #$CE : BEQ .skipSound ; Skip the current-dungeon key ring pickup fanfare - LDA $0C5E, X ; thing we wrote over PHA ; Shuffled boss prizes keep the victory fanfare even when the prize is not @@ -122,6 +120,8 @@ NormalItemSkipSound: RTL + PLA + CPY.b #$CE : BEQ .skipSound ; Skip the current-dungeon key ring pickup fanfare + CMP.b #$3E : BEQ + CLC RTL From c32ab539c9cf11a74291387624d4e897f160026b Mon Sep 17 00:00:00 2001 From: Alchav Date: Fri, 1 May 2026 21:16:15 -0400 Subject: [PATCH 28/53] Require Number of Dungeons; check actual boss kills --- goalitem.asm | 32 ++++++++++++++++++++++++++------ tables.asm | 11 ++++++----- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/goalitem.asm b/goalitem.asm index 6b956a10..119fcc66 100644 --- a/goalitem.asm +++ b/goalitem.asm @@ -27,11 +27,8 @@ CheckGanonVulnerability: + : CMP #$01 : BEQ .fail ;#$01 = On + : CMP #$02 : BNE + - ;#$02 = Require All Dungeons - LDA $7EF374 : AND.b #$07 : CMP #$07 : BNE .fail ; require all pendants - LDA $7EF37A : AND.b #$7F : CMP #$7F : BNE .fail ; require all crystals - LDA $7EF3C5 : CMP.b #$03 : !BLT .fail ; require post-aga world state - LDA $7EF2DB : AND.b #$20 : CMP #$20 : BNE .fail ; require aga2 defeated (pyramid hole open) + ;#$02 = Require Number of Dungeons + JSL CheckEnoughDungeonsForGanon : !BLT .fail ; require specified number of boss rooms/Aga fights BRA .success + : CMP #$04 : BNE + ;#$04 = Require Crystals @@ -79,7 +76,30 @@ CheckEnoughCrystalsForGanon: PHX : PHY LDA $7EF37A : JSL CountBits ; the comparison is against 1 less PLY : PLX - CMP.l NumberOfCrystalsRequiredForGanon + CMP.l GanonRequirementCount +RTL +;-------------------------------------------------------------------------------- +CheckEnoughDungeonsForGanon: + PHX : PHY + LDX.b #$00 + + LDA.l $7EF191 : AND.b #$08 : BEQ + : INX : + ; Eastern Palace / Armos Knights + LDA.l $7EF067 : AND.b #$08 : BEQ + : INX : + ; Desert Palace / Lanmolas + LDA.l $7EF00F : AND.b #$08 : BEQ + : INX : + ; Tower of Hera / Moldorm + LDA.l $7EF0B5 : AND.b #$08 : BEQ + : INX : + ; Palace of Darkness / Helmasaur King + LDA.l $7EF00D : AND.b #$08 : BEQ + : INX : + ; Swamp Palace / Arrghus + LDA.l $7EF053 : AND.b #$08 : BEQ + : INX : + ; Skull Woods / Mothula + LDA.l $7EF159 : AND.b #$08 : BEQ + : INX : + ; Thieves' Town / Blind + LDA.l $7EF1BD : AND.b #$08 : BEQ + : INX : + ; Ice Palace / Kholdstare + LDA.l $7EF121 : AND.b #$08 : BEQ + : INX : + ; Misery Mire / Vitreous + LDA.l $7EF149 : AND.b #$08 : BEQ + : INX : + ; Turtle Rock / Trinexx + + LDA.l $7EF3C5 : CMP.b #$03 : !BLT + : INX : + ; Agahnim 1 + LDA.l $7EF2DB : AND.b #$20 : BEQ + : INX : + ; Agahnim 2 + + TXA + PLY : PLX + CMP.l GanonRequirementCount RTL ;-------------------------------------------------------------------------------- CheckEnoughCrystalsForTower: diff --git a/tables.asm b/tables.asm index 4230cba1..0a9cc3b7 100644 --- a/tables.asm +++ b/tables.asm @@ -179,9 +179,9 @@ InvincibleGanon: db #$00 ; #$00 = Off (default) ; #$01 = On -; #$02 = Require All Dungeons -; #$03 = Require "NumberOfCrystalsRequiredForGanon" Crystals and Aga2 -; #$04 = Require "NumberOfCrystalsRequiredForGanon" Crystals +; #$02 = Require "GanonRequirementCount" dungeon completions +; #$03 = Require "GanonRequirementCount" Crystals and Aga2 +; #$04 = Require "GanonRequirementCount" Crystals ; #$05 = Require "GoalItemRequirement" Goal Items ; #$06 = Require Master sword pedestal to be pulled ;-------------------------------------------------------------------------------- @@ -289,9 +289,10 @@ CrystalPendantFlags_2: org $30805E ; PC 0x18005E - Number of crystals required to enter GT NumberOfCrystalsRequiredForTower: db #$07 ; #$07 = 7 Crystals -org $30805F ; PC 0x18005F - Number of crystals required to kill Ganon +org $30805F ; PC 0x18005F - Count required to kill Ganon +GanonRequirementCount: NumberOfCrystalsRequiredForGanon: -db #$07 ; #$07 = 7 Crystals +db #$07 ; Crystals for modes $03/$04, dungeon completions for mode $02 ;-------------------------------------------------------------------------------- org $308060 ; PC 0x180060 - 0x18007E ProgrammableItemLogicJump_1: From 6f45db16a26a97bc43b2dda9ef7818fed846d2b0 Mon Sep 17 00:00:00 2001 From: alchav Date: Sat, 2 May 2026 13:44:48 -0400 Subject: [PATCH 29/53] Fix Crystal Palettes in Shops --- shopkeeper.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/shopkeeper.asm b/shopkeeper.asm index 99b08af6..fd1e1990 100644 --- a/shopkeeper.asm +++ b/shopkeeper.asm @@ -963,6 +963,7 @@ Shopkeeper_DrawNextItem: PHX : LDA #0 : XBA : TXA : LSR #2 : TAX : LDA.l !SHOP_INVENTORY_DISGUISE, X : PLX : CMP #$0 : BNE ++ LDA.l !SHOP_INVENTORY, X ; get item palette ++ + JSL.l MaybeLoadCrystalSpritePalette CMP.b #$2E : BNE + : BRA .potion + CMP.b #$2F : BNE + : BRA .potion + CMP.b #$30 : BEQ .potion From 82589340aab3bd31f497dec546cb544a2faf94dd Mon Sep 17 00:00:00 2001 From: alchav Date: Sat, 2 May 2026 19:50:34 -0400 Subject: [PATCH 30/53] Remove obsolete crystal palette workarounds --- LTTP_RND_GeneralBugfixes.asm | 2 +- darkroomitems.asm | 35 ----------------------------------- hooks.asm | 4 ---- newitems.asm | 20 ++++++++------------ pendantcrystalhud.asm | 18 +++++++++--------- shopkeeper.asm | 1 - utilities.asm | 22 ++++++---------------- 7 files changed, 24 insertions(+), 78 deletions(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index ceaeb9f8..e872fc3a 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -307,7 +307,7 @@ org $31A800 GFX_New_Items: ;incbin newitems.gfx ;incbin eventitems.gfx ; *EVENT* -; 2026 item graphics include the key ring art and keep within the original slot. +; 2026 item graphics include the key ring art incbin 2026items.gfx warnpc $31B000 diff --git a/darkroomitems.asm b/darkroomitems.asm index 5c01ee59..ffd3c32d 100644 --- a/darkroomitems.asm +++ b/darkroomitems.asm @@ -5,10 +5,6 @@ CheckReceivedItemPropertiesBeforeLoad: LDA $7F504C : BEQ + LDA $7F504D : TAX + - TXA - PHY - JSL.l MaybeLoadCrystalSpritePalette - PLY LDA $A0 : BEQ .normalCode LDA $7EC005 : BNE .lightOff .normalCode @@ -81,34 +77,3 @@ CrystalItemBehaviorCheck: .bossPrizeCrystal JML.l CrystalSpecialBehaviorContinue - -; Dynamic/freestanding crystals need SP6 loaded before draw, unlike most items -; whose palettes are already present in the normal received-item path. -MaybeLoadCrystalSpritePalette: - PHA - CMP.b #$20 : BEQ .loadPalette - CMP.b #$B9 : BCC .done - CMP.b #$C0 : BCS .done - -.loadPalette - PHX : PHY - REP #$20 - LDA $00 : PHA - LDA $02 : PHA - SEP #$20 - - LDA.b #$04 : STA $0AB1 - LDA.b #$02 : STA $0AA9 - JSL.l $1BED72 ; Palette_MiscSpr.justSP6 - INC $15 - - REP #$20 - PLA : STA $02 - PLA : STA $00 - SEP #$20 - PLY - PLX - -.done - PLA -RTL diff --git a/hooks.asm b/hooks.asm index aea60f9d..ce35bdb6 100755 --- a/hooks.asm +++ b/hooks.asm @@ -900,10 +900,6 @@ LDA.w AddReceivedItemExpanded_item_masks, X org $098769 ; 48769 - ancilla_init.asm:1005 (LDA .item_graphics_indices, Y) LDA.w AddReceivedItemExpanded_item_graphics_indices, Y -; Let expanded graphics IDs use the variable animated-sprite tile loader. -org $09878C ; 4878C - ancilla_init.asm:1028 (JSL GetAnimatedSpriteTile.variable) -JSL.l GetAnimatedSpriteTile_variable - org $09884D ; 4884D - ancilla_init.asm:1137 (LDA $836C, Y) LDA.w AddReceivedItemExpanded_y_offsets, Y org $09885B ; 4885B - ancilla_init.asm:1139 (LDA .x_offsets, X) - I think the disassembly is wrong here, should have been LDA .x_offsets, Y diff --git a/newitems.asm b/newitems.asm index 7af81afb..896eb118 100644 --- a/newitems.asm +++ b/newitems.asm @@ -498,10 +498,6 @@ RTL !SINGLE_INDEX_BITMASK_TEMP = "$7F5022" !LOCK_IN = "$7F5090" !ITEM_BUSY = "$7F5091" -; Received-item graphics IDs are separate from dynamic ground-sprite IDs. -; Key rings reuse the former Silver Arrow slot; Silver Arrows use single-arrow art. -!SINGLE_ARROW_RECEIVED_ITEM_GFX = $33 -!KEY_RING_RECEIVED_ITEM_GFX = $41 ;2B:Bottle Already Filled w/ Red Potion ;2C:Bottle Already Filled w/ Green Potion ;2D:Bottle Already Filled w/ Blue Potion @@ -667,7 +663,7 @@ AddReceivedItemExpanded: db -5 ; Master Sword (Safe) db -4, -4, -4, -4 ; +5/+10 Bomb Arrows db -4, -4, -4 ; 3x Programmable Item - db -2 ; Upgrade-Only Sivler Arrows + db -2 ; Upgrade-Only Silver Arrows db -4 ; 1 Rupoor db -4 ; Null Item db -4, -4, -4 ; Red, Blue & Green Clocks @@ -749,7 +745,7 @@ AddReceivedItemExpanded: db $18 ; Master Sword (Safe) db $3D, $3E, $3F, $40 ; +5/+10 Bomb Arrows db $00, $00, $00 ; 3x Programmable Item - db !SINGLE_ARROW_RECEIVED_ITEM_GFX ; Upgrade-Only Sivler Arrows + db $33 ; Upgrade-Only Silver Arrows db $24 ; 1 Rupoor db $47 ; Null Item db $48, $48, $48 ; Red, Blue & Green Clocks @@ -771,10 +767,10 @@ AddReceivedItemExpanded: db $47 ; Bee Trap db $47, $2C, $47, $47 ; Fae, Bee, Jar, Apple db $47, $23, $23, $23, $28, $28, $28, $28, $28, $28, $28 ; Unused, Pendants, Crystals - db !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX ; Key Ring - db !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX - db !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX - db !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX, !KEY_RING_RECEIVED_ITEM_GFX + db $41, $41, $41, $41 ; Key Ring + db $41, $41, $41, $41 + db $41, $41, $41, $41 + db $41, $41, $41, $41 db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused @@ -798,7 +794,7 @@ AddReceivedItemExpanded: db $00 ; Master Sword (Safe) db $02, $02, $02, $02 ; +5/+10 Bomb Arrows db $02, $02, $02 ; 3x Programmable Item - db $00 ; Upgrade-Only Sivler Arrows + db $00 ; Upgrade-Only Silver Arrows db $00 ; 1 Rupoor db $02 ; Null Item db $02, $02, $02 ; Red, Blue & Green Clocks @@ -855,7 +851,7 @@ AddReceivedItemExpanded: db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Big Key db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Small Key db 1 ; Bee Trap - db 4, 4, 4, 4, 4, 4, 2, 1, 6, 6, 6, 6, 6, 6, 6 ; Unused, Pendants, Crystals + db 4, 4, 4, 4, 4, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2 ; Unused, Pendants, Crystals db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused diff --git a/pendantcrystalhud.asm b/pendantcrystalhud.asm index c6e75c64..843b1de3 100644 --- a/pendantcrystalhud.asm +++ b/pendantcrystalhud.asm @@ -462,15 +462,15 @@ DrawPendantCrystalDiagram: REP #$30 ; Set 16-bit accumulator & index registers LDX.w #$0000 ; Paint entire box black & draw empty pendants and crystals - - LDA.w .row0, X : STA $12EA, X - LDA.w .row1, X : STA $132A, X - LDA.w .row2, X : STA $136A, X - LDA.w .row3, X : STA $13AA, X - LDA.w .row4, X : STA $13EA, X - LDA.w .row5, X : STA $142A, X - LDA.w .row6, X : STA $146A, X - LDA.w .row7, X : STA $14AA, X - LDA.w .row8, X : STA $14EA, X + LDA.l .row0, X : STA $12EA, X + LDA.l .row1, X : STA $132A, X + LDA.l .row2, X : STA $136A, X + LDA.l .row3, X : STA $13AA, X + LDA.l .row4, X : STA $13EA, X + LDA.l .row5, X : STA $142A, X + LDA.l .row6, X : STA $146A, X + LDA.l .row7, X : STA $14AA, X + LDA.l .row8, X : STA $14EA, X INX #2 : CPX.w #$0014 : BCC - ;pendants diff --git a/shopkeeper.asm b/shopkeeper.asm index fd1e1990..99b08af6 100644 --- a/shopkeeper.asm +++ b/shopkeeper.asm @@ -963,7 +963,6 @@ Shopkeeper_DrawNextItem: PHX : LDA #0 : XBA : TXA : LSR #2 : TAX : LDA.l !SHOP_INVENTORY_DISGUISE, X : PLX : CMP #$0 : BNE ++ LDA.l !SHOP_INVENTORY, X ; get item palette ++ - JSL.l MaybeLoadCrystalSpritePalette CMP.b #$2E : BNE + : BRA .potion + CMP.b #$2F : BNE + : BRA .potion + CMP.b #$30 : BEQ .potion diff --git a/utilities.asm b/utilities.asm index 72e95238..d3b896ca 100644 --- a/utilities.asm +++ b/utilities.asm @@ -3,10 +3,6 @@ ;================================================================================ !PROGRESSIVE_SHIELD = "$7EF416" ; ss-- ---- !BEE_TRAP_DISGUISE = "$7EF4DA" -; Dynamic ground-sprite graphics IDs. This table is not the same ID space as -; received/held-up item graphics. -!SINGLE_ARROW_SPRITE_GFX = $33 -!KEY_RING_SPRITE_GFX = $41 ;-------------------------------------------------------------------------------- ; GetSpriteTile ; in: A - Loot ID @@ -146,7 +142,7 @@ RTL db $44 ; Safe Master Sword db $3D, $3E, $3F, $40 ; Bomb & Arrow +5/+10 db $2C, $00, $00 ; 3x Programmable Item - db !SINGLE_ARROW_SPRITE_GFX ; Upgrade-Only Silver Arrows + db $33 ; Upgrade-Only Silver Arrows db $24 ; 1 Rupoor db $47 ; Null Item db $48, $48, $48 ; Red, Blue & Green Clocks @@ -179,10 +175,10 @@ RTL ;Cx ; Key rings use the dynamic slot where the Silver Arrow graphic is stored. - db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX ; Key Ring - db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX - db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX - db !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX, !KEY_RING_SPRITE_GFX + db $41, $41, $41, $41 ; Key Ring + db $41, $41, $41, $41 + db $41, $41, $41, $41 + db $41, $41, $41, $41 db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Unused db $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49, $49 ; Reserved @@ -318,7 +314,7 @@ RTL db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Free Small Key db $04 ; Bee Trap db $08, $02, $08, $02 ; Fae, Bee, Jar, Apple - db $08, $08, $04, $02, $0C, $0C, $0C, $0C, $0C, $0C, $0C ; Unused, Pendants, Crystals + db $08, $08, $04, $02, $04, $04, $04, $04, $04, $04, $04 ; Unused, Pendants, Crystals db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Key Ring db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused @@ -497,9 +493,6 @@ RTS ;-------------------------------------------------------------------------------- DrawDynamicTile: JSR PrepDrawRemoteItemSprite - ; Crystals can appear as ordinary ground sprites when boss prizes shuffle. - JSL.l MaybeLoadCrystalSpritePalette - JSL.l IsNarrowSprite : BCS .narrow .full @@ -530,9 +523,6 @@ RTL ;-------------------------------------------------------------------------------- DrawDynamicTileNoShadow: JSR PrepDrawRemoteItemSprite - ; Shadowless dynamic draws need the same crystal palette preload. - JSL.l MaybeLoadCrystalSpritePalette - JSL.l IsNarrowSprite : BCS .narrow .full From 7e1b486e3cfd580a8c76d94714a7e1f313c66c99 Mon Sep 17 00:00:00 2001 From: alchav Date: Sat, 2 May 2026 21:00:19 -0400 Subject: [PATCH 31/53] Fix Aga 1 and 2 checks for Ganon goal --- goalitem.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/goalitem.asm b/goalitem.asm index 119fcc66..5fb89fa2 100644 --- a/goalitem.asm +++ b/goalitem.asm @@ -94,8 +94,8 @@ CheckEnoughDungeonsForGanon: LDA.l $7EF121 : AND.b #$08 : BEQ + : INX : + ; Misery Mire / Vitreous LDA.l $7EF149 : AND.b #$08 : BEQ + : INX : + ; Turtle Rock / Trinexx - LDA.l $7EF3C5 : CMP.b #$03 : !BLT + : INX : + ; Agahnim 1 - LDA.l $7EF2DB : AND.b #$20 : BEQ + : INX : + ; Agahnim 2 + LDA.l $7EF041 : AND.b #$08 : BEQ + : INX : + ; Agahnim 1 + LDA.l $7EF01B : AND.b #$08 : BEQ + : INX : + ; Agahnim 2 TXA PLY : PLX From 21d63ab65f40a93585dbec5bab5abe38abd69a01 Mon Sep 17 00:00:00 2001 From: alchav Date: Sat, 2 May 2026 21:53:49 -0400 Subject: [PATCH 32/53] Fix GT opening crash --- hooks.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks.asm b/hooks.asm index ce35bdb6..4b4d21f4 100755 --- a/hooks.asm +++ b/hooks.asm @@ -942,7 +942,7 @@ org $08C70F ; 4470F - ancilla_receive_item.asm : 582 - (LDA.b #$00 : STA ($92), JSL.l LoadNarrowObject ; Boss-prize narrow items need the shadow position adjusted after the item body. -org $08CDF3 ; 44DF3 - ancilla_milestone_item.asm:239 (REP #$20 : LDA $06 : ADD.w #$000C : STA $00) +org $08CBF3 ; 44BF3 - ancilla_milestone_item.asm:239 (REP #$20 : LDA $06 : ADD.w #$000C : STA $00) JSL.l BossPrizeMilestoneShadowPrep NOP #6 From 49faf6f656d14075ee8a4aeba773c8760925907f Mon Sep 17 00:00:00 2001 From: alchav Date: Sat, 2 May 2026 22:05:22 -0400 Subject: [PATCH 33/53] Fix key ring for current dungeon animation skipped on chest --- LTTP_RND_GeneralBugfixes.asm | 7 ++++--- heartpieces.asm | 7 ++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index e872fc3a..ba27086a 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -175,12 +175,13 @@ incsrc init.asm org $A48000 ; code bank - PUT NEW CODE HERE -; Current-dungeon key rings are inventory-only rewards. They should add the +; Current-dungeon key rings picked up from floor objects should add the ; dungeon's key quantity and update HUD/stats without the normal item fanfare. Link_ReceiveItem_HandleCurrentDungeonKeyRing: CPY.b #$CE : BNE .normalReceive LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE .normalReceive JSL.l BossPrizeReceiveContextMatches : BCS .normalReceive + LDA $02E9 : CMP.b #$03 : BNE .normalReceive JSL.l ReceiveCurrentDungeonKeyRingQuiet JSL.l Player_HaltDashAttackLong CLC @@ -196,8 +197,8 @@ Link_ReceiveItem_HandleCurrentDungeonKeyRing: .fromTextOrObject JML $0799C8 -; Grant the current dungeon's key ring directly because the generic receive-item -; path only handles one concrete item ID at a time. +; Grant floor-object current-dungeon key rings directly because they should not +; use the normal hold-up animation. ReceiveCurrentDungeonKeyRingQuiet: PHX : PHY LDA $040C : CMP.b #$FF : BEQ .cleanup diff --git a/heartpieces.asm b/heartpieces.asm index 1f815b77..c4ef2bb6 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -120,7 +120,12 @@ NormalItemSkipSound: RTL + PLA - CPY.b #$CE : BEQ .skipSound ; Skip the current-dungeon key ring pickup fanfare + CMP.b #$CE : BNE + + PHA + LDA $0C54, X : CMP.b #$03 + PLA + BEQ .skipSound ; Skip floor-object current-dungeon key ring pickup fanfare + + CMP.b #$3E : BEQ + CLC From 9529b7737c3ea2592001e14eb5d3956792303de7 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 3 May 2026 00:07:55 -0400 Subject: [PATCH 34/53] Fix Boss Heart Container Fanfare --- heartpieces.asm | 19 ++++++++++++------- tables.asm | 3 ++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/heartpieces.asm b/heartpieces.asm index c4ef2bb6..06d99f32 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -1,6 +1,8 @@ ;================================================================================ ; Randomize Heart Pieces ;-------------------------------------------------------------------------------- +!BOSS_HEART_FANFARE = "$7F5072" + HeartPieceGet: PHX : PHY LDY $0E80, X ; load item value into Y register @@ -30,6 +32,7 @@ HeartPieceGet: BRL .done ; finished .unfinished_heart + LDA.b #$00 : STA !BOSS_HEART_FANFARE SEC ; return true .done @@ -47,6 +50,8 @@ HeartContainerGet: JSL.l LoadHeartContainerRoomValue : TAY + + LDA.b #$01 : STA !BOSS_HEART_FANFARE + LDA.b #$2E : JSL Sound_SetSfx3PanLong BRA HeartPieceGet_skipLoad ;-------------------------------------------------------------------------------- !REDRAW = "$7F5000" @@ -94,15 +99,16 @@ DrawHeartContainerGFX: BRA DrawHeartPieceGFX_skipLoad ;-------------------------------------------------------------------------------- HeartContainerSound: - CPY.b #$3E : BNE + - LDA.b #$2E - SEC - RTL - + CLC RTL ;-------------------------------------------------------------------------------- NormalItemSkipSound: + LDA !BOSS_HEART_FANFARE : BEQ + + LDA.b #$00 : STA !BOSS_HEART_FANFARE + SEC + RTL + + + LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + SEC RTL @@ -127,10 +133,9 @@ NormalItemSkipSound: BEQ .skipSound ; Skip floor-object current-dungeon key ring pickup fanfare + - CMP.b #$3E : BEQ + CLC RTL - + + .skipSound SEC RTL diff --git a/tables.asm b/tables.asm index 0a9cc3b7..1f59721b 100644 --- a/tables.asm +++ b/tables.asm @@ -1555,7 +1555,8 @@ dw #9999 ; Rupee Limit ; $7F504F - $7F506F - Shop Block ; $7F5070 - Reserved for OneMind ; $7F5071 - Reserved for OneMind -; $7F5072 - $7F507D - Unused +; $7F5072 - Boss Heart Fanfare / Normal Sound Suppress Flag +; $7F5073 - $7F507D - Unused ; $7F507E - Clock Status ; $7F507F - Always Zero ; $7F5080 - $7F5083 - Clock Hours From a4059b03fc65540132b885b22a7dc495ef2b07be Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 3 May 2026 01:43:55 -0400 Subject: [PATCH 35/53] Earlier prize location check --- dungeondrops.asm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index 58754260..9e8c2771 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -299,11 +299,13 @@ BossPrizeObjectContextMatches: CLC RTL ;-------------------------------------------------------------------------------- -; Apply the configured multiworld recipient before the item is granted. +; Mark the location check and apply the configured multiworld recipient before +; the item is granted. BossPrizeApplyItemPlayer: JSL.l BossPrizeReceiveContextMatches : BCC .done + JSL.l MarkBossPrizeDungeonCompletion JSL.l BossPrizeGetPlayer : STA !MULTIWORLD_ITEM_PLAYER_ID -.done + .done RTL ;-------------------------------------------------------------------------------- ; Non-pendant shuffled prizes still need the victory fanfare before warping out. @@ -330,11 +332,10 @@ BossPrizePendantWaitCheck: .dontWaitForMusic JML.l PendantFanfareDone ;-------------------------------------------------------------------------------- -; Finish a shuffled boss prize by marking dungeon completion, showing deferred -; text if needed, then routing to the dungeon-exit path. +; Finish a shuffled boss prize by showing deferred text if needed, then routing +; to the dungeon-exit path. HandleBossPrizeObjectFinished: JSL.l BossPrizeObjectContextMatches : BCC .normalObjectFinished - JSL.l MarkBossPrizeDungeonCompletion JSL.l ClearBossPrizeContext LDA $7F509F : BEQ + From 5c52417ea4d5744b05e820de366c7de85aa87070 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 3 May 2026 10:53:42 -0400 Subject: [PATCH 36/53] Substitute bombs for rupees when capacity is 0 --- newitems.asm | 1 + utilities.asm | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/newitems.asm b/newitems.asm index 896eb118..5d24d770 100644 --- a/newitems.asm +++ b/newitems.asm @@ -1210,6 +1210,7 @@ IncrementItemCounters: RTS ;-------------------------------------------------------------------------------- AttemptItemSubstitution: + JSR SubstituteBombsWithRupeesWhenCapacityIsZero PHX : PHA LDX.b #$00 - diff --git a/utilities.asm b/utilities.asm index d3b896ca..ad76f4c8 100644 --- a/utilities.asm +++ b/utilities.asm @@ -4,12 +4,43 @@ !PROGRESSIVE_SHIELD = "$7EF416" ; ss-- ---- !BEE_TRAP_DISGUISE = "$7EF4DA" ;-------------------------------------------------------------------------------- +SubstituteBombsWithRupeesWhenCapacityIsZero: + PHA + LDA $7EF370 + !ADD.l StartingMaxBombs + BEQ .substitute + PLA +RTS + +.substitute + PLA + CMP.b #$27 : BNE + ; Bomb + LDA.b #$34 ; Green Rupee + RTS + + + CMP.b #$28 : BNE + ; 3 Bombs + LDA.b #$35 ; Blue Rupee + RTS + + + CMP.b #$31 : BNE + ; 10 Bombs + LDA.b #$36 ; Red Rupee + + +RTS +;-------------------------------------------------------------------------------- ; GetSpriteTile ; in: A - Loot ID ; out: A - Sprite GFX ID ;-------------------------------------------------------------------------------- GetSpriteID: - ;JSR AttemptItemSubstitution + ; Skip local capacity substitutions for items that will be sent to another player. + PHA + LDA !MULTIWORLD_SPRITEITEM_PLAYER_ID : BNE + + PLA + JSR SubstituteBombsWithRupeesWhenCapacityIsZero + BRA ++ + + + PLA + ++ CMP.b #$16 : BEQ .bottle ; Bottle CMP.b #$2B : BEQ .bottle ; Red Potion w/bottle CMP.b #$2C : BEQ .bottle ; Green Potion w/bottle @@ -191,7 +222,15 @@ RTL ; out: A - Palette ;-------------------------------------------------------------------------------- GetSpritePalette: - ;JSR AttemptItemSubstitution + ; Skip local capacity substitutions for items that will be sent to another player. + PHA + LDA !MULTIWORLD_SPRITEITEM_PLAYER_ID : BNE + + PLA + JSR SubstituteBombsWithRupeesWhenCapacityIsZero + BRA ++ + + + PLA + ++ CMP.b #$16 : BEQ .bottle ; Bottle CMP.b #$2B : BEQ .bottle ; Red Potion w/bottle CMP.b #$2C : BEQ .bottle ; Green Potion w/bottle From 7497aeda4a9110be0a54e4e258464904576790c4 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 3 May 2026 18:57:13 -0400 Subject: [PATCH 37/53] Record read hints --- contrib.asm | 1 + dialog.asm | 38 +++++++++++++++++++++++++++++++++++--- heartpieces.asm | 12 +++++++----- hooks.asm | 6 +++--- multiworld.asm | 19 ++++++++++++++++--- newitems.asm | 9 ++++++--- stats.asm | 2 +- tables.asm | 11 ++++++++++- 8 files changed, 79 insertions(+), 19 deletions(-) diff --git a/contrib.asm b/contrib.asm index 0fbf3540..b4f80116 100644 --- a/contrib.asm +++ b/contrib.asm @@ -109,6 +109,7 @@ Sprite_ShowSolicitedMessageIfPlayerFacing_Alt: .SahasrahlaDialogs REP #$20 : LDA.l MapReveal_Sahasrahla : ORA !MAP_OVERLAY : STA !MAP_OVERLAY : SEP #$20 + JSL.l TrackHintRead JSL DialogSahasrahla : BRA .SayNothing .BombShopGuyDialog diff --git a/dialog.asm b/dialog.asm index 3dbe4b1f..2bbf6420 100644 --- a/dialog.asm +++ b/dialog.asm @@ -408,20 +408,50 @@ DialogBombShopGuy: JSL.l Sprite_ShowMessageUnconditional RTL ;-------------------------------------------------------------------------------- +!HINT_READ_FLAGS = "$7EF4F1" +;-------------------------------------------------------------------------------- +TrackHintRead: + PHX : PHP + REP #$30 + LDA.w $1CF0 + LDX.w #$0000 + + - + CMP.l HintReadTable, X : BEQ .match + LDA.l HintReadTable, X : CMP.w #$FFFF : BEQ .done + INX #4 + LDA.w $1CF0 + BRA - + + .match + LDA.l HintReadTable+2, X + PHA + AND.w #$00FF + TAX + PLA + XBA + SEP #$20 + ORA.l !HINT_READ_FLAGS, X + STA.l !HINT_READ_FLAGS, X + .done + PLP : PLX +RTL +;-------------------------------------------------------------------------------- Main_ShowTextMessage_Alt: ; Are we in text mode? If so then end the routine. LDA $10 : CMP.b #$0E : BEQ .already_in_text_mode Sprite_ShowMessageMinimal_Alt: STZ $11 - PHX : PHY + PHX : PHY : PHP + SEP #$20 LDA.b $00 : PHA LDA.b $01 : PHA LDA.b $02 : PHA LDA.b #$1C : STA.b $02 REP #$30 - LDA.w $1CF0 : ASL : TAX + LDA.w $1CF0 : ASL : CLC : ADC.w $1CF0 : TAX LDA.l $7f71c0, X STA.b $00 SEP #$30 @@ -437,6 +467,8 @@ Sprite_ShowMessageMinimal_Alt: BRL .end + + JSL.l TrackHintRead + STZ $0223 ; Otherwise set it so we are in text mode. STZ $1CD8 ; Initialize the step in the submodule @@ -452,7 +484,7 @@ Sprite_ShowMessageMinimal_Alt: PLA : STA.b $02 PLA : STA.b $01 PLA : STA.b $00 - PLY : PLX + PLP : PLY : PLX Main_ShowTextMessage_Alt_already_in_text_mode: RTL diff --git a/heartpieces.asm b/heartpieces.asm index 06d99f32..49502441 100644 --- a/heartpieces.asm +++ b/heartpieces.asm @@ -109,11 +109,6 @@ NormalItemSkipSound: RTL + - LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + - SEC - RTL - + - LDA $0C5E, X ; thing we wrote over PHA ; Shuffled boss prizes keep the victory fanfare even when the prize is not @@ -126,6 +121,13 @@ NormalItemSkipSound: RTL + PLA + + LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + + SEC + RTL + + + + LDA $0C5E, X ; thing we wrote over CMP.b #$CE : BNE + PHA LDA $0C54, X : CMP.b #$03 diff --git a/hooks.asm b/hooks.asm index 4b4d21f4..0fb39f67 100755 --- a/hooks.asm +++ b/hooks.asm @@ -1933,9 +1933,9 @@ org $05FA8E Sprite_ShowMessageMinimal: JML.l Sprite_ShowMessageMinimal_Alt ;-------------------------------------------------------------------------------- -;org $1CFD69 -;Main_ShowTextMessage: -;JML.l Main_ShowTextMessage_Alt +org $1CFD69 +Main_ShowTextMessage: +JML.l Main_ShowTextMessage_Alt ;-------------------------------------------------------------------------------- org $07b0cc ; <- 3b0d0 - Bank 07.asm : 7767 (JSL Main_ShowTextMessage) JSL.l Main_ShowTextMessage_Alt diff --git a/multiworld.asm b/multiworld.asm index 446c32f7..03b44667 100644 --- a/multiworld.asm +++ b/multiworld.asm @@ -44,6 +44,12 @@ PHX : PHY : PHP PLP : PLY : PLX endmacro +Multiworld_PrintSentTo: +{ + %Print_Text(HUD_SentTo, #$0010, !MULTIWORLD_ITEM_PLAYER_ID) +RTL +} + WriteText: { PHA : PHX : PHP @@ -273,12 +279,19 @@ Multiworld_AddReceivedItem_notCrystal: { TYA : STA $02E4 : PHX ; things we wrote over - LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE + + LDA !MULTIWORLD_ITEM_PLAYER_ID : BNE .remote JML.l AddReceivedItem_notCrystal+5 - + + + .remote + JSL.l BossPrizeReceiveContextMatches : BCC .showSentTo + PHY : LDY $02D8 : JSL AddInventory : PLY + JSL.l Multiworld_PrintSentTo + JML.l AddReceivedItem_gfxHandling + + .showSentTo PHY : LDY $02D8 : JSL AddInventory : PLY - %Print_Text(HUD_SentTo, #$0010, !MULTIWORLD_ITEM_PLAYER_ID) + JSL.l Multiworld_PrintSentTo LDA #$33 : STA $012F JML.l AddReceivedItem_gfxHandling diff --git a/newitems.asm b/newitems.asm index 5d24d770..60cfcde6 100644 --- a/newitems.asm +++ b/newitems.asm @@ -508,9 +508,11 @@ AddReceivedItemExpanded: { PHA : PHX ; Boss prizes may be remote items, so set the recipient before normal - ; local/remote inventory handling runs. + ; local/remote inventory handling runs. They still need the normal + ; receive-item object path for the prize fanfare and dungeon exit. JSL.l BossPrizeApplyItemPlayer - LDA RemoteItems : BEQ + : LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ + + JSL.l BossPrizeReceiveContextMatches : BCS .normalReceive + LDA RemoteItems : BEQ .normalReceive : LDA !MULTIWORLD_ITEM_PLAYER_ID : BEQ .normalReceive LDA $02E9 : BEQ ++ : CMP #$03 : BNE +++ : ++ ; fromTextOrObject LDA $0345 : BEQ ++ : LDA.b #$04 : ++ : STA $5D ; Restore Link to his swimming state @@ -520,7 +522,8 @@ AddReceivedItemExpanded: STZ $02D8 : STZ $02D9 : STZ $02E9 PHY : LDY.b #$00 : JSL AddInventory : PLY PLX : PLA : RTL - + + + .normalReceive JSL.l PreItemGet diff --git a/stats.asm b/stats.asm index a87593ba..1de59cc4 100644 --- a/stats.asm +++ b/stats.asm @@ -134,7 +134,7 @@ ;-------------------------------------------------------------------------------- ; $7EF4F0 - Fresh File Marker. ;-------------------------------------------------------------------------------- -; $7EF4F1 - 7EF4FD - Free space +; $7EF4F1 - 7EF4FD - Read in-game hint flags ;-------------------------------------------------------------------------------- ; 7EF4FEw[2] - Save Checksum ;-------------------------------------------------------------------------------- diff --git a/tables.asm b/tables.asm index 1f59721b..9fbf1420 100644 --- a/tables.asm +++ b/tables.asm @@ -1999,7 +1999,16 @@ BossPrize_Trinexx_Player: db #$00 ;-------------------------------------------------------------------------------- -; 0x1863AA - 187FFF (unused) +org $30E3B0 ; PC 0x1863B0 - 0x1864AF +; AP in-game hint tracking table. +; Entry format: dw message_id : db flag_byte_offset, flag_bit_mask +; $FFFF terminates the table. +HintReadTable: +dw $FFFF : db $FF, $FF +warnpc $30E4B0 + +;-------------------------------------------------------------------------------- +; 0x1864B0 - 187FFF (unused) ;-------------------------------------------------------------------------------- org $30EFFF ; PC 0x186FFF From 5b9554a3e2febd9b8d54af8c1a8224f883b8cb40 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 3 May 2026 21:24:06 -0400 Subject: [PATCH 38/53] Fix Bomb substitution in shops --- shopkeeper.asm | 15 ++++++++++++++- utilities.asm | 10 +++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/shopkeeper.asm b/shopkeeper.asm index 99b08af6..7d6e3529 100644 --- a/shopkeeper.asm +++ b/shopkeeper.asm @@ -355,10 +355,17 @@ SetupShopItem: JSL GetRandomInt : AND #$3F : STA !BEE_TRAP_DISGUISE BNE ++ : LDA #$49 : ++ : CMP #$26 : BNE ++ : LDA #$6A : ++ ; if 0 (fighter's sword + shield), set to just sword, if filled container (bugged palette), switch to triforce piece STA.l !SHOP_INVENTORY_DISGUISE, X : PLX - + : TAY + + + PHA : PHX + LDA #0 : XBA : TYA : LSR #2 : TAX + LDA.l !SHOP_INVENTORY_PLAYER, X : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID + PLX : PLA + TAY REP #$20 ; set 16-bit accumulator LDA 1,s : TAX : LDA.l .tile_offsets, X : TAX JSR LoadTile + SEP #$20 ; set 8-bit accumulator + LDA #$00 : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID PLY : PLX RTS .tile_offsets @@ -959,6 +966,11 @@ Shopkeeper_DrawNextItem: ++ SEP #$20 ; set 8-bit accumulator PLY + + PHX + LDA #0 : XBA : TXA : LSR #2 : TAX + LDA.l !SHOP_INVENTORY_PLAYER, X : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID + PLX PHX : LDA #0 : XBA : TXA : LSR #2 : TAX : LDA.l !SHOP_INVENTORY_DISGUISE, X : PLX : CMP #$0 : BNE ++ LDA.l !SHOP_INVENTORY, X ; get item palette @@ -1037,6 +1049,7 @@ Shopkeeper_DrawNextItem: + .next + LDA.b #$00 : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID INY INX #4 RTS diff --git a/utilities.asm b/utilities.asm index ad76f4c8..58f8c278 100644 --- a/utilities.asm +++ b/utilities.asm @@ -369,7 +369,15 @@ RTL IsNarrowSprite: PHA : PHX PHB : PHK : PLB - ;JSR AttemptItemSubstitution + ; Skip local capacity substitutions for items that will be sent to another player. + PHA + LDA !MULTIWORLD_SPRITEITEM_PLAYER_ID : BNE + + PLA + JSR SubstituteBombsWithRupeesWhenCapacityIsZero + BRA ++ + + + PLA + ++ ;-------- CMP.b #$16 : BEQ .bottle ; Bottle CMP.b #$2B : BEQ .bottle ; Red Potion w/bottle From f38e1054573b0f7881cf4b002a87d689848d9ed8 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 3 May 2026 21:40:52 -0400 Subject: [PATCH 39/53] Fix full-size pot key replacement sprite sizing --- keydropshuffle.asm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/keydropshuffle.asm b/keydropshuffle.asm index 9edd66e8..bbe25621 100644 --- a/keydropshuffle.asm +++ b/keydropshuffle.asm @@ -133,7 +133,10 @@ SpriteKeyDrawGFX: cmp #$24 : bne + lda $a0 : cmp #$80 : bne - : lda #$24 + jsl DrawDynamicTile ; see DrawHeartPieceGFX if problems - cmp #$03 : bne + + cmp #$03 : beq .narrow + pha : lda $0e60, x : and.b #$DF : sta $0E60, x : pla + bra + + .narrow pha : lda $0e60, x : ora.b #$20 : sta $0E60, x : pla + jsl.l Sprite_DrawShadowLong From 23c909930bca3f0bd5650e5810d8895f097116f2 Mon Sep 17 00:00:00 2001 From: alchav Date: Tue, 5 May 2026 02:01:26 -0400 Subject: [PATCH 40/53] Fix floodgate softlock not triggering --- floodgatesoftlock.asm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/floodgatesoftlock.asm b/floodgatesoftlock.asm index 7dfe0ca9..01c6e1a1 100644 --- a/floodgatesoftlock.asm +++ b/floodgatesoftlock.asm @@ -12,7 +12,9 @@ FloodGateReset: + FloodGateResetInner: LDA.l Bugfix_SwampWaterLevel : BEQ .done - LDA $279004 : BEQ .check_room_53 ; Only do the check for room 55 if on door rando + LDA.l ShuffleKeyDrops : BNE .check_room_55 + LDA $279004 : BEQ .check_room_53 ; Only do the check for room 55 if on door rando or key drop shuffle + .check_room_55 LDA $7EF06F : AND.b #$04 : BEQ .drain_room_55 ; Check if key in room 55 has been collected. LDA $7EF356 : AND.b #$01 : BNE .check_room_53 ; Check for flippers. This can otherwise softlock doors if flooded without flippers and no way to reset. .drain_room_55 From dbc82010104cf37d635fd107ec70ab3b9f022637 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 21 Jun 2026 20:41:48 -0400 Subject: [PATCH 41/53] Add prize location IDs to entrance lookup table --- dungeondrops.asm | 97 ++++++++++++++++++++++++++++++++++++------------ hooks.asm | 6 ++- 2 files changed, 78 insertions(+), 25 deletions(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index 9e8c2771..bb3530e6 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -381,33 +381,23 @@ RTL ;-------------------------------------------------------------------------------- ; Record shuffled boss-prize completion separately from vanilla pendant/crystal bits. MarkBossPrizeDungeonCompletion: - LDA $040C - CMP #$FF : BEQ .done - LSR : AND #$0F : CMP #$08 : !BGE + - JSR BossPrizeValueShift - ORA $7EF46B : STA $7EF46B - BRA .done - + - !SUB #$08 - JSR BossPrizeValueShift - BIT.b #$C0 : BEQ ++ : LDA.b #$C0 : ++ ; Make Hyrule Castle / Sewers Count for Both - ORA $7EF46C : STA $7EF46C + JSR BossPrizeRoomCompletionMask : BCC .done + CPX.b #$01 : BEQ .highByte + ORA $7EF46B : STA $7EF46B + BRA .done + .highByte + ORA $7EF46C : STA $7EF46C .done RTL -; Check the shuffled boss-prize completion bit for the current dungeon. +; Check the shuffled boss-prize completion bit for the current boss-prize room. BossPrizeDungeonCompletionMatches: - LDA $040C - CMP #$FF : BEQ .mismatch - LSR : AND #$0F : CMP #$08 : !BGE + - JSR BossPrizeValueShift - AND.l $7EF46B : BNE .match - BRA .mismatch - + - !SUB #$08 - JSR BossPrizeValueShift - BIT.b #$C0 : BEQ ++ : LDA.b #$C0 : ++ - AND.l $7EF46C : BNE .match + JSR BossPrizeRoomCompletionMask : BCC .mismatch + CPX.b #$01 : BEQ .highByte + AND.l $7EF46B : BNE .match + BRA .mismatch + .highByte + AND.l $7EF46C : BNE .match .mismatch CLC @@ -417,6 +407,67 @@ RTL SEC RTL +; Map the current boss room to the boss-prize completion byte and mask used by +; the client. Carry set on match. X=0 means $7EF46B; X=1 means $7EF46C. +BossPrizeRoomCompletionMask: + REP #$20 ; set 16-bit accumulator + LDA $A0 + CMP.w #200 : BNE + + SEP #$20 : LDA.b #$04 : LDX.b #$00 : SEC : RTS + + CMP.w #51 : BNE + + SEP #$20 : LDA.b #$08 : LDX.b #$00 : SEC : RTS + + CMP.w #7 : BNE + + SEP #$20 : LDA.b #$04 : LDX.b #$01 : SEC : RTS + + CMP.w #90 : BNE + + SEP #$20 : LDA.b #$40 : LDX.b #$00 : SEC : RTS + + CMP.w #6 : BNE + + SEP #$20 : LDA.b #$20 : LDX.b #$00 : SEC : RTS + + CMP.w #41 : BNE + + SEP #$20 : LDA.b #$01 : LDX.b #$01 : SEC : RTS + + CMP.w #172 : BNE + + SEP #$20 : LDA.b #$08 : LDX.b #$01 : SEC : RTS + + CMP.w #222 : BNE + + SEP #$20 : LDA.b #$02 : LDX.b #$01 : SEC : RTS + + CMP.w #144 : BNE + + SEP #$20 : LDA.b #$80 : LDX.b #$00 : SEC : RTS + + CMP.w #164 : BNE + + SEP #$20 : LDA.b #$10 : LDX.b #$01 : SEC : RTS + + + SEP #$20 + CLC +RTS + +; Tag routine 0x16 "clear level to open doors". In shuffled-prize mode, +; use the boss-prize completion bits instead of vanilla pendant/crystal bits. +BossPrizeClearLevelToOpenDoors: + LDA BossPrizeShuffle : BEQ .vanilla + JSL.l CheckIfBossRoom : BCC .vanilla + JSL.l BossPrizeDungeonCompletionMatches : BCS .openDoors + BRA .dontHaveGoalItem + +.vanilla + LDA $040C : LSR A : TAX + LDA.l CrystalPendantFlags_2, X : BNE .inDarkWorld + LDA $7EF374 : AND.l CrystalPendantFlags, X : BNE .openDoors + BRA .dontHaveGoalItem + +.inDarkWorld + LDA $7EF37A : AND.l CrystalPendantFlags, X : BEQ .dontHaveGoalItem + +.openDoors + REP #$30 + STZ $0468 + STZ $068E + STZ $0690 + SEP #$30 + LDA.b #$05 : STA $11 + LDX $0E + STZ $AE, X + +.dontHaveGoalItem + SEP #$30 +RTL + ; Convert a dungeon index into a single-bit mask for completion storage. BossPrizeValueShift: PHX diff --git a/hooks.asm b/hooks.asm index 0fb39f67..311daadf 100755 --- a/hooks.asm +++ b/hooks.asm @@ -1765,8 +1765,10 @@ JSL.l FlipLWDWFlag NOP #2 ;================================================================================ ;Clear level to open doors -org $01C50D ; 0xC50D - Bank01.asm:10032 - (LDA $7EF3CA : BNE .inDarkWorld) -LDA CrystalPendantFlags_2, X +org $01C508 ; 0xC508 - Bank01.asm:10027 - tag routine 0x16 +JSL.l BossPrizeClearLevelToOpenDoors +RTS +NOP #52 ;================================================================================ ;Kill enemy to clear level org $01C715 ; <- C715 - Bank01.asm:10358 - (LDA $7EF3CA : BNE .inDarkWorld) From afad00e0ec92e6f00aa3e15d0e34133706844798 Mon Sep 17 00:00:00 2001 From: alchav Date: Mon, 22 Jun 2026 03:27:21 -0400 Subject: [PATCH 42/53] Keep hint read tracking from suppressing textboxes --- dialog.asm | 21 +++++++++++++++++++++ hooks.asm | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/dialog.asm b/dialog.asm index 2bbf6420..49d8b8f4 100644 --- a/dialog.asm +++ b/dialog.asm @@ -437,6 +437,27 @@ TrackHintRead: PLP : PLX RTL ;-------------------------------------------------------------------------------- +Main_ShowTextMessage_TrackHintRead: + ; Are we in text mode? If so then end the routine. + LDA $10 : CMP.b #$0E : BEQ .already_in_text_mode + + JSL.l TrackHintRead + + STZ $0223 ; Otherwise set it so we are in text mode. + STZ $1CD8 ; Initialize the step in the submodule + + ; Go to text display mode (as opposed to maps, etc) + LDA.b #$02 : STA $11 + + ; Store the current module in the temporary location. + LDA $10 : STA $010C + + ; Switch the main module ($10) to text mode. + LDA.b #$0E : STA $10 + +.already_in_text_mode +RTL +;-------------------------------------------------------------------------------- Main_ShowTextMessage_Alt: ; Are we in text mode? If so then end the routine. LDA $10 : CMP.b #$0E : BEQ .already_in_text_mode diff --git a/hooks.asm b/hooks.asm index 311daadf..7a63da9e 100755 --- a/hooks.asm +++ b/hooks.asm @@ -1937,13 +1937,13 @@ JML.l Sprite_ShowMessageMinimal_Alt ;-------------------------------------------------------------------------------- org $1CFD69 Main_ShowTextMessage: -JML.l Main_ShowTextMessage_Alt +JML.l Main_ShowTextMessage_TrackHintRead ;-------------------------------------------------------------------------------- org $07b0cc ; <- 3b0d0 - Bank 07.asm : 7767 (JSL Main_ShowTextMessage) -JSL.l Main_ShowTextMessage_Alt +JSL.l Main_ShowTextMessage_TrackHintRead ;-------------------------------------------------------------------------------- org $08c5fe ; <- 445FE - ancilla_receive_item.asm : 408 (JSL Main_ShowTextMessage) -JSL.l Main_ShowTextMessage_Alt +JSL.l Main_ShowTextMessage_TrackHintRead ;-------------------------------------------------------------------------------- org $05E21F ; <- 2E21F - Bank05.asm : 2691 (STZ $0223) JSL.l Sprite_ShowMessageMinimal_Alt From bb8f6962c6ebdf65d3ac0dd018f2c57bcfb887d7 Mon Sep 17 00:00:00 2001 From: alchav Date: Tue, 23 Jun 2026 02:25:51 -0400 Subject: [PATCH 43/53] Direct patch to Mothula sword damage --- damage_table.bin | Bin 2048 -> 2048 bytes hooks.asm | 3 --- swordswap.asm | 20 -------------------- 3 files changed, 23 deletions(-) diff --git a/damage_table.bin b/damage_table.bin index fe0d0465f40829219ca48e7091286fd8da03960b..32cee7e81e6e4fc5e404bdf644c73a47940d1add 100644 GIT binary patch delta 14 VcmZn=Xb{-o#KI`J*_mZ8GXNf81LFVy delta 14 VcmZn=Xb{-o#KOq1*_mZ8GXNd?1JVEh diff --git a/hooks.asm b/hooks.asm index 7a63da9e..a6511c1c 100755 --- a/hooks.asm +++ b/hooks.asm @@ -799,9 +799,6 @@ org $06B49D ; <- 3349D - sprite_smithy_bros.asm : 485 (.tempered_sword_or_better Smithy_AlreadyGotSword: org $06B561 ; <- 33561 - sprite_smithy_bros.asm : 640 (JSL Link_ReceiveItem) ;-------------------------------------------------------------------------------- -org $06ED55 ; <- 36D55 - Bank06.asm : 4817 -JSL.l LoadSwordForDamage ; moth gold sword fix -;-------------------------------------------------------------------------------- org $08C5F7 ; <- 445F7 - ancilla_receive_item.asm : 400 (LDA.b #$09 : STA $012D) NOP #5 ; remove spooky telepathy sound ;-------------------------------------------------------------------------------- diff --git a/swordswap.asm b/swordswap.asm index 9901dcf2..70b8abef 100644 --- a/swordswap.asm +++ b/swordswap.asm @@ -19,26 +19,6 @@ ; ;JSL ItemSet_SmithSword - too early ;JML.l Smithy_DoesntHaveSword ;================================================================================ -;LoadSwordForDamage: -; LDA $7EF359 : CMP #$04 : BNE .done ; skip if not gold sword -; LDA $1B : BEQ + ; skip if outdoors -; LDA $A0 : CMP #41 : BNE + ; decimal 41 ; skip if not in the mothula room -; LDA #$03 ; pretend we're using tempered -; BRA .done -; + -; LDA #$04 ; nvm gold sword is fine -; .done -;RTL -;================================================================================ -LoadSwordForDamage: - LDA $0E20, X : CMP.b #$88 : BNE .notMoth - JSR.w LoadModifiedSwordLevel ; load normal sword value - CMP.b #$04 : !BLT + : DEC : + ; if it's gold sword, change it to tempered - RTL - .notMoth - JSR.w LoadModifiedSwordLevel ; load normal sword value -RTL -;================================================================================ ;!StalfosBombDamage = "$7F509D" LookupDamageLevel: CPX.w #$0918 : BNE + From 414470e981058385984564793a49fe441204178b Mon Sep 17 00:00:00 2001 From: Alchav Date: Sun, 28 Jun 2026 20:07:42 -0400 Subject: [PATCH 44/53] Don't lock up when reapplying freezes/stuns with sword --- hardmode.asm | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hardmode.asm b/hardmode.asm index 0bda6344..9f5fdeda 100644 --- a/hardmode.asm +++ b/hardmode.asm @@ -82,7 +82,22 @@ GetItemDamageValue: CPX.b #$3d : BEQ .hookshot .normal - lda $0db8f1,x ;what we wrote over + LDA $0DB8F1, X ; what we wrote over + CMP.b #$FB : !BLT .done + CMP.b #$FD : BEQ .done ; incinerate should still apply + + ; The caller has the sprite slot saved under the JSL return address. + TAY + LDA $04,s : TAX + LDA $0DD0, X : CMP.b #$0B : BNE .restoreDamage + STZ $47 + STZ $02E3 + LDA.b #$00 +RTL + + .restoreDamage + TYA + .done RTL .boomerang LDA.l StunItemAction : AND #$01 : BNE .normal From 52a8119ccf45bec1b2c1d1ab93f2455f5de20085 Mon Sep 17 00:00:00 2001 From: alchav Date: Mon, 6 Jul 2026 03:45:23 -0400 Subject: [PATCH 45/53] Crystals 5 and 6 are red --- newitems.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newitems.asm b/newitems.asm index 60cfcde6..f0b31372 100644 --- a/newitems.asm +++ b/newitems.asm @@ -854,7 +854,7 @@ AddReceivedItemExpanded: db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Big Key db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Free Small Key db 1 ; Bee Trap - db 4, 4, 4, 4, 4, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2 ; Unused, Pendants, Crystals + db 4, 4, 4, 4, 4, 4, 2, 1, 2, 2, 2, 2, 1, 1, 2 ; Unused, Pendants, Crystals db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused db 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ; Unused From f59b7ac885e61a204add50cc63cf998605ef366b Mon Sep 17 00:00:00 2001 From: alchav Date: Wed, 8 Jul 2026 13:57:41 -0400 Subject: [PATCH 46/53] Two-torch rooms --- hooks.asm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/hooks.asm b/hooks.asm index a6511c1c..15ed2ccc 100755 --- a/hooks.asm +++ b/hooks.asm @@ -74,6 +74,31 @@ org $02E21B ; <- 1621B - Bank02.asm : 11211 (STA $040C) JSL.l OnDungeonExit : NOP #2 ;-------------------------------------------------------------------------------- +;================================================================================ +; Two-torch puzzle rooms +;-------------------------------------------------------------------------------- +; Vanilla torch room tags require 4 lit torches. Puzzle shuffle can place torch +; tags in rooms 0x0B and 0x74, which only have 2 usable torches. +org $01C642 ; <- Bank01.asm, tag 0x33 "light torches to open" (LDA $00 : CMP #$0004) +JSL.l ComparePuzzleTorchRequirement +NOP + +org $01C8C7 ; <- Bank01.asm, tag 0x3E "light torches to get chest" (LDA $00 : CMP #$0004) +JSL.l ComparePuzzleTorchRequirement +NOP + +org $36F000 +ComparePuzzleTorchRequirement: + LDA $A0 : CMP.w #$000B : BEQ .twoTorches + CMP.w #$0074 : BEQ .twoTorches + LDA $00 : CMP.w #$0004 + RTL + +.twoTorches + LDA $00 : CMP.w #$0002 + RTL +;-------------------------------------------------------------------------------- + ;================================================================================ ; Quit Hook (for both types of save and quit) ;-------------------------------------------------------------------------------- From 6f364541dac9a23a2d4721636a0f4c6b13e49148 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 12 Jul 2026 02:36:10 -0400 Subject: [PATCH 47/53] Finish making red crystals red --- utilities.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities.asm b/utilities.asm index 58f8c278..73b50560 100644 --- a/utilities.asm +++ b/utilities.asm @@ -353,7 +353,7 @@ RTL db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Free Small Key db $04 ; Bee Trap db $08, $02, $08, $02 ; Fae, Bee, Jar, Apple - db $08, $08, $04, $02, $04, $04, $04, $04, $04, $04, $04 ; Unused, Pendants, Crystals + db $08, $08, $04, $02, $04, $04, $04, $04, $02, $02, $04 ; Unused, Pendants, Crystals db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Key Ring db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused db $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08 ; Unused From 9a811f9f090ea1cb2ee8e360bb856efe89fb3456 Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 12 Jul 2026 03:26:37 -0400 Subject: [PATCH 48/53] Fix floodgate animation when left lever is good --- LTTP_RND_GeneralBugfixes.asm | 2 +- floodgatesoftlock.asm => floodgates.asm | 49 ++++++++++++++++++++++++- hooks.asm | 20 ++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) rename floodgatesoftlock.asm => floodgates.asm (52%) diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index ba27086a..3eeaea4e 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -116,7 +116,7 @@ incsrc itemdowngrade.asm incsrc bugfixes.asm incsrc darkworldspawn.asm incsrc lampmantlecone.asm -incsrc floodgatesoftlock.asm +incsrc floodgates.asm incsrc heartpieces.asm incsrc npcitems.asm incsrc utilities.asm diff --git a/floodgatesoftlock.asm b/floodgates.asm similarity index 52% rename from floodgatesoftlock.asm rename to floodgates.asm index 01c6e1a1..c3ca911c 100644 --- a/floodgatesoftlock.asm +++ b/floodgates.asm @@ -1,5 +1,5 @@ ;================================================================================ -; Floodgate Softlock Fix +; Floodgate Fixes ;-------------------------------------------------------------------------------- FloodGateAndMasterSwordFollowerReset: JSL.l MasterSwordFollowerClear @@ -26,3 +26,50 @@ FloodGateResetInner: .done RTL ;================================================================================ + +; Puzzle randomization can place the good Floodgate lever on the left side of the +; room. Pulling it from there leaves the camera farther west than vanilla expects, +; which makes the watergate HDMA window start partly off-screen. +; +; $E2 is the BG2 camera scroll mirror. The watergate object position in $0680 +; still needs to be converted to screen space, but for this one room we clamp +; the effective camera position to the vanilla-ish right-lever view and clip the +; packed left/right HDMA bounds so the later gate opening intervals do not wrap +; and make the water disappear. + +ClampFloodgateWatergateHdmaScroll: + LDA $A0 : CMP.w #$010B : BNE .normal ; Dam/Floodgate room 267. + LDA $E2 : CMP.w #$1660 : BCS .normal + LDA $0680 : SEC : SBC.w #$1660 + RTL + + .normal + LDA $0680 : SEC : SBC $E2 +RTL +;================================================================================ + +BuildFloodgateWatergateLineBounds: + STA $0C + LDA $A0 : CMP.w #$010B : BEQ .clipped ; Dam/Floodgate room 267. + + .normal + LDA $0C : CLC : ADC $0670 : STA $02 + LDA $0670 : SEC : SBC $0C : AND.w #$00FF : STA $00 + LDA $02 : AND.w #$00FF : XBA : ORA $00 : STA $0C + RTL + + .clipped + LDA $0670 : SEC : SBC $0C : BPL .leftInBounds + LDA.w #$0000 + + .leftInBounds + AND.w #$00FF : STA $00 + + LDA $0670 : CLC : ADC $0C + CMP.w #$0100 : BCC .rightInBounds + LDA.w #$00FF + + .rightInBounds + AND.w #$00FF : XBA : ORA $00 : STA $0C +RTL +;================================================================================ diff --git a/hooks.asm b/hooks.asm index 15ed2ccc..82d87590 100755 --- a/hooks.asm +++ b/hooks.asm @@ -99,6 +99,26 @@ ComparePuzzleTorchRequirement: RTL ;-------------------------------------------------------------------------------- +;================================================================================ +; Floodgate HDMA scroll fix +;-------------------------------------------------------------------------------- +org $00F664 ; <- Bank00.asm, Hdma_ConfigureWaterTable (LDA $0680 : SUB $E2) +JSL.l ClampFloodgateWatergateHdmaScroll +NOP #2 + +org $00F742 ; <- Bank00.asm, Hdma_ConfigureWaterTableForWaterfall (LDA $0680 : SUB $E2) +JSL.l ClampFloodgateWatergateHdmaScroll +NOP #2 + +org $00F754 ; <- Bank00.asm, Hdma_ConfigureWaterTableForWaterfall first line-bounds packing +JSL.l BuildFloodgateWatergateLineBounds +NOP #22 + +org $00F78D ; <- Bank00.asm, Hdma_ConfigureWaterTableForWaterfall second line-bounds packing +JSL.l BuildFloodgateWatergateLineBounds +NOP #23 +;-------------------------------------------------------------------------------- + ;================================================================================ ; Quit Hook (for both types of save and quit) ;-------------------------------------------------------------------------------- From c2ee7999f5d995a92c43ca7f73904585b7a3162e Mon Sep 17 00:00:00 2001 From: alchav Date: Thu, 16 Jul 2026 04:34:01 -0400 Subject: [PATCH 49/53] Fix fourth heart piece on boss prize preventing warp-out --- dungeondrops.asm | 41 ++++++++++++++++++++++++++++++++++++++++- hooks.asm | 5 +++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index bb3530e6..b96eb916 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -293,12 +293,51 @@ BossPrizeObjectContextMatches: JSL.l BossPrizeContextMatchesRoom : BCC .mismatch JSL.l BossPrizeContextMatchesSlot : BCC .mismatch SEC - RTL +RTL .mismatch CLC RTL ;-------------------------------------------------------------------------------- +; Every fourth received Piece of Heart obtained is converted into a second +; receive-item animation, then the original ancilla is cleared without entering +; the ordinary object-finished path. If that original item was a shuffled boss +; prize, move the boss-prize context to the new completion-heart ancilla so the +; existing finish hook can warp after the full-heart animation ends. +BossPrizeRetargetHeartPieceCompletion: + JSL.l BossPrizeObjectContextMatches : BCC .done + PHX + LDX.b #$09 + +.nextAncilla + LDA $0C4A, X : CMP.b #$22 : BNE .next + LDA $0C5E, X : CMP.b #$26 : BNE .next + LDA.b #$03 : STA $0C54, X + TXA : STA !BOSS_PRIZE_SLOT + BRA .found + +.next + DEX : BPL .nextAncilla + +.found + PLX + +.done +RTL +;-------------------------------------------------------------------------------- +; Replacement for the vanilla Piece of Heart completion branch in receive-item +; object cleanup. This preserves the normal completion-heart animation and adds +; the boss-prize retargeting above before clearing the original receive object. +BossPrizeHeartPieceCompletionBranch: + PHX + LDY.b #$26 + JSL.l Link_ReceiveItem + PLX + JSL.l BossPrizeRetargetHeartPieceCompletion + STZ $0C4A, X + STZ $0FC1 +RTL +;-------------------------------------------------------------------------------- ; Mark the location check and apply the configured multiworld recipient before ; the item is granted. BossPrizeApplyItemPlayer: diff --git a/hooks.asm b/hooks.asm index 82d87590..77e596c5 100755 --- a/hooks.asm +++ b/hooks.asm @@ -2102,6 +2102,11 @@ org $08C45F ; <- 4445F - ancilla_recieve_item.asm:157 (STZ $02E9 : LDA $0C5E, X) Ancilla_ReceiveItem_optimus: JML.l PostItemAnimation : NOP #2 +org $08C46F ; <- 4446F - ancilla_receive_item.asm:164 (PHX : LDY.b #$26 : JSL Link_ReceiveItem ...) +JSL.l BossPrizeHeartPieceCompletionBranch +RTS +NOP #10 + ; Split receive-item dispatch so boss-prize text/object states can be handled. org $08C3D0 ; <- 443D0 - ancilla_receive_item.asm:62 (LDA $0C54, X) JML.l BossPrizeReceiveDispatch From 8acac4a95fd77ca2c9a512e7ec32fe30edee2e25 Mon Sep 17 00:00:00 2001 From: alchav Date: Fri, 17 Jul 2026 05:18:02 -0400 Subject: [PATCH 50/53] Wallmasters stay dead option --- enemy_adjustments.asm | 26 ++++++++++++++++++++++++++ hooks.asm | 3 +++ tables.asm | 4 +++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/enemy_adjustments.asm b/enemy_adjustments.asm index a0206f26..b13ed0c9 100644 --- a/enemy_adjustments.asm +++ b/enemy_adjustments.asm @@ -28,3 +28,29 @@ RTL RTL ;-------------------------------------------------------------------------------- +;-------------------------------------------------------------------------------- +; WallmastersStayDeadCheckDamage: +; optionally clear the active Wallmaster spawner when one of its spawned +; Wallmasters is killed, preventing further spawns in this room visit. +;-------------------------------------------------------------------------------- +WallmastersStayDeadCheckDamage: + JSL.l $06F2B0 ; Sprite_CheckDamageFromPlayerLong, what we wrote over + LDA.l WallmastersStayDead : BEQ .return + LDA $0DD0, X : CMP.b #$09 : BNE .clear_spawners + LDA $0E20, X : CMP.b #$90 : BNE .clear_spawners ; transformed into another sprite + LDA $0CE2, X : BEQ .return + CMP.b #$FD : BEQ .clear_spawners ; incinerated + CMP.b #$FB : BCS .return ; stunned or frozen, not killed + CMP $0E50, X : BCC .return ; pending damage is not lethal +.clear_spawners + PHX + LDX.b #$07 +.next_spawner + LDA $0B00, X : CMP.b #$09 : BNE .skip_spawner + STZ $0B00, X +.skip_spawner + DEX : BPL .next_spawner + PLX +.return + RTL +;-------------------------------------------------------------------------------- diff --git a/hooks.asm b/hooks.asm index 77e596c5..9cef820c 100755 --- a/hooks.asm +++ b/hooks.asm @@ -685,6 +685,9 @@ NOP #2 ;================================================================================ ; Wallmaster camera fix ;-------------------------------------------------------------------------------- +org $1EAF10 ; <- F2F10 sprite_wallmaster.asm : 68 (JSL Sprite_CheckDamageFromPlayerLong) +JSL.l WallmastersStayDeadCheckDamage + org $1EAF77 ; <- F2F77 sprite_wallmaster.asm : 141 (LDA.b #$2A : JSL Sound_SetSfx3PanLong) JSL.l WallmasterCameraFix diff --git a/tables.asm b/tables.asm index 9fbf1420..c6221939 100644 --- a/tables.asm +++ b/tables.asm @@ -946,7 +946,9 @@ org $30818E ; PC 0x18018E BossPrizeShuffle: db #$00 ; #$00 = vanilla boss prizes (default) - #$01 = shuffled boss prizes use ordinary item IDs and warp after collection ;================================================================================ -; 0x18018F (unused) +org $30818F ; PC 0x18018F +WallmastersStayDead: +db #$00 ; #$00 = vanilla behavior (default) - #$01 = killing a Wallmaster stops further Wallmaster spawns ;================================================================================ org $308190 ; PC 0x180190 - 0x180192 TimerStyle: From a9d27de5641dd45fc8e1a5e12e833809f74c2e0f Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 19 Jul 2026 15:45:55 -0400 Subject: [PATCH 51/53] Dungeons cleared indicator row --- c2e3e.bin | Bin 2048 -> 2048 bytes c2e3e.gfx | Bin 1537 -> 1671 bytes pendantcrystalhud.asm | 153 ++++++++++++++++++++++++++---------------- 3 files changed, 96 insertions(+), 57 deletions(-) diff --git a/c2e3e.bin b/c2e3e.bin index 9675a12aa7f7338ad4d37c31196e69cb022ebdd6..98f66f96e814941b7c2a42359ab8d443abb9b5a9 100644 GIT binary patch delta 28 hcmZn=Xb{-Yz{LOm|NrCvoByu{lGlOk&HYS;tN`(t5v2eC delta 16 XcmZn=Xb{-Yz%=;+lj!EDOxdgeF^>g@ diff --git a/c2e3e.gfx b/c2e3e.gfx index 1298f28e913c96f58031e288c04bee13bda04614..18f9de6410e2666c783ac50596f3d7061473c488 100644 GIT binary patch literal 1671 zcmZ8heQZ-z6u+g8I0Cui33EpOzSntu`cGQ5>DPo-m}4YlFAumy9}T7Ho;q0%9)vT>UH%%@))8V?%#@I zQ;GceR3bN}=LqkhyfGOKZA$0|hh(20ViJy7mq~-nVj7M?c~fF+Nn6rKu?!TDCloO= zvY8v*9)u%C;7!I7i_uho%|H=_YLu>!yL&re<*@YX1}}2MrWe!NcM`e?NQc}FyW9g8 ztO)S`)T0iz9PT5>;o1v1itUIZFGtNjbP0CLL$-yE#_}yyDIW1N=fcWo${VWM{Ou(> z`8LuUpA0{L^_`ETn~ogM1mG$_E2x^9O{mG~030DA^fcz-jEJ$ad)L)FS_&Bxt>ZFu zIXj&7#(Ag)?i_KML5`}ZBI(B?K04=xkF*4C;|9i!WMLdhs+q}R02`5(H=2xtc=8nW zv)Z|QqL9YV7|nAylk%DP=^K=);v+hg(M&T^7P^Q7+Tf!*~UQSdXWXLP3O4sv&K*DTiYx^an_NwXhh-Nyykzh@gw0(aF)Z zKDBqNTA|D*>V=3-W|j+}M8Jjt%_qUj2(zUKGGv=nxOFPvRed0E6=Uj(D7h0=J{>{R)@A3??iZWV2I!QthzlVvMS zme+Cafvt;2N&~5yiMbl_>}aD#+Jxg6@?&k8m-^(NLKte{2S1t^I7M{-i0j6fk)RqV z$dm5@&Gx?b!A$>}OrQHQPRL{O?NBG7ZSkX)(HVkR%WM(W+EukKa(EqB9jv>;V2^_t zHE`sJ(;nhjCdTN-qH;fecOd_X_A%*H`jFBx65rmNUy`pU{{Y-G`egQ!+MgVvrU-GA zJm|8Fm`qu}y4a`E2K8Ae>lJmob-Loh3W`D=dR*_-y+ymx&%ySu!YTG1UHuu3;8PsK zW|9xl^k}C157mHOk#N#-3Rh|%jzSE9jgo_e&3MyXB(KLMyo_T>2>kHq|X!6WbrrW#a4Fk(#OBntJDXPr_ delta 1299 zcmWktZERCj7(VBo+xB*A=@5t`A{%WPZed|CNM@K;xrLxH0e={kI2l5O1aUJ<1l;JI zySFVcu*3QlM7D$o5r~-V2P%w}EZagbR1AoGr6mQc5$K&4>B?>IZHWA8Rq}1tTPpkO$J~dDZDd>BF}!8I&@?ZgZ8p%RJ>C$>Y)W z3cbBgU;V?ctpkY{y1RWu7H2tx&?{Y1Q$xc%!h}#)*SyC;T3IPeO*0xArZ+zknu@1E z(PIU>nwp%QiklN0= zkiU4;s#j{goi;)$+BZ!uU-`$3KE1V-kV>gpL~W=pBw%W;c5Ezsfv{#VBm_YTf{jE* zV`PGO_vv+tuh@*wOdp>k}TBO~bNi251zLCo;i(I5uH2dFrLI8H^vG#a8reH^Pj zPSqZ&-loKe9HZr&ejVRthxnfLL(1mQ=Pu_yPkpC$()cy%Q^M5(y<@5K1vvx9A!YNG z>kBrf)Mh~fEEG{dT>F6Tx=*8j(NA?kumVNVLJ37brY}|0SO*voGp$m|vdmJ(_$7$$ zDL{v!!l6V_&SBpdA;FKSlX!$lpcl#rwqpbZMeU+XJcLk(Fh!gtHC41%rxOV;DVtUK zd_`mRMsJ&KhkAgxNz%7pM+LRHBe zGR_pP6f^i8!v!FvoJyX&%B#p$0oh@FCDPg(%pL29w=wUADGE<}06L zHqPuUiO%lsM8cP@xi#HTLrmI;W7v$NIO4@Br)PINV^*&Cn-|gZVthcHuW*KsP>@~k z+I&Pzkk;<%)ro=CAh98_9>n6>+S7>gqLpwPbC$A?k`MX|2aRvS3X=lawS&p+vBCni z%N7&ut_kx_{#-7eI>N;dL>4ik%c(T`X{;}&En`9;?~zRhyEkogX?P)XnMpHdIy@zZ z6$j!QYzr0DMYz|4*n;=8jD0So7M#OtxQUi%OpptZ4Ft1bvu6k9$bou~@}hN6?`v&+ z`1NG6l;v}@PH+@~wnEAnR(DdO1Q94l2LGAX#9ea?G0jCC5AY~oGOat|I+6Q|{ad;} zA>YWzKaTgdudzEy%x&Nz@9KUQ-p{;{_TUtD^R=f24uQqBI_F||8(nWlU lSGmb9*1%ol7X16+)jzM_{(1ED$gXy~O;y(QKRdpF;C}%Nnu7oU diff --git a/pendantcrystalhud.asm b/pendantcrystalhud.asm index 843b1de3..eeff56bd 100644 --- a/pendantcrystalhud.asm +++ b/pendantcrystalhud.asm @@ -291,75 +291,114 @@ DrawHUDDungeonItems: ; write black LDX.w #$0000 ; Paint entire box black & draw empty pendants and crystals - - LDA #$24F5 : STA $1686, X : STA $16C6, X + LDA #$24F5 : STA $1686, X : STA $16C6, X : STA $1706, X INX #2 : CPX.w #$0020 : BCC - + ; Dungeon clears used by the Dungeons goal. Hyrule Castle/Sewers has no boss flag. + LDA.w #$2828 : STA $1684 ; dungeon clear icon + LDA $7EF041 : AND.w #$0008 : BEQ + ; Agahnim 1 + LDA.w #$2826 : STA $1688 + + + LDA $7EF191 : AND.w #$0008 : BEQ + ; Eastern Palace / Armos Knights + LDA.w #$2826 : STA $168C + + + LDA $7EF067 : AND.w #$0008 : BEQ + ; Desert Palace / Lanmolas + LDA.w #$2826 : STA $168E + + + LDA $7EF00F : AND.w #$0008 : BEQ + ; Tower of Hera / Moldorm + LDA.w #$2826 : STA $1690 + + + LDA $7EF0B5 : AND.w #$0008 : BEQ + ; Palace of Darkness / Helmasaur King + LDA.w #$2826 : STA $1694 + + + LDA $7EF00D : AND.w #$0008 : BEQ + ; Swamp Palace / Arrghus + LDA.w #$2826 : STA $1696 + + + LDA $7EF053 : AND.w #$0008 : BEQ + ; Skull Woods / Mothula + LDA.w #$2826 : STA $1698 + + + LDA $7EF159 : AND.w #$0008 : BEQ + ; Thieves' Town / Blind + LDA.w #$2826 : STA $169A + + + LDA $7EF1BD : AND.w #$0008 : BEQ + ; Ice Palace / Kholdstare + LDA.w #$2826 : STA $169C + + + LDA $7EF121 : AND.w #$0008 : BEQ + ; Misery Mire / Vitreous + LDA.w #$2826 : STA $169E + + + LDA $7EF149 : AND.w #$0008 : BEQ + ; Turtle Rock / Trinexx + LDA.w #$2826 : STA $16A0 + + + LDA $7EF01B : AND.w #$0008 : BEQ + ; Agahnim 2 + LDA.w #$2826 : STA $16A4 + + + LDA !HUD_FLAG : AND.w #$0020 : BEQ + : BRL +++ : + LDA HUDDungeonItems : AND.w #$0001 : BNE + : BRL ++ : + - LDA.w #$2810 : STA $1684 ; small keys icon + LDA.w #$2810 : STA $16C4 ; small keys icon SEP #$20 ; set 8-bit accumulator ; Small Keys - LDA.b #$16 : !ADD $7EF37D : STA $1686 : LDA.b #$28 : ADC #$00 : sta.w $1686+1 ; Hyrule Castle - LDA.b #$16 : !ADD $7EF380 : STA $1688 : LDA.b #$28 : ADC #$00 : sta.w $1688+1 ; Agahnims Tower + LDA.b #$16 : !ADD $7EF37D : STA $16C6 : LDA.b #$28 : ADC #$00 : sta.w $16C6+1 ; Hyrule Castle + LDA.b #$16 : !ADD $7EF380 : STA $16C8 : LDA.b #$28 : ADC #$00 : sta.w $16C8+1 ; Agahnims Tower - LDA.b #$16 : !ADD $7EF37E : STA $168C : LDA.b #$28 : ADC #$00 : sta.w $168C+1 ; Eastern - LDA.b #$16 : !ADD $7EF37F : STA $168E : LDA.b #$28 : ADC #$00 : sta.w $168E+1 ; Desert - LDA.b #$16 : !ADD $7EF386 : STA $1690 : LDA.b #$28 : ADC #$00 : sta.w $1690+1 ; Hera + LDA.b #$16 : !ADD $7EF37E : STA $16CC : LDA.b #$28 : ADC #$00 : sta.w $16CC+1 ; Eastern + LDA.b #$16 : !ADD $7EF37F : STA $16CE : LDA.b #$28 : ADC #$00 : sta.w $16CE+1 ; Desert + LDA.b #$16 : !ADD $7EF386 : STA $16D0 : LDA.b #$28 : ADC #$00 : sta.w $16D0+1 ; Hera - LDA.b #$16 : !ADD $7EF382 : STA $1694 : LDA.b #$28 : ADC #$00 : sta.w $1694+1 ; PoD - LDA.b #$16 : !ADD $7EF381 : STA $1696 : LDA.b #$28 : ADC #$00 : sta.w $1696+1 ; Swamp - LDA.b #$16 : !ADD $7EF384 : STA $1698 : LDA.b #$28 : ADC #$00 : sta.w $1698+1 ; Skull Woods - LDA.b #$16 : !ADD $7EF387 : STA $169A : LDA.b #$28 : ADC #$00 : sta.w $169A+1 ; Thieves Town - LDA.b #$16 : !ADD $7EF385 : STA $169C : LDA.b #$28 : ADC #$00 : sta.w $169C+1 ; Ice - LDA.b #$16 : !ADD $7EF383 : STA $169E : LDA.b #$28 : ADC #$00 : sta.w $169E+1 ; Mire - LDA.b #$16 : !ADD $7EF388 : STA $16A0 : LDA.b #$28 : ADC #$00 : sta.w $16A0+1 ; Turtle Rock + LDA.b #$16 : !ADD $7EF382 : STA $16D4 : LDA.b #$28 : ADC #$00 : sta.w $16D4+1 ; PoD + LDA.b #$16 : !ADD $7EF381 : STA $16D6 : LDA.b #$28 : ADC #$00 : sta.w $16D6+1 ; Swamp + LDA.b #$16 : !ADD $7EF384 : STA $16D8 : LDA.b #$28 : ADC #$00 : sta.w $16D8+1 ; Skull Woods + LDA.b #$16 : !ADD $7EF387 : STA $16DA : LDA.b #$28 : ADC #$00 : sta.w $16DA+1 ; Thieves Town + LDA.b #$16 : !ADD $7EF385 : STA $16DC : LDA.b #$28 : ADC #$00 : sta.w $16DC+1 ; Ice + LDA.b #$16 : !ADD $7EF383 : STA $16DE : LDA.b #$28 : ADC #$00 : sta.w $16DE+1 ; Mire + LDA.b #$16 : !ADD $7EF388 : STA $16E0 : LDA.b #$28 : ADC #$00 : sta.w $16E0+1 ; Turtle Rock - LDA.b #$16 : !ADD $7EF389 : STA $16A4 : LDA.b #$28 : ADC #$00 : sta.w $16A4+1 ; Ganon's Tower + LDA.b #$16 : !ADD $7EF389 : STA $16E4 : LDA.b #$28 : ADC #$00 : sta.w $16E4+1 ; Ganon's Tower REP #$20 ; set 16-bit accumulator ++ ; Big Keys LDA HUDDungeonItems : AND.w #$0002 : BNE + : BRL ++ : + - LDA.w #$2811 : STA $16C4 ; big key icon + LDA.w #$2811 : STA $1704 ; big key icon LDA $7EF367 : AND.w #$0040 : BEQ + ; Hyrule Castle - LDA.w #$2826 : STA $16C6 + LDA.w #$2826 : STA $1706 + LDA $7EF367 : AND.w #$0008 : BEQ + ; Agahnims Tower - LDA.w #$2826 : STA $16C8 + LDA.w #$2826 : STA $1708 + LDA $7EF367 : AND.w #$0020 : BEQ + ; Eastern - LDA.w #$2826 : STA $16CC + LDA.w #$2826 : STA $170C + LDA $7EF367 : AND.w #$0010 : BEQ + ; Desert - LDA.w #$2826 : STA $16CE + LDA.w #$2826 : STA $170E + LDA $7EF366 : AND.w #$0020 : BEQ + ; Hera - LDA.w #$2826 : STA $16D0 + LDA.w #$2826 : STA $1710 + LDA $7EF367 : AND.w #$0002 : BEQ + ; PoD - LDA.w #$2826 : STA $16D4 + LDA.w #$2826 : STA $1714 + LDA $7EF367 : AND.w #$0004 : BEQ + ; Swamp - LDA.w #$2826 : STA $16D6 + LDA.w #$2826 : STA $1716 + LDA $7EF366 : AND.w #$0080 : BEQ + ; Skull Woods - LDA.w #$2826 : STA $16D8 + LDA.w #$2826 : STA $1718 + LDA $7EF366 : AND.w #$0010 : BEQ + ; Thieves Town - LDA.w #$2826 : STA $16DA + LDA.w #$2826 : STA $171A + LDA $7EF366 : AND.w #$0040 : BEQ + ; Ice - LDA.w #$2826 : STA $16DC + LDA.w #$2826 : STA $171C + LDA $7EF367 : AND.w #$0001 : BEQ + ; Mire - LDA.w #$2826 : STA $16DE + LDA.w #$2826 : STA $171E + LDA $7EF366 : AND.w #$0008 : BEQ + ; Turtle Rock - LDA.w #$2826 : STA $16E0 + LDA.w #$2826 : STA $1720 + LDA $7EF366 : AND.w #$0004 : BEQ + ; Ganon's Tower - LDA.w #$2826 : STA $16E4 + LDA.w #$2826 : STA $1724 + ++ @@ -368,89 +407,89 @@ DrawHUDDungeonItems: LDA !HUD_FLAG : AND.w #$0020 : BNE + : BRL +++ : + ; Maps LDA HUDDungeonItems : AND.w #$0004 : BNE + : BRL ++ : + - LDA.w #$2821 : STA $1684 ; map icon + LDA.w #$2821 : STA $16C4 ; map icon LDA $7EF369 : AND.w #$0040 : BEQ + ; Hyrule Castle - LDA.w #$2826 : STA $1686 + LDA.w #$2826 : STA $16C6 + LDA $7EF369 : AND.w #$0008 : BEQ + ; Agahnims Tower - LDA.w #$2826 : STA $1688 + LDA.w #$2826 : STA $16C8 + LDA $7EF369 : AND.w #$0020 : BEQ + ; Eastern - LDA.w #$2826 : STA $168C + LDA.w #$2826 : STA $16CC + LDA $7EF369 : AND.w #$0010 : BEQ + ; Desert - LDA.w #$2826 : STA $168E + LDA.w #$2826 : STA $16CE + LDA $7EF368 : AND.w #$0020 : BEQ + ; Hera - LDA.w #$2826 : STA $1690 + LDA.w #$2826 : STA $16D0 + LDA $7EF369 : AND.w #$0002 : BEQ + ; PoD - LDA.w #$2826 : STA $1694 + LDA.w #$2826 : STA $16D4 + LDA $7EF369 : AND.w #$0004 : BEQ + ; Swamp - LDA.w #$2826 : STA $1696 + LDA.w #$2826 : STA $16D6 + LDA $7EF368 : AND.w #$0080 : BEQ + ; Skull Woods - LDA.w #$2826 : STA $1698 + LDA.w #$2826 : STA $16D8 + LDA $7EF368 : AND.w #$0010 : BEQ + ; Thieves Town - LDA.w #$2826 : STA $169A + LDA.w #$2826 : STA $16DA + LDA $7EF368 : AND.w #$0040 : BEQ + ; Ice - LDA.w #$2826 : STA $169C + LDA.w #$2826 : STA $16DC + LDA $7EF369 : AND.w #$0001 : BEQ + ; Mire - LDA.w #$2826 : STA $169E + LDA.w #$2826 : STA $16DE + LDA $7EF368 : AND.w #$0008 : BEQ + ; Turtle Rock - LDA.w #$2826 : STA $16A0 + LDA.w #$2826 : STA $16E0 + LDA $7EF368 : AND.w #$0004 : BEQ + ; Ganon's Tower - LDA.w #$2826 : STA $16A4 + LDA.w #$2826 : STA $16E4 + ++ ; Compasses LDA HUDDungeonItems : AND.w #$0008 : BNE + : BRL ++ : + - LDA.w #$2C20 : STA $16C4 ; compass icon + LDA.w #$2C20 : STA $1704 ; compass icon LDA $7EF365 : AND.w #$0040 : BEQ + ; Hyrule Castle - LDA.w #$2C26 : STA $16C6 + LDA.w #$2C26 : STA $1706 + LDA $7EF365 : AND.w #$0008 : BEQ + ; Agahnims Tower - LDA.w #$2C26 : STA $16C8 + LDA.w #$2C26 : STA $1708 + LDA $7EF365 : AND.w #$0020 : BEQ + ; Eastern - LDA.w #$2C26 : STA $16CC + LDA.w #$2C26 : STA $170C + LDA $7EF365 : AND.w #$0010 : BEQ + ; Desert - LDA.w #$2C26 : STA $16CE + LDA.w #$2C26 : STA $170E + LDA $7EF364 : AND.w #$0020 : BEQ + ; Hera - LDA.w #$2C26 : STA $16D0 + LDA.w #$2C26 : STA $1710 + LDA $7EF365 : AND.w #$0002 : BEQ + ; PoD - LDA.w #$2C26 : STA $16D4 + LDA.w #$2C26 : STA $1714 + LDA $7EF365 : AND.w #$0004 : BEQ + ; Swamp - LDA.w #$2C26 : STA $16D6 + LDA.w #$2C26 : STA $1716 + LDA $7EF364 : AND.w #$0080 : BEQ + ; Skull Woods - LDA.w #$2C26 : STA $16D8 + LDA.w #$2C26 : STA $1718 + LDA $7EF364 : AND.w #$0010 : BEQ + ; Thieves Town - LDA.w #$2C26 : STA $16DA + LDA.w #$2C26 : STA $171A + LDA $7EF364 : AND.w #$0040 : BEQ + ; Ice - LDA.w #$2C26 : STA $16DC + LDA.w #$2C26 : STA $171C + LDA $7EF365 : AND.w #$0001 : BEQ + ; Mire - LDA.w #$2C26 : STA $16DE + LDA.w #$2C26 : STA $171E + LDA $7EF364 : AND.w #$0008 : BEQ + ; Turtle Rock - LDA.w #$2C26 : STA $16E0 + LDA.w #$2C26 : STA $1720 + LDA $7EF364 : AND.w #$0004 : BEQ + ; Ganon's Tower - LDA.w #$2C26 : STA $16E4 + LDA.w #$2C26 : STA $1724 + ++ : +++ PLP From cdf2d99c61c57abf51a2c0bba6de8464e29a0e6c Mon Sep 17 00:00:00 2001 From: alchav Date: Sun, 19 Jul 2026 16:11:44 -0400 Subject: [PATCH 52/53] Room 131 three torch hack --- hooks.asm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hooks.asm b/hooks.asm index 9cef820c..b626bd62 100755 --- a/hooks.asm +++ b/hooks.asm @@ -75,10 +75,11 @@ JSL.l OnDungeonExit : NOP #2 ;-------------------------------------------------------------------------------- ;================================================================================ -; Two-torch puzzle rooms +; Puzzle-shuffled torch counts ;-------------------------------------------------------------------------------- ; Vanilla torch room tags require 4 lit torches. Puzzle shuffle can place torch -; tags in rooms 0x0B and 0x74, which only have 2 usable torches. +; tags in rooms 0x0B and 0x74, which only have 2 usable torches, and room 0x83, +; which has 3 usable torches. org $01C642 ; <- Bank01.asm, tag 0x33 "light torches to open" (LDA $00 : CMP #$0004) JSL.l ComparePuzzleTorchRequirement NOP @@ -91,12 +92,17 @@ org $36F000 ComparePuzzleTorchRequirement: LDA $A0 : CMP.w #$000B : BEQ .twoTorches CMP.w #$0074 : BEQ .twoTorches + CMP.w #$0083 : BEQ .threeTorches LDA $00 : CMP.w #$0004 RTL .twoTorches LDA $00 : CMP.w #$0002 RTL + +.threeTorches + LDA $00 : CMP.w #$0003 + RTL ;-------------------------------------------------------------------------------- ;================================================================================ From 9a11bb62d43d005af661eec1b762ed7f22898182 Mon Sep 17 00:00:00 2001 From: alchav Date: Tue, 28 Jul 2026 02:12:47 -0400 Subject: [PATCH 53/53] Fix boss_prize_shuffle off bug --- dungeondrops.asm | 2 +- hooks.asm | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/dungeondrops.asm b/dungeondrops.asm index b96eb916..4ea75023 100644 --- a/dungeondrops.asm +++ b/dungeondrops.asm @@ -43,7 +43,7 @@ BossPrizeRoomTag: LDA $0403 : AND.b #$80 : BEQ .heartContainerStillExists LDA $040C : LSR A : TAX - LDA $7EF3CA : BNE .inDarkWorld + LDA.l CrystalPendantFlags_2, X : BNE .inDarkWorld LDA $7EF374 : AND.l CrystalPendantFlags, X : BNE .criticalItemAlreadyObtained BRA .giveCriticalItem diff --git a/hooks.asm b/hooks.asm index b626bd62..57f10970 100755 --- a/hooks.asm +++ b/hooks.asm @@ -1821,11 +1821,6 @@ JSL.l BossPrizeClearLevelToOpenDoors RTS NOP #52 ;================================================================================ -;Kill enemy to clear level -org $01C715 ; <- C715 - Bank01.asm:10358 - (LDA $7EF3CA : BNE .inDarkWorld) -LDA CrystalPendantFlags_2, X -;JSL.l GetPendantCrystalWorld -;================================================================================ ;org $0AC5C3 ; <- 545C3 - Bank0A.asm:1859 - (LDA $7EF374 : AND $0AC5A6, X : BEQ .fail) ;NOP #10 ;CLC