Alchemy
Loading...
Searching...
No Matches

mogall_forest.c

Go to the documentation of this file.
1/// @file
2/// Mogall Forest's three areas. Apes (sprite 0xbf) hide in the undergrowth;
3/// Force on a hiding place (an invisible actor, sprite 0x16, on the same spot)
4/// brings one out. Most point the way on and leave; the hostile ones attack,
5/// fought as encounter table 53 slot 0, the "Ape", and the last is the Killer
6/// Ape of slot 1. Logs (sprites 0xcd and 0xcf) can be pushed into the river.
7
8#include "script.h"
9#include "game_state.h"
10#include "engine_call.h"
11#include "global_cells.h"
12#include "unit/import.h"
16#include "unit/object/object.h"
18
19#define FIELD_STAGED_ACTOR_IMPORTS
20#include "field_obj.h"
21#include "mapcopy.h"
22#include "types.h"
23#include "field_event.h"
24#include "field_scene.h"
25#include "djinn_ids.h"
26#include "field_effect.h"
27#include "staged_actor.h"
29#include "battle.h"
30#include "debug.h"
31#include "field.h"
32#include "game.h"
33#include "graphics.h"
34#include "menu.h"
35#include "minigame.h"
36#include "sound.h"
37#include "system.h"
38#include "edition.h"
39#include "call.h"
40#include "scene_ids.h"
41#include "text/msg_ids.h"
42#include "ability_ids.h"
43#include "objcmd.h"
44#include "field_runtime.h"
45#include "fixed_math.h"
46#include "vector3.h"
47#include "flags.h"
48#include "item_ids.h"
49#include "songs.h"
50
51/// The first area.
60 ACTOR_NUT ///< a Nut floating over the river, caught with Catch
61};
62
63/// The second area.
67 ACTOR_SECOND_AREA_OBSTACLE, ///< sprite 0x125, moved with Move
74 ACTOR_QUARTZ ///< Venus Djinni 2
75};
76
77/// The third area.
87 ACTOR_THIRD_AREA_EAST_APE, ///< later the Killer Ape
92};
93
94/// Kept until the party leaves the forest: each ape once it has come out
95/// (or, for two, moved on to a second hiding place) and each rolled log.
96enum {
114};
115
116/// Scene flag, kept while the party stays in the area.
118
119enum {
123};
124
125// The third area's east ape: in the first patch it is placed only until it
126// has come out, and from the first patch on the hiding place that shares its
127// sprite too.
128#if TBS_PATCH_LEVEL == 1
129#define MOGALL_FOREST_EAST_ACTOR_CONDITION FLAG_THIRD_AREA_EAST_APE_OUT
130#else
131#define MOGALL_FOREST_EAST_ACTOR_CONDITION CONDITION_ALWAYS
132#endif
133
134#if !TBS_PATCH_1
135#define MOGALL_FOREST_EAST_SHARED_SPRITE_CONDITION CONDITION_ALWAYS
136#else
137#define MOGALL_FOREST_EAST_SHARED_SPRITE_CONDITION FLAG_THIRD_AREA_EAST_APE_OUT
138#endif
139
141
142#include "common/effect_create.h"
143#include "common/effect_spawn.h"
144
145/// Talking to Quartz in the second area: the Djinni battle (Djinni 2).
148}
149
150/// Jumps the leader to an unobstructed fixed-point position and restores
151/// motion.
154 u8 *motionFlags = &leader->motionFlags;
155 s32 savedMotionFlags = *motionFlags;
156
157 s32 collision = FieldObject_CheckMovementCollision(leader, position);
158
159 if (collision == 0) {
160 s32 jumpMotionFlags;
161
163 Object_SetMode(leader, 6);
166 Object_SetMode(leader, 7);
167 leader->speed = PIXELS(3);
168 leader->acceleration = PIXELS(2);
169 leader->velocityY = PIXELS(4);
170 jumpMotionFlags = 0x7e;
171 jumpMotionFlags &= *motionFlags;
172 *motionFlags = jumpMotionFlags;
175 (s16)((u32)position->z >> 16));
176 Object_SetMode(leader, 6);
178 *motionFlags = savedMotionFlags;
180 return 1;
181 }
182 return 0;
183}
184
185/// Script command: the actor shows the part its timer names.
186static s32
188 struct FieldActor *actor = (struct FieldActor *)interpreter;
189 ObjectGroup_SetChildValue(actor, actor->timer);
190 return 0;
191}
192
193/// Clears the actor sprite flags when its script requests it.
194static s32
196 struct FieldActor *actor = (struct FieldActor *)interpreter;
198 return 0;
199}
200
201/// Hops an actor to a pixel destination with the requested vertical speed.
203 s32 verticalSpeed) {
204 struct FieldActor *actor;
205
206 actor = Object_GetById(actorId);
208 Actor_SetSpeed(actorId, PIXELS(3), PIXELS(3) / 2);
210 actor->velocityY = verticalSpeed;
211 actor->gravity = PIXELS(1) / 2;
212 actor->bounce = 0;
217 actor->gravity = PIXELS(1);
218}
219
220/// Scatters a complete ring of rising puffs around an actor.
222 struct Vector3 velocity;
223 struct EffectOptions options;
224 struct EffectOptions *effectOptions;
225 struct Vector3 *emissionVelocity;
226 struct FieldActor *actor;
227 u32 directionIndex;
228 s32 x;
229 s32 z;
230
231 actor = Object_GetById(id);
233 effectOptions = &options;
234 effectOptions->priority = 1;
235 for (directionIndex = 0; directionIndex <= 16; directionIndex++) {
236 emissionVelocity = &velocity;
237 emissionVelocity->x = Engine_MathCos(directionIndex << 12);
238 emissionVelocity->y = 0;
239 z = Engine_MathSin(directionIndex << 12);
240 x = emissionVelocity->x;
241 emissionVelocity->z = z;
242 x += x / 3;
243 emissionVelocity->x = x;
244 Effect_Spawn(actor->x.fixed, PIXELS(16), actor->z.fixed, x,
245 emissionVelocity->y + PIXELS(1) / 10, z, EFFECT_USE_PRIORITY,
246 effectOptions);
247 }
248}
249
250/// The camera goes to the ape's hiding place, which bursts in a ring of
251/// puffs, and the ape shows itself.
252static void MogallForest_ApeComesOut(s32 actorId, s32 drawParameter) {
253 s32 cameraSpeed = PIXELS(2);
254 s32 cameraAcceleration = PIXELS(1) / 4;
255
256 Engine_CameraSetSpeed(cameraSpeed, cameraAcceleration);
257 Engine_CameraMoveToActor(actorId, 1);
261 Engine_ActorSetChildValue(actorId, drawParameter);
262}
263
264/// The ape turns to the leader, hops and gestures down the way to go.
265static inline void MogallForest_ApePointsTheWay(s32 guideId) {
266 Engine_CameraFollowActor(guideId, 1);
270 Engine_ActorSetAttachedEffect(guideId, 258);
272}
273
275 s16 selector = gGameState.scene;
276
277 if (selector == (s32)&SceneId_MogallForest1) {
279 }
280 if (selector == (s32)&SceneId_MogallForest2) {
282 }
283 if (selector == (s32)&SceneId_MogallForest3) {
285 }
287}
288
289const struct SceneRegion *MogallForest_GetRegions(void) { return NULL; }
290
291/// The exits, shared by the three areas.
293
295 s16 selector = gGameState.scene;
296
297 if (selector == (s32)&SceneId_MogallForest1) {
299 }
300 if (selector == (s32)&SceneId_MogallForest2) {
302 }
303 if (selector == (s32)&SceneId_MogallForest3) {
305 }
307}
308
309/// Pushing a log in the first area (walking into trigger 20): the river log
310/// pushed to row 26 rolls into the water and can be crossed.
312 struct StagedActorProbe probe;
313
315 if (StagedActor_FindClearPosition(&probe) != 0) {
316 SceneActor_MoveAndRedraw(probe);
318 (probe.position.z >> 20) == 26) {
329 Map_CopyCellAttributes(38, 27, 4, 2, 31, 25);
330 }
331 }
333}
334
335/// Walking north into trigger 25: the leader jumps north across the log.
337 struct FieldPosition position;
338#if TBS_PATCH_1
340
341 position.x = (leader->x.fixed & 0xfff00000) + PIXELS(8);
342 position.y = leader->y.fixed;
343 position.z = (leader->z.fixed & 0xfff00000) - PIXELS(24);
344#else
347 position.z = Object_GetById(ACTOR_PARTY_LEADER)->z.fixed - PIXELS(32);
348#endif
350}
351
352/// Walking south into trigger 26: the leader jumps onto the log, which
353/// bobs under the weight.
355 struct FieldPosition position;
357 u8 *motionFlags = &actor->motionFlags;
358 s32 savedMotionFlags = *motionFlags;
359
360#if TBS_PATCH_1
361 position.x = (actor->x.fixed & 0xfff00000) + PIXELS(8);
362 position.y = actor->y.fixed;
363 position.z = (actor->z.fixed & 0xfff00000) + PIXELS(40);
364#else
367 position.z = Object_GetById(ACTOR_PARTY_LEADER)->z.fixed + PIXELS(32);
368#endif
369 if (MogallForest_TryJumpLeaderTo(&position) != 0) {
371 *motionFlags = 0;
373 actor->y.fixed += -PIXELS(1);
374 actor->terrainHeight += -PIXELS(1);
376 actor->y.fixed += -PIXELS(1);
377 actor->terrainHeight += -PIXELS(1);
378 Engine_TaskWait(10);
379 actor->y.fixed += PIXELS(1);
380 actor->terrainHeight += PIXELS(1);
382 actor->y.fixed += PIXELS(1);
383 actor->terrainHeight += PIXELS(1);
384 *motionFlags = savedMotionFlags;
386 }
387}
388
389/// Searching the sign (trigger 27). "The broken sign reads: North: Fuchin
390/// Temple / South: Mogall Prairie..."
394 Engine_MessageShowCentered(MSGNO(MsgMogallForestBrokenSign), 1);
396}
397
398/// Force on the north hiding place in the first area: the ape comes out,
399/// points the way and hops off south.
401 struct FieldActor *creature;
402
404
406
409
410 Effect_Spawn(creature->x.fixed, creature->y.fixed,
411 creature->z.fixed + PIXELS(24), 0, 0, 0, 1, 0);
412
414
418
422
426
430
432}
433
434/// Force on the hostile ape's hiding place: it comes out angry, leaps at the
435/// leader and the battle with the Ape begins (encounter table 53, slot 0).
437 struct FieldActor *creature;
438
440
442
445
446 Effect_Spawn(creature->x.fixed, creature->y.fixed,
447 creature->z.fixed + PIXELS(24), 0, 0, 0, 1, 0);
448
451 0);
457
461 PIXELS(4));
462
466
468
470
472}
473
474/// Force on the east hiding place in the first area: the ape comes out,
475/// points the way and hops off east.
477 struct FieldActor *creature;
478
480
482
485
486 Effect_Spawn(creature->x.fixed, creature->y.fixed,
487 creature->z.fixed + PIXELS(16), 0, 0, 0, 1, 0);
488
490
494
498
502
505
507}
508
509/// Catch on the Nut floating over the river: it is caught and found.
510static void MogallForest_CatchNut(void) {
517}
518
519/// Pushing a log in the second area (walking into trigger 20): the log at row
520/// 23 changes the ground beside it; the river log pushed to column 35 rolls
521/// into the water.
523 struct StagedActorProbe probe;
524 s32 destinationColumn;
525 s32 destinationRow;
526 s32 rectangleHeight;
527 s32 attributes;
528
530
531 if (StagedActor_FindClearPosition(&probe) != 0) {
532 SceneActor_MoveAndRedraw(probe);
533
534 if (probe.actorSlot == ACTOR_SECOND_AREA_LOG &&
535 (probe.position.z >> 20) == 23) {
536 destinationColumn = 35;
537 destinationRow = 68;
538 Map_CopyCellAttributes(35, 67, 4, 1, destinationColumn, destinationRow);
539 } else if (probe.actorSlot == ACTOR_SECOND_AREA_RIVER_LOG &&
540 (probe.position.x >> 20) == 35) {
541
542 attributes = 0;
549
552
553 destinationColumn = 34;
554 destinationRow = 30;
555 Map_CopyCellAttributes(44, 30, 2, 4, destinationColumn, destinationRow);
556 rectangleHeight = 4;
557 StagedActor_FillGridAttributeRectangle(2, 35, 30, 1, rectangleHeight,
558 attributes);
559 }
560 }
561
563}
564
565/// Marks the obstacle cell and clears the cells it could have moved from.
566static inline void MogallForest_UpdateObstacleFootprint(s32 column, s32 row) {
567 StagedActor_FillGridAttributeRectangle(2, column, row, 1, 1, 255);
568 StagedActor_FillGridAttributeRectangle(2, column + 1, row, 1, 1, 0);
569 StagedActor_FillGridAttributeRectangle(2, column - 1, row, 1, 1, 0);
570 StagedActor_FillGridAttributeRectangle(2, column, row + 1, 1, 1, 0);
571 StagedActor_FillGridAttributeRectangle(2, column, row - 1, 1, 1, 0);
572}
573
574/// Move on the second area's obstacle: its footprint follows it, and at
575/// (36, 24) it sinks two pixels into place.
577 s32 column;
578 s32 row;
579
581
584
586
587 if (column == 36 && row == 24) {
589
590 obstacle->motionFlags = 0;
591 obstacle->terrainHeight = -PIXELS(2);
592 obstacle->y.fixed = -PIXELS(2);
593 }
594
596}
597
598/// Force on the north hiding place in the second area: the ape points the
599/// way and hops off south.
601 struct FieldActor *creature;
602
608 Effect_Spawn(creature->x.fixed, creature->y.fixed,
609 (creature->z.fixed + PIXELS(4)), 0, 0, 0, 1, 0);
627}
628
629/// Force on the east hiding place in the second area: the ape points the way
630/// and hops off east.
632 struct FieldActor *creature;
633
635
637
641
642 Effect_Spawn(creature->x.fixed, creature->y.fixed,
643 creature->z.fixed + PIXELS(4), 0, 0, 0, 1, 0);
644
646
650
654
658
662
666
668}
669
670/// Force on the south hiding place the first time: the ape bolts to another
671/// hiding place nearby.
673 struct FieldActor *creature;
674
678 PIXELS(38) / 5);
683 Engine_ActorSetSpriteFlags(creature, 0);
688}
689
690/// Force on its new hiding place: the ape points the way and hops off west.
692 struct FieldActor *creature;
693
695
697
701
702 Effect_Spawn(creature->x.fixed, creature->y.fixed,
703 creature->z.fixed + PIXELS(4), 0, 0, 0, 1, 0);
704
706
710
714
718
722
728
730}
731
732/// Pushing a log in the third area (walking into trigger 20): each river
733/// log rolls into the water at its column (42 and 40) and can be crossed.
735 struct StagedActorProbe probe;
736 s32 landed;
737
739 landed = 0;
740 if (StagedActor_FindClearPosition(&probe) != 0) {
741 SceneActor_MoveAndRedraw(probe);
745 Map_CopyCellAttributes(38, 68, 1, 4, probe.position.x >> 20, 68);
746 if (probe.position.x >> 20 == 42) {
747 Map_CopyCellAttributes(26, 20, 2, 4, probe.position.x >> 20, 23);
749 landed = 1;
751 }
752 } else {
753 if (probe.position.x >> 20 == 40) {
754 Map_CopyCellAttributes(26, 20, 2, 4, probe.position.x >> 20, 32);
756 landed = 1;
758 }
759 }
760 if (landed == 0) {
762 return;
763 }
769 Actor_Get(probe.actorSlot)->priorityFlags = ACTOR_PRIORITY_UNDERFOOT;
770 } else {
771 if (probe.actorSlot == ACTOR_THIRD_AREA_LOG)
772 Map_CopyCellAttributes(42, 49, 1, 4, probe.position.x >> 20, 49);
773 }
774 }
776}
777
778/// Walking west into trigger 25: the leader jumps onto the second river log,
779/// which bobs under the weight.
781 struct FieldActor *leader;
783 u8 savedMotionFlags;
784 struct FieldPosition position;
785
787 motionFlags = &leader->motionFlags;
788 savedMotionFlags = *motionFlags;
789
790 position.x = Object_GetById(ACTOR_PARTY_LEADER)->x.fixed - PIXELS(32);
793
794 if (MogallForest_TryJumpLeaderTo(&position) != 0) {
795
797
798 *motionFlags = 0;
800
801 leader->y.fixed += -PIXELS(1);
802 leader->terrainHeight += -PIXELS(1);
804
805 leader->y.fixed += -PIXELS(1);
806 leader->terrainHeight += -PIXELS(1);
807 Engine_TaskWait(10);
808
809 leader->y.fixed += PIXELS(1);
810 leader->terrainHeight += PIXELS(1);
812
813 leader->y.fixed += PIXELS(1);
814 leader->terrainHeight += PIXELS(1);
815
816 *motionFlags = savedMotionFlags;
818 }
819}
820
821/// Move on the third area's north obstacle: at (45, 6) it sinks into place.
823 s32 column;
824 s32 row;
825
827
830
832
833 if (column == 45 && row == 6) {
834 struct FieldActor *obstacle =
836
837 obstacle->motionFlags = 0;
838 obstacle->terrainHeight = -PIXELS(2);
839 obstacle->y.fixed = -PIXELS(2);
840 }
841
843}
844
845/// Move on the south obstacle: on row 27 it sinks into place and stays.
847
848 s32 column;
849 s32 row;
850 struct FieldActor *obstacle;
851
854 column = obstacle->x.fixed;
856 row = obstacle->z.fixed;
857 column >>= 20;
858 row >>= 20;
861 if ((obstacle->z.fixed >> 20) == 27) {
863 obstacle->motionFlags = 0;
864 obstacle->terrainHeight = -PIXELS(2);
865 obstacle->y.fixed = -PIXELS(2);
867 StagedActor_FillGridAttributeRectangle(2, 43, 23, 1, 1, 255);
868 }
870}
871
872/// Force on the third area's hostile hiding place: the ape leaps at the
873/// leader and the battle with the Ape begins.
875
876 struct FieldActor *creature;
877 s32 jumpSpeed;
878 struct FieldActor *leaderForX;
879 s32 leaderX;
880 struct FieldActor *leaderForZ;
881
883 jumpSpeed = PIXELS(8);
888 Effect_Spawn(creature->x.fixed, creature->y.fixed,
889 (creature->z.fixed + jumpSpeed), 0, 0, 0, 1, 0);
892 0);
899 leaderX = leaderForX->x.part.pixel;
902 leaderForZ->z.part.pixel, PIXELS(6));
908}
909
910/// Force on the central hiding place: the ape points the way and hops off
911/// south.
913 struct FieldActor *creature;
914
916
918
922
923 Effect_Spawn(creature->x.fixed, creature->y.fixed,
924 creature->z.fixed + PIXELS(4), 0, 0, 0, 1, 0);
925
927
931
935
939
945
947}
948
949/// Force on the west hiding place: the ape points the way and hops off west.
951 struct FieldActor *creature;
952
954
956
960
961 Effect_Spawn(creature->x.fixed, creature->y.fixed,
962 creature->z.fixed + PIXELS(4), 0, 0, 0, 1, 0);
963
965
969
973
977
983
985}
986
987/// Force on the east hiding place the first time: the ape bolts to another
988/// hiding place to the south.
990 struct FieldActor *creature;
991
994 Camera_MoveTo(PIXELS(744), -1, PIXELS(504), 1);
999 Engine_ActorSetSpriteFlags(creature, 0);
1000 Engine_EventWait(30);
1004}
1005
1006/// Force on its new hiding place: the ape points the way and hops off south.
1008 struct FieldActor *creature;
1009
1011
1013
1016 Engine_EventWait(10);
1017
1018 Effect_Spawn(creature->x.fixed, creature->y.fixed,
1019 creature->z.fixed + PIXELS(4), 0, 0, 0, 1, 0);
1020
1022
1025 Engine_EventWait(10);
1026
1030
1034
1038
1041 Engine_EventWait(30);
1043
1045}
1046
1047/// Touching trigger 22 in the third area, once: the ape appears again,
1048/// turns to the party and leads it south to a hiding place.
1050 struct FieldActor *creature;
1051
1057 Engine_EventWait(10);
1058 Effect_Spawn(creature->x.fixed, creature->y.fixed,
1059 (creature->z.fixed + PIXELS(4)), 0, 0, 0, 1, 0);
1066 Engine_EventWait(10);
1075 Engine_EventWait(60);
1078}
1079
1080/// Touching trigger 23 until it is beaten: the hiding place shakes twice and
1081/// out comes the Killer Ape, a fifth again as big, to fight (encounter table
1082/// 53, slot 1); the party returns to entrance 15.
1084 struct Vector3 velocity;
1085 struct Vector3 *emissionVelocity;
1086 struct FieldActor *actor;
1087 u32 directionIndex;
1088 s32 x;
1089 s32 z;
1090
1093 // Shake the hiding place twice before the creature appears.
1097 Engine_CameraSetSpeed(PIXELS(1) / 2, PIXELS(1) / 16);
1098 Camera_MoveTo(PIXELS(136), -1, PIXELS(392), 1);
1100 Engine_EventWait(60);
1104 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1107 Engine_EventWait(40);
1110 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1112 Engine_EventWait(40);
1114 actor->scaleX = 6 * Q16_ONE / 5;
1115 actor->scaleY = 6 * Q16_ONE / 5;
1118 Engine_EventWait(15);
1119 // The larger reveal uses a wider, level ring of puffs.
1121 for (directionIndex = 0; directionIndex <= 16; directionIndex++) {
1122 emissionVelocity = &velocity;
1123 emissionVelocity->x = Engine_MathCos(directionIndex << 12);
1124 emissionVelocity->y = 0;
1125 z = Engine_MathSin(directionIndex << 12);
1126 x = emissionVelocity->x;
1127 emissionVelocity->z = z;
1128 x += x / 2;
1129 emissionVelocity->x = x;
1130 Effect_Spawn(actor->x.fixed, 0, actor->z.fixed, x, emissionVelocity->y, z,
1131 1, NULL);
1132 }
1133 Engine_EventWait(30);
1134 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
1138 Engine_EventWait(20);
1139 // Jump toward the leader, then enter the final creature encounter.
1140 {
1141 s32 leaderX = Object_GetById(ACTOR_PARTY_LEADER)->x.part.pixel;
1142
1145 Object_GetById(ACTOR_PARTY_LEADER)->z.part.pixel - 16, PIXELS(8));
1146 }
1147 Engine_EventWait(10);
1148 Battle_SetStart(3);
1152}
1153
1155 s16 selector = gGameState.scene;
1156
1157 if (selector == (s32)&SceneId_MogallForest1) {
1158 return gMogallForestEvents1;
1159 }
1160 if (selector == (s32)&SceneId_MogallForest2) {
1161 return gMogallForestEvents2;
1162 }
1163 if (selector == (s32)&SceneId_MogallForest3) {
1164 return gMogallForestEvents3;
1165 }
1167}
1168
1169/// On entering an area: the first time, an ape peeks out and hides (the
1170/// first area); apes already out stay gone, rolled logs and moved obstacles
1171/// stay put; back from the Killer Ape (entrance 15) it is marked beaten.
1173 struct FieldActor *actor;
1174 s32 sceneId;
1175 s32 entrance;
1176 s32 column;
1177 s32 fixedZ;
1178
1180 sceneId = gGameState.scene;
1181 if (sceneId == (s32)&SceneId_MogallForest1) {
1182 // Show the first guide once, or restore the first area's completed
1183 // crossing.
1184 entrance = gGameState.entrance;
1185 switch (entrance) {
1186 case 1:
1187 case 2:
1188 case 3:
1189 case 4:
1192 Engine_TaskWait(1);
1202 Engine_EventWait(30);
1205 Engine_EventWait(30);
1207 PIXELS(7));
1211 0);
1213 Engine_EventWait(60);
1215 }
1217 break;
1218 }
1220 break;
1221 }
1224 break;
1225
1226 case 7:
1227 case 8:
1228 case 9:
1230 if (actor != 0) {
1232 }
1233 actor = Object_GetById(ACTOR_NUT);
1234 actor->update = 0;
1236 actor = Object_GetById(ACTOR_NUT);
1237 actor->y.fixed = PIXELS(32);
1238 }
1239 Engine_TaskWait(1);
1243 }
1247 0);
1249 FieldScene_RedrawActorFootprint(8);
1251 FieldScene_RedrawActorFootprint(ACTOR_FIRST_AREA_RIVER_LOG);
1252 break;
1253 }
1254 Engine_TaskWait(1);
1257 Map_CopyCellAttributes(38, 27, 4, 2, 31, 25);
1260 break;
1261 }
1262 } else if (sceneId == (s32)&SceneId_MogallForest2) {
1263 // Restore revealed guides, moved obstacles and the second crossing.
1264 entrance = gGameState.entrance;
1265 switch (entrance) {
1266 case 3:
1267 case 4:
1268 case 5:
1269 case 6:
1273 0);
1274 }
1276 break;
1277 }
1280 break;
1281
1282 case 10:
1283 case 11:
1284 case 12:
1286 FieldScene_RedrawActorFootprint(ACTOR_SECOND_AREA_RIVER_LOG);
1287 } else {
1288#if TBS_PATCH_1
1289 s32 attr = 0;
1290#endif
1291
1292 Engine_TaskWait(1);
1294 PIXELS(510));
1298 Map_CopyCellAttributes(44, 30, 2, 4, 34, 30);
1299#if TBS_PATCH_1
1301 attr);
1302#endif
1303 }
1304 FieldScene_RedrawActorFootprint(ACTOR_SECOND_AREA_LOG);
1305 FieldScene_RedrawActorFootprint(9);
1308 column >>= 20;
1309 StagedActor_FillGridAttributeRectangle(2, column, fixedZ >> 20, 1, 1,
1310 255);
1311 Engine_TaskWait(1);
1315 break;
1316 }
1319 0);
1321 break;
1322 }
1325 PIXELS(480));
1326 break;
1327 }
1328 } else if (sceneId == (s32)&SceneId_MogallForest3) {
1329 // Restore both crossing logs and the creatures leading to the final
1330 // encounter.
1331 entrance = gGameState.entrance;
1332 switch (entrance) {
1333 case 3:
1334 case 4:
1335 case 5:
1336 case 6:
1337 Engine_TaskWait(1);
1341 0);
1344 }
1348 0);
1351 }
1353 break;
1354 }
1358 0);
1359 break;
1360
1361 case 7:
1364 column >>= 20;
1365 StagedActor_FillGridAttributeRectangle(2, column, fixedZ >> 20, 1, 1,
1366 255);
1368 Engine_TaskWait(1);
1370 FieldScene_RedrawActorFootprint(ACTOR_THIRD_AREA_LOG);
1371 break;
1372
1373 case 8:
1374 case 9:
1375 case 10:
1376 case 11:
1379 FieldScene_RedrawActorFootprint(10);
1380 FieldScene_RedrawActorFootprint(12);
1382 FieldScene_RedrawActorFootprint(ACTOR_THIRD_AREA_RIVER_LOG_1);
1383 } else {
1384 Engine_TaskWait(1);
1387 PIXELS(398));
1390 Map_CopyCellAttributes(26, 20, 2, 4, 42, 23);
1393 PIXELS(440));
1396 }
1398 FieldScene_RedrawActorFootprint(ACTOR_THIRD_AREA_RIVER_LOG_2);
1399 } else {
1400 Engine_TaskWait(1);
1403 PIXELS(550));
1406 Map_CopyCellAttributes(26, 20, 2, 4, 40, 32);
1407 }
1410 column >>= 20;
1411 StagedActor_FillGridAttributeRectangle(2, column, fixedZ >> 20, 1, 1,
1412 255);
1414 Engine_TaskWait(1);
1419 0);
1422 PIXELS(504));
1424 PIXELS(504));
1425 }
1426#if TBS_PATCH_2
1427 } else {
1429#endif
1430 }
1432 break;
1433
1434 case 12:
1435 case 13:
1439 break;
1440 }
1442 break;
1443 }
1445 break;
1446
1447 case 15:
1449 break;
1450 }
1451 }
1452 return 0;
1453}
1454
1455#include "common/object_orbit.h"
1456
1457/// Pixel step by direction: X in the upper halfword, Z in the lower.
1458#define DIRECTION_STEP(dx, dz) (((u32)(dx) << 16) | ((dz) & 0xffff))
1459
1461 DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0), DIRECTION_STEP(16, 0),
1462 DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16), DIRECTION_STEP(0, 16),
1463 DIRECTION_STEP(0, 16), DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0),
1464 DIRECTION_STEP(-16, 0), DIRECTION_STEP(-16, 0), DIRECTION_STEP(0, -16),
1465 DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16), DIRECTION_STEP(0, -16),
1466 DIRECTION_STEP(16, 0),
1467};
1468
1469// clang-format off
1471 207, 205, 228, 229, 298, 297,
1472};
1473
1475 -32, -8, 32, 8,
1476 -8, -32, 8, 32,
1477 -32, -16, 32, 0,
1478 -8, -32, 8, 32,
1479 -32, -8, 32, 8,
1480 -8, -32, 8, 32,
1481};
1482
1484 SC_WAIT(1),
1485 SC_LOOP(22, SC_TOP),
1486 SC_WAIT(1),
1487 SC_POS(0, 0, 0),
1488 SC_WAIT(1),
1489 SC_FREE,
1490};
1491
1493 SC_WAIT(1),
1494 SC_LOOP(44, SC_TOP),
1495 SC_WAIT(1),
1496 SC_POS(0, 0, 0),
1497 SC_WAIT(1),
1498 SC_FREE,
1499};
1500
1502 SC_WAIT(1),
1503 SC_LOOP(126, SC_TOP),
1504 SC_WAIT(1),
1505 SC_POS(0, 0, 0),
1506 SC_WAIT(1),
1507 SC_FREE,
1508};
1509
1514};
1515
1517 SC_ARG(2),
1518 SC_SET(0x23, 6),
1520 SC_END,
1521};
1522
1524 SC_SET(SW_SCALE_X, 4 * Q16_ONE / 5),
1525 SC_SET(SW_SCALE_Y, 4 * Q16_ONE / 5),
1526 SC_SET(0x23, 15),
1529 SC_END,
1530};
1531
1533 SC_SET(SW_MOTION, 0),
1534 SC_SET(SW_Y, 0),
1535 SC_SET(SW_TARGET_Y, PIXELS(-32768)),
1537 SC_WAIT(2),
1538 SC_END,
1539};
1540
1542 { 1, CONDITION_ALWAYS, 136, 0, 24, FACING_SOUTH, 0, 0, 0, 272, 224, 0 },
1543 { 2, CONDITION_ALWAYS, 24, 0, 128, FACING_EAST, 0, 0, 0, 272, 224, 0 },
1544 { 3, CONDITION_ALWAYS, 248, 0, 128, FACING_WEST, 0, 0, 0, 272, 224, 0 },
1545 { 4, CONDITION_ALWAYS, 136, 0, 200, FACING_NORTH, 0, 0, 0, 272, 224, 0 },
1546 { 5, CONDITION_ALWAYS, 72, 0, 264, FACING_SOUTH, 0, 0, 240, 272, 464, 0 },
1547 { 6, CONDITION_ALWAYS, 200, 0, 440, FACING_NORTH, 0, 0, 240, 272, 464, 0 },
1548 { 7, CONDITION_ALWAYS, 416, 0, 264, FACING_SOUTH, 0, 288, 240, 672, 624, 0 },
1549 { 8, CONDITION_ALWAYS, 560, 0, 264, FACING_SOUTH, 0, 288, 240, 672, 624, 0 },
1550 { 9, CONDITION_ALWAYS, 648, 0, 344, FACING_WEST, 0, 288, 240, 672, 624, 0 },
1551 { SCENE_TABLE_END },
1552};
1553
1555 { 0, CONDITION_ALWAYS, 120, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1556 { 1, CONDITION_ALWAYS, 24, 0, 128, FACING_EAST, 0, 0, 0, 272, 224, 0 },
1557 { 2, CONDITION_ALWAYS, 248, 0, 128, FACING_WEST, 0, 0, 0, 272, 224, 0 },
1558 { 3, CONDITION_ALWAYS, 424, 0, 24, FACING_SOUTH, 0, 288, 0, 560, 224, 0 },
1559 { 4, CONDITION_ALWAYS, 312, 0, 136, FACING_EAST, 0, 288, 0, 560, 224, 0 },
1560 { 5, CONDITION_ALWAYS, 536, 0, 120, FACING_WEST, 0, 288, 0, 560, 224, 0 },
1561 { 6, CONDITION_ALWAYS, 424, 0, 200, FACING_NORTH, 0, 288, 0, 560, 224, 0 },
1562 { 7, CONDITION_ALWAYS, 744, 0, 24, FACING_SOUTH, 0, 576, 0, 848, 224, 0 },
1563 { 8, CONDITION_ALWAYS, 744, 0, 200, FACING_NORTH, 0, 576, 0, 848, 224, 0 },
1564 { 9, CONDITION_ALWAYS, 24, 0, 368, FACING_EAST, 0, 0, 240, 272, 464, 0 },
1565 { 10, CONDITION_ALWAYS, 488, 0, 264, FACING_SOUTH, 0, 288, 240, 736, 624, 0 },
1566 { 11, CONDITION_ALWAYS, 312, 0, 528, FACING_EAST, 0, 288, 240, 736, 624, 0 },
1567 { 12, CONDITION_ALWAYS, 360, 0, 600, FACING_NORTH, 0, 288, 240, 736, 624, 0 },
1568 { SCENE_TABLE_END },
1569};
1570
1572 { 0, CONDITION_ALWAYS, 172, 0, 160, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1573 { 1, CONDITION_ALWAYS, 24, 0, 128, FACING_EAST, 0, 0, 0, 272, 224, 0 },
1574 { 2, CONDITION_ALWAYS, 248, 0, 128, FACING_WEST, 0, 0, 0, 272, 224, 0 },
1575 { 3, CONDITION_ALWAYS, 424, 0, 24, FACING_SOUTH, 0, 288, 0, 560, 224, 0 },
1576 { 4, CONDITION_ALWAYS, 312, 0, 160, FACING_EAST, 0, 288, 0, 560, 224, 0 },
1577 { 5, CONDITION_ALWAYS, 536, 0, 160, FACING_WEST, 0, 288, 0, 560, 224, 0 },
1578 { 6, CONDITION_ALWAYS, 424, 0, 200, FACING_NORTH, 0, 288, 0, 560, 224, 0 },
1579 { 7, CONDITION_ALWAYS, 824, 0, 136, FACING_WEST, 0, 576, 0, 848, 224, 0 },
1580 { 8, CONDITION_ALWAYS, 728, 0, 264, FACING_SOUTH, 0, 400, 240, 848, 640, 0 },
1581 { 9, CONDITION_ALWAYS, 824, 0, 512, FACING_WEST, 0, 400, 240, 848, 640, 0 },
1582 { 10, CONDITION_ALWAYS, 824, 0, 608, FACING_WEST, 0, 400, 240, 848, 640, 0 },
1583 { 11, CONDITION_ALWAYS, 736, 0, 616, FACING_NORTH, 0, 400, 240, 848, 640, 0 },
1584 { 12, CONDITION_ALWAYS, 264, 0, 264, FACING_SOUTH, 0, 0, 240, 384, 496, 0 },
1585 { 13, CONDITION_ALWAYS, 136, 0, 472, FACING_NORTH, 0, 0, 240, 384, 496, 0 },
1586 { 15, CONDITION_ALWAYS, 136, 0, 432, FACING_NORTH, 0, 0, 240, 384, 496, 0 },
1587 { SCENE_TABLE_END },
1588};
1589
1591 { 1, CONDITION_ALWAYS, 312, 0, 128, FACING_EAST, 0, 288, 0, 560, 224, 0 },
1592 { 2, CONDITION_ALWAYS, 248, 0, 368, FACING_WEST, 0, 0, 240, 272, 464, 0 },
1593 { 3, CONDITION_ALWAYS, 424, 0, 440, FACING_NORTH, 0, 288, 240, 560, 464, 0 },
1594 { 4, CONDITION_ALWAYS, 712, 0, 264, FACING_SOUTH, 0, 576, 240, 848, 464, 0 },
1595 { 5, CONDITION_ALWAYS, 136, 0, 680, FACING_NORTH, 0, 0, 480, 272, 704, 0 },
1596 { 6, CONDITION_ALWAYS, 312, 0, 552, FACING_EAST, 0, 288, 480, 560, 704, 0 },
1597 { 7, CONDITION_ALWAYS, 312, 0, 648, FACING_EAST, 0, 288, 480, 560, 704, 0 },
1598 { 8, CONDITION_ALWAYS, 648, 0, 680, FACING_NORTH, 0, 576, 480, 848, 704, 0 },
1599 { 9, CONDITION_ALWAYS, 536, 0, 128, FACING_WEST, 0, 288, 0, 560, 224, 0 },
1600 { 10, CONDITION_ALWAYS, 24, 0, 368, FACING_EAST, 0, 0, 240, 272, 464, 0 },
1601 { SCENE_TABLE_END },
1602};
1603
1605 SCENE_EXITS(68),
1606 SCENE_EXIT(1, 2, 13),
1607 SCENE_EXIT(2, 71, 2),
1608 SCENE_EXIT(3, 71, 1),
1609 SCENE_EXIT(4, 68, 5),
1610 SCENE_EXIT(5, 68, 4),
1611 SCENE_EXIT(6, 68, 7),
1612 SCENE_EXIT(7, 68, 6),
1613 SCENE_EXIT(8, 71, 8),
1614 SCENE_EXIT(9, 69, 1),
1615 SCENE_EXIT(0, 69, 0),
1616 SCENE_EXIT(1, 68, 9),
1617 SCENE_EXIT(2, 69, 4),
1618 SCENE_EXIT(3, 71, 3),
1619 SCENE_EXIT(4, 69, 2),
1620 SCENE_EXIT(5, 69, 9),
1621 SCENE_EXIT(6, 69, 7),
1622 SCENE_EXIT(7, 69, 6),
1623 SCENE_EXIT(8, 69, 10),
1624 SCENE_EXIT(9, 69, 5),
1625 SCENE_EXIT(10, 69, 8),
1626 SCENE_EXIT(11, 70, 2),
1627 SCENE_EXIT(12, 71, 4),
1628 SCENE_EXIT(0, 70, 0),
1629 SCENE_EXIT(1, 70, 5),
1630 SCENE_EXIT(2, 69, 11),
1631 SCENE_EXIT(3, 71, 5),
1632 SCENE_EXIT(4, 70, 7),
1633 SCENE_EXIT(5, 70, 1),
1634 SCENE_EXIT(6, 70, 8),
1635 SCENE_EXIT(7, 70, 4),
1636 SCENE_EXIT(8, 70, 6),
1637 SCENE_EXIT(9, 71, 6),
1638 SCENE_EXIT(10, 71, 7),
1639 SCENE_EXIT(11, 70, 12),
1640 SCENE_EXIT(12, 70, 11),
1641 SCENE_EXIT(13, 2, 43),
1642 SCENE_EXIT(0, 71, 0),
1643 SCENE_EXIT(1, 68, 3),
1644 SCENE_EXIT(2, 68, 2),
1645 SCENE_EXIT(3, 69, 3),
1646 SCENE_EXIT(4, 69, 12),
1647 SCENE_EXIT(5, 70, 3),
1648 SCENE_EXIT(6, 70, 9),
1649 SCENE_EXIT(7, 70, 10),
1650 SCENE_EXIT(8, 68, 8),
1651 SCENE_EXIT(11, 71, 1),
1652 SCENE_EXIT(12, 71, 2),
1653 SCENE_EXIT(13, 71, 3),
1654 SCENE_EXIT(14, 71, 4),
1655 SCENE_EXIT(15, 71, 5),
1656 SCENE_EXIT(16, 71, 6),
1657 SCENE_EXIT(17, 71, 7),
1658 SCENE_EXIT(18, 71, 8),
1659 SCENE_EXIT(19, 71, 9),
1660 SCENE_EXIT(20, 71, 10),
1662};
1663
1665 { 0xcd, CONDITION_ALWAYS, 7,
1666 PIXELS(488), 0, PIXELS(464), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1667 { 0xcf, CONDITION_ALWAYS, 7,
1668 PIXELS(528), 0, PIXELS(504), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1670 PIXELS(136), 0, PIXELS(120), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1672 PIXELS(376), 0, PIXELS(432), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1674 PIXELS(504), 0, PIXELS(312), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1676 PIXELS(136), 0, PIXELS(120), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1681 { 0x16, FLAG_NUT_CAUGHT, 7,
1682 PIXELS(632), 0, PIXELS(440), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1683 { SCENE_TABLE_END },
1684};
1685
1687 { 0xcf, CONDITION_ALWAYS, 7,
1688 PIXELS(592), 0, PIXELS(360), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1689 { 0xcf, CONDITION_ALWAYS, 7,
1690 PIXELS(592), 0, PIXELS(456), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1691 { 0xcd, CONDITION_ALWAYS, 7,
1692 PIXELS(648), 0, PIXELS(512), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1694 PIXELS(584), 0, PIXELS(376), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1696 PIXELS(360), 0, PIXELS(80), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1698 PIXELS(488), 0, PIXELS(80), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1700 PIXELS(504), 0, PIXELS(480), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1702 PIXELS(360), 0, PIXELS(80), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1707 { 0x5a, FLAG_DJINNI_0 + 2, ACTOR_STAND,
1708 PIXELS(488), 0, PIXELS(568), FACING_EAST, TALK_FACE_PARTY, 0 },
1709 { SCENE_TABLE_END },
1710};
1711
1713 { 0xcd, CONDITION_ALWAYS, 7,
1714 PIXELS(680), 0, PIXELS(96), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1715 { 0xcd, CONDITION_ALWAYS, 7,
1716 PIXELS(616), 0, PIXELS(400), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1717 { 0xcd, CONDITION_ALWAYS, 7,
1718 PIXELS(552), 0, PIXELS(480), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1719 { 0xcd, CONDITION_ALWAYS, 7,
1720 PIXELS(600), 0, PIXELS(544), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1721 { 0xcf, CONDITION_ALWAYS, 7,
1722 PIXELS(544), 0, PIXELS(536), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1724 PIXELS(696), 0, PIXELS(120), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1728 PIXELS(488), 0, PIXELS(88), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1730 PIXELS(424), 0, PIXELS(120), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1732 PIXELS(360), 0, PIXELS(80), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1734 PIXELS(744), 0, PIXELS(400), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1736 PIXELS(488), 0, PIXELS(88), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1743 { SCENE_TABLE_END },
1744};
1745
1747 { SCENE_TABLE_END },
1748};
1749
1751 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1752 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1753 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1754 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1755 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1756 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
1757 { EVENT_EXIT, 7, CONDITION_ALWAYS, 7 },
1758 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
1759 { EVENT_EXIT, 9, CONDITION_ALWAYS, 9 },
1768 { SCENE_EVENTS_END },
1769};
1770
1772 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1773 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1774 { EVENT_EXIT, 3, CONDITION_ALWAYS, 3 },
1775 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1776 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1777 { EVENT_EXIT, 6, CONDITION_ALWAYS, 6 },
1778 { EVENT_EXIT, 7, CONDITION_ALWAYS, 7 },
1779 { EVENT_EXIT, 8, CONDITION_ALWAYS, 8 },
1780 { EVENT_EXIT, 9, CONDITION_ALWAYS, 9 },
1781 { EVENT_EXIT, 10, CONDITION_ALWAYS, 10 },
1782 { EVENT_EXIT, 11, CONDITION_ALWAYS, 11 },
1783 { EVENT_EXIT, 12, CONDITION_ALWAYS, 12 },
1792 { SCENE_EVENTS_END },
1793};
1794// clang-format on
1795
1806 {EVENT_EXIT, 10, CONDITION_ALWAYS, 10},
1807 {EVENT_EXIT, 11, CONDITION_ALWAYS, 11},
1808 {EVENT_EXIT, 12, CONDITION_ALWAYS, 12},
1809 {EVENT_EXIT, 13, CONDITION_ALWAYS, 13},
1842};
1843
1853 {EVENT_EXIT, 11, CONDITION_ALWAYS, 20},
1854 {EVENT_EXIT, 12, CONDITION_ALWAYS, 19},
1855 {EVENT_EXIT, 13, CONDITION_ALWAYS, 13},
1856 {EVENT_EXIT, 14, CONDITION_ALWAYS, 14},
1857 {EVENT_EXIT, 15, CONDITION_ALWAYS, 15},
1858 {EVENT_EXIT, 16, CONDITION_ALWAYS, 16},
1859 {EVENT_EXIT, 17, CONDITION_ALWAYS, 17},
1860 {EVENT_EXIT, 18, CONDITION_ALWAYS, 18},
1863};
Ability numbers, named from the English release.
@ ABILITY_FORCE
Definition ability_ids.h:17
@ ABILITY_CATCH
Definition ability_ids.h:23
@ 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.
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
s32 gStagedActor_DirectionSteps[]
Pixel step by direction: X in the upper halfword, Z in the lower.
s32 gStagedActor_FootprintBounds[]
#define DIRECTION_STEP(dx, dz)
Pixel step by direction: X in the upper halfword, Z in the lower.
u32 gStagedActor_FootprintKinds[]
s32 gEffectScript0[]
const s32 * gEffectScripts[]
s32 gEffectScript1[]
s32 gEffectScript2[]
Calls through a function pointer, by argument count.
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
The engine calls the debug menus import, and their palette swatch tiles.
Djinn numbers, named from the English release.
@ DJINNI_QUARTZ
Definition djinn_ids.h:13
The edition's language, for C to compare (LANGUAGE == LANGUAGE_GERMAN).
static UNUSED void * OverlayObject_CreateConfiguredObject(s32 x, s32 y, s32 z, s32 type)
A still effect in palette 15, at sprite priority 1, drawn under the actors.
The engine call layer: one typed inline for each of the thirteen main-image routines below that the s...
static s32 FieldObject_CheckMovementCollision(struct FieldActor *actor, struct FieldPosition *position)
Definition engine_call.h:66
Field effects, their scripts and the flags that spawn them.
@ EFFECT_USE_PRIORITY
options.priority, as the sprite's priority
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
@ ANIM_STAND
Definition field_event.h:43
void Engine_ActorFaceActor(s32 actor, s32 target, s32 frames)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
void Engine_MessageShowCentered(s32 message, s32 flags)
s32 Engine_PartyGiveItem(s32 item, s32 flags)
#define GameFlag_IsSet
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
void Engine_CameraMoveToActor(s32 actor, s32 pan)
void Engine_ActorMoveToAndWait(s32 actor, s32 x, s32 z)
#define EMOTE_IN_FRONT
Definition field_event.h:49
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
s32 Engine_MathSin(s32 angle)
void Engine_ItemShowFound(s32 item, s32 height)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_EventOpenScreen(void)
void Engine_MapWaitWorkValuesBelow256(void)
void Engine_GameFlagSet(s32 flag)
void Engine_CameraWaitForMove(void)
static void Actor_SetActionScript(s32 actor, const s32 *script)
The engine encodes either a built-in action or an action-script address.
void Engine_ActorWaitForMove(s32 actor)
void Engine_CameraFollowActor(s32 actor, s32 keep_position)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
void Engine_ActorWalkTo(s32 actor, s32 x, s32 z)
void Engine_ActorSetAttachedEffect(s32 actor, s32 effect)
void Engine_ActorSetChildValue(s32 actor, s32 value)
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
s32 Engine_MathCos(s32 angle)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ActorFaceEachOther(s32 actor, s32 other, s32 frames)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
static struct FieldActor * Actor_Get(s32 actor)
Field objects and actors, and the scene transition styles.
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ ACTOR_PRIORITY_UNDERFOOT
The depth sort treats it as 320 pixels higher on the screen.
Definition field_obj.h:155
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
The field's runtime work: map cells, scene records and regions, map markers and FieldWork.
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define FIND_PSYNERGY_STONE
#define SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_FIRST_PLACED
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
@ FACING_EAST
Definition field_scene.h:26
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define TOUCH_WALKING
#define PIXELS(value)
@ SEARCH_UNNAMED
@ SEARCH_CHEST
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_DJINNI_0
the flag of Djinni 0, set once it is caught
Definition flags.h:15
#define FLAG_MOGALL_FOREST_KILLER_APE_BEATEN
Definition flags.h:364
#define FLAG_SCENE_TEMP_00
Definition flags.h:713
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_NYUNPA_ENLIGHTENED
Nyunpa is enlightened, beyond words: he has passed away.
Definition flags.h:610
#define FLAG_NYUNPA_TAUGHT_FORCE
the power the monks call Ki
Definition flags.h:615
#define FLAG_MOGALL_FOREST_FIRST_APE_SEEN
an ape hides on arrival
Definition flags.h:361
#define FLAG_MOGALL_FOREST_LED_TO_KILLER_APE
The last guiding ape has led the party to the Killer Ape's hiding place.
Definition flags.h:363
GameState, the game's state: play time, coins, the scene and the leader's position,...
#define Battle_SetStart(mode)
Sets the battle start type.
Definition game_state.h:164
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
The screen blend's globals and the graphics routines.
The main-image routines scene overlays import.
Item numbers, named from the English release.
@ ITEM_APPLE
Definition item_ids.h:52
@ ITEM_NUT
Definition item_ids.h:41
@ ITEM_ELVEN_SHIRT
Definition item_ids.h:26
Declares nothing of its own: it only includes edition.h and types.h.
@ FLAG_PSYNERGY_STONE
The reel game's title lettering.
struct ScenePlacement gMogallForestPlacements3[]
static void MogallForest_SecondArea_SouthApeHidesAgain(void)
Force on the south hiding place the first time: the ape bolts to another hiding place nearby.
static void MogallForest_SecondArea_SouthApeShowsWay(void)
Force on its new hiding place: the ape points the way and hops off west.
static void MogallForest_ThirdArea_JumpWest(void)
Walking west into trigger 25: the leader jumps onto the second river log, which bobs under the weight...
static void MogallForest_ThirdArea_PushLog(void)
Pushing a log in the third area (walking into trigger 20): each river log rolls into the water at its...
static void MogallForest_FirstArea_ApeAttacks(void)
Force on the hostile ape's hiding place: it comes out angry, leaps at the leader and the battle with ...
static s32 MogallForest_ClearActorSpriteFlags(struct ScriptInterpreter *interpreter)
Clears the actor sprite flags when its script requests it.
static void MogallForest_ApeLeadsToKillerApe(void)
Touching trigger 22 in the third area, once: the ape appears again, turns to the party and leads it s...
const struct ScenePlacement * MogallForest_GetPlacements(void)
static void MogallForest_UpdateObstacleFootprint(s32 column, s32 row)
Marks the obstacle cell and clears the cells it could have moved from.
struct SceneEvent gMogallForestEvents3[]
struct ScenePlacement gMogallForestPlacementsOther[]
static void MogallForest_SecondArea_PushLog(void)
Pushing a log in the second area (walking into trigger 20): the log at row 23 changes the ground besi...
@ FLAG_SECOND_AREA_LOG_ROLLED
@ FLAG_SECOND_AREA_NORTH_APE_OUT
@ FLAG_SECOND_AREA_EAST_APE_OUT
@ FLAG_THIRD_AREA_EAST_APE_OUT
@ FLAG_FIRST_AREA_EAST_APE_OUT
@ FLAG_THIRD_AREA_CENTRAL_APE_OUT
@ FLAG_THIRD_AREA_FIRST_LOG_ROLLED
@ FLAG_SECOND_AREA_SOUTH_APE_OUT
@ FLAG_THIRD_AREA_EAST_APE_MOVED
@ FLAG_THIRD_AREA_WEST_APE_OUT
@ FLAG_THIRD_AREA_SECOND_LOG_ROLLED
@ FLAG_FIRST_AREA_NORTH_APE_OUT
@ FLAG_FIRST_AREA_LOG_ROLLED
@ FLAG_THIRD_AREA_HOSTILE_APE_OUT
@ FLAG_SECOND_AREA_SOUTH_APE_MOVED
@ FLAG_FIRST_AREA_HOSTILE_APE_OUT
static void MogallForest_ReadBrokenSign(void)
Searching the sign (trigger 27).
struct SceneEntrance gMogallForestEntrances2[]
@ FLAG_SOUTH_OBSTACLE_SETTLED
MogallForest1Actor
The first area.
@ ACTOR_FIRST_AREA_RIVER_LOG
@ ACTOR_FIRST_AREA_NORTH_APE
@ ACTOR_FIRST_AREA_NORTH_HIDEOUT
@ ACTOR_FIRST_AREA_EAST_HIDEOUT
@ ACTOR_NUT
a Nut floating over the river, caught with Catch
@ ACTOR_FIRST_AREA_EAST_APE
@ ACTOR_FIRST_AREA_HOSTILE_HIDEOUT
@ ACTOR_FIRST_AREA_HOSTILE_APE
#define MOGALL_FOREST_EAST_ACTOR_CONDITION
static void MogallForest_FirstArea_JumpNorth(void)
Walking north into trigger 25: the leader jumps north across the log.
#define MOGALL_FOREST_EAST_SHARED_SPRITE_CONDITION
struct SceneEvent gMogallForestEvents2[]
MogallForest3Actor
The third area.
@ ACTOR_THIRD_AREA_WEST_HIDEOUT
@ ACTOR_THIRD_AREA_WEST_APE
@ ACTOR_THIRD_AREA_EAST_HIDEOUT
@ ACTOR_THIRD_AREA_HOSTILE_HIDEOUT
@ ACTOR_THIRD_AREA_NORTH_OBSTACLE
@ ACTOR_THIRD_AREA_HOSTILE_APE
@ ACTOR_THIRD_AREA_EAST_APE
later the Killer Ape
@ ACTOR_THIRD_AREA_LOG
@ ACTOR_THIRD_AREA_RIVER_LOG_2
@ ACTOR_THIRD_AREA_SOUTH_OBSTACLE
@ ACTOR_THIRD_AREA_RIVER_LOG_1
@ ACTOR_THIRD_AREA_CENTRAL_HIDEOUT
@ ACTOR_THIRD_AREA_CENTRAL_APE
struct SceneEntrance gMogallForestEntrances1[]
static void MogallForest_HopActorTo(s32 actorId, s32 targetX, s32 targetZ, s32 verticalSpeed)
Hops an actor to a pixel destination with the requested vertical speed.
MogallForest2Actor
The second area.
@ ACTOR_SECOND_AREA_EAST_APE
@ ACTOR_SECOND_AREA_SOUTH_APE
@ ACTOR_SECOND_AREA_NORTH_HIDEOUT
@ ACTOR_SECOND_AREA_LOG
@ ACTOR_SECOND_AREA_EAST_HIDEOUT
@ ACTOR_SECOND_AREA_NORTH_APE
@ ACTOR_SECOND_AREA_OBSTACLE
sprite 0x125, moved with Move
@ ACTOR_QUARTZ
Venus Djinni 2.
@ ACTOR_SECOND_AREA_RIVER_LOG
@ ACTOR_SECOND_AREA_SOUTH_HIDEOUT
const u32 * MogallForest_GetExits(void)
The exits, shared by the three areas.
struct SceneEvent gMogallForestEventsOther[]
static void MogallForest_SecondArea_EastApeShowsWay(void)
Force on the east hiding place in the second area: the ape points the way and hops off east.
static void MogallForest_ThirdArea_EastApeHidesAgain(void)
Force on the east hiding place the first time: the ape bolts to another hiding place to the south.
s32 gMogallForest_ActorScript[]
static void MogallForest_StartDjinnBattle(void)
Talking to Quartz in the second area: the Djinni battle (Djinni 2).
static void MogallForest_FirstArea_NorthApeShowsWay(void)
Force on the north hiding place in the first area: the ape comes out, points the way and hops off sou...
static void MogallForest_FirstArea_PushLog(void)
Pushing a log in the first area (walking into trigger 20): the river log pushed to row 26 rolls into ...
static void MogallForest_ThirdArea_ApeAttacks(void)
Force on the third area's hostile hiding place: the ape leaps at the leader and the battle with the A...
s32 gMogallForestPlacements1_1[]
const struct SceneEvent * MogallForest_GetEvents(void)
struct SceneEntrance gMogallForestEntrances3[]
u32 gMogallForest_Exits[]
static void MogallForest_ThirdArea_UpdateSouthObstacle(void)
Move on the south obstacle: on row 27 it sinks into place and stays.
static void MogallForest_ThirdArea_UpdateNorthObstacle(void)
Move on the third area's north obstacle: at (45, 6) it sinks into place.
static s32 MogallForest_TryJumpLeaderTo(struct FieldPosition *position)
Jumps the leader to an unobstructed fixed-point position and restores motion.
static void MogallForest_ApeComesOut(s32 actorId, s32 drawParameter)
The camera goes to the ape's hiding place, which bursts in a ring of puffs, and the ape shows itself.
static void MogallForest_ThirdArea_WestApeShowsWay(void)
Force on the west hiding place: the ape points the way and hops off west.
static void MogallForest_SecondArea_NorthApeShowsWay(void)
Force on the north hiding place in the second area: the ape points the way and hops off south.
struct ScenePlacement gMogallForestPlacements1[]
static void MogallForest_CatchNut(void)
Catch on the Nut floating over the river: it is caught and found.
static void MogallForest_FirstArea_EastApeShowsWay(void)
Force on the east hiding place in the first area: the ape comes out, points the way and hops off east...
s32 gMogallForestPlacements2_0[]
struct ScenePlacement gMogallForestPlacements2[]
struct SceneEntrance gMogallForestEntrancesOther[]
static s32 MogallForest_CopyTimerToChild(struct ScriptInterpreter *interpreter)
Script command: the actor shows the part its timer names.
const struct SceneEntrance * MogallForest_GetEntrances(void)
struct SceneEvent gMogallForestEvents1[]
static void MogallForest_ApePointsTheWay(s32 guideId)
The ape turns to the leader, hops and gestures down the way to go.
const struct SceneRegion * MogallForest_GetRegions(void)
static void MogallForest_FirstArea_JumpSouth(void)
Walking south into trigger 26: the leader jumps onto the log, which bobs under the weight.
s32 MogallForest_Initialize(void)
On entering an area: the first time, an ape peeks out and hides (the first area); apes already out st...
static void MogallForest_ThirdArea_EastApeShowsWay(void)
Force on its new hiding place: the ape points the way and hops off south.
static void MogallForest_SecondArea_UpdateMovableObstacle(void)
Move on the second area's obstacle: its footprint follows it, and at (36, 24) it sinks two pixels int...
static void MogallForest_SpawnPuffRing(s32 id)
Scatters a complete ring of rising puffs around an actor.
@ FLAG_NUT_CAUGHT
@ FLAG_CHEST_APPLE
@ FLAG_CHEST_ITEM_5D
static void MogallForest_ThirdArea_CentralApeShowsWay(void)
Force on the central hiding place: the ape points the way and hops off south.
static void MogallForest_KillerApeAttacks(void)
Touching trigger 23 until it is beaten: the hiding place shakes twice and out comes the Killer Ape,...
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_ARG(v)
Definition objcmd.h:44
#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_TARGET_Y
Definition objcmd.h:70
@ SW_SCALE_Y
Definition objcmd.h:63
@ SW_MOTION
Definition objcmd.h:75
@ SW_Y
Definition objcmd.h:59
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
static s32 StagedActor_FillGridAttributeRectangle(u32 layer, s32 x, s32 z, u32 width, u32 height, s32 value)
Sets the collision code of a width by height rectangle of cells, from cell (x, z),...
void Field_RequestBattleFromEncounterTable(s32 zoneNo, s32 slotNo)
Sets up a battle with enemy group slot of encounter table zone.
Definition requests.c:14
void Event_SetNextDestination(s32 scene, s32 entrance)
Sets the scene and entrance that the field goes to next (gGameState.nextScene and nextEntrance).
Definition requests.c:61
void Field_RequestDjinnBattle(s32 flag, s32 no)
Sets up the battle with Djinni number no.
Definition requests.c:35
Scene numbers, named after their places.
char SceneId_MogallForest3
char SceneId_MogallForest1
char SceneId_MogallForest2
The field object script interpreter and the operands its commands read.
Declares nothing of its own: it only includes types.h.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_240
Definition songs.h:235
#define SE_147
Definition songs.h:140
#define SE_148
Definition songs.h:141
#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_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_ActorShowEmote()
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
void Scene_FloatNut(s32 id)
Draws actor id as the Nut's icon and starts it floating, 32 pixels up unless the party returns to whe...
The pushable actors' movement probes and footprint bounds.
The options of a spawned field effect, each used when its EFFECT_USE_ flag (or EFFECT_SCALE_TO_TARGET...
s32 priority
the sprite's priority
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s16 timer
The parameter its action script reads (a follow distance or an angle to face), the player's frames to...
Definition field_obj.h:109
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 targetZ
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:61
s32 bounce
The share of its falling speed kept as it bounces on landing, 16.16 fixed point (0x4000 when created)...
Definition field_obj.h:64
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
u8 priorityFlags
ActorPriorityFlag bits, read by the scrolling camera.
Definition field_obj.h:51
s32 terrainHeight
16.16 fixed-point pixels
Definition field_obj.h:38
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
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
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
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
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
Where a large thing ahead of the leader would roll to: its footprint, its actor, that position,...
struct FieldPosition position
16.16 pixels while moving; converted to cells by footprint redraws.
s32 actorSlot
the large thing's actor number, 8 to 65
Three coordinates, x, y and z: a position, a velocity or a direction.
Definition vector3.h:11
s32 z
Definition vector3.h:24
s32 x
Definition vector3.h:22
s32 y
Definition vector3.h:23
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
signed short s16
Definition types.h:12
unsigned char u8
Definition types.h:11
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels
Vector3, a three-coordinate vector.