Alchemy
Loading...
Searching...
No Matches

formation.c

Go to the documentation of this file.
1/// @file
2/// Enemy formations: the enemies chosen, levelled and lettered.
3/// Part of battle.c, the battle object, compiled only through it.
4
6
7/// The rows of gBattleFormation_Records.
8#define FORMATION_COUNT 380
9
10// How many name letters tell the enemies of one class apart: 26 in Japanese,
11// 9 in the localizations.
12#if (LANGUAGE != LANGUAGE_JAPANESE)
13#define ENEMY_NAME_SUFFIX_COUNT 9
14#else
15#define ENEMY_NAME_SUFFIX_COUNT 26
16#endif
17
18/// Returns a formation's average enemy level, for the monster battles to
19/// choose by.
20/// Returns -1 for a formation with no required member, -2 when it holds an
21/// enemy above level 3 the party has not defeated (ENEMY_DEFEATED_FLAG,
22/// unless flag 0x174 is set), and -3 when it has no member. Called by
23/// BattleFormation_SelectLevelMatchedCandidate for every formation.
25 struct BattleFormationRecord *record;
26 struct EnemyDefinition *enemy;
27 u32 memberIndex;
28 s32 enemyId;
29 s32 levelTotal;
30 s32 enemyCount;
31 /* FAKEMATCH(dead): an unused array for the frame's 28 bytes; without it, 2
32 * of 94 instructions differ in tbs-en. */
33 UNUSED s32 levels[7];
34
35 enemyCount = 0;
36 levelTotal = 0;
37 record = &gBattleFormation_Records[recordId];
38 for (memberIndex = 0; memberIndex < 5; memberIndex++) {
39 if (record->minimumCounts[memberIndex] != 0)
40 break;
41 }
42 if (memberIndex == 5)
43 return -1;
44 // The average counts each member that may appear once, whatever its
45 // numbers.
46 for (memberIndex = 0; memberIndex < 5; memberIndex++) {
47 if (record->maximumCounts[memberIndex] == 0)
48 continue;
49 enemyId = record->memberIds[memberIndex];
50 enemy = (struct EnemyDefinition *)Enemy_GetDefinitionFar(enemyId +
52 if (enemy == 0)
53 continue;
54 // XXX: flag 0x174 makes every enemy eligible; what sets it would name it.
55 if (enemy->level > 3 && !GameFlag_TestFar(0x174) &&
57 return -2;
58 levelTotal += enemy->level;
59 enemyCount++;
60 }
61 if (enemyCount == 0)
62 return -3;
63 return levelTotal / enemyCount;
64}
65
66/// A formation that may be chosen for the party's level: its record and its
67/// enemies' average level.
69 s16 recordId; ///< the formation's row
70 s16 score; ///< its average level (BattleFormation_AverageLevel); -1 empty
71};
72
73/// A copy of a unit's base stats, from baseHp to its element stats, kept
74/// while its level is adjusted: BattleEnemy_AdjustLevel reads only the stats
75/// it changes, for their 70 percent floors.
79 s16 hpGauge; ///< copied, not read
80 s16 ppGauge; ///< copied, not read
84 u8 baseLuck; ///< copied, not read
85 u8 actionCount; ///< copied, not read
86 u8 hpRegen; ///< copied, not read
87 u8 ppRegen; ///< copied, not read
89 struct BattleElementStats element[4]; ///< the base power is read
90};
91
92/// Chooses a monster battle's formation for the party's level, and returns it
93/// with the levels its enemies must gain in outMargin.
94/// The target is the active members' average level plus the monster battles
95/// won in a row (FLAG_MONSTER_BATTLE_WINS), between 1 and 99; a formation
96/// qualifies when its average level is at most 3 above it, and one of up to
97/// 32 qualifying is chosen at random. With none, it returns formation 1 and a
98/// margin of 0. Called by BattleFormation_BuildEnemyList under
99/// FLAG_MONSTER_BATTLE; clears the defeated flags of the classes in
100/// gBattleFormation_LevelMatchedEnemies, excluding them unless flag 0x174
101/// bypasses the defeated-enemy check.
103 s32 matchCount = 0;
105 u16 party[8];
106 s32 levelTotal = 0;
107 s32 unitCount = BattleParty_PrepareActiveOwners(party);
108 s32 candidateOrUnitIndex;
109 s32 poolIndex;
110 s32 targetLevel;
111 s32 result;
112
113 if (unitCount > 0) {
114 u16 *unitCursor = party;
115
116 candidateOrUnitIndex = unitCount;
117 do {
118 u8 level = UnitGetFar(*unitCursor)->level;
119
120 candidateOrUnitIndex--;
121 unitCursor++;
122 levelTotal += level;
123 } while (candidateOrUnitIndex != 0);
124 }
125
126 // The flag byte is -1 once a series has ended, which takes a level off.
127 targetLevel = levelTotal / unitCount;
129 if (targetLevel <= 0)
130 targetLevel = 1;
131 if (targetLevel > 99)
132 targetLevel = 99;
133
134 for (candidateOrUnitIndex = 0; candidateOrUnitIndex <= 31;
135 candidateOrUnitIndex++)
136 pool[candidateOrUnitIndex].score = -1;
137
138 // Forget defeated classes that the monster battles normally exclude;
139 // flag 0x174 can still admit them. The definition read is unused.
140 for (candidateOrUnitIndex = 0; (u32)candidateOrUnitIndex <= 19;
141 candidateOrUnitIndex++) {
143 gBattleFormation_LevelMatchedEnemies[candidateOrUnitIndex]);
145 gBattleFormation_LevelMatchedEnemies[candidateOrUnitIndex]));
146 }
147
148 // Each qualifying formation replaces the pool's lowest entry; empty
149 // entries score -1, so the pool fills first.
150 for (candidateOrUnitIndex = 0; (u32)candidateOrUnitIndex < FORMATION_COUNT;
151 candidateOrUnitIndex++) {
152 s32 score = BattleFormation_AverageLevel(candidateOrUnitIndex);
153
154 if (score >= 0 && score <= targetLevel + 3) {
155 s32 lowestIndex = -1;
156 s32 lowestLevel;
157
158 for (poolIndex = 0, lowestLevel = 999; poolIndex <= 31; poolIndex++) {
159 if (pool[poolIndex].score < lowestLevel) {
160 lowestLevel = pool[poolIndex].score;
161 lowestIndex = poolIndex;
162 }
163 }
164
165 if (lowestIndex >= 0) {
166 pool[lowestIndex].score = score;
167 pool[lowestIndex].recordId = candidateOrUnitIndex;
168 matchCount++;
169 }
170 }
171 }
172
173 // matchCount includes formations evicted from the pool.
174 if (matchCount > 32)
175 matchCount = 32;
176
177 if (matchCount != 0) {
178 struct FormationCandidate *chosen = &pool[(matchCount * Random16()) >> 16];
179
180 result = chosen->recordId;
181 *outMargin = targetLevel - chosen->score;
182 } else {
183 *outMargin = matchCount;
184 result = 1;
185 }
186
187 MemFree(pool);
188 return result;
189}
190
191/// Raises an enemy by levels, or lowers it for a negative count: each base
192/// stat changes by a fixed amount a level, kept between 70 percent of what it
193/// was and its cap.
194/// A level is worth 9.7 HP, 1.5 PP, 12.3 Attack, 3.3 Defense, 5.1 Agility and
195/// 15 power in each element; HP and PP are capped at 9999, the other stats at
196/// 999 and power at 200. Changes the unit's base stats and level and works
197/// out its stats again (UnitCalc). Called by BattleFormation_BuildEnemyList
198/// for each enemy of a monster battle.
199#ifdef UBFIX
200void BattleEnemy_AdjustLevel(s32 owner, s32 levels) {
201#else
203#endif
204 struct BattleBaseStats *base;
205 struct BattleUnit *unit;
206 s32 value;
207 s32 minimumStat;
208 s32 element;
209
211 unit = UnitGetFar(owner);
212 Iwram_CopyWords(base, &unit->baseHp, sizeof(struct BattleBaseStats));
213
214 value = unit->baseHp;
215 value += levels * 97 / 10;
216 minimumStat = base->baseHp * 7 / 10;
217 CLAMP(value, minimumStat, 9999);
218 unit->baseHp = value;
219
220 value = unit->basePp;
221 value += levels * 15 / 10;
222 minimumStat = base->basePp * 7 / 10;
223 CLAMP(value, minimumStat, 9999);
224 unit->basePp = value;
225
226 minimumStat = levels * 123 / 10;
227 value = unit->baseAttack;
228 value += minimumStat;
229 minimumStat = base->baseAttack * 7 / 10;
230 CLAMP(value, minimumStat, 999);
231 unit->baseAttack = value;
232
233 minimumStat = levels * 33 / 10;
234 value = unit->baseDefense;
235 value += minimumStat;
236 minimumStat = base->baseDefense * 7 / 10;
237 CLAMP(value, minimumStat, 999);
238 unit->baseDefense = value;
239
240 minimumStat = levels * 51 / 10;
241 value = unit->baseAgility;
242 value += minimumStat;
243 minimumStat = base->baseAgility * 7 / 10;
244 CLAMP(value, minimumStat, 999);
245 unit->baseAgility = value;
246
247 for (element = 0; element < 4; element++) {
248 value = unit->baseElement[element].power + levels * 15;
249 minimumStat = base->element[element].power * 7 / 10;
250 CLAMP(value, minimumStat, 200);
251 unit->baseElement[element].power = value;
252 }
253
254 unit->level += levels;
255 UnitCalcFar(owner);
256 MemFree(base);
257}
258
259/// Gives an enemy of the class its name letter, which tells it from others of
260/// its kind, and returns the letter's number for BattleUnitSetFar.
261/// The letters are digits from 1 abroad and the alphabet in Japanese. The
262/// class's first enemy gets ENEMY_NAME_SUFFIX_COUNT, which BattleUnitSetFar
263/// takes as no letter. Its second gets letter 1 with bit 15 (0x8001), telling
264/// the caller to give the first letter 0 (BattleEnemy_LetterFirstOfClass);
265/// later ones take the next free letter, wrapping. Returns -1 when five classes
266/// are already listed. Called by BattleFormation_BuildEnemyList for each enemy
267/// and by BattleTargetExec for an enemy called into the battle. Changes
268/// BattleWork's enemyClasses, summonChannels, summonMasks and summonCount.
270 struct BattleWork *battle;
271 s32 classCount;
272 s32 classIndex;
273 s32 attempt;
274 s32 suffix;
275
276 battle = gBattleWork;
277 classCount = battle->summonCount;
278 for (classIndex = 0; classIndex < classCount; classIndex++) {
279 if (battle->enemyClasses[classIndex] == classId)
280 break;
281 }
282 if (classIndex != classCount) {
283 attempt = 0;
284 // The second of its class: letters 0 and 1 both taken.
285 if (battle->summonChannels[classIndex] < 0) {
286 battle->summonChannels[classIndex] = 1;
287 battle->summonMasks[classIndex] = 3;
288 return 0x8001;
289 }
290 // The next letter after the last given that is free; after 32 tries the
291 // last one tried is reused.
292 for (; attempt <= 31; attempt++) {
293 suffix =
294 (battle->summonChannels[classIndex] + 1) % ENEMY_NAME_SUFFIX_COUNT;
295 battle->summonChannels[classIndex] = suffix;
296 if ((battle->summonMasks[classIndex] & (1 << (s8)suffix)) == 0)
297 break;
298 }
299 battle->summonMasks[classIndex] |= 1 << battle->summonChannels[classIndex];
300 return battle->summonChannels[classIndex];
301 }
302 if (classCount <= 4) {
303 battle->summonChannels[classCount] = -1;
304 battle->enemyClasses[classCount] = classId;
305 battle->summonMasks[classCount] = 0;
306 battle->summonCount = classCount + 1;
308 }
309 return -1;
310}
311
312/// Frees a departing enemy's name letter for the next of its class, reading
313/// the letter back from the end of its name.
314/// Does nothing for a unit that is not an enemy, a class not listed or one
315/// with no letters given. Clears the letter's bit in BattleWork.summonMasks.
316/// Called by BattleActor_RemoveFromLists.
317#ifdef UBFIX
319#else
321#endif
322 struct BattleWork *battle = gBattleWork;
323 struct BattleUnit *unit;
324 s32 count = battle->summonCount;
325 s32 index;
326 s32 nameLength;
327 s32 suffixIndex;
328 s32 classId;
329
330 unit = UnitGetFar(actorId);
331 if (unit->classIndex != 0)
332 return;
333
334 classId = unit->classId;
335 for (index = 0; index < count; index++) {
336 if (battle->enemyClasses[index] == classId)
337 break;
338 }
339 if (index == count || battle->summonMasks[index] == 0)
340 return;
341
342 for (nameLength = 0; nameLength <= 13; nameLength++) {
343 if (unit->name[nameLength] == 0)
344 break;
345 }
346
347 // An empty name uses a shift of 32, which emits zero on ARM. A name with
348 // no suffix instead uses its last character as a suffix.
349 suffixIndex = 32;
350 if (nameLength > 0)
351 suffixIndex = unit->name[nameLength - 1] - LIST_MARKER_CHAR;
352 battle->summonMasks[index] &= ~(1 << suffixIndex);
353}
354
355/// Gives the first enemy of the class on the field the first letter (0),
356/// appended to its name, once a second of its class arrives.
357/// Called by BattleFormation_BuildEnemyList and BattleTargetExec when
358/// BattleEnemy_ClaimNameLetter returns bit 15. Writes BattleUnit.name.
359#ifdef UBFIX
361#else
363#endif
364 struct BattleUnit *unit;
365 s32 enemyIndex;
366 s32 nameIndex;
367 s32 terminatorIndex;
368 u8 nameByte;
369 u8 firstSuffix;
370
371 enemyIndex = 0;
372 firstSuffix = LIST_MARKER_CHAR;
373 for (; enemyIndex <= 5; enemyIndex++) {
374 unit = UnitGetFar(enemyIndex + FIRST_ENEMY_UNIT);
375 nameByte = unit->side;
376 if (nameByte != BATTLE_UNIT_ENEMY)
377 continue;
378 if (unit->classId != classId)
379 continue;
380 // nameByte still holds BATTLE_UNIT_ENEMY here, used as the index after
381 // the letter; nameIndex holds the terminator, 0.
382 nameIndex = 0;
383 if (unit->name[0] == 0) {
384 unit->name[0] = firstSuffix;
385 unit->name[nameByte] = nameIndex;
386 return;
387 }
388 // The name's end, then the letter and a new terminator after it.
389 scan_slots:
390 nameIndex++;
391 if (nameIndex > 13)
392 return;
393 nameByte = unit->name[nameIndex];
394 if (nameByte != 0)
395 goto scan_slots;
396 terminatorIndex = nameIndex + 1;
397 unit->name[nameIndex] = firstSuffix;
398 unit->name[terminatorIndex] = nameByte;
399 return;
400 }
401}
402
403/// Returns the class id of a random member of the formation, among those
404/// that may appear (maximum count above 0); formation 1 stands in for an id
405/// out of range.
406/// Called by BattleTargetExec when an enemy calls for help.
408 s32 choices[5];
409 struct BattleFormationRecord *record;
410 s32 *choicesBase;
411 s32 *choiceCursor;
412 u8 *maximumCount;
413 u8 *memberId;
414 u32 choiceCount;
415 s32 remainingMembers;
416
417 choiceCount = 0;
418 if (recordId < 0 || recordId >= FORMATION_COUNT)
419 recordId = 1;
420
421 choicesBase = choices;
422 record = &gBattleFormation_Records[recordId];
423 memberId = record->memberIds;
424 maximumCount = record->maximumCounts;
425 choiceCursor = choicesBase;
426 remainingMembers = 4;
427 do {
428 if (*maximumCount++ != 0) {
429 *choiceCursor++ = *memberId + ENEMY_CLASS_FIRST;
430 choiceCount++;
431 }
432 memberId++;
433 remainingMembers--;
434 } while (remainingMembers >= 0);
435
436 return choices[(Random16() * choiceCount) >> 16];
437}
438
439/// Builds the battle's enemies from formation recordId and returns how many
440/// there are.
441/// Each member comes its minimum number of times, plus a random number more
442/// up to its maximum while the six sprite slots hold them (a large enemy
443/// takes two). The formation's battle type orders them: shuffled kinds, each
444/// kind together (FORMATION_SHUFFLED), interleaved at random
445/// (FORMATION_INTERLEAVED), or in the record's order. Under
446/// FLAG_MONSTER_BATTLE the formation is chosen for the party's level instead,
447/// and each enemy raised to it. An empty or out-of-range formation becomes
448/// formation 1. Called once by Battle_RunEncounter. Fills the enemy units
449/// from FIRST_ENEMY_UNIT, with their name letters, and sets BattleWork's
450/// battleType, firstDefeated, defeatState and the name-letter lists.
452 u16 *enemyClasses;
453 struct BattleWork *battle;
454 struct BattleFormationRecord *record;
455 s32 enemyCount;
456 s32 levelAdjustment;
457 u16 listBuffer[14];
458 s32 extraCounts[5];
459 s32 memberCounts[5];
460 s32 memberOrder[5];
461 s32 freeSpriteSlots;
462 s32 changed;
463 s32 additionalRoom;
464 s32 spriteSlots;
465 s32 fittingCount;
466 s32 classId;
467 s32 memberOrCopyIndex;
468 s32 remainingKinds;
469 s32 copies;
470 u32 memberOrEnemyIndex;
471 s32 memberIndex;
472
473 battle = gBattleWork;
474 levelAdjustment = 0;
475 battle->summonCount = 0;
476 enemyClasses = listBuffer;
478 recordId = BattleFormation_SelectLevelMatchedCandidate(&levelAdjustment);
479 if (recordId < 0 || recordId >= FORMATION_COUNT)
480 recordId = 1;
481 record = &gBattleFormation_Records[recordId];
482 for (memberIndex = 0;
483 memberIndex <= 4 && record->minimumCounts[memberIndex] == 0;
484 memberIndex++)
485 ;
486 if (memberIndex == 5)
487 record = &gBattleFormation_Records[1];
488
489 // The six sprite slots left once every member's minimum is placed; a
490 // large enemy takes two.
491 freeSpriteSlots = 6;
492 enemyCount = 0;
493 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4; memberOrEnemyIndex++) {
494 if (record->minimumCounts[memberOrEnemyIndex] != 0) {
495 s32 requiredSlots =
496 2 - (BattleClass_IsSmall(record->memberIds[memberOrEnemyIndex] +
497 ENEMY_CLASS_FIRST) != 0);
498
499 freeSpriteSlots -=
500 requiredSlots * record->minimumCounts[memberOrEnemyIndex];
501 }
502 }
503
504 // Each member's extra enemies: a random number from 0 to as many more as
505 // its maximum allows and the free slots would hold on their own.
506 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4; memberOrEnemyIndex++) {
507 s32 minimum;
508 s32 maximum;
509
510 memberCounts[memberOrEnemyIndex] = minimum =
511 record->minimumCounts[memberOrEnemyIndex];
512 maximum = record->maximumCounts[memberOrEnemyIndex];
513 additionalRoom = maximum - minimum;
514 if (additionalRoom > 0) {
515 s32 memberSlots =
516 2 - (BattleClass_IsSmall(record->memberIds[memberOrEnemyIndex] +
517 ENEMY_CLASS_FIRST) != 0);
518
519 fittingCount = freeSpriteSlots / memberSlots;
520 if (fittingCount < additionalRoom)
521 additionalRoom = fittingCount;
522 extraCounts[memberOrEnemyIndex] =
523 ((additionalRoom + 1) * Random16()) >> 16;
524 } else {
525 extraCounts[memberOrEnemyIndex] = 0;
526 }
527 }
528
529 // The extras then take the shared slots one per member a pass, in member
530 // order, until none fits.
531 do {
532 changed = 0;
533 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4;
534 memberOrEnemyIndex++) {
535 classId = record->memberIds[memberOrEnemyIndex] + ENEMY_CLASS_FIRST;
536 if (extraCounts[memberOrEnemyIndex] != 0) {
537 spriteSlots = 2 - (BattleClass_IsSmall(classId) != 0);
538 if (spriteSlots > freeSpriteSlots) {
539 extraCounts[memberOrEnemyIndex] = 0;
540 } else {
541 memberCounts[memberOrEnemyIndex]++;
542 extraCounts[memberOrEnemyIndex]--;
543 freeSpriteSlots -= spriteSlots;
544 changed = 1;
545 }
546 }
547 }
548 } while (changed);
549
550 // The list of class ids, in the order the battle type gives, ended by 0.
551 battle->battleType = record->battleType;
552 switch (battle->battleType) {
554 // The members' order shuffled by ten random swaps.
555 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4; memberOrEnemyIndex++)
556 memberOrder[memberOrEnemyIndex] = memberOrEnemyIndex;
557 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 9;
558 memberOrEnemyIndex++) {
559 s32 first = (Random16() * 5) >> 16;
560 s32 second = (Random16() * 5) >> 16;
561 s32 swap = memberOrder[first];
562
563 memberOrder[first] = memberOrder[second];
564 memberOrder[second] = swap;
565 }
566 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4;
567 memberOrEnemyIndex++) {
568 s32 copyIndex;
569 s32 slot = memberOrder[memberOrEnemyIndex];
570
571 for (copyIndex = 0; copyIndex < memberCounts[slot]; copyIndex++)
572 enemyClasses[enemyCount++] =
573 record->memberIds[slot] + ENEMY_CLASS_FIRST;
574 }
575 break;
577 // Each enemy drawn from a random member with any left.
578 for (;;) {
579 remainingKinds = 0;
580 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4;
581 memberOrEnemyIndex++) {
582 if (memberCounts[memberOrEnemyIndex] != 0)
583 memberOrder[remainingKinds++] = memberOrEnemyIndex;
584 }
585 if (remainingKinds == 0)
586 break;
587 memberOrCopyIndex = memberOrder[(Random16() * remainingKinds) >> 16];
588 enemyClasses[enemyCount++] =
589 record->memberIds[memberOrCopyIndex] + ENEMY_CLASS_FIRST;
590 memberCounts[memberOrCopyIndex]--;
591 }
592 break;
593 default:
594 for (memberOrEnemyIndex = 0; memberOrEnemyIndex <= 4;
595 memberOrEnemyIndex++) {
596 copies = memberCounts[memberOrEnemyIndex];
597 for (memberOrCopyIndex = 0; memberOrCopyIndex < copies;
598 memberOrCopyIndex++)
599 enemyClasses[enemyCount++] =
600 record->memberIds[memberOrEnemyIndex] + ENEMY_CLASS_FIRST;
601 }
602 break;
603 }
604 // No class has fallen yet (6), and the enemy units start cleared.
605 enemyClasses[enemyCount] = 0;
606 battle->firstDefeated = 6;
607 battle->defeatState = 0;
608 for (memberOrEnemyIndex = FIRST_ENEMY_UNIT;
609 memberOrEnemyIndex < FIRST_ENEMY_UNIT + ENEMY_BATTLE_SIZE;
610 memberOrEnemyIndex++)
611 Iwram_ClearWords(UnitGetFar(memberOrEnemyIndex), BATTLE_UNIT_SIZE);
612
613 memberOrEnemyIndex = 0;
614 if (enemyClasses[0] == 0)
615 goto assigned;
616assign_enemy:
617 // Each enemy unit, with its name letter (BattleEnemy_ClaimNameLetter) and,
618 // in a monster battle, the level margin.
619 {
620 s32 suffixCode =
621 BattleEnemy_ClaimNameLetter(enemyClasses[memberOrEnemyIndex], 1);
622
623 if (suffixCode & 0x8000)
624 BattleEnemy_LetterFirstOfClass(enemyClasses[memberOrEnemyIndex]);
625 BattleUnitSetFar(memberOrEnemyIndex + FIRST_ENEMY_UNIT,
626 enemyClasses[memberOrEnemyIndex], suffixCode & 0x7fff);
627 UnitGetFar(memberOrEnemyIndex + FIRST_ENEMY_UNIT);
628 if (levelAdjustment != 0)
629 BattleEnemy_AdjustLevel(memberOrEnemyIndex + FIRST_ENEMY_UNIT,
630 levelAdjustment);
631 }
632 memberOrEnemyIndex++;
633 if (memberOrEnemyIndex > 5)
634 goto assigned;
635 if (enemyClasses[memberOrEnemyIndex] != 0)
636 goto assign_enemy;
637assigned:
638 return memberOrEnemyIndex;
639}
s32 BattleClass_IsSmall(s32 index)
Returns 1 for a small class, which takes one enemy sprite slot instead of two and stands closer to it...
Definition classes.c:45
s32 BattleParty_PrepareActiveOwners(u16 *owners)
Lists the party members who fight (the first four of the party, three in a link battle) and marks eac...
Definition encounter.c:371
u16 gBattleFormation_LevelMatchedEnemies[]
struct BattleFormationRecord gBattleFormation_Records[]
What every part of the battle object shares: its includes, in their original order,...
#define ENEMY_CLASS_FIRST
An enemy's class id is its row of enemies.tsv plus 8 (Enemy_GetDefinition); class ids 0 to 7 are the ...
#define FORMATION_INTERLEAVED
#define FORMATION_SHUFFLED
BattleWork.battleType, from the enemy formation (BattleFormation_BuildEnemyList): the random formatio...
#define FIRST_ENEMY_UNIT
Unit ids from 128 are the enemies'; in a link battle the opponent's party takes the first three.
#define ENEMY_BATTLE_SIZE
#define ENEMY_DEFEATED_FLAG(classId)
The game flag of an enemy class the party has defeated, set by BattleEnemy_RecordDefeat outside the m...
@ BATTLE_UNIT_ENEMY
@ BATTLE_UNIT_SIZE
Definition battle_unit.h:13
struct BattleWork * gBattleWork
struct BattleUnit * UnitGetFar(u32 owner)
s32 BattleUnitSetFar(s32 unitId, s32 enemyId, s32 suffix)
s32 GameFlag_TestFar(s32 flag)
const u8 * Enemy_GetDefinitionFar(s32 selector)
s32 GameFlag_GetByteFar(s32 flag)
void GameFlag_ClearBitFar(s32 flag)
void UnitCalcFar(s32 owner)
#define FLAG_MONSTER_BATTLE_WINS
Monster battles won in a row, added to the monsters' level; -1 after the series ends.
Definition flags.h:88
#define FLAG_MONSTER_BATTLE
The link lobby's battle against a monster when no opponent is linked: formations matched to the party...
Definition flags.h:77
#define ENEMY_NAME_SUFFIX_COUNT
Definition formation.c:13
s32 BattleEnemy_LetterFirstOfClass(s32 classId)
Gives the first enemy of the class on the field the first letter (0), appended to its name,...
Definition formation.c:362
s32 BattleFormation_BuildEnemyList(s32 recordId)
Builds the battle's enemies from formation recordId and returns how many there are.
Definition formation.c:451
s32 BattleGroupRandom(s32 recordId)
Returns the class id of a random member of the formation, among those that may appear (maximum count ...
Definition formation.c:407
s32 BattleFormation_SelectLevelMatchedCandidate(s32 *outMargin)
Chooses a monster battle's formation for the party's level, and returns it with the levels its enemie...
Definition formation.c:102
s32 BattleFormation_AverageLevel(s32 recordId)
Returns a formation's average enemy level, for the monster battles to choose by.
Definition formation.c:24
s32 BattleEnemy_AdjustLevel(s32 owner, s32 levels)
Raises an enemy by levels, or lowers it for a negative count: each base stat changes by a fixed amoun...
Definition formation.c:202
#define FORMATION_COUNT
The rows of gBattleFormation_Records.
Definition formation.c:8
s32 BattleEnemy_ClaimNameLetter(s32 classId, s32 unused)
Gives an enemy of the class its name letter, which tells it from others of its kind,...
Definition formation.c:269
s32 BattleEnemy_ReleaseNameLetter(s32 actorId)
Frees a departing enemy's name letter for the next of its class, reading the letter back from the end...
Definition formation.c:320
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
Definition macros.h:23
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void MemFree(void *buffer)
A copy of a unit's base stats, from baseHp to its element stats, kept while its level is adjusted: Ba...
Definition formation.c:76
u8 baseLuck
copied, not read
Definition formation.c:84
s16 ppGauge
copied, not read
Definition formation.c:80
s16 hpGauge
copied, not read
Definition formation.c:79
struct BattleElementStats element[4]
the base power is read
Definition formation.c:89
u8 hpRegen
copied, not read
Definition formation.c:86
u8 actionCount
copied, not read
Definition formation.c:85
u8 ppRegen
copied, not read
Definition formation.c:87
A unit's elemental power and resistance in one element.
Definition battle_unit.h:27
s16 power
Elemental power in the element.
Definition battle_unit.h:28
An enemy formation: its battle type and up to five kinds of enemy, each with the fewest and most of i...
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u16 baseDefense
before equipment, Djinn, class and stages
u16 baseAttack
before equipment, Djinn, class and stages
u16 baseAgility
before equipment, Djinn, class and stages
u8 side
BATTLE_UNIT_ABSENT (0), BATTLE_UNIT_ENEMY (1) or BATTLE_UNIT_PARTY (2).
u8 name[0x0f]
The name, one byte a character, ending in 0.
struct BattleElementStats element[4]
Power and resistance in each element, 0 to 200, after equipment, element levels and Resistance stages...
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 basePp
before equipment, Djinn and class (UnitCalc)
u8 classIndex
The character's class, worked out from its Djinn (Unit_UpdateClass); 0 marks an enemy,...
s16 baseHp
before equipment, Djinn and class (UnitCalc)
u8 level
1 to 99 for a character
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
Definition battle_work.h:71
u16 firstDefeated
The enemyClasses index of the first class to fall; 6 for none.
Definition battle_work.h:83
u8 summonCount
classes listed in enemyClasses, at most 5
Definition battle_work.h:85
u16 enemyClasses[6]
The enemy classes met so far, for their name letters, and the first class to fall (firstDefeated).
Definition battle_work.h:76
s8 summonChannels[6]
The letter each class in enemyClasses gave out last; -1 for none yet.
Definition battle_work.h:80
u16 defeatState
DEFEAT_ONE, DEFEAT_SEVERAL or DEFEAT_BY_PARTY_MEMBER.
Definition battle_work.h:84
u8 battleType
FORMATION_SHUFFLED or FORMATION_INTERLEAVED.
Definition battle_work.h:87
u32 summonMasks[6]
Name letters in use by each class in enemyClasses, a bit per letter.
Definition battle_work.h:78
An enemy's definition: its level and stats, items, element preset, the actions it chooses from and it...
Definition character.h:89
A formation that may be chosen for the party's level: its record and its enemies' average level.
Definition formation.c:68
s16 recordId
the formation's row
Definition formation.c:69
s16 score
its average level (BattleFormation_AverageLevel); -1 empty
Definition formation.c:70
#define LIST_MARKER_CHAR
Definition tbs_edition.h:80
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11