seibaby

Hacker
  • Content count

    149
  • Joined

  • Last visited

  • Days Won

    26

Posts posted by seibaby


  1. 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
    


  2. Scan doesn't trigger counters

    @Synchysi

    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

     


  3. 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.

    @Synchysi

    	   
    ;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()
       
    	
    


  4. 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
    


  5. 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
    	
    

     


  6. 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
    

    • Upvote 1

  7. 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"
    	

    ]

    • Upvote 1

  8. 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

     

    • Upvote 1

  9. 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
    	
    
    • Upvote 1

  10. 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()
    	

    • Upvote 1

  11. 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
    	 
    	
    
    • Upvote 1

  12. 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
    	
    
    • Upvote 1

  13. 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   
    	
    • Upvote 1

  14. 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
    
    • Upvote 1

  15. 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"
    

     

    • Upvote 1

  16. This thread is for the devs. There are a lot of assembly patches going into 1.10.0 2.0, let's collect them all in one place.

    @BTB@Synchysi

     

    TASKS:

    @seibaby

    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 - HERE

    Assassin
    Genji Glove BatPwr Display Fix - ???
    Rage list re-order - HERE
    Optimize Fix - HERE

    Poco Loco
    WoR BGM Fix - HERE

    Bydoless
    Tritoch Animation Fix - HERE

    Deschain
    Phunbaba Event Tile Fix - HERE (disclaimer)

     

    Just clarifying:  this isn’t a discussion thread so any non dev post stuff will be purged. - Mish

    • Upvote 4