When we talk about range, we don’t worry about roots and powers and bla bla. That’s too complicated for the player, and the engine doesn’t really handle decimals as well. Range between two units is just counting the tile difference.
add r0,#0x10 @move to x cordinate?
add r1,#0x10 @same but for defender?
One of the biggest things we have to worry about in ASM is knowing what’s currently in our registers. Generally really, this code doesn’t mean much in a vacuum because it depends on what’s in r0 and r1. I’m thinking you’re going to want this code within your unit loop, and that’s not what those registers hold.
Also for defender
, we need to think about what two units we want the distance between. Know that the pre-battle calc loop is looped twice for each battle calculation. Once where the attacker is passed in as r0, and the defender is passed in as r1; and again when the defender is r0, and the attacker is r1. Comments in these skill sources are pretty deceptive in this way, but this is how it works.
I’m going to move to look at your other code block and show you how I would integrate each part of your code.
> mov r1, r5 @Attacker data
> ldr r0, ForLadyID
> .short 0xf800
> cmp r1, #0
> beq Done
You’re comparing r1 to 0 here. Remember that convention dictates that function return values are returned in r0.
> CheckSkill:
> @now check for the skill
> ldr r0, AuraSkillCheck
> mov lr, r0
> mov r0, r4 @attacker
> ldr r1, ForLadyID
> mov r1, #0x0
> mov r2, #0 @can_trade
> mov r3, #2 @range
> .short 0xf800
> cmp r0, #0
> beq Done
You shouldn’t still have the Aura skill checker in here. Remember that it’s only good for checking whether nearby units have skills.
> mov r4, #0x01 @int i=1
> Loop:
> add r4, r4, #0x01
When we loop, it’s good to think about a few important cases in the loop. Think about the first case for example. When we first run this code, r4 is set to 1 and then immediately incremented to 2. This means that the 1 case is skipped! We have a problem. To remedy this, I would just do
> mov r4, #0x00
> Loop:
> add r4, r4, #0x01
lol I’m going to assume that the double gender check is a mistake.
Here’s how I would take each piece and implement them together.
.thumb
.equ AuraSkillCheck, SkillTester+4
.equ ForLadyID, AuraSkillCheck+4
push { r4, r5, lr } @ I only push r4 and r5 because it's unnecessary to push r6 and r7. Pushing/popping is relatively time-consuming!
mov r4, r0 @ We only need to store one battle struct pointer.
@ Does this unit have the skill?
ldr r0, ForLadyID
mov r1, r4
blh SkillTester, r2
cmp r0, #0x00
beq Done
@ Now we need to start looping through player units.
mov r5, #0x00
StartLoop:
add r5, r5, #0x01
cmp r5, #0x63
beq Done
mov r0, r5
blh GetUnit, r1 @ Unit we want to test is in r0.
cmp r0, #0x00
beq StartLoop
ldr r1, [ r0 ]
cmp r0, #0x00
beq StartLoop @ Does this unit exist?
ldr r1, [ r1, #0x28 ] @ Character abilities.
ldr r2, [ r0, #0x04 ]
ldr r2, [ r2, #0x28 ] @ Class abilities.
orr r1, r1, r2
mov r2, #0x40
lsl r2, r2, #0x08 @ IsFemale.
tst r1, r2
beq LoopStart @ Reiterate if this unit is male.
@ We should probably check if this unit is dead too.
ldr r1, [ r0, #0x0C ]
lsr r1, r1, #2
lsl r1, r1, #31
cmp r1, #0x00
bne StartLoop @ Reiterate if this unit is dead.
@ Now let's check the ranges.
ldrb r1, [ r4, #0x10 ] @ Main unit X.
ldrb r2, [ r0, #0x10 ] @ This unit X.
sub r1, r1, r2
cmp r1, #0x00
bge NotNegativeX @ Aaaaa we have to account for the differences being negative.
mov r2, #0x01
neg r2, r2
mul r1, r2 @ Multiply by -1. There may be a more efficient way to do this but eh.
NotNegativeX:
ldrb r2, [ r4, #0x11 ] @ Main unit Y.
ldrb r3, [ r4, #0x11 ] @ This unit Y.
sub r2, r2, r3
cmp r2, #0x00
bge NotNegativeY
mov r3, #0x01
neg r3, r3
mul r2, r3
NotNegativeY:
@ r1 has |XDifference|, and r2 has |YDifference|.
add r1, r1, r2 @ Total distance between these units.
cmp r1, #0x03 @ I think 3 is your range?
bgt StartLoop @ This unit is outside the range.
@ We've passed all of the conditions. Let's apply the bonus!
mov r1, #0x5A
ldrh r2, [ r4, r1 ] @ Attacker's damage.
add r2, r2, #2 @ Add 2 damage.
strh r2, [ r4, r1 ]
mov r1, #0x60
ldrh r2, [ r4, r1 ] @ Attacker's hit.
add r2, r2, #10 @ Add 10 hit.
strh r2, [ r4, r1 ]
Done:
pop { r4, r5 }
pop { r0 }
bx r0
.align
.ltorg
CharData:
.long 0x202be4c
MovementPoin:
.long 0x880bb96
SkillTester:
@POIN SkillTester
@ POIN AuraSkillCheck
@ WORD ForLadyID
Untested, and I probably made mistakes, but this is how I would do this.
A problem with this methodology occurred to me while writing this, though. This only works for player units. When we write skills, we want them to work for all allegiances. This means that we need to find a way to loop through units of a given allegiance matching the passed in unit’s. This is only if you want the bonus to be applied if a female unit of the same allegiance is within the range. All units could just be looped through if you want this to not be allegiance-specific.