I made this command, I’m intending to make skills like this one to be used like to commans and add various effects in combat, this skill makes the user inflicts silence in himself during 3 turns (Not having the silence effect already is a requirement to trigger it, besides, only this character can use it and it can only use magic to attack) and deals 30 points of damage to every unit in 3 radio squares, allies and enemies (including him). I’m not very good with ASM but I manage to do things like this, but I do not have any idea about how to make a graphic effect and I fell that one is needed for the skill command (i think it feels bad without the effect), does anyone have a tutorial here or in FEUniverse or another site to do it? (sorry for the long spanish introduction in the video, is for a Facebook Group)
I don’t think there’s a tutorial on this, but I’ll try to explain how I do it.
If you know how to make the visual and sound effects with events you can just do that for your skills, then you can call the event in your asm routine, so:
- Load the offset to your event in r0
- Set r1 to 1 (I think this is what makes it so everything else waits for the event to finish)
- Call 0x800D07C (this will make the event run)
That’s what I did for the lifetaker animation, here is the relevant part of the routine:
ldr r0,=#0x800D07C @event engine thingy
mov lr, r0
ldr r0, LifetakerEvent @this event is just “teleport animation on current character”
mov r1, #0x01 @0x01 = wait for events
.short 0xF800
.short 0xF800 will call the routine at offset r14 (also known as lr)
“LifetakerEvent” is the offset of the event to display, the event looks like this:
CAM1 0xFFFF
WARP_IN
STAL 0x32
NoFade
ENDA
There probably is a better way to do this and I highly doubt this is how staffs and other items do it (I never checked) but it does work.
I would also suggest using the skill system (unless you have reasons not to) since it will make a lot of this stuff easier, there are some functions already made that you can call to check units in range, a lot of hooks in place, it comes with a ton of skills, the modular stat screen and all that good stuff.
This is my code
.thumb
.org 0x00
Initial:
push {r0-r7}
ldr r4, =0x03004E50
ldr r3, [r4]
ldrb r6, [r3,#0x10] @ r6 = coordenada en X
ldrb r7, [r3,#0x11] @ r7 = coordenada en Y
mov r4, r3
add r4, #0x30 @Es la posicion del estado
mov r5, #0x33 @Silencio por 3 turnos
strb r5, [r4]
ldr r3, TablaAliada
Ciclo:
ldr r4, [r3]
ldr r5, Vacio
cmp r4, r5
beq FinCiclo
mov r5, #0
ChecaX:
ldrb r4, [r3,#0x10]
cmp r6, r4
blo XEsMenor
bhi XEsMayor
XEsIgual:
b ChecaY
XEsMenor:
sub r4, r4, r6
add r5, r4
b ChecaY
XEsMayor:
sub r4, r6, r4
add r5, r4
ChecaY:
ldrb r4, [r3,#0x11]
cmp r7, r4
blo YEsMenor
bhi YEsMayor
YEsIgual:
b ChecaEscribe
YEsMenor:
sub r4, r4, r7
add r5, r4
b ChecaEscribe
YEsMayor:
sub r4, r7, r4
add r5, r4
ChecaEscribe:
cmp r5, #03
bhi NoEscribe
Escribe:
ldrb r4, [r3,#0x13]
sub r4, #30
ChecaNegativo:
cmp r4, #121
blo ChecaCero
mov r4, #01
ChecaCero:
cmp r4, #0
bhi NoAjusta
mov r4, #01
NoAjusta:
strb r4, [r3,#0x13]
NoEscribe:
add r3, #0x48
b Ciclo
FinCiclo:
ldr r4, TablaEnemiga
cmp r3, r4
blo EditaEnemigos
ldr r4, TablaNPC
cmp r3, r4
blo EditaNPC
b Animacion
EditaEnemigos:
ldr r3, TablaEnemiga
b Ciclo
EditaNPC:
ldr r3, TablaNPC
b Ciclo
@Here start the animation part
Animacion:
mov r3, lr
ldr r0, =0x0800D07C
mov lr, r0
ldr r0, =0x09000700
mov r1, #0x01
.short 0xF800
mov lr, r3
b End
End:
pop {r0-r7}
ldr r1, =0x203A958
mov r0, #0x01
strb r0, [r1, #0x11]
mov r0, #0x17
bx r14
.align 2, 0
Vacio:
.long 0x00000000
TablaAliada:
.long 0x0202BE4C
TablaEnemiga:
.long 0x0202CFBC
TablaNPC:
.long 0x0202DDCC
and the event
ORG 0x1000700
MUS1 0x68
STAL 200
STAL 200
STAL 200
STAL 200
STAL 200
STAL 200
ENDA
I’ve been trying to make it work for over two hours.
The game crash, then I realized that when doing the “mov lr, r0” this happened, I thought that to avoid it, move from lr to r3 and then returning it so that I can have it at the end of the routine, but it continues crashing and this it stops when I remove the “.short 0xF800” so I guess that is what causes the crash, I really do not know what is wrong.
First problem I see is that you didn’t push r14 in the beginning. When you use bl
(or .short 0xF800
, which is just bl lr+0
), r14 gets overwritten by the new function call. When it’s time to go back, since you didn’t save the address to return to, bx r14
ends up…somewhere else.
You don’t usually need to push r0-r3, those are “scratch” registers, meaning you don’t need to preserve their values.
Instead of ldr r5, Vacio
, where Vacio = 0x00000000, just use mov r5,#0x0
instead.
I’d call the function at 0x19430, which takes a unit number as an argument and returns the character data pointer, rather than having Player_Table, Enemy_Table, and NPC_Table and adding 0x48 to get the next unit. That works, sure, but it’s cleaner to use the existing function.
Made a clearer version:
.thumb
.org 0x0
Initial:
push {r4-r7,r14}
ldr r4, =0x03004E50
ldr r3, [r4]
ldrb r6, [r3,#0x10] @ r6 = coordenada en X
ldrb r7, [r3,#0x11] @ r7 = coordenada en Y
add r3,#0x30 @Es la posicion del estado
mov r0,#0x33 @Silencio por 3 turnos
strb r0,[r3]
mov r4,#1
ldr r5,=#0x8019431 @19430 is the function that, given unit number, returns data
Loop1:
mov r0,r4
bl bx_r5 @puts character's data pointer in r0
cmp r0,#0
beq NextUnit
ldr r1,[r0] @rom character data pointer, is 0 if unit doesn't exist/died
cmp r1,#0
beq NextUnit
ldrb r2,[r0,#0x10] @unit's x coordinate
sub r1,r6,r2
cmp r1,#0
bge Label1
sub r1,r2,r6
Label1:
ldrb r2,[r0,#0x11] @unit's y coordinate
sub r3,r7,r2
cmp r3,#0
bge Label2
sub r3,r2,r7
Label2:
add r1,r1,r3 @r1 = distance between units
cmp r1,#3
bgt NextUnit
ldrb r1,[r0,#0x13] @unit's current hp
sub r1,#30
cmp r1,#1 @make sure hp is positive
bge HpNotNegative
mov r1,#1
HpNotNegative:
strb r1,[r0,#0x13]
NextUnit:
add r4,#1
cmp r4,#0xBF @last enemy unit ID
ble Loop1
ldr r5,=#0x800D07D
ldr r0,=#0x9000700
mov r1,#1
bl bx_r5
ldr r1,=#0x203A958
mov r0,#1
strb r0,[r1,#0x11]
mov r0,#0x17
pop {r4-r7}
pop {r1}
bx r1
bx_r5:
bx r5
.ltorg
Thanks, I’ll see what I learn by examining it