Alchemy
Loading...
Searching...
No Matches

altin_peak.c

Go to the documentation of this file.
1/// @file
2/// Altin Mine, the eleven rooms under Altin where the hydros statues flood the
3/// village. The party rides rolling logs, freezes puddles into pillars with
4/// Frost, fights the water beasts, lowers the water three times and finds the
5/// ancient ruins at the bottom.
6
7#include "script.h"
8#include "version.h"
9#include "macros.h"
10#include "game_state.h"
11#include "scene_ids.h"
12#include "unit/import.h"
14#include "unit/object/object.h"
16#include "unit/field/field.h"
18#include "battle.h"
19#include "keystate.h"
20#include "debug.h"
21#include "field.h"
22#include "game.h"
23#include "graphics.h"
24#include "menu.h"
25#include "minigame.h"
26#include "sound.h"
27#include "system.h"
28#include "global_cells.h"
29#include "types.h"
30#include "animspr.h"
31#include "field_event.h"
32#include "io_reg.h"
33#include "text/msg_ids.h"
34#include "field_service.h"
35#include "call.h"
36#include "field_effect.h"
37#include "iwram_call.h"
38#include "dma.h"
39
40#include "types.h"
41
42#include "facing_object.h"
43#include "field_event.h"
44#include "field_scene.h"
45#include "djinn_ids.h"
46
48#include "ability_ids.h"
49#include "flags.h"
50#include "item_ids.h"
51#include "objcmd.h"
52#include "irq.h"
53#include "fixed_math.h"
54#include "field_runtime.h"
55#include "map_scroll.h"
56#include "songs.h"
57
58// Place flags: Scene_ResetFlagsOnEnter clears 0x300 to 0x3ff when the party
59// enters another place group, and other places use the numbers for their own.
60
61// A room's floor switch has been flipped from its first position.
62#define FLAG_ALTIN_PEAK_ROOM_3_SWITCH 0x323
63#define FLAG_ALTIN_PEAK_ROOM_5_SWITCH 0x325
64#define FLAG_ALTIN_PEAK_ROOM_6_SWITCH 0x326
65#define FLAG_ALTIN_PEAK_ROOM_7_SWITCH 0x327
66
67static void AltinPeak_RunBoulderChase(s32 boulderDelay);
68static void AltinPeak_RestoreRoom1(void);
69static void AltinPeak_RestoreRoom3(void);
70static void AltinPeak_RestoreRoom4(void);
71static void AltinPeak_RestoreRoom5(void);
72static void AltinPeak_RestoreRoom6(void);
73static void AltinPeak_RestoreRoom7(void);
74static void AltinPeak_RestoreRoom9(void);
75static void AltinPeak_RestoreRoom10(void);
76static void AltinPeak_RestoreRoom11(void);
77static void AltinPeak_StartSpitting(s32 x, s32 y, s32 z, s32 facing);
78static void AltinPeak_SpawnDebris(void);
79static void AltinPeak_SparkleIce(union FieldObject *object);
80static void AltinPeak_BeastFreezesWidePuddle(void);
81static void AltinPeak_AwardFrostJewelAndDrain(void);
82static void AltinPeak_DrainAfterSecondBeast(void);
83static void AltinPeak_DrainAfterThirdBeast(void);
84static void AltinPeak_CelebrateHydrosVictory(void);
86static void AltinPeak_MarkActorTerrainCell(s32 actorId);
87static void AltinPeak_RollLog(s32 id, s32 heading);
88static void AltinPeak_StartPaletteAnim(void);
89
90#define SCENE_MINE_ROOM(n) ((s32)&SceneId_AltinPeak##n)
91
92/// Each room's water beast fight returns the party to this entrance.
94
95/// The rooms' actors, from their placement tables. Rooms 3, 5, 6 and 7 place
96/// the log the party rides first.
97enum { ACTOR_LOG = 8 };
98
99/// Room 1: a puddle that appears with the first drain, a wide puddle and the
100/// water beast.
101enum {
105};
106
108
110
112
113enum {
119};
120
122
123/// Room 9: the boulder that falls and its shadow, the rock that topples as it
124/// comes down, and the actor Force is cast on.
125enum {
130};
131
132/// Room 10: the guardian statue and its shadow.
134
136
137/// The rooms' puzzles, kept while the party stays in the mine.
138enum {
139 /// Frost has frozen the room's first puddle.
141 /// Frost has frozen room 1's wide puddle or room 7's second.
143 /// Frost has frozen room 7's third puddle.
145 /// Garet has come out to look at room 9's falling-rock sign.
147};
148
149/// A chest searched while facing the given way.
150#define SEARCH_CHEST_FACING(facing) \
151 (SEARCH(SEARCH_CHEST) | EVENT_TOUCH_FACING | (facing))
152
153/// The leader's jump animations.
155
156/// The sprites the scene makes objects from: the water beast's spray (as in
157/// Altin) and room 9's boulder, whose pieces fly in the crash.
158enum { SPRITE_BOULDER = 200, SPRITE_SPRAY = 222 };
159
160// The spray's direction (0 east, 0x8000 west) and origin, and the water's
161// flicker timer.
165
166/// Talking to the Djinni in room 7 makes it hop and starts the battle for
167/// Djinni 23.
168static void AltinPeak_TalkToDjinni(void) {
170}
171
172// Shared source, included where its bytes sit in the ROM.
173#include "common/object_facing.h"
174
175// Update callback of room 9's boulder shadow: it stays under the boulder, on
176// the ground 12 pixels down, while the boulder bounces.
177// UB: update hooks return void. Plain void removes the native zero result
178// and changes its return sequence (three instructions in tbs-en).
179#ifdef UBFIX
180static void AltinPeak_ShadowFollowBoulder(union FieldObject *object) {
181#else
183#endif
184 struct FieldActor *follower = (struct FieldActor *)object;
186
187 follower->x.fixed = actor->x.fixed;
188 follower->y.fixed = -PIXELS(12);
189 follower->z.fixed = actor->z.fixed;
190#ifndef UBFIX
191 return 0;
192#endif
193}
194
195/// Script callback for a piece of flying rock debris: it moves by its
196/// velocity, grows by its z velocity and falls under its gravity.
197static s32 AltinPeak_FlyDebris(struct ScriptInterpreter *interpreter) {
198 struct FieldActor *actor = (struct FieldActor *)interpreter;
199 s32 rise;
200 s32 growth;
201
202 actor->x.fixed += actor->velocityX;
203 rise = actor->velocityY;
204 actor->y.fixed += rise;
205 growth = actor->velocityZ;
206 actor->scaleX += growth;
207 actor->scaleY += growth;
208 actor->velocityY = rise - actor->gravity;
209 return 0;
210}
211
213 s16 scene = gGameState.scene;
214
215 if (scene == SCENE_MINE_ROOM(1)) {
217 }
218 if (scene == SCENE_MINE_ROOM(2)) {
220 }
221 if (scene == SCENE_MINE_ROOM(3)) {
223 }
224 if (scene == SCENE_MINE_ROOM(4)) {
226 }
227 if (scene == SCENE_MINE_ROOM(5)) {
229 }
230 if (scene == SCENE_MINE_ROOM(6)) {
232 }
233 if (scene == SCENE_MINE_ROOM(7)) {
235 }
236 if (scene == SCENE_MINE_ROOM(8)) {
238 }
239 if (scene == SCENE_MINE_ROOM(9)) {
241 }
242 if (scene == SCENE_MINE_ROOM(10)) {
244 }
245 if (scene == SCENE_MINE_ROOM(11)) {
247 }
249}
250
251/// Rooms 9 and 10 have regions.
252const struct SceneRegion *Scene_GetRegions(void) {
253 s16 scene = gGameState.scene;
254
255 if (scene == SCENE_MINE_ROOM(9)) {
256 return gAltinPeak_Regions9;
257 }
258 if (scene == SCENE_MINE_ROOM(10)) {
260 }
261 return 0;
262}
263
264/// All the rooms share one exit table.
265const u32 *Scene_GetExits(void) { return gAltinPeak_Exits; }
266
268 s16 scene = gGameState.scene;
269
270 if (scene == SCENE_MINE_ROOM(1)) {
272 }
273 if (scene == SCENE_MINE_ROOM(3)) {
275 }
276 if (scene == SCENE_MINE_ROOM(5)) {
278 }
279 if (scene == SCENE_MINE_ROOM(6)) {
281 }
282 if (scene == SCENE_MINE_ROOM(7)) {
284 }
285 if (scene == SCENE_MINE_ROOM(8)) {
287 }
288 if (scene == SCENE_MINE_ROOM(9)) {
290 }
291 if (scene == SCENE_MINE_ROOM(10)) {
293 }
294 if (scene == SCENE_MINE_ROOM(11)) {
296 }
298}
299
300/// Talking to a log: the party leader jumps onto it, and once the leader has
301/// landed on top the log rolls away with the leader riding it.
302static void AltinPeak_RideLog(s32 log) {
303 struct FieldActor *logActor;
304 struct FieldActor *leader;
305
307 logActor = Object_GetById(ACTOR_LOG);
314 // Leap by the height between leader and log, in quarter pixels, plus 4.
315 leader->velocityY =
316 ((ABS(logActor->y.fixed - leader->y.fixed) >> 14) << 14) + PIXELS(4);
318 Engine_ObjectSetPosition(leader, logActor->x.fixed, logActor->y.fixed,
319 logActor->z.fixed);
320 Engine_TaskWait(10);
321 leader->sprite->image.priority = 3;
323
324 // Wait until the leader has come down onto the log.
325 for (;;) {
326 if (!((logActor->y.fixed >> 14) < (leader->y.fixed >> 14)))
327 break;
329 }
332 AltinPeak_RollLog(log, 0);
333 Engine_TaskWait(20);
335}
336
337/// Talking to (or reading the mind of) a room's water beast starts its
338/// battle; afterwards the party returns to the room's battle entrance.
339static void AltinPeak_FightRoom1Beast(void) {
343}
344
345static void AltinPeak_FightRoom3Beast(void) {
349}
350
351static void AltinPeak_FightRoom5Beast(void) {
355}
356
357/// Move on room 7's block: the cell it left becomes free again and the cell
358/// it now stands on (column 24 or 25 of row 26) takes the blocking
359/// attributes kept at (0, 0).
360static void AltinPeak_SettleRoom7Block(void) {
362
363 if (block != 0) {
364 s32 column;
365
366 Map_CopyCellAttributes(24, 27, 2, 1, 24, 26);
367 column = block->x.fixed >> 20;
368 if (column == 25) {
369 Map_CopyCellAttributes(0, 0, 1, 1, column, 26);
370 } else {
371 Map_CopyCellAttributes(0, 0, 1, 1, 24, 26);
372 }
374 block->motionFlags = 0;
377 }
378}
379
380/// Frost on a puddle freezes it into an ice pillar the party can stand on:
381/// the puddle's cell takes the pillar's attributes, kept elsewhere on the
382/// map, and the pillar is drawn 32 pixels lower, under the party. Each
383/// room's puddle has its own copy, setting its own scene flag.
385 struct FieldActor *puddle;
386
388 Map_CopyCellAttributes(7, 13, 1, 1, 9, 13);
389 if (puddle != 0) {
391 puddle->y.fixed -= PIXELS(32);
393 }
395}
396
397/// Frost on room 1's wide puddle, three cells across: the cells take the
398/// ice's attributes and the ice is left to fall to the ground.
400 struct FieldActor *puddle;
401
403 Map_CopyCellAttributes(29, 1, 3, 1, 17, 13);
404 if (puddle != 0) {
405 puddle->motionFlags = ACTOR_FALLS;
406 }
408}
409
410/// Frost on room 7's first puddle.
412 struct FieldActor *puddle;
413
415 Map_CopyCellAttributes(0, 0, 1, 1, 26, 26);
416 if (puddle != 0) {
418 puddle->y.fixed -= PIXELS(32);
420 }
422}
423
424/// Frost on room 5's puddle.
426 struct FieldActor *puddle;
427
429 Map_CopyCellAttributes(23, 13, 1, 1, 25, 13);
430 if (puddle != 0) {
432 puddle->y.fixed -= PIXELS(32);
434 }
436}
437
438/// Frost on room 6's puddle.
440 struct FieldActor *puddle;
441
443 Map_CopyCellAttributes(45, 41, 1, 1, 43, 41);
444 if (puddle != 0) {
446 puddle->y.fixed -= PIXELS(32);
448 }
450}
451
452/// Frost on room 7's second puddle.
454 struct FieldActor *puddle;
455
457 Map_CopyCellAttributes(1, 0, 1, 1, 17, 10);
458 if (puddle != 0) {
460 puddle->y.fixed -= PIXELS(32);
462 }
464}
465
466/// Frost on room 7's third puddle.
468 struct FieldActor *puddle;
469
471 Map_CopyCellAttributes(1, 0, 1, 1, 26, 15);
472 if (puddle != 0) {
474 puddle->y.fixed -= PIXELS(32);
476 }
478}
479
480/// Interrupt handler while the water layer vanishes: each time, background 1
481/// (the water) stays on only when a random percentage reaches the timer, so
482/// as the timer climbs to 100 the water flickers away.
483static void Water_FlickerOut(void) {
484 volatile u16 *reg = &REG_DISPCNT;
485 s16 v = *reg & 0xfdff;
486
487 if ((u32)(Engine_RandomNext() * 100) >> 16 >= gAltinPeak_FlickerTimer) {
488 s32 k = 0x200;
489
490 v |= k;
491 }
492 {
493 u32 t = (u16)v;
494
495 *reg = t;
496 }
497}
498
499/// The first drain, after the Frost Jewel is found: the screen shakes, the
500/// water layer sinks 24 pixels, one step every 4 frames (a puddle growing
501/// from a tenth of its size partway down), then flickers away over 100
502/// frames. The way on opens and the drain is remembered.
503static void AltinPeak_DrainFirstWater(void) {
504 s32 step;
505 struct FieldActor *puddle;
506 u8 *mapWork;
507 u8 *waterLayer;
508 s32 timer;
509
510 mapWork = gMapWork[0];
514 // Sink the water layer one pixel every 4 frames, 24 in all.
515 waterLayer = mapWork + 356;
516 for (step = 0; step <= 23; step++) {
517 *(s32 *)(waterLayer + 12) -= PIXELS(1);
519 if (step == 8) {
521 puddle->scaleX = Q16_ONE / 10;
523 puddle->scaleY = Q16_ONE / 10;
526 }
527 }
528 // Flicker the water away while the timer counts to 100.
531 do {
535 } while ((u32)(timer << 16) <= 0x640000);
537 Runtime_SetIrqHandler(1, 0, 0);
539 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
541 Map_CopyCellAttributes(0, 0, 1, 2, 3, 14);
543}
544
545/// The second drain: the same sinking and flicker over the cells the water
546/// leaves behind, which then take their dry form.
547static void AltinPeak_DrainSecondWater(void) {
548 s32 step;
549 u8 *mapWork;
550 u8 *waterLayer;
551 s32 timer;
552
553 mapWork = gMapWork[0];
554 Map_CopyCells(93, 41, 16, 4, 77, 28);
558 // Sink the water layer one pixel every 4 frames, 24 in all.
559 waterLayer = mapWork + 356;
560 for (step = 23; step >= 0; step--) {
561 *(s32 *)(waterLayer + 12) -= PIXELS(1);
563 }
564 // Flicker the water away while the timer counts to 100.
567 do {
571 } while ((u32)(timer << 16) <= 0x640000);
573 Runtime_SetIrqHandler(1, 0, 0);
575 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
577 Map_CopyCells(77, 41, 16, 4, 77, 28);
579}
580
581/// The third drain, likewise.
582static void AltinPeak_DrainThirdWater(void) {
583 s32 step;
584 u8 *mapWork;
585 u8 *waterLayer;
586 s32 timer;
587
588 mapWork = gMapWork[0];
589 Map_CopyCellsTo(113, 31, 103, 17, 1, 1);
590 Map_CopyCellsTo(111, 32, 104, 18, 3, 2);
591 Map_CopyCellsTo(64, 32, 103, 18, 1, 2);
595 // Sink the water layer one pixel every 4 frames, 24 in all.
596 waterLayer = mapWork + 356;
597 for (step = 23; step >= 0; step--) {
598 *(s32 *)(waterLayer + 12) -= PIXELS(1);
600 }
601 // Flicker the water away while the timer counts to 100.
604 do {
608 } while ((u32)(timer << 16) <= 0x640000);
610 Runtime_SetIrqHandler(1, 0, 0);
612 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
614 Map_CopyCellsTo(103, 14, 103, 17, 4, 3);
616}
617
618/// Flips room 3's switch to its other position, redrawing it and changing the
619/// cell its position opens or closes.
622 Map_CopyCellAttributes(2, 0, 1, 1, 24, 80);
623 Map_CopyCellsTo(2, 1, 24, 11, 1, 2);
625 } else {
626 Map_CopyCellAttributes(0, 0, 1, 1, 24, 80);
627 Map_CopyCellsTo(0, 1, 24, 11, 1, 2);
629 }
630}
631
632/// Searching room 3's switch flips it. "You flipped the switch."
633static void AltinPeak_FlipRoom3Switch(void) {
635 Engine_MessageShowCentered(MsgFieldFlippedSwitch, 1);
638 Engine_TaskWait(20);
641}
642
643/// Flips room 5's switch, the same way.
646 Map_CopyCellAttributes(12, 72, 1, 1, 11, 73);
647 Map_CopyCellsTo(48, 32, 11, 4, 1, 2);
649 } else {
650 Map_CopyCellAttributes(10, 72, 1, 1, 11, 73);
651 Map_CopyCellsTo(49, 32, 11, 4, 1, 2);
653 }
654}
655
656/// Searching room 5's switch flips it.
657static void AltinPeak_FlipRoom5Switch(void) {
659 Engine_MessageShowCentered(MsgFieldFlippedSwitch, 1);
662 Engine_TaskWait(20);
665}
666
667/// Searching room 6's switch flips it.
668static void AltinPeak_FlipRoom6Switch(void) {
670 Engine_MessageShowCentered(MsgFieldFlippedSwitch, 1);
673 Map_CopyCellAttributes(15, 93, 1, 1, 16, 92);
674 Map_CopyCellsTo(47, 29, 16, 28, 1, 2);
676 } else {
677 Map_CopyCellAttributes(17, 93, 1, 1, 16, 92);
678 Map_CopyCellsTo(46, 29, 16, 28, 1, 2);
680 }
681 Engine_TaskWait(20);
684}
685
686/// Searching room 7's switch flips it.
687static void AltinPeak_FlipRoom7Switch(void) {
689 Engine_MessageShowCentered(MsgFieldFlippedSwitch, 1);
692 Map_CopyCellAttributes(28, 82, 1, 1, 29, 81);
693 Map_CopyCellsTo(47, 28, 29, 17, 1, 2);
695 } else {
696 Map_CopyCellAttributes(30, 82, 1, 1, 29, 81);
697 Map_CopyCellsTo(46, 28, 29, 17, 1, 2);
699 }
700 Engine_TaskWait(20);
703}
704
705/// Stepping onto room 7's block: it is drawn under the party leader.
709}
710
711/// Stepping off room 7's block: it sorts against the leader again.
714}
715
716/// Walking east into room 7's block pushes it one cell along with a scrape;
717/// the leader follows it and its cells are settled as after Move.
718static void AltinPeak_PushRoom7Block(void) {
720 Map_CopyCellAttributes(24, 27, 2, 1, 24, 26);
732}
733
734/// Force on room 9's wall: it rumbles, the rock on it rocks one way and back,
735/// then topples with a crash, and the rockfall follows.
736static void AltinPeak_ForceRockOver(void) {
737 struct FieldActor *actor;
738 struct AnimationObject *sprite;
739 s32 originX;
740 s32 originHeight;
741 s32 cosine;
742 s32 sine;
743 u16 rotationStep;
744
746 sprite = actor->sprite;
747 originX = actor->x.fixed;
748 originHeight = actor->y.fixed;
749 Event_Begin();
752 Event_Wait(10);
754 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
755 Event_Wait(20);
756
757 // Rock the obstacle to each side before the accelerating fall.
758 rotationStep = 0;
759 while (1) {
760 rotationStep += 8;
761 sprite->rotation += rotationStep;
762 cosine = Math_Cos(sprite->rotation + 0x4000);
763 actor->x.fixed = (cosine << 4) + originX;
764 if (sprite->rotation > 0x8fff) {
765 break;
766 }
767 Task_Wait(1);
768 }
769 rotationStep = 0;
770 while (1) {
771 rotationStep += 8;
772 sprite->rotation -= rotationStep;
773 cosine = Math_Cos(sprite->rotation + 0x4000);
774 actor->x.fixed = (cosine << 4) + originX;
775 if (sprite->rotation <= 0x7000) {
776 break;
777 }
778 Task_Wait(1);
779 }
780 rotationStep = 8;
781 while (1) {
782 rotationStep += rotationStep >> 3;
783 sprite->rotation += rotationStep;
784 cosine = Math_Cos(sprite->rotation + 0x4000);
785 sine = Math_Sin(sprite->rotation + 0x8000);
786 actor->x.fixed = (cosine << 4) + originX;
787 if (sprite->rotation > 0x8000) {
788 actor->y.fixed = originHeight - (sine << 3);
789 }
790 if (sprite->rotation + rotationStep > 0xbfff) {
791 break;
792 }
793 Task_Wait(1);
794 }
795 Task_Wait(1);
796 sprite->rotation = 0xc000;
799 Event_Wait(20);
801 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
803 Event_End();
804}
805
806/// Room 9's rockfall. The party leader steps back and looks up as the slope
807/// rumbles; the rock lies toppled and a boulder drops onto the path. The
808/// leader flees down the winding path, and after boulderDelay frames the
809/// boulder rolls after; it bounces to a stop at the bottom and crashes into
810/// the wall, throwing up rock debris and leaving rubble. Garet, if he came out
811/// at the sign, rejoins the leader. Remembered by
812/// FLAG_ALTIN_PEAK_BOULDER_FALLEN.
813static void AltinPeak_RunBoulderChase(s32 boulderDelay) {
814 struct FieldActor *leader;
815 struct FieldActor *boulder;
816 struct FieldActor *shadow;
817 struct FieldActor *rock;
818 struct FieldActor *actor;
819
826 Camera_SetSpeed(PIXELS(1), PIXELS(1) / 8);
827 Camera_MoveTo(PIXELS(784), -1, PIXELS(116), 1);
837 // Stage the rolling object and its follower for the escape route.
838 shadow->scaleX = 6 * Q16_ONE / 5;
839 shadow->scaleY = 6 * Q16_ONE / 5;
841#ifdef UBFIX
843#else
844 shadow->update = (void (*)(union FieldObject *))AltinPeak_ShadowFollowBoulder;
845#endif
847 boulder->bounce = PIXELS(1) / 2;
848 boulder->x.fixed = PIXELS(786);
849 boulder->y.fixed = PIXELS(32);
850 boulder->z.fixed = PIXELS(90);
851 boulder->scaleX = 2 * Q16_ONE;
852 boulder->scaleY = 2 * Q16_ONE;
857 rock->x.fixed += PIXELS(14);
858 rock->y.fixed += -PIXELS(8);
859 rock->sprite->rotation = 0xc000;
868 // Send the leader first, then release the rolling object after its delay.
870 leader->timer = 0;
876 }
877 Camera_SetSpeed(PIXELS(5) / 4, PIXELS(5) / 32);
878 Camera_MoveTo(PIXELS(786), -1, PIXELS(556), 1);
879 Engine_EventWait(boulderDelay);
881 Actor_SetSpeed(ACTOR_FALLING_BOULDER, PIXELS(317) / 200, PIXELS(275) / 347);
882 boulder->timer = 0;
884 do {
886 } while (leader->timer == 0);
888 do {
890 } while (boulder->timer == 0);
894 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
895 shadow->x.fixed = PIXELS(786);
896 shadow->update = NULL;
897 shadow->z.fixed = PIXELS(618);
898 shadow->y.fixed = -PIXELS(64);
899 // Let the rolling object bounce before the final collapse.
901 boulder->bounce = PIXELS(1) / 10;
902 boulder->gravity = PIXELS(1) / 5;
903 boulder->velocityY = PIXELS(4);
909 Map_CopyCellsTo(25, 36, 43, 36, 11, 9);
910 Map_CopyCellAttributes(25, 35, 10, 5, 43, 35);
913 // Hide the rolling actors and animate the falling debris.
919 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
920 // Return Garet to the party if the warning sign brought him into the scene.
921 Engine_EventWait(120);
923 Actor_SetSpeed(GARET, PIXELS(1), PIXELS(1) / 2);
924 Actor_WalkTo(GARET, 824, 558);
925 }
931 }
935 Camera_MoveTo(PIXELS(788), -PIXELS(64), PIXELS(610), 1);
938 Engine_EventWait(240);
940 Camera_SetSpeed(PIXELS(4), PIXELS(1) / 2);
941 Camera_MoveTo(PIXELS(854), 0, PIXELS(584), 1);
943 Actor_WalkToAndWait(GARET, 840, 552);
944 Actor_WalkToAndWait(GARET, 854, 562);
947 if (actor != NULL) {
948 Actor_SetDestination(GARET, actor->x.part.pixel, actor->z.part.pixel);
949 }
952 }
955}
956
957/// Searching room 9's sign, which can bring the rockfall. "Watch for falling
958/// rocks! Do not strike the wall!" Before the rockfall, while the party has no
959/// Orb of Force, Garet steps out, grumbles at the dead end and strikes the
960/// wall; the ground shakes, he tells the leader to run and runs down the path,
961/// and the rockfall follows.
963 struct FieldActor *actor;
964 s32 message;
965
967 message = MsgAltinWatchFallingRocks;
968 Engine_MessageShowCentered(message, 1);
971 // Bring Garet out to inspect the warning and demonstrate the danger.
978 if (actor != 0) {
979 Actor_SetPosition(GARET, actor->x.fixed, actor->z.fixed);
980 }
981 Actor_SetSpeed(GARET, PIXELS(4) / 5, PIXELS(2) / 5);
982 Actor_WalkToAndWait(GARET, 800, 140);
984 Engine_EventSetMessage(message + 1);
988 Engine_ActorJump(GARET, 6, 0);
989 Actor_SetSpeed(GARET, PIXELS(8) / 5, PIXELS(4) / 5);
991 Actor_WalkToAndWait(GARET, 792, 110);
997 Actor_WalkToAndWait(GARET, 792, 120);
999 {
1000 struct FieldActor *actor = Actor_Get(GARET);
1001
1003 }
1004 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1005 Engine_EventWait(80);
1008 Engine_EventWait(40);
1012 Actor_FaceDirection(GARET, 0, 20);
1016 Actor_FaceDirection(GARET, 0, 40);
1023 Actor_SetSpeed(GARET, PIXELS(5) / 2, PIXELS(5) / 4);
1025 Actor_MoveToAndWait(GARET, 796, 138);
1027 Actor_MoveToAndWait(GARET, 804, 140);
1029 Actor_MoveToAndWait(GARET, 804, 166);
1030 Actor_MoveToAndWait(GARET, 764, 166);
1031 Actor_MoveToAndWait(GARET, 764, 198);
1032 Actor_MoveToAndWait(GARET, 786, 198);
1034 Actor_MoveToAndWait(GARET, 786, 246);
1036 Actor_SetPosition(GARET, 0, 0);
1037 Engine_EventWait(40);
1039 }
1041}
1042
1043/// Room 1 has its own events once the first drain has lowered its water.
1044const struct SceneEvent *Scene_GetEvents(void) {
1045 const struct SceneEvent *table;
1046
1047 if (gGameState.scene == SCENE_MINE_ROOM(1)) {
1050 } else {
1051 table = gAltinPeak_Events1;
1052 }
1053 } else if (gGameState.scene == SCENE_MINE_ROOM(2)) {
1054 table = gAltinPeak_Events2;
1055 } else if (gGameState.scene == SCENE_MINE_ROOM(3)) {
1056 table = gAltinPeak_Events3;
1057 } else if (gGameState.scene == SCENE_MINE_ROOM(4)) {
1058 table = gAltinPeak_Events4;
1059 } else if (gGameState.scene == SCENE_MINE_ROOM(5)) {
1060 table = gAltinPeak_Events5;
1061 } else if (gGameState.scene == SCENE_MINE_ROOM(6)) {
1062 table = gAltinPeak_Events6;
1063 } else if (gGameState.scene == SCENE_MINE_ROOM(7)) {
1064 table = gAltinPeak_Events7;
1065 } else if (gGameState.scene == SCENE_MINE_ROOM(8)) {
1066 table = gAltinPeak_Events8;
1067 } else if (gGameState.scene == SCENE_MINE_ROOM(9)) {
1068 table = gAltinPeak_Events9;
1069 } else if (gGameState.scene == SCENE_MINE_ROOM(10)) {
1070 table = gAltinPeak_Events10;
1071 } else if (gGameState.scene == SCENE_MINE_ROOM(11)) {
1072 table = gAltinPeak_Events11;
1073 } else {
1074 table = gAltinPeak_EventsOther;
1075 }
1076 return table;
1077}
1078
1079/// Update callback of the hopping water beast: once a second it leaps up and
1080/// lands with a splash (SE_229) that shakes the screen briefly.
1081static void AltinPeak_UpdateBeastHops(union FieldObject *object) {
1082 struct FieldActor *beast = &object->actor;
1083 s16 *shakeDelay = (s16 *)&beast->work;
1084
1085 // The route owns timer (hop phase), work (shake delay) and the effect's
1086 // countdown (landing-sound latch) until it removes this hook.
1087 if (*shakeDelay != 0) {
1088 if (--*shakeDelay == 1)
1089 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1090 }
1091 if (beast->velocityY == 0) {
1092 Object_SetMode(&object->actor, 1);
1093 beast->y.fixed -= PIXELS(3) / 2;
1094 if (beast->y.fixed < beast->terrainHeight) {
1095 if (object->effect.countdown != 0) {
1097 object->effect.countdown = 0;
1098 beast->work = 4;
1099 Map_SetShake(PIXELS(1), 0, Q16_ONE);
1100 }
1101 beast->y.fixed = beast->terrainHeight;
1102 }
1103 beast->paused = 1;
1104 } else {
1105 beast->paused = 0;
1106 }
1107 if (beast->timer == 0) {
1109 object->effect.countdown = 1;
1110 Object_SetMode(&object->actor, 2);
1111 beast->velocityY = PIXELS(3);
1112 }
1113 if (++beast->timer == 60)
1114 beast->timer = 0;
1115}
1116
1117/// The beast lands with a splash, shaking the screen for holdFrames.
1118static __inline__ void AltinPeak_PlayLandingShake(s32 amplitude,
1119 s32 holdFrames) {
1121 Map_SetShake(amplitude, 0, Q16_ONE);
1122 Engine_EventWait(holdFrames);
1123 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1124}
1125
1126/// Stepping near room 1's water beast the first time: the camera finds it, it
1127/// cries out and hops away around the room, freezes the wide puddle with
1128/// Frost and hops across it, then stops to watch the party leader.
1130 union FieldObject *beast;
1131 struct FieldActor *leader;
1132 struct FieldActor *actor;
1133 s32 jumpSpeed;
1134
1137 Engine_CameraSetSpeed(PIXELS(12) / 5, PIXELS(3) / 10);
1138 Camera_MoveTo(PIXELS(298), -1, PIXELS(337), 1);
1142 Engine_EventWait(40);
1143 Engine_CameraSetSpeed(PIXELS(4) / 5, PIXELS(1) / 10);
1144 Engine_CameraMoveTo(PIXELS(295), PIXELS(32), PIXELS(212), 1);
1145 // Run the timed hopping callback while the beast moves along its route.
1146 beast->effect.countdown = 0;
1147 beast->actor.timer = 0;
1148 beast->actor.work = 0;
1149 beast->actor.gravity = PIXELS(2) / 5;
1154 beast->actor.update = 0;
1155 beast->actor.paused = 0;
1156 Engine_EventWait(16);
1159 Engine_EventWait(40);
1162 // Demonstrate Frost between the hopping sections.
1164 Engine_EventWait(40);
1167 Camera_MoveTo(PIXELS(334), -1, PIXELS(244), 1);
1168 beast->effect.countdown = 0;
1169 beast->actor.timer = 0;
1170 beast->actor.work = 0;
1175 beast->actor.update = 0;
1176 Engine_EventWait(16);
1179 Engine_EventWait(20);
1184 actor->velocityY = PIXELS(4);
1187 Engine_EventWait(10);
1191 Engine_EventWait(40);
1194 Camera_MoveTo(PIXELS(304), -1, PIXELS(215), 1);
1195 beast->effect.countdown = 0;
1196 beast->actor.timer = 0;
1197 beast->actor.work = 0;
1200 beast->actor.update = 0;
1202 Engine_EventWait(16);
1204 Engine_EventWait(40);
1207 // Open the route for the final two beast jumps.
1208 Map_CopyCellAttributes(3, 0, 1, 1, 17, 13);
1209 Map_CopyCellAttributes(3, 0, 1, 1, 18, 13);
1210 Map_CopyCellAttributes(3, 0, 1, 1, 19, 13);
1215 jumpSpeed = PIXELS(5);
1217 actor->velocityY = jumpSpeed;
1224 Engine_EventWait(40);
1227 actor->velocityY = jumpSpeed;
1232 Engine_EventWait(40);
1235 20);
1238 Engine_EventWait(40);
1239 Map_CopyCellAttributes(4, 0, 1, 1, 17, 13);
1240 Map_CopyCellAttributes(2, 0, 1, 1, 18, 13);
1241 Map_CopyCellAttributes(4, 0, 1, 1, 19, 13);
1243 Engine_CameraSetSpeed(PIXELS(24) / 5, PIXELS(3) / 5);
1244 Engine_CameraMoveTo(leader->x.fixed, leader->y.fixed, leader->z.fixed, 1);
1251}
1252
1253/// Stepping near the beast again: it hops back over the ice and settles down,
1254/// spitting water.
1256 union FieldObject *actor;
1257 struct FieldActor *movingActor;
1258 u32 waitedFrames;
1259
1263 Camera_SetSpeed(PIXELS(12) / 5, PIXELS(3) / 10);
1264 Camera_MoveTo(PIXELS(279), PIXELS(64), PIXELS(216), 1);
1268 Engine_EventWait(40);
1272 Camera_SetSpeed(PIXELS(4) / 5, PIXELS(1) / 10);
1273 Camera_MoveTo(PIXELS(128), PIXELS(64), PIXELS(202), 1);
1274 actor->effect.countdown = 0;
1275 actor->actor.timer = 0;
1276 actor->actor.work = 0;
1277 actor->actor.gravity = PIXELS(2) / 5;
1282 actor->actor.update = NULL;
1283 actor->actor.paused = 0;
1284 Engine_EventWait(10);
1287 Engine_EventWait(20);
1291 movingActor = Object_GetById(ACTOR_ROOM1_BEAST);
1292 Engine_ActorSetSpriteFlags(movingActor, 0);
1294 movingActor = Object_GetById(ACTOR_ROOM1_BEAST);
1295 movingActor->velocityY = PIXELS(4);
1299 movingActor = Object_GetById(ACTOR_ROOM1_BEAST);
1300 Engine_ActorSetSpriteFlags(movingActor, 1);
1301 Engine_EventWait(10);
1303 Engine_EventWait(40);
1307 actor->effect.countdown = 0;
1308 actor->actor.timer = 0;
1309 actor->actor.work = 0;
1313 actor->actor.update = NULL;
1314 actor->actor.paused = 0;
1316 Engine_EventWait(16);
1318 Engine_EventWait(40);
1322 Engine_EventWait(80);
1324 // End the route with a spray gust and a short skippable wait.
1325 AltinPeak_StartSpitting(PIXELS(130), 0, PIXELS(168), 0);
1326 Engine_EventWait(60);
1327 for (waitedFrames = 0; waitedFrames < 60 && gKeysPressed == 0;
1328 waitedFrames++) {
1330 }
1332 Camera_SetSpeed(PIXELS(24) / 5, PIXELS(3) / 5);
1333 Engine_CameraMoveTo(actor->actor.x.fixed, actor->actor.y.fixed,
1334 actor->actor.z.fixed, 1);
1338}
1339
1340/// Sets up the room being entered: puzzles already solved and the water
1341/// levels already lowered. Returns 0.
1344 if (gGameState.scene == SCENE_MINE_ROOM(1)) {
1346 } else if (gGameState.scene == SCENE_MINE_ROOM(3)) {
1348 } else if (gGameState.scene == SCENE_MINE_ROOM(4)) {
1350 } else if (gGameState.scene == SCENE_MINE_ROOM(5)) {
1352 } else if (gGameState.scene == SCENE_MINE_ROOM(6)) {
1354 } else if (gGameState.scene == SCENE_MINE_ROOM(7)) {
1356 } else if (gGameState.scene == SCENE_MINE_ROOM(9)) {
1358 } else if (gGameState.scene == SCENE_MINE_ROOM(10)) {
1360 } else if (gGameState.scene == SCENE_MINE_ROOM(11)) {
1362 }
1363 return 0;
1364}
1365
1366/// Room 1: after its beast's battle the Frost Jewel is found and the water
1367/// drains; the beast stays where its routes left it while the water is up,
1368/// and the frozen puddles are restored once it is down.
1369static void AltinPeak_RestoreRoom1(void) {
1370 s32 opened;
1371 s32 flag;
1372 struct FieldActor *actor;
1373 struct MapScrollWork *map;
1374
1378 }
1379 }
1383 } else {
1385 if (actor != 0) {
1388 }
1389 }
1391 if (actor != 0) {
1394 }
1396 if (opened == 0) {
1399 if (flag != 0) {
1405 actor->y.fixed = PIXELS(32);
1406 Map_CopyCellAttributes(2, 0, 1, 1, 18, 13);
1409 actor->facing = opened;
1411 AltinPeak_StartSpitting(PIXELS(130), 0, PIXELS(168), 0);
1412 return;
1413 }
1415 return;
1416 }
1422 actor->y.fixed = PIXELS(32);
1423 Map_CopyCellAttributes(2, 0, 1, 1, 18, 13);
1428 } else {
1429 map = gMapWork[0];
1431 Map_CopyCellAttributes(0, 0, 1, 2, 3, 14);
1432 map->flags &= 0xfdff;
1436 Map_CopyCellAttributes(7, 13, 1, 1, 9, 13);
1438 actor->y.fixed = 0;
1440 }
1444 Map_CopyCellAttributes(29, 1, 3, 1, 17, 13);
1446 actor->y.fixed = PIXELS(32);
1448 }
1449 }
1450}
1451
1452/// Room 3: after its beast's battle the second drain runs; while the water is
1453/// up the beast spits it; the switch is restored.
1454static void AltinPeak_RestoreRoom3(void) {
1456 ((struct MapScrollWork *)gMapWork[0])->flags &= ~0x200;
1458 } else {
1463 } else {
1464 Map_CopyCellAttributes(38, 24, 1, 2, 37, 24);
1465 Map_CopyCellAttributes(44, 23, 1, 2, 45, 23);
1469 AltinPeak_StartSpitting(PIXELS(238), 0, PIXELS(418), 0x8000);
1470 }
1471 }
1472 }
1474 Map_CopyCellAttributes(0, 0, 1, 1, 24, 80);
1475 Map_CopyCellsTo(0, 1, 24, 11, 1, 2);
1476 } else {
1477 Map_CopyCellAttributes(2, 0, 1, 1, 24, 80);
1478 Map_CopyCellsTo(2, 1, 24, 11, 1, 2);
1479 }
1480}
1481
1482/// Room 4: its water is up until the second drain; entrances 6 and 7 skip
1483/// the arrival event.
1484static void AltinPeak_RestoreRoom4(void) {
1486 ((struct MapScrollWork *)gMapWork[0])->flags &= ~0x200;
1487 } else {
1488 Map_CopyCellAttributes(52, 42, 1, 1, 53, 42);
1489 }
1490 {
1491 // Entrances 6 and 7 do not run the pending arrival event.
1492 if ((u32)(((u16)gGameState.entrance - 6) << 16) <= 0x10000) {
1494 }
1495 }
1496}
1497
1498/// Room 5: after its beast's battle the third drain runs; while the water is
1499/// up the beast spits it; the frozen puddle and the switch are restored.
1500static void AltinPeak_RestoreRoom5(void) {
1501
1503 ((struct MapScrollWork *)gMapWork[0])->flags &= ~0x200;
1505 } else {
1509 }
1510 }
1515 AltinPeak_StartSpitting(PIXELS(748), PIXELS(8), PIXELS(280), 0x8000);
1516 }
1517 }
1521 Map_CopyCellAttributes(23, 13, 1, 1, 25, 13);
1522 {
1523 struct FieldActor *actor = Actor_Get(ACTOR_ROOM5_PUDDLE);
1525 }
1526 }
1528 Map_CopyCellAttributes(10, 72, 1, 1, 11, 73);
1529 Map_CopyCellsTo(49, 32, 11, 4, 1, 2);
1530 } else {
1531 Map_CopyCellAttributes(12, 72, 1, 1, 11, 73);
1532 Map_CopyCellsTo(48, 32, 11, 4, 1, 2);
1533 }
1534}
1535
1536/// Room 6: arriving at entrance 2 the log waits there; the frozen puddle, the
1537/// water level and the switch are restored.
1538static void AltinPeak_RestoreRoom6(void) {
1539 struct FieldActor *pillar;
1540
1541 if (gGameState.entrance == 2) {
1544 }
1545 }
1548 pillar = Actor_Get(ACTOR_ROOM6_PUDDLE);
1550 Map_CopyCellAttributes(45, 41, 1, 1, 43, 41);
1551 {
1553 }
1554 }
1556 ((struct MapScrollWork *)gMapWork[0])->flags &= ~0x200;
1557 }
1559 Map_CopyCellAttributes(17, 93, 1, 1, 16, 92);
1560 Map_CopyCellsTo(46, 29, 16, 28, 1, 2);
1561 } else {
1562 Map_CopyCellAttributes(15, 93, 1, 1, 16, 92);
1563 Map_CopyCellsTo(47, 29, 16, 28, 1, 2);
1564 }
1565}
1566
1567/// Room 7: the block, the three frozen puddles and the switch are restored.
1568static void AltinPeak_RestoreRoom7(void) {
1569 struct FieldActor *actor;
1570
1577 Map_CopyCellAttributes(0, 0, 1, 1, 26, 26);
1578 {
1579 struct FieldActor *actor = Actor_Get(ACTOR_ROOM7_PUDDLE);
1581 }
1582 }
1586 Map_CopyCellAttributes(1, 0, 1, 1, 17, 10);
1587 {
1590 }
1591 }
1595 Map_CopyCellAttributes(1, 0, 1, 1, 26, 15);
1596 {
1599 }
1600 }
1604 Map_CopyCellAttributes(30, 82, 1, 1, 29, 81);
1605 Map_CopyCellsTo(46, 28, 29, 17, 1, 2);
1606 } else {
1607 Map_CopyCellAttributes(28, 82, 1, 1, 29, 81);
1608 Map_CopyCellsTo(47, 28, 29, 17, 1, 2);
1609 }
1610}
1611
1612/// Room 9: the boulder is put away; once the rockfall is over the rock lies
1613/// toppled and the rubble fills the bottom of the path. Arriving at entrance
1614/// 6, the leader starts 88 pixels down.
1615static void AltinPeak_RestoreRoom9(void) {
1616 struct FieldActor *actor;
1617
1622 actor->motionFlags = 0;
1623 actor->scaleX = 9 * Q16_ONE / 10;
1624 actor->scaleY = 3 * Q16_ONE / 5;
1625 actor->sprite->rotation = 0x8000;
1626 Object_GetById(12)->motionFlags = 0;
1627 Object_GetById(12)->y.fixed = -PIXELS(28);
1629 actor->x.fixed += PIXELS(14);
1630 actor->y.fixed += -PIXELS(8);
1631 actor->sprite->rotation = 0xc000;
1632 }
1634 Map_CopyCellsTo(25, 36, 43, 36, 11, 9);
1635 Map_CopyCellAttributes(25, 35, 10, 5, 43, 35);
1637 Engine_TaskWait(1);
1638 }
1639 if (gGameState.entrance == 6 &&
1643 Engine_CameraMoveTo(PIXELS(792), -PIXELS(88), PIXELS(577), 0);
1645 Engine_TaskWait(1);
1647 }
1648}
1649
1650/// Room 10: the guardian statue stands until the Hydros statues are beaten;
1651/// after their battle the party talks it over.
1652static void AltinPeak_RestoreRoom10(void) {
1653 s32 statuesDefeated;
1654 struct FieldActor *leader;
1655 struct FieldActor *actor;
1656 s16 entrance;
1657
1659 if (statuesDefeated != 0) {
1662 } else {
1669 }
1670 entrance = gGameState.entrance;
1671 if (entrance == 1 || entrance == 98) {
1675 leader->y.fixed = PIXELS(16);
1677 }
1678 } else if (entrance == ENTRANCE_AFTER_BATTLE) {
1681 }
1682 }
1683}
1684
1685/// Room 11: arriving at entrance 2 the block stands at its pushed place.
1686static void AltinPeak_RestoreRoom11(void) {
1687 struct FieldActor *actor;
1688
1691 if (gGameState.entrance == 2) {
1693 }
1694}
1695
1696/// Gives a new spray particle its look: standing still, on sprite priority 1
1697/// and at 0.3 scale.
1698static void AltinPeak_InitSpray(struct FieldActor *spray) {
1699 spray->motionFlags = 0;
1700 spray->sprite->image.priority = 1;
1701 ObjectGroup_SetChildValue(spray, 3);
1703 spray->scaleX = 3 * Q16_ONE / 10;
1704 spray->scaleY = 3 * Q16_ONE / 10;
1705}
1706
1707/// Update callback of a spray particle: it grows while drifting away from the
1708/// beast, then curls and flattens when its movement timer runs low. The timer
1709/// can start another curl; the separate lifetime still ends after 20 updates.
1710static void AltinPeak_DriftSpray(union FieldObject *object) {
1711 struct FieldActor *spray = &object->actor;
1712
1713 switch (gAltinPeak_SprayDirection) {
1714 case 0:
1715 spray->x.fixed +=
1716 (spray->timer << 12) +
1717 ((s32)((((u32)(Engine_RandomNext() << 1) >> 16) - 1) << 16) >> 1);
1718 break;
1719 case 0x8000:
1720 spray->x.fixed -=
1721 (spray->timer << 12) +
1722 ((s32)((((u32)(Engine_RandomNext() << 1) >> 16) - 1) << 16) >> 1);
1723 break;
1724 }
1725 if (spray->timer <= 3) {
1726 switch (gAltinPeak_SprayDirection) {
1727 case 0:
1728 spray->x.fixed += PIXELS(1) / 2;
1729 break;
1730 case 0x8000:
1731 spray->x.fixed -= PIXELS(1) / 2;
1732 break;
1733 }
1734 spray->scaleX += Q16_ONE / 10;
1735 spray->scaleY -= Q16_ONE / 20;
1736 } else {
1737 spray->z.fixed += PIXELS(6) / 5;
1738 spray->scaleX += 3 * Q16_ONE / 100;
1739 spray->scaleY += 3 * Q16_ONE / 100;
1740 }
1741 if ((u32)(spray->timer * Engine_RandomNext()) >> 16 == 0)
1742 ObjectGroup_SetChildValue(spray, 7);
1743 if (spray->timer != 0)
1744 spray->timer -= 2;
1745 else
1746 spray->timer = ((u32)(Engine_RandomNext() * 5) >> 16) * 2 + 2;
1747 if (--object->effect.countdown == 0)
1749}
1750
1751/// Scheduler task while a beast spits: every fourth frame a spray particle
1752/// starts from its spout, living 20 frames.
1753static void AltinPeak_SpawnSpray(void) {
1754 union FieldObject *spray;
1755
1756 if ((gFrameCount & 3) != 0)
1757 return;
1758 spray = (union FieldObject *)Engine_ObjectCreate(
1761 if (spray == NULL)
1762 return;
1763 spray->actor.timer = 30;
1764 spray->actor.work = 1;
1765 spray->effect.countdown = 20;
1766 AltinPeak_InitSpray(&spray->actor);
1768 Object_SetMode(&spray->actor, 1);
1769}
1770
1771/// A water beast starts spitting water from (x, y, z) toward facing (east, 0,
1772/// or west, 0x8000), with its sound (SE_170).
1773static void AltinPeak_StartSpitting(s32 x, s32 y, s32 z, s32 facing) {
1776
1779}
1780
1781/// Scheduler task while the boulder crashes: every third frame a piece of rock
1782/// (the boulder's own sprite, small) flies out at random, with a clatter
1783/// (SE_144 or SE_145) every ninth frame.
1784static void AltinPeak_SpawnDebris(void) {
1785 struct FieldActor *debris;
1786 s32 scale;
1787
1788 if (gFrameCount % 3 == 0) {
1790 (((u32)(Engine_RandomNext() * 48) >> 16) << 16) +
1791 PIXELS(765),
1792 -PIXELS(64), PIXELS(608));
1793 if (debris != NULL) {
1794 if (gFrameCount % 9 == 0) {
1795 if ((u32)(Engine_RandomNext() << 1) >> 16 != 0)
1797 else
1799 }
1800 debris->motionFlags = 0;
1801 scale = ((u32)(Engine_RandomNext() << 15) >> 16) + 3 * Q16_ONE / 10;
1802 debris->gravity = PIXELS(2) / 5;
1803 debris->scaleY = scale;
1804 debris->scaleX = scale;
1805 debris->frozen = 1;
1806 Engine_ActorSetSpriteFlags(debris, 0);
1808 debris->sprite->image.priority = 1;
1809 Object_SetMode(debris, 1);
1811 SET_VELOCITY(debris, (((u32)(Engine_RandomNext() * 6) >> 16) - 3) << 16,
1812 PIXELS(8),
1813 ((u32)(Engine_RandomNext() * 0x600) >> 16) - 0x300);
1814 }
1815 }
1816}
1817
1818/// Update callback of the frozen wide puddle: its ice glints every eight
1819/// frames.
1820static void AltinPeak_SparkleIce(union FieldObject *object) {
1821 struct FieldActor *actor = (struct FieldActor *)object;
1822
1823 s32 framePhase = gFrameCount & 7;
1824
1825 if (framePhase == 0) {
1826 ObjectGroup_SetChildValue(actor, 2);
1827 } else if (framePhase == 2) {
1828 ObjectGroup_SetChildValue(actor, 0);
1829 }
1830}
1831
1832/// Room 1's water beast casts Frost on the wide puddle.
1845}
1846
1847/// Back from room 1's beast battle: the beast is gone and the party finds the
1848/// Frost Jewel; the camera pans to the water and the first drain runs.
1850 struct FieldActor *leader;
1851
1859 Engine_EventWait(20);
1863 Camera_SetSpeed(PIXELS(8) / 5, PIXELS(1) / 5);
1864 Camera_MoveTo(PIXELS(100), 0, PIXELS(249), 1);
1866 Engine_EventWait(20);
1868 Camera_MoveTo(leader->x.fixed, leader->y.fixed, leader->z.fixed, 1);
1873}
1874
1875/// Back from room 3's beast battle: the beast is gone, the log waits at
1876/// (328, 424), the switch is back in its first position, and the second
1877/// drain runs.
1885 Engine_TaskWait(1);
1892}
1893
1894/// Back from room 5's beast battle, the same way, with the third drain.
1902 Engine_TaskWait(1);
1909}
1910
1911/// Scheduler task while the statue wakes: a rumble (SE_183) every second.
1914 if (gAltinPeak_RumbleTicks == 60) {
1917 }
1918}
1919
1920/// Stepping toward room 10's guardian statue: the leader walks up to it, it
1921/// rumbles and slides forward, and the battle with the Hydros statues
1922/// starts.
1925 Camera_SetSpeed(PIXELS(3) / 5, PIXELS(3) / 40);
1926 Camera_MoveTo(PIXELS(328), -1, PIXELS(87), 1);
1932 Actor_SetSpeed(ACTOR_STATUE, PIXELS(1) / 10, PIXELS(1) / 20);
1937 Engine_EventWait(60);
1941 Battle_SetStart(3);
1944}
1945
1946/// Scheduler task while the statue sinks: it flickers every other frame.
1947static void AltinPeak_FlickerStatue(void) {
1948 if (((gFrameCount >> 1) & 1) != 0) {
1950 } else {
1952 }
1953}
1954
1955/// Back from the Hydros statues' battle: Garet, Ivan and Mia step out. Garet
1956/// cheers, Ivan asks whether the leader agrees, and Mia tells of the guardian
1957/// statues; the statue shakes, sinks into the floor and shows a chest behind
1958/// it, and they agree to open it before they go, then rejoin the leader.
1960 struct FieldActor *leader;
1961 struct EventWork *work;
1962 SchedulerCallback update;
1963 const s32 *celebrate;
1964 const s32 *party;
1965
1970 work = gEventWork;
1972 work->transitionFrames = 40;
1975 Engine_EventWait(20);
1976 // Bring the party out for the victory conversation.
1978 if (leader != 0) {
1979 Actor_SetPosition(GARET, leader->x.fixed, leader->z.fixed);
1980 }
1982 if (leader != 0) {
1983 Actor_SetPosition(IVAN, leader->x.fixed, leader->z.fixed);
1984 }
1986 if (leader != 0) {
1987 Actor_SetPosition(MIA, leader->x.fixed, leader->z.fixed);
1988 }
1989 Actor_SetSpeed(GARET, PIXELS(3) / 5, PIXELS(3) / 10);
1990 Actor_SetSpeed(IVAN, PIXELS(3) / 5, PIXELS(3) / 10);
1991 Actor_SetSpeed(MIA, PIXELS(3) / 5, PIXELS(3) / 10);
2000 Engine_EventSetMessage(MsgAltinWeDidIsaacWeBeat);
2006 if (Engine_EventChooseYesNo(0, 0) == 0) {
2008 } else {
2011 }
2017 Engine_EventWait(20);
2019 Engine_EventSetMessage(MsgAltinGuardianStatuesWereCreatedLong);
2032 Engine_EventWait(10);
2043 // Animate the statues while the party reacts.
2044 update = AltinPeak_FlickerStatue;
2046 celebrate = gAltinPeak_StatueSinkScript;
2050 Engine_EventWait(60);
2052 Engine_EventWait(20);
2059 Engine_EventWait(20);
2070 Engine_EventWait(20);
2071 // Return the companions and save the completed Hydros battle.
2076 Engine_EventWait(20);
2082}
2083
2084/// Request the original unused Frost action.
2086 gEventWork->psynergyRequest = 0x1018;
2087}
2088
2089/// Scheduler task in room 7: while the leader stands higher than 48 pixels
2090/// the second pillar is drawn under the party and the third further back.
2092 if (Object_GetById(ACTOR_PARTY_LEADER)->y.fixed > PIXELS(48)) {
2093 {
2095 s32 bit = 2;
2096
2097 bit |= *flag;
2098 *flag = bit;
2099 }
2101 } else {
2103 }
2104}
2105
2106/// Makes a puddle walkable to the actor checks and marks its map cell.
2108 struct FieldActor *actor;
2109
2110 actor = Object_GetById(actorId);
2111 actor->collisionFlags &= 0xfe;
2112
2113 SetMapCellCollision(0, actor->x.fixed, actor->z.fixed, 255);
2114}
2115
2116/// The log reaches the end of its run: it settles in the middle of its cell
2117/// and the party leader jumps off it to the south.
2118static void AltinPeak_StopLogAndJumpOff(struct FieldActor *object) {
2119 s32 x;
2120 s32 z;
2121 s32 centerZ;
2122 struct AnimationObject *sprite;
2123 struct FieldActor *leader;
2124
2127 x = object->x.fixed & 0xfff00000;
2128 centerZ = PIXELS(8);
2129 z = object->z.fixed & 0xfff00000;
2130 object->acceleration = PIXELS(2);
2131 x += centerZ;
2132 centerZ += z;
2133 Engine_ObjectSetPosition(object, x, object->y.fixed, centerZ);
2135 object->terrainId = 0;
2136 object->x.fixed = x;
2137 object->z.fixed = centerZ;
2138 object->velocityX = 0;
2139 object->velocityZ = 0;
2140 Object_SetMode(object, 2);
2141 Engine_TaskWait(15);
2142 Object_SetMode(object, 1);
2143 Engine_TaskWait(30);
2144 sprite = object->sprite;
2145 sprite->count = 1;
2147 sprite->entries[1] = NULL;
2148 sprite->dirty = 1;
2151 leader->x.fixed = x;
2152 leader->velocityY = PIXELS(6);
2153 leader->gravity = PIXELS(1);
2154 leader->z.fixed = centerZ;
2155 leader->sprite->image.priority = 0;
2156 Object_SetMode(leader, 7);
2157 Engine_ObjectSetPosition(leader, x, leader->y.fixed, z + PIXELS(24));
2158 leader->facing = FACING_SOUTH;
2159 Engine_TaskWait(20);
2160 leader->sprite->image.priority = 2;
2162}
2163
2164UNUSED static void AltinPeak_ReservedNoOp(void) {}
2165
2166/// The log turns a quarter turn right around the corner it reaches.
2167static void AltinPeak_TurnLogRight(struct FieldActor *object) {
2168 struct FieldPosition *point;
2169 struct FieldPosition position;
2170 s32 angle;
2171 s32 x;
2172 s32 z;
2173 s32 turnFrame;
2174
2175 angle = (object->facing + 0x4000) & 0xc000;
2176 point = &position;
2177 SET_POSITION(point, object->x.fixed, object->y.fixed, object->z.fixed);
2178 FieldVector_AddPolarOffset(PIXELS(24), angle, point);
2179 x = (point->x + PIXELS(8)) & 0xfff00000;
2180 z = (point->z + PIXELS(8)) & 0xfff00000;
2181 angle += 0x8000;
2182 Object_SetMode(object, 5);
2183 turnFrame = 0;
2185 while (turnFrame < 16) {
2186 angle += 0x400;
2187 point->x = x;
2188 point->z = z;
2189 FieldVector_AddPolarOffset(PIXELS(24), angle, point);
2190 object->x.fixed = point->x;
2191 object->z.fixed = point->z;
2192 object->facing = angle + 0x4000;
2193 Engine_TaskWait(1);
2194 turnFrame++;
2195 }
2197}
2198
2199/// The log turns a quarter turn left.
2200static void AltinPeak_TurnLogLeft(struct FieldActor *object) {
2201 struct FieldPosition *point;
2202 struct FieldPosition position;
2203 s32 angle;
2204 s32 x;
2205 s32 z;
2206 s32 turnFrame;
2207
2208 angle = (object->facing - 0x4000) & 0xc000;
2209 point = &position;
2210 SET_POSITION(point, object->x.fixed, object->y.fixed, object->z.fixed);
2211 FieldVector_AddPolarOffset(PIXELS(24), angle, point);
2212 x = (point->x + PIXELS(8)) & 0xfff00000;
2213 z = (point->z + PIXELS(8)) & 0xfff00000;
2214 angle += 0x8000;
2215 Object_SetMode(object, 6);
2216 turnFrame = 0;
2218 while (turnFrame < 16) {
2219 angle -= 0x400;
2220 point->x = x;
2221 point->z = z;
2222 FieldVector_AddPolarOffset(PIXELS(24), angle, point);
2223 object->x.fixed = point->x;
2224 object->z.fixed = point->z;
2225 object->facing = angle - 0x4000;
2226 Engine_TaskWait(1);
2227 turnFrame++;
2228 }
2230}
2231
2232/// The log rolls over a marked cell: SE_288 plays, and SE_184 and SE_233
2233/// follow as its countdown runs out.
2234static void AltinPeak_StartLogCountdown(struct FieldActor *object) {
2235 object->work = 33;
2237}
2238
2239/// Rolls the log on by a frame and picks its animation from the terrain ahead
2240/// of and behind it: flat, uphill or downhill.
2241static void AltinPeak_AdvanceLog(struct FieldActor *object) {
2242 s32 angle = 0xc000;
2243 s32 radius;
2244 s16 *timer;
2245 struct FieldPosition position;
2246 struct FieldPosition *point;
2247 s32 ahead;
2248 s32 behind;
2249
2250 angle &= object->facing;
2251 radius = object->y.fixed / Q16_ONE;
2252 radius = gAltinPeak_RollRadii[object->timer - radius + 16];
2253 timer = (s16 *)&object->work;
2254 if (*timer != 0) {
2255 if (--*timer == 20) {
2257 }
2258 if (*timer == 0) {
2260 }
2261 }
2262 point = &position;
2263 SET_POSITION(point, object->x.fixed, object->y.fixed, object->z.fixed);
2264 FieldVector_AddPolarOffset(Iwram_MulQ16(radius, 3 * Q16_ONE / 4), angle,
2265 point);
2266 object->x.fixed = point->x;
2267 object->z.fixed = point->z;
2268 ahead = Map_GetTerrainHeight(2, point->x, point->z);
2269 FieldVector_AddPolarOffset(-Iwram_MulQ16(radius, 3 * Q16_ONE / 2), angle,
2270 point);
2271 behind = Map_GetTerrainHeight(2, point->x, point->z);
2272 if (*timer <= 20) {
2273 if (ahead == behind) {
2274 Object_SetMode(object, 2);
2275 } else if (ahead > behind) {
2276 Object_SetMode(object, 3);
2277 } else {
2278 Object_SetMode(object, 4);
2279 }
2280 }
2281}
2282
2283/// Rolls the log the party leader rides: it sets off the first way it can
2284/// roll, starting from heading (or its own facing for -1), follows the turns
2285/// its route's cells mark until the end cell, and the leader jumps off.
2286static void AltinPeak_RollLog(s32 id, s32 heading) {
2287 struct FieldActor *object = Object_GetById(id);
2289 struct FieldPosition position;
2290 s32 directionIndex;
2291
2293 if (heading == -1) {
2294 heading = object->facing;
2295 }
2296 for (directionIndex = 0; directionIndex <= 3; directionIndex++) {
2297 position.x = object->x.fixed;
2298 position.y = object->y.fixed;
2299 position.z = object->z.fixed;
2300 FieldVector_AddPolarOffset(PIXELS(16), heading, &position);
2301 if (Map_GetTerrainHeight(2, position.x, position.z) == object->y.fixed) {
2302 break;
2303 }
2304 heading += 0x4000;
2305 }
2306 if (directionIndex == 4) {
2307 return;
2308 }
2309 object->terrainId = 2;
2310 leader->x.fixed = 0;
2311 leader->z.fixed = 0;
2312 ResourceMetadata_Register(object->sprite, 16);
2315 Camera_SetSpeed(PIXELS(16), PIXELS(2));
2316 object->facing = heading;
2317 object->speed = PIXELS(2);
2318 object->acceleration = PIXELS(1) / 20;
2319 object->paused = 0;
2320 object->timer = object->y.fixed / Q16_ONE;
2321 object->work = 0;
2322 position.x = object->x.fixed;
2323 position.y = object->y.fixed;
2324 position.z = object->z.fixed;
2325 FieldVector_AddPolarOffset(PIXELS(24), heading, &position);
2326 Engine_ObjectSetPosition(object, position.x, object->y.fixed, position.z);
2329 // The route cells select turns, a countdown cue, and the destination.
2330 for (;;) {
2331 switch (GetMapCellCollision(2, object->x.fixed, object->z.fixed)) {
2332 case 98:
2333 AltinPeak_TurnLogRight(object);
2334 break;
2335 case 97:
2336 AltinPeak_TurnLogLeft(object);
2337 break;
2338 case 96:
2340 break;
2341 case 99:
2342 goto arrived;
2343 }
2344 AltinPeak_AdvanceLog(object);
2345 Engine_TaskWait(1);
2346 }
2347arrived:
2350}
2351
2352/// Scheduler task that cycles the water's palette colors through
2353/// gAltinPeak_PaletteScript.
2354static void AltinPeak_StepPaletteAnim(void) {
2355 // The palette cycle borrows RGB555 colours from the fade work's source
2356 // palette; each step replaces BG colours 3 to 11.
2357 u16 *palette = gPaletteBufferWork->palette;
2358
2359 if (gAltinPeak_PaletteHold <= 0) {
2360 s32 frame;
2361
2362 next:
2364 if (frame == -1) {
2366 goto next;
2367 }
2369 palette += frame;
2370 Dma_Set(palette, (void *)0x05000006, (DMA_ENABLE << 16) | 9, REG_DMA3);
2371 }
2373}
2374
2375/// Starts the water's palette cycle.
2380}
2381
2382// clang-format off
2383/// The water's palette cycle: pairs of a color offset and the frames it holds,
2384/// repeating from the top at -1.
2386 3, 16,
2387 2, 32,
2388 1, 64,
2389 2, 32,
2390 -1,
2391};
2392
2393/// Room 1's beast keeps turning to face the party leader.
2395 SC_CALL(Scene_TurnTowardTarget),
2397};
2398
2399/// The new puddle grows to full size over 108 frames.
2401 SC_ADD(SW_SCALE_X, 546),
2402 SC_ADD(SW_SCALE_Y, 546),
2403 SC_WAIT(1),
2404 SC_LOOP(108, SC_TOP),
2405 SC_END,
2406};
2407
2408/// Room 9's boulder rolls straight down the path, and marks its arrival.
2410 SC_MOVE(PIXELS(786), 0, PIXELS(220)),
2411 SC_SYNC,
2412 SC_MOVE(PIXELS(786), 0, PIXELS(326)),
2413 SC_SYNC,
2414 SC_MOVE(PIXELS(786), 0, PIXELS(326)),
2415 SC_SYNC,
2416 SC_MOVE(PIXELS(786), 0, PIXELS(480)),
2417 SC_SYNC,
2418 SC_MOVE(PIXELS(786), 0, PIXELS(520)),
2419 SC_SYNC,
2420 SC_SET(0x23, 1),
2421 SC_END,
2422};
2423
2424/// The party leader flees down the winding path ahead of the boulder, marks
2425/// the arrival, steps aside and turns round.
2427 SC_ARG(5),
2428 SC_MOVE(PIXELS(804), 0, PIXELS(140)),
2429 SC_SYNC,
2430 SC_MOVE(PIXELS(804), 0, PIXELS(166)),
2431 SC_SYNC,
2432 SC_MOVE(PIXELS(764), 0, PIXELS(166)),
2433 SC_SYNC,
2434 SC_MOVE(PIXELS(764), 0, PIXELS(198)),
2435 SC_SYNC,
2436 SC_MOVE(PIXELS(786), 0, PIXELS(198)),
2437 SC_SYNC,
2438 SC_MOVE(PIXELS(786), 0, PIXELS(246)),
2439 SC_SYNC,
2440 SC_MOVE(PIXELS(764), 0, PIXELS(246)),
2441 SC_SYNC,
2442 SC_MOVE(PIXELS(764), 0, PIXELS(282)),
2443 SC_SYNC,
2444 SC_MOVE(PIXELS(780), 0, PIXELS(298)),
2445 SC_SYNC,
2446 SC_MOVE(PIXELS(804), 0, PIXELS(298)),
2447 SC_SYNC,
2448 SC_MOVE(PIXELS(804), 0, PIXELS(326)),
2449 SC_SYNC,
2450 SC_MOVE(PIXELS(776), 0, PIXELS(326)),
2451 SC_SYNC,
2452 SC_MOVE(PIXELS(776), 0, PIXELS(358)),
2453 SC_SYNC,
2454 SC_MOVE(PIXELS(804), 0, PIXELS(358)),
2455 SC_SYNC,
2456 SC_MOVE(PIXELS(804), 0, PIXELS(392)),
2457 SC_SYNC,
2458 SC_MOVE(PIXELS(786), 0, PIXELS(392)),
2459 SC_SYNC,
2460 SC_MOVE(PIXELS(762), 0, PIXELS(416)),
2461 SC_SYNC,
2462 SC_MOVE(PIXELS(762), 0, PIXELS(438)),
2463 SC_SYNC,
2464 SC_MOVE(PIXELS(804), 0, PIXELS(438)),
2465 SC_SYNC,
2466 SC_MOVE(PIXELS(804), 0, PIXELS(472)),
2467 SC_SYNC,
2468 SC_MOVE(PIXELS(794), 0, PIXELS(472)),
2469 SC_SYNC,
2470 SC_MOVE(PIXELS(792), 0, PIXELS(504)),
2471 SC_SYNC,
2472 SC_MOVE(PIXELS(808), 0, PIXELS(504)),
2473 SC_SYNC,
2474 SC_MOVE(PIXELS(808), 0, PIXELS(552)),
2475 SC_SYNC,
2476 SC_SET(0x23, 1),
2477 SC_MOVE(PIXELS(854), 0, PIXELS(552)),
2478 SC_SYNC,
2480 SC_LABEL(1),
2481 SC_ADD(SW_FACING, 1024),
2482 SC_LOOP(24, SC_TO(1)),
2483 SC_END,
2484};
2485
2486/// A piece of debris flies for 60 frames and is freed.
2489 SC_WAIT(1),
2490 SC_LOOP(60, SC_TOP),
2491 SC_POS(0, 0, 0),
2492 SC_WAIT(1),
2493 SC_FREE,
2494};
2495
2496/// Garet, Ivan and Mia step out beside the leader after the Hydros battle.
2499 SC_MOVE(PIXELS(314), 0, PIXELS(126)),
2500 SC_SYNC,
2502 SC_WAIT(10),
2503 SC_END,
2504};
2505
2508 SC_MOVE(PIXELS(346), 0, PIXELS(126)),
2509 SC_SYNC,
2511 SC_WAIT(10),
2512 SC_END,
2513};
2514
2517 SC_MOVE(PIXELS(328), 0, PIXELS(138)),
2518 SC_SYNC,
2520 SC_WAIT(10),
2521 SC_END,
2522};
2523
2524/// The guardian statue and its shadow flatten into the floor over 60 frames.
2526 SC_ADD(SW_SCALE_X, 128),
2527 SC_ADD(SW_SCALE_Y, -1024),
2528 SC_WAIT(1),
2529 SC_LOOP(60, SC_TOP),
2530 SC_POS(0, 0, 0),
2531 SC_WAIT(1),
2532 SC_END,
2533};
2534
2535/// Garet, Ivan and Mia walk back to the leader and rejoin the party.
2538 SC_MOVE(PIXELS(328), 0, PIXELS(118)),
2539 SC_SYNC,
2540 SC_POS(0, 0, 0),
2541 SC_WAIT(1),
2542 SC_END,
2543};
2544
2546 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2548};
2549
2551 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2552 {1, CONDITION_ALWAYS, 456, 0, 520, FACING_NORTH, 0, 0, 56, 506, 530, 0},
2553 {98, CONDITION_ALWAYS, 456, 0, 488, FACING_NORTH, 0, 0, 56, 506, 530, 0},
2554 {99, CONDITION_ALWAYS, 104, 0, 232, FACING_SOUTH, 0, 0, 56, 506, 530, 0},
2556};
2557
2559 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2560 {1, CONDITION_ALWAYS, 248, 0, 464, FACING_NORTH, 0, -1, -1, -1, -1, 0},
2561 {2, CONDITION_ALWAYS, 56, 0, 72, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2563};
2564
2566 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2567 {1, CONDITION_ALWAYS, 488, 0, 560, FACING_NORTH, 0, -1, -1, -1, -1, 0},
2568 {2, CONDITION_ALWAYS, 664, 0, 380, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2569 {3, CONDITION_ALWAYS, 904, 0, 214, FACING_NORTH, 0, 842, 40, 1016, 248, 0},
2570 {98, CONDITION_ALWAYS, 488, 0, 560, FACING_NORTH, 0, -1, -1, -1, -1, 0},
2571 {99, CONDITION_ALWAYS, 320, 0, 472, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2573};
2574
2576 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2577 {1, CONDITION_ALWAYS, 248, 0, 498, FACING_NORTH, 0, 24, 0, 648, 560, 0},
2578 {2, CONDITION_ALWAYS, 119, 0, 108, FACING_SOUTH, 0, 24, 0, 648, 560, 0},
2579 {3, CONDITION_ALWAYS, 567, 0, 105, FACING_SOUTH, 0, 24, 0, 648, 560, 0},
2580 {4, CONDITION_ALWAYS, 887, 0, 798, FACING_NORTH, 0, 712, 568, 960, 860, 0},
2581 {5, CONDITION_ALWAYS, 791, 0, 679, FACING_SOUTH, 0, 712, 560, 960, 860, 0},
2582 {6, CONDITION_ALWAYS, 88, 0, 840, FACING_NORTH, 0, 32, 704, 272, 864, 0},
2583 {7, CONDITION_ALWAYS, 216, 0, 840, FACING_NORTH, 0, 32, 704, 272, 864, 0},
2585};
2586
2588 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2589 {1, CONDITION_ALWAYS, 585, 0, 501, FACING_NORTH, 0, 0, 0, 798, 530, 0},
2590 {98, CONDITION_ALWAYS, 585, 0, 501, FACING_NORTH, 0, 0, 0, 798, 530, 0},
2591 {99, CONDITION_ALWAYS, 747, 0, 258, FACING_SOUTH, 0, 0, 0, 798, 530, 0},
2593};
2594
2596 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2597 {1, CONDITION_ALWAYS, 568, 0, 348, FACING_NORTH, 0, 0, 0, 798, 530, 0},
2598 {2, CONDITION_ALWAYS, 295, 0, 95, FACING_SOUTH, 0, 0, 0, 798, 530, 0},
2599 {3, CONDITION_ALWAYS, 442, 0, 774, FACING_NORTH, 0, 0, 530, 512, 948, 0},
2600 {4, CONDITION_ALWAYS, 72, 0, 870, FACING_NORTH, 0, 0, 530, 512, 948, 0},
2601 {5, CONDITION_ALWAYS, 918, 0, 712, FACING_SOUTH, 0, 520, 570, 992, 786, 0},
2602 {6, CONDITION_ALWAYS, 615, 0, 684, FACING_SOUTH, 0, 520, 570, 992, 786, 0},
2604};
2605
2607 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2608 {1, CONDITION_ALWAYS, 72, 0, 502, FACING_NORTH, 0, 0, 0, 820, 568, 0},
2609 {2, CONDITION_ALWAYS, 152, 0, 174, FACING_SOUTH, 0, 0, 0, 820, 568, 0},
2610 {3, CONDITION_ALWAYS, 264, 0, 890, FACING_NORTH, 0, 144, 720, 384, 908, 0},
2612};
2613
2615 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2616 {1, CONDITION_ALWAYS, 392, 0, 116, FACING_SOUTH, 0, 0, 0, 830, 564, 0},
2617 {2, CONDITION_ALWAYS, 40, 0, 116, FACING_NORTH, 0, 0, 0, 830, 564, 0},
2618 {3, CONDITION_ALWAYS, 520, 0, 616, FACING_SOUTH, 0, 244, 564, 1024, 1024, 0},
2619 {4, CONDITION_ALWAYS, 408, 0, 970, FACING_NORTH, 0, 244, 564, 1024, 1024, 0},
2620 {5, CONDITION_ALWAYS, 951, 0, 791, FACING_SOUTH, 0, 244, 564, 1024, 1024, 0},
2622};
2623
2625 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2626 {1, CONDITION_ALWAYS, 361, 0, 309, FACING_NORTH, 0, 0, 0, 524, 816, 0},
2627 {2, CONDITION_ALWAYS, 89, 0, 749, FACING_NORTH, 0, 0, 0, 524, 816, 0},
2628 {3, CONDITION_ALWAYS, 728, 0, 717, FACING_NORTH, 0, 618, 0, 990, 854, 0},
2629 {4, CONDITION_ALWAYS, 935, 0, 493, FACING_SOUTH, 0, 618, 0, 990, 854, 0},
2630 {5, CONDITION_ALWAYS, 791, 0, 566, FACING_SOUTH, 0, 618, 0, 990, 854, 0},
2631 {6, CONDITION_ALWAYS, 792, 16, 577, FACING_SOUTH, 0, 618, 0, 998, 854, 0},
2633};
2634
2636 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2637 {1, CONDITION_ALWAYS, 88, 4, 424, FACING_SOUTH, 0, 0, 0, 448, 524, 0},
2638 {98, CONDITION_ALWAYS, 88, 4, 424, FACING_SOUTH, 0, 0, 0, 448, 524, 0},
2639 {99, CONDITION_ALWAYS, 328, 0, 118, FACING_NORTH, 0, 0, 0, 448, 524, 0},
2641};
2642
2644 {0, CONDITION_ALWAYS, 160, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2645 {1, CONDITION_ALWAYS, 408, 0, 517, FACING_NORTH, 0, 0, 0, 540, 590, 0},
2646 {2, CONDITION_ALWAYS, 198, 0, 336, FACING_SOUTH, 0, 0, 0, 540, 590, 0},
2647 {3, CONDITION_ALWAYS, 568, 0, 136, FACING_NORTH, 0, 480, 15, 684, 180, 0},
2648 {4, CONDITION_ALWAYS, 73, 0, 190, FACING_NORTH, 0, 0, 0, 540, 590, 0},
2650};
2651
2653#if !TBS_PATCH_3
2654 {790, -106, 575, 794, -102, 579, CONDITION_ALWAYS, 6},
2655 {788, -108, 579, 796, -100, 587, CONDITION_ALWAYS, 6},
2656#else
2657 {784, -116, 572, 800, -100, 588, CONDITION_ALWAYS, 6},
2658#endif
2660};
2661
2663#if !TBS_PATCH_3
2664 {84, 38, 420, 92, 46, 428, CONDITION_ALWAYS, 1},
2665#else
2666 {80, 34, 416, 96, 50, 432, CONDITION_ALWAYS, 1},
2667#endif
2669};
2670
2672 SCENE_EXITS(77),
2673 SCENE_EXIT(1, 75, 10),
2674 SCENE_EXIT(0, 78, 0),
2675 SCENE_EXIT(1, 80, 3),
2676 SCENE_EXIT(2, 79, 1),
2677 SCENE_EXIT(0, 79, 0),
2678 SCENE_EXIT(1, 78, 2),
2679 SCENE_EXIT(2, 79, 3),
2680 SCENE_EXIT(3, 79, 2),
2681 SCENE_EXIT(0, 80, 0),
2682 SCENE_EXIT(1, 75, 11),
2683 SCENE_EXIT(2, 80, 4),
2684 SCENE_EXIT(3, 78, 1),
2685 SCENE_EXIT(4, 80, 2),
2686 SCENE_EXIT(5, 82, 1),
2687 SCENE_EXIT(6, 74, 4),
2688 SCENE_EXIT(7, 74, 5),
2689 SCENE_EXIT(0, 81, 0),
2690 SCENE_EXIT(1, 82, 6),
2691 SCENE_EXIT(0, 82, 0),
2692 SCENE_EXIT(1, 80, 5),
2693 SCENE_EXIT(2, 82, 3),
2694 SCENE_EXIT(3, 82, 2),
2695 SCENE_EXIT(4, 82, 5),
2696 SCENE_EXIT(5, 82, 4),
2697 SCENE_EXIT(6, 81, 1),
2698 SCENE_EXIT(0, 83, 0),
2699 SCENE_EXIT(1, 84, 1),
2700 SCENE_EXIT(2, 85, 1),
2701 SCENE_EXIT(3, 75, 13),
2702 SCENE_EXIT(0, 84, 0),
2703 SCENE_EXIT(1, 83, 1),
2704 SCENE_EXIT(2, 85, 5),
2705 SCENE_EXIT(3, 87, 1),
2706 SCENE_EXIT(4, 75, 12),
2707 SCENE_EXIT(5, 85, 3),
2708 SCENE_EXIT(0, 85, 0),
2709 SCENE_EXIT(1, 83, 2),
2710 SCENE_EXIT(2, 85, 4),
2711 SCENE_EXIT(3, 84, 5),
2712 SCENE_EXIT(4, 85, 2),
2713 SCENE_EXIT(5, 84, 2),
2714 SCENE_EXIT(6, 86, 1),
2715 SCENE_EXIT(0, 86, 0),
2716 SCENE_EXIT(1, 85, 6),
2717 SCENE_EXIT(0, 87, 0),
2718 SCENE_EXIT(1, 84, 3),
2719 SCENE_EXIT(2, 87, 3),
2720 SCENE_EXIT(3, 87, 2),
2721 SCENE_EXIT(4, 2, 52),
2723};
2724
2727};
2728
2730 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(152), 0, PIXELS(216), FACING_SOUTH,
2731 TALK_KEEP_FACING, 0},
2732 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(296), 0, PIXELS(216), FACING_SOUTH,
2733 TALK_KEEP_FACING, 0},
2734 {0xbe, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(296), 0, PIXELS(336), FACING_SOUTH,
2735 TALK_KEEP_FACING, 0},
2737};
2738
2740 {0xe7, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(216), 0, PIXELS(312), FACING_EAST,
2741 TALK_KEEP_FACING, 0},
2742 {0xbe, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(248), 0, PIXELS(464), FACING_WEST,
2743 TALK_KEEP_FACING, 0},
2744 {0x127, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(888), 0, PIXELS(172), FACING_SOUTH,
2745 TALK_KEEP_FACING, 0},
2747};
2748
2750 {0xe7, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(536), 0, PIXELS(296), FACING_EAST,
2751 TALK_KEEP_FACING, 0},
2752 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(408), 0, PIXELS(216), FACING_SOUTH,
2753 TALK_KEEP_FACING, 0},
2754 {0xbe, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(759), 0, PIXELS(285), FACING_WEST,
2755 TALK_KEEP_FACING, 0},
2757};
2758
2760 {0xe7, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(712), 0, PIXELS(184), FACING_EAST,
2761 TALK_KEEP_FACING, 0},
2762 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(696), 0, PIXELS(664), FACING_SOUTH,
2763 TALK_KEEP_FACING, 0},
2765};
2766
2768 {0xe7, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(264), 0, PIXELS(408), FACING_EAST,
2769 TALK_KEEP_FACING, 0},
2770 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(424), 0, PIXELS(424), FACING_SOUTH,
2771 TALK_KEEP_FACING, 0},
2772 {0xd3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(408), 0, PIXELS(424), FACING_SOUTH,
2773 TALK_KEEP_FACING, 0},
2774 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(280), 0, PIXELS(168), FACING_SOUTH,
2775 TALK_KEEP_FACING, 0},
2776 {0xe3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(424), 0, PIXELS(248), FACING_SOUTH,
2777 TALK_KEEP_FACING, 0},
2778 {0x127, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(520), 0, PIXELS(632), FACING_SOUTH,
2779 TALK_KEEP_FACING, 0},
2780 {0x5b, FLAG_DJINNI_0 + 23, ACTOR_STAND, PIXELS(56), 0, PIXELS(392), FACING_SOUTH, TALK_FACE_PARTY, 0},
2782};
2783
2785 {0x127, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(536), 0, PIXELS(636), FACING_SOUTH,
2786 TALK_KEEP_FACING, 0},
2788};
2789
2791 {0xc8, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(784), 0, PIXELS(80), FACING_SOUTH,
2792 TALK_KEEP_FACING, 0},
2793 {0x120, CONDITION_ALWAYS, 7, PIXELS(784), 0, PIXELS(80), FACING_SOUTH, TALK_KEEP_FACING, 0},
2794 {0xcd, CONDITION_ALWAYS, 7, PIXELS(774), 0, PIXELS(76), FACING_SOUTH, TALK_KEEP_FACING, 0},
2795 {0x16, CONDITION_ALWAYS, 7, PIXELS(774), 0, PIXELS(88), FACING_SOUTH, TALK_KEEP_FACING, 0},
2796 {0x112, CONDITION_ALWAYS, 7, PIXELS(792), 0, PIXELS(88), FACING_SOUTH, TALK_KEEP_FACING, 0},
2799};
2800
2802 {0xc7, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(328), 0, PIXELS(84), FACING_SOUTH,
2803 TALK_KEEP_FACING, 0},
2804 {0x120, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(328), 0, PIXELS(88), FACING_SOUTH,
2805 TALK_KEEP_FACING, 0},
2810};
2811
2813 {0x127, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(312), 0, PIXELS(280), FACING_SOUTH,
2814 TALK_KEEP_FACING, 0},
2815 {0xd3, CONDITION_ALWAYS, ACTOR_STAND, PIXELS(200), 0, PIXELS(328), FACING_SOUTH,
2816 TALK_KEEP_FACING, 0},
2818};
2819
2822};
2823
2832};
2833
2840};
2841
2846};
2847
2861 {SEARCH(SEARCH_CHEST), 100, 0xf05, FIND_ITEM(ITEM_HERB)},
2863};
2864
2874};
2875
2884 // The Dragon Shield's chest opens only from its west side.
2889};
2890
2901 {SEARCH(SEARCH_CHEST), 100, 0xef2, 0x500002},
2903};
2904
2924};
2925// clang-format on
2926
2937};
2938
2950};
2951
2958};
2959
2966 0},
2970};
2971
2972/// Frames since the statue's last rumble.
2974
2975/// The log's speed factor by its height against where it set off: 2 to the
2976/// power i / 16 for i from 0 to 32, in 16.16.
2978 0x10000, 0x10b55, 0x1172b, 0x12387, 0x1306f, 0x13dea, 0x14bfd,
2979 0x15ab0, 0x16a09, 0x17a11, 0x18ace, 0x19c49, 0x1ae89, 0x1c199,
2980 0x1d581, 0x1ea4b, 0x20000, 0x216ab, 0x22e56, 0x2470f, 0x260df,
2981 0x27bd4, 0x297fb, 0x2b560, 0x2d413, 0x2f422, 0x3159c, 0x33892,
2982 0x35d13, 0x38333, 0x3ab03, 0x3d495, 0x40000,
2983};
Ability numbers, named from the English release.
@ ABILITY_FORCE
Definition ability_ids.h:17
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_LIFT
Definition ability_ids.h:18
@ ABILITY_MOVE
Definition ability_ids.h:15
@ ABILITY_FROST
Definition ability_ids.h:11
void ObjectGroup_SetChildValue(struct FieldActor *actor, s32 param)
Sets the param byte of every animated part of an actor's sprite.
void ObjectMotion_EnableActionAndResetMotion(u32 objectId)
The event command "stop actor": stops its action and puts it back under event control (dispatch scrip...
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
const struct ScenePlacement * Scene_GetPlacements(void)
const struct SceneEntrance * Scene_GetEntrances(void)
const struct SceneEvent * Scene_GetEvents(void)
const u32 * Scene_GetExits(void)
Both scenes share one exit table.
const struct SceneRegion * Scene_GetRegions(void)
s32 Scene_Initialize(void)
Sets up whichever scene is being entered and runs its arrival events.
@ SPRITE_SPRAY
Definition altin.c:110
@ ACTOR_ROOM5_BEAST
Definition altin_peak.c:109
@ ACTOR_ROOM5_PUDDLE
Definition altin_peak.c:109
struct SceneEvent gAltinPeak_Events7[]
static void AltinPeak_FreezeRoom7SecondPuddle(void)
Frost on room 7's second puddle.
Definition altin_peak.c:453
static void AltinPeak_FightRoom1Beast(void)
Talking to (or reading the mind of) a room's water beast starts its battle; afterwards the party retu...
Definition altin_peak.c:339
static void AltinPeak_MarkActorTerrainCell(s32 actorId)
Makes a puddle walkable to the actor checks and marks its map cell.
static void AltinPeak_UpdateBeastHops(union FieldObject *object)
Update callback of the hopping water beast: once a second it leaps up and lands with a splash (SE_229...
s32 gAltinPeak_StatueSinkScript[]
The guardian statue and its shadow flatten into the floor over 60 frames.
@ SPRITE_BOULDER
Definition altin_peak.c:158
static void AltinPeak_UpdateFrostPillarPriority(void)
Scheduler task in room 7: while the leader stands higher than 48 pixels the second pillar is drawn un...
@ ACTOR_ROOM6_PUDDLE
Definition altin_peak.c:111
static void AltinPeak_StopLogAndJumpOff(struct FieldActor *object)
The log reaches the end of its run: it settles in the middle of its cell and the party leader jumps o...
static void AltinPeak_BeastFreezesWidePuddle(void)
Room 1's water beast casts Frost on the wide puddle.
static void AltinPeak_RestoreRoom6(void)
Room 6: arriving at entrance 2 the log waits there; the frozen puddle, the water level and the switch...
struct SceneEvent gAltinPeak_Events9[]
static void AltinPeak_RestoreRoom1(void)
Room 1: after its beast's battle the Frost Jewel is found and the water drains; the beast stays where...
struct ScenePlacement gAltinPeak_Placements11[]
@ FLAG_THIRD_PUDDLE_FROZEN
Frost has frozen room 7's third puddle.
Definition altin_peak.c:144
@ FLAG_GARET_WATCHING_ROCKS
Garet has come out to look at room 9's falling-rock sign.
Definition altin_peak.c:146
@ FLAG_SECOND_PUDDLE_FROZEN
Frost has frozen room 1's wide puddle or room 7's second.
Definition altin_peak.c:142
static void AltinPeak_FlipRoom7Switch(void)
Searching room 7's switch flips it.
Definition altin_peak.c:687
struct SceneEvent gAltinPeak_Events6[]
static void AltinPeak_SpawnDebris(void)
Scheduler task while the boulder crashes: every third frame a piece of rock (the boulder's own sprite...
struct SceneEvent gAltinPeak_Events3[]
struct SceneEntrance gAltinPeak_Entrances11[]
static void AltinPeak_DrainAfterSecondBeast(void)
Back from room 3's beast battle: the beast is gone, the log waits at (328, 424), the switch is back i...
struct SceneEntrance gAltinPeak_Entrances4[]
#define SEARCH_CHEST_FACING(facing)
A chest searched while facing the given way.
Definition altin_peak.c:150
static void AltinPeak_SettleRoom7Block(void)
Move on room 7's block: the cell it left becomes free again and the cell it now stands on (column 24 ...
Definition altin_peak.c:360
@ ACTOR_FALLING_BOULDER
Definition altin_peak.c:126
@ ACTOR_WALL
Definition altin_peak.c:129
@ ACTOR_TOPPLING_ROCK
Definition altin_peak.c:128
@ ACTOR_BOULDER_SHADOW
Definition altin_peak.c:127
static void AltinPeak_RunBoulderChase(s32 boulderDelay)
Room 9's rockfall.
Definition altin_peak.c:813
static void AltinPeak_RestoreRoom10(void)
Room 10: the guardian statue stands until the Hydros statues are beaten; after their battle the party...
struct SceneEntrance gAltinPeak_Entrances1[]
struct SceneEvent gAltinPeak_Events4[]
static void AltinPeak_RestoreRoom4(void)
Room 4: its water is up until the second drain; entrances 6 and 7 skip the arrival event.
@ ACTOR_ROOM3_BEAST
Definition altin_peak.c:107
@ ACTOR_ROOM3_BOULDER
Definition altin_peak.c:107
struct SceneRegion gAltinPeak_Regions9[]
s32 gAltinPeak_FaceLeaderScript[]
Room 1's beast keeps turning to face the party leader.
@ ACTOR_ROOM1_PUDDLE
Definition altin_peak.c:102
@ ACTOR_ROOM1_BEAST
Definition altin_peak.c:104
@ ACTOR_ROOM1_WIDE_PUDDLE
Definition altin_peak.c:103
static void AltinPeak_PlayHydrosRumble(void)
Scheduler task while the statue wakes: a rumble (SE_183) every second.
static void AltinPeak_StartHydrosBattle(void)
Stepping toward room 10's guardian statue: the leader walks up to it, it rumbles and slides forward,...
static void AltinPeak_FlipRoom5Switch(void)
Searching room 5's switch flips it.
Definition altin_peak.c:657
static void AltinPeak_SparkleIce(union FieldObject *object)
Update callback of the frozen wide puddle: its ice glints every eight frames.
static void AltinPeak_InitSpray(struct FieldActor *spray)
Gives a new spray particle its look: standing still, on sprite priority 1 and at 0....
s32 gAltinPeak_PuddleGrowScript[]
The new puddle grows to full size over 108 frames.
#define FLAG_ALTIN_PEAK_ROOM_3_SWITCH
Definition altin_peak.c:62
@ ACTOR_ROOM11_BLOCK
Definition altin_peak.c:135
@ ACTOR_ROOM11_BOULDER
Definition altin_peak.c:135
@ ACTOR_LOG
Definition altin_peak.c:97
s32 gAltinPeak_SprayDirection
u32 gAltinPeak_Exits[]
static void AltinPeak_RestoreRoom9(void)
Room 9: the boulder is put away; once the rockfall is over the rock lies toppled and the rubble fills...
static void AltinPeak_FlipRoom3Switch(void)
Searching room 3's switch flips it. "You flipped the switch.".
Definition altin_peak.c:633
static void AltinPeak_RollLog(s32 id, s32 heading)
Rolls the log the party leader rides: it sets off the first way it can roll, starting from heading (o...
struct SceneEntrance gAltinPeak_Entrances9[]
static void AltinPeak_SpawnSpray(void)
Scheduler task while a beast spits: every fourth frame a spray particle starts from its spout,...
s32 gAltinPeak_MiaScript[]
static __inline__ void AltinPeak_PlayLandingShake(s32 amplitude, s32 holdFrames)
The beast lands with a splash, shaking the screen for holdFrames.
u32 gAltinPeak_RollRadii[]
The log's speed factor by its height against where it set off: 2 to the power i / 16 for i from 0 to ...
static void AltinPeak_FightRoom5Beast(void)
Definition altin_peak.c:351
struct ScenePlacement gAltinPeak_Placements1[]
static void AltinPeak_FreezeRoom1WidePuddle(void)
Frost on room 1's wide puddle, three cells across: the cells take the ice's attributes and the ice is...
Definition altin_peak.c:399
static void AltinPeak_FreezeRoom7Puddle(void)
Frost on room 7's first puddle.
Definition altin_peak.c:411
static void AltinPeak_RestoreRoom5(void)
Room 5: after its beast's battle the third drain runs; while the water is up the beast spits it; the ...
struct SceneEntrance gAltinPeak_EntrancesOther[]
static void AltinPeak_RestoreRoom7(void)
Room 7: the block, the three frozen puddles and the switch are restored.
static void AltinPeak_TurnLogLeft(struct FieldActor *object)
The log turns a quarter turn left.
s32 gAltinPeak_RumbleTicks
Frames since the statue's last rumble.
static s32 AltinPeak_ShadowFollowBoulder(union FieldObject *object)
Definition altin_peak.c:182
struct ScenePlacement gAltinPeak_Placements6[]
struct SceneEvent gAltinPeak_EventsOther[]
static void AltinPeak_FlipRoom6Switch(void)
Searching room 6's switch flips it.
Definition altin_peak.c:668
#define FLAG_ALTIN_PEAK_ROOM_6_SWITCH
Definition altin_peak.c:64
static void AltinPeak_RestoreBlockAutomaticPriority(void)
Stepping off room 7's block: it sorts against the leader again.
Definition altin_peak.c:712
struct SceneEvent gAltinPeak_Events1[]
@ ACTOR_ROOM7_SECOND_PUDDLE
Definition altin_peak.c:116
@ ACTOR_ROOM7_THIRD_PUDDLE
Definition altin_peak.c:117
@ ACTOR_ROOM7_PUDDLE
Definition altin_peak.c:114
@ ACTOR_ROOM7_BLOCK
Definition altin_peak.c:115
@ ACTOR_DJINNI
Definition altin_peak.c:118
static void AltinPeak_FreezeRoom5Puddle(void)
Frost on room 5's puddle.
Definition altin_peak.c:425
@ ACTOR_STATUE_SHADOW
Definition altin_peak.c:133
@ ACTOR_STATUE
Definition altin_peak.c:133
static UNUSED void AltinPeak_ReservedNoOp(void)
static void AltinPeak_ToggleRoom5SwitchCells(void)
Flips room 5's switch, the same way.
Definition altin_peak.c:644
struct SceneEntrance gAltinPeak_Entrances5[]
struct SceneRegion gAltinPeak_Regions10[]
static void AltinPeak_StepPaletteAnim(void)
Scheduler task that cycles the water's palette colors through gAltinPeak_PaletteScript.
struct SceneEvent gAltinPeak_Events2[]
static void AltinPeak_FreezeRoom7ThirdPuddle(void)
Frost on room 7's third puddle.
Definition altin_peak.c:467
struct SceneEntrance gAltinPeak_Entrances10[]
static void AltinPeak_RestoreRoom3(void)
Room 3: after its beast's battle the second drain runs; while the water is up the beast spits it; the...
struct SceneEvent gAltinPeak_Events8[]
struct ScenePlacement gAltinPeak_Placements5[]
static void AltinPeak_AwardFrostJewelAndDrain(void)
Back from room 1's beast battle: the beast is gone and the party finds the Frost Jewel; the camera pa...
struct ScenePlacement gAltinPeak_Placements9[]
s8 gAltinPeak_PaletteScript[]
The water's palette cycle: pairs of a color offset and the frames it holds, repeating from the top at...
static void AltinPeak_FreezeRoom6Puddle(void)
Frost on room 6's puddle.
Definition altin_peak.c:439
s32 gAltinPeak_LeaderFleePath[]
The party leader flees down the winding path ahead of the boulder, marks the arrival,...
struct SceneEntrance gAltinPeak_Entrances8[]
static void AltinPeak_DrainAfterThirdBeast(void)
Back from room 5's beast battle, the same way, with the third drain.
struct SceneEntrance gAltinPeak_Entrances7[]
@ ANIM_LEADER_JUMP
Definition altin_peak.c:154
@ ANIM_LEADER_LEAP
Definition altin_peak.c:154
struct SceneEntrance gAltinPeak_Entrances3[]
static void AltinPeak_DrainSecondWater(void)
The second drain: the same sinking and flicker over the cells the water leaves behind,...
Definition altin_peak.c:547
struct ScenePlacement gAltinPeak_Placements8[]
static void AltinPeak_PushRoom7Block(void)
Walking east into room 7's block pushes it one cell along with a scrape; the leader follows it and it...
Definition altin_peak.c:718
static void AltinPeak_FightRoom3Beast(void)
Definition altin_peak.c:345
struct SceneEvent gAltinPeak_Events11[]
#define FLAG_ALTIN_PEAK_ROOM_7_SWITCH
Definition altin_peak.c:65
#define SCENE_MINE_ROOM(n)
Definition altin_peak.c:90
static void AltinPeak_CelebrateHydrosVictory(void)
Back from the Hydros statues' battle: Garet, Ivan and Mia step out.
static void AltinPeak_TurnLogRight(struct FieldActor *object)
The log turns a quarter turn right around the corner it reaches.
static void AltinPeak_PlaceBlockUnderLeader(void)
Stepping onto room 7's block: it is drawn under the party leader.
Definition altin_peak.c:706
#define FLAG_ALTIN_PEAK_ROOM_5_SWITCH
Definition altin_peak.c:63
s32 gAltinPeak_RejoinScript[]
Garet, Ivan and Mia walk back to the leader and rejoin the party.
static void AltinPeak_StartPaletteAnim(void)
Starts the water's palette cycle.
struct ScenePlacement gAltinPeak_Placements3[]
static void AltinPeak_StartSpitting(s32 x, s32 y, s32 z, s32 facing)
A water beast starts spitting water from (x, y, z) toward facing (east, 0, or west,...
static void AltinPeak_AdvanceLog(struct FieldActor *object)
Rolls the log on by a frame and picks its animation from the terrain ahead of and behind it: flat,...
@ ENTRANCE_AFTER_BATTLE
Definition altin_peak.c:93
s32 gAltinPeak_GaretScript[]
Garet, Ivan and Mia step out beside the leader after the Hydros battle.
@ ACTOR_ROOM8_BOULDER
Definition altin_peak.c:121
static void AltinPeak_ShowFirstBeastRoute(void)
Stepping near room 1's water beast the first time: the camera finds it, it cries out and hops away ar...
struct ScenePlacement gAltinPeak_PlacementsOther[]
static void AltinPeak_DriftSpray(union FieldObject *object)
Update callback of a spray particle: it grows while drifting away from the beast, then curls and flat...
static void AltinPeak_StartLogCountdown(struct FieldActor *object)
The log rolls over a marked cell: SE_288 plays, and SE_184 and SE_233 follow as its countdown runs ou...
static void AltinPeak_ToggleRoom3SwitchCells(void)
Flips room 3's switch to its other position, redrawing it and changing the cell its position opens or...
Definition altin_peak.c:620
s32 gAltinPeak_IvanScript[]
static void AltinPeak_ForceRockOver(void)
Force on room 9's wall: it rumbles, the rock on it rocks one way and back, then topples with a crash,...
Definition altin_peak.c:736
static void AltinPeak_ReadFallingRockSign(void)
Searching room 9's sign, which can bring the rockfall.
Definition altin_peak.c:962
struct SceneEvent gAltinPeak_Events5[]
static void AltinPeak_RestoreRoom11(void)
Room 11: arriving at entrance 2 the block stands at its pushed place.
static void AltinPeak_DrainFirstWater(void)
The first drain, after the Frost Jewel is found: the screen shakes, the water layer sinks 24 pixels,...
Definition altin_peak.c:503
static void AltinPeak_ShowSecondBeastRoute(void)
Stepping near the beast again: it hops back over the ice and settles down, spitting water.
struct SceneEvent gAltinPeak_Events10[]
s32 gAltinPeak_BoulderPath[]
Room 9's boulder rolls straight down the path, and marks its arrival.
static s32 AltinPeak_FlyDebris(struct ScriptInterpreter *interpreter)
Script callback for a piece of flying rock debris: it moves by its velocity, grows by its z velocity ...
Definition altin_peak.c:197
s32 gAltinPeak_DebrisScript[]
A piece of debris flies for 60 frames and is freed.
struct SceneEntrance gAltinPeak_Entrances6[]
struct SceneEntrance gAltinPeak_Entrances2[]
s32 gAltinPeak_SprayOrigin[3]
struct SceneEvent gAltinPeak_Events1Drained[]
static void AltinPeak_FlickerStatue(void)
Scheduler task while the statue sinks: it flickers every other frame.
struct ScenePlacement gAltinPeak_Placements10[]
static void AltinPeak_RideLog(s32 log)
Talking to a log: the party leader jumps onto it, and once the leader has landed on top the log rolls...
Definition altin_peak.c:302
static void AltinPeak_FreezeRoom1Puddle(void)
Frost on a puddle freezes it into an ice pillar the party can stand on: the puddle's cell takes the p...
Definition altin_peak.c:384
struct ScenePlacement gAltinPeak_Placements7[]
static void AltinPeak_TalkToDjinni(void)
Talking to the Djinni in room 7 makes it hop and starts the battle for Djinni 23.
Definition altin_peak.c:168
static void Water_FlickerOut(void)
Interrupt handler while the water layer vanishes: each time, background 1 (the water) stays on only w...
Definition altin_peak.c:483
static void AltinPeak_DrainThirdWater(void)
The third drain, likewise.
Definition altin_peak.c:582
static UNUSED void AltinPeak_RequestPsynergy(void)
Request the original unused Frost action.
u16 gAltinPeak_FlickerTimer
s32 ResourceMetadata_Register(struct AnimationObject *sprite, s32 id)
Adds a layer of animation id to a sprite, in its first free layer of four.
Definition animation.c:191
void ResourceMetadata_ClearRecord(struct AnimationEntry *record)
Zeroes one animation layer (struct AnimationEntry); does nothing for NULL.
Definition animation.c:499
Animated sprites: their layers, frames and colour modes, and the resource slots they draw from.
The battle animation state, render objects and effect entries, and the palette buffer work.
struct BattleEffectBuffers * gPaletteBufferWork
Calls through a function pointer, by argument count.
void(*) SchedulerCallback(void)
struct FieldActor * Camera_GetEventObject(void)
The event command "get view centre": returns the camera object.
Definition camera.c:133
#define GARET
Jerald.
#define MIA
Mary.
#define IVAN
Ivan.
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
struct FieldActor * Engine_ObjectCreate(s32, s32, s32, s32)
The engine calls the debug menus import, and their palette swatch tiles.
Djinn numbers, named from the English release.
@ DJINNI_SPRITZ
Definition djinn_ids.h:21
DMA channel registers, and the DMA and CPU fills.
static __inline__ void Dma_Set(const volatile void *source, volatile void *destination, u32 control, volatile u32 *channel)
Starts a DMA transfer: stores the source, destination and control words into channel's registers with...
Definition dma.h:62
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
FacingObject, the view of an object that turns to face a target.
s16 gAltinPeak_PaletteStep
s16 gAltinPeak_PaletteHold
Field effects, their scripts and the flags that spawn them.
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
void Engine_ObjectSetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
@ ANIM_WALK
Definition field_event.h:44
@ ANIM_STAND
Definition field_event.h:43
@ ANIM_NOD
Definition field_event.h:45
@ ANIM_SHAKE_HEAD
Definition field_event.h:46
static s32 Event_OpenMessage(s32 speaker, s32 flags)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
void Engine_PsynergyBegin(s32 ability, s32 flags)
struct FieldActor * Engine_ActorLookup(s32 actor)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
s32 Engine_EventChooseYesNo(s32 actor, s32 flags)
void Engine_MessageShowCentered(s32 message, s32 flags)
s32 Engine_PartyGiveItem(s32 item, s32 flags)
#define GameFlag_IsSet
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
static void Camera_SetSpeed(s32 speed, s32 acceleration)
void Engine_CameraMoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
void Engine_PsynergyRaiseHands(void)
s32 Engine_TaskRemoveCallback(void(*callback)(void))
void Engine_PsynergyLowerHands(void)
void Engine_ActorMoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_ItemShowFound(s32 item, s32 height)
void Engine_ActorSetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ObjectDispatchRelease(struct FieldActor *object)
static void Actor_RunActionScriptAndWait(s32 actor, const s32 *script)
Runs a script, waiting at most 300 frames for its final command.
static void Map_CopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
static void Event_SkipMessages(s32 count)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
#define GameFlag_Clear
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_CameraWaitForMove(void)
static void Actor_SetActionScript(s32 actor, const s32 *script)
The engine encodes either a built-in action or an action-script address.
void Engine_ActorWaitForMove(s32 actor)
void Engine_CameraFollowActor(s32 actor, s32 keep_position)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
static void Event_ShowMessage(s32 speaker, s32 flags)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
static void Map_CopyCells(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorSetChildValue(s32 actor, s32 value)
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_PsynergyPlayEffect(s32 effect)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static struct FieldActor * Object_Create(s32 type, s32 fixed_x, s32 fixed_y, s32 fixed_z)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
@ TASK_PRIORITY_SCENE
Definition field_event.h:40
void Engine_MapRedraw(void)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
void Engine_PsynergySetTarget(s32 caster, s32 target)
static struct FieldActor * Actor_Get(s32 actor)
@ ACTOR_LINK_KEEP_MOTION
Definition field_obj.h:148
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ TRANSITION_BACKDROP_FADE
Definition field_obj.h:16
@ ACTOR_PRIORITY_UNDERFOOT
The depth sort treats it as 320 pixels higher on the screen.
Definition field_obj.h:155
@ ACTOR_PRIORITY_AUTOMATIC
The sprite takes its priority from the map cell under it.
Definition field_obj.h:153
@ ACTOR_FALLS
falls by its gravity and bounces
Definition field_obj.h:161
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
@ ACTOR_FACES_MOTION
turns toward its velocity, 1/16 turn a frame
Definition field_obj.h:166
The field's runtime work: map cells, scene records and regions, map markers and FieldWork.
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
@ FACING_NORTHEAST
Definition field_scene.h:33
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTHWEST
Definition field_scene.h:29
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_UNNAMED
@ SEARCH_CHEST
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static void Event_End(void)
static void FieldObject_SetTargetAndCallback(s32 object, s32 target, const s32 *actions)
static s32 Task_AddCallback(void(*callback)(void), s32 priority)
Calls the main-image scheduler through engine_call.h.
static s32 Math_Cos(s32 angle)
static void Task_Wait(s32 frames)
static void Event_Begin(void)
static void FieldVector_AddPolarOffset(s32 radius, s32 heading, struct FieldPosition *probe)
static s32 Math_Sin(s32 angle)
static void Actor_SetAnimation(s32 actor, s32 animation)
static void Event_Wait(s32 frames)
16.16 fixed-point constants, sine and cosine, and the library division.
#define Q16_ONE
One in the engine's signed 16.16 fixed-point format.
Definition fixed_math.h:10
Game flags, named where their meaning is shown.
#define FLAG_SCENE_TEMP_05
Definition flags.h:718
#define FLAG_SHOW_LOCATION_NAME
Definition flags.h:94
#define FLAG_DJINNI_0
the flag of Djinni 0, set once it is caught
Definition flags.h:15
#define FLAG_ALTIN_PEAK_DRAGON_SHIELD
room 5's chest
Definition flags.h:158
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_ALTIN_PEAK_SECOND_BEAST_ROUTE_SEEN
Definition flags.h:154
#define FLAG_ALTIN_PEAK_BOULDER_FALLEN
Room 9's boulder has fallen and rolled down after the party leader.
Definition flags.h:156
#define FLAG_ALTIN_PEAK_LUCKY_MEDAL
room 8's chest
Definition flags.h:159
#define FLAG_ALTIN_PEAK_COOKIE
room 3's chest
Definition flags.h:157
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_ALTIN_PEAK_FIRST_BEAST_ROUTE_SEEN
Room 1's water beast has been seen hopping along its first and its second route.
Definition flags.h:153
#define FLAG_ALTIN_PEAK_LIFTING_GEM
room 10's chest
Definition flags.h:162
#define FLAG_ALTIN_MINE_SECOND_DRAIN
Definition flags.h:116
#define FLAG_HYDROS_STATUES_DEFEATED
Definition flags.h:118
#define FLAG_FUCHIN_FALLS_ORB_OF_FORCE_FOUND
The Orb of Force's chest in Fuchin Falls has been opened.
Definition flags.h:618
#define FLAG_ALTIN_MINE_THIRD_DRAIN
Definition flags.h:117
#define FLAG_SCENE_TEMP_01
Definition flags.h:714
#define FLAG_ALTIN_PEAK_VIAL
room 11's chest
Definition flags.h:160
#define FLAG_SCENE_TEMP_04
Definition flags.h:717
#define FLAG_ALTIN_PEAK_PSY_CRYSTAL
room 7's chest
Definition flags.h:161
#define FLAG_ALTIN_MINE_FIRST_DRAIN
Definition flags.h:115
void Runtime_SetIrqHandler(u32 irq, s32 vcount, InterruptHandler handler)
Installs handler for interrupt irq and enables that interrupt, or with a null handler disables it and...
Definition frame.c:37
volatile u32 gFrameCount
Frames WaitFrames has finished.
GameState, the game's state: play time, coins, the scene and the leader's position,...
#define Battle_SetStart(mode)
Sets the battle start type.
Definition game_state.h:164
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
void * gMapWork[]
The screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
void Event_LoadAreaScript(const struct SceneEvent *events)
The hardware's I/O registers and their bits, as pret names them.
#define REG_DISPCNT
Definition io_reg.h:9
#define REG_DMA3
Definition io_reg.h:153
#define DMA_ENABLE
Definition io_reg.h:217
The hardware's interrupt sources and the interrupt handler table.
Item numbers, named from the English release.
@ ITEM_DRAGON_SHIELD
Definition item_ids.h:31
@ ITEM_COOKIE
Definition item_ids.h:51
@ ITEM_LIFTING_GEM
Definition item_ids.h:58
@ ITEM_FROST_JEWEL
Definition item_ids.h:57
@ ITEM_VIAL
Definition item_ids.h:42
@ ITEM_HERB
Definition item_ids.h:40
@ ITEM_LUCKY_MEDAL
Definition item_ids.h:70
@ ITEM_PSY_CRYSTAL
Definition item_ids.h:46
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
The keypad state the VBlank interrupt keeps.
volatile u32 gKeysPressed
Keys that went down this frame.
Small statement macros both games use for positions, velocities and bounds.
#define SET_VELOCITY(p, vx, vy, vz)
Definition macros.h:18
#define ABS(v)
The magnitude of v. v is read twice.
Definition macros.h:32
#define SET_POSITION(p, px, py, pz)
Sets the position or the velocity of a particle, a piece of debris or an object in one statement.
Definition macros.h:16
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
Definition macros.h:12
The map layers' scroll work and the background scroll values.
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_LABEL(n)
Branch destination.
Definition objcmd.h:11
#define SC_SET(w, v)
Write a work value.
Definition objcmd.h:37
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_FREE
Release.
Definition objcmd.h:43
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_FOREVER
Definition objcmd.h:14
#define SC_TO(n)
Definition objcmd.h:12
#define SC_ADD(w, v)
Definition objcmd.h:38
#define SC_ARG(v)
Definition objcmd.h:44
#define SC_MOVE(x, y, z)
Move toward the target.
Definition objcmd.h:19
#define SC_WAIT(n)
Wait n frames.
Definition objcmd.h:16
#define SC_TOP
Script start.
Definition objcmd.h:13
#define SC_END
Return to the main script.
Definition objcmd.h:32
@ SW_SCALE_Y
Definition objcmd.h:63
@ SW_FACING
Definition objcmd.h:57
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void Battle_ResetEffectCounter(void)
Clears the field's busy flag and, while Reveal is active, ends it: Reveal used with ACT_PACKED runs i...
Definition targets.c:261
void BattleEffect_CleanupSceneObjects(void)
Ends a Psynergy effect: frees the effect slots still in use and, unless another effect is being resol...
Definition setup.c:110
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
void Field_RequestBattleFromEncounterTable(s32 zoneNo, s32 slotNo)
Sets up a battle with enemy group slot of encounter table zone.
Definition requests.c:14
void Event_SetNextDestination(s32 scene, s32 entrance)
Sets the scene and entrance that the field goes to next (gGameState.nextScene and nextEntrance).
Definition requests.c:61
void BattleFx_PlayQueuedSound(void)
Plays the sound BattleFx_SetQueuedSoundAndPlay remembered, if any.
Definition requests.c:102
void Field_RequestDjinnBattle(s32 flag, s32 no)
Sets up the battle with Djinni number no.
Definition requests.c:35
void BattleFx_SetQueuedSoundAndPlay(s32 soundId)
Plays SE_298, then soundId (SE_289 for -1), and remembers soundId for BattleFx_PlayQueuedSound in the...
Definition requests.c:90
void Audio_PlayCueFromEventWork(void)
Starts the current scene's field music, chosen by Scene_ResolveInteractionResult.
Definition scene.c:355
Scene numbers, named after their places.
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_144
Definition songs.h:137
#define SE_233
Definition songs.h:228
#define SE_159
Definition songs.h:154
#define SE_170
Definition songs.h:165
#define SE_107
Definition songs.h:100
#define MUS_055
Definition songs.h:59
#define SE_185
Definition songs.h:180
#define SE_232
Definition songs.h:227
#define SE_288
Definition songs.h:281
#define SE_147
Definition songs.h:140
#define SE_125
Definition songs.h:118
#define SE_183
Definition songs.h:178
#define SE_148
Definition songs.h:141
#define SE_184
Definition songs.h:179
#define MUS_017
Definition songs.h:27
#define SE_190
Definition songs.h:185
#define SE_141
Definition songs.h:134
#define SE_145
Definition songs.h:138
#define SE_161
Definition songs.h:156
#define SE_229
Definition songs.h:224
#define SE_230
Definition songs.h:225
#define SE_JUMP
An actor jumps: ObjectMotion_Launch plays the high jump above 5 pixels a frame.
Definition songs.h:147
#define SE_289
Definition songs.h:282
#define SE_103
Definition songs.h:96
#define SE_HIGH_JUMP
Definition songs.h:148
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_TaskWait()
void Engine_EventSetMessage()
#define NULL
Definition bilibin.h:6
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
u16 rotation
1/65536 turns
Definition animspr.h:118
struct AnimationEntry * entries[4]
its layers; empty ones null
Definition animspr.h:130
u8 count
layers in use, up to the last one present
Definition animspr.h:129
u8 dirty
nonzero redraws its pixels into VRAM when next drawn
Definition animspr.h:125
u16 palette[0x1c0]
The source palette, RGB555: 224 BG colours, then 224 OBJ colours; palette[0] is the backdrop.
Definition palbuf.h:43
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
Definition event_work.h:20
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
s16 psynergyRequest
a field Psynergy to use, as owner << 10 | Psynergy
Definition event_work.h:33
s32 transitionFrames
frames
Definition event_work.h:45
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s16 timer
The parameter its action script reads (a follow distance or an angle to face), the player's frames to...
Definition field_obj.h:109
u8 steeringFlags
ActorSteeringFlag bits.
Definition field_obj.h:92
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
u8 paused
nonzero skips its script and motion, not its update
Definition field_obj.h:93
s32 bounce
The share of its falling speed kept as it bounces on landing, 16.16 fixed point (0x4000 when created)...
Definition field_obj.h:64
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
u8 priorityFlags
ActorPriorityFlag bits, read by the scrolling camera.
Definition field_obj.h:51
s32 terrainHeight
16.16 fixed-point pixels
Definition field_obj.h:38
s32 velocityY
16.16 fixed-point pixels per frame
Definition field_obj.h:53
s32 gravity
Taken off the vertical velocity each frame while it is above the ground, in 16.16 fixed-point pixels ...
Definition field_obj.h:68
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition field_obj.h:40
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
u8 collisionFlags
bits: 7 refuses to move into a solid object | 4 nearer for Psynergy targets | 3 never a talk or Psyne...
Definition field_obj.h:91
s32 velocityZ
16.16 fixed-point pixels per frame
Definition field_obj.h:54
u8 frozen
Nonzero skips steering, terrain, gravity and floating; its velocity still moves it (ScriptMotionObjec...
Definition field_obj.h:104
void(*) update(union FieldObject *object)
Called each frame while the effect is live: the spawner sets BattleFx_UpdateObjectMotionScaleAndLinke...
s32 countdown
Frames until a scene's update hook releases the effect: 20 for Altin Peak's spray,...
A position on the field.
s32 z
16.16 fixed-point pixels
s16 entrance
Definition game_state.h:37
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
u16 flags
REG_DISPCNT bits: objects and the BG1 to BG3 shown.
Definition map_scroll.h:35
A scene entrance: where and facing which way the party arrives, and the camera's bounds there (-1 for...
Definition field_scene.h:54
A scene event: its kind and detail, the trigger it answers, its condition and its value (a message or...
An actor a scene places: its sprite, the condition for placing it, how it behaves,...
Definition field_scene.h:81
A scene's exit region: the box that, while its condition holds, takes the party leader out through it...
The prefix that command handlers read from a field object's 0x70-byte slot.
Definition script.h:16
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
s32 GetMapCellCollision(s32 layer, s32 x, s32 y)
Returns the collision code of a layer's cell at (x, y) in 16.16 pixels.
Definition terrain.c:401
void SetMapCellCollision(u32 layer, s32 x, s32 y, u32 collisionCode)
Sets the collision code of a layer's cell at (x, y) in 16.16 pixels.
Definition terrain.c:422
s32 Map_GetTerrainHeight(s32 layer, s32 x, s32 y)
Returns the ground height of a layer at (x, y) in 16.16 pixels: the height function of the cell's ter...
Definition terrain.c:343
The integer types, TRUE, UNUSED and the fixed-address macros.
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
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldActor actor
struct FieldEffect effect
The patch levels: our groups of the measured changes from the Japanese release.