Alchemy
Loading...
Searching...
No Matches

imil_fuchin_falls.c

Go to the documentation of this file.
1/// @file
2/// The Djinni's ice room by Imil and Fuchin Falls, in seven maps: the ice room,
3/// then Fuchin Falls' four platform rooms, the room of the Ki inscription and
4/// the dragon statue's room.
5///
6/// Flags 0x301 to 0x315 belong to the cave and hold the platforms' stops: 0x301
7/// to 0x303 the first room's, 0x304 to 0x307 the second's, 0x308 to 0x312 the
8/// third's and 0x313 to 0x315 the fourth's.
9
10#include "script.h"
11#include "game_state.h"
12#include "keystate.h"
13#include "scene_ids.h"
14#include "unit/import.h"
16#include "unit/object/object.h"
18#include "unit/field/field.h"
19#include "unit/game/game.h"
20#include "battle.h"
21#include "field_service.h"
22#include "debug.h"
23#include "field.h"
24#include "game.h"
25#include "graphics.h"
26#include "menu.h"
27#include "minigame.h"
28#include "sound.h"
29#include "system.h"
30#include "imil_fuchin_falls.h"
31#include "types.h"
32#include "glyph.h"
33#include "field_event.h"
34#include "field_scene.h"
35#include "djinn_ids.h"
36#include "call.h"
37#include "battle_party.h"
38#include "field_effect.h"
39#include "scene.h"
40#include "field_runtime.h"
41#include "display_transition.h"
42#include "fx_scene.h"
43#include "text/msg_ids.h"
44#include "ability_ids.h"
45#include "objcmd.h"
46#include "fixed_math.h"
47#include "object_effect.h"
48#include "palbuf.h"
49#include "flags.h"
50#include "songs.h"
51#include "item_ids.h"
52
54 ACTOR_IMIL_DJINNI = 8, ///< in the ice room
55 /// The platforms, in each platform room
60 ACTOR_FUCHIN_DJINNI = 11 ///< in the second platform room
61};
62
63enum {
64 IMIL_SLIDE_ANIMATION_STEP = 3 * 16 ///< three times normal animation speed
65};
66
67static void Fuchin_RebuildFirstRoomPlatforms(void);
68static void Fuchin_RebuildSecondRoomPlatforms(void);
69static void Fuchin_RebuildThirdRoomPlatforms(void);
70static void Fuchin_RebuildFourthRoomPlatforms(void);
71static void Imil_WalkTowardDjinni(void);
72static void ImilFuchinFalls_PrepareRoom(void);
74static void ImilFuchinFalls_HopBy(s32 dx, s32 dz);
75static void ImilFuchinFalls_PlaceDragonsEye(void);
76static void Imil_SlideActorAcrossIce(void);
77
79
80/// The three action scripts cave dust can run, chosen by its spawn flags.
82 const s32 *script[3];
83};
84
85/// EffectOptions cut after its scales: the caller's frame holds only these 24
86/// bytes.
94};
95
97 offsetof(struct EffectOptions, priority));
99 offsetof(struct EffectOptions, palette));
101 offsetof(struct EffectOptions, startScaleX));
103 offsetof(struct EffectOptions, startScaleY));
104STATIC_ASSERT(offsetof(struct CaveDustOptions, targetScaleX) ==
105 offsetof(struct EffectOptions, targetScaleX));
106STATIC_ASSERT(offsetof(struct CaveDustOptions, targetScaleY) ==
107 offsetof(struct EffectOptions, targetScaleY));
108
109/// Talking to the Djinni in the ice room adds it to the party.
110static void Imil_RecruitDjinni(void) {
112}
113
114/// Talking to the Djinni in the second platform room starts its battle.
115static void Fuchin_StartDjinnBattle(void) {
117}
118
120 s16 sceneId = gGameState.scene;
121
122 if (sceneId == (s32)&SceneId_ImilFuchinFalls1) {
124 }
125 if (sceneId == (s32)&SceneId_ImilFuchinFalls2) {
127 }
128 if (sceneId == (s32)&SceneId_ImilFuchinFalls3) {
130 }
131 if (sceneId == (s32)&SceneId_ImilFuchinFalls4) {
133 }
134 if (sceneId == (s32)&SceneId_ImilFuchinFalls5) {
136 }
137 if (sceneId == (s32)&SceneId_ImilFuchinFalls6) {
139 }
140 if (sceneId == (s32)&SceneId_ImilFuchinFalls7) {
142 }
144}
145
146const struct SceneRegion *ImilFuchinFalls_GetRegions(void) { return NULL; }
147
148/// Returns the exit connections shared by these rooms.
150
152 s16 sceneId = gGameState.scene;
153
154 if (sceneId == (s32)&SceneId_ImilFuchinFalls1) {
156 }
157 if (sceneId == (s32)&SceneId_ImilFuchinFalls2) {
159 }
160 if (sceneId == (s32)&SceneId_ImilFuchinFalls3) {
162 }
163 if (sceneId == (s32)&SceneId_ImilFuchinFalls4) {
165 }
166 if (sceneId == (s32)&SceneId_ImilFuchinFalls5) {
168 }
169 if (sceneId == (s32)&SceneId_ImilFuchinFalls7) {
171 }
173}
174
176
177/// Lets the platform settle before rebuilding its room's collision cells.
178static inline void Fuchin_FinishPlatformMove(void (*rebuildPlatforms)(void)) {
181 rebuildPlatforms();
182}
183
189 Engine_GameFlagSet(0x301);
192}
193
195 s32 offset = 112;
196
197 offset = -offset;
205}
206
214}
215
220 Engine_GameFlagSet(0x302);
223}
224
232}
233
238 Engine_GameFlagSet(0x303);
241}
242
247 Engine_GameFlagSet(0x304);
250}
251
257 Engine_GameFlagSet(0x305);
260}
261
266 Engine_GameFlagSet(0x305);
269}
270
273
274 if (Engine_GameFlagIsSet(0x306) != 0) {
277 } else {
279
280 Engine_GameFlagSet(0x304);
281 }
282
284}
285
290 Engine_GameFlagSet(0x306);
293}
294
302}
303
312}
313
315 s32 depth = -96;
316
322 Engine_GameFlagSet(0x307);
325}
326
329
330 if (Engine_GameFlagIsSet(0x310) != 0 || Engine_GameFlagIsSet(0x30D) != 0) {
333 Engine_GameFlagSet(0x309);
334 } else {
336 Engine_GameFlagSet(0x308);
338 }
339
341}
342
349}
350
352 if (Engine_GameFlagIsSet(0x310) != 0) {
353 return;
354 }
355 if (Engine_GameFlagIsSet(0x30D) != 0) {
356 return;
357 }
358
360
361 Engine_GameFlagSet(0x308);
363
366}
367
374}
375
380 Engine_GameFlagSet(0x30A);
383}
384
392}
393
396 if (Engine_GameFlagIsSet(0x308) != 0) {
399 Engine_GameFlagSet(0x30c);
402 } else {
404 Engine_GameFlagSet(0x30b);
408 }
410}
411
414
415 if (Engine_GameFlagIsSet(0x308) != 0) {
418 Engine_GameFlagSet(0x30c);
421 } else if (Engine_GameFlagIsSet(0x310) != 0) {
424 Engine_GameFlagSet(0x30c);
427 } else if (Engine_GameFlagIsSet(0x311) != 0) {
431 Engine_GameFlagSet(0x30d);
433 } else {
439 }
441}
442
447 Engine_GameFlagSet(0x30b);
453}
454
457 if (Engine_GameFlagIsSet(0x311) != 0) {
460
462 Engine_GameFlagSet(0x30d);
464 } else if (Engine_GameFlagIsSet(0x310) != 0) {
467 Engine_GameFlagSet(0x30c);
470 } else {
476 }
478}
479
484 Engine_GameFlagSet(0x30B);
488}
489
500}
501
506 Engine_GameFlagSet(0x30b);
512}
513
524}
525
528
529 if (Engine_GameFlagIsSet(0x308) != 0 || Engine_GameFlagIsSet(0x30d) != 0) {
533 Engine_GameFlagSet(0x311);
535 } else if (Engine_GameFlagIsSet(0x30c) != 0) {
538 Engine_GameFlagSet(0x310);
541 } else {
543 Engine_GameFlagSet(0x30f);
547 }
549}
550
551/// Clears all saved intermediate stops for the fourth platform.
557}
558
564}
565
570 Engine_GameFlagSet(0x30F);
576}
577
585}
586
594}
595
603}
604
612}
613
618 Engine_GameFlagSet(0x313);
621}
622
630}
631
636 Engine_GameFlagSet(0x314);
639}
640
648}
649
654 Engine_GameFlagSet(0x315);
657}
658
666}
667
668/// Advances the first platform through its two rolling animations.
672}
673
674/// Advances the second platform through its two rolling animations.
678}
679
680/// Advances the third platform through its two rolling animations.
684}
685
686/// Advances the fourth platform through its two rolling animations.
690}
691
692/// Creates a stationary foreground actor with its palette and priority set.
694 s32 resourceId) {
695 struct FieldActor *actor = Engine_ObjectCreate(resourceId, x, y, z);
696
697 if (actor != 0) {
698 actor->sprite->image.priority = 1;
699 actor->motionFlags = 0;
701 ObjectGroup_SetChildValue(actor, 15);
703 return actor;
704 }
705 return 0;
706}
707
709 s16 sceneId = gGameState.scene;
710
711 if (sceneId == (s32)&SceneId_ImilFuchinFalls1) {
713 }
714 if (sceneId == (s32)&SceneId_ImilFuchinFalls2) {
716 }
717 if (sceneId == (s32)&SceneId_ImilFuchinFalls3) {
719 }
720 if (sceneId == (s32)&SceneId_ImilFuchinFalls4) {
722 }
723 if (sceneId == (s32)&SceneId_ImilFuchinFalls5) {
725 }
726 if (sceneId == (s32)&SceneId_ImilFuchinFalls6) {
728 }
729 if (sceneId == (s32)&SceneId_ImilFuchinFalls7) {
731 }
733}
734
735/// Faces the leader south and leaves the Imil Djinn room.
736static void Imil_LeaveDjinnRoom(void) {
737 struct FieldActor *leader;
738
741 leader->facing = FACING_SOUTH;
746}
747
748/// Starts sliding the selected actor in the held direction.
750
751/// Centers a platform on its cell and gives it underfoot priority.
752static void Fuchin_PlacePlatformAtCell(s32 id, s32 column, s32 row) {
753 struct FieldActor *actor = Object_GetById(id);
754
755 if (actor != NULL) {
757 actor->terrainId = 2;
759 actor->x.fixed = PIXELS(column * 16) + PIXELS(8);
760 actor->z.fixed = PIXELS(row * 16) + PIXELS(8);
761 }
762}
763
764/// Restores platform positions and collision cells in the first puzzle room.
766 {
767 s32 column = 8;
768 s32 row = 29;
769 Map_CopyCellAttributes(8, 42, 15, 5, column, row);
770 }
771
772 if (Engine_GameFlagIsSet(0x301) != 0) {
774 {
775 s32 column = 8;
776 s32 row = 30;
777 Map_CopyCellAttributes(9, 30, 1, 3, column, row);
778 }
779 } else {
781 {
782 s32 column = 22;
783 s32 row = 30;
784 Map_CopyCellAttributes(9, 30, 1, 3, column, row);
785 }
786 }
787
788 if (Engine_GameFlagIsSet(0x302) != 0) {
790 {
791 s32 column = 11;
792 s32 row = 33;
793 Map_CopyCellAttributes(14, 33, 3, 1, column, row);
794 }
795 } else {
797 {
798 s32 column = 11;
799 s32 row = 29;
800 Map_CopyCellAttributes(14, 29, 3, 1, column, row);
801 }
802 }
803
804 if (Engine_GameFlagIsSet(0x303) != 0) {
806 {
807 s32 column = 17;
808 s32 row = 33;
809 Map_CopyCellAttributes(14, 33, 3, 1, column, row);
810 }
811 } else {
813 {
814 s32 column = 17;
815 s32 row = 29;
816 Map_CopyCellAttributes(14, 29, 3, 1, column, row);
817 }
818 }
819}
820
821/// Restores platform positions and collision cells in the second puzzle room.
823 {
824 s32 column = 12;
825 s32 row = 8;
826 Map_CopyCellAttributes(0, 28, 10, 18, column, row);
827 }
828
829 if (Engine_GameFlagIsSet(0x304) != 0) {
831 {
832 s32 column = 13;
833 s32 row = 19;
834 Map_CopyCellAttributes(20, 19, 1, 3, column, row);
835 }
836 } else {
838 {
839 s32 column = 21;
840 s32 row = 19;
841 Map_CopyCellAttributes(20, 19, 1, 3, column, row);
842 }
843 }
844
845 if (Engine_GameFlagIsSet(0x305) != 0) {
847 {
848 s32 column = 12;
849 s32 row = 19;
850 Map_CopyCellAttributes(5, 19, 1, 3, column, row);
851 }
852 {
853 s32 column = 13;
854 s32 row = 19;
855 Map_CopyCellAttributes(20, 19, 1, 3, column, row);
856 }
857 if (Engine_GameFlagIsSet(0x304) != 0) {
859 {
860 s32 column = 13;
861 s32 row = 19;
862 Map_CopyCellAttributes(20, 19, 1, 3, column, row);
863 }
864 {
865 s32 column = 12;
866 s32 row = 19;
867 Map_CopyCellAttributes(20, 19, 1, 3, column, row);
868 }
869 }
870 }
871
872 if (Engine_GameFlagIsSet(0x306) != 0) {
874 {
875 s32 column = 14;
876 s32 row = 17;
877 Map_CopyCellAttributes(14, 18, 3, 1, column, row);
878 }
879 } else {
881 {
882 s32 column = 14;
883 s32 row = 21;
884 Map_CopyCellAttributes(14, 18, 3, 1, column, row);
885 }
886 }
887
888 if (Engine_GameFlagIsSet(0x307) != 0) {
890 {
891 s32 column = 18;
892 s32 row = 25;
893 Map_CopyCellAttributes(14, 18, 3, 1, column, row);
894 }
895 } else {
897 {
898 s32 column = 18;
899 s32 row = 8;
900 Map_CopyCellAttributes(14, 18, 3, 1, column, row);
901 }
902 }
903}
904
905/// Restores the interacting platform stops and collision cells in the third
906/// room.
908 {
909 Map_CopyCellAttributes(12, 3, 9, 16, 12, 21);
910 }
911
912 if (Engine_GameFlagIsSet(0x308) != 0) {
914 {
915 Map_CopyCellAttributes(16, 24, 1, 3, 20, 24);
916 }
917 } else if (Engine_GameFlagIsSet(0x309) != 0) {
919 {
920 s32 row = 24;
921 Map_CopyCellAttributes(18, 24, 1, 3, 20, row);
922 Map_CopyCellAttributes(18, 24, 1, 3, 14, row);
923 Map_CopyCellAttributes(8, 41, 1, 3, 17, row);
924 }
925 } else {
927 {
928 Map_CopyCellAttributes(16, 24, 1, 3, 14, 24);
929 }
930 }
931
932 if (Engine_GameFlagIsSet(0x30a) != 0) {
934 {
935 Map_CopyCellAttributes(14, 34, 1, 3, 15, 34);
936 }
937 } else {
939 {
940 Map_CopyCellAttributes(14, 34, 1, 3, 13, 34);
941 }
942 }
943
944 if (Engine_GameFlagIsSet(0x30b) != 0) {
946 {
947 s32 column = 14;
948 Map_CopyCellAttributes(14, 29, 3, 1, column, 30);
949 Map_CopyCellAttributes(5, 41, 3, 1, column, 22);
950 }
951 } else if (Engine_GameFlagIsSet(0x30c) != 0) {
953 {
954 s32 column = 14;
955 Map_CopyCellAttributes(5, 42, 3, 1, column, 23);
956 Map_CopyCellAttributes(14, 29, 3, 1, column, 30);
957 Map_CopyCellAttributes(10, 44, 3, 1, column, 21);
958 }
959 } else if (Engine_GameFlagIsSet(0x30d) != 0) {
961 {
962 s32 column = 14;
963 Map_CopyCellAttributes(14, 29, 3, 1, column, 22);
964 Map_CopyCellAttributes(5, 43, 3, 1, column, 26);
965 Map_CopyCellAttributes(14, 29, 3, 1, column, 30);
966 }
967 } else if (Engine_GameFlagIsSet(0x30e) != 0) {
969 {
970 s32 column = 14;
971 Map_CopyCellAttributes(14, 29, 3, 1, column, 22);
972 Map_CopyCellAttributes(14, 29, 3, 1, column, 30);
973 Map_CopyCellAttributes(5, 44, 3, 1, column, 27);
974 }
975 } else {
977 }
978
979 if (Engine_GameFlagIsSet(0x30f) != 0) {
981 {
982 s32 column = 14;
983 Map_CopyCellAttributes(14, 29, 3, 1, column, 31);
984 Map_CopyCellAttributes(10, 40, 3, 1, column, 23);
985 }
986 } else if (Engine_GameFlagIsSet(0x310) != 0) {
988 {
989 s32 column = 14;
990 Map_CopyCellAttributes(14, 29, 3, 1, column, 31);
991 Map_CopyCellAttributes(10, 41, 3, 1, column, 24);
992 }
993 } else if (Engine_GameFlagIsSet(0x311) != 0) {
995 {
996 s32 column = 14;
997 Map_CopyCellAttributes(14, 29, 3, 1, column, 31);
998 Map_CopyCellAttributes(10, 42, 3, 1, column, 27);
999 }
1000 } else if (Engine_GameFlagIsSet(0x312) != 0) {
1002 {
1003 s32 column = 14;
1004 Map_CopyCellAttributes(14, 29, 3, 1, column, 31);
1005 Map_CopyCellAttributes(10, 43, 3, 1, column, 28);
1006 }
1007 } else {
1009 }
1010}
1011
1012/// Restores both halves of the fourth puzzle room from its saved platform
1013/// stops.
1015 if (((u32)((u16)gGameState.entrance - 1) << 16) <= 0x10000) {
1016 {
1017 s32 column = 14;
1018 s32 row = 10;
1019 Map_CopyCellAttributes(22, 20, 9, 8, column, row);
1020 }
1021 } else {
1022 {
1023 s32 column = 7;
1024 s32 row = 45;
1025 Map_CopyCellAttributes(20, 45, 11, 4, column, row);
1026 }
1027 }
1028
1029 if (Engine_GameFlagIsSet(0x313) != 0) {
1031 {
1032 s32 column = 19;
1033 s32 row = 10;
1034 Map_CopyCellAttributes(19, 11, 3, 1, column, row);
1035 }
1036 } else {
1038 {
1039 s32 column = 19;
1040 s32 row = 17;
1041 Map_CopyCellAttributes(19, 11, 3, 1, column, row);
1042 }
1043 }
1044
1045 if (Engine_GameFlagIsSet(0x314) != 0) {
1047 {
1048 s32 column = 22;
1049 s32 row = 15;
1050 Map_CopyCellAttributes(16, 15, 1, 3, column, row);
1051 }
1052 } else {
1054 {
1055 s32 column = 14;
1056 s32 row = 15;
1057 Map_CopyCellAttributes(16, 15, 1, 3, column, row);
1058 }
1059 }
1060
1061 if (Engine_GameFlagIsSet(0x315) != 0) {
1063 {
1064 s32 column = 7;
1065 s32 row = 45;
1066 Map_CopyCellAttributes(15, 15, 1, 3, column, row);
1067 }
1068 } else {
1070 {
1071 s32 column = 17;
1072 s32 row = 45;
1073 Map_CopyCellAttributes(15, 15, 1, 3, column, row);
1074 }
1075 }
1076}
1077
1078/// Attaches the active cave light to the party leader.
1081 struct FadeOverlayWork *work = *(gWorkSlot + 36);
1082
1084 }
1085}
1086
1087/// Detaches the active cave light from the party leader.
1090 struct FadeOverlayWork *work = *(gWorkSlot + 36);
1091
1092 work->actor = NULL;
1093 }
1094}
1095
1096/// Entering the Djinni's ice room the first time, the leader walks toward the
1097/// Djinni; otherwise each room restores its platforms, eye and lighting.
1104 } else {
1106 }
1107 return 0;
1108}
1109
1110/// Shows the Imil Djinni and walks the leader toward it.
1111static void Imil_WalkTowardDjinni(void) {
1112 struct FieldActor *actor;
1113
1121}
1122
1123/// Restores room props and the cave light for this entrance.
1125 struct FieldActor *actor;
1126 /* FAKEMATCH: needed to match: the shared zero/address-word lifetime avoids
1127 * swapping registers and adding a heap-cell add. Literal zeros and the slot
1128 * read in place: differ 51. */
1129 s32 value;
1130
1133 if (!GameFlag_IsSet(0xf13) && gGameState.entrance == 1) {
1135 }
1136 if ((u16)(gGameState.entrance - 2) <= 3) {
1137 Fuchin_CreateForegroundActor(PIXELS(156), 0, PIXELS(452), 223);
1138 Fuchin_CreateForegroundActor(PIXELS(188), 0, PIXELS(452), 223);
1139 }
1140 } else if (gGameState.scene == (s32)&SceneId_ImilFuchinFalls7) {
1141 value = 0;
1142 actor = Actor_Get(8);
1144 actor->motionFlags = value;
1145 actor->y.fixed = value;
1147 Actor_SetChildValue(8, 15);
1148 switch (gGameState.entrance) {
1149 case 1:
1150 case 2:
1153 break;
1154 case 5:
1157 value = *(s32 *)(gWorkSlot + 36);
1158 ((struct FadeOverlayWork *)value)->actor = NULL;
1159 break;
1160 }
1161 if (gGameState.entrance <= 6) {
1163 Map_CopyCellsTo(30, 57, 19, 57, 1, 1);
1164 Map_CopyCellsTo(30, 8, 12, 8, 8, 7);
1165 } else {
1168 ColorBuffer_ApplySource(0x203108, 1);
1169 ColorBuffer_ApplyTarget(0x203108, 1);
1171 Engine_TaskWait(1);
1172 }
1173 }
1174 }
1175}
1176
1177/// Restores the collision templates for the current platform room.
1180 Map_CopyCellAttributes(8, 29, 15, 5, 8, 42);
1182 } else if (gGameState.scene == (s32)&SceneId_ImilFuchinFalls3) {
1183 Map_CopyCellAttributes(12, 8, 10, 18, 0, 28);
1185 } else if (gGameState.scene == (s32)&SceneId_ImilFuchinFalls4 &&
1186 gGameState.entrance != 1) {
1187 Map_CopyCellAttributes(12, 21, 9, 16, 12, 3);
1189 } else if (gGameState.scene == (s32)&SceneId_ImilFuchinFalls5) {
1190 if (gGameState.entrance == 1 || gGameState.entrance == 2) {
1191 Map_CopyCellAttributes(14, 10, 9, 8, 22, 20);
1192 } else {
1193 Map_CopyCellAttributes(7, 45, 11, 4, 20, 45);
1194 }
1196 }
1197}
1198
1199/// Hops across a platform edge when its current stop permits it.
1201 s32 trigger = gEventWork->touchedTrigger;
1202
1204 if (trigger == 17) {
1205 ImilFuchinFalls_HopBy(0, -32);
1206 } else {
1207 ImilFuchinFalls_HopBy(-32, 0);
1208 }
1209 }
1210 if (gGameState.scene == (s32)&SceneId_ImilFuchinFalls4 && trigger == 25 &&
1211 Engine_GameFlagIsSet(0x309)) {
1212 ImilFuchinFalls_HopBy(0, 32);
1213 }
1214}
1215
1216/// Hops the leader one gap north.
1217static void Fuchin_HopNorth(void) { ImilFuchinFalls_HopBy(0, -32); }
1218
1219/// Hops the leader one gap west.
1220static void Fuchin_HopWest(void) { ImilFuchinFalls_HopBy(-32, 0); }
1221
1222/// Jumps the leader by a pixel offset while using the hopping animations.
1223static void ImilFuchinFalls_HopBy(s32 dx, s32 dz) {
1232}
1233
1234/// Creates the collectible eye and uploads its item icon.
1236 struct FieldActor *actor;
1237 struct AnimationObject *sprite;
1238 GlyphTransfer *glyph;
1239 u8 clear = 0;
1240
1241 actor = Object_Create(22, PIXELS(248), PIXELS(8), PIXELS(152));
1242 if (actor != NULL) {
1243 sprite = actor->sprite;
1244 sprite->flags = clear;
1245 sprite->count = clear;
1246 sprite->image.fullColor = 0;
1247 sprite->image.palette = 0;
1248 actor->motionFlags = clear;
1249 actor->retainSpriteCache = 1;
1250 glyph = Engine_HeapAllocate(17, sizeof(*glyph));
1252 Engine_VramLoad(sprite->slot, 128, glyph->tiles);
1255 }
1256}
1257
1258/// Gives the eye to the party and removes its displayed actor.
1259static void Fuchin_CollectDragonsEye(void) {
1261
1264 }
1265
1267 Engine_GameFlagSet(0xF13);
1268
1271 }
1272
1274}
1275
1276/// Applies the dust velocity and scale change for one frame.
1277static void Fuchin_UpdateDustMotion(union FieldObject *raw) {
1278 struct FieldEffect *object = &raw->effect;
1279
1280 object->x += object->velocity.x;
1281 object->y += object->velocity.y;
1282 object->z += object->velocity.z;
1283 object->scaleX += object->scaleRateX;
1284 object->scaleY += object->scaleRateY;
1285}
1286
1287/// Selects the dust palette when its object script finishes looping.
1288static s32 Fuchin_SetDustPalette(struct ScriptInterpreter *interpreter) {
1289 struct FieldActor *actor = (struct FieldActor *)interpreter;
1290 ObjectGroup_SetChildValue(actor, 15);
1291 return 0;
1292}
1293
1294/// Creates scripted cave dust with the requested velocity, palette and scale.
1296 s32 velocityY, s32 velocityZ, u32 flags,
1297 const struct EffectOptions *extra) {
1298 struct FieldEffect *effect;
1299 struct AnimationObject *sprite;
1300 const s32 *script;
1301 /* FAKEMATCH: needed to match: copying three scripts keeps the 12-byte frame
1302 * and prevents an early scale-script load. Reading
1303 * gImilFuchinFalls_DustScripts in place: differ 107. */
1304 struct CaveEffectScripts scripts =
1306
1307 effect = (struct FieldEffect *)Engine_ObjectCreate(222, x, y, z);
1308 if (effect == 0)
1309 return;
1310 sprite = effect->sprite;
1311 Object_SetMode((struct FieldActor *)effect, (flags + 1) & EFFECT_SCRIPT_MASK);
1312 Engine_ObjectSetScript((struct FieldActor *)effect,
1313 scripts.script[flags & EFFECT_SCRIPT_MASK]);
1314 effect->motionFlags = 0;
1315 sprite->flags = 0;
1317 effect->velocity.x = velocityX;
1318 effect->velocity.y = velocityY;
1319 effect->velocity.z = velocityZ;
1320 effect->scaleRateX = 0;
1321 effect->scaleRateY = 0;
1322 sprite->image.priority = 1;
1323 if ((flags & 0xffff0000) == 0 || extra == 0)
1324 return;
1325 if (flags & EFFECT_USE_PALETTE)
1326 ObjectGroup_SetChildValue((struct FieldActor *)effect, extra->palette);
1327 if (flags & EFFECT_USE_PRIORITY) {
1329 sprite->image.priority = extra->priority;
1330 }
1331 if (flags & EFFECT_USE_START_SCALE) {
1332 effect->scaleX = extra->startScaleX;
1333 effect->scaleY = extra->startScaleY;
1334 }
1335 if (flags & EFFECT_SCALE_TO_TARGET) {
1336 script = scripts.script[flags & EFFECT_SCRIPT_MASK];
1337 if (flags & EFFECT_USE_START_SCALE) {
1338 effect->scaleRateX = (extra->targetScaleX - effect->scaleX) / script[3];
1339 effect->scaleRateY = (extra->targetScaleY - effect->scaleY) / script[3];
1340 } else {
1341 effect->scaleRateX = (extra->targetScaleX - Q16_ONE) / script[3];
1342 effect->scaleRateY = (extra->targetScaleY - Q16_ONE) / script[3];
1343 }
1344 }
1345}
1346
1347/// Emits cave-mouth dust every fourth frame while the dragon awakens.
1349 struct CaveDustOptions options;
1350 s32 framePhase;
1351 s32 velocityX;
1352 s32 velocityY;
1353
1354 framePhase = gFrameCount & 3;
1355 if (framePhase != 0)
1356 return;
1357 options.palette = 10;
1358 options.startScaleX = Q16_ONE / 2;
1359 options.startScaleY = Q16_ONE / 2;
1360 options.targetScaleX = 9 * Q16_ONE / 5;
1361 options.targetScaleY = 9 * Q16_ONE / 5;
1362 if ((gFrameCount & 7) == 0)
1364 velocityX = -PIXELS(1) - ((((u32)Engine_RandomNext() << 1) >> 16) << 16);
1365 velocityY = -((((u32)Engine_RandomNext() * 3) >> 16) * (PIXELS(1) / 5));
1367 PIXELS(308), PIXELS(64), PIXELS(222), velocityX, velocityY, framePhase,
1369 (const struct EffectOptions *)&options);
1370}
1371
1372/// Inserts the eye, lights the dragon room and reveals its hidden path.
1373static void Fuchin_LightDragonWithEye(void) {
1374 u32 pass;
1375
1376 // Flash the room as the eye opens the dragon's path.
1381
1382 for (pass = 0; pass < 4; pass++) {
1383 Engine_ColorBufferApplyTarget(0x204318, 1);
1385 Engine_TaskWait(2);
1386 if (pass == 0) {
1387 Map_CopyCellsTo(30, 8, 12, 8, 8, 7);
1388 Map_CopyCellsTo(30, 57, 19, 57, 1, 1);
1389 }
1390 Engine_ColorBufferApplyTarget(0x203108, 1);
1392 Engine_TaskWait(2);
1393 }
1394
1395 Engine_TaskWait(30);
1396
1397 // Blow dust from the cave mouth while the room brightens.
1400 Engine_TaskWait(40);
1401 Engine_ColorBufferApplyTarget(0x201090, 1);
1403 Engine_TaskWait(80);
1405 Engine_TaskWait(20);
1406
1407 // Settle the lighting, consume the eye and remember the revealed path.
1410
1411 Engine_TaskWait(80);
1412
1416
1418}
1419
1420/// Reads the inscription describing the dragon flame.
1423 Engine_MessageShowCentered(MsgFuchinDragonFlameShowsPath, 1);
1425}
1426
1427/// Reads the inscription about the secret power of Ki.
1428static void Fuchin_ReadKiInscription(void) {
1430 Engine_MessageShowCentered(MsgFuchinSecretKiRevealed, 1);
1432}
1433
1434/// Reads the inscription about light revealing shadows.
1437 Engine_MessageShowCentered(MsgFuchinLightRevealsShadows, 1);
1439}
1440
1441/// Describes the dragon eyes or offers to insert the carried eye.
1442static void Fuchin_SearchDragonStatue(void) {
1444
1446 Engine_MessageShowCentered(MsgFuchinDragonRedEyes, 1);
1447 } else {
1448 Engine_MessageShowCentered(MsgFuchinEyelessDragon, 1);
1450 gEventWork->unk172 = 1;
1451 }
1452 }
1454}
1455
1456/// Restores the dark cave lighting when Reveal expires.
1457static void Fuchin_EndRevealLighting(void) {
1458 struct BattleFxScene *scene;
1459 struct DisplayTransitionState *transition;
1460
1461 if (gGameState.entrance <= 6) {
1462 scene = *(gWorkSlot + 56);
1463 transition = *(gWorkSlot + 31);
1464 scene->childOption = 1;
1465 transition->nextMode = 0;
1466 transition->duration = 1;
1467 transition->step = 1;
1469 Engine_ColorBufferApplyTarget(0x203108, 1);
1471 Engine_TaskWait(16);
1472 }
1473}
1474
1475/// Turns the sliding actor gradually toward the held direction.
1477 struct FieldActor *actor = &object->actor;
1478 s32 timer;
1479 s32 direction;
1480 u16 facing;
1481
1482 timer = actor->timer;
1483 if (timer != 0) {
1484 actor->timer--;
1485 return;
1486 }
1487 actor->steeringFlags = 0;
1488 direction = gImilFuchinFalls_KeyHeadings[(gKeysHeld >> 4) & 15];
1489 if (direction == -1) {
1490 Object_SetMode(actor, 9);
1491 return;
1492 }
1493 facing = actor->facing;
1494 direction = (s16)(direction - facing);
1495 if (direction > 0x1000)
1496 direction = 0x1000;
1497 if (direction < -0x1000)
1498 direction = -0x1000;
1499 actor->facing = facing + direction;
1500 Object_SetMode(actor, 2);
1503}
1504
1505/// Slides along the ice until terrain or a collision boundary ends the move.
1506static void Imil_SlideActorAcrossIce(void) {
1507 struct FieldActor *actor;
1508 struct FieldPosition probe;
1509 s32 heading;
1510 s32 startCollision;
1511 s32 nextCollision;
1512 s32 z;
1513 s32 x;
1514
1516
1517 for (;;) {
1518 heading = gImilFuchinFalls_SlideHeadings[(gKeysHeld >> 4) & 15];
1519 if (((u32)heading << 16) == 0xffff0000) {
1520 return;
1521 }
1522
1524
1525 // Start at the cell center and reject a blocked or raised next cell.
1526 probe.x = (actor->x.fixed & 0xfff00000) + PIXELS(8);
1527 probe.y = actor->y.fixed;
1528 probe.z = (actor->z.fixed & 0xfff00000) + PIXELS(8);
1529 z = probe.z;
1530 x = probe.x;
1531 startCollision = GetMapCellCollision(actor->terrainId, x, z);
1532 FieldVector_AddPolarOffset(PIXELS(16), heading, &probe);
1533
1534 nextCollision = GetMapCellCollision(actor->terrainId, probe.x, probe.z);
1535 if (nextCollision == 255 ||
1536 Map_GetTerrainHeight(actor->terrainId, probe.x, probe.z) -
1537 actor->y.fixed >
1538 PIXELS(8)) {
1539 actor->facing = heading;
1540 goto tail;
1541 }
1542
1543 probe.x = x;
1544 probe.z = z;
1545 actor->speed = PIXELS(2);
1546 actor->acceleration = PIXELS(1) / 10;
1547 actor->timer = 0;
1548 Engine_ObjectSetPosition(actor, x, actor->y.fixed, z);
1549
1550 Object_SetMode(actor, 2);
1554 actor->update = Imil_TurnSkaterTowardHeldDirection;
1555
1556 // Keep sliding through cells with the same collision kind.
1557 for (;;) {
1558 FieldVector_AddPolarOffset(PIXELS(16), heading, &probe);
1559 nextCollision = GetMapCellCollision(actor->terrainId, probe.x, probe.z);
1560 if (nextCollision == 255) {
1561 break;
1562 }
1563 if (Map_GetTerrainHeight(actor->terrainId, probe.x, probe.z) -
1564 actor->y.fixed >
1565 PIXELS(8)) {
1566 break;
1567 }
1568 x = probe.x;
1569 z = probe.z;
1570 actor->speed = PIXELS(2);
1571 actor->acceleration = PIXELS(1) / 10;
1572 Engine_ObjectSetPosition(actor, probe.x, probe.y, probe.z);
1574 if (nextCollision != startCollision) {
1575 goto blocked;
1576 }
1577 }
1578
1579 actor->speed = PIXELS(2);
1580 actor->acceleration = PIXELS(1);
1581 Engine_ObjectSetPosition(actor, x, actor->y.fixed, z);
1583 Engine_TaskWait(2);
1584 }
1585
1586blocked:
1587 // A collision-kind change ends the slide and restores normal steering.
1588 actor->update = NULL;
1590
1591 actor->acceleration = PIXELS(1) / 4;
1592
1593tail:
1594 Engine_TaskWait(10);
1596}
1597
1602};
1603
1604// clang-format off
1608 0xffff, FACING_EAST, FACING_WEST, 0xffff, FACING_NORTH, 0xffff, 0xffff, FACING_NORTH,
1609 FACING_SOUTH, 0xffff, 0xffff, FACING_SOUTH, 0xffff, FACING_EAST, FACING_WEST, 0xffff,
1610};
1611
1616};
1617
1619
1621 { 0, CONDITION_ALWAYS, 256, 0, 600, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1622 { SCENE_TABLE_END },
1623};
1624
1626 { 0, CONDITION_ALWAYS, 172, 0, 149, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1627 { 1, CONDITION_ALWAYS, 264, 0, 289, FACING_NORTH, 0, 135, 62, 376, 328, 0 },
1628 { SCENE_TABLE_END },
1629};
1630
1632 { 0, CONDITION_ALWAYS, 248, 0, 600, FACING_SOUTH, 0, 64, 64, 416, 656, 0 },
1633 { 1, CONDITION_ALWAYS, 248, 0, 632, FACING_NORTH, 0, 64, 368, 416, 656, 0 },
1634 { 2, CONDITION_ALWAYS, 376, 0, 488, FACING_SOUTH, 0, 64, 368, 416, 656, 0 },
1635 { 3, CONDITION_ALWAYS, 120, 0, 488, FACING_SOUTH, 0, 64, 368, 416, 656, 0 },
1636 { 4, CONDITION_ALWAYS, 232, 0, 408, FACING_SOUTH, 0, 64, 368, 416, 656, 0 },
1637 { 5, CONDITION_ALWAYS, 232, 0, 344, FACING_NORTH, 0, 64, 48, 416, 376, 0 },
1638 { 6, CONDITION_ALWAYS, 376, 0, 152, FACING_NORTH, 0, 64, 48, 416, 376, 0 },
1639 { 7, CONDITION_ALWAYS, 120, 0, 200, FACING_SOUTH, 0, 64, 48, 416, 376, 0 },
1640 { 8, CONDITION_ALWAYS, 248, 0, 104, FACING_SOUTH, 0, 64, 48, 416, 376, 0 },
1641 { SCENE_TABLE_END },
1642};
1643
1645 { 1, CONDITION_ALWAYS, 248, 0, 120, FACING_SOUTH, 0, 96, 64, 416, 480, 0 },
1646 { 2, CONDITION_ALWAYS, 152, 0, 200, FACING_NORTH, 0, 96, 64, 416, 480, 0 },
1647 { SCENE_TABLE_END },
1648};
1649
1651 { 1, CONDITION_ALWAYS, 248, 0, 104, FACING_SOUTH, 0, 128, 64, 368, 256, 0 },
1652 { 2, CONDITION_ALWAYS, 184, 0, 328, FACING_SOUTH, 0, 96, 256, 416, 656, 0 },
1653 { 3, CONDITION_ALWAYS, 152, 0, 432, FACING_SOUTH, 0, 96, 256, 416, 656, 0 },
1654 { 4, CONDITION_ALWAYS, 184, 0, 552, FACING_SOUTH, 0, 96, 256, 416, 656, 0 },
1655 { 5, CONDITION_ALWAYS, 280, 0, 616, FACING_NORTH, 0, 96, 256, 416, 656, 0 },
1656 { SCENE_TABLE_END },
1657};
1658
1660 { 1, CONDITION_ALWAYS, 328, 0, 72, FACING_SOUTH, 0, 64, 16, 416, 416, 0 },
1661 { 2, CONDITION_ALWAYS, 248, 0, 392, FACING_NORTH, 0, 64, 16, 416, 416, 0 },
1662 { 3, CONDITION_ALWAYS, 248, 0, 472, FACING_SOUTH, 0, 64, 416, 416, 800, 0 },
1663 { 4, CONDITION_ALWAYS, 344, 0, 632, FACING_NORTH, 0, 64, 416, 416, 800, 0 },
1664 { SCENE_TABLE_END },
1665};
1666
1668 { 1, CONDITION_ALWAYS, 264, 0, 232, FACING_NORTH, 0, 128, 16, 384, 256, 0 },
1669 { 2, CONDITION_ALWAYS, 248, 0, 472, FACING_SOUTH, 0, 64, 256, 416, 720, 0 },
1670 { 3, CONDITION_ALWAYS, 216, 0, 664, FACING_NORTH, 0, 64, 256, 416, 720, 0 },
1671 { 4, CONDITION_ALWAYS, 280, 0, 664, FACING_NORTH, 0, 64, 256, 416, 720, 0 },
1672 { SCENE_TABLE_END },
1673};
1674
1676 { 1, CONDITION_ALWAYS, 280, 0, 120, FACING_SOUTH, 0, 64, 0, 416, 344, 0 },
1677 { 2, CONDITION_ALWAYS, 216, 0, 120, FACING_SOUTH, 0, 64, 0, 416, 344, 0 },
1678 { 3, CONDITION_ALWAYS, 104, 0, 280, FACING_SOUTH, 0, 64, 0, 416, 344, 0 },
1679 { 4, CONDITION_ALWAYS, 200, 0, 344, FACING_NORTH, 0, 64, 16, 416, 344, 0 },
1680 { 5, CONDITION_ALWAYS, 248, 0, 312, FACING_NORTH, 0, 64, 16, 416, 344, 0 },
1681 { 6, CONDITION_ALWAYS, 296, 0, 344, FACING_NORTH, 0, 64, 16, 416, 344, 0 },
1682 { 7, CONDITION_ALWAYS, 200, 0, 440, FACING_SOUTH, 0, 32, 344, 432, 736, 0 },
1683 { 8, CONDITION_ALWAYS, 248, 0, 440, FACING_SOUTH, 0, 32, 344, 432, 736, 0 },
1684 { 9, CONDITION_ALWAYS, 296, 0, 424, FACING_SOUTH, 0, 32, 344, 432, 736, 0 },
1685 { 10, CONDITION_ALWAYS, 376, 0, 472, FACING_SOUTH, 0, 32, 344, 432, 736, 0 },
1686 { 11, CONDITION_ALWAYS, 248, 0, 536, FACING_NORTH, 0, 32, 344, 432, 736, 0 },
1687 { 12, CONDITION_ALWAYS, 120, 0, 696, FACING_SOUTH, 0, 32, 344, 432, 752, 0 },
1688 { SCENE_TABLE_END },
1689};
1690
1692 SCENE_EXITS(52),
1693 SCENE_EXIT(1, 50, 9),
1694 SCENE_EXIT(0, 62, 0),
1695 SCENE_EXIT(1, 60, 3),
1696 SCENE_EXIT(2, 63, 2),
1697 SCENE_EXIT(3, 65, 4),
1698 SCENE_EXIT(4, 62, 5),
1699 SCENE_EXIT(5, 62, 4),
1700 SCENE_EXIT(6, 64, 4),
1701 SCENE_EXIT(7, 67, 12),
1702 SCENE_EXIT(8, 67, 11),
1703 SCENE_EXIT(0, 63, 0),
1704 SCENE_EXIT(1, 64, 5),
1705 SCENE_EXIT(2, 62, 2),
1706 SCENE_EXIT(0, 64, 0),
1707 SCENE_EXIT(1, 64, 3),
1708 SCENE_EXIT(2, 67, 10),
1709 SCENE_EXIT(3, 64, 1),
1710 SCENE_EXIT(4, 62, 6),
1711 SCENE_EXIT(5, 63, 1),
1712 SCENE_EXIT(0, 65, 0),
1713 SCENE_EXIT(1, 67, 3),
1714 SCENE_EXIT(2, 65, 3),
1715 SCENE_EXIT(3, 65, 2),
1716 SCENE_EXIT(4, 62, 3),
1717 SCENE_EXIT(0, 66, 0),
1718 SCENE_EXIT(1, 66, 2),
1719 SCENE_EXIT(2, 66, 1),
1720 SCENE_EXIT(3, 67, 2),
1721 SCENE_EXIT(4, 67, 1),
1722 SCENE_EXIT(0, 67, 0),
1723 SCENE_EXIT(1, 66, 3),
1724 SCENE_EXIT(2, 66, 4),
1725 SCENE_EXIT(3, 65, 1),
1726 SCENE_EXIT(4, 67, 7),
1727 SCENE_EXIT(5, 67, 8),
1728 SCENE_EXIT(6, 67, 9),
1729 SCENE_EXIT(7, 67, 4),
1730 SCENE_EXIT(8, 67, 5),
1731 SCENE_EXIT(9, 67, 6),
1732 SCENE_EXIT(10, 64, 2),
1733 SCENE_EXIT(11, 62, 8),
1734 SCENE_EXIT(12, 62, 7),
1736};
1737
1739 { SCENE_TABLE_END },
1740};
1741
1743 { 0x5c, 0x59, ACTOR_STAND,
1744 PIXELS(263), 0, PIXELS(204), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1745 { SCENE_TABLE_END },
1746};
1747
1749 { 0xed, CONDITION_ALWAYS, 7,
1750 PIXELS(136), 0, PIXELS(504), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1751 { 0xec, CONDITION_ALWAYS, 7,
1752 PIXELS(200), 0, PIXELS(536), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1753 { 0xec, CONDITION_ALWAYS, 7,
1754 PIXELS(296), 0, PIXELS(536), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1755 { SCENE_TABLE_END },
1756};
1757
1759 { 0xed, CONDITION_ALWAYS, 7,
1760 PIXELS(216), 0, PIXELS(328), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1761 { 0xec, CONDITION_ALWAYS, 7,
1762 PIXELS(248), 0, PIXELS(280), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1763 { 0xec, CONDITION_ALWAYS, 7,
1764 PIXELS(312), 0, PIXELS(408), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1765 { 0x5d, 0x6e, ACTOR_STAND,
1766 PIXELS(344), 0, PIXELS(280), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1767 { SCENE_TABLE_END },
1768};
1769
1771 { 0xed, CONDITION_ALWAYS, 7,
1772 PIXELS(328), 0, PIXELS(408), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1773 { 0xed, CONDITION_ALWAYS, 7,
1774 PIXELS(248), 0, PIXELS(568), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1775 { 0xec, CONDITION_ALWAYS, 7,
1776 PIXELS(248), 0, PIXELS(488), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1777 { 0xec, CONDITION_ALWAYS, 7,
1778 PIXELS(248), 0, PIXELS(504), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1779 { SCENE_TABLE_END },
1780};
1781
1783 { 0xec, CONDITION_ALWAYS, 7,
1784 PIXELS(328), 0, PIXELS(168), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1785 { 0xed, CONDITION_ALWAYS, 7,
1786 PIXELS(360), 0, PIXELS(264), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1787 { 0xed, CONDITION_ALWAYS, 7,
1788 PIXELS(120), 0, PIXELS(744), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1789 { SCENE_TABLE_END },
1790};
1791
1793 { 0xdf, CONDITION_ALWAYS, 7,
1794 PIXELS(312), 0, PIXELS(128), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1795 { SCENE_TABLE_END },
1796};
1797
1799 { SCENE_EVENTS_END },
1800};
1801
1806 { SCENE_EVENTS_END },
1807};
1808
1822 { EVENT_EXIT, 21, CONDITION_ALWAYS, 1 },
1823 { EVENT_EXIT, 22, CONDITION_ALWAYS, 2 },
1824 { EVENT_EXIT, 23, CONDITION_ALWAYS, 3 },
1825 { EVENT_EXIT, 24, CONDITION_ALWAYS, 4 },
1826 { EVENT_EXIT, 25, CONDITION_ALWAYS, 5 },
1827 { EVENT_EXIT, 26, CONDITION_ALWAYS, 6 },
1828 { 0x21, 27, CONDITION_ALWAYS, 7 },
1829 { EVENT_EXIT, 28, CONDITION_ALWAYS, 8 },
1831 { SEARCH(SEARCH_CHEST), 100, 0xef1, 0x500001 },
1832 { SCENE_EVENTS_END },
1833};
1834
1854 { EVENT_EXIT, 1, CONDITION_ALWAYS, 1 },
1855 { EVENT_EXIT, 2, CONDITION_ALWAYS, 2 },
1857 { SCENE_EVENTS_END },
1858};
1859
1901 { 0x21, 1, CONDITION_ALWAYS, 1 },
1902 { 0x21, 2, CONDITION_ALWAYS, 2 },
1903 { 0x31, 3, CONDITION_ALWAYS, 3 },
1904 { EVENT_EXIT, 4, CONDITION_ALWAYS, 4 },
1905 { EVENT_EXIT, 5, CONDITION_ALWAYS, 5 },
1907 { SCENE_EVENTS_END },
1908};
1909// clang-format on
1910
1920 {TOUCH_WALKING_INTO(FACING_WEST), 13, 0x313,
1936 {0x21, 1, CONDITION_ALWAYS, 1},
1942};
1943
1954};
1955
1959 {0x31, 3, CONDITION_ALWAYS, 3},
1966 {0x31, 10, CONDITION_ALWAYS, 10},
1967 {EVENT_EXIT, 11, CONDITION_ALWAYS, 11},
1968 {0x31, 12, CONDITION_ALWAYS, 12},
1982};
1983
1986 SC_WAIT(1), SC_POS(0, 0, 0), SC_WAIT(1),
1987 SC_FREE,
1988};
1989
1992 SC_WAIT(1), SC_POS(0, 0, 0), SC_WAIT(1),
1993 SC_FREE,
1994};
1995
1998 SC_WAIT(1), SC_POS(0, 0, 0), SC_WAIT(1),
1999 SC_FREE,
2000};
Ability numbers, named from the English release.
@ ABILITY_REVEAL
Definition ability_ids.h:19
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.
Which units are in a battle, and the Djinn recovery list.
@ ELEMENT_MARS
Definition battle_unit.h:38
Calls through a function pointer, by argument count.
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
struct FieldActor * Engine_ObjectCreate(s32, s32, s32, s32)
The engine calls the debug menus import, and their palette swatch tiles.
The display transition's frames, windows and state.
Djinn numbers, named from the English release.
@ DJINNI_ZEPHYR
Definition djinn_ids.h:34
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
void BattleFx_StartFadeOverlay(void *object)
Starts the fade overlay on object (the party leader when NULL): loads its solid tiles,...
void ObjectDispatch_SetAnimationSpeed(struct DispatchObject *rawObject, s32 value)
Sets the animation speed (timer step) of all of an object's sprites.
Definition objects.c:370
Field effects, their scripts and the flags that spawn them.
@ EFFECT_USE_PALETTE
options.palette, as its group child value
@ EFFECT_SCRIPT_MASK
Picks one of gEffectScripts; the object's mode is this plus 1.
@ EFFECT_USE_START_SCALE
options.startScaleX and startScaleY
@ EFFECT_SCALE_TO_TARGET
Grows from the start scale, or full size, to the target scale over the script's repeat count.
@ 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,...
void Engine_ObjectSetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
struct FieldActor * Engine_ActorLookup(s32 actor)
void Engine_MessageShowCentered(s32 message, s32 flags)
s32 Engine_PartyGiveItem(s32 item, s32 flags)
#define GameFlag_IsSet
s32 Engine_TaskRemoveCallback(void(*callback)(void))
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
void Engine_ItemLoadIcon(s32 item)
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_EventCloseScreen(void)
void Engine_ObjectDispatchRelease(struct FieldActor *object)
static void Map_CopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
void Engine_HeapRelease(s32 slot)
static void ColorBuffer_ApplyTarget(s32 value, s32 mode)
s32 Engine_VramLoad(s32 block, s32 size, const void *data)
void Engine_EventWaitForScreen(void)
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_GameFlagClear(s32 flag)
void Engine_ActorWaitForMove(s32 actor)
void * Engine_HeapAllocate(s32 slot, s32 size)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
s32 Engine_RandomNext()
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_RunRisingObjectSequence(struct FieldActor *object, s32 mode)
static struct FieldActor * Object_Create(s32 type, s32 fixed_x, s32 fixed_y, s32 fixed_z)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
@ TASK_PRIORITY_SCENE
Definition field_event.h:40
void Engine_ColorBufferInterpolate(s32 frames)
void Engine_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ColorBufferApplyTarget(s32 value, s32 mode)
void Engine_ColorBufferApplySource(s32 value, s32 mode)
static struct FieldActor * Actor_Get(s32 actor)
static void ColorBuffer_ApplySource(s32 value, s32 mode)
@ TRANSITION_WINDOW
Definition field_obj.h:17
@ 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
@ ACTOR_PRIORITY_AUTOMATIC
The sprite takes its priority from the map cell under it.
Definition field_obj.h:153
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
@ ACTOR_FACES_MOTION
turns toward its velocity, 1/16 turn a frame
Definition field_obj.h:166
The field's runtime work: map cells, scene records and regions, map markers and FieldWork.
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_EXIT
@ EVENT_TALK
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define PSYNERGY_IN_AREA(ability, phase)
#define IF_FLAG_SET(flag)
Definition field_scene.h:48
#define USE_ITEM(item)
#define SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
#define EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
@ FACING_NORTHEAST
Definition field_scene.h:33
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTHWEST
Definition field_scene.h:29
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_UNNAMED
@ SEARCH_CHEST
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static void FieldVector_AddPolarOffset(s32 radius, s32 heading, struct FieldPosition *probe)
16.16 fixed-point constants, sine and cosine, and the library division.
#define Q16_ONE
One in the engine's signed 16.16 fixed-point format.
Definition fixed_math.h:10
Game flags, named where their meaning is shown.
#define FLAG_FUCHIN_FALLS_DRAGONS_EYE_SET
The Dragon's Eye is set in the dragon statue, which opened the hidden path.
Definition flags.h:243
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_FUCHIN_FALLS_ORB_OF_FORCE_FOUND
The Orb of Force's chest in Fuchin Falls has been opened.
Definition flags.h:618
volatile u32 gFrameCount
Frames WaitFrames has finished.
BattleFxScene, the work of a battle or field Psynergy effect scene, and its arc objects.
GameState, the game's state: play time, coins, the scene and the leader's position,...
struct GameState gGameState
Font glyphs and their palettes.
The screen blend's globals and the graphics routines.
struct ScenePlacement gImilFuchinFalls_ThirdRoomPlacements[]
static void Fuchin_HopWest(void)
Hops the leader one gap west.
static void Fuchin_ThirdRoom_MoveFourthPlatformNorth(void)
struct SceneEvent gImilFuchinFalls_ThirdRoomEvents[]
static void Fuchin_FourthRoom_MoveFirstPlatformNorth(void)
s32 gImilFuchinFalls_TrackLeader
static void Fuchin_ThirdRoom_MoveFirstPlatformWestIfClear(void)
static void Fuchin_EndRevealLighting(void)
Restores the dark cave lighting when Reveal expires.
static void Fuchin_FirstRoom_MoveSecondPlatformNorth(void)
s16 gImilFuchinFalls_KeyHeadings[]
static void Fuchin_SecondRoom_MoveThirdPlatformNorth(void)
struct ScenePlacement gImilFuchinFalls_DragonRoomPlacements[]
static void Fuchin_ReadDragonFlameInscription(void)
Reads the inscription describing the dragon flame.
struct ScenePlacement gImilFuchinFalls_DjinniRoomPlacements[]
static void Fuchin_ThirdRoom_MoveSecondPlatformWest(void)
static struct FieldActor * Fuchin_CreateForegroundActor(s32 x, s32 y, s32 z, s32 resourceId)
Creates a stationary foreground actor with its palette and priority set.
struct SceneEntrance gImilFuchinFalls_DjinniRoomEntrances[]
struct SceneEntrance gImilFuchinFalls_ThirdRoomEntrances[]
static void Fuchin_FourthRoom_MoveThirdPlatformEast(void)
static void Fuchin_RebuildFourthRoomPlatforms(void)
Restores both halves of the fourth puzzle room from its saved platform stops.
static void Fuchin_FourthRoom_MoveFirstPlatformSouth(void)
static void Imil_LeaveDjinnRoom(void)
Faces the leader south and leaves the Imil Djinn room.
static void Fuchin_FinishPlatformMove(void(*rebuildPlatforms)(void))
Lets the platform settle before rebuilding its room's collision cells.
struct SceneEntrance gImilFuchinFalls_SecondRoomEntrances[]
static void ImilFuchinFalls_PrepareRoom(void)
Restores room props and the cave light for this entrance.
static void Fuchin_FirstRoom_MoveThirdPlatformNorth(void)
static void Fuchin_ThirdRoom_MoveThirdPlatformNorthFromSouthEnd(void)
struct ScenePlacement gImilFuchinFalls_FourthRoomPlacements[]
struct SceneEntrance gImilFuchinFalls_FourthRoomEntrances[]
static void Fuchin_ThirdRoom_NudgeThirdPlatformNorth(void)
struct ScenePlacement gImilFuchinFalls_SecondRoomPlacements[]
static void Fuchin_ThirdRoom_MoveThirdPlatformSouthFromLowerStop(void)
s32 * gImilFuchinFalls_DustScripts[]
s16 gImilFuchinFalls_SlideHeadings[]
static void Fuchin_StartDjinnBattle(void)
Talking to the Djinni in the second platform room starts its battle.
static void Imil_MoveAcrossIce(void)
Starts sliding the selected actor in the held direction.
s32 gImilFuchinFalls_DustScript2[]
static void Fuchin_FourthRoom_MoveThirdPlatformWest(void)
static void Fuchin_AnimateThirdPlatform(void)
Advances the third platform through its two rolling animations.
struct SceneEvent gImilFuchinFalls_KiRoomEvents[]
struct SceneEntrance gImilFuchinFalls_DragonRoomEntrances[]
static void Fuchin_SecondRoom_NudgeFirstPlatformWest(void)
static void ImilFuchinFalls_HopOnTrigger(void)
Hops across a platform edge when its current stop permits it.
static void Fuchin_RebuildFirstRoomPlatforms(void)
Restores platform positions and collision cells in the first puzzle room.
static void Fuchin_SecondRoom_MoveFirstPlatformToWestEnd(void)
static void ImilFuchinFalls_RebuildPlatformRoom(void)
Restores the collision templates for the current platform room.
static void Fuchin_ThirdRoom_MoveFirstPlatformEastFromMiddle(void)
static void Fuchin_PlacePlatformAtCell(s32 id, s32 column, s32 row)
Centers a platform on its cell and gives it underfoot priority.
struct SceneEvent gImilFuchinFalls_DragonRoomEvents[]
static void Fuchin_SecondRoom_MoveFirstPlatformToEastEnd(void)
static void Fuchin_FirstRoom_MoveSecondPlatformSouth(void)
static void Fuchin_UpdateDustMotion(union FieldObject *raw)
Applies the dust velocity and scale change for one frame.
static void Fuchin_SearchDragonStatue(void)
Describes the dragon eyes or offers to insert the carried eye.
static void Imil_RecruitDjinni(void)
Talking to the Djinni in the ice room adds it to the party.
static void Fuchin_ReadShadowInscription(void)
Reads the inscription about light revealing shadows.
u32 gImilFuchinFalls_Exits[]
static void Fuchin_AnimateFourthPlatform(void)
Advances the fourth platform through its two rolling animations.
static void ImilFuchinFalls_BlowCaveMouthDust(void)
Emits cave-mouth dust every fourth frame while the dragon awakens.
static void Fuchin_ClearFourthPlatformStops(void)
Clears all saved intermediate stops for the fourth platform.
struct SceneEntrance gImilFuchinFalls_NoEntrances[]
static void Fuchin_ThirdRoom_MoveFourthPlatformSouthFromNorthEnd(void)
struct SceneEvent gImilFuchinFalls_SecondRoomEvents[]
struct SceneEvent gImilFuchinFalls_DjinniRoomEvents[]
const struct SceneEntrance * ImilFuchinFalls_GetEntrances(void)
static void Fuchin_StopLightFollowingLeader(void)
Detaches the active cave light from the party leader.
static void Fuchin_ThirdRoom_MoveFourthPlatformSouthFromLastStop(void)
static void Fuchin_ThirdRoom_MoveThirdPlatformSouthFromMiddle(void)
static void Fuchin_ReadKiInscription(void)
Reads the inscription about the secret power of Ki.
s32 gImilFuchinFalls_DustScript1[]
static void Fuchin_SecondRoom_MoveThirdPlatformSouth(void)
s32 ImilFuchinFalls_Initialize(void)
Entering the Djinni's ice room the first time, the leader walks toward the Djinni; otherwise each roo...
struct SceneEvent gImilFuchinFalls_NoEvents[]
static void Fuchin_RebuildThirdRoomPlatforms(void)
Restores the interacting platform stops and collision cells in the third room.
static void Fuchin_SecondRoom_MoveFirstPlatformEast(void)
static void Fuchin_ThirdRoom_MoveFirstPlatformWest(void)
struct FieldActor * gImilFuchinFalls_DragonsEye
const struct ScenePlacement * ImilFuchinFalls_GetPlacements(void)
static void Fuchin_FourthRoom_MoveSecondPlatformEast(void)
static void Fuchin_SecondRoom_MoveSecondPlatformSouth(void)
static void Fuchin_ThirdRoom_MoveThirdPlatformNorthFromMiddle(void)
static void Fuchin_RebuildSecondRoomPlatforms(void)
Restores platform positions and collision cells in the second puzzle room.
struct SceneEvent gImilFuchinFalls_FirstRoomEvents[]
static void Imil_TurnSkaterTowardHeldDirection(union FieldObject *object)
Turns the sliding actor gradually toward the held direction.
static void Imil_SlideActorAcrossIce(void)
Slides along the ice until terrain or a collision boundary ends the move.
static s32 Fuchin_SetDustPalette(struct ScriptInterpreter *interpreter)
Selects the dust palette when its object script finishes looping.
s32 gImilFuchinFalls_DustScript0[]
static void Fuchin_ThirdRoom_MoveThirdPlatformSouthFromNorthEnd(void)
void ImilFuchinFalls_SpawnDust(s32 x, s32 y, s32 z, s32 velocityX, s32 velocityY, s32 velocityZ, u32 flags, const struct EffectOptions *extra)
Creates scripted cave dust with the requested velocity, palette and scale.
static void Fuchin_ThirdRoom_NudgeFourthPlatformNorth(void)
static void Fuchin_ThirdRoom_MoveFirstPlatformEastFromWestEnd(void)
static void Fuchin_FourthRoom_MoveSecondPlatformWest(void)
static void ImilFuchinFalls_HopBy(s32 dx, s32 dz)
Jumps the leader by a pixel offset while using the hopping animations.
static void Fuchin_HopNorth(void)
Hops the leader one gap north.
const u32 * ImilFuchinFalls_GetExits(void)
Returns the exit connections shared by these rooms.
static void ImilFuchinFalls_PlaceDragonsEye(void)
Creates the collectible eye and uploads its item icon.
struct SceneEvent gImilFuchinFalls_FourthRoomEvents[]
static void Fuchin_FirstRoom_MoveFirstPlatformWest(void)
static void Fuchin_ThirdRoom_MoveFourthPlatformSouthFromMiddle(void)
struct SceneEntrance gImilFuchinFalls_FirstRoomEntrances[]
static void Fuchin_ThirdRoom_MoveFourthPlatformSouthFromLowerStop(void)
static void Fuchin_LightDragonWithEye(void)
Inserts the eye, lights the dragon room and reveals its hidden path.
struct ScenePlacement gImilFuchinFalls_FirstRoomPlacements[]
static void Imil_WalkTowardDjinni(void)
Shows the Imil Djinni and walks the leader toward it.
const struct SceneRegion * ImilFuchinFalls_GetRegions(void)
static void Fuchin_ThirdRoom_MoveSecondPlatformEast(void)
static void Fuchin_CollectDragonsEye(void)
Gives the eye to the party and removes its displayed actor.
static void Fuchin_ThirdRoom_MoveThirdPlatformSouthFromUpperStop(void)
static void Fuchin_ThirdRoom_MoveFourthPlatformSouthFromUpperStop(void)
static void Fuchin_SecondRoom_MoveSecondPlatformNorth(void)
struct SceneEntrance gImilFuchinFalls_KiRoomEntrances[]
static void Fuchin_FirstRoom_MoveThirdPlatformSouth(void)
static void Fuchin_ThirdRoom_MoveThirdPlatformNorthFromLowerStop(void)
const struct SceneEvent * ImilFuchinFalls_GetEvents(void)
static void Fuchin_AnimateFirstPlatform(void)
Advances the first platform through its two rolling animations.
ImilFuchinFallsActor
@ ACTOR_FOURTH_PLATFORM
@ ACTOR_FUCHIN_DJINNI
in the second platform room
@ ACTOR_SECOND_PLATFORM
@ ACTOR_THIRD_PLATFORM
@ ACTOR_FIRST_PLATFORM
The platforms, in each platform room.
@ ACTOR_IMIL_DJINNI
in the ice room
static void Fuchin_FirstRoom_MoveFirstPlatformEast(void)
static void Fuchin_FollowLeaderWithLight(void)
Attaches the active cave light to the party leader.
@ IMIL_SLIDE_ANIMATION_STEP
three times normal animation speed
static void Fuchin_AnimateSecondPlatform(void)
Advances the second platform through its two rolling animations.
struct ScenePlacement gImilFuchinFalls_NoPlacements[]
The main-image routines scene overlays import.
s32 PartyInventory_Discard(s32 itemId)
Discards one itemId from whoever carries it first, as Inventory_Discard does; always returns 0.
Definition inventory.c:422
s32 PartyInventory_FindOwner(s32 itemId)
Returns who carries itemId, asking the selected character first, or -1.
Definition inventory.c:229
Item numbers, named from the English release.
@ ITEM_DRAGONS_EYE
Definition item_ids.h:71
@ ITEM_ORB_OF_FORCE
Definition item_ids.h:56
@ ITEM_ARCTIC_BLADE
Definition item_ids.h:10
The keypad state the VBlank interrupt keeps.
volatile u32 gKeysHeld
Keys down now.
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#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_WAIT(n)
Wait n frames.
Definition objcmd.h:16
#define SC_TOP
Script start.
Definition objcmd.h:13
#define SC_CALL(fn)
Definition objcmd.h:50
void Battle_ResetEffectCounter(void)
Clears the field's busy flag and, while Reveal is active, ends it: Reveal used with ACT_PACKED runs i...
Definition targets.c:261
The fade overlay, the weather particles and the actor effect work.
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
static void SceneActor_PlacePairAtOffset(s32 id, s32 dx, s32 dz)
Moves the character the player controls (in mode 27) and actor id together by (dx,...
Palette fades, the battle effect palette buffers and the colour channel curves.
@ PALETTE_TRANSFORM_PLAIN
each colour unchanged
Definition palbuf.h:72
void Field_RequestDjinnBattle(s32 flag, s32 no)
Sets up the battle with Djinni number no.
Definition requests.c:35
void Audio_PlayCueFromEventWork(void)
Starts the current scene's field music, chosen by Scene_ResolveInteractionResult.
Definition scene.c:355
FIELD_AT_OFFSET and the entity and camera views older scene code reads.
Scene numbers, named after their places.
char SceneId_ImilFuchinFalls4
char SceneId_ImilFuchinFalls7
char SceneId_ImilFuchinFalls3
char SceneId_ImilFuchinFalls6
char SceneId_ImilFuchinFalls5
char SceneId_ImilFuchinFalls2
char SceneId_ImilFuchinFalls1
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_136
Definition songs.h:129
#define SE_MAP_EXIT
Definition songs.h:116
#define SE_241
Definition songs.h:236
#define SE_182
Definition songs.h:177
#define MUS_019
Definition songs.h:29
#define SE_289
Definition songs.h:282
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
void * gWorkSlot[]
#define STATIC_ASSERT(condition)
C89 permits repeated extern declarations of the same array.
#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
struct AnimationSpritePart image
Definition animspr.h:109
u8 flags
bits: 1 outlined in ObjectSystemWork's edge and fill colours | 0 shadow drawn (set when created)
Definition animspr.h:128
u8 slot
VRAM cache entry holding its tiles.
Definition animspr.h:112
u8 count
layers in use, up to the last one present
Definition animspr.h:129
u16 fullColor
256 colours; set for both parts when created
Definition animspr.h:94
u16 priority
2 when created
Definition animspr.h:100
The work of a Psynergy effect scene: its caster and target, where it takes place, the map state it re...
Definition fx_scene.h:31
s8 childOption
Set by some scenes before an effect; Carry, Frost, Force and Reveal treat the target differently with...
Definition fx_scene.h:52
EffectOptions cut after its scales: the caller's frame holds only these 24 bytes.
The three action scripts cave dust can run, chosen by its spawn flags.
const s32 * script[3]
A field object as the object dispatcher's far calls take it.
The display transition state (heap block 31): two pages of window edges for every line,...
s8 nextMode
The mode taken when the value reaches its end; 0 ends the transition.
s8 duration
frames; 0 when the value is not moving
The options of a spawned field effect, each used when its EFFECT_USE_ flag (or EFFECT_SCALE_TO_TARGET...
s32 targetScaleY
16.16 fixed point, 0x10000 full size
s32 targetScaleX
16.16 fixed point, 0x10000 full size
s32 palette
passed to ObjectGroup_SetChildValue
s32 startScaleY
16.16 fixed point, 0x10000 full size
s32 priority
the sprite's priority
s32 startScaleX
16.16 fixed point, 0x10000 full size
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
s16 touchedTrigger
the step event a touch or exit event answers
Definition event_work.h:26
u16 unk172
FieldWork's menu request; scenes set it to 1.
Definition event_work.h:29
The fade overlay draws one mark on each side of its tracked actor.
struct FieldActor * actor
the actor tracked; null draws nothing
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
u8 steeringFlags
ActorSteeringFlag bits.
Definition field_obj.h:92
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
u8 retainSpriteCache
Nonzero keeps its sprite's VRAM cache entry while sprites are suspended or it is off screen (ObjectSy...
Definition field_obj.h:96
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
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
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
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
s32 velocityZ
16.16 fixed-point pixels per frame
Definition field_obj.h:54
u8 terrainId
The map layer (0 to 3) its ground height is read from, which the scrolling camera updates from the ce...
Definition field_obj.h:47
A field effect: a small object on the field that moves at its velocity and grows and spins at its rat...
void(*) update(union FieldObject *object)
Called each frame while the effect is live: the spawner sets BattleFx_UpdateObjectMotionScaleAndLinke...
struct Vector3 velocity
Added to x, y and z each frame by the update hooks, in 16.16 fixed-point pixels per frame; FieldActor...
s32 z
16.16 fixed-point pixels
struct AnimationObject * sprite
the sprite spin turns
u8 priorityFlags
ActorPriorityFlag bits: the spawner clears ACTOR_PRIORITY_AUTOMATIC when EFFECT_USE_PRIORITY sets the...
s32 scaleRateX
Added to scaleX each frame by the update hooks, in 16.16 fixed point a frame; zeroed by the spawner.
u8 motionFlags
ActorMotionFlag bits; zeroed by the spawner.
s32 scaleY
16.16 fixed point, 0x10000 full size
s32 scaleX
16.16 fixed point, 0x10000 full size
s32 y
16.16 fixed-point pixels
s32 x
16.16 fixed-point pixels
s32 scaleRateY
as scaleRateX, for scaleY
A position on the field.
s32 z
16.16 fixed-point pixels
s16 entrance
Definition game_state.h:37
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
u8 tiles[0x200]
Definition glyph.h:40
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
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.
s32 GetMapCellCollision(s32 layer, s32 x, s32 y)
Returns the collision code of a layer's cell at (x, y) in 16.16 pixels.
Definition terrain.c:401
s32 Map_GetTerrainHeight(s32 layer, s32 x, s32 y)
Returns the ground height of a layer at (x, y) in 16.16 pixels: the height function of the cell's ter...
Definition terrain.c:343
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldEffect effect