Zeroing/nullifying mov FEDS style (based on AI parameters?)

I didn’t see a thread discussing this, but it’s also hard to search for the exact concept.

In FEDS, enemy units who are stationary (mostly bosses) have their mov set to – and their corresponding movement/attack range on the map altered to match. This makes it easier to check enemy attack ranges without having to experimentally figure out whether an enemy’s AI is set to attack in range or to never move at all.

I’m thinking that this is possible to create in FE7 with a routine that checks for AI parameters and then sets movement to 0 or – if the AI parameters are [0x0, 0x3, 0x9, 0x20] or something like that. In cases where you want to CHAI a unit via events to become mobile mid-chapter, you would simply use a different initial stationary AI parameter ([0x0, 0x3, 0x9, 0x0]). It may actually be better to only check for the 4th byte, although I’m not sure what it’s used for other than Guard and GuardTile.

Of course, I have no idea how feasible this is, and it’s ultimately not a high priority mechanic - I just think it’s a neat feature that saves some effort for the player. I’m merely bringing this up to put it on the docket, so to speak. If anyone is interested in investigating it, be my guest.

1 Like

Sen. Arch seconds the motion, it proceeds to the floor for a vote.

This’d be a cool little tweak to include in BlazingShell, too.

1 Like

making it 0 instead of – will yield better results and less back talk from the game. It should just be editing one routine if it’s for the display only

Wasn’t @AlfredKamon wanting to do something like this (although not necessarily with the ability to give them movement mid-chapter)?

I feel like I remember him having to settle with making a separate class for what he did, so perhaps he’d also be interested in whatever comes out of this? (albeit for FE8)

Yeah, I was looking through the forum and @AlfredKamon ended up using a separate class for stationary knights in Midnight Sun. It works, but I think there can be a more elegant solution.

This patch (FE8, writes data to $E90130-18F and $E901F0-213) checks if AI byte 4 is 0x20:

Incidentally, if you wanted to be evil and restrict player units’ movement you can now also do this with a simple CHAI.

And source for anyone who wants to make an FE7 port:
###Map movement to 0

MOV_Map_Hook_Start: @paste to 0x801CB70
push {r4-r6,r14}
ldr r3, Jump_to
bl GOTO_R3
b End
GOTO_R3:
bx r3
.align
Jump_to:
.long 0x08E90131
End:
MOV_Map_Hack_Start:  @paste to 0x08e90130
push {lr}
mov r6, r0
mov r4, #0x1
ldr r5, CharDataPointer
ldr r0, [r5]
mov r3, #0x41
ldrb r3, [r0,r3] @Check AI byte 4
cmp r3, #0x20 @Guard Tile?
beq NoMove

ldr r1, [r0,#0x4] @else continue as normal
ldrb r1, [r1,#0x12] @mov from class data
ldrb r2, [r0,#0x1D] @mov bonus (boots)
b End

NoMove:
mov r1, #0x0
mov r2, #0x0

End:
pop {r3}
bx r3

.align
CharDataPointer:
.long 0x03004e50

###Stat screen to –

MOV_Info_Hook_Start: @paste to 0x8087300
ldr r3, Jump_to
bl GOTO_R3
b End
GOTO_R3:
bx r3
.align
Jump_to:
.long 0x08E90161
End:
MOV_Info_Hack_Start: @paste to 0x8E90160
push {lr}

ldr r1, [r5,#0xC] @r1 = char data

mov r3, #0x41
ldrb r3, [r1,r3] @AI byte 4
cmp r3, #0x20
beq NoMove

ldr r0, [r1,#0x4]
mov r3, #0x12
ldsb r3, [r0,r3] @r3 is the return value
mov r0, #0x1D
ldsb r0, [r1,r0]
b End

NoMove:
ldr r3, DisplayNegative
mov r0, #0x0

End:
pop {r1} @saves some stack manipulation by popping first
add r0,r0,r3
str r0, [sp]
bx r1

DisplayNegative:
.long 0xFFFFFFFF

###Danger Zone compatibility

@paste to 801b898 - b8aa
ldr r0, Jump_To
bl GOTO_R0
b End
GOTO_R0:
bx r0
.align
Jump_To:
.long 0x8e901f1
nop
End:
@paste to e901f0

mov r3, #0x41 @check AI
ldrb r3, [r4,r3]
cmp r3, #0x20
beq NoMove

ldr r0,[r4,#0x4]
ldrb r1, [r0,#0x12] @mov from class data
ldrb r0, [r4,#0x1D] @mov bonus (boots)
add r1,r1,r0
b End

NoMove:
mov r1, #0x0

End:
lsl r1,r1,#0x18
asr r1,r1,#0x18
mov r0,r4
ldr r3, Function
bx r3

.align
Function:
.long 0x801a3cd
5 Likes

The updated patch (FE8, same as in previous post) is now compatible with the enemy display hack.
It still works if you don’t have the enemy display hack for some reason.

Before and After:

1 Like

Well this is awesome. It’ll be way easier than making new classes for that purpose. Thanks @circleseverywhere!

1 Like

Fair warning, this isn’t perfect. I’m going to change it to check for AI byte 1 = 0x3 instead of AI byte 2, because currently things like AttackInRangeAI, MoveWithLeaderAI, and DemonKingAI all display 0 mov but move anyway.

It’s more like it doesn’t make much sense to bunch up AI3 and AI4 into the array. They’re still there; look at AI documentation to see which bits are unused (it’s mostly AI byte 4 bits, so you might want to stick with just that)

Any love for FE7? Guys?

Another useful UI function that everyone should totally use. Great stuff, circles!

3 Likes

Patch updated, now only checks for AI Byte 4 and is compatible with Danger Zone patch.

As for FE7, this is how FE8 hackers feel all the time
I’ll get around to porting it eventually, otherwise the source is there for anyone who wants a crack at it.

2 Likes

So you have to put 0x3 in AI Byte 4 now?

It checks for 0x20 in AI byte 4, I removed the check for 0x3.

IIRC Byte 4 0x20 was bugged, meaning that you couldn’t AI change it otherwise the units would move but not attack the enemies in range. Does this retain the same properties as the original 0x20, aside from the zero movement display?

It only checks the byte, it has no effect on the AI. If AI Byte 4 0x20 can’t be changed, then you should only set it on units that will never move at all.

If you really want to catch players off guard by letting “stationary” enemies move, I guess you could change it to check for AI byte 1 0x3 (Attack in place) instead? I don’t know enough about AI to say for sure.

(writes data from $D90130-189)

Here’s the source. It’s also a bit cleaner than the FE8 one.
###Map move to 0

.thumb
.org 0x0 @paste to 0x801C4D0
push {r4-r6,r14}
ldr r3, Jump_to
mov lr, r3
.short 0xF800 @dunno how to assemble BLH but yeah
b End
.align
Jump_to:
.long 0x08D90131 @or wherever+1
End:
.thumb
.org 0x0 @paste to $D90130 or wherever
mov r6, r0
mov r4, #0x1
ldr r5, CharDataPointer
ldr r0, [r5]
mov r3, #0x41
ldrb r3, [r0,r3] @AI byte 4
cmp r3, #0x20 @Guard Tile?
beq NoMove
ldr r1, [r0,#0x4]
ldrb r1, [r1,#0x12] @mov from class data
ldrb r2, [r0,#0x1D] @mov bonus (boots)
b End
NoMove:
mov r1, #0x0
mov r2, #0x0
End:
bx lr
.align
CharDataPointer:
.long 0x03004690

###Stat screen to –

.thumb
.org 0x0 @paste to 0x807FF90
ldr r3, Jump_to
mov lr, r3
.short 0xF800
b End
.align
Jump_to:
.long 0x08D90155 @or wherever+1
End:
.thumb
.org 0x0 @paste to $D90154 or wherever

ldr r1, [r6,#0xC] @r1 = char data

mov r3, #0x41
ldrb r3, [r1,r3] @AI byte 4
cmp r3, #0x20
beq NoMove

ldr r0, [r1,#0x4]
mov r3, #0x12
ldsb r3, [r0,r3]
mov r0, #0x1D
ldsb r0, [r1,r0]
b End

NoMove:
mov r0, #0x0
mvn r3, r0

End:
bx lr

###Danger zone compatibility

.thumb
.org 0x0 @paste to 801b090

ldr r0, Jump_To
mov lr, r0
.short 0xF800
b End
.align
Jump_To:
.long 0x8D90171 @or wherever+1
End:
.thumb
.org 0 @paste to $D90170 or wherever

mov r3, #0x41 @check AI
ldrb r3, [r4,r3]
cmp r3, #0x20
beq NoMove

ldr r0,[r4,#0x4]
ldrb r2, [r4,#0x1D] @mov bonus (boots)
ldrb r0, [r0,#0x12] @mov from class data
add r1,r2,r0
lsl r1,r1,#0x18
asr r1,r1,#0x18
b End

NoMove:
mov r1, #0x0

End:
bx lr
3 Likes

Uh… help?

I have a lot of patches applied to the ROM, so I can’t tell which one makes the interference.

fuck yes i was waiting for this.
@Arch we gotta make moves on these vids

Do you have anything already at D90130? Does the map display work or is that broken too?