You may have noticed that in FE3, if you hack a siege weapon in player inventories, they behave a little oddly.
If you haven't done that, here are the odd things about them:
- Siege weapons have infinite range.
- Their animations don't play when PC characters use them.
Here is an Asar patch that fixes animations and adds a range check to limit siege tomes to 10 range:
lorom
if read1($00FFDB) == $01
!siegeWeaponOffenseEnable = $83B352
!rangeWeaponEnable = $83A500
!proceed = $83AA8E
!checkIf2Range = $83B314
elseif read1($00FFDB) == $00
!siegeWeaponOffenseEnable = $83B33D
!rangeWeaponEnable = $83A4EB
!proceed = $83AA79
!checkIf2Range = $83B2FF
endif
ORG !checkIf2Range
nop #4 ; asar pseudo opcode to pad 4 NOPs
; the nop padding replaces a unit alignment check
; if the unit is player controlled,
; the range check is skipped.
; prsumanbly because the devs assumed the played would never
; have siege weapons
;
lda $075F,Y ; in vanilla this is LDA $0760
; which only checks enemy weapons
; the player weapon check is bypassed
ORG !siegeWeaponOffenseEnable
lda $16 ; changed cpy #$01 -> lda $16
; effectivley changes from "is this an enemy attacking"
; to "is this unit initiating the attack"
; TODO: Investigate if the AI already checks distance so I can hook into that.
ORG !rangeWeaponEnable
asl A
asl A
asl A
xba
sep #$20
and #$01
cmp $07D3
jsl checkDistance
beq dontSelect
lda $7F2800,x
sta $08F2
; everything before this enables the range check
lda #$02
sta $08F3
; $08F3 needs to be 1 or 2 or battle animations won't play correctly
rep #$20
brl proceedLabel
nop
nop
dontSelect:
rep #$20
rts
ORG !proceed
proceedLabel:
; siege weapons are inifnite range by default, so I added a distance check for them
ORG $CCA6B0
checkDistance:
php
phx
phy
sep #$10
ldy #$00
phy
distanceLoop:
lda $08EE,y
sec
sbc $085E,y
bpl notNegative
eor #$FF
inc A
notNegative:
clc
adc 1,s
sta 1,s
iny
cpy #$02
bne distanceLoop
pla
cmp #$0B
bpl outOfRange
cmp #$03
bmi outOfRange
bra inRange
outOfRange:
rep #$10
ply
plx
plp
sep #$02
bra exitLabel
inRange:
rep #$10
ply
plx
plp
exitLabel:
rtl
I assume that AI has some routine to check distance. But I haven't investigated that deeply so I don't know where it's located or if it can be reused here