Alchemy
Loading...
Searching...
No Matches

sol_sanctum_entrance.c

Go to the documentation of this file.
1/// @file
2/// Sol Sanctum's entrance, in two maps: the door, the two minotaur reliefs that
3/// open passages once the Small Jewels are set in them, and the rooms of
4/// movable blocks.
5
6#include "game_state.h"
7#include "unit/field/field.h"
8#include "unit/import.h"
10#include "unit/object/object.h"
12#include "battle.h"
13#include "debug.h"
14#include "field.h"
15#include "game.h"
16#include "graphics.h"
17#include "menu.h"
18#include "minigame.h"
19#include "sound.h"
20#include "system.h"
21#include "types.h"
22#include "field_event.h"
23#include "field_scene.h"
24#include "field_service.h"
26#include "scene_ids.h"
27#include "text/msg_ids.h"
28#include "ability_ids.h"
29#include "field_obj.h"
30#include "fixed_math.h"
31#include "macros.h"
32#include "songs.h"
33#include "item_ids.h"
34
35// Place flags: Scene_ResetFlagsOnEnter clears 0x300 to 0x3ff when the party
36// enters another place group, and other places use the numbers for their own.
37
38// The column each movable block stands in, east or west of its pair.
39#define FLAG_SOL_SANCTUM_OUTER_RIGHT_BLOCK_EAST 0x300
40#define FLAG_SOL_SANCTUM_OUTER_RIGHT_BLOCK_WEST 0x301
41#define FLAG_SOL_SANCTUM_OUTER_LEFT_BLOCK_EAST 0x302
42#define FLAG_SOL_SANCTUM_OUTER_LEFT_BLOCK_WEST 0x303
43#define FLAG_SOL_SANCTUM_INNER_BLOCK_1_EAST 0x310
44#define FLAG_SOL_SANCTUM_INNER_BLOCK_1_WEST 0x311
45#define FLAG_SOL_SANCTUM_INNER_BLOCK_2_EAST 0x312
46#define FLAG_SOL_SANCTUM_INNER_BLOCK_2_WEST 0x313
47#define FLAG_SOL_SANCTUM_INNER_BLOCK_3_EAST 0x314
48#define FLAG_SOL_SANCTUM_INNER_BLOCK_3_WEST 0x315
49#define FLAG_SOL_SANCTUM_INNER_BLOCK_4_EAST 0x316
50#define FLAG_SOL_SANCTUM_INNER_BLOCK_4_WEST 0x317
51#define FLAG_SOL_SANCTUM_INNER_BLOCK_5_EAST 0x318
52#define FLAG_SOL_SANCTUM_INNER_BLOCK_5_WEST 0x319
53#define FLAG_SOL_SANCTUM_INNER_BLOCK_6_EAST 0x31a
54#define FLAG_SOL_SANCTUM_INNER_BLOCK_6_WEST 0x31b
55
56// Scene flags, cleared on every ordinary entrance:
57// - FLAG_SCENE_TEMP_34: set on entering the inner block room (entrances 14 to
58// 16); the outer block room's Move rows apply only while it is clear.
59// XXX: the two rooms are entered separately, so the flag is clear whenever
60// the outer room's table is read; a return after a battle
61// (FLAG_KEEP_PARTY_POSITION) would settle whether it is ever set there.
62
63// An exit's flag word of -1 stands for no flag: GameFlag_TestFar reads it as
64// flag 0xfff, which nothing sets, so the exit is always taken.
65#define EXIT_FLAG_NONE 0xffffffff
66
72static void SolSanctumEntrance_RestoreInnerBlockCells(s32 placeActors);
74
75s32 gSolSanctumEntrance_RumbleTimer __attribute__((section(".bss")));
76
78
79/// Returns the approach's entrances (scene 19) or the halls' (scene 16), which
80/// share this overlay.
82 s16 scene = gGameState.scene;
83
84 if (scene == (s32)&SceneId_SolSanctumEntrance2) {
86 }
87 if (scene == (s32)&SceneId_SolSanctumEntrance1) {
89 }
91}
92
93const struct SceneRegion *SolSanctumEntrance_GetRegions(void) { return 0; }
94
97}
98
99/// Selects the actors for the current map and puzzle room.
100/// Inside, entrances 11 to 13 (the outer block room) and 14 to
101/// 16 (the inner one) place Kraden and the blocks, the rest of the halls
102/// Kraden and actor 9; the approach places its sentry.
104 struct ScenePlacement *table;
105 s32 firstBlockEntrance = 11;
106
108 if (gGameState.entrance >= firstBlockEntrance) {
109 if (gGameState.entrance > 13) {
110 if (gGameState.entrance <= 16) {
112 }
113 } else {
115 }
116 }
119 return table;
120 }
123 }
125}
126
127/// Selects the events for the current map and puzzle room, by the same
128/// entrances as SolSanctumEntrance_GetPlacements.
130 s32 firstBlockEntrance = 11;
131
134 }
136 if (gGameState.entrance >= firstBlockEntrance) {
137 if (gGameState.entrance > 13) {
138 if (gGameState.entrance <= 16) {
140 }
141 } else {
143 }
144 }
146 }
148}
149
150/// Walking up to the sanctum's door: it slides open and the leader walks in.
151/// Reached by walking north into the door (cell code 2) on the approach.
152/// Takes exit 2, into the halls at entrance 8.
153static void Event_OpenDoorAndEnter(void) {
154 s32 width;
155 s32 height;
156
158 // The door opens over three frames.
159 width = 3;
160 height = 2;
162 Map_CopyCellsTo(16, 28, 21, 3, width, height);
163 Engine_TaskWait(10);
164 Map_CopyCellsTo(16, 30, 21, 3, width, height);
165 Engine_TaskWait(10);
166 Map_CopyCellsTo(16, 32, 21, 3, width, height);
167 Engine_TaskWait(10);
178}
179
180/// Searching the first minotaur relief: one eye sparkles, or both once the
181/// Small Jewel is set. "The right eye is sparkling, but there's a hole where
182/// the left eye should be." Reached by searching the relief (cell code 20) in
183/// the halls. Once the first Small Jewel is found, and until it is set, it
184/// requests the field menu (the event work's unk172, FieldWork's menu), which
185/// opens when the search ends so that the jewel can be used.
187
189
191 Engine_MessageShowCentered(MsgSolSanctumMinotaurReliefBothEyes, 1);
192 } else {
193 Engine_MessageShowCentered(MsgSolSanctumMinotaurReliefOneEye, 1);
195 u16 *stateSlot = &gEventWork->unk172;
196 u16 value = 1;
197 *stateSlot = value;
198 }
199 }
200
202}
203
204/// The room shakes as stone shifts; the leader looks around and jumps.
217 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
219}
220
221/// Using the Small Jewel on the first relief: the leader sets it in and a
222/// passage opens. "set the small gem into the empty socket.", "You hear the
223/// sound of shifting stone." Reached by using the Small Jewel on the relief
224/// (trigger 0x414: cell code 20, with its own message); does nothing until the
225/// first Small Jewel is found, or once it is set. Sets
226/// FLAG_SOL_SANCTUM_FIRST_GEM_PLACED and FLAG_ITEM_USED_UP, which takes the
227/// jewel.
228static void Event_SetFirstSmallJewel(void) {
229 s32 message;
230 s32 oneCell;
231 s32 reliefWidth;
232
234 } else {
236 } else {
239 // The eye sparkles, then the wall opens.
240 oneCell = 1;
242 Map_CopyCellsTo(0, 70, 30, 42, oneCell, oneCell);
245 message = MsgSolSanctumSetSmallGem;
246 Engine_MessageShowCentered(message, 1);
248 reliefWidth = 3;
250 Map_CopyCellsTo(0, 29, 3, 1, reliefWidth, 2);
251 Map_CopyCellAttributes(0, 29, 3, 2, reliefWidth, oneCell);
252 Map_CopyCellsTo(1, 109, 4, 81, oneCell, oneCell);
255 Engine_MessageShowCentered(message + 1, 1);
259 }
260 }
261}
262
263/// Searching the second minotaur relief, as the first. Reached by searching it
264/// (cell code 21) in the inner block room; once the second Small Jewel is
265/// found, and until it is set, it requests the field menu.
267
268 struct EventWork *work;
269
271
273 Engine_MessageShowCentered(MsgSolSanctumMinotaurReliefBothEyes, 1);
275 0) {
276 work = gEventWork;
277 Engine_MessageShowCentered(MsgSolSanctumMinotaurReliefOneEye, 1);
278 {
279
280 u16 *stateSlot = &work->unk172;
281 s32 one = 1;
282 *stateSlot = one;
283 }
284 } else {
285 Engine_MessageShowCentered(MsgSolSanctumMinotaurReliefOneEye, 1);
286 }
287
289}
290
291/// Using the Small Jewel on the second relief: as the first, and the inner
292/// doorway opens. Reached by using the Small Jewel on it (trigger 0x415: cell
293/// code 21, with its own message) in the inner block room, once the second
294/// Small Jewel is found and until it is set. Sets
295/// FLAG_SOL_SANCTUM_SECOND_GEM_PLACED and FLAG_ITEM_USED_UP.
296static void Event_SetSecondSmallJewel(void) {
297 s32 message;
298
303 // The eye sparkles, then the doorway opens.
305 Map_CopyCellsTo(0, 71, 100, 71, 1, 1);
308 message = MsgSolSanctumSetSmallGem;
312 Map_CopyCellsTo(122, 20, 120, 30, 1, 2);
313 Map_CopyCellAttributes(122, 20, 1, 2, 120, 30);
320 }
321}
322
323/// Remembers which of a movable block's two destination columns it occupies.
325 s32 flagBase,
326 s32 leftColumn,
327 s32 rightColumn) {
328 GameFlag_Clear(flagBase);
329 GameFlag_Clear(flagBase + 1);
330 if (column == leftColumn) {
331 Engine_GameFlagSet(flagBase + 1);
332 } else if (column == rightColumn) {
333 Engine_GameFlagSet(flagBase);
334 }
335}
336
337/// Moving the outer left block with Move: the column it stops in is saved.
338/// Reached by Move on actor 9 in the outer block room while FLAG_SCENE_TEMP_34
339/// is clear, and called by Event_PushBlock there. Sets one of
340/// FLAG_SOL_SANCTUM_OUTER_LEFT_BLOCK_EAST and _WEST, or clears both when the
341/// block stands in neither column.
342static void Event_OuterLeftBlockMoved(void) {
344 s32 column;
345
346 if (block == NULL) {
347 return;
348 }
349 column = block->x.fixed >> 20;
352}
353
354/// Moving the outer right block with Move: the column it stops in is saved.
355/// Reached by Move on actor 10, as the left block. Sets one of
356/// FLAG_SOL_SANCTUM_OUTER_RIGHT_BLOCK_EAST and _WEST, or clears both.
357static void Event_OuterRightBlockMoved(void) {
359 s32 column;
360
361 if (block == NULL) {
362 return;
363 }
364 column = block->x.fixed >> 20;
367 if (column == 115) {
369 } else if (column == 113) {
371 }
372}
373
374/// Moving an inner block with Move: the column it stops in is saved and the
375/// floor under all six is set again. Reached by Move on actor 9 in the inner
376/// block room, and called by Event_PushBlock there. Sets one of
377/// FLAG_SOL_SANCTUM_INNER_BLOCK_1_EAST and _WEST, or clears both.
378static void Event_InnerBlock1Moved(void) {
380 s32 column;
381
382 if (block == NULL) {
383 return;
384 }
385 column = block->x.fixed >> 20;
387 column, FLAG_SOL_SANCTUM_INNER_BLOCK_1_EAST, 99, 101);
389}
390
391/// As Event_InnerBlock1Moved, for the second block (actor 10).
392static void Event_InnerBlock2Moved(void) {
394 s32 column;
395
396 if (block == NULL) {
397 return;
398 }
399 column = block->x.fixed >> 20;
401 column, FLAG_SOL_SANCTUM_INNER_BLOCK_2_EAST, 103, 105);
403}
404
405/// As Event_InnerBlock1Moved, for the third block (actor 11).
406static void Event_InnerBlock3Moved(void) {
408 s32 column;
409
410 if (block == NULL) {
411 return;
412 }
413 column = block->x.fixed >> 20;
415 column, FLAG_SOL_SANCTUM_INNER_BLOCK_3_EAST, 107, 109);
417}
418
419/// As Event_InnerBlock1Moved, for the fourth block (actor 12).
420static void Event_InnerBlock4Moved(void) {
422 s32 column;
423
424 if (block == NULL) {
425 return;
426 }
427 column = block->x.fixed >> 20;
429 column, FLAG_SOL_SANCTUM_INNER_BLOCK_4_EAST, 111, 113);
431}
432
433/// As Event_InnerBlock1Moved, for the fifth block (actor 13).
434static void Event_InnerBlock5Moved(void) {
436 s32 column;
437
438 if (block == NULL) {
439 return;
440 }
441 column = block->x.fixed >> 20;
443 column, FLAG_SOL_SANCTUM_INNER_BLOCK_5_EAST, 115, 117);
445}
446
447/// As Event_InnerBlock1Moved, for the sixth block (actor 14).
448static void Event_InnerBlock6Moved(void) {
450 s32 column;
451
452 if (block == NULL)
453 return;
454 column = block->x.fixed >> 20;
456 column, FLAG_SOL_SANCTUM_INNER_BLOCK_6_EAST, 119, 121);
458}
459
461
462/// Walking into a block: the leader pushes it one cell, and its column is
463/// saved. Reached by walking into a block's cell: code 22, or 23 facing east
464/// and 25 facing west, in the outer block room, and code 24 in the inner one.
465/// Updates the room's block flags through the Moved events.
466static void Event_PushBlock(void) {
467 struct FieldActor *leader;
468 struct FieldActor *block;
469 s32 stoppedVelocity;
470 s32 packedStep;
471 u32 direction;
472 struct FieldPosition target;
473 struct FieldPosition *destination;
474
475 // Find the block one map cell ahead in the leader's facing direction.
477 direction = leader->facing >> 12;
478 block = SceneActor_FindActorAtCell(
479 (leader->x.part.pixel + (gSolSanctumPushSteps[direction] >> 16)) >> 4,
480 (leader->z.part.pixel + (s16)gSolSanctumPushSteps[direction]) >> 4);
481 if (block != NULL) {
482 stoppedVelocity = 0;
483 block->terrainId = 2;
484 destination = &target;
485 packedStep = gSolSanctumPushSteps[direction];
486 SET_POSITION(destination, block->x.fixed + (packedStep & -0x10000),
487 block->y.fixed, block->z.fixed + (packedStep << 16));
488 // Move only after the block's proposed position passes collision.
489 if (FieldObject_CheckMovementCollision(block, destination) <= 0) {
490 Object_SetMode(leader, 8);
491 Engine_TaskWait(15);
493 block->speed = PIXELS(1) / 5;
494 block->acceleration = PIXELS(1) / 5;
495 Engine_ObjectSetPosition(block, destination->x, destination->y,
496 destination->z);
497 leader->speed = PIXELS(1) / 5;
498 leader->acceleration = PIXELS(1) / 5;
499 Engine_ObjectSetPosition(leader, destination->x, destination->y,
500 destination->z);
502 block->x.fixed = destination->x;
503 block->z.fixed = destination->z;
504 block->velocityX = stoppedVelocity;
505 block->velocityZ = stoppedVelocity;
506 Object_SetMode(leader, 1);
507 // Save the moved block in the flag set belonging to this room.
508 switch (gGameState.entrance) {
509 case 11:
510 case 12:
511 case 13:
514 break;
515 case 14:
516 case 15:
517 case 16:
524 break;
525 }
526 }
527 }
528}
529
530/// Restores the outdoor or interior state for this entrance. Called by
531/// Field_RunScene once the actors exist.
533 s32 scene = gGameState.scene;
534
535 if (scene == (s32)&SceneId_SolSanctumEntrance2) {
537 } else if (scene == (s32)&SceneId_SolSanctumEntrance1) {
539 }
540 return 0;
541}
542
543/// Sets up the approach: after the eruption it rumbles now and then, the
544/// collision of two rows of cells changes with FLAG_VALE_RETURNED_FROM_MT_ALEPH
545/// and FLAG_PARTY_LEFT_VALE, and with the latter the sentry stands at
546/// another spot. Called by
547/// SolSanctumEntrance_Initialize for scene 19. Sets FLAG_RETREAT_BLOCKED and
548/// starts SolSanctumEntrance_UpdateEruptionRumbles after the eruption.
550 // Retreat does not work here (flag 0x144).
556 }
558 Map_CopyCellAttributes(5, 6, 1, 1, 6, 6);
559 Map_CopyCellAttributes(5, 6, 1, 1, 7, 6);
560 Map_CopyCellAttributes(5, 6, 1, 1, 8, 6);
561 Map_CopyCellAttributes(0, 1, 3, 1, 6, 5);
562 }
565 Map_CopyCellAttributes(2, 10, 1, 1, 6, 14);
566 Map_CopyCellAttributes(2, 10, 1, 1, 7, 14);
567 Map_CopyCellAttributes(2, 10, 1, 1, 8, 14);
568 }
569}
570
571/// Restores opened passages and the current room's block positions, and plays
572/// a room's first cutscene. Called by SolSanctumEntrance_Initialize for scene
573/// 16. Entrance 8, the way in, sets the Retreat point there and introduces the
574/// sanctum until FLAG_SOL_SANCTUM_ENTERED is set; the outer block room plays
575/// Kraden's search until FLAG_SEARCHING_FOR_HIDDEN_PASSAGE is set, the inner
576/// one shows the statues out of reach until FLAG_SOL_SANCTUM_INNER_STATUES_SEEN
577/// is set and sets FLAG_SCENE_TEMP_34.
579 s32 entrance;
585 }
586
587 entrance = gGameState.entrance;
588 switch (entrance) {
589 case 1:
590 case 2:
592 Map_CopyCellsTo(1, 109, 4, 81, 1, 1);
593 Map_CopyCellsTo(0, 70, 30, 42, 1, 1);
594 Map_CopyCellsTo(0, 29, 3, 1, 3, 2);
595 Map_CopyCellAttributes(0, 29, 3, 2, 3, 1);
597 }
598 break;
599
600 case 3:
602 break;
603
604 case 8:
609 break;
610
611 case 11:
612 case 12:
613 case 13:
614 // Recreate the outer puzzle after its introduction has played.
636 break;
637
638 case 14:
639 case 15:
640 case 16:
641 // Restore the inner blocks and the second gem's doorway.
653 Map_CopyCellsTo(0, 71, 100, 71, 1, 1);
654 Map_CopyCellsTo(122, 20, 120, 30, 1, 2);
655 Map_CopyCellAttributes(122, 20, 1, 2, 120, 30);
657 }
658 break;
659 }
660}
661
662/// Kraden welcomes the party into Sol Sanctum on their first visit, asking
663/// whether it is their first time here. Called by
664/// SolSanctumEntrance_RestoreInteriorState at entrance 8 until
665/// FLAG_SOL_SANCTUM_ENTERED is set. Sets FLAG_SOL_SANCTUM_ENTERED and clears
666/// FLAG_SHOW_LOCATION_NAME.
668 struct FieldActor *leader;
669
675 Camera_MoveTo(-1, -1, -1, 0);
676 // Gather the followers around the leader for Kraden's introduction.
677 Camera_SetSpeed(PIXELS(3) / 5, PIXELS(3) / 40);
678 Camera_MoveTo(PIXELS(1224), -1, PIXELS(136), 1);
680 if (leader != NULL) {
681 Actor_SetPosition(ACTOR_KRADEN, leader->x.fixed, leader->z.fixed);
682 }
684 if (leader != NULL) {
685 Actor_SetPosition(JENNA, leader->x.fixed, leader->z.fixed);
686 }
688 if (leader != NULL) {
689 Actor_SetPosition(GARET, leader->x.fixed, leader->z.fixed);
690 }
691 Actor_SetSpeed(ACTOR_KRADEN, PIXELS(3) / 5, PIXELS(3) / 10);
692 Actor_SetSpeed(JENNA, PIXELS(3) / 5, PIXELS(3) / 10);
693 Actor_SetSpeed(GARET, PIXELS(3) / 5, PIXELS(3) / 10);
714 // Kraden: "This is your first time here, right?" Yes: "Take a good look at
715 // it." No: "I doubt that..."
716 Engine_EventSetMessage(MsgSolSanctumKradenFirstTimeAtSol);
719 Camera_MoveTo(PIXELS(1224), -1, PIXELS(148), 1);
722 if (leader != NULL) {
723 Actor_SetDestination(GARET, leader->x.part.pixel, leader->z.part.pixel);
724 }
727 if (leader != NULL) {
728 Actor_SetDestination(JENNA, leader->x.part.pixel, leader->z.part.pixel);
729 }
732 if (leader != NULL) {
734 leader->z.part.pixel);
735 }
748}
749
750/// Kraden looks around the outer block room and decides a hidden passage must
751/// lead deeper in; Garet asks whether to split up. Called by
752/// SolSanctumEntrance_RestoreInteriorState in the outer block room until
753/// FLAG_SEARCHING_FOR_HIDDEN_PASSAGE is set. Sets
754/// FLAG_SEARCHING_FOR_HIDDEN_PASSAGE and clears FLAG_SHOW_LOCATION_NAME.
756 struct FieldActor *leader;
757
761
762 // Spread the party out while Kraden examines the room.
764 if (leader != NULL)
767 if (leader != NULL)
768 Engine_ActorSetPosition(JENNA, leader->x.fixed, leader->z.fixed);
770 if (leader != NULL)
771 Engine_ActorSetPosition(GARET, leader->x.fixed, leader->z.fixed);
772
773 Actor_SetSpeed(ACTOR_KRADEN, PIXELS(3) / 5, PIXELS(3) / 10);
774 Actor_SetSpeed(JENNA, PIXELS(3) / 5, PIXELS(3) / 10);
775 Actor_SetSpeed(GARET, PIXELS(3) / 5, PIXELS(3) / 10);
818
819 // Survey both sides of the room before returning to Kraden.
820 Camera_SetSpeed(PIXELS(2), PIXELS(1) / 4);
821 Camera_MoveTo(PIXELS(1585), -1, PIXELS(150), 1);
824 Camera_SetSpeed(PIXELS(6) / 5, PIXELS(3) / 20);
825 Camera_MoveTo(PIXELS(1621), -1, PIXELS(100), 1);
827 Camera_MoveTo(PIXELS(1718), -1, PIXELS(100), 1);
830 Camera_MoveTo(PIXELS(1752), -1, PIXELS(150), 1);
833 Camera_SetSpeed(PIXELS(12) / 5, PIXELS(3) / 10);
834 Camera_MoveTo(PIXELS(1668), -1, PIXELS(256), 1);
838
842 // Garet: "What's wrong, Kraden?"
843 Engine_EventSetMessage(MsgSolSanctumWrongKraden);
847 // Kraden: those two spoke of a hidden passage leading deeper in.
858 // Kraden: the sanctum always looked strange to him, not as he imagined.
870 // Jenna: "What do you mean?"
873 // Kraden: a sanctum built in honour of the sun ought to show it somewhere.
886 // Kraden: "If there is a hidden passage, then maybe it leads to..."
890
891 // Kraden hops: "Let's see if we can find it!"
894 // Garet: "I think he's serious! Should we help him?"
896 if (Engine_EventChooseYesNo(0, 0) == 0) {
897 // Yes: Garet says it is too dangerous to split up; they stay together.
898 Engine_EventSetMessage(MsgSolSanctumDangerousSplitStay);
901 } else {
902 // No: Jenna objects to turning back now; Isaac nods and Garet agrees to
903 // help Kraden.
904 Engine_EventSetMessage(MsgSolSanctumCantSeriouslyWant);
920 }
921
922 // Bring Kraden back and return the followers to the party.
923 Actor_SetSpeed(ACTOR_KRADEN, PIXELS(3) / 5, PIXELS(3) / 10);
939
941 if (leader != NULL)
942 Engine_ActorSetDestination(GARET, leader->x.part.pixel,
943 leader->z.part.pixel);
946 if (leader != NULL)
947 Engine_ActorSetDestination(JENNA, leader->x.part.pixel,
948 leader->z.part.pixel);
951 if (leader != NULL)
953 leader->z.part.pixel);
954
965}
966
967/// Shows the inner statues that Kraden cannot reach; he asks Isaac to try
968/// Psynergy. Called by SolSanctumEntrance_RestoreInteriorState in the inner
969/// block room until FLAG_SOL_SANCTUM_INNER_STATUES_SEEN is set, which it sets.
971 struct FieldActor *leader;
972
979 if (leader != NULL) {
980 Actor_SetPosition(ACTOR_KRADEN, leader->x.fixed, leader->z.fixed);
981 }
990 Camera_SetSpeed(PIXELS(12) / 5, PIXELS(3) / 10);
991 // Pan across the statues, then return to the party's position.
992 Camera_MoveTo(PIXELS(1672), -1, PIXELS(524), 1);
995 Camera_SetSpeed(PIXELS(8) / 5, PIXELS(1) / 5);
996 Camera_MoveTo(PIXELS(1880), -1, PIXELS(524), 1);
999 Camera_SetSpeed(PIXELS(16) / 5, PIXELS(2) / 5);
1000 Camera_MoveTo(PIXELS(1769), -1, PIXELS(548), 1);
1002 Engine_EventWait(20);
1005 // Kraden: "More statues... It doesn't look like we can reach them".
1006 Engine_EventSetMessage(MsgSolSanctumMoreStatuesOutOfReach);
1011 // Kraden: "Perhaps Psynergy is the key..."
1015 if (leader != NULL) {
1016 Actor_SetDestination(ACTOR_KRADEN, leader->x.part.pixel,
1017 leader->z.part.pixel);
1018 }
1023}
1024
1025/// Restores the inner blocks' collision cells and, when placeActors is
1026/// nonzero (on entry), moves the blocks to their saved columns.
1028 // Clear all six destinations before restoring occupied cells.
1029 Map_CopyCellAttributes(122, 20, 1, 1, 100, 32);
1030 Map_CopyCellAttributes(122, 20, 1, 1, 104, 32);
1031 Map_CopyCellAttributes(122, 20, 1, 1, 108, 32);
1032 Map_CopyCellAttributes(122, 20, 1, 1, 112, 32);
1033 Map_CopyCellAttributes(122, 20, 1, 1, 116, 32);
1034 Map_CopyCellAttributes(122, 20, 1, 1, 120, 32);
1036 Map_CopyCellAttributes(121, 20, 1, 1, 100, 32);
1037 if (placeActors != 0) {
1039 }
1040 } else {
1042 Map_CopyCellAttributes(121, 20, 1, 1, 100, 32);
1043 if (placeActors != 0) {
1045 }
1046 }
1047 }
1049 Map_CopyCellAttributes(121, 20, 1, 1, 104, 32);
1050 if (placeActors != 0) {
1052 }
1053 } else {
1055 Map_CopyCellAttributes(121, 20, 1, 1, 104, 32);
1056 if (placeActors != 0) {
1058 }
1059 }
1060 }
1062 Map_CopyCellAttributes(121, 20, 1, 1, 108, 32);
1063 if (placeActors != 0) {
1065 }
1066 } else {
1068 Map_CopyCellAttributes(121, 20, 1, 1, 108, 32);
1069 if (placeActors != 0) {
1071 }
1072 }
1073 }
1075 Map_CopyCellAttributes(121, 20, 1, 1, 112, 32);
1076 if (placeActors != 0) {
1078 }
1079 } else {
1081 Map_CopyCellAttributes(121, 20, 1, 1, 112, 32);
1082 if (placeActors != 0) {
1084 }
1085 }
1086 }
1088 Map_CopyCellAttributes(121, 20, 1, 1, 116, 32);
1089 if (placeActors != 0) {
1091 }
1092 } else {
1094 Map_CopyCellAttributes(121, 20, 1, 1, 116, 32);
1095 if (placeActors != 0) {
1097 }
1098 }
1099 }
1101 Map_CopyCellAttributes(121, 20, 1, 1, 120, 32);
1102 if (placeActors != 0) {
1104 }
1105 } else {
1107 Map_CopyCellAttributes(121, 20, 1, 1, 120, 32);
1108 if (placeActors != 0) {
1110 }
1111 }
1112 }
1113}
1114
1115/// Searching the door beside the way in. "The door is tightly locked."
1116/// Reached by searching cell code 10 on the approach.
1117static void Event_DoorTightlyLocked(void) {
1119 Engine_MessageShowCentered(MsgFieldDoorTightlyLocked, 1);
1121}
1122
1123/// After the eruption the approach rumbles now and then, and each shake fades.
1124/// Run each frame as a callback that SolSanctumEntrance_ApplyEntryState adds
1125/// once FLAG_SOL_SANCTUM_ERUPTED is set.
1127 s32 randomValue;
1128 s32 *timer;
1129 s32 remainingFrames;
1130
1132 if (*timer != 0) {
1133 remainingFrames = (*timer - 1);
1134 *timer = (*timer - 1);
1135 if (remainingFrames == 40) {
1136 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1137 }
1138 } else {
1139 randomValue = Engine_RandomNext();
1140 if (((u32)(((randomValue << 4) - randomValue) << 3) >> 16) == 0) {
1143 *timer = 80;
1144 }
1145 }
1146}
1147
1149 {0, CONDITION_ALWAYS, 172, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
1151};
1152
1154 {0, CONDITION_ALWAYS, 172, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
1155 {1, CONDITION_ALWAYS, 80, 0, 288, FACING_NORTH, 0, -1, -1, -1, -1, 0},
1156 {2, CONDITION_ALWAYS, 120, 0, 112, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
1158};
1159
1161 {0, CONDITION_ALWAYS, 172, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
1162 {1, CONDITION_ALWAYS, 280, 0, 472, FACING_NORTH, 0, 5, 0, 555, 510, 0},
1163 {2, CONDITION_ALWAYS, 72, 0, 56, FACING_SOUTH, 0, 5, 0, 555, 510, 0},
1164 {3, CONDITION_ALWAYS, 744, 0, 152, FACING_NORTH, 0, 620, 0, 860, 195, 0},
1165 {4, CONDITION_ALWAYS, 696, 0, 568, FACING_NORTH, 0, 575, 265, 815, 610, 0},
1166 {5, CONDITION_ALWAYS, 696, 0, 328, FACING_SOUTH, 0, 575, 265, 815, 610, 0},
1167 {6, CONDITION_ALWAYS, 984, 0, 152, FACING_NORTH, 0, 860, 0, 1100, 195, 0},
1168 {7, CONDITION_ALWAYS, 984, 0, 56, FACING_SOUTH, 0, 860, 0, 1100, 195, 0},
1169 {8, CONDITION_ALWAYS, 1224, 0, 184, FACING_NORTH, 0, 1100, 20, 1340, 220,
1170 0},
1171 {9, CONDITION_ALWAYS, 1224, 0, 104, FACING_SOUTH, 0, 1100, 20, 1340, 220,
1172 0},
1173 {10, CONDITION_ALWAYS, 1320, 0, 456, FACING_NORTH, 0, 905, 285, 1365, 490,
1174 0},
1175 {11, CONDITION_ALWAYS, 1672, 0, 280, FACING_NORTH, 0, 1455, 0, 1890, 310,
1176 0},
1177 {12, CONDITION_ALWAYS, 1512, 0, 136, FACING_SOUTH, 0, 1455, 0, 1890, 310,
1178 0},
1179 {13, CONDITION_ALWAYS, 1832, 0, 136, FACING_SOUTH, 0, 1455, 0, 1890, 310,
1180 0},
1181 {14, CONDITION_ALWAYS, 1768, 0, 568, FACING_NORTH, 0, 1540, 440, 1995, 600,
1182 0},
1183 {15, CONDITION_ALWAYS, 1672, 0, 520, FACING_SOUTH, 0, 1540, 440, 1995, 600,
1184 0},
1185 {16, CONDITION_ALWAYS, 1928, 0, 520, FACING_SOUTH, 0, 1540, 440, 1995, 600,
1186 0},
1188};
1189
1190// The approach (scene 19), then the halls inside (scene 16). The approach's
1191// way down leads to Vale (scene 4) until the eruption, then to scene 10 until
1192// the party has left Vale.
1194 SCENE_EXITS(19),
1197 SCENE_EXIT_IF(1, 4, 2, EXIT_FLAG_NONE),
1198 SCENE_EXIT_IF(2, 16, 8, EXIT_FLAG_NONE),
1199 SCENE_EXITS(16),
1200 SCENE_EXIT_IF(1, 15, 2, EXIT_FLAG_NONE),
1201 SCENE_EXIT_IF(2, 16, 11, EXIT_FLAG_NONE),
1202 SCENE_EXIT_IF(3, 16, 12, EXIT_FLAG_NONE),
1203 SCENE_EXIT_IF(4, 16, 9, EXIT_FLAG_NONE),
1204 SCENE_EXIT_IF(5, 15, 1, EXIT_FLAG_NONE),
1205 SCENE_EXIT_IF(6, 16, 13, EXIT_FLAG_NONE),
1206 SCENE_EXIT_IF(7, 14, 1, EXIT_FLAG_NONE),
1207 SCENE_EXIT_IF(8, 19, 2, EXIT_FLAG_NONE),
1208 SCENE_EXIT_IF(9, 16, 4, EXIT_FLAG_NONE),
1209 SCENE_EXIT_IF(10, 16, 15, EXIT_FLAG_NONE),
1210 SCENE_EXIT_IF(11, 16, 2, EXIT_FLAG_NONE),
1211 SCENE_EXIT_IF(12, 16, 3, EXIT_FLAG_NONE),
1212 SCENE_EXIT_IF(13, 16, 6, EXIT_FLAG_NONE),
1213 SCENE_EXIT_IF(14, 14, 2, EXIT_FLAG_NONE),
1214 SCENE_EXIT_IF(15, 16, 10, EXIT_FLAG_NONE),
1215 SCENE_EXIT_IF(16, 11, 1, EXIT_FLAG_NONE),
1217};
1218
1221};
1222
1223// clang-format off
1226 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1228 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1230 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1231 { 0xcb, 0x0, ACTOR_STAND,
1232 PIXELS(744), 0, PIXELS(56), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1233 { SCENE_TABLE_END },
1234};
1235
1238 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1240 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1242 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1244 PIXELS(1512), 0, PIXELS(136), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1265 { SCENE_TABLE_END },
1266};
1267
1270 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1272 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1274 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1276 PIXELS(1608), 0, PIXELS(520), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1287 { SCENE_TABLE_END },
1288};
1289
1292 0, 0, 0, FACING_SOUTH + FACING_STEP, TALK_FACE_PARTY, 0 },
1293 { SCENE_TABLE_END },
1294};
1295
1297 { SCENE_EVENTS_END },
1298};
1299
1301 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1304 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgValeItIsVeryDangerousToGo) },
1305 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgValeIAmAllAloneInThis) },
1306 { SCENE_EVENTS_END },
1307};
1308
1310 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1311 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1312 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1313 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1314 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1315 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
1316 { 0x21, 7, CONDITION_ALWAYS, 7 },
1317 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
1318 { EVENT_EXIT, 9, CONDITION_ALWAYS, 9 },
1319 { EVENT_EXIT, 10, CONDITION_ALWAYS, 10 },
1320 { EVENT_EXIT, 11, CONDITION_ALWAYS, 11 },
1321 { EVENT_EXIT, 12, CONDITION_ALWAYS, 12 },
1322 { EVENT_EXIT, 13, CONDITION_ALWAYS, 13 },
1323 { EVENT_EXIT, 14, CONDITION_ALWAYS, 14 },
1324 { EVENT_EXIT, 15, CONDITION_ALWAYS, 15 },
1325 { EVENT_EXIT, 16, CONDITION_ALWAYS, 16 },
1329 { SCENE_EVENTS_END },
1330};
1331
1333 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1334 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1335 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1336 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1337 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1338 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
1339 { 0x21, 7, CONDITION_ALWAYS, 7 },
1340 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
1341 { EVENT_EXIT, 9, CONDITION_ALWAYS, 9 },
1342 { EVENT_EXIT, 10, CONDITION_ALWAYS, 10 },
1343 { EVENT_EXIT, 11, CONDITION_ALWAYS, 11 },
1344 { EVENT_EXIT, 12, CONDITION_ALWAYS, 12 },
1345 { EVENT_EXIT, 13, CONDITION_ALWAYS, 13 },
1346 { EVENT_EXIT, 14, CONDITION_ALWAYS, 14 },
1347 { EVENT_EXIT, 15, CONDITION_ALWAYS, 15 },
1348 { EVENT_EXIT, 16, CONDITION_ALWAYS, 16 },
1354 { SCENE_EVENTS_END },
1355};
1356
1358 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1359 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1360 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1361 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1362 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1363 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
1364 { 0x21, 7, CONDITION_ALWAYS, 7 },
1365 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
1366 { EVENT_EXIT, 9, CONDITION_ALWAYS, 9 },
1367 { EVENT_EXIT, 10, CONDITION_ALWAYS, 10 },
1368 { EVENT_EXIT, 11, CONDITION_ALWAYS, 11 },
1369 { EVENT_EXIT, 12, CONDITION_ALWAYS, 12 },
1370 { EVENT_EXIT, 13, CONDITION_ALWAYS, 13 },
1371 { EVENT_EXIT, 14, CONDITION_ALWAYS, 14 },
1372 { EVENT_EXIT, 15, CONDITION_ALWAYS, 15 },
1373 { EVENT_EXIT, 16, CONDITION_ALWAYS, 16 },
1383 { SCENE_EVENTS_END },
1384};
1385// clang-format on
1386
1387/// Packs a push step: X in the upper halfword, Z in the lower (pixels).
1388#define PUSH_STEP(x, z) (((x) << 16) | ((z) & 0xffff))
1389
1391 PUSH_STEP(16, 0), PUSH_STEP(16, 0), PUSH_STEP(16, 0), PUSH_STEP(0, 16),
1392 PUSH_STEP(0, 16), PUSH_STEP(0, 16), PUSH_STEP(0, 16), PUSH_STEP(-16, 0),
1393 PUSH_STEP(-16, 0), PUSH_STEP(-16, 0), PUSH_STEP(-16, 0), PUSH_STEP(0, -16),
1394 PUSH_STEP(0, -16), PUSH_STEP(0, -16), PUSH_STEP(0, -16), PUSH_STEP(16, 0),
1395};
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_MOVE
Definition ability_ids.h:15
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
static void Event_PushBlock(void)
Pushing a block: it slides one cell ahead with the leader behind it, if the cell is free.
Definition bilibin.c:645
#define GARET
Jerald.
#define JENNA
Jasmine.
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
The engine calls the debug menus import, and their palette swatch tiles.
static s32 FieldObject_CheckMovementCollision(struct FieldActor *actor, struct FieldPosition *position)
Definition engine_call.h:66
void FieldScene_PrepareActors(struct ScenePlacement *entry)
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
void Engine_ObjectSetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
@ ANIM_WALK
Definition field_event.h:44
@ ANIM_STAND
Definition field_event.h:43
@ ANIM_NOD
Definition field_event.h:45
static s32 Event_OpenMessage(s32 speaker, s32 flags)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Object_SetMode(struct FieldActor *object, s32 animation)
#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_EventShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
#define GameFlag_IsSet
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
static void Camera_SetSpeed(s32 speed, s32 acceleration)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
static void Actor_SetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_EventCloseScreen(void)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
static void Map_CopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
#define GameFlag_Clear
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_GameFlagClear(s32 flag)
void Engine_CameraWaitForMove(void)
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
static void Event_ShowMessage(s32 speaker, s32 flags)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
s32 Engine_GameFlagIsSet(s32 flag)
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 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_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ActorFaceEachOther(s32 actor, s32 other, s32 frames)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
Field objects and actors, and the scene transition styles.
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ TRANSITION_BACKDROP_FADE
Definition field_obj.h:16
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define USE_ITEM(item)
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ FLAG_PARTY_LEFT_VALE
Definition field_scene.h:50
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
#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_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define TOUCH_WALKING
#define PIXELS(value)
#define SCENE_EXIT_IF(exit, scene, entrance, flag)
Definition field_scene.h:75
@ SEARCH_UNNAMED
@ SEARCH_CHEST
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static s32 Task_AddCallback(void(*callback)(void), s32 priority)
Calls the main-image scheduler through engine_call.h.
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
#define FLAG_SHOW_LOCATION_NAME
Definition flags.h:94
#define FLAG_SOL_SANCTUM_FIRST_SMALL_JEWEL_FOUND
The chests: the Small Jewel for each minotaur relief, and a Herb.
Definition flags.h:686
#define FLAG_SCENE_TEMP_34
Definition flags.h:765
#define FLAG_SOL_SANCTUM_SECOND_GEM_PLACED
Definition flags.h:101
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_SOL_SANCTUM_ERUPTED
The volcano has erupted and the sanctum's rooms rumble and shake.
Definition flags.h:660
#define FLAG_SOL_SANCTUM_SECOND_SMALL_JEWEL_FOUND
Definition flags.h:687
#define FLAG_SOL_SANCTUM_INNER_STATUES_SEEN
Kraden has seen the statues out of his reach behind the blocks.
Definition flags.h:671
#define FLAG_SOL_SANCTUM_ENTERED
Definition flags.h:97
#define FLAG_VALE_RETURNED_FROM_MT_ALEPH
Isaac and Garet followed the elders into the sanctum.
Definition flags.h:535
#define FLAG_ITEM_USED_UP
the item just used is removed afterwards
Definition flags.h:52
#define FLAG_SOL_SANCTUM_FIRST_GEM_PLACED
Definition flags.h:100
#define FLAG_SEARCHING_FOR_HIDDEN_PASSAGE
Definition flags.h:98
GameState, the game's state: play time, coins, the scene and the leader's position,...
struct GameState gGameState
The screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
Item numbers, named from the English release.
@ ITEM_SMALL_JEWEL
Definition item_ids.h:66
Small statement macros both games use for positions, velocities and bounds.
#define SET_POSITION(p, px, py, pz)
Sets the position or the velocity of a particle, a piece of debris or an object in one statement.
Definition macros.h:16
The reel game's title lettering.
void Battle_ResetEffectCounter(void)
Clears the field's busy flag and, while Reveal is active, ends it: Reveal used with ACT_PACKED runs i...
Definition targets.c:261
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
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
Scene numbers, named after their places.
char SceneId_SolSanctumEntrance2
char SceneId_SolSanctumEntrance1
#define FLAG_SOL_SANCTUM_INNER_BLOCK_3_WEST
static void Event_InspectFirstMinotaurRelief(void)
Searching the first minotaur relief: one eye sparkles, or both once the Small Jewel is set.
void InitializeSceneRecordBuffer()
static void Event_SetFirstSmallJewel(void)
Using the Small Jewel on the first relief: the leader sets it in and a passage opens.
#define FLAG_SOL_SANCTUM_INNER_BLOCK_6_WEST
struct SceneEntrance gSolSanctumEntranceEntrances1[]
static void Event_InnerBlock3Moved(void)
As Event_InnerBlock1Moved, for the third block (actor 11).
struct SceneEntrance gSolSanctumEntranceEntrances2[]
#define FLAG_SOL_SANCTUM_INNER_BLOCK_5_EAST
static void SolSanctumEntrance_InspectInnerStatues(void)
Shows the inner statues that Kraden cannot reach; he asks Isaac to try Psynergy.
static void Event_InnerBlock4Moved(void)
As Event_InnerBlock1Moved, for the fourth block (actor 12).
struct SceneEvent gSolSanctumEntranceEventsOther[]
const struct SceneEntrance * SolSanctumEntrance_GetEntrances(void)
Returns the approach's entrances (scene 19) or the halls' (scene 16), which share this overlay.
static void Event_InnerBlock1Moved(void)
Moving an inner block with Move: the column it stops in is saved and the floor under all six is set a...
#define FLAG_SOL_SANCTUM_OUTER_LEFT_BLOCK_EAST
struct SceneEvent gSolSanctumEntranceEvents1Entrances14To16[]
static void Event_InnerBlock6Moved(void)
As Event_InnerBlock1Moved, for the sixth block (actor 14).
#define FLAG_SOL_SANCTUM_INNER_BLOCK_5_WEST
static void SolSanctumEntrance_RecordBlockColumn(s32 column, s32 flagBase, s32 leftColumn, s32 rightColumn)
Remembers which of a movable block's two destination columns it occupies.
static void Event_SetSecondSmallJewel(void)
Using the Small Jewel on the second relief: as the first, and the inner doorway opens.
static void Event_InspectSecondMinotaurRelief(void)
Searching the second minotaur relief, as the first.
struct SceneEvent gSolSanctumEntranceEvents2[]
const u32 * SolSanctumEntrance_GetExits(void)
static void SolSanctumEntrance_RestoreInteriorState(void)
Restores opened passages and the current room's block positions, and plays a room's first cutscene.
#define FLAG_SOL_SANCTUM_INNER_BLOCK_2_WEST
const struct ScenePlacement * SolSanctumEntrance_GetPlacements(void)
Selects the actors for the current map and puzzle room.
s32 gSolSanctumEntrance_RumbleTimer
#define FLAG_SOL_SANCTUM_INNER_BLOCK_2_EAST
#define FLAG_SOL_SANCTUM_INNER_BLOCK_4_EAST
#define FLAG_SOL_SANCTUM_OUTER_LEFT_BLOCK_WEST
#define FLAG_SOL_SANCTUM_INNER_BLOCK_3_EAST
u32 gSolSanctumEntrance_Exits[]
#define FLAG_SOL_SANCTUM_OUTER_RIGHT_BLOCK_EAST
#define FLAG_SOL_SANCTUM_OUTER_RIGHT_BLOCK_WEST
struct ScenePlacement gSolSanctumEntrancePlacements1[]
static void SolSanctumEntrance_RestoreInnerBlockCells(s32 placeActors)
Restores the inner blocks' collision cells and, when placeActors is nonzero (on entry),...
#define FLAG_SOL_SANCTUM_INNER_BLOCK_4_WEST
static void Event_InnerBlock5Moved(void)
As Event_InnerBlock1Moved, for the fifth block (actor 13).
static void Event_OuterRightBlockMoved(void)
Moving the outer right block with Move: the column it stops in is saved.
struct SceneEntrance gSolSanctumEntranceEntrancesOther[]
#define EXIT_FLAG_NONE
static void Event_OuterLeftBlockMoved(void)
Moving the outer left block with Move: the column it stops in is saved.
#define FLAG_SOL_SANCTUM_INNER_BLOCK_1_WEST
static void Event_OpenDoorAndEnter(void)
Walking up to the sanctum's door: it slides open and the leader walks in.
#define PUSH_STEP(x, z)
Packs a push step: X in the upper halfword, Z in the lower (pixels).
s32 gSolSanctumPushSteps[]
static void SolSanctumEntrance_ApplyEntryState(void)
Sets up the approach: after the eruption it rumbles now and then, the collision of two rows of cells ...
const struct SceneEvent * SolSanctumEntrance_GetEvents(void)
Selects the events for the current map and puzzle room, by the same entrances as SolSanctumEntrance_G...
struct ScenePlacement gSolSanctumEntrancePlacements1Entrances14To16[]
static void Event_DoorTightlyLocked(void)
Searching the door beside the way in.
#define FLAG_SOL_SANCTUM_INNER_BLOCK_6_EAST
s32 SolSanctumEntrance_Initialize(void)
Restores the outdoor or interior state for this entrance.
struct ScenePlacement gSolSanctumEntrancePlacements1Entrances11To13[]
struct ScenePlacement gSolSanctumEntrancePlacementsOther[]
#define FLAG_SOL_SANCTUM_INNER_BLOCK_1_EAST
static void Event_InnerBlock2Moved(void)
As Event_InnerBlock1Moved, for the second block (actor 10).
const struct SceneRegion * SolSanctumEntrance_GetRegions(void)
static void SolSanctumEntrance_KradenSuspectsHiddenPassage(void)
Kraden looks around the outer block room and decides a hidden passage must lead deeper in; Garet asks...
static void SolSanctumEntrance_UpdateEruptionRumbles(void)
After the eruption the approach rumbles now and then, and each shake fades.
struct SceneEvent gSolSanctumEntranceEvents1Entrances11To13[]
struct ScenePlacement gSolSanctumEntrancePlacements2[]
static void SolSanctumEntrance_IntroduceSanctum(void)
Kraden welcomes the party into Sol Sanctum on their first visit, asking whether it is their first tim...
static void SolSanctumEntrance_ReactToOpeningPassage(void)
The room shakes as stone shifts; the leader looks around and jumps.
struct SceneEvent gSolSanctumEntranceEvents1[]
Song and sound effect ids, indices into gSound_SongTable.
#define SE_181
Definition songs.h:176
#define SE_185
Definition songs.h:180
#define SE_183
Definition songs.h:178
#define SE_182
Definition songs.h:177
#define SE_141
Definition songs.h:134
#define SE_ITEM_BREAK
Definition songs.h:131
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_TaskWait()
void Engine_EventSetMessage()
#define NULL
Definition bilibin.h:6
@ ACTOR_INNER_BLOCK_3
@ ACTOR_INNER_BLOCK_5
@ ACTOR_INNER_BLOCK_4
@ ACTOR_INNER_BLOCK_1
@ ACTOR_INNER_BLOCK_2
@ ACTOR_INNER_BLOCK_6
@ ACTOR_OUTER_RIGHT_BLOCK
@ ACTOR_OUTER_LEFT_BLOCK
@ ACTOR_APPROACH_SENTRY
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
u16 unk172
FieldWork's menu request; scenes set it to 1.
Definition event_work.h:29
u16 message
the next message, advanced as each window opens
Definition event_work.h:47
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
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
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 velocityZ
16.16 fixed-point pixels per frame
Definition field_obj.h:54
u8 terrainId
The map layer (0 to 3) its ground height is read from, which the scrolling camera updates from the ce...
Definition field_obj.h:47
A position on the field.
s32 z
16.16 fixed-point pixels
s16 retreatEntrance
where Retreat goes; the group's first entrance
Definition game_state.h:109
s16 retreatScene
where Retreat goes; the group's first entrance
Definition game_state.h:108
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...
u32 value
A message below 0x10000, else an event function; for an exit, the exit kind its scene's exit table ma...
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 system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
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
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels