-
Content count
149 -
Joined
-
Last visited
-
Days Won
26
Posts posted by seibaby
-
-
Include a music change to AI command FA 06 (characters run left)
@Synchysi this replaces the SrBehemoth fix from Madsiur
; Animation script $025C: Misc. Monster Animation $06: Characters Run Right to Left (bg1) ; Include a change to boss battle music hirom ;header !freespace = $D0CF4A ; Requires 18 bytes in bank D0 ; Relocate animation script org !freespace anim_script_025c: db $00,$20 ; speed 1, align to center of character/monster db $D1,$01 ; invalidate character/monster sprite priority db $C7,$0B,$10,$14,$FF ; SPC command $10, $14, $FF (play boss music) db $89,$37 ; loop start (55 times) db $80,$79 ; command $80/$79 db $0F ; [$0F] db $8A ; loop end db $80,$7B ; command $80/$7B db $FF ; end of script ; Update the pointer org $D1EF90 dw anim_script_025c
-
Scan doesn't trigger counters
NOTE: I'm unsure of whether this conflicts with @darknil's scan code. Anyway, just find a way to fit a STZ $341A in the Scan target effect code.
;No Scan counters hirom ;header !freespace = $C2xxxx ; Requires 6 bytes of free space in C2 ; Scan effect org $C23C5B JSR clearCounterVar ; X-Zone, etc org $C23C8C C23C8C: STZ $341A ; Clear variable that enables counterattacks C23C8F: RTS ; New code org !freespace clearCounterVar: LDA $3C80,Y ; (Moved code) JMP C23C8C ; Go to X-Zone, etc code
-
Tank & Spank 1.1beta
There was an issue in Tank & Spank where Love Token would be prevented by Blind/Berserk/Image just like Cover is. This should fix it.
NOTE: the free space requirements have changed and the freespace defines needs to be set up again. The main part of the code now requires 114 damn bytes. I set the define for it it to the newly freed up chunk where the Rage table used to be, for testing.;Tank & Spank (previously Cover Knight and Smart Cover) ;by Seibaby ;v1.01 - Fixed a bug with Love Token being prevented by Image, Dark, and Berserk ;v1.0 - Only allows back row targets for Stamina-based cover ; Disables Cover when Dancing ;v0.9 - Disables Interceptor and halves Evasion when Covering ;v0.7 - Fixes a bug where Knight wouldn't reset Defending stance when Covering ;v0.6 - New Smart Cover logic ; Some Cover nerfs ;v0.5 - Fixes an issue with Knights not taking targets' statuses into ; account (Image and Clear, but also Zombie and Petrify) ;v0.4 - Fixes a bug causing Knights to Cover monsters attacking other ; monsters ;v0.3 - Adds an exception to not trigger Cover if the Knight is Near Fatal ; and the target is healthy. ;v0.2 - Fixes a bug that caused the wrong statuses (on the target) to be ; considered for whether or not to disable True Knight. ;Changes the True Knight effect to trigger with a Stamina / 192 chance even if ;the target isn't in Near Fatal status. ;New Smart Cover patch, which disables True Knight for all attacks ;originating from a player character, unless that character is uncontrollable, ;in which case it will only disable it if the attack comes from a healing weapon, ;or if the weapon is elemental and the target absorbs/nullifies that element. ;It also considers a few extra statuses for purposes of disabling True Knight. ;ON TARGET: Death, Petrify, Zombie, Magitek, and Image ; (in addition to Clear) ;ON KNIGHT: Dark, Magitek, Image, Berserk ; (in addition to Death, Petrify, Clear, Zombie, Sleep, and Muddled) ;xkas 0.06 hirom ;header !smartCover = $C2FAD0 ;Requires 114 bytes of free space !halveEvade = ;Requires 20 bytes of free space !noDogBlock = ;Requires 9 bytes of free space ;A few notes on the changes made to these functions: ;Entering this function, A is 16-bit and X/Y are 8-bit. Register width is ;never changed and the call following this function doesn't care about Carry, ;so I have removed a bunch of useless PHP/PLP and REP #$20 throughout, to make ;room for the new code. ;I have also removed some code related to monsters using True Knight, which was ;supported in vanilla, but unused (and remains so in BNW). The check for if the ;bodyguard was Controlled was also removed (doubly useless). org $C2123A exit: ;True Knight and Love Token org $C2123B trueKnightAndLoveToken: PHX LDA $B2 BIT #$0002 ;Is "No critical and Ignore True Knight" set? BNE .exit ;Exit if so LDA $B8 ;intended target(s). to my knowledge, there's only ;one intended target set if we call this function.. JMP smartCover macro smartCover() print "Writing smartCover() to ",pc reset bytes smartCover: BEQ .exit ;Exit if none LDY #$FF STY $F4 ;default to no bodyguards. JSR $51F9 ;Y = index of our highest intended target. ;0, 2, 4, or 6 for characters. 8, 10, 12, 14, 16, ;or 18 for monsters. STY $F8 ;save target index STZ $F2 ;Highest Bodyguard HP So Far = 0. this makes the ;first eligible bodyguard we check get accepted. ;later ones may replace him/her if they have more ;HP. PHX LDX $336C,Y ;Love Token - which target takes damage for you BMI .noLove ;Branch if none do JSR evalKnight_skip ;consider this target as a bodyguard (skip Stamina ;and Near Fatal checks) JSR newTarget ;if it was valid, make it intercept the attack .noLove PLX LDA $3A36 BNE .exit ;Exit if Golem is active CPX #$08 ;Check attacker BCS .status ;Branch if attacker is a monster CPX $F8 BEQ .exit ;Exit if Attacker = Target LDA $3EE4,X ;Attacker status byte 1-2 BIT #$2002 BNE .heals ;Branch if Muddled or Zombied LDA $3394,X ;Check if Attacker is Charmed BMI .exit ;If not Muddled, Zombied, or Charmed, this ;attack was initiated by the player, so exit .heals LDA $11A9 ;Special weapon property AND #$00FF ;Isolate bottom byte CMP #$0018 ;Check "Curative Attributes" BEQ .exit ;Exit if set SEP #$20 LDA $11A1 ;Attack element(s) PHA XBA PLA ;Copy to high byte REP #$20 AND $3BCC,Y ;Target absorbed/immune elements BNE .exit ;If any absorbed or nullified, exit .status LDA $3EE4,Y ;Target status byte 1-2 BIT #$04DA BNE .exit ;Branch if Death, Petrify, Clear, Zombie, Magitek, ;or Image .seize LDA $3358,Y ;$3359 = who is Seizing you BPL .exit ;Branch if target is seized LDA #$000F ;Load all characters as potential bodyguards .cover CPY #$08 BCC .saveBg ;Branch if target is character TDC ;Null all potential bodyguards .saveBg STA $F0 ;Save potential bodyguards LDA $3018,Y ;bit representing target ORA $3018,X ;bit representing attacker TRB $F0 ;Clear attacker and target from potential ;bodyguards JMP trueKnightAndLoveToken_contd .exit PLX RTS print "smartCover: ",bytes," bytes written, ending at ",pc endmacro .contd LDX #$12 .loop LDA $3C57,X ;High byte = Relic Effects 3 ASL #2 ;Check bit 6 (True Knight) BCC .next ;Branch if no True Knight effect LDA $3018,X BIT $F0 BEQ .next ;Branch if this candidate isn't on the same ;team as the target JSR evalKnight ;consider them as candidate bodyguard. if they're ;valid and their HP is >= past valid candidates, ;they become the new frontrunner. .next DEX DEX BPL .loop ;Do for all characters and monsters LDA $F2 BEQ .exit ;Exit if no bodyguard found [or if the selfless ;soul has 0 HP, which shouldn't be possible outside ;of bugs]. JSR newTarget ;make chosen bodyguard -- provided there was one -- ;intercept attack. if somebody's already been ;slated to intercept it [i.e. due to Love Token], ;the True Knight will sensibly defer to them. .exit PLX RTS ;Make chosen bodyguard intercept attack, provided one hasn't been marked to do ;so already. newTarget: LDX $F4 BMI .exit ;exit if no bodyguard found CPY $F8 BNE .exit ;exit if $F8 no longer points to the original ;target, which means we've already assigned a ;bodyguard with this function. STX $F8 ;save bodyguard's index STY $A8 ;save intended target's index LSR $A8 ;.. but for the latter, use 0,1,2,etc rather ;than 0,2,4,etc LDA $3018,X STA $B8 ;save bodyguard as the new target of attack SEP #$20 LDA $3AA1,X BIT #$02 BEQ .noDef ;Branch if not Defending JSR $0A41 ;Clear Defending flag JSR $0A3C ;Relax Defending pose .noDef REP #$20 .exit RTS ;Consider candidate bodyguard for True Knight or Love Token evalKnight: LDA #$0020 BIT $3AA1,X BNE .exit ;Exit if guard is in back row LDA $3EE5,Y ;Low byte = Status byte 2 LSR #2 ;Check bit 1 (Near Fatal) BCS .skip ;Skip Stamina check if target Near Fatal LDA $3AA1,Y BIT #$0020 BEQ .exit ;Exit if target is in back row LDA $3EE5,X ;Knight's Status byte 2 LSR #2 ;Check Near Fatal BCS .exit ;If Knight is Near Fatal, exit SEP #$20 LDA #$C0 ;192 JSR $4B65 ;Random: 0 to 191 CMP $3B40,X ;Stamina REP #$20 BCS .exit ;Exit if Stamina was lower .skip ;Love Token enters here LDA $3AA0,X LSR BCC .exit ;Exit function if entity not present in battle? LDA $3358,X ;$3359 = who is Seizing you BPL .exit ;Exit if you're Seized LDA $336B,Y ;Love Token - which target takes damage for you BMI .noLove ;Branch if none do LDA $3EE4,X ;Bodyguard's status BIT #$A0DA ;Death, Petrify, Clear, Zombie, Sleep, Muddled, ;Dark, Magitek, Image, Berserk BNE .exit BRA .love .noLove LDA $3EE4,X ;Bodyguard's status BIT #$B4DB ;Death, Petrify, Clear, Zombie, Sleep, Muddled, ;Dark, Magitek, Image, Berserk BNE .exit ;Exit if any set .love LDA $3EF8,X BIT #$3211 ;Dance, Stop, Freeze, Spell Chant, Hide BNE .exit ;Exit if any set LDA $3018,X TSB $A6 ;make this potential guard jump in front of the ;target, can accompany others LDA $3BF4,X ;HP of this potential bodyguard CMP $F2 BCC .exit ;branch if it's not >= the highest HP of the other ;bodyguards considered so far for this attack. STA $F2 ;if it is, save this entity's HP as the highest ;HP so far. STX $F4 ;and this entity becomes the new bodyguard. .exit RTS print "Cover function end: ",pc print "Vanilla Cover ends: c212f4" ;Check for Covered attacks in Hit Determination ;Disable Dog Block if attack was Covered org $C22282 checkDogBlock: LDA $3EF9,Y ASL BPL C22293 ;Branch if not dog block JSR skipDogBlock macro skipDogBlock() print "Writing skipDogBlock() to ",pc reset bytes skipDogBlock: CPY $F4 ;Is target = bodyguard? BNE .exit ;If not, return CLC ;Otherwise, set carry = 0, ie. RTS .exit JMP $4B53 ;Random: carry 0 or 1 print "skipDogBlock: ",bytes," bytes written, ending at ",pc endmacro ; BCC C22293 ;50% chance ; LDA #$40 ; STA $FE ;Set dog block animation flag org $C22293 C22293: ;Halve Evasion if attack was Covered org $C22345 JSR halveEvasion ;Get Evade macro halveEvasion() print "Writing halveEvasion() to ",pc reset bytes halveEvasion: ;Y = target of attack CPY $F4 ;Index of bodyguard ($FF if no bodyguard) BNE .exit ;If not the same as target, exit LDA #$FF ;255 SEC SBC $3B54,Y ;255 - (255 - Evade * 2 + 1) ;(= Evade * 2 - 1) INC ;Evade * 2 LSR ;Evade LSR ;Evade / 2 JMP $2861 ;New blockvalue from halved Evade .exit LDA $3B54,Y ;(255 - Evade * 2 + 1) RTS print "halveEvasion: ",bytes," bytes written, ending at ",pc endmacro org !smartCover %smartCover() org !halveEvade %halveEvasion() org !noDogBlock %skipDogBlock()
-
-
Updated the Melee/MP damage counter code to fix the bug where MP damage would trigger melee counters.
@Synchysi NOTE: the free space requirements have changed. Details in the code comments.
-
RC4 - The Shell spell sets Stop instead of Shell.
(Fixed in RC-5)- 2
-
Status display bugfix
org $C14587 XBA PHA XBA LDA $2EBE,X ; Status byte 2 (for Sap) ROL #2 ; Rotate Sap into carry TDC ; Clear A ROL ; Rotate Sap into bit 0 XBA ; Save Sap LDA $2EC0,X ; Status byte 4 (Rerise byte) LSR #3 ; Shift Rerise into carry XBA ; Get Sap again ROL ; Rotate Rerise into bit 0, Sap into bit 1 XBA ; Save Sap and Rerise LDA $2EBF,X ; Status byte (for Regen) LSR #2 ; Shift Regen into carry XBA ; Get Sap and Rerise ROL ; Rotate Regen into bit 0, Rerise into bit 1, Sap into bit 2 XBA PLA XBA RTS
-
Made of Explodium - DONE
EDIT: Updated to fix a bug. No changed requirements (just changed the CPX to a CPY).
; Add a multiplier for Exploder when used by a player character ; 1 Spell Power = +50% damage ; Updated to fix a bug where Exploder cast by characters wouldn't gain the multiplier from Spell Power. hirom ;header !freespace = $C2A8D2 ; 12 bytes ; Exploder effect org $C23FFC JSR newfunc org !freespace newfunc: TDC ; Clear 16-bit A CPY #$08 ; Check if monster BCS .exit ; If monster, multiplier = 0 LDA $11A6 ; Else, use Spell Power as multiplier .exit STA $BC ; Store multiplier TYX RTS
-
Lack of back attack damage stack hack - DONE
hirom ;header org $C23447 NOP #7
- 1
-
Modified Pincer/Side/Back attack probabilities - DONE
; Probabilities for Side/Pincer/Back/Normal attacks org $C25279 db $20 ; Side attack (32/255) db $20 ; Pincer (32/255) db $20 ; Back attack (32/255) db $9B ; Normal (155/255)
- 1
-
Vindictive targeting fix - DONE
hirom ;header org $C22002 CMP #$04
- 1
-
Quake/Vanish fix - DONE
; Quake removes Clear status even when missing Floating targets fix ; Version 1.0 ; by Seibaby ;xkas 0.06 hirom ;header !freespace = $C2xxxx ; Spell Effect Pointer $25: Quake (Once-per-strike) org $C2432B dw groundBased ; Untarget Floating targets, except if all targets are Floating org !freespace reset bytes groundBased: REP #$20 ; Set 16-bit Accumulator LDA $A2 STA $EE ; Copy targets to temporary variable LDX #$12 .loop LDA $3EF8,X ; Current status byte 3-4 BPL .next ; Check next target if this one is not floating LDA $3018,X TRB $EE ; Clear this monster from potential targets .next DEX DEX BPL .loop ; Loop for all 10 targets LDA $EE BNE .save ; Branch if any target(s) left LDA #$0080 TRB $B3 ; No targets valid, so set Ignore Clear LDA $A2 ; Else, use original Targets .save STA $B8 ; save target(s) TYX JMP $57C2 print bytes
- 1
-
Reflect timer - DONE
; Disable Reflect timer and randomly remove Reflect when triggered ; by Seibaby (2018-12-01) hirom ;header !freespace = $C2AEA9 ; Requires 9 bytes of free space in C2 ; The hook offset for the new code depends on whether you have Terii's ; Vanish/Doom patch applied or not. ;!hook = $C22248 ; Vanilla !hook = $C22256 ; Vanish/Doom patch applied ; Disable Reflect timer org $C2469B nothing: RTS org $C246DE dw nothing ; Action when setting Rflect ; Hook Hit Determination to call new code org !hook JMP remove_reflect ; Make attack miss if reflecting ; The purpose of the following modifications are to make room for the ; new code. The Reflect timer is no longer used, so it's safe to remove ; both the code that sets the timer, and the code that checks whether it ; has run out. This frees up enough space for the new code. ; This new code replaces the code that set the Reflect timer (10 bytes) org $C24687 remove_reflect: SEP #$20 ; 8-bit A JSR $4B5A ; RNG: 0..255 CMP #$55 ; 1 in 3 chance to clear Rflect status JMP remove_reflect2 ; (continued...) ; The following code handles timers and status removal upon expiry. ; The code that handled the Reflect timer was removed, and the second part ; of the new code was inserted at the end of the function. org $C25AE9 exit: RTS org $C25B06 C25B06: ; (Code relevant to the Reflect timer was ; removed from the start of this block) STA $B8 LDA $3F0D,X ; Time until Freeze wears off BEQ .sleep ; Branch if timer not active DEC $3F0D,X ; Decrement Freeze timer BNE .sleep LDA #$04 TSB $B8 ; If Freeze timer reached 0 on this tick, ; Set to remove Freeze .sleep LDA $3CF9,X ; Time until Sleep wears off BEQ .end ; Branch if timer not active DEC $3CF9,X ; Decrement Sleep timer BNE .end LDA #$08 TSB $B8 ; If Sleep timer reached 0 on this tick, ; Set to remove Sleep .end LDA $B8 BEQ exit ; Exit if we haven't marked any of the ; Statuses to be auto-removed LDA #$29 JMP $4E91 ; Queue the status removal ; New code (continued) ; Replaces the code that handled the Reflect timer (14 bytes) remove_reflect2: BCS .end ; Exit 2/3 times LDA $3330,Y ; Blocked status 3 BPL .end ; No removal if permanent Reflect JSR remove_reflect3 .end JMP $22E5 ; Make attack miss NOP ; (Padding) ; The space freed up by excising the Reflect timer isn't enough to ; handle the message boxes, so here's dipping into free space. org !freespace reset bytes remove_reflect3: LDA $3E10,Y ; Status to clear 3 ORA #$80 ; Bit 7 = Rflect STA $3E10,Y ; Mark Rflect to be cleared RTS print bytes," bytes added"
]
- 1
-
Random encounter mod - DONE
EDIT: updated to fix a bug with formation odds.
;Random encounters mod for BNW ;v4 - no longer screws up formation odds ;v3 - re-jiggered some numbers courtesy of nowea ;v2 - should actually work now ;Should raise the minimum number of steps for a random encounter to 10, while still maintaining the overall rate hirom ;header !freespaceC2 = $C2FBF0 !freespaceC0 = $C0FF90 ; Overworld and Town/Dungeon encounters org $C0C48C LDA #$E9 ; 233 JSR longCall CLC ADC #$04 ; Random 4..236 org !freespaceC0 longCall: JSL c2rand ; Random 0..232 RTS org !freespaceC2 c2rand: JSR $4B65 RTL
- 1
-
ATB colors - DONE
palettes-bnw.bin; Time Magic affects the ATB bar colors ; By Seibaby 2018-09-23 ; It also changes the endcaps on the ATB bar based on whether ATB is full or not. ; This requires two new glyphs in the 8x8 font tileset (the two tiles immediately following ; the ATB endcaps, left and right). The endcaps are changed so that the uncharged ones don't ; use colors 2 or 4, just the grey and transparency. Then the charged endcaps use colors ; 4 (the brightest) and optionally color 2 like the vanilla endcaps did. ; Palette color order ; 0: transparency ; 1: Text Drop shadow / ATB gauge outline ; 2: Text Grey magic dot / ATB gauge border ; 3: Text / ATB gauge core ; $2EAF01: Palette #1: $21 - White text ; $2EAF09: Palette #2: $25 - Grey text ; $2EAF11: Palette #3: $29 - Yellow text / Full ATB gauge ; $2EAF19: Palette #4: $2D - Blue ; $2EAF21: Palette #5: $31 - All black (???) ; $2EAF29: Palette #6: $35 - White (charging) ATB gauge ; $2EAF31: Palette #7: $39 - Green Morph gauge ; $2EAF39: Palette #8: $3D - Red Condemned gauge (unused) hirom ;header !freespace = $EEAF01 ; Add checks for statuses to ATB drawing routine org $C16872 drawGauge: LDA $2021 ; ATB gauge setting LSR ; Gauge enabled? BCC drawMaxHP ; Branch if disabled LDA $3A8F ; nATB: is ATB paused? LSR ; (01 = paused) BCS .exit ; Don't update bars while ATB is paused LDA $4E ; Text color PHA ; Save it LDA $18 ; Which character is it (0-3) TAX ; Index it LDA $619E,X ; Character's ATB gauge value PHA ; Save it for later TXA ; A = character 0-3 ASL ; Double it JSL newfunc macro newfunc() newfunc: TAX ; Character index (0-6) LDA $3EF8,X ; Status byte 3 BIT #$10 ; Is Stop status set? BEQ .slow ; Branch if not Stopped LDA #$3D ; Select palette #8 STOPPED BRA .store ; Store palette .slow LDA $3EF8,X ; Status byte 3 BIT #$04 ; Is Slow status set? BEQ .haste ; Branch if not Slowed LDA #$2D ; Select palette #4 SLOW BRA .store ; Store palette .haste LDA $3EF8,X ; Status byte 3 BIT #$08 ; Is Haste status set? BEQ .normal ; Branch if not Hasted LDA #$39 ; Select palette #7 HASTE BRA .store ; Store palette .normal LDA #$35 ; Select palette #6 NORMAL .store RTL endmacro STA $4E ; Store palette PLA ; Restore ATB gauge value JSR $6854 ; Draw the gauge PLA ; Get saved text color STA $4E ; Store text color .exit RTS print "c1/6872 ends at: ", pc,", should be c16898" org $C16898 drawMaxHP: LDA #$C0 ; Draw a "/" as HP divider ; Endcaps stuff org $C16854 endcaps: PHA JSL newfunc2 macro newfunc2() newfunc2: LSR A AND #$FC TAX LDA $04,S INC BEQ .leftfull LDA #$F9 BRA .drawleftcap .leftfull LDA #$FB .drawleftcap RTL endmacro JSR $66F3 ; Draw opening end of ATB gauge LDA #$04 STA $1A .loop LDA $C168AC,X ; Get the ATB gauge character JSR $66F3 ; Draw tile A INX DEC $1A ; Decrement tiles to do BNE .loop ; Branch if we haven't done 4 PLA JML newfunc3 macro newfunc3() newfunc3: INC BEQ .rightfull LDA #$FA BRA .drawrightcap .rightfull LDA #$FC ; Draw tail end of ATB gauge .drawrightcap JML $C166F3 ; Draw tile A endmacro NOP print "c1/6854 ends at: ",pc,", should be c16872" ; Relocate 2bpp palettes org !freespace print "palettes written to ",pc palettes: incbin palettes-bnw.bin ; Use SNESpal to edit the palettes print "new code written to ", pc %newfunc() %newfunc2() %newfunc3() org $C140A8 LDA palettes,X ; Load battle text palettes white and gray org $C140AF LDA palettes+16,X ; Load battle text palettes yellow and cyan org $C14100 LDA palettes+40,X ; Load battle gauge palette
- 1
-
New status screen - WIP
"Wip"
- 1
-
Tank & Spank 1.0 - DONE
;Tank & Spank (previously Cover Knight and Smart Cover) ;by Seibaby ;v1.0 - Only allows back row targets for Stamina-based cover ; Disables Cover when Dancing ;v0.9 - Disables Interceptor and halves Evasion when Covering ;v0.7 - Fixes a bug where Knight wouldn't reset Defending stance when Covering ;v0.6 - New Smart Cover logic ; Some Cover nerfs ;v0.5 - Fixes an issue with Knights not taking targets' statuses into ; account (Image and Clear, but also Zombie and Petrify) ;v0.4 - Fixes a bug causing Knights to Cover monsters attacking other ; monsters ;v0.3 - Adds an exception to not trigger Cover if the Knight is Near Fatal ; and the target is healthy. ;v0.2 - Fixes a bug that caused the wrong statuses (on the target) to be ; considered for whether or not to disable True Knight. ;Changes the True Knight effect to trigger with a Stamina / 192 chance even if ;the target isn't in Near Fatal status. ;New Smart Cover patch, which disables True Knight for all attacks ;originating from a player character, unless that character is uncontrollable, ;in which case it will only disable it if the attack comes from a healing weapon, ;or if the weapon is elemental and the target absorbs/nullifies that element. ;It also considers a few extra statuses for purposes of disabling True Knight. ;ON TARGET: Death, Petrify, Zombie, Magitek, and Image ; (in addition to Clear) ;ON KNIGHT: Dark, Magitek, Image, Berserk ; (in addition to Death, Petrify, Clear, Zombie, Sleep, and Muddled) ;xkas 0.06 hirom ;header !smartCover = $C2AE31 ;Requires 99 bytes of free space ;!halveEvade = $C10000 ;Requires 20 bytes of free space ;!noDogBlock = $C20000 ;Requires 9 bytes of free space ;A few notes on the changes made to these functions: ;Entering this function, A is 16-bit and X/Y are 8-bit. Register width is ;never changed and the call following this function doesn't care about Carry, ;so I have removed a bunch of useless PHP/PLP and REP #$20 throughout, to make ;room for the new code. ;I have also removed some code related to monsters using True Knight, which was ;supported in vanilla, but unused (and remains so in BNW). The check for if the ;bodyguard was Controlled was also removed (doubly useless). org $C2123A exit: ;True Knight and Love Token org $C2123B trueKnightAndLoveToken: PHX LDA $B2 BIT #$0002 ;Is "No critical and Ignore True Knight" set? BNE .exit ;Exit if so LDA $B8 ;intended target(s). to my knowledge, there's only ;one intended target set if we call this function.. JMP smartCover macro smartCover() print "Writing smartCover() to ",pc reset bytes smartCover: BEQ .exit ;Exit if none LDY #$FF STY $F4 ;default to no bodyguards. JSR $51F9 ;Y = index of our highest intended target. ;0, 2, 4, or 6 for characters. 8, 10, 12, 14, 16, ;or 18 for monsters. STY $F8 ;save target index STZ $F2 ;Highest Bodyguard HP So Far = 0. this makes the ;first eligible bodyguard we check get accepted. ;later ones may replace him/her if they have more ;HP. PHX LDX $336C,Y ;Love Token - which target takes damage for you BMI .noLove ;Branch if none do JSR evalKnight_skip ;consider this target as a bodyguard (skip Stamina ;and Near Fatal checks) JSR newTarget ;if it was valid, make it intercept the attack .noLove PLX LDA $3A36 BNE .exit ;Exit if Golem is active CPX #$08 ;Check attacker BCS .status ;Branch if attacker is a monster CPX $F8 BEQ .exit ;Exit if Attacker = Target LDA $3EE4,X ;Attacker status byte 1-2 BIT #$2002 BNE .heals ;Branch if Muddled or Zombied LDA $3394,X ;Check if Attacker is Charmed BMI .exit ;If not Muddled, Zombied, or Charmed, this ;attack was initiated by the player, so exit .heals LDA $11A9 ;Special weapon property AND #$00FF ;Isolate bottom byte CMP #$0018 ;Check "Curative Attributes" BEQ .exit ;Exit if set SEP #$20 LDA $11A1 ;Attack element(s) PHA XBA PLA ;Copy to high byte REP #$20 AND $3BCC,Y ;Target absorbed/immune elements BNE .exit ;If any absorbed or nullified, exit .status LDA $3EE4,Y ;Target status byte 1-2 BIT #$04DA BNE .exit ;Branch if Death, Petrify, Clear, Zombie, Magitek, ;or Image .seize LDA $3358,Y ;$3359 = who is Seizing you BPL .exit ;Branch if target is seized LDA #$000F ;Load all characters as potential bodyguards JMP trueKnightAndLoveToken_cover .exit PLX RTS print "smartCover: ",bytes," bytes written, ending at ",pc endmacro .cover CPY #$08 BCC .saveBg ;Branch if target is character TDC ;Null all potential bodyguards .saveBg STA $F0 ;Save potential bodyguards LDA $3018,Y ;bit representing target ORA $3018,X ;bit representing attacker TRB $F0 ;Clear attacker and target from potential ;bodyguards LDX #$12 .loop LDA $3C57,X ;High byte = Relic Effects 3 ASL #2 ;Check bit 6 (True Knight) BCC .next ;Branch if no True Knight effect LDA $3018,X BIT $F0 BEQ .next ;Branch if this candidate isn't on the same ;team as the target JSR evalKnight ;consider them as candidate bodyguard. if they're ;valid and their HP is >= past valid candidates, ;they become the new frontrunner. .next DEX DEX BPL .loop ;Do for all characters and monsters LDA $F2 BEQ .exit ;Exit if no bodyguard found [or if the selfless ;soul has 0 HP, which shouldn't be possible outside ;of bugs]. JSR newTarget ;make chosen bodyguard -- provided there was one -- ;intercept attack. if somebody's already been ;slated to intercept it [i.e. due to Love Token], ;the True Knight will sensibly defer to them. .exit PLX RTS ;Make chosen bodyguard intercept attack, provided one hasn't been marked to do ;so already. newTarget: LDX $F4 BMI .exit ;exit if no bodyguard found CPY $F8 BNE .exit ;exit if $F8 no longer points to the original ;target, which means we've already assigned a ;bodyguard with this function. STX $F8 ;save bodyguard's index STY $A8 ;save intended target's index LSR $A8 ;.. but for the latter, use 0,1,2,etc rather ;than 0,2,4,etc LDA $3018,X STA $B8 ;save bodyguard as the new target of attack SEP #$20 LDA $3AA1,X BIT #$02 BEQ .noDef ;Branch if not Defending JSR $0A41 ;Clear Defending flag JSR $0A3C ;Relax Defending pose .noDef REP #$20 .exit RTS ;Consider candidate bodyguard for True Knight or Love Token evalKnight: LDA #$0020 BIT $3AA1,X BNE .exit ;Exit if guard is in back row LDA $3EE5,Y ;Low byte = Status byte 2 LSR #2 ;Check bit 1 (Near Fatal) BCS .skip ;Skip Stamina check if target Near Fatal LDA $3AA1,Y BIT #$0020 BEQ .exit ;Exit if target is in back row LDA $3EE5,X ;Knight's Status byte 2 LSR #2 ;Check Near Fatal BCS .exit ;If Knight is Near Fatal, exit SEP #$20 LDA #$C0 ;192 JSR $4B65 ;Random: 0 to 191 CMP $3B40,X ;Stamina REP #$20 BCS .exit ;Exit if Stamina was lower .skip ;Love Token enters here LDA $3AA0,X LSR BCC .exit ;Exit function if entity not present in battle? LDA $3358,X ;$3359 = who is Seizing you BPL .exit ;Exit if you're Seized LDA $3EE4,X BIT #$B4DB ;Death, Petrify, Clear, Zombie, Sleep, Muddled, ;Dark, Magitek, Image, Berserk BNE .exit ;Exit if any set LDA $3EF8,X BIT #$3211 ;Dance, Stop, Freeze, Spell Chant, Hide BNE .exit ;Exit if any set LDA $3018,X TSB $A6 ;make this potential guard jump in front of the ;target, can accompany others LDA $3BF4,X ;HP of this potential bodyguard CMP $F2 BCC .exit ;branch if it's not >= the highest HP of the other ;bodyguards considered so far for this attack. STA $F2 ;if it is, save this entity's HP as the highest ;HP so far. STX $F4 ;and this entity becomes the new bodyguard. .exit RTS print "Cover function end: ",pc print "Vanilla Cover ends: c212f4" ;Check for Covered attacks in Hit Determination ;Disable Dog Block if attack was Covered org $C22282 checkDogBlock: LDA $3EF9,Y ASL BPL C22293 ;Branch if not dog block JSR skipDogBlock macro skipDogBlock() print "Writing skipDogBlock() to ",pc reset bytes skipDogBlock: CPY $F4 ;Is target = bodyguard? BNE .exit ;If not, return CLC ;Otherwise, set carry = 0, ie. RTS .exit JMP $4B53 ;Random: carry 0 or 1 print "skipDogBlock: ",bytes," bytes written, ending at ",pc endmacro ; BCC C22293 ;50% chance ; LDA #$40 ; STA $FE ;Set dog block animation flag org $C22293 C22293: ;Halve Evasion if attack was Covered org $C22345 JSR halveEvasion ;Get Evade macro halveEvasion() print "Writing halveEvasion() to ",pc reset bytes halveEvasion: ;Y = target of attack CPY $F4 ;Index of bodyguard ($FF if no bodyguard) BNE .exit ;If not the same as target, exit LDA #$FF ;255 SEC SBC $3B54,Y ;255 - (255 - Evade * 2 + 1) ;(= Evade * 2 - 1) INC ;Evade * 2 LSR ;Evade LSR ;Evade / 2 JMP $2861 ;New blockvalue from halved Evade .exit LDA $3B54,Y ;(255 - Evade * 2 + 1) RTS print "halveEvasion: ",bytes," bytes written, ending at ",pc endmacro org !smartCover %smartCover() ;org !halveEvade %halveEvasion() ;org !noDogBlock %skipDogBlock()
- 1
-
Mind blast mod - DONE
;BNW Mind Blast tweak hirom ;header !freespace = $C25141 ; free space in 1.9...I think ; Loop 5 times for Mind Blast org $C2413E LDY #$08 org $C23BB8 LDX #$08 org $C23BC1 JSR checkStam ; Check Stamina before attempting to set status org !freespace checkStam: SEP #$20 JSR $23B2 ; Check if Stamina blocks REP #$20 BCS .exit ; Exit if so JMP $3BD0 ; Randomly mark a status from attack data to be set .exit RTS
- 1
-
N. Cross rebalance - DONE
hirom ;header !freespace = $C2661B ; N. Cross (Special effect $29) ; One or two targets will be picked randomly org $C2414D C2414D: REP #$20 ; Set 16-bit A C2414F: LDA $A4 ; Targets C24151: PHA ; Save targets C24152: JSR $522A ; Randomly pick an entity from among the targets C24155: JMP morecode org !freespace morecode: STA $A4 ; Save new target PLA ; Get original targets again JSR $522A ; Pick one at random TSB $A4 ; Save new target(s) SEP #$20 ; Set 8-bit A RTS
- 1
-
Runic ignores Clear - DONE
; Set Runicked attacks to Ignore Clear org $C2357E LDA #$2182 STA $11A3 ;Set just concern MP, not reflectable, Unblockable, Heal LDA #$8040 TRB $B2 ;Flag little Runic sword animation, set Ignore Clear SEP #$20 ;Set 8-bit Accumulator LDA #$60 STA $11A2 ;Set just ignore defense, no split damage TDC ;need top half of A clear LDA $11A5 ;MP cost of spell JSR $4792 ;divide by X STA $11A6 ;save as Battle Power JSR $385E ;Sets level, magic power to 0 JSR $2A0F ;(some runic patch hook?) LDA #$04 ; A = 4 STA $BA ;Don't retarget if target invalid DEC A ; A = 3
- 1
-
MP low counter - DONE
; HP/MP low counter redesign ; By Seibaby ; FC command $06 (HP low counter) normally checks HP versus <parameter> * 128 while ; FC command $07 (MP low counter) checks MP versus <param> only. This makes it so that ; MP is compared to <param> * 128 as well. hirom ;header ; FC command $06 (HP low counter) org $C21D61 dw mpLowCounter ; FC command $07 (MP low counter) org $C21D63 dw mpLowCounter org $C21BB7 mpLowCounter: JSR $1D34 BCC .exit TDC LDA $3A2F XBA REP #$20 LSR CPX #$0E ; is it command $07 - MP low counter? BCC .hp ; branch if it's not (ie. it's $06 - HP low counter) CMP $3C08,Y ; MP BRA .exit .hp CMP $3BF4,Y ; HP .exit RTS padbyte $FF : pad $C21BD6 warnpc $C21BD7
- 1
-
Melee Counter - DONE
EDIT: updated to fix a bug. NOTE: The free space requirements have increased.
; New parameters for FC 05 - Melee counter and MP damage counter ; Updated to fix a bug where MP damage would trigger melee counters. The checkParams code is now 1 byte longer. ; AI Script commands: ; FC 05 00 00 = counterattack all damage, as usual ; FC 05 00 01 = counterattack ONLY damage that's both physical and row-respecting ; FC 05 00 02 = counterattack ONLY MP damage hirom ;header !freespace = $C23C61 ; Requires 5 bytes of free space in C2 !freespacelong = $C3F577 ; Requires 67 bytes of free space anywhere ; Preparation: ; Hook functon C2/35E3 (Initialize several variables for counterattack purposes) org $C235E9 JSL initAttackVars ; (initialize new var $327D,index containing bitflags for ; physical damage, respects row, and MP damage in bit 0, ; bit 5, and bit 7 respectively) macro initAttackVars() initAttackVars: TXA ; (displaced code) STA $3290,Y ; (displaced code) LDA $B3 ; If Bit 5 is set it ignores attacker row EOR #$FF ; Invert it so bit 5 is set if melee LSR ; Shift it to bit 4 ORA $11A7 ; Merge with bit 4 of $11A7 ("respects row") AND #$10 ; Isolate bit 4 (1 = respects row) PHA LDA $11A2 ; Bit 0 = physical damage if set LSR ; Carry = 1 if physical damage PLA ROL ; Bit 1 = physical ; Bit 5 = melee ASL ; Shift again PHA LDA $11A3 ROL ; Carry = 1 if affects MP PLA ROR ; A: bit 1 = physical damage ; bit 5 = melee attack ; bit 7 = affects MP ; (all other bits are 0) STA $327D,Y ; Save attack properties to unused var $327D,index .exit RTL endmacro ; Execution: ; FC command $05 (Counter if damaged) org $C21C70 doCounter: ; (vanilla FC 05 code) ; Redirect pointer for FC command $05 to new code org $C21D5F dw checkParams org !freespace checkParams: JML checkParamsLong macro checkParamsLong() checkParamsLong: LDA $3A2F ; Script command byte 4 LSR ; Check if it's 1 (melee counter) BCS .melee LSR ; Check if it's 2 (MP damage counter) BCC .omni ; If not set, it's a normal counter LDA $327D,Y CMP #$80 ; Check if attack affects MP BNE .exit ; Exit if not BRA .omni ; Counter if attack affects MP .melee LDA $327D,Y ; Attack properties CMP #$21 ; Check respect row, physical BNE .exit ; Exit if not both are set .omni JML doCounter .exit CLC JML noCounter endmacro noCounter: RTS org !freespacelong reset bytes %initAttackVars() %checkParamsLong() print "New code requires ",bytes," bytes of free space anywhere"
- 1
-
This thread is for the devs. There are a lot of assembly patches going into
1.10.02.0, let's collect them all in one place.TASKS:
Pincer/Back/Side probabilities - DONE
Vindictive targeting fix - DONE
Encounter Rate - DONE
Reflect Timer - DONE
Melee Counter - DONE
MP low counter - DONE
Runic ignores Clear - DONE
N. Cross rebalance - DONE
Mind blast mod - DONE
Tank & Spank 1.0 - DONE
ATB colors - DONE
Quake/Vanish Fix - DONE
Modified Pincer/Side/Back attack probabilities - DONE
Lack of back attack damage stack hack - DONE
Exploder Multplier (for Gau) - DONE
Retreat Is Faster - ABANDONED
New status screen - WIP@darknil
??? Update - (to be PM'ed directly to Synchysi)
Status Display Update (Cycling Auras) - DONE
Status Display Update (Regen/Rerise) - DONE
Doomstick Bugfix - DONE
Relics Block Stop - DONE
Shop Preview - DONE
Spell Dot Display - DONE@GrayShadows
Weapon Swap in Combat - WIP/TENTATIVE
Max HP/ATB toggle - DONE
Inventory Index Fix - DONE@Think0028
Defend/Row 1/2 Turn - WIP/TENTATIVE
EsperXP Display Bugfix - PENDING BETA FEEDBACK
Elemental Mixing - DONE@madsiur
SrBehemoth OpCode Update - DONE
Aero Speed Hack - DONE@Gi Nattak
Booty Fix - DONE
Leet Sketcher
Imp Skimp - HEREAssassin
Genji Glove BatPwr Display Fix - ???
Rage list re-order - HERE
Optimize Fix - HEREPoco Loco
WoR BGM Fix - HEREBydoless
Tritoch Animation Fix - HEREDeschain
Phunbaba Event Tile Fix - HERE (disclaimer)Just clarifying: this isn’t a discussion thread so any non dev post stuff will be purged. - Mish
- 4
-
And this is the N. Cross mod - it causes the N. Cross special effect to pick either one or two targets among those hit by the spell, all others will be untargeted. In short, it makes N. Cross hit at least one and at most two targets.
Code repository for 2.0
in Final Fantasy VI: Brave New World
Posted · Report reply
Updated the random encounter patch with a bugfix. Current RC as of writing this is 27.8 (which does not include this fix).