Code:
;xkas 0.06
hirom
;header
;Stop - set
org $C24680
LDA #$48 ;Time until Stop wears off x 4
;Called whenever battle timer is incremented.
;Handles various time-based events for entities. Advances their timers, does
;periodic damage/healing from Poison/Regen/etc., checks for running, and more.
;(assassin's Premature Continuation Fix included)
org $C25A83
timed_events:
LDA $3A91 ;Lower byte of battle time counter equivalent
INC $3A91 ;increment that counter equiv.
AND #$0F
CMP #$0A
BCS .other ;Branch if lower nibble of time counter was >= #$0A
;otherwise, A now corresponds to one of the 10
;onscreen entities.
ASL
TAX
LDA $3AA0,X
LSR
BCC .exit ;Exit if entity not present in battle
;Stop block, relocated
LDA $3AF1,X ;Get Stop timer, originally set to #$12
;at C2/467D
BEQ .noStop ;Branch if it's 0, as that *should* mean the
;entity is not stopped.
DEC $3AF1,X ;Decrement Stop timer
BNE .exit ;did it JUST run down on this tick? if not, exit
;Premature Continuation Fix
JMP expire_Stop ;go set up Stop to wear off
NOP ;Note that I could have fit the entire patch in this
;function with "STA $B8 / BRA $5B30", but the latter
;instruction would've been so cheap and ugly that I'd
;have had to kill myself.
.noStop
;End of Stop block
CLC
LDA $3ADC,X ;Timer that determines how often timers and time-based
;events will countdown and happen for this entity.
ADC $3ADD,X ;Add ATB multiplier (set at C2/09D2: 64 normally,
;32 if Slowed, 84 if Hasted)
STA $3ADC,X
BCC .exit ;Exit if timer didn't meet or exceed 256
LDA $3AA0,X
BIT #$10 ;is entity Wounded, Petrified, or Stopped, or is
;somebody else under the influence of Quick?
BNE .exit ;Exit if any are true
LDA $3B05,X ;Condemned counter - originally set at 09B4.
;To be clear, this counter is "one off" from the
;actual numerals you'll see onscreen:
;00 value = numerals disabled
;01 value = numerals at "00", 02 = "01", 03 = "02", etc
CMP #$02
BCC .l_5AC9 ;Branch if counter < 2. [i.e. numerals < "01",
;meaning they're "00" or disabled.]
DEC
STA $3B05,X ;decrement counter
DEC ;just think of this second "DEC" as an optimized
;"CMP #$01", as we're not altering the counter.
BNE .l_5AC9 ;Branch if counter now != 1 [i.e. numerals != "00"]
JSR $5BC7 ;Cast Doom when countdown numerals reach 0
.l_5AC9
JSR $5C1B ;Check if character runs from combat
JSR $5B4F ;Trigger Poison, Seizure, Regen, Phantasm, or
;Tentacle Drain damage
TDC
JSR dec_timers ;Decrement Reflect, Freeze, and Sleep timers if
;applicable, and check if any have worn off
INC $3AF0,X ;advance this entity's pointer to the next entry
;in the 5AEA function table
LDA $3AF0,X
TXY ;preserve X in Y
AND #$07 ;convert it to 0-7, wrapping as necessary
ASL
TAX
JMP ($5AEA,X) ;determine which periodic/damage healing type
;will be checked on this entity's next tick.
.other
SBC #$0A ;should only be reached if $3A91 AND 15 was >= 10
;[i.e. not corresponding to any specific entity]
;at start of function. now subtract 10.
ASL
TAX
JMP ($5AFA,X)
TYX ;restore X from Y
.exit
RTS
org $C25B06
dec_timers:
org $C25B36
queue_removal:
;assassin's patch
;Set to check for Poison on this entity's next tick
org $C25B3B
LDA #$10
BRA reuse ;finish this function's work by using its near-twin's
;code.
;Added code to mark Stop for removal upon its timer's expiration
expire_Stop:
STA $B8 ;flag Stop for removal)
BRA queue_removal ;queue Stop to be removed. but leave Reflect, Freeze,
;and Sleep timers untouched. let them resume on the
;next tick, just like the entity's Condemned countdown
;and periodic Regen/Seizure/etc. do, which is the
;sensible behavior. after all, time is supposed to
;unfreeze *after* Stop wears off.
NOP
RTS ;Never reached, but just in case
;Set to check for Regen, Seizure, Phantasm on this entity's next tick
;(identical results to original function, but reordered slightly)
LDA #$08
reuse:
TYX
ORA $3E4C,X
STA $3E4C,X ;Set bit 3 of $3E4C,X . or bit 4 if we
;reached here from Function C2/5B3B.
RTS