Alchemy
Loading...
Searching...
No Matches

tolbi_ship_mast.c

Go to the documentation of this file.
1/// @file
2/// The mast of the ship across the Karagol Sea, where the lookout announces the
3/// course, the approaching monsters and land, and an Anchor Charm can be found.
4
5#include "script.h"
6#include "game_state.h"
7#include "scene_ids.h"
8#include "unit/import.h"
10#include "unit/object/object.h"
11#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 "global_cells.h"
23#include "item_ids.h"
24#include "flags.h"
25#include "songs.h"
26#include "types.h"
27#include "field_event.h"
28#include "field_service.h"
29#include "text/msg_ids.h"
30#include "ability_ids.h"
31#include "field_scene.h"
32#include "objcmd.h"
33#include "fixed_math.h"
34#include "map_scroll.h"
35#include "heap_state.h"
36#include "macros.h"
37
38// Scene sequences and the mast's per-frame updates.
41static void TolbiShipMast_AnnounceClearCourse(void);
42static void TolbiShipMast_RunAvastScene(void);
43static void TolbiShipMast_ShowMonsters(void);
45static void TolbiShipMast_RunLandingSequence(void);
46static void TolbiShipMast_AnnounceLand(void);
47static void TolbiShipMast_UpdateSway(void);
50
51s32 gTolbiShipMast_DriftY __attribute__((section(".bss")));
52s32 gTolbiShipMast_DriftX __attribute__((section(".bss")));
53s32 gTolbiShipMast_SwayY __attribute__((section(".bss")));
54s32 gTolbiShipMast_SwayUnused __attribute__((section(".bss")));
55s32 gTolbiShipMast_CameraCenter[2] __attribute__((section(".bss")));
56s32 gTolbiShipMast_CameraOrigin[2] __attribute__((section(".bss")));
57s32 gTolbiShipMast_SwayX __attribute__((section(".bss")));
58
59/// Keeps the effect actor relative to the saved camera origin and rotates it.
60static s32
62 struct FieldActor *object = (struct FieldActor *)interpreter;
63 s32 *position = ((struct MapScrollWork *)gMapWork[0])->origin;
66 s32 cameraX = *position++;
67 s32 cameraY = *position;
68
69 object->x.fixed = center[0] + (cameraX - origin[0]);
70 object->y.fixed = center[1] + (cameraY - origin[1]) / 2;
71 object->sprite->rotation += 0x600;
72 return 0;
73}
74
75/// A random sample of 6 or 9 turns the lookout to either side of north.
76static s32
78 struct FieldActor *object = (struct FieldActor *)interpreter;
79 u32 sample = (u32)(Engine_RandomNext() << 6) >> 16;
80
81 if (sample == 6) {
83
84 object->facing = value;
85 } else if (sample == 9) {
87
88 object->facing = value;
89 }
90
91 return 1;
92}
93
94/// Grows both axes by the same amount until the actor reaches full scale.
95static void TolbiShipMast_GrowActorScale(union FieldObject *fieldObject) {
96 struct FieldActor *actor = (struct FieldActor *)fieldObject;
97 if (actor->scaleX < Q16_ONE) {
98 actor->scaleX += 160;
99 actor->scaleY += 160;
100 }
101}
102
103/// Randomly reverses horizontal drift and vertical bobbing at their limits.
104static s32 TolbiShipMast_SwayActor(struct ScriptInterpreter *interpreter) {
105 struct FieldActor *actor = (struct FieldActor *)interpreter;
106 s16 *state = &actor->timer;
107 s32 next;
108
109 // State 9 zeros drift or vertical position; 0 and 1 alternate direction.
110 if (*state == 9) {
111 actor->riseBaseY = 0;
112 } else if (*state != 0) {
113 actor->riseBaseY -= (u32)(Engine_RandomNext() << 11) >> 16;
114 if (actor->riseBaseY < -3 * PIXELS(1) / 4) {
115 next = 0;
116 *state = next;
117 }
118 } else {
119 actor->riseBaseY += (u32)(Engine_RandomNext() << 11) >> 16;
120 if (actor->riseBaseY > 3 * PIXELS(1) / 4) {
121 next = 1;
122 *state = next;
123 }
124 }
125 if (actor->x.fixed > PIXELS(40) && actor->x.fixed < PIXELS(320)) {
126 actor->x.fixed += actor->riseBaseY;
127 }
128 state = (s16 *)&actor->work;
129 if (*state == 9) {
130 actor->y.fixed = 0;
131 } else if (*state != 0) {
132 actor->y.fixed -= ((u32)Engine_RandomNext() * 3 << 14) >> 16;
133 if (actor->y.fixed < 0) {
134 next = 0;
135 *state = next;
136 }
137 } else {
138 actor->y.fixed += ((u32)Engine_RandomNext() * 3 << 14) >> 16;
139 if (actor->y.fixed > PIXELS(16)) {
140 next = 1;
141 *state = next;
142 }
143 }
144 return 1;
145}
146
147/// Shrinks both axes; once small enough, clears the actor's position and speed.
148static s32
150 struct FieldActor *actor = (struct FieldActor *)interpreter;
151 struct AnimationObject *sprite = actor->sprite;
152
153 sprite->image.priority = 3;
154 actor->speed = PIXELS(2);
155 actor->acceleration = PIXELS(1);
156 if (actor->scaleX > Q16_ONE / 16) {
157 actor->scaleX -= Q16_ONE / 64;
158 actor->scaleY -= Q16_ONE / 64;
159 } else {
160 actor->x.fixed = 0;
161 actor->y.fixed = 0;
162 actor->z.fixed = 0;
163 SET_VELOCITY(actor, 0, 0, 0);
164 }
165 return 1;
166}
167
168/// Returns the entrances from the ship's deck and scripted sequences.
171}
172
173/// Returns the ladder's three-dimensional activation region.
176}
177
178/// Returns exits to the deck and the continuing ship scenes.
180
181/// Returns the lookout's initial placement table.
184}
185
186/// Returns the ladder, lookout dialogue and Anchor Charm search events.
189}
190
191/// Touching the ladder starts the descent.
193
194/// Gives the Anchor Charm once either discovery flag permits the search.
203 }
204}
205
206/// Starts the ship sway when allowed, then runs this entrance's mast sequence.
208 struct FieldActor *leader;
209
219 }
222 Actor_SetPosition(8, PIXELS(164), PIXELS(328));
223 }
224 // The ship's scripted entrances resume their matching lookout scenes.
225 switch (gGameState.entrance) {
226 case 1:
231 leader->y.fixed = PIXELS(56);
232 Camera_MoveTo(-1, -1, -1, 0);
238 }
239 break;
240 case 10:
243 } else {
245 }
246 break;
247 case 11:
251 break;
252 case 12:
256 break;
257 case 13:
261 break;
262 case 14:
264 break;
265 }
266 return 0;
267}
268
269/// Frames the lookout with the leader moved out of view, then announces course.
272 Camera_MoveTo(-1, -1, -1, 0);
275 Camera_MoveTo(PIXELS(164), PIXELS(64), PIXELS(321), 0);
281}
282
283/// Keeps the leader visible for the course announcement.
285 struct FieldActor *leader;
286
297}
298
299/// The lookout scans both sides, announces a clear course and leaves by
300/// exit 10.
306 Actor_SetSpeed(8, PIXELS(1), PIXELS(1) / 2);
307 Actor_WalkToAndWait(8, 164, 321);
312 Actor_WalkToAndWait(8, 164, 334);
313 Engine_ActorJump(8, 4, 40);
315 Engine_EventSetMessage(MsgTolbiShipShipsCourseClear);
316 Event_ShowMessageAndWait(8, 0, 20);
320}
321
322/// Stages four approaching actors and the lookout's reaction. "Avast!"
324 s32 *placement = ((struct MapScrollWork *)gMapWork[0])->origin;
325 struct FieldActor *actor;
326 struct EventWork **event;
327 s32 x;
328 s32 zero = 0;
329 s32 scale;
330 void (*update)(union FieldObject *);
331
338 event = (struct EventWork **)(gMapWork + (HEAP_SLOT_EVENT - HEAP_SLOT_MAP));
339 (*event)->startTransition = SCENE_TRANSITION(TRANSITION_WINDOW, 3);
342 // Save the camera origin before the rotating approach effect begins.
344 gTolbiShipMast_CameraOrigin[0] = *placement++;
345 gTolbiShipMast_CameraOrigin[1] = *placement;
346 Actor_SetPosition(9, PIXELS(80), PIXELS(210));
347 x = PIXELS(80);
348 Object_GetById(9)->motionFlags = zero;
359 Engine_EventSetMessage(MsgTolbiShipAvast);
361 // Three trailing actors grow from half scale while converging on the mast.
362 Actor_SetPosition(10, x, PIXELS(210));
363 Actor_SetPosition(11, x, PIXELS(210));
364 Engine_ActorSetPosition(12, x, PIXELS(210));
371 // Grow the three trailing actors as they approach the lookout.
372 actor = Object_GetById(10);
373 scale = Q16_ONE / 2;
375 actor->scaleY = scale;
376 actor->scaleX = scale;
377 actor->update = update;
378 actor = Object_GetById(11);
379 actor->scaleY = scale;
380 actor->scaleX = scale;
381 actor->update = update;
382 actor = Object_GetById(12);
383 actor->scaleY = scale;
384 actor->scaleX = scale;
385 actor->update = update;
387 Actor_SetSpeed(10, 13 * PIXELS(1) / 25, 13 * PIXELS(1) / 50);
388 Actor_SetSpeed(11, 9 * PIXELS(1) / 20, 9 * PIXELS(1) / 40);
389 Actor_SetSpeed(12, 3 * PIXELS(1) / 5, 3 * PIXELS(1) / 10);
390 Actor_SetDestination(10, 128, 345);
391 Actor_SetDestination(11, 136, 330);
392 Engine_ActorSetDestination(12, 156, 340);
395 Actor_WalkToAndWait(8, 164, 344);
396 Engine_ActorJump(8, 4, 10);
397 Engine_ActorJump(8, 6, 40);
400 (*event)->startTransition = SCENE_TRANSITION(TRANSITION_WINDOW, 2);
405}
406
407/// Clears the movement left by a drifting script before its staged approach.
408static inline void TolbiShipMast_StopDriftingActor(struct FieldActor *actor) {
409 actor->targetX = ACTOR_NO_TARGET;
410 actor->targetY = ACTOR_NO_TARGET;
411 actor->targetZ = ACTOR_NO_TARGET;
412 SET_VELOCITY(actor, 0, 0, 0);
413 actor->riseBaseY = 0;
414}
415
416/// Gives each of the seven approaching actors its own random drift and bob.
425}
426
427/// Stops the drifting actions and gives the group its departure walking speed.
428static inline void TolbiShipMast_PrepareGroupDeparture(void) {
436 Actor_SetSpeed(9, PIXELS(3), 3 * PIXELS(1) / 2);
437 Actor_SetSpeed(10, PIXELS(3), 3 * PIXELS(1) / 2);
438 Actor_SetSpeed(11, PIXELS(3), 3 * PIXELS(1) / 2);
439 Actor_SetSpeed(12, PIXELS(3), 3 * PIXELS(1) / 2);
440 Actor_SetSpeed(13, PIXELS(3), 3 * PIXELS(1) / 2);
441 Actor_SetSpeed(14, PIXELS(3), 3 * PIXELS(1) / 2);
442 Actor_SetSpeed(15, PIXELS(3), 3 * PIXELS(1) / 2);
443}
444
445/// Repeats actor 9's approach before the lookout reports monsters.
446static void TolbiShipMast_ShowMonsters(void) {
447 struct FieldActor *approachingActor;
448 struct FieldActor *leader;
449
452 leader = Object_GetById(0);
462 Engine_EventWait(120);
463 // Repeat the foreground approach while the rest of the group keeps drifting.
464 approachingActor = Object_GetById(9);
466 TolbiShipMast_StopDriftingActor(approachingActor);
468 Actor_SetSpeed(9, PIXELS(8), PIXELS(4));
469 FieldObject_SetPosition(approachingActor, PIXELS(164), PIXELS(144),
470 PIXELS(321));
471 FieldObject_WaitForMove(approachingActor);
472 FieldObject_SetPosition(approachingActor, PIXELS(164), PIXELS(104),
473 PIXELS(321));
474 FieldObject_WaitForMove(approachingActor);
475 FieldObject_SetPosition(approachingActor, PIXELS(204), PIXELS(124),
476 PIXELS(321));
477 FieldObject_WaitForMove(approachingActor);
478 FieldObject_SetPosition(approachingActor, PIXELS(144), 0, PIXELS(169));
483 Actor_SetSpeed(9, PIXELS(2), PIXELS(1));
487 Engine_EventWait(120);
489 TolbiShipMast_StopDriftingActor(approachingActor);
491 Actor_SetSpeed(9, PIXELS(8), PIXELS(4));
492 FieldObject_SetPosition(approachingActor, PIXELS(164), PIXELS(144),
493 PIXELS(321));
494 FieldObject_WaitForMove(approachingActor);
495 Actor_SetSpeed(9, PIXELS(5), 5 * PIXELS(1) / 2);
496 FieldObject_SetPosition(approachingActor, PIXELS(164), PIXELS(104),
497 PIXELS(321));
498 FieldObject_WaitForMove(approachingActor);
499 FieldObject_SetPosition(approachingActor, PIXELS(164), PIXELS(114),
500 PIXELS(321));
501 FieldObject_WaitForMove(approachingActor);
502 FieldObject_SetPosition(approachingActor, PIXELS(164), PIXELS(104),
503 PIXELS(321));
504 FieldObject_WaitForMove(approachingActor);
505 FieldObject_SetPosition(approachingActor, PIXELS(204), PIXELS(124),
506 PIXELS(321));
507 FieldObject_WaitForMove(approachingActor);
508 Engine_ObjectSetPosition(approachingActor, PIXELS(144), 0, PIXELS(169));
513 Actor_SetSpeed(9, PIXELS(2), PIXELS(1));
515 // The lookout recognizes the approaching group and reports monsters.
516 Engine_ActorJump(8, 4, 20);
517 Engine_ActorJump(8, 6, 40);
520 Engine_EventSetMessage(MsgTolbiShipMonsters2);
521 Event_ShowMessageAndWait(16, 0, 20);
523 Actor_WalkToAndWait(8, 164, 344);
530}
531
532/// Initializes a drifting actor, retaining the random draws' original order.
534 struct FieldActor *actor;
535 u32 randomValue;
536
537 actor = Object_GetById(actorId);
539 actor->motionFlags = 0;
540 actor->timer = (u32)Engine_RandomNext() >> 15;
541 actor->work = (u32)Engine_RandomNext() >> 15;
542 randomValue = Engine_RandomNext();
543 randomValue <<= 2;
544 randomValue >>= 16;
545 randomValue <<= 16;
546 randomValue += PIXELS(6);
547 actor->y.fixed = randomValue;
548 randomValue = Engine_RandomNext();
549 actor->riseBaseY = ((randomValue * 3 << 13) >> 16) - 3 * PIXELS(1) / 16;
550 actor->scaleX = 5 * Q16_ONE / 4;
551 actor->scaleY = 5 * Q16_ONE / 4;
553}
554
555/// Moves the drifting group aside, then stages the two landing actors.
557 u32 frame;
558 struct FieldActor *actor;
559
573 Engine_EventWait(300);
575 Engine_EventWait(100);
576 // Clear the approaching group from the foreground before the landing reveal.
578 Actor_SetDestination(9, 0, 100);
579 Actor_SetDestination(10, 60, 100);
580 Actor_SetDestination(11, 120, 100);
581 Actor_SetDestination(12, 180, 100);
582 Actor_SetDestination(13, 240, 100);
583 Actor_SetDestination(14, 320, 100);
584 Actor_SetDestination(15, 380, 100);
588 Actor_SetPosition(9, 0, 0);
589 Actor_SetPosition(10, 0, 0);
590 Actor_SetPosition(11, 0, 0);
591 Actor_SetPosition(12, 0, 0);
592 Actor_SetPosition(13, 0, 0);
593 Actor_SetPosition(14, 0, 0);
594 Actor_SetPosition(15, 0, 0);
595 Engine_EventWait(100);
596 // Grow the first landing actor into view, then drop the second beside it.
597 actor = Object_GetById(18);
598 actor->scaleX = Q16_ONE / 10;
599 actor->scaleY = Q16_ONE / 10;
600 Actor_SetPosition(18, PIXELS(172), PIXELS(340));
607 // Grow actor 18 over 32 frames before staging actor 17 beside it.
608 for (frame = 0; frame < 32; frame++) {
609 actor->scaleX += Q16_ONE / 20;
610 actor->scaleY += Q16_ONE / 20;
612 }
615 Actor_WalkToAndWait(8, 168, 340);
616 Actor_WalkToAndWait(8, 200, 340);
618 actor = Object_GetById(17);
619 actor->scaleX = 23 * Q16_ONE / 20;
620 actor->scaleY = 23 * Q16_ONE / 20;
621 actor->x.fixed = PIXELS(172);
622 actor->y.fixed = PIXELS(160);
623 actor->z.fixed = PIXELS(340);
624 actor->facing = 0;
625 actor->bounce = 2 * Q16_ONE / 5;
626 actor->gravity = PIXELS(3);
628 Engine_ActorJump(8, 6, 20);
633 // Let the landing actor bounce, then move both actors out of the shot.
635 Actor_SetSpeed(17, PIXELS(1), PIXELS(1) / 2);
636 actor->bounce = Q16_ONE / 10;
637 actor->gravity = 7 * PIXELS(1) / 10;
639 actor->velocityY = PIXELS(8);
640 Actor_SetDestination(17, 132, 360);
641 Actor_SetDestination(18, 132, 360);
643 Actor_SetPosition(17, 0, 0);
644 actor = Object_GetById(8);
645 actor->scaleX = Q16_ONE;
646 actor->scaleY = Q16_ONE;
654}
655
656/// Walks the seven actors away, then the lookout announces land.
657static void TolbiShipMast_AnnounceLand(void) {
668 Engine_EventWait(400);
669 // Each actor takes its own departure path while shrinking out of view.
681 Engine_EventWait(120);
684 Actor_SetSpeed(8, PIXELS(1), PIXELS(1) / 2);
685 Actor_WalkToAndWait(8, 164, 344);
686 Engine_ActorJump(8, 4, 10);
687 Engine_ActorJump(8, 6, 20);
688 Engine_EventSetMessage(MsgTolbiShipLandHo);
689 Event_ShowMessageAndWait(8, 0, 20);
693 // How evenly the passengers row picks the next scene: a balance of 11 takes
694 // exit 15.
697 if (TolbiShipMast_GetRowingBalance() == 11) {
699 } else {
701 }
703}
704
705/// Adds horizontal and vertical sway to the camera origin each frame.
706static void TolbiShipMast_UpdateSway(void) {
707 s32 *position = ((struct MapScrollWork *)gMapWork[0])->origin;
710
711 *position++ += swayX;
712 swayY *= 4;
713 *position += swayY;
714 gTolbiShipMast_DriftX += swayX;
715 gTolbiShipMast_DriftY += swayY;
716 gTolbiShipMast_SwayX += (u32)(Engine_RandomNext() * 3 << 7) >> 16;
717 gTolbiShipMast_SwayY += (u32)(Engine_RandomNext() << 9) >> 16;
718 gTolbiShipMast_SwayX &= 0xffff;
719 gTolbiShipMast_SwayY &= 0xffff;
720}
721
722/// How evenly the chosen passengers row: the values of those at the west seats
723/// (the first and third filled) less those at the east seats.
725 s32 westSeats;
726 s32 eastSeats;
727
728 westSeats = TolbiShipMast_GetSeatRowValue(0);
729 westSeats += TolbiShipMast_GetSeatRowValue(2);
730 eastSeats = TolbiShipMast_GetSeatRowValue(1);
731 eastSeats += TolbiShipMast_GetSeatRowValue(3);
732 return westSeats - eastSeats;
733}
734
735/// The rowing value of the passenger chosen for a seat, or 0 while it is empty.
737 s32 firstFlag = 0;
738 u32 passenger;
739
740 switch (seat) {
741 case 0:
743 break;
744 case 1:
746 break;
747 case 2:
749 break;
750 case 3:
752 break;
753 }
754 for (passenger = 0; passenger <= 8; passenger++) {
755 if (Engine_GameFlagIsSet(firstFlag + passenger) != 0)
756 return gTolbiShipMast_PassengerRowValues[passenger];
757 }
758 return 0;
759}
760
765 SC_WAIT(1),
766 SC_LOOP(10, SC_TOP),
767 SC_LABEL(1),
768 SC_ADD(SW_SCALE_X, -Q16_ONE / 32),
769 SC_ADD(SW_SCALE_Y, -Q16_ONE / 32),
771 SC_WAIT(1),
772 SC_LOOP(24, SC_TO(1)),
773 SC_POS(0, 0, 0),
774 SC_WAIT(1),
775 SC_END,
776};
777
780};
781
784};
785
789 SC_ADD(SW_SCALE_X, -5 * Q16_ONE / 16),
791 SC_WAIT(1),
792 SC_ADD(SW_SCALE_X, 5 * Q16_ONE / 32),
793 SC_ADD(SW_SCALE_Y, -Q16_ONE / 32),
794 SC_WAIT(1),
795 SC_ADD(SW_SCALE_X, 5 * Q16_ONE / 64),
796 SC_ADD(SW_SCALE_Y, -Q16_ONE / 64),
797 SC_WAIT(1),
798 SC_ADD(SW_SCALE_X, 5 * Q16_ONE / 64),
799 SC_ADD(SW_SCALE_Y, -Q16_ONE / 64),
800 SC_WAIT(1),
802};
803
805 SC_MOVE(PIXELS(72), 0, PIXELS(216)),
806 SC_SYNC,
807 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
809 SC_END,
810};
811
813 SC_MOVE(PIXELS(132), 0, PIXELS(242)),
814 SC_SYNC,
815 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
817 SC_END,
818};
819
821 SC_MOVE(PIXELS(88), 0, PIXELS(166)),
822 SC_SYNC,
823 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
825 SC_END,
826};
827
829 SC_MOVE(PIXELS(220), 0, PIXELS(134)),
830 SC_SYNC,
831 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
833 SC_END,
834};
835
837 SC_MOVE(PIXELS(264), 0, PIXELS(228)),
838 SC_SYNC,
839 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
841 SC_END,
842};
843
845 SC_MOVE(PIXELS(282), 0, PIXELS(168)),
846 SC_SYNC,
847 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
849 SC_END,
850};
851
852// clang-format off
854 SC_MOVE(PIXELS(154), 0, PIXELS(135)),
855 SC_SYNC,
856 SC_MOVE(PIXELS(152), 0, PIXELS(196)),
858 SC_END,
859 // Unidentified words following the script terminator.
860 0x9090000, 0xd70090d, 0xdb315cb, 0x15f5164c,
861 0x1f0e1aad, 0x1f6f227a, 0x23f223b1, 0x2bf727f4,
862};
863
865 { 0, CONDITION_ALWAYS, 165, 0, 235, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
866 { 1, CONDITION_ALWAYS, 184, 56, 352, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
867 { 10, CONDITION_ALWAYS, 164, 96, 321, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
868 { 11, CONDITION_ALWAYS, 164, 96, 321, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
869 { 12, CONDITION_ALWAYS, 164, 96, 321, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
870 { 13, CONDITION_ALWAYS, 164, 96, 321, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
871 { 14, CONDITION_ALWAYS, 164, 96, 321, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
872 { SCENE_TABLE_END },
873};
874
876 {176, 16, 348, 192, 32, 364, -1, 1},
877 {-1, 0, 0, 0, 0, 0, 0, 0},
878};
879
881 SCENE_EXITS(110),
882 SCENE_EXIT(1, 109, 4),
883 SCENE_EXIT(10, 111, 10),
884 SCENE_EXIT(11, 111, 13),
885 SCENE_EXIT(12, 109, 13),
886 SCENE_EXIT(13, 109, 14),
887 SCENE_EXIT(14, 109, 17),
888 SCENE_EXIT(15, 109, 19),
890};
891
895 { SCENE_TABLE_END },
896};
897
899 { 0x11e, CONDITION_ALWAYS, 7,
900 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
901 { 0xbd, CONDITION_ALWAYS, 7,
902 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
903 { 0xbd, CONDITION_ALWAYS, 7,
905 { 0xbd, CONDITION_ALWAYS, 7,
907 { SCENE_TABLE_END },
908};
909
911 { 0x9b, CONDITION_ALWAYS, 7,
912 PIXELS(144), 0, PIXELS(169), FACING_SOUTH, TALK_KEEP_FACING, 0 },
913 { 0x9b, CONDITION_ALWAYS, 7,
914 PIXELS(134), 0, PIXELS(189), FACING_SOUTH, TALK_KEEP_FACING, 0 },
915 { 0x9b, CONDITION_ALWAYS, 7,
916 PIXELS(124), 0, PIXELS(209), FACING_SOUTH, TALK_KEEP_FACING, 0 },
917 { 0x9b, CONDITION_ALWAYS, 7,
918 PIXELS(129), 0, PIXELS(174), FACING_SOUTH, TALK_KEEP_FACING, 0 },
919 { 0x9b, CONDITION_ALWAYS, 7,
920 PIXELS(139), 0, PIXELS(184), FACING_SOUTH, TALK_KEEP_FACING, 0 },
921 { 0x9b, CONDITION_ALWAYS, 7,
922 PIXELS(149), 0, PIXELS(204), FACING_SOUTH, TALK_KEEP_FACING, 0 },
923 { 0x9b, CONDITION_ALWAYS, 7,
924 PIXELS(154), 0, PIXELS(194), FACING_SOUTH, TALK_KEEP_FACING, 0 },
926 PIXELS(182), 0, PIXELS(420), FACING_SOUTH, TALK_KEEP_FACING, 0 },
927 { SCENE_TABLE_END },
928};
929
931 { 0xc5, CONDITION_ALWAYS, 7,
932 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
934 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
935 { SCENE_TABLE_END },
936};
937
940 { EVENT_TALK, 8, FLAG_TOLBI_SHIP_FIRST_ATTACK_REPELLED, MSGNO(MsgTolbiShipWatchSeasHelpKaja) },
941 { EVENT_TALK, 8, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipLookoutCannotRow) },
942 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipIslandMonstersUnknown) },
943 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_FIRST_ATTACK_REPELLED, MSGNO(MsgTolbiShipHiddenAnchorDiscovered) },
944 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipSeaTooVast) },
945 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipIslandTreasures) },
948};
949
950/// Each passenger's rowing value, in the order of their actors in the hold
951/// from 8.
953 7, 5, 8, 4, 9, 12, 6, 3,
954 0,
955};
956// clang-format on
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
struct FieldActor * Camera_GetEventObject(void)
The event command "get view centre": returns the camera object.
Definition camera.c:133
s32 Field_ClimbUp(void)
Climbing up (the player presses up at a climbable wall).
Definition climbing.c:196
s32 Field_ClimbDown(void)
Climbing down (the player presses down at a climbable wall).
Definition climbing.c:119
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
The engine calls the debug menus import, and their palette swatch tiles.
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
void Engine_ObjectSetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
s32 Engine_PartyGiveItem(s32 item, s32 flags)
void Engine_EventShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
s32 Engine_MathSin(s32 angle)
void Engine_ItemShowFound(s32 item, s32 height)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_EventCloseScreen(void)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
static void Actor_SetActionScript(s32 actor, const s32 *script)
The engine encodes either a built-in action or an action-script address.
void Engine_CameraFollowActor(s32 actor, s32 keep_position)
void Engine_ActorStop(s32 actor)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
void Engine_ActorSetChildValue(s32 actor, s32 value)
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
s32 Engine_MathCos(s32 angle)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_MapRedraw(void)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
@ TRANSITION_WINDOW
Definition field_obj.h:17
#define ACTOR_NO_TARGET
A target coordinate that is not set: the object has no target.
Definition field_obj.h:145
#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
@ 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
#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_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_UNNAMED
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static void FieldObject_SetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
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_TOLBI_SHIP_REACHED_TOLBI
The ship reached Tolbi. "The ship has arrived safely".
Definition flags.h:425
#define FLAG_TOLBI_SHIP_CREWMAN_CONFRONTED
Definition flags.h:120
#define FLAG_TOLBI_SHIP_ROWING
the oars are moving
Definition flags.h:411
#define FLAG_TOLBI_SHIP_FOURTH_SEAT_ROWERS
Definition flags.h:423
#define FLAG_TOLBI_SHIP_ANCHOR_CHARM_FOUND
Definition flags.h:121
#define FLAG_TOLBI_SHIP_SECOND_SEAT_ROWERS
Definition flags.h:421
#define FLAG_TOLBI_SHIP_FIRST_SEAT_ROWERS
The passengers chosen to row: a group of nine flags for each empty seat, one flag for each passenger,...
Definition flags.h:420
#define FLAG_TOLBI_SHIP_FIRST_ATTACK_REPELLED
The monster attacks fought off.
Definition flags.h:414
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_TOLBI_SHIP_AT_ISLAND
at anchor off the island
Definition flags.h:396
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED
The party gave back the captain's Anchor Charm and agreed to protect the ship.
Definition flags.h:407
#define FLAG_TOLBI_SHIP_WARRIORS_SEEK_CAPTAIN
Definition flags.h:119
#define FLAG_TOLBI_SHIP_MONSTERS_SIGHTED
The ship's place plays music 29, the monsters' theme, instead of 41.
Definition flags.h:398
#define FLAG_TOLBI_SHIP_THIRD_SEAT_ROWERS
Definition flags.h:422
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.
void * gMapWork[]
The screen blend's globals and the graphics routines.
The heap's work slots and HeapState.
@ HEAP_SLOT_MAP
Definition heap_state.h:36
@ HEAP_SLOT_EVENT
Definition heap_state.h:40
The main-image routines scene overlays import.
Item numbers, named from the English release.
@ ITEM_ANCHOR_CHARM
Definition item_ids.h:73
Small statement macros both games use for positions, velocities and bounds.
#define SET_VELOCITY(p, vx, vy, vz)
Definition macros.h:18
The map layers' scroll work and the background scroll values.
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_LABEL(n)
Branch destination.
Definition objcmd.h:11
#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_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_FOREVER
Definition objcmd.h:14
#define SC_TO(n)
Definition objcmd.h:12
#define SC_ADD(w, v)
Definition objcmd.h:38
#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_SCALE_Y
Definition objcmd.h:63
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void Event_CallWithLastActiveObjectId(struct ScenePlacement *table)
Spawns the actors of a placement table after the last actor in use.
Definition events.c:148
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
Scene numbers, named after their places.
char SceneId_TolbiShipInteriors
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define MUS_029
Definition songs.h:39
#define SE_147
Definition songs.h:140
#define SE_HIGH_JUMP
Definition songs.h:148
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_TaskWait()
void Engine_EventSetMessage()
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
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
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
s16 timer
The parameter its action script reads (a follow distance or an angle to face), the player's frames to...
Definition field_obj.h:109
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
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
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
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
s32 targetY
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:60
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition field_obj.h:40
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
s32 riseBaseY
Zeroed by FieldObject_Create and not read by the engine; scene code keeps a resting height,...
Definition field_obj.h:71
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
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
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
s32 * origin
The followed point, read as x, height and z in 16.16 fixed-point pixels; Camera_FollowActor points it...
Definition map_scroll.h:30
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.
s32 gTolbiShipMast_SwayX
struct SceneEntrance gTolbiShipMast_Entrances[]
const struct SceneRegion * TolbiShipMast_GetRegions(void)
Returns the ladder's three-dimensional activation region.
struct ScenePlacement gTolbiShipMast_Placements[]
struct ScenePlacement gTolbiShipMast_StagingObjects[]
static void TolbiShipMast_ClimbDownLadder(void)
Touching the ladder starts the descent.
s32 gTolbiShipMast_SwayUnused
const u32 * TolbiShipMast_GetExits(void)
Returns exits to the deck and the continuing ship scenes.
const struct ScenePlacement * TolbiShipMast_GetPlacements(void)
Returns the lookout's initial placement table.
s32 gTolbiShipMast_LookoutActions[]
static void TolbiShipMast_InitializeDriftingGroup(void)
Gives each of the seven approaching actors its own random drift and bob.
static void TolbiShipMast_GrowActorScale(union FieldObject *fieldObject)
Grows both axes by the same amount until the actor reaches full scale.
s32 gTolbiShipMast_DriftY
s32 TolbiShipMast_Initialize(void)
Starts the ship sway when allowed, then runs this entrance's mast sequence.
s32 gTolbiShipMast_FollowCameraActions[]
u32 gTolbiShipMast_Exits[]
s32 gTolbiShipMast_EnsembleWalk11[]
static void TolbiShipMast_SetupHiddenLeaderLookout(void)
Frames the lookout with the leader moved out of view, then announces course.
s32 gTolbiShipMast_EnsembleWalk10[]
static void TolbiShipMast_PrepareGroupDeparture(void)
Stops the drifting actions and gives the group its departure walking speed.
u32 gTolbiShipMast_PassengerRowValues[]
Each passenger's rowing value, in the order of their actors in the hold from 8.
struct SceneEvent gTolbiShipMast_Events[]
static s32 TolbiShipMast_FollowCameraAndRotate(struct ScriptInterpreter *interpreter)
Keeps the effect actor relative to the saved camera origin and rotates it.
s32 gTolbiShipMast_CameraOrigin[2]
s32 gTolbiShipMast_WaveActions[]
struct ScenePlacement gTolbiShipMast_EnsembleObjects[]
static void TolbiShipMast_AnnounceClearCourse(void)
The lookout scans both sides, announces a clear course and leaves by exit 10.
const struct SceneEntrance * TolbiShipMast_GetEntrances(void)
Returns the entrances from the ship's deck and scripted sequences.
s32 gTolbiShipMast_DriftX
static void TolbiShipMast_FindAnchorCharm(void)
Gives the Anchor Charm once either discovery flag permits the search.
struct ScenePlacement gTolbiShipMast_LandingObjects[]
s32 gTolbiShipMast_EnsembleWalk12[]
static s32 TolbiShipMast_ShrinkAndStopActor(struct ScriptInterpreter *interpreter)
Shrinks both axes; once small enough, clears the actor's position and speed.
static void TolbiShipMast_ShowMonsters(void)
Repeats actor 9's approach before the lookout reports monsters.
s32 gTolbiShipMast_EnsembleWalk14[]
s32 gTolbiShipMast_EnsembleWalk9[]
static s32 TolbiShipMast_GetSeatRowValue(u32 seat)
The rowing value of the passenger chosen for a seat, or 0 while it is empty.
static s32 TolbiShipMast_RandomizeLookoutFacing(struct ScriptInterpreter *interpreter)
A random sample of 6 or 9 turns the lookout to either side of north.
s32 gTolbiShipMast_DriftActions[]
const struct SceneEvent * TolbiShipMast_GetEvents(void)
Returns the ladder, lookout dialogue and Anchor Charm search events.
static void TolbiShipMast_RunLandingSequence(void)
Moves the drifting group aside, then stages the two landing actors.
static void TolbiShipMast_SetupVisibleLeaderLookout(void)
Keeps the leader visible for the course announcement.
s32 gTolbiShipMast_SwayY
static s32 TolbiShipMast_GetRowingBalance(void)
How evenly the chosen passengers row: the values of those at the west seats (the first and third fill...
struct SceneRegion gTolbiShipMast_Regions[]
s32 gTolbiShipMast_EnsembleWalk13[]
static void TolbiShipMast_UpdateSway(void)
Adds horizontal and vertical sway to the camera origin each frame.
static s32 TolbiShipMast_SwayActor(struct ScriptInterpreter *interpreter)
Randomly reverses horizontal drift and vertical bobbing at their limits.
u32 gTolbiShipMast_EnsembleWalk15[]
static void TolbiShipMast_InitializeDriftingActor(s32 actorId)
Initializes a drifting actor, retaining the random draws' original order.
static void TolbiShipMast_AnnounceLand(void)
Walks the seven actors away, then the lookout announces land.
s32 gTolbiShipMast_CameraCenter[2]
static void TolbiShipMast_StopDriftingActor(struct FieldActor *actor)
Clears the movement left by a drifting script before its staged approach.
static void TolbiShipMast_RunAvastScene(void)
Stages four approaching actors and the lookout's reaction. "Avast!".
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
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.