Alchemy
Loading...
Searching...
No Matches

vale_storm.c

Go to the documentation of this file.
1/// @file
2/// Vale on the stormy night: the paths and doors the party passes as the storm
3/// rages, with Dora and Kyle on the first arrival.
4
5#include "script.h"
6#include "game_state.h"
7#include "unit/import.h"
10#include "unit/object/object.h"
12#include "unit/field/field.h"
14#include "battle.h"
15#include "debug.h"
16#include "field.h"
17#include "game.h"
18#include "graphics.h"
19#include "menu.h"
20#include "minigame.h"
21#include "sound.h"
22#include "system.h"
23#include "types.h"
24#include "callback_scheduler.h"
25#include "field_event.h"
26#include "field_scene.h"
27#include "call.h"
28#include "field_service.h"
29#include "field_obj.h"
30#include "animspr.h"
31#include "text/msg_ids.h"
32#include "resource.h"
33#include "field_effect.h"
34#include "tbs_edition.h"
35#include "b5_context.h"
36#include "objcmd.h"
37#include "global_cells.h"
38#include "vram_tab.h"
39#include "fixed_math.h"
40#include "flags.h"
41#include "songs.h"
42#include "fx_scene.h"
43
44static void Event_DoraSendsIsaacToThePlaza(void);
45static void ValeStorm_ApplyRock11Collision(void);
46static void ValeStorm_ApplyRock12Collision(void);
47static void ValeStorm_ApplyRock13Collision(void);
48static void ValeStorm_ApplyRock14Collision(void);
49static void ValeStorm_MeetVillagerAtExit6(void);
50static void ValeStorm_RunCallOutSequence(void);
52static void ValeStorm_RunRiverSearch(void);
54static void ValeStorm_FlashLightning(void);
55static void ValeStorm_UpdatePulsingGlow(void);
56static void ValeStorm_FlickerGlowOffset(void);
57static void ValeStorm_GaretLeavesIsaac(void);
58static void ValeStorm_RebuildRiverbank(void);
59static void ValeStorm_FlashPaletteAndSpawnEffects(struct FieldActor *actor);
60static void ValeStorm_SpawnEffectPair(struct FieldActor *parent);
62static void ValeStorm_CycleBoulderPalette(void);
64
66
67/// The placed actors, numbered in the order of gValeStorm_Placements; the
68/// elders holding back the Boulder (gValeStorm_BoulderWatchers) follow as 28
69/// to 33.
71 /// Worn out from holding the Boulder: "I... I'll go!", then "It's no use. I
72 /// can't move..."
76 /// Rocks 11 to 14 fall across the paths (FLAG_VALE_STORM_FIRST_ROCK_FELL
77 /// on); 15 to 18 already lie there.
79 ACTOR_BOULDER = ACTOR_FIRST_PLACED + 11, ///< drawn at twice its size
80 /// Runs out of his house and shoves Isaac. "Huh? Isaac?"
82 /// The things Garet struggles to save. "If a rock hits me now, I'll lose
83 /// both my chest and my life."
85 ACTOR_GARET, ///< the young Garet's sprite, 0x13
86 ACTOR_FELIX, ///< in the river
87 /// The pair at the river whom Jenna calls "Mom! Dad!". "Hang on, Felix!
88 /// Help is on the way!"
90 ACTOR_JENNAS_PARENT_B, ///< "Don't let go, Felix!"
91 ACTOR_JENNA, ///< "Oh no! My brother!"
92 ACTOR_BOULDER_GLOW ///< the light around the Boulder as it rolls
93};
94
95/// Vale's place flags this scene keeps while the party is in Vale.
97 /// The villager at the river tried to go for help and could not.
99 /// Garet has said once that they cannot get around a fallen rock.
101 /// Kyle has greeted Isaac at the river. "Oh, Isaac..."
103 /// The party has passed each rock's spot since coming to Vale, so its event
104 /// does not play again.
109};
110
111// Scene flags, cleared on every ordinary entrance:
112// - FLAG_SCENE_TEMP_05: the door of exit 7, from which Dora and Kyle came,
113// stands open.
114// - FLAG_SCENE_TEMP_06: the villager has run out of exit 6's door, leaving it
115// open.
116// - FLAG_SCENE_TEMP_10: the leader is on the upper path, whose collision cells
117// are swapped until the leader steps off it.
118
121
122/// Chooses a new random heading whenever the actor countdown expires.
123static s32
125 struct FieldActor *actor = (struct FieldActor *)interpreter;
126 s32 timer = actor->timer;
127 s32 countdown = (s16)timer;
128
129 if (timer == 0) {
130 actor->facing = Engine_RandomNext();
131 countdown = Math_RemainderUnsigned(Engine_RandomNext(), 20) + 20;
132 actor->timer = countdown;
133 }
134 actor->timer = countdown - 1;
135 return 1;
136}
137
138#include "common/object_pulse.h"
139
140/// Returns where the party appears; entrance 15 is where Dora and Isaac run
141/// in from the south-west of Vale (ValeBabi's exit 21).
144}
145
146const struct SceneRegion *ValeStorm_GetRegions(void) { return NULL; }
147
149
152}
153
154const struct SceneEvent *ValeStorm_GetEvents(void) { return gValeStorm_Events; }
155
156/// Swaps the upper path's collision cells as the leader steps onto it.
157/// Reached by stepping on cell code 15. Sets FLAG_SCENE_TEMP_10,
158/// which ValeStorm_Initialize reads to swap them again.
159static void Event_SetPathCellOverride(void) {
161 Map_CopyCellAttributes(40, 84, 7, 4, 10, 84);
162}
163
164/// Restores the upper path's collision cells as the leader steps off it.
165/// Reached by stepping on cell code 14. Clears FLAG_SCENE_TEMP_10.
168 Map_CopyCellAttributes(40, 89, 7, 4, 10, 84);
169}
170
171#include "common/vale.h"
172
173/// Opens a door and takes exit 11, to ValeInteriors' entrance 1. No event row
174/// names it.
181}
182
183/// Stepping on cell code 2 requests exit 1, which has no table row.
184/// Scene_TakeExit therefore falls back to scene 5, entrance 0 (ValeHome),
185/// using the first exit's scene.
186static void Event_LeaveByExit1(void) {
189}
190
191/// Reached by stepping on cell code 3; takes exit 3, to Kraden's cottage
192/// (ValeKraden's entrance 1).
193static void Event_LeaveByExit3(void) {
196}
197
198/// Reached by stepping on cell code 4; takes exit 4, to Kraden's cottage
199/// (ValeKraden's entrance 2).
200static void Event_LeaveByExit4(void) {
203}
204
205/// Reached by stepping on cell code 5; takes exit 2, to ValeHome's entrance 8.
206/// After the river gathering Garet first leaves Isaac
207/// (ValeStorm_GaretLeavesIsaac).
208static void Event_LeaveByExit2(void) {
213 }
215}
216
217/// Opens the door and goes in.
218/// Reached by walking north into cell code 6; takes exit 5, to Vale's houses
219/// (ValeInteriors' entrance 6).
220static void Event_LeaveByExit5(void) {
226}
227
228/// Isaac's first time at the door of exit 6: a villager runs out and shoves
229/// him; afterwards the door opens as usual. "Huh? Isaac?"
230/// Reached by walking north into cell code 7. The shove plays until
231/// FLAG_VALE_STORM_BUMPED_INTO_VILLAGER or FLAG_VALE_STORM_SECOND_ROCK_FELL is
232/// set, and sets FLAG_SCENE_TEMP_06; otherwise takes exit 6, to
233/// ValeInteriors' entrance 5.
234static void Event_LeaveByExit6(void) {
238 }
243 } else {
247 }
248}
249
250/// Opens the door, unless Dora and Kyle left it open, and goes in.
251/// Reached by walking north into cell code 8; takes exit 7, to the south-west
252/// of Vale (ValeBabi's entrance 6).
253static void Event_LeaveByExit7(void) {
257 }
261}
262
263/// Opens the door and goes in.
264/// Reached by walking north into cell code 9; takes exit 8, to
265/// ValeInteriors' entrance 2.
266static void Event_LeaveByExit8(void) {
272}
273
274/// Opens the door and goes in.
275/// Reached by walking north into cell code 10; takes exit 9, to
276/// ValeInteriors' entrance 1.
277static void Event_LeaveByExit9(void) {
283}
284
285/// Opens the door and goes in.
286/// Reached by walking north into cell code 11; takes exit 10, to
287/// ValeInteriors' entrance 1.
288static void Event_LeaveByExit10(void) {
294}
295
296/// Opens the door and goes in.
297/// Reached by walking north into cell code 12; takes exit 12, to ValeBabi's
298/// entrance 11.
299static void Event_LeaveByExit12(void) {
305}
306
307/// Opens the door and goes in.
308/// Reached by walking north into cell code 13; takes exit 13, to ValeBabi's
309/// entrance 12.
310static void Event_LeaveByExit13(void) {
316}
317
318/// Restores the fallen rocks, the river scene and the Boulder from their
319/// flags, starts the storm, and plays the scene with Dora and Kyle on the
320/// first arrival by entrance 15.
321/// Called by Field_RunScene once the actors are placed. Sets FLAG_VALE_STORM;
322/// after a battle (FLAG_KEEP_PARTY_POSITION) the two doors close again.
323/// Garet, until he joins, is shown struggling with his things.
330 }
331 // Restore the rocks that have already fallen.
333 Actor_SetPosition(11, PIXELS(334), PIXELS(932));
335 }
337 Actor_SetPosition(12, PIXELS(224), PIXELS(872));
339 }
341 Actor_SetPosition(13, PIXELS(64), PIXELS(703));
343 }
345 Actor_SetPosition(14, PIXELS(432), PIXELS(1147));
347 }
348 // All eight rocks block the way.
357 // Garet walks with the party once he has joined.
360 }
361 {
362 struct FieldActor *actor;
363
365 actor->scaleX = 2 * Q16_ONE;
366 actor->scaleY = 2 * Q16_ONE;
367 }
368 // The Boulder lies where it fell, or waits on the mountainside.
371 } else {
373 }
374 // Restore the riverbank cast at the saved stage of the storm.
376 s32 facing;
377 const s32 *table;
380 {
381 struct FieldActor *actor;
382
383 actor = Object_GetById(ACTOR_DORA);
385 actor->facing = facing;
388 actor->work = 1;
390 }
392 {
393 struct FieldActor *actor;
394
396 actor->facing = facing;
398 actor->work = 2;
400 }
402 {
403 struct FieldActor *actor;
404
406 actor->facing = facing;
408 actor->work = 3;
410 }
412 PIXELS(1304));
413 {
414 struct FieldActor *actor;
415
417 actor->facing = facing;
419 actor->work = 4;
421 }
434 }
435 // After the rescue was seen: Kyle and Jenna's parents at the river, Felix
436 // in it.
438 const s32 *table;
442 {
443 struct FieldActor *actor;
444
445 actor = Object_GetById(ACTOR_KYLE);
447 }
453 {
454 struct FieldActor *actor;
455
458 }
463 {
464 struct FieldActor *actor;
465
468 }
473 Engine_ActorSetPosition(17, 0, 0);
474 Engine_ActorSetPosition(18, 0, 0);
475 } else {
476 Engine_ActorSetPosition(17, 0, 0);
477 Engine_ActorSetPosition(18, 0, 0);
478 }
479 // The lightning starts at once, except before Dora and Kyle's scene.
480 if (gGameState.entrance != 15 ||
484 }
487 }
489 Map_CopyCellAttributes(29, 24, 1, 2, 26, 46);
490 Map_CopyCellAttributes(29, 25, 1, 1, 27, 46);
491 Map_CopyCellAttributes(29, 25, 1, 1, 28, 46);
492 Map_CopyCellAttributes(19, 90, 1, 1, 20, 88);
493 Map_CopyCellAttributes(19, 90, 1, 1, 20, 89);
494 {
495 struct FieldActor *actor;
496
498 actor->motionFlags = 0;
499 actor->y.fixed = PIXELS(192);
500 actor->collisionFlags = 8;
502 }
505 gGameState.entrance == 15) {
507 return 0;
508 }
509 // Garet drags his chest out of his house until he joins, then the chest
510 // stands by the door.
517 Actor_WalkTo(ACTOR_GARET, 400, 619);
522 } else {
528 }
534 return 0;
535}
536
537/// Dora and Kyle come out into the storm with Isaac and send him to the plaza
538/// while they go to help. "Kyle... Will they be able to stop the Boulder?"
539/// Called by ValeStorm_Initialize on arrival by entrance 15 until
540/// FLAG_VALE_STORM_SENT_TO_PLAZA is set. Sets it and
541/// FLAG_SCENE_TEMP_05, clears FLAG_SHOW_LOCATION_NAME, and
542/// removes Dora and Kyle.
544 s32 message;
545
550 Engine_TaskWait(60);
551 // The camera looks down on the door of exit 7; Kyle waits outside.
552 Camera_SetSpeed(PIXELS(1) / 4, PIXELS(1) / 32);
553 Camera_MoveTo(PIXELS(316), PIXELS(160), PIXELS(880), 1);
561 // Dora and Isaac come out of the door.
565 Actor_SetSpeed(ACTOR_DORA, PIXELS(4) / 5, PIXELS(2) / 5);
567 Actor_SetSpeed(ACTOR_KYLE, PIXELS(4) / 5, PIXELS(2) / 5);
571 Actor_WalkTo(ACTOR_DORA, 296, 905);
579 // Dora: "Kyle... Will they be able to stop the Boulder?" Kyle: "I don't think
580 // so..." and tells the two to take refuge in the plaza.
581 message = MsgValeKyleAbleStop;
582 Engine_EventSetMessage(message);
594 // "Aren't you coming?" "I need to help evacuate the other villagers."
602 // Dora runs to Kyle: "Let me help you, Kyle!" "It's too dangerous, Dora."
603 Actor_SetSpeed(ACTOR_DORA, PIXELS(3) / 2, PIXELS(3) / 4);
610 // "Isaac is old enough to get to the plaza on his own."
613 // "You can find your way, can't you, Isaac?" She asks again on every no:
614 // "You're a big boy now, Isaac."
615 Engine_EventSetMessage((message + 8));
619 while (Engine_EventChooseYesNo(0, 0) == 1) {
621 Engine_EventSetMessage(MsgValeBigBoyWhy);
623 }
625 // "You know the way--just go south to get to the plaza. Be careful!"
626 Engine_EventSetMessage(MsgValeKnowWayGo);
629 // Kyle and Dora run north toward the Boulder and out of sight.
630 Actor_SetSpeed(ACTOR_KYLE, PIXELS(3) / 2, PIXELS(3) / 4);
631 Actor_WalkTo(ACTOR_KYLE, 297, 750);
643}
644
645/// Walking past: rock 11 falls across the path, and Garet, once with Isaac,
646/// says they cannot get around it.
647/// Reached by stepping on cell code 41 until FLAG_VALE_STORM_FIRST_ROCK_PASSED
648/// is set, which this sets. Sets FLAG_VALE_STORM_FIRST_ROCK_FELL as the rock
649/// falls; with Garet along, before the river gathering, his first comment on
650/// any rock sets FLAG_VALE_STORM_GARET_SAW_BLOCKED_PATH.
651static void Event_Rock11Falls(void) {
652 struct FieldActor *rock;
653 struct FieldActor *leader;
654 s32 targetHeight;
655 s32 walkZ;
656 struct AnimationObject *rockSprite;
657
659 } else {
662 rock = Object_GetById(11);
663 rockSprite = rock->sprite;
664 // A rumble (SE_141, SE_145), then the rock bounces down from the east.
667 Engine_TaskWait(40);
670 rockSprite->image.priority = 1;
671 Actor_SetPosition(11, PIXELS(473), PIXELS(932));
672 rock->speed = PIXELS(3) / 2;
673 rock->acceleration = PIXELS(3) / 2;
674 targetHeight = (rock->y.fixed + PIXELS(240));
675 rock->y.fixed += PIXELS(240);
676 rock->targetY = targetHeight;
677 rock->bounce = 0x6666;
678 Actor_WalkToAndWait(11, 344, 932);
679 rockSprite->image.priority = 3;
682 // It lands (SE_289) and the shaking dies down.
684 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
688 }
689 // The rock now blocks the path.
695 // Garet comes out beside Isaac on whichever side of the rock he
696 // stands.
698 if (leader->y.fixed > PIXELS(128)) {
699 walkZ = 0x396;
702 } else {
704 }
706 }
707 }
708 }
710 }
711}
712
713/// Applies the collision cells left by rock 11.
714/// Called by Event_Rock11Falls and, once the rock has fallen, by
715/// ValeStorm_Initialize.
717 Map_CopyCellAttributes(29, 64, 1, 1, 21, 57);
718 Map_CopyCellAttributes(29, 64, 1, 1, 21, 58);
719 Map_CopyCellAttributes(29, 64, 1, 1, 22, 58);
720 Map_CopyCellAttributes(29, 64, 1, 1, 20, 58);
721 Map_CopyCellAttributes(28, 20, 1, 1, 20, 57);
722}
723
724/// Walking past: rock 12 falls down the path.
725/// Reached by stepping on cell code 42; the second rock, as Event_Rock11Falls
726/// does the first, with FLAG_VALE_STORM_SECOND_ROCK_FELL and
727/// FLAG_VALE_STORM_SECOND_ROCK_PASSED.
728static void Event_Rock12Falls(void) {
729 struct FieldActor *rock;
730 struct FieldActor *leader;
731 s32 targetHeight;
732
734 } else {
737 rock = Object_GetById(12);
738 // A rumble, then the rock rolls down the slope from the north-east.
741 Engine_TaskWait(40);
743 Actor_SetPosition(12, PIXELS(381), PIXELS(808));
744 rock->speed = PIXELS(3) / 2;
745 rock->acceleration = PIXELS(3) / 2;
746 targetHeight = (rock->y.fixed + PIXELS(256));
747 rock->y.fixed += PIXELS(256);
748 rock->targetY = targetHeight;
749 rock->bounce = 0x8000;
750 Actor_WalkToAndWait(12, 290, 833);
752 Actor_WalkToAndWait(12, 258, 852);
754 Actor_WalkToAndWait(12, 224, 872);
756 // It lands (SE_289) and the shaking dies down.
758 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
762 }
768 // Garet comes out beside Isaac on whichever side of the rock he
769 // stands.
771 if (leader->y.fixed > PIXELS(128)) {
774 } else {
777 }
779 }
780 }
781 }
783 }
784}
785
786/// Applies the collision cells left by rock 12.
787/// Called by Event_Rock12Falls and, once the rock has fallen, by
788/// ValeStorm_Initialize.
790 Map_CopyCellAttributes(29, 23, 1, 1, 15, 53);
791 Map_CopyCellAttributes(29, 23, 1, 1, 14, 53);
792 Map_CopyCellAttributes(29, 23, 1, 1, 13, 53);
793 Map_CopyCellAttributes(26, 20, 2, 1, 14, 52);
794 Map_CopyCellAttributes(25, 21, 1, 1, 13, 54);
795 Map_CopyCellAttributes(25, 21, 1, 1, 15, 54);
796 Map_CopyCellAttributes(14, 53, 1, 1, 14, 54);
797 Map_CopyCellAttributes(13, 55, 1, 1, 15, 55);
798}
799
800/// Walking past: rock 13 falls down the path.
801/// Reached by stepping on cell code 43; the third rock, as Event_Rock11Falls
802/// does the first, with FLAG_VALE_STORM_THIRD_ROCK_FELL and
803/// FLAG_VALE_STORM_THIRD_ROCK_PASSED.
804static void Event_Rock13Falls(void) {
808 struct FieldActor *actor = Actor_Get(13);
809 struct FieldActor *leader = Actor_Get(ACTOR_PARTY_LEADER);
810 u16 priority = leader->sprite->image.priority;
811 u8 flags = leader->priorityFlags;
812
813 // A rumble, then the rock drops in from the west while Isaac is drawn
814 // behind it.
817 Engine_TaskWait(40);
821 Actor_SetPosition(13, 0, PIXELS(703));
822 actor->speed = PIXELS(3) / 2;
823 actor->acceleration = PIXELS(3) / 2;
824 actor->y.fixed += PIXELS(80);
825 actor->targetY = actor->y.fixed;
826 actor->bounce = 0x8000;
827 Actor_WalkToAndWait(13, 64, 703);
829 // It lands (SE_289); Isaac's drawing priority is put back.
831 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
837 leader->priorityFlags = flags;
838 }
844 // Garet comes out beside Isaac on whichever side of the rock he
845 // stands.
846 if (Actor_Get(ACTOR_PARTY_LEADER)->z.fixed <= 0x2b4ffff) {
849 } else {
852 }
854 }
855 }
856 }
858 }
859}
860
861/// Applies the collision cells left by rock 13.
862/// Called by Event_Rock13Falls and, once the rock has fallen, by
863/// ValeStorm_Initialize.
865 Map_CopyCellAttributes(29, 22, 1, 1, 3, 42);
866 Map_CopyCellAttributes(29, 21, 1, 1, 2, 42);
867 Map_CopyCellAttributes(29, 21, 1, 1, 4, 42);
868 Map_CopyCellAttributes(23, 20, 3, 1, 2, 43);
869}
870
871/// Walking past: rock 14 falls down the path.
872/// Reached by stepping on cell code 44; the fourth rock, as Event_Rock11Falls
873/// does the first, with FLAG_VALE_STORM_FOURTH_ROCK_FELL and
874/// FLAG_VALE_STORM_FOURTH_ROCK_PASSED.
875static void Event_Rock14Falls(void) {
876 struct FieldActor *rock;
877 struct FieldActor *leader;
878 s32 targetHeight;
879
881 } else {
884 rock = Object_GetById(14);
885 // A rumble, then the rock rolls in from the east.
888 Engine_TaskWait(40);
890 Actor_SetPosition(14, PIXELS(474), PIXELS(1147));
891 rock->speed = PIXELS(1);
892 rock->acceleration = PIXELS(1);
893 targetHeight = (rock->y.fixed + PIXELS(72));
894 rock->y.fixed += PIXELS(72);
895 rock->targetY = targetHeight;
896 rock->bounce = 0x8000;
897 Engine_ActorWalkToAndWait(14, 432, 1147);
899 // It lands (SE_289) and the shaking dies down.
901 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
905 }
911 // Garet comes out beside Isaac on whichever side of the rock he
912 // stands.
914 if (leader->z.fixed <= 0x479ffff) {
917 } else {
920 }
922 }
923 }
924 }
926 }
927}
928
929/// Applies the collision cells left by rock 14.
930/// Called by Event_Rock14Falls and, once the rock has fallen, by
931/// ValeStorm_Initialize.
933 Map_CopyCellAttributes(29, 20, 1, 1, 26, 71);
934 Map_CopyCellAttributes(29, 20, 1, 1, 26, 70);
935 Map_CopyCellAttributes(29, 20, 1, 1, 27, 70);
936 Map_CopyCellAttributes(28, 21, 1, 1, 28, 71);
937 Map_CopyCellAttributes(28, 22, 1, 1, 27, 72);
938}
939
940/// Stops the leader at exit 6 for the first villager conversation.
941/// The villager runs out of the door, knocks Isaac back and runs off to the
942/// plaza. "Huh? Isaac?" Called by Event_LeaveByExit6. Sets
943/// FLAG_VALE_STORM_BUMPED_INTO_VILLAGER.
945 s32 message;
946
961 message = MsgValeHuh;
962 Engine_EventSetMessage(message);
967 Engine_EventSetMessage((message + 4));
973}
974
975/// Isaac hears Garet struggling with his things. "Ugh... Hrnghhh..."
976/// Reached by stepping on cell code 30, until Garet has joined. Sets
977/// FLAG_VALE_STORM_HEARD_GARET.
978static void Event_HearGaretStruggling(void) {
982 Engine_EventSetMessage(MsgValeUghHrnghhh);
992 }
993 }
994}
995
996/// Walking away from him, Garet calls after Isaac, asking whether he will just
997/// leave him there.
998/// Reached by stepping on cell code 31 once Isaac has heard Garet and before
999/// Garet joins; ValeStorm_RunCallOutSequence brings him along.
1005 Engine_EventWait(20);
1006 Engine_EventSetMessage(MsgValeDontLeaveMeHere);
1009 }
1010}
1011
1012/// Talking to Garet: whether to leave his things behind, or, after the river,
1013/// the Boulder.
1014/// Reached by talking to Garet (actor 22): before he joins,
1015/// ValeStorm_RunCallOutSequence brings him along.
1016static void Event_TalkToGaret(void) {
1020 Engine_EventWait(20);
1021 Engine_EventSetMessage(MsgValeBoulderNeedGet);
1025 } else {
1028 Engine_EventSetMessage(MsgValeWantDumpStuff);
1031 }
1032 }
1033}
1034
1035/// Resolves the belongings conversation and brings Garet into the party.
1036/// Called by Event_GaretCallsAfterIsaac and Event_TalkToGaret. Sets
1037/// FLAG_VALE_STORM_GARET_JOINED and puts Garet in the party.
1039 struct FieldActor *leader;
1040 s32 agreedToLeaveBelongings;
1041
1044 agreedToLeaveBelongings = 0;
1045 if (Engine_EventChooseYesNo(0, 0) == 0) {
1046 Engine_EventSetMessage(MsgValeThinkForgetThings);
1047 agreedToLeaveBelongings = 1;
1048 } else {
1049 Engine_EventSetMessage(MsgValeRockHitsLose);
1050 }
1051 Engine_EventWait(20);
1056 Engine_EventWait(40);
1058 Engine_EventWait(20);
1060 if (agreedToLeaveBelongings != 0) {
1061 Engine_EventSetMessage(MsgValeKnowRightOk);
1062 } else {
1063 Engine_EventSetMessage(MsgValeRightDitchStuff);
1064 }
1068 if (leader != 0) {
1070 leader->z.part.pixel);
1071 }
1076}
1077
1078/// Garet catches up and joins Isaac. "Hey! Isaac!"
1079/// Reached by stepping on cell code 32 until Garet has joined. Sets
1080/// FLAG_VALE_STORM_GARET_JOINED and puts Garet in the party.
1081static void Event_GaretJoinsIsaac(void) {
1082 struct FieldActor *actor;
1083 s32 message;
1084
1088 message = MsgValeHey;
1089 Engine_EventSetMessage(message);
1093 Camera_SetSpeed(PIXELS(2) / 5, PIXELS(1) / 20);
1094 Camera_MoveTo(PIXELS(256), -1, PIXELS(588), 1);
1098 Engine_EventWait(30);
1101 actor = Actor_Get(ACTOR_GARET);
1102 actor->scaleY = Q16_ONE;
1104 Engine_EventWait(20);
1106 Engine_EventWait(40);
1108 Engine_EventSetMessage((message + 5));
1116 if (actor != 0) {
1117 Actor_SetDestination(ACTOR_GARET, actor->x.part.pixel,
1118 actor->z.part.pixel);
1119 }
1126 }
1127}
1128
1129/// Garet warns where the path north leads. It leads to Mt. Aleph.
1130/// Reached by stepping on cell code 33, every time; Isaac is walked back south.
1131static void Event_WarnAboutMtAleph(void) {
1132 struct FieldActor *leader;
1133 struct FieldActor *initialLeader;
1134
1136 initialLeader = Actor_Get(ACTOR_PARTY_LEADER);
1137 if (initialLeader != NULL) {
1138 Actor_SetPosition(ACTOR_GARET, initialLeader->x.fixed,
1139 initialLeader->z.fixed);
1140 }
1144 Engine_EventWait(30);
1145 Engine_EventSetMessage(MsgValeNorthLeadsToMtAleph);
1148 Engine_EventWait(10);
1150 Engine_EventWait(20);
1155 if (leader != 0) {
1156 Actor_SetDestination(ACTOR_GARET, leader->x.part.pixel,
1157 leader->z.part.pixel);
1158 }
1163}
1164
1165/// Brings Garet out to discuss a blocked path, then returns him to Isaac.
1166/// Called by the four rock events; x and y are the pixels where Garet stands.
1168 struct FieldActor *leaderAtStart;
1169 s32 speed = PIXELS(1);
1170 s32 acceleration = (PIXELS(1) / 2);
1171 struct FieldActor *leaderAtEnd;
1172
1173 leaderAtStart = Object_GetById(ACTOR_PARTY_LEADER);
1174 if (leaderAtStart != 0) {
1176 leaderAtStart->z.fixed);
1177 }
1181 Engine_EventWait(20);
1183 Engine_EventWait(40);
1184 Engine_EventSetMessage(MsgValeCantGetAroundThisRock);
1190 leaderAtEnd = Object_GetById(ACTOR_PARTY_LEADER);
1191 if (leaderAtEnd != 0) {
1192 Engine_ActorSetDestination(ACTOR_GARET, leaderAtEnd->x.part.pixel,
1193 leaderAtEnd->z.part.pixel);
1194 }
1197}
1198
1199/// The Boulder falls toward Vale while the elders hold it with their Psynergy.
1200/// "Ahhh! The Boulder! It's falling!"
1201static void Event_WatchBoulderFall(void) {
1202 u32 i;
1203 struct FieldActor *movingActor;
1204 s32 *shakeShift;
1205 struct FieldActor *actor;
1206 SchedulerCallback updateEffects;
1207 SchedulerCallback cycleBoulderPalette;
1208 s32 boulderHeight;
1209
1214 Engine_TaskWait(1);
1217 Engine_EventWait(30);
1220 Engine_EventWait(30);
1222 if (actor != NULL) {
1223 Actor_SetPosition(ACTOR_GARET, actor->x.fixed, actor->z.fixed);
1224 }
1234 Engine_EventWait(40);
1237 Engine_EventWait(20);
1240 Engine_EventWait(40);
1241 // Show the actors holding back the boulder.
1246 Actor_Get(30)->scaleX = -Q16_ONE;
1251 Engine_EventSetMessage(MsgValeTheBoulderIsFalling);
1252 Event_ShowMessageAndWait(28, 0, 20);
1255 Camera_SetSpeed(PIXELS(4), PIXELS(1) / 2);
1256 Camera_MoveTo(PIXELS(112), -1, PIXELS(331), 1);
1258 for (i = 0; i < 40; i++) {
1263 Engine_TaskWait(1);
1264 }
1265 // Run the palette effects while the boulder rocks back and forth.
1266 shakeShift = &sShakeShift;
1268 sShakeDone = 0;
1269 *shakeShift = 0;
1271 cycleBoulderPalette = ValeStorm_CycleBoulderPalette;
1273 Engine_EventWait(40);
1274 *shakeShift = 1;
1275 Engine_EventWait(30);
1277 movingActor = Actor_Get(ACTOR_BOULDER);
1278 boulderHeight = movingActor->y.fixed + PIXELS(64);
1279 movingActor->y.fixed = boulderHeight;
1280 movingActor->targetY = boulderHeight;
1281 Actor_SetSpeed(ACTOR_BOULDER, PIXELS(4) / 5, PIXELS(2) / 5);
1287 *shakeShift = 0;
1288 Actor_SetSpeed(ACTOR_BOULDER, PIXELS(2) / 5, PIXELS(1) / 5);
1293 *shakeShift = 2;
1294 Actor_SetSpeed(ACTOR_BOULDER, PIXELS(4) / 5, PIXELS(2) / 5);
1299 *shakeShift = 0;
1300 Actor_SetSpeed(ACTOR_BOULDER, PIXELS(2) / 5, PIXELS(1) / 5);
1305 *shakeShift = 2;
1306 Actor_SetSpeed(ACTOR_BOULDER, PIXELS(4) / 5, PIXELS(2) / 5);
1311 *shakeShift = 1;
1312 Engine_EventWait(20);
1313 Actor_SetAttachedEffect(32, 0x102);
1315 Event_ShowMessage(31, 0);
1316 Actor_ShowEmote(33, EMOTE_IN_FRONT | 0, 0);
1318 Event_ShowMessageAndWait(28, 0, 40);
1319 Actor_SetAttachedEffect(30, 0x102);
1321 Event_ShowMessage(30, 0);
1322 // Stop the final actor effect and return the camera to Isaac.
1323 sShakeDone = 1;
1325 Engine_TaskWait(1);
1326 Actor_SetChildValue(29, 0);
1327 Actor_ShowEmote(29, EMOTE_IN_FRONT | 5, 20);
1332 Actor_ShowEmote(29, EMOTE_IN_FRONT | 0, 0);
1334 Engine_ActorJump(29, 4, 40);
1336 Engine_EventWait(10);
1337 Event_ShowMessageAndWait(29, 0, 20);
1339 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1340 Camera_SetSpeed(PIXELS(6), PIXELS(3) / 4);
1341 Camera_MoveTo(PIXELS(84), -1, PIXELS(564), 1);
1345 Engine_EventWait(20);
1347 Engine_EventWait(30);
1348 Scheduler_RemoveCallback(updateEffects);
1349 Scheduler_RemoveCallback(cycleBoulderPalette);
1352 Engine_EventWait(20);
1356 Engine_EventWait(20);
1358 movingActor = Object_GetById(ACTOR_PARTY_LEADER);
1359 if (movingActor != 0) {
1360 Actor_SetDestination(ACTOR_GARET, movingActor->x.part.pixel,
1361 movingActor->z.part.pixel);
1362 }
1373 }
1374}
1375
1376/// Applies an animation parameter to each active entry of a single sprite.
1377static void Storm_SetActorFrameMode(struct FieldActor *actor, s32 mode) {
1378 if ((actor->spriteStorageKind & 0xf) == 1) {
1379 struct AnimationObject *animation = actor->sprite;
1380 s32 animationParameter = mode - 1;
1381 u8 count;
1382 if (mode == 0) {
1383 animationParameter =
1385 (actor->spriteStorageKind & 0xf)];
1386 }
1387 count = animation->count;
1388 if (count != 0) {
1389 struct AnimationEntry **entries = animation->entries;
1390 s32 remainingEntries = count;
1391 do {
1392 struct AnimationEntry *entry = *entries++;
1393 if (entry != NULL && entry->script != NULL) {
1394 entry->param = animationParameter;
1395 }
1396 remainingEntries--;
1397 } while (remainingEntries != 0);
1398 }
1399 animation->dirty = 1;
1400 }
1401}
1402
1403/// Alternates four actors between the normal and flashing parameters.
1405 if (((gFrameCount >> sShakeShift) & 3) != 0) {
1410 } else {
1415 }
1416}
1417
1418/// At the river, Jenna cries out for her brother as the villagers try to save
1419/// Felix. "Oh no! My brother!"
1420static void Event_WitnessRiverRescue(void) {
1421 const s32 *pulseScript;
1422
1424 return;
1425 }
1430 {
1431 struct FieldActor *actor;
1432 s32 pulseDelay;
1433 actor = Object_GetById(ACTOR_KYLE);
1434 pulseDelay = Math_RemainderUnsigned(Engine_RandomNext(), 90) + 60;
1435 pulseScript = gValeStorm_ActorEightScript;
1436 actor->timer = pulseDelay;
1437 Actor_SetActionScript(ACTOR_KYLE, pulseScript);
1438 }
1444 {
1445 struct FieldActor *actor;
1446 s32 pulseDelay;
1448 pulseDelay = Math_RemainderUnsigned(Engine_RandomNext(), 90) + 60;
1449 actor->timer = pulseDelay;
1451 }
1455 {
1456 struct FieldActor *actor;
1457 s32 pulseDelay;
1459 pulseDelay = Math_RemainderUnsigned(Engine_RandomNext(), 90) + 60;
1460 actor->timer = pulseDelay;
1462 }
1468 Engine_TaskWait(3);
1469 Engine_EventSetMessage(MsgValeNoBrother);
1473 {
1474 struct FieldActor *leader;
1476 if (leader != 0) {
1477 Engine_ActorSetPosition(ACTOR_GARET, leader->x.fixed, leader->z.fixed);
1478 }
1479 }
1480 Actor_WalkToAndWait(ACTOR_GARET, 132, 1094);
1482 Engine_EventWait(40);
1485 Camera_SetSpeed(PIXELS(4), PIXELS(1) / 2);
1486 Camera_MoveTo(PIXELS(216), -1, PIXELS(1232), 1);
1488 Engine_EventWait(40);
1496 Camera_SetSpeed(PIXELS(3), PIXELS(3) / 8);
1497 Camera_MoveTo(PIXELS(232), -1, PIXELS(1253), 1);
1499 Engine_EventWait(20);
1503 Engine_EventWait(10);
1505 Engine_EventWait(60);
1508 {
1509 struct FieldActor *actor;
1510 actor = Object_GetById(ACTOR_KYLE);
1511 actor->scaleX = Q16_ONE;
1512 actor->scaleY = Q16_ONE;
1513 }
1515 {
1516 struct FieldActor *actor;
1518 actor->scaleX = Q16_ONE;
1519 actor->scaleY = Q16_ONE;
1520 }
1522 {
1523 struct FieldActor *actor;
1525 actor->scaleX = Q16_ONE;
1526 actor->scaleY = Q16_ONE;
1527 }
1533 Camera_SetSpeed(PIXELS(3) / 5, PIXELS(3) / 40);
1534 Camera_MoveTo(PIXELS(216), -1, PIXELS(1232), 1);
1538 Engine_EventWait(60);
1546 Engine_EventWait(90);
1547 Camera_MoveTo(PIXELS(232), -1, PIXELS(1253), 1);
1550 Engine_TaskWait(1);
1552 {
1553 struct FieldActor *actor;
1554 actor = Object_GetById(ACTOR_FELIX);
1555 actor->velocityY = PIXELS(2);
1556 }
1559 Engine_EventWait(20);
1561 Engine_EventWait(20);
1562 Engine_CameraSetSpeed(PIXELS(8) / 5, PIXELS(1) / 5);
1563 Engine_CameraMoveTo(PIXELS(216), -1, PIXELS(1232), 1);
1566 Engine_EventWait(20);
1569 Engine_EventWait(10);
1572 {
1573 struct FieldActor *actor;
1576 }
1577 {
1578 struct FieldActor *actor;
1579 actor = Object_GetById(ACTOR_JENNA);
1581 }
1583 Actor_SetSpeed(ACTOR_JENNA, PIXELS(3) / 5, PIXELS(3) / 10);
1585 Actor_MoveToAndWait(ACTOR_JENNA, 227, 1189);
1586 {
1587 struct FieldActor *actor;
1590 }
1596 0, 10);
1623 Engine_EventWait(20);
1631 Engine_EventWait(20);
1646 Engine_EventWait(20);
1652 Engine_EventWait(20);
1655 // Search both river paths before asking the children to help.
1659}
1660
1661/// Sends the searchers along the river and asks Isaac to help.
1662static void ValeStorm_RunRiverSearch(void) {
1663 struct FieldActor *villager;
1664 s32 random;
1665 const s32 *script;
1666 s32 northMessage;
1667 s32 helpMessage;
1668 struct FieldActor *leader;
1669
1680 Engine_EventWait(20);
1681 Camera_SetSpeed(PIXELS(1), PIXELS(1) / 8);
1682 Camera_MoveTo(PIXELS(134), -1, PIXELS(1195), 1);
1683 Actor_SetSpeed(ACTOR_JENNA, PIXELS(8) / 5, PIXELS(4) / 5);
1684 Actor_SetSpeed(ACTOR_DORA, PIXELS(8) / 5, PIXELS(4) / 5);
1689 Engine_EventWait(10);
1690 Actor_WalkToAndWait(ACTOR_DORA, 149, 1175);
1700 villager = Actor_Get(ACTOR_KYLE);
1701 random = Engine_RandomNext();
1702 villager->timer = (Math_RemainderUnsigned(random, 90) + 60);
1703 villager = Actor_Get(ACTOR_JENNAS_PARENT_A);
1704 random = Engine_RandomNext();
1705 villager->timer = (Math_RemainderUnsigned(random, 90) + 60);
1706 villager = Actor_Get(ACTOR_JENNAS_PARENT_B);
1707 random = Engine_RandomNext();
1708 villager->timer = (Math_RemainderUnsigned(random, 90) + 60);
1714 Engine_EventWait(10);
1717 Engine_EventWait(30);
1719 Camera_MoveTo(PIXELS(112), -1, PIXELS(1225), 1);
1722 Engine_EventWait(20);
1725 Engine_EventWait(20);
1727 Engine_EventWait(40);
1732 Engine_EventWait(40);
1733 northMessage = MsgValeGoLookNorth;
1734 Engine_EventSetMessage(northMessage);
1740 Engine_EventWait(30);
1743 Engine_EventWait(40);
1744 Camera_SetSpeed(PIXELS(2), PIXELS(1) / 4);
1745 Camera_MoveTo(PIXELS(105), -1, PIXELS(1086), 1);
1752 Actor_WalkToAndWait(ACTOR_DORA, 105, 1086);
1756 if (Engine_EventChooseYesNo(0, 0) == 0) {
1758 Engine_EventSetMessage((northMessage + 4));
1759 } else {
1761 Engine_EventSetMessage((northMessage + 5));
1762 }
1766 helpMessage = MsgValeDontSupposeTwo;
1767 Engine_EventSetMessage(helpMessage);
1769 if (Engine_EventChooseYesNo(0, 0) == 0) {
1771 Engine_EventSetMessage((helpMessage + 1));
1777 Engine_EventWait(40);
1778 } else {
1782 Engine_EventSetMessage((helpMessage + 2));
1784 }
1786 Engine_EventWait(90);
1788 Engine_EventWait(40);
1791 Engine_EventWait(20);
1793 leader = Actor_Get(ACTOR_PARTY_LEADER);
1794 if (leader != NULL) {
1795 Actor_SetDestination(ACTOR_GARET, leader->x.part.pixel,
1796 leader->z.part.pixel);
1797 }
1800}
1801
1802/// A villager at the river talks of rescuing Felix.
1805 const s32 *pulseScript;
1806
1809 Engine_EventWait(10);
1812 Engine_EventSetMessage(MsgValeTwoDontEnough);
1814 } else {
1815 Engine_EventSetMessage(MsgValeOh);
1820 }
1823 Engine_EventWait(10);
1824 {
1825 struct FieldActor *villager;
1826 s32 pulseDelay;
1827 villager = Object_GetById(ACTOR_KYLE);
1828 pulseDelay = Math_RemainderUnsigned(Engine_RandomNext(), 90) + 60;
1829 pulseScript = gValeStorm_ActorEightScript;
1830 villager->timer = pulseDelay;
1831 Actor_SetActionScript(ACTOR_KYLE, pulseScript);
1832 }
1833 Engine_EventWait(20);
1836}
1837
1838/// Jenna comes back to the river, and the scene ends with the Boulder sweeping
1839/// down it. "Mom! Dad! We're back!"
1841 struct FieldActor *leader;
1842 struct FieldActor *actor;
1843 s32 automaticPriority;
1844 struct AnimationObject *sprite;
1845
1847 } else {
1849 } else {
1857 if (actor != 0) {
1859 }
1860 Actor_WalkToAndWait(ACTOR_GARET, 235, 1367);
1863 if (actor != 0) {
1865 }
1866 Actor_WalkToAndWait(ACTOR_JENNA, 199, 1367);
1871 sprite = actor->sprite;
1873 sprite->image.priority = 1;
1875 sprite = leader->sprite;
1877 sprite->image.priority = 2;
1879 if (actor != 0) {
1881 actor->z.fixed);
1882 }
1887 Engine_EventSetMessage(MsgValeMomDadBack);
1893 Engine_CameraSetSpeed(PIXELS(6) / 5, PIXELS(3) / 20);
1894 Camera_MoveTo(PIXELS(101), -1, PIXELS(1197), 1);
1895 Actor_SetSpeed(ACTOR_DORA, PIXELS(7) / 5, PIXELS(7) / 10);
1897 Engine_EventWait(60);
1898 Engine_CameraSetSpeed(PIXELS(3) / 5, PIXELS(3) / 40);
1899 Camera_MoveTo(PIXELS(187), -1, PIXELS(1328), 1);
1901 Engine_EventWait(40);
1907 Camera_MoveTo(PIXELS(221), -1, PIXELS(1385), 1);
1911 Engine_CameraMoveTo(PIXELS(182), -1, PIXELS(1360), 1);
1914 Engine_EventWait(30);
1916 Engine_EventWait(10);
1930 Engine_EventWait(40);
1936 Engine_EventWait(20);
1941 automaticPriority = ACTOR_PRIORITY_AUTOMATIC;
1943 leader->priorityFlags |= automaticPriority;
1945 actor->priorityFlags |= automaticPriority;
1949 }
1950 }
1951}
1952
1953/// Places an actor and its motion targets at the supplied coordinates.
1954static __inline__ void ValeStorm_PlaceActor(struct FieldActor *object,
1955 s32 horizontalPosition,
1956 s32 groundPosition) {
1957 object->x.fixed = horizontalPosition;
1958 object->y.fixed = horizontalPosition;
1959 object->targetX = horizontalPosition;
1960 object->targetY = horizontalPosition;
1961 object->z.fixed = groundPosition;
1962 object->targetZ = groundPosition;
1963}
1964
1965/// Shakes the scene at the impact cue and waits for the beat.
1966static __inline__ void ValeStorm_PlayImpactBeat(s32 shakeAmplitude,
1967 s32 frames) {
1968 Map_SetShake(shakeAmplitude, shakeAmplitude, Q16_ONE);
1970 Event_Wait(frames);
1971}
1972
1973/// Follows the boulder downriver, then restores the riverbank actors.
1975 struct AnimationObject *actorVisual;
1976 struct AnimationObject *groupVisual;
1977 struct FieldActor *actor;
1978 struct FieldActor *lookingActor;
1979 struct FieldActor *groupActor;
1980 struct FieldActor *currentActor;
1981 u32 random;
1982 const s32 *entryActions;
1983 s32 stoppedVelocity;
1984 u8 stoppedMotion;
1985 const s32 *lookAroundActions;
1986 s32 resetValue;
1987 const s32 *departureActions;
1988
1989 actor = Actor_Get(ACTOR_BOULDER);
1990 groupActor = Actor_Get(ACTOR_BOULDER_GLOW);
1991 actorVisual = actor->sprite;
1992 groupVisual = groupActor->sprite;
1993 Camera_SetSpeed(PIXELS(1), PIXELS(1) / 8);
1994 Camera_MoveTo(PIXELS(110), -1, PIXELS(1419), 1);
1996 Actor_SetSpeed(ACTOR_JENNA, PIXELS(6) / 5, PIXELS(3) / 5);
1998 Actor_SetSpeed(ACTOR_GARET, PIXELS(6) / 5, PIXELS(3) / 5);
1999 // Bring the group to the riverbank as the lightning subsides.
2000 entryActions = gValeStorm_ArriveScript;
2002 Event_Wait(10);
2003 Actor_SetActionScript(ACTOR_JENNA, entryActions);
2005 Event_Wait(10);
2007 Event_Wait(10);
2009 Actor_SetActionScript(ACTOR_GARET, entryActions);
2010 Event_Wait(128);
2012 Camera_MoveTo(PIXELS(174), -1, PIXELS(1428), 1);
2013 Event_Wait(104);
2014 Camera_MoveTo(PIXELS(153), -1, PIXELS(1325), 1);
2015 Actor_WalkToAndWait(ACTOR_DORA, 158, 1272);
2024 Event_Wait(60);
2032 Event_Wait(20);
2033 lookingActor = Actor_Get(ACTOR_PARTY_LEADER);
2034 random = Random_Next();
2035 random = Math_RemainderUnsigned(random, 20) + 20;
2036 lookingActor->timer = random;
2037 stoppedVelocity = 0;
2038 stoppedMotion = 0;
2039 lookingActor = Actor_Get(ACTOR_GARET);
2040 random = Random_Next();
2041 lookingActor->timer = (Math_RemainderUnsigned(random, 20) + 20);
2042 lookingActor = Actor_Get(ACTOR_JENNA);
2043 random = Random_Next();
2044 lookingActor->timer = (Math_RemainderUnsigned(random, 20) + 20);
2045 lookingActor = Actor_Get(ACTOR_EXHAUSTED_VILLAGER);
2046 random = Random_Next();
2047 lookingActor->timer = (Math_RemainderUnsigned(random, 20) + 20);
2048 lookingActor = Actor_Get(ACTOR_DORA);
2049 random = Random_Next();
2050 lookingActor->timer = (Math_RemainderUnsigned(random, 20) + 20);
2051 lookAroundActions = gValeStorm_LookAroundScript;
2052 Actor_SetActionScript(ACTOR_DORA, lookAroundActions);
2053 Event_Wait(30);
2054 Actor_SetActionScript(ACTOR_PARTY_LEADER, lookAroundActions);
2055 Actor_SetActionScript(ACTOR_JENNA, lookAroundActions);
2056 Actor_SetActionScript(ACTOR_GARET, lookAroundActions);
2058 Event_Wait(10);
2062 Event_Wait(120);
2065 Event_Wait(60);
2068 Event_Wait(60);
2071 Event_Wait(60);
2074 Event_Wait(1);
2075 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
2077 Camera_MoveTo(PIXELS(217), -1, PIXELS(1084), 1);
2080 Task_Wait(40);
2081 // Stage the boulder and its glow for the downriver camera shot.
2083 currentActor = Actor_Get(ACTOR_BOULDER);
2084 Actor_SetSpriteFlags(currentActor, 0);
2085 currentActor = Actor_Get(ACTOR_BOULDER_GLOW);
2086 Actor_SetSpriteFlags(currentActor, 0);
2087 groupActor->scaleX = 0xcccc;
2088 groupActor->scaleY = 0xcccc;
2090 groupVisual->image.priority = 1;
2091 ValeStorm_PlaceActor(actor, PIXELS(200), PIXELS(898));
2092 actor->motionFlags = stoppedMotion;
2094 actorVisual->image.priority = 0;
2095 currentActor = Camera_GetEventObject();
2096 currentActor->targetX = ACTOR_NO_TARGET;
2097 currentActor = Camera_GetEventObject();
2098 currentActor->targetY = ACTOR_NO_TARGET;
2099 currentActor = Camera_GetEventObject();
2100 currentActor->targetZ = ACTOR_NO_TARGET;
2101 currentActor = Camera_GetEventObject();
2102 currentActor->velocityX = stoppedVelocity;
2103 currentActor = Camera_GetEventObject();
2104 currentActor->velocityY = stoppedVelocity;
2105 currentActor = Camera_GetEventObject();
2106 currentActor->velocityZ = stoppedVelocity;
2107 Task_Wait(1);
2108 Camera_MoveTo(PIXELS(247), PIXELS(128), PIXELS(917), 0);
2110 Task_Wait(1);
2111 ColorBuffer_ApplyTarget(0x10003, 1);
2112 ColorBuffer_ApplyTarget(0x10000, 2);
2114 Task_Wait(30);
2115 // Follow the boulder script until its eighth movement phase.
2119 Camera_SetSpeed(PIXELS(2), PIXELS(3) / 100);
2120 Camera_MoveTo(PIXELS(175), PIXELS(96), PIXELS(1086), 1);
2121 do {
2122 Task_Wait(1);
2123 } while ((s16)actor->work != 8);
2126 Task_Wait(60);
2128 currentActor = Camera_GetEventObject();
2129 currentActor->targetX = ACTOR_NO_TARGET;
2130 currentActor = Camera_GetEventObject();
2131 currentActor->targetY = ACTOR_NO_TARGET;
2132 currentActor = Camera_GetEventObject();
2133 currentActor->targetZ = ACTOR_NO_TARGET;
2134 resetValue = 0;
2135 currentActor = Camera_GetEventObject();
2136 currentActor->velocityX = resetValue;
2137 currentActor = Camera_GetEventObject();
2138 currentActor->velocityY = resetValue;
2139 currentActor = Camera_GetEventObject();
2140 currentActor->velocityZ = resetValue;
2143 Task_Wait(1);
2145 groupActor->scaleX = 0x14000;
2146 groupActor->scaleY = 0x14000;
2147 groupVisual->offsetY = 2;
2148 groupVisual->scale = 0x14000;
2149 actor->scaleX = 2 * Q16_ONE;
2150 actor->scaleY = 2 * Q16_ONE;
2151 actor->x.fixed = resetValue;
2152 actor->z.fixed = resetValue;
2153 actor->targetX = resetValue;
2154 actor->targetZ = resetValue;
2155 Task_Wait(1);
2156 // Stage the riverbank reactions between lightning flashes.
2173 Camera_MoveTo(PIXELS(166), 0, PIXELS(1337), 0);
2175 actor->motionFlags = resetValue;
2176 actor->targetX = ACTOR_NO_TARGET;
2177 actor->targetY = ACTOR_NO_TARGET;
2178 actor->targetZ = ACTOR_NO_TARGET;
2181 Camera_MoveTo(PIXELS(210), 0, PIXELS(1196), 0);
2183 groupActor->scaleX = 2 * Q16_ONE;
2184 groupActor->scaleY = 2 * Q16_ONE;
2190 Task_Wait(1);
2191 groupActor = Actor_Get(ACTOR_KYLE);
2192 groupVisual = groupActor->sprite;
2194 groupActor->scaleX = Q16_ONE;
2195 groupActor->scaleY = Q16_ONE;
2196 groupActor->facing = 0xd000;
2197 groupVisual->image.priority = 0;
2199 groupActor = Actor_Get(ACTOR_JENNAS_PARENT_A);
2200 groupVisual = groupActor->sprite;
2202 groupActor->scaleX = Q16_ONE;
2203 groupActor->scaleY = Q16_ONE;
2204 groupActor->facing = 0xb000;
2205 groupVisual->image.priority = 0;
2207 groupActor = Actor_Get(ACTOR_JENNAS_PARENT_B);
2208 groupVisual = groupActor->sprite;
2210 groupActor->scaleX = Q16_ONE;
2211 groupActor->scaleY = Q16_ONE;
2212 groupActor->facing = 0xb000;
2213 groupVisual->image.priority = 0;
2215 groupActor = Actor_Get(ACTOR_BOULDER_GLOW);
2216 groupVisual = groupActor->sprite;
2218 actor->y.fixed = PIXELS(48);
2219 actor->x.fixed = PIXELS(214);
2220 actor->z.fixed = PIXELS(1216);
2221 actor->targetX = ACTOR_NO_TARGET;
2222 actor->targetY = ACTOR_NO_TARGET;
2223 actor->targetZ = ACTOR_NO_TARGET;
2224 groupVisual->image.priority = 1;
2228 GameFlag_Set(0x166);
2235 ColorBuffer_ApplyTarget(0x10003, 1);
2236 ColorBuffer_ApplyTarget(0x10000, 2);
2238 Task_Wait(160);
2239 ColorBuffer_ApplyTarget(0x7fff, 1);
2240 ColorBuffer_ApplyTarget(0x7fff, 2);
2242 Event_Wait(80);
2243 Event_Wait(100);
2245 groupVisual->scale = groupActor->scaleX;
2246 GameFlag_Clear(0x166);
2253 // Restore the riverbank and the idle actor scripts.
2257 actor = Actor_Get(ACTOR_DORA);
2258 actor->facing = FACING_NORTHEAST;
2259 random = Random_Next();
2260 actor->timer = Math_RemainderUnsigned(random, 90) + 60;
2261 departureActions = gValeStorm_ActorEightScript;
2262 actor->work = 1;
2263 Actor_SetActionScript(ACTOR_DORA, departureActions);
2266 actor = Actor_Get(ACTOR_JENNA);
2267 actor->facing = FACING_NORTHEAST;
2268 random = Random_Next();
2269 actor->timer = Math_RemainderUnsigned(random, 90) + 60;
2270 actor->work = 2;
2271 Actor_SetActionScript(ACTOR_JENNA, departureActions);
2274 actor = Actor_Get(ACTOR_GARET);
2275 actor->facing = FACING_NORTHEAST;
2276 random = Random_Next();
2277 actor->timer = Math_RemainderUnsigned(random, 90) + 60;
2278 actor->work = 3;
2279 Actor_SetActionScript(ACTOR_GARET, departureActions);
2282 actor->facing = FACING_NORTHEAST;
2283 random = Random_Next();
2284 actor->timer = Math_RemainderUnsigned(random, 90) + 60;
2285 actor->work = 4;
2294 currentActor = Actor_Get(ACTOR_PARTY_LEADER);
2295 currentActor->facing = FACING_NORTHEAST;
2297 Camera_MoveTo(PIXELS(181), 0, PIXELS(1273), 0);
2305 Actor_SetPosition(17, PIXELS(144), PIXELS(1070));
2306 Actor_SetPosition(18, PIXELS(276), PIXELS(1270));
2307 Task_Wait(60);
2308 ColorBuffer_ApplyTarget(0x10003, 1);
2309 ColorBuffer_ApplyTarget(0x10000, 2);
2311 Event_Wait(60);
2313 Event_Wait(60);
2316}
2317
2318/// Flashes the scene layers before fading back to the storm palette.
2319static void ValeStorm_FlashLightning(void) {
2320 Engine_TaskWait(20);
2321 GameFlag_Set(0x166);
2328 ColorBuffer_ApplyTarget(0x10003, 1);
2329 ColorBuffer_ApplyTarget(0x10000, 2);
2331 Engine_TaskWait(120);
2334 Engine_TaskWait(60);
2335 GameFlag_Clear(0x166);
2342}
2343
2344/// Tracks the boulder and pulses its glow with the movement script phases.
2346 struct FieldActor *source;
2347 struct FieldActor *glow;
2348 struct AnimationObject *sprite;
2349 s16 *timer;
2350
2351 source = Object_GetById(ACTOR_BOULDER);
2353 sprite = glow->sprite;
2354 timer = &source->timer;
2355 if (*timer != 0) {
2356 if (*timer == 60) {
2358 }
2359 if (*timer == 40) {
2361 }
2362 if (*timer == 30) {
2364 }
2365 if (*timer == 20) {
2366 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
2367 }
2368 (*timer)--;
2369 }
2370 glow->x.fixed = source->x.fixed;
2371 glow->z.fixed = source->z.fixed;
2372 glow->targetX = glow->x.fixed;
2373 sprite->offsetY = 10;
2374 if (gFrameCount & 1) {
2375 switch ((s16)source->work) {
2376 case 1:
2377 case 5:
2378 glow->scaleX += 0xa3d;
2379 glow->scaleY += 0xa3d;
2380 break;
2381 case 4:
2382 glow->scaleX += 0x51e;
2383 glow->scaleY += 0x51e;
2384 break;
2385 case 2:
2386 case 3:
2387 case 6:
2388 case 7:
2389 case 8:
2390 case 9:
2391 glow->scaleX += -0x7ae;
2392 glow->scaleY += -0x7ae;
2393 break;
2394 }
2395 sprite->scale = glow->scaleX;
2396 } else {
2397 sprite->scale = 0;
2398 }
2399}
2400
2401/// Alternates the glow vertical offset on successive frames.
2404 u32 frame = gFrameCount;
2405 struct AnimationObject *sprite = actor->sprite;
2406
2407 if (frame & 1) {
2408 sprite->offsetY = 2;
2409 } else {
2410 sprite->offsetY = 64;
2411 }
2412}
2413
2414/// A villager who cannot move asks Isaac to get help. "I can't move..."
2415static void Event_VillagerAsksForHelp(void) {
2416 struct FieldActor *villager;
2417 struct FieldActor *leader;
2418
2424 Engine_EventWait(10);
2426 Engine_EventWait(40);
2427 if ((s16)leader->facing >= 0) {
2429 } else {
2431 }
2433 Engine_EventWait(20);
2434 Engine_EventSetMessage(MsgValeICantMoveGetHelp);
2439 } else {
2441 villager->scaleX = Q16_ONE;
2442 villager->scaleY = Q16_ONE;
2444 if ((s16)leader->facing >= 0) {
2446 } else {
2448 }
2449 Engine_EventWait(20);
2450 Engine_EventSetMessage(MsgValeIllGo);
2454 Engine_EventWait(80);
2456 Engine_EventWait(40);
2457 if ((s16)leader->facing >= 0) {
2459 } else {
2461 }
2464 Engine_EventWait(60);
2466 Engine_EventWait(20);
2472 }
2474}
2475
2476/// Has Garet leave Isaac at the restored riverbank.
2479 Camera_MoveTo(-1, -1, -1, 0);
2487 Engine_TaskWait(1);
2488 Engine_EventSetMessage(MsgValeIsaac);
2491 Engine_TaskWait(1);
2492 Camera_SetSpeed(PIXELS(4), PIXELS(1) / 2);
2493 Camera_MoveTo(PIXELS(162), 0, PIXELS(1285), 1);
2495 Engine_EventWait(40);
2504 Actor_WalkToAndWait(ACTOR_GARET, 165, 1300);
2505 Actor_WalkToAndWait(ACTOR_GARET, 195, 1432);
2507}
2508
2509/// Redraws the riverbank cells after the boulder has passed.
2511 Map_CopyCellsTo(16, 96, 11, 73, 6, 3);
2512 Map_CopyCellsTo(16, 96, 34, 68, 14, 10);
2513 Map_CopyCellsTo(16, 96, 64, 68, 7, 7);
2514 Map_CopyCellsTo(9, 95, 11, 73, 6, 3);
2515 Map_CopyCellsTo(40, 94, 34, 68, 14, 10);
2516 Map_CopyCellsTo(54, 94, 64, 68, 8, 7);
2517 Map_CopyCellsTo(72, 75, 72, 76, 1, 1);
2518 Map_CopyCellsTo(72, 75, 74, 76, 1, 1);
2519 Map_CopyCellAttributes(7, 75, 1, 1, 6, 75);
2520 Map_CopyCellAttributes(8, 70, 3, 1, 8, 71);
2521 Map_CopyCellAttributes(8, 70, 2, 1, 9, 72);
2522 Map_CopyCellAttributes(8, 70, 2, 1, 9, 73);
2523 Map_CopyCellAttributes(11, 66, 1, 1, 8, 73);
2524 Map_CopyCellAttributes(12, 66, 1, 4, 11, 73);
2525 Map_CopyCellAttributes(25, 0, 1, 1, 6, 74);
2527}
2528
2529/// On the stormy night, a monster attacks on the paths (encounter 2 of table
2530/// 12).
2531static void Event_FightThirdMonster(void) {
2532 struct EventWork *state;
2533
2535 state = gEventWork;
2537 state->transitionFrames = 64;
2542}
2543
2544/// On the stormy night, another monster attacks (encounter 3 of table 12).
2545static void Event_FightFourthMonster(void) {
2546 struct EventWork *state;
2547
2549 state = gEventWork;
2551 state->transitionFrames = 64;
2556}
2557
2558/// Flashes the actor palette and emits paired effects at the shake interval.
2560 s32 spawnInterval;
2561
2562 if ((gFrameCount & 2) != 0) {
2564 } else {
2566 }
2567 {
2568 volatile u32 *frame = &gFrameCount;
2569
2570 spawnInterval = (sShakeShift << 3) + 16;
2571 if (Math_RemainderUnsigned(*frame, spawnInterval) == 0) {
2573 }
2574 }
2575}
2576
2577/// Cycles six palettes and emits paired effects at the shake interval.
2579 s32 paletteFrame;
2580 s32 spawnInterval;
2581
2582 if ((gFrameCount & 1) != 0) {
2583 paletteFrame = (gFrameCount >> 1);
2585 Math_RemainderUnsigned(paletteFrame, 6));
2586 }
2587 spawnInterval = (sShakeShift << 3) + 16;
2588 if (Math_RemainderUnsigned(gFrameCount, spawnInterval) == 0) {
2590 }
2591}
2592
2593/// Cycles six actor palettes on alternate frames.
2594static void ValeStorm_CycleObjectPalettes(struct FieldActor *actor) {
2595 s32 paletteFrame;
2596
2597 if ((gFrameCount & 1) != 0) {
2598 paletteFrame = (gFrameCount >> 1);
2600 Math_RemainderUnsigned(paletteFrame, 6));
2601 }
2602}
2603
2604#include "common/effect_vertical.h"
2605
2606/// Creates the two linked effects that travel in opposite vertical directions.
2607static void ValeStorm_SpawnEffectPair(struct FieldActor *parent) {
2608 struct FieldActor *pair[2];
2609 struct FieldActor *child;
2610 struct AnimationObject *sprite;
2611 struct BattleFxScene *work = gEffectWork;
2612 s32 i;
2613
2615 for (i = 0; i < 2; ++i) {
2616 child = Engine_ObjectCreate(26, parent->x.fixed, parent->y.fixed,
2617 parent->z.fixed);
2618 pair[i] = child;
2619 if (child != NULL) {
2620 child->terrainHeight = parent->terrainHeight;
2621 sprite = child->sprite;
2622 child->motionFlags = 0;
2623 child->timer = 0;
2624 child->linkedObject = parent;
2625 if (sprite != NULL) {
2626 Object_InitializeMode(sprite, 0);
2627 sprite->flags = 0;
2628 Resource_ResetEntry(sprite->slot);
2629 sprite->slot = work->tileSlot;
2630 sprite->retainCacheEntry = 1;
2631 sprite->image.tile =
2632 (gVramBlockCache[sprite->slot].offset >> 5) & 0x3ff;
2633 sprite->image.fullColor = 0;
2634 sprite->image.shape = 1;
2635 sprite->image.size = 2;
2636 sprite->entries[0]->frame = 0;
2637 }
2638 }
2639 }
2640 {
2641 struct FieldActor *effect = pair[0];
2642 struct AnimationObject *effectSprite = effect->sprite;
2643
2644 effect->update = Effect_AnimateVerticalNegative;
2645 effectSprite->image.priority = parent->sprite->image.priority;
2646 }
2647 {
2648 struct FieldActor *effect = pair[1];
2649 struct AnimationObject *effectSprite = effect->sprite;
2650
2651 effectSprite->image.priority = parent->sprite->image.priority;
2652 effect->update = Effect_AnimateVerticalPositive;
2653 effect->priorityFlags = 2;
2654 }
2655}
2656
2657#include "common/effect_psynergy.h"
2658
2659/// Updates the four boulder scene actors until the final reaction stops.
2664 if (sShakeDone == 0) {
2666 }
2667}
2668
2671}
2672
2673/// Keeps Garet and actor 8 at the leader sprite priority.
2675 struct AnimationObject *sourceSprite;
2676#if !TBS_PATCH_3
2677 struct AnimationObject *targetSprite;
2678 struct AnimationObject *secondTargetSprite;
2679#endif
2680
2681 sourceSprite = Object_GetById(ACTOR_PARTY_LEADER)->sprite;
2682#if TBS_PATCH_3
2685 sourceSprite->image.priority);
2686#else
2687 targetSprite = Object_GetById(ACTOR_GARET)->sprite;
2688 targetSprite->image.priority = sourceSprite->image.priority;
2689 secondTargetSprite = Object_GetById(ACTOR_EXHAUSTED_VILLAGER)->sprite;
2690 secondTargetSprite->image.priority = sourceSprite->image.priority;
2691#endif
2692}
2693
2694/// The door won't open: the impact knocked it off its hinges.
2695static void Event_SearchBrokenDoor(void) {
2697 Engine_MessageShowCentered(MsgValeDoorWontOpen, 1);
2699}
2700
2703 Engine_MessageShowCentered(MsgValeSChestValuables, 1);
2705}
2706
2707u8 gValeStorm_FrameModes[] = {7, 0, 0, 0};
2708
2710 SC_ARG(2), SC_MOVE(PIXELS(185), 0, PIXELS(824)),
2711 SC_SYNC, SC_MOVE(PIXELS(179), 0, PIXELS(836)),
2712 SC_SYNC, SC_MOVE(PIXELS(226), 0, PIXELS(840)),
2713 SC_SYNC, SC_MOVE(PIXELS(226), 0, PIXELS(944)),
2714 SC_SYNC, SC_POS(0, 0, 0),
2715 SC_ARG(1), SC_END,
2716};
2717
2719 SC_ARG(2), SC_MOVE(PIXELS(345), 0, PIXELS(612)),
2720 SC_SYNC, SC_MOVE(PIXELS(311), 0, PIXELS(638)),
2721 SC_SYNC, SC_MOVE(PIXELS(256), 0, PIXELS(608)),
2722 SC_SYNC, SC_ARG(1),
2723 SC_END,
2724};
2725
2727 SC_LABEL(1),
2728 SC_ADD(SW_SCALE_X, 192),
2729 SC_ADD(SW_SCALE_Y, 384),
2730 SC_WAIT(1),
2731 SC_LOOP(24, SC_TO(1)),
2732 SC_LABEL(2),
2733 SC_ADD(SW_SCALE_X, -384),
2734 SC_ADD(SW_SCALE_Y, -768),
2735 SC_WAIT(1),
2736 SC_LOOP(12, SC_TO(2)),
2738 SC_END,
2739};
2740
2742 SC_ARG(2),
2743 SC_END,
2744};
2745
2747 SC_ARG(2), SC_MOVE(PIXELS(94), 0, PIXELS(564)), SC_SYNC,
2749 SC_END,
2750};
2751
2753 SC_ARG(2), SC_MOVE(PIXELS(76), 0, PIXELS(564)), SC_SYNC,
2755 SC_END,
2756};
2757
2759 SC_ARG(2), SC_MOVE(PIXELS(178), 0, PIXELS(1190)),
2760 SC_SYNC, SC_MOVE(PIXELS(149), 0, PIXELS(1194)),
2761 SC_SYNC, SC_ARG(1),
2762 SC_END,
2763};
2764
2766 SC_ARG(2), SC_MOVE(PIXELS(198), 0, PIXELS(1176)),
2767 SC_SYNC, SC_MOVE(PIXELS(170), 0, PIXELS(1195)),
2768 SC_SYNC, SC_MOVE(PIXELS(149), 0, PIXELS(1194)),
2769 SC_SYNC, SC_MOVE(PIXELS(149), 0, PIXELS(1175)),
2770 SC_SYNC, SC_POS(0, 0, 0),
2771 SC_ARG(1), SC_END,
2772};
2773
2775 SC_ARG(2),
2777 SC_WAIT(30),
2778 SC_POS(PIXELS(102), 0, PIXELS(1189)),
2779 SC_WAIT(1),
2780 SC_MOVE(PIXELS(102), 0, PIXELS(1218)),
2781 SC_SYNC,
2782 SC_MOVE(PIXELS(84), 0, PIXELS(1228)),
2783 SC_SYNC,
2784 SC_ARG(1),
2786 SC_END,
2787};
2788
2790 SC_ARG(2),
2792 SC_WAIT(30),
2793 SC_POS(PIXELS(102), 0, PIXELS(1189)),
2794 SC_SYNC,
2795 SC_MOVE(PIXELS(102), 0, PIXELS(1218)),
2796 SC_SYNC,
2797 SC_MOVE(PIXELS(120), 0, PIXELS(1228)),
2798 SC_SYNC,
2799 SC_ARG(1),
2801 SC_END,
2802};
2803
2805 SC_ARG(2), SC_MOVE(PIXELS(50), 0, PIXELS(1214)),
2806 SC_SYNC, SC_MOVE(PIXELS(46), 0, PIXELS(1130)),
2807 SC_SYNC, SC_MOVE(PIXELS(67), 0, PIXELS(1100)),
2808 SC_SYNC, SC_ARG(1),
2809 SC_END,
2810};
2811
2813 SC_ARG(2), SC_MOVE(PIXELS(153), 0, PIXELS(1251)),
2814 SC_SYNC, SC_MOVE(PIXELS(177), 0, PIXELS(1357)),
2815 SC_SYNC, SC_POS(0, 0, 0),
2816 SC_ARG(1), SC_END,
2817};
2818
2820 SC_ARG(2), SC_MOVE(PIXELS(123), 0, PIXELS(1078)),
2821 SC_SYNC, SC_MOVE(PIXELS(148), 0, PIXELS(1078)),
2822 SC_SYNC, SC_MOVE(PIXELS(148), 0, PIXELS(1064)),
2823 SC_SYNC, SC_MOVE(PIXELS(35), 0, PIXELS(1064)),
2824 SC_SYNC, SC_POS(0, 0, 0),
2825 SC_ARG(1), SC_END,
2826};
2827
2829 SC_ARG(2), SC_MOVE(PIXELS(102), 0, PIXELS(1236)),
2830 SC_SYNC, SC_MOVE(PIXELS(148), 0, PIXELS(1256)),
2831 SC_SYNC, SC_MOVE(PIXELS(177), 0, PIXELS(1303)),
2832 SC_SYNC, SC_ARG(1),
2833 SC_END,
2834};
2835
2837 SC_ARG(2), SC_MOVE(PIXELS(137), 0, PIXELS(1379)),
2838 SC_SYNC, SC_MOVE(PIXELS(114), 0, PIXELS(1416)),
2839 SC_SYNC, SC_MOVE(PIXELS(95), 0, PIXELS(1416)),
2840 SC_SYNC, SC_MOVE(PIXELS(83), 0, PIXELS(1427)),
2841 SC_SYNC, SC_MOVE(PIXELS(154), 0, PIXELS(1430)),
2842 SC_SYNC, SC_MOVE(PIXELS(179), 0, PIXELS(1398)),
2843 SC_SYNC, SC_MOVE(PIXELS(179), 0, PIXELS(1361)),
2844 SC_SYNC, SC_END,
2845};
2846
2848 SC_MOVE(PIXELS(184), 0, PIXELS(1309)),
2849 SC_SYNC,
2850 SC_ARG(1),
2851 SC_SET(SW_FACING, 0xb000),
2852 SC_END,
2853};
2854
2856 SC_MOVE(PIXELS(165), 0, PIXELS(1306)), SC_SYNC, SC_ARG(1),
2858};
2859
2861 SC_MOVE(PIXELS(183), 0, PIXELS(1325)), SC_SYNC, SC_ARG(1),
2863};
2864
2866 SC_MOVE(PIXELS(166), 0, PIXELS(1325)),
2867 SC_SYNC,
2868 SC_ARG(1),
2869 SC_SET(SW_FACING, 0xb000),
2870 SC_END,
2871};
2872
2876};
2877
2881};
2882
2884 SC_ARG(2),
2885 SC_SET(SW_SPEED, PIXELS(3)),
2886 SC_SET(SW_ACCEL, PIXELS(1)),
2887 SC_SET(0x23, 0),
2888 SC_SET(0x24, 1),
2891 SC_MOVE(PIXELS(256), PIXELS(128), PIXELS(931)),
2892 SC_SYNC,
2893 SC_SE(145),
2894 SC_SET(0x23, 60),
2895 SC_SET(0x24, 2),
2896 SC_MOVE(PIXELS(228), PIXELS(149), PIXELS(957)),
2897 SC_SYNC,
2898 SC_SET(0x24, 3),
2899 SC_MOVE(PIXELS(201), PIXELS(160), PIXELS(984)),
2900 SC_SYNC,
2901 SC_SET(0x24, 4),
2902 SC_MOVE(PIXELS(173), PIXELS(138), PIXELS(1011)),
2903 SC_SYNC,
2904 SC_SET(0x24, 5),
2905 SC_MOVE(PIXELS(146), PIXELS(96), PIXELS(1038)),
2906 SC_SYNC,
2907 SC_SE(145),
2908 SC_SET(SW_SPEED, PIXELS(3) / 2),
2909 SC_SET(SW_ACCEL, PIXELS(1) / 2),
2910 SC_SET(0x23, 60),
2911 SC_SET(0x24, 6),
2912 SC_MOVE(PIXELS(161), PIXELS(107), PIXELS(1050)),
2913 SC_SYNC,
2914 SC_SET(SW_SPEED, PIXELS(2)),
2915 SC_SET(SW_ACCEL, PIXELS(3) / 5),
2916 SC_SET(0x24, 7),
2917 SC_MOVE(PIXELS(177), PIXELS(96), PIXELS(1062)),
2918 SC_SYNC,
2919 SC_SET(SW_SPEED, PIXELS(5) / 2),
2920 SC_SET(SW_ACCEL, PIXELS(4) / 5),
2921 SC_SET(0x24, 8),
2922 SC_MOVE(PIXELS(201), PIXELS(74), PIXELS(1074)),
2923 SC_SYNC,
2924 SC_SET(SW_SPEED, PIXELS(3)),
2925 SC_SET(SW_ACCEL, PIXELS(1)),
2926 SC_SET(0x24, 9),
2927 SC_MOVE(PIXELS(225), -PIXELS(64), PIXELS(1086)),
2928 SC_SYNC,
2929 SC_SET(0x23, 0),
2930 SC_SET(0x24, 0),
2931 SC_END,
2932};
2933
2935 {0, CONDITION_ALWAYS, 167, 0, 1281, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2936 {1, CONDITION_ALWAYS, 257, 0, 456, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2937 {2, CONDITION_ALWAYS, 113, 0, 303, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2938 {3, CONDITION_ALWAYS, 27, 0, 621, FACING_EAST, 0, -1, -1, -1, -1, 0},
2939 {4, CONDITION_ALWAYS, 29, 0, 792, FACING_EAST, 0, -1, -1, -1, -1, 0},
2940 {5, CONDITION_ALWAYS, 458, 0, 1393, FACING_WEST, 0, -1, -1, -1, -1, 0},
2941 {6, CONDITION_ALWAYS, 406, 0, 743, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2942 {7, CONDITION_ALWAYS, 262, 0, 821, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2943 {8, CONDITION_ALWAYS, 340, 0, 904, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2944 {9, CONDITION_ALWAYS, 326, 0, 1142, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2945 {10, CONDITION_ALWAYS, 374, 0, 1254, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2946 {11, CONDITION_ALWAYS, 102, 0, 1222, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2947 {12, CONDITION_ALWAYS, 101, 0, 1216, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2948 {13, CONDITION_ALWAYS, 146, 0, 1193, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
2949 {15, CONDITION_ALWAYS, 335, 0, 908, FACING_NORTH, 0, -1, -1, -1, -1, 0},
2950 {16, CONDITION_ALWAYS, 181, 0, 1273, FACING_NORTHEAST, 0, -1, -1, -1, -1,
2951 0},
2953};
2954
2956 SCENE_EXITS(3), SCENE_EXIT(2, 5, 8), SCENE_EXIT(3, 6, 1),
2957 SCENE_EXIT(4, 6, 2), SCENE_EXIT(5, 7, 6), SCENE_EXIT(6, 7, 5),
2958 SCENE_EXIT(7, 8, 6), SCENE_EXIT(8, 7, 2), SCENE_EXIT(9, 7, 1),
2959 SCENE_EXIT(10, 7, 1), SCENE_EXIT(11, 7, 1), SCENE_EXIT(12, 8, 11),
2960 SCENE_EXIT(13, 8, 12), SCENE_EXIT(20, 3, 16), SCENE_EXITS_END,
2961};
2962
2963// clang-format off
2966 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
2968 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
2970 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
2972 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
2974 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
2976 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
2978 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
2980 PIXELS(437), 0, PIXELS(762), FACING_SOUTH, TALK_KEEP_FACING, 0 },
2988 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
2990 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
2992 PIXELS(420), 0, PIXELS(619), FACING_SOUTH, TALK_FACE_PARTY, 0 },
2994 PIXELS(396), 0, PIXELS(619), FACING_EAST, TALK_FACE_PARTY, 0 },
2996 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
2998 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
3000 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
3002 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
3003 { 0x120, CONDITION_ALWAYS, ACTOR_STAND,
3004 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
3005 { SCENE_TABLE_END },
3006};
3007
3009 { 0x16, CONDITION_ALWAYS, 7,
3015 { 0x16, CONDITION_ALWAYS, 7,
3016 PIXELS(100), 0, PIXELS(375), FACING_NORTH + FACING_STEP, TALK_KEEP_FACING, 0 },
3020 PIXELS(100), 0, PIXELS(375), FACING_NORTH + FACING_STEP, TALK_KEEP_FACING, 0 },
3021 { SCENE_TABLE_END },
3022};
3023// clang-format on
3024
3051 MSGNO(MsgValeHangOnFelixHelpIsOn)},
3053 MSGNO(MsgValeDontLetGoFelix)},
3054 {EVENT_TALK, ACTOR_DORA, CONDITION_ALWAYS, MSGNO(MsgValeNoItCantBeKyleIt)},
3056 MSGNO(MsgValeMomDadFelixPleaseDontLeave)},
3059 {EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3060 {EVENT_TALK, 12, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3061 {EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3062 {EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3063 {EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3064 {EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3065 {EVENT_TALK, 17, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3066 {EVENT_TALK, 18, CONDITION_ALWAYS, MSGNO(MsgValeRockCannotBeMoved)},
3094};
3095
3097 MAP_CELL_STEP(0, 98, 2, 2, 2),
3098 MAP_CELL_STEP(2, 98, 2, 2, 2),
3100};
3101
3103 MAP_CELL_STEP(0, 96, 2, 2, 2),
3104 MAP_CELL_STEP(2, 96, 2, 2, 2),
3106};
3107
3109 MAP_CELL_STEP(4, 98, 2, 2, 2),
3110 MAP_CELL_STEP(6, 98, 2, 2, 2),
3112};
3113
3115 MAP_CELL_STEP(4, 96, 2, 2, 2),
3116 MAP_CELL_STEP(6, 96, 2, 2, 2),
3118};
3119
3121 MAP_CELL_STEP(0, 96, 2, 2, 2),
3122 MAP_CELL_STEP(50, 44, 2, 2, 2),
3124};
3125
3127 MAP_CELL_STEP(4, 98, 2, 2, 2),
3128 MAP_CELL_STEP(44, 108, 2, 2, 2),
3130};
void Object_RefreshSelectorById(u32 objectId)
Waits, at most 300 frames, for an actor's script to reach its end (command 0x10).
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
@ ACTOR_FIRST_ROCK
Animated sprites: their layers, frames and colour modes, and the resource slots they draw from.
B5Context, the object context a battle routine reads; most of its fields are still unnamed.
s32 Object_InitializeMode(struct AnimationObject *state, s32 flags)
Calls through a function pointer, by argument count.
The task scheduler: tasks, their order and the scheduler's state.
void(*) SchedulerCallback(void)
struct FieldActor * Camera_GetEventObject(void)
The event command "get view centre": returns the camera object.
Definition camera.c:133
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.
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
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,...
@ 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
#define SPEAKER_PORTRAIT_LEFT
Definition field_event.h:54
u32 Math_RemainderUnsigned(u32 dividend, u32 divisor)
static s32 Event_OpenMessage(s32 speaker, s32 flags)
void Engine_ActorFaceActor(s32 actor, s32 target, s32 frames)
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)
static void Map_AnimateCells(const u16 *steps, s32 destX, s32 destY)
#define SPEAKER_WINDOW_ABOVE
Definition field_event.h:56
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
s32 Engine_EventChooseYesNo(s32 actor, s32 flags)
void Engine_MessageShowCentered(s32 message, s32 flags)
void Engine_ObjectSetPartPalettes(struct FieldActor *object, s32 palette)
void Engine_EventShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
#define GameFlag_IsSet
#define SPEAKER_PORTRAIT_RIGHT
Definition field_event.h:55
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_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)
#define MAP_CELL_STEP(srcX, srcY, width, height, frames)
Definition field_event.h:59
void Engine_ActorSetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
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)
void Engine_ActorWalkToAndWait(s32 actor, s32 x, s32 z)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
#define SPEAKER_WINDOW_BELOW
Definition field_event.h:57
static void ColorBuffer_ApplyTarget(s32 value, s32 mode)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
#define GameFlag_Clear
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
void Engine_ActorDestroy(s32 actor)
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_EventOpenScreen(void)
s32 Engine_EventOpenMessage(s32 speaker, s32 flags)
void Engine_MapWaitWorkValuesBelow256(void)
void Engine_GameFlagSet(s32 flag)
void Engine_GameFlagClear(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)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorStop(s32 actor)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
void Engine_ActorWalkTo(s32 actor, s32 x, s32 z)
static void Event_ShowMessage(s32 speaker, s32 flags)
void Engine_ActorSetAttachedEffect(s32 actor, s32 effect)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
#define MAP_CELL_STEPS_END
Definition field_event.h:61
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_MapAnimateCells(const u16 *steps, s32 destX, s32 destY)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static s32 Event_AskYesNo(s32 speaker, s32 flags)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_MapRedraw(void)
static s32 Random_Next(void)
void Engine_ColorBufferInterpolate(s32 frames)
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_ActorFaceEachOther(s32 actor, s32 other, s32 frames)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
static struct FieldActor * Actor_Get(s32 actor)
Field objects and actors, and the scene transition styles.
@ 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
#define ACTOR_NO_TARGET
A target coordinate that is not set: the object has no target.
Definition field_obj.h:145
#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 scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
@ EVENT_TOUCH
@ 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_FIRST_PLACED
@ 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 EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
@ 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
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static void Task_Wait(s32 frames)
static void Actor_Stop(s32 actor)
static void Actor_SetSpriteFlags(struct FieldActor *actor, s32 flags)
static void Actor_SetAnimation(s32 actor, s32 animation)
static void Event_Wait(s32 frames)
static s32 FieldScheduler_AddOrUpdateCallback(SchedulerCallback callback, s32 priority)
Calls the main-image scheduler through engine_call.h.
static void Actor_FaceEachOther(s32 actor, s32 other, 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_VALE_STORM_SECOND_ROCK_FELL
Definition flags.h:474
#define FLAG_VALE_STORM_RIVER_GATHERING_SEEN
Jenna came back to the river and the scene there ended with ValeStorm_ShowBoulderSweepingDownriver.
Definition flags.h:489
#define FLAG_VALE_STORM_FOURTH_ROCK_FELL
Definition flags.h:476
#define FLAG_VALE_STORM_HEARD_GARET
Isaac heard Garet struggling with his things.
Definition flags.h:482
#define FLAG_VALE_STORM_FIRST_ROCK_FELL
The four rocks that fall across the paths (actors 11 to 14).
Definition flags.h:473
#define FLAG_VALE_STORM_GARET_JOINED
Definition flags.h:483
#define FLAG_VALE_STORM_THIRD_MONSTER_FOUGHT
Definition flags.h:494
#define FLAG_VALE_STORM_MONSTER_FOUGHT
A monster was fought on the stormy night: Vale's music changes (song 23).
Definition flags.h:453
#define FLAG_VALE_BOULDER_FELL
Definition flags.h:484
#define FLAG_SCENE_TEMP_06
Definition flags.h:719
#define FLAG_VALE_STORM
The prologue's stormy night: lightning over Vale, the rockslide and the monsters loose in the village...
Definition flags.h:438
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_VALE_STORM_BUMPED_INTO_VILLAGER
A villager running out of his house shoved Isaac.
Definition flags.h:479
#define FLAG_SCENE_TEMP_10
Definition flags.h:729
#define FLAG_VALE_STORM_GARET_LEFT
Garet ran off, leaving Isaac alone. "Isaac!".
Definition flags.h:491
#define FLAG_VALE_STORM_THIRD_ROCK_FELL
Definition flags.h:475
#define FLAG_VALE_STORM_SENT_TO_AID_ELDERS
On the stormy night, the villagers sent Isaac to aid the elders holding back the Boulder.
Definition flags.h:500
#define FLAG_VALE_STORM_SAW_RIVER_RESCUE
Isaac saw the villagers trying to pull Felix from the river.
Definition flags.h:486
#define FLAG_VALE_STORM_FOURTH_MONSTER_FOUGHT
Definition flags.h:495
#define FLAG_VALE_STORM_SENT_TO_PLAZA
Dora and Kyle sent Isaac to the plaza.
Definition flags.h:493
volatile u32 gFrameCount
Frames WaitFrames has finished.
BattleFxScene, the work of a battle or field Psynergy effect scene, and its arc objects.
GameState, the game's state: play time, coins, the scene and the leader's position,...
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
void * gEffectWork
Slot 56: points to a scene-specific structure.
The screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
void Effect_SoundAndFlash(void)
void Map_SetLayerEntryFlag(u32 channelIndex)
Pauses tile animation channel channelIndex by setting its paused byte.
void Map_ClearLayerEntryFlag(u32 channelIndex)
Resumes tile animation channel channelIndex by clearing its paused byte.
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_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_SE(n)
Sound effect.
Definition objcmd.h:46
#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_ACCEL
Definition objcmd.h:68
@ SW_SCALE_Y
Definition objcmd.h:63
@ SW_SPEED
Definition objcmd.h:67
@ SW_FACING
Definition objcmd.h:57
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void Party_RemoveOwnerRestored(s32 unit)
Takes unit out of the party, fully restoring its HP and PP and curing its poison.
Definition events.c:214
void Event_CallWithLastActiveObjectId(struct ScenePlacement *table)
Spawns the actors of a placement table after the last actor in use.
Definition events.c:148
void Event_PrepareObjectAndApplyValue(s32 unit, s32 announce)
Adds unit to the party.
Definition events.c:165
static s32 Scene_SquashAndStretch(struct ScriptInterpreter *interpreter)
An object script call, each frame: every 60 to 149 frames the actor squashes and stretches back to it...
Definition object_pulse.h:9
void Field_RequestBattleFromEncounterTable(s32 zoneNo, s32 slotNo)
Sets up a battle with enemy group slot of encounter table zone.
Definition requests.c:14
void BattleFx_PlayQueuedSound(void)
Plays the sound BattleFx_SetQueuedSoundAndPlay remembered, if any.
Definition requests.c:102
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
@ ACTOR_DORA
Definition sanctum.c:58
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_159
Definition songs.h:154
#define SE_170
Definition songs.h:165
#define SE_DOOR_OPEN
Definition songs.h:153
#define SE_MAP_EXIT
Definition songs.h:116
#define SE_106
Definition songs.h:99
#define MUS_017
Definition songs.h:27
#define SE_141
Definition songs.h:134
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_145
Definition songs.h:138
#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
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()
void Engine_EventShowMessage()
#define NULL
Definition bilibin.h:6
Vale, its home, storm and Babi scenes, Sol Sanctum's eruption and Venus Lighthouse's aerie: Psynergy ...
void Scene_EndCutscenePsynergy(void)
Ends the cutscene's Psynergy and releases its effect work.
void Scene_BeginCutscenePsynergy(void)
Prepares the effect work and spark tiles of Move (ability 140) for the cutscene's Psynergy.
Vale's storm and Vale's homes: going indoors through a door.
static void Vale_RequestBackdropExit(s32 no)
Takes exit no in the backdrop fade over 16 frames, first stopping the storm's lightning while the sto...
Definition vale.h:10
One animation layer of a sprite: its animation id, frames, running script and timer.
Definition animspr.h:37
u8 param
SpriteColorMode its pixels are drawn with; 0 when taken.
Definition animspr.h:45
u8 * script
the running script; null when stopped (ANIM_CMD_END)
Definition animspr.h:50
u8 frame
frame shown, frameBase plus the facing offset; 255 none
Definition animspr.h:53
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
s8 offsetY
pixels
Definition animspr.h:122
struct AnimationSpritePart image
Definition animspr.h:109
u8 flags
bits: 1 outlined in ObjectSystemWork's edge and fill colours | 0 shadow drawn (set when created)
Definition animspr.h:128
u8 slot
VRAM cache entry holding its tiles.
Definition animspr.h:112
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
s32 scale
16.16 fixed point, 0x10000 full size
Definition animspr.h:111
u8 retainCacheEntry
Keeps the VRAM cache entry when it is released or off screen.
Definition animspr.h:114
u8 dirty
nonzero redraws its pixels into VRAM when next drawn
Definition animspr.h:125
u16 fullColor
256 colours; set for both parts when created
Definition animspr.h:94
u16 tile
first sprite tile in VRAM
Definition animspr.h:99
u16 priority
2 when created
Definition animspr.h:100
The work of a Psynergy effect scene: its caster and target, where it takes place, the map state it re...
Definition fx_scene.h:31
u16 tileSlot
resource entry holding the spark tiles
Definition fx_scene.h:64
void * child
the target's object, or NULL
Definition fx_scene.h:37
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
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
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
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 targetZ
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:61
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
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
u8 spriteStorageKind
Zero hides sprites; one draws a single sprite, two draws a group.
Definition field_obj.h:78
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
s32 targetY
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:60
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
s16 entrance
Definition game_state.h:37
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
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
Values that differ by patch level or language, chosen once for their code.
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 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
static void Event_SetPathCellOverride(void)
Walking onto the upper path: its collision cells change, remembered in FLAG_SCENE_TEMP_10.
Definition vale.c:267
static void Event_ClearPathCellOverride(void)
Walking off the upper path restores its collision cells.
Definition vale.c:273
@ ACTOR_KYLE
Isaac's father (sprite 0x35, Kyle in vale_storm.c).
Definition vale_babi.c:70
struct SceneEvent gValeStorm_Events[]
static void ValeStorm_RunRiverSearch(void)
Sends the searchers along the river and asks Isaac to help.
u8 gValeStorm_FrameModes[]
static void Event_TalkToGaret(void)
Talking to Garet: whether to leave his things behind, or, after the river, the Boulder.
s32 gValeStorm_ActorTwentySixScriptC[]
StormNightActor
The placed actors, numbered in the order of gValeStorm_Placements; the elders holding back the Boulde...
Definition vale_storm.c:70
@ ACTOR_JENNA
"Oh no! My brother!"
Definition vale_storm.c:91
@ ACTOR_JENNAS_PARENT_B
"Don't let go, Felix!"
Definition vale_storm.c:90
@ ACTOR_EXHAUSTED_VILLAGER
Worn out from holding the Boulder: "I... I'll go!", then "It's no use.
Definition vale_storm.c:73
@ ACTOR_SHOVING_VILLAGER
Runs out of his house and shoves Isaac. "Huh? Isaac?".
Definition vale_storm.c:81
@ ACTOR_GARET
the young Garet's sprite, 0x13
Definition vale_storm.c:85
@ ACTOR_GARETS_CHEST
The things Garet struggles to save.
Definition vale_storm.c:84
@ ACTOR_JENNAS_PARENT_A
The pair at the river whom Jenna calls "Mom! Dad!".
Definition vale_storm.c:89
@ ACTOR_BOULDER_GLOW
the light around the Boulder as it rolls
Definition vale_storm.c:92
static void Event_LeaveByExit13(void)
Opens the door and goes in.
Definition vale_storm.c:310
s32 ValeStorm_Initialize(void)
Restores the fallen rocks, the river scene and the Boulder from their flags, starts the storm,...
Definition vale_storm.c:324
u16 gValeStorm_CellSteps4[]
static __inline__ void ValeStorm_PlayImpactBeat(s32 shakeAmplitude, s32 frames)
Shakes the scene at the impact cue and waits for the beat.
static void Event_WatchBoulderFall(void)
The Boulder falls toward Vale while the elders hold it with their Psynergy.
static void ValeStorm_CopyLeaderSpritePriority(void)
Keeps Garet and actor 8 at the leader sprite priority.
static void ValeStorm_ApplyRock11Collision(void)
Applies the collision cells left by rock 11.
Definition vale_storm.c:716
static void ValeStorm_CycleObjectPalettes(struct FieldActor *actor)
Cycles six actor palettes on alternate frames.
static UNUSED void ValeStorm_OpenBackdropExit11(void)
Opens a door and takes exit 11, to ValeInteriors' entrance 1.
Definition vale_storm.c:175
static void ValeStorm_FlickerGlowOffset(void)
Alternates the glow vertical offset on successive frames.
s32 gValeStorm_ActorNineteenScript[]
u16 gValeStorm_CellSteps3[]
static void Event_LeaveByExit1(void)
Stepping on cell code 2 requests exit 1, which has no table row.
Definition vale_storm.c:186
static void ValeStorm_UpdateBoulderSceneEffects(void)
Updates the four boulder scene actors until the final reaction stops.
static void Event_LeaveByExit9(void)
Opens the door and goes in.
Definition vale_storm.c:277
static void Event_WitnessRiverRescue(void)
At the river, Jenna cries out for her brother as the villagers try to save Felix.
u16 gValeStorm_CellSteps5[]
s32 gValeStorm_ActorTwentySixScriptB[]
@ STORM_CALLBACK_PRIORITY
Definition vale_storm.c:65
static void Event_GaretJoinsIsaac(void)
Garet catches up and joins Isaac.
static void Event_WarnAboutMtAleph(void)
Garet warns where the path north leads.
static void Event_Rock11Falls(void)
Walking past: rock 11 falls across the path, and Garet, once with Isaac, says they cannot get around ...
Definition vale_storm.c:651
static s32 ValeStorm_RerollHeadingOnCountdown(struct ScriptInterpreter *interpreter)
Chooses a new random heading whenever the actor countdown expires.
Definition vale_storm.c:124
static void ValeStorm_ApplyRock14Collision(void)
Applies the collision cells left by rock 14.
Definition vale_storm.c:932
static void Event_LeaveByExit10(void)
Opens the door and goes in.
Definition vale_storm.c:288
u16 gValeStorm_CellSteps1[]
u32 gValeStorm_Exits[]
struct ScenePlacement gValeStorm_Placements[]
static void ValeStorm_GaretCommentsOnBlockedPath(s32 x, s32 y)
Brings Garet out to discuss a blocked path, then returns him to Isaac.
static void Event_LeaveByExit5(void)
Opens the door and goes in.
Definition vale_storm.c:220
static void ValeStorm_ApplyRock12Collision(void)
Applies the collision cells left by rock 12.
Definition vale_storm.c:789
const struct SceneRegion * ValeStorm_GetRegions(void)
Definition vale_storm.c:146
static void Event_LeaveByExit12(void)
Opens the door and goes in.
Definition vale_storm.c:299
static void ValeStorm_UpdatePulsingGlow(void)
Tracks the boulder and pulses its glow with the movement script phases.
static void Event_LeaveByExit6(void)
Isaac's first time at the door of exit 6: a villager runs out and shoves him; afterwards the door ope...
Definition vale_storm.c:234
const struct SceneEntrance * ValeStorm_GetEntrances(void)
Returns where the party appears; entrance 15 is where Dora and Isaac run in from the south-west of Va...
Definition vale_storm.c:142
static void Event_FightFourthMonster(void)
On the stormy night, another monster attacks (encounter 3 of table 12).
static void Event_LeaveByExit2(void)
Reached by stepping on cell code 5; takes exit 2, to ValeHome's entrance 8.
Definition vale_storm.c:208
const u32 * ValeStorm_GetExits(void)
Definition vale_storm.c:148
const struct ScenePlacement * ValeStorm_GetPlacements(void)
Definition vale_storm.c:150
s32 gValeStorm_GatherPath22[]
static void Event_Rock13Falls(void)
Walking past: rock 13 falls down the path.
Definition vale_storm.c:804
static void ValeStorm_SpawnEffectPair(struct FieldActor *parent)
Creates the two linked effects that travel in opposite vertical directions.
struct SceneEntrance gValeStorm_Entrances[]
s32 gValeStorm_ActorNineteenRiseScript[]
static void Event_VillagerAsksForHelp(void)
A villager who cannot move asks Isaac to get help. "I can't move...".
static void Event_Rock12Falls(void)
Walking past: rock 12 falls down the path.
Definition vale_storm.c:728
static void Event_GaretCallsAfterIsaac(void)
Walking away from him, Garet calls after Isaac, asking whether he will just leave him there.
struct ScenePlacement gValeStorm_BoulderWatchers[]
static void Event_HearGaretStruggling(void)
Isaac hears Garet struggling with his things.
Definition vale_storm.c:978
static void Event_SearchValuablesChest(void)
static s32 sShakeShift
Definition vale_storm.c:120
s32 gValeStorm_ActorTwentyTwoScript[]
static void Event_SearchBrokenDoor(void)
The door won't open: the impact knocked it off its hinges.
static void Event_LeaveByExit7(void)
Opens the door, unless Dora and Kyle left it open, and goes in.
Definition vale_storm.c:253
s32 gValeStorm_ActorNineScriptD[]
s32 gValeStorm_ArriveScript[]
static s32 sShakeDone
Definition vale_storm.c:119
s32 gValeStorm_LookAroundScript[]
static void Event_LeaveByExit3(void)
Reached by stepping on cell code 3; takes exit 3, to Kraden's cottage (ValeKraden's entrance 1).
Definition vale_storm.c:193
static void ValeStorm_MeetVillagerAtExit6(void)
Stops the leader at exit 6 for the first villager conversation.
Definition vale_storm.c:944
u16 gValeStorm_CellSteps2[]
s32 gValeStorm_ActorTwentySixScriptA[]
s32 gValeStorm_ActorTwentyTwoScriptA[]
s32 gValeStorm_ActorEightScript[]
static void Event_LeaveByExit8(void)
Opens the door and goes in.
Definition vale_storm.c:266
s32 gValeStorm_StormRunActions[]
static void ValeStorm_GaretLeavesIsaac(void)
Has Garet leave Isaac at the restored riverbank.
static void Event_GatherAfterRiverRescue(void)
Jenna comes back to the river, and the scene ends with the Boulder sweeping down it.
static void Storm_SetActorFrameMode(struct FieldActor *actor, s32 mode)
Applies an animation parameter to each active entry of a single sprite.
s32 gValeStorm_GatherPath0[]
s32 gValeStorm_LeaderScript[]
static void Event_Rock14Falls(void)
Walking past: rock 14 falls down the path.
Definition vale_storm.c:875
s32 gValeStorm_GatherPath26[]
static void Event_DoraSendsIsaacToThePlaza(void)
Dora and Kyle come out into the storm with Isaac and send him to the plaza while they go to help.
Definition vale_storm.c:543
static void ValeStorm_ShowBoulderSweepingDownriver(void)
Follows the boulder downriver, then restores the riverbank actors.
const struct SceneEvent * ValeStorm_GetEvents(void)
Definition vale_storm.c:154
static void ValeStorm_CyclePaletteAndSpawnEffects(struct FieldActor *actor)
Cycles six palettes and emits paired effects at the shake interval.
static void Event_TalkAboutRescuingFelix(void)
A villager at the river talks of rescuing Felix.
static void ValeStorm_FlashLightning(void)
Flashes the scene layers before fading back to the storm palette.
StormNightPlaceFlag
Vale's place flags this scene keeps while the party is in Vale.
Definition vale_storm.c:96
@ FLAG_VALE_STORM_KYLE_GREETED_ISAAC
Kyle has greeted Isaac at the river. "Oh, Isaac...".
Definition vale_storm.c:102
@ FLAG_VALE_STORM_GARET_SAW_BLOCKED_PATH
Garet has said once that they cannot get around a fallen rock.
Definition vale_storm.c:100
@ FLAG_VALE_STORM_VILLAGER_TRIED_TO_GO
The villager at the river tried to go for help and could not.
Definition vale_storm.c:98
@ FLAG_VALE_STORM_THIRD_ROCK_PASSED
Definition vale_storm.c:107
@ FLAG_VALE_STORM_SECOND_ROCK_PASSED
Definition vale_storm.c:106
@ FLAG_VALE_STORM_FOURTH_ROCK_PASSED
Definition vale_storm.c:108
@ FLAG_VALE_STORM_FIRST_ROCK_PASSED
The party has passed each rock's spot since coming to Vale, so its event does not play again.
Definition vale_storm.c:105
static void ValeStorm_CycleBoulderPalette(void)
s32 gValeStorm_ActorNineScriptC[]
s32 gValeStorm_ActorNineScriptB[]
static void ValeStorm_FlashPaletteAndSpawnEffects(struct FieldActor *actor)
Flashes the actor palette and emits paired effects at the shake interval.
s32 gValeStorm_GatherPath8[]
static void ValeStorm_ApplyRock13Collision(void)
Applies the collision cells left by rock 13.
Definition vale_storm.c:864
static void Event_LeaveByExit4(void)
Reached by stepping on cell code 4; takes exit 4, to Kraden's cottage (ValeKraden's entrance 2).
Definition vale_storm.c:200
s32 gValeStorm_ActorTwentyScript[]
s32 gValeStorm_ActorNineScriptA[]
static UNUSED void ValeStorm_FlashBoulderSceneAnimationEntries(void)
Alternates four actors between the normal and flashing parameters.
static void ValeStorm_RebuildRiverbank(void)
Redraws the riverbank cells after the boulder has passed.
s32 gValeStorm_ActorTwentyTwoScriptB[]
u16 gValeStorm_CellSteps0[]
static void ValeStorm_RunCallOutSequence(void)
Resolves the belongings conversation and brings Garet into the party.
static void Event_FightThirdMonster(void)
On the stormy night, a monster attacks on the paths (encounter 2 of table 12).
static __inline__ void ValeStorm_PlaceActor(struct FieldActor *object, s32 horizontalPosition, s32 groundPosition)
Places an actor and its motion targets at the supplied coordinates.
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
The sprite VRAM block cache and its owners.
struct VramBlockCacheEntry gVramBlockCache[]
void FieldFx_ResumeLightning(void)
Restarts the lightning: the next flash in 128 frames, repeating.
Definition weather.c:458
void FieldFx_StartLightning(void)
Starts the storm's lightning (FieldFx_UpdateLightning): builds the dark (0x10003) and lit (0x10005) p...
Definition weather.c:425
void FieldFx_StopLightning(void)
Stops the lightning: no flash for 0x7fff frames, and none after.
Definition weather.c:442
void FieldFx_LastLightning(void)
One last flash of lightning in 12 frames, then no more.
Definition weather.c:450