Alchemy
Loading...
Searching...
No Matches

mercury_lighthouse_entrance.c

Go to the documentation of this file.
1/// @file
2/// Mercury Lighthouse's entrance: Mia's doorway scene, the Ply mechanism,
3/// and the rising pillars used to cross the interior pools.
4
5#include "script.h"
6#include "animspr.h"
7#include "game_state.h"
8#include "global_cells.h"
9#include "heap_state.h"
10#include "keystate.h"
11#include "unit/import.h"
16#include "unit/object/object.h"
18#include "unit/field/field.h"
19#include "unit/window/window.h"
22#include "iowrite.h"
23#include "macros.h"
24
25#define NULL ((void *)0)
26#include "field_obj.h"
27#include "mem.h"
28#include "types.h"
29#include "mercury.h"
30#include "field_scene.h"
31#include "staged_actor.h"
32#include "battle.h"
33#include "debug.h"
34#include "field.h"
35#include "game.h"
36#include "graphics.h"
37#include "menu.h"
38#include "minigame.h"
39#include "sound.h"
40#include "system.h"
41#include "mapcopy.h"
42#include "call.h"
43#include "engine_call.h"
44#include "scene_ids.h"
45#include "field_effect.h"
46#include "io_reg.h"
47#include "field_event.h"
48#include "text/msg_ids.h"
49#include "iwram_call.h"
50#include "ability_ids.h"
51#include "objcmd.h"
52#include "flags.h"
53#include "songs.h"
54#include "item_ids.h"
55
56/// The entrance's actors. Mia stands in her own party slot; the Lizard Man is
57/// the monster she cannot get past (encounter table 36 fights him as "Lizard
58/// Man"); the Ply target is the invisible actor Ply is cast on.
62};
63
64/// Entrances with a scene of their own.
66 ENTRANCE_DROP_FROM_ABOVE = 6, ///< the leader drops in from above
69 ENTRANCE_AFTER_LIZARD_MAN = 31 ///< the return from the Lizard Man battle
70};
71
72/// Exits the events take: the doorway scenes at entrances 30 and 31, and on
73/// to Mercury Lighthouse after rising from the channels.
78};
79
80/// Scene flags, kept while the party stays here.
81enum {
84 /// The Lizard Man has stepped into the leader's column.
86};
87
88/// The chests: an unnamed item (0x4c) and a chest whose find kind is 5.
89enum { FLAG_CHEST_ITEM_4C = 0xf65, FLAG_CHEST_EF0 = 0xef0 };
90
91// Forward declarations.
94
96#include "common/effect_spawn.h"
99
100/// The sound of the Lizard Man's sidestep, played by all three step scripts
101/// as he lands.
102static s32
105 return 0;
106}
107
108// Mia's update while she waits by the Lizard Man: she turns to watch the
109// leader while the leader is north of 184 pixels, and looks back north at
110// the doorway otherwise.
111// UB: the field updater invokes a void hook. Plain void removes the zero
112// result and changes the native return register (three instructions in EN).
113#ifdef UBFIX
114static void
116#else
117static s32
119#endif
120 struct FieldActor *object = (struct FieldActor *)fieldObject;
122
123 if ((leader->z.fixed >> 19) <= 22) {
124 object->facing = ArcTan2(leader->z.fixed - object->z.fixed,
125 leader->x.fixed - object->x.fixed);
126 } else if (object->facing != FACING_NORTH) {
128 }
129#ifndef UBFIX
130 return 0;
131#endif
132}
133
135
136/// Touching trigger 21 once Ply has worked: rising sparks keep appearing
137/// while the leader stands on the pillar.
140}
141
142/// Touching trigger 31 once Ply has worked: the raised pillar is let go.
145}
146
147/// Walking into trigger 11, 21 or 31 once Ply has worked: one step across
148/// the water pillars in the pressed direction.
151}
152
153/// Touching trigger 11 once Ply has worked: the pillar underfoot rises to its
154/// full height.
157}
158
161}
162
164 return NULL;
165}
166
169}
170
171/// Mia, the Lizard Man, the actors at the doorway and the Ply target.
174}
175
176/// Searching the inscription (trigger 1).
177/// "He who honors the heart of the goddess..."
181 Engine_MessageShowCentered(MsgMercuryWhoHonorsHeart, 1);
183}
184
186
187/// Walking north into trigger 67: the leader rises to the southern landing.
190}
191
192/// Walking north into trigger 68: the leader rises to the northern landing.
195}
196
197/// Walking north into trigger 69: the leader rises to the middle landing.
200}
201
202/// The touch, search, talk and Psynergy events.
205}
206
207/// Ply on the Ply target, from cell (12, 32) only: the room dims, fifteen
208/// sparks rise from the pool, the lights start to cycle and the pillar
209/// triggers come into play.
211 s32 leaderColumn;
212 s32 leaderRow;
213 s32 velocityZ;
214 s32 sparkIndex;
215 s32 sparkX;
216 s32 sparkZ;
217 s32 speedRoll;
218 s32 velocityY;
219 struct EffectOptions *effectData;
220 struct EffectOptions effectOptions;
221
222 leaderColumn = Object_GetById(ACTOR_PARTY_LEADER)->x.fixed / 0x100000;
223 leaderRow = Object_GetById(ACTOR_PARTY_LEADER)->z.fixed / 0x100000;
224 if (leaderColumn == 12 && leaderRow == 32) {
226 // Fade the scene before releasing fifteen sparks above the pool.
227 ColorBuffer_ApplyTarget(0x10000, 0);
229 Engine_EventWait(120);
230 ColorBuffer_ApplyTarget(0x10005, 1);
233 sparkIndex = 0;
234 effectData = &effectOptions;
235 velocityZ = 0;
236 do {
237 effectData->priority = 1;
238 {
239 u16 effectType = 0x11e;
240
241 effectData->type = effectType;
242 }
245 sparkX = 208 - ((u32)(Random_Next() << 4) >> 16);
246 sparkZ = 560 - ((u32)(Random_Next() << 4) >> 16);
247 speedRoll = ((u32)(Engine_RandomNext() << 2) >> 16);
248 velocityY =
249 Math_Divide((((speedRoll << 4) - speedRoll) << 16) + 0x3c0000, 100);
250 Effect_Spawn(sparkX << 16, 0, sparkZ << 16, 0, velocityY, velocityZ,
252 1,
253 effectData);
255 sparkIndex++;
256 } while ((u32)sparkIndex <= 14);
259 // Persist the activated state and replace the pool's map cells.
262 Map_CopyCellsTo(37, 98, 10, 97, 5, 3);
263 Map_CopyCellAttributes(70, 32, 13, 7, 6, 32);
264 ColorBuffer_ApplyTarget(0x10000, 0);
266 Engine_EventWait(120);
268 }
269}
270
271/// Touching trigger 10 by the doorway: the scene starts again at the
272/// doorway, where Mia goes in if she has not yet.
275}
276
277/// Touching trigger 40 or 42 while the Lizard Man stands aside: he steps back
278/// in front of the doorway.
283}
284
285/// Touching trigger 41 while he stands in the doorway: the Lizard Man steps
286/// into the leader's way, west from column 7 and east otherwise.
288 struct FieldActor *leader;
289 s32 leaderX;
290 s32 leaderColumn;
291
293 leaderX = leader->x.fixed;
294 leaderColumn = leaderX / 0x100000;
296 if (leaderColumn == 7) {
299 } else {
302 }
303}
304
305/// Talking to the Lizard Man, Mind Read on him, or walking north into
306/// trigger 40 or 41: he stirs and the battle begins. The party returns to
307/// the doorway afterwards.
316 // Encounter table 36, slot 1: the Lizard Man.
319}
320
322
323/// On entering: the lights, the Retreat point and the pillar routes Ply has
324/// opened, then the scene of the entrance taken.
326 struct EffectOptions options;
327 s32 velocity[3];
328 struct FieldActor *actor;
329 u32 sparkIndex;
330 s32 angle;
331 s32 arrivalSeen;
332
334 {
335 s32 alpha = BLEND_ALPHA(16, 16);
336 REG_BLDALPHA = alpha;
337 }
338 // Restore persistent lighting and the Retreat destination first.
347 else
350 // Each entrance restores its route or plays its one-time arrival.
351 switch (gGameState.entrance) {
352 case 1:
353 // Until Mia has gone in, arriving here plays the Lizard Man scene.
356 // Both doorway entrances flip actors 12 to 14.
357 // Fall through.
358 case 2:
359 Actor_Get(12)->scaleX = -0x10000;
360 Actor_Get(13)->scaleX = -0x10000;
361 Actor_Get(14)->scaleX = -0x10000;
363 break;
364 case 7:
365 case 8:
366 case 9:
367 case 10:
368 case 11:
369 case 12:
371 Map_CopyCellAttributes(84, 5, 10, 7, 20, 5);
372 Map_CopyCellAttributes(101, 5, 12, 7, 37, 5);
373 }
374 break;
375 case 3:
376 case 4:
377 case 5:
381 Map_CopyCellsTo(37, 98, 10, 97, 5, 3);
384 Map_CopyCellAttributes(70, 32, 13, 7, 6, 32);
385 }
387 break;
389 if (arrivalSeen != 0)
390 break;
391 // The first time, the leader drops from 130 pixels up and lands in a
392 // burst; until Ply has been used, the inscription's words appear.
395 Camera_MoveTo(-1, -1, -1, 0);
398 Actor_Get(ACTOR_PARTY_LEADER)->y.fixed = PIXELS(130);
399 Actor_Get(ACTOR_PARTY_LEADER)->gravity = 0x8000;
400 Actor_Get(ACTOR_PARTY_LEADER)->bounce = arrivalSeen;
401 Actor_Get(ACTOR_PARTY_LEADER)->motionFlags = arrivalSeen;
405 Actor_Get(ACTOR_PARTY_LEADER)->motionFlags = 3;
408 // Scatter seventeen effects around the leader before the landing.
410 options.palette = 7;
411 for (sparkIndex = 0; sparkIndex <= 16; sparkIndex++) {
412 angle = sparkIndex << 12;
413 SET_VECTOR(velocity, Engine_MathCos(angle), 0, Engine_MathSin(angle));
414 velocity[0] -= velocity[0] / 4;
415 velocity[2] -= velocity[2] / 2;
416 Effect_Spawn(actor->x.fixed, actor->y.fixed, actor->z.fixed, velocity[0],
417 velocity[1], velocity[2], EFFECT_USE_PALETTE | 1, &options);
418 }
422 Map_SetShake(0x50000, 0x50000, 0x10000);
423 Map_SetShake(-1, -1, 0xe666);
426 Actor_Get(ACTOR_PARTY_LEADER)->gravity = 0x10000;
427 Actor_Get(ACTOR_PARTY_LEADER)->bounce = 0x4000;
429 ColorBuffer_ApplySource(0x10000, 0);
430 ColorBuffer_ApplyTarget(0x10003, 1);
435 UiText_ShowCenteredMessage(MsgMercuryWhoHonorsHeart, 0, 0);
436 ColorBuffer_ApplyTarget(0x10000, 0);
438 }
440 break;
441 case 18:
442 case 19:
443 case 20:
445 // All four arrivals play the same sound.
446 // Fall through.
447 case 17:
449 break;
459 Engine_EventWait(120);
462 break;
466 else
467 Map_CopyCellAttributes(0, 0, 3, 3, 7, 9);
468 break;
472 break;
473 }
474 return 0;
475}
476
477/// Entrance 30, unless resuming: Mia tries to get past the Lizard Man in the
478/// doorway, who steps across to block her each time; then she waits, watching
479/// the leader come up.
481 s32 paceCycle;
482 struct FieldActor *mia;
483 struct FieldActor *actor;
484
486 actor = Object_GetById(12);
487 actor->scaleX = -0x10000;
488 actor = Object_GetById(13);
489 actor->scaleX = -0x10000;
490 actor = Object_GetById(14);
491 actor->scaleX = -0x10000;
492 Actor_SetPosition(MIA, PIXELS(136), PIXELS(184));
495 Actor_SetSpeed(MIA, 0x18000, 0xc000);
496 Actor_SetSpeed(ACTOR_LIZARD_MAN, 0x18000, 0xc000);
497 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0xcccc, 0x6666);
498 Engine_CameraSetSpeed(0xcccc, 0x1999);
499 Engine_CameraMoveTo(PIXELS(136), -1, PIXELS(184), 0);
505 // Twice she tries the east side and then the west.
506 for (paceCycle = 0; paceCycle < 2; paceCycle++) {
507 Engine_ActorWalkTo(MIA, 152, 168);
514 mia = Object_GetById(MIA);
516 Engine_ActorWalkTo(MIA, 136, 184);
523 Engine_ActorWalkTo(MIA, 120, 168);
532 Engine_ActorWalkTo(MIA, 136, 184);
539 }
542 actor = Object_GetById(MIA);
543#ifdef UBFIX
545#else
546 actor->update =
548#endif
549 // The leader walks up behind her; the cells before the doorway become
550 // walkable.
555 Map_CopyCellAttributes(0, 0, 3, 3, 7, 9);
557}
558
559/// Entrance 31, back from the Lizard Man battle and once only: Mia nods to
560/// the leader and goes on into the lighthouse.
562 struct FieldActor *actor;
563
567 actor = Actor_Get(12);
568 actor->scaleX = -0x10000;
569 actor = Object_GetById(13);
570 actor->scaleX = -0x10000;
571 actor = Actor_Get(14);
572 actor->scaleX = -0x10000;
573 Actor_SetPosition(MIA, PIXELS(136), PIXELS(144));
582 Actor_WalkTo(MIA, 136, 72);
586 Actor_SetPosition(MIA, 0, 0);
590 }
591}
592
594
595/// Spawns the short-lived rising effect at an actor's position.
597 struct FieldActor *effect = Engine_ObjectCreate(
598 24, source->x.fixed, source->y.fixed, source->z.fixed);
599
600 if (effect != 0) {
601 struct AnimationObject *sprite = (struct AnimationObject *)effect->sprite;
602
604 effect->motionFlags = 0;
605 effect->terrainId = 1;
606 effect->priorityFlags = 2;
607 if (sprite != 0) {
609 sprite->flags = 0;
610 sprite->image.priority = 3;
611 }
612 }
613}
614
616
618 SC_WAIT(1), SC_LOOP(22, SC_TOP), SC_WAIT(1),
619 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
620};
621
623 SC_WAIT(1), SC_LOOP(44, SC_TOP), SC_WAIT(1),
624 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
625};
626
628 SC_WAIT(1), SC_LOOP(126, SC_TOP), SC_WAIT(1),
629 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
630};
631
632/// Pixel step by direction: X in the upper halfword, Z in the lower.
633#define DIRECTION_STEP(dx, dz) (((dx) << 16) | ((dz) & 0xffff))
634
636 DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0),
637 DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16),
638 DIRECTION_STEP(0, 16), DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0),
639 DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0), DIRECTION_STEP(0, -16),
640 DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16),
641 DIRECTION_STEP(16, 0),
642};
643
644// clang-format off
646 207, 205, 228, 229, 298, 297,
647};
648
650 -32, -8, 32, 8,
651 -8, -32, 8, 32,
652 -32, -16, 32, 0,
653 -8, -32, 8, 32,
654 -32, -8, 32, 8,
655 -8, -32, 8, 32,
656};
657
659 SC_WAIT(30),
660 SC_FREE,
661};
662
665 SC_FREE,
666};
667
670 SC_END,
671};
672
675 SC_FREE,
676};
677
680 SC_END,
681};
682
684 0xffff, FACING_EAST, FACING_WEST, 0xffff, FACING_NORTH, 0xffff, 0xffff, FACING_NORTH,
685 FACING_SOUTH, 0xffff, 0xffff, FACING_SOUTH, 0xffff, FACING_EAST, FACING_WEST, 0xffff,
686};
687
688const s32 *gEffectScripts[] = {
692};
693
695 SC_SET(SW_SPEED, 0x20000),
696 SC_SET(SW_ACCEL, 0x20000),
698 SC_ARG(2),
699 SC_MOVE(PIXELS(136), 0, PIXELS(152)),
701 SC_SYNC,
702 SC_ARG(1),
703 SC_END,
704};
705
707 SC_SET(SW_SPEED, 0x20000),
708 SC_SET(SW_ACCEL, 0x20000),
710 SC_ARG(2),
711 SC_MOVE(PIXELS(120), 0, PIXELS(152)),
713 SC_SYNC,
714 SC_ARG(1),
715 SC_END,
716};
717
719 SC_SET(SW_SPEED, 0x20000),
720 SC_SET(SW_ACCEL, 0x20000),
722 SC_ARG(2),
723 SC_MOVE(PIXELS(152), 0, PIXELS(152)),
725 SC_SYNC,
726 SC_ARG(1),
727 SC_END,
728};
729
731
733
735
737 { 0, CONDITION_ALWAYS, 209, 0, 279, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
738 { 1, CONDITION_ALWAYS, 136, 0, 280, FACING_NORTH, 0, 16, 32, 256, 320, 0 },
739 { 2, CONDITION_ALWAYS, 136, 0, 120, FACING_SOUTH, 0, 16, 32, 256, 320, 0 },
740 { 3, CONDITION_ALWAYS, 200, 0, 648, FACING_NORTH, 0, 80, 432, 320, 688, 0 },
741 { 4, CONDITION_ALWAYS, 120, 0, 520, FACING_SOUTH, 0, 80, 432, 320, 688, 0 },
742 { 5, CONDITION_ALWAYS, 280, 0, 520, FACING_SOUTH, 0, 80, 432, 320, 688, 0 },
743 { 6, CONDITION_ALWAYS, 200, 0, 552, FACING_SOUTH, 0, 80, 432, 320, 688, 0 },
744 { 7, CONDITION_ALWAYS, 360, 0, 184, FACING_NORTH, 0, 304, 32, 800, 208, 0 },
745 { 8, CONDITION_ALWAYS, 456, 0, 184, FACING_NORTH, 0, 304, 32, 800, 208, 0 },
746 { 9, CONDITION_ALWAYS, 616, 0, 184, FACING_NORTH, 0, 304, 32, 800, 208, 0 },
747 { 10, CONDITION_ALWAYS, 760, 0, 184, FACING_NORTH, 0, 304, 32, 800, 208, 0 },
748 { 11, CONDITION_ALWAYS, 344, 0, 88, FACING_SOUTH, 0, 304, 32, 800, 208, 0 },
749 { 12, CONDITION_ALWAYS, 536, 0, 88, FACING_SOUTH, 0, 304, 32, 800, 208, 0 },
750 { 13, FLAG_MERCURY_LIGHTHOUSE_CHANNELS_OPEN, 744, 0, 680, FACING_NORTH, 0, 544, 512, 784, 720, 0 },
751 { 14, FLAG_MERCURY_LIGHTHOUSE_CHANNELS_OPEN, 584, 0, 568, FACING_SOUTH, 0, 544, 512, 784, 720, 0 },
752 { 15, FLAG_MERCURY_LIGHTHOUSE_CHANNELS_OPEN, 744, 0, 568, FACING_SOUTH, 0, 544, 512, 784, 720, 0 },
753 { 13, CONDITION_ALWAYS, 584, 0, 424, FACING_NORTH, 0, 384, 256, 624, 448, 0 },
754 { 14, CONDITION_ALWAYS, 424, 0, 312, FACING_SOUTH, 0, 384, 256, 624, 448, 0 },
755 { 15, CONDITION_ALWAYS, 584, 0, 312, FACING_SOUTH, 0, 384, 256, 624, 448, 0 },
756 { 16, CONDITION_ALWAYS, 744, 0, 424, FACING_NORTH, 0, 704, 256, 944, 448, 0 },
757 { 17, CONDITION_ALWAYS, 344, 0, 872, FACING_SOUTH, 0, 48, 768, 400, 960, 0 },
758 { 18, CONDITION_ALWAYS, 232, 0, 872, FACING_SOUTH, 0, 48, 768, 400, 960, 0 },
759 { 19, CONDITION_ALWAYS, 568, 0, 872, FACING_SOUTH, 0, 464, 768, 816, 960, 0 },
760 { 20, CONDITION_ALWAYS, 696, 0, 872, FACING_SOUTH, 0, 464, 768, 816, 960, 0 },
761 { 25, CONDITION_ALWAYS, 744, 0, 600, FACING_SOUTH, 0, 544, 512, 784, 720, 0 },
762 { 30, CONDITION_ALWAYS, 136, 0, 296, FACING_NORTH, 0, 16, 32, 256, 320, 0 },
763 { 31, CONDITION_ALWAYS, 136, 0, 168, FACING_NORTH, 0, 16, 32, 256, 320, 0 },
764 { 60, CONDITION_ALWAYS, 136, 0, 152, FACING_SOUTH, 0, 16, 32, 256, 320, 0 },
765 { 99, CONDITION_ALWAYS, 136, 0, 232, FACING_EAST, 0, 16, 32, 256, 320, 0 },
766 { SCENE_TABLE_END },
767};
768
770 SCENE_EXITS(53),
771 SCENE_EXIT(1, 57, 12),
772 SCENE_EXIT(2, 53, 3),
773 SCENE_EXIT(3, 53, 2),
774 SCENE_EXIT(4, 53, 9),
775 SCENE_EXIT(5, 53, 8),
776 SCENE_EXIT(6, 53, 17),
777 SCENE_EXIT(7, 53, 4),
778 SCENE_EXIT(8, 53, 5),
779 SCENE_EXIT(9, 53, 19),
780 SCENE_EXIT(10, 54, 1),
781 SCENE_EXIT(11, 54, 2),
782 SCENE_EXIT(12, 54, 7),
783 SCENE_EXIT(13, 54, 4),
784 SCENE_EXIT(14, 53, 18),
785 SCENE_EXIT(15, 53, 20),
786 SCENE_EXIT(16, 53, 7),
787 SCENE_EXIT(17, 53, 13),
788 SCENE_EXIT(18, 53, 10),
789 SCENE_EXIT(19, 53, 16),
794};
795
801 { 0xe0, CONDITION_ALWAYS, 7,
802 PIXELS(88), 0, PIXELS(136), FACING_SOUTH, TALK_KEEP_FACING, 0 },
803 { 0xe0, CONDITION_ALWAYS, 7,
805 { 0xe0, CONDITION_ALWAYS, 7,
807 { 0xe0, CONDITION_ALWAYS, 7,
809 { 0xe0, CONDITION_ALWAYS, 7,
811 { 0xe0, CONDITION_ALWAYS, 7,
814 PIXELS(200), 0, PIXELS(616), FACING_SOUTH, TALK_KEEP_FACING, 0 },
815 { 0x16, CONDITION_ALWAYS, 7,
816 PIXELS(200), 0, PIXELS(512), FACING_SOUTH, TALK_KEEP_FACING, 0 },
817 { SCENE_TABLE_END },
818};
819
836 { EVENT_EXIT, 51, CONDITION_ALWAYS, 1 },
837 { EVENT_EXIT, 52, CONDITION_ALWAYS, 2 },
838 { EVENT_EXIT, 53, CONDITION_ALWAYS, 3 },
839 { EVENT_EXIT, 54, CONDITION_ALWAYS, 4 },
840 { EVENT_EXIT, 55, CONDITION_ALWAYS, 5 },
841 { EVENT_EXIT, 56, CONDITION_ALWAYS, 6 },
842 { EVENT_EXIT, 57, CONDITION_ALWAYS, 7 },
843 { EVENT_EXIT, 58, CONDITION_ALWAYS, 8 },
844 { EVENT_EXIT, 59, CONDITION_ALWAYS, 9 },
845 { EVENT_EXIT, 60, CONDITION_ALWAYS, 10 },
846 { EVENT_EXIT, 61, CONDITION_ALWAYS, 11 },
847 { 0x21, 62, CONDITION_ALWAYS, 12 },
848 { EVENT_EXIT, 63, CONDITION_ALWAYS, 13 },
849 { EVENT_EXIT, 64, CONDITION_ALWAYS, 14 },
850 { EVENT_EXIT, 65, CONDITION_ALWAYS, 15 },
851 { EVENT_EXIT, 66, CONDITION_ALWAYS, 16 },
852 { EVENT_TALK, MIA, CONDITION_ALWAYS, MSGNO(MsgMercuryMonsterInsideTower) },
853 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), MIA, CONDITION_ALWAYS, MSGNO(MsgMercuryLetMePass) },
860 { SEARCH(SEARCH_CHEST), 101, FLAG_CHEST_EF0, 0x500000 },
862};
863
864/// Each spark pulses in size four times, then is released.
866 SC_SET(SW_SCALE_Y, 0x10000),
867 SC_SET(SW_SCALE_X, 0x10000),
868 SC_WAIT(6),
869 SC_SET(SW_SCALE_Y, 0xa000),
870 SC_SET(SW_SCALE_X, 0xa000),
871 SC_WAIT(6),
872 SC_SET(SW_SCALE_Y, 0x4000),
873 SC_SET(SW_SCALE_X, 0x4000),
874 SC_WAIT(6),
875 SC_SET(SW_SCALE_Y, 0xa000),
876 SC_SET(SW_SCALE_X, 0xa000),
877 SC_WAIT(6),
878 SC_LOOP(4, SC_TOP),
879 SC_WAIT(1),
880 SC_POS(0, 0, 0),
881 SC_WAIT(1),
882 SC_FREE,
883};
884// clang-format on
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_PLY
Definition ability_ids.h:14
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
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 AnimationObjects_SelectAnimation(struct AnimationObject *sprite, s32 animation)
Starts animation flags & 0x7f on every layer of a sprite (bit 7 keeps each layer's place and timer),...
Definition animation.c:317
Animated sprites: their layers, frames and colour modes, and the resource slots they draw from.
s32 gEffectScript0[]
const s32 * gEffectScripts[]
s32 gEffectScript1[]
s32 gEffectScript2[]
Calls through a function pointer, by argument count.
#define MIA
Mary.
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.
The engine call layer: one typed inline for each of the thirteen main-image routines below that the s...
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
void BattleFx_StartFadeOverlay(void *object)
Starts the fade overlay on object (the party leader when NULL): loads its solid tiles,...
Field effects, their scripts and the flags that spawn them.
@ EFFECT_USE_PALETTE
options.palette, as its group child value
@ EFFECT_USE_TYPE
options.type, else object type 222
@ EFFECT_USE_PRIORITY
options.priority, as the sprite's priority
@ EFFECT_USE_SCRIPT
options.script, run in mode 1
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
@ ANIM_STAND
Definition field_event.h:43
@ ANIM_NOD
Definition field_event.h:45
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Engine_MessageShowCentered(s32 message, s32 flags)
#define GameFlag_IsSet
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
void Engine_CameraMoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
void Engine_CameraMoveToActor(s32 actor, s32 pan)
#define EMOTE_IN_FRONT
Definition field_event.h:49
s32 Engine_MathSin(s32 angle)
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 Actor_FaceActor(s32 actor, s32 target, s32 frames)
static void ColorBuffer_ApplyTarget(s32 value, s32 mode)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
static s32 Math_Divide(s32 dividend, s32 divisor)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_MapRenderWaitForValues(void)
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_ActorRunRepeatedMotion(s32 actor, s32 repeats)
void Engine_ActorWalkTo(s32 actor, s32 x, s32 z)
s32 Engine_RandomNext()
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
static void Actor_SetChildValue(s32 actor, s32 value)
u8 gSceneState[]
s32 Engine_MathCos(s32 angle)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_MapRedraw(void)
static s32 Random_Next(void)
void Engine_ColorBufferInterpolate(s32 frames)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
static struct FieldActor * Actor_Get(s32 actor)
static void ColorBuffer_ApplySource(s32 value, s32 mode)
Field objects and actors, and the scene transition styles.
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ TRANSITION_BACKDROP_FADE
Definition field_obj.h:16
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
@ 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
#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 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
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
@ FACING_EAST
Definition field_scene.h:26
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define TOUCH_WALKING
#define PIXELS(value)
@ SEARCH_UNNAMED
@ SEARCH_CHEST
Game flags, named where their meaning is shown.
#define FLAG_SCENE_TEMP_05
Definition flags.h:718
#define FLAG_MIA_ENTERED_MERCURY_LIGHTHOUSE
Past the Lizard Man, Mia has gone on into the lighthouse.
Definition flags.h:341
#define FLAG_MERCURY_LIGHTHOUSE_LIT
Definition flags.h:30
#define FLAG_MERCURY_LIGHTHOUSE_PLY_ACTIVATED
Ply in the entrance hall: the lights cycle and the pillar routes open.
Definition flags.h:346
#define FLAG_MERCURY_LIGHTHOUSE_CHANNELS_OPEN
All three channel blocks are in place and the water runs.
Definition flags.h:348
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_SCENE_TEMP_50
Definition flags.h:793
GameState, the game's state: play time, coins, the scene and the leader's position,...
#define Battle_SetStart(mode)
Sets the battle start type.
Definition game_state.h:164
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
The screen blend's globals and the graphics routines.
The heap's work slots and HeapState.
The main-image routines scene overlays import.
The hardware's I/O registers and their bits, as pret names them.
#define BLDCNT_EFFECT_BLEND
weighted by REG_BLDALPHA
Definition io_reg.h:131
#define BLDCNT_TGT2_ALL
Definition io_reg.h:140
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
Definition io_reg.h:145
#define REG_BLDALPHA
Definition io_reg.h:142
#define REG_BLDCNT
Definition io_reg.h:119
Io_Write16, a 16-bit write to a register or memory.
#define Io_Write16(v, reg)
Writes a value to a 16-bit register or memory location.
Definition iowrite.h:14
Item numbers, named from the English release.
@ ITEM_PSYNERGY_ARMOR
Definition item_ids.h:21
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
The keypad state the VBlank interrupt keeps.
Small statement macros both games use for positions, velocities and bounds.
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
Definition macros.h:12
Declares nothing of its own: it only includes edition.h and types.h.
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 heaps: allocating and freeing blocks.
Includes field_event.h with FIELD_STAGED_ACTOR_IMPORTS defined, so a scene gets the staged-actor impo...
s32 gMercuryLighthouse_PillarScript[]
s32 gPaletteCycleGreen
s32 gMercuryLighthouse_ScaleCounterScript[]
@ ACTOR_PLY_TARGET
s32 gPaletteCycleRed
s32 gMercuryLighthouse_RampScript[]
s32 gPaletteCycleBlue
s32 gMercuryLighthouse_SparkScript[]
u16 gMercuryLighthouse_MoveAngles[]
Mercury Lighthouse and its entrance: arriving on a floor through one of its sparkling passages.
static void MercuryLighthouse_ArriveWithSparks(void)
Unless the party returns to where it was, the leader appears 16 pixels north of the entrance,...
static void MercuryLighthouseEntrance_FightLizardMan(void)
Talking to the Lizard Man, Mind Read on him, or walking north into trigger 40 or 41: he stirs and the...
s32 gMercuryLighthouseEntrance_LizardManStepEast[]
const struct SceneEntrance * MercuryLighthouseEntrance_GetEntrances(void)
u32 gMercuryLighthouseEntrance_Exits[]
MercuryLighthouseEntranceActor
The entrance's actors.
static void MercuryLighthouseEntrance_MiaEntersLighthouse(void)
Entrance 31, back from the Lizard Man battle and once only: Mia nods to the leader and goes on into t...
s32 MercuryLighthouseEntrance_Initialize(void)
On entering: the lights, the Retreat point and the pillar routes Ply has opened, then the scene of th...
struct ScenePlacement gMercuryLighthouseEntrance_Placements[]
MercuryLighthouseEntranceExit
Exits the events take: the doorway scenes at entrances 30 and 31, and on to Mercury Lighthouse after ...
const struct ScenePlacement * MercuryLighthouseEntrance_GetPlacements(void)
Mia, the Lizard Man, the actors at the doorway and the Ply target.
static void MercuryLighthouseEntrance_TryPillarStep(void)
Walking into trigger 11, 21 or 31 once Ply has worked: one step across the water pillars in the press...
static void MercuryLighthouseEntrance_ReleaseRaisedPillar(void)
Touching trigger 31 once Ply has worked: the raised pillar is let go.
static void MercuryLighthouseEntrance_LizardManReturnsToCentre(void)
Touching trigger 40 or 42 while the Lizard Man stands aside: he steps back in front of the doorway.
@ FLAG_DROP_FROM_ABOVE_SEEN
@ FLAG_LIZARD_MAN_STEPPED_ASIDE
The Lizard Man has stepped into the leader's column.
static void MercuryLighthouseEntrance_RiseToMiddleLanding(void)
Walking north into trigger 69: the leader rises to the middle landing.
MercuryLighthouseEntranceEntrance
Entrances with a scene of their own.
@ ENTRANCE_DROP_FROM_ABOVE
the leader drops in from above
@ ENTRANCE_AFTER_LIZARD_MAN
the return from the Lizard Man battle
@ ENTRANCE_BEFORE_LIZARD_MAN
@ ENTRANCE_RISE_FROM_CHANNELS
static void MercuryLighthouseEntrance_RaiseTouchedPillar(void)
Touching trigger 11 once Ply has worked: the pillar underfoot rises to its full height.
static void MercuryLighthouseEntrance_SpawnTimedRiseEffect(void)
Touching trigger 21 once Ply has worked: rising sparks keep appearing while the leader stands on the ...
const struct SceneEvent * MercuryLighthouseEntrance_GetEvents(void)
The touch, search, talk and Psynergy events.
static s32 MercuryLighthouseEntrance_PlayStepSound(struct ScriptInterpreter *interpreter)
The sound of the Lizard Man's sidestep, played by all three step scripts as he lands.
const struct SceneRegion * MercuryLighthouseEntrance_GetRegions(void)
static void MercuryLighthouseEntrance_LizardManBlocksLeader(void)
Touching trigger 41 while he stands in the doorway: the Lizard Man steps into the leader's way,...
struct SceneEvent gMercuryLighthouseEntrance_Events[]
static void OverlayObject_SpawnKind24AtObject(struct FieldActor *source)
Spawns the short-lived rising effect at an actor's position.
static void MercuryLighthouseEntrance_ReadHeartInscription(void)
Searching the inscription (trigger 1).
const u32 * MercuryLighthouseEntrance_GetExits(void)
s32 gMercuryLighthouseEntrance_LizardManStepWest[]
static void MercuryLighthouseEntrance_RiseToSouthernLanding(void)
Walking north into trigger 67: the leader rises to the southern landing.
static void MercuryLighthouseEntrance_RiseToNorthernLanding(void)
Walking north into trigger 68: the leader rises to the northern landing.
static void MercuryLighthouseEntrance_ActivateWithPly(void)
Ply on the Ply target, from cell (12, 32) only: the room dims, fifteen sparks rise from the pool,...
s32 gMercuryLighthouseEntrance_LizardManStepCentre[]
s32 gMercuryLighthouseEntrance_RiseScript[]
struct SceneEntrance gMercuryLighthouseEntrance_Entrances[]
static void MercuryLighthouseEntrance_LizardManBlocksMia(void)
Entrance 30, unless resuming: Mia tries to get past the Lizard Man in the doorway,...
s32 gMercuryLighthouseEntrance_SparkBurstScript[]
Each spark pulses in size four times, then is released.
static s32 MercuryLighthouseEntrance_MiaWatchesLeader(union FieldObject *fieldObject)
static void MercuryLighthouseEntrance_ReturnToDoorway(void)
Touching trigger 10 by the doorway: the scene starts again at the doorway, where Mia goes in if she h...
static void MercuryLighthouse_ClearPalette(void)
While the pool sleeps: colours 9 to 15 of background palette 6 are black.
static void MercuryLighthouse_CyclePalette(void)
A scene callback: every fifth frame colour 9's red level steps on by 4, and each of colours 10 to 15 ...
Mercury Lighthouse and its entrance: leaving a floor through one of its sparkling passages.
static void MercuryLighthouse_LeaveThroughPassage(s32 exit)
Touch a passage: the leader moves north with the trail of sparks, vanishes, and after half a second t...
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_SET(w, v)
Write a work value.
Definition objcmd.h:37
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_FREE
Release.
Definition objcmd.h:43
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#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
@ SW_ACCEL
Definition objcmd.h:68
@ SW_SCALE_Y
Definition objcmd.h:63
@ SW_SPEED
Definition objcmd.h:67
@ SW_STEERING
Definition objcmd.h:80
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void Field_RequestBattleFromEncounterTable(s32 zoneNo, s32 slotNo)
Sets up a battle with enemy group slot of encounter table zone.
Definition requests.c:14
void Event_SetNextDestination(s32 scene, s32 entrance)
Sets the scene and entrance that the field goes to next (gGameState.nextScene and nextEntrance).
Definition requests.c:61
void BattleFx_SetQueuedSoundAndPlay(s32 soundId)
Plays SE_298, then soundId (SE_289 for -1), and remembers soundId for BattleFx_PlayQueuedSound in the...
Definition requests.c:90
Scene numbers, named after their places.
char SceneId_MercuryLighthouseEntrance
char SceneId_MercuryLighthouse4
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_220
Definition songs.h:215
#define SE_170
Definition songs.h:165
#define SE_204
Definition songs.h:199
#define SE_118
Definition songs.h:111
#define SE_188
Definition songs.h:183
#define SE_246
Definition songs.h:241
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_ActorShowEmote()
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
void MercuryLighthouse_RestoreLights(s32 region, struct MercuryLighthouseLights *st)
Keeps the lights' state st in work slot 35 for the floor's region, the pool's collision code.
static s32 OverlayObject_RampWords24And28Over16Frames(struct ScriptInterpreter *interpreter)
Grows the moving light over the first sixteen script frames.
void MercuryLighthouse_HopAcrossPool(void)
Pushing against the pool's edge (triggers 11, 21 and 31): the leader hops two cells the way the pad p...
static s32 MercuryLighthouse_FollowLeader(struct ScriptInterpreter *interpreter)
Follows the linked actor and alternates the light's animation parameter.
static void MercuryLighthouse_RemoveColumnOnRetreat(void)
Retreat (PSYNERGY_IN_AREA(ABILITY_RETREAT, 1)): remove the column of light.
void MercuryLighthouse_LoseLights(void)
Touch trigger 31: the leader loses their lights, and the column swells and fades away.
static s32 OverlayObject_AdvanceScaleCounter(struct ScriptInterpreter *interpreter)
Expands the released light before its script removes it.
void MercuryLighthouse_SparkleAtLeader(void)
Touch trigger 21: while the leader stands there, a sparkle rises from them every 10 to 39 frames.
void MercuryLighthouse_ChargeLights(void)
Touch trigger 11, the pool's heart: the column of light appears over the leader if it is not there,...
static s32 SceneEffect_AdvanceAnchoredRiseFrame(struct ScriptInterpreter *interpreter)
Raises the spark while its scale follows a half-sine pulse.
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 options of a spawned field effect, each used when its EFFECT_USE_ flag (or EFFECT_SCALE_TO_TARGET...
s16 type
the object type to create; 222 without the flag
s32 palette
passed to ObjectGroup_SetChildValue
s32 priority
the sprite's priority
const s32 * script
the object script, run in mode 1
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 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 retreatEntrance
where Retreat goes; the group's first entrance
Definition game_state.h:109
s16 retreatScene
where Retreat goes; the group's first entrance
Definition game_state.h:108
s16 entrance
Definition game_state.h:37
Published in the scene's light-controller slot while the pillar is active.
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
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
void UiText_ShowCenteredMessage(s32 message, s32 mode, s32 yOffset)
Shows a message centred on the screen (yOffset tiles lower) and waits until it is typed out,...
Definition messages.c:325