Alchemy
Loading...
Searching...
No Matches

round.c

Go to the documentation of this file.
1/// @file
2/// A round's actions: the party's commands, the enemies' or the link
3/// opponent's, and their turn order.
4/// Part of battle.c, the battle object, compiled only through it.
5
7
8/// Background palette 14, which takes palette 15 brightened.
9#define BG_PALETTE_14 ((u16 *)&BG_PLTT_COLOR(14, 0))
10
11/// Pulses BG palette 14's colours: each takes the matching colour of
12/// palette 15 brightened by up to twelve steps, rising and falling with the
13/// frame count. Nothing in the source calls it. Writes BG palette RAM.
15 u16 *palette;
16 s32 remainingColors;
17 s32 channelMask;
18
19 palette = BG_PALETTE_14;
20 channelMask = 31;
21 remainingColors = 15;
22 do {
23 u32 color;
24 s32 brightness;
25 u32 frameCount;
26 s32 angle;
27 s32 blue;
28 s32 green;
29 s32 red;
30
31 // 3/64 of a turn a frame, a pulse about every 21 frames; 1 - cos runs
32 // from 0 to 2.0 (16.16), and a sixth of 1.0 (0x2aaa) is one step.
33 frameCount = gFrameCount;
34 angle = (frameCount * 3U) << 10;
35 color = palette[16];
36 brightness = (0x10000 - Trig_Cos(angle)) / 0x2AAA;
37
38 blue = (color >> 10) & channelMask;
39 green = (color >> 5) & channelMask;
40 red = color & channelMask;
41 blue += brightness;
42 green += brightness;
43 red += brightness;
44
45 if (blue < 0 || blue > 31)
46 blue = 31;
47 if (green < 0 || green > 31)
48 green = 31;
49 if (red < 0 || red > 31)
50 red = 31;
51
52 *palette++ = (blue << 10) | (green << 5) | red;
53 remainingColors--;
54 } while (remainingColors >= 0);
55}
56
57/// Sets the camera up for the fixed view the battle shows while commands are
58/// chosen, raised by verticalOffset pixels, with its projection and the
59/// background's perspective to match. Called by
60/// BattlePresentation_BuildActions, and through its far stub by
61/// Battle_CollectPartyCommands and UpdateLinkSessionCountdown. Writes the
62/// camera, the transition's targetYaw and flag (left 1, so the camera
63/// callback leaves the background alone), gProjection and the background's
64/// affine page.
65void Camera_ConfigureScene(s32 verticalOffset) {
66 // UB: indexing past scalar gCameraWork reaches another work slot. Named
67 // slots add four bytes in the native EN trial (0xd8 to 0xdc).
68#ifdef UBFIX
69 struct BattleCamera *camera = gCameraWork;
70 struct BattlePresentationTransition *transition =
72#else
73 void **slots = (void **)&gCameraWork;
74 struct BattleCamera *camera = slots[0];
75 struct BattlePresentationTransition *transition =
77#endif
78 struct FixedPointPosition eyeOffset;
79 u32 result;
80
81 // Positions are 16.16 pixels and angles 1/65536 turns: the focus 5
82 // pixels up, a quarter turn of yaw, 750 pixels away.
83 camera->pos[1] = 160 << 11;
84 camera->pos[0] = 0;
85 camera->pos[2] = 0;
86 transition->targetYaw = 128 << 7;
87 camera->yaw = 128 << 7;
88 camera->pitch = 244 << 8;
89 camera->followPos = 0;
90 camera->distance = 0x02ee0000;
91 camera->unk18 = 0;
92
97
98 eyeOffset.x = 0;
99 eyeOffset.y = 0;
100 eyeOffset.z = camera->distance;
101 Iwram_TransformVector(&eyeOffset, (s32 *)camera);
102
103 result = Iwram_RatioMulQ14(0x03c90000, 192 << 8);
104 Projection_Set(0, result, 0x07920000);
105
106 // While active (the view's busy) is set, BattleCamera_SetRange leaves
107 // BG1's scroll alone. The range: centre x 120, scale 2.0.
108 gProjection.centerY = verticalOffset + 120;
109 transition->active = 1;
110 BattleCamera_SetRange(240 << 15, (0x76 - verticalOffset) << 16, 0, 128 << 4,
111 128 << 10);
112 transition->flag = 1;
113 transition->active = 0;
114}
115
116/// Ends every unit's guard (Defend and the like) and recalculates its stats.
117/// Called by BattlePresentation_BuildActions as each round begins. Clears
118/// every unit's guardLevel.
120 u16 unitIds[14];
121 s32 count;
122 s32 unitIndex;
123
125 for (unitIndex = 0; unitIndex < count; unitIndex++) {
126 struct BattleUnit *unit;
127
128 unit = UnitGetFar(unitIds[unitIndex]);
129 unit->guardLevel = 0;
130 UnitCalcFar(unitIds[unitIndex]);
131 }
132}
133
134/// gGameState.battleStart of a battle the party cannot run from.
135#define BATTLE_START_NO_ESCAPE 2
136
137/// Rolls whether the party gets away. The chance, in hundredths of a
138/// percent, is 5000 plus 2000 for each attempt that failed, plus 500 times
139/// the party's average level, less 500 times the enemies' average level. A
140/// party that struck first always gets away; no one gets away from a battle
141/// that forbids it. Every attempt counts toward the next. Returns 1 when
142/// the party gets away. Called by BattlePresentation_BuildActions when the
143/// first action is CMD_FLEE. Each roll, even a successful one, raises
144/// gBattleWork->escapeFailures.
146 s32 escaped;
147 u8 *failedAttempts;
148 s16 livingUnits[14];
149 s32 livingCount;
150 s32 levelTotal;
151 s32 unitIndex;
152 s32 chance;
153 struct BattleWork *escapeState;
154
155 escaped = 0;
156 escapeState = gBattleWork;
157 if (escapeState->encounterMode == BATTLE_ENCOUNTER_PARTY_FIRST) {
158 escaped = 1;
159 } else {
160 failedAttempts = &escapeState->escapeFailures;
161 chance = 5000 + (escapeState->escapeFailures * 2000);
162 livingCount = BattleParty_ListLivingUnits(BATTLE_SIDE_PARTY, livingUnits);
163 levelTotal = 0;
164 for (unitIndex = escaped; unitIndex < livingCount; unitIndex++) {
165 levelTotal += UnitGetFar(livingUnits[unitIndex])->level;
166 }
167 chance += levelTotal * 500 / livingCount;
168 livingCount = BattleParty_ListLivingUnits(BATTLE_SIDE_ENEMIES, livingUnits);
169 levelTotal = 0;
170 for (unitIndex = 0; unitIndex < livingCount; unitIndex++) {
171 levelTotal += UnitGetFar(livingUnits[unitIndex])->level;
172 }
173 chance -= levelTotal * 500 / livingCount;
174 // A roll from 0 to 9999 against the chance.
175 if ((chance > 0) && (((10000 * Random16()) >> 0x10) < chance)) {
176 escaped = 1;
177 }
178 *failedAttempts += 1;
179 }
181 escaped = 0;
182 }
183 return escaped;
184}
185
186/// The party's actions for the round, from the command menu: a member who
187/// is asleep, confused, charmed or stunned loses each of their turns
188/// (CMD_NONE); the others choose theirs (Battle_CollectPartyCommandsFar).
189/// Returns how many actions there are, or -1 if the menu gave up. Called by
190/// BattlePresentation_BuildActions. Fills entries.
192 u16 *choosingUnits = Runtime_BumpAllocateAlternatePool(17);
195 s32 choosingCount = 0;
196 s32 entryCount = 0;
197 s32 unitIndex;
198
199 for (unitIndex = 0; unitIndex < unitCount; unitIndex++) {
200 struct BattleUnit *unit = UnitGetFar(unitIds[unitIndex]);
201 s32 copyIndex;
202
203 for (copyIndex = 0; copyIndex < unit->actionEntryCount; copyIndex++) {
204 if (unit->sleep != 0 || unit->confusion != 0 || unit->charm != 0 ||
205 unit->stun != 0) {
206 struct BattleActionRecord *entry = &entries[entryCount];
207 entry->unitId = unitIds[unitIndex];
208 entry->priority = unit->agi;
209 entry->command = CMD_NONE;
210 entry->parameter = 0;
211 entry->target = TARGET_NONE_PARTY;
212 entryCount++;
213 } else {
214 choosingUnits[choosingCount++] = unitIds[unitIndex];
215 }
216 }
217 }
218
219 // The command menu appends the choosing members' actions.
220 {
221 s32 appended;
222
223 entries += entryCount;
224 appended =
225 Battle_CollectPartyCommandsFar(entries, choosingUnits, choosingCount);
226 if (appended < 0) {
227 unitCount = -1;
228 } else {
229 unitCount = entryCount + appended;
230 }
231 MemFree(unitIds);
232 MemFree(choosingUnits);
233 return unitCount;
234 }
235}
236
237/// The enemies' actions for the round, in a shuffled order, each chosen by
238/// BattleCommand_SelectAutomatic; a sleeping or stunned enemy loses its
239/// turns. An enemy acting more than once a turn acts later at half its
240/// Agility. None act when the party struck first; when the party is caught
241/// by surprise, only two to five enemies act, once each. Returns how many
242/// actions there are. Called by BattlePresentation_BuildActions outside a
243/// link battle. Fills entries.
245 u16 unitIds[14];
246 s32 entryCount = 0;
247 struct BattleWork *battle = gBattleWork;
248 s32 unitCount;
249 s32 shuffleOrUnitIndex;
250
252 return 0;
253 }
254
256 if (unitCount == 0) {
257 return 0;
258 }
259
260 for (shuffleOrUnitIndex = 31; shuffleOrUnitIndex >= 0; shuffleOrUnitIndex--) {
261 u32 first = (unitCount * Random16()) >> 16;
262 u32 second = (unitCount * Random16()) >> 16;
263 s32 swap = unitIds[first];
264 unitIds[first] = unitIds[second];
265 unitIds[second] = swap;
266 }
267
268 // A roll of 1 to 5, raised to at least 2.
270 s32 limit = ((Random16() * 5) >> 16) + 1;
271
272 if (limit <= 1) {
273 limit = 2;
274 }
275 if (limit < unitCount) {
276 unitCount = limit;
277 }
278 }
279
280 for (shuffleOrUnitIndex = 0; shuffleOrUnitIndex < unitCount;
281 shuffleOrUnitIndex++) {
282 s32 unitId = unitIds[shuffleOrUnitIndex];
283 struct BattleUnit *unit = UnitGetFar(unitId);
284 s32 copyIndex;
285
286 for (copyIndex = 0; copyIndex < unit->actionEntryCount; copyIndex++) {
287 struct BattleActionRecord *entry = &entries[entryCount];
288 s32 agility;
289
290 entry->unitId = unitId;
291 agility = unit->agi;
292 entry->priority = agility;
293 if (copyIndex != 0) {
294 entry->priority = (s16)agility / 2;
295 }
296
297 if (unit->sleep != 0 || unit->stun != 0) {
298 entry->command = CMD_NONE;
299 entry->parameter = 0;
300 entry->target = TARGET_NONE_ENEMY;
301 } else {
303 }
304
305 entryCount++;
306
308 break;
309 }
310 }
311 }
312
313 return entryCount;
314}
315
316/// A Djinni whose effect is a guard or Ground acts before everyone else.
317#define DJINN_FIRST_PRIORITY 10000
318
319/// Sorts the round's actions into turn order, fastest first, after moving
320/// the guarding and grounding Djinn to the front. Called by
321/// BattlePresentation_BuildActions. Raises those Djinn actions' priority
322/// and reorders entries in place.
324 s32 actionIndex;
325 s32 sortIndex;
326 s32 swapCount;
327
328 for (actionIndex = 0; actionIndex < count; actionIndex++) {
329 struct BattleActionRecord *entry = &entries[actionIndex];
330
331 if (entry->command == CMD_DJINN) {
332 struct BattleAct *action;
333
334 // parameter: the Djinni's element in bits 8 to 11, its number below.
335 // The unit lookup's result is unused.
336 UnitGetFar(entry->unitId);
337 action = BattleActGet(Djinn_GetAbilityIdFar(entry->parameter >> 8 & 15,
338 entry->parameter & 0xff));
339 if (action->effect == ABILITY_EFFECT_DEFEND ||
341 action->effect == ABILITY_EFFECT_GROUND) {
343 }
344 }
345 }
346
347 // Equal priorities keep their order, including the shuffle of enemies.
348 do {
349 swapCount = 0;
350 for (sortIndex = count - 1; sortIndex > 0; sortIndex--) {
351 if ((s16)entries[sortIndex].priority >
352 (s16)entries[sortIndex - 1].priority) {
353 struct BattleActionRecord temporary;
354
355 Iwram_CopyWords(&temporary, &entries[sortIndex],
356 sizeof(struct BattleActionRecord));
357 Iwram_CopyWords(&entries[sortIndex], &entries[sortIndex - 1],
358 sizeof(struct BattleActionRecord));
359 Iwram_CopyWords(&entries[sortIndex - 1], &temporary,
360 sizeof(struct BattleActionRecord));
361 swapCount++;
362 }
363 }
364 } while (swapCount != 0);
365}
366
367/// The header a link battle sends before its actions: how many there are,
368/// the next random number to check the consoles agree, and the parent's
369/// random seed for the round.
371 s32 count; ///< actions that follow the header
372 s32 check; ///< the parent's next BattleRandomFar; the child checks its own
373 s32 seed; ///< the parent's gRandomSeed, the round's battle seed
374 u8 unused[28]; ///< padding; a header packet carries only the first 20 bytes
375};
376
377/// The link sends in packets of 20 bytes (the header is one), and a transfer
378/// may take 300 frames.
379#define LINK_PACKET_BYTES 20
380#define LINK_TRANSFER_TIMEOUT 300
381/// The bytes of count actions, in whole packets.
382#define LINK_ACTIONS_BYTES(count) \
383 ((u32)((count) * 16 + LINK_PACKET_BYTES - 1) / LINK_PACKET_BYTES * \
384 LINK_PACKET_BYTES)
385
386/// Link battle: exchanges the round's actions with the other console and
387/// appends the opponent's after the count of this console's. Each console
388/// sees its own party as the party: the received actions' units take the
389/// ids they have here and their targets swap sides. The parent sends first
390/// and gives the round its random seed; the child checks both consoles
391/// agree on the next random number. A party member's priority is made even
392/// on the parent and odd on the child, so equal speeds sort alike on both.
393/// Returns how many actions were received, or -1 when the exchange fails.
394/// Called by BattlePresentation_BuildActions in a link battle. Sets
395/// gBattleRandomSeed, writes each action's slot and priority, and on a
396/// failure resets the link transfer and removes its interrupt handlers.
398 s32 count) {
399 struct BattleWork *battle = gBattleWork;
400 s32 result = 0;
401 s32 allocationSize = LINK_ACTIONS_BYTES(count);
402 struct BattleLinkedActionState *state =
404 s32 index;
405
406 // Sends the header, then this console's actions. Both transfers share one
407 // timeout of LINK_TRANSFER_TIMEOUT frames.
408 s32 BattleLink_SendActions(void) {
409 s32 timeout;
410 s32 disconnected;
412
413 disconnected = 0;
414 timeout = LINK_TRANSFER_TIMEOUT;
415 if (status == -1)
416 return status;
418 WaitFrames(1);
419 if (--timeout < 0)
420 return -1;
422 if (++disconnected > LINK_MAX_MISSED_FRAMES)
423 return -1;
424 } else {
425 disconnected = 0;
426 }
427 }
428 if (allocationSize) {
429 status = SerialRuntime_BeginSend(actions, allocationSize);
430 if (status == -1)
431 return status;
433 WaitFrames(1);
434 if (--timeout < 0)
435 return -1;
437 if (++disconnected > LINK_MAX_MISSED_FRAMES)
438 return -1;
439 } else {
440 disconnected = 0;
441 }
442 }
443 }
444 return 0;
445 }
446
447 // Receives the header, then the other console's actions after ours. A
448 // transfer that grows past its expected size, or ends short of it, fails.
449 s32 BattleLink_ReceiveActions(void) {
450 // gSerialReceivedSize changes under the serial interrupt and is volatile
451 // (serial_runtime.h), so every read here loads it again.
452 s32 timeout;
453 s32 disconnected;
454 s32 status = SerialRuntime_BeginReceive(state);
455
456 disconnected = 0;
457 timeout = LINK_TRANSFER_TIMEOUT;
458 if (status == -1)
459 return status;
462 return -1;
463 WaitFrames(1);
464 if (--timeout < 0)
465 return -1;
467 if (++disconnected > LINK_MAX_MISSED_FRAMES)
468 return -1;
469 } else {
470 disconnected = 0;
471 }
472 }
474 return -1;
475 result = state->count;
476 if (state->count) {
477 status = SerialRuntime_BeginReceive(actions + count);
478 if (status == -1)
479 return status;
482 return -1;
483 WaitFrames(1);
484 if (--timeout < 0)
485 return -1;
487 if (++disconnected > LINK_MAX_MISSED_FRAMES)
488 return -1;
489 } else {
490 disconnected = 0;
491 }
492 }
494 return -1;
495 }
496 return 0;
497 }
498
499 // Each action carries its unit's id as the opponent knows it.
500 for (index = 0; index < count; index++) {
501 struct BattleActionRecord *action = &actions[index];
502
503 action->slot = battle->ownerSlots[action->unitId];
504
505 if (battle->linkSide == 0) {
506 if (action->priority & 1)
507 action->priority++;
508 } else {
509 action->priority |= 1;
510 }
511 }
512
513 // The parent (link side 0) sends, then receives; the child receives,
514 // then sends and checks the parent's next random number against its own.
515 if (battle->linkPaused == 0) {
516 if (battle->linkSide == 0) {
517 u32 saved;
518
519 state->count = count;
520 state->check = BattleRandomFar();
521 IRQ_LOCK(saved);
523 IRQ_UNLOCK(saved);
524 if (BattleLink_SendActions() < 0 || BattleLink_ReceiveActions() < 0)
525 goto fail;
526 result = state->count;
527 } else {
528 if (BattleLink_ReceiveActions() < 0)
529 goto fail;
530 result = state->count;
531 state->count = count;
532 if (BattleLink_SendActions() < 0 || BattleRandomFar() != state->check)
533 goto fail;
534 gBattleRandomSeed = state->seed;
535 }
536
537 // The received actions, seen from this side: the xor with 0x80 moves a
538 // target between the party's ids and the enemies'.
539 for (index = 0; index < result; index++) {
540 struct BattleActionRecord *action = &actions[count + index];
541
542 action->unitId = action->slot;
543 action->target ^= FIRST_ENEMY_UNIT;
544 }
545
546 MemFree(state);
547 return result;
548 }
549
550fail:
553 MemFree(state);
554 return -1;
555}
556
557/// Copies BG palette 15 to 14 and 5 to 4, brightened or darkened. Called by
558/// BattlePresentation_BuildActions with 8, as the round's commands are
559/// chosen.
560/// @param offset added to each of the red, green and blue values (held in 0
561/// to 31)
563 s32 bankIndex;
564 s32 sourceBank;
565 s32 colorIndex;
566 s32 channelMask;
567 s32 paletteIndex;
568
569 sourceBank = 15;
570 bankIndex = 0;
571 channelMask = 31;
572 do {
573 for (colorIndex = 0; colorIndex <= 15; colorIndex++) {
574 u32 color;
575 s32 blue;
576 s32 green;
577 s32 red;
578 s32 adjustedColor;
579
580 paletteIndex = sourceBank * 16 + colorIndex;
581 color = ((u16 *)BG_PLTT)[paletteIndex];
582 blue = (color >> 10) & channelMask;
583 green = (color >> 5) & channelMask;
584 red = color & channelMask;
585 blue += offset;
586 green += offset;
587 red += offset;
588 if (blue > 31)
589 blue = 31;
590 if (green > 31)
591 green = 31;
592 if (red > 31)
593 red = 31;
594 if (blue < 0)
595 blue = 0;
596 if (green < 0)
597 green = 0;
598 if (red < 0)
599 red = 0;
600 adjustedColor = blue << 10;
601 adjustedColor |= green << 5;
602 adjustedColor |= red;
603 // Into the palette before the source, 14 and 4: 0x04ffffe0 is BG
604 // palette RAM (0x05000000) less one palette's 32 bytes.
605 ((s16 *)0x04ffffe0)[paletteIndex] = adjustedColor;
606 }
607 bankIndex++;
608 sourceBank = 5;
609 } while (bankIndex <= 1);
610}
611
612/// Builds the turn's actions and sorts them into turn order: the party's
613/// commands, then the link opponent's or the enemies' actions.
614/// Returns how many actions there are; negative to abort (a link failure).
615/// Called by Battle_RunEncounter at the start of each round outside auto
616/// battle. Clears gBattleWork->actions, sets every defender's guardLevel,
617/// may set encounterMode to BATTLE_ENCOUNTER_ENEMIES_FIRST after a failed
618/// escape, and holds FLAG_CHOOSING_COMMANDS while the commands are chosen.
619/// @param actions the actions (20 at most)
621 struct BattleUnit *unit;
622 struct BattleWork *battle;
624 s32 count;
625 s32 received;
626 s32 remainingActions;
627
628 battle = gBattleWork;
629 // Empty every action slot of the battle work.
630 {
631 struct BattleActionRecord *record = battle->actions;
632 u32 actionIndex;
633
634 for (actionIndex = 0; actionIndex < BATTLE_ACTION_CAPACITY; actionIndex++) {
635 record[actionIndex].unitId = BATTLE_UNIT_LIST_END;
636 // The lowest priority.
637 record[actionIndex].priority = 0x8000;
638 }
639 }
640
641 // Last round's guards end; palettes 14 and 4 take 15 and 5 eight steps
642 // brighter; the camera takes the command view.
646 encounterMode = &battle->encounterMode;
649
650 // The party's commands (none when the enemies strike first).
651 if (*encounterMode != BATTLE_ENCOUNTER_ENEMIES_FIRST) {
652 count = BattlePres_BuildUnitEntries(actions);
653 if (count < 0)
654 goto finish;
655 // A failed escape turns the round into one the enemies began.
656 if (count != 0 && actions[0].command == CMD_FLEE &&
658 *encounterMode = BATTLE_ENCOUNTER_ENEMIES_FIRST;
659 } else {
660 count = 0;
661 }
662
663 // The link opponent's actions, or the enemies'.
664 // A link battle syncs even after a failed exchange, before giving up.
665 if (gBattleWork->twoSided != 0) {
666 received = BattlePresentation_AppendLinkedActions(actions, count);
667 if (BattlePres_WaitSync() < 0) {
668 count = -1;
669 goto finish;
670 }
671 count += received;
672 if (received < 0) {
673 count = -1;
674 goto finish;
675 }
676 } else {
677 count += BattlePres_BuildOpponentEntries(actions + count);
678 }
679
680 // Sort by priority, and raise the guards of Defend and Total Defense at
681 // once, before anyone acts.
682 BattleQueue_SortByPriority(actions, count);
683 if (count > 0) {
684 struct BattleActionRecord *action = actions;
685
686 remainingActions = count;
687 do {
688 if (action->command == CMD_DEFEND || action->command == CMD_DEFEND2) {
689 unit = UnitGetFar(action->unitId);
690 // Half the damage, or a tenth.
691 unit->guardLevel =
693 }
694 action++;
695 remainingActions--;
696 } while (remainingActions != 0);
697 }
698
699finish:
700 // The battle view again, turned toward the party's turn.
704 return count;
705}
706
707/// Returns the unit id at a list place. Called by BattleCommand_BuildPlan
708/// for a command's target.
709/// @param taggedPlace the place in the low four bits; 0x80 set for the
710/// enemies' list
712 struct BattleWork *battle = gBattleWork;
713
714 if ((taggedPlace & 0x80) != 0)
715 return battle->enemyIds[taggedPlace & 0xf];
716 return battle->partyUnits[taggedPlace & 0xf];
717}
718
719/// Returns the list place of unit id, or -1 if it is in neither list: the
720/// party's as 0x100 | place, the enemies' as 0x180 | place (PLACE_PARTY,
721/// PLACE_ENEMY). Called by the enemies' command choice (enemy_ai.c) to aim
722/// at a unit.
723/// @param unitId 0 to 7 the party, any other an enemy
725 struct BattleWork *battle = gBattleWork;
726 s32 placeIndex;
727 s16 listedUnit;
728
729 if (unitId <= 7) {
730 for (placeIndex = 0;; placeIndex++) {
731 listedUnit = battle->partyUnits[placeIndex];
732 if (listedUnit == BATTLE_UNIT_LIST_END)
733 return -1;
734 if (listedUnit != BATTLE_UNIT_REMOVED && listedUnit == unitId)
735 return placeIndex | 0x100;
736 }
737 }
738 for (placeIndex = 0;; placeIndex++) {
739 listedUnit = battle->enemyIds[placeIndex];
740 if (listedUnit == BATTLE_UNIT_LIST_END)
741 return -1;
742 if (listedUnit != BATTLE_UNIT_REMOVED && listedUnit == unitId)
743 return placeIndex | 0x180;
744 }
745}
746
747/// Turns the camera while L or R is held (a second copy). Nothing in the
748/// source calls it.
750
751/// Does nothing; Battle_RunEncounter calls it at the start of each round.
void BattleCamera_SetRange(s32 centerX, s32 centerY, s32 offsetX, s32 offsetY, s32 scale)
Builds the perspective plane's next page for a zoom of scale about centerX and centerY (all 16....
Definition background.c:224
s32 BattleParty_ListLivingUnits(s32 sideMask, u16 *unitIds)
Lists the units still standing (HP above 0) on the sides in sideMask (BATTLE_SIDE_PARTY,...
Definition encounter.c:437
s32 BattleParty_ListActorIds(s32 sideMask, u16 *unitIds)
Lists the units in the battle's unit lists on the sides in sideMask, party first, skipping those remo...
Definition encounter.c:510
void Camera_InitDefaultTransform(void)
Puts the battle camera at its default view of the battlefield's centre.
Definition objects.c:644
struct BattlePresentationTransition * gTransitionWork
u32 gRandomSeed
struct BattleCamera * gCameraWork
What every part of the battle object shares: its includes, in their original order,...
#define GUARD_TOTAL_DEFENSE
#define FIRST_ENEMY_UNIT
Unit ids from 128 are the enemies'; in a link battle the opponent's party takes the first three.
#define TARGET_NONE_ENEMY
BattleActionRecord.target of an action that needs none: a held unit's lost turn (the enemies' and the...
#define LINK_MAX_MISSED_FRAMES
The frames a link battle tolerates without a connection before it gives up.
#define YAW_PARTY_TURN
The camera's yaw while a party member acts, and while an enemy does.
#define LINK_BOTH_CONNECTED
gLinkStatus: both consoles are connected.
#define TARGET_NONE_PARTY
#define GUARD_DEFEND
BattleUnit.guardLevel: Defend and Granite halve the damage, Total Defense and Flash cut it to a tenth...
@ BATTLE_ENCOUNTER_ENEMIES_FIRST
@ BATTLE_ENCOUNTER_PARTY_FIRST
@ BATTLE_UNIT_LIST_END
ends the list
@ BATTLE_UNIT_REMOVED
a place whose unit has left the battle
@ BATTLE_SIDE_PARTY
@ BATTLE_SIDE_ENEMIES
@ BATTLE_SIDE_BOTH
s32 gBattleRandomSeed
@ CMD_DJINN
@ CMD_DEFEND
@ CMD_NONE
nothing this turn
@ CMD_FLEE
@ CMD_DEFEND2
an enemy's Total Defense (effect 47)
@ ABILITY_EFFECT_TOTAL_DEFENSE
Total Defense, Flash.
@ ABILITY_EFFECT_DEFEND
Defend, Granite.
@ ABILITY_EFFECT_GROUND
Ground: the target's turn lost.
struct BattleWork * gBattleWork
@ BATTLE_ACTION_CAPACITY
Definition battle_work.h:66
s32 BattleCommand_SelectAutomatic(struct BattleActionRecord *request, s32 retry)
Chooses an enemy's action (a party member's is chosen in the menu): one of the eight in its definitio...
Definition enemy_ai.c:33
struct BattleUnit * UnitGetFar(u32 owner)
struct BattleAct * BattleActGet(s32 actionId)
Far call to BattleAction_GetDirect.
s32 GameFlag_SetBitFar(s32 flag)
s32 Djinn_GetAbilityIdFar(u32 group, u32 index)
s32 BattleRandomFar(void)
void GameFlag_ClearBitFar(s32 flag)
void UnitCalcFar(s32 owner)
void UiWork_FinalizeSharedSlotFar(void)
s32 Battle_CollectPartyCommandsFar(struct BattleActionRecord *out, u16 *in, s32 count)
s32 Trig_Cos(s32 angle)
#define FLAG_CHOOSING_COMMANDS
set while the commands are chosen
Definition flags.h:67
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
volatile u32 gFrameCount
Frames WaitFrames has finished.
struct GameState gGameState
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
@ HEAP_SLOT_BATTLE_BACKGROUND
Definition heap_state.h:45
@ HEAP_SLOT_CAMERA
Definition heap_state.h:38
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
#define BG_PLTT
Definition io_reg.h:157
#define IRQ_UNLOCK(saved)
Restores the IME value saved by IRQ_LOCK.
Definition irqlock.h:50
#define IRQ_LOCK(saved)
Disables interrupts and saves IME in saved; IRQ_UNLOCK restores it.
Definition irqlock.h:38
static s32 Iwram_RatioMulQ14(s32 divisor, s32 value)
All calls go through this layer.
Definition iwram_call.h:51
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
static s32 Iwram_TransformVector(const void *vector, s32 *result)
Definition iwram_call.h:65
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)
struct Projection gProjection
s32 BattlePresentation_BuildActions(struct BattleActionRecord *actions)
Builds the turn's actions and sorts them into turn order: the party's commands, then the link opponen...
Definition round.c:620
void Palette_UpdatePulseBrightness(void)
Pulses BG palette 14's colours: each takes the matching colour of palette 15 brightened by up to twel...
Definition round.c:14
#define LINK_TRANSFER_TIMEOUT
Definition round.c:380
void Palette_CopyBanksWithBrightnessOffset(s32 offset)
Copies BG palette 15 to 14 and 5 to 4, brightened or darkened.
Definition round.c:562
void BattleQueue_SortByPriority(struct BattleActionRecord *entries, s32 count)
Sorts the round's actions into turn order, fastest first, after moving the guarding and grounding Dji...
Definition round.c:323
#define LINK_PACKET_BYTES
The link sends in packets of 20 bytes (the header is one), and a transfer may take 300 frames.
Definition round.c:379
s32 Battle_GetTaggedSlotValue(s32 taggedPlace)
Returns the unit id at a list place.
Definition round.c:711
s32 BattleEscape_CheckSuccess(void)
Rolls whether the party gets away.
Definition round.c:145
s32 BattlePres_BuildUnitEntries(struct BattleActionRecord *entries)
The party's actions for the round, from the command menu: a member who is asleep, confused,...
Definition round.c:191
#define DJINN_FIRST_PRIORITY
A Djinni whose effect is a guard or Ground acts before everyone else.
Definition round.c:317
void Battle_ReservedNoOp9B2C(void)
Does nothing; Battle_RunEncounter calls it at the start of each round.
Definition round.c:752
void BattleUnit_ResetGuardLevels(void)
Ends every unit's guard (Defend and the like) and recalculates its stats.
Definition round.c:119
#define BATTLE_START_NO_ESCAPE
gGameState.battleStart of a battle the party cannot run from.
Definition round.c:135
void Camera_ConfigureScene(s32 verticalOffset)
Sets the camera up for the fixed view the battle shows while commands are chosen, raised by verticalO...
Definition round.c:65
s32 BattlePresentation_AppendLinkedActions(struct BattleActionRecord *actions, s32 count)
Link battle: exchanges the round's actions with the other console and appends the opponent's after th...
Definition round.c:397
#define LINK_ACTIONS_BYTES(count)
The bytes of count actions, in whole packets.
Definition round.c:382
void BattlePres_AdjustCameraByShoulderKeysAlt(void)
Turns the camera while L or R is held (a second copy).
Definition round.c:749
#define BG_PALETTE_14
Background palette 14, which takes palette 15 brightened.
Definition round.c:9
s32 Battle_FindTaggedSlotByValue(u32 unitId)
Returns the list place of unit id, or -1 if it is in neither list: the party's as 0x100 | place,...
Definition round.c:724
s32 BattlePres_BuildOpponentEntries(struct BattleActionRecord *entries)
The enemies' actions for the round, in a shuffled order, each chosen by BattleCommand_SelectAutomatic...
Definition round.c:244
s32 SerialRuntime_BeginReceive(void *destination)
Starts receiving the partner's blocks into destination: sets the receive destination and clears the r...
Definition serial.c:474
s32 SerialRuntime_BeginSend(void *source, s32 size)
Starts sending size bytes from source to the partner in 20-byte blocks: sets the send source,...
Definition serial.c:454
void SerialRuntime_RemoveIrqHandlers(void)
Clears gSerialExchangeActive, which stops the per-frame exchange, and removes the link interrupt hand...
Definition serial.c:431
void BattleLink_ResetTransferState(void)
Definition serial.c:536
s32 SerialRuntime_GetActiveTransfers(void)
Returns bit 0 while a send runs and bit 1 while a receive runs.
Definition serial.c:523
volatile u16 gLinkStatus
Link status, updated by the VBlank exchange handler.
volatile u16 gSerialReceivedSize
volatile: tagged where it steers, in BattleLink_ReceiveActions (tbs battle.c) and LinkLobby_ReceivePa...
An ability's definition, a row of gBattleAction_DefinitionTable: its targeting, kind,...
u8 effect
enum AbilityEffect
A unit's chosen action for the turn: its command, the command's parameter, its target and range,...
s16 target
the aimed unit's id
s16 parameter
an ability id, or CMD_ITEM's inventory index (-1 gone)
u16 slot
in a link battle, unitId as the opponent knows it
s16 command
enum BattleCommand
u16 priority
from the unit's Agility; higher acts first
The battle camera: its eye, the focus it turns about, and its pitch, yaw and distance.
u16 pitch
1/65536 turns
s32 distance
eye to focus, 16.16 fixed-point pixels
u16 yaw
1/65536 turns
s32 * followPos
when set, the focus followed instead of pos
s32 pos[3]
the focus, 16.16 fixed-point pixels
s32 unk18
cleared beside followPos; not read by name in TBS
The header a link battle sends before its actions: how many there are, the next random number to chec...
Definition round.c:370
s32 check
the parent's next BattleRandomFar; the child checks its own
Definition round.c:372
s32 seed
the parent's gRandomSeed, the round's battle seed
Definition round.c:373
u8 unused[28]
padding; a header packet carries only the first 20 bytes
Definition round.c:374
s32 count
actions that follow the header
Definition round.c:371
The battle background's work slot as the camera reads it: the yaw the camera eases toward and the fra...
s32 flag
0 lets the camera update set the background's range each frame; 1 for a critical hit's zoom and once ...
s32 active
BattleBackgroundView's busy, at the same offset.
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
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
u16 agi
Agility, 0 to 999: the order of the round's actions.
u8 actionEntryCount
Actions each round, 0 to 2: baseActionCount, one more while ready, and the equipment's extra turns (U...
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
Definition battle_work.h:71
u8 twoSided
1 in a link battle
Definition battle_work.h:90
u8 ownerSlots[8]
For each party unit, its slot as a link opponent's enemy, minus FIRST_ENEMY_UNIT; 0xff for none.
Definition battle_work.h:97
u8 encounterMode
BATTLE_ENCOUNTER_: who strikes first.
Definition battle_work.h:91
s16 partyUnits[7]
ends with BATTLE_UNIT_LIST_END
u8 escapeFailures
Failed attempts to run; each adds 2000 to the base chance of 5000.
Definition battle_work.h:93
struct BattleActionRecord actions[BATTLE_ACTION_CAPACITY]
The actions chosen for the turn.
u8 linkPaused
set when the link drops or the console's id changes
u8 linkSide
this console's multiplayer id
Definition battle_work.h:98
s16 enemyIds[BATTLE_ENEMY_CAPACITY+1]
ends with BATTLE_UNIT_LIST_END
A position in three coordinates, each in 16.16 fixed point.
s32 z
16.16 fixed point
s32 x
16.16 fixed point
s32 y
16.16 fixed point
u8 battleStart
how the next battle starts (Battle_SetStart)
Definition game_state.h:92
s32 centerY
screen pixels
Definition project.h:17
void SceneTransform_ApplyYaw(s32 angle)
Rotates gTransform about the Y axis by angle.
Definition transform.c:113
void Projection_Set(u32 focal, u32 nearDepth, u32 farDepth)
Sets gProjection's focal length and depth range directly.
Definition transform.c:350
void SceneTransform_ApplyPitch(s32 angle)
Rotates gTransform about the X axis by angle.
Definition transform.c:97
void SceneTransform_ApplyPosition(const s32 *position)
Translates gTransform by position (x, y, z in 16.16).
Definition transform.c:145
void Render_ResetTransformState(void)
Allocates the one-level save area (heap slot HEAP_SLOT_TRANSFORM_STACK), clears gTransformStackDepth ...
Definition transform.c:19
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
#define DEFINE_ADJUST_CAMERA(name)
Moves camera yaw by 512 while L/R is held; two identical functions exist.
Definition battle.h:67