Users browsing this thread: 1 Guest(s)
Possible solution to the sap death bug
Hey, didn't mean to step on your toes -- if it weren't for your C2 disassembly, there's pretty much no way I'd even have started learning asm in the first place, much less started trying to patch bugs! So you really have my gratitude.
Could you walk me through some of the pitfalls of the simpler approach I posted above? I saw in your code that you ensured these "death override" counters use the limited script functionality (i.e. >= FC only), which is definitely something that I overlooked. But aside from that, can you help me figure out a scenario where my patch would fail?
I also am wondering whether your patch at $4CA2 would have any effect at all. Under what circumstance would a "normal" attack be preparing its counterattacks while the counterattack queue had pending periodic damage? Wouldn't the counterattack queue have to be empty before the "normal" attack queue got checked?
Edit: With regard to the limited script handling I overlooked, I think this may do the trick:
The above code will cause $33FE to only be flagged for regular attacks, which will ensure counters/periodic damage always use the limited reaction script.
Alternate code approach that doesn't require freespace:
OK, I thought through the above, and figured out a scenario that would break. If an attack triggers a counterattack from Enemy A, and Enemy B gets a sap queued while the attack executes, then if Enemy A's reaction targets Enemy B, then the pending Sap tick will prevent Enemy B from queuing its reactive script, even if it is killed by the counterattack. (Edit: On second thought, this would still function correctly, as Enemy B's next Sap tick will trigger its reactive script, due to $3A56).
My next thought is -- why not remove the check at $4CA2 altogether? If a duplicate reaction script is queued, it will inevitably be aborted due to the $33FC flag. And the $3A56 flag will only override the $33FC flag once (per my changes above).
Could you walk me through some of the pitfalls of the simpler approach I posted above? I saw in your code that you ensured these "death override" counters use the limited script functionality (i.e. >= FC only), which is definitely something that I overlooked. But aside from that, can you help me figure out a scenario where my patch would fail?
I also am wondering whether your patch at $4CA2 would have any effect at all. Under what circumstance would a "normal" attack be preparing its counterattacks while the counterattack queue had pending periodic damage? Wouldn't the counterattack queue have to be empty before the "normal" attack queue got checked?
Edit: With regard to the limited script handling I overlooked, I think this may do the trick:
Code:
org $C24C80 : JSR LimitCodes
org !free_space
LimitCodes:
LDA $B1 ; attack flags
LSR ; carry: non-normal attack
TDC ; zero A
BCS .exit ; exit without bit if non-normal attack
LDA $3018,X ; else, exit with target unique bit
.exit
RTS
The above code will cause $33FE to only be flagged for regular attacks, which will ensure counters/periodic damage always use the limited reaction script.
Alternate code approach that doesn't require freespace:
Code:
org $C24C68
RewritePrepare:
STZ $B8 ; zero targets for counterattack
STZ $B9 ; zero targets for counterattack
LDA $B1 ; check for "normal" attack
LSR ; carry: "non-normal" attack
BCS .skip ; branch if ^
LDA $32E0,X ; "hit by attack"
BPL .skip ; branch if not ^
ASL ; get attacker index
STA $EE ; save in scratch RAM
CPX $EE ; target === attacker?
BEQ .skip ; branch if ^
TAY ; attacker index
REP #$20 ; 16-bit A
LDA $3018,Y ; attacker unique bit
STA $B8 ; save target for counterattack
LDA $3018,X ; current target bit
TRB $33FE ; flag to use full reactive script
.skip
REP #$20 ; 16-bit A
LDA $3018,X ; current target bit
BIT $3A56 ; "died since last reactive script"
SEP #$20 ; 8-bit A
BNE .react ; branch if "died", so force script
LDA $B8 ; else, check if was attacked by normal
ORA $B9 ; ^
BEQ .next ; no counterattack if not ^
warnpc $C24C9E
padbyte $EA
pad $C24C9D
org $C24C9D
.react
org $C24CBE
.next
(12-11-2020, 01:20 AM)Bropedio Wrote: I also am wondering whether your patch at $4CA2 would have any effect at all. Under what circumstance would a "normal" attack be preparing its counterattacks while the counterattack queue had pending periodic damage? Wouldn't the counterattack queue have to be empty before the "normal" attack queue got checked?
OK, I thought through the above, and figured out a scenario that would break. If an attack triggers a counterattack from Enemy A, and Enemy B gets a sap queued while the attack executes, then if Enemy A's reaction targets Enemy B, then the pending Sap tick will prevent Enemy B from queuing its reactive script, even if it is killed by the counterattack. (Edit: On second thought, this would still function correctly, as Enemy B's next Sap tick will trigger its reactive script, due to $3A56).
My next thought is -- why not remove the check at $4CA2 altogether? If a duplicate reaction script is queued, it will inevitably be aborted due to the $33FC flag. And the $3A56 flag will only override the $33FC flag once (per my changes above).
« Next Oldest | Next Newest »
Users browsing this thread: 1 Guest(s)