Alchemy
Loading...
Searching...
No Matches

tolbi_ship_interiors.c

Go to the documentation of this file.
1/// @file
2/// Below the decks of the ship across the Karagol Sea: the captain's cabin, the
3/// passengers' hold and the rowing deck. After each monster attack the party
4/// chooses which passenger rows at the empty seat; the attacks fought off
5/// number the seat being filled, and each seat has a group of flags, one for
6/// each passenger.
7
8#include "script.h"
9#include "flags.h"
10#include "songs.h"
11#include "macros.h"
12#include "game_state.h"
13#include "unit/import.h"
15#include "unit/object/object.h"
17#include "unit/game/game.h"
18#include "unit/window/window.h"
20#include "types.h"
21#include "field_event.h"
22#include "field_scene.h"
23#include "battle.h"
24#include "debug.h"
25#include "field.h"
26#include "game.h"
27#include "graphics.h"
28#include "menu.h"
29#include "minigame.h"
30#include "sound.h"
31#include "system.h"
32#include "field_service.h"
33#include "text/msg_ids.h"
34#include "callback_scheduler.h"
35#include "scene_ids.h"
36#include "inventory.h"
37#include "ability_ids.h"
38#include "item_ids.h"
39#include "objcmd.h"
40#include "fixed_math.h"
41#include "field_runtime.h"
42
43// Place flags: Scene_ResetFlagsOnEnter clears 0x300 to 0x3ff when the party
44// enters another place group, and other places use the numbers for their own.
45#define FLAG_TOLBI_SHIP_ROWER_CHOSEN 0x300 ///< a passenger follows the party
46#define FLAG_TOLBI_SHIP_MONSTERS_ABOARD 0x301 ///< the hold's stairs are barred
47/// The Kraken is aboard: the deck shakes until it is defeated
48/// (tolbi_ship_deck.c reads it too). "There's a huge sea monster on the ship!"
49#define FLAG_TOLBI_SHIP_KRAKEN_ABOARD 0x302
50
51/// Operations shared by the cabin, passenger hold and rowing-deck events.
79};
80
81/// The warriors bound for Colosso in the hold while the ship waits at Kalay
82/// (gTolbiShipInteriors_HoldPlacements): Ouranos and his friend Sean. Ouranos
83/// "can't stand water".
87};
88
89/// A speaker: the actor, and in the top four bits where the message window
90/// opens beside them.
91#define SPEAKER(actor, window) ((window) << 12 | (actor))
92
93// Defined below, in the order of the ROM.
94static void TolbiShipInteriors_StepBesideLeader(s32 passengerId);
97static void TolbiShipInteriors_AskToRow(s32 speaker, s32 question,
98 s32 seatFlag);
100static void TolbiShipInteriors_SetUpCabin(void);
101static void TolbiShipInteriors_SetUpHold(void);
102static void TolbiShipInteriors_SetUpRowingDeck(void);
105static void TolbiShipInteriors_CastOff(void);
109static void TolbiShipInteriors_ShowRowing(void);
111static void TolbiShipInteriors_AnnounceTurn(void);
113static void TolbiShipInteriors_EndFirstAttack(void);
117static void TolbiShipInteriors_Say(s32 speaker);
118static void TolbiShipInteriors_Turn(s32 actorId, u16 facing);
119static void TolbiShipInteriors_PlaceActor(s32 actorId, s32 x, s32 z,
120 s32 facing);
122 u32 flags);
123static void TolbiShipInteriors_RunSceneCommand(s32 step, u32 arg, u32 opt);
124static s32 TolbiShipInteriors_FindFirstSetFlag(u32 group, s32 alternate);
127 s32 firstFlag);
131static void TolbiShipInteriors_EndSecondAttack(void);
133static void TolbiShipInteriors_EndThirdAttack(void);
137static void TolbiShipInteriors_ReachIsland(void);
139static void TolbiShipInteriors_SwapRowerSelections(s32 firstSeatFlags,
140 s32 secondSeatFlags);
141
142/// An action-script call: stands the actor still at the origin, with no
143/// velocity and no target. Returns 0.
144static s32
146 struct FieldActor *actor = (struct FieldActor *)interpreter;
147 Object_SetMode(actor, 1);
148 actor->x.fixed = 0;
149 actor->y.fixed = 0;
150 actor->z.fixed = 0;
151 SET_VELOCITY(actor, 0, 0, 0);
152 actor->targetY = ACTOR_NO_TARGET;
153 actor->targetX = ACTOR_NO_TARGET;
154 return 0;
155}
156
157/// Bobs the actor between the floor and 8 pixels up by a random amount each
158/// frame. Returns 1.
159static s32 TolbiShipInteriors_Bob(struct ScriptInterpreter *interpreter) {
160 struct FieldActor *actor = (struct FieldActor *)interpreter;
161 s16 verticalMotionDirection;
162 s32 descendingY;
163 s32 ascendingY;
164
165 if ((s16)actor->work != 0) {
166 descendingY = (actor->y.fixed - ((u32)(Engine_RandomNext() << 15) >> 16)) -
167 PIXELS(1) / 2;
168 actor->y.fixed = descendingY;
169 if (descendingY < 0) {
170 verticalMotionDirection = 0;
171 actor->work = verticalMotionDirection;
172 }
173 } else {
174 ascendingY = actor->y.fixed + ((u32)(Engine_RandomNext() << 15) >> 16) +
175 PIXELS(1) / 2;
176 actor->y.fixed = ascendingY;
177 if (ascendingY > PIXELS(8)) {
178 verticalMotionDirection = 1;
179 actor->work = verticalMotionDirection;
180 }
181 }
182 return 1;
183}
184
185/// Now and then (two chances in 64) turns the actor to face south-southeast or
186/// south-southwest. Returns 1.
187static s32
189 struct FieldActor *actor = (struct FieldActor *)interpreter;
190 u32 choice = (u32)(Engine_RandomNext(actor) << 6) >> 16;
191
192 if (choice == 6) {
193 s32 facing = 0x3000;
194 actor->facing = facing;
195 } else if (choice == 9) {
196 s32 facing = 0x5000;
197 actor->facing = facing;
198 }
199 return 1;
200}
201
202/// Counts the frames of a pause in riseCounter and moves the pacing actor to
203/// its next step after 80 frames.
205 u8 *counter = &actor->riseCounter;
206 s32 frame = *counter + 1;
207
208 *counter = frame;
209 if ((u8)frame > 80) {
210 actor->work += 1;
211 }
212}
213
214/// Counts down the actor's walking time in riseBaseY. Returns 1 once the time
215/// is up or the actor has reached its target, else 0.
217 s32 remaining = actor->riseBaseY;
218
219 if (remaining != 0) {
220 actor->riseBaseY = remaining - 1;
221 } else {
222 return 1;
223 }
224 if (actor->targetX == ACTOR_NO_TARGET && actor->targetY == actor->targetX &&
225 actor->targetZ == actor->targetY) {
226 return 1;
227 }
228 return 0;
229}
230
231/// The update of a crewman who paces between two spots in the cabin, looking
232/// about at each, and signals actor 9 through riseEnabled at three points of
233/// the round. While actor 8 is paused he sends no signals. work holds the step.
234static void TolbiShipInteriors_PaceCabin(union FieldObject *fieldObject) {
235 struct FieldActor *obj = (struct FieldActor *)fieldObject;
236 struct FieldActor *leader;
237
238 leader = Object_GetById(8);
239 switch ((s16)obj->work) {
240 case 0:
241 obj->facing = 0xb000;
242 obj->work++;
243 obj->riseCounter = 0;
244 break;
245 case 2:
246 obj->facing = 0;
247 obj->work++;
248 obj->riseCounter = 0;
249 break;
250 case 4:
251 Object_SetMode(obj, 2);
252 FieldObject_SetPosition(obj, PIXELS(468), PIXELS(32), PIXELS(632));
253 obj->riseBaseY = 60;
254 obj->work++;
255 break;
256 case 5:
257 if (TolbiShipInteriors_HasArrived(obj) != 0) {
258 Object_SetMode(obj, 1);
259 obj->riseCounter = 0;
260 if (leader->paused == 0) {
261 obj->riseEnabled = 1;
262 }
263 obj->work++;
264 }
265 break;
266 case 7:
267 if (leader->paused == 0) {
268 Object_SetMode(obj, 3);
269 obj->riseEnabled = 2;
270 }
271 obj->work++;
272 obj->riseCounter = 0;
273 break;
274 case 9:
275 Object_SetMode(obj, 2);
276 FieldObject_SetPosition(obj, PIXELS(480), PIXELS(32), PIXELS(600));
277 obj->riseBaseY = 60;
278 obj->work++;
279 if (leader->paused == 0) {
280 obj->riseEnabled = 3;
281 }
282 break;
283 case 10:
284 if (TolbiShipInteriors_HasArrived(obj) != 0) {
285 Object_SetMode(obj, 1);
286 obj->riseCounter = 0;
287 obj->work++;
288 }
289 break;
290 case 1:
291 case 3:
292 case 6:
293 case 8:
294 case 11:
296 break;
297 case 12:
298 obj->work = 0;
299 break;
300 }
301}
302
303/// The update of the actor who watches the pacing crewman: turns
304/// north-northeast at the first signal, shrugs at the second if still turned,
305/// and faces east at the third. Does nothing while paused.
306static void TolbiShipInteriors_WatchPacer(union FieldObject *fieldObject) {
307 struct FieldActor *watcher = (struct FieldActor *)fieldObject;
308 struct FieldActor *pacer;
309
310 pacer = Object_GetById(9);
311 if (watcher->paused != 0)
312 return;
313 if (pacer->riseEnabled == 1) {
314 watcher->facing = 0xd000;
315 watcher->riseCounter = 1;
316 pacer->riseEnabled = 0;
317 } else if (pacer->riseEnabled == 2) {
318 if (watcher->riseCounter != 0)
319 Object_SetMode(watcher, 3);
320 watcher->riseCounter = 0;
321 pacer->riseEnabled = 0;
322 } else if (pacer->riseEnabled == 3) {
323 watcher->facing = 0;
324 pacer->riseEnabled = 0;
325 }
326}
327
328/// An action-script call: lays the actor flat on the floor, drawn underfoot at
329/// priority 1 with its parts hidden. Returns 1.
331 struct FieldActor *work = (struct FieldActor *)interpreter;
332 struct AnimationObject *sprite = work->sprite;
333
334 work->collisionFlags = 8;
336 sprite->image.priority = 1;
337 sprite->shadow.priority = 1;
338 work->priorityFlags = (work->priorityFlags & ~1) | 2;
340 return 1;
341}
342
346 }
348}
349
350const struct SceneRegion *TolbiShipInteriors_GetRegions(void) { return 0; }
351
354}
355
356/// A byte view keeps the native address arithmetic; direct row-field writes
357/// choose different bases and registers. The layout still belongs to the row.
358#define TOLBI_SHIP_TALK_FACING(bytes, row) \
359 ((bytes)[(row) * sizeof(struct ScenePlacement) + \
360 offsetof(struct ScenePlacement, talkFacing)])
361
362/// Picks the placements for the room entered and the voyage's stage. Some
363/// stages change who turns to face the party when talked to (talkFacing) in the
364/// shared tables.
366 u8 *placementBytes;
367
368 switch (gGameState.entrance) {
369 case 1:
370 case 2:
371 case 11:
375 0) {
377 // Update talkFacing in the placement rows, preserving their write
378 // order.
380 TOLBI_SHIP_TALK_FACING(placementBytes, 0) = TALK_KEEP_FACING;
381 TOLBI_SHIP_TALK_FACING(placementBytes, 2) = TALK_KEEP_FACING;
382 TOLBI_SHIP_TALK_FACING(placementBytes, 4) = TALK_KEEP_FACING;
383 TOLBI_SHIP_TALK_FACING(placementBytes, 5) = TALK_KEEP_FACING;
384 TOLBI_SHIP_TALK_FACING(placementBytes, 8) = TALK_KEEP_FACING;
385 TOLBI_SHIP_TALK_FACING(placementBytes, 7) = TALK_KEEP_FACING;
387 TOLBI_SHIP_TALK_FACING(placementBytes, 3) = TALK_KEEP_FACING;
388 }
396 }
398 } else {
400 }
401 break;
402 case 4:
403 case 12:
404 case 16:
405 case 18:
406 case 20:
407 case 21:
408 case 23:
409 case 24:
411 break;
412 case 15:
413 case 17:
414 case 19:
416 TOLBI_SHIP_TALK_FACING(placementBytes, 0) = TALK_KEEP_FACING;
417 TOLBI_SHIP_TALK_FACING(placementBytes, 1) = TALK_KEEP_FACING;
419 TOLBI_SHIP_TALK_FACING(placementBytes, 4) = TALK_KEEP_FACING;
420 TOLBI_SHIP_TALK_FACING(placementBytes, 5) = TALK_KEEP_FACING;
421 TOLBI_SHIP_TALK_FACING(placementBytes, 6) = TALK_KEEP_FACING;
422 TOLBI_SHIP_TALK_FACING(placementBytes, 7) = TALK_KEEP_FACING;
424 TOLBI_SHIP_TALK_FACING(placementBytes, 9) = TALK_KEEP_FACING;
425 return (const struct ScenePlacement *)placementBytes;
426 case 5:
434 }
439 }
440 }
442 }
444 } else {
446 }
447 break;
448 case 10:
449 case 13:
450 case 14:
451 case 22:
453 break;
454 default:
456 break;
457 }
458 return (const struct ScenePlacement *)placementBytes;
459}
460
461#undef TOLBI_SHIP_TALK_FACING
462
463/// Chooses the room's interactions for the current stage of the voyage.
465 s32 entrance = gGameState.entrance;
466
467 switch (entrance) {
468 case 1:
469 case 2:
472 }
476 }
478 case 4:
479 case 23:
482 }
484 case 5:
487 }
490 }
492 case 15:
493 case 17:
494 case 19:
496 case 21:
498 default:
499 break;
500 }
501
503}
504
505/// Once the warriors want to see the captain, actor 10 asks whether the party
506/// wants to join them in forcing the launch.
511 Engine_EventSetMessage(MsgTolbiShipIfShipFromTolbiHad);
512 Event_ShowMessage(10, 0);
513 } else {
515 Engine_EventSetMessage(MsgTolbiShipNowWantSeeCaptainToo);
516 Event_OpenMessage(10, 0);
517 if (Engine_EventChooseYesNo(0, 0) == 0) {
519 } else {
521 Event_ShowMessage(10, 0);
522 Actor_FaceDirection(10, 0xd000, 0);
523 }
524 } else {
525 Engine_EventSetMessage(MsgTolbiShipButWeCantSendShip);
526 Event_ShowMessage(10, 0);
527 }
528 }
530}
531
532/// Actor 12 in the captain's cabin asks whether the party came to ask the
533/// captain to set sail.
536 Engine_EventSetMessage(MsgTolbiShipYouCameAskCaptainSet);
539}
540
541/// The captain, by the voyage's stage: too late to hire mercenaries, then his
542/// bad luck at losing his lucky anchor, then uncertain what might happen, and
543/// under sail the news of an injured oarsman. After finding the Anchor Charm,
544/// talking to him also sets the event work's unk172 request.
548 Engine_EventSetMessage(MsgTolbiShipOarsmanWasInjured);
550 Actor_FaceDirection(8, 0xd000, 60);
555 Engine_EventSetMessage(MsgTolbiShipWeDontKnowMightHappen);
556 Event_ShowMessage(8, 0);
558 Engine_EventSetMessage(MsgTolbiShipBadLuckLosingMyLucky);
559 Event_ShowMessage(8, 0);
562 gEventWork->unk172 = 1;
563 }
564 } else {
565 Engine_EventSetMessage(MsgTolbiShipItsTooLateHireMercenaries);
566 Event_ShowMessage(8, 0);
567 }
569}
570
571/// A passenger in the hold while the ship waits. Once the party has agreed to
572/// protect the ship, she worries the proud warriors won't like being told to
573/// row, and asks the party.
578 Engine_EventSetMessage(MsgTolbiShipTheseProudWarriorsNotGoing);
581 Event_OpenMessage(8, 0);
582 if (Engine_EventChooseYesNo(0, 0) == 0) {
585 TolbiShipInteriors_Turn(8, 0x3000);
586 Event_ShowMessage(8, 0);
587 } else {
588 gEventWork->message += 2;
589 Event_ShowMessage(8, 0);
590 Actor_FaceDirection(8, 0x3000, 0);
591 }
592 } else {
593 Engine_EventSetMessage(MsgTolbiShipLongerWeSitHereMore);
594 Event_ShowMessage(8, 0);
595 }
597}
598
599/// Another waiting passenger, once the party has agreed to protect the ship,
600/// asks whether it will row. "Are you going to row?"
604 Engine_EventSetMessage(MsgTolbiShipYouGoingRow);
606 } else {
607 Engine_EventSetMessage(MsgTolbiShipTheresWholeBunchReallyMuscular);
609 }
611}
612
613/// Walks the rower back to the leader and hides its separate scene actor.
614static inline void TolbiShipInteriors_RejoinParty(s32 rowerId) {
615 struct FieldActor *leader;
616
617 Engine_ActorSetAnimation(rowerId, 2);
618 leader = Object_GetById(0);
619 if (leader != 0) {
620 Engine_ActorSetDestination(rowerId, leader->x.part.pixel,
621 leader->z.part.pixel);
622 }
624 Engine_ActorSetPosition(rowerId, 0, 0);
625}
626
627/// Passenger 8 under sail, when an oar needs a rower. If someone has already
628/// been chosen this round, the chosen passenger steps beside the
629/// leader and follows them out; otherwise the party may ask passenger 8 to row
630/// at the open seat.
634
637 Engine_EventSetMessage(MsgTolbiShipLooksLikeYouveBeenChosen);
642 TolbiShipInteriors_AskToRow(8, MsgTolbiShipNoooooNotGoing,
645 TolbiShipInteriors_AskToRow(8, MsgTolbiShipNoooooNotGoing,
648 0) {
649 TolbiShipInteriors_AskToRow(8, MsgTolbiShipNoooooNotGoing,
651 } else {
652 TolbiShipInteriors_AskToRow(8, MsgTolbiShipNoooooNotGoing,
654 }
655}
656
657/// The same for passenger 10.
661
664 Engine_EventSetMessage(MsgTolbiShipHaHaHaChosenOarsman);
669 TolbiShipInteriors_AskToRow(10, MsgTolbiShipJokingWantRow,
672 TolbiShipInteriors_AskToRow(10, MsgTolbiShipJokingWantRow,
675 0) {
676 TolbiShipInteriors_AskToRow(10, MsgTolbiShipJokingWantRow,
678 } else {
679 TolbiShipInteriors_AskToRow(10, MsgTolbiShipJokingWantRow,
681 }
682}
683
684/// The same for passenger 11, who is too seasick to talk once the ship is at
685/// anchor.
691 Engine_EventSetMessage(MsgTolbiShipDontFeelDontTalkMe);
696
699 Engine_EventSetMessage(MsgTolbiShipYouFinallyPickedSomeoneDidnt);
704 TolbiShipInteriors_AskToRow(11, MsgTolbiShipDontTellGoing,
707 TolbiShipInteriors_AskToRow(11, MsgTolbiShipDontTellGoing,
710 0) {
711 TolbiShipInteriors_AskToRow(11, MsgTolbiShipDontTellGoing,
713 } else {
714 TolbiShipInteriors_AskToRow(11, MsgTolbiShipDontTellGoing,
716 }
717}
718
719/// The same for passenger 12, written out in full rather than through
720/// TolbiShipInteriors_AskToRow.
722 s32 rowerId;
723 struct FieldActor *actor;
724
729 Engine_EventSetMessage(MsgTolbiShipGivesMeChillsThinkCould);
732 } else {
735 Engine_EventSetMessage(MsgTolbiShipOhhhhNooooGoingMakeMe);
736 Event_OpenMessage(12, 0);
737 if (Engine_EventChooseYesNo(0, 0) == 0) {
740 actor = Object_GetById(0);
741 if (actor != 0) {
742 Actor_SetDestination(12, actor->x.part.pixel, actor->z.part.pixel);
743 }
745 Actor_SetPosition(12, 0, 0);
753 } else {
755 }
756 } else {
759 }
760 }
762}
763
764/// The same for passenger 9, written out in full.
766 s32 rowerId;
767 struct FieldActor *actor;
768
773 Engine_EventSetMessage(MsgTolbiShipIsaacYouveGotGoodEye);
776 } else {
777 Engine_EventSetMessage(MsgTolbiShipHaHaHaRowingFeel);
780 Event_OpenMessage(9, 0);
781 if (Engine_EventChooseYesNo(0, 0) == 0) {
784 actor = Object_GetById(0);
785 if (actor != 0) {
786 Actor_SetDestination(9, actor->x.part.pixel, actor->z.part.pixel);
787 }
789 Actor_SetPosition(9, 0, 0);
797 } else {
799 }
800 } else {
803 }
804 }
806}
807
808/// The same for passenger 13.
812
815 Engine_EventSetMessage(MsgTolbiShipThatsWhoYouPickedOarsman);
820 TolbiShipInteriors_AskToRow(13, MsgTolbiShipNotThinkingMaking,
823 TolbiShipInteriors_AskToRow(13, MsgTolbiShipNotThinkingMaking,
826 0) {
827 TolbiShipInteriors_AskToRow(13, MsgTolbiShipNotThinkingMaking,
829 } else {
830 TolbiShipInteriors_AskToRow(13, MsgTolbiShipNotThinkingMaking,
832 }
833}
834
835/// The same for passenger 14.
839
842 Engine_EventSetMessage(MsgTolbiShipIfYouveChosenOarsmanLets);
847 TolbiShipInteriors_AskToRow(14, MsgTolbiShipOarsmanGiveBreak,
850 TolbiShipInteriors_AskToRow(14, MsgTolbiShipOarsmanGiveBreak,
853 0) {
854 TolbiShipInteriors_AskToRow(14, MsgTolbiShipOarsmanGiveBreak,
856 } else {
857 TolbiShipInteriors_AskToRow(14, MsgTolbiShipOarsmanGiveBreak,
859 }
860}
861
862/// The same for passenger 15.
866
869 Engine_EventSetMessage(MsgTolbiShipYouveBeenChosenAsOarsman);
874 TolbiShipInteriors_AskToRow(15, MsgTolbiShipPoorOarsmanFeel,
877 TolbiShipInteriors_AskToRow(15, MsgTolbiShipPoorOarsmanFeel,
880 0) {
881 TolbiShipInteriors_AskToRow(15, MsgTolbiShipPoorOarsmanFeel,
883 } else {
884 TolbiShipInteriors_AskToRow(15, MsgTolbiShipPoorOarsmanFeel,
886 }
887}
888
889/// The same for passenger 16.
891 s32 rowerId;
892
897 Engine_EventSetMessage(MsgTolbiShipHoHoPersonGoingGet);
901 } else {
903 TolbiShipInteriors_AskToRow(16, MsgTolbiShipPeopleAskingFrail,
906 0) {
907 TolbiShipInteriors_AskToRow(16, MsgTolbiShipPeopleAskingFrail,
910 0) {
911 TolbiShipInteriors_AskToRow(16, MsgTolbiShipPeopleAskingFrail,
913 } else {
914 TolbiShipInteriors_AskToRow(16, MsgTolbiShipPeopleAskingFrail,
916 }
917 }
918}
919
920/// Finds a placed actor within twelve pixels of the requested floor position.
922 struct EventWork *work;
923 struct FieldActor **actor;
924 struct FieldActor *current;
925 u32 i;
926 s32 actorX;
927 s32 actorZ;
928 s32 left;
929 s32 top;
930 s32 right;
931 s32 bottom;
932
934 i = 8;
935 left = x - 12;
936 right = x + 12;
937 top = z - 12;
938 bottom = z + 12;
939 actor = work->placedActors;
940 while (i <= 65) {
941 current = *actor++;
942 actorX = current->x.part.pixel;
943 actorZ = current->z.part.pixel;
944 if (left < actorX && right > actorX && top < actorZ && bottom > actorZ)
945 return current;
946 i++;
947 }
948 return 0;
949}
950
951/// The chosen oarsman steps out beside the leader, on the leader's right if
952/// that spot is free, else on the left, else behind, and turns the way the
953/// leader faces.
954static void TolbiShipInteriors_StepBesideLeader(s32 passengerId) {
955 struct FieldActor *leader;
956 struct FieldActor *leaderPosition;
957 s32 blocked;
958 s32 direction;
959
960 leader = Object_GetById(0);
961 blocked = 1;
962 Engine_ActorSetSpritePriority(passengerId, 2);
963 {
964 struct FieldActor *passenger = Object_GetById(passengerId);
965
966 passenger->priorityFlags =
968 }
969 // Try the leader's right, then left, then the space behind.
970 direction = (((leader->facing + 0x4000) & 0xf000) >> 12);
972 (((leader->facing + 0x4000) & 0xf000) >> 12)) != 0) {
973 blocked = 0;
974 }
975 if (blocked != 0) {
976 direction = (((leader->facing + -0x4000) & 0xf000) >> 12);
978 (((leader->facing + -0x4000) & 0xf000) >> 12)) != 0) {
979 blocked = 0;
980 }
981 if (blocked != 0) {
982 direction = (((leader->facing + 0x8000) & 0xf000) >> 12);
983 }
984 }
985 leaderPosition = Object_GetById(0);
986 if (leaderPosition != 0) {
987 Engine_ActorSetPosition(passengerId, leaderPosition->x.fixed,
988 leaderPosition->z.fixed);
989 }
990 Actor_SetSpeed(passengerId, PIXELS(8) / 5, PIXELS(4) / 5);
991 Engine_ActorSetAnimation(passengerId, 2);
992 {
993 s32 offset = gTolbiShipInteriors_TurnSteps[direction];
994
995 Engine_ActorSetDestinationOffset(passengerId, offset >> 16,
996 (offset << 16) >> 16);
997 }
998 Engine_ActorWaitForMove(passengerId);
999 Engine_ActorSetAnimation(passengerId, 1);
1000 TolbiShipInteriors_Turn(passengerId, leader->facing);
1001}
1002
1003enum { CabinSpeakerRequest = 0xa01b };
1004
1005/// Returns 1 when the spot next to the leader in the given sixteenth of a turn
1006/// holds no actor and no wall, else 0.
1008 struct FieldActor *obj = Object_GetById(0);
1009 u32 offset = gTolbiShipInteriors_TurnSteps[bucket];
1010 s32 x = obj->x.part.pixel + ((s32)offset >> 16);
1011 s32 z = obj->z.part.pixel + (s16)offset;
1012
1014 return 0;
1015 }
1016
1017 {
1018 struct FieldPosition point;
1019 point.x = x << 16;
1020 point.y = obj->y.fixed;
1021 point.z = z << 16;
1022
1023 if (FieldObject_CheckMovementCollision(obj, &point) != 0) {
1024 return 0;
1025 }
1026 }
1027
1028 return 1;
1029}
1030
1031/// Returns the passenger chosen to row at the open seat, which the attacks
1032/// fought off number.
1034 s32 ret = 0;
1035
1037 ret = 3;
1039 ret = 2;
1041 0) {
1042 ret = 1;
1043 }
1044
1046}
1047
1048/// A passenger at the oars, by the round they were chosen in: Kaja's men are
1049/// worried, monsters are everywhere, or the ship is starting to list.
1053 Engine_EventSetMessage(MsgTolbiShipThingHasKajaHisMen);
1055 Engine_EventSetMessage(MsgTolbiShipMonstersEverywhereImStuckRowing);
1056 else
1057 Engine_EventSetMessage(MsgTolbiShipShipStartingListIfWe);
1058 Engine_EventShowMessage(0x12, 0);
1060}
1061
1062/// The same for rower 19.
1066 Engine_EventSetMessage(MsgTolbiShipThingHasKajaHisMen);
1068 Engine_EventSetMessage(MsgTolbiShipMonstersEverywhereImStuckRowing);
1069 else
1070 Engine_EventSetMessage(MsgTolbiShipShipStartingListIfWe);
1071 Engine_EventShowMessage(0x13, 0);
1073}
1074
1075/// The same for rower 20.
1079 Engine_EventSetMessage(MsgTolbiShipThingHasKajaHisMen);
1081 Engine_EventSetMessage(MsgTolbiShipMonstersEverywhereImStuckRowing);
1082 else
1083 Engine_EventSetMessage(MsgTolbiShipShipStartingListIfWe);
1084 Engine_EventShowMessage(0x14, 0);
1086}
1087
1088/// Rower 21 asks how many monsters are out there.
1092 Engine_EventSetMessage(MsgTolbiShipHowManyMonstersOutThere);
1093 else
1094 Engine_EventSetMessage(MsgTolbiShipAnotherMonsterIsntFirstClass);
1097}
1098
1099/// The same as rower 18, for rower 22.
1103 Engine_EventSetMessage(MsgTolbiShipThingHasKajaHisMen);
1105 Engine_EventSetMessage(MsgTolbiShipMonstersEverywhereImStuckRowing);
1106 else
1107 Engine_EventSetMessage(MsgTolbiShipShipStartingListIfWe);
1110}
1111
1112/// The same for rower 23.
1116 Engine_EventSetMessage(MsgTolbiShipThingHasKajaHisMen);
1118 Engine_EventSetMessage(MsgTolbiShipMonstersEverywhereImStuckRowing);
1119 else
1120 Engine_EventSetMessage(MsgTolbiShipShipStartingListIfWe);
1123}
1124
1125/// The same for rower 24.
1129 Engine_EventSetMessage(MsgTolbiShipThingHasKajaHisMen);
1131 Engine_EventSetMessage(MsgTolbiShipMonstersEverywhereImStuckRowing);
1132 else
1133 Engine_EventSetMessage(MsgTolbiShipShipStartingListIfWe);
1136}
1137
1138/// As rower 21, for rower 25.
1142 Engine_EventSetMessage(MsgTolbiShipHowManyMonstersOutThere);
1143 else
1144 Engine_EventSetMessage(MsgTolbiShipAnotherMonsterIsntFirstClass);
1147}
1148
1149/// Mind Read on a rower, by the round they were chosen in.
1150/// "Just hurry up and slay that beast!"
1154 Engine_EventSetMessage(MsgTolbiShipDontCareTakesJustHurry);
1156 Engine_EventSetMessage(MsgTolbiShipIfThoseMonstersComeBack);
1157 else
1158 Engine_EventSetMessage(MsgTolbiShipBoatsRockingMuchImCertain);
1161}
1162
1163/// The same for rower 19.
1167 Engine_EventSetMessage(MsgTolbiShipDontCareTakesJustHurry);
1169 Engine_EventSetMessage(MsgTolbiShipIfThoseMonstersComeBack);
1170 else
1171 Engine_EventSetMessage(MsgTolbiShipBoatsRockingMuchImCertain);
1174}
1175
1176/// The same for rower 20.
1180 Engine_EventSetMessage(MsgTolbiShipDontCareTakesJustHurry);
1182 Engine_EventSetMessage(MsgTolbiShipIfThoseMonstersComeBack);
1183 else
1184 Engine_EventSetMessage(MsgTolbiShipBoatsRockingMuchImCertain);
1187}
1188
1189/// Mind Read on rower 21: there are so many monsters at sea.
1193 Engine_EventSetMessage(MsgTolbiShipHadIdeaThereWereMany);
1194 else
1195 Engine_EventSetMessage(MsgTolbiShipWereSurroundedByMonstersStill);
1198}
1199
1200/// As rower 18, for rower 22.
1204 Engine_EventSetMessage(MsgTolbiShipDontCareTakesJustHurry);
1206 Engine_EventSetMessage(MsgTolbiShipIfThoseMonstersComeBack);
1207 else
1208 Engine_EventSetMessage(MsgTolbiShipBoatsRockingMuchImCertain);
1211}
1212
1213/// The same for rower 23.
1217 Engine_EventSetMessage(MsgTolbiShipDontCareTakesJustHurry);
1219 Engine_EventSetMessage(MsgTolbiShipIfThoseMonstersComeBack);
1220 else
1221 Engine_EventSetMessage(MsgTolbiShipBoatsRockingMuchImCertain);
1224}
1225
1226/// The same for rower 24.
1230 Engine_EventSetMessage(MsgTolbiShipDontCareTakesJustHurry);
1232 Engine_EventSetMessage(MsgTolbiShipIfThoseMonstersComeBack);
1233 else
1234 Engine_EventSetMessage(MsgTolbiShipBoatsRockingMuchImCertain);
1237}
1238
1239/// As rower 21, for rower 25.
1243 Engine_EventSetMessage(MsgTolbiShipHadIdeaThereWereMany);
1244 else
1245 Engine_EventSetMessage(MsgTolbiShipWereSurroundedByMonstersStill);
1248}
1249
1250/// Asks a passenger to row. On yes they walk to the leader and leave with them,
1251/// and the seat's flag for this passenger (seatFlag) and
1252/// FLAG_TOLBI_SHIP_ROWER_CHOSEN are set; on no the next message refuses.
1253static void TolbiShipInteriors_AskToRow(s32 speaker, s32 question,
1254 s32 seatFlag) {
1255 struct FieldActor *leader;
1256
1258 Engine_EventSetMessage(question);
1259 Engine_EventOpenMessage(speaker, 0);
1260 if (Engine_EventChooseYesNo(0, 0) == 0) {
1261 TolbiShipInteriors_Say(speaker);
1262 Engine_ActorSetAnimation(speaker, 2);
1263 leader = Object_GetById(0);
1264 if (leader != 0) {
1265 Engine_ActorSetDestination(speaker, leader->x.part.pixel,
1266 leader->z.part.pixel);
1267 }
1268 Engine_ActorWaitForMove(speaker);
1269 Engine_ActorSetPosition(speaker, 0, 0);
1271 Engine_GameFlagSet(seatFlag);
1272 } else {
1274 TolbiShipInteriors_Say(speaker);
1275 }
1277}
1278
1279/// The travelling priest. From in front of him (the leader facing roughly east)
1280/// he opens his sanctum; otherwise he talks by the voyage's stage. Under sail,
1281/// until the ship is docked, he is actor 17, else actor 15.
1283 struct FieldActor *leader;
1284
1285 leader = Object_GetById(0);
1286 if ((u16)(leader->facing - 0x2000) > 0xc000) {
1290 } else {
1292 }
1293 } else {
1296 Engine_EventSetMessage(MsgTolbiShipGoodShipHasArrivedSafely);
1298 Engine_EventSetMessage(MsgTolbiShipHateArguing);
1300 0) {
1301 Engine_EventSetMessage(MsgTolbiShipShipsCrewReadyAnything);
1303 0) {
1304 Engine_EventSetMessage(MsgTolbiShipShipsCrewReadyForAnything);
1305 } else {
1306 Engine_EventSetMessage(MsgTolbiShipImSpreadingGoodwillWhereverTravel);
1307 }
1311 } else {
1313 }
1315 }
1316}
1317
1318/// Talking to one of the monsters in the hold (actors 36 to 38) starts the
1319/// battle with them: group 62, its variant and the entrance the party comes
1320/// back to chosen by how far the voyage has gone.
1322
1325 Battle_SetStart(3);
1330 } else {
1334 } else {
1338 }
1339 }
1340 }
1342}
1343
1344/// While the monsters are aboard, the leader is walked back from the stairs.
1345/// "Where are you going, Isaac? Slay the beasts and save my mates!"
1350 UiText_ShowCenteredMessage(MsgTolbiShipWhereGoingSlay, 1, 8);
1353 TolbiShipInteriors_Turn(0, 0x4000);
1355 }
1356}
1357
1358/// Once the warriors have gone to the captain, the three crewmen
1359/// wonder what could have happened to the replacement ship.
1362 return;
1363
1366 Engine_CameraSetSpeed(0x19999, 0x3333);
1368 0x10000028u);
1369 Engine_EventSetMessage(MsgTolbiShipWonderCouldHaveHappened);
1370
1373 TolbiShipInteriors_Turn(8, 0x3000);
1375 TolbiShipInteriors_Turn(10, 0xd000);
1377 TolbiShipInteriors_Turn(9, 0x5000);
1379
1382 TolbiShipInteriors_Turn(9, 0x8000);
1386 TolbiShipInteriors_Turn(10, 0xb000);
1388
1391}
1392
1393/// Once the party has heard of the delay at Kalay: Ouranos threatens to go
1394/// ashore if the ship doesn't sail. Actor 12 can't say when it will, so Sean
1395/// and Ouranos set off to make the captain set sail, and actor 12 ("I don't
1396/// want any violence!") hurries after them past the party.
1398 s32 actor12Speaker;
1399 s32 seanSpeaker;
1400 const s32 *action;
1401
1403 // Not yet: the party has not heard of the delay.
1404 } else {
1407 Camera_SetSpeed(0x26666, 0x4ccc);
1409 0x10000014);
1411 Engine_EventSetMessage(MsgTolbiShipIfWeArentGoingSet);
1413 TolbiShipInteriors_Turn(12, 0xd000);
1414 actor12Speaker = SPEAKER(12, 8);
1415 Actor_ShowEmote(12, 0x102, 20);
1417 TolbiShipInteriors_Say(actor12Speaker);
1421 seanSpeaker = SPEAKER(HOLD_SEAN, 10);
1422 Actor_ShowEmote(12, 0x101, 40);
1423 Actor_ShowEmote(HOLD_SEAN, 0x103, 40);
1425 TolbiShipInteriors_Say(seanSpeaker);
1426 Actor_SetAttachedEffect(12, 0x102);
1427 Engine_EventWait(40);
1429 TolbiShipInteriors_Say(actor12Speaker);
1431 TolbiShipInteriors_Say(seanSpeaker);
1433 TolbiShipInteriors_Say(seanSpeaker);
1434 TolbiShipInteriors_Turn(12, 0xd000);
1435 Actor_ShowEmote(12, 0x100, 30);
1437 TolbiShipInteriors_Say(actor12Speaker);
1443 TolbiShipInteriors_Say(actor12Speaker);
1445 TolbiShipInteriors_Say(seanSpeaker);
1448 Event_ShowMessageAndWait(seanSpeaker, 0, 20);
1450 Actor_ShowEmote(12, 0x102, 80);
1451 Event_ShowMessageAndWait(actor12Speaker, 0, 20);
1452 Actor_ShowEmote(HOLD_SEAN, 0x103, 0);
1453 Actor_ShowEmote(HOLD_OURANOS, 0x103, 60);
1455 TolbiShipInteriors_Say(seanSpeaker);
1458 TolbiShipInteriors_Say(seanSpeaker);
1460 Actor_ShowEmote(HOLD_OURANOS, 0x101, 0);
1461 Actor_ShowEmote(12, 0x101, 60);
1464 Actor_ShowEmote(HOLD_SEAN, 0x103, 40);
1466 TolbiShipInteriors_Say(seanSpeaker);
1467 Actor_FaceDirection(12, 0xd000, 0);
1468 Actor_FaceDirection(HOLD_OURANOS, 0x5000, 40);
1472 Event_ShowMessageAndWait(actor12Speaker, 0, 20);
1474 TolbiShipInteriors_Say(seanSpeaker);
1477 Engine_EventWait(60);
1481 TolbiShipInteriors_Say(seanSpeaker);
1482 Actor_ShowEmote(12, 0x102, 40);
1484 TolbiShipInteriors_Say(actor12Speaker);
1487 Actor_FaceDirection(HOLD_SEAN, 0xb000, 40);
1490 Actor_SetSpeed(HOLD_SEAN, PIXELS(8) / 5, PIXELS(4) / 5);
1491 Actor_SetSpeed(HOLD_OURANOS, PIXELS(8) / 5, PIXELS(4) / 5);
1495 Engine_EventWait(20);
1498 Object_GetById(0)->steeringFlags &= 254;
1501 {
1502 struct FieldActor *actor = Object_GetById(0);
1504 }
1507 Engine_ActorJump(12, 4, 20);
1511 Actor_SetSpeed(12, PIXELS(8) / 5, PIXELS(4) / 5);
1512 Actor_SetActionScript(12, action);
1513 Engine_EventWait(40);
1518 }
1519}
1520
1521/// The passengers pressure the captain to launch despite the missing anchor.
1523 s32 actor12Speech;
1524 s32 actor11Speech;
1525 s32 actor8Speech;
1526
1527 // Gather the cabin's attention around the argument about launching.
1529 Camera_SetSpeed(0x26666, 0x4ccc);
1531 0x10000014);
1533 Engine_EventSetMessage(MsgTolbiShipYoureTryingLaunchShip);
1536 Actor_FaceDirection(10, 0xd000, 0);
1538 Actor_FaceDirection(12, 0x3000, 0);
1540 Actor_ShowEmote(9, 0x103, 40);
1544 Actor_FaceDirection(11, 0xd000, 0);
1545 Actor_FaceDirection(13, 0xd000, 20);
1547 TolbiShipInteriors_Say(0x100b);
1548 Actor_ShowEmote(13, 0x102, 20);
1551 Actor_ShowEmote(9, 0x105, 60);
1553 Actor_ShowEmote(12, 0x104, 20);
1554 TolbiShipInteriors_Say(0x900c);
1558 TolbiShipInteriors_Turn(12, 0x3000);
1559 TolbiShipInteriors_Say(0x900c);
1560 TolbiShipInteriors_Turn(11, 0xb000);
1562 Engine_EventWait(10);
1567 Actor_FaceDirection(12, 0x5000, 0);
1568 TolbiShipInteriors_Turn(11, 0x5000);
1569 // Two passengers step aside as the conversation continues.
1570 Actor_SetSpeed(13, PIXELS(2) / 5, PIXELS(1) / 5);
1571 Actor_SetSpeed(12, PIXELS(4) / 5, PIXELS(2) / 5);
1572 Actor_WalkTo(12, 444, 668);
1573 Actor_WalkToAndWait(13, 472, 668);
1576 Engine_EventWait(80);
1577 TolbiShipInteriors_Turn(12, 0xd000);
1578 Actor_ShowEmote(12, 0x101, 60);
1580 Engine_EventWait(20);
1583 Actor_FaceDirection(11, 0xd000, 0);
1584 TolbiShipInteriors_Say(0x100b);
1585 Actor_FaceDirection(12, 0xd000, 0);
1586 Actor_ShowEmote(9, 0x101, 60);
1588 Engine_EventWait(20);
1589 TolbiShipInteriors_Say(0x100b);
1592 Actor_FaceDirection(13, 0xd000, 0);
1593 Actor_SetAttachedEffect(13, 0x102);
1594 Engine_ActorJump(13, 2, 20);
1597 actor12Speech = 0x100c;
1599 TolbiShipInteriors_Turn(11, 0xd000);
1601 TolbiShipInteriors_Say(actor12Speech);
1602 Actor_ShowEmote(8, 0x105, 40);
1605 Actor_ShowEmote(13, 0x102, 40);
1606 Engine_ActorJump(13, 4, 0);
1611 TolbiShipInteriors_Say(0x100b);
1612 Actor_ShowEmote(8, 0x102, 40);
1613 Event_ShowMessage(8, 0);
1616 Actor_ShowEmote(9, 0x100, 0);
1617 Actor_FaceDirection(9, 0x5000, 20);
1619 Event_ShowMessageAndWait(9, 0, 20);
1621 Engine_EventWait(20);
1622 Actor_ShowEmote(12, 0x100, 40);
1624 actor11Speech = 0x400b;
1625 TolbiShipInteriors_Say(actor12Speech);
1626 Actor_FaceDirection(11, 0x5000, 20);
1627 TolbiShipInteriors_Say(actor11Speech);
1629 TolbiShipInteriors_Say(actor12Speech);
1632 TolbiShipInteriors_Say(actor11Speech);
1633 Actor_ShowEmote(12, 0x102, 60);
1636 Actor_ShowEmote(11, 0x101, 40);
1637 Actor_FaceDirection(11, 0xd000, 20);
1640 Actor_ShowEmote(11, 0x103, 20);
1642 TolbiShipInteriors_Say(0x100b);
1643 Actor_ShowEmote(9, 0x108, 40);
1648 Actor_FaceDirection(9, 0xd000, 40);
1651 Engine_EventWait(20);
1652 TolbiShipInteriors_Say(actor12Speech);
1653 Actor_FaceDirection(11, 0x5000, 0);
1654 Actor_FaceDirection(9, 0x5000, 0);
1657 Actor_FaceDirection(10, 0xb000, 40);
1659 TolbiShipInteriors_Say(actor11Speech);
1661 Event_ShowMessageAndWait(actor12Speech, 0, 20);
1664 Actor_ShowEmote(12, 0x108, 40);
1666 TolbiShipInteriors_Say(actor12Speech);
1672 actor8Speech = 0x8008;
1673 Actor_ShowEmote(8, 0x100, 80);
1674 TolbiShipInteriors_Say(actor8Speech);
1675 Actor_ShowEmote(12, 0x101, 0);
1676 Actor_ShowEmote(11, 0x101, 0);
1677 Actor_ShowEmote(13, 0x101, 0);
1678 Actor_ShowEmote(10, 0x101, 0);
1680 Actor_FaceDirection(12, 0xd000, 0);
1681 Actor_FaceDirection(11, 0xd000, 0);
1682 Actor_FaceDirection(13, 0xb000, 0);
1683 Actor_FaceDirection(10, 0xb000, 0);
1685 Actor_SetAttachedEffect(8, 0x102);
1686 Engine_ActorJump(8, 4, 40);
1688 Event_ShowMessage(actor8Speech, 0);
1689 Actor_SetSpeed(8, PIXELS(8) / 5, PIXELS(4) / 5);
1690 Actor_WalkToAndWait(8, 475, 598);
1692 Actor_SetSpeed(9, PIXELS(1), PIXELS(1) / 2);
1693 Actor_WalkToAndWait(9, 462, 618);
1694 TolbiShipInteriors_Turn(9, 0xb000);
1695 Actor_ShowEmote(9, 0x100, 40);
1697 TolbiShipInteriors_Say(0x8009);
1698 Actor_ShowEmote(11, 0x101, 60);
1700 Actor_ShowEmote(12, 0x102, 20);
1701 TolbiShipInteriors_Say(actor12Speech);
1702 Actor_ShowEmote(8, 0x103, 20);
1703 Engine_ActorJump(8, 4, 0);
1704 Actor_FaceDirection(8, 0x5000, 20);
1709 Actor_ShowEmote(13, 0x101, 60);
1711 TolbiShipInteriors_Turn(8, 0x3000);
1714 // Settle the passengers into their positions for the next cabin visit.
1715 Actor_WalkToAndWait(12, 444, 628);
1716 TolbiShipInteriors_Turn(12, 0xd000);
1717 TolbiShipInteriors_Say(0x900c);
1718 Actor_FaceDirection(8, 0x5000, 20);
1721 Actor_ShowEmote(11, 0x102, 60);
1722 TolbiShipInteriors_Say(0x100b);
1723 Actor_ShowEmote(13, 0x107, 40);
1726 TolbiShipInteriors_Turn(9, 0x3000);
1728 TolbiShipInteriors_Say(0x1009);
1733 Actor_ShowEmote(12, 0x105, 0);
1734 Actor_ShowEmote(9, 0x105, 60);
1735 Camera_SetSpeed(0x13333, 0x2666);
1737 0x10000000);
1742 Actor_ShowEmote(10, 0x102, 40);
1745 Actor_ShowEmote(10, 0x100, 0);
1746 Engine_ActorJump(10, 4, 40);
1750 Actor_SetSpeed(13, PIXELS(1), PIXELS(1) / 2);
1751 Actor_WalkTo(13, 438, 659);
1753 Actor_FaceDirection(9, 0xb000, 0);
1754 Actor_FaceDirection(12, 0x3000, 0);
1755 Actor_FaceDirection(11, 0xb000, 0);
1757 Actor_SetSpeed(10, PIXELS(1), PIXELS(1) / 2);
1758 Actor_WalkToAndWait(10, 488, 686);
1759 Actor_FaceDirection(10, 0xb000, 0);
1762 Actor_FaceDirection(13, 0xd000, 0);
1765}
1766
1767/// Returns the captain's lucky anchor and agrees to protect the ship.
1769 struct FieldActor *actor;
1770 s32 requestA;
1771 s32 requestB;
1772 s32 value;
1773 s32 requestC;
1774 const s32 *action;
1775
1776 // Let the captain explain why the anchor matters and ask the party to help.
1780 Actor_ShowEmote(8, 0x100, 40);
1781 requestA = 0x1008;
1783 Engine_EventSetMessage(MsgTolbiShipItsMyLuckyAnchor);
1784 TolbiShipInteriors_Say(requestA);
1790 Actor_FaceDirection(9, 0xd000, 0);
1791 Actor_FaceDirection(12, 0xd000, 0);
1792 Actor_FaceDirection(11, 0xd000, 0);
1793 Actor_FaceDirection(13, 0xd000, 0);
1794 Actor_FaceDirection(10, 0xb000, 20);
1796 Event_OpenMessage(requestA, 0);
1797 if (Engine_EventChooseYesNo(0, 0) == 0) {
1799 TolbiShipInteriors_Say(0x9009);
1800 Actor_ShowEmote(8, 0x108, 40);
1801 TolbiShipInteriors_Say(requestA);
1802 gEventWork->message += 2;
1803 } else {
1804 gEventWork->message += 2;
1806 TolbiShipInteriors_Say(0x9009);
1808 TolbiShipInteriors_Say(0x9008);
1809 }
1810 Actor_ShowEmote(13, 0x105, 40);
1811 Camera_SetSpeed(0xcccc, 0x1999);
1812 Camera_MoveTo(PIXELS(472), -1, PIXELS(636), 1);
1813 Actor_SetSpeed(13, PIXELS(1), PIXELS(1) / 2);
1814 Actor_WalkToAndWait(13, 472, 662);
1815 TolbiShipInteriors_Turn(13, 0xb000);
1817 TolbiShipInteriors_Turn(8, 0x5000);
1824 Engine_EventWait(20);
1826 TolbiShipInteriors_Turn(12, 0x3000);
1828 Actor_FaceDirection(11, 0xb000, 20);
1829 Actor_ShowEmote(11, 0x101, 40);
1831 requestB = 0x900c;
1832 TolbiShipInteriors_Turn(12, 0xd000);
1834 TolbiShipInteriors_Say(requestB);
1835 TolbiShipInteriors_Turn(13, 0xb000);
1838 Actor_ShowEmote(9, 0x100, 20);
1839 TolbiShipInteriors_Turn(9, 0x3000);
1843 TolbiShipInteriors_Say(requestB);
1846 TolbiShipInteriors_Turn(12, 0xd000);
1848 TolbiShipInteriors_Say(requestB);
1850 TolbiShipInteriors_Turn(11, 0xb000);
1853 TolbiShipInteriors_Say(requestB);
1854 Actor_FaceDirection(8, 0x3000, 0);
1856 Actor_FaceDirection(11, 0xd000, 0);
1857 Actor_FaceDirection(13, 0xd000, 0);
1858 // Bring the rest of the party out beside Isaac for the agreement.
1862 actor = Object_GetById(0);
1863 if (actor != 0) {
1864 Actor_SetPosition(GARET, actor->x.fixed, actor->z.fixed);
1865 }
1866 Actor_SetSpeed(GARET, PIXELS(1), PIXELS(1) / 2);
1867 Actor_WalkToAndWait(GARET, 486, 624);
1869 actor = Object_GetById(1);
1870 if (actor != 0) {
1871 Actor_SetPosition(IVAN, actor->x.fixed, actor->z.fixed);
1872 }
1873 Actor_SetSpeed(IVAN, PIXELS(1), PIXELS(1) / 2);
1874 Actor_WalkToAndWait(IVAN, 486, 640);
1876 actor = Object_GetById(2);
1877 if (actor != 0) {
1878 Actor_SetPosition(MIA, actor->x.fixed, actor->z.fixed);
1879 }
1880 Actor_SetSpeed(MIA, PIXELS(1), PIXELS(1) / 2);
1881 Actor_WalkToAndWait(MIA, 486, 656);
1883 Actor_ShowEmote(12, 0x108, 40);
1884 TolbiShipInteriors_Say(requestB);
1886 TolbiShipInteriors_Say(0x1009);
1888 TolbiShipInteriors_Turn(8, 0x5000);
1890 TolbiShipInteriors_Turn(8, 0x3000);
1891 Event_OpenMessage(8, 0);
1892 if (Engine_EventChooseYesNo(0, 0) == 1) {
1896 TolbiShipInteriors_Say(requestB);
1898 Event_ShowMessageAndWait(0x9009, 0, 40);
1899 gEventWork->message += 1;
1900 } else {
1901 gEventWork->message += 3;
1903 Event_ShowMessageAndWait(8, 0, 40);
1904 }
1908 value = 176;
1909 TolbiShipInteriors_Turn(8, 0x5000);
1912 TolbiShipInteriors_Turn(13, (value << 8));
1913 Event_ShowMessageAndWait(13, 0, 20);
1915 Actor_SetSpeed(8, PIXELS(4) / 5, PIXELS(2) / 5);
1916 requestC = 0x4008;
1917 Actor_WalkToAndWait(8, 472, 632);
1918 TolbiShipInteriors_Say(requestC);
1919 Actor_ShowEmote(13, 0x103, 40);
1923 Event_ShowMessageAndWait(requestC, 0, 40);
1925 TolbiShipInteriors_Turn(11, (value << 8));
1926 TolbiShipInteriors_Say(0x100b);
1927 Actor_ShowEmote(10, 0x102, 20);
1928 Actor_SetSpeed(10, PIXELS(12) / 5, PIXELS(6) / 5);
1929 Engine_ActorJump(10, 2, 0);
1930 Actor_WalkToAndWait(10, 462, 674);
1931 TolbiShipInteriors_Turn(10, (value << 8));
1934 TolbiShipInteriors_Turn(9, 0x5000);
1938 TolbiShipInteriors_Say(requestC);
1939 Actor_ShowEmote(13, 0x102, 40);
1940 Event_ShowMessageAndWait(13, 0, 40);
1941 TolbiShipInteriors_Turn(9, 0x3000);
1943 TolbiShipInteriors_Say(0x1009);
1946 Actor_FaceDirection(9, 0x5000, 0);
1947 Actor_FaceDirection(11, (value << 8), 0);
1948 Actor_FaceDirection(13, (value << 8), 0);
1949 Actor_FaceDirection(10, (value << 8), 20);
1952 Actor_ShowEmote(8, 0x101, 40);
1953 TolbiShipInteriors_Turn(8, 0xd000);
1955 if (Engine_EventChooseYesNo(0, 0) == 0) {
1957 TolbiShipInteriors_Say(0x1008);
1958 gEventWork->message += 1;
1959 } else {
1960 gEventWork->message += 1;
1961 TolbiShipInteriors_Say(0x1008);
1962 }
1965 TolbiShipInteriors_Say(0x1008);
1966 TolbiShipInteriors_Turn(8, 0x8000);
1967 TolbiShipInteriors_Say(0x4008);
1974 Engine_EventWait(20);
1975 // Send the crew away and merge the party's separate scene actors again.
1977 Actor_SetActionScript(10, action);
1979 Actor_SetActionScript(11, action);
1981 Actor_SetActionScript(12, action);
1983 Actor_SetActionScript(9, action);
1985 actor = Object_GetById(2);
1986 if (actor != 0) {
1987 Actor_SetDestination(MIA, actor->x.part.pixel, actor->z.part.pixel);
1988 }
1990 Actor_SetPosition(MIA, 0, 0);
1992 actor = Object_GetById(1);
1993 if (actor != 0) {
1994 Actor_SetDestination(IVAN, actor->x.part.pixel, actor->z.part.pixel);
1995 }
1997 Actor_SetPosition(IVAN, 0, 0);
1999 actor = Object_GetById(0);
2000 if (actor != 0) {
2001 Actor_SetDestination(GARET, actor->x.part.pixel, actor->z.part.pixel);
2002 }
2004 Actor_SetPosition(GARET, 0, 0);
2005 Actor_SetActionScript(13, action);
2006 Actor_WalkToAndWait(8, 456, 648);
2011}
2012
2013/// Restores the room or plays the event selected by this entrance.
2015 Engine_TaskWait(1);
2018 switch (gGameState.entrance) {
2019 case 1:
2020 case 2:
2021 case 11:
2027 }
2028 break;
2029 case 4:
2030 case 12:
2031 case 15:
2032 case 16:
2033 case 17:
2034 case 18:
2035 case 19:
2036 case 20:
2037 case 21:
2038 case 23:
2039 case 24:
2041 break;
2042 case 5:
2046 }
2047 break;
2048 }
2049 switch (gGameState.entrance) {
2050 case 1:
2051 case 2:
2053 break;
2054 case 4:
2056 break;
2057 case 5:
2059 break;
2060 case 10:
2063 } else {
2065 }
2066 break;
2067 case 11:
2070 } else {
2072 }
2073 break;
2074 case 12:
2076 break;
2077 case 13:
2079 break;
2080 case 14:
2082 break;
2083 case 15:
2087 0);
2096 } else {
2098 }
2099 break;
2100 case 16:
2102 break;
2103 case 17:
2107 0);
2112 } else {
2114 }
2115 break;
2116 case 18:
2118 break;
2119 case 19:
2123 0);
2130 } else {
2132 }
2133 break;
2134 case 20:
2136 break;
2137 case 21:
2142 0xc80);
2144 }
2145 } else {
2147 }
2148 break;
2149 case 22:
2151 break;
2152 case 23:
2155 }
2156 break;
2157 case 24:
2159 break;
2160 case 30:
2165 Engine_GameFlagSet(0x902);
2167 break;
2168 }
2169 return 0;
2170}
2171
2172/// Restores the cabin's actors after the anchor and departure conversations.
2174 struct FieldActor *actor;
2175 struct FieldActor *other;
2176 s32 done;
2177 s32 x;
2178 s32 heading;
2179 u16 zero;
2180
2183 return;
2184 }
2187 }
2189 if (done != 0) {
2190 return;
2191 }
2193 actor = Object_GetById(9);
2195 TolbiShipInteriors_PlaceActor(8, 456, 652, 0);
2196 x = 0x1e0;
2197 TolbiShipInteriors_PlaceActor(9, x, 600, 0xb000);
2198 Actor_SetSpeed(9, PIXELS(4) / 5, PIXELS(2) / 5);
2199 actor->work = done;
2200 zero = 0;
2201 actor->riseEnabled = zero;
2202 actor->collisionFlags |= 128;
2204 other = Object_GetById(8);
2205 other->riseCounter = zero;
2208 TolbiShipInteriors_PlaceActor(0, x, 666, 0xa000);
2209 }
2211 TolbiShipInteriors_PlaceActor(8, 444, 614, 0xd000);
2214 TolbiShipInteriors_PlaceActor(8, 456, 648, 0);
2217 heading = 0xb000;
2218 TolbiShipInteriors_PlaceActor(8, 475, 598, 0x8000);
2219 TolbiShipInteriors_PlaceActor(9, 462, 618, heading);
2220 Object_GetById(12)->facing = 0x3000;
2221 Object_GetById(11)->facing = heading;
2222 TolbiShipInteriors_PlaceActor(13, 438, 659, 0xd000);
2223 TolbiShipInteriors_PlaceActor(10, 488, 688, heading);
2224 }
2225}
2226
2227/// Restores the passenger hold after recruitment and departure events.
2230 Engine_ActorSetPosition(8, 0, 0);
2231 Engine_ActorSetPosition(9, 0, 0);
2232 Engine_ActorSetPosition(10, 0, 0);
2233 Engine_ActorSetPosition(11, 0, 0);
2234 Engine_ActorSetPosition(12, 0, 0);
2236 return;
2237 }
2238
2240 TolbiShipInteriors_PlaceActor(8, 152, 444, 0x3000);
2242 TolbiShipInteriors_PlaceActor(10, 184, 480, 0xb000);
2243 TolbiShipInteriors_PlaceActor(12, 170, 488, 0xb000);
2244 TolbiShipInteriors_PlaceActor(13, 136, 488, 0xd000);
2245 TolbiShipInteriors_PlaceActor(15, 120, 480, 0xd000);
2246 TolbiShipInteriors_PlaceActor(14, 184, 526, 0xb000);
2247 TolbiShipInteriors_PlaceActor(11, 136, 584, 0x8000);
2249 return;
2250 }
2251
2254 return;
2255 }
2256
2259 return;
2260 }
2261
2265 Engine_ActorSetPosition(12, 0, 0);
2266 }
2267}
2268
2269/// Restores the rowing deck and introduces a newly recruited replacement.
2271 Engine_TaskWait(1);
2275 TolbiShipInteriors_PlaceActor(8, 412, 222, 12288);
2276 TolbiShipInteriors_PlaceActor(9, 458, 161, 32768);
2277 } else {
2279 Actor_SetPosition(8, PIXELS(472), PIXELS(152));
2282 } else {
2287 } else {
2292 } else {
2295 0);
2298 } else {
2301 0);
2302 Actor_SetPosition(10, 0, 0);
2304 } else {
2308 0) {
2310 }
2311 }
2312 }
2313 }
2314 }
2315 }
2316 }
2317}
2318
2319/// Sets collision bit 3 on the eight actors surrounding the rowing seats.
2321 u32 actorId;
2322
2323 for (actorId = 28; actorId <= 35; actorId++) {
2324 struct FieldActor *actor = Object_GetById(actorId);
2325 u32 flags = actor->collisionFlags;
2326 actor->collisionFlags = flags | 0x08;
2327 }
2328}
2329
2330/// Puts each recruited rower at its seat and hides the original occupant.
2332 s32 actor;
2333
2335 return;
2336 }
2337 if ((actor = TolbiShipInteriors_FindFirstSetFlag(0, 0)) != 0) {
2338 TolbiShipInteriors_PlaceActor(actor, 410, 172, 0xd000);
2339 Engine_ActorSetPosition(10, 0, 0);
2340 }
2342 return;
2343 }
2344 if ((actor = TolbiShipInteriors_FindFirstSetFlag(1, 0)) != 0) {
2345 TolbiShipInteriors_PlaceActor(actor, 470, 172, 0xb000);
2346 Engine_ActorSetPosition(11, 0, 0);
2347 }
2349 return;
2350 }
2351 if ((actor = TolbiShipInteriors_FindFirstSetFlag(2, 0)) != 0) {
2352 TolbiShipInteriors_PlaceActor(actor, 410, 204, 0xd000);
2353 Engine_ActorSetPosition(12, 0, 0);
2354 }
2355 if (gated) {
2356 return;
2357 }
2358 if ((actor = TolbiShipInteriors_FindFirstSetFlag(3, 0)) != 0) {
2359 TolbiShipInteriors_PlaceActor(actor, 470, 204, 0xb000);
2360 Engine_ActorSetPosition(13, 0, 0);
2361 }
2362}
2363
2364/// The crew explains the missing replacements and asks the party to find
2365/// rowers.
2367 struct FieldActor *actor;
2368 s32 mode;
2369
2370 // Bring Isaac to the crewman who explains the shortage of rowers.
2374 TolbiShipInteriors_MoveCameraAndWait(PIXELS(440), -1, PIXELS(168), 0x1000001);
2375 TolbiShipInteriors_PlaceActor(27, 440, 164, 0x5000);
2376 TolbiShipInteriors_PlaceActor(8, 428, 190, 0xd000);
2377 TolbiShipInteriors_PlaceActor(9, 452, 190, 0xb000);
2379 mode = 128;
2380 TolbiShipInteriors_PlaceActor(0, 440, 134, 0x8000);
2381 gEventWork->startTransition = (mode << 1);
2389 Engine_EventSetMessage(MsgTolbiShipOurReplacementNeverArrivedBut);
2395 TolbiShipInteriors_Turn(27, 0xd000);
2396 actor = Object_GetById(0);
2397 if (actor != 0) {
2398 Actor_SetPosition(GARET, actor->x.fixed, actor->z.fixed);
2399 }
2400 Actor_SetSpeed(GARET, PIXELS(4) / 5, PIXELS(2) / 5);
2401 Actor_WalkToAndWait(GARET, 440, 148);
2403 actor = Object_GetById(1);
2404 if (actor != 0) {
2405 Actor_SetPosition(IVAN, actor->x.fixed, actor->z.fixed);
2406 }
2407 Actor_SetSpeed(IVAN, PIXELS(4) / 5, PIXELS(2) / 5);
2408 Actor_WalkToAndWait(IVAN, 456, 148);
2410 actor = Object_GetById(2);
2411 if (actor != 0) {
2412 Actor_SetPosition(MIA, actor->x.fixed, actor->z.fixed);
2413 }
2414 Actor_SetSpeed(MIA, PIXELS(4) / 5, PIXELS(2) / 5);
2415 Actor_WalkToAndWait(MIA, 472, 148);
2417 // Let the full party respond to the request for replacement oarsmen.
2421 Actor_FaceDirection(27, 0x5000, 20);
2424 Actor_ShowEmote(9, (mode << 1), 40);
2427 Actor_ShowEmote(GARET, 0x103, 60);
2443 Actor_ShowEmote(8, 0x102, 60);
2450 Actor_ShowEmote(8, 0x102, 0);
2451 Actor_ShowEmote(8, 0x102, 40);
2454 Event_ShowMessageAndWait(27, 0, 20);
2457 Engine_EventWait(40);
2458 Actor_ShowEmote(9, (mode << 1), 20);
2459 TolbiShipInteriors_Turn(9, 0xb000);
2461 TolbiShipInteriors_Turn(27, 0x3000);
2462 Actor_ShowEmote(27, 0x101, 60);
2463 Event_ShowMessageAndWait(27, 0, 60);
2464 Actor_ShowEmote(27, 0x106, 20);
2465 TolbiShipInteriors_Turn(27, 0xb000);
2469 TolbiShipInteriors_Turn(8, 0xd000);
2475 TolbiShipInteriors_Turn(27, 0x5000);
2479 Actor_SetSpeed(27, PIXELS(4) / 5, PIXELS(2) / 5);
2480 Actor_WalkToAndWait(27, 408, 158);
2481 Actor_WalkToAndWait(27, 408, 148);
2487 Actor_WalkToAndWait(27, 408, 134);
2488 Actor_WalkTo(27, 440, 134);
2489 Engine_EventWait(40);
2492}
2493
2494/// Raises the anchor charm and announces the ship's first departure.
2496 struct FieldActor *anchorCharm;
2497
2501 Engine_EventWait(20);
2502 Actor_SetSpeed(8, PIXELS(4) / 5, PIXELS(2) / 5);
2503 Actor_WalkToAndWait(8, 468, 614);
2504 Actor_WalkToAndWait(8, 472, 596);
2506 Engine_ActorJump(8, 4, 20);
2508 Engine_EventWait(20);
2511 Engine_EventWait(40);
2513 Engine_EventWait(20);
2514 Actor_WalkToAndWait(8, 466, 624);
2515 TolbiShipInteriors_Turn(8, 0x5000);
2517 Engine_EventSetMessage(MsgTolbiShipCastOff);
2518 Event_ShowMessageAndWait(8, 0, 20);
2520}
2521
2522/// Announces departure after a replacement rower has joined the crew.
2526 Actor_FaceDirection(8, 0x5000, 40);
2528 Engine_EventSetMessage(MsgTolbiShipWereOff);
2529 Event_ShowMessageAndWait(8, 0, 20);
2531}
2532
2533/// Calls the first passenger to the rowing deck.
2539 Actor_SetPosition(16, PIXELS(150), PIXELS(586));
2540 TolbiShipInteriors_MoveCameraAndWait(PIXELS(156), -1, PIXELS(536), 0x1000001);
2542 Actor_SetSpeed(16, PIXELS(4) / 5, PIXELS(2) / 5);
2543 Actor_WalkToAndWait(16, 168, 578);
2544 Actor_WalkToAndWait(16, 168, 554);
2547 Engine_EventSetMessage(MsgTolbiShipRowThoseOars);
2548 Event_ShowMessageAndWait(16, 0, 20);
2550}
2551
2552/// Calls a replacement rower back to the rowing deck.
2557 Actor_SetPosition(18, PIXELS(150), PIXELS(586));
2558 TolbiShipInteriors_MoveCameraAndWait(PIXELS(156), -1, PIXELS(536), 0x1000001);
2560 Actor_SetSpeed(18, PIXELS(4) / 5, PIXELS(2) / 5);
2561 Actor_WalkToAndWait(18, 168, 578);
2562 Actor_WalkToAndWait(18, 168, 554);
2565 Engine_EventSetMessage(MsgTolbiShipRowThoseOars);
2566 Event_ShowMessageAndWait(18, 0, 20);
2568}
2569
2570/// Restores the rowing deck for the current set of selected passengers.
2579 Engine_CameraSetSpeed(0x6666, 0xccc);
2580 Engine_CameraMoveTo(0x1b80000, -1, 0xb00000, 1);
2581 Engine_EventWait(20);
2583 Engine_EventWait(30);
2585 Engine_EventWait(30);
2587 Engine_EventWait(0x50);
2589 Engine_EventWait(0x3c);
2591 Engine_EventWait(30);
2593 Engine_EventWait(30);
2595 Engine_EventWait(0x50);
2597 Engine_EventWait(0x5a);
2599 Engine_EventWait(30);
2600
2602
2604
2610 0) {
2614 } else {
2616 }
2617}
2618
2619/// Asks the crew about the monsters before returning belowdecks.
2624 Engine_EventWait(10);
2625 Actor_FaceDirection(8, 0x3000, 20);
2627 Engine_EventSetMessage(MsgTolbiShipMonsters);
2628 Event_ShowMessageAndWait(8, 0, 20);
2630}
2631
2632/// Announces the ship's next turn and returns control to the rowing deck.
2635 Camera_MoveTo(-1, -1, -1, 0);
2636 Engine_TaskWait(1);
2639 Engine_EventSetMessage(MsgTolbiShipImTurning);
2641 Actor_FaceDirection(8, 0xd000, 40);
2643}
2644
2645/// Stages the first monster encounter with the original rowers.
2647 const s32 *entryScript;
2648
2656 entryScript = gTolbiShipInteriors_MonsterBob;
2657 Actor_SetActionScript(36, entryScript);
2658 Actor_SetActionScript(37, entryScript);
2659 Actor_SetActionScript(38, entryScript);
2665}
2666
2667/// Restores the original rowers after the first monster attack.
2676}
2677
2678/// Introduces the selected passenger and leads them to the open rowing seat.
2680 s32 rowerId;
2681 struct FieldActor *actor;
2682 s32 halfStep;
2683 s32 leftSeat;
2684 s32 x;
2685
2688 x = 0x1b0;
2689 halfStep = PIXELS(1) / 2;
2692 Engine_TaskWait(1);
2694 Actor_SetSpeed(0, PIXELS(4) / 5, PIXELS(2) / 5);
2695 Actor_WalkToAndWait(0, 406, 134);
2696 Actor_WalkToAndWait(0, 406, 152);
2697 Actor_WalkToAndWait(0, 421, 152);
2699 Engine_EventWait(20);
2700 Engine_ActorFaceEachOther(27, 0, 10);
2702 rowerId = TolbiShipInteriors_FindFirstSetFlag(seat, 0);
2704 Engine_EventWait(20);
2705 Engine_ActorFaceEachOther(27, 0, 10);
2706 Engine_EventSetMessage(MsgTolbiShipBackBroughtOarsman);
2709 leftSeat = 0;
2710 Actor_SetSpeed(0, PIXELS(1), halfStep);
2713 actor = Object_GetById(0);
2714 if (actor != 0) {
2715 Engine_ActorSetPosition(rowerId, actor->x.fixed, actor->z.fixed);
2716 }
2717 Actor_SetSpeed(rowerId, PIXELS(1), halfStep);
2718 Actor_WalkToAndWait(rowerId, 448, 168);
2719 Actor_FaceDirection(rowerId, 0xb000, 20);
2720 Actor_FaceDirection(27, 0x3000, 20);
2723 Actor_ShowEmote(rowerId, 0x102, 60);
2730 Actor_FaceDirection(27, 0x3000, 0);
2731 Actor_WalkToAndWait(rowerId, 470, 204);
2732 TolbiShipInteriors_Turn(rowerId, 0xb000);
2734 0) {
2735 Actor_WalkToAndWait(0, 422, 154);
2737 Actor_FaceDirection(27, 0x5000, 0);
2738 Actor_WalkToAndWait(rowerId, 410, 204);
2739 leftSeat = 1;
2740 TolbiShipInteriors_Turn(rowerId, 0xd000);
2742 0) {
2744 Actor_FaceDirection(27, 0x3000, 0);
2745 Actor_WalkToAndWait(rowerId, 470, 172);
2746 TolbiShipInteriors_Turn(rowerId, 0xb000);
2747 } else {
2748 Actor_WalkToAndWait(0, 422, 154);
2750 Actor_FaceDirection(27, 0x5000, 0);
2751 Actor_WalkToAndWait(rowerId, 410, 172);
2752 leftSeat = 1;
2753 TolbiShipInteriors_Turn(rowerId, 0xd000);
2754 }
2755 Engine_ActorFaceEachOther(27, 0, 20);
2756 TolbiShipInteriors_Say(0x201b);
2759 Actor_SetSpeed(27, PIXELS(1), PIXELS(1) / 2);
2760 if (leftSeat != 0) {
2761 Actor_WalkToAndWait(27, 428, 164);
2762 Actor_WalkToAndWait(27, 408, 164);
2763 }
2764 Actor_WalkToAndWait(27, 408, 134);
2765 Engine_ActorWalkTo(27, 0x1b8, 134);
2766 Engine_EventWait(40);
2768 } else {
2769 Engine_EventSetMessage(MsgTolbiShipBack);
2771 Engine_ActorShowEmote(27, 0x101, 60);
2774 Engine_EventWait(60);
2775 Actor_ShowEmote(27, 0x103, 40);
2778 Engine_ActorShowEmote(27, 0x105, 40);
2783 Engine_EventWait(20);
2785 }
2786}
2787
2788/// Creates the visible anchor charm once a visit (FLAG_SCENE_TEMP_00 records
2789/// it) and retains it for departure events.
2792 struct FieldActor *object;
2793 struct AnimationObject *sprite;
2794 u8 *buffer;
2795
2796 if (set != 0) {
2798 }
2799 object = Engine_ObjectCreate(22, 0x1c70000, 0x40000, 0x2200000);
2800 object->motionFlags = set;
2801 object->retainSpriteCache = 1;
2802 sprite = object->sprite;
2803 sprite->count = set;
2804 sprite->image.fullColor = 0;
2805 sprite->image.palette = 0;
2806 buffer = Engine_HeapAllocate(17, 0x608);
2808 Engine_VramLoad(sprite->slot, 128, buffer + 0x400);
2812 return object;
2813}
2814
2815/// Restores each replacement rower or the original occupant of that seat.
2819 Engine_ActorSetPosition(rowerId, PIXELS(410), PIXELS(172));
2821 action);
2822 Engine_ActorSetPosition(10, 0, 0);
2823 } else {
2825 }
2826
2829 Engine_ActorSetPosition(rowerId, PIXELS(470), PIXELS(172));
2830 Object_GetById(rowerId)->scaleX = -Q16_ONE;
2832 action);
2833 Engine_ActorSetPosition(11, 0, 0);
2834 } else {
2836 action);
2837 }
2838
2841 Engine_ActorSetPosition(rowerId, PIXELS(410), PIXELS(204));
2843 action);
2844 Engine_ActorSetPosition(12, 0, 0);
2845 } else {
2847 }
2848
2851 Engine_ActorSetPosition(rowerId, PIXELS(470), PIXELS(204));
2852 Object_GetById(rowerId)->scaleX = -Q16_ONE;
2854 action);
2855 Engine_ActorSetPosition(13, 0, 0);
2856 } else {
2858 action);
2859 }
2860
2863 action);
2866 action);
2867}
2868
2869/// Applies the seated pose and rowing action assigned to this rower.
2871 switch (id) {
2872 case 19:
2874 Object_SetActionById(id, 8);
2875 break;
2876 case 18:
2877 case 20:
2879 Object_SetActionById(id, 16);
2880 break;
2881 case 22:
2882 case 23:
2884 Object_SetActionById(id, 20);
2885 break;
2886 case 24:
2888 Object_SetActionById(id, 8);
2889 break;
2890 case 21:
2891 case 25:
2893 Object_SetActionById(id, 4);
2894 break;
2895 case 26:
2897 Object_SetActionById(id, 4);
2898 break;
2899 }
2900}
2901
2902static void TolbiShipInteriors_Say(s32 speaker) {
2903 Engine_EventShowMessage(speaker, 0);
2904 Engine_EventWait(10);
2905}
2906
2907/// Turns an actor to a facing over 10 frames.
2908static void TolbiShipInteriors_Turn(s32 actorId, u16 facing) {
2909 Engine_ActorFaceDirection(actorId, facing, 10);
2910}
2911
2912/// Places an actor at pixel coordinates and sets its initial heading.
2913static void TolbiShipInteriors_PlaceActor(s32 actorId, s32 x, s32 z,
2914 s32 facing) {
2915 Engine_ActorSetPosition(actorId, x << 16, z << 16, facing);
2916 Object_GetById(actorId)->facing = facing;
2917}
2918
2919/// Moves the camera, optionally waits or redraws, then honors the packed delay.
2921 u32 flags) {
2922 u32 selected;
2923
2924 Engine_CameraMoveTo(x, y, z, ~flags & 1);
2925 selected = flags & 0x1111;
2926 if ((flags & 0x10000000) != 0)
2928 if ((flags & 0x01000000) != 0)
2930 Engine_EventWait(selected);
2931}
2932
2933/// Reuses the voyage's actor, camera, transition and selection operations.
2934/// Each command names how it interprets the two arguments below.
2935static void TolbiShipInteriors_RunSceneCommand(s32 step, u32 arg, u32 opt) {
2936 u32 slot;
2937
2938 switch (step) {
2944 break;
2945 case SHIP_FACE_PARTY:
2947 Actor_FaceDirection(GARET, arg, 0);
2948 Actor_FaceDirection(IVAN, arg, 0);
2949 Actor_FaceDirection(MIA, arg, opt);
2950 break;
2956 if (arg != 0) {
2958 }
2959 if (opt == 0) {
2960 break;
2961 }
2962 Engine_EventWait(opt);
2963 break;
2969 Engine_EventWait(opt);
2970 break;
2972 for (slot = 0; slot < arg; slot++) {
2973 Actor_SetPosition(slot + 10, 0, 0);
2974 }
2975 break;
2977 struct FieldActor *actor;
2978
2979 actor = Object_GetById(arg);
2980 actor->facing = 0x5000;
2981 }
2983 Object_SetActionById(arg, opt);
2984 break;
2986 struct FieldActor *actor;
2987
2988 actor = Object_GetById(arg);
2989 actor->facing = 0x5000;
2990 actor->scaleX = -Q16_ONE;
2991 }
2993 Object_SetActionById(arg, opt);
2994 break;
2996 struct FieldActor *actor;
2997
2998 actor = Object_GetById(arg);
2999 actor->facing = 0x5000;
3000 }
3002 if (opt == 0) {
3003 Object_SetActionById(arg, 0);
3004 }
3005 break;
3006 case SHIP_OPEN_SCENE:
3009 if (arg != 0) {
3011 }
3013 break;
3014 case SHIP_CLOSE_SCENE:
3017 if (arg == 0) {
3018 break;
3019 }
3021 break;
3026 TolbiShipInteriors_PlaceActor(0, 432, 168, 0x4000);
3027 TolbiShipInteriors_PlaceActor(1, 448, 168, 0x4000);
3028 TolbiShipInteriors_PlaceActor(2, 424, 152, 0x4000);
3029 TolbiShipInteriors_PlaceActor(3, 458, 152, 0x4000);
3030 break;
3032 if (arg != 0) {
3033 struct FieldActor *actor;
3034
3036 actor = Object_GetById(13);
3037 actor->facing = 0x3000;
3038 actor = Object_GetById(13);
3039 actor->scaleX = Q16_ONE;
3040 }
3041 {
3042 struct FieldActor *actor;
3043
3045 actor = Object_GetById(14);
3046 actor->facing = 0x5000;
3048 actor = Object_GetById(15);
3049 actor->facing = 0x3000;
3050 actor = Object_GetById(15);
3051 actor->scaleX = Q16_ONE;
3053 actor = Object_GetById(16);
3054 actor->facing = 0x5000;
3056 actor = Object_GetById(17);
3057 actor->facing = 0x3000;
3058 actor = Object_GetById(17);
3059 actor->scaleX = Q16_ONE;
3060 }
3061 Actor_SetPosition(28, PIXELS(410), PIXELS(174));
3062 Actor_SetPosition(29, PIXELS(470), PIXELS(174));
3063 Actor_SetPosition(30, PIXELS(410), PIXELS(206));
3064 Actor_SetPosition(31, PIXELS(470), PIXELS(206));
3065 Actor_SetPosition(32, PIXELS(410), PIXELS(286));
3066 Actor_SetPosition(33, PIXELS(470), PIXELS(286));
3067 Actor_SetPosition(34, PIXELS(410), PIXELS(316));
3068 Actor_SetPosition(35, PIXELS(470), PIXELS(316));
3069 Engine_TaskWait(1);
3070 if (arg != 0) {
3071 Actor_FaceDirection(13, 0xb000, 0);
3072 }
3073 Actor_FaceDirection(14, 0xd000, 0);
3074 Actor_FaceDirection(15, 0xb000, 0);
3075 Actor_FaceDirection(16, 0xd000, 0);
3076 TolbiShipInteriors_Turn(17, 0xb000);
3077 break;
3079 struct FieldActor *actor;
3080
3081 actor = Object_GetById(arg);
3083 if (opt != 0) {
3084 actor->facing = 0x3000;
3085 } else {
3086 actor->facing = 0x5000;
3087 }
3088 actor->scaleX = Q16_ONE;
3089 } break;
3091 Actor_SetPosition(9, 0, 0);
3092 Actor_SetPosition(12, 0, 0);
3093 Actor_SetPosition(11, 0, 0);
3094 Actor_SetPosition(13, 0, 0);
3095 Actor_SetPosition(10, 0, 0);
3096 break;
3098 Actor_SetPosition(14, 0, 0);
3099 Actor_SetPosition(13, 0, 0);
3100 break;
3103 Actor_SetPosition(9, 0, 0);
3104 Actor_SetPosition(10, 0, 0);
3105 TolbiShipInteriors_PlaceActor(8, 444, 614, 0xd000);
3107 if (arg != 0) {
3109 }
3111 0x1000001);
3112 if (opt == 0) {
3113 break;
3114 }
3118 Engine_EventWait(20);
3119 break;
3121 Actor_SetPosition(8, 0, 0);
3122 Actor_SetPosition(9, 0, 0);
3123 Actor_SetPosition(27, PIXELS(438), PIXELS(152));
3124 break;
3126 slot = 0;
3127 do {
3128 Actor_SetPosition(slot + 28, 0, 0);
3129 slot++;
3130 } while (slot <= 7);
3131 break;
3133 TolbiShipInteriors_PlaceActor(12, 152, 532, 0xb000);
3134 TolbiShipInteriors_PlaceActor(8, 134, 490, 0x3000);
3135 TolbiShipInteriors_PlaceActor(9, 166, 490, 0x5000);
3136 TolbiShipInteriors_PlaceActor(10, 182, 504, 0x5000);
3137 TolbiShipInteriors_PlaceActor(11, 118, 504, 0x3000);
3139 break;
3141 TolbiShipInteriors_PlaceActor(8, 416, 328, 0);
3142 TolbiShipInteriors_PlaceActor(9, 448, 352, 0xd000);
3143 TolbiShipInteriors_PlaceActor(10, 454, 248, 0x3000);
3144 TolbiShipInteriors_PlaceActor(arg, 408, 290, 0);
3145 TolbiShipInteriors_PlaceActor(opt, 408, 342, 0);
3146 TolbiShipInteriors_PlaceActor(13, 420, 356, 0xd000);
3147 TolbiShipInteriors_PlaceActor(14, 408, 304, 0);
3148 TolbiShipInteriors_PlaceActor(15, 418, 378, 0xd000);
3149 TolbiShipInteriors_PlaceActor(16, 440, 262, 0x3000);
3150 TolbiShipInteriors_PlaceActor(17, 448, 378, 0xd000);
3151 break;
3153 for (slot = arg; slot <= opt; slot++) {
3154 GameFlag_Clear(slot);
3155 }
3156 break;
3170 break;
3172 Engine_TaskWait(1);
3175 break;
3180 break;
3181 case SHIP_RESET_CAMERA:
3182 Camera_MoveTo(-1, -1, -1, 0);
3183 Engine_TaskWait(1);
3184 if (arg != 0) {
3186 }
3187 break;
3191 Engine_TaskWait(1);
3192 if (arg == 1) {
3194 Engine_TaskWait(1);
3195 } else if (arg == 2) {
3198 Engine_TaskWait(1);
3199 } else if (arg == 3) {
3201 Engine_TaskWait(1);
3202 }
3203 break;
3204 }
3205}
3206
3207/// Finds the selected passenger or rowing-deck actor for a seat's flag group.
3209 s32 flag = 0;
3210 s32 id = 8;
3211 u32 i;
3212
3213 if (alternate == 0) {
3214 id = 18;
3215 }
3216 switch (group) {
3217 case 0:
3219 break;
3220 case 1:
3222 break;
3223 case 2:
3225 break;
3226 case 3:
3228 break;
3229 }
3230 for (i = 0; i <= 8; i++, flag++, id++) {
3231 if (Engine_GameFlagIsSet(flag) != 0) {
3232 return id;
3233 }
3234 }
3235 return 0;
3236}
3237
3238/// Hides the four passengers who are already filling rowing seats.
3248}
3249
3250/// Hides the passenger whose selection flag is set in this seat's flag group.
3252 s32 firstFlag) {
3253 unsigned int i = 0;
3254
3255 do {
3256 if (Engine_GameFlagIsSet(firstFlag) != 0) {
3257 Engine_ActorSetPosition(actorId, 0, 0);
3258 break;
3259 }
3260 i++;
3261 actorId++;
3262 firstFlag++;
3263 } while (i <= 8);
3264}
3265
3266/// Stages the next monster encounter with one replacement rower.
3268 s32 firstRower;
3269 const s32 *rowerScript;
3270 const s32 *entryScript;
3271
3272 firstRower = TolbiShipInteriors_FindFirstSetFlag(0, 0);
3278 12);
3280 rowerScript = gTolbiShipInteriors_Shiver;
3281 Actor_SetActionScript(firstRower, rowerScript);
3283 Actor_SetActionScript(12, rowerScript);
3284 entryScript = gTolbiShipInteriors_MonsterBob;
3285 Actor_SetActionScript(36, entryScript);
3286 Actor_SetActionScript(37, entryScript);
3289}
3290
3291/// Gathers the party after the crew reports monsters belowdecks.
3293 struct FieldActor *actor;
3294 s32 message;
3295
3296 TolbiShipInteriors_MoveCameraAndWait(PIXELS(440), -1, PIXELS(176), 0x1000001);
3306 actor = Object_GetById(0);
3307 if (actor != 0) {
3308 Actor_SetPosition(IVAN, actor->x.fixed, actor->z.fixed);
3309 }
3310 actor = Object_GetById(0);
3311 if (actor != 0) {
3312 Actor_SetPosition(GARET, actor->x.fixed, actor->z.fixed);
3313 }
3314 actor = Object_GetById(1);
3315 if (actor != 0) {
3316 Actor_SetPosition(MIA, actor->x.fixed, actor->z.fixed);
3317 }
3318 Engine_TaskWait(1);
3319 Actor_SetSpeed(IVAN, PIXELS(8) / 5, PIXELS(4) / 5);
3320 Actor_WalkTo(IVAN, 424, 152);
3321 Actor_SetSpeed(GARET, PIXELS(8) / 5, PIXELS(4) / 5);
3322 Actor_WalkTo(GARET, 448, 168);
3324 Actor_WalkToAndWait(MIA, 458, 152);
3331 message = MsgTolbiShipMonstersBelowdecks;
3332 UiText_ShowCenteredMessage(message, 1, 10);
3333 Engine_EventWait(10);
3336 Camera_SetSpeed(0x39999, 0x7333);
3338 0x10000014);
3340 TolbiShipInteriors_Turn(8, 0xd000);
3341 Engine_EventSetMessage(message + 1);
3345 0x10000000);
3349 Engine_EventWait(40);
3353}
3354
3355/// The crew checks on the party after the monster fight, then resumes rowing.
3357 const s32 *action;
3358
3359 TolbiShipInteriors_PlaceActor(0, 444, 300, 0);
3360 TolbiShipInteriors_PlaceActor(1, 458, 310, 0);
3361 TolbiShipInteriors_PlaceActor(2, 444, 330, 0);
3362 TolbiShipInteriors_PlaceActor(3, 432, 310, 0);
3363 TolbiShipInteriors_PlaceActor(27, 440, 134, 0x8000);
3364 TolbiShipInteriors_PlaceActor(10, 454, 248, 0x3000);
3366 TolbiShipInteriors_MoveCameraAndWait(PIXELS(440), -1, PIXELS(308), 0x1000001);
3369 Engine_EventWait(20);
3375 Engine_EventSetMessage(MsgTolbiShipHeyAreYouOk);
3378 Camera_SetSpeed(0x26666, 0x4ccc);
3379 Camera_MoveTo(PIXELS(440), -1, PIXELS(176), 1);
3380 Actor_SetSpeed(27, PIXELS(8) / 5, PIXELS(4) / 5);
3381 Actor_WalkToAndWait(27, 408, 134);
3382 Actor_WalkToAndWait(27, 408, 152);
3383 Actor_WalkToAndWait(27, 424, 164);
3384 Camera_SetSpeed(0x19999, 0x3333);
3385 Camera_MoveTo(PIXELS(440), -1, PIXELS(300), 1);
3386 Actor_WalkToAndWait(27, 424, 222);
3387 Actor_WalkToAndWait(27, 424, 262);
3388 Actor_FaceDirection(27, 0x3000, 20);
3400 Actor_MoveToAndWait(27, 0x1b0, 0x10c);
3401 Actor_MoveToAndWait(27, 0x1c4, 0x10c);
3403 TolbiShipInteriors_Turn(27, 0xd000);
3405 Event_ShowMessageAndWait(27, 0, 20);
3408 Engine_EventWait(40);
3409 Event_ShowMessageAndWait(27, 0, 80);
3411 Engine_EventWait(20);
3413 Engine_EventWait(10);
3414 TolbiShipInteriors_Turn(27, 0x5000);
3415 Event_OpenMessage(27, 0);
3416 if (Engine_EventChooseYesNo(0, 0) == 0) {
3419 } else {
3421 gEventWork->message += 1;
3427 }
3431 Actor_SetActionScript(IVAN, action);
3433 Camera_SetSpeed(0x9999, 0x1333);
3434 Camera_MoveTo(PIXELS(440), -1, PIXELS(176), 1);
3438 Engine_EventWait(60);
3444}
3445
3446/// Restores one replacement rower after the next monster attack.
3449
3455 Engine_ActorSetPosition(11, 0, 0);
3459}
3460
3461/// Stages the next monster encounter with two replacement rowers.
3463 s32 secondRower;
3464 s32 firstRower;
3465 const s32 *rowerScript;
3466 const s32 *entryScript;
3467
3468 firstRower = TolbiShipInteriors_FindFirstSetFlag(0, 0);
3469 secondRower = TolbiShipInteriors_FindFirstSetFlag(1, 0);
3475 secondRower);
3477 rowerScript = gTolbiShipInteriors_Shiver;
3478 Actor_SetActionScript(firstRower, rowerScript);
3480 Actor_SetActionScript(secondRower, rowerScript);
3482 entryScript = gTolbiShipInteriors_MonsterBob;
3483 Actor_SetActionScript(36, entryScript);
3484 Actor_SetActionScript(37, entryScript);
3489}
3490
3491/// Restores two replacement rowers after the next monster attack.
3495
3501 other);
3502 Engine_ActorSetPosition(11, 0, 0);
3503 Engine_ActorSetPosition(12, 0, 0);
3507}
3508
3509/// The party notices the ship rocking and discusses the rowers' progress.
3511 s32 secondRower;
3512 s32 thirdRower;
3513 s32 firstRower;
3514 struct FieldActor *actor;
3515 const s32 *action;
3516
3517 firstRower = TolbiShipInteriors_FindFirstSetFlag(0, 0);
3518 secondRower = TolbiShipInteriors_FindFirstSetFlag(1, 0);
3519 thirdRower = TolbiShipInteriors_FindFirstSetFlag(2, 0);
3520 // Restore the occupied rowing seats before showing the ship's movement.
3524 Actor_SetPosition(8, PIXELS(472), PIXELS(152));
3526 Actor_SetPosition(27, PIXELS(440), PIXELS(134));
3527 Actor_SetChildValue(27, 15);
3528 actor = Object_GetById(27);
3531 TolbiShipInteriors_MoveCameraAndWait(PIXELS(438), -1, PIXELS(174), 0x1000001);
3536 Engine_EventWait(10);
3537 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
3538 Engine_EventWait(80);
3541 Engine_EventWait(10);
3542 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
3546 Engine_EventWait(40);
3547 TolbiShipInteriors_Turn(3, 0x6000);
3548 // The party notices the rocking, then turns to the crew for an explanation.
3549 Engine_EventSetMessage(MsgTolbiShipWonderWhatsWrongShipShouldnt);
3561 Actor_ShowEmote(IVAN, 0x100, 60);
3562 TolbiShipInteriors_Turn(2, 0x2000);
3568 Engine_EventWait(10);
3573 Actor_SetChildValue(27, 0);
3574 actor = Object_GetById(27);
3576 Actor_SetSpeed(27, PIXELS(1), PIXELS(1) / 2);
3577 Actor_WalkToAndWait(27, 430, 134);
3578 TolbiShipInteriors_Turn(27, 0x3000);
3581 Engine_ActorStartRepeatedMotion(firstRower, 1);
3582 Engine_ActorStartRepeatedMotion(secondRower, 1);
3583 Engine_ActorStartRepeatedMotion(thirdRower, 1);
3585 Actor_SetAttachedEffect(firstRower, 0x102);
3586 Actor_SetAttachedEffect(secondRower, 0x102);
3587 Actor_SetAttachedEffect(thirdRower, 0x102);
3588 Actor_SetAttachedEffect(13, 0x102);
3589 Engine_EventWait(40);
3594 Actor_FaceDirection(firstRower, 0xd000, 0);
3595 Actor_FaceDirection(secondRower, 0xb000, 0);
3596 Actor_FaceDirection(thirdRower, 0xd000, 0);
3602 Event_ShowMessage(27, 0);
3607 Actor_WalkToAndWait(27, 440, 134);
3608 Actor_SetPosition(27, 0, 0);
3609 TolbiShipInteriors_Turn(1, 0x8000);
3613 TolbiShipInteriors_Turn(3, 0x8000);
3618 Actor_SetSpeed(GARET, PIXELS(1), PIXELS(1) / 2);
3619 Actor_SetSpeed(IVAN, PIXELS(1), PIXELS(1) / 2);
3620 Actor_SetSpeed(MIA, PIXELS(1), PIXELS(1) / 2);
3623 Actor_SetActionScript(IVAN, action);
3633}
3634
3635/// Plays the intermittent voyage cue and restores its effect after ten frames.
3637 s32 value;
3639 s32 remaining;
3640 if (*timer != 0) {
3641 remaining = *timer - 1;
3642 *timer = *timer - 1;
3643 if (remaining == 70)
3644 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
3645 } else {
3646 value = Engine_RandomNext();
3647 if (((u32)(((value << 4) - value) << 3) >> 16) == 0) {
3650 *timer = 80;
3651 }
3652 }
3653}
3654
3655/// Plays the short cabin exchange before returning to the voyage.
3659 TolbiShipInteriors_PlaceActor(9, 468, 616, 32768);
3662 Engine_EventWait(20);
3663 Actor_FaceDirection(8, 53248, 80);
3666 Engine_EventWait(20);
3668}
3669
3670/// Rests the rowers at the island and plays the selected passengers' responses.
3672 s32 fourthRower;
3673 s32 secondRower;
3674 s32 thirdRower;
3675 s32 firstRower;
3676 struct FieldActor *actor;
3677 s32 reaction = 0;
3678 const s32 *progressB;
3679 const s32 *progressC;
3680 const s32 *progressA;
3681
3682 firstRower = TolbiShipInteriors_FindFirstSetFlag(0, 0);
3683 secondRower = TolbiShipInteriors_FindFirstSetFlag(1, 0);
3684 thirdRower = TolbiShipInteriors_FindFirstSetFlag(2, 0);
3685 fourthRower = TolbiShipInteriors_FindFirstSetFlag(3, 0);
3686 // Restore all four selected rowers and announce the island stop.
3691 Actor_SetPosition(8, PIXELS(472), PIXELS(152));
3692 Actor_SetPosition(27, PIXELS(440), PIXELS(134));
3694 actor = Object_GetById(27);
3698 TolbiShipInteriors_MoveCameraAndWait(PIXELS(438), -1, PIXELS(174), 0x1000001);
3701 actor = Object_GetById(27);
3703 Actor_SetSpeed(27, PIXELS(1), PIXELS(1) / 2);
3704 Actor_WalkToAndWait(27, 408, 132);
3705 Actor_WalkToAndWait(27, 408, 142);
3706 Actor_FaceDirection(27, 0x3000, 20);
3708 Engine_EventSetMessage(MsgTolbiShipReachedIslandRowers);
3710 Engine_EventWait(120);
3716 Actor_FaceDirection(firstRower, 0xd000, 0);
3717 Actor_FaceDirection(secondRower, 0xb000, 0);
3718 Actor_FaceDirection(thirdRower, 0xd000, 0);
3719 Engine_ActorFaceDirection(fourthRower, 0xb000, 60);
3720 // The first rower's identity selects the response to the unexpected stop.
3722 reaction = 2;
3725 reaction = 1;
3726 }
3727 Engine_ActorRunRepeatedMotion(firstRower, 1);
3728 if (reaction == 1) {
3729 gEventWork->message += 1;
3730 } else if (reaction == 2) {
3731 gEventWork->message += 2;
3732 }
3733 Engine_ActorStartRepeatedMotion(firstRower, 2);
3734 TolbiShipInteriors_Say(firstRower);
3735 Engine_EventSetMessage(MsgTolbiShipShipWentOff);
3738 Actor_ShowEmote(firstRower, 0x102, 0);
3739 Actor_ShowEmote(secondRower, 0x102, 0);
3740 Actor_ShowEmote(thirdRower, 0x102, 0);
3741 Engine_ActorShowEmote(fourthRower, 0x102, 60);
3743 Actor_WalkToAndWait(27, 408, 132);
3744 Actor_WalkToAndWait(27, 444, 132);
3746 Engine_EventWait(40);
3747 if (reaction == 0 &&
3750 reaction = 3;
3751 }
3752 if (reaction == 0) {
3753 gEventWork->message += 1;
3754 } else if (reaction == 1) {
3755 gEventWork->message += 2;
3756 } else if (reaction == 2) {
3757 gEventWork->message += 3;
3758 }
3759 // Send the rowers and party back through their departure scripts.
3760 TolbiShipInteriors_Turn(firstRower, 0);
3761 TolbiShipInteriors_Say(firstRower);
3762 Actor_SetSpeed(firstRower, PIXELS(1), PIXELS(1) / 2);
3764 Actor_RunActionScriptAndWait(firstRower, progressB);
3765 Actor_FaceDirection(secondRower, 0x5000, 0);
3766 Engine_ActorFaceDirection(thirdRower, FACING_EAST, 0);
3767 Actor_FaceDirection(fourthRower, FACING_WEST, 40);
3768 Engine_ActorFaceDirection(secondRower, 0xd000, 0);
3769 Engine_ActorFaceDirection(thirdRower, 0xb000, 0);
3770 Engine_ActorFaceDirection(fourthRower, 0x5000, 20);
3771 Actor_SetSpeed(secondRower, PIXELS(1), PIXELS(1) / 2);
3772 Actor_SetSpeed(thirdRower, PIXELS(1), PIXELS(1) / 2);
3773 Actor_SetSpeed(fourthRower, PIXELS(1), PIXELS(1) / 2);
3774 Actor_SetActionScript(thirdRower, progressB);
3775 Engine_EventWait(40);
3777 Actor_RunActionScriptAndWait(secondRower, progressC);
3778 Actor_SetActionScript(secondRower, progressB);
3779 Actor_RunActionScriptAndWait(fourthRower, progressC);
3780 Actor_RunActionScriptAndWait(fourthRower, progressB);
3781 Actor_SetSpeed(1, PIXELS(1), PIXELS(1) / 2);
3782 Actor_SetSpeed(2, PIXELS(1), PIXELS(1) / 2);
3783 Actor_SetSpeed(3, PIXELS(1), PIXELS(1) / 2);
3785 Actor_SetActionScript(1, progressA);
3786 Actor_SetActionScript(2, progressA);
3787 Actor_RunActionScriptAndWait(3, progressA);
3793}
3794
3795/// Returns the replacement rowers to their seats and exchanges their
3796/// selections.
3798 s32 firstRower;
3799 s32 fourthRower;
3800 s32 thirdRower;
3801 s32 secondRower;
3802
3803 firstRower = TolbiShipInteriors_FindFirstSetFlag(0, 0);
3804 secondRower = TolbiShipInteriors_FindFirstSetFlag(1, 0);
3805 thirdRower = TolbiShipInteriors_FindFirstSetFlag(2, 0);
3806 fourthRower = TolbiShipInteriors_FindFirstSetFlag(3, 0);
3809 TolbiShipInteriors_PlaceActor(8, 472, 144, 0x5000);
3810 TolbiShipInteriors_PlaceActor(27, 408, 142, 0x3000);
3814 Engine_EventWait(40);
3816 Engine_EventSetMessage(MsgTolbiShipSorryEveryoneButWeNeed);
3818 Engine_ActorStartRepeatedMotion(firstRower, 2);
3819 Engine_ActorStartRepeatedMotion(secondRower, 2);
3820 Engine_ActorStartRepeatedMotion(thirdRower, 2);
3821 Engine_ActorRunRepeatedMotion(fourthRower, 2);
3822 Engine_EventWait(20);
3823 Actor_FaceDirection(firstRower, FACING_EAST, 0);
3824 Actor_FaceDirection(secondRower, FACING_WEST, 0);
3825 Actor_FaceDirection(thirdRower, FACING_EAST, 0);
3826 Actor_FaceDirection(fourthRower, FACING_WEST, 40);
3827 Actor_SetSpeed(firstRower, PIXELS(1), PIXELS(1) / 2);
3828 Actor_SetSpeed(secondRower, PIXELS(1), PIXELS(1) / 2);
3829 Actor_SetSpeed(thirdRower, PIXELS(1), PIXELS(1) / 2);
3830 Actor_SetSpeed(fourthRower, PIXELS(1), PIXELS(1) / 2);
3831 Actor_WalkTo(firstRower, 470, 172);
3832 Actor_WalkTo(secondRower, 410, 172);
3833 Actor_WalkTo(thirdRower, 470, 204);
3834 Actor_WalkToAndWait(fourthRower, 410, 204);
3835 Engine_ActorSetAnimation(firstRower, 1);
3836 Engine_ActorSetAnimation(secondRower, 1);
3837 Engine_ActorSetAnimation(thirdRower, 1);
3838 Actor_FaceDirection(secondRower, 0xd000, 0);
3839 Actor_FaceDirection(firstRower, 0xb000, 0);
3840 Actor_FaceDirection(fourthRower, 0xd000, 0);
3841 Actor_FaceDirection(thirdRower, 0xb000, 20);
3844 Engine_ActorSetAnimation(firstRower, 3);
3845 Engine_ActorSetAnimation(secondRower, 3);
3846 Engine_ActorSetAnimation(thirdRower, 3);
3847 Engine_ActorSetAnimationAndWait(fourthRower, 3);
3849 Engine_ActorSetAnimation(firstRower, 3);
3850 Engine_ActorSetAnimation(secondRower, 3);
3851 Engine_ActorSetAnimation(thirdRower, 3);
3852 Engine_ActorSetAnimationAndWait(fourthRower, 3);
3854 TolbiShipInteriors_Turn(0, 0x8000);
3857 Actor_SetSpeed(27, PIXELS(1), PIXELS(1) / 2);
3858 Actor_WalkToAndWait(27, 408, 132);
3859 Actor_WalkToAndWait(27, 444, 132);
3860 Actor_SetPosition(27, 0, 0);
3870}
3871
3872/// Exchanges the chosen passengers between two rowing seats.
3874 s32 secondSeatFlags) {
3875 s32 firstPassenger = 0;
3876 s32 secondPassenger = 0;
3877 u32 i;
3878
3879 for (i = 0; i <= 8; i++) {
3880 s32 flag = firstSeatFlags + i;
3881 if (Engine_GameFlagIsSet(flag) != 0) {
3883 break;
3884 }
3885 firstPassenger++;
3886 }
3887
3888 for (i = 0; i <= 8; i++) {
3889 s32 flag = secondSeatFlags + i;
3890 if (Engine_GameFlagIsSet(flag) != 0) {
3892 break;
3893 }
3894 secondPassenger++;
3895 }
3896
3897 Engine_GameFlagSet(secondSeatFlags + firstPassenger);
3898 Engine_GameFlagSet(firstSeatFlags + secondPassenger);
3899}
3900
3901/// The step beside the leader for each of the 16 facings: the high 16 bits are
3902/// x, the low 16 bits z.
3903#define TURN_STEP(dx, dz) (((dx) << 16) | ((dz) & 0xffff))
3904
3906 TURN_STEP(16, 0), TURN_STEP(16, 0), TURN_STEP(16, 0), TURN_STEP(0, 16),
3907 TURN_STEP(0, 16), TURN_STEP(0, 16), TURN_STEP(0, 16), TURN_STEP(-16, 0),
3908 TURN_STEP(-16, 0), TURN_STEP(-16, 0), TURN_STEP(-16, 0), TURN_STEP(0, -16),
3909 TURN_STEP(0, -16), TURN_STEP(0, -16), TURN_STEP(0, -16), TURN_STEP(16, 0),
3910};
3911
3912/// The warriors walk out of the hold.
3914 SC_ARG(2), SC_MOVE(PIXELS(168), 0, PIXELS(500)),
3915 SC_SYNC, SC_MOVE(PIXELS(168), 0, PIXELS(584)),
3917 SC_END,
3918};
3919
3920/// Those gathered in the cabin walk out.
3922 SC_SET(SW_SPEED, PIXELS(1)),
3923 SC_SET(SW_ACCEL, PIXELS(1) / 2),
3924 SC_ARG(2),
3925 SC_MOVE(PIXELS(456), 0, PIXELS(674)),
3926 SC_SYNC,
3927 SC_MOVE(PIXELS(456), 0, PIXELS(712)),
3928 SC_SYNC,
3930 SC_END,
3931};
3932
3933/// The Anchor Charm swells and shrinks twice as the captain raises it.
3935 SC_SET(SW_SCALE_X, 11 * Q16_ONE / 8),
3936 SC_SET(SW_SCALE_Y, 11 * Q16_ONE / 8),
3937 SC_WAIT(2),
3938 SC_SET(SW_SCALE_X, 3 * Q16_ONE / 2),
3939 SC_SET(SW_SCALE_Y, 3 * Q16_ONE / 2),
3940 SC_WAIT(2),
3941 SC_SET(SW_SCALE_X, 9 * Q16_ONE / 8),
3942 SC_SET(SW_SCALE_Y, 9 * Q16_ONE / 8),
3943 SC_WAIT(2),
3946 SC_WAIT(2),
3947 SC_LOOP(2, SC_TOP),
3948 SC_END,
3949};
3950
3951/// The party's followers walk into the leader by the rowing deck's stairs.
3953 SC_ARG(2), SC_MOVE(PIXELS(434), 0, PIXELS(166)),
3955 SC_END,
3956};
3957
3958/// The same, in the middle of the rowing deck.
3960 SC_ARG(2), SC_MOVE(PIXELS(438), 0, PIXELS(300)),
3962 SC_END,
3963};
3964
3965/// The same, by the first row of seats.
3967 SC_ARG(2), SC_MOVE(PIXELS(432), 0, PIXELS(168)),
3969 SC_END,
3970};
3971
3972/// Squashes and stretches the actor over and over: a shiver.
3976 SC_ADD(SW_SCALE_X, -0x5000),
3977 SC_ADD(SW_SCALE_Y, 0x1000),
3978 SC_WAIT(2),
3979 SC_ADD(SW_SCALE_X, 0x2800),
3980 SC_ADD(SW_SCALE_Y, -2048),
3981 SC_WAIT(2),
3982 SC_ADD(SW_SCALE_X, 0x1400),
3983 SC_ADD(SW_SCALE_Y, -1024),
3984 SC_WAIT(2),
3985 SC_ADD(SW_SCALE_X, 0x1400),
3986 SC_ADD(SW_SCALE_Y, -1024),
3987 SC_WAIT(2),
3989};
3990
3991/// A monster in the hold bobs in place.
3993 SC_SET(SW_MOTION, 0),
3994 SC_SET(0x24, 0),
3996};
3997
3998/// A rower walks up the stairs and is freed.
4000 SC_ARG(2), SC_MOVE(PIXELS(408), 0, PIXELS(132)),
4001 SC_SYNC, SC_MOVE(PIXELS(444), 0, PIXELS(132)),
4003};
4004
4005/// A rower steps into the aisle.
4007 SC_ARG(2),
4008 SC_MOVE(PIXELS(416), 0, PIXELS(186)),
4009 SC_SYNC,
4010 SC_END,
4011};
4012
4013/// A passenger glances about at random.
4016};
4017
4018/// Lies flat on the floor of the hold.
4021};
4022
4023/// The Anchor Charm's object, once placed this visit.
4025
4026/// The other scenes have no entrances.
4029};
4030
4031/// The hold (entrances 1, 2, 11 and 30), a side room (3), the rowing deck (4,
4032/// 12 and 15 to 24 but 22) and the cabin (5, 10, 13, 14 and 22).
4034 {1, CONDITION_ALWAYS, 152, 0, 584, FACING_NORTH, 0, 30, 380, 270, 620, 0},
4035 {2, CONDITION_ALWAYS, 160, 0, 552, FACING_EAST, 0, 30, 380, 270, 620, 0},
4036 {3, CONDITION_ALWAYS, 120, 0, 136, FACING_WEST, 0, 25, 80, 265, 350, 0},
4037 {4, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4038 {5, CONDITION_ALWAYS, 440, 0, 728, FACING_NORTH, 0, 315, 500, 555, 765, 0},
4039 {10, CONDITION_ALWAYS, 440, 0, 728, FACING_NORTH, 0, 315, 500, 555, 765, 0},
4040 {11, CONDITION_ALWAYS, 152, 0, 584, FACING_NORTH, 0, 30, 380, 270, 620, 0},
4041 {12, CONDITION_ALWAYS, 440, 0, 342, FACING_NORTH, 0, 315, 80, 555, 410, 0},
4042 {13, CONDITION_ALWAYS, 440, 0, 728, FACING_NORTH, 0, 315, 500, 555, 765, 0},
4043 {14, CONDITION_ALWAYS, 440, 0, 728, FACING_NORTH, 0, 315, 500, 555, 765, 0},
4044 {15, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4045 {16, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4046 {17, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4047 {18, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4048 {19, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4049 {20, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4050 {21, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 305, 60, 565, 430, 0},
4051 {22, CONDITION_ALWAYS, 444, 0, 632, FACING_NORTH, 0, 315, 500, 555, 765, 0},
4052 {23, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4053 {24, CONDITION_ALWAYS, 408, 0, 136, FACING_WEST, 0, 315, 80, 555, 410, 0},
4054 {30, CONDITION_ALWAYS, 166, 0, 570, FACING_NORTH, 0, 30, 380, 270, 620, 0},
4056};
4057
4059 SCENE_EXITS(111), SCENE_EXIT(1, 109, 1), SCENE_EXIT(2, 111, 4),
4060 SCENE_EXIT(3, 109, 2), SCENE_EXIT(4, 111, 2), SCENE_EXIT(5, 109, 3),
4061 SCENE_EXIT(10, 109, 10), SCENE_EXIT(11, 111, 11), SCENE_EXIT(12, 111, 12),
4062 SCENE_EXIT(13, 2, 65), SCENE_EXIT(14, 109, 11), SCENE_EXIT(15, 109, 12),
4063 SCENE_EXIT(16, 2, 66), SCENE_EXIT(17, 2, 67), SCENE_EXIT(18, 2, 68),
4064 SCENE_EXIT(19, 109, 15), SCENE_EXIT(20, 2, 69), SCENE_EXIT(21, 2, 75),
4066};
4067
4070};
4071
4072// clang-format off
4077 PIXELS(472), 0, PIXELS(626), FACING_WEST, TALK_KEEP_FACING, 0 },
4080 { SCENE_TABLE_END },
4081};
4082
4083/// The cabin once the warriors have come to see the captain, with the party's
4084/// followers.
4089 PIXELS(474), 0, PIXELS(624), FACING_SOUTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4091 PIXELS(464), 0, PIXELS(690), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4093 PIXELS(456), 0, PIXELS(648), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4095 PIXELS(444), 0, PIXELS(628), FACING_EAST, TALK_FACE_PARTY, 0 },
4099 0, 0, 0, FACING_EAST, TALK_KEEP_FACING, 0 },
4101 0, 0, 0, FACING_EAST, TALK_KEEP_FACING, 0 },
4103 0, 0, 0, FACING_EAST, TALK_KEEP_FACING, 0 },
4104 { SCENE_TABLE_END },
4105};
4106
4107/// The cabin once the ship has reached Tolbi.
4111 { SCENE_TABLE_END },
4112};
4113
4114/// The hold before the party hears of the delay at Kalay.
4117 PIXELS(150), 0, PIXELS(528), FACING_SOUTH, TALK_KEEP_FACING, 0 },
4118 { SCENE_TABLE_END },
4119};
4120
4121/// The hold while the ship waits at Kalay, and after it reaches Tolbi.
4130 PIXELS(120), 0, PIXELS(520), FACING_EAST, TALK_FACE_PARTY, 0 },
4132 PIXELS(130), 0, PIXELS(456), FACING_EAST, TALK_FACE_PARTY, 0 },
4134 PIXELS(142), 0, PIXELS(446), FACING_SOUTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4136 PIXELS(156), 0, PIXELS(466), FACING_WEST, TALK_FACE_PARTY, 0 },
4140 0, 0, 0, FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4142 PIXELS(150), 0, PIXELS(528), FACING_SOUTH, TALK_KEEP_FACING, 0 },
4143 { SCENE_TABLE_END },
4144};
4145
4146/// The hold at sea, once the passengers row.
4153 PIXELS(182), 0, PIXELS(492), FACING_WEST, TALK_FACE_PARTY, 0 },
4155 PIXELS(168), 0, PIXELS(492), FACING_EAST, TALK_FACE_PARTY, 0 },
4157 PIXELS(120), 0, PIXELS(480), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4161 PIXELS(172), 0, PIXELS(448), FACING_EAST, TALK_FACE_PARTY, 0 },
4163 PIXELS(180), 0, PIXELS(464), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4165 PIXELS(122), 0, PIXELS(516), FACING_EAST, TALK_FACE_PARTY, 0 },
4169 0, 0, 0, FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4171 PIXELS(150), 0, PIXELS(528), FACING_SOUTH, TALK_KEEP_FACING, 0 },
4172 { SCENE_TABLE_END },
4173};
4174
4175/// The rowing deck: the crew (actors 8 and 9), the oarsmen at the seats (10 to
4176/// 17), the passengers who may take a seat (18 to 26) and eight actors beside
4177/// the seats (28 to 35).
4180 PIXELS(438), 0, PIXELS(152), FACING_SOUTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4182 PIXELS(438), 0, PIXELS(374), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4184 PIXELS(410), 0, PIXELS(172), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4188 PIXELS(410), 0, PIXELS(204), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4192 PIXELS(410), 0, PIXELS(284), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4196 PIXELS(410), 0, PIXELS(314), FACING_NORTH + FACING_STEP, TALK_FACE_PARTY, 0 },
4200 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4202 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4204 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4206 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4208 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4210 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4212 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4214 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4216 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
4218 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
4219 { 0xbc, CONDITION_ALWAYS, 7,
4220 PIXELS(410), 0, PIXELS(174), FACING_EAST, TALK_FACE_PARTY, 0 },
4221 { 0xbc, CONDITION_ALWAYS, 7,
4223 { 0xbc, CONDITION_ALWAYS, 7,
4225 { 0xbc, CONDITION_ALWAYS, 7,
4227 { 0xbc, CONDITION_ALWAYS, 7,
4229 { 0xbc, CONDITION_ALWAYS, 7,
4231 { 0xbc, CONDITION_ALWAYS, 7,
4233 { 0xbc, CONDITION_ALWAYS, 7,
4235 { SCENE_TABLE_END },
4236};
4237
4238/// The party's followers, placed for a scene.
4241 0, 0, 0, FACING_EAST, TALK_KEEP_FACING, 0 },
4243 0, 0, 0, FACING_EAST, TALK_KEEP_FACING, 0 },
4245 0, 0, 0, FACING_EAST, TALK_KEEP_FACING, 0 },
4246 { SCENE_TABLE_END },
4247};
4248
4249/// The monsters of each attack, beside the seats.
4252 PIXELS(474), 0, PIXELS(300), FACING_WEST, TALK_KEEP_FACING, 0 },
4257 { SCENE_TABLE_END },
4258};
4259
4262 PIXELS(474), 0, PIXELS(300), FACING_WEST, TALK_KEEP_FACING, 0 },
4266 PIXELS(458), 0, PIXELS(310), FACING_WEST, TALK_KEEP_FACING, 0 },
4267 { SCENE_TABLE_END },
4268};
4269
4272 PIXELS(474), 0, PIXELS(300), FACING_WEST, TALK_KEEP_FACING, 0 },
4276 PIXELS(458), 0, PIXELS(310), FACING_WEST, TALK_KEEP_FACING, 0 },
4277 { SCENE_TABLE_END },
4278};
4279
4280/// The side room, and the cutscenes.
4282 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
4284 { SCENE_EVENTS_END },
4285};
4286
4287/// The hold while the ship waits at Kalay, and after it reaches Tolbi.
4289 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
4290 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
4293 { EVENT_TALK, 9, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsApparentlyWeCantTakeSilkRoad) },
4294 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsAllThatMoneyOnTicketsAnd) },
4296 { EVENT_TALK, 11, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsYoureGoingToTolbiToSee) },
4297 { EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsINeverThoughtIdGetTo) },
4298 { EVENT_TALK, 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouAllAgreedToHelpOf) },
4300 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsMaybeIShouldJustForgetAbout) },
4301 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfSomethingHappensToOurOarsmen) },
4302 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsTheyreJustTakingAdvantageOfUs) },
4303 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsDoTheyHonestlyThinkImGoing) },
4304 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsMusclesRipplingEverywhereLooksGreatIf) },
4305 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImSureItdBeEasierTo) },
4306 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsWeLeftTheOldLadyBack) },
4307 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWellShootMaybeWeShouldHave) },
4308 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsAskingThePassengersToHelpOut) },
4309 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsEvenThoughImOpposedToViolence) },
4310 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, FLAG_TOLBI_SHIP_REACHED_TOLBI, MSGNO(MsgTolbiShipInteriorsICantRowButIAm) },
4311 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeMadeItToColossoIn) },
4312 { SEARCH(SEARCH_BARREL), 101, 0xf93, FIND_COINS(23) },
4313 { SCENE_EVENTS_END },
4314};
4315
4316/// The hold at sea: talking to a passenger asks them to row.
4318 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
4319 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
4321 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIsThisCruelOrdealPartOf) },
4331 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsNobodyWouldChooseMeAfterAll) },
4332 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouMakeMeNervousJustStanding) },
4333 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsHeyLooksLikeTheyNeedSomeone) },
4334 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIveBeenInAColdSweat) },
4335 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsRowingIsAToughJobIsnt) },
4336 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsOhThisPoorSapLooksSad) },
4337 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsHeyThisGuysBeenStaringAt) },
4338 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsOhNoNoWhenOurEyes) },
4339 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsOhOhNoHesNotComing) },
4340 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsItsOnlyNaturalThatINot) },
4341 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsPleasePleaseImBeggingJustDont) },
4342 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsISnuckByThisTimeBut) },
4343 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsWhatsWithYouGoBotherThe) },
4344 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWowThisWarriorIsntGonnaLet) },
4345 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsWhyAmIGettingSoWorked) },
4346 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouCanJustMoveRightAlong) },
4347 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, FLAG_TOLBI_SHIP_ROWER_CHOSEN, MSGNO(MsgTolbiShipInteriorsWeHadEnoughTroubleJustGetting) },
4348 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsCarefulNowWatchOutDontMake) },
4349 { SEARCH(SEARCH_BARREL), 101, 0xf93, FIND_COINS(23) },
4350 { SCENE_EVENTS_END },
4351};
4352
4353/// The hold while the ship waits off the island.
4355 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
4356 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
4358 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsInAPerfectWorldThereWouldnt) },
4359 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouCantGoOntoTheIsland) },
4360 { EVENT_TALK, 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsButThereWereMonstersAtSea) },
4361 { EVENT_TALK, 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeveBeenCoopedUpOnThat) },
4362 { EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsThereCouldBeMonstersHereSo) },
4363 { EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheShipKeepsShakingSheCant) },
4364 { EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhyShouldWeHaveToWait) },
4365 { EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfThereAreMonstersImNot) },
4366 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIDontHearThePassengersScreaming) },
4368 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhatToDoImWorriedAbout) },
4369 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsButWhyShouldWeStayOnboard) },
4370 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImSickOfThisShipIm) },
4371 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsLandMonstersICanHandleSea) },
4372 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIveBeenWobblingOnThisBoat) },
4373 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsGoAheadTryAndStopMe) },
4374 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsJustDontMakeMeFaceThat) },
4375 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsSoAnyoneKnowIfThereAre) },
4376 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsOhhThatsCreepy) },
4377 { SEARCH(SEARCH_BARREL), 101, 0xf93, FIND_COINS(23) },
4378 { SCENE_EVENTS_END },
4379};
4380
4381/// The cabin, from the wait at Kalay until the ship reaches Tolbi. The Anchor
4382/// Charm is given back to the captain here.
4384 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
4387 { EVENT_TALK, 9, FLAG_TOLBI_SHIP_CAPTAIN_DECIDED_TO_SAIL, MSGNO(MsgTolbiShipInteriorsIWonderIfThereAreAny) },
4388 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsRightWhenWeFoundSomeWarriors) },
4389 { EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsICantBelieveHimRefusingTo) },
4390 { EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIHadNoIdeaHeWas) },
4392 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_CAPTAIN_DECIDED_TO_SAIL, MSGNO(MsgTolbiShipInteriorsThisIsAChanceToMake) },
4393 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_ANCHOR_CHARM_RETURNED, MSGNO(MsgTolbiShipInteriorsTheShipWontLeaveDockUntil) },
4394 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_FIRST_ATTACK_REPELLED, MSGNO(MsgTolbiShipInteriorsAsLongAsWeHaveThe) },
4395 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeKnewTheRisksWhenWe) },
4396 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, FLAG_TOLBI_SHIP_CAPTAIN_DECIDED_TO_SAIL, MSGNO(MsgTolbiShipInteriorsSendingOutAShipWhenIts) },
4397 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIWaitedTooLongIllGet) },
4398 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, FLAG_TOLBI_SHIP_CAPTAIN_DECIDED_TO_SAIL, MSGNO(MsgTolbiShipInteriorsIfWeDontSetSailNow) },
4399 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsThisIsRidiculousTheShipCant) },
4400 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsThatThingCouldntHaveGottenLost) },
4401 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIDontThinkAnyoneWouldSteal) },
4402 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfTheShipDoesntLeaveSoon) },
4405 { 0xc423, 102, 0xf94, FIND_ITEM(ITEM_NUT) },
4406 { SCENE_EVENTS_END },
4407};
4408
4409/// The cabin while the ship waits off the island.
4411 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
4412 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeMayHaveTakenTheWrong) },
4413 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWereLookingIntoTheShipsPosition) },
4414 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImReallySurprisedThatThereIs) },
4415 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheWindsDirectionAndTheHigh) },
4416 { SEARCH(SEARCH_JAR), 102, 0xf94, FIND_ITEM(ITEM_NUT) },
4417 { SCENE_EVENTS_END },
4418};
4419
4420/// The cabin once the ship has reached Tolbi.
4422 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
4423 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhenTheWatersAreThisDangerous) },
4424 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsSeeOurShipSurvivedAnAttack) },
4425 { SEARCH(SEARCH_JAR), 102, 0xf94, FIND_ITEM(ITEM_NUT) },
4426 { SCENE_EVENTS_END },
4427};
4428
4430 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
4431 { EVENT_TALK, 8, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsWeCanLeaveAsSoonAs) },
4432 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIveBeenSailingForManyYears) },
4433 { EVENT_TALK, 9, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsEveryoneRowsInTimeWithThis) },
4434 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWowIHaveABlisterOn) },
4435 { EVENT_TALK, 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsRowingIsAMansJob) },
4436 { EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWereTheOnesWhoMakeThe) },
4437 { EVENT_TALK, 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsOnceWeCastOffYouJust) },
4438 { EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouCanOnlyDoHardWork) },
4439 { EVENT_TALK, 14, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsHmmmIWonderWhenWereGoing) },
4440 { EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIWonderIfItsOkayTo) },
4441 { EVENT_TALK, 15, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsICantWaitUntilWeGet) },
4442 { EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsStoppingAgainAndAgainLikeThis) },
4443 { EVENT_TALK, 16, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsIHearTheresAnIsleIn) },
4444 { EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsLetsSeeIslandsInTheKaragol) },
4445 { EVENT_TALK, 17, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsFromTheSeaItLooksLike) },
4446 { EVENT_TALK, 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhenWereRowingWeCanJust) },
4447 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsEnoughIsEnoughLetsSetOff) },
4448 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsItsCrazyToHaveInexperiencedPassengers) },
4449 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsILoveItWhenTheOars) },
4450 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsItWasHardForMeAll) },
4451 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsEveryoneDownHereGetsSoCompetitive) },
4452 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheseBigMusclesAreASign) },
4453 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWellSeeToItThatThey) },
4454 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouveGotToSaveUpLots) },
4455 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsIDontFeelLikeRowingAll) },
4456 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsISureHopeAnotherMonsterDoesnt) },
4457 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsSpendYourMoneyWhileYoureYoung) },
4458 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsLooksLikeImGoingToHave) },
4459 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsItSeemsLikeThereWouldBe) },
4460 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsCouldThisBeThatIslandThats) },
4461 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, FLAG_TOLBI_SHIP_AT_ISLAND, MSGNO(MsgTolbiShipInteriorsHaHahIfYouWantTo) },
4462 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsMaybeItsTimeForMeTo) },
4463 { SCENE_EVENTS_END },
4464};
4465
4466/// The rowing deck while monsters are aboard: talking to one (actors 36 to 38)
4467/// fights it.
4473 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsMonstersFromTheDeepAreAttacking) },
4474 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsCurseThoseBeastsTheyGotOne) },
4475 { EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsFightingOffTheMonstersIsYour) },
4476 { EVENT_TALK, 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsFoulBeastIMayBeTrembling) },
4477 { EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfIWerentSoTiredId) },
4478 { EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsCursesIWantToSmackThat) },
4479 { EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhoIsThatThingGoingTo) },
4480 { EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfYouDontDoABetter) },
4481 { EVENT_TALK, 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeOarsmenMayBeStrongBut) },
4482 { EVENT_TALK, 18, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWereSurroundedByDangerOnAll) },
4483 { EVENT_TALK, 20, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsAhhhhSeaMonstersRealLiveSea) },
4484 { EVENT_TALK, 21, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhaHeyYouThisIsNo) },
4485 { EVENT_TALK, 22, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsAahIHaveToRowThis) },
4486 { EVENT_TALK, 19, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsHHeyIsaacShouldntYouBe) },
4487 { EVENT_TALK, 23, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYaaahhhIImNotAfraidOf) },
4488 { EVENT_TALK, 24, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheOarsmenAreInDireStraights) },
4489 { EVENT_TALK, 25, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIICantDoThisFighting) },
4490 { EVENT_TALK, 26, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIDontCareWhatHappensNow) },
4491 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhyArentYouDoingAnythingTo) },
4492 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfWeLoseAnyMoreOarsmen) },
4493 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfTheSeaMonstersGetUs) },
4494 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImScaredThoseSeaMonstersAre) },
4495 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsFightingSeaMonstersIsForWarriors) },
4496 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheSeaMonstersAreSoTough) },
4497 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIDontCareWhoElseThe) },
4498 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsPleaseJustStayHereAndProtect) },
4499 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeDontEvenKnowIfAttacking) },
4500 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 18, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsSeaMonstersAreTerriblyFerocious) },
4501 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 20, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfIWereAWarriorI) },
4502 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 21, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIWonderIfThisWarriorHas) },
4503 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 22, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWereSureInAFixSay) },
4504 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 19, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImSoOutOfMyWits) },
4505 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 23, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheseSeaMonstersLookAwfullyStrong) },
4506 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 24, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsPleaseOhPleaseLetMeMake) },
4507 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 25, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhyDidSeaMonstersHaveTo) },
4508 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 26, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIdRatherBeEatenByA) },
4509 { SCENE_EVENTS_END },
4510};
4511
4512/// The rowing deck while the Kraken rocks the ship.
4514 { EVENT_EXIT, 4, CONDITION_ALWAYS, 19 },
4515 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImagineTheSizeOfThatBeast) },
4516 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsHowCanTheseSeaMonstersKeep) },
4517 { EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsJudgingFromKajasReactionItMust) },
4518 { EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsKajaWouldntAskForHelpUnless) },
4519 { EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsTheWholeShipIsRockingThat) },
4520 { EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWereOkayWithYouHereWe) },
4521 { EVENT_TALK, 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIfTheShipSinksWereFinished) },
4530 { EVENT_TALK, 26, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsOwwwMyHandsAreRawFrom) },
4531 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhyIsHeDownHereShouldnt) },
4532 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhatTheHowManyMonstersDoes) },
4533 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWhatKindOfMonsterIsRocking) },
4534 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWereRunningLowOnOarsmenAnd) },
4535 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImTakingALittleBreakUntil) },
4536 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsGoodThingWeHaveSomeStrong) },
4537 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIWonderIfTheMonsterIs) },
4546 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 26, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIWonderIfTheyllMakeUs) },
4547 { SCENE_EVENTS_END },
4548};
4549
4550/// The rowing deck once the ship has reached Tolbi.
4552 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
4553 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIDontThinkAnyoneWillBe) },
4554 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouFolksReallyFoughtWell) },
4555 { EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsALotOfOarsmenWereInjured) },
4556 { EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsAreWeSafeItsAllBecause) },
4557 { EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIveBeenAnOarsmanAllMy) },
4558 { EVENT_TALK, 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsYouGoOnAheadJustWhen) },
4559 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsWeCantFindAnyoneToReplace) },
4560 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImJustGladTheKrakenDidnt) },
4561 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsSureThePaysGoodButIt) },
4562 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIsaacAndHisPalsWereSo) },
4563 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsIFeelBetterNowIWas) },
4564 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgTolbiShipInteriorsImInNoRushAnywayThis) },
4565 { SCENE_EVENTS_END },
4566};
4567// clang-format on
4568
4569/// Frames left of the Kraken's current jolt; at 0 another may start.
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
void ObjectGroup_SetChildValue(struct FieldActor *actor, s32 param)
Sets the param byte of every animated part of an actor's sprite.
void Object_RefreshSelectorById(u32 objectId)
Waits, at most 300 frames, for an actor's script to reach its end (command 0x10).
void ObjectMotion_WaitForAnimationChange(u32 objectId)
Waits, at most 90 frames, for an actor's animation to change.
void Object_SetActionById(u32 objectId, s32 steps)
Sets the animation timer steps of each of an actor's sprites (AnimationObjects_SetActiveTimerSteps).
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
The task scheduler: tasks, their order and the scheduler's state.
struct FieldActor * Camera_GetEventObject(void)
The event command "get view centre": returns the camera object.
Definition camera.c:133
#define GARET
Jerald.
#define MIA
Mary.
#define IVAN
Ivan.
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.
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
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
#define SPEAKER_PORTRAIT_LEFT
Definition field_event.h:54
static s32 Event_OpenMessage(s32 speaker, s32 flags)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Engine_SanctumOpen(s32 priest)
void Object_SetMode(struct FieldActor *object, s32 animation)
#define SPEAKER_WINDOW_ABOVE
Definition field_event.h:56
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
s32 Engine_EventChooseYesNo(s32 actor, s32 flags)
void Engine_EventShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
#define GameFlag_IsSet
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
static void Camera_SetSpeed(s32 speed, s32 acceleration)
void Engine_CameraMoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
void Engine_ItemLoadIcon(s32 item)
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_EventCloseScreen(void)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
static void Actor_RunActionScriptAndWait(s32 actor, const s32 *script)
Runs a script, waiting at most 300 frames for its final command.
void Engine_ActorWalkToAndWait(s32 actor, s32 x, s32 z)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
void Engine_HeapRelease(s32 slot)
s32 Engine_VramLoad(s32 block, s32 size, const void *data)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
#define GameFlag_Clear
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
void Engine_ActorDestroy(s32 actor)
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
s32 Engine_EventAskYesNo(s32 speaker, s32 flags)
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
void Engine_EventOpenScreen(void)
s32 Engine_EventOpenMessage(s32 speaker, s32 flags)
void Engine_GameFlagSet(s32 flag)
void Engine_GameFlagClear(s32 flag)
void Engine_CameraWaitForMove(void)
static void Actor_SetActionScript(s32 actor, const s32 *script)
The engine encodes either a built-in action or an action-script address.
void Engine_ActorWaitForMove(s32 actor)
void * Engine_HeapAllocate(s32 slot, s32 size)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
void Engine_ActorWalkTo(s32 actor, s32 x, s32 z)
static void Event_ShowMessage(s32 speaker, s32 flags)
void Engine_ActorSetAttachedEffect(s32 actor, s32 effect)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
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.
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
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_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ActorFaceEachOther(s32 actor, s32 other, s32 frames)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ ACTOR_PRIORITY_AUTOMATIC
The sprite takes its priority from the map cell under it.
Definition field_obj.h:153
#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
@ ACTOR_FACES_MOTION
turns toward its velocity, 1/16 turn a frame
Definition field_obj.h:166
The field's runtime work: map cells, scene records and regions, map markers and FieldWork.
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
@ TALK_FACE_PARTY_AND_BACK
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
#define USE_ITEM_ON_ACTOR(item)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
@ FACING_NORTHEAST
Definition field_scene.h:33
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTHWEST
Definition field_scene.h:29
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_JAR
@ SEARCH_BARREL
#define FIND_COINS(coins)
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_CAPTAIN_DECIDED_TO_SAIL
The party has heard that the captain decided to sail.
Definition flags.h:404
#define FLAG_SHOW_LOCATION_NAME
Definition flags.h:94
#define FLAG_TOLBI_SHIP_REACHED_TOLBI
The ship reached Tolbi. "The ship has arrived safely".
Definition flags.h:425
#define FLAG_KEEP_MUSIC
The next scene keeps the music that is playing; scene.c clears FLAG_KEEP_MUSIC as it does,...
Definition flags.h:35
#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_SECOND_ATTACK_REPELLED
Definition flags.h:415
#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_THIRD_ATTACK_REPELLED
Definition flags.h:416
#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_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_TOLBI_SHIP_AT_ISLAND
at anchor off the island
Definition flags.h:396
#define FLAG_TOLBI_SHIP_KRAKEN_DEFEATED
Definition flags.h:417
#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_SAILING_WITHOUT_REPLACEMENT
The ship has set sail without its replacement.
Definition flags.h:410
#define FLAG_TOLBI_SHIP_THIRD_SEAT_ROWERS
Definition flags.h:422
#define FLAG_KALAY_COLOSSO_TOUR_LEFT
the tour group has left town
Definition flags.h:229
#define FLAG_TOLBI_SHIP_CREW_WONDERED_AT_DELAY
The crew have wondered what became of the replacement ship.
Definition flags.h:401
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 screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
s32 PartyInventory_Discard(s32 itemId)
Discards one itemId from whoever carries it first, as Inventory_Discard does; always returns 0.
Definition inventory.c:422
gOverflowItem, an item slot the spoils code uses when items are handed out.
Item numbers, named from the English release.
@ ITEM_NUT
Definition item_ids.h:41
@ ITEM_ANCHOR_CHARM
Definition item_ids.h:73
@ ITEM_LUCKY_MEDAL
Definition item_ids.h:70
Small statement macros both games use for positions, velocities and bounds.
#define SET_VELOCITY(p, vx, vy, vz)
Definition macros.h:18
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_FREE
Release.
Definition objcmd.h:43
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_FOREVER
Definition objcmd.h:14
#define SC_ADD(w, v)
Definition objcmd.h:38
#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_MOTION
Definition objcmd.h:75
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void Battle_ResetEffectCounter(void)
Clears the field's busy flag and, while Reveal is active, ends it: Reveal used with ACT_PACKED runs i...
Definition targets.c:261
void Event_CallWithLastActiveObjectId(struct ScenePlacement *table)
Spawns the actors of a placement table after the last actor in use.
Definition events.c:148
void Ui_SetMessageVoiceFromActor(s32 actor)
Sets the voice of the messages that follow to that of actor's sprite, at the rate the message speed o...
Definition messages.c:483
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 Audio_PlayCueFromEventWork(void)
Starts the current scene's field music, chosen by Scene_ResolveInteractionResult.
Definition scene.c:355
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_063
Definition songs.h:67
#define SE_181
Definition songs.h:176
#define MUS_028
Definition songs.h:38
#define MUS_017
Definition songs.h:27
#define SE_188
Definition songs.h:183
#define MUS_019
Definition songs.h:29
#define SE_214
Definition songs.h:209
void Engine_ActorSetAnimation()
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_ActorShowEmote()
void Engine_TaskWait()
void Engine_EventSetMessage()
void Engine_EventShowMessage()
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart shadow
Definition animspr.h:110
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
u8 slot
VRAM cache entry holding its tiles.
Definition animspr.h:112
u8 count
layers in use, up to the last one present
Definition animspr.h:129
u16 fullColor
256 colours; set for both parts when created
Definition animspr.h:94
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
u16 unk172
FieldWork's menu request; scenes set it to 1.
Definition event_work.h:29
u16 message
the next message, advanced as each window opens
Definition event_work.h:47
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
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 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
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
u8 riseCounter
not read by the engine; scene code's own counter
Definition field_obj.h:105
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
u8 paused
nonzero skips its script and motion, not its update
Definition field_obj.h:93
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 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
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
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 riseEnabled
not read by the engine; scene code's own state
Definition field_obj.h:106
A position on the field.
s32 z
16.16 fixed-point pixels
s16 entrance
Definition game_state.h:37
A scene entrance: where and facing which way the party arrives, and the camera's bounds there (-1 for...
Definition field_scene.h:54
A scene event: its kind and detail, the trigger it answers, its condition and its value (a message or...
An actor a scene places: its sprite, the condition for placing it, how it behaves,...
Definition field_scene.h:81
u8 talkFacing
enum ActorTalkFacing; 3 follows the leader afterwards
Definition field_scene.h:95
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.
#define FLAG_TOLBI_SHIP_KRAKEN_ABOARD
"There's a huge sea monster on the ship!": the deck shakes until the Kraken is defeated (set in tolbi...
#define SPEAKER(actor, window)
A speaker: the actor, and in the top four bits where the message window opens beside them (4,...
static void TolbiShipInteriors_WatchWarriorsStormOff(void)
Once the party has heard of the delay at Kalay: Ouranos threatens to go ashore if the ship doesn't sa...
static void TolbiShipInteriors_TalkToWaitingPassenger8(void)
A passenger in the hold while the ship waits.
static void TolbiShipInteriors_RunSceneCommand(s32 step, u32 arg, u32 opt)
Reuses the voyage's actor, camera, transition and selection operations.
const struct SceneRegion * TolbiShipInteriors_GetRegions(void)
static void TolbiShipInteriors_EndThirdAttack(void)
Restores two replacement rowers after the next monster attack.
static void TolbiShipInteriors_ReadRower21Mind(void)
Mind Read on rower 21: there are so many monsters at sea.
struct SceneEvent gTolbiShipInteriors_RowingDeckEventsMonstersAboard[]
The rowing deck while monsters are aboard: talking to one (actors 36 to 38) fights it.
static void TolbiShipInteriors_RejoinParty(s32 rowerId)
Walks the rower back to the leader and hides its separate scene actor.
struct SceneEntrance gTolbiShipInteriors_EntrancesOther[]
The other scenes have no entrances.
static void TolbiShipInteriors_CallActorEighteenToRow(void)
Calls a replacement rower back to the rowing deck.
static void TolbiShipInteriors_Say(s32 speaker)
s32 gTolbiShipInteriors_FollowersRejoinMidDeck[]
The same, in the middle of the rowing deck.
struct ScenePlacement gTolbiShipInteriors_HoldPlacementsEmpty[]
The hold before the party hears of the delay at Kalay.
static void TolbiShipInteriors_DismissReplacementRowers(void)
Returns the replacement rowers to their seats and exchanges their selections.
static void TolbiShipInteriors_ReadRower24Mind(void)
The same for rower 24.
static void TolbiShipInteriors_TalkToRower20(void)
The same for rower 20.
static void TolbiShipInteriors_TalkToRower22(void)
The same as rower 18, for rower 22.
s32 gTolbiShipInteriors_TurnSteps[]
static void TolbiShipInteriors_ShakeWhileKrakenAboard(void)
Plays the intermittent voyage cue and restores its effect after ten frames.
static struct FieldActor * TolbiShipInteriors_PlaceAnchorCharm(void)
Creates the visible anchor charm once a visit (FLAG_SCENE_TEMP_00 records it) and retains it for depa...
struct SceneEvent gTolbiShipInteriors_RowingDeckEventsKrakenAboard[]
The rowing deck while the Kraken rocks the ship.
struct FieldActor * gTolbiShipInteriors_AnchorObject
The Anchor Charm's object, once placed this visit.
static void TolbiShipInteriors_TalkToRower18(void)
A passenger at the oars, by the round they were chosen in: Kaja's men are worried,...
static void TolbiShipInteriors_AnnounceDeparture(void)
Announces departure after a replacement rower has joined the crew.
struct SceneEvent gTolbiShipInteriors_CabinEventsAtIsland[]
The cabin while the ship waits off the island.
static void TolbiShipInteriors_NoticeShipRocking(void)
The party notices the ship rocking and discusses the rowers' progress.
struct ScenePlacement gTolbiShipInteriors_PartyFollowerPlacements[]
The party's followers, placed for a scene.
static void TolbiShipInteriors_HideSelectedPassenger(s32 actorId, s32 firstFlag)
Hides the passenger whose selection flag is set in this seat's flag group.
static void TolbiShipInteriors_TalkToCaptainsCabinActor10(void)
Once the warriors want to see the captain, actor 10 asks whether the party wants to join them in forc...
s32 TolbiShipInteriors_ApplyEntryState(void)
Restores the room or plays the event selected by this entrance.
const u32 * TolbiShipInteriors_GetExits(void)
static void TolbiShipInteriors_SwapRowerSelections(s32 firstSeatFlags, s32 secondSeatFlags)
Exchanges the chosen passengers between two rowing seats.
struct SceneEvent gTolbiShipInteriors_EventsOther[]
The side room, and the cutscenes.
static s32 TolbiShipInteriors_Bob(struct ScriptInterpreter *interpreter)
Bobs the actor between the floor and 8 pixels up by a random amount each frame.
static void TolbiShipInteriors_TalkToRower23(void)
The same for rower 23.
static void TolbiShipInteriors_ReactToMonsterAttack(void)
The crew checks on the party after the monster fight, then resumes rowing.
static void TolbiShipInteriors_ShowCabinBeforeKraken(void)
Plays the short cabin exchange before returning to the voyage.
static void TolbiShipInteriors_ShowRowing(void)
Restores the rowing deck for the current set of selected passengers.
static s32 TolbiShipInteriors_LookAround(struct ScriptInterpreter *interpreter)
Now and then (two chances in 64) turns the actor to face south-southeast or south-southwest.
static void TolbiShipInteriors_PlaceFoundActors(s32 gated)
Puts each recruited rower at its seat and hides the original occupant.
struct SceneEvent gTolbiShipInteriors_RowingDeckEvents[]
static s32 TolbiShipInteriors_HasArrived(struct FieldActor *actor)
Counts down the actor's walking time in riseBaseY.
const struct SceneEvent * TolbiShipInteriors_SelectEvents(void)
Chooses the room's interactions for the current stage of the voyage.
static void TolbiShipInteriors_AskPassenger14ToRow(void)
The same for passenger 14.
static void TolbiShipInteriors_SetUpRowingDeck(void)
Restores the rowing deck and introduces a newly recruited replacement.
static s32 TolbiShipInteriors_GetChosenOarsman(void)
Returns the passenger chosen to row at the open seat, which the attacks fought off number.
s32 gTolbiShipInteriors_LieFlatScript[]
Lies flat on the floor of the hold.
static void TolbiShipInteriors_MoveCameraAndWait(s32 x, s32 y, s32 z, u32 flags)
Moves the camera, optionally waits or redraws, then honors the packed delay.
static void TolbiShipInteriors_AskForReplacementOarsmen(void)
The crew explains the missing replacements and asks the party to find rowers.
s32 gTolbiShipInteriors_FollowersRejoinByStairs[]
The party's followers walk into the leader by the rowing deck's stairs.
static void TolbiShipInteriors_AnnounceTurn(void)
Announces the ship's next turn and returns control to the rowing deck.
static void TolbiShipInteriors_StepBesideLeader(s32 passengerId)
The chosen oarsman steps out beside the leader, on the leader's right if that spot is free,...
s32 gTolbiShipInteriors_ShakeTimer
Frames left of the Kraken's current jolt; at 0 another may start.
#define TURN_STEP(dx, dz)
The step beside the leader for each of the 16 facings: the high 16 bits are x, the low 16 bits z.
s32 gTolbiShipInteriors_LookAroundScript[]
A passenger glances about at random.
static void TolbiShipInteriors_AskPassenger10ToRow(void)
The same for passenger 10.
struct ScenePlacement gTolbiShipInteriors_PlacementsNone[]
#define TOLBI_SHIP_TALK_FACING(bytes, row)
A byte view keeps the native address arithmetic; direct row-field writes choose different bases and r...
s32 gTolbiShipInteriors_FollowersRejoinBySeats[]
The same, by the first row of seats.
static struct FieldActor * TolbiShipInteriors_FindActorNear(s32 x, s32 z)
Finds a placed actor within twelve pixels of the requested floor position.
s32 gTolbiShipInteriors_Shiver[]
Squashes and stretches the actor over and over: a shiver.
static void TolbiShipInteriors_AskAboutMonsters(void)
Asks the crew about the monsters before returning belowdecks.
static void TolbiShipInteriors_SetUpCabin(void)
Restores the cabin's actors after the anchor and departure conversations.
static void TolbiShipInteriors_EndSecondAttack(void)
Restores one replacement rower after the next monster attack.
const struct ScenePlacement * TolbiShipInteriors_SelectPlacements(void)
Picks the placements for the room entered and the voyage's stage.
static void TolbiShipInteriors_AskPassenger9ToRow(void)
The same for passenger 9, written out in full.
struct ScenePlacement gTolbiShipInteriors_FirstAttackMonsters[]
The monsters of each attack, beside the seats.
struct ScenePlacement gTolbiShipInteriors_HoldPlacements[]
The hold while the ship waits at Kalay, and after it reaches Tolbi.
static void TolbiShipInteriors_AskPassenger13ToRow(void)
The same for passenger 13.
static void TolbiShipInteriors_WatchCrewWonderAtDelay(void)
Once the warriors have gone to the captain, the three crewmen wonder what could have happened to the ...
static void TolbiShipInteriors_ReadRower18Mind(void)
Mind Read on a rower, by the round they were chosen in.
struct SceneEvent gTolbiShipInteriors_HoldEventsChoosingRowers[]
The hold at sea: talking to a passenger asks them to row.
u32 gTolbiShipInteriors_Exits[]
const struct SceneEntrance * TolbiShipInteriors_SelectEntrances(void)
static s32 TolbiShipInteriors_FindFirstSetFlag(u32 group, s32 alternate)
Finds the selected passenger or rowing-deck actor for a seat's flag group.
struct SceneEvent gTolbiShipInteriors_CabinEvents[]
The cabin, from the wait at Kalay until the ship reaches Tolbi.
@ CabinSpeakerRequest
static void TolbiShipInteriors_AskToRow(s32 speaker, s32 question, s32 seatFlag)
Asks a passenger to row.
static void TolbiShipInteriors_StartFirstAttack(void)
Stages the first monster encounter with the original rowers.
struct ScenePlacement gTolbiShipInteriors_CabinPlacementsWarriors[]
The cabin once the warriors have come to see the captain, with the party's followers.
struct ScenePlacement gTolbiShipInteriors_CabinPlacements[]
s32 gTolbiShipInteriors_StepIntoAisle[]
A rower steps into the aisle.
static void TolbiShipInteriors_ReturnLuckyAnchor(void)
Returns the captain's lucky anchor and agrees to protect the ship.
struct ScenePlacement gTolbiShipInteriors_HoldPlacementsAtSea[]
The hold at sea, once the passengers row.
s32 gTolbiShipInteriors_LeaveCabin[]
Those gathered in the cabin walk out.
static void TolbiShipInteriors_TalkToCaptain(void)
The captain, by the voyage's stage: too late to hire mercenaries, then his bad luck at losing his luc...
static void TolbiShipInteriors_StartThirdAttack(void)
Stages the next monster encounter with two replacement rowers.
#define FLAG_TOLBI_SHIP_ROWER_CHOSEN
a passenger follows the party
static void TolbiShipInteriors_SetUpHold(void)
Restores the passenger hold after recruitment and departure events.
struct ScenePlacement gTolbiShipInteriors_RowingDeckPlacements[]
The rowing deck: the crew (actors 8 and 9), the oarsmen at the seats (10 to 17), the passengers who m...
static void TolbiShipInteriors_TalkToRower21(void)
Rower 21 asks how many monsters are out there.
static void TolbiShipInteriors_AskPassenger15ToRow(void)
The same for passenger 15.
struct SceneEntrance gTolbiShipInteriors_Entrances[]
The hold (entrances 1, 2, 11 and 30), a side room (3), the rowing deck (4, 12 and 15 to 24 but 22) an...
ShipSceneCommand
Operations shared by the cabin, passenger hold and rowing-deck events.
@ SHIP_CLOSE_SCENE
@ SHIP_PLACE_FOLLOWERS_AND_MONSTERS
@ SHIP_RESTORE_ROWING_DECK_POSES
@ SHIP_FACE_PARTY_EAST_AND_WEST
@ SHIP_OPEN_SCENE
@ SHIP_HIDE_ACTORS_13_AND_14
@ SHIP_START_ROWING_ANIMATION
@ SHIP_CLEAR_FLAG_RANGE
@ SHIP_CLEAR_ROWING_SELECTIONS
@ SHIP_SETUP_CAPTAINS_CABIN
@ SHIP_RESET_CAMERA
@ SHIP_SETUP_MONSTER_ENCOUNTER
@ SHIP_SETUP_RECRUITMENT_DECK
@ SHIP_HIDE_CABIN_CREW
@ SHIP_START_MIRRORED_ROWING_ANIMATION
@ SHIP_HIDE_PASSENGERS
@ SHIP_SET_SELECTED_ROWER_POSE
@ SHIP_SETUP_ROWING_PARTY
@ SHIP_HIDE_PARTY_FOLLOWERS
@ SHIP_RESTORE_ROWER_POSE
@ SHIP_HIDE_ACTORS_28_TO_35
@ SHIP_RESTORE_ACTOR_12_SCRIPT
@ SHIP_SHOW_PARTY_EMOTE
@ SHIP_PLAY_PARTY_ANIMATION
@ SHIP_SETUP_PASSENGER_HOLD
@ SHIP_FACE_PARTY
s32 gTolbiShipInteriors_LeaveByStairs[]
A rower walks up the stairs and is freed.
static void TolbiShipInteriors_CastOff(void)
Raises the anchor charm and announces the ship's first departure.
static void TolbiShipInteriors_TalkToRower24(void)
The same for rower 24.
TolbiShipInteriorsActor
The warriors bound for Colosso in the hold while the ship waits at Kalay (gTolbiShipInteriors_HoldPla...
@ HOLD_OURANOS
static void TolbiShipInteriors_CallActorSixteenToRow(void)
Calls the first passenger to the rowing deck.
static void TolbiShipInteriors_InstallRowingDeckActors(u32 action)
Restores each replacement rower or the original occupant of that seat.
s32 gTolbiShipInteriors_AnchorCharmPulse[]
The Anchor Charm swells and shrinks twice as the captain raises it.
static void TolbiShipInteriors_AskPassenger12ToRow(void)
The same for passenger 12, written out in full rather than through TolbiShipInteriors_AskToRow.
s32 gTolbiShipInteriors_LeaveHold[]
The warriors walk out of the hold.
static void TolbiShipInteriors_PlaceActor(s32 actorId, s32 x, s32 z, s32 facing)
Places an actor at pixel coordinates and sets its initial heading.
struct SceneEvent gTolbiShipInteriors_RowingDeckEventsArrived[]
The rowing deck once the ship has reached Tolbi.
static void TolbiShipInteriors_WaitThenAdvance(struct FieldActor *actor)
Counts the frames of a pause in riseCounter and moves the pacing actor to its next step after 80 fram...
s32 gTolbiShipInteriors_MonsterBob[]
A monster in the hold bobs in place.
static void TolbiShipInteriors_ReadRower20Mind(void)
The same for rower 20.
static void TolbiShipInteriors_ReachIsland(void)
Rests the rowers at the island and plays the selected passengers' responses.
struct ScenePlacement gTolbiShipInteriors_ThirdAttackMonsters[]
static s32 TolbiShipInteriors_ResetActor(struct ScriptInterpreter *interpreter)
An action-script call: stands the actor still at the origin, with no velocity and no target.
static void TolbiShipInteriors_TalkToRower19(void)
The same for rower 19.
static void TolbiShipInteriors_PoseSceneActor(s32 id)
Applies the seated pose and rowing action assigned to this rower.
static void TolbiShipInteriors_TalkToPriest(void)
The travelling priest.
static void TolbiShipInteriors_TalkToRower25(void)
As rower 21, for rower 25.
static s32 TolbiShipInteriors_LayFlat(struct ScriptInterpreter *interpreter)
An action-script call: lays the actor flat on the floor, drawn underfoot at priority 1 with its parts...
static void TolbiShipInteriors_ReadRower25Mind(void)
As rower 21, for rower 25.
static void TolbiShipInteriors_TalkToCaptainsCabinActor12(void)
Actor 12 in the captain's cabin asks whether the party came to ask the captain to set sail.
static void TolbiShipInteriors_TalkToWaitingPassenger10(void)
Another waiting passenger, once the party has agreed to protect the ship, asks whether it will row.
static s32 TolbiShipInteriors_IsSpotFree(s32 bucket)
Returns 1 when the spot next to the leader in the given sixteenth of a turn holds no actor and no wal...
static void TolbiShipInteriors_AskPassenger8ToRow(void)
Passenger 8 under sail, when an oar needs a rower.
#define FLAG_TOLBI_SHIP_MONSTERS_ABOARD
the hold's stairs are barred
struct SceneEvent gTolbiShipInteriors_CabinEventsArrived[]
The cabin once the ship has reached Tolbi.
static void TolbiShipInteriors_WatchPacer(union FieldObject *fieldObject)
The update of the actor who watches the pacing crewman: turns north-northeast at the first signal,...
static void TolbiShipInteriors_AskPassenger16ToRow(void)
The same for passenger 16.
static void TolbiShipInteriors_DiscussLaunchingWithoutAnchor(void)
The passengers pressure the captain to launch despite the missing anchor.
static void TolbiShipInteriors_Turn(s32 actorId, u16 facing)
Turns an actor to a facing over 10 frames.
static void TolbiShipInteriors_IntroduceReplacementOarsman(s32 seat)
Introduces the selected passenger and leads them to the open rowing seat.
static void TolbiShipInteriors_PaceCabin(union FieldObject *fieldObject)
The update of a crewman who paces between two spots in the cabin, looking about at each,...
struct SceneEvent gTolbiShipInteriors_HoldEvents[]
The hold while the ship waits at Kalay, and after it reaches Tolbi.
struct ScenePlacement gTolbiShipInteriors_SecondAttackMonsters[]
static void TolbiShipInteriors_EndFirstAttack(void)
Restores the original rowers after the first monster attack.
static void TolbiShipInteriors_ReadRower23Mind(void)
The same for rower 23.
static void TolbiShipInteriors_AskPassenger11ToRow(void)
The same for passenger 11, who is too seasick to talk once the ship is at anchor.
struct SceneEvent gTolbiShipInteriors_HoldEventsAtIsland[]
The hold while the ship waits off the island.
static void TolbiShipInteriors_ReportMonstersBelowdecks(void)
Gathers the party after the crew reports monsters belowdecks.
struct ScenePlacement gTolbiShipInteriors_CabinPlacementsArrived[]
The cabin once the ship has reached Tolbi.
static void TolbiShipInteriors_ReadRower22Mind(void)
As rower 18, for rower 22.
static void TolbiShipInteriors_TurnBackFromStairs(void)
While the monsters are aboard, the leader is walked back from the stairs.
static void TolbiShipInteriors_StartSecondAttack(void)
Stages the next monster encounter with one replacement rower.
static void TolbiShipInteriors_HideSelectedPassengers(void)
Hides the four passengers who are already filling rowing seats.
static void TolbiShipInteriors_ReadRower19Mind(void)
The same for rower 19.
static void TolbiShipInteriors_FightMonstersInHold(void)
Talking to one of the monsters in the hold (actors 36 to 38) starts the battle with them: group 62,...
static void TolbiShipInteriors_SetSeatActorCollision(void)
Sets collision bit 3 on the eight actors surrounding the rowing seats.
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
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
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