Alchemy
Loading...
Searching...
No Matches

goma_cave_pillar.c

Go to the documentation of this file.
1/// @file
2/// Goma Cave: the room with two pillars, a stump and the Djinni Forge.
3#include "script.h"
4#include "version.h"
5#include "global_cells.h"
6#include "unit/import.h"
10#include "unit/field/field.h"
11#include "battle.h"
12#include "debug.h"
13#include "field.h"
14#include "game.h"
15#include "graphics.h"
16#include "menu.h"
17#include "minigame.h"
18#include "sound.h"
19#include "system.h"
20#include "mapcopy.h"
21#include "types.h"
22#include "animspr.h"
23#include "field_event.h"
24#include "field_scene.h"
25#include "djinn_ids.h"
26#include "staged_actor.h"
27#include "b5_context.h"
28#include "edition.h"
29#include "tbs_edition.h"
30#include "field_obj.h"
31#include "game_state.h"
32#include "field_service.h"
33#include "text/msg_ids.h"
35#include "ability_ids.h"
36#include "item_ids.h"
37#include "objcmd.h"
38#include "fixed_math.h"
39
40#include "flags.h"
41#include "songs.h"
42#include "event.h"
43
44// Place flags: Scene_ResetFlagsOnEnter clears 0x300 to 0x3ff when the party
45// enters another place group, and other places use the numbers for their own.
46#define FLAG_GOMA_CAVE_STUMP_FELL 0x300 ///< pushed over into the room below
47#define FLAG_GOMA_CAVE_EAST_PILLAR_IN_PLACE 0x301 ///< sunk into its place
48#define FLAG_GOMA_CAVE_WEST_PILLAR_MOVED 0x302 ///< one step east of its start
49
51
52// The room's actors, in placement order.
53#define WEST_PILLAR 8
54#define STUMP 9
55#define EAST_PILLAR 10
56#define FORGE 12
57#define WITNESS 13 ///< the man who fought Forge and lost it
58
59// Shared movement routines stay in their linked order.
61
62/// Talking to Forge: the man beside it jumps in surprise, and the battle with
63/// the Djinni begins.
64static void Event_FightForge(void) {
68}
69
70/// Advances the fragment's selected coordinate plane and keeps its targets in
71/// step.
72static void GomaCavePillar_UpdateFragment(union FieldObject *fieldObject) {
73 struct FieldActor *fragment = (struct FieldActor *)fieldObject;
74 // The actor's speed and acceleration slots carry the two selected axis steps.
75 s16 plane = (s16)fragment->work;
76
77 switch (plane) {
78 case PLANE_XY:
79 fragment->x.fixed += fragment->speed;
80 fragment->targetX = fragment->x.fixed;
81 fragment->y.fixed += fragment->acceleration;
82 fragment->targetY = fragment->y.fixed;
83 break;
84 case PLANE_XZ:
85 fragment->x.fixed += fragment->speed;
86 fragment->targetX = fragment->x.fixed;
87 fragment->z.fixed += fragment->acceleration;
88 fragment->targetZ = fragment->z.fixed;
89 break;
90 case PLANE_YZ:
91 fragment->y.fixed += fragment->speed;
92 fragment->targetY = fragment->y.fixed;
93 fragment->z.fixed += fragment->acceleration;
94 fragment->targetZ = fragment->z.fixed;
95 break;
96 }
97}
98
99/// Applies child value 15 at the end of a fragment's lifetime.
100static s32
102 struct FieldActor *actor = (struct FieldActor *)interpreter;
103 ObjectGroup_SetChildValue(actor, 15);
104 return 0;
105}
106
107/// Creates a fragment with two axis rates, a script and packed plane/priority.
108static void GomaCavePillar_SpawnFragment(s32 x, s32 y, s32 z, s32 firstRate,
109 s32 secondRate,
110 s32 scriptAndChildValue,
111 s32 planeAndPriority) {
113 struct FieldActor *leader;
114 struct FieldActor *fragment;
115 struct AnimationObject *sprite;
116 u32 priority;
117
120 fragment = Engine_ObjectCreate(222, x, y, z);
121 if (fragment == 0)
122 return;
123 sprite = fragment->sprite;
124 Object_SetMode(fragment, (scriptAndChildValue + 1) & 15);
125 Engine_ObjectSetScript(fragment, table.scripts[scriptAndChildValue & 15]);
126 ObjectGroup_SetChildValue(fragment, ((u32)scriptAndChildValue >> 16) & 15);
127 fragment->motionFlags = 0;
128 sprite->flags = 0;
130 fragment->speed = firstRate;
131 fragment->acceleration = secondRate;
132 fragment->work = (u16)planeAndPriority;
133 priority = (u32)planeAndPriority >> 16;
134 switch (priority) {
135 case 0:
136 sprite->image.priority = leader->sprite->image.priority;
137 break;
138 case 1:
139 case 2:
140 case 3:
142 sprite->image.priority = priority;
143 break;
144 }
145}
146
149}
150
151const struct SceneRegion *Scene_GetRegions(void) { return NULL; }
152
154
157}
158
159/// Copies the map cells for the west pillar on either side of its track.
160static inline void GomaCavePillar_CopyWestPillarCells(s32 sourceColumn) {
161 Map_CopyCellAttributes(sourceColumn, 40, 6, 3, 18, 6);
162}
163
164/// Move on the west pillar: it slides between its two places, and the map
165/// cells follow it.
166static void Event_MoveWestPillar(void) {
167 struct FieldActor *actor;
168 s32 x;
169
171 x = actor->x.fixed;
172 if (x < 0)
173 x += 0xfffff;
174 x >>= 20;
175 EV_BEGIN();
176 if (x == 20) {
179 } else {
182 }
183 EV_END();
184}
185
186/// While the stump teeters, dust falls from it: one fragment every eighth
187/// frame, two on every sixteenth.
189 s32 framePhase;
190 s32 fixedX;
191 s32 fixedZ;
192 struct FieldActor *heightSource;
193 struct FieldActor *firstXSource, *firstZSource;
194 s32 firstRandomX, firstRandomSpeed, firstStyle, firstSpeedBand,
195 firstSpeedTimes13, firstFallingSpeed;
196 struct FieldActor *secondXSource, *secondZSource;
197 s32 secondRandomX, secondRandomSpeed, secondStyle, secondSpeedBand,
198 secondSpeedTimes13, secondFallingSpeed;
199
200 framePhase = gFrameCount & 7;
201 if (framePhase == 0) {
202 firstXSource = Object_GetById(STUMP);
203 firstRandomX = Engine_RandomNext();
204 fixedX = firstXSource->x.fixed;
205 fixedX +=
206 ((((u32)(((firstRandomX << 1) + firstRandomX) << 2)) >> 16) << 16);
207 heightSource = Object_GetById(STUMP);
208 firstZSource = Object_GetById(STUMP);
209 fixedZ = firstZSource->z.fixed;
210 fixedZ += PIXELS(6);
211 firstRandomSpeed = Engine_RandomNext();
212 firstSpeedBand = ((u32)((firstRandomSpeed << 2) + firstRandomSpeed) >> 16);
213 // These shifts produce speedBand * 6553: a tenth-pixel falling step.
214 firstSpeedTimes13 =
215 (((firstSpeedBand << 1) + firstSpeedBand) << 2) + firstSpeedBand;
216 firstFallingSpeed = firstSpeedTimes13 << 6;
217 firstFallingSpeed -= firstSpeedTimes13;
218 firstFallingSpeed <<= 3;
219 firstFallingSpeed += firstSpeedBand;
220 firstStyle = (u32)(Engine_RandomNext() << 1) >> 16;
221 firstFallingSpeed = -firstFallingSpeed;
222 GomaCavePillar_SpawnFragment(fixedX, heightSource->y.fixed, fixedZ, 0,
223 firstFallingSpeed, firstStyle, framePhase);
224 framePhase = gFrameCount & 15;
225 if (framePhase == 0) {
226 secondXSource = Object_GetById(STUMP);
227 secondRandomX = Engine_RandomNext();
228 fixedX = secondXSource->x.fixed;
229 fixedX +=
230 ((((u32)(((secondRandomX << 1) + secondRandomX) << 2)) >> 16) << 16);
231 heightSource = Object_GetById(STUMP);
232 secondZSource = Object_GetById(STUMP);
233 fixedZ = secondZSource->z.fixed;
234 fixedZ += PIXELS(6);
235 secondRandomSpeed = Engine_RandomNext();
236 secondSpeedBand =
237 ((u32)((secondRandomSpeed << 2) + secondRandomSpeed) >> 16);
238 // Keep the same five falling speeds for the second fragment.
239 secondSpeedTimes13 =
240 (((secondSpeedBand << 1) + secondSpeedBand) << 2) + secondSpeedBand;
241 secondFallingSpeed = secondSpeedTimes13 << 6;
242 secondFallingSpeed -= secondSpeedTimes13;
243 secondFallingSpeed <<= 3;
244 secondFallingSpeed += secondSpeedBand;
245 secondStyle = (u32)(Engine_RandomNext() << 1) >> 16;
246 secondFallingSpeed = -secondFallingSpeed;
247 GomaCavePillar_SpawnFragment(fixedX, heightSource->y.fixed, fixedZ, 0,
248 secondFallingSpeed, secondStyle, framePhase);
249 }
250 }
251}
252
254
255/// Move on the stump: once it is pushed to the edge (column 25), it teeters
256/// shedding dust, tips over and falls into the room below with a crash that
257/// shakes the screen.
258static void Event_PushStumpOver(void) {
259 s32 column;
260 s32 zero;
261 void (*fragmentCallback)(void);
262 s32 fixedX;
263 s32 fixedZ;
264 struct FieldActor *heightSource;
265 struct FieldActor *stump;
266 struct FieldActor *spriteActor;
267 struct FieldActor *blendActor;
268 struct FieldActor *bounceActor, *gravityActor;
269 struct FieldActor *movedActor;
270 struct FieldActor *zSource, *xSource;
271 s32 randomX, randomSpeed, style, speedBand, speedTimes13, fallingSpeed;
272 struct FieldActor *overlayActor;
273
274 stump = Object_GetById(STUMP);
275 column = stump->x.fixed / PIXELS(16);
276 EV_BEGIN();
277 if (column == 25) {
278 overlayActor = Object_GetById(11);
279 zero = 0;
280 overlayActor->terrainId = 1;
281 spriteActor = Object_GetById(11);
282 Engine_ActorSetSpriteFlags(spriteActor, 0);
284 blendActor = Object_GetById(11);
285 Engine_ObjectSetBlendMode(blendActor, 1);
286 Engine_ActorSetPosition(11, PIXELS(414), PIXELS(240));
287 WAIT(10);
288 // Dust falls while the stump rocks on the edge.
289 fragmentCallback = GomaCavePillar_SpawnStumpDust;
290 FieldScheduler_AddCallback(fragmentCallback, 3200);
294 WAIT(10);
297 bounceActor = Object_GetById(STUMP);
298 bounceActor->bounce = zero;
299 gravityActor = Object_GetById(STUMP);
300 gravityActor->gravity = PIXELS(3) / 5;
301 WAIT(3);
302 // It tips over the edge.
303 Engine_ActorSetSpeed(STUMP, 5 * PIXELS(1) / 2, PIXELS(1) / 4);
306 movedActor = Object_GetById(STUMP);
307 Engine_ActorSetSpriteFlags(movedActor, 0);
308 Engine_TaskRemoveCallback(fragmentCallback);
309 WAIT(12);
311 xSource = Object_GetById(STUMP);
312 randomX = Engine_RandomNext();
313 fixedX = xSource->x.fixed;
314 fixedX += ((((u32)(((randomX << 1) + randomX) << 2)) >> 16) << 16);
315 heightSource = Object_GetById(STUMP);
316 zSource = Object_GetById(STUMP);
317 fixedZ = zSource->z.fixed;
318 fixedZ += PIXELS(6);
319 randomSpeed = Engine_RandomNext();
320 speedBand = ((u32)((randomSpeed << 2) + randomSpeed) >> 16);
321 // A last piece of dust, with the same tenth-pixel speed bands.
322 speedTimes13 = (((speedBand << 1) + speedBand) << 2) + speedBand;
323 fallingSpeed = speedTimes13 << 6;
324 fallingSpeed -= speedTimes13;
325 fallingSpeed <<= 3;
326 fallingSpeed += speedBand;
327 style = (u32)(Engine_RandomNext() << 1) >> 16;
328 fallingSpeed = -fallingSpeed;
329 GomaCavePillar_SpawnFragment(fixedX, heightSource->y.fixed, fixedZ, zero,
330 fallingSpeed, style, zero);
331 WAIT(20);
332 // It lands below; the shake dies down before the map cells change.
335 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
338 Engine_ActorSetPosition(11, 0, 0);
340 Map_CopyCellAttributes(21, 45, 4, 2, 21, 11);
341 }
342 EV_END();
343}
344
345/// Once the east pillar reaches its place (cell 38, 14), it sinks two pixels
346/// into the floor and six fragments fly out around it.
348 s32 x;
349 s32 z;
350
353 if (x == 38 && z == 14) {
360 PIXELS(1) / 2, 0, 0, PLANE_XZ);
364 PIXELS(2) / 5, PIXELS(2) / 5, 0, PLANE_XZ);
368 -PIXELS(2) / 5, PIXELS(2) / 5, 0, PLANE_XZ);
372 -PIXELS(1) / 2, 0, 0, PLANE_XZ);
376 PIXELS(2) / 5, -PIXELS(2) / 5, 0, PLANE_XZ);
380 -PIXELS(2) / 5, -PIXELS(2) / 5, 0, PLANE_XZ);
382 }
383}
384
385/// Move on the east pillar.
386static void Event_MoveEastPillar(void) {
387 EV_BEGIN();
389 EV_END();
390}
391
392/// Walking into the east pillar pushes it a step.
393static void Event_PushEastPillar(void) {
394 EV_BEGIN();
395 StagedActor_AdvancePair();
397 EV_END();
398}
399
400/// Walking west at the gap: the leader jumps across it. Later patches use the
401/// shared forward jump.
402static void Event_JumpGapWest(void) {
403#if TBS_PATCH_1
405#else
406 struct FieldActor *leader;
407 struct FieldPosition target;
408 struct FieldPosition *destination;
409 u8 *motionFlags;
410 u8 savedMotionFlags;
411
412 leader = Object_GetById(0);
413 motionFlags = &leader->motionFlags;
414 savedMotionFlags = *motionFlags;
415 target.x = Object_GetById(0)->x.fixed - PIXELS(32);
416 destination = &target;
417 destination->y = Object_GetById(0)->y.fixed;
418 destination->z = Object_GetById(0)->z.fixed;
419 if (FieldObject_CheckMovementCollision(leader, destination) == 0) {
420 EV_BEGIN();
421 Object_SetMode(leader, 6);
424 Object_SetMode(leader, 7);
425 leader->speed = PIXELS(3);
426 leader->acceleration = PIXELS(2);
427 leader->velocityY = PIXELS(4);
428 *motionFlags &= 0x7e;
430 Engine_ActorMoveToAndWait(0, *(s16 *)((u8 *)destination + 2),
431 *(s16 *)((u8 *)destination + 10));
432 Object_SetMode(leader, 6);
434 *motionFlags = savedMotionFlags;
435 EV_END();
436 }
437#endif
438}
439
440const struct SceneEvent *Scene_GetEvents(void) {
442}
443
444/// While the battle with Forge runs, the man reacts on a timer; once the
445/// Djinni event is over, it raises event 99.
447 struct EventWork *work;
448 s32 frame;
449
450 work = gEventWork;
452 switch (frame) {
453 case 60:
456 break;
457 case 180:
459 break;
460 case 240:
461 case 270:
463 break;
464 case 480:
466 break;
467 }
469 work->raisedTrigger = 99;
470}
471
472/// Raised once Forge is caught: the man is amazed, then walks off.
475 EV_BEGIN();
479 MESSAGE_SET(MsgGomaGotWowThatsPrettyImpressive);
482 WAIT(30);
485 Actor_WalkToAndWait(WITNESS, 600, 216);
486 Actor_WalkToAndWait(WITNESS, 600, 248);
487 Actor_WalkToAndWait(WITNESS, 568, 296);
488 OBJ_POS_SET(WITNESS, 0, 0);
491 EV_END();
492}
493
494/// Puts the pillars and the stump where the party left them. Entrance 99 shows
495/// the stump falling again; after a Djinni battle, the man's reaction starts.
497 struct FieldActor *actor;
498 struct EventWork *work;
499
500 work = gEventWork;
502 work->transitionFrames = 24;
505 OBJ_POS_SET(WEST_PILLAR, 344, 104);
507 } else {
509 }
511 OBJ_POS_SET(STUMP, 0, 0);
512 Map_CopyCellAttributes(21, 45, 4, 2, 21, 11);
513 }
515 OBJ_POS_SET(EAST_PILLAR, 616, 232);
516 if (gGameState.entrance == 2 || gGameState.entrance == 3) {
519 actor->y.fixed--;
521 Map_CopyCellAttributes(36, 48, 5, 1, 36, 14);
522 }
523 }
524 // Entrance 99 shows the stump being pushed to the edge and falling.
525 if (gGameState.entrance == 99) {
528 OBJ_POS_SET(STUMP, 384, 192);
529 WAIT(60);
531 Actor_MoveToAndWait(STUMP, 408, 192);
532 WAIT(60);
534 }
535 // Coming back from a Djinni battle: the man reacts until it is over.
536 if (gGameState.pendingDjinnEvent != 0) {
539 }
540 return 0;
541}
542
543/// One step per facing: X pixels in the high halfword, Z pixels in the low
544/// half.
545#define DIRECTION_STEP(dx, dz) (((u32)(dx) << 16) | ((dz) & 0xffff))
546
548 DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0),
549 DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16),
550 DIRECTION_STEP(0, 16), DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0),
551 DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0), DIRECTION_STEP(0, -16),
552 DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16),
553 DIRECTION_STEP(16, 0),
554};
555
556// clang-format off
558 207, 205, 228, 229, 298, 297,
559};
560
562 -32, -8, 32, 8,
563 -8, -32, 8, 32,
564 -32, -16, 32, 0,
565 -8, -32, 8, 32,
566 -32, -8, 32, 8,
567 -8, -32, 8, 32,
568};
569
574}};
575
577 SC_WAIT(1),
578 SC_LOOP(22, SC_TOP),
580 SC_WAIT(1),
581 SC_FREE,
582};
583
585 SC_WAIT(1),
586 SC_LOOP(44, SC_TOP),
588 SC_WAIT(1),
589 SC_FREE,
590};
591
593 SC_WAIT(1),
594 SC_LOOP(126, SC_TOP),
596 SC_WAIT(1),
597 SC_FREE,
598};
599
601 { 0, CONDITION_ALWAYS, 172, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
602 { 1, CONDITION_ALWAYS, 88, 0, 184, FACING_SOUTH, 0, 8, 8, 728, 504, 0 },
603 { 2, CONDITION_ALWAYS, 584, 0, 184, FACING_SOUTH, 0, 8, 8, 728, 504, 0 },
604 { 3, CONDITION_ALWAYS, 520, 0, 232, FACING_SOUTH, 0, 8, 8, 728, 504, 0 },
605 { 4, CONDITION_ALWAYS, 232, 0, 184, FACING_SOUTH, 0, 8, 8, 728, 504, 0 },
606 { 5, CONDITION_ALWAYS, 536, 0, 408, FACING_SOUTH, 0, 8, 8, 728, 504, 0 },
607 { 99, CONDITION_ALWAYS, 376, 0, 200, FACING_SOUTH, 0, 8, 8, 728, 504, 0 },
608 { SCENE_TABLE_END },
609};
610
612 SCENE_EXITS(27),
613 SCENE_EXIT(1, 28, 2),
614 SCENE_EXIT(2, 26, 1),
615 SCENE_EXIT(3, 26, 2),
616 SCENE_EXIT(4, 26, 3),
617 SCENE_EXIT(5, 28, 3),
619};
620
629};
630
632 { 0x21, 5, CONDITION_ALWAYS, 1 },
633 { 0x31, 6, CONDITION_ALWAYS, 2 },
634 { 0x31, 7, CONDITION_ALWAYS, 3 },
635 { 0x31, 8, CONDITION_ALWAYS, 4 },
636 { 0x21, 9, CONDITION_ALWAYS, 5 },
640 { EVENT_TALK, WITNESS, 0xa8, MSGNO(MsgVaultDidYouSeeSomethingStrangeOver) },
641 { EVENT_TALK, WITNESS, CONDITION_ALWAYS, MSGNO(MsgVaultHmmmItMustBeHidingSomewhere) },
642 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), WITNESS, 0xa8, MSGNO(MsgVaultItJustWhackedMeInThe) },
643 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), WITNESS, CONDITION_ALWAYS, MSGNO(MsgVaultIKnowitsKindItllBeBack) },
650};
651// clang-format on
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_MOVE
Definition ability_ids.h:15
void ObjectGroup_SetChildValue(struct FieldActor *actor, s32 param)
Sets the param byte of every animated part of an actor's sprite.
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[]
Animated sprites: their layers, frames and colour modes, and the resource slots they draw from.
B5Context, the object context a battle routine reads; most of its fields are still unnamed.
s32 Field_TryJumpForward(void)
Makes the leader jump two tiles forward, over the tile in front, when the map allows it (Map_CheckObj...
Definition climbing.c:25
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
struct FieldActor * Engine_ObjectCreate(s32, s32, s32, s32)
The engine calls the debug menus import, and their palette swatch tiles.
Djinn numbers, named from the English release.
@ DJINNI_FORGE
Definition djinn_ids.h:25
The edition's language, for C to compare (LANGUAGE == LANGUAGE_GERMAN).
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
static s32 FieldObject_CheckMovementCollision(struct FieldActor *actor, struct FieldPosition *position)
Definition engine_call.h:66
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 WAIT(n)
Definition event.h:7
#define OBJ_MODE(no, m)
Definition event.h:18
#define MESSAGE_SET(m)
Definition event.h:9
#define FLAG_SET(f)
Definition event.h:26
#define FLAG_CHECK(f)
Definition event.h:25
#define OBJ_EMOTE(no, e, t)
Definition event.h:19
#define OBJ_SPEED(no, s, a)
Definition event.h:15
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
@ ANIM_NOD
Definition field_event.h:45
@ ANIM_SHAKE_HEAD
Definition field_event.h:46
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Object_SetMode(struct FieldActor *object, s32 animation)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
s32 Engine_TaskRemoveCallback(void(*callback)(void))
void Engine_ActorMoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_ActorSetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
void Engine_EventWaitForScreen(void)
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
void Engine_ObjectSetBlendMode(struct FieldActor *object, s32 mode)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_MapRenderWaitForValues(void)
void Engine_GameFlagClear(s32 flag)
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()
void Engine_ActorSetChildValue(s32 actor, s32 value)
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
void Engine_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
Field objects and actors, and the scene transition styles.
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ 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
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_TALK
@ EVENT_RAISED
#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_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ 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_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
FixedPointPosition, a position in 16.16 fixed point.
Game flags, named where their meaning is shown.
#define FLAG_DJINNI_0
the flag of Djinni 0, set once it is caught
Definition flags.h:15
#define FLAG_GOMA_CAVE_WITNESS_LEFT
after the party caught Forge
Definition flags.h:601
volatile u32 gFrameCount
Frames WaitFrames has finished.
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 STUMP
#define WEST_PILLAR
static void Event_MoveWestPillar(void)
Move on the west pillar, and after each push: the pillar stands on one of three columns,...
#define EAST_PILLAR
static void Event_MoveEastPillar(void)
Move on the east pillar: once it reaches column 23 it settles into the floor and can be walked over.
s32 gGomaCavePillar_WitnessFrames
struct SceneEvent gGomaCavePillar_Events[]
static s32 GomaCavePillar_FinishFragment(struct ScriptInterpreter *interpreter)
Applies child value 15 at the end of a fragment's lifetime.
#define FLAG_GOMA_CAVE_EAST_PILLAR_IN_PLACE
sunk into its place
static void Event_PushEastPillar(void)
Walking into the east pillar pushes it a step.
static void GomaCavePillar_UpdateFragment(union FieldObject *fieldObject)
Advances the fragment's selected coordinate plane and keeps its targets in step.
static void Event_WitnessCheersForgeCaught(void)
Raised once Forge is caught: the man is amazed, then walks off.
#define FLAG_GOMA_CAVE_WEST_PILLAR_MOVED
one step east of its start
static void GomaCavePillar_SpawnStumpDust(void)
While the stump teeters, dust falls from it: one fragment every eighth frame, two on every sixteenth.
static void GomaCavePillar_SpawnFragment(s32 x, s32 y, s32 z, s32 firstRate, s32 secondRate, s32 scriptAndChildValue, s32 planeAndPriority)
Creates a fragment with two axis rates, a script and packed plane/priority.
static void Event_PushStumpOver(void)
Move on the stump: once it is pushed to the edge (column 25), it teeters shedding dust,...
#define FLAG_GOMA_CAVE_STUMP_FELL
pushed over into the room below
#define WITNESS
the man who fought Forge and lost it
GomaCavePillarFragmentPlane
@ PLANE_YZ
@ PLANE_XZ
@ PLANE_XY
s32 gGomaCavePillar_FragmentScript2[]
static void Event_FightForge(void)
Talking to Forge: the man beside it jumps in surprise, and the battle with the Djinni begins.
static void Event_JumpGapWest(void)
Walking west at the gap: the leader jumps across it.
static void GomaCavePillar_FidgetWhileForgeFights(void)
While the battle with Forge runs, the man reacts on a timer; once the Djinni event is over,...
#define FORGE
u32 gGomaCavePillar_Exits[]
s32 gGomaCavePillar_FragmentScript0[]
static void GomaCavePillar_CopyWestPillarCells(s32 sourceColumn)
Copies the map cells for the west pillar on either side of its track.
struct ScenePlacement gGomaCavePillar_Placements[]
s32 gGomaCavePillar_FragmentScript1[]
struct SceneEntrance gGomaCavePillar_Entrances[]
static void GomaCavePillar_SettleEastPillar(void)
Once the east pillar reaches its place (cell 38, 14), it sinks two pixels into the floor and six frag...
struct GomaCavePillarFragmentScripts gGomaCavePillar_FragmentScripts
The screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
Item numbers, named from the English release.
@ ITEM_LUCKY_MEDAL
Definition item_ids.h:70
Declares nothing of its own: it only includes edition.h and types.h.
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_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
#define SC_CALL(fn)
Definition objcmd.h:50
void Field_RequestDjinnBattle(s32 flag, s32 no)
Sets up the battle with Djinni number no.
Definition requests.c:35
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_189
Definition songs.h:184
#define SE_288
Definition songs.h:281
#define SE_CAST
Definition songs.h:149
#define SE_188
Definition songs.h:183
#define SE_141
Definition songs.h:134
#define SE_JUMP
An actor jumps: ObjectMotion_Launch plays the high jump above 5 pixels a frame.
Definition songs.h:147
struct EventWork * gEventWork
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_AudioPlayCue()
void Engine_ActorShowEmote()
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
The pushable actors' movement probes and footprint bounds.
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
u8 flags
bits: 1 outlined in ObjectSystemWork's edge and fill colours | 0 shadow drawn (set when created)
Definition animspr.h:128
u16 priority
2 when created
Definition animspr.h:100
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
Definition event_work.h:20
s16 raisedTrigger
a raised event for Scene_RunRaisedEvent
Definition event_work.h:35
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
s32 transitionFrames
frames
Definition event_work.h:45
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 targetZ
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:61
s32 bounce
The share of its falling speed kept as it bounces on landing, 16.16 fixed point (0x4000 when created)...
Definition field_obj.h:64
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
u8 priorityFlags
ActorPriorityFlag bits, read by the scrolling camera.
Definition field_obj.h:51
s32 velocityY
16.16 fixed-point pixels per frame
Definition field_obj.h:53
s32 gravity
Taken off the vertical velocity each frame while it is above the ground, in 16.16 fixed-point pixels ...
Definition field_obj.h:68
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
s32 targetY
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:60
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
u8 collisionFlags
bits: 7 refuses to move into a solid object | 4 nearer for Psynergy targets | 3 never a talk or Psyne...
Definition field_obj.h:91
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 pendingDjinnEvent
The Djinni battle pending (DJINNI_0 plus its number, flags in bits 15 to 11), resolved on returning t...
Definition game_state.h:103
s16 entrance
Definition game_state.h:37
The action scripts a pillar fragment can run, chosen by the low bits of its spawn value.
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.
Values that differ by patch level or language, chosen once for their code.
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
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.
The patch levels: our groups of the measured changes from the Japanese release.