-
Notifications
You must be signed in to change notification settings - Fork 94
Modular Hooks
There are many skills and other engine hacks that all need to make some change at an identical or very similar point in the code to apply their effect. To prevent each of these locations either having one incredibly long function with a myriad of effects within it or conflicts between skills and/or other engine hacks, these locations are converted to modular hooks.
A modular hook is a wrapper inserted into a function that will call an arbitrary number of other functions when run. This is accomplished with a list of pointers to the functions to be run, which the wrapper will loop through all of. This also makes writing functions that go within these lists less complicated, as rather than a function that hooks in the middle of some existing function and needs to preserve register values when it returns, these functions are called like any normal function would be and therefore follow the comparatively less strict conventions of normal functions.
Here, type signatures will be given for the functions called by each modular hook. The types and naming conventions are taken from the FE8U decomp.
Calculation loops, or calc loops for short, are the majority of the modular hooks used by the skill system. They cover a broad amount of the commonly used areas, with most of the rest covered by other, more specific modular hooks elsewhere.
void BattleProcFunc(struct BattleUnit* bunitA, struct BattleUnit* bunitB, struct BattleHit* curRound, struct BattleStats* stats)
The Battle Proc Calc Loop is run on each round of battle being calculated and is used primarily for skills that have a chance of activating during battle, commonly referred to as "proc skills". Within the function list, functions here should go between Proc_Start
and Proc_Finish
.
int CanUnitDoubleFunc(struct BattleUnit* bunitA, struct BattleUnit* bunitB)
The Can Unit Double Calc Loop is run when determining if unit A can double unit B, immediately following the normal Attack Speed calculation. The value returned by these functions determines the behavior:
-
0
forces unit A to be unable to double, and exits the loop. -
1
forces unit A to be able to double, and exits the loop. -
2
continues the loop. If the end of the loop is reached without a function returning0
or1
, the Attack Speed result is kept.
int EXPFunc(int exp, struct BattleUnit* bunitA, struct BattleUnit* bunitB
The EXP Calc Loop is run during post-battle experience gain calculation, immediately following the standard calculation's conclusion. The value returned by these functions is the modified EXP value, or the input exp
if no changes are made.
int HPRestorationFunc(struct Unit* unit, int healPercent)
The HP Restoration Calc Loop is run at the start of each phase when determining what units should be healed by things such as terrain. The value returned by these functions is the modified heal %, or the input healPercent
if no changes are made.
int MugLoadingFunc(u16 controlCode)
The Mug Loading Calc Loop is run when interpreting a control code in text. The value returned by these functions is the mug ID to display. If a function returns a non-zero value, the loop is exited and that value is used as the mug ID. If a function returns 0, the loop continues.
void PostActionFunc(Unit* unit)
The Post-Action Calc Loop is run immediately after a unit's state is set to have acted for the turn.
void PostBattleFunc()
The Post-Battle Calc Loop is run in place of the normal function that sets if a unit is able to Canto.
void PreBattleFunc(struct BattleUnit* bunitA, struct BattleUnit* bunitB)
The Pre-Battle Calc Loop is run in place of calculating battle stats.
u32 RangeFunc(struct Unit* unit, u16 item, u32 minMaxRange)
The Range Calc Loop is run during weapon range calculations. This one is somewhat unique in that the loop itself contains a built-in skill check, so functions do not need to include one, only specify a skill ID when placed into the loop. The value returned by these functions is the updated minMaxRange
word, or the input one if unchanged. The format of this value is (minRange << 16 | maxRange)
.
int SkillActivationChanceFunc(int activationChance, struct BattleUnit* unit)
The Skill Activation Chance Calc Loop contains modifiers on the activation rate of proc skills. The value returned by these functions is the updated activation chance %, or the input activationChance
if no change.
int WeaponUsabilityFunc(struct Unit* unit, u16 item, u8 rank)
The Weapon Usability Calc Loop is run when determining if a unit is able to wield a weapon. The value returned by these functions is one of 3:
-
0
means the unit cannot use the weapon, and the loop is exited. -
1
means the unit can use the weapon, and the loop is exited. -
2
means to continue the loop.
void WTAFunc(struct BattleUnit* bunitA, struct BattleUnit* bunitB)
The WTA Calc Loop is run immediately after calculating the weapon triangle stat bonuses.
The Turn Loop encompasses a few different calc loops, each with their own signature:
void StartOfTurnSilentFunc()
The TurnCalcLoop_Silent
list contains functions that run silently at the start of each turn. They take no arguments and return no value. This is the only turn loop that runs multiple functions per frame: every other loop only runs one function per frame.
void StartOfTurnFunc(struct Proc* parent)
The StartOfTurnCalcLoop
list contains functions that run at the start of each turn. They take a proc as an argument, and blocking that proc allows them to apply effects before the loop advances.
void EndOfTurnFunc(struct Proc* parent)
The EndOfTurnCalcLoop
list contains functions that run at the end of each turn. They take a proc as an argument, and blocking that proc allows them to apply effects before the loop advances.
Modular Stat Getters are used when calculating a unit's stats. All stat getters use the same function signature.
u8 StatGetterFunc(u8 stat, struct Unit* unit)
stat
is the stat as has been calculated so far by the loop. unit
is the unit whose stat is being calculated. Returns the modified stat, to be passed to the next function in the loop.