17#define PLACE_PARTY 0x100
18#define PLACE_ENEMY 0x180
43 unitId = unitIds[place];
46 if (requireLivingUnit &&
UnitGetFar(unitId)->hp == 0)
48 positions[count++] = place | sideTag;
66 if (requireLivingUnit != 0) {
93 entry = (order->
items + 1);
112 return positions[(
Random16() * count) >> 16];
117#define COUNT_PARTIAL_CURES(unit, count) \
119 if ((unit)->delusion != 0) \
121 if ((u8)(unit)->confusion != 0) \
123 if ((unit)->charm != 0) \
125 if ((unit)->sleep != 0) \
127 if ((unit)->psySeal != 0) \
129 if ((unit)->grimReaper != 0) \
134#define COUNT_ALL_CURES(unit, count) \
136 COUNT_PARTIAL_CURES((unit), (count)); \
137 if ((unit)->haunt != 0) \
139 if ((unit)->poison != 0) \
144#define COUNT_POSITIVE_MODIFIERS(unit, count) \
146 if ((unit)->attackStage > 0) \
148 if ((unit)->defenseStage > 0) \
150 if ((unit)->resistanceStage > 0) \
152 if ((unit)->elementLevels[0] > 0) \
154 if ((unit)->elementLevels[1] > 0) \
156 if ((unit)->elementLevels[2] > 0) \
158 if ((unit)->elementLevels[3] > 0) \
168#define CHECK_EFFECT_TARGET(unit, action, applies, kindIndex) \
171 switch ((action)->effect) { \
172 case ABILITY_EFFECT_ATTACK_UP_2: \
173 case ABILITY_EFFECT_ATTACK_UP: \
174 if ((unit)->attackStage + 1 <= 4) \
176 if ((unit)->attackTurns == 1) \
179 case ABILITY_EFFECT_ATTACK_DOWN_2: \
180 case ABILITY_EFFECT_ATTACK_DOWN: \
181 if ((unit)->attackStage - 1 >= -4) \
183 if ((unit)->attackTurns == 1) \
186 case ABILITY_EFFECT_DEFENSE_UP_2: \
187 case ABILITY_EFFECT_DEFENSE_UP: \
188 if ((unit)->defenseStage + 1 <= 4) \
190 if ((unit)->defenseTurns == 1) \
193 case ABILITY_EFFECT_DEFENSE_DOWN_2: \
194 case ABILITY_EFFECT_DEFENSE_DOWN: \
195 if ((unit)->defenseStage - 1 >= -4) \
197 if ((unit)->defenseTurns == 1) \
200 case ABILITY_EFFECT_RESISTANCE_UP_2: \
201 case ABILITY_EFFECT_RESISTANCE_UP: \
202 if ((unit)->resistanceStage + 1 <= 4) \
204 if ((unit)->resistanceTurns == 1) \
207 case ABILITY_EFFECT_RESISTANCE_DOWN_2: \
208 case ABILITY_EFFECT_RESISTANCE_DOWN: \
209 if ((unit)->resistanceStage - 1 >= -4) \
211 if ((unit)->resistanceTurns == 1) \
214 case ABILITY_EFFECT_CURE_POISON: \
215 if ((unit)->poison != 0) \
218 case ABILITY_EFFECT_RESTORE: \
219 COUNT_PARTIAL_CURES((unit), (applies)); \
221 case ABILITY_EFFECT_HEAL_HP_60: \
222 case ABILITY_EFFECT_HEAL_HP_30: \
223 if ((unit)->hp < (unit)->maxHp) \
226 case ABILITY_EFFECT_BREAK: \
227 COUNT_POSITIVE_MODIFIERS((unit), (applies)); \
229 case ABILITY_EFFECT_CURE_ALL: \
230 COUNT_ALL_CURES((unit), (applies)); \
232 case ABILITY_EFFECT_CURSE: \
233 if ((unit)->grimReaper == 0) \
236 case ABILITY_EFFECT_POISON: \
237 if ((unit)->poison == 0) \
240 case ABILITY_EFFECT_DEADLY_POISON: \
241 if ((unit)->poison <= 1) \
244 case ABILITY_EFFECT_STUN: \
245 if ((unit)->stun == 0) \
248 case ABILITY_EFFECT_SLEEP: \
249 if ((unit)->sleep == 0) \
252 case ABILITY_EFFECT_HAUNT: \
253 if ((unit)->haunt == 0) \
256 case ABILITY_EFFECT_REVIVE: \
257 case ABILITY_EFFECT_REVIVE_HALF: \
258 case ABILITY_EFFECT_REVIVE_80: \
259 if ((unit)->hp == 0) \
270 if ((unit)->hp == 0 && Battle_IsReviveEffectFar((action)->effect) == 0) \
272 if ((applies) == 0) { \
273 (kindIndex) = ((action)->flags & ABILITY_KIND_MASK) - 1; \
274 switch (kindIndex) { \
275 case ABILITY_KIND_ATTACK - 1: \
276 case ABILITY_KIND_ATTACK_MULTIPLIED - 1: \
277 if ((unit)->hp != 0) \
280 case ABILITY_KIND_SUMMON - 1: \
282 if ((action)->power != 0 && (unit)->hp != 0) \
285 case ABILITY_KIND_PP_DAMAGE - 1: \
286 if ((unit)->pp != 0) \
289 case ABILITY_KIND_HEAL_HP - 1: \
290 if ((unit)->hp != 0 && (unit)->hp < (unit)->maxHp) \
293 case ABILITY_KIND_EFFECT - 1: \
294 case ABILITY_KIND_DAMAGE - 1: \
295 case ABILITY_KIND_UNLEASHED_DAMAGE - 1: \
296 if ((action)->power != 0 && (unit)->hp != 0) \
305#define STRATEGY_MOST_HP 0
306#define STRATEGY_MOST_MAX_HP 1
307#define STRATEGY_RANDOM 2
318 u16 orderPositions[6];
320 s32 targetPositions[6];
353 if (actorId < 0 || actorId > 7) {
356 }
else if (ownSide == 0) {
366 unitIds[candidateCount] = unitId;
368 orderPositions[candidateCount] |= targetIndex;
379 unitId = turnOrder->
enemyIds[targetIndex];
382 unitIds[candidateCount] = unitId;
384 orderPositions[candidateCount] |= targetIndex;
394 if (candidateCount == 0)
398 for (targetIndex = 0; targetIndex < candidateCount; targetIndex++) {
402 unitIds[targetCount] = unitIds[targetIndex];
403 targetPositions[targetCount] = orderPositions[targetIndex];
408 if (targetCount == 0)
421 for (targetIndex = 0; targetIndex < targetCount; targetIndex++) {
422 for (innerIndex = targetIndex; innerIndex < targetCount - 1;
425 nextUnit =
UnitGetFar(unitIds[innerIndex + 1]);
429 value = thisUnit->
hp;
430 nextValue = nextUnit->
hp;
432 value = thisUnit->
maxHp;
433 nextValue = nextUnit->
maxHp;
435 if (value < nextValue) {
436 temp = unitIds[innerIndex];
437 unitIds[innerIndex] = unitIds[innerIndex + 1];
438 unitIds[innerIndex + 1] = temp;
439 temp = targetPositions[innerIndex];
440 targetPositions[innerIndex] = targetPositions[innerIndex + 1];
441 targetPositions[innerIndex + 1] = temp;
449 switch (targetCount) {
463 else if (selected <= 10)
472 else if (selected <= 10)
474 else if (selected <= 14)
482 return targetPositions[selected];
484 return targetPositions[(
Random16() * targetCount) >> 16];
What every part of the battle object shares: its includes, in their original order,...
#define TARGET_MODE_ALLIES
@ BATTLE_UNIT_LIST_END
ends the list
@ BATTLE_UNIT_REMOVED
a place whose unit has left the battle
@ ABILITY_KIND_ATTACK
Attack vs Defense, plus the power.
#define ABILITY_KIND_MASK
The low four bits of BattleAct.flags: how BattleTargetExec applies the ability's power.
struct BattleWork * gBattleWork
struct BattleUnit * UnitGetFar(u32 owner)
const u8 * Enemy_GetDefinitionFar(s32 selector)
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
An ability's definition, a row of gBattleAction_DefinitionTable: its targeting, kind,...
u8 range
the aimed unit and range - 1 either side, or ABILITY_RANGE_ALL
u8 targetMode
TARGET_MODE_NONE, _FOES, _ALLIES or _SELF.
u8 flags
bits: 7 usable in battle | 6 usable in the field | 5..4 clear in every row | 3..0 kind (ABILITY_KIND_...
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
s16 hp
current HP, 0 when downed
u8 classId
Who the unit is: a character's id (ISAAC to JENNA, below 8) or an enemy's id (BattleUnitSet).
s16 maxHp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
s16 partyUnits[7]
ends with BATTLE_UNIT_LIST_END
s16 enemyIds[BATTLE_ENEMY_CAPACITY+1]
ends with BATTLE_UNIT_LIST_END
An enemy's definition: its level and stats, items, element preset, the actions it chooses from and it...
BattleWork's unit lists, read as one array of halfwords.
s16 items[64]
BattleWork from its start; each list at its offset / 2.
#define PLACE_PARTY
The list place codes the target pickers return: the party's places 0x100 | place, the enemies' 0x180 ...
#define CHECK_EFFECT_TARGET(unit, action, applies, kindIndex)
How worthwhile an enemy's ability is against unit, in applies (0 for pointless): a stat change that c...
s32 BattleTarget_SelectForAction(s32 actorId, struct BattleAct *action)
Picks the target of an enemy's ability (or a confused unit's), as a place code: among the units of th...
s32 BattleTarget_SelectRandomPosition(s32 requireLivingUnit)
Picks a random place: with requireLivingUnit, a party member still standing; otherwise any enemy plac...