Alchemy
Loading...
Searching...
No Matches

xian.c

Go to the documentation of this file.
1/// @file
2/// Xian: the water carrier who spills her water, Frost on the spill, the kung
3/// fu student and his training tree, Feizhi, and a Mercury Djinni.
4
5#include "game_state.h"
6#include "unit/import.h"
7#include "unit/scene/xian.h"
11#include "unit/field/field.h"
13#include "macros.h"
14
15#define NULL ((void *)0)
16#include "field_obj.h"
17#include "types.h"
18#include "field_event.h"
19#include "field_scene.h"
21#include "iwram_call.h"
22#include "battle.h"
23#include "debug.h"
24#include "field.h"
25#include "game.h"
26#include "graphics.h"
27#include "menu.h"
28#include "minigame.h"
29#include "sound.h"
30#include "system.h"
31#include "call.h"
32#include "field_service.h"
33#include "text/msg_ids.h"
34#include "ability_ids.h"
35#include "item_ids.h"
36#include "objcmd.h"
37#include "flags.h"
38#include "songs.h"
39
41#include "common/effect_spawn.h"
42
43// Xian's temporary flags:
44// FLAG_SCENE_TEMP_00 the water carrier has spilled her water
45// FLAG_SCENE_TEMP_01 the spilled water is frozen
46// FLAG_SCENE_TEMP_02 the kung fu student has shown his strike on the tree
47// FLAG_SCENE_TEMP_03 Force has made the tree jump once
48
49/// The actors, numbered from the placements (the first placed is actor 8).
50enum {
51 /// Strikes the tree before him with a shout. "Hoo-whaaa... Hachaaa!"
53 /// Feizhi, as at Alpine Crossing: looking for someone to take her west.
55 /// Carries water along the street. "You made me spill my water!"
57 /// The tree the student strikes; it jumps when hit.
59 /// The spilled water, which Frost freezes.
61 /// Force's mark on the training tree.
64 /// The first of three actors kept below the others.
66};
67
68enum { ANIM_PUDDLE_FROZEN = 5 };
69
70/// The trigger the water carrier raises when the leader has stood in her way
71/// for two seconds.
73
74/// Talking to the Djinni: it joins the party (Mercury Djinni 2).
75static void Xian_RecruitVillageDjinni(void) {
77}
78
79/// Draws the frozen puddle under the leader while the leader stands on top of
80/// it.
83 if (leader->y.part.pixel > 31) {
85 } else {
87 }
88}
89
90/// Rotates the training tree during the student's strike and Force animation.
91static void Xian_RotateTrainingTree(void) {
93 struct AnimationObject *sprite = tree->sprite;
94 sprite->rotation += 0x1400;
95}
96
97/// Emits particles beside the student every fourth frame.
98static void Xian_SpawnTrainingParticles(void) {
99 // The byte view keeps the Z load ahead of the options-script store.
100 u8 *studentActor = (u8 *)Object_GetById(ACTOR_KUNG_FU_STUDENT);
101
102 if ((gFrameCount & 3) == 0) {
103 struct EffectOptions config;
104 config.priority = 1;
105 config.palette = 9;
106 config.type = 169;
108 Effect_Spawn(*(s32 *)(studentActor + offsetof(struct FieldActor, x)),
109 *(s32 *)(studentActor + offsetof(struct FieldActor, y)),
110 *(s32 *)(studentActor + offsetof(struct FieldActor, z)) -
111 PIXELS(1),
112 0, -PIXELS(1), -PIXELS(1),
115 &config);
116 }
117}
118
120
121/// Tracks a nearby target only within the actor's current facing sector.
123 struct FieldActor *target,
124 s32 distanceLimit, s32 forceTracking) {
125 s32 isTracking = 0;
126
127 // This route uses paused/timer as its tracking latch and mode.
128 if (actor->paused == 1 && actor->timer == 0) {
129 Object_SetMode(actor, 1);
130 return 1;
131 }
132
133 if (FixedPoint_Distance((const u8 *)target + offsetof(struct FieldActor, x),
134 (const u8 *)actor + offsetof(struct FieldActor, x)) <
135 distanceLimit ||
136 forceTracking != 0) {
137 u16 angle = ArcTan2(target->z.fixed - actor->z.fixed,
138 target->x.fixed - actor->x.fixed);
139 s32 previousHeading = (angle - 0x1000) & 0xf000;
140 s32 nextHeading = (angle + 0x1000) & 0xf000;
141 s32 targetHeading = angle & 0xf000;
142 s32 currentHeading = actor->facing & 0xf000;
143
144 if (targetHeading == currentHeading || nextHeading == currentHeading ||
145 previousHeading == currentHeading || forceTracking != 0) {
146 actor->paused = 1;
147 Object_SetMode(actor, 1);
148 isTracking = 1;
149 actor->timer = isTracking;
150 } else {
151 actor->paused = 0;
152 Object_SetMode(actor, 2);
153 actor->timer = 0;
154 }
155 } else {
156 actor->paused = 0;
157 Object_SetMode(actor, 2);
158 actor->timer = 0;
159 }
160
161 return isTracking;
162}
163
164// Ask the carrier to move after the leader blocks her route for two seconds.
165// UB: calling this s32 function through a void update hook is incompatible.
166// Plain void changes 154 to 150 bytes in tbs-en.
167#ifdef UBFIX
168static void Xian_WatchWaterCarrierPath(union FieldObject *fieldObject) {
169#else
170static s32 Xian_WatchWaterCarrierPath(union FieldObject *fieldObject) {
171#endif
172 struct FieldActor *self = (struct FieldActor *)fieldObject;
173 struct FieldActor *leader;
174 s32 near = 0;
175
176 if (self->targetX == ACTOR_NO_TARGET && self->targetZ == ACTOR_NO_TARGET)
177#ifdef UBFIX
178 return;
179#else
180 return 0;
181#endif
183 if ((u32)((leader->x.fixed >> 20) - 17) <= 1 && leader->z.fixed >> 20 == 14 &&
184 self->x.fixed >> 20 <= 19 && self->velocityX <= 0) {
185 if (leader->x.fixed <= self->x.fixed) {
186 self->riseCounter++;
187 near = 1;
188 }
189 } else {
190 self->riseCounter = 0;
191 }
192 if (near && self->riseCounter > XIAN_CARRIER_BLOCKED_FRAMES - 1) {
194 self->riseCounter = 0;
195 }
196 Xian_UpdateCarrierTracking(self, leader, 18, near);
197#ifdef UBFIX
198 return;
199#else
200 return 0;
201#endif
202}
203
204// Keep the native callback representation beside its modern signature choice.
205#ifdef UBFIX
206#define XIAN_WATER_CARRIER_UPDATE Xian_WatchWaterCarrierPath
207#else
208#define XIAN_WATER_CARRIER_UPDATE ((void *)Xian_WatchWaterCarrierPath)
209#endif
210
211const struct SceneEntrance *Xian_GetEntrances(void) { return gXian_Entrances; }
212
213const struct SceneRegion *Xian_GetRegions(void) { return NULL; }
214
215const u32 *Xian_GetExits(void) { return gXian_Exits; }
216
217/// Once Xian has heard Hsu is trapped, actor 15 turns to face the party.
221 return gXian_Placements;
222}
223
224/// Asks about the young warriors' way here.
225/// "Young warriors, very gallant! You came through Mogall Forest?"
226static void Xian_AskAboutYoungWarriors(void) {
228 Engine_EventSetMessage(MsgXianYoungWarriorsVeryGallantCame);
231}
232
233/// Talking to the water carrier. While she carries her water east of x = 320
234/// the first time, she spills it: a puddle spreads at her feet, she cries "You
235/// made me spill my water!" and walks back west to fetch more, the leader
236/// stepping aside if he is in her way. Otherwise she only answers: "Do not
237/// speak to me. I might spill my water.", or once it is spilled, "Now I must
238/// get water again."
239static void Xian_TalkToWaterCarrier(void) {
240 struct FieldActor *puddle;
241 struct FieldActor *carrier;
242 struct FieldActor *leader;
243 s32 leaderMustStepAside;
244 s32 savedFacing;
245 s32 carrierX;
246 s32 carrierCellZ;
247 s32 carrierColumnX;
248 s32 scaleY;
249 s32 scaleX;
250
253 leaderMustStepAside = 0;
255 carrier->update = NULL;
257 (Object_GetById(ACTOR_WATER_CARRIER)->x.fixed >> 20) <= 19) {
259 savedFacing = carrier->facing;
262 Engine_EventSetMessage(MsgXianNowMustGetWaterAgain);
268 carrier->facing = savedFacing;
269 } else {
272 }
276 return;
277 }
278 // Make room for the carrier before spilling the water.
279 if ((Object_GetById(ACTOR_PARTY_LEADER)->z.fixed >> 19) > 27 &&
280 (Object_GetById(ACTOR_PARTY_LEADER)->z.fixed >> 19) <= 29 &&
281 (Object_GetById(ACTOR_PARTY_LEADER)->x.fixed >> 20) != 26) {
282 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0x8000, 0x4000);
287 if (leader->x.fixed < carrier->x.fixed) {
290 Actor_WalkTo(ACTOR_PARTY_LEADER, ((carrier->x.fixed >> 20) << 4) - 8,
291 232);
292 leaderMustStepAside = 1;
293 } else {
296 Actor_WalkTo(ACTOR_PARTY_LEADER, ((carrier->x.fixed >> 20) << 4) + 24,
297 232);
298 }
300 }
302 carrier->targetX = ACTOR_NO_TARGET;
304 carrier->targetY = ACTOR_NO_TARGET;
306 carrier->targetZ = ACTOR_NO_TARGET;
312 // Copy the wet terrain cell and grow the puddle into view.
313 puddle->scaleX = 0x4ccc;
314 puddle->scaleY = 0x4ccc;
316 carrierX = carrier->x.fixed;
318 carrierCellZ = carrier->z.fixed >> 20;
319 Actor_SetPosition(ACTOR_PUDDLE, ((carrierX >> 20) << 20) + PIXELS(8),
320 (carrierCellZ << 20) + PIXELS(8));
322 carrierColumnX = carrier->x.fixed;
324 Map_CopyCellAttributes(16, 16, 1, 1, carrierColumnX >> 20,
325 carrier->z.fixed >> 20);
328 do {
330 scaleY = puddle->scaleY;
331 scaleX = puddle->scaleX;
332 puddle->scaleY = scaleY + 0x1999;
333 scaleX += 0x1999;
334 puddle->scaleX = scaleX;
335 } while (scaleX <= 0xffff);
342 Engine_EventSetMessage(MsgXianDoingMadeMeSpillMy);
345 if ((Object_GetById(ACTOR_PARTY_LEADER)->x.fixed >> 20) == 26 &&
346 (Object_GetById(ACTOR_PARTY_LEADER)->z.fixed >> 20) > 13) {
347 leaderMustStepAside = 1;
348 }
349 // Clear the carrier's route back to the water supply.
350 if (leaderMustStepAside != 0) {
351 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0xcccc, 0x6666);
358 }
359 Actor_SetSpeed(ACTOR_WATER_CARRIER, 0xcccc, 0x6666);
361 if ((carrier->z.fixed >> 20) != 14) {
363 Actor_WalkToAndWait(ACTOR_WATER_CARRIER, carrier->x.part.pixel, 232);
364 }
369}
370
371/// Frost on the spilled water, before it freezes: the puddle is drawn in
372/// front while the leader stands north of it.
373static void Xian_UpdatePuddlePriority(void) {
375 if ((leader->z.fixed >> 20) <= 13)
377}
378
379/// Frost freezes the spilled water: the puddle turns to ice the leader can
380/// stand on, and there is nothing left to jump over.
381static void Xian_FreezeSpilledWater(void) {
382 struct FieldActor *puddle;
383 s32 stationaryMotionFlags;
384 s32 puddleX;
385
388 stationaryMotionFlags = 0;
389 Object_GetById(ACTOR_PUDDLE)->motionFlags = stationaryMotionFlags;
391 puddleX = puddle->x.fixed;
393 Map_CopyCellAttributes(3, 17, 1, 1, (puddleX >> 20), (puddle->z.fixed >> 20));
398}
399
400/// The kung fu student. The first time: "Hoo-whaaa... Hachaaa!", the leader
401/// steps back, and the student leaps at the tree, which jumps under his strike;
402/// "Heh heh heh..." Afterwards: "My kung fu is strong."
403static void Xian_TalkToKungFuStudent(void) {
404 s32 demonstrationSeen;
405 struct FieldActor *leader;
406 SchedulerCallback particleCallback;
407 s32 reboundVelocity;
408 s32 stepBackOffset[3];
409 struct EffectOptions effectParams;
410
412 demonstrationSeen = Engine_GameFlagIsSet(FLAG_SCENE_TEMP_02);
413 if (demonstrationSeen != 0) {
416 Engine_EventSetMessage(MsgXianKungFuStrong);
420 } else {
421 // Step back, then watch the student jump and strike the tree.
422 Engine_EventSetMessage(MsgXianHooWhaaaHachaaa);
426 SET_VECTOR(stepBackOffset, demonstrationSeen, demonstrationSeen,
427 demonstrationSeen);
430 (struct FieldPosition *)stepBackOffset);
433 stepBackOffset[0] / 0x10000,
434 stepBackOffset[2] / 0x10000);
439 effectParams.priority = 1;
440 Effect_Spawn(PIXELS(192), 0, PIXELS(312), 0x1999, 0x3333, 0, 0x20001, 0);
441 Effect_Spawn(PIXELS(192), 0, PIXELS(312), 0x3333, 0x1999, 0, 0x20001, 0);
443 particleCallback = Xian_SpawnTrainingParticles;
444 Task_AddCallback(particleCallback, TASK_PRIORITY_SCENE);
448 Actor_SetSpeed(ACTOR_KUNG_FU_STUDENT, 0x30000, 0x18000);
454 effectParams.type = 0x11b;
455 effectParams.script = gXian_TreeImpactScript;
456 effectParams.rotation = 0x4000;
457 Effect_Spawn(PIXELS(168), 0, PIXELS(332), 0, 0, 0,
460 &effectParams);
463 // Finish the impact effects and leave the student in the final pose.
464 Engine_TaskRemoveCallback((void (*)(void))particleCallback);
465 Effect_Spawn(PIXELS(144), 0, PIXELS(312), 0, 0, 0, 0x20001, 0);
466 Effect_Spawn(PIXELS(144), 0, PIXELS(312), -0x3333, 0x1999, 0, 0x20001, 0);
467 reboundVelocity = -0x8000;
468 Effect_Spawn(PIXELS(144), 0, PIXELS(312), reboundVelocity, 0, 0, 0x20001,
469 0);
472 Effect_Spawn(PIXELS(168), PIXELS(8), PIXELS(312), 0, 0, 0, 0x20001, 0);
473 Effect_Spawn(PIXELS(168), PIXELS(8), PIXELS(312), 0x3333, 0, 0, 0x20001, 0);
474 Effect_Spawn(PIXELS(168), PIXELS(8), PIXELS(312), -0x3333, 0, 0, 0x20001,
475 0);
477 Object_GetById(ACTOR_TRAINING_TREE)->sprite->rotation = reboundVelocity;
488 }
489}
490
491/// Talking to Feizhi.
492/// "You are the warriors from the school... Are you strong warriors?"
493static void Xian_TalkToFeizhi(void) {
495 Engine_EventSetMessage(MsgXianWarriorsFromSchoolStrongWarriors);
498}
499
500/// Walking into the spilled water before it is frozen: the leader jumps two
501/// cells over it, where nothing stands in the way.
502static void Xian_JumpOverSpilledWater(void) {
503 s32 savedMotionFlags;
504 struct FieldActor *leader;
505 struct FieldPosition landingPosition;
506 struct FieldPosition *landing;
507
509 savedMotionFlags = leader->motionFlags;
511 landing = &landingPosition;
512 landing->x = (leader->x.fixed & -0x100000) + PIXELS(8);
513 landing->y = leader->y.fixed;
514 landing->z = (leader->z.fixed & -0x100000) + PIXELS(8);
515 FieldVector_AddPolarOffset(PIXELS(32), (leader->facing + 0x2000) & 0xc000,
516 landing);
517 if (FieldObject_CheckMovementCollision(leader, landing) == 0) {
519 Object_SetMode(leader, 6);
522 Object_SetMode(leader, 7);
523 leader->speed = PIXELS(3);
524 leader->acceleration = PIXELS(2);
525 leader->velocityY = PIXELS(4);
526 leader->motionFlags &= 126;
529 ACTOR_PARTY_LEADER, landing->x >> 16, landing->z >> 16);
530 Object_SetMode(leader, 6);
532 leader->motionFlags = savedMotionFlags;
534 }
535 }
536}
537
538/// Walks the leader through a doorway and leaves by its exit.
539static void Xian_WalkThroughExit(s32 exitId) {
541 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0x8000, 0x4000);
542 if (exitId == 6) {
545 } else {
547 }
550}
551
552/// Walking into one of Xian's doors: it opens and the party goes in.
553static void Xian_OpenDoorAndLeave(void) {
554 struct EventWork *event = gEventWork;
555
557
558 switch (event->touchedTrigger) {
559 case 1:
562 break;
563 case 2:
566 break;
567 case 3:
570 break;
571 case 4:
574 break;
575 case 5:
578 break;
579 case 6:
582 break;
583 case 7:
586 break;
587 default:
588 break;
589 }
590
591 Xian_WalkThroughExit(event->touchedTrigger);
593}
594
595/// Force on the training tree: it jumps, and the student cries out.
596/// "Wha-Wha-What happened? The tree jumped on its own!", the next time
597/// "...It jumped again... I am too tired...".
599 SchedulerCallback rotationCallback;
600
603 rotationCallback = Xian_RotateTrainingTree;
607 Effect_Spawn(PIXELS(168), PIXELS(8), PIXELS(312), 0, 0, 0, 0x20001, 0);
608 Effect_Spawn(PIXELS(168), PIXELS(8), PIXELS(312), 0x3333, 0, 0, 0x20001, 0);
609 Effect_Spawn(PIXELS(168), PIXELS(8), PIXELS(312), -0x3333, 0, 0, 0x20001, 0);
610 Engine_TaskRemoveCallback(rotationCallback);
611 Object_GetById(ACTOR_TRAINING_TREE)->sprite->rotation = 0x8000;
617 Engine_EventSetMessage(MsgXianWhaWhaHappened);
620 }
625}
626
627/// The leader has stood in the water carrier's way for two seconds: both walk
628/// to the start of her route, the leader turns west, and she sets off again.
630 struct FieldActor *carrier;
631
635 carrier->update = 0;
637 carrier->targetX = ACTOR_NO_TARGET;
639 carrier->targetZ = ACTOR_NO_TARGET;
641 carrier->velocityX = 0;
643 carrier->velocityZ = 0;
645 carrier->speed = 0;
647 carrier->acceleration = 0;
651 Actor_SetSpeed(ACTOR_WATER_CARRIER, 0x18000, 0xc000);
652 Actor_SetSpeed(ACTOR_PARTY_LEADER, 0x18000, 0xc000);
662}
663
664const struct SceneEvent *Xian_GetEvents(void) { return gXian_Events; }
665
666/// Queues sound 169 and sets up the village as the story and this visit left
667/// it.
669 struct FieldActor *actor;
670 u32 decorationIndex;
671
674 if (gGameState.entrance > 9) {
676 }
683 }
684 }
685 // Gone once she has found the road blocked (Alpine Crossing's
686 // FLAG_FEIZHI_SAW_ROCKSLIDE).
689 }
690 // Keep the three decorative actors below the moving characters.
691 for (decorationIndex = 0; decorationIndex <= 2; decorationIndex++) {
692 struct FieldActor *actor;
693 actor = Object_GetById(decorationIndex + ACTOR_FIRST_DECORATION);
694 actor->sprite->image.priority = 1;
695 actor->motionFlags = 0;
696 actor->collisionFlags = 8;
698 ObjectGroup_SetChildValue(actor, 15);
699 actor->priorityFlags = (actor->priorityFlags & 254) | 2;
700 }
704 }
705 // Restore the frozen puddle and callbacks when re-entering the village.
708 {
710
711 Engine_MapCopyCellAttributes(3, 17, 1, 1, puddleX >> 20,
713 }
716 }
720 actor->motionFlags = 0;
721 actor->y.fixed = PIXELS(16);
722 actor->targetY = PIXELS(16);
723 actor->scaleX = 0x8ccc;
724 actor->scaleY = 0x6666;
725 actor->sprite->rotation = 0x8000;
730 return 0;
731}
732
734 SC_WAIT(1), SC_LOOP(22, SC_TOP), SC_WAIT(1),
735 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
736};
737
739 SC_WAIT(1), SC_LOOP(44, SC_TOP), SC_WAIT(1),
740 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
741};
742
744 SC_WAIT(1), SC_LOOP(126, SC_TOP), SC_WAIT(1),
745 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
746};
747
748const s32 *gEffectScripts[] = {
752};
753
754/// The water carrier's round: from (280, 232) east to (424, 232), up to
755/// (424, 216) and back, pausing at each end.
757 SC_SET(SW_SPEED, 0x6666),
758 SC_SET(SW_ACCEL, 0x1999),
759 SC_WAIT(60),
760 SC_LABEL(1),
761 SC_ARG(3),
762 SC_WAIT(60),
763 SC_ARG(3),
764 SC_WAIT(180),
765 SC_ARG(2),
766 SC_MOVE(PIXELS(424), 0, PIXELS(232)),
767 SC_SYNC,
768 SC_MOVE(PIXELS(424), 0, PIXELS(216)),
769 SC_SYNC,
770 SC_WAIT(10),
771 SC_SET(SW_FACING, 0x1000),
772 SC_WAIT(10),
773 SC_ARG(3),
774 SC_WAIT(60),
775 SC_ARG(3),
776 SC_WAIT(120),
777 SC_ARG(2),
778 SC_MOVE(PIXELS(424), 0, PIXELS(232)),
779 SC_SYNC,
780 SC_MOVE(PIXELS(280), 0, PIXELS(232)),
781 SC_SYNC,
783 SC_END,
784};
785
786/// The struck tree jumps 32 pixels and drops back.
788 SC_SET(SW_SNAP, 0),
789 SC_SET(SW_SPEED, 0x30000),
790 SC_SET(SW_ACCEL, 0x18000),
791 SC_MOVE(PIXELS(168), PIXELS(48), PIXELS(312)),
792 SC_SYNC,
793 SC_SET(SW_SPEED, 0x30000),
794 SC_SET(SW_ACCEL, 0x1999),
795 SC_SET(SW_SNAP, 1),
796 SC_MOVE(PIXELS(168), PIXELS(16), PIXELS(312)),
797 SC_SYNC,
798 SC_END,
799};
800
801/// The effect at the tree's foot when the student strikes it: 18 frames.
803 SC_WAIT(18), SC_WAIT(1), SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
804};
805
806/// Each particle beside the leaping student, facing west: 16 frames.
809 SC_WAIT(16),
810 SC_WAIT(1),
811 SC_POS(0, 0, 0),
812 SC_WAIT(1),
813 SC_FREE,
814};
815
816/// The doors' opening frames, copied from map cells.
818 MAP_CELL_STEP(64, 48, 1, 2, 4),
819 MAP_CELL_STEP(63, 48, 1, 2, 4),
821};
822
824 MAP_CELL_STEP(69, 50, 2, 2, 4),
825 MAP_CELL_STEP(65, 50, 2, 2, 4),
827};
828
830 MAP_CELL_STEP(66, 46, 3, 2, 4),
831 MAP_CELL_STEP(63, 46, 3, 2, 4),
833};
834
836 MAP_CELL_STEP(67, 50, 4, 2, 4),
837 MAP_CELL_STEP(63, 50, 4, 2, 4),
839};
840
842 MAP_CELL_STEP(66, 44, 3, 2, 4),
843 MAP_CELL_STEP(63, 44, 3, 2, 4),
845};
846
848 {0, CONDITION_ALWAYS, 172, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
849 {1, CONDITION_ALWAYS, 376, 0, 504, FACING_NORTH, 0, -1, -1, -1, -1, 0},
850 {5, CONDITION_ALWAYS, 344, 0, 328, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
851 {6, CONDITION_ALWAYS, 376, 0, 216, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
852 {7, CONDITION_ALWAYS, 424, 0, 216, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
853 {8, CONDITION_ALWAYS, 408, 0, 424, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
854 {9, CONDITION_ALWAYS, 216, 0, 184, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
855 {10, CONDITION_ALWAYS, 392, 0, 184, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
856 {11, CONDITION_ALWAYS, 176, 0, 216, FACING_SOUTH, 0, -1, -1, -1, -1, 0},
858};
859
861 SCENE_EXITS(72), SCENE_EXIT(1, 73, 1), SCENE_EXIT(2, 73, 2),
862 SCENE_EXIT(3, 73, 3), SCENE_EXIT(4, 73, 4), SCENE_EXIT(5, 73, 6),
863 SCENE_EXIT(6, 9, 32), SCENE_EXIT(7, 61, 2), SCENE_EXIT(8, 2, 14),
865};
866
867// clang-format off
870 PIXELS(328), 0, PIXELS(448), FACING_EAST, TALK_FACE_PARTY, 0 },
872 PIXELS(152), 0, PIXELS(184), FACING_SOUTHEAST, TALK_FACE_PARTY, 0 },
874 PIXELS(420), 0, PIXELS(304), FACING_SOUTH, TALK_FACE_PARTY, 0 },
878 PIXELS(312), 0, PIXELS(200), FACING_EAST, TALK_FACE_PARTY, 0 },
882 PIXELS(192), 0, PIXELS(312), FACING_WEST, TALK_KEEP_FACING, 0 },
884 PIXELS(428), 0, PIXELS(432), FACING_WEST, TALK_FACE_PARTY, 0 },
886 PIXELS(200), 0, PIXELS(440), FACING_NORTH, TALK_FACE_PARTY, 0 },
888 PIXELS(368), 0, PIXELS(496), FACING_SOUTHEAST + FACING_STEP, 3, 0 },
890 PIXELS(280), 0, PIXELS(232), FACING_WEST, TALK_KEEP_FACING, 0 },
891 { 0xcd, CONDITION_ALWAYS, 7,
892 PIXELS(168), 0, PIXELS(312), FACING_WEST, TALK_FACE_PARTY, 0 },
893 { 0xe3, CONDITION_ALWAYS, 7,
894 0, 0, 0, FACING_WEST, TALK_FACE_PARTY, 0 },
896 PIXELS(168), 0, PIXELS(312), FACING_WEST, TALK_FACE_PARTY, 0 },
897 { 0x5b, FLAG_DJINNI_0 + ELEMENT_MERCURY * 20 + 2, ACTOR_STAND,
898 PIXELS(448), 0, PIXELS(328), FACING_WEST, TALK_FACE_PARTY, 0 },
900 PIXELS(426), 0, PIXELS(428), FACING_WEST, TALK_FACE_PARTY, 0 },
905 { SCENE_TABLE_END },
906};
907
916 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
921 { EVENT_TALK, 8, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianThisIsXianTravelersAreWelcome) },
923 { EVENT_TALK, 10, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianXianIsTheVillageOfKinu) },
924 { EVENT_TALK, 11, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianMartialArtsAreVeryPopularIn) },
925 { EVENT_TALK, 12, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianYouWarriorsShouldVisitMasterFehs) },
926 { EVENT_TALK, 13, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianMyClothesAreNotSilkSilk) },
928 { EVENT_TALK, 15, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianDisastersFromTheSkyManyMany) },
929 { EVENT_TALK, 16, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianThisIsTheMulberryOrchardWhen) },
932 { EVENT_TALK, 8, CONDITION_ALWAYS, MSGNO(MsgXianXianIsAPeacefulVillageBut) },
933 { EVENT_TALK, 9, CONDITION_ALWAYS, MSGNO(MsgXianThereWasARockslideOnSilk) },
934 { EVENT_TALK, 10, CONDITION_ALWAYS, MSGNO(MsgXianIWentToHelpMoveBoulders) },
935 { EVENT_TALK, 11, CONDITION_ALWAYS, MSGNO(MsgXianThePeopleWhoClearedTheRockslide) },
936 { EVENT_TALK, 12, CONDITION_ALWAYS, MSGNO(MsgXianHsuIsVeryGoodAtKung) },
937 { EVENT_TALK, 13, CONDITION_ALWAYS, MSGNO(MsgXianThePeopleOfXianLoveTheir) },
938 { EVENT_TALK, ACTOR_KUNG_FU_STUDENT, CONDITION_ALWAYS, MSGNO(MsgXianAltinWasFloodedWithWaterBut) },
939 { EVENT_TALK, 15, CONDITION_ALWAYS, MSGNO(MsgXianWeClearedTheRocksFromSilk) },
940 { EVENT_TALK, 16, CONDITION_ALWAYS, MSGNO(MsgXianManyStrangeThingsHappenedAllAt) },
944 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianTheseChildrenMustHaveComeTo) },
945 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianYouYoungWarriorsLookStrongBut) },
946 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianIHopeManyPeopleComeTo) },
947 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianFightingWithKicksAndPunchesIs) },
948 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianMasterFehsSchoolIsTrainingIt) },
949 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianSilkIsShinyAndSmoothIt) },
950 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_KUNG_FU_STUDENT, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianBreakingTreesWithMyHandHurts) },
951 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianMasterFehSaidYahAndThen) },
952 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianTheOrchardGivesTheVillageLife) },
953 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_FEIZHI, FLAG_XIAN_HEARD_HSU_TRAPPED, MSGNO(MsgXianGoingWestAloneIsVeryDangerous) },
954 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_WATER_CARRIER, CONDITION_ALWAYS, MSGNO(MsgXianIMustCarryWaterEveryDay) },
955 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 8, CONDITION_ALWAYS, MSGNO(MsgXianHsuWasCaughtUnderABoulder) },
956 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 9, CONDITION_ALWAYS, MSGNO(MsgXianTheRocksThereWereVeryHard) },
957 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 10, CONDITION_ALWAYS, MSGNO(MsgXianSomePeopleDidNotCarryRocks) },
958 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 11, CONDITION_ALWAYS, MSGNO(MsgXianSandIsTheColorOfThe) },
959 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 12, CONDITION_ALWAYS, MSGNO(MsgXianHsuIsStrongHeadedHeWould) },
960 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 13, CONDITION_ALWAYS, MSGNO(MsgXianEveryoneStaysInXianTheyDo) },
961 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_KUNG_FU_STUDENT, CONDITION_ALWAYS, MSGNO(MsgXianThisWarriorSavedAltinVillageNo) },
962 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 15, CONDITION_ALWAYS, MSGNO(MsgXianItIsBadForXianIf) },
963 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), 16, CONDITION_ALWAYS, MSGNO(MsgXianIWasHappyToSeeGems) },
964 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ACTOR_FEIZHI, CONDITION_ALWAYS, MSGNO(MsgXianWhereAreTheMerchantsNoOne) },
969};
970// clang-format on
Ability numbers, named from the English release.
@ ABILITY_FORCE
Definition ability_ids.h:17
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_FROST
Definition ability_ids.h:11
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_DJINNI
Definition altin_peak.c:118
s32 gEffectScript0[]
const s32 * gEffectScripts[]
s32 gEffectScript1[]
s32 gEffectScript2[]
@ ELEMENT_MERCURY
Definition battle_unit.h:37
Calls through a function pointer, by argument count.
void(*) SchedulerCallback(void)
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
The engine calls the debug menus import, and their palette swatch tiles.
void Djinn_JoinParty(s32 slot, s32 element, s32 djinn)
A Djinni joins the party: djinn (0 to 19) of element goes to the member with the fewest Djinn,...
Definition djinni.c:124
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
@ EFFECT_USE_PALETTE
options.palette, as its group child value
@ EFFECT_USE_ROTATION
options.rotation, as the sprite's
@ EFFECT_USE_TYPE
options.type, else object type 222
@ EFFECT_USE_PRIORITY
options.priority, as the sprite's priority
@ EFFECT_USE_SCRIPT
options.script, run in mode 1
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
@ ANIM_WALK
Definition field_event.h:44
@ ANIM_STAND
Definition field_event.h:43
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_MapCopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
static void Actor_SetBuiltinAction(s32 actor, s32 action)
void Engine_EventShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
#define GameFlag_IsSet
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
s32 Engine_TaskRemoveCallback(void(*callback)(void))
#define EMOTE_IN_FRONT
Definition field_event.h:49
#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_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
#define GameFlag_Set
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
s32 Engine_EventAskYesNo(s32 speaker, s32 flags)
void Engine_GameFlagSet(s32 flag)
void Engine_GameFlagClear(s32 flag)
static void Actor_SetActionScript(s32 actor, const s32 *script)
The engine encodes either a built-in action or an action-script address.
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
static void Event_ShowMessage(s32 speaker, s32 flags)
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_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static void Actor_CenterAndWalk(s32 actor, s32 priority, s32 dz)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ObjectMotionSetPositionAndCommit(s32 actor, s32 x, s32 z)
@ TASK_PRIORITY_SCENE
Definition field_event.h:40
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_EventWait(s32 frames)
static struct FieldActor * Actor_Get(s32 actor)
Field objects and actors, and the scene transition styles.
@ TRANSITION_BACKDROP_FADE
Definition field_obj.h:16
@ ACTOR_PRIORITY_UNDERFOOT
The depth sort treats it as 320 pixels higher on the screen.
Definition field_obj.h:155
#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 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
@ EVENT_RAISED
@ 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 SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
@ TALK_FACE_PARTY_AND_BACK
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
#define EVENT_TOUCH_WALKING
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_JAR
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static s32 Task_AddCallback(void(*callback)(void), s32 priority)
Calls the main-image scheduler through engine_call.h.
static void FieldVector_AddPolarOffset(s32 radius, s32 heading, struct FieldPosition *probe)
Game flags, named where their meaning is shown.
#define FLAG_SHOW_LOCATION_NAME
Definition flags.h:94
#define FLAG_DJINNI_0
the flag of Djinni 0, set once it is caught
Definition flags.h:15
#define FLAG_SCENE_TEMP_03
Definition flags.h:716
#define FLAG_XIAN_HEARD_HSU_TRAPPED
Definition flags.h:112
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_SCENE_TEMP_02
Definition flags.h:715
#define FLAG_XIAN_LUCKY_MEDAL_JAR
Xian: set once the jar's Lucky Medal is taken.
Definition flags.h:586
#define FLAG_SCENE_TEMP_01
Definition flags.h:714
#define FLAG_FEIZHI_WENT_TO_HSU
Definition flags.h:113
#define FLAG_FEIZHI_SAW_ROCKSLIDE
Feizhi has found the road blocked and run ahead to look for Hsu.
Definition flags.h:133
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 screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
Item numbers, named from the English release.
@ ITEM_LUCKY_MEDAL
Definition item_ids.h:70
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
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
s32 ArcTan2(s32 x, s32 y)
Returns the angle of the vector (x, y), in 1/65536 turns, measured from the y axis: 0 along +y,...
Definition math.c:36
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_LABEL(n)
Branch destination.
Definition objcmd.h:11
#define SC_SET(w, v)
Write a work value.
Definition objcmd.h:37
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_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_TO(n)
Definition objcmd.h:12
#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_SNAP
Definition objcmd.h:78
@ SW_SPEED
Definition objcmd.h:67
@ SW_FACING
Definition objcmd.h:57
#define ACTOR_ACTION_IDLE
void BattleFx_PlayQueuedSound(void)
Plays the sound BattleFx_SetQueuedSoundAndPlay remembered, if any.
Definition requests.c:102
void BattleFx_SetQueuedSoundAndPlay(s32 soundId)
Plays SE_298, then soundId (SE_289 for -1), and remembers soundId for BattleFx_PlayQueuedSound in the...
Definition requests.c:90
Declares nothing of its own: it only includes types.h.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_DOOR_OPEN
Definition songs.h:153
#define SE_169
Definition songs.h:164
#define SE_132
Definition songs.h:125
#define SE_188
Definition songs.h:183
#define SE_228
Definition songs.h:223
#define SE_HEAVY_IMPACT
Definition songs.h:127
#define SE_124
Definition songs.h:117
#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
#define offsetof(type, member)
Definition stddef.h:19
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
u16 rotation
1/65536 turns
Definition animspr.h:118
The options of a spawned field effect, each used when its EFFECT_USE_ flag (or EFFECT_SCALE_TO_TARGET...
s16 type
the object type to create; 222 without the flag
s32 palette
passed to ObjectGroup_SetChildValue
s32 priority
the sprite's priority
u16 rotation
1/65536 turns
const s32 * script
the object script, run in mode 1
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
Definition event_work.h:20
s16 raisedTrigger
a raised event for Scene_RunRaisedEvent
Definition event_work.h:35
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
s32 transitionFrames
frames
Definition event_work.h:45
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 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
u8 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
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
u8 paused
nonzero skips its script and motion, not its update
Definition field_obj.h:93
s32 bounce
The share of its falling speed kept as it bounces on landing, 16.16 fixed point (0x4000 when created)...
Definition field_obj.h:64
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
u8 priorityFlags
ActorPriorityFlag bits, read by the scrolling camera.
Definition field_obj.h:51
s32 velocityY
16.16 fixed-point pixels per frame
Definition field_obj.h:53
s32 gravity
Taken off the vertical velocity each frame while it is above the ground, in 16.16 fixed-point pixels ...
Definition field_obj.h:68
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
s32 targetY
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:60
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition field_obj.h:40
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
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
s32 velocityZ
16.16 fixed-point pixels per frame
Definition field_obj.h:54
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 system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned short u16
Definition types.h:13
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.
static void Xian_StrikeTrainingTreeWithForce(void)
Force on the training tree: it jumps, and the student cries out.
Definition xian.c:598
s32 gXian_TreeImpactScript[]
The effect at the tree's foot when the student strikes it: 18 frames.
Definition xian.c:802
u32 gXian_Exits[]
Definition xian.c:860
s32 gXian_TrainingTreeJump[]
The struck tree jumps 32 pixels and drops back.
Definition xian.c:787
struct ScenePlacement gXian_Placements[]
Definition xian.c:868
static void Xian_RotateTrainingTree(void)
Rotates the training tree during the student's strike and Force animation.
Definition xian.c:91
static void Xian_TalkToFeizhi(void)
Talking to Feizhi.
Definition xian.c:493
@ ACTOR_KUNG_FU_STUDENT
Strikes the tree before him with a shout. "Hoo-whaaa... Hachaaa!".
Definition xian.c:52
@ ACTOR_FORCE_TARGET
Force's mark on the training tree.
Definition xian.c:62
@ ACTOR_FIRST_DECORATION
The first of three actors kept below the others.
Definition xian.c:65
@ ACTOR_WATER_CARRIER
Carries water along the street. "You made me spill my water!".
Definition xian.c:56
@ ACTOR_TRAINING_TREE
The tree the student strikes; it jumps when hit.
Definition xian.c:58
static s32 Xian_UpdateCarrierTracking(struct FieldActor *actor, struct FieldActor *target, s32 distanceLimit, s32 forceTracking)
Tracks a nearby target only within the actor's current facing sector.
Definition xian.c:122
u16 gXian_DoorSteps2[]
Definition xian.c:823
u16 gXian_DoorSteps3[]
Definition xian.c:829
static void Xian_RecruitVillageDjinni(void)
Talking to the Djinni: it joins the party (Mercury Djinni 2).
Definition xian.c:75
struct SceneEvent gXian_Events[]
Definition xian.c:908
const struct SceneEntrance * Xian_GetEntrances(void)
Definition xian.c:211
static void Xian_FreezeSpilledWater(void)
Frost freezes the spilled water: the puddle turns to ice the leader can stand on, and there is nothin...
Definition xian.c:381
static void Xian_OpenDoorAndLeave(void)
Walking into one of Xian's doors: it opens and the party goes in.
Definition xian.c:553
u16 gXian_DoorSteps1[]
The doors' opening frames, copied from map cells.
Definition xian.c:817
static void Xian_JumpOverSpilledWater(void)
Walking into the spilled water before it is frozen: the leader jumps two cells over it,...
Definition xian.c:502
s32 gXian_WaterCarrierRoute[]
The water carrier's round: from (280, 232) east to (424, 232), up to (424, 216) and back,...
Definition xian.c:756
const struct ScenePlacement * Xian_GetPlacements(void)
Once Xian has heard Hsu is trapped, actor 15 turns to face the party.
Definition xian.c:218
@ ANIM_PUDDLE_FROZEN
Definition xian.c:68
static void Xian_UpdateFrozenPuddleLayer(void)
Draws the frozen puddle under the leader while the leader stands on top of it.
Definition xian.c:81
s32 gXian_TrainingParticleScript[]
Each particle beside the leaping student, facing west: 16 frames.
Definition xian.c:807
static void Xian_AskAboutYoungWarriors(void)
Asks about the young warriors' way here.
Definition xian.c:226
static void Xian_MoveAsideForWaterCarrier(void)
The leader has stood in the water carrier's way for two seconds: both walk to the start of her route,...
Definition xian.c:629
#define XIAN_WATER_CARRIER_UPDATE
Definition xian.c:208
struct SceneEntrance gXian_Entrances[]
Definition xian.c:847
const u32 * Xian_GetExits(void)
Definition xian.c:215
u16 gXian_DoorSteps4[]
Definition xian.c:835
static void Xian_SpawnTrainingParticles(void)
Emits particles beside the student every fourth frame.
Definition xian.c:98
const struct SceneEvent * Xian_GetEvents(void)
Definition xian.c:664
static void Xian_WalkThroughExit(s32 exitId)
Walks the leader through a doorway and leaves by its exit.
Definition xian.c:539
static void Xian_TalkToKungFuStudent(void)
The kung fu student.
Definition xian.c:403
u16 gXian_DoorSteps5[]
Definition xian.c:841
static s32 Xian_WatchWaterCarrierPath(union FieldObject *fieldObject)
Definition xian.c:170
@ XIAN_CARRIER_BLOCKED_FRAMES
Definition xian.c:72
@ XIAN_TRIGGER_CARRIER_BLOCKED
Definition xian.c:72
static void Xian_UpdatePuddlePriority(void)
Frost on the spilled water, before it freezes: the puddle is drawn in front while the leader stands n...
Definition xian.c:373
static void Xian_TalkToWaterCarrier(void)
Talking to the water carrier.
Definition xian.c:239
s32 Xian_Initialize(void)
Queues sound 169 and sets up the village as the story and this visit left it.
Definition xian.c:668
const struct SceneRegion * Xian_GetRegions(void)
Definition xian.c:213