[FE8] Skill System v1.0 - 404 skills done, more on the way

NewSupplyUsability

Rule.
1.Anyone with the Supply skill can access the convoy.
2.Adjacent ones with Supply skills have access to convoys.
3.If AlsoUseVanillaCheck is enabled, check the vanilla routine in addition to the above.
4.If the above conditions are not met, the convoy will not be available.

The current routine fails to implement rule 2 and rule3 and rule 4.
and , The current routine has a bug “If AlsoUseVanillaCheck is enabled, anyone can access Supply.”

Therefore, I rewrote.

@Rule.
@1.Anyone with the Supply skill can access the convoy.
@2.Adjacent ones with Supply skills have access to convoys.
@3.If AlsoUseVanillaCheck is enabled, check the vanilla routine in addition to the above.
@4.If the above conditions are not met, the convoy will not be available.
@

.thumb
.align

.equ SupplyID,SkillTester+4
.equ AlsoUseVanillaCheck,SupplyID+4
.equ gActiveUnit,0x3004E50

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

push {r4,r14}
ldr r0, SkillTester
mov lr, r0
ldr r1, =gActiveUnit
ldr r0, [r1]
ldr r1, SupplyID
.short  0xf800
cmp r0, #1
beq ReturnTrue

bl IsPhantom
cmp r0,#0x1
beq ReturnFalse

bl IsAdjacent
cmp r0,#0x1
beq ReturnTrue

ldr r1,AlsoUseVanillaCheck
cmp r1,#0x00
beq ReturnFalse

ForAlsoUseVanillaCheck:
blh 0x08023F64 @VanillaSupplyUsability
b GoBack

ReturnFalse:
mov r0,#3
b GoBack

ReturnTrue:
mov r0,#1

GoBack:
pop {r4}
pop {r1}
bx r1


IsPhantom:
push {lr}
ldr r1,=gActiveUnit
ldr r3,[r1]

ldr r0,[r3,#4]  @RAMUnit->Class
ldrb r0,[r0,#4] @RAMUnit->Class->ID

ldr r1,=0x08023F78  @SupplyUsability => cmp r0, #0x51
ldrb r1,[r1]
cmp r0,r1           @check #0x51
beq IsPhantom_ReturnTrue

@check 7743's summon
ldrb r1, [r3, #0xF] @ramunit->status4
lsr  r1,#0x7
cmp r1,#0x01
beq IsPhantom_ReturnTrue

IsPhantom_ReturnFalse:
mov r0,#0x0
b IsPhantom_Exit

IsPhantom_ReturnTrue:
mov r0,#0x01

IsPhantom_Exit:
pop {r1}
bx r1



IsAdjacent:
push {r4,r5,r6,r7,lr}

ldr r1,=gActiveUnit
ldr r0,[r1]

mov r7, #0x10
ldsb r7, [r0, r7] @RAMUnit->X
mov r6, #0x11
ldsb r6, [r0, r6] @RAMUnit->Y
mov r5, #0x0
ldr r4, =0x080D7C04	@AjaxFourSides[4]

IsAdjacent_Loop:
mov r2, #0x0
ldsb r2, [r4, r2]
add r2 ,r7, r2
mov r0, #0x1
ldsb r0, [r4, r0]
add r0 ,r6, r0
ldr r1, =0x0202E4D8 @(gMapUnit )
ldr r1, [r1, #0x0]

lsl r0 ,r0 ,#0x2    @gMapUnit[x]
add r0 ,r0, r1
ldr r0, [r0, #0x0]

add r0 ,r0, r2      @gMapUnit[x][y]
ldrb r1, [r0, #0x0]
mov r0, #0x80       @???
and r0 ,r1
cmp r0, #0x0
bne IsAdjacent_Next
	mov r0 ,r1
	blh 0x08019430   @GetUnitStruct RET=RAM Unit:@UNIT
	cmp r0, #0x0
	beq IsAdjacent_Next

	ldrb r1, [r0, #0xB]  @ RAMUnit->Unit table ID
	cmp r1,#0x80         @ Enemy supply are not available.
	bge IsAdjacent_Next

	ldr r3, SkillTester
	mov lr, r3
	ldr r1, SupplyID
	.short  0xf800
	cmp r0, #1
	beq IsAdjacent_Return_True

IsAdjacent_Next:
add r4, #0x2
add r5, #0x1
cmp r5, #0x3
ble IsAdjacent_Loop

mov r0, #0x0
b IsAdjacent_Return_Exit

IsAdjacent_Return_True:
mov r0, #0x1

IsAdjacent_Return_Exit:
pop {r4,r5,r6,r7}
pop {r1}
bx r1

.ltorg
.align

SkillTester:
@POIN SkillTester
@WORD SupplyID
@WORD AlsoUseVanillaCheck
2 Likes

Arena_Mage_Melee_Fix.asm in strmag split does not handle Magic Sword correctly.
So I rewritten this.

Rule

  1. The Battle from a position two squares away will display a range motion.
  2. If the weapon supports a range attack in a battle at Arena, display range motion.
  3. If the above does not apply, display melee motion.

Arena_Mage_Melee_Fix.asm

.thumb
.org 0x0

@r0=battle struct
mov		r2, r0		@BattleUnit

@If you're far distance, then Magic Motion.
ldr		r1,=0x0203e120	@gSomethingRelatedToAnimAndDistance
ldrh	r0,[r1]
cmp		r0,#0x00        @Check Distance != 0
bne		RangeMotion		@range motion.

@If not Arena, Melee Motion.
@in Arena, Distance is 0.
ldr		r1,=0x0203E1E4 @gBoolIsArena
ldr		r0,[r1]
cmp		r0,#0x00
beq		MeleeMotion

@If not Arena and weapon->range >=2 , then RangeMotion
mov		r0,r2
add		r0,#0x48
ldrh	r0,[r0]   @ItemID
lsl		r0,#0x18
lsr		r0,#0x18

mov		r1,#0x24
mul		r0,r1
ldr		r1,ItemTable
add		r1,r0

mov		r0, #0x19    @Weapon Range
ldrb	r0, [r1 ,r0]

mov		r1, #0xf
and		r0, r1

cmp		r0, #0x2     @if range >= 2
bge		RangeMotion

MeleeMotion:
mov 	r0,#0x0
b		Exit

RangeMotion:
mov 	r0,#0x1

Exit:
bx		r14

.ltorg
ItemTable:
@
3 Likes

Couple months ago Vigilance would only provide +10 Avoid, but now it doesn’t seem to be working at all.

GetSkills.s

    @ personal skill first, if any

    ldr  r6, [r4]
+    cmp  r6, #0x00
+    beq  no_personal
    ldrb r6, [r6, #0x04] @ var r6 = character id

    ldr  r2, lPersonalSkillTable
    ldrb r2, [r2, r6] @ skill byte

Reference to the class of the dead unit is fine for now.
For the best checking, you should ignore references to the class of the dead unit in the function entry.
However, it may be overkill, since it’s bad when compatibility issues arise.
Therefore, I propose null check only for personal skill check.

This issue was found in a Fury Skill bug.
Fury Skill also determines the skills of dead enemies, so it probably behave strangely from time to time.

5 Likes

Has anyone had issues with the Cunning skill yet?
Currently none of it’s features (lockpicking, steal etc.) are working for me.

Cunning is a display-only skill.
List of skills here, at the bottom of the file are display-only and nonfunctional skills.

Thank you, I didn’t know that. Are there skills with the extended sight in fog/lockpick effect?

Edit: Nevermind, already fixed my problem.

Added AlsoUseVanillaStealCheck option.

#define AlsoUseVanillaStealCheck True

	ALIGN 4
	Can_Unit_Steal:
	#incbin "Can_Unit_Steal.dmp"
	POIN SkillTester
	WORD StealID
	WORD StealPlusID
	WORD AlsoUseVanillaStealCheck <<<

Can_Unit_Steal.s

.thumb

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

@r0=char data ptr

.equ StealID, SkillTester+4
.equ StealPlusID, StealID+4
.equ AlsoUseCheckVanillaSteal, StealPlusID+4

push	{r4-r5,r14}
mov		r4,r0
ldr		r5,SkillTester
ldr		r1,StealID
mov		r14,r5
.short	0xF800
cmp		r0,#0
bne		RetTrue
mov		r0,r4
ldr		r1,StealPlusID
mov		r14,r5
.short	0xF800
cmp		r0,#0
bne		RetTrue

ldr		r0,AlsoUseCheckVanillaSteal
cmp		r0,#0
beq		RetFlase

CheckVanillaSteal_Wrapper:
bl		StealCommandUsability
cmp		r0,#0
bne		RetTrue

RetFlase:
mov		r0,#0
b		GoBack

RetTrue:
mov		r0,#1

GoBack:
pop		{r4-r5}
pop		{r1}
cmp		r0,#0				@necessary due to laziness and space constraints
bx		r1

StealCommandUsability:
push {r4,lr}
ldr r4, =0x03004E50
ldr r2, [r4, #0x0] 
ldr r0, [r2, #0x0]
ldr r1, [r2, #0x4]
ldr r0, [r0, #0x28]
ldr r1, [r1, #0x28]
orr r0 ,r1
mov r1, #0x4
and r0 ,r1
cmp r0, #0x0
beq StealCommandUsability_RetFalse
	ldr r0, [r2, #0xc]
    mov r1, #0x40
    and r0 ,r1
    cmp r0, #0x0
    bne StealCommandUsability_RetFalse
        mov r0 ,r2
        blh 0x08025c00   @MakeTargetListForSteal
        blh 0x0804fd28   @GetTargetListSize Gets list size (used to check for empty lists in usability routines) Number of entries in the list
        cmp r0, #0x0
        beq StealCommandUsability_RetFalse

ldr r0, [r4, #0x0] 
blh 0x080179d8   @GetUnitItemCount
cmp r0, #0x5
beq StealCommandUsability_RetFalse   @ItemFull

StealCommandUsability_RetTrue:
mov		r0,#1
b		StealCommandUsability_GoBack

StealCommandUsability_RetFalse:
mov		r0,#0

StealCommandUsability_GoBack:
pop {r4}
pop {r1}
bx r1

.align
.ltorg
SkillTester:
@
1 Like

This macro issues ORG internally, so PUSH and POP are required.
Without PUSH and POP, the location of ORG will change and cause strange bugs.

skill_animations.event

-#define SkillAnimation(SkillID,Animation) "ORG (SkillAnimationTable + (4*SkillID)); POIN Animation"
+#define SkillAnimation(SkillID,Animation) "PUSH; ORG (SkillAnimationTable + (4*SkillID)); POIN Animation; POP;"

Isn’t the section containing all invocations of this macro immediately followed by an ORG to after the area it’s writing to

I’ve actually encountered a strange bug, so I’m suggesting a fix.
With the addition of this fix it now works correctly.
The current writing style is dangerous.

1 Like

Including the code for Hexing Rod used in the GBA version of SoA, as I was asked about it today.

Include the MasterBuildFile.txt somewhere in your code, and define some free space (Old code so uses free space).

In addition, in the EngineHacks/ModularStatGetters/DebuffRallyStatmods.event file you add

prHexingRod:
  rIfHasStatus(0x9); rHalveStat

and in EngineHacks/ModularStatGetters.event, replace the HP part with

pMaxHPGetterModifiers: // Max HP
    POIN prAddUnitMaxHP prHexingRod prAddEquipHP 0

This codes makes a staff defined in StaffRepoint.asm (By default the Berserk Staff, 0x53 item ID above beq halve) give the 0x9 Status (I believe this is normally sick). The Modular Stat system then halves the max HP of anyone with that status.

6 Likes

The patch to change the modifier of the seal skills seen broken, can anyone fix it?

Is there any known way to have a “Capture Quote” or on-capture flag trigger that’s different from a regular death quote? I understand this is going to be some weird ASM shit, but was just curious if someone had already tried this.

Can someone make a skill that allows to auto heal?
Lemme explain, you open the command menu. You select “heal”. So far so good.
The unit will recover 10 Hp like he uses a vulnerary. What do you think? Can be made with the actual system?

If this is an FEBuilder-specific issue, then this thread isn’t the place for this report. This is for issues that can be reproduced on the Skill System master buildfile.

Yes there’s a way to do anything that’s not limited by the machine. I wouldn’t consider this weird ASM shit, but since this is not behavior that exists to my knowledge, you would need to write new code to accomplish this. Maybe you could replicate the behavior with event ID shenanigans, but you would need to work with ASM for the real deal.

This is absolutely possible, but if you want results, I suggest learning ASM so that you can do these kinds of things yourself.

4 Likes
@Flare: Halve enemy resistance (Skill% activation)
@differs from Luna in that it only negates res

.thumb
.macro blh to, reg=r3
  ldr \reg, =\to
  mov lr, \reg
  .short 0xf800
.endm
.equ CoronaID, SkillTester+4
.equ d100Result, 0x802a52c
@ r0 is attacker, r1 is defender, r2 is current buffer, r3 is battle data
push {r4-r7,lr}
mov r4, r0 @attacker
mov r5, r1 @defender
mov r6, r2 @battle buffer
mov r7, r3 @battle data
ldr     r0,[r2]           @r0 = battle buffer                @ 0802B40A 6800     
lsl     r0,r0,#0xD                @ 0802B40C 0340     
lsr     r0,r0,#0xD        @Without damage data                @ 0802B40E 0B40     
mov r1, #0xC0 @skill flag
lsl r1, #8 @0xC000
add r1, #2 @miss
tst r0, r1
bne End
@if another skill already activated, don't do anything

@check for Corona proc
ldr r0, SkillTester
mov lr, r0
mov r0, r4 @attacker data
ldr r1, CoronaID
.short 0xf800
cmp r0, #0
beq End
@if user has sure shot, check for proc rate

@check if we are hitting res with our attack
mov r0,r4
add r0,#0x4C
ldr r2,[r0] @r0 = weapon ability word
@is magic weapon: bit 0x00000002
@is magic sword: bit 0x00000040
@either mean we hit res
mov r0,r2
ldr r1,=#0x00000002
and r0,r1
cmp r0,r1
beq ActivateSkill
ldr r1,=0x00000040
and r0,r1
cmp r0,r1
bne End

ActivateSkill:
ldrb r0, [r4, #0x15] @skill stat as activation rate
mov r1, r4 @skill user
blh d100Result
cmp r0, #1
bne End


@if we proc, set the offensive skill flag
ldr     r2,[r6]    
lsl     r1,r2,#0xD                @ 0802B42C 0351     
lsr     r1,r1,#0xD                @ 0802B42E 0B49     
mov     r0, #0x40
lsl     r0, #8           @0x4000, attacker skill activated
orr     r1, r0
ldr     r0,=#0xFFF80000                @ 0802B434 4804     
and     r0,r2                @ 0802B436 4010     
orr     r0,r1                @ 0802B438 4308     
str     r0,[r6]                @ 0802B43A 6018  

ldrb  r0, CoronaID
strb  r0, [r6,#4] 


NegateDefenses:

@if so, recalculate damage with def/2
ldrh r0, [r7, #6] @final mt
ldrh r1, [r7, #8] @enemy def
lsr r1,#1 @/2
sub r0,r1
ldr r2, [r6]
mov r1, #1
tst r1, r2
beq NoCrit
@if crit, multiply by 3
lsl r1, r0, #1
add r0, r1

NoCrit:

cmp r0, #0x7f @damage cap of 127
ble NotCap
mov r0, #0x7f
NotCap:
strh r0, [r7, #4] @final damage

End:
pop {r4-r7}
pop {r15}

.align
.ltorg
SkillTester:
@POIN SkillTester
@WORD CoronaID

Naive fix for Flare bug pointed out by @blood . I tested it and it seems to work, however I’m not 100% sure it works for magic swords.

2 Likes

It has been reported that Skill Forager and Aptitude have stopped working.
str / mag split may be involved.

these have been fixed for a while


2 Likes

In SkillSystems passive booster, the setting position of STAT_CON and STAT_MOV is opposite to the regulation.
This proposal solves that.

//HelperDefinitions.event

#define STAT_HP         0x00
#define STAT_POWER      0x01
#define STAT_SKILL      0x02
#define STAT_SPEED      0x03
#define STAT_DEFENSE    0x04
#define STAT_RESISTANCE 0x05
#define STAT_LUCK       0x06
-#define STAT_CON        0x07
-#define STAT_MOV        0x08
+#define STAT_MOV        0x07
+#define STAT_CON        0x08

If search with STAT_CON, STAT_MOV, it will also hit asm.
It just doesn’t seem to be referenced.

However, it is not good that the values are different, so I think that it should be corrected.

//GetItemConBonus.s

-.equ STAT_CON, 0x7
+.equ STAT_CON, 0x8

//GetItemMovBonus.s

-.equ STAT_MOV, 0x8
+.equ STAT_MOV, 0x7