diff --git a/dialog.asm b/dialog.asm index 645ff2a..53e3a45 100644 --- a/dialog.asm +++ b/dialog.asm @@ -280,31 +280,31 @@ RTL ; s = silver arrow bow ; p = 2nd progressive bow DialogGanon2: - JSL.l CheckGanonVulnerability - - REP #$20 - BCS + + JSL.l CheckGanonVulnerability + + REP #$20 + BCS + LDA.w #$018D : BRA ++ - + - LDA.l BowTracking + + + LDA.l BowTracking BIT.w #$0080 : BNE + ; branch if bow LDA.w #$0192 : BRA ++ - + + + BIT.w #$0040 : BEQ + ; branch if no silvers LDA.w #$0195 : BRA ++ - + + + BIT.w #$0020 : BNE + ; branch if p bow LDA.w #$0194 : BRA ++ - + + + BIT.w #$0080 : BEQ + ; branch if no bow LDA.w #$0193 : BRA ++ - + + + LDA.w #$016E - ++ - STA.w TextID - SEP #$20 - JSL.l Sprite_ShowMessageMinimal_Alt + ++ + STA.w TextID + SEP #$20 + JSL.l Sprite_ShowMessageMinimal_Alt RTL ;-------------------------------------------------------------------------------- DialogEtherTablet: @@ -371,7 +371,7 @@ RTL ;--------------------------------------------------------------------------------------------------- AgahnimAsksAboutPed: - LDA.l InvincibleGanon + LDA.l GanonVulnerableMode CMP.b #$06 : BNE .vanilla LDA.l OverworldEventDataWRAM+$80 ; check ped flag diff --git a/elder.asm b/elder.asm index 7967a0c..e35598a 100644 --- a/elder.asm +++ b/elder.asm @@ -42,7 +42,7 @@ RTL { REP #$20 LDA.l GoalItemRequirement : BEQ .despawn - LDA.l InvincibleGanon : AND.w #$00FF : CMP.w #$0005 : BEQ .despawn + LDA.l GanonVulnerableMode : AND.w #$00FF : CMP.w #$0005 : BEQ .despawn LDA.l TurnInGoalItems : AND.w #$00FF : BNE + .despawn SEP #$20 diff --git a/entrances.asm b/entrances.asm index 6ae4e76..59c729a 100644 --- a/entrances.asm +++ b/entrances.asm @@ -14,7 +14,7 @@ LockAgahnimDoors: JSR.w LockAgahnimDoorsCore : BEQ .unlock PHX : PHY SEP #$30 - JSL.l CheckEnoughCrystalsForTower + JSL.l CheckTowerOpen REP #$30 PLY : PLX !BGE .crystalOrUnlock diff --git a/goalitem.asm b/goalitem.asm index 799bf41..8a97dde 100644 --- a/goalitem.asm +++ b/goalitem.asm @@ -15,7 +15,7 @@ RTL ;Carry set = ganon vulnerable CheckGanonVulnerability: PHX - LDA.l InvincibleGanon + LDA.l GanonVulnerableMode ASL TAX @@ -112,65 +112,86 @@ CheckGanonVulnerability: ;-------------------------------------------------------------------------------- GetRequiredCrystalsForTower: BEQ + : JSL.l BreakTowerSeal_ExecuteSparkles : + ; thing we wrote over - LDA.l NumberOfCrystalsRequiredForTower : CMP.b #$00 : BNE + : JML.l Ancilla_BreakTowerSeal_stop_spawning_sparkles : + - LDA.l NumberOfCrystalsRequiredForTower : CMP.b #$01 : BNE + : JML.l Ancilla_BreakTowerSeal_draw_single_crystal : + - LDA.l NumberOfCrystalsRequiredForTower : DEC #2 : TAX + LDA.l GanonsTowerOpenTarget : CMP.b #$00 : BNE + : JML.l Ancilla_BreakTowerSeal_stop_spawning_sparkles : + + LDA.l GanonsTowerOpenTarget : CMP.b #$01 : BNE + : JML.l Ancilla_BreakTowerSeal_draw_single_crystal : + + LDA.l GanonsTowerOpenTarget : DEC #2 : TAX JML.l GetRequiredCrystalsForTower_continue ;-------------------------------------------------------------------------------- GetRequiredCrystalsInX: - LDA.l NumberOfCrystalsRequiredForTower : CMP.b #$00 : BNE + + LDA.l GanonsTowerOpenTarget : CMP.b #$00 : BNE + TAX RTL + TXA -- CMP.l NumberOfCrystalsRequiredForTower : BCC + - SBC.l NumberOfCrystalsRequiredForTower ; carry guaranteed set +- CMP.l GanonsTowerOpenTarget : BCC + + SBC.l GanonsTowerOpenTarget ; carry guaranteed set BRA - - + INC : CMP.l NumberOfCrystalsRequiredForTower : BNE + + + INC : CMP.l GanonsTowerOpenTarget : BNE + LDA.b #$08 + : DEC : TAX RTL ;-------------------------------------------------------------------------------- CheckEnoughCrystalsForGanon: + REP #$20 LDA.l CrystalCounter - CMP.l NumberOfCrystalsRequiredForGanon + CMP.l GanonVulnerableTarget + SEP #$20 RTL ;-------------------------------------------------------------------------------- -CheckEnoughCrystalsForTower: - LDA.l CrystalCounter - CMP.l NumberOfCrystalsRequiredForTower +CheckTowerOpen: + REP #$30 + LDA.l GanonsTowerOpenMode : ASL : TAX + JSR.w (.tower_open_modes,X) + SEP #$30 RTL + .tower_open_modes + dw .vanilla + dw .arbitrary_cmp + + .vanilla + LDA.l CrystalsField + AND.w #$007F : CMP.w #$007F + RTS + + .arbitrary_cmp + LDA.l GanonsTowerOpenAddress : TAX + LDA.l $7E0000,X + CMP.l GanonsTowerOpenTarget + RTS ;--------------------------------------------------------------------------------------------------- CheckAgaForPed: - LDA.l InvincibleGanon - CMP.b #$06 : BNE .vanilla + REP #$20 + LDA.l GanonVulnerableMode + CMP.w #$0006 : BNE .vanilla .light_speed - LDA.l OverworldEventDataWRAM+$80 ; check ped flag - AND.b #$40 - BEQ .force_blue_ball + SEP #$20 + LDA.l OverworldEventDataWRAM+$80 ; check ped flag + AND.b #$40 + BEQ .force_blue_ball .vanilla ; run vanilla check for phase - LDA.w SpriteAux, X - CMP.b #$02 - RTL + SEP #$20 + LDA.w SpriteAux, X + CMP.b #$02 + RTL .force_blue_ball - LDA.b #$01 : STA.w SpriteAuxTable, Y - LDA.b #$20 : STA.w SpriteTimer, Y - CLC ; skip the RNG check - RTL + LDA.b #$01 : STA.w SpriteAuxTable, Y + LDA.b #$20 : STA.w SpriteTimer, Y + CLC ; skip the RNG check + RTL ;--------------------------------------------------------------------------------------------------- KillGanon: STA.l ProgressIndicator ; vanilla game state stuff we overwrote - LDA.l InvincibleGanon + LDA.l GanonVulnerableMode CMP.b #$06 : BNE .exit .light_speed @@ -182,7 +203,6 @@ KillGanon: RTL ;--------------------------------------------------------------------------------------------------- - CheckForCrystalBossesDefeated: PHB : PHX : PHY @@ -220,8 +240,34 @@ CheckForCrystalBossesDefeated: SEP #$30 PLY : PLX : PLB - LDA.b Scrap00 : CMP.l NumberOfCrystalsRequiredForGanon + LDA.b Scrap00 : CMP.l GanonVulnerableTarget RTS +;--------------------------------------------------------------------------------------------------- +CheckPedestalPull: +; Out: c - Successful ped pull if set, do nothing if unset. + PHX + LDA.l PedCheckMode : ASL : TAX + JSR.w (.pedestal_modes,X) + PLX +RTL + .pedestal_modes + dw .vanilla + dw .arbitrary_cmp + + .vanilla + LDA.l PendantsField + AND.b #$07 : CMP.b #$07 : BNE ..nopull + SEC + RTS + ..nopull + CLC + RTS + + .arbitrary_cmp + LDA.l PedPullAddress : TAX + LDA.l $7E000,X + CMP.l PedPullTarget + RTS diff --git a/hooks.asm b/hooks.asm index 1e2e8cd..23a5406 100644 --- a/hooks.asm +++ b/hooks.asm @@ -496,9 +496,8 @@ PreventEnterOnBonk_BRANCH_IX: ;================================================================================ ; Crystals Mode ;-------------------------------------------------------------------------------- -org $899B7B ; <- ancilla_init.asm : 4136 (LDA $7EF37A : AND.b #$7F : CMP.b #$7F) -JSL CheckEnoughCrystalsForTower : NOP #4 -db $90 ; BCC +org $899B7F ; <- ancilla_init.asm : 4136 (LDA $7EF37A : AND.b #$7F : CMP.b #$7F) +JSL CheckTowerOpen : BCC $899B6D ;-------------------------------------------------------------------------------- org $88CE0C ; <- 44E0C - ancilla_break_tower_seal.asm : 168 (BEQ #$03 : JSR BreakTowerSeal_ExecuteSparkles : LDX.b #$06) JML GetRequiredCrystalsForTower : NOP #3 @@ -549,6 +548,8 @@ JSL GoalItemGanonCheck org $86F2EA ; <- 372EA - Bank06.asm : 5791 (LDA $0E20, X : CMP.b #$D6 : BCS .no_collision) JSL CheckGanonHammerDamage : NOP ;-------------------------------------------------------------------------------- +org $858922 +JSL.l CheckPedestalPull : BCC MasterSword_InPedestal_exit ;================================================================================ ; Stat Hooks diff --git a/inventory.asm b/inventory.asm index 18c0f85..d1a87c7 100644 --- a/inventory.asm +++ b/inventory.asm @@ -168,6 +168,7 @@ AddInventory: RTL ShopCheck: +; TODO: If we write all shops, we can use the ShopPurchase flag instead of this LDA.b IndoorsFlag : BEQ .count LDA.w ItemReceiptMethod : CMP.b #$01 : BEQ .count LDA.w InventoryTable_properties,Y : BIT.b #$02 : BNE .count diff --git a/itemdatatables.asm b/itemdatatables.asm index 1b0c690..743def2 100644 --- a/itemdatatables.asm +++ b/itemdatatables.asm @@ -1009,7 +1009,7 @@ ItemReceiptGraphicsOffsets: dw BigDecompressionBuffer+$0080 ; 38 - Blue pendant dw BigDecompressionBuffer+$0080 ; 39 - Red pendant dw BigDecompressionBuffer+$0920 ; 3A - Tossed bow - dw BigDecompressionBuffer+$08E0 ; 3B - Silvers + dw BigDecompressionBuffer+$08E0 ; 3B - Silver bow dw BigDecompressionBuffer+$09A0 ; 3C - Full bottle (bee) dw BigDecompressionBuffer+$0960 ; 3D - Full bottle (fairy) dw BigDecompressionBuffer+$18C0 ; 3E - Boss heart diff --git a/newitems.asm b/newitems.asm index ff67b88..9716321 100644 --- a/newitems.asm +++ b/newitems.asm @@ -280,7 +280,9 @@ ItemBehavior: RTS .silversbow + LDA.l BowTracking : ORA.b #$80 : STA.l BowTracking LDA.l SilverArrowsUseRestriction : BNE + + LDA.l BowTracking : ORA.b #$40 : STA.l BowTracking LDA.b #03 : STA.l BowEquipment ; set bow to silver + LDA.b #$01 : STA.l BowEquipment @@ -322,22 +324,36 @@ ItemBehavior: JMP.w .increment_map .bow_and_arrows - LDA.l BowTracking : BIT.b #$40 : BEQ + - LDA.l SilverArrowsUseRestriction : BNE + - LDA.b #03 : STA.l BowEquipment ; set bow to silver + LDA.b #$80 : ORA.l BowTracking : STA.l BowTracking + LDA.l BowTracking : BIT.b #$40 : BEQ .no_silvers + LDA.l SilverArrowsUseRestriction : BNE .no_silvers + LDA.l CurrentArrows : BEQ + + LDA.b #04 : STA.l BowEquipment + BRA .store_bow + + + LDA.b #$03 + BRA .store_bow + .no_silvers + LDA.l CurrentArrows : BEQ + + LDA.b #02 + BRA .store_bow + + LDA.b #$01 + .store_bow + STA.l BowEquipment RTS .silver_bow - LDA.b #$40 : ORA.l BowTracking : STA.l BowTracking + LDA.b #$80 : ORA.l BowTracking : STA.l BowTracking LDA.l SilverArrowsUseRestriction : BNE .noequip - LDA.l SilverArrowsAutoEquip : AND.b #$01 : BEQ .noequip - LDA.l ArrowsFiller : BNE + ; check arrows - LDA.b #$03 : BRA ++ ; bow without arrow - + - LDA.b #$04 ; bow with arrow - ++ - STA.l BowEquipment + LDA.b #$40 : ORA.l BowTracking : STA.l BowTracking + LDA.l SilverArrowsAutoEquip : AND.b #$01 : BEQ .noequip + LDA.l CurrentArrows : BNE + ; check arrows + LDA.b #$03 : BRA ++ ; bow without arrow + + + LDA.b #$04 ; bow with arrow + ++ + STA.l BowEquipment .noequip RTS @@ -405,15 +421,15 @@ ItemBehavior: RTS .silver_arrows - LDA.l BowTracking : ORA.b #$40 : STA.l BowTracking LDA.l SilverArrowsUseRestriction : BNE ++ - LDA.l SilverArrowsAutoEquip : AND.b #$01 : BEQ ++ - LDA.l BowEquipment : BEQ ++ : CMP.b #$03 : !BGE + - !ADD.b #$02 : STA.l BowEquipment ; switch to silver bow - + - ++ + LDA.l BowTracking : ORA.b #$40 : STA.l BowTracking + LDA.l SilverArrowsAutoEquip : AND.b #$01 : BEQ ++ + LDA.l BowEquipment : BEQ ++ : CMP.b #$03 : !BGE + + !ADD.b #$02 : STA.l BowEquipment ; switch to silver bow + + + ++ LDA.l ArrowMode : BEQ + - LDA.b #$01 : STA.l ArrowsFiller + LDA.b #$01 : STA.l CurrentArrows + RTS @@ -819,10 +835,10 @@ HandleBowTracking: CMP.b #$65 : BEQ .prog_two RTS .prog_one - LDA.b #$80 + LDA.b #$90 BRA .done .prog_two - LDA.b #$20 + LDA.b #$A0 .done ORA.l BowTracking : STA.l BowTracking LDA.w ItemReceiptID diff --git a/sram.asm b/sram.asm index 2ff50d3..92b93df 100644 --- a/sram.asm +++ b/sram.asm @@ -177,8 +177,9 @@ InventoryTracking: skip 2 ; - - - - - - o q b r m p n s k f (bitfield) ; p = Magic Powder | n = Mushroom Past | s = Shovel ; k = Inactive Flute | f = Active Flute | o = Any bomb acquired ; q = Quickswap locked -BowTracking: skip 2 ; b s p - - - - - - - - - - - - - (bitfield) - ; b = Bow | s = Silver Arrows Upgrade | p = Second Progressive Bow +BowTracking: skip 2 ; b s p f - - - - - - - - - - - - (bitfield) + ; b = Any Bow | s = Silver Arrows Upgrade | p = Second Progressive Bow + ; f = First progressive bow ; The front end writes two distinct progressive bow items. p ; indicates whether the "second" has been found independent of ; the first @@ -314,11 +315,12 @@ MagicCounter: skip 2 ; Magic used by player (16-bit integer) HighestMail: skip 1 ; Highest mail level SmallKeyCounter: skip 1 ; Total Number of small keys collected (integer) HeartPieceCounter: skip 1 ; Total Number of heartpieces collected (integer) -CrystalCounter: skip 1 ; Total Number of crystals collected (integer) +skip 1 ; Unused DungeonsCompleted: skip 2 ; Bitfield indicating whether a dungeon's prize has been collected. ; This has the same shape as the dungeon item bitfields. MapCountDisplay: skip 2 ; -skip 42 ; Unused +CrystalCounter: skip 2 ; Total Number of crystals collected (integer) +skip 40 ; Unused ServiceSequence: ; See servicerequest.asm ServiceSequenceRx: skip 8 ; Service sequence receive ServiceSequenceTx: skip 8 ; Service sequence transmit @@ -594,9 +596,9 @@ endmacro %assertSRAM(HighestMail, $7EF46E) %assertSRAM(SmallKeyCounter, $7EF46F) %assertSRAM(HeartPieceCounter, $7EF470) -%assertSRAM(CrystalCounter, $7EF471) %assertSRAM(DungeonsCompleted, $7EF472) %assertSRAM(MapCountDisplay, $7EF474) +%assertSRAM(CrystalCounter, $7EF476) ;-------------------------------------------------------------------------------- %assertSRAM(ServiceSequence, $7EF4A0) %assertSRAM(ServiceSequenceRx, $7EF4A0) diff --git a/tables.asm b/tables.asm index 816dd84..17ad2f6 100644 --- a/tables.asm +++ b/tables.asm @@ -132,21 +132,7 @@ org $B0803D ; PC 0x18003D PersistentFloodgate: db $00 ; #$00 = Off (default) - #$01 = On ;-------------------------------------------------------------------------------- -org $B0803E ; PC 0x18003E -InvincibleGanon: -db $00 -; #$00 = Off (default) -; #$01 = On -; #$02 = Require All Dungeons -; #$03 = Require "NumberOfCrystalsRequiredForGanon" Crystals and Aga2 -; #$04 = Require "NumberOfCrystalsRequiredForGanon" Crystals -; #$05 = Require "GoalItemRequirement" Goal Items -; #$06 = Light Speed -; #$07 = Require All Crystals and Crystal Bosses -; #$08 = Require All Crystal Bosses only -; #$09 = Require All Dungeons No Agahnim -; #$0A = Require 100% Item Collection -; #$0B = Require 100% Item Collection and All Dungeons +org $B0803E ; PC 0x18003E (unused) ;-------------------------------------------------------------------------------- org $B0803F ; PC 0x18003F HammerableGanon: @@ -247,12 +233,7 @@ CrystalPendantFlags_2: ;Aga1: $01 ;Aga2: $02 ;-------------------------------------------------------------------------------- -org $B0805E ; PC 0x18005E - Number of crystals required to enter GT -NumberOfCrystalsRequiredForTower: -db $07 ; #$07 = 7 Crystals -org $B0805F ; PC 0x18005F - Number of crystals required to kill Ganon -NumberOfCrystalsRequiredForGanon: -db $07 ; #$07 = 7 Crystals +org $B0805E ; PC 0x18005E - 0x18005F (Unused) ;-------------------------------------------------------------------------------- org $B08060 ; PC 0x180060 - 0x18007E ProgrammableItemLogicJump_1: @@ -936,14 +917,42 @@ org $B08195 ; PC 0x180195 ByrnaCaveSpikeDamage: db $08 ; #$08 = 1 Heart (default) - #$02 = 1/4 Heart ;-------------------------------------------------------------------------------- -org $B08196 ; PC 0x180196-0x180197 +org $B08196 ; PC 0x180196-0x180197 TotalItemCount: ; Total item count for HUD. Only counts items that use "item get" animation. dw $00D8 ; 216 -org $B08198 ; PC 0x180198-0x180199 -GanonsTowerOpenAddress: ; Target address for GT open check +org $B08198 ; PC 0x180198-0x1801A9 +GanonsTowerOpenAddress: ; 0x180198-0x180199 +dw CrystalCounter ; Target address for GT open check +GanonsTowerOpenTarget: ; 0x18019A-0x18019B +dw $0007 ; Target amount for GT open modes to compare +GanonsTowerOpenMode: ; 0x18019C-0x18019D +dw $0001 ; $00 = Vanilla | $01 = Compare target with address +PedPullAddress: ; 0x18019E-0x18019F +dw PendantCounter ; Target address for ped pull check +PedPullTarget: ; 0x1801A0-0x1801A1 +dw $0003 ; Target amount for ped pull modes to check +PedCheckMode: ; 0x1801A2-0x1801A3 +dw $0000 ; $00 = vanilla | $01 = Compare address to target value +GanonVulnerableAddress: ; 0x1801A4-0x1801A5 +dw CrystalCounter ; Target address for ped pull check +GanonVulnerableTarget: ; 0x1801A6-0x1801A7 +dw $0007 ; Target amount for Ganon vulnerability modes to compare +GanonVulnerableMode: ; 0x1801A8-0x1801A9 +dw $0000 ; #$00 = Off (default) + ; #$01 = On + ; #$02 = Require All Dungeons + ; #$03 = Require "GanonVulnerableTarget" Crystals and Aga2 + ; #$04 = Require "GanonVulnerableTarget" Crystals + ; #$05 = Require "GoalItemRequirement" Goal Items + ; #$06 = Light Speed + ; #$07 = Require All Crystals and Crystal Bosses + ; #$08 = Require All Crystal Bosses only + ; #$09 = Require All Dungeons No Agahnim + ; #$0A = Require 100% Item Collection + ; #$0B = Require 100% Item Collection and All Dungeons ;-------------------------------------------------------------------------------- -; 0x180196 - 0x1801FF (unused) +; 0x18019A - 0x1801FF (unused) ;================================================================================ org $B08200 ; PC 0x180200 - 0x18020B RedClockAmount: diff --git a/utilities.asm b/utilities.asm index 97b37f8..380baa4 100644 --- a/utilities.asm +++ b/utilities.asm @@ -84,6 +84,7 @@ LoadDynamicTileOAMTable: .narrow REP #$20 LDA.w #$0004 : STA.l SpriteOAM + LDA.w #$0000 : STA.l SpriteOAM+2 LDA.w #$0200 : STA.l SpriteOAM+6 LDA.w #$0400 : STA.l SpriteOAM+7 : STA.l SpriteOAM+14 diff --git a/vanillalabels.asm b/vanillalabels.asm index 85ffe34..9943358 100644 --- a/vanillalabels.asm +++ b/vanillalabels.asm @@ -39,6 +39,8 @@ Dungeon_SaveRoomQuadrantData = $82B861 LoadGearPalettes_bunny = $82FD8A LoadGearPalettes_variable = $82FD95 Filter_Majorly_Whiten_Color = $82FEAB +MasterSword_InPedestal = $858908 +MasterSword_InPedestal_exit = $85894C Ancilla_SpawnFallingPrize = $85A51D Sprite_DrawMultiple = $85DF6C Sprite_DrawMultiple_quantity_preset = $85DF70