i actually have a pretty drawn-out plan for skills (i suggested part of this to CC for modular battle but i think he went a different route with it)
[code]// there’s an array of these somewhere in the ROM and classes have some value
// that corresponds to an entry
struct Skill {
int type; // enum determining whether it’s passive, %activation, etc
func effect; // function that takes generic parameters depending on the above “type” enum
// % chance effects would probably be handled in the function themselves, it’s trivial to
// do something like “if this rng value is lower than this next one then multiply might by
// 5 or something”
}
// battle routine, probably the one that would also call the routine status swords hijacks
void calcRound(ptr att, ptr def) {
for (Skill sk : att.jobSkills()) {
// this would include things like passive might boosts
if (sk.type == PASSIVE) sk.effect(att, def);
}
// repeat for defender
// BattleData would ideally be a struct that contains the damage, final hit, crit, etc for
// everything that takes place in a single "round" (aka one attack)
BattleData bd = calcDamage(att, def);
for (Skill sk : att.jobSkills()) {
// this would adjust the damage, final hit, etc
if (sk.type == BATTLE) sk.effect(bd);
}
}[/code]
the difficulty would be in making things that contradict each other (like a flat boost vs a multiplication modifier) stack properly
EDIT
(from a PM to CC)
[code]struct BattleData {
// These are calculated the normal way
int attHit, attCrit, attDmg;
int defHit, defCrit, defDmg;
}
func[] getEffects(UnitData att, UnitData def) {
func[] ptrs;
if (att.eqItem.hasEffect()) {
*ptrs = eqItem.getEffect();
ptrs++;
}
// repeat for defender
for (ItemData item : att.inventory) {
if (item.hasPassiveEffect()) {
*ptrs = item.getPassiveEffect();
ptrs++;
}
}
// repeat for defender
if (att.job.hasBattleEffect()) {
*ptrs = job.getBattleEffect();
}
// etc
// "long_call" means
// > param stuff
// ldr rn, FUNC_PTR_TARG
// bx rn
// that way the user can just "bx lr" out of it
// Optional routine handling effect priority
long_call(handlePriority, ptrs);
}
void runBattle() {
// this function just does things the normal way
BattleData data = calculateBattleData();
func[] battleEffects = getEffects(attackerData, defenderData);
for (func eff : battleEffects) {
eff(attackerData, defenderData, data);
}
runBattle(attackerData, defenderData, data);
// probably can do something similar to the above to handle post-battle effects
}
[/code]
E2: wow there’s gotta be a way to collapse this stuff