Alchemy
Loading...
Searching...
No Matches

gondowan_cave.c

Go to the documentation of this file.
1/// @file
2/// Gondowan Cave: the soldiers guarding the bridge to Gondowan, Iodem waiting
3/// there on the way to Babi Lighthouse, and the cave's moving puzzles.
4#include "game_state.h"
5#include "global_cells.h"
6#include "scene_ids.h"
7#include "unit/import.h"
10#include "unit/object/object.h"
12#include "unit/field/field.h"
13#include "battle.h"
14#include "debug.h"
15#include "field.h"
16#include "game.h"
17#include "graphics.h"
18#include "menu.h"
19#include "minigame.h"
20#include "sound.h"
21#include "system.h"
22#include "types.h"
23#include "field_event.h"
24#include "field_scene.h"
25#include "staged_actor.h"
26#include "field_effect.h"
27#include "text/msg_ids.h"
28#include "field_obj.h"
29#include "fixed_math.h"
30#include "flags.h"
31#include "songs.h"
32#include "event.h"
33
34// The first room's actors: the soldiers who guard the bridge, and Iodem.
35#define SOLDIER_1 8
36#define SOLDIER_2 9
37#define SOLDIER_3 10
38#define IODEM 11
39
40// The third room's actors: two objects the party moves, and the one that
41// stands in for the second once it has moved.
42#define FIRST_OBJECT 8
43#define SECOND_OBJECT 9
44#define SECOND_OBJECT_MOVED 10
45
46// The leap event also runs after the shared staged-actor movement.
47static void Event_MoveSecondObject(void);
48static void GondowanCave_RunSpinningLeap(s32 actorId);
49
50// Shared effect routines retain their position before the scene handlers.
52
53// Particle and movable-object routines precede this scene's entry points.
54#include "common/effect_spawn.h"
56#include "ability_ids.h"
57#include "item_ids.h"
58#include "objcmd.h"
59
60const struct SceneEntrance *Scene_GetEntrances(void) {
61 s16 scene = gGameState.scene;
62
63 if (scene == (s32)&SceneId_GondowanCave1) {
65 }
66 if (scene == (s32)&SceneId_GondowanCave2) {
68 }
69 if (scene == (s32)&SceneId_GondowanCave3) {
71 }
73}
74
75const struct SceneRegion *Scene_GetRegions(void) { return NULL; }
76
77/// All cave sections share the exit table.
78const u32 *Scene_GetExits(void) { return gGondowanCaveExits; }
79
80/// Iodem waits in the first room once he is on his way to Babi Lighthouse.
82 s16 scene = gGameState.scene;
83
84 if (scene == (s32)&SceneId_GondowanCave1) {
87 }
89 }
90 if (scene == (s32)&SceneId_GondowanCave2) {
92 }
93 if (scene == (s32)&SceneId_GondowanCave3) {
95 }
97}
98
99/// Each room's events, with Iodem's in the first room when he is there.
100const struct SceneEvent *Scene_GetEvents(void) {
101 s16 scene = gGameState.scene;
102
103 if (scene == (s32)&SceneId_GondowanCave1) {
106 }
108 }
109 if (scene == (s32)&SceneId_GondowanCave2) {
111 }
112 if (scene == (s32)&SceneId_GondowanCave3) {
114 }
116}
117
118/// Walking back (trigger 10) with Iodem in the party: he steps out and
119/// asks why Isaac is going back. Yes: he waits here for the party's return.
120/// No: he rejoins the party and Isaac steps away from the trigger.
122 struct FieldActor *leader;
123
126 EV_BEGIN();
127 // Bring Iodem out of the party before opening his question.
130 if (leader != 0) {
131 Actor_SetPosition(IODEM, leader->x.fixed, leader->z.fixed);
132 }
136 WAIT(10);
138 MESSAGE_SET(MsgKaragolWhyGoingBackIsaacDo);
140 if (Engine_EventChooseYesNo(0, 0) == 0) {
141 // "I see... In that case, I shall wait here for you to return." The
142 // saved place becomes Tolbi's.
144 OBJ_WALK(IODEM, 152, 232);
150 } else {
151 // "Then we should continue on our way to the lighthouse." He rejoins
152 // the party, and Isaac steps away from the trigger.
153 gEventWork->message += 1;
157 if (leader != 0) {
158 Actor_SetDestination(IODEM, leader->x.part.pixel, leader->z.part.pixel);
159 }
161 OBJ_POS_SET(IODEM, 0, 0);
162 WAIT(30);
167 }
168 EV_END();
169 }
170}
171
172/// Talking to Iodem where he waits, or walking up to him (trigger 11): he joins
173/// the party again. "I've been waiting for you, Isaac! We should go to Babi
174/// Lighthouse soon."
175static void Event_IodemRejoins(void) {
176 EV_BEGIN();
180 WAIT(10);
182 MESSAGE_SET(MsgKaragolIveBeenWaitingForIsaac);
183 MESSAGE_PUT(IODEM, 0);
185 {
187
188 if (leader != 0)
189 Engine_ActorSetDestination(IODEM, leader->x.part.pixel,
190 leader->z.part.pixel);
191 }
194 WAIT(20);
196 EV_END();
197}
198
199/// Talking to the first soldier, who asks whether the party will cross into
200/// Gondowan. "Do you wish to cross into Gondowan?" Yes: "I won't stop you, but
201/// I wouldn't go unless I had business there." No: "That's a good idea. They
202/// wouldn't let you into Babi Lighthouse, anyway."
204 s32 firstMessage;
205
206 firstMessage = MsgKaragolDoYouWishCrossInto;
207 MESSAGE_SET(firstMessage);
209 if (Engine_EventChooseYesNo(0, 0) == 0) {
212 // The shorter answer, without the advice to watch Colosso.
213 MESSAGE_SET(firstMessage + 8);
214 }
215 }
217 } else {
220 }
221}
222
223/// Mind Read on the second soldier: once flag 0x950 is set and until Iodem
224/// waits here, he grumbles that guard duty made him miss all of Colosso;
225/// before, that the warriors fight while he guards the bridge.
226static void Event_ReadSoldierMind(void) {
229 MESSAGE_SET(MsgKaragolWeMissedColossoBecauseWe);
230 else
231 MESSAGE_SET(MsgKaragolWarriorsHaveBeenFightingWhile);
233}
234
235/// Leaving the third room by its first exit (trigger 1). With temporary flag
236/// 0x204 set, the puzzle's saved flags return to one arrangement first.
237static void Event_LeaveThroughEntrance(void) {
238 struct EventWork *event;
239
240 event = gEventWork;
241 EV_BEGIN();
242 if (FLAG_CHECK(FLAG_SCENE_TEMP_04) != 0) {
243 GameFlag_Clear(0x9a3);
245 GameFlag_Clear(0x9a4);
246 GameFlag_Clear(0x9a6);
248 FLAG_SET(0x9a4);
249 }
253 EV_END();
254}
255
256/// Walking into the second object from the east or the west (triggers 10
257/// and 11): look at what is ahead, which starts the push.
259
260/// Move on the first object: from column 30 or less it spins and leaps across,
261/// freeing the cell where it stood.
262static void Event_MoveFirstObject(void) {
264 EV_BEGIN();
265 {
266 struct FieldActor *actor = Object_GetById(FIRST_OBJECT);
267
268 if ((actor->x.fixed >> 20) <= 30) {
270 Map_CopyCellAttributes(29, 19, 1, 1, 27, 19);
272 }
273 }
274 EV_END();
275}
276
277/// Pushing the second object (trigger 50): it moves a step, then may have
278/// reached its place.
279static void Event_PushSecondObject(void) {
280 StagedActor_AdvancePair();
282}
283
284/// Hides the second object and shows the one that stands in for it in its
285/// place.
286static inline void GondowanCave_PlaceMovedSecondObject(s32 animation) {
289 OBJ_MODE(SECOND_OBJECT_MOVED, animation);
290}
291
292/// Move on the second object, and after each push: past column 42 it drops
293/// into its place for good.
294static void Event_MoveSecondObject(void) {
295 EV_BEGIN();
296 if ((Object_GetById(SECOND_OBJECT)->x.fixed >> 20) > 42) {
297 s32 destinationCellX = 107;
298 s32 destinationCellZ = 17;
299
300 Map_CopyCellAttributes(108, 17, 1, 1, destinationCellX, destinationCellZ);
301 WAIT(8);
303 SE(SE_CAST);
305 }
306 EV_END();
307}
308
310
311/// Rotates the sprite during the airborne part of the leap.
312static void GondowanCave_RotateLeapingObject(union FieldObject *fieldObject) {
313 fieldObject->actor.sprite->rotation -= 0x400;
314}
315
316/// Waits at most forty frames for the actor to descend to the height limit.
317static void GondowanCave_WaitForDescent(struct FieldActor *actor,
318 s32 heightLimit) {
319 s32 framesRemaining = 40;
320
321 while (framesRemaining != 0) {
323 framesRemaining--;
324 if (actor->y.fixed <= heightLimit) {
325 break;
326 }
327 }
328}
329
330/// The object spins in place, leaps and lands with a shake and a ring of dust,
331/// then comes to rest a little further on.
332static void GondowanCave_RunSpinningLeap(s32 actorId) {
333 struct FieldActor *actor;
334 u32 stepIndex;
335 struct Vector3 particleVelocity;
336 s32 angle;
337
338 actor = Object_GetById(actorId);
339 // Wind up the spin while horizontal motion is disabled.
340 actor->motionFlags = 0;
341 for (stepIndex = 0; stepIndex < 9; stepIndex++) {
343 actor->sprite->rotation -= 0x100;
344 actor->x.fixed -= Engine_MathCos(actor->sprite->rotation) / 2;
345 actor->targetX = ACTOR_NO_TARGET;
346 }
348 // Continue spinning through the first jump.
350 OBJ_SPEED(actorId, PIXELS(2), PIXELS(1));
351 Actor_SetDestination(actorId, 472, 288);
352 actor->gravity = 4 * PIXELS(1) / 5;
354 actor->terrainId = 0;
358 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
359 // Emit a complete particle fan, including its closing direction.
360 for (stepIndex = 0; stepIndex < 17; stepIndex++) {
361 angle = stepIndex << 12;
362 particleVelocity.x = Engine_MathCos(angle);
363 particleVelocity.y = 0;
364 particleVelocity.z = Engine_MathSin(angle);
365 particleVelocity.x -= particleVelocity.x / 4;
366 particleVelocity.z -= particleVelocity.z / 2;
367 Effect_Spawn(actor->x.fixed, actor->y.fixed, actor->z.fixed,
368 particleVelocity.x, particleVelocity.y, particleVelocity.z, 0,
369 0);
370 }
371 Actor_SetDestination(actorId, 440, 308);
372 // Finish the second movement before restoring the resting animation.
375 actor->update = 0;
376 actor->sprite->rotation = 0x1000;
378 OBJ_MODE(actorId, 3);
380 WAIT(10);
381 OBJ_MODE(actorId, 2);
382}
383
385
386/// Lift on the third room's actor 11 also takes away actor 12 beside it.
387static void Event_LiftObject(void) { Engine_ActorSetPosition(12, 0, 0); }
388
389/// The first room keeps Iodem out of sight while he travels with the party;
390/// the third puts the moved objects where the party left them.
392 struct FieldActor *actor;
393
397 OBJ_POS_SET(IODEM, 0, 0);
398 }
399 }
401 if (gGameState.entrance == 1) {
402 Map_CopyCellAttributes(108, 17, 1, 1, 107, 17);
403 }
405 OBJ_POS_SET(FIRST_OBJECT, 440, 308);
407 Map_CopyCellAttributes(29, 19, 1, 1, 27, 19);
408 }
411 }
412 actor = Actor_Get(12);
414 }
415 return 0;
416}
417
419 SC_WAIT(1), SC_LOOP(22, SC_TOP), SC_WAIT(1),
420 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
421};
422
424 SC_WAIT(1), SC_LOOP(44, SC_TOP), SC_WAIT(1),
425 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
426};
427
429 SC_WAIT(1), SC_LOOP(126, SC_TOP), SC_WAIT(1),
430 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
431};
432
433/// Packs signed pixel steps with X in the upper halfword and Z in the lower.
434/// Shift the unsigned representation so westward steps remain defined C.
435#define DIRECTION_STEP(dx, dz) (((u32)(dx) << 16) | ((dz) & 0xffff))
436
438 DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0),
439 DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16),
440 DIRECTION_STEP(0, 16), DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0),
441 DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0), DIRECTION_STEP(0, -16),
442 DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16),
443 DIRECTION_STEP(16, 0),
444};
445
446// clang-format off
448 207, 205, 228, 229, 298, 297,
449};
450
452 -32, -8, 32, 8,
453 -8, -32, 8, 32,
454 -32, -16, 32, 0,
455 -8, -32, 8, 32,
456 -32, -8, 32, 8,
457 -8, -32, 8, 32,
458};
459
460const s32 *gEffectScripts[] = {
464};
465
467 { 0, CONDITION_ALWAYS, 120, 0, 152, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
468 { SCENE_TABLE_END },
469};
470
472 { 1, CONDITION_ALWAYS, 152, 0, 120, FACING_SOUTH, 0, 32, 32, 272, 480, 0 },
473 { 2, CONDITION_ALWAYS, 152, 0, 440, FACING_NORTH, 0, 32, 32, 272, 480, 0 },
474 { SCENE_TABLE_END },
475};
476
478 { 1, CONDITION_ALWAYS, 728, 0, 312, FACING_NORTH, 0, 96, 48, 768, 432, 0 },
479 { 2, CONDITION_ALWAYS, 168, 0, 408, FACING_NORTH, 0, 96, 48, 768, 432, 0 },
480 { 3, CONDITION_ALWAYS, 168, 0, 520, FACING_SOUTH, 0, 112, 464, 576, 704, 0 },
481 { 4, CONDITION_ALWAYS, 504, 0, 664, FACING_NORTH, 0, 112, 464, 576, 704, 0 },
482 { SCENE_TABLE_END },
483};
484
486 { 1, CONDITION_ALWAYS, 792, 0, 456, FACING_NORTH, 0, 240, 48, 864, 464, 0 },
487 { 2, CONDITION_ALWAYS, 360, 0, 152, FACING_SOUTH, 0, 240, 48, 864, 464, 0 },
488 { 3, CONDITION_ALWAYS, 344, 0, 440, FACING_NORTH, 0, 240, 48, 864, 464, 0 },
489 { 4, CONDITION_ALWAYS, 344, 0, 584, FACING_SOUTH, 0, 48, 432, 408, 896, 0 },
490 { 5, CONDITION_ALWAYS, 136, 0, 504, FACING_SOUTH, 0, 48, 432, 408, 896, 0 },
491 { 6, CONDITION_ALWAYS, 216, 0, 888, FACING_NORTH, 0, 48, 432, 408, 896, 0 },
492 { SCENE_TABLE_END },
493};
494
496 SCENE_EXITS(152),
497 SCENE_EXIT(1, 2, 25),
498 SCENE_EXIT(2, 2, 54),
499 SCENE_EXIT(0, 157, 0),
500 SCENE_EXIT(1, 158, 2),
501 SCENE_EXIT(2, 157, 3),
502 SCENE_EXIT(3, 157, 2),
503 SCENE_EXIT(4, 158, 5),
504 SCENE_EXIT(0, 158, 0),
505 SCENE_EXIT(1, 2, 26),
506 SCENE_EXIT(2, 157, 1),
507 SCENE_EXIT(3, 158, 4),
508 SCENE_EXIT(4, 158, 3),
509 SCENE_EXIT(5, 157, 4),
510 SCENE_EXIT(6, 2, 41),
512};
513
515 { SCENE_TABLE_END },
516};
517
525 { SCENE_TABLE_END },
526};
527
535 // Iodem
538 { SCENE_TABLE_END },
539};
540
543 PIXELS(504), 0, PIXELS(624), FACING_SOUTH, TALK_FACE_PARTY, 0 },
545 PIXELS(440), 0, PIXELS(104), FACING_SOUTH, TALK_KEEP_FACING, 0 },
547 PIXELS(392), 0, PIXELS(216), FACING_SOUTH, TALK_KEEP_FACING, 0 },
548 { SCENE_TABLE_END },
549};
550
553 PIXELS(496), 0, PIXELS(304), FACING_SOUTH, TALK_KEEP_FACING, 0 },
555 PIXELS(664), 0, PIXELS(280), FACING_SOUTH, TALK_KEEP_FACING, 0 },
557 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
559 PIXELS(344), 0, PIXELS(636), FACING_SOUTH, TALK_FACE_PARTY, 0 },
562 { SCENE_TABLE_END },
563};
564
567};
568
570 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
571 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
573 { EVENT_TALK, SOLDIER_2, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveUsWereTheSoldiersWhoGuard) },
574 { EVENT_TALK, SOLDIER_3, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveEvenIfYouHeadEastYou) },
575 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), SOLDIER_1, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveThoseWhoGoToGondowanRarely) },
577 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), SOLDIER_3, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveYoudThinkYouCouldGetThrough) },
578 { SEARCH(SEARCH_CHEST), 100, 0xfa0, FIND_ITEM(ITEM_APPLE) },
581};
582
584 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
585 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
588 { EVENT_TALK, SOLDIER_1, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveWhyWouldIodemChooseToWait) },
589 { EVENT_TALK, SOLDIER_2, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveWeHaventSeenAnybodyUnusualCrossing) },
590 { EVENT_TALK, SOLDIER_3, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveEvenIfYouGoEastFrom) },
592 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), SOLDIER_1, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveIodemIsGoingToBabiLighthouse) },
593 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), SOLDIER_2, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveItsALotOfStressBut) },
594 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), SOLDIER_3, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveEveryoneComesDownThisWayWhen) },
595 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), IODEM, CONDITION_ALWAYS, MSGNO(MsgGondowanCaveWeHaveToHeadForThe) },
596 { SEARCH(SEARCH_CHEST), 100, 0xfa0, FIND_ITEM(ITEM_APPLE) },
599};
600
602 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
603 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
604 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
605 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
607 { SEARCH(SEARCH_CHEST), 100, 0xfa0, FIND_ITEM(ITEM_APPLE) },
610};
611
612/// Temporary flag 0x205 ends Move on the second object.
615 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
616 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
617 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
618 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
619 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
626 { SEARCH(SEARCH_CHEST), 100, 0xfa0, FIND_ITEM(ITEM_APPLE) },
629};
630// clang-format on
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_LIFT
Definition ability_ids.h:18
@ ABILITY_MOVE
Definition ability_ids.h:15
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
const struct ScenePlacement * Scene_GetPlacements(void)
const struct SceneEntrance * Scene_GetEntrances(void)
const struct SceneEvent * Scene_GetEvents(void)
const u32 * Scene_GetExits(void)
Both scenes share one exit table.
const struct SceneRegion * Scene_GetRegions(void)
s32 Scene_Initialize(void)
Sets up whichever scene is being entered and runs its arrival events.
s32 gStagedActor_DirectionSteps[]
Pixel step by direction: X in the upper halfword, Z in the lower.
s32 gStagedActor_FootprintBounds[]
#define DIRECTION_STEP(dx, dz)
Pixel step by direction: X in the upper halfword, Z in the lower.
u32 gStagedActor_FootprintKinds[]
s32 gEffectScript0[]
const s32 * gEffectScripts[]
s32 gEffectScript1[]
s32 gEffectScript2[]
static void Event_CheckAhead(void)
Checks the blocked direction before allowing another movement step.
Definition bilibin.c:331
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
The engine calls the debug menus import, and their palette swatch tiles.
Scene commands: the all-caps macros the scene scripts are written in.
#define EV_BEGIN()
Definition event.h:30
#define OBJ_DIR(no, d, t)
Definition event.h:16
#define OBJ_POS_SET(no, x, z)
Definition event.h:13
#define EV_END()
Definition event.h:31
#define MESSAGE_OPEN(no, f)
Definition event.h:11
#define WAIT(n)
Definition event.h:7
#define OBJ_MODE(no, m)
Definition event.h:18
#define OBJ_WALK(no, x, z)
Definition event.h:14
#define MESSAGE_PUT(no, f)
Definition event.h:10
#define MESSAGE_SET(m)
Definition event.h:9
#define SE(n)
Definition event.h:28
#define FLAG_SET(f)
Definition event.h:26
#define FLAG_CHECK(f)
Definition event.h:25
#define OBJ_FACE(no, to, t)
Definition event.h:17
#define OBJ_SPEED(no, s, a)
Definition event.h:15
void Map_WaitForShakeToSettle(void)
Waits until both shake amplitudes are below 1/256 pixel, with a 300-frame limit for a shake whose dec...
Definition view.c: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
static s32 Event_OpenMessage(s32 speaker, s32 flags)
s32 Engine_LeaderCheckAhead(void)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
s32 Engine_EventChooseYesNo(s32 actor, s32 flags)
s32 Engine_MathSin(s32 angle)
void Engine_ActorSetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_EventCloseScreen(void)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
#define GameFlag_Clear
void Engine_EventWaitForScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
static void Event_ShowMessage(s32 speaker, s32 flags)
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)
s32 Engine_MathCos(s32 angle)
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)
static struct FieldActor * Actor_Get(s32 actor)
Field objects and actors, and the scene transition styles.
@ ACTOR_FOLLOWS_TERRAIN
moves with the ground height under it
Definition field_obj.h:160
@ ACTOR_FALLS
falls by its gravity and bounces
Definition field_obj.h:161
#define ACTOR_NO_TARGET
A target coordinate that is not set: the object has no target.
Definition field_obj.h:145
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
@ TALK_FACE_PARTY_AND_BACK
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
#define EVENT_TOUCH_WALKING
@ ACTOR_WANDER
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_CHEST
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_COLOSSO_OVER
the Colosso finals have been fought
Definition flags.h:191
#define FLAG_GONDOWAN_CAVE_SECOND_OBJECT_MOVED
Definition flags.h:129
#define FLAG_BABI_SPOKE_AFTER_COLOSSO
Babi and Iodem have spoken with the party after Colosso.
Definition flags.h:209
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_IODEM_AT_BABI_LIGHTHOUSE
Set with it: Iodem has come to Babi Lighthouse, and from then on he no longer leaves the party in Suh...
Definition flags.h:185
#define FLAG_IODEM_FOLLOWING_PARTY
Definition flags.h:127
#define FLAG_SCENE_TEMP_04
Definition flags.h:717
#define FLAG_GONDOWAN_CAVE_FIRST_LEAP_COMPLETE
Definition flags.h:128
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.
#define SOLDIER_3
struct ScenePlacement gGondowanCavePlacements3[]
static void Event_LiftObject(void)
Lift on the third room's actor 11 also takes away actor 12 beside it.
struct ScenePlacement gGondowanCavePlacements1WithIodem[]
static void Event_LeaveThroughEntrance(void)
Leaving the third room by its first exit (trigger 1).
#define SOLDIER_2
static UNUSED void GondowanCave_UnusedSceneCallback(void)
#define SECOND_OBJECT
static void GondowanCave_RunSpinningLeap(s32 actorId)
The object spins in place, leaps and lands with a shake and a ring of dust, then comes to rest a litt...
static void Event_PushSecondObject(void)
Pushing the second object (trigger 50): it moves a step, then may have reached its place.
struct ScenePlacement gGondowanCavePlacementsOther[]
struct SceneEntrance gGondowanCaveEntrances1[]
#define FIRST_OBJECT
struct SceneEvent gGondowanCaveEvents2[]
#define IODEM
struct SceneEvent gGondowanCaveEvents1[]
#define SECOND_OBJECT_MOVED
u32 gGondowanCaveExits[]
static void Event_IodemAsksWhyTurningBack(void)
Walking back (trigger 10) with Iodem in the party: he steps out and asks why Isaac is going back.
static void Event_IodemRejoins(void)
Talking to Iodem where he waits, or walking up to him (trigger 11): he joins the party again.
struct SceneEvent gGondowanCaveEventsOther[]
struct SceneEntrance gGondowanCaveEntrances2[]
#define SOLDIER_1
struct SceneEntrance gGondowanCaveEntrancesOther[]
struct SceneEvent gGondowanCaveEvents3[]
Temporary flag 0x205 ends Move on the second object.
static void Event_ReadSoldierMind(void)
Mind Read on the second soldier: once flag 0x950 is set and until Iodem waits here,...
struct SceneEntrance gGondowanCaveEntrances3[]
static void GondowanCave_WaitForDescent(struct FieldActor *actor, s32 heightLimit)
Waits at most forty frames for the actor to descend to the height limit.
static void Event_MoveSecondObject(void)
Move on the second object, and after each push: past column 42 it drops into its place for good.
struct ScenePlacement gGondowanCavePlacements2[]
static void Event_SoldierAsksAboutCrossing(void)
Talking to the first soldier, who asks whether the party will cross into Gondowan.
struct SceneEvent gGondowanCaveEvents1WithIodem[]
static void GondowanCave_PlaceMovedSecondObject(s32 animation)
Hides the second object and shows the one that stands in for it in its place.
struct ScenePlacement gGondowanCavePlacements1[]
static UNUSED void GondowanCave_UnusedActorCallback(void)
static void GondowanCave_RotateLeapingObject(union FieldObject *fieldObject)
Rotates the sprite during the airborne part of the leap.
static void Event_MoveFirstObject(void)
Move on the first object: from column 30 or less it spins and leaps across, freeing the cell where it...
The screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
Item numbers, named from the English release.
@ ITEM_APPLE
Definition item_ids.h:52
@ ITEM_LUCKY_MEDAL
Definition item_ids.h:70
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_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_FREE
Release.
Definition objcmd.h:43
#define SC_WAIT(n)
Wait n frames.
Definition objcmd.h:16
#define SC_TOP
Script start.
Definition objcmd.h:13
Scene numbers, named after their places.
char SceneId_GondowanCave2
char SceneId_GondowanCave1
char SceneId_GondowanCave3
char SceneId_TolbiInteriors
Song and sound effect ids, indices into gSound_SongTable.
#define SE_136
Definition songs.h:129
#define SE_CAST
Definition songs.h:149
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_AudioPlayCue()
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
The pushable actors' movement probes and footprint bounds.
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
Definition event_work.h:20
s16 touchedTrigger
the step event a touch or exit event answers
Definition event_work.h:26
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
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
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
s32 gravity
Taken off the vertical velocity each frame while it is above the ground, in 16.16 fixed-point pixels ...
Definition field_obj.h:68
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
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
s16 entrance
Definition game_state.h:37
s16 savedScene
where a defeat returns to without a defeat point
Definition game_state.h:38
s16 savedEntrance
where a defeat returns to without a defeat point
Definition game_state.h:39
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...
Three coordinates, x, y and z: a position, a velocity or a direction.
Definition vector3.h:11
s32 z
Definition vector3.h:24
s32 x
Definition vector3.h:22
s32 y
Definition vector3.h:23
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
#define UNUSED
Definition types.h:22
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldActor actor