Allow Ganon to be vulnerable to arbitrary item

This commit is contained in:
2021-06-26 08:11:01 -07:00
parent 8b0f0464f8
commit b8dc86d7c5
7 changed files with 218 additions and 12 deletions

View File

@@ -223,6 +223,7 @@ incsrc msu.asm
incsrc multiworld.asm incsrc multiworld.asm
incsrc terrorpin.asm incsrc terrorpin.asm
incsrc special_bombs.asm incsrc special_bombs.asm
incsrc variable_ganon_vulnerability.asm
warnpc $A58000 warnpc $A58000
;org $228000 ; contrib area ;org $228000 ; contrib area

View File

@@ -303,28 +303,57 @@ DialogGanon2:
REP #$20 REP #$20
BCS + BCS +
LDA.w #$018D : BRA ++ LDA.w #$018D : JMP .done
+ +
LDA.l GanonVulnerabilityItem : AND #$00FF : BNE .special_item
LDA.l SpecialBombs LDA.l SpecialBombs
AND.w #$00FF : BEQ + ; branch if not special bomb mode AND.w #$00FF : BNE .bombs ; bombs if special bomb mode
LDA.w #$0195 : BRA ++ .silver_arrows
+
LDA.l $7EF38E LDA.l $7EF38E
BIT.w #$0080 : BNE + ; branch if bow BIT.w #$0080 : BNE + ; branch if bow
LDA.w #$0192 : BRA ++ LDA.w #$0192 : JMP .done
+ +
BIT.w #$0040 : BEQ + ; branch if no silvers BIT.w #$0040 : BEQ + ; branch if no silvers
LDA.w #$0195 : BRA ++ LDA.w #$0195 : JMP .done
+ +
BIT.w #$0020 : BNE + ; branch if p bow BIT.w #$0020 : BNE + ; branch if p bow
LDA.w #$0194 : BRA ++ LDA.w #$0194 : JMP .done
+ +
BIT.w #$0080 : BEQ + ; branch if no bow BIT.w #$0080 : BEQ + ; branch if no bow
LDA.w #$0193 : BRA ++ LDA.w #$0193 : JMP .done
+ +
LDA.w #$016E LDA.w #$016E : JMP .done
++ .special_item
CMP.w #$0001 : BEQ .silver_arrows
CMP.w #$0004 : BEQ .bombs
CMP.w #$0005 : BEQ .powder
CMP.w #$0010 : BEQ .bee
PHX : TAX
LDA.l $7EF33F, X : PLX : AND #$00FF : BNE +
LDA.w #$0192 : JMP .done
+
LDA.w #$0195 : BRA .done
.bombs
LDA.l $7EF343 : AND #$00FF : BNE +
LDA.l $7F50C9 : AND #$00FF : BNE + ; check for infinite bombs
LDA.w #$0192 : BRA .done
+
LDA.w #$0195 : BRA .done
.powder
LDA.l $7EF38C : AND #$0010 : BNE +
LDA.w #$0192 : BRA .done
+
LDA.w #$0195 : BRA .done
.bee
LDA.l $7EF35C : AND #$00FF : CMP.w #$0007 : BEQ + : CMP.w #$0008 : BEQ +
LDA.l $7EF35D : AND #$00FF : CMP.w #$0007 : BEQ + : CMP.w #$0008 : BEQ +
LDA.l $7EF35E : AND #$00FF : CMP.w #$0007 : BEQ + : CMP.w #$0008 : BEQ +
LDA.l $7EF35F : AND #$00FF : CMP.w #$0007 : BEQ + : CMP.w #$0008 : BEQ +
LDA.w #$0192 : BRA .done
+
LDA.w #$0195 : BRA .done
.done
STA $1CF0 STA $1CF0
SEP #$20 SEP #$20
JSL.l Sprite_ShowMessageMinimal_Alt JSL.l Sprite_ShowMessageMinimal_Alt

View File

@@ -2760,3 +2760,23 @@ db $B2, $2C, $B3, $2C, $C2, $2C, $18, $2C
db $B2, $24, $B3, $24, $C2, $24, $19, $24 db $B2, $24, $B3, $24, $C2, $24, $19, $24
db $B2, $28, $B3, $28, $C2, $28, $1A, $28 db $B2, $28, $B3, $28, $C2, $28, $1A, $28
db $B2, $28, $B3, $28, $C2, $28, $1B, $28 db $B2, $28, $B3, $28, $C2, $28, $1B, $28
;--------------------------------------------------------------------------------
;================================================================================
; Variable Ganon Vulnerability
;--------------------------------------------------------------------------------
org $08BBD4 ; ancilla_magic_powder.asm@253 (LDA #$0A : JSL Ancilla_CheckSpriteDamage.preset_class)
JSL Ganon_CheckPowderVulnerability
NOP #2
;--------------------------------------------------------------------------------
org $1D8F4E ; sprite_ganon.asm@325 (LDA $04C5 : CMP #$02)
JSL Ganon_CheckInvincible
NOP
;--------------------------------------------------------------------------------
org $0DD628 ; Bank0D.asm@1266 (LDA $0B6B, Y : AND #$02)
JSL CheckBeeBoss
NOP
;--------------------------------------------------------------------------------
org $0DD677 ; Bank0D.asm@1303 (JSL Ancilla_CheckSpriteDamage.preset_class)
JSL Ganon_CheckBeeVulnerability
;--------------------------------------------------------------------------------

View File

@@ -1,9 +1,17 @@
;-------------------------------------------------------------------------------- ;--------------------------------------------------------------------------------
!ANCILLA_DAMAGE = "$06EC84" !ANCILLA_DAMAGE = "$06EC84"
!BOMB_LEVEL = "$7EF4A8" !BOMB_LEVEL = "$7EF4A8"
; start with X = sprite index, A = ancilla index ; start with X = sprite index, A = ancilla type index
;-------------------------------------------------------------------------------- ;--------------------------------------------------------------------------------
DamageClassCalc: DamageClassCalc:
PHA
LDA GanonVulnerabilityItem : BEQ +
LDA $0E20, X : CMP #$D7 : BNE +
PLA
JSL Ganon_CheckAncillaVulnerability
RTL
+
PLA
CMP #$01 : BEQ .cane CMP #$01 : BEQ .cane
CMP #$2C : BEQ .cane CMP #$2C : BEQ .cane
CMP #$31 : BEQ .cane CMP #$31 : BEQ .cane
@@ -58,11 +66,13 @@ DamageClassCalc:
PLX PLX
CMP.b #$06 : BNE .done ; not arrows CMP.b #$06 : BNE .done ; not arrows
LDA $7EF340 : CMP.b #$03 : !BGE .actual_silver_arrows LDA $7EF340 : CMP.b #$03 : !BGE .actual_silver_arrows
.normal_arrows
LDA #$06 LDA #$06
.done .done
RTL RTL
.actual_silver_arrows .actual_silver_arrows
LDA $0E20, X : CMP.b #$D7 : BNE + LDA $0E20, X : CMP.b #$D7 : BNE +
LDA SpecialBombs : BNE .normal_arrows
LDA #$20 : STA $0F10, X LDA #$20 : STA $0F10, X
+ +
LDA #$09 LDA #$09
@@ -195,6 +205,7 @@ Utility_CheckImpervious:
LDA $0CF2 : CMP #$FF : BEQ .impervious ; special "always-impervious" class LDA $0CF2 : CMP #$FF : BEQ .impervious ; special "always-impervious" class
LDA $0E20, X : CMP.b #$CC : BEQ .sidenexx : CMP.b #$CD : BEQ .sidenexx LDA $0E20, X : CMP.b #$CC : BEQ .sidenexx : CMP.b #$CD : BEQ .sidenexx
LDA $0301 : AND.b #$0A : BEQ .not_impervious ; normal behavior if not hammer LDA $0301 : AND.b #$0A : BEQ .not_impervious ; normal behavior if not hammer
JSL Ganon_CheckHammerVulnerability : BCS .not_impervious
LDA.l SpecialBombs : BEQ .not_impervious LDA.l SpecialBombs : BEQ .not_impervious
LDA $0E20, X : CMP.b #$1E : BEQ .not_impervious ; crystal switch LDA $0E20, X : CMP.b #$1E : BEQ .not_impervious ; crystal switch
CMP.b #$40 : BEQ .not_impervious ; aga barrier CMP.b #$40 : BEQ .not_impervious ; aga barrier

View File

@@ -149,7 +149,17 @@ CheckGanonHammerDamage:
LDA $0E20, X : CMP.b #$D8 ; original behavior except ganon LDA $0E20, X : CMP.b #$D8 ; original behavior except ganon
RTL RTL
+ +
LDA.l GanonVulnerabilityItem : CMP.b #$0C : BEQ +
LDA $0E20, X : CMP.b #$D6 ; original behavior LDA $0E20, X : CMP.b #$D6 ; original behavior
RTL
+
LDA $0E20, X : CMP.b #$D8 : BCC +
RTL
+
CMP.b #$D6 : BNE +
RTL
+
CLC
RTL RTL
;================================================================================ ;================================================================================
GetSmithSword: GetSmithSword:

View File

@@ -98,7 +98,11 @@ db #$02 ; #$02 = Tempered Sword (default)
;org $05EBD4 ; PC 0x2EBD4 - sprite_zelda.asm:23 - (LDA $7EF359 : CMP.b #$02 : BCS .hasMasterSword) - Zelda Spawnpoint Sword Check ;org $05EBD4 ; PC 0x2EBD4 - sprite_zelda.asm:23 - (LDA $7EF359 : CMP.b #$02 : BCS .hasMasterSword) - Zelda Spawnpoint Sword Check
;db #$05 ; #$02 = Tempered Sword (default) - #$05 = All Swords ;db #$05 ; #$02 = Tempered Sword (default) - #$05 = All Swords
;-------------------------------------------------------------------------------- ;--------------------------------------------------------------------------------
; 0x18002B- 0x18002E (Unused) ; 0x18002B- 0x18002D (Unused)
;--------------------------------------------------------------------------------
org $30802E ; PC 0x18003E
GanonVulnerabilityItem:
db #$00 ; #$00 = Default behavior (silver arrows)
;-------------------------------------------------------------------------------- ;--------------------------------------------------------------------------------
org $30802F ; PC 0x18003F org $30802F ; PC 0x18003F
SpecialBombs: SpecialBombs:

View File

@@ -0,0 +1,131 @@
;--------------------------------------------------------------------------------
!ANCILLA_DAMAGE = "$06EC84"
; start with X = sprite index, A = ancilla type index
;--------------------------------------------------------------------------------
Ganon_CheckAncillaVulnerability:
PHA
LDA $0EE0, X : BNE .not_vulnerable_pla
PLA
PHX : PHA
LDA.l GanonVulnerabilityItem
TAX : PLA
CMP.l Ganon_CheckByAncilla, X : BNE +
PLX : BRA .vulnerable
+
PLX : PHA
LDA.l GanonVulnerabilityItem
CMP #$01 : BEQ .silver_arrows
CMP #$11 : BEQ .somaria
BRA .not_vulnerable_pla
.silver_arrows
PLA : CMP #$09 : BNE .not_vulnerable
LDA $7EF340 : CMP.b #$03 : !BGE +
LDA #$09 : BRA .not_vulnerable
+
BRA .vulnerable
.hammer
BRA .not_vulnerable_pla ; NYI
.golden_bee
BRA .not_vulnerable_pla ; NYI
.somaria
PLA : CMP #$01 : BEQ .vulnerable
CMP #$2C : BEQ .vulnerable
BRA .vulnerable
.vulnerable
PHX
LDA.l GanonVulnerabilityItem
TAX
LDA.l Ganon_IFrameDuration, X
PLX
STA $0EE0, X ; give the poor pig some iframes
LDA #$20 : STA $0F10, X
LDA #$09
RTL
.not_vulnerable_pla
PLA
.not_vulnerable
PHX : TAX
LDA.l !ANCILLA_DAMAGE, X
PLX
RTL
; end with X = sprite index, A = damage class
;--------------------------------------------------------------------------------
!ANCILLA_CHECK_SPRITE_DAMAGE_PRESET_CLASS = "$06ECE6"
;--------------------------------------------------------------------------------
Ganon_CheckPowderVulnerability: ; we know it's powder
LDA.l GanonVulnerabilityItem : CMP #$05 : BNE .normal ; ganon not vulnerable to powder
LDA $0E20, X : CMP #$D7 : BNE .normal ; not stunned ganon
LDA $0EE0, X : BNE .normal ; ganon has iframes
LDA.l Ganon_IFrameDuration+$05
STA $0EE0, X ; give the poor pig some iframes
LDA #$20 : STA $0F10, X
LDA #$09
BRA .done
.normal
LDA.b #$0A
.done
JSL.l !ANCILLA_CHECK_SPRITE_DAMAGE_PRESET_CLASS
RTL
;--------------------------------------------------------------------------------
Ganon_CheckBeeVulnerability: ; we know it's a bee
LDA.l GanonVulnerabilityItem : CMP #$10 : BNE .normal ; ganon not vulnerable to bee
LDA $0E20, X : CMP #$D7 : BNE .normal ; not stunned ganon
LDA $0EE0, X : BNE .normal ; ganon has iframes
LDA.l Ganon_IFrameDuration+$10
STA $0EE0, X ; give the poor pig some iframes
LDA #$20 : STA $0F10, X
LDA #$09
BRA .done
.normal
LDA.b #$0A
.done
JSL.l !ANCILLA_CHECK_SPRITE_DAMAGE_PRESET_CLASS
RTL
;--------------------------------------------------------------------------------
Ganon_CheckInvincible:
LDA $04C5 : CMP.b #$02 : BEQ .not_transparent
LDA $0E20, X : CMP #$D7 : BNE .transparent ; non-stunned ganon
LDA $0301 : AND.b #$0A : BEQ .transparent ; normal behavior if not hammer
LDA.l GanonVulnerabilityItem : CMP #$0C : BNE .transparent ; ganon not vulnerable to hammer
.not_transparent
LDA #$00 : RTL
.transparent
LDA #$01 : RTL
; return non-zero A if ganon should be invincible
;--------------------------------------------------------------------------------
Ganon_CheckHammerVulnerability: ; we know it's hammer
LDA.l GanonVulnerabilityItem : CMP #$0C : BNE .normal ; ganon not vulnerable to hammer
LDA $0E20, X : CMP #$D7 : BNE .normal ; not stunned ganon
LDA $0EE0, X : BNE .normal ; ganon has iframes
LDA.l Ganon_IFrameDuration+$0C
STA $0EE0, X ; give the poor pig some iframes
LDA #$20 : STA $0F10, X
LDA #$09 : STA $0CF2 ; set damage class to silver
SEC : RTL
.normal
CLC : RTL
; return carry set bit if stunned Ganon and Ganon vulnerable to hammer
;--------------------------------------------------------------------------------
CheckBeeBoss:
; Y is sprite index
LDA.l GanonVulnerabilityItem : CMP #$10 : BNE .normal ; ganon not vulnerable to bee
LDA $0E20, Y : CMP #$D7 : BNE .normal ; not stunned ganon
LDA #$00 : RTL
.normal
LDA $0B6B, Y : AND.b #$02
RTL
; return non-zero A if entity is a boss (and bee should not attack)
;--------------------------------------------------------------------------------
Ganon_CheckByAncilla:
db #$00 ; default behavior--we shouldn't be checking the table here anyway
db #$00, #$05, #$1F, #$07, #$00
db #$02, #$0B, #$19, #$18, #$1C
db #$00, #$00, #$00, #$00, #$00
db #$00, #$00, #$31, #$00, #$00
Ganon_IFrameDuration:
db #$00 ; default behavior--we shouldn't be here anyway
db #$00, #$00, #$00, #$34, #$00
db #$00, #$00, #$00, #$00, #$00
db #$00, #$00, #$00, #$00, #$00
db #$00, #$00, #$00, #$00, #$00
;--------------------------------------------------------------------------------