From 9716ca09c8ce98ff017a6ef079ad53648fe8503c Mon Sep 17 00:00:00 2001 From: JesterWizard Date: Thu, 6 Nov 2025 15:46:45 +0000 Subject: [PATCH] Initial commit --- .../StatusExpansion/AssembleLynEvent.bat | 26 + .../StatusExpansion/Enfeeble/Enfeeble.event | 14 + .../Enfeeble/Enfeeble.lyn.event | 7 + .../StatusExpansion/Enfeeble/Enfeeble.s | 37 + .../StatusExpansion/Freeze/EventFreeze.event | 18 + .../StatusExpansion/Freeze/Freeze.event | 67 + .../Freeze/asm/AssembleARM.bat | 20 + .../Freeze/asm/freeze_decrease.dmp | Bin 0 -> 44 bytes .../Freeze/asm/freeze_decrease.s | 30 + .../Freeze/asm/freeze_decrease_2.dmp | Bin 0 -> 108 bytes .../Freeze/asm/freeze_decrease_2.s | 65 + .../StatusExpansion/Freeze/asm/freezeall.dmp | Bin 0 -> 40 bytes .../StatusExpansion/Freeze/asm/freezeall.s | 27 + .../Freeze/asm/unused/freeze.dmp | Bin 0 -> 52 bytes .../Freeze/asm/unused/freeze.s | 32 + .../Freeze/asm/unused/freezemovement.dmp | 1 + .../Haste/AssembleLynEvent.bat | 26 + .../StatusExpansion/Haste/Haste.event | 22 + .../StatusExpansion/Haste/Haste.lyn.event | 11 + .../StatusExpansion/Haste/Haste.s | 75 + .../StatusExpansion/HexingRod/HexingRod.event | 13 + .../StatusExpansion/MinimugBoxNames.png | Bin 0 -> 909 bytes .../StatusExpansion/Numb/AssembleLynEvent.bat | 26 + .../StatusExpansion/Numb/Numb.event | 11 + .../StatusExpansion/Numb/Numb.lyn.event | 8 + .../ExternalHacks/StatusExpansion/Numb/Numb.s | 55 + .../Regen/AssembleLynEvent.bat | 26 + .../StatusExpansion/Regen/Regen.event | 13 + .../StatusExpansion/Regen/Regen.lyn.event | 7 + .../StatusExpansion/Regen/Regen.s | 32 + .../Regen/RenewalAmaterasu.lyn.event | 40 + .../StatusExpansion/Regen/RenewalAmaterasu.s | 281 ++++ .../StatusExpansion/Slow/AssembleLynEvent.bat | 26 + .../StatusExpansion/Slow/Slow.event | 14 + .../StatusExpansion/Slow/Slow.lyn.event | 6 + .../ExternalHacks/StatusExpansion/Slow/Slow.s | 41 + .../StatusExpansion/StatusExpansion.event | 274 ++++ .../StatusExpansion/StatusExpansion.lyn.event | 11 + .../StatusExpansion/StatusExpansion.s | 59 + .../StatusExpansion/_compat/Boon.dmp | Bin 0 -> 100 bytes .../StatusExpansion/_compat/Boon.s | 86 + .../_compat/CanUnitWieldWeapon.dmp | Bin 0 -> 244 bytes .../_compat/CanUnitWieldWeapon.s | 183 +++ .../_compat/ProcSkills/proc_deadeye.dmp | Bin 0 -> 108 bytes .../_compat/ProcSkills/proc_deadeye.s | 76 + .../_compat/ProcSkills/proc_enrage.dmp | Bin 0 -> 108 bytes .../_compat/ProcSkills/proc_enrage.s | 76 + .../_compat/ProcSkills/proc_petrify.dmp | Bin 0 -> 108 bytes .../_compat/ProcSkills/proc_petrify.s | 76 + .../_compat/WarningAndHpBars.lyn.event | 29 + .../_compat/WarningAndHpBars.s | 442 ++++++ .../StatusExpansion/_compat/mss_defs.s | 1397 +++++++++++++++++ .../StatusExpansion/_compat/status_text.txt | 51 + EngineHacks/_MasterHackInstaller.event | 4 + 54 files changed, 3841 insertions(+) create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/AssembleLynEvent.bat create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/EventFreeze.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/Freeze.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/AssembleARM.bat create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freeze_decrease.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freeze_decrease.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freeze_decrease_2.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freeze_decrease_2.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freezeall.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freezeall.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freezemovement.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Haste/AssembleLynEvent.bat create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/HexingRod/HexingRod.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/MinimugBoxNames.png create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Numb/AssembleLynEvent.bat create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Regen/AssembleLynEvent.bat create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Slow/AssembleLynEvent.bat create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.dmp create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.lyn.event create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/mss_defs.s create mode 100644 EngineHacks/ExternalHacks/StatusExpansion/_compat/status_text.txt diff --git a/EngineHacks/ExternalHacks/StatusExpansion/AssembleLynEvent.bat b/EngineHacks/ExternalHacks/StatusExpansion/AssembleLynEvent.bat new file mode 100644 index 00000000..b78658fe --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/AssembleLynEvent.bat @@ -0,0 +1,26 @@ +@echo off + +SET startDir="C:\devkitPro\devkitARM\bin\" +SET as="%startDir%arm-none-eabi-as" +SET LYN="C:\devkitPro\lyn.exe" + +@rem Assemble into an elf +%as% -g -mcpu=arm7tdmi -mthumb-interwork %1 -o "%~n1.elf" + +if exist "Definitions.s" ( + + @rem Assemble definitions into a .elf if exists + %as% -g -mcpu=arm7tdmi -mthumb-interwork "Definitions.s" -o "Definitions.elf" + + @rem Assebmle into a .lyn.event with definitions + %LYN% "%~n1.elf" "Definitions.elf" > "%~n1.lyn.event" + + echo y | del "%~dp0Definitions.elf" +) else ( + @rem Assemble into a .lyn.event + %LYN% "%~n1.elf" > "%~n1.lyn.event" +) + +echo y | del "%~n1.elf" + +pause \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.event b/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.event new file mode 100644 index 00000000..2d7cbd0c --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.event @@ -0,0 +1,14 @@ +#define EnfeebleStatusID 0x0E //last valid status ID + +// SetStatusName(EnfeebleStatusID,EnfeebleStatusName) +// SetStatusDesc(EnfeebleStatusID,EnfeebleStatusDesc) +SetStatusBlinkyIconFunc(EnfeebleStatusID,BlinkyIconFuncSilenceIcon) + +#include "Enfeeble.lyn.event" + +ALIGN 4 +EnfeebleStatusIDLink: +BYTE EnfeebleStatusID + +// Add `EnfeebleStatDebuff` to stat getters for stats you want enfeeble to debuff +// Define EnfeebleName and EnfeebleDesc (only used on stat screen) diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.lyn.event new file mode 100644 index 00000000..bd8b39a7 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.lyn.event @@ -0,0 +1,7 @@ +ALIGN 4 +PUSH +ORG CURRENTOFFSET+$1;EnfeebleStatDebuff: +POP +SHORT $B5F0 $1C05 $1C0C $4E08 $7836 $1C20 $3030 $7800 $211F $4001 $42B1 $D101 $940 $1A2D $1C28 $1C21 $BCF0 $BC04 $4710 +BYTE $0 $0 +POIN EnfeebleStatusIDLink diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.s b/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.s new file mode 100644 index 00000000..af8d7bb6 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Enfeeble/Enfeeble.s @@ -0,0 +1,37 @@ +.thumb +.align + + +.global EnfeebleStatDebuff +.type EnfeebleStatDebuff, %function + + +EnfeebleStatDebuff: +push {r4-r7,r14} +mov r5, r0 @stat +mov r4, r1 @unit +ldr r6,=EnfeebleStatusIDLink +ldrb r6,[r6] + +mov r0,r4 +add r0,#0x30 +ldrb r0,[r0] +mov r1,#0x1F +and r1,r0 +cmp r1,r6 +bne EndEnfeebled + +lsr r0,r0,#5 +sub r5,r0 + + +EndEnfeebled: +mov r0,r5 +mov r1,r4 +pop {r4-r7} +pop {r2} +bx r2 + + +.ltorg +.align diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/EventFreeze.event b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/EventFreeze.event new file mode 100644 index 00000000..6125f2c3 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/EventFreeze.event @@ -0,0 +1,18 @@ +#ifndef EVENT_FREEZE +#define EVENT_FREEZE + +// Freeze all enemies ASMC. +// Hack by circleseverywhere + +#ifdef _FE8_ + + ALIGN 4 + FreezeAllASMC: + #incbin "asm/freezeall.dmp" + WORD FreezeStatusID + +#else // _FE8_ + ERROR Freeze All ASMC hack is for FE8 +#endif // _FE8_ + +#endif // EVENT_FREEZE diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/Freeze.event b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/Freeze.event new file mode 100644 index 00000000..53678f54 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/Freeze.event @@ -0,0 +1,67 @@ +#define FreezeStatusID 0xF + +// SetStatusName(FreezeStatusID,FreezeStatusName) +// SetStatusDesc(FreezeStatusID,FreezeStatusDesc) +SetStatusBlinkyIconFunc(FreezeStatusID,BlinkyIconFuncSleepIcon) + +//Define text IDs for name and desc +//put the following in the mov getter in place of what's normally there for freeze +// prNullifyIfFreeze: +// rIfUnitHasStatus(FreezeStatusID) +// rConstant(0) + +// Freeze status. +// Hack by CrazyColorz5 + +#ifdef _FE8_ + + { + + // TODO: make the sleep staff inflict freeze + + PUSH + //ORG 0x276F8 //sick displays sleep map anim + //WORD 0x80277A8 + + // ORG 0x178EA //2 turns = 1 player phase + // BYTE 0x20 + + //ORG 0x8C3D8 + // WORD 0x808C3F0 //HP area display + + ORG $18d50 + // jumpToHack(FreezeEffect) //I think the move getters are good enough + + ORG $188e4 + jumpToHack(FreezeDecrease) + + ORG $18878 + jumpToHack(FreezeDecrease2) + POP + + ALIGN 4 + // FreezeEffect: + // #incbin "ASM/freeze.dmp" + // POIN FreezeMovement + + ALIGN 4 + // FreezeMovement: + // #incbin "ASM/freezemovement.dmp" + + ALIGN 4 + FreezeDecrease: + #incbin "asm/freeze_decrease.dmp" + WORD FreezeStatusID + + ALIGN 4 + FreezeDecrease2: + #incbin "asm/freeze_decrease_2.dmp" + WORD FreezeStatusID + + } + +#else // _FE8_ + ERROR Freeze hack is for FE8 +#endif // _FE8_ + + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/AssembleARM.bat b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/AssembleARM.bat new file mode 100644 index 00000000..43a1b73d --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/AssembleARM.bat @@ -0,0 +1,20 @@ +@echo off + +SET startDir=C:\devkitPro\devkitARM\bin\ + +@rem Assemble into an elf +SET as="%startDir%arm-none-eabi-as" +%as% -g -mcpu=arm7tdmi -mthumb-interwork %1 -o "%~n1.elf" + +@rem Print symbol table +SET readelf="%startDir%arm-none-eabi-readelf" +%readelf% -s "%~n1.elf" > "%~n1.symbols.log" + +@rem Extract raw assembly binary (text section) from elf +SET objcopy="%startDir%arm-none-eabi-objcopy" +%objcopy% -S "%~n1.elf" -O binary "%~n1.dmp" + +echo y | del "%~n1.elf" + +echo y | del "%~n1.symbols.log" +pause \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freeze_decrease.dmp b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freeze_decrease.dmp new file mode 100644 index 0000000000000000000000000000000000000000..faf93ba07804d1727e7773df1a251b8cfbc3b9c9 GIT binary patch literal 44 ycmd%ov*hG_Au^YaA#mJn8L^b0RN#3C;$Ke literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freezeall.s b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freezeall.s new file mode 100644 index 00000000..aee68470 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/freezeall.s @@ -0,0 +1,27 @@ +.thumb +@freeze all enemies + +push {r4-r6,lr} +mov r4, #0x81 @first enemy +ldr r5, =0x8019430 @get ram from dplynum +mov r6, #0x30 @status byte +NextEnemy: +mov r0, r4 +mov lr, r5 +.short 0xf800 +@r0 is now ram +ldr r2,FreezeStatusID +mov r1,#0x2 @1-turn duration +orr r1,r2 +strb r1, [r0, r6] +add r4, #1 +cmp r4, #0xC0 +blt NextEnemy +pop {r4-r6} +pop {r0} +bx r0 + +.ltorg +.align + +FreezeStatusID: diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.dmp b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.dmp new file mode 100644 index 0000000000000000000000000000000000000000..bc64f656943912d5085874b0a3b1a4b9ec3fb619 GIT binary patch literal 52 zcmXp|5QyPd)nMuQ?JBZmWn2Ga#54`xpecMxV^kl53}(cR0)kqX2B DE5i$n literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.s b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.s new file mode 100644 index 00000000..e1123b76 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freeze.s @@ -0,0 +1,32 @@ +.thumb +@replaces 8018d50 (use jumpToHack there) +@0x8 bytes) + +mov r0, #0x30 +ldrb r0, [r2,r0] @status +mov r1, #0xF +and r0, r1 +cmp r0, #0x9 +bne NotFrozen +ldr r0, FrozenMovementTable +b MoveFound + +NotFrozen: +ldr r0, [r2, #0xC] +mov r1, #0x80 +lsl r1, #4 @bit 0x800 'in ballista' +and r0, r1 +cmp r0, #0 +beq NotBallista +ldr r0, =0x880bc18 @ballista movement + +MoveFound: +ldr r1, =0x8018d8a+1 @return with movement found +bx r1 +NotBallista: +ldr r1, =0x8018d64+1 @return for normal +bx r1 + +.ltorg +FrozenMovementTable: +@POIN table of 0xFF 104 times diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freezemovement.dmp b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freezemovement.dmp new file mode 100644 index 00000000..6e5b7a5f --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Freeze/asm/unused/freezemovement.dmp @@ -0,0 +1 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Haste/AssembleLynEvent.bat b/EngineHacks/ExternalHacks/StatusExpansion/Haste/AssembleLynEvent.bat new file mode 100644 index 00000000..b78658fe --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Haste/AssembleLynEvent.bat @@ -0,0 +1,26 @@ +@echo off + +SET startDir="C:\devkitPro\devkitARM\bin\" +SET as="%startDir%arm-none-eabi-as" +SET LYN="C:\devkitPro\lyn.exe" + +@rem Assemble into an elf +%as% -g -mcpu=arm7tdmi -mthumb-interwork %1 -o "%~n1.elf" + +if exist "Definitions.s" ( + + @rem Assemble definitions into a .elf if exists + %as% -g -mcpu=arm7tdmi -mthumb-interwork "Definitions.s" -o "Definitions.elf" + + @rem Assebmle into a .lyn.event with definitions + %LYN% "%~n1.elf" "Definitions.elf" > "%~n1.lyn.event" + + echo y | del "%~dp0Definitions.elf" +) else ( + @rem Assemble into a .lyn.event + %LYN% "%~n1.elf" > "%~n1.lyn.event" +) + +echo y | del "%~n1.elf" + +pause \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.event b/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.event new file mode 100644 index 00000000..799525e7 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.event @@ -0,0 +1,22 @@ + +#include "Haste.lyn.event" + +#define HasteStatusID 0x0B + +// SetStatusName(HasteStatusID,HasteStatusName) +// SetStatusDesc(HasteStatusID,HasteStatusDesc) +SetStatusBlinkyIconFunc(HasteStatusID,BlinkyIconFuncDancerRingIcon) + +HasteStatusIDLink: +BYTE HasteStatusID + +// define text & put `HastePostBattle` in the post-battle calc loop + +ALIGN 4 +HasteEvent: //plays a sound when getting refreshed +CAM1 0xFFFF +SOUN 0x10F +STAL 0x16 +NoFade +ENDA + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.lyn.event new file mode 100644 index 00000000..59a797f4 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.lyn.event @@ -0,0 +1,11 @@ +ALIGN 4 +PUSH +ORG CURRENTOFFSET+$1;HastePostBattle: +POP +SHORT $B500 $7CE0 $2800 $D024 $68E0 $2104 $209 $4008 $2800 $D11E $1C20 $3030 $7800 $211F $4008 $490E $7809 $4288 $D115 $68E0 $2142 $43C9 $4008 $2104 $209 $4308 $60E0 $4809 $7AE1 $3001 $7802 $2A00 $D1FB $7001 $3001 $7002 $4805 $4686 $4805 $2101 +BYTE $0 $F8 +SHORT $BC01 $4700 +BYTE $0 $0 +POIN HasteStatusIDLink +BYTE $3 $AA $3 $2 $7C $D0 $0 $8 +POIN HasteEvent diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.s b/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.s new file mode 100644 index 00000000..39860dc9 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Haste/Haste.s @@ -0,0 +1,75 @@ +.thumb +.align + +.global HastePostBattle +.type HastePostBattle, %function + +.macro blh to, reg=r3 + ldr \reg, =\to + mov lr, \reg + .short 0xf800 +.endm + +HastePostBattle: +push {r14} + +@check if dead +ldrb r0, [r4,#0x13] +cmp r0, #0x00 +beq End + +@check if already galeforced this turn +ldr r0, [r4,#0x0C] @status bitfield +mov r1, #0x04 +lsl r1, #0x08 +and r0, r1 +cmp r0, #0x00 +bne End + +@check for status +mov r0, r4 +add r0,#0x30 +ldrb r0,[r0] +mov r1,#0x1F +and r0,r1 +ldr r1,=HasteStatusIDLink +ldrb r1,[r1] +cmp r0,r1 +bne End + +@unset 0x2 and 0x40, set 0x400, write to status +ldr r0, [r4,#0x0C] @status bitfield +mov r1, #0x42 +mvn r1, r1 +and r0, r1 @unset bits 0x42 +mov r1, #0x04 +lsl r1, #0x08 +orr r0, r1 +str r0, [r4,#0x0C] + +@add unit to the AI list so enemies act twice +ldr r0,=#0x203AA03 +ldrb r1, [r4,#0x0B] @allegiance byte of the character we are checking +AddAILoop: +add r0, #0x01 +ldrb r2, [r0] +cmp r2, #0x00 +bne AddAILoop +strb r1, [r0] +add r0, #0x01 +strb r2, [r0] + +Event: +ldr r0,=#0x800D07C @event engine thingy +mov lr, r0 +ldr r0, =HasteEvent @this event is just "play some sound effects" +mov r1, #0x01 @0x01 = wait for events +.short 0xF800 + +End: +pop {r0} +bx r0 + +.ltorg +.align + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/HexingRod/HexingRod.event b/EngineHacks/ExternalHacks/StatusExpansion/HexingRod/HexingRod.event new file mode 100644 index 00000000..9be1c6f5 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/HexingRod/HexingRod.event @@ -0,0 +1,13 @@ + +#define HexingRodStatusID 0x0A + +// SetStatusName(HexingRodStatusID,HexingRodStatusName) +// SetStatusDesc(HexingRodStatusID,HexingRodStatusDesc) +SetStatusBlinkyIconFunc(HexingRodStatusID,BlinkyIconFuncNoIcon) + +//add this to the max HP getter file +// prHexingRodStatus: +// rIfUnitHasStatus(HexingRodStatusID); rHalved +//and a ptr to prHexingRodStatus to the getter loop itself +//define text IDs for name and desc (only used on stat screen) + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/MinimugBoxNames.png b/EngineHacks/ExternalHacks/StatusExpansion/MinimugBoxNames.png new file mode 100644 index 0000000000000000000000000000000000000000..483d0c11bde8a6a18dd8ab812ea814952c82baee GIT binary patch literal 909 zcmV;819JR{P)*x0zZxF{$n5S}QK0009R zNklnWBc0zCi#+~q+~jqnIw zd_!Y-+N1yxhzRtF1LUs%ZM}d#25KLCLdGs8M;rNHofUc_4!n0S=~mA+@u+x zdhK@Z)MJR9upWqi^cX4ZI_RF{BbGOI@~eMPi|N9S#>cOdf7p}@lJuy4@CkAkvYZ1f zMs|~V=pdZY{vxBMaxu~mq%H93mw4^Jg4X<8Tfmr~eVU1k7P2Bqn|ca;juVchOk}i> z)!`gIF%;Gx8mo&dRE1H4j6d@=>b`66C|zElDWP;bF0g}x`Z0Y{fHXn7 z*dnQK|8Sp^g)&&OQz)~8b_<|fgK@Jkk7N&y3W`sL1K2dYzhAA7#{9^s5hJ_@gp6d( zm3h4CO|UXR4Ac-Yw*Sp&*K!c>B>o)9TtOiO6;qJF{%~0CpVW-Gc0g${)&OHckP?V2 z0NTAN+d(#PU3ktH;je8tD(6Oeyuy%i5wa!8ZcqX(6eN3d7LOxBU_WAHIty9{jZ{f1 z5qVJC&)O+QHIn;{6Cd|fi}Wm#XnBYHe#ecBh|#mu`#p=4^b62#1FsX+sni84r{nsC zj-a*{nl4sSGolyOmP5<6=uV};dl|i3De&r(%_n_Jl(qCcscj%>VQ>DJpd?P?h*{6B zr>R_LD38lVDiI~0U>tuEg>$2FqDn4hZJ1UQlICb7rKmn@a-a8`&=>$ril>N6PrxIfCH*24K1lto7N "%~n1.lyn.event" + + echo y | del "%~dp0Definitions.elf" +) else ( + @rem Assemble into a .lyn.event + %LYN% "%~n1.elf" > "%~n1.lyn.event" +) + +echo y | del "%~n1.elf" + +pause \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.event b/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.event new file mode 100644 index 00000000..63d2cc93 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.event @@ -0,0 +1,11 @@ + +#define NumbStatusID 0x08 + +// SetStatusName(NumbStatusID,NumbStatusName) +// SetStatusDesc(NumbStatusID,NumbStatusDesc) +SetStatusBlinkyIconFunc(NumbStatusID,BlinkyIconFuncSilenceIcon) + +#include "Numb.lyn.event" + +NumbStatusIDLink: +BYTE NumbStatusID diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.lyn.event new file mode 100644 index 00000000..7889eadc --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.lyn.event @@ -0,0 +1,8 @@ +ALIGN 4 +PUSH +ORG CURRENTOFFSET+$1;NumbFunc: +POP +SHORT $B5F0 $1C04 $1C0D $1C16 $1C20 $3030 $7800 $6C0 $EC0 $490D $7809 $4288 $D111 $21FF $4029 $2024 $4341 $480A $1842 $1C10 $3008 $6800 $2146 $4008 $2800 $D104 $79D0 $2804 $D001 $2000 $E000 $2001 $BCF0 $BC02 $4708 +BYTE $0 $0 +POIN NumbStatusIDLink +POIN ItemTable diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.s b/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.s new file mode 100644 index 00000000..df32b540 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Numb/Numb.s @@ -0,0 +1,55 @@ +.thumb +.align + + +.global NumbFunc +.type NumbFunc, %function +NumbFunc: @return usability bool in r0 + +push {r4-r7,r14} +mov r4,r0 @character pointer +mov r5,r1 @item halfword +mov r6,r2 @character wrank. + +mov r0,r4 +add r0,#0x30 +ldrb r0,[r0] +lsl r0,#27 +lsr r0,#27 +ldr r1,=NumbStatusIDLink +ldrb r1,[r1] +cmp r0,r1 +bne RetTrue + +@load weapon ability word @@@@@this is not an attacker struct we can't use the version in ram!!! +mov r1,#0xFF +and r1,r5 +mov r0,#0x24 +mul r1,r0 +ldr r0,=ItemTable +add r2,r0,r1 +mov r0,r2 +add r0,#8 +ldr r0,[r0] +mov r1,#0x46 @magic weapon or staff or magic sword +and r0,r1 +cmp r0,#0 +bne RetTrue +ldrb r0,[r2,#7] @weapon type +cmp r0,#4 @staff because apparently the staff bit doesn't count +beq RetTrue + +RetFalse: +mov r0,#0 +b GoBack + +RetTrue: +mov r0,#1 + +GoBack: +pop {r4-r7} +pop {r1} +bx r1 + +.ltorg +.align diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Regen/AssembleLynEvent.bat b/EngineHacks/ExternalHacks/StatusExpansion/Regen/AssembleLynEvent.bat new file mode 100644 index 00000000..b78658fe --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Regen/AssembleLynEvent.bat @@ -0,0 +1,26 @@ +@echo off + +SET startDir="C:\devkitPro\devkitARM\bin\" +SET as="%startDir%arm-none-eabi-as" +SET LYN="C:\devkitPro\lyn.exe" + +@rem Assemble into an elf +%as% -g -mcpu=arm7tdmi -mthumb-interwork %1 -o "%~n1.elf" + +if exist "Definitions.s" ( + + @rem Assemble definitions into a .elf if exists + %as% -g -mcpu=arm7tdmi -mthumb-interwork "Definitions.s" -o "Definitions.elf" + + @rem Assebmle into a .lyn.event with definitions + %LYN% "%~n1.elf" "Definitions.elf" > "%~n1.lyn.event" + + echo y | del "%~dp0Definitions.elf" +) else ( + @rem Assemble into a .lyn.event + %LYN% "%~n1.elf" > "%~n1.lyn.event" +) + +echo y | del "%~n1.elf" + +pause \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.event b/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.event new file mode 100644 index 00000000..6ccb64d9 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.event @@ -0,0 +1,13 @@ + +#define RegenStatusID 0x09 + +// SetStatusName(RegenStatusID,RegenStatusName) +// SetStatusDesc(RegenStatusID,RegenStatusDesc) + +ALIGN 4 +RegenStatusIDLink: +BYTE RegenStatusID + +#include "Regen.lyn.event" + +//add `RegenFunc` to HP restoration calc loop diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.lyn.event new file mode 100644 index 00000000..c2bee942 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.lyn.event @@ -0,0 +1,7 @@ +ALIGN 4 +PUSH +ORG CURRENTOFFSET+$1;RegenFunc: +POP +SHORT $B500 $3030 $7800 $221F $4010 $4A04 $7812 $4290 $D100 $3119 $1C08 $BC02 $4708 +BYTE $0 $0 +POIN RegenStatusIDLink diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.s b/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.s new file mode 100644 index 00000000..49821b59 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Regen/Regen.s @@ -0,0 +1,32 @@ +.thumb +.align + +.global RegenFunc +.type RegenFunc, %function + +RegenFunc: +push {r14} + +//r0 = unit, r1 = current heal % +//return new heal % in r0 + +@check for status +add r0,#0x30 +ldrb r0,[r0] +mov r2,#0x1F +and r0,r2 +ldr r2,=RegenStatusIDLink +ldrb r2,[r2] +cmp r0,r2 +bne NoRegenStatus + +@add 25% regen +add r1,#25 + +NoRegenStatus: +mov r0, r1 @return the amount healed. +pop {r1} +bx r1 + +.ltorg +.align diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.lyn.event new file mode 100644 index 00000000..c297abe6 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.lyn.event @@ -0,0 +1,40 @@ +ALIGN 4 +SHORT $B570 $4951 $1840 $7800 $600 $1604 $484F $4686 $1C28 $494F $7809 +BYTE $0 $F8 +SHORT $2800 $D000 $341E $484D $4686 $1C28 $494C $7809 $2200 $2302 +BYTE $0 $F8 +SHORT $2800 $D000 $3414 $4845 $4686 $1C28 $4948 $7809 +BYTE $0 $F8 +SHORT $2800 $D009 $4843 $4686 $1C28 $2100 $2200 $2302 +BYTE $0 $F8 +SHORT $2800 $D000 $340A $483C $4686 $1C28 $4940 $7809 +BYTE $0 $F8 +SHORT $2800 $D009 $483A $4686 $1C28 $2100 $2200 $2302 +BYTE $0 $F8 +SHORT $2800 $D100 $3414 $4835 $4686 $1C28 $4938 $7809 $2200 $2303 +BYTE $0 $F8 +SHORT $2800 $D000 $340A $482E $4686 $1C28 $4933 $7809 +BYTE $0 $F8 +SHORT $2800 $D00F $7C28 $7C69 $89 $4A30 $6812 $5852 $5C10 $492F $780A $2A00 $D004 $4282 $D001 $3101 $E7F8 $3414 $4822 $4686 $1C28 $492A $7809 +BYTE $0 $F8 +SHORT $2800 $D009 $1C28 $303A $7800 $2164 $4348 $1C29 $7C89 $1840 $DF06 $1824 $4824 $7B80 $4924 $468E +BYTE $0 $F8 +SHORT $6A03 $3B06 $7C28 $7C69 $4E21 $7836 $3306 $881A $2A00 $D012 $781A $42B2 $D1F8 $785A $4290 $D1F5 $789A $4291 $D1F2 $B40B $7958 $491A $468E +BYTE $0 $F8 +SHORT $2801 $BC0B $D0EA $791A $1914 $1C28 $3030 $7800 $211F $4008 $4914 $7809 $4288 $D100 $3419 $1C20 $BC70 $BC02 $4708 $46C0 +BYTE $44 $C7 $80 $8 +POIN SkillTester +POIN RenewalRenewalIDLink +POIN AuraSkillCheck +POIN RenewalAmaterasuIDLink +POIN RenewalCamaraderieIDLink +POIN RenewalReliefIDLink +POIN RenewalBondIDLink +POIN RenewalForagerIDLink +BYTE $DC $E4 $2 $2 +POIN ForagerList +POIN RenewalImbueIDLink +BYTE $F0 $BC $2 $2 $B0 $46 $3 $8 +POIN RenewalHealTrapID +BYTE $A8 $3D $8 $8 +POIN RegenStatusIDLink diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.s b/EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.s new file mode 100644 index 00000000..870b708e --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Regen/RenewalAmaterasu.s @@ -0,0 +1,281 @@ +.thumb +@.equ RenewalID, SkillTester+4 +@.equ AuraSkillCheck, RenewalID+4 +@.equ AmaterasuID, AuraSkillCheck+4 +@.equ CamaraderieID, AmaterasuID+4 +@.equ ReliefID, CamaraderieID+4 +@.equ BondID, ReliefID+4 +@.equ ChapterDataStruct, BondID+4 +@.equ GetChapterEvents, ChapterDataStruct+4 +@.equ HealTrapID, GetChapterEvents+4 + +@.equ ChapterDataStruct, #0x0202BCF0 +@.equ GetChapterEvents, #0x080346B0 +@.equ CheckEventID, #0x08083DA8 + +.macro blh to, reg + ldr \reg, =\to + mov lr, \reg + .short 0xF800 +.endm + +push {r4 - r6, lr} +ldr r1, Some_Offset +add r0, r0, r1 +ldrb r0, [r0] +lsl r0, r0, #0x18 +asr r4, r0, #0x18 +@That much is copy-paste from vanilla. +@It loads %HP to heal from terrain into r4 + +@Now check for Renewal skill + +ldr r0, =SkillTester +mov lr, r0 +mov r0, r5 +ldr r1, =RenewalRenewalIDLink +ldrb r1, [ r1 ] +.short 0xf800 +cmp r0, #0x0 +beq no_renewal + @add hp + add r4, #30 +no_renewal: + +@Now check for Amaterasu +ldr r0, =AuraSkillCheck +mov lr, r0 +mov r0, r5 @unit +ldr r1, =RenewalAmaterasuIDLink +ldrb r1, [ r1 ] +mov r2, #0 @same_team +mov r3, #2 @range +.short 0xf800 +cmp r0, #0 +beq no_amaterasu +add r4, #20 @heal 20% hp + +no_amaterasu: + +@Now check for Camaraderie +ldr r0, =SkillTester +mov lr, r0 +mov r0, r5 +ldr r1, =RenewalCamaraderieIDLink +ldrb r1, [ r1 ] +.short 0xf800 +cmp r0, #0x0 +beq no_camaraderie + @check for allies in range: + ldr r0, =AuraSkillCheck + mov lr, r0 + mov r0, r5 @unit + mov r1, #0 @always true + mov r2, #0 @same_team + mov r3, #2 @range + .short 0xf800 + cmp r0, #0 + beq no_camaraderie + @if allies in range, heal 10% + add r4, #10 + +no_camaraderie: + +@check for relief +ldr r0, =SkillTester +mov lr, r0 +mov r0, r5 +ldr r1, =RenewalReliefIDLink +ldrb r1, [ r1 ] +.short 0xf800 +cmp r0, #0x0 +beq no_relief + @check for allies in range: + ldr r0, =AuraSkillCheck + mov lr, r0 + mov r0, r5 @unit + mov r1, #0 @always true + mov r2, #0 @same_team + mov r3, #2 @range + .short 0xf800 + cmp r0, #0 + bne no_relief + @if no allies in range, heal 20% + add r4, #20 + +no_relief: + +@Now check for bond +ldr r0, =AuraSkillCheck +mov lr, r0 +mov r0, r5 @unit +ldr r1, =RenewalBondIDLink +ldrb r1, [ r1 ] +mov r2, #0 @same_team +mov r3, #3 @range +.short 0xf800 +cmp r0, #0 +beq no_bond +add r4, #10 @heal 10% hp + +no_bond: + +@Now check for forager +ldr r0, =SkillTester +mov lr,r0 +mov r0,r5 +ldr r1, =RenewalForagerIDLink +ldrb r1,[r1] +.short 0xf800 +cmp r0,#0x0 +beq no_forager + +@check the terrain the unit is on, compare it against the list +ldrb r0,[r5,#0x10] @x coord of unit +ldrb r1,[r5,#0x11] @y coord of unit +lsl r1,#2 @y times 4 since it's pointer +ldr r2,=0x202E4DC @tile id map pointer +ldr r2,[r2] @tile id map offset +ldr r2,[r2,r1] @load pointer to y row +ldrb r0,[r2,r0] @load x byte of the row, which gets us tile id +ldr r1, =ForagerList +ForagerLoop: +ldrb r2,[r1] +cmp r2,#0 +beq no_forager +cmp r2,r0 +beq yes_forager +add r1,#1 +b ForagerLoop + +@if on correct terrain, heal 20% +yes_forager: +add r4,#20 + +no_forager: + +@check for Imbue +ldr r0, =SkillTester +mov lr,r0 +mov r0,r5 +ldr r1, =RenewalImbueIDLink +ldrb r1,[r1] +.short 0xf800 +cmp r0,#0x0 +beq NoImbue + +@unit is in r5 +@get mag stat +mov r0,r5 +add r0,#0x3A +ldrb r0,[r0] @r0 = mag + +@multiply it by 100 +mov r1,#100 +mul r0,r1 + + +@divide it by MHP +mov r1,r5 +ldrb r1,[r1,#0x12] @r1 = mhp + +@add MHP to dividend to make it round up +add r0,r1 + +swi 0x6 @div [r0/r1] + +@r0 = div result +@add it to r4 +add r4,r0 + + +NoImbue: + +@ Check for healing tiles +ldr r0, =#0x0202BCF0 +ldrb r0, [ r0, #0x0E ] +@blh GetChapterEvents, r1 +ldr r1, =#0x080346B0 +mov lr, r1 +.short 0xF800 +ldr r3, [ r0, #0x20 ] @ Pointer to trap data in r3. +sub r3, #6 +ldrb r0, [ r5, #0x10 ] @ X coordinate of current unit in r0 +ldrb r1, [ r5, #0x11 ] @ Y coordinate of current unit in r1 +ldr r6, =RenewalHealTrapID +ldrb r6, [ r6 ] + +BeginHealingTileLoop: +add r3, #6 +ldrh r2, [ r3 ] +cmp r2, #0x00 +beq NoHealingTiles @ If this is an ENDTRAP, end. +ldrb r2, [ r3 ] +cmp r2, r6 +bne BeginHealingTileLoop @ If this isn't an 0x23, loop back and try again. +ldrb r2, [ r3, #1 ] +cmp r0, r2 +bne BeginHealingTileLoop @ If the X coordinates don't match up, loop back. +ldrb r2, [ r3, #2 ] +cmp r1, r2 +bne BeginHealingTileLoop @ If the Y coordinates don't match up, loop back. +push { r0, r1, r3 } +ldrb r0, [ r3, #5 ] @ Event ID of this one in r0. +ldr r1, =#0x08083DA8 +mov lr, r1 +.short 0xF800 +cmp r0, #0x01 +pop { r0, r1, r3 } +beq BeginHealingTileLoop @ If the event ID is set, loop back. + +@ If I'm here, this unit is on a good healing tile. Spooky. + +ldrb r2, [ r3, #4 ] @ Percent healed in r2 +add r4, r2, r4 @ Add to the main healing percentage. + +@346B0: (Get_Chapter_Events) (FE8J: 345B8) (FE7: 315BC) +@Params: r0=chapter number +@Returns: Pointer to that chapter's events + +@83DA8: (Check_Event_ID) (FE7: 798F8) (FE8J: 860D0) (FE6: 6BA5C) +@Params: r0=event id to check +@Returns: True if event id is set + +NoHealingTiles: + + +@check for status +mov r0,r5 +add r0,#0x30 +ldrb r0,[r0] +mov r1,#0x1F +and r0,r1 +ldr r1,=RegenStatusIDLink +ldrb r1,[r1] +cmp r0,r1 +bne NoRegenStatus + +@add 10% regen +add r4,#25 + + +NoRegenStatus: + +mov r0, r4 @return the amount healed. +pop {r4 - r6} +pop {r1} +bx r1 +.align +Some_Offset: +.long 0x880C744 +@SkillTester: +@POIN SkillTester +@WORD RenewalID +@POIN AuraSkillCheck +@WORD AmaterasuID +@WORD CamaraderieID +@WORD ReliefID +@WORD BondID +@WORD ChapterDataStruct +@POIN GetChapterEvents +@WORD HealTileTrapID diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Slow/AssembleLynEvent.bat b/EngineHacks/ExternalHacks/StatusExpansion/Slow/AssembleLynEvent.bat new file mode 100644 index 00000000..b78658fe --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Slow/AssembleLynEvent.bat @@ -0,0 +1,26 @@ +@echo off + +SET startDir="C:\devkitPro\devkitARM\bin\" +SET as="%startDir%arm-none-eabi-as" +SET LYN="C:\devkitPro\lyn.exe" + +@rem Assemble into an elf +%as% -g -mcpu=arm7tdmi -mthumb-interwork %1 -o "%~n1.elf" + +if exist "Definitions.s" ( + + @rem Assemble definitions into a .elf if exists + %as% -g -mcpu=arm7tdmi -mthumb-interwork "Definitions.s" -o "Definitions.elf" + + @rem Assebmle into a .lyn.event with definitions + %LYN% "%~n1.elf" "Definitions.elf" > "%~n1.lyn.event" + + echo y | del "%~dp0Definitions.elf" +) else ( + @rem Assemble into a .lyn.event + %LYN% "%~n1.elf" > "%~n1.lyn.event" +) + +echo y | del "%~n1.elf" + +pause \ No newline at end of file diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.event b/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.event new file mode 100644 index 00000000..760d3f9f --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.event @@ -0,0 +1,14 @@ + +#include "Slow.lyn.event" + +#define SlowStatusID 0x0C + +// SetStatusName(SlowStatusID,SlowStatusName) +// SetStatusDesc(SlowStatusID,SlowStatusDesc) +SetStatusBlinkyIconFunc(SlowStatusID,BlinkyIconFuncNoIcon) + +SlowStatusIDLink: +BYTE SlowStatusID + +//define text IDs, and add SlowStatusEffect to (near the end of) pre-battle calc loop + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.lyn.event new file mode 100644 index 00000000..35b810c9 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.lyn.event @@ -0,0 +1,6 @@ +ALIGN 4 +PUSH +ORG CURRENTOFFSET+$1;SlowStatusEffect: +POP +SHORT $B530 $1C04 $1C0D $1C28 $3030 $7800 $211F $4008 $4906 $7809 $4288 $D106 $1C28 $305E $8800 $3004 $1C21 $315E $8008 $BC30 $BC01 $4700 +POIN SlowStatusIDLink diff --git a/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.s b/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.s new file mode 100644 index 00000000..9f1b4f59 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/Slow/Slow.s @@ -0,0 +1,41 @@ +.thumb +.align + +.global SlowStatusEffect +.type SlowStatusEffect, %function + + +SlowStatusEffect: +push {r4-r5,r14} +mov r4,r0 @attacker +mov r5,r1 @defender + +@does defender have slow status? + +mov r0,r5 +add r0,#0x30 +ldrb r0,[r0] +mov r1,#0x1F +and r0,r1 +ldr r1,=SlowStatusIDLink +ldrb r1,[r1] +cmp r0,r1 +bne GoBack + +@attacker AS = defender AS +4 +mov r0,r5 +add r0,#0x5E +ldrh r0,[r0] +add r0,#4 +mov r1,r4 +add r1,#0x5E +strh r0,[r1] + + +GoBack: +pop {r4-r5} +pop {r0} +bx r0 + +.ltorg +.align diff --git a/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.event b/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.event new file mode 100644 index 00000000..2a837559 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.event @@ -0,0 +1,274 @@ + +#ifndef STATUS_EXPANSION_INSTALLED +#define STATUS_EXPANSION_INSTALLED + +PUSH + +//ORG $16604 //CanUnitWieldWeapon +//SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $178EA //SetUnitNewStatus +SHORT 0x21A0 //change 0x50 duration to 0xA0 duration + +ORG $178F6 //SetUnitStatus +SHORT 0x231F //change 0xF bitmask to 0x1F bitmask +SHORT 0x0152 //change left shift amount to 1 more bit + +ORG $1941C //draw status ID +SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0E40 //change right shift amount to 1 less bit (0x19 from 0x1A) + +ORG $1D58E +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $24D18 +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $25AA6 +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $27200 +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $27A8C +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $27B42 +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $88A38 //cond desc getter +SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC0 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $8C470 +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + + +ORG $A5F34 +SHORT 0x06D1 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC9 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $A60A2 +SHORT 0x06C9 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC9 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $8C536 +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $8C440 //minimug box status duration +SHORT 0x0940 //change right shift amount to 1 more bit (5 from 4) + +ORG $8C396 //minimug box status ID +SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC0 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $1D732 +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $178E6 +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $25FC4 //restore staff targeting +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $2A8E4 //stone-related thing +SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC0 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $2C88C +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $25A22 +SHORT 0x201F //change 0xF bitmask to 0x1F bitmask + +ORG $2AD98 +SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC0 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $2AE62 +SHORT 0x221F //change 0xF bitmask to 0x1F bitmask + +ORG $59A8C //something stone-related +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $569BA //stone-related thing +SHORT 0x211F //change 0xF bitmask to 0x1F bitmask + +ORG $54A58 //probably the glow +SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +SHORT 0x0EC0 //change right shift amount to 1 less bit (0x1B from 0x1C) + +//conflicts w/ HP bars +//ORG $276BA +//SHORT 0x06C0 //change left shift amount to 1 less bit (0x1B from 0x1C) +//SHORT 0x0EC0 //change right shift amount to 1 less bit (0x1B from 0x1C) + +ORG $178EA +SHORT 0x21A0 //updated 5-turn duration on applied statuses + +//things to let you actually apply statuses with the highest bit set via staves +//should be made irrelevant by IER +//ORG $2FF94 +//SHORT 0x0E00 //asr -> lsr (this is really dumb) +//ORG $30026 +//SHORT 0x7820 0x2800 0xD009 //ldsb -> ldrb, unchanged cmp, blt -> beq +//ORG $30036 +//SHORT 0x7821 //ldsb -> ldrb + +//change staff battle init to not give 0xFF status on miss +ORG $2CBAC +SHORT 0x2100 //mov r1,#1 -> mov r1,#0 +SHORT 0x46C0 //neg r1,r1 -> nop +ORG $2A5FE +SHORT 0x2000 //mov r0,#0xFF -> mov r0,#0 + +ORG $88A3C +jumpToHack(NewStatusDescIndexer) + +ORG $8C39C +jumpToHack(NewMinimugBoxGraphicIndexer) + +ORG $19410 +POIN StatusNameTextIDTable +ORG $1942C +POIN StatusNameTextIDTable + +// ORG $276C0 +// jumpToHack(NewBlinkyStatusIcons) + +POP + + +#include "StatusExpansion.lyn.event" + + +ALIGN 4 +NewMinimugBoxLabelNames: +#incext Png2Dmp "MinimugBoxNames.png" + +ALIGN 4 +StatusNameTextIDTable: +FILL 256 + +ALIGN 4 +StatusDescTextIDTable: +FILL 128 + +ALIGN 4 +BlinkyStatusIconJumpTable: +FILL 256 + + +#define SetStatusName(statusID,textID) "PUSH; ORG (StatusNameTextIDTable+(statusID*4)); WORD textID; POP" + +#define SetStatusDesc(statusID,textID) "PUSH; ORG (StatusDescTextIDTable+(2*statusID)); SHORT textID; POP" + +#define SetStatusBlinkyIconFunc(statusID,funcPtr) "PUSH; ORG (BlinkyStatusIconJumpTable+(statusID*4)); POIN funcPtr; POP" + +/* +#define NoStatusID 0 +#define PoisonStatusID 1 +#define SleepStatusID 2 +#define SilenceStatusID 3 +#define BerserkStatusID 4 +#define AtkRingStatusID 5 +#define DefRingStatusID 6 +#define CritRingStatusID 7 +#define AvoRingStatusID 8 +#define SickStatusID 9 +#define PetrifyStatusID 13 +*/ +SetStatusName(NoStatusID,0x536) +SetStatusName(PoisonStatusID,0x514) +SetStatusName(SleepStatusID,0x515) +SetStatusName(SilenceStatusID,0x516) +SetStatusName(BerserkStatusID,0x517) +SetStatusName(AtkRingStatusID,0x51B) +SetStatusName(DefRingStatusID,0x51C) +SetStatusName(CritRingStatusID,0x51D) +SetStatusName(AvoRingStatusID,0x51E) +SetStatusName(SickStatusID,0x518) +SetStatusName(PetrifyStatusID,0x51A) + +SetStatusDesc(NoStatusID,0x552) +SetStatusDesc(PoisonStatusID,0x553) +SetStatusDesc(SleepStatusID,0x554) +SetStatusDesc(SilenceStatusID,0x556) +SetStatusDesc(BerserkStatusID,0x555) +SetStatusDesc(AtkRingStatusID,0x558) +SetStatusDesc(DefRingStatusID,0x559) +SetStatusDesc(CritRingStatusID,0x55A) +SetStatusDesc(AvoRingStatusID,0x55B) +SetStatusDesc(SickStatusID,0x553) +SetStatusDesc(PetrifyStatusID,0x557) + +#define BlinkyIconFuncNoIcon $278A6 +#define BlinkyIconFuncPoisonIcon $27700 +#define BlinkyIconFuncSleepIcon $277A8 +#define BlinkyIconFuncSilenceIcon $27754 +#define BlinkyIconFuncBerserkIcon $277F8 +#define BlinkyIconFuncDancerRingIcon $27858 + +SetStatusBlinkyIconFunc(NoStatusID,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(PoisonStatusID,BlinkyIconFuncPoisonIcon) +SetStatusBlinkyIconFunc(SleepStatusID,BlinkyIconFuncSleepIcon) +SetStatusBlinkyIconFunc(SilenceStatusID,BlinkyIconFuncSilenceIcon) +SetStatusBlinkyIconFunc(BerserkStatusID,BlinkyIconFuncBerserkIcon) +SetStatusBlinkyIconFunc(AtkRingStatusID,BlinkyIconFuncDancerRingIcon) +SetStatusBlinkyIconFunc(DefRingStatusID,BlinkyIconFuncDancerRingIcon) +SetStatusBlinkyIconFunc(CritRingStatusID,BlinkyIconFuncDancerRingIcon) +SetStatusBlinkyIconFunc(AvoRingStatusID,BlinkyIconFuncDancerRingIcon) +SetStatusBlinkyIconFunc(SickStatusID,BlinkyIconFuncNoIcon) +//fill the rest with no icon by default to avoid issues +SetStatusBlinkyIconFunc(10,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(11,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(12,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(13,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(14,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(15,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(16,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(17,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(18,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(19,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(20,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(21,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(22,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(23,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(24,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(25,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(26,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(27,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(28,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(29,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(30,BlinkyIconFuncNoIcon) +SetStatusBlinkyIconFunc(31,BlinkyIconFuncNoIcon) + + +/* +fix all proc skills that apply statuses + +things changed: +- HP Bars +- MSG InstallHelpers +- Freeze decrease funcs +- MSS defs + +Compatibility folder contains updated funcs for various things listed above, +This is the updated MSG InstallHelpers bit +a +prCheckUnitStatus: + SHORT 0x6B08 0x231F 0x4018 0x4290 0xD101 0x202A 0xE000 0x2000 0x4770 0x46C0 + +*/ + +#include "Enfeeble/Enfeeble.event" +#include "Freeze/Freeze.event" +#include "Freeze/EventFreeze.event" +#include "Slow/Slow.event" +#include "Numb/Numb.event" +#include "HexingRod/HexingRod.event" +#include "Regen/Regen.event" +#include "Haste/Haste.event" + +#endif // STATUS_EXPANSION_INSTALLED + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.lyn.event new file mode 100644 index 00000000..19ac341a --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.lyn.event @@ -0,0 +1,11 @@ +ALIGN 4 +PUSH +ORG CURRENTOFFSET+$1;NewMinimugBoxGraphicIndexer: +ORG CURRENTOFFSET+$20;NewStatusDescIndexer: +POP +SHORT $2800 $D006 $3801 $21A0 $4348 $4903 $1840 $4B03 $4718 $BC70 $BC01 $4700 +POIN NewMinimugBoxLabelNames +BYTE $21 $C4 $8 $8 +SHORT $40 $4904 $1840 $8800 $1C11 $314C $8008 $BC01 $4700 +BYTE $0 $0 +POIN StatusDescTextIDTable diff --git a/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.s b/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.s new file mode 100644 index 00000000..c0a1b702 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/StatusExpansion.s @@ -0,0 +1,59 @@ +.thumb +.align + +.global NewMinimugBoxGraphicIndexer +.type NewMinimugBoxGraphicIndexer, %function + + +NewMinimugBoxGraphicIndexer: @r3 hook at 8C39C +cmp r0,#0 +beq MinimugBoxGfx_NoStatus + +sub r0,#1 +mov r1,#0xA0 +mul r0,r1 +ldr r1,=NewMinimugBoxLabelNames +add r0,r1 +ldr r3,=#0x808C421 @return point +bx r3 + + +MinimugBoxGfx_NoStatus: +pop {r4-r6} +pop {r0} +bx r0 + + +.ltorg +.align + + + + + +.global NewStatusDescIndexer +.type NewStatusDescIndexer, %function + + +NewStatusDescIndexer: @r3 hook at 88A3C +lsl r0,r0,#1 +ldr r1,=StatusDescTextIDTable +add r0,r1 +ldrh r0,[r0] +mov r1,r2 +add r1,#0x4C +strh r0,[r1] + +pop {r0} +bx r0 + +.ltorg +.align + + + + + + + + diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.dmp b/EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.dmp new file mode 100644 index 0000000000000000000000000000000000000000..92cdb8f47a11a16482705da974683818d6e61257 GIT binary patch literal 100 zcmdJ$zf_6(k(EH5f1OYOq{nQo7{)AVa|6K?2_%1_h1+ xo(Ft;7&I6!auhH>a9|X0<|z38oU`JC0<)KZ`vEruWbI_+007d`A7ual literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.s new file mode 100644 index 00000000..983ab40e --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/Boon.s @@ -0,0 +1,86 @@ +.thumb +.align 4 + +.equ BoonID,SkillTester+4 + +@check if you have boon +push {r1-r3} @don't crucify me this is the easiest way to do this since every single register is in use here +mov r0,r4 +ldr r1,BoonID +ldr r2,SkillTester +mov r14,r2 +.short 0xF800 +cmp r0,#1 +bne DecrementStatusTimer @if you don't have Boon, do vanilla + +BoonEffect: +pop {r1-r3} + +@ Issue #374 +@ Boon needs to unset petrify state bits + +@ r1 - Address unit.status +@ r3 - Value unit.status +@ r4 - unit* + +push {r1-r3} + +# Are we petrified? +mov r0, #0x1F +and r0, r3 @ status index low 5 bits +cmp r0, #0xB @ petrify index +beq YesPetrify +cmp r0, #0xD @ also petrify index +bne NoPetrify + +YesPetrify: +# We are petrified so unset state bits +mov r2, #2 +mvn r2, r2 + +ldr r0, [r4, #0xC] @ unit state + +and r0, r2 +str r0, [r4, #0xC] + +NoPetrify: +pop {r1-r3} +mov r0,#0 @otherwise, status is over +strb r0,[r1] +b GoBack + +DecrementStatusTimer: @the part of the vanilla function that the hook overwrites and we return to after +pop {r1-r3} +mov r2,#0x1F +and r2,r3 +lsr r0,r3,#5 +sub r0,#1 +cmp r0,#0 +bne KeepStatus +strb r0,[r1] +b GoBack +KeepStatus: +lsl r0,r0,#5 +orr r0,r2 +strb r0,[r1] +b GoBack + + + + + +GoBack: +ldrb r1,[r1] +mov r0,#0xF0 + +ldr r2,ReturnPoint +bx r2 + +.ltorg +.align 4 + +ReturnPoint: +.word 0x8018905 +SkillTester: +@POIN SkillTester +@WORD BoonID diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.dmp b/EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.dmp new file mode 100644 index 0000000000000000000000000000000000000000..c959a480bbfc3ac6ca5108d1fadc984daa1e454a GIT binary patch literal 244 zcmeycl|_bEhCw&z!hc0g2NeYmXA4gUiKYxj1pxnK+vGzz{KdlpvitgK}J)C*R#)!;Rgd7gN6{0Z(zV!A+NyUAnwhq!FLhlo)ZiX z5)BLoBpNc96ghydV7|bhDD^-rosk3LT1RId4+n{Zl?pN%1`ZNz72N*T84TJSV6%;6 c=7G%CczS`w{PS~0MGlz{dzkicxF2u>0M$oDg8%>k literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.s new file mode 100644 index 00000000..64c28fc5 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/CanUnitWieldWeapon.s @@ -0,0 +1,183 @@ +.thumb +.align +.equ LookupList,ItemTable+4 +.equ ExternalLoop,LookupList+4 + +.macro blh to, reg + ldr \reg, =\to + mov lr, \reg + .short 0xF800 +.endm + +CanUnitWieldWeapon: +push {r4-r7,r14} + +mov r4,r0 @r4= char struct pointer +mov r5,r1 @r5= item halfword +cmp r5,#0 +beq CannotWield + +HasAWeapon: +mov r1,#0xFF +and r1,r5 @get just item ID in r1 +mov r0,#0x24 +mul r0,r1 +ldr r1,ItemTable +add r0,r1 @r0= item table data offset +ldr r2,[r0,#8] @r2 = weapon ability word +mov r0,#1 +and r0,r2 +mov r3,r1 @r3 = item table offset +cmp r0,#0 @check if the "is a weapon" bit is set +beq CannotWield @if so, continue + +IsAWeapon: +ldr r0,=#0x003D3C00 @word to be &ed to the item ability word +and r0,r2 +cmp r0,#0 +beq IsUnitStatused + +HasWeaponLocks: + +@this is terrible so let's redo it entirely +@1. lookup list; each entry is 8 bytes, ties item ability bit to character/class ability bit in a word for each (this alone is 1/4 the size of the current function and is data that will likely be larger than the replacement for the current function!!) +@2. BEGIN with the check for no ability bits to be set on character/class, then skip the whole loop if there are none (This will free up cycles so it doesn't have to run all of this every time even if it's unnecessary!!) +@3. loop that goes through the list, testing for each bit set in both +@4. list is terminated by 0xFFFFFFFF word, at which point it continues (since it will have exited from the loop with a return false if it's found a combination that doesn't work) +@this should get rid of a ton of the bloat in this function which lets us put more things inline along with this!!! + + +ldr r0,[r4] +ldr r0,[r0,#0x28] +ldr r1,[r4,#4] +ldr r1,[r1,#0x28] +orr r0,r1 +mov r6,r0 @r6= char/class ability word + +ldr r0,=#0xF0070000 +tst r0,r6 +beq CannotWield @don't run the loop if we don't have any weapon locks set, we know we can't use it since to reach this point it needs to have a lock + +mov r1,#0xFF +and r1,r5 +mov r0,#0x24 +mul r1,r0 +ldr r0,ItemTable +add r1,r0 +ldr r0,[r1,#8] +mov r3,r0 @r3= item ability word + +ldr r7,LookupList @r7= current lookup list position + +LoopStart: +ldr r0,[r7] +ldr r1,=#0xFFFFFFFF +cmp r0,r1 +beq IsUnitStatused @if we've reached the end, leave + +@otherwise, check for our current lock on our current item + +TestItemAbilityByte: +tst r0,r3 @if this returns true, then the current lock is not set on the weapon +beq RestartLoop + +@otherwise, check if the equivalent char/class ability bit is set +ldr r0,[r7,#4] + +TestCharClassAbilityByte: +tst r0,r6 +beq CannotWield + +RestartLoop: +add r7,#8 +b LoopStart + +.ltorg +.align + +LockCheck7: +mov r0,#0x80 +lsl r0,r0,#9 +and r1,r0 +cmp r1,#0 +beq IsUnitStatused +mov r0,r4 +mov r1,r5 +blh 0x8016716,r1 +lsl r0,r0,#0x18 +cmp r0,#0 +beq CannotWield + +IsUnitStatused: +mov r0,r4 +add r0,#0x30 +ldrb r1,[r0] @This is the status byte? +mov r0,#0x1F @status bitmask +and r0,r1 +ldr r3,ItemTable +cmp r0,#3 @checking for Sleep status, can't attack if sleeped +bne PrepareExternalLoop +mov r1,#0xFF +and r1,r5 +lsl r0,r1,#3 +add r0,r1 +lsl r0,r0,#2 +add r0,r3 +ldr r0,[r0,#8] +mov r1,#2 +and r0,r1 +cmp r0,#0 +beq PrepareExternalLoop + +CannotWield: +mov r1,#0 +b GoBack + +.ltorg +.align + +PrepareExternalLoop: +@get weapon rank for item type and put it in r6, but don't do the "is your wrank high enough for this weapon" part +mov r1,#0xFF +and r1,r5 +mov r0,#0x24 +mul r1,r0 +ldr r0,ItemTable +add r0,r1 +ldrb r1,[r0,#7] @weapon type +mov r0,r4 +add r0,#0x28 @start of wranks +add r0,r1 @proper wrank +ldrb r6,[r0] @r6 = rank + +@here we gonna put our external function loop +ldr r7,ExternalLoop +ExternalLoopStart: +ldr r3,[r7] +cmp r3,#0 +beq ExitLoop +mov r0,r4 +mov r1,r5 +mov r2,r6 +mov lr,r3 +.short 0xF800 +cmp r0,#0 +beq CannotWield +add r7,#4 +b ExternalLoopStart + +ExitLoop: +mov r1,#1 + +GoBack: +mov r0,r1 +Reeg: +pop {r4-r7} +pop {r1} +bx r1 + +.ltorg +.align + +ItemTable: +@POIN ItemTable diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.dmp b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.dmp new file mode 100644 index 0000000000000000000000000000000000000000..4b4c685f3305365b8b424daf20782d63026e2bd7 GIT binary patch literal 108 zcmeycl|_bEModOtMj*q1*@63jA}14*A%~OV#e4;gFa{0TTM9Blo`T-<+!%f^Xoy`% zs8y8V2J;v-_%9k|1TuSaJ18(PIT$cHvv~+Oa5x(zuz461GAZOMW`um$!?=gRU1up1 J2Lr>8{{WUH8_NIy literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.s new file mode 100644 index 00000000..4f36161f --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_deadeye.s @@ -0,0 +1,76 @@ +.thumb + +.macro blh to, reg=r3 + ldr \reg, =\to + mov lr, \reg + .short 0xf800 +.endm + +.equ PetrifyID, SkillTester+4 +.equ d100Result, 0x802a52c +.equ NextRN_100, 0x8000C64 + +@ 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 +mov r0,#0x6F +ldsb r0,[r5,r0] +cmp r0,#0 +bge End @if already inflicting a status, don't check for ours + +mov r0,r4 +ldr r1,PetrifyID +ldr r3,SkillTester +mov r14,r3 +.short 0xF800 +cmp r0,#0 +beq End +ldrb r0,[r4,#0x15] @skill% proc rate +@mov r0,#100 @for testing +mov r1,r4 +blh d100Result +cmp r0,#1 +bne End @didn't proc + +@if we proc, set the offensive skill and poison 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 +add r0,#0x40 @poison +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, PetrifyID +strb r0, [r6,#4] + + +WriteStatus: +mov r0,#0x2 @sleep ID +mov r1,#0x6F +strb r0,[r5,r1] + +End: +pop {r4-r7} +pop {r0} +bx r0 + +.ltorg +SkillTester: +@ diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.dmp b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.dmp new file mode 100644 index 0000000000000000000000000000000000000000..7ae33ac838abf535c7c6b184ad7baf7e33a555c3 GIT binary patch literal 108 zcmeycl|_bEModOtMj*q1*@63jA}14*A%~OV#e4;gFa{0TTM9Blo`T-<+!%f^Xoy`% zs8y8V2J;v-_%9k|1TuSaJ18(PIT$cHvv~+Oa5x(zuz461vMA&$W`um$!?=gRU1up1 J2Lr>8{{WUv8_fU! literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.s new file mode 100644 index 00000000..bfca4420 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_enrage.s @@ -0,0 +1,76 @@ +.thumb + +.macro blh to, reg=r3 + ldr \reg, =\to + mov lr, \reg + .short 0xf800 +.endm + +.equ PetrifyID, SkillTester+4 +.equ d100Result, 0x802a52c +.equ NextRN_100, 0x8000C64 + +@ 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 +mov r0,#0x6F +ldsb r0,[r5,r0] +cmp r0,#0 +bge End @if already inflicting a status, don't check for ours + +mov r0,r4 +ldr r1,PetrifyID +ldr r3,SkillTester +mov r14,r3 +.short 0xF800 +cmp r0,#0 +beq End +ldrb r0,[r4,#0x15] @skill% proc rate +@mov r0,#100 @for testing +mov r1,r4 +blh d100Result +cmp r0,#1 +bne End @didn't proc + +@if we proc, set the offensive skill and poison 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 +add r0,#0x40 @poison +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, PetrifyID +strb r0, [r6,#4] + + +WriteStatus: +mov r0,#0x4 @berserk ID +mov r1,#0x6F +strb r0,[r5,r1] + +End: +pop {r4-r7} +pop {r0} +bx r0 + +.ltorg +SkillTester: +@ diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.dmp b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.dmp new file mode 100644 index 0000000000000000000000000000000000000000..4870520133751a0f62354b4e037e5526fef94f59 GIT binary patch literal 108 zcmeycl|_bEModOtMj*q1*@63jA}14*A%~OV#e4;gFa{0TTM9Blo`T-<+!%f^Xoy`% zs8y8V2J;v-_%9k|1TuSaJ18(PIT$cHvv~+Oa5x(zuz461ax3I3W`um$!?=gRU1up1 J2Lr>8{{WWR8`J;* literal 0 HcmV?d00001 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.s new file mode 100644 index 00000000..4d3e7310 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/ProcSkills/proc_petrify.s @@ -0,0 +1,76 @@ +.thumb + +.macro blh to, reg=r3 + ldr \reg, =\to + mov lr, \reg + .short 0xf800 +.endm + +.equ PetrifyID, SkillTester+4 +.equ d100Result, 0x802a52c +.equ NextRN_100, 0x8000C64 + +@ 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 +mov r0,#0x6F +ldsb r0,[r5,r0] +cmp r0,#0 +bge End @if already inflicting a status, don't check for ours + +mov r0,r4 +ldr r1,PetrifyID +ldr r3,SkillTester +mov r14,r3 +.short 0xF800 +cmp r0,#0 +beq End +ldrb r0,[r4,#0x15] @skill% proc rate +@mov r0,#100 @for testing +mov r1,r4 +blh d100Result +cmp r0,#1 +bne End @didn't proc + +@if we proc, set the offensive skill and poison 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 +add r0,#0x40 @poison +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, PetrifyID +strb r0, [r6,#4] + + +WriteStatus: +mov r0,#0xB @petrify ID +mov r1,#0x6F +strb r0,[r5,r1] + +End: +pop {r4-r7} +pop {r0} +bx r0 + +.ltorg +SkillTester: +@ diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.lyn.event b/EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.lyn.event new file mode 100644 index 00000000..26a97b47 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.lyn.event @@ -0,0 +1,29 @@ +ALIGN 4 +SHORT $B4F0 $B084 $4824 $7800 $2180 $4208 $D000 $E0E1 $2000 $9000 $2110 $5661 $109 $4A20 $230C $5ED0 $1A0B $2011 $5620 $100 $210E $5E51 $1A42 $1C19 $3110 $2080 $40 $4281 $D838 $1C10 $3010 $28B0 $D834 $2101 $9100 $9301 $9202 $4915 $9103 $2012 $5620 $B480 $1C07 $2013 $5620 $1C02 $1C38 $BC80 $2A00 $D023 $4282 $DA21 $1C01 $1A80 $220B $4350 $DF06 $490C $468E $82 $4B0B $18D2 $6812 $9903 $9B01 $1858 $3902 $4008 $9902 $31FB $23FF $4019 $2300 +BYTE $0 $F8 +SHORT $E00A $46C0 +BYTE $31 $BD $2 $2 $B0 $BC $2 $2 $1 $2 $0 $0 $B8 $2B $0 $8 +POIN HPFramePointers +SHORT $4E0D $6836 $2E00 $D007 $7AF0 $21C0 $4208 $D103 $7B30 $2101 $4208 $D103 $4808 $2100 $6001 $E083 $4806 $7801 $2902 $D064 $7841 $7AE2 $428A $DC07 $2102 $7001 $E05D $46C0 +BYTE $50 $4E $0 $3 $0 $AE $3 $2 +SHORT $7042 $2101 $7001 $2700 $483B $7800 $2110 $4208 $D12C $7AE0 $2180 $4208 $D028 $1C20 $1C31 $4A37 $4696 +BYTE $0 $F8 +SHORT $2800 $D11C $251E $5B61 $2900 $D01D $1C20 $4A33 $4696 +BYTE $0 $F8 +SHORT $2800 $D00E $5B60 $1C31 $4A30 $4696 +BYTE $0 $F8 +SHORT $2800 $D10B $5B60 $492E $468E +BYTE $0 $F8 +SHORT $28FF $D001 $2818 $DC06 $3502 $2D26 $DDE4 $E004 $2001 $4307 $E001 $2002 $4307 $6830 $7900 $6821 $7909 $4A25 $4696 +BYTE $0 $F8 +SHORT $2800 $D001 $2004 $4307 $4823 $3002 $7AE1 $1840 $7007 $7AE0 $21C0 $4208 $D129 $1C30 $6821 $7909 $F000 $F85B $2800 $D001 $2004 $4307 $481A $3002 $7AE1 $1840 $7007 $E01A $4D17 $3502 $7AE0 $5C2D $2D00 $D014 $2001 $4228 $D003 $2000 $4669 $F000 $F826 $2002 $4228 $D003 $2008 $4669 $F000 $F81F $2004 $4228 $D003 $2010 $4669 $F000 $F818 $B004 $BCF0 $2030 $5C20 $6C0 $EC0 $4907 $4708 +BYTE $31 $BD $2 $2 $88 $6C $1 $8 $74 $65 $1 $8 $EC $6B $1 $8 $24 $76 $1 $8 $68 $3F $8 $8 $0 $AE $3 $2 $BF $76 $2 $8 +SHORT $B530 $680A $2A00 $D011 $1C04 $1C0D $4909 $468E $68E9 $6868 $1840 $300B $3902 $4008 $68A9 $31EE $22FF $4011 $4A04 $1912 $2300 +BYTE $0 $F8 +SHORT $BC30 $BC01 $4700 $46C0 +BYTE $B8 $2B $0 $8 +POIN WS_FrameData +SHORT $B518 $1C03 $6800 $6AC0 $1C02 $2800 $D00F $2400 $3C01 $3401 $2C07 $DA09 $1910 $7800 $4288 $D1F8 $1C18 $1C21 $4A03 $4696 +BYTE $0 $F8 +SHORT $E000 $2000 $BC18 $BC02 $4708 +BYTE $10 $83 $2 $8 diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.s new file mode 100644 index 00000000..b6fb3079 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/WarningAndHpBars.s @@ -0,0 +1,442 @@ +@Don't have more than 1 of these equal to 1 at a time. Issues will arise. +.equ FE6, 0 +.equ FE7, 0 +.equ FE8, 1 @untested + +.thumb +.org 0 + +@jumped to at 22410 (fe6) +@r4 = char data ptr + +.equ crit_warning_cutoff, 24 @anything less than or equal this won't trigger the ! + +.if FE6 == 1 + .equ WarningCache, 0x0203ACC0 @free space in ram. Change this if necessary. + .equ OptionByte2, 0x0202AA66 + .equ CameraStuff, 0x0202AA08 + .equ WRAMDisplay, 0x08003870 + .equ CurrentCharPtr, 0x030044B0 + .equ Can_Equip_Item, 0x08016538 + @ .equ Get_Unit_Max_Hp, TODO + .equ Get_Item_Crit, 0x08017224 + .equ Check_Effectiveness, 0x08016A10 + .equ Talk_Check, 0x0806AF4C + .equ return_addr, 0x0802241A+1 + .equ x_coord, 0x0E + .equ y_coord, 0x0F + .equ maximum_hp, 0x10 + .equ current_hp, 0x11 + .equ inventory_slot1, 0x1C + .equ status_byte, 0x2E +.endif + +.if FE7 == 1 + .equ WarningCache, 0x0203ACC0 @free space in ram. Change this if necessary. + .equ OptionByte2, 0x0202BC39 + .equ CameraStuff, 0x0202BBB8 + .equ WRAMDisplay, 0x08004388 + .equ CurrentCharPtr, 0x03004690 + .equ Can_Equip_Item, 0x080161A4 + @ .equ Get_Unit_Max_Hp, TODO + .equ Get_Item_Crit, 0x08017328 + .equ Check_Effectiveness, 0x08016820 + .equ Talk_Check, 0x080789FC + .equ return_addr, 0x08025C16+1 + .equ x_coord, 0x10 + .equ y_coord, 0x11 + .equ maximum_hp, 0x12 + .equ current_hp, 0x13 + .equ inventory_slot1, 0x1E + .equ status_byte, 0x30 +.endif + +.if FE8 == 1 + .equ WarningCache, 0x0203AE00 @free space in ram. Change this if necessary. + .equ OptionByte2, 0x0202BD31 + .equ CameraStuff, 0x0202BCB0 + .equ WRAMDisplay, 0x08002BB8 + .equ CurrentCharPtr, 0x03004E50 + .equ Can_Equip_Item, 0x08016574 + .equ Get_Unit_Max_Hp, 0x08019190 + .equ Get_Unit_Cur_HP, 0x08019150 + .equ Get_Item_Crit, 0x08017624 + .equ Check_Effectiveness, 0x08016BEC + .equ Slayer_Check, 0x08016C88 + .equ Talk_Check, 0x08083F68 + .equ Support_Check, 0x08028310 + .equ return_addr, 0x080276BE+1 + .equ x_coord, 0x10 + .equ y_coord, 0x11 + .equ maximum_hp, 0x12 + .equ current_hp, 0x13 + .equ inventory_slot1, 0x1E + .equ status_byte, 0x30 +.endif + +push {r4-r7} +add sp,#-0x10 + +@First, check if all this stuff is even enabled +ldr r0,=OptionByte2 +ldrb r0,[r0] +.if FE8 == 1 +mov r1,#0x80 +.else +@ NOTE: this is either the fe6-specific bit, or teq has added an extra setting in the original impl of this +mov r1,#0x20 +.endif +tst r0,r1 +beq HpBars @if bit isn't set, hp bars are on (at the very least) +b GoBack + +HpBars: +mov r0,#0 +str r0,[sp] @bool for whether the unit is on the screen +mov r1,#x_coord +ldsb r1,[r4,r1] +lsl r1,#4 +ldr r2,=CameraStuff +mov r3,#0xC +ldsh r0,[r2,r3] @camera x +sub r3,r1,r0 @r3= x - camera_x +mov r0,#y_coord +ldsb r0,[r4,r0] +lsl r0,#4 +mov r1,#0xE +ldsh r1,[r2,r1] @camera y +sub r2,r0,r1 @r2 = y - camera_y +mov r1,r3 +add r1,#0x10 +mov r0,#0x80 +lsl r0,#1 +cmp r1,r0 +bhi CheckIfSelected @x is either >0x100 or <0, so out of range +mov r0,r2 +add r0,#0x10 +cmp r0,#0xB0 +bhi CheckIfSelected @y is either >0xB0 or <0, so out of range +mov r1,#1 +str r1,[sp] @change bool to true (display whatever) +str r3,[sp,#0x4] @sp+4 = x - x' +str r2,[sp,#0x8] @sp+8 = y - y' +ldr r1,=#0x201 +str r1,[sp,#0xC] @constant to determine where things get drawn +@Find out whether we even need to display an hp bar +@.if FE8 == 1 @ TODO: other games +@ mov r0, r4 @ arg r0 = Unit +@ ldr r1, =Get_Unit_Max_Hp +@ mov r14,r1 +@ .short 0xF800 +@.else + mov r0,#maximum_hp + ldsb r0,[r4,r0] +@.endif +push {r7} +mov r7,r0 +@.if FE8 == 1 +@ mov r0,r4 +@ ldr r1,=Get_Unit_Cur_HP +@ mov r14,r1 +@ .short 0xF800 +@.else +mov r0,#current_hp +ldsb r0,[r4,r0] +@.endif + +mov r2,r0 +mov r0,r7 +pop {r7} + +cmp r2, #0x0 +beq CheckIfSelected @if hp is zero, don't try to show the bar + +cmp r2,r0 +bge CheckIfSelected @if hp is max, don't show the bar +mov r1,r0 @ arg r1 = mhp +sub r0,r2 +mov r2,#11 +mul r0,r2 @ arg r0 = damage*11 +swi #6 @damage*11/maxHP +@Call the drawing routine +ldr r1,=WRAMDisplay +mov r14,r1 +lsl r2,r0,#2 +ldr r3,=HPFramePointers @EA defined +add r2,r3 +ldr r2,[r2] +ldr r1,[sp,#0xC] @0x201 +ldr r3,[sp,#0x4] @x-x' +add r0,r3,r1 +sub r1,#2 @0x1FF +and r0,r1 +ldr r1,[sp,#0x8] @y-y' +add r1,#0xFB +mov r3,#0xFF +and r1,r3 +mov r3,#0 +.short 0xF800 @call routine to display bars +b CheckIfSelected + +.align +.ltorg + +@This section is for effectiveness/talk/wta/whatever, which only display if a unit is selected. Since checking for this every frame makes it super laggy, we create a cache. First byte will be reserved for status of the operation: 0 if unit isn't selected, 1 if filling the cache, 2 if done +CheckIfSelected: +ldr r6,=CurrentCharPtr +ldr r6,[r6] +cmp r6,#0 +beq UnitNotSelected @no current unit +ldrb r0,[r6,#0xB] +mov r1,#0xC0 +tst r0,r1 +bne UnitNotSelected @selecting enemy/ally shouldn't do anything + +ldrb r0,[r6,#0xC] @status byte +mov r1,#1 @do not display standing map sprite +tst r0,r1 +bne CheckIfFirstPass + +UnitNotSelected: +ldr r0,=WarningCache +mov r1,#0 +str r1,[r0] +b GoBack + +CheckIfFirstPass: +ldr r0,=WarningCache +ldrb r1,[r0] +cmp r1,#2 +beq DisplayOtherIcons +@at this point, we must be on the first pass +ldrb r1,[r0,#1] @most recent allegiance byte we looked at +ldrb r2,[r4,#0xB] @current allegiance +cmp r2,r1 +bgt FirstPass @we haven't looped through all the units yet if current>previous +mov r1,#2 +strb r1,[r0] @first pass is complete +b DisplayOtherIcons + +.align +.ltorg + +FirstPass: +strb r2,[r0,#1] @replace previous looked-at unit with current one +mov r1,#1 +strb r1,[r0] @and ensure we're still in first-pass mode +mov r7,#0 @initialize the bitfield we write to the cache + +@Effectiveness/Critical checks (WTA/D would also go here, if applicable) +ldr r0,=OptionByte2 +ldrb r0,[r0] +mov r1,#0x10 +tst r0,r1 +bne TalkEventCheck @if this bit is set, we only want hp bars and talk icons +ldrb r0,[r4,#0xB] +mov r1,#0x80 +tst r0,r1 +beq TalkEventCheck @if not enemy, no need for this check + +@slayer check for fe8 +.if FE8 == 1 + mov r0,r4 + mov r1,r6 + ldr r2,=Slayer_Check + mov r14,r2 + .short 0xF800 + cmp r0,#0 + bne IsEffective +.endif +mov r5,#inventory_slot1 +LoopThroughItems: +ldrh r1,[r4,r5] +cmp r1,#0 +beq TalkEventCheck +mov r0,r4 +ldr r2,=Can_Equip_Item +mov r14,r2 +.short 0xF800 +cmp r0,#0 +beq NextItem +ldrh r0,[r4,r5] +mov r1,r6 +ldr r2,=Check_Effectiveness +mov r14,r2 +.short 0xF800 +cmp r0,#0 +bne IsEffective +ldrh r0,[r4,r5] +ldr r1,=Get_Item_Crit +mov r14,r1 +.short 0xF800 +cmp r0,#0xFF +beq NextItem +cmp r0,#crit_warning_cutoff +bgt IsCritty +NextItem: +add r5,#2 +cmp r5,#inventory_slot1+8 +ble LoopThroughItems +b TalkEventCheck + +IsEffective: +mov r0,#1 +orr r7,r0 +b TalkEventCheck + +IsCritty: +mov r0,#2 +orr r7,r0 + +TalkEventCheck: +ldr r0,[r6] +ldrb r0,[r0,#4] @active unit's char id +ldr r1,[r4] +ldrb r1,[r1,#4] @current unit's char id +ldr r2,=Talk_Check +mov r14,r2 +.short 0xF800 +cmp r0,#0 +beq WriteToCache +mov r0,#4 +orr r7,r0 +WriteToCache: +ldr r0,=WarningCache +add r0,#2 @first 2 bytes are occupied +ldrb r1,[r4,#0xB] +add r0,r1 +strb r7,[r0] + +SupportCheck: +@28310 should work, but it needs to check the SupportDenier code. +ldrb r0,[r4,#0xB] @allegiance +mov r1,#0xC0 +tst r0,r1 +bne GoBack @selecting enemy/ally shouldn't do anything + +mov r0,r6 @current unit's RAM ptr +ldr r1,[r4] +ldrb r1,[r1,#4] @current unit's char id +bl SupportCheckerFunction +cmp r0,#0 +beq WriteToCache2 +mov r0,#4 +orr r7,r0 +WriteToCache2: +ldr r0,=WarningCache +add r0,#2 @first 2 bytes are occupied (we can use same bit as talk) +ldrb r1,[r4,#0xB] +add r0,r1 +strb r7,[r0] +b GoBack @opting to do the displaying on the second pass + +DisplayOtherIcons: +ldr r5,=WarningCache +add r5,#2 +ldrb r0,[r4,#0xB] +ldrb r5,[r5,r0] +cmp r5,#0 +beq GoBack @nothing to display +@DisplayEffective +mov r0,#1 @effective +tst r0,r5 +beq DisplayCrit +mov r0,#0 +mov r1,sp +bl Draw_Warning_Sign +DisplayCrit: +mov r0,#2 +tst r0,r5 +beq DisplayTalk +mov r0,#8 +mov r1,sp +bl Draw_Warning_Sign +DisplayTalk: +mov r0,#4 +tst r0,r5 +beq GoBack +mov r0,#0x10 +mov r1,sp +bl Draw_Warning_Sign + +GoBack: +add sp,#0x10 +pop {r4-r7} +mov r0,#status_byte +ldrb r0,[r4,r0] +lsl r0,#0x1B +lsr r0,#0x1B +ldr r1,=return_addr +bx r1 + +.align +.ltorg + +Draw_Warning_Sign: +@r0=thing to determine what we're drawing, r1=sp (to retrieve x and y stuff) +push {r4,r5,r14} +ldr r2,[r1] @bool to determine whether we're on screen +cmp r2,#0 +beq FinishedDrawing +mov r4,r0 +mov r5,r1 +ldr r1,=WRAMDisplay +mov r14,r1 +ldr r1,[r5,#0xC] @0x201 +ldr r0,[r5,#0x4] @x-x' +add r0,r1 +add r0,#0xB @tweak for x coordinate, whatever that means +sub r1,#2 +and r0,r1 +ldr r1,[r5,#0x8] @y-y' +add r1,#0xEE @y coordinate tweak? +mov r2,#0xFF +and r1,r2 +ldr r2,=WS_FrameData +add r2,r4 +mov r3,#0 +.short 0xF800 @call routine to display bars +FinishedDrawing: +pop {r4-r5} +pop {r0} +bx r0 + +.align +.ltorg + +SupportCheckerFunction: @r0=unit struct, r1=unitID. Check if unitID is in unit's support list +push {r3,r4,lr} +mov r3, r0 @save unit pointer to r3 +ldr r0, [r0] @unit ROM data +ldr r0, [r0, #0x2C] @unit support data +mov r2, r0 @save support data to r2 +cmp r0, #0x0 +beq EndSupportCheckerFunc +mov r4, #0x0 +sub r4, #0x1 + +SupportPartnerLoop: +add r4, #0x1 +cmp r4, #0x7 +bge ReturnNoSupport +add r0, r2, r4 +ldrb r0, [r0] @unit id +cmp r0, r1 +bne SupportPartnerLoop + +mov r0, r3 +mov r1, r4 +ldr r2,=Support_Check +mov r14,r2 +.short 0xF800 +b EndSupportCheckerFunc + +ReturnNoSupport: +mov r0, #0x0 +EndSupportCheckerFunc: +pop {r3,r4} +pop {r1} +bx r1 + +.align +.ltorg diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/mss_defs.s b/EngineHacks/ExternalHacks/StatusExpansion/_compat/mss_defs.s new file mode 100644 index 00000000..bcceb202 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/mss_defs.s @@ -0,0 +1,1397 @@ +@graphics and text +.equ CopyToPaletteBuffer, 0x08000DB8 +.equ _ResetIconGraphics, 0x08003578 +.equ DrawIcon, 0x080036BC +.equ Text_InitFont, 0x08003C94 +.equ Text_GetColorID, 0x08003E64 +.equ Text_Display, 0x08003E70 +.equ Text_GetStringTextWidth, 0x08003EDC +.equ Text_GetStringTextCenteredPos, 0x08003F90 +.equ Text_DrawString, 0x08004004 +.equ DrawTextInline, 0x0800443C +.equ Text_InsertString, 0x08004480 +.equ DrawSpecialUiChar, 0x08004B0C +.equ DrawDecNumber, 0x08004B94 +.equ DrawUiSmallNumber, 0x08004BE4 +.equ DrawStatScreenBonusNumber, 0x08004BF0 +.equ DrawLargeFont, 0x08004D5C +.equ String_GetFromIndex, 0x0800A240 +.equ String_ExpandTactName, 0x0800A3B8 + +@Menus and boxes +.equ FillBgMap, 0x08001220 +.equ Decompress, 0x08012F50 +.equ LoadNewUIPal, 0x0804E0A8 +.equ MakeUIWindowTileMap_BG0BG1, 0x0804E368 +.equ MovingMapSprite_CreateForUI, 0x080784F4 +.equ MovingMapSprite_EndAll, 0x080790A4 +.equ BgMap_ApplyTsa, 0x080D74A0 +.equ BgMapFillRect, 0x080D74B8 + +@getters +.equ UnitHasMagicRank, 0x08018A58 +.equ MountedIconHelper, 0x08018AF0 +.equ MagCheck, 0x8018A58 +.equ AidCheck, 0x080189B8 +.equ CurHPGetter, 0x08019150 +.equ MaxHPGetter, 0x08019190 +.equ StrGetter, 0x080191b0 +.equ MagGetter, 0x080191b8 +.equ SklGetter, 0x080191d0 +.equ SpdGetter, 0x08019210 +.equ LuckGetter, 0x08019298 +.equ DefGetter, 0x08019250 +.equ ResGetter, 0x08019270 +.equ MagConGetter, 0x08019284 @defined in the modularstatgetter +.equ MovGetter, 0x08019224 @defined in the modularstatgetter +.equ AffinityGetter, 0x080286BC +.equ EquippedWeaponGetter, 0x08016B28 +.equ EquippedItemSlotGetter, 0x08016B58 +.equ GetItemRangeString, 0x08016CC0 +.equ IsItemUsable, 0x08016EE4 +.equ ItemWeightGetter, 0x0801760C +.equ GetUnitItemCount, 0x080179D8 +.equ SetupBattleStructFromUnitAndWeapon, 0x0802A400 +.equ GetBallistaItemAt, 0x0803798C +.equ CheckGameLinkArenaBit, 0x08042E98 + +@Statscreen-specific stuff +.equ DrawItemOnStatscreen, 0x08016A2C +.equ WriteTrvText, 0x080193E8 +.equ WriteStatusText, 0x08019414 +.equ Statscreen_ClearBuffer, 0x08086DF0 @clears 2003c00 region +.equ DrawStatscreenTextMap, 0x08086E00 +.equ Statscreen_StartLeftPanel, 0x08086E44 +.equ DrawBWLNumbers, 0x08086FAC +.equ DrawBar, 0x080870BC +.equ DrawSupports, 0x08087698 +.equ DrawWeaponRank, 0x08087788 + +@RAM +.equ DebuffTable, 0x203F100 +.equ gActiveBattleUnit, 0x203A4EC +.equ StatScreenStruct, 0x2003BFC +.equ BgBitfield, 0x300000D +.equ TileBufferBase, 0x2003C2C +.equ tile_origin, 0x2003C94 +.equ gpStatScreenPageBg0Map, 0x2003D2C +.equ gpStatScreenPageBg2Map, 0x200472C +.equ gGenericBuffer, 0x2020188 +.equ gBg0MapBuffer, 0x2022CA8 +.equ gCurrentTextString, 0x202A6AC +.equ Const_2022D40, 0x2022D40 +.equ Const_2023D40, 0x2023D40 +.equ Const_2003D2C, 0x2003D2C +.equ Const_200472C, 0x200472C + +@With this in mind, any unlabeled RAM addresses beginning with 0x200 can reasonably be assumed to be offsets within the tilemap + +@Colours +.equ Green, 4 +.equ Yellow, 3 +.equ Blue, 2 +.equ Grey, 1 +.equ White, 0 + +@Hardcoded classIDs (Gorgon Eggs) +.equ Deny_Statscreen_Class_Lo, 0x34 +.equ Deny_Statscreen_Class_Hi, 0x62 + +.macro blh to, reg=r3 + push {\reg} + ldr \reg, =\to + mov lr, \reg + pop {\reg} + .short 0xf800 +.endm + +.macro blm to, from=origin + .equ func_\to, . + \to - \from + bl func_\to +.endm + +@08087184 +.macro page_start + push {r4-r7, r14} + mov r7, r8 + push {r7} + add sp, #-0x50 + ldr r7, =TileBufferBase @r7 contains the latest buffer. starts at 2003c2c. + ldr r5, =StatScreenStruct + ldr r0, [r5, #0xC] + mov r8, r0 @r8 contains the current unit's data + clear_buffers +.endm + +.macro page_end + add sp, #0x50 + pop {r7} + mov r8, r7 + pop {r4-r7} + pop {r0} + bx r0 +.endm + +.macro draw_textID_at tile_x, tile_y, textID=0, width=3, colour=3, growth_func=-1 @growth func is # of growth getter in growth_getters_table; 0=hp, 1=str, 2=skl, etc + mov r3, r7 + mov r1, #\width + @r3 is current buffer location, r1 is width. + ldrh r2, [r3] @current number + add r2, r1 @for the next one. + strb r1, [r3, #4] @store width + strb r2, [r3, #8] @assign the next one. + .if \textID + ldr r0, =\textID @otherwise assume it's in r0 + .endif + blh String_GetFromIndex + mov r2, #0x0 + str r2, [sp] + str r0, [sp, #4] + mov r2, #\colour @colour + .ifge \growth_func + ldr r1, [sp, #0xC] @growth getters table + mov r0, #\growth_func-1 + lsl r0, #2 + ldr r1, [r1, r0] @relevant growth getter function + mov r0, r8 + mov r14, r1 + .short 0xF800 @returns growth + mov r1, sp + add r1, #0x18 + ldr r2, [sp, #0x14] @growth options word and'd with 0x10, so non-zero if stat name color should reflect growth + ldr r3, =Get_Palette_Index + mov r14, r3 + .short 0xF800 @given growth, returns palette index, and does some shenanigans + mov r2, r0 + .endif + mov r0, r7 + ldr r1, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r3, #0 + blh DrawTextInline, r4 + .ifge \growth_func + ldr r1, [sp, #0x14] + ldr r0, [sp, #0x18] + bl Restore_Palette @see that func for an explanation (mss_page1_skills) + .endif + add r7, #8 +.endm + +.macro draw_buffered_text, tile_x, tile_y, width=10, colour=3 + mov r0, sp + mov r1, #\width + str r1, [r0] + mov r0, #0 + ldr r1, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r2, #\colour + mov r3, #0 + blh DrawTextInline, r4 + bl Restore_Palette +.endm + +.macro draw_skillname_at tile_x, tile_y, textID=0, width=14, colour=3, growth_func=-1 @growth func is # of growth getter in growth_getters_table; 0=hp, 1=str, 2=skl, etc + mov r3, r7 + mov r1, #\width + @r3 is current buffer location, r1 is width. + ldrh r2, [r3] @current number + add r2, r1 @for the next one. + strb r1, [r3, #4] @store width + strb r2, [r3, #8] @assign the next one. + .if \textID + ldr r0, =#\textID @otherwise assume it's in r0 + .endif + blh String_GetFromIndex + bl GetSkillNameFromSkillDesc + mov r2, #0x0 + str r2, [sp] + str r0, [sp, #4] + mov r2, #\colour @colour + .ifge \growth_func + ldr r1, [sp, #0xC] @growth getters table + mov r0, #\growth_func-1 + lsl r0, #2 + ldr r1, [r1, r0] @relevant growth getter function + mov r0, r8 + mov r14, r1 + .short 0xF800 @returns growth + mov r1, sp + add r1, #0x18 + ldr r2, [sp, #0x14] @growth options word and'd with 0x10, so non-zero if stat name color should reflect growth + .set pal_index, (Get_Palette_Index - . - 6) + ldr r3, =pal_index + add r3, pc + ldr r3, [r3] + mov r14, r3 + .short 0xF800 @given growth, returns palette index, and does some shenanigans + mov r2, r0 + .endif + mov r0, r7 + ldr r1, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r3, #0 + blh DrawTextInline, r4 + .ifge \growth_func + ldr r1, [sp, #0x14] + ldr r0, [sp, #0x18] + bl Restore_Palette @see that func for an explanation (mss_page1_skills) + .endif + add r7, #8 +.endm + +.macro draw_bar_at bar_x, bar_y, getter, offset, bar_id + mov r0, r8 + blh \getter + mov r1, r8 + mov r3, #\offset + ldsb r3, [r1, r3] + str r0, [sp] + ldr r0, [r1, #0x4] @class + ldrb r0, [r0, #\offset] @stat cap + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + str r0, [sp, #0x4] + mov r0, #(\bar_id) + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_bar_at_with_cap_getter bar_x, bar_y, statgetter, capgetter, offset, bar_id + mov r0, r8 + blh \statgetter + mov r1, r8 + mov r3, #\offset + ldsb r3, [r1, r3] + str r0, [sp] + ldr r0, [r1, #0x4] @class + ldrb r0, [r0, #0x4] @class id + blh \capgetter + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + str r0, [sp, #0x4] + mov r0, #(\bar_id) + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_halved_bar_at bar_x, bar_y, getter, offset, bar_id + mov r0, r8 + blh \getter + mov r1, r8 + mov r3, #\offset + ldsb r3, [r1, r3] @base stat + asr r3, #1 + str r0, [sp] + ldr r0, [r1, #0x4] @class + ldrb r0, [r0, #\offset] @stat cap + lsl r0, r0, #0x18 + asr r0, r0, #0x19 @divided by 2 + str r0, [sp, #0x4] + mov r0, #(\bar_id) + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_str_bar_at, bar_x, bar_y + draw_bar_at \bar_x, \bar_y, StrGetter, 0x14, 0 +.endm + +.macro draw_mag_bar_at, bar_x, bar_y + mov r0, r8 + blh MagGetter + mov r1, r8 + mov r3, #0x3A + ldsb r3, [r1, r3] + str r0, [sp] + ldr r0, [r1, #0x4] @class + ldrb r0, [r0, #0x4] @class id + lsl r0, #0x2 + ldr r1, =MagClassTable + add r0, r1 + ldrb r0, [r0, #0x2] + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + str r0, [sp, #0x4] + mov r0, #0x1 + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_skl_bar_at, bar_x, bar_y + draw_bar_at \bar_x, \bar_y, SklGetter, 0x15, 2 +.endm + +.macro draw_skl_reduced_bar_at, bar_x, bar_y @for rescuing + draw_halved_bar_at \bar_x, \bar_y, SklGetter, 0x15, 2 +.endm + +.macro draw_spd_bar_at, bar_x, bar_y + draw_bar_at \bar_x, \bar_y, SpdGetter, 0x16, 3 +.endm + +.macro draw_spd_reduced_bar_at, bar_x, bar_y @for rescuing + draw_halved_bar_at \bar_x, \bar_y, SpdGetter, 0x16, 3 +.endm + +.macro draw_luck_bar_at, bar_x, bar_y + mov r0, r8 + blh LuckGetter + mov r1, r8 + mov r3, #0x19 + ldsb r3, [r1, r3] + str r0, [sp] + mov r0, #0x1e @cap is always 30 + str r0, [sp, #0x4] + mov r0, #0x6 + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_def_bar_at, bar_x, bar_y + draw_bar_at \bar_x, \bar_y, DefGetter, 0x17, 4 +.endm + +.macro draw_res_bar_at, bar_x, bar_y + draw_bar_at \bar_x, \bar_y, ResGetter, 0x18, 5 +.endm + +.macro draw_growth_at, bar_x, bar_y + mov r14, r0 @r0 = growth getter to bl to + mov r0, r8 + .short 0xF800 @returns total growth in r0, base growth in r1 + sub r0, r0, r1 @difference between total and base + str r0, [sp, #0x10] + mov r2, r1 @base in r2 + mov r1, #0x2 @palette index + ldr r0, =(tile_origin+(0x20*2*\bar_y)+(2*\bar_x)) + blh DrawDecNumber + ldr r0, [sp, #0x10] @difference from earlier + ldr r1, =(tile_origin+(0x20*2*\bar_y)+(2*(\bar_x+1))) + blh DrawStatScreenBonusNumber +.endm + +.macro draw_move_bar_at, bar_x, bar_y + mov r1, r8 + @check AI + mov r3, #0x41 + ldrb r3, [r1, r3] @AI byte 4 + cmp r3, #0x20 + beq NoMove + mov r3, #0x30 + ldrb r3, [r1, r3] @status + mov r0, #0xF + and r3, r0 + cmp r3, #0x9 @freeze status + beq NoMove + ldr r0, [r1, #0x4] @class + mov r3, #0x12 @move + ldsb r3, [r0, r3] + mov r0, #0x1D @bonus + ldsb r0, [r1, r0] + b NormalMove + + NoMove: + mov r0, #0 + mov r3, #1 + neg r3, r3 + b DrawMove + + NormalMove: + DrawMove: + add r0, r0, r3 + str r0, [sp] @r0 is total, r3 is base + mov r6, #0xF + str r6, [sp, #0x4] + mov r0, #0x6 @why 6? + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_move_bar_with_getter_at, bar_x, bar_y +@base in r3, final in sp, cap in sp+4, call getter + mov r1, r8 + ldr r0, [r1, #0x4] @class + mov r3, #0x12 @move + ldsb r3, [r0, r3] + @ mov r0, #0x1D @bonus + @ ldsb r0, [r1, r0] + @ add r0, r0, r3 + + push {r1-r3} + mov r0, r8 + blh MovGetter + pop {r1-r3} + cmp r0, #0 + bne MoveNotNegated + mvn r0, r0 + mov r3, r0 + MoveNotNegated: + str r0, [sp] @final + mov r6, #0xF + str r6, [sp, #4] + mov r0, #0x8 + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_move_number_at, tile_x, tile_y + mov r1, r8 + ldr r0, [r1, #0x4] @class + mov r3, #0x12 @move + ldsb r3, [r0, r3] + mov r0, #0x1D @bonus + ldsb r0, [r1, r0] + cmp r0, #0 + beq MoveNotBoosted + mov r1, #Green + b FromMoveBoosted + MoveNotBoosted: + mov r1, #Blue + FromMoveBoosted: + add r0, r0, r3 + draw_number_at \tile_x, \tile_y +.endm + +.macro draw_con_bar_at, bar_x, bar_y + mov r1, r8 + ldr r0, [r1, #0x4] @class + mov r3, #0x11 @con + ldsb r3, [r0, r3] + ldr r0, [r1] + ldrb r0, [r0, #0x13] @bonus + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + add r3, r3, r0 + mov r0, #0x1A + ldsb r0, [r1, r0] + add r0, r3, r0 + str r0, [sp] + ldr r0, [r1, #0x4] + ldrb r0, [r0, #0x19] + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + str r0, [sp, #0x4] + mov r0, #0x7 + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_rating_at, tile_x, tile_y + push {r4} + mov r4, #0x0 + mov r0, r8 + blh MaxHPGetter + add r4, r4, r0 + mov r0, r8 + blh StrGetter + add r4, r4, r0 + mov r0, r8 + blh SklGetter + add r4, r4, r0 + mov r0, r8 + blh SpdGetter + add r4, r4, r0 + mov r0, r8 + blh LuckGetter + add r4, r4, r0 + mov r0, r8 + blh DefGetter + add r4, r4, r0 + mov r0, r8 + blh ResGetter + add r4, r4, r0 + mov r0, r4 + pop {r4} + mov r1, #Blue + draw_number_at \tile_x, \tile_y +.endm + +.macro draw_con_number_at, tile_x, tile_y + mov r1, r8 + ldr r0, [r1, #0x4] @class + mov r3, #0x11 @con + ldsb r3, [r0, r3] + ldr r0, [r1] + ldrb r0, [r0, #0x13] @bonus + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + add r3, r3, r0 + mov r0, #0x1A + ldsb r0, [r1, r0] + cmp r0, #0 + beq ConNotBoosted + mov r1, #Green + b FromConBoosted + ConNotBoosted: + mov r1, #Blue + FromConBoosted: + add r0, r0, r3 + draw_number_at \tile_x, \tile_y +.endm + +.macro draw_con_bar_with_getter_at, bar_x, bar_y +@base in r3, final in sp, cap in sp+4, call getter + mov r1, r8 + ldr r0, [r1, #0x4] @class + mov r3, #0x11 @con + ldsb r3, [r0, r3] + ldr r0, [r1] + ldrb r0, [r0, #0x13] @bonus + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + add r3, r3, r0 + + push {r1-r3} + mov r0, r8 + blh MagConGetter + pop {r1-r3} + str r0, [sp] @final + ldr r0, [r1, #0x4] + ldrb r0, [r0, #0x19] + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + str r0, [sp, #0x4] @store cap + mov r0, #0x7 + mov r1, #(\bar_x-11) + mov r2, #(\bar_y-2) + blh DrawBar, r4 +.endm + +.macro draw_number_at, num_x, num_y, routine=0, colour=2 @r0 is number and r1 is colour + .if \routine + mov r0, r8 + blh \routine + .endif + mov r1, #\colour @defaults to blue + mov r2, r0 + ldr r0, =(tile_origin+(0x20*2*\num_y)+(2*\num_x)) + blh DrawDecNumber +.endm + +.macro draw_charge_at, num_x, num_y, colour=2 @r0 is number and r1 is colour + mov r0, r8 + mov r1, #0x47 + ldrb r0, [r0, r1] + sub r0, #0x10 + cmp r0, #0x0 + beq Greeny + mov r1, #0x2 + b Naxty + Greeny: + mov r1, #0x4 + Naxty: + mov r2, r0 + ldr r0, =(tile_origin+(0x20*2*\num_y)+(2*\num_x)) + blh DrawDecNumber +.endm + +.macro draw_aid_icon_at tile_x, tile_y + mov r0, r8 + ldr r1, [r0] + ldr r2, [r0, #4] + ldr r0, [r1, #0x28] + ldr r1, [r2, #0x28] + orr r0, r1 + blh MountedIconHelper + mov r1, #3 @sheet ID + lsl r1, r1, #8 @shifted 8 bits left + orr r1, r0 + mov r2, #0xA0 + lsl r2, #7 + ldr r0, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + blh DrawIcon +.endm + +.macro draw_trv_text_at, tile_x, tile_y, colour=Blue + draw_textID_at \tile_x, \tile_y, 0x4f9, width=9 @trv + mov r4, r7 + sub r4, #8 @un-advance the buffer + mov r0, r8 + blh WriteTrvText + mov r3, r0 + mov r0, r4 + mov r1, #0x18 @what is this? + mov r2, #\colour + blh Text_InsertString, r4 +.endm + +.macro draw_talk_text_at, tile_x, tile_y, colour=Blue + draw_textID_at \tile_x, \tile_y, width=9 @ideally you want a diff id. + blh CheckGameLinkArenaBit, r4 + mov r4, r7 + sub r4, #8 + cmp r0, #1 + beq DidntFindAPerson + mov r0, r8 + ldr r0, [r0] + ldrb r0, [r0, #0x4] @char byte + bl GetTalkee + cmp r0, #0x0 + bne FoundAPerson + DidntFindAPerson: + ldr r1, =0x7f7f7f @---[X] + ldr r0, =gCurrentTextString + str r1, [r0] + b TextBuffered + FoundAPerson: + mov r1, #0x34 + mul r0, r1 + ldr r1, =0x8017d64 @pointer to character table (in case repointed) + ldr r1, [r1] @actual character table + add r0, r1 + ldrh r0, [r0] + ldr r1, =String_GetFromIndex + mov r14, r1 + .short 0xF800 + TextBuffered: + mov r3, r0 + ldr r0, =Text_InsertString + mov r14, r0 + mov r0, r4 + @ add r0, #0x90 + mov r1, #0x18 + mov r2, #\colour + .short 0xF800 +.endm + +.macro rescue_check + mov r1, r8 + ldr r0, [r1, #0xc] @status + mov r1, #0x10 @rescuing? + and r0, r1 +.endm + +.macro draw_status_text_at, tile_x, tile_y, colour=Blue + draw_textID_at \tile_x, \tile_y, 0x4fa, width=9 @cond + mov r4, r7 + sub r4, #8 + mov r1, r8 + mov r0, r1 + blh WriteStatusText + mov r3, r0 + mov r0, r4 + mov r1, #0x16 @16 if status, otherwise 18??? + mov r2, #\colour + blh Text_InsertString, r4 + mov r1, r8 + add r1, #0x30 + ldrb r2, [r1] + cmp r2, #0 + beq NoStatusCount + ldr r0, =(0x2003ca2+(0x20*2*\tile_y)+(2*\tile_x)) + lsr r2, #5 + mov r1, #0 + blh DrawUiSmallNumber + NoStatusCount: +.endm + +.macro draw_affinity_icon_at, tile_x, tile_y + ldr r4, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r0, r8 + blh AffinityGetter + mov r1, #2 @icon sheet ID + lsl r1, r1, #8 @shifted 8 bits left + orr r1, r0 + mov r2, #0xA0 + lsl r2, r2, #0x7 + mov r0, r4 + blh DrawIcon +.endm + +.macro draw_icon_at, tile_x, tile_y, number=0 + @assumes icon number in r0 or else in number + .if \number + mov r0, #\number + .endif + ldr r4, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r1, r0 + mov r2, #0xA0 + lsl r2, r2, #0x7 + mov r0, r4 + blh DrawIcon +.endm + +.macro draw_stats_box showBallista=0 + ldr r0, =#0x8A02204 @box TSA + ldr r4, =gGenericBuffer + mov r1, r4 + blh Decompress + ldr r0, =#0x20049EE @somewhere on the bgmap + mov r2, #0xC1 + lsl r2, r2, #0x6 + mov r1, r4 + blh BgMap_ApplyTsa + ldr r0, =#0x8205A24 @map of text labels and positions + blh DrawStatscreenTextMap + ldr r6, =StatScreenStruct + ldr r0, [r6, #0xC] + ldr r0, [r0, #0x4] + ldrb r0, [r0, #0x4] + cmp r0, #Deny_Statscreen_Class_Hi + beq SS_DoneEquipHighlightBar + cmp r0, #Deny_Statscreen_Class_Lo + beq SS_DoneEquipHighlightBar + + .if \showBallista + + ldr r2, [r6, #0xC] + ldr r0, [r2, #0xC] + mov r1, #0x80 + lsl r1, r1, #0x4 @Check "in ballista" bit + and r0, r1 + cmp r0, #0x0 + beq NoBallistaEquipped_Box + + @get a non-empty ballista at unit position + mov r0, #0x10 + mov r1, #0x11 + ldsb r0, [r2, r0] + ldsb r1, [r2, r1] + blh GetBallistaItemAt + cmp r0, #0x0 + beq NoBallistaEquipped_Box + mov r5, r0 + mov r4, #0x0 @slot id + b SS_DrawEquippedItemHighlight + + .endif + + NoBallistaEquipped_Box: + ldr r0, [r6, #0xC] + blh EquippedItemSlotGetter + mov r4, r0 + mov r5, #0x0 + cmp r4, #0x0 @no equipped item will be -1 + blt SS_DoneEquipHighlightBar + + SS_DrawEquippedItemHighlight: + lsl r4, r4, #0x1 + add r0, r4, #1 + lsl r0, r0, #0x6 + ldr r1, =#0x2003D4C + add r0, r0, r1 + mov r1, #0x0 + mov r2, #0x35 @the equip 'E' + blh DrawSpecialUiChar + add r0, r4, #2 + lsl r0, r0, #0x6 + ldr r1, =#0x200472E + add r0, r0, r1 + ldr r1, =#0x8A02250 @TSA for highlight bar + mov r2, #0xC1 + lsl r2, r2, #0x6 + blh BgMap_ApplyTsa + + cmp r5, #0x0 + bne SS_DoneEquipHighlightBar + + SS_ItemBox_GetID: + ldr r0, [r6, #0xC] + add r0, #0x1E + add r0, r0, r4 + ldrh r5, [r0] + + SS_DoneEquipHighlightBar: + ldr r0, =StatScreenStruct + ldr r0, [r0, #0xC] + ldr r0, [r0, #0x4] + ldrb r0, [r0, #0x4] + cmp r0, #Deny_Statscreen_Class_Hi + beq SS_DrawItemBox_Unarmed + cmp r0, #Deny_Statscreen_Class_Lo + beq SS_DrawItemBox_Unarmed + + ldr r4, =#0x200407C @bgmap offset + ldr r6, =gActiveBattleUnit + mov r0, r6 + add r0, #0x5A @load battle atk + mov r1, #0x0 + ldsh r2, [r0, r1] + mov r0, r4 + mov r1, #0x2 + blh DrawDecNumber + mov r0, r4 + add r0, #0x80 + mov r1, r6 + add r1, #0x60 @load battle hit + mov r3, #0x0 + ldsh r2, [r1, r3] + mov r1, #0x2 + blh DrawDecNumber + mov r0, r4 + add r0, #0xE + mov r1, r6 + add r1, #0x66 @load battle crit + mov r3, #0x0 + ldsh r2, [r1, r3] + mov r1, #0x2 + blh DrawDecNumber + add r4, #0x8E + mov r0, r6 + add r0, #0x62 @load battle avoid + mov r6, #0x0 + ldsh r2, [r0, r6] + mov r0, r4 + mov r1, #0x2 + blh DrawDecNumber + b SS_DrawItemBox_RangeText + + SS_DrawItemBox_Unarmed: + ldr r4, =#0x200407C + mov r0, r4 + mov r1, #0x2 + mov r2, #0xFF + blh DrawDecNumber + mov r0, r4 + add r0, #0x80 + mov r1, #0x2 + mov r2, #0xFF + blh DrawDecNumber + mov r0, r4 + add r0, #0xE + mov r1, #0x2 + mov r2, #0xFF + blh DrawDecNumber + add r4, #0x8E + ldr r0, =gActiveBattleUnit + add r0, #0x62 @load battle avoid + mov r1, #0x0 + ldsh r2, [r0, r1] + mov r0, r4 + mov r1, #0x2 + blh DrawDecNumber + mov r5, #0x0 @set item as blank + + SS_DrawItemBox_RangeText: + mov r0, r5 + blh GetItemRangeString + mov r5, r0 + ldr r4, =#0x2003CB4 + blh Text_GetStringTextWidth + mov r1, #0x37 + sub r1, r1, r0 + mov r0, r4 + mov r2, #0x2 + mov r3, r5 + blh Text_InsertString, r4 + mov r4, #0x0 + ldr r0, =gpStatScreenPageBg0Map + ldr r3, =#0x7060 + mov r5, r3 + ldr r6, =#0x2C2 + add r2, r0, r6 + ldr r1, =#0x7068 + mov r3, r1 + add r6, #0x40 + add r1, r0, r6 + + @i think this loop just clears a gfx buffer + loc_0x8087660: + add r0, r4, r5 + strh r0, [r2] + add r0, r4, r3 + strh r0, [r1] + add r2, #0x2 + add r1, #0x2 + add r4, #0x1 + cmp r4, #0x7 + ble loc_0x8087660 + +.endm + +.macro draw_items_text showBallista=0 + push {r7} + mov r7, r8 + push {r7} + ldr r2, =StatScreenStruct + ldr r1, [r2, #0xC] + ldr r0, [r1, #0x4] + ldrb r0, [r0, #0x4] + cmp r0, #Deny_Statscreen_Class_Hi + beq GorgonEggSkip_ItemList + cmp r0, #Deny_Statscreen_Class_Lo + beq GorgonEggSkip_ItemList + + SS_StartItemsList: + mov r6, #0x40 + mov r7, r2 + + .if \showBallista + + ldr r2, [r7, #0xC] + ldr r0, [r2, #0xC] + mov r1, #0x80 + lsl r1, r1, #0x4 @Check "in ballista" bit + and r0, r1 + cmp r0, #0x0 + beq NoBallistaEquipped + + @get a non-empty ballista at unit position + mov r0, #0x10 + mov r1, #0x11 + ldsb r0, [r2, r0] + ldsb r1, [r2, r1] + blh GetBallistaItemAt + cmp r0, #0x0 + beq NoBallistaEquipped + mov r5, r0 + + mov r4, #0x2 + neg r4, r4 + mov r8, r4 + mov r4, #0x0 @draws item 1 in slot 2 + mov r2, #Yellow + b SS_DrawItemName + + .endif + + NoBallistaEquipped: + ldr r1, [r7, #0xC] + mov r4, #0x0 + ldrh r5, [r1, #0x1E] + cmp r5, #0x0 @does unit have items left? + beq GorgonEggSkip_ItemList + mov r8, r4 + b SS_LoopItemsList + + GorgonEggSkip_ItemList: + b SS_FinishItemsList + + SS_LoopItemsList: + ldr r2, [r7, #0xC] + ldr r0, [r2, #0xC] + mov r1, #0x80 + lsl r1, r1, #0x5 @Check "drop item" bit + and r0, r1 + cmp r0, #0x0 + beq SS_NotDroppableItem + + mov r0, r2 + blh GetUnitItemCount + sub r0, #0x1 + cmp r4, r0 + bne SS_NotDroppableItem + mov r2, #Green + b SS_DrawItemName + + .ltorg + + SS_NotDroppableItem: + ldr r0, [r7, #0xC] + mov r1, r5 + blh IsItemUsable + mov r2, #White + lsl r0, r0, #0x18 + cmp r0, #0x0 + bne SS_DrawItemName + mov r2, #Grey + SS_DrawItemName: + lsl r0, r4, #0x3 + ldr r1, =#0x2003C8C + add r0, r0, r1 + ldr r3, =#0x2003D2E @ypos? + add r3, r6, r3 + mov r1, r5 + blh DrawItemOnStatscreen, r5 + mov r0, #0x2 + add r8, r0 + add r6, #0x80 + add r4, #0x1 + cmp r4, #0x4 + bgt SS_FinishItemsList + ldr r0, [r7, #0xC] + add r0, #0x1E + add r0, r8 + ldrh r5, [r0] + cmp r5, #0x0 + bne SS_LoopItemsList + b SS_FinishItemsList + + .ltorg + + SS_FinishItemsList: + pop {r7} + mov r8, r7 + pop {r7} +.endm + +.macro clear_buffers + blh Text_InitFont + blh _ResetIconGraphics + @ blh Statscreen_ClearBuffer + blh DontBlinkLeft + @ blh MovingMapSprite_EndAll + @ ldr r4, =StatScreenStruct + @ ldr r0, [r4, #0xc] + @ mov r1, #0x50 + @ mov r2, #0x8A + @ blh MovingMapSprite_CreateForUI + @ str r0, [r4, #0x10] + blh Statscreen_StartLeftPanel + mov r0, #0 + str r0, [sp] + mov r0, sp + ldr r1, =0x6001380 + ldr r2, =0x1000a68 + swi 0xC @clear vram +.endm + + +.equ Sword, 0 +.equ Lance, 1 +.equ Axe, 2 +.equ Bow, 3 +.equ Staff, 4 +.equ Anima, 5 +.equ Light, 6 +.equ Dark, 7 + +.macro draw_weapon_rank_at, tile_x, tile_y, weapon, id + mov r0, #\id + mov r1, #\tile_x + mov r2, #\tile_y + mov r3, #\weapon + blh DrawWeaponRank, r4 +.endm + +.macro get_attack_speed + mov r0, r8 + blh SpdGetter + mov r4, r0 @speed in r4 + mov r0, r8 + blh EquippedWeaponGetter + blh ItemWeightGetter + mov r5, r0 @weight in r5 + mov r1, r8 + ldr r0, [r1, #0x4] @class + mov r3, #0x11 @con + ldsb r3, [r0, r3] + ldr r0, [r1] + ldrb r0, [r0, #0x13]@char bonus + lsl r0, r0, #0x18 + asr r0, r0, #0x18 + add r3, r3, r0 + mov r0, #0x1A + ldsb r0, [r1, r0] @body ring bonus + add r0, r3, r0 @total con in r0 + cmp r0, r5 + blt WeighedDown + mov r0, r4 @put speed directly + b AS_End + WeighedDown: + sub r5, r0 @weight - con in r5 + sub r0, r4, r5 + AS_End: +.endm + +.macro get_attack + ldr r6, =gActiveBattleUnit + mov r0, r6 + add r0, #0x5A + mov r1, #0x0 + ldsh r0, [r0, r1] +.endm + +.macro get_hit + mov r1, r6 + add r1, #0x60 + mov r3, #0x0 + ldsh r0, [r1, r3] +.endm + +.macro get_avoid + ldr r0, =gActiveBattleUnit + add r0, #0x62 + mov r1, #0x0 + ldsh r0, [r0, r1] +.endm + +@requires alternateicondraw +.macro draw_skill_icon_at, tile_x, tile_y, number=0 + .if NoAltIconDraw + .if \number + mov r0, #\number + .endif + + @ r1 = 0x0100 + mov r1, #1 + lsl r1, #8 + + @ r1 = [0x01][SkillIndex] + orr r1, r0 + + @ r2 = 0x4000 (aka tiles have palette #4) + mov r2, #0x40 + lsl r2, #8 + + ldr r0, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + + blh DrawIcon + .else + @assumes icon number in r0 or else in number + .if \number + mov r0, #\number + .endif + + ldr r4, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r1, r0 + mov r2, #0x80 + lsl r2, r2, #0x7 + mov r0, r4 + bl DrawSkillIcon + .endif +.endm + + +.macro draw_rating_icon_at, tile_x, tile_y, number=0 + .if NoAltIconDraw + .if \number + mov r0, #\number + .endif + + @ r1 = 0x0100 + mov r1, #1 + lsl r1, #9 + + @ r1 = [0x01][SkillIndex] + orr r1, r0 + + @ r2 = 0x4000 (aka tiles have palette #4) + mov r2, #0x20 + lsl r2, #8 + + ldr r0, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + + blh DrawIcon + .else + @assumes icon number in r0 or else in number + .if \number + mov r0, #\number + .endif + + ldr r4, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x)) + mov r1, r0 + mov r2, #0x80 + lsl r2, r2, #0x7 + mov r0, r4 + bl DrawSkillIcon + .endif +.endm + +.macro setup_menu + ldr r0, =0x020234A8 + mov r1, #0 + blh FillBgMap + mov r0, #0x0 + mvn r0, r0 @-1 + blh LoadNewUIPal+1 +.endm + +.macro draw_menu, tile_x, tile_y, width, height + push {r4} + sub sp, #4 + mov r0, #0 + str r0, [sp] + mov r0, #\tile_x+0xC + mov r1, #\tile_y+0x2 + mov r2, #\width + mov r3, #\height + blh MakeUIWindowTileMap_BG0BG1+1, reg=r4 + add sp, #4 + pop {r4} +.endm + + +.macro draw_character_name_at, tile_x, tile_y + ldr r0, [r7, #0xC] @load unit's pointer + ldr r0, [r0] @load character pointer + ldrh r0, [r0] @load name + blh String_GetFromIndex + mov r5, r0 + mov r0, #0x30 + mov r1, r5 + blh Text_GetStringTextCenteredPos + mov r6, r0 + + mov r0, r7 + add r0, #0x18 + ldr r1, =(0x20*2*\tile_y)+(2*\tile_x) + add r1, r8 + mov r4, #0 + str r4, [sp] + str r5, [sp, #4] + mov r2, #0 + mov r3, r6 + add r3, #3 + blh DrawTextInline +.endm + +.macro draw_class_name_at, tile_x, tile_y + ldr r0, [r7, #0xC] @load unit's pointer + ldr r0, [r0, #4] @load class pointer + ldrh r0, [r0] @load class name + blh String_GetFromIndex + mov r2, r7 + add r2, #0x20 + ldr r1, =(0x20*2*\tile_y)+(2*\tile_x) @#0x342 + add r1, r8 + str r4, [sp] + str r0, [sp, #4] + mov r0, r2 + mov r2, #0 + mov r3, #0 + blh DrawTextInline +.endm + +.macro draw_lv_icon_at, tile_x, tile_y + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) @#0x3C2 + add r0, r8 + mov r1, #3 + mov r2, #0x24 + mov r3, #0x25 + blh DrawLargeFont +.endm + +.macro draw_exp_icon_at, tile_x, tile_y + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) @#0x3CA + add r0, r8 + mov r1, #3 + mov r2, #0x1D + blh DrawSpecialUiChar +.endm + +.macro draw_hp_icon_at, tile_x, tile_y + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) @#0x442 + add r0, r8 + mov r1, #3 + mov r2, #0x22 + mov r3, #0x23 + blh DrawLargeFont +.endm + +.macro draw_ui_slash_at, tile_x, tile_y + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) @#0x44A + add r0, r8 + mov r1, #3 + mov r2, #0x16 + blh DrawSpecialUiChar +.endm + +.macro draw_level_at, tile_x, tile_y + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) @#0xF2 + add r0, r8 + ldr r1, [r7, #0xC] @unit pointer + mov r2, #8 + ldrb r2, [r1, r2] @level + mov r1, #2 + blh DrawDecNumber +.endm + +.macro draw_exp_at, tile_x, tile_y + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) @#0x3CE + add r0, r8 + ldr r1, [r7, #0xC] @unit pointer + ldrb r2, [r1, #9] @exp + mov r1, #2 + blh DrawDecNumber +.endm + +.macro draw_hp_at, tile_x, tile_y + ldr r0, [r7, #0xC] @unit pointer + blh CurHPGetter + cmp r0, #100 + ble DrawHP + mov r0, #0 + sub r0, #1 + DrawHP: + mov r2, r0 + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) + add r0, r8 + @ldr r0, [r7, #0xC] @unit pointer + @blh CurHPGetter + mov r1, #2 + blh DrawDecNumber +.endm + +.macro draw_max_hp, tile_x, tile_y + ldr r0, [r7, #0xC] @unit pointer + blh MaxHPGetter + cmp r0, #100 + blt DrawMaxHP + mov r0, #0 + sub r0, #1 + DrawMaxHP: + mov r2, r0 + ldr r0, =(0x20*2*\tile_y)+(2*\tile_x) + add r0, r8 + mov r1, #2 + blh DrawDecNumber + DrawMaxHP_End: +.endm + +.macro leftpage_start + push {r4-r7, r14} + mov r7, r8 + push {r7} + add sp, #-0x50 + ldr r7, =TileBufferBase @r7 contains the latest buffer. starts at 2003c2c. + ldr r5, =StatScreenStruct + ldr r0, [r5, #0xC] + mov r8, r0 @r8 contains the current unit's data + blh Text_InitFont + blh _ResetIconGraphics + @blh Statscreen_ClearBuffer + blh DontBlinkLeft + mov r0, #0 + str r0, [sp] + mov r0, sp + ldr r1, =0x6001380 + ldr r2, =0x1000a68 + swi 0xC @clear vram + ldr r7, =0x2003BFC + ldr r0, =gBg0MapBuffer + mov r8, r0 + mov r1, #0 + blh FillBgMap + ldr r4, [r7, #0xC] @load unit's pointer + mov r0, r4 + blh EquippedItemSlotGetter + mov r1, r0 + lsl r1, #0x18 + lsr r1, #0x18 + mov r0, r4 + blh SetupBattleStructFromUnitAndWeapon +.endm + +.macro draw_left_affinity_icon_at, tileX, tileY + ldr r0, [r7, #0xC] @load unit's pointer + blh AffinityGetter + mov r1, #2 + lsl r1, #8 + orr r1, r0 + mov r2, #0xA0 + lsl r2, r2, #0x7 + ldr r0, =(gBg0MapBuffer+(0x20*2*\tileY)+(2*\tileX)) + blh DrawIcon +.endm + +.macro draw_gaiden_spells_at, tile_x, tile_y, gaidenStatScreenRoutine +@ This will do nothing if Gaiden Magic is not installed. + ldr r0, =\gaidenStatScreenRoutine + ldr r1, [ r0 ] + cmp r1, #0x00 + beq SkipGaidenDraw + @ Gaiden magic is installed. Call the function for stat screen drawing. + mov lr, r0 + mov r0, #\tile_x @ X coordinate. + mov r1, #\tile_y @ Y coordinate. + mov r2, r7 @ Current TextHandle. + .short 0xF800 + mov r0, r7 @ Next "blank" TextHandle. + SkipGaidenDraw: +.endm diff --git a/EngineHacks/ExternalHacks/StatusExpansion/_compat/status_text.txt b/EngineHacks/ExternalHacks/StatusExpansion/_compat/status_text.txt new file mode 100644 index 00000000..91d83223 --- /dev/null +++ b/EngineHacks/ExternalHacks/StatusExpansion/_compat/status_text.txt @@ -0,0 +1,51 @@ +// this is what I use for status names & descriptions +// you are free to add/change/remove anything you want + +## EnfeebleName +Feeble[X] + +## EnfeebleDesc +Oof.... So heavy...[N] +Stats are lowered...[X] + +## HexingRodStatusName +Hexed[X] + +## HexingRodStatusDesc +You've been hexed![N] +Max HP is halved![X] + +## FreezeStatusName +Frozen[X] + +## FreezeStatusDesc +Brr! Too...cold![N] +Can't...move![X] + +## RegenStatusName +Regen[X] + +## RegenStatusDesc +Ahh! Invigorating![N] +Heal some every turn![X] + +## HasteStatusName +Haste[X] + +## HasteStatusDesc +I feel so light![N] +Move twice per turn![X] + +## SlowStatusName +Slow[X] + +## SlowStatusDesc +I feel so heavy... Enemies[N] +will always attack twice.[X] + +## NumbStatusName +Numb[X] + +## NumbStatusDesc +I can't feel my hands...[N] +I can only attack with magic.[X] diff --git a/EngineHacks/_MasterHackInstaller.event b/EngineHacks/_MasterHackInstaller.event index c5d6437f..860bda5b 100644 --- a/EngineHacks/_MasterHackInstaller.event +++ b/EngineHacks/_MasterHackInstaller.event @@ -212,6 +212,10 @@ POP // Unlock working on chests #include "ExternalHacks/UnlockChest/UnlockChest.event" + + // Status expansion by Sme + ALIGN 4 + #include "ExternalHacks/StatusExpansion/StatusExpansion.event" ALIGN 4 #include "SkillSystem/SkillSystemInstaller.event"