28#define STAT_STAGE_MIN -4
29#define STAT_STAGE_MAX 4
31#define AGILITY_STAGE_DOUBLED 8
33#define RESISTANCE_PER_STAGE 20
37#define STAT_CHANGE_TURNS 7
38#define AGILITY_CHANGE_TURNS 5
46#define PSY_SEAL_BIND 7
47#define PSY_SEAL_LUFF 16
53#define MESSAGE_NONE -1
56#define IS_PARTY_UNIT(unitId) ((unitId) >= 0 && (unitId) < 8)
62#define CLAMP_STAT_STAGE(stage) \
64 if ((stage) < STAT_STAGE_MIN) \
65 (stage) = STAT_STAGE_MIN; \
66 if ((stage) > STAT_STAGE_MAX) \
67 (stage) = STAT_STAGE_MAX; \
71#define PUSH_SIDE_MESSAGE(unitId, partyMessage, enemyMessage) \
73 if (IS_PARTY_UNIT(unitId)) \
74 PUSH_MESSAGE(partyMessage); \
76 PUSH_MESSAGE(enemyMessage); \
80#define REDUCE_BY_GUARD(damage, unit) \
82 s32 guard = (unit)->guardLevel; \
85 if (guard == GUARD_DEFEND) \
191 distance = -distance;
205 if (resistance < target->
baseElement[i].resistance)
242 chance *= 65536 / 100;
319 for (i = 0; i < enemyCount; i++)
372 if (skipDamage == 0 &&
388 baseDefense = target->
def;
389 defense = baseDefense;
390 if (halveDefense != 0)
391 defense = (
u32)baseDefense / 2;
395 for (pass = 1; pass <= 1; pass++) {
400 power = ability->
power;
406 amount *= multiplier;
411 amount = amount * 5 / 4;
413 amount = amount * 3 / 2;
414 amount += (target->
level / 5) + 6;
422 message = MsgCritical;
433 if (leaveOneHp != 0) {
434 if (amount < hp - 1) {
463 damageDealt = target->
hp - hp;
470 if (ability->
power == 0)
475 power = ability->
power;
478 amount *= multiplier;
492 damageDealt = target->
pp - pp;
501 if (ability->
power == 0)
506 power = ability->
power;
510 amount *= multiplier;
513 if (newHp > target->
maxHp) {
514 newHp = target->
maxHp;
515 amount = newHp - target->
hp;
518 if (newHp == target->
maxHp)
524 damageDealt = target->
hp - newHp;
533 if (ability->
power == 0)
538 power = ability->
power;
541 amount *= multiplier;
563 if (ability->
power == 0)
567 for (pass = 1; pass <= 1; pass++) {
572 power = ability->
power;
610 power += target->
maxHp * maxHpPercent / 100;
613 amount *= multiplier;
649 damageDealt = target->
hp - newHp;
656 if (ability->
power == 0)
659 power = ability->
power;
663 amount *= multiplier;
665 if (pp > target->
maxPp) {
667 amount = pp - target->
pp;
670 if (pp == target->
maxPp)
690 if (ability->
power == 0)
695 power = ability->
power;
697 amount *= multiplier;
713 damageDealt = target->
hp - newHp;
736 switch (ability->
effect) {
746 if (target->
stun != 0) {
763 if (target->
haunt != 0) {
768 if (target->
poison != 0) {
784 if (target->
stun != 0) {
820 oldHp = (
u16)target->
hp;
823 maxHp = target->
maxHp;
825 stat = (
u16 *)&target->
hp;
827 newHp = *(
s16 *)(stat + 1);
830 maxHp = *(
s16 *)(stat + 1);
833 newHp += maxHp * 60 / 100;
835 newHp += maxHp * 30 / 100;
836 if (newHp > (
s16)maxHpBits)
837 newHp = (
s16)maxHpBits;
838 restored = newHp - (
s16)oldHp;
842 if (newHp == (
s16)maxHpBits)
860 maxPp = target->
maxPp;
862 newPp += maxPp * 7 / 100;
865 restored = newPp - oldPp;
985 target->
hp = target->
maxHp / 2;
993 target->
hp = target->
maxHp * 8 / 10;
1127 amount = damageDealt;
1131 if (newHp > actor->
maxHp) {
1132 newHp = actor->
maxHp;
1133 amount = newHp - actor->
hp;
1137 if (newHp == actor->
maxHp)
1154 drained = damageDealt;
1156 if (newPp > actor->
maxPp) {
1157 newPp = actor->
maxPp;
1158 drained = newPp - actor->
pp;
1162 if (newPp == actor->
maxPp)
1176 amount = damageDealt / 10;
1177 if (target->
pp < amount)
1178 amount = target->
pp;
1179 if (actor->
pp + amount > actor->
maxPp)
1180 amount = actor->
maxPp - actor->
pp;
1296 if (target->
hp != 0)
1304 share = damageDealt >> 2;
1312#define ABILITY_PSY_DRAIN 126
1325 return (
u32)((0 - pp) | pp) >> 31;
@ ABILITY_VENUS
The summons: four to an element, in the order of their Djinn costs, each element's six ids apart.
@ ABILITY_SPEED_SURGE
An enemy that splits itself in two. Its message: "attempts to divide".
s32 BattleEnemyList(s16 *unitIds)
Lists the enemy units present, ended by BATTLE_UNIT_LIST_END, and returns how many there are (0 when ...
u32 BattleEvPush(u32 opcode, u32 operand)
Queues one battle event (enum BattleEventOpcode) with its operand, and returns the opcode.
struct BattleObj * BattleObjGet(s32 unitId)
Returns unitId's battle object, through its place, or null for a unit with no place.
void BattleObjPut(void)
Readies the sprite of every unit in the battle (releasing those of units that left) and sets each one...
s32 EnemyCheck(s32 classId)
Returns 1 if an enemy of class classId would find room among the enemy sprite slots: one free slot fo...
@ BATTLE_EVENT_DEFEAT
the unit falls; an enemy fades out
@ BATTLE_EVENT_UNIT_NAME
a unit's name for the next message
@ BATTLE_EVENT_MARK
sets gBattleDisplayWork->marked
@ BATTLE_EVENT_DJINN_BONUS
later defeats give the Djinn bonus
@ BATTLE_EVENT_HIT
the unit flinches and flashes
@ BATTLE_EVENT_CLEAR_ARGUMENTS
forgets the names and numbers pushed
@ BATTLE_EVENT_REFRESH_UNIT
the unit's status icons, colour, pose
@ BATTLE_EVENT_REMOVE_UNIT
an enemy leaves the battle
@ BATTLE_EVENT_MESSAGE_NO_WAIT
a message, going straight on
@ BATTLE_EVENT_NUMBER
a number for the next message
What every part of the battle object shares: its includes, in their original order,...
#define GUARD_TOTAL_DEFENSE
#define POISON_NORMAL
BattleUnit.poison: the poison takes a tenth of the maximum HP at the end of each turn,...
#define GUARD_DEFEND
BattleUnit.guardLevel: Defend and Granite halve the damage, Total Defense and Flash cut it to a tenth...
@ BATTLE_UNIT_LIST_END
ends the list
@ BATTLE_UNIT_REMOVED
a place whose unit has left the battle
#define HIT_NOT_ROLLED
BattlePlan.targetHit while the hit is still to be rolled, as the ability lands; BattleCommand_BuildPl...
@ CRITICAL_HIT
an attack's: a quarter more damage
@ ABILITY_KIND_PP_DAMAGE
Crazy Voice: the target loses PP.
@ ABILITY_KIND_DAMAGE
HP damage from the power (Psynergy).
@ ABILITY_KIND_HEAL_PP
Ember, Psy Crystal, Adept Ring.
@ ABILITY_KIND_HEAL_HP
Cure, Fizz, healing items.
@ ABILITY_KIND_EFFECT
damage only if the effect lands
@ ABILITY_KIND_ATTACK
Attack vs Defense, plus the power.
@ ABILITY_KIND_UNLEASHED_DAMAGE
an enemy's. Shown as X unleashes Y!
@ ABILITY_KIND_SUMMON
the summons: damage scaled by distance
@ ABILITY_KIND_ATTACK_MULTIPLIED
that attack times power / 10
@ ABILITY_EFFECT_CHALLENGE
no ability has it
@ ABILITY_EFFECT_LEAVE_ONE_HP
Severe Blow, Thrash.
@ ABILITY_EFFECT_SEAL_2_TURNS
Luff.
@ ABILITY_EFFECT_HAUNT
Haunt.
@ ABILITY_EFFECT_INSTANT_DEATH
Condemn.
@ ABILITY_EFFECT_DRAIN_HALF_HP
Sap.
@ ABILITY_EFFECT_ATTACK_DOWN
Blunt.
@ ABILITY_EFFECT_POISON
Taint.
@ ABILITY_EFFECT_BREAK
Break: raised stats undone.
@ ABILITY_EFFECT_HALVE_DEFENSE
Torch.
@ ABILITY_EFFECT_SELF_DESTRUCT
Dynamite, Mortal Blow.
@ ABILITY_EFFECT_HEAL_HP_30
Spritz: 30%.
@ ABILITY_EFFECT_SEAL
Bind: Psynergy sealed.
@ ABILITY_EFFECT_CURE_ALL
Tonic.
@ ABILITY_EFFECT_RESISTANCE_UP
Resist.
@ ABILITY_EFFECT_ATTACK_UP_2
Impact: two stages.
@ ABILITY_EFFECT_ATTACK_UP
High Impact: one stage.
@ ABILITY_EFFECT_THREATEN
Contain, Threaten, Tremble.
@ ABILITY_EFFECT_TOTAL_DEFENSE
Total Defense, Flash.
@ ABILITY_EFFECT_REVIVE_HALF
Quartz.
@ ABILITY_EFFECT_DRAIN_HP
Drain.
@ ABILITY_EFFECT_STUN
Paralyze.
@ ABILITY_EFFECT_SLEEP
Sleep.
@ ABILITY_EFFECT_CHARM
Charm.
@ ABILITY_EFFECT_RESISTANCE_DOWN_2
Weaken.
@ ABILITY_EFFECT_DEFENSE_UP
Protect.
@ ABILITY_EFFECT_REGENERATE
Regenerate.
@ ABILITY_EFFECT_RESTORE
Restore, Elixir.
@ ABILITY_EFFECT_REVIVE_80
Dew: 80% of max HP.
@ ABILITY_EFFECT_ATTACK_DOWN_2
Dull.
@ ABILITY_EFFECT_DEFENSE_DOWN
Debilitate.
@ ABILITY_EFFECT_HEAL_HP_60
Fizz: 60% of max HP.
@ ABILITY_EFFECT_RESISTANCE_UP_2
Ward.
@ ABILITY_EFFECT_CALL_ALLY
Ally Search, Speed Surge.
@ ABILITY_EFFECT_CURSE
Curse: the Grim Reaper's countdown.
@ ABILITY_EFFECT_RESISTANCE_DOWN
Enfeeble.
@ ABILITY_EFFECT_DEFENSE_UP_2
Guard.
@ ABILITY_EFFECT_AGILITY_DOWN
Vine.
@ ABILITY_EFFECT_DEFEND
Defend, Granite.
@ ABILITY_EFFECT_REVIVE
Revive, Water of Life: full HP.
@ ABILITY_EFFECT_GROUND
Ground: the target's turn lost.
@ ABILITY_EFFECT_DELUSION
Delude.
@ ABILITY_EFFECT_CALL_HELP
Search for Help.
@ ABILITY_EFFECT_DRAIN_PP
Psy Drain.
@ ABILITY_EFFECT_CONFUSION
Confuse.
@ ABILITY_EFFECT_HEAL_PP_7
Ember: 7% of max PP.
@ ABILITY_EFFECT_REFLECT
Reflect.
@ ABILITY_EFFECT_DEADLY_POISON
Poison.
@ ABILITY_EFFECT_PSY_LEECH
Psy Leech.
@ ABILITY_EFFECT_CURE_POISON
Cure Poison, Antidote.
@ ABILITY_EFFECT_AGILITY_UP
Zephyr.
@ ABILITY_EFFECT_DEFENSE_DOWN_2
Impair.
@ ABILITY_EFFECT_ACT_TWICE
Kite.
#define ABILITY_KIND_MASK
The low four bits of BattleAct.flags: how BattleTargetExec applies the ability's power.
#define ABILITY_RANGE_ALL
BattleAct.range of an ability that reaches every unit on the side, each as if aimed at.
struct BattleWork * gBattleWork
struct BattleUnit * UnitGetFar(u32 owner)
s32 BattleUnitSetFar(s32 unitId, s32 enemyId, s32 suffix)
s16 Unit_AddPpFar(s32 owner, s32 delta)
s32 BattleHitCheck(s32 caster, s32 target, s32 resistance_category, s32 effect_id, s32 success_scale)
Far call to BattleFx_RollSuccess.
s32 GameFlag_TestFar(s32 flag)
s32 BattlePowerCalc(s32 power, s32 bonus, s32 rate)
Far call to Battle_CalcPsynergyPower.
void UnitRatioFar(s32 owner_id)
struct BattleAct * BattleActGet(s32 actionId)
Far call to BattleAction_GetDirect.
s32 BattleRecoveryCalc(s32 power, s32 element, s32 rate)
Far call to Battle_CalcRecovery.
s32 Battle_IsReviveEffectFar(s32 effect_id)
s32 BattleRandomFar(void)
void UnitCalcFar(s32 owner)
s32 BattleAtkCalc(s32 atk, s32 def, s32 add, s32 bonus)
Far call to Battle_CalcAttackDamage.
void PartyStatusDrawFar(s32 flags)
#define FLAG_DJINN_TUTORIAL
void * MemAlloc(s32 size)
Allocates size bytes (rounded up to words) with no slot, from IWRAM when they fit and EWRAM otherwise...
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
void MemFree(void *buffer)
void ObjMotRst(s32 unitId)
Sends unitId back to its spot, landing there, and turns it to face the centre.
s32 EnemySlotGet(void)
Returns the id of the first free enemy unit, or -1 when all six are taken.
void BattleObjMake(struct BattleObj *actor, s32 unitId, s32 x, s32 y)
Creates the battle object of unit at (x, y) on the battlefield, in pixels: its sprite (an enemy's fro...
s32 EnemyUpdate(void)
Lays the enemies out again and moves each one's object anchor to its new place.
An ability's definition, a row of gBattleAction_DefinitionTable: its targeting, kind,...
u8 ppCost
PP the ability costs.
u8 effect
enum AbilityEffect
u8 range
the aimed unit and range - 1 either side, or ABILITY_RANGE_ALL
u8 flags
bits: 7 usable in battle | 6 usable in the field | 5..4 clear in every row | 3..0 kind (ABILITY_KIND_...
u16 power
what the kind applies, 0 for none
s16 resistance
Elemental resistance to it.
s16 power
Elemental power in the element.
A unit's place on the battlefield: its sprite object, resources and animations, its anchor spot and s...
s32 anchorZ
16.16 fixed-point pixels
s32 anchorX
16.16 fixed-point pixels
One action, as BattleCommand_BuildPlan lays it out for BattleTargetExec to apply target by target.
u32 hauntDamage
The damage the evil spirit deals a haunted actor at the end of its turn.
u8 actorId
the acting unit
u8 targetIds[BATTLE_TARGET_CAPACITY]
in battlefield order
s8 targetHit[BATTLE_TARGET_CAPACITY]
1, 0 or HIT_NOT_ROLLED
s8 targetOffset[BATTLE_TARGET_CAPACITY]
Each target's place relative to the aimed one: negative to one side.
s8 targetCritical[BATTLE_TARGET_CAPACITY]
enum BattleCritical
s16 command
enum BattleCommand
s8 targetMultiplier[BATTLE_TARGET_CAPACITY]
The damage multiplier: 0 a miss, 1 a blow, 2 or 3 a double or triple.
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u8 agilityTurns
the Agility change's turns left, 5 when cast
u8 immobile
set by Ground: the next action is lost
s8 elementLevels[4]
A summon's boost to each element: the Djinn of that element the summon spent, adding (n * n + n) * 5 ...
u8 grimReaper
The Grim Reaper's countdown: 7 when cursed, down one at each turn's end; at 0 the unit falls.
u8 psySeal
bits: 7..3 Luff (16 when cast, minus 8 a turn) | 2..0 Bind's turns (7 when cast).
u8 side
BATTLE_UNIT_ABSENT (0), BATTLE_UNIT_ENEMY (1) or BATTLE_UNIT_PARTY (2).
s16 maxPp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
s8 poison
1 poisoned, 2 deadly poison
u8 haunt
set while an evil spirit grips the unit
s16 hp
current HP, 0 when downed
struct BattleElementStats element[4]
Power and resistance in each element, 0 to 200, after equipment, element levels and Resistance stages...
s8 challenge
Set by the challenge effect: an enemy with it never chooses to flee.
u8 classId
Who the unit is: a character's id (ISAAC to JENNA, below 8) or an enemy's id (BattleUnitSet).
struct BattleElementStats baseElement[4]
Power and resistance before equipment and stages: an enemy's from its element preset,...
s16 maxHp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
s8 agilityStage
The Agility stage: -4 (Vine) to 8 (Zephyr, twice the Agility).
u8 refrain
Regenerate's turns left, 7 when cast.
s8 reflect
Reflect's turns left, 7 when cast.
u16 atk
Attack, 0 to 999 (UnitCalc).
s8 guardLevel
0, GUARD_DEFEND (1, half the damage) or GUARD_TOTAL_DEFENSE (2, a tenth); set by Defend and Granite,...
u8 level
1 to 99 for a character
u8 attackTurns
Each stat change: the turns it has left, and its stage (UnitCalc: an eighth of Attack,...
u16 agi
Agility, 0 to 999: the order of the round's actions.
u16 def
Defense, 0 to 999 (UnitCalc).
u8 delusion
Delusion to sleep: the turns each status has left, 7 when it lands; each may end sooner at the end of...
u8 ready
Kite's extra action: 2 when cast, down one at each turn's end; while nonzero UnitCalc gives the unit ...
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
u8 partyStatus
PARTY_STATUS_SUMMONS or PARTY_STATUS_NO_SUMMONS.
s32 enemyGroup
the encounter's enemy formation
u8 challengeFlag
bits: 1 a party unit was challenged; nonzero, the party cannot run
struct BattleActionRecord actions[BATTLE_ACTION_CAPACITY]
The actions chosen for the turn.
s16 enemyIds[BATTLE_ENEMY_CAPACITY+1]
ends with BATTLE_UNIT_LIST_END
#define FULL_RATE
The rate BattlePowerCalc and BattleRecoveryCalc scale by: 256 is 1.
#define PSY_SEAL_BIND
BattleUnit.psySeal: Bind's seal counts its seven turns in the low three bits, and may end sooner; Luf...
#define CURSE_TURNS
The Grim Reaper's countdown.
#define IS_PARTY_UNIT(unitId)
Unit ids 0 to 7 are the party's; enemy units start at FIRST_ENEMY_UNIT.
#define AGILITY_CHANGE_TURNS
#define REDUCE_BY_GUARD(damage, unit)
A guarding unit takes half the damage, or a tenth behind Total Defense.
#define AGILITY_STAGE_DOUBLED
Zephyr's Agility stage, beyond the usual highest: twice the Agility.
#define PUSH_SIDE_MESSAGE(unitId, partyMessage, enemyMessage)
Pushes one message for a unit of the party and another for an enemy.
#define MESSAGE_NONE
A message operand that shows nothing: the event only waits for the player.
#define STAT_CHANGE_TURNS
s32 BattleEffectDeadCheck(s32 effect)
Returns 1 for an effect that still applies when the ability's damage has just knocked its target out:...
s32 BattleTargetExec(struct BattlePlan *plan, s32 slot)
Applies the planned ability to one of its targets: first its damage or healing, then its added effect...
#define CLAMP_STAT_STAGE(stage)
Holds a stat stage within STAT_STAGE_MIN to STAT_STAGE_MAX.
#define RESISTANCE_PER_STAGE
A Resistance stage adds 20 to the resistance to every element (UnitCalc).
#define STAT_STAGE_MIN
A stat stage changes the stat by an eighth of it (UnitCalc), from half at the lowest to one and a hal...
u32 Ability_IsPsynergy(s32 abilityId)
Returns 1 for an ability that costs PP, and for Psy Drain, which costs none.
#define ABILITY_PSY_DRAIN
The ability Psy Drain, Psynergy that costs no PP.
#define PUSH_MESSAGE(message)
Pushes a message to show, waiting for the player to read it.