Alchemy
Loading...
Searching...
No Matches

imil.c

Go to the documentation of this file.
1/// @file
2/// Imil, in two maps: the town and its interiors. The townspeople are sick
3/// until the epidemic is cured (flag 0x881); Mia heals the old man, and the
4/// cold villager waits for her.
5
6#include "script.h"
7#include "animspr.h"
8#include "version.h"
9#include "game_state.h"
10#include "keystate.h"
11#include "scene_ids.h"
12#include "unit/scene/imil.h"
13#include "unit/object/object.h"
15#include "unit/field/field.h"
17#include "battle.h"
18#include "debug.h"
19#include "field.h"
20#include "game.h"
21#include "graphics.h"
22#include "menu.h"
23#include "minigame.h"
24#include "sound.h"
25#include "system.h"
26#include "global_cells.h"
27#include "types.h"
28#include "text/msg_ids.h"
29#include "field_event.h"
30#include "field_scene.h"
31#include "field_effect.h"
32#include "facing_object.h"
34#include "object_lookup.h"
35#include "field_service.h"
36#include "iwram_call.h"
37#include "frame.h"
38#include "ability_ids.h"
39#include "item_ids.h"
40#include "objcmd.h"
41#include "fixed_math.h"
42#include "palbuf.h"
43#include "map.h"
44#include "macros.h"
45#include "flags.h"
46#include "character_ids.h"
47#include "songs.h"
48
49/// Imil's two maps share actor numbers; each is named on the map it is proved.
51 // Town
52 ACTOR_COLD_VILLAGER = 8, ///< shivering and sneezing in the snow
56 // Interiors
57 ACTOR_OLD_WOMAN = 8, ///< the old couple's house
61 ACTOR_ITEM_SHOP_CHILD = 14, ///< minds the shop while the mother is sick
65 ACTOR_APPRENTICE = 19, ///< Mia's apprentices, the first in the sanctum
67};
68
69/// The town's own flags, kept while the party is there.
71 /// Which map layer the leader walks on, from where he stands.
75};
76
77// Keep native call forms while UBFIX uses the declared void contracts.
78#ifdef UBFIX
79#define IMIL_OPEN_SHOP Engine_ShopOpen
80#else
81#define IMIL_OPEN_SHOP ((s32 (*)())Engine_ShopOpen)
82#endif
83
84static void Imil_MeetMiaAtOldCouplesHouse(void);
85static void Imil_MiaCastsPlyOnOldMan(void);
86static void Imil_SpawnAmbientEffects(void);
88static void Imil_MoveSnowmanToChimney(void);
89static void Imil_ShowFirstArrival(void);
90static void Imil_MiaSaysFarewellToApprentices(void);
91static void Imil_RunIceSlide(void);
92
93/// The position (x, y, z) the unused arc and sway effects move around.
94extern s32 gImil_ArcOrigin[];
95
96/// A sick person shivers: a quick squash, then a pause, longer for the old man.
97static s32 Imil_UpdateShiver(struct ScriptInterpreter *interpreter) {
98 struct FieldActor *actor = (struct FieldActor *)interpreter;
99 switch (actor->timer) {
100 case 6:
101 actor->scaleX += -Q16_ONE / 4;
102 actor->scaleY += Q16_ONE / 8;
103 break;
104 case 4:
105 actor->scaleX += Q16_ONE / 8;
106 actor->scaleY -= Q16_ONE / 16;
107 break;
108 case 2:
109 actor->scaleX += Q16_ONE / 16;
110 actor->scaleY += -Q16_ONE / 32;
111 break;
112 case 0:
113 actor->scaleX += Q16_ONE / 16;
114 actor->scaleY += -Q16_ONE / 32;
115 if ((s16)actor->work != 0) {
116 actor->timer = (u32)Engine_RandomNext() % 40 + 40;
117 } else {
118 actor->timer = (u32)Engine_RandomNext() % 20 + 20;
119 }
120 break;
121 }
122 actor->timer--;
123 return 1;
124}
125
126#include "common/object_facing.h"
127
128/// Imil is two maps: the town and its interiors.
129const struct SceneEntrance *Imil_GetEntrances(void) {
132 }
133 return gImil_TownEntrances;
134}
135
136const struct SceneRegion *Imil_GetRegions(void) { return NULL; }
137
138const u32 *Imil_GetExits(void) { return gImil_Exits; }
139
140/// Once the epidemic is cured (flag 0x881), the townspeople are well again and
141/// the old man is up and about.
143 struct ScenePlacement *script;
144
145 if (gGameState.scene == ((s32)&SceneId_Imil2)) {
149 /* FAKEMATCH: retain row 10's talk-facing byte access (10 * 24 + 22);
150 * as script[10].talkFacing, tbs-en is two bytes shorter. */
151 ((u8 *)script)[262] = 0;
152 script[3].x = PIXELS(182);
153 script[3].z = PIXELS(564);
154 script[3].behavior = 2;
155 }
156 return script;
157 }
158
161 }
163}
164
165/// Stepping onto the ice starts a slide.
166static void Imil_StartIceSlide(void) { Imil_RunIceSlide(); }
167
168/// The town's or the interiors' conversations and Psynergy targets.
169const struct SceneEvent *Imil_GetEvents(void) {
172 }
173 return gImil_TownEvents;
174}
175
176/// The cold villager sneezes and shivers, waiting for Mia; once she travels
177/// with the party (flag 3), he says that even her healing can't help them all.
178static void Imil_TalkToColdVillager(void) {
181 Engine_EventSetMessage(MSGNO(MsgImilEvenIfMiaHealsUs));
182 } else {
183 Engine_EventSetMessage(MSGNO(MsgImilBrrrrrChooImFreezingMia));
184 }
185 {
186 s32 val = 0;
187 s32 mode = 8;
188 Engine_EventShowMessage(mode, val);
189 }
191}
192
193/// Mind Read on the cold villager: Mia should be here by now, or, once she
194/// has joined the party, he can't understand why she left.
195static void Imil_ReadColdVillagerMind(void) {
198 Engine_EventSetMessage(MSGNO(MsgImilCantUnderstandWhyAnyOne));
199 } else {
200 Engine_EventSetMessage(MSGNO(MsgImilMiaShouldHereByNow));
201 }
204}
205
206/// A villager turns to the leader and asks whether he is new in Imil.
207static void Imil_GreetVisitor(void) {
210 Engine_EventSetMessage(MSGNO(MsgImilHiNewInImil));
213}
214
215/// The counting child stops, turns to the leader and goes back to
216/// counting.
217static void Imil_TalkToCountingChild(void) {
219
221 Engine_EventSetMessage(MSGNO(MsgImilCountingAfterDeparture));
230 10);
232 } else {
233 Engine_EventSetMessage(MSGNO(MsgImilOneTwoThreeFour));
242 10);
244 }
245
247}
248
249/// The old man moans for help until the old woman hurries to fetch Mia; after
250/// Mia's healing he feels much better, and once the town is cured he asks
251/// whether the party really thought he would die.
252static void Imil_TalkToOldMan(void) {
253
254 struct FieldActor *oldMan;
255 struct FieldActor *oldWoman;
256
261 Engine_EventSetMessage(MsgMercuryReallySayDie);
264 } else {
269 Engine_EventSetMessage(MsgMercuryFeelMuchBetter);
274 } else {
277 oldMan->timer = 10;
279 Engine_EventSetMessage(MsgMercuryOoohHelpMe);
299 oldWoman->collisionFlags ^= 0x2;
300 GameFlag_Set(0x82c);
302 }
303 }
304}
305
306/// Once the epidemic is cured, the weapon merchant asks whether the party
307/// wants weapons.
308static void Imil_AskAboutWeapons(void) {
310 Engine_EventSetMessage(MSGNO(MsgImilDoWantWeapons));
313}
314
315/// Once the epidemic is cured, the restaurant owner offers the menu.
318 Engine_EventSetMessage(MSGNO(MsgImilDoWantSeeRestaurantMenu));
321}
322
323/// Mia's second apprentice asks whether the party has visited the old couple,
324/// where Mia went; once Mia has joined, she says everyone counts on her.
328 Engine_EventSetMessage(MSGNO(MsgImilEveryoneCountsOnMiaThats));
330 } else {
331 Engine_EventSetMessage(MsgImilHaveVisitedOldCoupleWho);
334 Engine_GameFlagSet(0x82c);
335 }
337}
338
339/// Mind Read on the second apprentice: Mia had a bad feeling, or, once she has
340/// joined, they must help her.
344 Engine_EventSetMessage(MSGNO(MsgImilWeHaveDoWhateverWe));
345 } else {
346 Engine_EventSetMessage(MSGNO(MsgImilMiaWasSayingSheHas));
347 }
350}
351
352/// Once the epidemic is cured, the old woman asks what happened at the
353/// lighthouse.
354static void Imil_TalkToOldWoman(void) {
356 Engine_EventSetMessage(MSGNO(MsgImilHappenedInLighthouseNortheast));
360}
361
362/// Mind Read on the old woman: about Mia's clan, her husband's exaggerating,
363/// or Mia running all over town.
364static void Imil_ReadOldWomanMind(void) {
367 Engine_EventSetMessage(MSGNO(MsgImilMiaClanOnceLivedHere));
368 } else if (Engine_GameFlagIsSet(0x82c) != 0) {
369 Engine_EventSetMessage(MSGNO(MsgImilHesAlwaysExaggeratingThingsBut));
370 } else {
371 Engine_EventSetMessage(MSGNO(MsgImilMiaRunningAroundTownCaring));
372 }
375}
376
377/// After Mia's visit, speaking across the bed reaches the old man.
379
380/// Mind Read on the counting child: admiration for Mia.
381static void Imil_ReadCountingChildMind(void) {
383 Engine_EventSetMessage(MSGNO(MsgImilMiaIsAGoodGirlI));
386}
387
388/// Mind Read on Mia's apprentice: she will do her best, or, once Mia has
389/// joined, she feels grown up.
390static void Imil_ReadApprenticeMind(void) {
393 Engine_EventSetMessage(MSGNO(MsgImilFeelLikeGrownUpWhen));
394 } else {
395 Engine_EventSetMessage(MSGNO(MsgImilTheseFolkOkayTheyDont));
396 }
399}
400
401/// Walking north into a door, everyone stops, the door opens and the leader
402/// walks in; door 6 has its own sound and a slower walk.
403static void Imil_OpenDoorAndExit(void) {
404 struct EventWork *event;
405 struct FieldActor *actor;
406 u32 i;
407 s32 exit;
408
409 event = gEventWork;
411 for (i = 8; i <= 65; i++) {
412 actor = Object_GetById(i);
413 if (actor != NULL) {
414 actor->motionFlags = 0;
415 }
416 }
417 exit = (s16)(event->touchedTrigger - 50);
418 if (exit == 6) {
420 } else {
422 }
423 {
424 s32 x = gImil_DoorCellPoints[exit - 1][0];
425 s32 y = gImil_DoorCellPoints[exit - 1][1];
426
428 }
431 if (exit == 6) {
436 } else {
439 }
443}
444
445/// Across the counter, the leader facing north, the weapon shop opens once the
446/// town is cured; before, the sick merchant says the shop is closed.
447static void Imil_TalkToWeaponMerchant(void) {
448 s32 facing;
449
452 if ((u32)((facing << 16) + 0x5fff0000) <= 0x3ffe0000) {
454 return;
455 }
459 Engine_EventSetMessage(MsgMercuryCatchUpLostOpportunity);
463 } else {
464 if ((u32)((facing << 16) + 0x5fff0000) <= 0x3ffe0000) {
467 Camera_MoveTo(PIXELS(426), -1, PIXELS(492), 1);
471 Engine_EventSetMessage(MsgMercuryStoreClosedUntilWell);
473 Engine_CameraMoveTo(PIXELS(426), -1, PIXELS(616), 1);
476 }
477 }
478}
479
480/// Across the counter, the leader facing north, the armor shop opens once the
481/// town is cured; before, the merchant is too sick for business.
482static void Imil_TalkToArmorMerchant(void) {
483 s32 facing;
484
487 if ((u32)((facing << 16) + 0x5fff0000) <= 0x3ffe0000) {
489 return;
490 }
494 Engine_EventSetMessage(MsgMercuryShameStoreClosed);
498 } else {
499 if ((u32)((facing << 16) + 0x5fff0000) <= 0x3ffe0000) {
502 Camera_MoveTo(PIXELS(426), -1, PIXELS(492), 1);
506 Engine_EventSetMessage(MsgMercuryTooSickBusiness);
508 Engine_CameraMoveTo(PIXELS(426), -1, PIXELS(616), 1);
511 }
512 }
513}
514
515/// The item shop: once the town is cured the mother sells again; before, her
516/// child minds the counter while she is sick, or talks of the lumberjack
517/// father.
518static void Imil_TalkToItemMerchant(void) {
519 s32 facing;
520
523 if ((u32)((facing << 16) + 0x5fff0000) <= 0x3ffe0000) {
525 return;
526 }
529 Engine_EventSetMessage(MsgMercuryRecoveredThanksFountain);
533 } else {
534 if ((u32)((facing << 16) + 0x5fff0000) <= 0x3ffe0000) {
536 Engine_EventSetMessage(MsgMercuryMomsSickGetWhatever);
538 /* FAKEMATCH: called through a cast to the value-returning call the bytes
539 * show; as a call by its void prototype, the two argument moves swap and
540 * 2 instructions differ in tbs-en. */
541 IMIL_OPEN_SHOP(12, 14);
543 } else {
545 Engine_EventSetMessage(MsgMercuryDadLumberjack);
548 10);
549 }
550 }
551}
552
553/// Across the counter, the leader facing north, the inn opens; otherwise the
554/// innkeeper talks of the two groups of travellers, or of the party's leaving.
555static void Imil_TalkToInnkeeper(void) {
556 struct FieldActor *leader;
557
559 if ((u16)(leader->facing + 0x5fff) <= 0x3ffe) {
561 } else {
565 Engine_EventSetMessage(MSGNO(MsgImilItsAlmostTimeForLeave));
567 } else {
568 Engine_EventSetMessage(MSGNO(MsgImilWhyHaveTwoGroupsTravelers));
570 }
573 }
574}
575
576/// Across the counter, the leader facing north, Mia's apprentice offers the
577/// sanctum, the first time saying she can act as healer; otherwise she talks of
578/// Mia.
579static void Imil_TalkToApprentice(void) {
580 struct FieldActor *leader;
581
583 if ((u16)(leader->facing + 0x5fff) <= 0x3ffe) {
586 Engine_EventSetMessage(MSGNO(MsgImilMayOnlyStudentButCan));
589 }
592 } else {
595 Engine_EventSetMessage(MSGNO(MsgImilMiaGoingOnJourneyWith));
597 } else if (GameFlag_IsSet(FLAG_IN_PARTY(MIA)) != 0) {
598 Engine_EventSetMessage(MSGNO(MsgImilAmHealerWhileMiaOut));
600 } else {
601 Engine_EventSetMessage(MSGNO(MsgImilLookingForMia));
604 }
606 }
607}
608
609/// The town gets its rising effects, map layers and snowman, and the first
610/// arrival walks in; each interior restores its people for the town's state.
612 struct FieldActor *leader;
613 s32 entrance;
614
622 }
623 leader->timer = 0;
624 leader->work = 0;
631 }
633 gGameState.entrance == 9) {
635 }
636 } else if (gGameState.scene == (s32)&SceneId_Imil2) {
637 // Restore each interior's occupants before running its arrival event.
639 entrance = gGameState.entrance;
640 if (entrance == 1) {
645 Map_CopyCellAttributes(10, 7, 1, 1, 10, 8);
646 Map_CopyCellsTo(3, 125, 9, 69, 3, 3);
650 Engine_ActorSetPosition(10, 0, 0);
651 } else if (Engine_GameFlagIsSet(0x82c) &&
662 }
663 } else {
664 Map_CopyCellAttributes(10, 7, 1, 1, 10, 8);
665 Map_CopyCellsTo(3, 125, 9, 69, 3, 3);
668 if (Engine_GameFlagIsSet(0x82c)) {
673 } else {
675 }
676 }
677 } else if (entrance == 2) {
679 Object_GetById(11)->work = 1;
681 }
682 } else if (entrance == 4) {
687 Map_CopyCellsTo(6, 125, 22, 88, 3, 3);
691 Map_CopyCellsTo(9, 125, 28, 88, 3, 3);
692 } else {
698 }
699 } else if (entrance == 3) {
705 PIXELS(264));
708 Map_CopyCellsTo(12, 125, 26, 70, 3, 3);
709 } else {
716 }
717 } else if (entrance == 7) {
724 } else {
726 }
727 }
728 }
729 }
730 return 0;
731}
732
733/// After hearing where Mia went, the party finds her at the old couple's
734/// house. She heals the old man with Ply when the Mercury Lighthouse flashes;
735/// Mia runs out and the party follows her.
737 struct FieldActor *leader;
738 const s32 *table;
739 struct EventWork *work;
740
742 Actor_SetPosition(MIA, PIXELS(182), PIXELS(150));
743 Camera_MoveTo(PIXELS(141), -1, PIXELS(221), 0);
745 Camera_SetSpeed(PIXELS(3) / 10, PIXELS(3) / 80);
746 Camera_MoveTo(PIXELS(140), -1, PIXELS(164), 1);
747 work = gEventWork;
749 work->transitionFrames = 40;
752 Actor_SetSpeed(GARET, PIXELS(2) / 5, PIXELS(1) / 5);
753 Actor_SetSpeed(IVAN, PIXELS(2) / 5, PIXELS(1) / 5);
757 if (leader != NULL) {
758 Actor_SetPosition(GARET, leader->x.fixed, leader->z.fixed);
759 }
761 if (leader != NULL) {
762 Actor_SetPosition(IVAN, leader->x.fixed, leader->z.fixed);
763 }
764 Actor_WalkTo(GARET, 150, 234);
765 Actor_WalkToAndWait(IVAN, 134, 234);
774 table = gImil_BobScript;
780 // Mia checks on the old man while the party enters the house.
781 Engine_EventSetMessage(MSGNO(MsgImilHowFeeling));
795
796 // Play the healing effect, then let the old man respond.
826 Actor_SetSpeed(MIA, PIXELS(1), PIXELS(1) / 2);
829 while (Object_GetById(MIA)->timer == 0) {
831 }
832 Camera_MoveTo(PIXELS(140), -1, PIXELS(198), 1);
840 // The lighthouse interrupts the visit; Mia leaves and the party follows.
842 ColorBuffer_ApplyTarget(0x207e9f, 0);
846 Engine_TaskWait(40);
849 Engine_TaskWait(60);
852 Actor_FaceDirection(MIA, 0, 10);
854 Actor_WalkToAndWait(MIA, 202, 198);
868 Actor_SetSpeed(MIA, PIXELS(3), PIXELS(3) / 2);
871 while (Object_GetById(MIA)->timer == 0) {
873 }
885 Actor_SetDestination(GARET, 136, 221);
886 Actor_SetDestination(IVAN, 122, 238);
893 Actor_SetSpeed(GARET, PIXELS(4) / 5, PIXELS(2) / 5);
894 Actor_SetSpeed(IVAN, PIXELS(4) / 5, PIXELS(2) / 5);
899 work = gEventWork;
901 work->transitionFrames = 24;
904}
905
906/// Moves an unused effect around its stored origin until its timer expires.
907UNUSED static void Imil_UpdateCountdownArc(struct FieldActor *actor) {
908 s32 buf[3];
909 s32 *b;
910 s32 n;
911 s32 t;
912
913 if (actor != NULL) {
914 n = (u16)actor->timer - 1;
915 actor->timer = n;
916 t = (s16)n;
917 if (t != 0) {
918 b = buf;
919 b[0] = gImil_ArcOrigin[0];
920 b[1] = gImil_ArcOrigin[1] + PIXELS(8);
921 b[2] = gImil_ArcOrigin[2];
922 Vector_AddPolarOffset(t << 16, (t << 11) + (s16)actor->work, b);
923 actor->x.fixed = b[0];
924 actor->y.fixed = b[1];
925 actor->z.fixed = b[2];
926 } else {
928 }
929 }
930}
931
932/// Sways an unused actor and occasionally emits a rising spark.
933UNUSED static void Imil_SwayAndSpark(struct FieldActor *actor) {
934 s32 pos[3];
935 struct FieldActor *spark;
936 s32 radius;
937
938 actor->x.fixed = gImil_ArcOrigin[0] +
939 Iwram_MulQ16(0x60000, Engine_MathSin(actor->timer << 10));
940 actor->timer++;
941 actor->timer = (actor->timer + 64) % 64;
942 if (gFrameCount % 3 == 0) {
943 SET_VECTOR(pos, actor->x.fixed, actor->y.fixed + PIXELS(2), actor->z.fixed);
946 spark = Engine_ObjectCreate(0x11d, pos[0], pos[1], pos[2]);
947 if (spark != NULL) {
948 spark->sprite->image.priority = 0;
950 Object_SetMode(spark, 1);
951 spark->scaleX = 3 * Q16_ONE / 5;
952 spark->scaleY = 3 * Q16_ONE / 5;
953 spark->priorityFlags = 2;
954 spark->motionFlags = 0;
957 }
958 }
959}
960
961/// The old man bobs and speaks as the healing reaches him.
962static void Imil_OldManBobsAndSpeaks(void) {
965}
966
967static void Imil_MiaCastsPlyOnOldMan(void) {
968 u8 *work;
969
973 *(s32 *)(work + 36) = (s32)Imil_OldManBobsAndSpeaks;
978}
979
980/// Resets a rising effect's motion, sprite priority, and initial scale.
982 struct AnimationObject *sprite;
983
984 work->motionFlags = 0;
985 work->timer = 0;
986 work->priorityFlags &= ~1;
987
988 sprite = work->sprite;
989 sprite->image.priority = 1;
990
993
994 work->scaleX = Q16_ONE / 2;
995 work->scaleY = Q16_ONE / 2;
996}
997
998/// Moves and enlarges an ambient effect, then releases it when its timer
999/// expires.
1000static void Imil_UpdateRisingEffect(union FieldObject *object) {
1001 object->effect.x += (s16)object->effect.spin << 8;
1002 object->effect.y += PIXELS(1) / 2;
1003 object->effect.scaleX += 3 * Q16_ONE / 100;
1004 object->effect.scaleY += 3 * Q16_ONE / 100;
1005 object->effect.spin += 2;
1006 if (--object->effect.countdown == 0) {
1008 }
1009}
1010
1011/// Initializes a newly created ambient effect for its one-second rise.
1012static inline void Imil_StartRisingEffect(union FieldObject *object) {
1013 if (object != NULL) {
1015 object->effect.countdown = 60;
1016 object->effect.update = Imil_UpdateRisingEffect;
1017 Object_SetMode(&object->actor, 5);
1018 }
1019}
1020
1021/// Effects rise at five places in the town, staggered over each second.
1022static void Imil_SpawnAmbientEffects(void) {
1023 // volatile: the type of &gFrameCount (tagged in frame.h); the six editions
1024 // build the same bytes without it
1025 volatile u32 *frame;
1026 union FieldObject *object;
1027
1028 frame = &gFrameCount;
1029 if (((u32)*frame % (u32)60) == 0) {
1030 object =
1031 (union FieldObject *)Object_Create(222, PIXELS(463), 0, PIXELS(292));
1032 Imil_StartRisingEffect(object);
1033 }
1034 if (((u32)(*frame + 30) % (u32)60) == 0) {
1035 object = (union FieldObject *)Object_Create(222, PIXELS(320), PIXELS(32),
1036 PIXELS(356));
1037 Imil_StartRisingEffect(object);
1038 }
1039 if (((u32)(*frame + 10) % (u32)60) == 0) {
1040 object =
1041 (union FieldObject *)Object_Create(222, PIXELS(118), 0, PIXELS(70));
1042 Imil_StartRisingEffect(object);
1043 }
1044 if (((u32)(*frame + 50) % (u32)60) == 0) {
1045 object =
1046 (union FieldObject *)Object_Create(222, PIXELS(342), 0, PIXELS(124));
1047 Imil_StartRisingEffect(object);
1048 }
1049 if (((u32)(*frame + 80) % (u32)60) == 0) {
1050 object =
1051 (union FieldObject *)Object_Create(222, PIXELS(431), 0, PIXELS(171));
1052 Imil_StartRisingEffect(object);
1053 }
1054}
1055
1056/// The leader walks on map layer 0 near the middle of town and on layer 1
1057/// elsewhere.
1059 struct FieldActor *actor;
1060 s32 x;
1061 s32 column;
1062 s32 isSet;
1063 s32 zoneFlag;
1064 s32 otherZoneFlag;
1065 struct MapState *map;
1066
1068 x = actor->x.fixed;
1069 column = x >> 19;
1070 zoneFlag = FLAG_IMIL_MAP_LAYER_0;
1071 otherZoneFlag = FLAG_IMIL_MAP_LAYER_1;
1072 if ((u32)(column - 24) <= 7 ||
1073 ((u32)((actor->z.fixed >> 19) - 36) <= 9 && (u32)(column - 22) <= 9)) {
1074 isSet = Engine_GameFlagIsSet(zoneFlag);
1075 if (isSet != 0)
1076 return;
1077 ((struct MapState *)gMapWork[0])->unk17 = isSet;
1078 Engine_GameFlagSet(zoneFlag);
1079 Engine_GameFlagClear(otherZoneFlag);
1080 return;
1081 }
1082 if (x > 0xE80000 && actor->y.fixed > 0x1E0000 && actor->z.fixed > 0xD40000) {
1083 map = gMapWork[0];
1084 map->unk17 = 0;
1085 Engine_GameFlagSet(zoneFlag);
1086 Engine_GameFlagClear(otherZoneFlag);
1087 return;
1088 }
1089 isSet = Engine_GameFlagIsSet(otherZoneFlag);
1090 if (isSet != 0)
1091 return;
1092 map = gMapWork[0];
1093 map->unk17 = 1;
1094 Engine_GameFlagSet(otherZoneFlag);
1095 Engine_GameFlagClear(zoneFlag);
1096 return;
1097}
1098
1099/// Moved onto the chimney, the snowman stays there and blocks its cell.
1100static void Imil_MoveSnowmanToChimney(void) {
1101 s32 a;
1102 s32 b;
1103
1104#if TBS_PATCH_3
1105 struct FieldActor *actor = Object_GetById(ACTOR_SNOWMAN);
1106
1107 a = actor->x.fixed >> 20;
1108 if (a != 15)
1109 return;
1110 b = actor->z.fixed >> 20;
1111 if (b != 7)
1112 return;
1115#else
1118 a = 15;
1119 b = 7;
1120#endif
1121 Map_CopyCellAttributes(15, 6, 1, 1, a, b);
1122}
1123
1124/// Walking into the north path, the leader faces north and leaves the town.
1125static void Imil_LeaveNorth(void) {
1126 struct FieldActor *work;
1127
1130 work->facing = FACING_NORTH;
1135}
1136
1137/// Arriving for the first time, the leader walks into town.
1138static void Imil_ShowFirstArrival(void) {
1144}
1145
1146/// Once the town is cured, Mia says farewell to her two apprentices in the
1147/// sanctum before leaving with the party.
1149
1150 struct FieldActor *leader;
1151 struct EventWork *work;
1152
1157
1159 Engine_CameraSetSpeed(PIXELS(4) / 5, PIXELS(1) / 10);
1160 Camera_MoveTo(PIXELS(690), 0, PIXELS(164), 1);
1161 work = gEventWork;
1163 work->transitionFrames = 48;
1167 Actor_SetSpeed(MIA, PIXELS(3) / 5, PIXELS(3) / 10);
1169 if (leader != NULL) {
1170 Actor_SetPosition(MIA, leader->x.fixed, leader->z.fixed);
1171 }
1172 Actor_WalkToAndWait(MIA, 673, 183);
1176 Engine_EventWait(40);
1177 Engine_EventSetMessage(MSGNO(MsgImilMia));
1182 Engine_EventWait(20);
1184 10);
1189 Engine_EventWait(20);
1191 Engine_EventWait(20);
1199 Engine_EventWait(20);
1201 20);
1204 Engine_EventWait(60);
1209 Engine_EventWait(20);
1217 0);
1221 20);
1223 // Let the student approach Mia before she rejoins the party.
1228 Engine_EventWait(20);
1230 10);
1232 Engine_EventWait(40);
1239 Engine_EventWait(40);
1248 Engine_EventWait(20);
1251 20);
1253 Engine_EventWait(20);
1263 20);
1271 10);
1280 Engine_EventWait(40);
1285 Engine_EventWait(20);
1286 Actor_WalkToAndWait(MIA, 688, 200);
1287 Actor_SetPosition(MIA, 0, 0);
1291 // Restore the student's steering after the farewell walk.
1292 /* FAKEMATCH: retain the byte access to steeringFlags; as the direct field,
1293 * the next gGameState load and constant move swap and 2 instructions differ
1294 * in tbs-en. */
1301}
1302
1303/// While sliding, the leader turns toward the held direction.
1304static void Imil_TurnSlidingActor(union FieldObject *object) {
1305 struct FieldActor *actor;
1306 s32 z;
1307 s32 t;
1308 s32 d;
1309 u16 prev;
1310 s32 n;
1311
1312 actor = &object->actor;
1313 n = (u16)actor->timer;
1314 z = 0;
1315 t = ((s16 *)&actor->timer)[z];
1316 if (t != 0) {
1317 actor->timer = n - 1;
1318 return;
1319 }
1320 actor->steeringFlags = t;
1321 z = 1;
1322 d = gImil_KeyHeadings[(gKeysHeld >> 4) & 0xF];
1323 z = -z;
1324 if (d == z) {
1325 Object_SetMode(actor, 9);
1326 return;
1327 }
1328 prev = actor->facing;
1329 d = (s16)(d - prev);
1330 if (d > 0x1000)
1331 d = 0x1000;
1332 if (d < -0x1000)
1333 d = -0x1000;
1334 actor->facing = prev + d;
1335 Object_SetMode(actor, 2);
1336 ObjectDispatch_SetAnimationSpeed((struct DispatchObject *)actor, 0x30);
1337}
1338
1339/// The leader slides along the ice until something stops him.
1340static void Imil_RunIceSlide(void) {
1341
1342 struct FieldActor *subject;
1343 struct FieldPosition probe;
1344 s32 heading;
1345 s32 goal;
1346 s32 marker;
1347 s32 z;
1348 s32 x;
1349 u8 *terrainId;
1350
1352
1353 for (;;) {
1354 heading = gImil_SwayHeadings[(gKeysHeld >> 4) & 15];
1355 if ((heading << 16) == -0x10000) {
1356 return;
1357 }
1358
1360
1361 probe.x = (subject->x.fixed & 0xfff00000) + PIXELS(8);
1362 probe.y = subject->y.fixed;
1363 probe.z = (subject->z.fixed & 0xfff00000) + PIXELS(8);
1364 z = probe.z;
1365 x = probe.x;
1366 terrainId = &subject->terrainId;
1367 goal = GetMapCellCollision(*terrainId, x, z);
1368 Vector_AddPolarOffset(PIXELS(16), heading, &probe);
1369
1370 marker = GetMapCellCollision(*terrainId, probe.x, probe.z);
1371 if (marker == 255 ||
1372 Map_GetTerrainHeight(*terrainId, probe.x, probe.z) - subject->y.fixed >
1373 PIXELS(8)) {
1374 subject->facing = heading;
1375 goto tail;
1376 }
1377
1378 probe.x = x;
1379 probe.z = z;
1380 subject->speed = PIXELS(2);
1381 subject->acceleration = PIXELS(1) / 10;
1382 subject->timer = 0;
1383 Engine_ObjectSetPosition(subject, x, subject->y.fixed, z);
1384 Object_SetMode(subject, 2);
1385 ObjectDispatch_SetAnimationSpeed((struct DispatchObject *)subject, 48);
1386 FieldObject_WaitForMove(subject);
1387 subject->update = Imil_TurnSlidingActor;
1388
1389 // Advance along the slide until its next cell is blocked or too high.
1390 for (;;) {
1391 FieldVector_AddPolarOffset(PIXELS(16), heading, &probe);
1392 if ((marker = GetMapCellCollision(*terrainId, probe.x, probe.z)) == 255) {
1393 break;
1394 }
1395 if (Map_GetTerrainHeight(*terrainId, probe.x, probe.z) -
1396 subject->y.fixed >
1397 0x80000) {
1398 break;
1399 }
1400 x = probe.x;
1401 z = probe.z;
1402 subject->speed = PIXELS(2);
1403 subject->acceleration = PIXELS(1) / 10;
1404 Engine_ObjectSetPosition(subject, probe.x, probe.y, probe.z);
1405 FieldObject_WaitForMove(subject);
1406 if (marker != goal) {
1407 goto blocked;
1408 }
1409 }
1410
1411 subject->speed = PIXELS(2);
1412 subject->acceleration = PIXELS(1);
1413 Engine_ObjectSetPosition(subject, x, subject->y.fixed, z);
1414 FieldObject_WaitForMove(subject);
1415 Engine_TaskWait(2);
1416 }
1417
1418blocked:
1419 subject->update = NULL;
1420 subject->steeringFlags |= 1;
1421
1422 subject->acceleration = PIXELS(1) / 4;
1423
1424tail:
1425 Engine_TaskWait(10);
1427}
1428
1429// clang-format off
1435};
1436
1440};
1441
1445 SC_ADD(SW_SCALE_X, -5 * Q16_ONE / 16),
1446 SC_ADD(SW_SCALE_Y, Q16_ONE / 16),
1447 SC_WAIT(1),
1448 SC_ADD(SW_SCALE_X, 5 * Q16_ONE / 32),
1449 SC_ADD(SW_SCALE_Y, -2048),
1450 SC_WAIT(1),
1451 SC_ADD(SW_SCALE_X, 5 * Q16_ONE / 64),
1452 SC_ADD(SW_SCALE_Y, -1024),
1453 SC_WAIT(1),
1454 SC_ADD(SW_SCALE_X, 5 * Q16_ONE / 64),
1455 SC_ADD(SW_SCALE_Y, -1024),
1456 SC_WAIT(1),
1458};
1459
1463};
1464
1466 SC_ARG(2),
1467 SC_MOVE(PIXELS(136), 0, PIXELS(192)),
1468 SC_SYNC,
1469 SC_MOVE(PIXELS(136), 0, PIXELS(136)),
1470 SC_SYNC,
1471 SC_MOVE(PIXELS(149), 0, PIXELS(116)),
1472 SC_SYNC,
1474 SC_ARG(1),
1475 SC_END,
1476};
1477
1479 SC_ARG(2),
1480 SC_MOVE(PIXELS(155), 0, PIXELS(135)),
1481 SC_SYNC,
1482 SC_ARG(1),
1483 SC_SET(SW_FACING, 0xd000),
1484 SC_END,
1485 SC_ADD(SW_SCALE_Y, 3 * Q16_ONE / 8),
1486 SC_WAIT(2),
1487 SC_ADD(SW_SCALE_Y, -3 * Q16_ONE / 16),
1488 SC_WAIT(2),
1489 SC_ADD(SW_SCALE_Y, -3 * Q16_ONE / 32),
1490 SC_WAIT(2),
1491 SC_ADD(SW_SCALE_Y, -3 * Q16_ONE / 32),
1492 SC_WAIT(4),
1493 SC_END,
1494};
1495
1497 SC_ADD(SW_SCALE_Y, 3 * Q16_ONE / 8),
1498 SC_WAIT(2),
1499 SC_ADD(SW_SCALE_Y, -3 * Q16_ONE / 16),
1500 SC_WAIT(2),
1501 SC_ADD(SW_SCALE_Y, -3 * Q16_ONE / 32),
1502 SC_WAIT(2),
1503 SC_ADD(SW_SCALE_Y, -3 * Q16_ONE / 32),
1504 SC_WAIT(4),
1505 SC_LOOP(2, SC_TOP),
1506 SC_END,
1507};
1508
1510 SC_ADD(SW_Y, -PIXELS(2) / 5),
1511 SC_WAIT(1),
1512 SC_LOOP(72, SC_TOP),
1513 SC_FREE,
1514};
1515
1517 SC_ARG(2),
1518 SC_MOVE(PIXELS(177), 0, PIXELS(136)),
1519 SC_SYNC,
1520 SC_MOVE(PIXELS(161), 0, PIXELS(124)),
1521 SC_SYNC,
1522 SC_SET(0x23, 1),
1523 SC_MOVE(PIXELS(134), 0, PIXELS(139)),
1524 SC_SYNC,
1525 SC_MOVE(PIXELS(135), 0, PIXELS(189)),
1526 SC_SYNC,
1527 SC_ARG(1),
1528 SC_END,
1529};
1530
1532 SC_ARG(2),
1533 SC_MOVE(PIXELS(165), 0, PIXELS(207)),
1534 SC_SYNC,
1535 SC_SET(0x23, 1),
1536 SC_MOVE(PIXELS(147), 0, PIXELS(252)),
1537 SC_SYNC,
1538 SC_MOVE(PIXELS(150), 0, PIXELS(268)),
1539 SC_SYNC,
1540 SC_POS(0, 0, 0),
1541 SC_WAIT(1),
1542 SC_END,
1543};
1544
1546 SC_CALL(Scene_TurnTowardTarget),
1548};
1549
1551 SC_ARG(2),
1552 SC_MOVE(PIXELS(132), 0, PIXELS(206)),
1553 SC_SYNC,
1554 SC_POS(0, 0, 0),
1555 SC_WAIT(1),
1556 SC_END,
1557};
1558
1560 { 0, CONDITION_ALWAYS, 380, 0, 433, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1561 { 1, CONDITION_ALWAYS, 288, 0, 488, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
1562 { 2, CONDITION_ALWAYS, 480, 0, 280, FACING_WEST, 0, -1, -1, -1, -1, 0 },
1563 { 3, CONDITION_ALWAYS, 312, 0, 424, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1564 { 4, CONDITION_ALWAYS, 424, 0, 392, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1565 { 5, CONDITION_ALWAYS, 456, 0, 248, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1566 { 6, CONDITION_ALWAYS, 376, 0, 200, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1567 { 7, CONDITION_ALWAYS, 120, 0, 208, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1568 { 8, CONDITION_ALWAYS, 64, 0, 360, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1569 { 9, CONDITION_ALWAYS, 229, 0, 88, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1570 { SCENE_TABLE_END },
1571};
1572
1574 { 0, CONDITION_ALWAYS, 136, 0, 248, FACING_NORTH, 0, -1, -1, -1, -1, 0 },
1575 { 1, CONDITION_ALWAYS, 144, 0, 242, FACING_NORTH, 0, 32, 52, 256, 280, 0 },
1576 { 2, CONDITION_ALWAYS, 143, 0, 596, FACING_NORTH, 0, 42, 424, 256, 631, 0 },
1577 { 3, CONDITION_ALWAYS, 399, 0, 322, FACING_NORTH, 0, 320, 58, 536, 360, 0 },
1578 { 4, CONDITION_ALWAYS, 400, 0, 659, FACING_NORTH, 0, 307, 382, 545, 697, 0 },
1579 { 5, CONDITION_ALWAYS, 129, 0, 915, FACING_NORTH, 0, 50, 706, 350, 949, 0 },
1580 { 6, CONDITION_ALWAYS, 446, 0, 825, FACING_SOUTH, 0, 402, 740, 670, 921, 0 },
1581 { 7, CONDITION_ALWAYS, 687, 0, 264, FACING_NORTH, 0, 594, 49, 806, 295, 0 },
1582 { 8, CONDITION_ALWAYS, 182, 0, 772, FACING_SOUTH, 0, 50, 706, 350, 949, 0 },
1583 { SCENE_TABLE_END },
1584};
1585
1587 SCENE_EXITS(50),
1588 SCENE_EXIT(1, 51, 1),
1589 SCENE_EXIT(2, 51, 5),
1590 SCENE_EXIT(3, 51, 3),
1591 SCENE_EXIT(4, 51, 4),
1592 SCENE_EXIT(5, 51, 2),
1593 SCENE_EXIT(6, 51, 7),
1594 SCENE_EXIT(8, 52, 1),
1595 SCENE_EXIT(11, 2, 9),
1596 SCENE_EXIT(12, 2, 39),
1597 SCENE_EXIT(0, 51, 0),
1598 SCENE_EXIT(1, 50, 3),
1599 SCENE_EXIT(2, 50, 7),
1600 SCENE_EXIT(3, 50, 5),
1601 SCENE_EXIT(4, 50, 6),
1602 SCENE_EXIT(5, 50, 4),
1603 SCENE_EXIT(6, 51, 8),
1604 SCENE_EXIT(7, 50, 8),
1605 SCENE_EXIT(8, 51, 6),
1607};
1608
1618 { SCENE_TABLE_END },
1619};
1620
1630 { SCENE_TABLE_END },
1631};
1632
1634 { 0x6f, 0x0, ACTOR_STAND,
1635 PIXELS(111), 0, PIXELS(215), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1636 { 0x67, 0x0, ACTOR_STAND,
1637 PIXELS(166), 0, PIXELS(116), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1638 { 0x16, 0x0, 7,
1639 PIXELS(174), 0, PIXELS(173), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1640 { 0x67, 0x0, ACTOR_STAND,
1641 PIXELS(118), 0, PIXELS(488), FACING_NORTH, TALK_FACE_PARTY, 0 },
1642 { 0x67, 0x0, ACTOR_STAND,
1643 PIXELS(370), 0, PIXELS(468), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1644 { 0x67, 0x0, ACTOR_STAND,
1645 PIXELS(478), 0, PIXELS(468), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1646 { 0x66, 0x0, ACTOR_STAND,
1647 PIXELS(460), 0, PIXELS(266), FACING_SOUTH + FACING_STEP, TALK_FACE_PARTY, 0 },
1648 { 0x73, 0x0, ACTOR_STAND,
1649 PIXELS(436), 0, PIXELS(184), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1650 { 0x77, 0x0, ACTOR_STAND,
1652 { 0x80, 0x0, ACTOR_WANDER,
1653 PIXELS(160), 0, PIXELS(880), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1654 { 0x6c, 0x0, ACTOR_STAND,
1656 { 0x6b, 0x0, ACTOR_STAND,
1657 PIXELS(686), 0, PIXELS(148), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1658 { 0x66, 0x0, ACTOR_STAND,
1661 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1663 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1665 0, 0, 0, FACING_SOUTH, TALK_FACE_PARTY, 0 },
1666 { 0xdf, 0x0, 7,
1667 PIXELS(192), 0, PIXELS(124), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1668 { SCENE_TABLE_END },
1669};
1670
1672 { EVENT_EXIT, 60, CONDITION_ALWAYS, 11 },
1673 { EVENT_EXIT, 61, CONDITION_ALWAYS, 12 },
1684 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgImilTheMercuryLighthouseIsShiningMia) },
1686 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgImilImilWillBeFineDiseaseIs) },
1689 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgImilMiaWasOnlyInImilTo) },
1690 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, 0x881, MSGNO(MsgImilWeveHadALotOfStrangers) },
1691 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgImilDontWorryAboutUsMiaWell) },
1692 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, 0x881, MSGNO(MsgImilPeopleGetSickBecauseTheyStay) },
1693 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgImilNowThatIveLetMyGuard) },
1694 { SEARCH(SEARCH_JAR), 100, 0xf5f, FIND_COINS(9) },
1695 { SEARCH(SEARCH_CHEST), 101, 0xf60, FIND_ITEM(ITEM_VIAL) },
1696 { SEARCH(SEARCH_GRAVE), 102, 0xf61, FIND_ITEM(ITEM_LUCKY_MEDAL) },
1697 { SCENE_EVENTS_END },
1698};
1699
1701 { EVENT_TALK, 8, 0x82c, MSGNO(MsgImilTheresBeenAnEpidemicGoingAround) },
1702 { EVENT_TALK, 8, FLAG_IMIL_MET_MIA, MSGNO(MsgImilGetMiaHurry) },
1704 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgImilThatFountainWaterReallyMadeGrandpa) },
1706 { EVENT_TALK, 9, FLAG_IMIL_MET_MIA, MSGNO(MsgImilItHurts) },
1709 { EVENT_TALK, 11, 0x881, MSGNO(MsgImilCoughTheEpidemicHasHitAlmost) },
1710 { EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgImilItsNiceThatTheFountainCan) },
1713 { EVENT_TALK, 13, 0x881, MSGNO(MsgImilWereClosedSorryIGetA) },
1715 { EVENT_TALK, 15, 0x881, MSGNO(MsgImilIfYouWantToBuyAnything) },
1718 { EVENT_TALK, 14, CONDITION_ALWAYS, MSGNO(MsgImilImSoHappyThatMommyIs) },
1720 { EVENT_TALK, 17, 0x881, MSGNO(MsgImilWereTheOnlyInnThatStays) },
1721 { EVENT_TALK, 17, CONDITION_ALWAYS, MSGNO(MsgImilThankGoodnessTheTownIsBack) },
1723 { EVENT_TALK, 18, CONDITION_ALWAYS, MSGNO(MsgImilImGladTheBeaconHasBeen) },
1726 { EVENT_TALK, 20, CONDITION_ALWAYS, MSGNO(MsgImilIWillBeAKindGirl) },
1728 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgImilGrandpasAllBetterNowThanksTo) },
1730 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, FLAG_IMIL_MET_MIA, MSGNO(MsgImilOoohIDontFeelSoGood) },
1731 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, 0x881, MSGNO(MsgImilMiaIsAGoodGirlI) },
1732 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgImilNowMiaCanLeaveTheVillage) },
1734 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, 0x881, MSGNO(MsgImilHerPalmsShineWithABlue) },
1735 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgImilThatBlueLightFromHerHands) },
1736 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, 0x881, MSGNO(MsgImilWhoAreThesePeopleTheyMust) },
1737 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgImilCustomersAreHardToComeBy) },
1738 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, 0x881, MSGNO(MsgImilWhyDoTheyAlwaysComeWhen) },
1739 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgImilTheCustomersAreBackIThought) },
1740 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, 0x881, MSGNO(MsgImilIfOnlyWeHadSomeOf) },
1741 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgImilMiaSaidItWouldntBeGood) },
1742 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, 0x881, MSGNO(MsgImilIWonderIfTheyAreHeaded) },
1743 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 14, CONDITION_ALWAYS, MSGNO(MsgImilMyDaddysStillInKolimaIll) },
1744 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, 0x881, MSGNO(MsgImilSoManyCustomersItJustGoes) },
1745 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgImilMiaWillBeLeavingWithYou) },
1746 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, 0x881, MSGNO(MsgImilWintersAreToughHereSoIm) },
1747 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 17, CONDITION_ALWAYS, MSGNO(MsgImilTheyCameToOurVillageAnd) },
1748 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 18, 0x881, MSGNO(MsgImilWeDontGetToEatMany) },
1749 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 18, CONDITION_ALWAYS, MSGNO(MsgImilINeverToldMiaThatI) },
1751 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 19, CONDITION_ALWAYS, MSGNO(MsgImilMiasGoingToDefendTheHonor) },
1753 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 20, CONDITION_ALWAYS, MSGNO(MsgImilImSorryMiaButICant) },
1754 { 0xc403, 10, 0x881, EVENT_SCRIPT(Imil_TalkToWeaponMerchant) },
1755 { 0xc403, 11, 0x881, EVENT_SCRIPT(Imil_TalkToArmorMerchant) },
1757 { SEARCH(SEARCH_BARREL), 101, 0xf62, FIND_ITEM(ITEM_SLEEP_BOMB) },
1758 { SEARCH(SEARCH_OVEN), 102, 0xf63, FIND_ITEM(ITEM_LUCKY_PEPPER) },
1759 { SEARCH(SEARCH_OVEN), 200, CONDITION_ALWAYS, FIND_MESSAGE(MSGNO(MsgImilItLooksLikePorridgeItIs)) },
1760 { SEARCH(SEARCH_OVEN), 102, CONDITION_ALWAYS, FIND_MESSAGE(MSGNO(MsgImilItsSomeHotStewItWarms)) },
1761 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1762 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1763 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1764 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1765 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1766 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
1767 { EVENT_EXIT, 7, CONDITION_ALWAYS, 7 },
1768 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
1769 { SCENE_EVENTS_END },
1770};
1771
1773 MAP_CELL_STEP(40, 37, 4, 2, 5), MAP_CELL_STEP(40, 39, 4, 2, 5), MAP_CELL_STEPS_END,
1774 MAP_CELL_STEP(35, 35, 2, 2, 5), MAP_CELL_STEP(33, 35, 2, 2, 5), MAP_CELL_STEPS_END,
1775};
1776
1778 MAP_CELL_STEP(35, 37, 2, 2, 5), MAP_CELL_STEP(33, 37, 2, 2, 5), MAP_CELL_STEPS_END,
1779};
1780
1782 MAP_CELL_STEP(35, 43, 2, 2, 5), MAP_CELL_STEP(33, 43, 2, 2, 5), MAP_CELL_STEPS_END,
1783};
1784
1786 MAP_CELL_STEP(35, 39, 2, 2, 5), MAP_CELL_STEP(33, 39, 2, 2, 5), MAP_CELL_STEPS_END,
1787};
1788
1790 MAP_CELL_STEP(42, 48, 2, 2, 5), MAP_CELL_STEP(40, 48, 2, 2, 5), MAP_CELL_STEPS_END,
1791};
1792
1794 MAP_CELL_STEP(42, 46, 2, 2, 5), MAP_CELL_STEP(40, 46, 2, 2, 5), MAP_CELL_STEPS_END,
1795};
1796
1804};
1805
1806/// Cell position (x, y) for each exit.
1808 { 50, 24 }, { 57, 22 }, { 59, 13 }, { 54, 10 }, { 38, 8 }, { 34, 19 },
1809};
1810// clang-format on
1811
1813 MAP_CELL_STEP(1, 125, 1, 2, 10),
1814 MAP_CELL_STEP(0, 125, 1, 2, 10),
1816};
1817
1819 MAP_CELL_STEP(1, 125, 1, 2, 10),
1820 MAP_CELL_STEP(2, 125, 1, 2, 10),
1822};
1823
Ability numbers, named from the English release.
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_MOVE
Definition ability_ids.h:15
void ObjectGroup_SetChildValue(struct FieldActor *actor, s32 param)
Sets the param byte of every animated part of an actor's sprite.
void Object_RefreshSelectorById(u32 objectId)
Waits, at most 300 frames, for an actor's script to reach its end (command 0x10).
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
@ ACTOR_INNKEEPER
Definition altin.c:82
Animated sprites: their layers, frames and colour modes, and the resource slots they draw from.
The battle animation state, render objects and effect entries, and the palette buffer work.
struct FieldActor * Camera_GetEventObject(void)
The event command "get view centre": returns the camera object.
Definition camera.c:133
Character numbers, with each character's Japanese name.
#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
FacingObject, the view of an object that turns to face a target.
void ObjectDispatch_SetAnimationSpeed(struct DispatchObject *rawObject, s32 value)
Sets the animation speed (timer step) of all of an object's sprites.
Definition objects.c:370
void FieldScene_PrepareActors(struct ScenePlacement *entry)
Field effects, their scripts and the flags that spawn them.
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
void Engine_ObjectSetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
@ ANIM_WALK
Definition field_event.h:44
@ ANIM_STAND
Definition field_event.h:43
@ ANIM_NOD
Definition field_event.h:45
@ ANIM_SHAKE_HEAD
Definition field_event.h:46
void Engine_ActorFaceActor(s32 actor, s32 target, s32 frames)
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)
static void Map_AnimateCells(const u16 *steps, s32 destX, s32 destY)
#define SPEAKER_WINDOW_ABOVE
Definition field_event.h:56
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
void Engine_PsynergyBegin(s32 ability, s32 flags)
struct FieldActor * Engine_ActorLookup(s32 actor)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
static void Actor_SetBuiltinAction(s32 actor, s32 action)
#define GameFlag_IsSet
#define SPEAKER_PORTRAIT_RIGHT
Definition field_event.h:55
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_PsynergyRaiseHands(void)
void Engine_PsynergyLowerHands(void)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
s32 Engine_MathSin(s32 angle)
#define MAP_CELL_STEP(srcX, srcY, width, height, frames)
Definition field_event.h:59
static void Actor_SetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_InnOpen(s32 inn, s32 keeper)
void Engine_EventCloseScreen(void)
void Engine_ObjectDispatchRelease(struct FieldActor *object)
static void Actor_RunActionScriptAndWait(s32 actor, const s32 *script)
Runs a script, waiting at most 300 frames for its final command.
static void Map_CopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
static void ColorBuffer_ApplyTarget(s32 value, s32 mode)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
#define GameFlag_Clear
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
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)
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)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorStop(s32 actor)
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)
#define MAP_CELL_STEPS_END
Definition field_event.h:61
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_MapAnimateCells(const u16 *steps, s32 destX, s32 destY)
void Engine_PsynergyPlayEffect(s32 effect)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static struct FieldActor * Object_Create(s32 type, s32 fixed_x, s32 fixed_y, s32 fixed_z)
static s32 Event_AskYesNo(s32 speaker, s32 flags)
static void Actor_CenterAndWalk(s32 actor, s32 priority, s32 dz)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
@ TASK_PRIORITY_SCENE
Definition field_event.h:40
void Engine_MapRedraw(void)
void Engine_ShopOpen(s32 shop, s32 keeper)
void Engine_ColorBufferInterpolate(s32 frames)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
void Engine_PsynergySetTarget(s32 caster, s32 target)
static void ColorBuffer_ApplySource(s32 value, s32 mode)
@ ACTOR_LINK_KEEP_MOTION
Definition field_obj.h:148
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ TRANSITION_BACKDROP_FADE
Definition field_obj.h:16
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
@ ACTOR_FACES_MOTION
turns toward its velocity, 1/16 turn a frame
Definition field_obj.h:166
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define IF_FLAG_SET(flag)
Definition field_scene.h:48
#define FIND_MESSAGE(message)
#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)
@ ACTOR_WANDER
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
@ 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_OVEN
@ SEARCH_JAR
@ SEARCH_CHEST
@ SEARCH_BARREL
@ SEARCH_GRAVE
#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_SetTargetAndCallback(s32 object, s32 target, const s32 *actions)
static s32 Task_AddCallback(void(*callback)(void), s32 priority)
Calls the main-image scheduler through engine_call.h.
static void FieldVector_AddPolarOffset(s32 radius, s32 heading, struct FieldPosition *probe)
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_IMIL_APPRENTICE_OFFERED_HEALING
Her apprentice told the party she can act as its healer in the sanctum.
Definition flags.h:238
#define FLAG_SCENE_TEMP_03
Definition flags.h:716
#define FLAG_IMIL_HEARD_MIA_WENT_TO_COUPLE
Mia's second apprentice told the party Mia went to the old couple's house.
Definition flags.h:234
#define FLAG_IN_PARTY(character)
Flags 0 to 7: the character with that id (character_ids.h) is in the party (Party_AddActiveOwner).
Definition flags.h:9
#define FLAG_IMIL_MIA_SAID_FAREWELL
to her two apprentices
Definition flags.h:239
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_IMIL_MET_MIA
Mia healed the old man, and the party saw the Mercury Lighthouse lit.
Definition flags.h:236
#define FLAG_SCENE_TEMP_01
Definition flags.h:714
#define FLAG_SATUROS_BEATEN_AT_MERCURY
Saturos is beaten at Mercury Lighthouse: the Hermes fountain at its foot flows again.
Definition flags.h:358
The frame loop's globals: lag counts, the CPU load display and the VBlank flags.
volatile u32 gFrameCount
Frames WaitFrames has finished.
GameState, the game's state: play time, coins, the scene and the leader's position,...
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
void * gMapWork[]
void * gEffectWork
Slot 56: points to a scene-specific structure.
The screen blend's globals and the graphics routines.
static void Imil_ReadOldWomanMind(void)
Mind Read on the old woman: about Mia's clan, her husband's exaggerating, or Mia running all over tow...
Definition imil.c:364
static void Imil_TalkToInnkeeper(void)
Across the counter, the leader facing north, the inn opens; otherwise the innkeeper talks of the two ...
Definition imil.c:555
s32 gImil_FaceTargetScript[]
Definition imil.c:1545
u16 gImil_DoorCellSteps3[]
Definition imil.c:1793
struct SceneEvent gImil_InteriorEvents[]
Definition imil.c:1700
static void Imil_ReadApprenticeMind(void)
Mind Read on Mia's apprentice: she will do her best, or, once Mia has joined, she feels grown up.
Definition imil.c:390
static void Imil_UpdateRisingEffect(union FieldObject *object)
Moves and enlarges an ambient effect, then releases it when its timer expires.
Definition imil.c:1000
u16 * gImil_DoorCellSteps[]
Definition imil.c:1797
static void Imil_ReadCountingChildMind(void)
Mind Read on the counting child: admiration for Mia.
Definition imil.c:381
ImilActor
Imil's two maps share actor numbers; each is named on the map it is proved.
Definition imil.c:50
@ ACTOR_ITEM_MERCHANT
Definition imil.c:62
@ ACTOR_SECOND_APPRENTICE
Definition imil.c:66
@ ACTOR_RESTAURANT_OWNER
Definition imil.c:64
@ ACTOR_COUNTING_CHILD
Definition imil.c:54
@ ACTOR_ARMOR_MERCHANT
Definition imil.c:60
@ ACTOR_SNOWMAN
Definition imil.c:55
@ ACTOR_WEAPON_MERCHANT
Definition imil.c:59
@ ACTOR_OLD_WOMAN
the old couple's house
Definition imil.c:57
@ ACTOR_ITEM_SHOP_CHILD
minds the shop while the mother is sick
Definition imil.c:61
@ ACTOR_OLD_MAN
Definition imil.c:58
@ ACTOR_APPRENTICE
Mia's apprentices, the first in the sanctum.
Definition imil.c:65
@ ACTOR_GREETER
Definition imil.c:53
@ ACTOR_COLD_VILLAGER
shivering and sneezing in the snow
Definition imil.c:52
s16 gImil_KeyHeadings[]
Definition imil.c:1430
static void Imil_TalkToColdVillager(void)
The cold villager sneezes and shivers, waiting for Mia; once she travels with the party (flag 3),...
Definition imil.c:178
s32 gImil_MiaCheckRoomScript[]
Definition imil.c:1516
static void Imil_RunIceSlide(void)
The leader slides along the ice until something stops him.
Definition imil.c:1340
static void Imil_TalkToOldWoman(void)
Once the epidemic is cured, the old woman asks what happened at the lighthouse.
Definition imil.c:354
static void Imil_InitializeRisingEffect(struct FieldActor *work)
Resets a rising effect's motion, sprite priority, and initial scale.
Definition imil.c:981
#define IMIL_OPEN_SHOP
Definition imil.c:81
static void Imil_TalkToCountingChild(void)
The counting child stops, turns to the leader and goes back to counting.
Definition imil.c:217
u16 gImil_DoorCellSteps0[]
Definition imil.c:1785
static void Imil_OldManBobsAndSpeaks(void)
The old man bobs and speaks as the healing reaches him.
Definition imil.c:962
const u32 * Imil_GetExits(void)
Definition imil.c:138
static void Imil_LeaveNorth(void)
Walking into the north path, the leader faces north and leaves the town.
Definition imil.c:1125
u16 gImil_DoorCellSteps4[]
Definition imil.c:1777
static void Imil_ReadColdVillagerMind(void)
Mind Read on the cold villager: Mia should be here by now, or, once she has joined the party,...
Definition imil.c:195
static void Imil_TalkToItemMerchant(void)
The item shop: once the town is cured the mother sells again; before, her child minds the counter whi...
Definition imil.c:518
static UNUSED void Imil_SwayAndSpark(struct FieldActor *actor)
Sways an unused actor and occasionally emits a rising spark.
Definition imil.c:933
struct SceneEvent gImil_TownEvents[]
Definition imil.c:1671
static void Imil_UpdateMapLayerByLeaderPosition(void)
The leader walks on map layer 0 near the middle of town and on layer 1 elsewhere.
Definition imil.c:1058
static void Imil_MeetMiaAtOldCouplesHouse(void)
After hearing where Mia went, the party finds her at the old couple's house.
Definition imil.c:736
static void Imil_AskAboutWeapons(void)
Once the epidemic is cured, the weapon merchant asks whether the party wants weapons.
Definition imil.c:308
static void Imil_TalkToApprentice(void)
Across the counter, the leader facing north, Mia's apprentice offers the sanctum, the first time sayi...
Definition imil.c:579
const struct SceneEvent * Imil_GetEvents(void)
The town's or the interiors' conversations and Psynergy targets.
Definition imil.c:169
ImilTownFlag
The town's own flags, kept while the party is there.
Definition imil.c:70
@ FLAG_IMIL_MAP_LAYER_0
Which map layer the leader walks on, from where he stands.
Definition imil.c:72
@ FLAG_IMIL_SNOWMAN_ON_CHIMNEY
Definition imil.c:74
@ FLAG_IMIL_MAP_LAYER_1
Definition imil.c:73
s16 gImil_DoorCellPoints[][2]
Cell position (x, y) for each exit.
Definition imil.c:1807
struct ScenePlacement gImil_TownPlacements[]
Definition imil.c:1609
u16 gImil_DoorCellSteps2[]
Definition imil.c:1789
static void Imil_OpenDoorAndExit(void)
Walking north into a door, everyone stops, the door opens and the leader walks in; door 6 has its own...
Definition imil.c:403
static void Imil_SpawnAmbientEffects(void)
Effects rise at five places in the town, staggered over each second.
Definition imil.c:1022
s32 gImil_ColdVillagerScript[]
Definition imil.c:1442
static void Imil_TalkToOldMan(void)
The old man moans for help until the old woman hurries to fetch Mia; after Mia's healing he feels muc...
Definition imil.c:252
const struct SceneEntrance * Imil_GetEntrances(void)
Imil is two maps: the town and its interiors.
Definition imil.c:129
u16 gImil_DoorCellSteps5[]
Definition imil.c:1772
struct SceneEntrance gImil_InteriorEntrances[]
Definition imil.c:1573
static void Imil_StartRisingEffect(union FieldObject *object)
Initializes a newly created ambient effect for its one-second rise.
Definition imil.c:1012
struct ScenePlacement gImil_TownPlacementsCured[]
Definition imil.c:1621
const struct SceneRegion * Imil_GetRegions(void)
Definition imil.c:136
s32 gImil_SparkScript[]
Definition imil.c:1509
u16 gImil_CellStepsA[]
Definition imil.c:1812
struct ScenePlacement gImil_InteriorPlacements[]
Definition imil.c:1633
static void Imil_TalkToWeaponMerchant(void)
Across the counter, the leader facing north, the weapon shop opens once the town is cured; before,...
Definition imil.c:447
static UNUSED void Imil_UpdateCountdownArc(struct FieldActor *actor)
Moves an unused effect around its stored origin until its timer expires.
Definition imil.c:907
static void Imil_AskAboutRestaurantMenu(void)
Once the epidemic is cured, the restaurant owner offers the menu.
Definition imil.c:316
static void Imil_GreetVisitor(void)
A villager turns to the leader and asks whether he is new in Imil.
Definition imil.c:207
s32 gImil_FollowMiaOutScript[]
Definition imil.c:1550
s32 gImil_ShiverScript[]
Definition imil.c:1460
static void Imil_MoveSnowmanToChimney(void)
Moved onto the chimney, the snowman stays there and blocks its cell.
Definition imil.c:1100
static s32 Imil_UpdateShiver(struct ScriptInterpreter *interpreter)
A sick person shivers: a quick squash, then a pause, longer for the old man.
Definition imil.c:97
s32 gImil_CaretakerHurryScript[]
Definition imil.c:1465
static void Imil_StartIceSlide(void)
Stepping onto the ice starts a slide.
Definition imil.c:166
static void Imil_MiaCastsPlyOnOldMan(void)
Definition imil.c:967
static void Imil_TalkToSecondApprentice(void)
Mia's second apprentice asks whether the party has visited the old couple, where Mia went; once Mia h...
Definition imil.c:325
u32 gImil_Exits[]
Definition imil.c:1586
static void Imil_ShowFirstArrival(void)
Arriving for the first time, the leader walks into town.
Definition imil.c:1138
static void Imil_TalkToArmorMerchant(void)
Across the counter, the leader facing north, the armor shop opens once the town is cured; before,...
Definition imil.c:482
u16 gImil_DoorCellSteps1[]
Definition imil.c:1781
static void Imil_ReadSecondApprenticeMind(void)
Mind Read on the second apprentice: Mia had a bad feeling, or, once she has joined,...
Definition imil.c:341
s16 gImil_SwayHeadings[]
Definition imil.c:1437
struct SceneEntrance gImil_TownEntrances[]
Definition imil.c:1559
s32 gImil_MiaRunOutScript[]
Definition imil.c:1531
s32 gImil_LeaderStepAsideScript[]
Definition imil.c:1478
s32 gImil_BobScript[]
Definition imil.c:1496
u16 gImil_CellStepsB[]
Definition imil.c:1818
static void Imil_TalkToOldManInBed(void)
After Mia's visit, speaking across the bed reaches the old man.
Definition imil.c:378
static void Imil_TurnSlidingActor(union FieldObject *object)
While sliding, the leader turns toward the held direction.
Definition imil.c:1304
static void Imil_MiaSaysFarewellToApprentices(void)
Once the town is cured, Mia says farewell to her two apprentices in the sanctum before leaving with t...
Definition imil.c:1148
s32 gImil_ArcOrigin[]
The position (x, y, z) the unused arc and sway effects move around.
Definition imil.c:1824
s32 Imil_Initialize(void)
The town gets its rising effects, map layers and snowman, and the first arrival walks in; each interi...
Definition imil.c:611
const struct ScenePlacement * Imil_GetPlacements(void)
Once the epidemic is cured (flag 0x881), the townspeople are well again and the old man is up and abo...
Definition imil.c:142
Item numbers, named from the English release.
@ ITEM_LUCKY_PEPPER
Definition item_ids.h:55
@ ITEM_EMPTY_BOTTLE
Definition item_ids.h:45
@ ITEM_SLEEP_BOMB
Definition item_ids.h:68
@ ITEM_VIAL
Definition item_ids.h:42
@ ITEM_LUCKY_MEDAL
Definition item_ids.h:70
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
The keypad state the VBlank interrupt keeps.
volatile u32 gKeysHeld
Keys down now.
Small statement macros both games use for positions, velocities and bounds.
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
Definition macros.h:12
Maps: their cells, layers, animations and blend scripts, and the map state.
void Vector_AddPolarOffset(s32 radius, s32 angle, void *position)
Moves the point position by radius in direction angle on the ground plane: x by the cosine,...
Definition math.c:23
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_SET(w, v)
Write a work value.
Definition objcmd.h:37
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_FREE
Release.
Definition objcmd.h:43
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_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_SCALE_Y
Definition objcmd.h:63
@ SW_FACING
Definition objcmd.h:57
@ SW_Y
Definition objcmd.h:59
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void BattleEffect_CleanupSceneObjects(void)
Ends a Psynergy effect: frees the effect slots still in use and, unless another effect is being resol...
Definition setup.c:110
Declares nothing: an empty header kept for the files that include it.
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
Palette fades, the battle effect palette buffers and the colour channel curves.
@ PALETTE_TRANSFORM_PLAIN
each colour unchanged
Definition palbuf.h:72
Scene numbers, named after their places.
char SceneId_Imil2
char SceneId_Imil1
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_220
Definition songs.h:215
#define SE_DOOR_OPEN
Definition songs.h:153
#define SE_131
Definition songs.h:124
#define SE_MAP_EXIT
Definition songs.h:116
#define SE_188
Definition songs.h:183
#define SE_JUMP
An actor jumps: ObjectMotion_Launch plays the high jump above 5 pixels a frame.
Definition songs.h:147
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_TaskWait()
void Engine_EventSetMessage()
void Engine_EventShowMessage()
#define NULL
Definition bilibin.h:6
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
u16 priority
2 when created
Definition animspr.h:100
A field object as the object dispatcher's far calls take it.
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
s16 touchedTrigger
the step event a touch or exit event answers
Definition event_work.h:26
s32 transitionFrames
frames
Definition event_work.h:45
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s16 timer
The parameter its action script reads (a follow distance or an angle to face), the player's frames to...
Definition field_obj.h:109
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
u16 radius
Collision radius in pixels: 16, or half the sprite metadata's boxY, when created; the overlap checks ...
Definition field_obj.h:43
u8 steeringFlags
ActorSteeringFlag bits.
Definition field_obj.h:92
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
u8 priorityFlags
ActorPriorityFlag bits, read by the scrolling camera.
Definition field_obj.h:51
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition field_obj.h:40
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
u8 collisionFlags
bits: 7 refuses to move into a solid object | 4 nearer for Psynergy targets | 3 never a talk or Psyne...
Definition field_obj.h:91
u8 terrainId
The map layer (0 to 3) its ground height is read from, which the scrolling camera updates from the ce...
Definition field_obj.h:47
s32 countdown
Frames until a scene's update hook releases the effect: 20 for Altin Peak's spray,...
u16 spin
Added to the sprite's rotation each frame by the update hooks, in 1/65536 turns per frame; Imil's ris...
A position on the field.
s32 z
16.16 fixed-point pixels
s16 entrance
Definition game_state.h:37
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
The map work in heap slot 8 (struct MapScrollWork), seen as its tile animation channels,...
Definition map.h:49
u8 unk17
MapScrollWork's footprints; Bilibin Cave sets it.
Definition map.h:53
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
s32 x
16.16 fixed-point pixels
Definition field_scene.h:91
s32 z
16.16 fixed-point pixels
Definition field_scene.h:93
s32 behavior
A built-in action (enum ActorBehavior, 1 to 7) or an action script, for ObjectMotion_SetActionCallbac...
Definition field_scene.h:90
A scene's exit region: the box that, while its condition holds, takes the party leader out through it...
The prefix that command handlers read from a field object's 0x70-byte slot.
Definition script.h:16
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
s32 GetMapCellCollision(s32 layer, s32 x, s32 y)
Returns the collision code of a layer's cell at (x, y) in 16.16 pixels.
Definition terrain.c:401
s32 Map_GetTerrainHeight(s32 layer, s32 x, s32 y)
Returns the ground height of a layer at (x, y) in 16.16 pixels: the height function of the cell's ter...
Definition terrain.c:343
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
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldActor actor
struct FieldEffect effect
The patch levels: our groups of the measured changes from the Japanese release.