Alchemy
Loading...
Searching...
No Matches

alpine_crossing_lama_temple.c

Go to the documentation of this file.
1/// @file
2/// Alpine Crossing and Lama Temple, two scenes that share this overlay:
3///
4/// - Alpine Crossing, the stretch of the Silk Road where a rockslide traps Hsu.
5/// Feizhi, Master Hama and the party meet there, and the party frees Hsu with
6/// Lift.
7/// - Lama Temple, Master Hama's temple, with its monks, a wall that only Reveal
8/// sees through, and Hama's farewell once Hsu is safe.
9
10#include "script.h"
11#include "game_state.h"
13#include "unit/object/object.h"
16#include "battle.h"
17#include "debug.h"
18#include "field.h"
19#include "game.h"
20#include "graphics.h"
21#include "menu.h"
22#include "minigame.h"
23#include "sound.h"
24#include "system.h"
25#include "types.h"
26#include "field_event.h"
27#include "field_scene.h"
28#include "scene_ids.h"
29#include "call.h"
30#include "text/msg_ids.h"
31#include "ability_ids.h"
32#include "flags.h"
33#include "item_ids.h"
34#include "objcmd.h"
35#include "field_effect.h"
36#include "songs.h"
37
38// Place flags: Scene_ResetFlagsOnEnter clears 0x300 to 0x3ff when the party
39// enters another place group, and other places use the numbers for their own.
40#define FLAG_LAMA_TEMPLE_PSYNERGY_STONE 0x350 ///< the temple's Psynergy Stone
41
42#define SCENE_ALPINE_CROSSING ((s32)&SceneId_AlpineCrossingLamaTemple1)
43#define SCENE_LAMA_TEMPLE ((s32)&SceneId_AlpineCrossingLamaTemple2)
44
45/// Lama Temple's actors. Garet, Ivan and Mia are placed in their own party
46/// slots for Hama's farewell; the others count from ACTOR_FIRST_PLACED.
56};
57
58/// Alpine Crossing's actors.
68};
69
73};
74
79};
80
81/// The exit that takes the party from the rescue to Hama's farewell, at Lama
82/// Temple's entrance 3.
84
85/// Alpine Crossing's Psynergy puzzles, kept while the party stays.
86enum {
89};
90
91enum {
98};
99
100/// Map triggers that the events below refer to.
101enum {
108};
109
110/// The door of Hama's room, three cells wide and two high: each step copies
111/// the next door picture onto it for five frames.
112enum { DOOR_X = 67, DOOR_Y = 6 };
113
114/// A search made while facing the given way.
115#define SEARCH_FACING(facing) (EVENT_SEARCH | EVENT_TOUCH_FACING | (facing))
116
117/// The map object that draws the passage behind the false wall.
118enum { MAP_OBJECT_PASSAGE = 100 };
119
120/// Draws the actor behind the background, on sprite priority 3 with automatic
121/// priority off. The first worker from Xian runs it from his placement.
122static s32 Actor_DrawBehindScenery(struct ScriptInterpreter *interpreter) {
123 union FieldObject *object = (union FieldObject *)interpreter;
124 object->actor.priorityFlags &= ~ACTOR_PRIORITY_AUTOMATIC;
125 object->actor.sprite->image.priority = 3;
126 object->actor.sprite->shadow.priority = 3;
127 return 0;
128}
129
130// Update callback that turns the party leader toward Feizhi while she runs
131// past.
132// UB: update hooks return void. Plain void removes the native zero result
133// and changes its return sequence (three instructions in tbs-en).
134#ifdef UBFIX
135static void Leader_FaceFeizhi(union FieldObject *object) {
136#else
137static s32 Leader_FaceFeizhi(union FieldObject *object) {
138#endif
139 struct FieldActor *leader = (struct FieldActor *)object;
140 struct FieldActor *feizhi;
141
143 leader->facing = ArcTan2(feizhi->z.fixed - leader->z.fixed,
144 feizhi->x.fixed - leader->x.fixed);
145#ifndef UBFIX
146 return 0;
147#endif
148}
149
153 }
155}
156
157const struct SceneRegion *Scene_GetRegions(void) { return 0; }
158
159/// Both scenes share one exit table.
161
165 }
167}
168
169/// The eastward monk asks whether the party came from the east, across
170/// Lamakan Desert, and otherwise whether it stopped in Xian.
172
174 Engine_EventSetMessage(MsgMountainYoungWarriorsDoComeFrom);
176
177 if (Engine_EventChooseYesNo(0, 0) == 1) {
180 } else {
183 }
184
186}
187
188/// The meditating monk explains meditation.
191 Engine_EventSetMessage(MsgMountainDoKnowMeditation);
194}
195
196/// The monk who praises Master Hama as the greatest master of Chi.
197static void LamaTemple_TalkToChiMonk(void) {
199 Engine_EventSetMessage(MsgMountainDidKnowMasterHamaGreatest);
202}
203
204/// Walking north into the door of Hama's room slides it open and walks the
205/// party leader through, into the room.
206static void LamaTemple_EnterHamasRoom(void) {
210 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0xcccc, 0x6666);
216}
217
218/// Hama's farewell, once the party has freed Hsu: she thanks the Adepts,
219/// Garet and Mia squabble over whose idea helping was, and Hama goes back to
220/// her room. Ivan wonders aloud about what Hama told him, and the others walk
221/// out ahead of the party leader. Mia's question is a yes or no choice.
228 Actor_SetPosition(IVAN, PIXELS(128), PIXELS(200));
229 Actor_SetPosition(MIA, PIXELS(112), PIXELS(192));
238
239 // "Adepts, let me thank you again."
242 Engine_EventSetMessage(MsgMountainAdeptsLetMeThankAgain);
262 Engine_EventWait(120);
263
264 // Garet claims that helping was his idea and asks the leader to agree.
269 if (Engine_EventChooseYesNo(0, 0) == 0) {
282 } else {
293 }
294
295 // Hama wishes them well and goes back into her room.
323 // The door slides open with SE_188, Hama walks through, and it slides shut.
326 Actor_SetSpeed(ACTOR_TEMPLE_HAMA, 0xcccc, 0x6666);
333
334 // Garet asks whether the leader means to leave Hama's words unasked.
348
349 // Ivan decides that Hama will tell him when their mission is done.
387 Actor_SetSpeed(IVAN, 0x8000, 0x4000);
388 Actor_WalkToAndWait(IVAN, 128, 184);
400
401 // Garet, Ivan and Mia walk to the leader and rejoin the party.
402 Actor_SetSpeed(GARET, 0x8000, 0x4000);
403 Actor_SetSpeed(MIA, 0x8000, 0x4000);
404 Actor_WalkTo(GARET, 144, 200);
405 Actor_WalkTo(IVAN, 144, 200);
406 Actor_WalkTo(MIA, 144, 200);
410 Actor_SetPosition(IVAN, 0, 0);
412 Actor_SetPosition(MIA, 0, 0);
414}
415
416/// Searching the temple wall reads its writing, the hint toward Reveal.
417static void LamaTemple_ReadWallWriting(void) {
418
421 Engine_MessageShowCentered(MsgMountainHeWhoHasPowerSee, 1);
423}
424
425/// Puts the false wall back when Reveal's light ends (and on entry): the
426/// wall's cell blocks the way again, the passage's map object is hidden and
427/// the wall actor stands in front of it.
428static void LamaTemple_ShowFalseWall(void) {
429
430 Map_CopyCellAttributes(85, 9, 1, 1, 21, 9);
433}
434
435/// Reveal shows the passage behind the false wall: the cell's original
436/// attributes (saved at (21, 73) on entry) come back, the passage's map object
437/// returns to its place and the wall actor is put away.
438static void LamaTemple_RevealPassage(void) {
439 Map_CopyCellAttributes(21, 73, 1, 1, 21, 9);
442}
443
444/// The traveling healer offers the sanctum's services when spoken to across
445/// his counter, from the south; from any other side he only greets the party.
446static void LamaTemple_TalkToHealer(void) {
447
449
451 if (FACING_IS_NORTH(heading)) {
453 } else {
454 Engine_EventSetMessage(MsgMountainAmTravelingAroundWorldSpread);
456 }
458}
459
460/// When the party steps onto the road by the rockslide, once Feizhi has set
461/// out after Hsu, she runs up behind it: she finds the boulders blocking the
462/// Silk Road, cries out for Hsu and runs ahead along the path to look for
463/// him, the party leader following part of the way.
465 struct FieldActor *leader;
466
470 Engine_EventSetMessage(MsgMountainYahhSilkRoadBouldersBlock);
474
475 // The leader turns to follow Feizhi as she runs past; one standing in
476 // her row steps aside first.
478#ifdef UBFIX
479 leader->update = Leader_FaceFeizhi;
480#else
481 leader->update = (void (*)(union FieldObject *))Leader_FaceFeizhi;
482#endif
484 if ((leader->z.fixed >> 20) == 13) {
486 }
487 Actor_SetSpeed(ACTOR_FEIZHI, 0x20000, 0x10000);
498
499 // Feizhi runs down the path with the camera; the leader follows her
500 // until the camera arrives.
502 Camera_MoveTo(PIXELS(296), -1, PIXELS(344), 1);
506 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0x10000, 0x8000);
511 leader->update = NULL;
513
514 // She cannot hear Hsu's voice.
524 }
525}
526
527/// Feizhi, before Xian hears of the accident, asks whether she should return
528/// to Xian; either way she decides to keep looking for Hsu.
531 Engine_EventSetMessage(MsgMountainDoDoWarriorShouldReturn);
534 if (Engine_EventChooseYesNo(0, 0) == 1) {
536 }
542}
543
544/// Master Hama, kneeling by Hsu, asks if he is hurt; he is unhurt but cannot
545/// move, and none of them knows how to free him.
548 // Reveal Hsu's position before Hama and Feizhi discuss freeing him.
557 Engine_EventSetMessage(MsgMountainHsuOkay);
580}
581
582/// Lift on the boulder: it floats, and Hama and Feizhi pull Hsu free in two
583/// heaves of two tugs each, asking the leader in between to hold on. Hsu is
584/// free; they will ask Master Feh to tend him and clear the road, and the
585/// scene fades out to Hama's farewell at Lama Temple.
586static void AlpineCrossing_LiftBoulder(void) {
587
592 Engine_EventSetMessage(MsgMountainIsaacDidLiftBoulder);
604
605 // Hama and Feizhi take hold of Hsu.
606 Actor_WalkTo(ACTOR_HAMA, 178, 276);
617 Actor_SetSpeed(ACTOR_HAMA, 0x3333, 0x1999);
618 Actor_SetSpeed(ACTOR_FEIZHI, 0x3333, 0x1999);
619
620 // The first heave: two tugs draw Hsu halfway out.
645
646 // Hama asks the leader to hold the boulder a moment longer.
651
652 // The second heave pulls Hsu free.
681
682 // Feizhi steps back; they agree to send for Master Feh.
684 Actor_SetSpeed(ACTOR_FEIZHI, 0xcccc, 0x6666);
703}
704
705/// Searching the signpost. "North: Altin Mine. West: Lama Temple."
709 Engine_MessageShowCentered(MsgMountainNorthAltinMineWestLama, 1);
711}
712
713/// Reveal shows the path hidden at (5, 13): the revealed cells, kept at
714/// (5, 28), are copied there with their attributes.
715static void AlpineCrossing_RevealPath(void) {
716 Map_CopyCellsTo(5, 28, 5, 13, 1, 2);
717 Map_CopyCellAttributes(5, 28, 1, 2, 5, 13);
719}
720
721/// When Reveal's light ends, the plain cells kept at (6, 28) cover the path
722/// again.
723static void AlpineCrossing_HidePath(void) {
724 Map_CopyCellsTo(6, 28, 5, 13, 1, 2);
725 Map_CopyCellAttributes(6, 28, 1, 2, 5, 13);
727}
728
729// Update callback of the frozen pillar: it draws under the party leader
730// while the leader stands higher than its top, so the leader can climb onto
731// it, and over the leader otherwise.
732// UB: this update hook has no result. Plain void changes the native return
733// sequence from pop {r1}; bx r1 to pop {r0}; bx r0 (tbs-en).
734#ifdef UBFIX
735static void Pillar_SortAgainstLeader(union FieldObject *object) {
736#else
738#endif
739 struct FieldActor *pillar = (struct FieldActor *)object;
742 } else {
744 }
745}
746
747/// As Frost reaches the puddle, a leader standing north of it sees the pillar
748/// rise in front of the background.
751 struct FieldActor *puddle = Object_GetById(ACTOR_PUDDLE);
752
753 if (leader->z.fixed <= puddle->z.fixed) {
755 }
756}
757
758/// Frost freezes the puddle into a pillar the party can climb: it stops
759/// blocking movement and moving, sorts itself against the leader each frame,
760/// and the cells beside it (and their copy at (20, 18)) become walkable.
761/// Also run on entry while the pillar is already frozen.
764
765 // Stop the pillar and install its height-dependent drawing priority.
769#ifdef UBFIX
771#else
773 (void (*)(union FieldObject *))Pillar_SortAgainstLeader;
774#endif
775
776 Map_CopyCellAttributes(55, 16, 1, 1, 56, 18);
777 Map_CopyCellAttributes(55, 16, 1, 1, 20, 18);
778
783}
784
785/// Growth grows the sprout into a vine the party can climb: the two cells
786/// above it take the climbable attributes kept at (14, 6). Also run on entry
787/// while the vine is already grown.
788static void AlpineCrossing_GrowSprout(void) {
790 Map_CopyCellAttributes(14, 6, 1, 2, 21, 11);
794}
795
796const struct SceneEvent *Scene_GetEvents(void) {
799 }
800 return gLamaTemple_Events;
801}
802
803/// Sets up whichever scene is being entered and runs its arrival events.
805 s32 entrance;
806
809 // Lama Temple: the temple's queued sound (SE_169) plays, two monks
810 // meditate and the false wall stands; the wall's own cell attributes are
811 // saved at (21, 73) for Reveal to restore.
816 Map_CopyCellAttributes(21, 9, 1, 1, 21, 73);
821 }
822 entrance = gGameState.entrance;
823 if (entrance == TEMPLE_ENTRANCE_FROM_HAMAS_ROOM) {
825 } else if (entrance == TEMPLE_ENTRANCE_FAREWELL &&
828 }
829 } else if (gGameState.scene == SCENE_ALPINE_CROSSING) {
830 // Alpine Crossing: restore the Psynergy puzzles already solved.
836 }
840 }
844 }
845
846 // Feizhi is here only once she has set out after Hsu.
851 }
852
853 // Arriving from Lama Temple after Xian has heard of the accident: Hsu is
854 // already free and the boulder gone.
862 }
863
864 // Once Hsu is free, the cleared rocks open the road.
866 Map_CopyCellsTo(54, 21, 53, 21, 1, 2);
867 Map_CopyCellAttributes(18, 20, 1, 3, 17, 21);
868 Map_CopyCellsTo(44, 18, 43, 17, 1, 1);
869 Map_CopyCellAttributes(8, 17, 1, 1, 7, 17);
870 }
871
872 // While Hsu is trapped, Hama and Feizhi stand by him, and the workers
873 // from Xian have not come yet.
884 Object_GetById(ACTOR_HSU)->scaleX = -0x10000;
885 }
889 Object_GetById(ACTOR_HSU)->scaleX = -0x10000;
890 }
896 }
897 }
898 return 0;
899}
900
901/// The first worker's placement script: draw him behind the background.
904 SC_END,
905};
906
907/// Feizhi's run down the path toward Hsu, walking, then standing.
910 SC_MOVE(PIXELS(392), 0, PIXELS(232)),
911 SC_SYNC,
912 SC_MOVE(PIXELS(376), 0, PIXELS(232)),
913 SC_SYNC,
914 SC_MOVE(PIXELS(344), 0, PIXELS(264)),
915 SC_SYNC,
916 SC_MOVE(PIXELS(344), 0, PIXELS(312)),
917 SC_SYNC,
918 SC_MOVE(PIXELS(312), 0, PIXELS(344)),
919 SC_SYNC,
920 SC_MOVE(PIXELS(296), 0, PIXELS(344)),
921 SC_SYNC,
923 SC_END,
924};
925
926/// The party leader follows Feizhi most of the way.
929 SC_MOVE(PIXELS(392), 0, PIXELS(232)),
930 SC_SYNC,
931 SC_MOVE(PIXELS(376), 0, PIXELS(232)),
932 SC_SYNC,
933 SC_MOVE(PIXELS(344), 0, PIXELS(264)),
934 SC_SYNC,
935 SC_MOVE(PIXELS(344), 0, PIXELS(312)),
936 SC_SYNC,
937 SC_MOVE(PIXELS(328), 0, PIXELS(328)),
938 SC_SYNC,
940 SC_END,
941};
942
943/// Hsu, pinned under the boulder, struggles now and then.
947 SC_WAIT(240),
950 SC_WAIT(60),
953 SC_WAIT(300),
955 SC_END,
956};
957
958/// The door of Hama's room sliding open, and shut again.
960 MAP_CELL_STEP(66, 46, 3, 2, 5),
961 MAP_CELL_STEP(63, 46, 3, 2, 5),
963};
964
966 MAP_CELL_STEP(66, 46, 3, 2, 5),
967 MAP_CELL_STEP(69, 46, 3, 2, 5),
969};
970
972 {0, CONDITION_ALWAYS, 496, 0, 216, FACING_WEST, 0, -1, -1, -1, -1, 0},
973 {1, CONDITION_ALWAYS, 216, 0, 520, FACING_NORTH, 0, -1, -1, -1, -1, 0},
974 {2, CONDITION_ALWAYS, 136, 0, 168, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
975 {3, CONDITION_ALWAYS, 144, 0, 200, FACING_NORTH, 0, -1, -1, -1, -1, 0},
976 {5, CONDITION_ALWAYS, 232, 0, 352, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
978};
979
981 {0, CONDITION_ALWAYS, 496, 0, 216, FACING_WEST, 0, -1, -1, -1, -1, 0},
982 {1, CONDITION_ALWAYS, 496, 0, 216, FACING_WEST, 0, 16, 32, 520, 416, 0},
983 {2, CONDITION_ALWAYS, 384, 0, 72, FACING_SOUTH, 0, 16, 32, 520, 416, 0},
984 {3, CONDITION_ALWAYS, 40, 0, 280, FACING_EAST, 0, 16, 32, 520, 416, 0},
985 {4, CONDITION_ALWAYS, 88, 0, 248, FACING_SOUTH, 0, 16, 32, 520, 416, 0},
986 {5, CONDITION_ALWAYS, 216, 0, 248, FACING_SOUTH, 0, 16, 32, 520, 416, 0},
988};
989
991 SCENE_EXITS(88), SCENE_EXIT(1, 2, 17), SCENE_EXIT(2, 61, 3),
992 SCENE_EXIT(0, 74, 0), SCENE_EXIT(1, 2, 15), SCENE_EXIT(2, 2, 50),
993 SCENE_EXIT(3, 2, 51), SCENE_EXIT(4, 80, 6), SCENE_EXIT(5, 80, 7),
994 SCENE_EXIT(6, 88, 3), SCENE_EXITS_END,
995};
996
997// clang-format off
1000 0, 0, 0, FACING_NORTH, TALK_KEEP_FACING, 0 },
1002 0, 0, 0, FACING_NORTH, TALK_KEEP_FACING, 0 },
1004 0, 0, 0, FACING_NORTH, TALK_KEEP_FACING, 0 },
1008 PIXELS(168), 0, PIXELS(336), FACING_EAST, TALK_FACE_PARTY, 0 },
1010 PIXELS(216), 0, PIXELS(240), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1012 PIXELS(312), 0, PIXELS(320), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1014 PIXELS(344), 0, PIXELS(320), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1017 { 0x125, CONDITION_ALWAYS, ACTOR_STAND,
1018 PIXELS(344), 0, PIXELS(152), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1021 { SCENE_TABLE_END },
1022};
1023
1028 0, 0, 0, FACING_NORTH, TALK_KEEP_FACING, 0 },
1031 { 0x127, FLAG_HSU_RESCUED, ACTOR_STAND,
1032 PIXELS(152), 0, PIXELS(276), FACING_WEST, TALK_FACE_PARTY, 0 },
1034 PIXELS(456), 0, PIXELS(200), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1036 PIXELS(184), 0, PIXELS(264), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1038 PIXELS(328), 0, PIXELS(296), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1040 PIXELS(344), 0, PIXELS(194), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1041 { SCENE_TABLE_END },
1042};
1043
1045 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1047 { EVENT_TALK, ACTOR_GREETING_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleThisIsLamaTempleWelcomeTravelers) },
1050 { EVENT_TALK, ACTOR_ANXIOUS_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleYouWhoSpeakToMeI) },
1052 { EVENT_TALK, ACTOR_GREETING_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleItIsVeryDangerousToCross) },
1053 { EVENT_TALK, ACTOR_EASTWARD_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleTheEvilDesertIsHotterThan) },
1054 { EVENT_TALK, ACTOR_MEDITATING_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleIBelieveItIsPossibleTo) },
1055 { EVENT_TALK, ACTOR_ANXIOUS_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleIWillBeMostThankfulOnce) },
1056 { EVENT_TALK, ACTOR_CHI_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleWhenYourTemperatureReachesItsMaximum) },
1058 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_GREETING_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleTheySeemToBeAnxiousThey) },
1059 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_EASTWARD_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleTheySayAPersonCanOvercome) },
1060 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_MEDITATING_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleIAmHungry) },
1061 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_ANXIOUS_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleISenseImpureThoughtsFromThe) },
1062 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_CHI_MONK, FLAG_HSU_RESCUED, MSGNO(MsgAlpineCrossingLamaTempleChiIsButAFragmentOf) },
1063 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_GREETING_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleICannotCrossTheDesertIt) },
1064 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_EASTWARD_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleTheEvilInTheDesertDistorts) },
1065 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_MEDITATING_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleHowNiceItWouldBeIf) },
1066 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_ANXIOUS_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleMasterHamaWillBeVerySad) },
1067 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_CHI_MONK, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleWithRevealYouWillFindOases) },
1068 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_TRAVELING_HEALER, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleForSomeReasonThesePeopleGive) },
1077 { SCENE_EVENTS_END },
1078};
1079
1081 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1082 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1083 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1084 { EVENT_EXIT, 5, CONDITION_ALWAYS, 4 },
1085 { EVENT_EXIT, 4, CONDITION_ALWAYS, 5 },
1088 { EVENT_TALK, ACTOR_HAMA, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleWellIsaacAdeptsYouCameTo) },
1089 { EVENT_TALK, ACTOR_HSU, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleIAmTrappedBetweenTheseTwo) },
1090 { EVENT_TALK, ACTOR_FEIZHI, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleBeStrongHsuWeWillHelp) },
1091 { EVENT_TALK, ACTOR_FIRST_WORKER, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleWeMovedTheRocksNowPeople) },
1092 { EVENT_TALK, ACTOR_SECOND_WORKER, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleManyPeopleFromXianHelpedMove) },
1094 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_FEIZHI, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgAlpineCrossingLamaTempleHsuIsInDangerICan) },
1095 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_HAMA, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleHowShouldWeMoveTheBoulders) },
1096 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_HSU, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleIWantToScreamButFeizhi) },
1097 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_FEIZHI, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleHsuTiresHeLooksExhaustedI) },
1098 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_FIRST_WORKER, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleWeClearedTheWayButWhat) },
1099 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_SECOND_WORKER, CONDITION_ALWAYS, MSGNO(MsgAlpineCrossingLamaTempleIAlmostHurtMyBackIt) },
1102 // Frost's first phase, as it reaches the puddle
1108 { SCENE_EVENTS_END },
1109};
1110// clang-format on
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_REVEAL
Definition ability_ids.h:19
@ ABILITY_LIFT
Definition ability_ids.h:18
@ ABILITY_FROST
Definition ability_ids.h:11
@ ABILITY_GROWTH
Definition ability_ids.h:10
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.
static void LamaTemple_ReadWallWriting(void)
Searching the temple wall reads its writing, the hint toward Reveal.
static s32 Actor_DrawBehindScenery(struct ScriptInterpreter *interpreter)
Draws the actor behind the background, on sprite priority 3 with automatic priority off.
@ TEMPLE_ENTRANCE_FROM_HAMAS_ROOM
static void LamaTemple_RunHamasFarewell(void)
Hama's farewell, once the party has freed Hsu: she thanks the Adepts, Garet and Mia squabble over who...
struct ScenePlacement gLamaTemple_Placements[]
static void AlpineCrossing_LiftBoulder(void)
Lift on the boulder: it floats, and Hama and Feizhi pull Hsu free in two heaves of two tugs each,...
static void AlpineCrossing_GrowSprout(void)
Growth grows the sprout into a vine the party can climb: the two cells above it take the climbable at...
struct SceneEvent gAlpineCrossing_Events[]
s32 gAlpineCrossing_WorkerPlacementScript[]
The first worker's placement script: draw him behind the background.
static void LamaTemple_TalkToChiMonk(void)
The monk who praises Master Hama as the greatest master of Chi.
#define SCENE_LAMA_TEMPLE
u32 gAlpineCrossingLamaTemple_Exits[]
static void LamaTemple_TalkToHealer(void)
The traveling healer offers the sanctum's services when spoken to across his counter,...
u16 gLamaTemple_DoorOpenCells[]
The door of Hama's room sliding open, and shut again.
static s32 Leader_FaceFeizhi(union FieldObject *object)
static void AlpineCrossing_FeizhiArrives(void)
When the party steps onto the road by the rockslide, once Feizhi has set out after Hsu,...
struct SceneEntrance gLamaTemple_Entrances[]
static void LamaTemple_TalkToMeditatingMonk(void)
The meditating monk explains meditation.
LamaTempleActor
Lama Temple's actors.
#define FLAG_LAMA_TEMPLE_PSYNERGY_STONE
the temple's Psynergy Stone
s32 gAlpineCrossing_LeaderPath[]
The party leader follows Feizhi most of the way.
static void AlpineCrossing_RevealPath(void)
Reveal shows the path hidden at (5, 13): the revealed cells, kept at (5, 28), are copied there with t...
struct SceneEntrance gAlpineCrossing_Entrances[]
const struct ScenePlacement * Scene_GetPlacements(void)
@ CROSSING_ENTRANCE_FROM_LAMA_TEMPLE
const struct SceneEntrance * Scene_GetEntrances(void)
static void AlpineCrossing_HamaReachesHsu(void)
Master Hama, kneeling by Hsu, asks if he is hurt; he is unhurt but cannot move, and none of them know...
static void AlpineCrossing_HidePath(void)
When Reveal's light ends, the plain cells kept at (6, 28) cover the path again.
static void AlpineCrossing_TalkToFeizhi(void)
Feizhi, before Xian hears of the accident, asks whether she should return to Xian; either way she dec...
#define SCENE_ALPINE_CROSSING
s32 gAlpineCrossing_HsuStruggle[]
Hsu, pinned under the boulder, struggles now and then.
@ TRIGGER_TEMPLE_WALL_WRITING
static void LamaTemple_RevealPassage(void)
Reveal shows the passage behind the false wall: the cell's original attributes (saved at (21,...
s32 gAlpineCrossing_FeizhiPath[]
Feizhi's run down the path toward Hsu, walking, then standing.
const struct SceneEvent * Scene_GetEvents(void)
static void LamaTemple_TalkToEastwardMonk(void)
The eastward monk asks whether the party came from the east, across Lamakan Desert,...
static void LamaTemple_ShowFalseWall(void)
Puts the false wall back when Reveal's light ends (and on entry): the wall's cell blocks the way agai...
static void AlpineCrossing_ReadSignpost(void)
Searching the signpost. "North: Altin Mine. West: Lama Temple.".
const u32 * Scene_GetExits(void)
Both scenes share one exit table.
AlpineCrossingActor
Alpine Crossing's actors.
const struct SceneRegion * Scene_GetRegions(void)
@ CROSSING_EXIT_TO_FAREWELL
struct ScenePlacement gAlpineCrossing_Placements[]
struct SceneEvent gLamaTemple_Events[]
static s32 Pillar_SortAgainstLeader(union FieldObject *object)
#define SEARCH_FACING(facing)
A search made while facing the given way.
s32 Scene_Initialize(void)
Sets up whichever scene is being entered and runs its arrival events.
static void AlpineCrossing_FreezePuddle(void)
Frost freezes the puddle into a pillar the party can climb: it stops blocking movement and moving,...
static void LamaTemple_EnterHamasRoom(void)
Walking north into the door of Hama's room slides it open and walks the party leader through,...
u16 gLamaTemple_DoorCloseCells[]
static void AlpineCrossing_PrepareFrost(void)
As Frost reaches the puddle, a leader standing north of it sees the pillar rise in front of the backg...
Calls through a function pointer, by argument count.
#define GARET
Jerald.
#define MIA
Mary.
#define IVAN
Ivan.
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
The engine calls the debug menus import, and their palette swatch tiles.
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
static s32 Event_OpenMessage(s32 speaker, s32 flags)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Engine_SanctumOpen(s32 priest)
static void Map_AnimateCells(const u16 *steps, s32 destX, s32 destY)
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)
#define GameFlag_IsSet
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
void Engine_CameraMoveToActor(s32 actor, s32 pan)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
#define MAP_CELL_STEP(srcX, srcY, width, height, frames)
Definition field_event.h:59
static void Actor_SetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
static void Map_CopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
static void Event_SkipMessages(s32 count)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
s32 Engine_EventAskYesNo(s32 speaker, s32 flags)
void Engine_EventOpenScreen(void)
s32 Engine_EventOpenMessage(s32 speaker, s32 flags)
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)
static void Event_PlayCue(s32 cue)
void Engine_MapObjectSetPosition(s32 object, s32 fixed_x, s32 fixed_z)
#define MAP_CELL_STEPS_END
Definition field_event.h:61
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static s32 Event_AskYesNo(s32 speaker, s32 flags)
static void MapObject_SetPosition(s32 object, s32 fixed_x, s32 fixed_z)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
@ 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 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
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define PSYNERGY_PHASE_ON_ACTOR(ability, phase)
A Psynergy event on an actor at one phase of the cast, as PSYNERGY_IN_AREA is for an area.
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define PSYNERGY_IN_AREA(ability, phase)
#define IF_FLAG_SET(flag)
Definition field_scene.h:48
#define FIND_PSYNERGY_STONE
#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
@ TALK_FACE_PARTY_AND_BACK
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
@ ACTOR_WANDER
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
#define FACING_IS_NORTH(facing)
Definition field_scene.h:38
@ FACING_NORTHEAST
Definition field_scene.h:33
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTHWEST
Definition field_scene.h:29
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_UNNAMED
@ SEARCH_CHEST
Game flags, named where their meaning is shown.
#define FLAG_SHOW_LOCATION_NAME
Definition flags.h:94
#define FLAG_XIAN_HEARD_HSU_TRAPPED
Definition flags.h:112
#define FLAG_LAMA_TEMPLE_WATER_OF_LIFE
the temple's chest
Definition flags.h:141
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_HSU_RESCUED_WITHOUT_PARTY
Hsu was freed without the party: set with FLAG_HSU_RESCUED when the party comes back from Lama Temple...
Definition flags.h:139
#define FLAG_HAMA_REACHED_HSU
Hama has reached Hsu and spoken with him and Feizhi.
Definition flags.h:135
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_ALPINE_CROSSING_POWER_BREAD
the crossing's chest
Definition flags.h:140
#define FLAG_SCENE_TEMP_01
Definition flags.h:714
#define FLAG_FEIZHI_WENT_TO_HSU
Definition flags.h:113
#define FLAG_HSU_RESCUED
Definition flags.h:114
#define FLAG_FEIZHI_SAW_ROCKSLIDE
Feizhi has found the road blocked and run ahead to look for Hsu.
Definition flags.h:133
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.
Item numbers, named from the English release.
@ ITEM_POWER_BREAD
Definition item_ids.h:50
@ ITEM_WATER_OF_LIFE
Definition item_ids.h:49
s32 ArcTan2(s32 x, s32 y)
Returns the angle of the vector (x, y), in 1/65536 turns, measured from the y axis: 0 along +y,...
Definition math.c:36
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_FOREVER
Definition objcmd.h:14
#define SC_ARG(v)
Definition objcmd.h:44
#define SC_MOVE(x, y, z)
Move toward the target.
Definition objcmd.h:19
#define SC_WAIT(n)
Wait n frames.
Definition objcmd.h:16
#define SC_TOP
Script start.
Definition objcmd.h:13
#define SC_END
Return to the main script.
Definition objcmd.h:32
#define SC_CALL(fn)
Definition objcmd.h:50
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
Scene numbers, named after their places.
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_125
Definition songs.h:118
#define SE_169
Definition songs.h:164
#define SE_188
Definition songs.h:183
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_EventBegin(void)
void Engine_TaskWait()
void Engine_EventSetMessage()
void Engine_EventShowMessage()
#define NULL
Definition bilibin.h:6
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
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
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
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
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
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
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
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.