[ASM] Attack modularly with SpecialCommand per unit

1 -

By adding the AttackEffect to 7743’s “Special Command per unit” I can run an event right before battle. It gives you a nice table to use, too.

AttackUsability
ldr r0, =0x80249ac @attack usability
mov lr, r0
.short 0xf800
cmp r0, #1
bne Exit

AttackEffect
ldr r2, =0x8022b30 @attack
mov lr, r2
.short 0xf800

Of course, certain events should not happen at the same time as AttackEffect. But this part works fine if the events are limited to say, only editing memory slots. (Only side effect is that it removes the attacker’s portrait when selecting your weapon.)

2 -

In the PreBattleLoop I can take over a skill, load the memoryslot to a register, and edit the battle that way. If the unit has this skill, it will always add the ldrh of memory slot B to the unit’s avoid.

Replaced Quickburn
.thumb
.equ QuickBurnID, SkillTester+4

push {r4-r5, lr}
mov	r4, r0 @attacker

ldr	r5,=#0x30004E4 @sB
ldrh	r5, [r5,#0x0]

@has skill
ldr	r0, SkillTester
mov	lr, r0
mov	r0, r4
ldr	r1, QuickBurnID
.short	0xf800
cmp	r0, #0
beq	End

mov	r0, #0x62
strh	r1, [r4,r0]     @store

End:
pop	{r4-r5, r15}
.align
.ltorg
SkillTester:
@Poin SkillTester
@WORD QuickBurnID


When I attack regularly, O’Neil has 8 hit, and when I run the event (through Mercy) he has 0 hit (and Eirika’s portrait disappears when the event that says SVAL 0x1 0xA runs. Of course, you could just back out of the attack and s1 would still be 0xA, giving you the 10 avoid anyway.

3 -

I want to make a modular battle command that requires no asm to edit. I see that I can do so with the above 2 things I’ve made edits to, though it clearly has some issues. It would make more sense to create a table of entries to edit for each command, and abandon the idea of running an event at all. Eg. + or - Hit rate, + or - Mt, etc.

a)

How do I check and set global flags? I don’t really understand the below example.

CasualMode uses 0xB0 flag
@hook: ORG 0x18418; jumpToHack(CasualMode)

.thumb
.org 0
CasualMode:
@check for something

push {r4}
mov r4,r2

bl CasualCheck

cmp r0, #0
bne Retreat
mov r3, #5
b Main
Retreat:
mov r3,#9

@original code:
Main:
ldr r0,[r4,#0xc]
mov r1,#5
mvn r1,r1
and r0,r1 @unkill unit (needed for pair up compatibility)
mov r1,r3 @5 for dead, 9 for retreated
orr r0,r1
str r0,[r4,#0xc]
mov r0,r4
ldr r3,=0x80283e1
bl goto_r3
pop {r4}
ldr r3,=0x801842d
goto_r3:
bx r3

CasualCheck:
push {lr}
mov r0, #0xb0 @unused permanent event id
ldr r3,=0x8083da9
bl goto_r3
pop {pc}


b)

Tables scare me. Could anyone recommend some simple examples to look at? Basically all I know about Nightmare is that it’s ran while processing tables in a buildfile. I don’t understand the csvmacro things - are those generated for you?

Magic Growths
#define csvmacro019(arg000,arg001) "BYTE arg000 arg001 "

PUSH
POP
ALIGN 4
MagCharTable:
csvmacro019(0x0,0x0)
csvmacro019(0x0,0x19)


c)

I know that storing data in memory slots between the event and the attack immediately after might be a bad idea. But this data could be stored permanently anyway via a table. How do I retrieve data from my own table that I create? I believe you’re supposed to use stuff like .equ, but is there a way to just give it a permanent address and reference that? Or is a fixed address a bad idea?

d)

SpecialCommand only has 1 menu option. How would I expand it to have around 7 options, just showing the ones available? I took a brief look at Sme’s combat arts but I don’t really understand it yet.

e)

Any suggestions on how I should be tackling this? I feel like I’m in over my head, but hey I got a very flawed event+attack to work. I’d honestly prefer to just magically make it an febuilder patch and continue working on my hack, but I think this will save myself work in the long run if I want to make tons of arbitrary edits to the active battle based on a bunch of parameters set up, similar to the SpecialCommand patch, except it initiates battle & has fields for stuff like bonus Mt, Hit, Avo, etc.

Thanks in advance for any advice given. I’m still pretty inexperienced with ASM, but I’ll do my best to understand your suggestions.

5 Likes

Hi Vesly, me too i am a complete newbie about the assembly codes, but i would still try to help you solve your problem, maybe two can do it
from what I understand, you are trying to recreate combat arts, uch as Echoes or TH3, right?
these bytes from what I have been able to understand from my previous experience are particular, because their state remains saved for the duration of a game, obviously if you create a new file
lifesaving systems start fake
in my project I used them to create multiple choices throughout the various chapters, to activate these bytes, you can easily do it through events, both of the event assembler (buildfile) and the editor of FEbuilderGBA as any other temporary flag
In this code in this code, the section that controls the byte (at least I think so) is:

CasualCheck:
push {lr}
mov r0, #0xb0   @unused permanent event id *this is the line with our byte*
ldr r3,=0x8083da9
bl goto_r3
pop {pc}


because this code checks if the flag 0xB0, he is active to do anything else

> ldr r3,=0x8083da9


this string, I’m not sure it does, but I believe it calls a vanilla function
i think you can use this piece of code to check any other flag bytes

for the CSV tables question, some I think are extracted from the base game, while others are modifications of the latter uch as that of the magic of the characters.
but I don’t think you need it, also I think through the definitions you can change the values of these tables senda go and really touch them (m pretty sure about that because I’ve seen it done)

about point c, I didn’t understand, sorry

while for point d, I did not know of a code for the combat arts but I’m afraid it’s not complete
Chapter 5 appendix by Sme
speaks of combat art as a function that could have come later … and for a temporal matter I think it has not been completed yet, we should ask the original author, it could probably help us

Finally about the final advice, I think we could create a kind of combat arts through command skills, we can try to see how the codes of abilities like capture and mercy are structured, if I’m not mistaken, the capture skill gives the user a debuff, we can lead it to be a buff instead and you can do, stupid example, make the user’s hp pay in order to use them, for this we must also create a function that sees that the HP of our character is greater than a certain tot, always if we do not want to make him make a suicide attack

don’t be afraid to use the buildfile if you also use FEbuilderGBA, I use them together, and never had any problems, to do this you need to use the Custom Skill Build sectio, it is not difficult to use, but if you have problems, I can try to help you

Maybe my message was not very helpful, but I hope that at least it gave you some advice, however I follow this new topic with interest, and if you need help, you can safely contact me, two minds are better than one is not?
and forgive me for my english

1 Like

I’m not 100% sure exactly what you’re trying to do and why, so could you elaborate on that a bit more?

a)
There are vanilla functions we use to toggle and check event IDs.

SET_FUNC SetEventId, 0x8083D81
SET_FUNC UnsetEventId, 0x8083D95
SET_FUNC CheckEventId, 0x8083DA9


These work for temporary and global event IDs.
For calling functions that are out of bl range (which is the case when calling vanilla functions from free space), the blh macro is most commonly used. blh is a pseudo-opcode that mimics bl. This macro needs to go near the top of your asm file:

.macro blh to, reg
ldr \reg, =\to
mov lr, \reg
.short 0xF800
.endm


And I would check an event ID like

mov r0, #EventIDToCheck
blh CheckEventId, r1 @ r1 here is a free (non-parameter) register.
@ r0 contains the boolean for whether this event ID is set.


(The example you showed is a blh call but without using the macro.)

b)
If you’d like to make a vanilla table, it’s easier than you may think. If your table is indexed by something (character ID, etc), you may consider using a CSV. It might be more elegant and easier to work with than an EA expression, but you do need to make an NMM, so the CSV assembler can correctly interpret your CSV. Though you can also just express your table in event assembler with macros. You can also consider a list format over a table format in which instead of referencing an entry based off of an index, you loop through a list checking for conditions in the list until a valid entry or the terminator are reached.

csvmacro…s are just generated by c2ea. That’s how the software expresses the CSV file in a format EA can understand.

c)
If you make your own table, you can organize the data and refer to it however you like. In regards to how exactly to reference your table, loading the pointer to the start of it depends a little bit on whether you’re using the dmp or lyn.event methods of assembling. Once you have the pointer to the start of your table, referencing the exact entry you’re looking for again depends on the format of your data. If you have an indexed table, you multiply the index by the size of a single entry and add it to the pointer to the start of your table. This gets you the pointer to the specific entry you’re looking for. Again alternatively you could use a list format which might be more appropriate.

d)
Sorry I don’t know what “SpeicalCommand” is aside from the OP description.

e)
Again I’m not 100% sure exactly what you’re trying to accomplish, but this sounds like a function in the pre-battle calc loop if you want to make arbitrary edits to battle stats.

Hope that clears some things up!

1 Like