Alchemy
Loading...
Searching...
No Matches

venus_lighthouse_aerie.c

Go to the documentation of this file.
1/// @file
2/// Venus Lighthouse's aerie: the pillars the leader jumps between, the Shaman's
3/// Rod handed over for Sheba, and the battle with Saturos and Menardi, who
4/// fuse.
5
6#include "script.h"
7#include "game_state.h"
8#include "vram_tab.h"
9#include "unit/import.h"
14#include "unit/object/object.h"
16#include "unit/field/field.h"
17#include "unit/game/game.h"
18#include "unit/window/window.h"
21#include "macros.h"
22
23#define NULL ((void *)0)
24#include "field_obj.h"
25#include "types.h"
26#include "animspr.h"
28#include "field_effect.h"
29#include "event.h"
30#include "field_event.h"
31#include "field_scene.h"
32#include "songs.h"
34#include "battle.h"
35#include "debug.h"
36#include "field.h"
37#include "game.h"
38#include "graphics.h"
39#include "menu.h"
40#include "minigame.h"
41#include "sound.h"
42#include "system.h"
43#include "resource.h"
44#include "iwram_call.h"
45#include "vram_block.h"
46#include "callback_scheduler.h"
47#include "call.h"
48#include "field_service.h"
49#include "b5_context.h"
50#include "text/msg_ids.h"
51#include "global_cells.h"
52#include "scene_ids.h"
53#include "staged_actor.h"
54#include "map_scroll.h"
55#include "tbs_edition.h"
56#include "io_reg.h"
57#include "window.h"
58#include "heap_state.h"
59#include "objcmd.h"
60#include "fixed_math.h"
61#include "fx_scene.h"
62#include "palbuf.h"
63#include "flags.h"
64#include "item_ids.h"
65
66// Place flags: Scene_ResetFlagsOnEnter clears 0x300 to 0x3ff when the party
67// enters another place group, and other places use the numbers for their own.
68
69/// Plus the party member (0 to 3) who carried the Shaman's Rod when it was
70/// handed over before the aerie's first battle; a defeat gives it back.
71#define FLAG_SHAMANS_ROD_OWNER 0x345
72
73static void Event_SteadyPillars(void);
75static void VenusLighthouseAerie_ShowPartyMember(s32 actor, s32 shown);
76static void VenusLighthouseAerie_FlashActorPalette(struct FieldActor *actor);
77static void
81static void VenusLighthouseAerie_FlashScreen(void);
89static void VenusLighthouseAerie_EruptBeacon(void);
93static void VenusLighthouseAerie_StopActorMotion(struct FieldActor *actor);
95static void VenusLighthouseAerie_AdvanceActorRise(struct FieldActor *actor);
97static void
99
100// The aerie's scene flags:
101// FLAG_SCENE_TEMP_34: Saturos and Menardi slide together as they fuse.
102// FLAG_SCENE_TEMP_35: they grow as they fuse.
103// FLAG_SCENE_TEMP_36: the beacon has erupted; its particles rise higher.
104// FLAG_SCENE_TEMP_37: the light has lifted the party and flashed white.
105// FLAG_SCENE_TEMP_50: the leader stands on a pillar.
106
107#include "common/effect_create.h"
108#include "common/effect_spawn.h"
109
110/// Pulses the actor scale around the countdown, then chooses its next pause.
111static s32
113 struct FieldActor *actor = (struct FieldActor *)interpreter;
114 s16 *counter = &actor->timer;
115
116 switch (*counter) {
117 case 6:
118 actor->scaleX += -Q16_ONE / 8;
119 actor->scaleY += Q16_ONE / 16;
120 break;
121 case 4:
122 actor->scaleX += Q16_ONE / 16;
123 actor->scaleY += -Q16_ONE / 32;
124 break;
125 case 2:
126 actor->scaleX += Q16_ONE / 32;
127 actor->scaleY += -Q16_ONE / 64;
128 break;
129 case 0:
130 actor->scaleX += Q16_ONE / 32;
131 actor->scaleY += -Q16_ONE / 64;
132 *counter = Math_RemainderUnsigned(Engine_RandomNext(), 80) + 80;
133 break;
134 }
135 {
136 s32 t = (u16)actor->timer;
137 t--;
138 actor->timer = t;
139 }
140 return 1;
141}
142
143/// Moves a particle, damps its horizontal velocity and updates its scale and
144/// spin.
145static void
147 s32 velocityX = object->effect.velocity.x;
149
150 object->effect.x += velocityX;
151 object->effect.y += object->effect.velocity.y;
152 velocityZ = object->effect.velocity.z;
153 object->effect.z += velocityZ;
154 object->effect.velocity.x = velocityX - velocityX / 22;
155 object->effect.velocity.z = velocityZ - velocityZ / 20;
156 object->effect.scaleX += object->effect.scaleRateX;
157 object->effect.scaleY += object->effect.scaleRateY;
158 object->effect.sprite->rotation += object->effect.spin;
159}
160
161/// Turns the falling actor sprite until its rotation leaves the negative
162/// half-turn.
163static void
165 struct FieldActor *actor = (struct FieldActor *)fieldObject;
166 struct AnimationObject *sprite = actor->sprite;
167 u16 rotation = sprite->rotation;
168
169 if ((s16)(rotation - 1) < 0) {
170 {
171 s32 nextRotation = rotation - 0xa00;
172 sprite->rotation = nextRotation;
173 }
174 }
175}
176
178
181}
182
183const struct SceneRegion *VenusLighthouseAerie_GetRegions(void) { return 0; }
184
187}
188
189/// Returns the platforms, antagonists, companions and beacon effects.
192}
193
196
197/// Walking off the edge of a pillar: if the ground two tiles ahead is clear,
198/// the leader jumps across to it.
199static void Event_JumpToNextPillar(void) {
200 struct FieldActor *actor;
201 union {
202 struct FieldPosition position;
203 s32 coordinates[3];
204 } destination;
205 s32 angle;
206 u8 flags;
207
209 angle = (actor->facing + 0x1000) & 0xe000;
210 flags = actor->motionFlags;
211 SET_VECTOR(destination.coordinates, (actor->x.fixed & 0xfff00000) + PIXELS(8),
212 actor->y.fixed, (actor->z.fixed & 0xfff00000) + PIXELS(8));
213 Vector_AddPolarOffset(PIXELS(32), angle, destination.coordinates);
214 if (FieldObject_CheckMovementCollision(actor, &destination.position) == 0) {
217 Object_SetMode(actor, 6);
219 Object_SetMode(actor, 7);
220 actor->speed = PIXELS(3);
221 actor->acceleration = PIXELS(2);
223 actor->velocityY = PIXELS(4);
224 actor->motionFlags &= 0x7e;
227 destination.coordinates[0] >> 16,
228 destination.coordinates[2] >> 16);
229 Object_SetMode(actor, 6);
231 actor->motionFlags = flags;
232 }
233}
234
235/// Landing on a pillar: it dips under the leader and springs back up.
236/// FLAG_SCENE_TEMP_50 is set while the leader stands on a pillar, so this runs
237/// once per landing.
238static void Event_LandOnPillar(void) {
240 struct FieldActor *pillar;
241 s32 pillarId;
242 s32 reboundStep;
243
247 if (pillarId != 0) {
250 pillar->motionFlags = 0;
251 leader->motionFlags &= 0xfe;
252 pillar->y.fixed += -PIXELS(3);
253 leader->y.fixed += -PIXELS(3);
254 leader->terrainHeight += -PIXELS(3);
256 pillar->y.fixed += -PIXELS(2);
257 leader->y.fixed += -PIXELS(2);
258 leader->terrainHeight += -PIXELS(2);
259 Engine_TaskWait(10);
260 reboundStep = PIXELS(2);
261 pillar->y.fixed += reboundStep;
262 leader->y.fixed += reboundStep;
263 leader->terrainHeight += reboundStep;
265 pillar->y.fixed += reboundStep;
266 leader->y.fixed += reboundStep;
267 leader->terrainHeight += reboundStep;
269 pillar->y.fixed += PIXELS(1);
270 leader->y.fixed += PIXELS(1);
271 leader->terrainHeight += PIXELS(1);
272 }
274}
275
276/// Stepping back onto the floor, and before each jump: the leader walks and
277/// falls normally again and the six pillars stand still.
278static void Event_SteadyPillars(void) {
279 s32 flags;
280
283 flags = 4;
290}
291
292/// Returns the pillar and confrontation triggers.
295}
296
297/// Restores the platforms and runs the scene selected by the arrival.
299 s32 mirroredScale;
300 u32 pillarId;
301 s32 clear;
302 s16 entrance;
303 struct FieldActor *pillar;
304
312 mirroredScale = -Q16_ONE;
315 pillarId = ACTOR_FIRST_PILLAR;
316 clear = 0;
317 do {
318 pillar = Object_GetById(pillarId);
321 pillar->motionFlags = 4;
322 pillar->priorityFlags |= 2;
323 pillar->y.fixed = PIXELS(1) / 2;
324 pillarId++;
325 } while (pillarId <= ACTOR_LAST_PILLAR);
326
327 entrance = gGameState.entrance;
328
329 switch (entrance) {
333 }
334 break;
337 break;
340 break;
343 break;
346 break;
351 } else if (Engine_GameFlagIsSet(FLAG_SHAMANS_ROD_OWNER + 1) != 0) {
353 } else if (Engine_GameFlagIsSet(FLAG_SHAMANS_ROD_OWNER + 2) != 0) {
355 } else {
357 }
359 break;
360 }
361
364
365 if (slot != 0) {
366 struct FieldActor *nearestPillar = Object_GetById(slot);
367 if (nearestPillar != 0) {
368 nearestPillar->motionFlags = 0;
369 }
370 }
371 }
372 return clear;
373}
374
376 Engine_EventShowMessage(speaker, 0);
378}
379
380/// Turns one actor and waits ten frames.
383}
384
385/// Brings the party onto the aerie and reveals the argument over Sheba.
387 struct FieldActor *arrivalPlatform;
388 struct FieldActor *leader;
389
390 // Bring the leader across on the moving platform, then reveal the party.
391 arrivalPlatform = Object_GetById(ACTOR_MOVING_PILLAR);
396 Engine_CameraMoveTo(-1, -1, -1, 0);
398 arrivalPlatform->motionFlags = 0;
399 arrivalPlatform->priorityFlags |= ACTOR_PRIORITY_UNDERFOOT;
404 leader->motionFlags = 0;
427 leader->x.fixed = PIXELS(516);
428 leader->y.fixed = PIXELS(8);
429 leader->z.fixed = PIXELS(148);
430 leader->facing = FACING_WEST;
433 leader->velocityY = PIXELS(4);
439 {
440 u16 shown = FACING_SOUTH;
441
442 leader->y.fixed = -PIXELS(32);
443 leader->facing = shown;
444 }
458 Engine_ActorWalkTo(GARET, 514, 164);
459 Actor_WalkTo(IVAN, 492, 140);
471 // Reveal Saturos and Menardi arguing with Felix about Sheba.
472 Engine_EventSetMessage(MsgVenusLongLastTime);
479 Engine_CameraSetSpeed(PIXELS(24) / 5, PIXELS(3) / 5);
480 Engine_CameraMoveTo(PIXELS(304), PIXELS(32), PIXELS(158), 1);
498 Engine_CameraSetSpeed(PIXELS(8) / 5, PIXELS(1) / 5);
499 Camera_MoveTo(PIXELS(294), -1, PIXELS(194), 1);
501 Actor_SetSpeed(ACTOR_FELIX, PIXELS(4) / 5, PIXELS(2) / 5);
574 Engine_CameraSetSpeed(PIXELS(2) / 5, PIXELS(1) / 20);
575 Camera_MoveTo(PIXELS(294), -1, PIXELS(180), 1);
633 Engine_CameraMoveTo(PIXELS(504), -PIXELS(24), PIXELS(168), 0);
646 Engine_ActorJump(GARET, 2, 20);
652 if (Engine_EventChooseYesNo(0, 0) == 1) {
653 gEventWork->message += 1;
654 }
668}
669
670/// Shows or hides one companion, setting its movement speed when shown.
671static void VenusLighthouseAerie_ShowPartyMember(s32 actorId, s32 shown) {
672 struct FieldActor *member;
673
674 if (shown != 0) {
675 Actor_SetChildValue(actorId, 0);
676 member = Actor_Get(actorId);
678 Actor_SetSpeed(actorId, PIXELS(4) / 5, PIXELS(2) / 5);
679 } else {
680 Actor_SetChildValue(actorId, 15);
681 member = Actor_Get(actorId);
683 }
684}
685
686/// Walking up to Saturos and Menardi: they promise not to harm Sheba for the
687/// Shaman's Rod, Felix carries it over, they will not let her go, and the
688/// battle begins.
690 s32 rodOwner;
691 struct FieldActor *object;
692 s32 answerAccepted;
693 s32 frame;
694 s32 receiptMessage;
695
698 Camera_SetSpeed(PIXELS(4) / 5, PIXELS(1) / 10);
699 Camera_MoveTo(PIXELS(332), PIXELS(32), PIXELS(180), 1);
704 Engine_EventSetMessage(MsgVenusIsaac);
708 Camera_SetSpeed(PIXELS(4) / 5, PIXELS(1) / 10);
709 Camera_MoveTo(PIXELS(304), PIXELS(32), PIXELS(180), 1);
710 Actor_SetSpeed(GARET, PIXELS(1), PIXELS(1) / 2);
711 Actor_SetSpeed(IVAN, PIXELS(1), PIXELS(1) / 2);
712 Actor_SetSpeed(MIA, PIXELS(7) / 5, PIXELS(7) / 10);
714 if (object != 0) {
715 Actor_SetPosition(GARET, object->x.fixed, object->z.fixed);
716 }
718 if (object != 0) {
719 Actor_SetPosition(IVAN, object->x.fixed, object->z.fixed);
720 }
722 if (object != 0) {
723 Actor_SetPosition(MIA, object->x.fixed, object->z.fixed);
724 }
725 Actor_WalkTo(GARET, 328, 168);
726 Actor_WalkTo(IVAN, 340, 196);
727 Actor_WalkToAndWait(MIA, 326, 204);
789 Actor_SetSpeed(SHEBA, PIXELS(4) / 5, PIXELS(2) / 5);
790 Actor_WalkToAndWait(SHEBA, 260, 186);
792 Actor_WalkToAndWait(SHEBA, 276, 192);
794 object->facing = FACING_SOUTH + FACING_STEP;
798 Engine_ActorJump(SHEBA, 2, 20);
799 Actor_SetSpeed(SHEBA, PIXELS(12) / 5, PIXELS(6) / 5);
800 Actor_WalkToAndWait(SHEBA, 260, 186);
802 Actor_WalkToAndWait(SHEBA, 248, 172);
810 frame = 0;
811 do {
812 object = Object_GetById(SHEBA);
814 frame = (frame + 1);
816 } while ((u32)frame <= 39);
838 Engine_TaskWait(10);
840 Engine_ActorJump(SHEBA, 2, 40);
846 Actor_WalkToAndWait(SHEBA, 250, 176);
856 Actor_SetSpeed(SHEBA, PIXELS(3) / 5, PIXELS(3) / 10);
858 Actor_WalkToAndWait(SHEBA, 248, 172);
885 if (Engine_EventChooseYesNo(0, 0) == 0) {
888 answerAccepted = 1;
889 } else {
892 gEventWork->message += 1;
893 answerAccepted = 0;
894 }
896 if (answerAccepted != 0) {
897 gEventWork->message += 1;
898 }
907 if (Engine_EventChooseYesNo(0, 0) == 0) {
910 answerAccepted = 1;
911 } else {
914 gEventWork->message += 1;
915 answerAccepted = 0;
916 }
918 if (answerAccepted != 0) {
919 gEventWork->message += 1;
920 }
955 Actor_SetSpeed(ACTOR_FELIX, PIXELS(4) / 5, PIXELS(2) / 5);
963
964 // Complete the Shaman's Rod exchange before the confrontation resumes.
965 receiptMessage = MsgVenusIsaacHandedOverShamansRod;
966 Engine_MessageShowCentered(receiptMessage, 1);
973 Engine_EventSetMessage((receiptMessage + 1));
982 Actor_SetSpeed(SHEBA, PIXELS(4) / 5, PIXELS(2) / 5);
983 Actor_WalkToAndWait(SHEBA, 260, 186);
985 Actor_WalkToAndWait(SHEBA, 276, 192);
988 object->facing = FACING_SOUTH + FACING_STEP;
996 Engine_ActorJump(MIA, 2, 20);
1069 // Save the rod owner for the defeat return path, then enter battle.
1089 Battle_SetStart(3);
1090 {
1092
1095 }
1097 GameFlag_Set(0x350);
1098}
1099
1100/// Flashes an actor palette and emits paired effects every fifteenth frame.
1102 if (*(s32 *)&gFrameCount & 2) {
1104 } else {
1106 }
1107 if (Math_RemainderUnsigned(*(s32 *)&gFrameCount, 15) == 0) {
1109 }
1110}
1111
1112/// Cycles the actor palette and emits paired effects every fifteenth frame.
1114 if (gFrameCount & 1) {
1117 }
1118 if (Math_RemainderUnsigned(gFrameCount, 15) == 0) {
1120 }
1121}
1122
1123#include "common/effect_vertical.h"
1124
1125/// Spawns two vertical effects using the parent position and shared cached
1126/// tiles.
1127static void
1129 struct FieldActor *pair[2];
1130 struct FieldActor *child;
1131 struct AnimationObject *sprite;
1132 struct BattleFxScene *sceneWork = gEffectWork;
1133 s32 effectIndex;
1134
1136 for (effectIndex = 0; effectIndex < 2; ++effectIndex) {
1137 child = Engine_ObjectCreate(26, parent->x.fixed, parent->y.fixed,
1138 parent->z.fixed);
1139 pair[effectIndex] = child;
1140 if (child != NULL) {
1141 child->terrainHeight = parent->terrainHeight;
1142 sprite = child->sprite;
1143 child->motionFlags = 0;
1144 child->timer = 0;
1145 child->linkedObject = parent;
1146 if (sprite != NULL) {
1148 sprite->flags = 0;
1149 Resource_ResetEntry(sprite->slot);
1150 sprite->slot = sceneWork->tileSlot;
1151 sprite->retainCacheEntry = 1;
1152 sprite->image.tile =
1153 (gVramBlockCache[sprite->slot].offset >> 5) & 0x3ff;
1154 sprite->image.fullColor = 0;
1155 sprite->image.shape = 1;
1156 sprite->image.size = 2;
1157 sprite->entries[0]->frame = 0;
1158 }
1159 }
1160 }
1161 {
1162 struct FieldActor *effect = pair[0];
1163 struct AnimationObject *effectSprite = effect->sprite;
1164
1165 effect->update = Effect_AnimateVerticalNegative;
1166 effectSprite->image.priority = parent->sprite->image.priority;
1167 }
1168 {
1169 struct FieldActor *effect = pair[1];
1170 struct AnimationObject *effectSprite = effect->sprite;
1171
1172 effectSprite->image.priority = parent->sprite->image.priority;
1173 effect->update = Effect_AnimateVerticalPositive;
1174 effect->priorityFlags = 2;
1175 }
1176}
1177
1178#include "common/effect_psynergy.h"
1179
1182}
1183
1184/// Builds the horizontal velocity for an elliptical radial particle burst.
1185static inline void VenusLighthouseAerie_AimBurst(s32 velocity[3], s32 angle) {
1186 s32 sine;
1187 s32 cosine;
1188
1189 velocity[0] = Engine_MathCos(angle);
1190 velocity[1] = 0;
1191 sine = Engine_MathSin(angle);
1192 cosine = velocity[0];
1193 cosine += cosine * 2;
1194 sine *= 2;
1195 velocity[2] = sine;
1196 velocity[0] = cosine;
1197}
1198
1199/// Gives Felix, Sheba and the party the same reaction, then waits after Mia.
1201 s32 waitFrames) {
1202 Actor_ShowEmote(ACTOR_FELIX, emote, 0);
1203 Actor_ShowEmote(SHEBA, emote, 0);
1205 Actor_ShowEmote(GARET, emote, 0);
1206 Actor_ShowEmote(IVAN, emote, 0);
1207 Actor_ShowEmote(MIA, emote, waitFrames);
1208}
1209
1210/// Shows the Venus Star lighting the beacon and the antagonists combining.
1212 struct EffectOptions menardiBurst;
1213 s32 velocity[3];
1214 struct EffectOptions saturosBurst;
1215 struct FieldActor *actor;
1216 struct FieldActor *menardi;
1217 struct FieldActor *saturos;
1218 union FieldObject *star = NULL;
1219 struct FieldActor *starCarrier;
1220 struct AnimationObject *sprite;
1221 u8 *iconPixels;
1222 // Reuse the dialogue answer word for the later radial burst directions.
1223 u32 sceneStep;
1224
1225 Event_Begin();
1226 Map_CopyCellAttributes(17, 10, 4, 2, 17, 8);
1227 Actor_Get(GARET)->facing = FACING_WEST;
1228 Actor_SetPosition(GARET, PIXELS(328), PIXELS(168));
1229 Actor_Get(IVAN)->facing = FACING_WEST;
1230 Actor_SetPosition(IVAN, PIXELS(340), PIXELS(196));
1231 Actor_Get(MIA)->facing = FACING_WEST;
1232 Actor_SetPosition(MIA, PIXELS(326), PIXELS(204));
1234 Actor_SetPosition(SHEBA, PIXELS(268), PIXELS(154));
1237 actor = Actor_Get(ACTOR_SATUROS);
1238 actor->timer = 10;
1239 actor->facing = FACING_NORTH + FACING_STEP;
1244 actor = Actor_Get(ACTOR_MENARDI);
1245 actor->timer = 10;
1246 actor->facing = FACING_EAST;
1251 Event_GetViewCenter()->motionFlags = 0;
1252 Camera_MoveTo(PIXELS(304), PIXELS(32), PIXELS(180), 0);
1253 Task_Wait(1);
1254 Map_Redraw();
1255 Task_Wait(1);
1258 Event_Wait(80);
1259
1260 Actor_Jump(GARET, 2, 20);
1262 Event_SetMessage(MsgVenusBeatEm);
1269 Actor_SetSpeed(ACTOR_FELIX, PIXELS(4) / 5, PIXELS(2) / 5);
1270 Actor_Get(ACTOR_FELIX)->steeringFlags &= ~ACTOR_FACES_MOTION;
1272 Event_Wait(1);
1273 Actor_Get(ACTOR_FELIX)->steeringFlags |= ACTOR_FACES_MOTION;
1274 Event_Wait(20);
1292 Actor_Jump(IVAN, 2, 20);
1301 if (Event_ChooseYesNo(0, 0) == 0) {
1302 sceneStep = TRUE;
1303 } else {
1305 sceneStep = FALSE;
1306 }
1307 Task_Wait(20);
1314 Event_Wait(40);
1315 if (sceneStep) {
1317 }
1318
1319 // The defeated antagonists recover before using the Venus Star.
1322 Task_Wait(1);
1323 actor = Actor_Get(ACTOR_SATUROS);
1324 actor->scaleX = Q16_ONE;
1325 actor->scaleY = Q16_ONE;
1326 actor = Actor_Get(ACTOR_MENARDI);
1327 actor->scaleX = Q16_ONE;
1328 actor->scaleY = Q16_ONE;
1329 Task_Wait(1);
1338 Event_Wait(20);
1339 Actor_SetSpeed(ACTOR_SATUROS, PIXELS(1) / 5, PIXELS(1) / 10);
1341 Event_Wait(20);
1343 Event_Wait(20);
1344 Actor_Get(ACTOR_SATUROS)->scaleX = -Q16_ONE;
1347 Event_Wait(20);
1350 Actor_Jump(ACTOR_MENARDI, 4, 40);
1351 Actor_SetSpeed(ACTOR_MENARDI, PIXELS(1) / 5, PIXELS(1) / 10);
1352 Actor_Get(ACTOR_MENARDI)->steeringFlags &= ~ACTOR_FACES_MOTION;
1354 Actor_SetSpeed(ACTOR_MENARDI, PIXELS(1) / 10, PIXELS(1) / 20);
1356 Actor_Get(ACTOR_MENARDI)->steeringFlags |= ACTOR_FACES_MOTION;
1357 Actor_Get(ACTOR_MENARDI)->scaleX = -Q16_ONE;
1360 Event_Wait(20);
1362 Event_Wait(20);
1364 Event_Wait(80);
1368 Event_Wait(40);
1378
1379 actor = Actor_Get(ACTOR_SATUROS);
1381 actor->scaleX = Q16_ONE;
1383 Event_Wait(10);
1386 Event_Wait(10);
1393 star = (union FieldObject *)Object_Create(
1394 22, actor->x.fixed, actor->y.fixed + PIXELS(8), actor->z.fixed);
1395 if (star != NULL) {
1396 sprite = star->actor.sprite;
1397 sprite->count = 0;
1398 sprite->image.fullColor = 0;
1399 sprite->image.palette = 0;
1400 sprite->image.priority = 0;
1401 star->actor.priorityFlags &= ~1;
1402 star->actor.motionFlags = 0;
1403 star->actor.retainSpriteCache = 1;
1404 star->actor.speed = PIXELS(8) / 5;
1405 star->actor.acceleration = 0xcccc;
1406 iconPixels = Heap_Allocate(17, 0x608);
1407 // Display the Venus Star icon before sending it toward the beacon.
1409 Vram_Load(sprite->slot, 128, iconPixels + 0x400);
1410 Heap_Release(17);
1411 }
1413 starCarrier = Actor_Get(ACTOR_STAR_CARRIER);
1414 starCarrier->x.fixed = actor->x.fixed;
1415 starCarrier->y.fixed = PIXELS(32);
1416 starCarrier->z.fixed = actor->z.fixed;
1417 starCarrier->motionFlags = 3;
1418 starCarrier->speed = PIXELS(8) / 5;
1419 starCarrier->acceleration = PIXELS(4) / 5;
1420 starCarrier->scaleX = 3 * Q16_ONE / 4;
1421 starCarrier->scaleY = 3 * Q16_ONE / 4;
1422 if (star != NULL) {
1423 star->actor.motionFlags = 3;
1424 star->effect.velocity.y = PIXELS(3) / 5;
1425 star->effect.velocity.x = PIXELS(4) / 5;
1426 star->actor.velocityY = PIXELS(8);
1427 FieldObject_SetPosition(&star->actor, PIXELS(308), PIXELS(32), PIXELS(164));
1428 }
1432 if (star != NULL) {
1434 Actor_SetSpriteFlags(&star->actor, 0);
1435 star->actor.velocityY = PIXELS(4);
1436 FieldObject_SetPosition(&star->actor, PIXELS(314), PIXELS(32), PIXELS(137));
1439 star->actor.sprite->image.priority = 1;
1440 star->actor.velocityY = PIXELS(6);
1441 FieldObject_SetPosition(&star->actor, PIXELS(285), PIXELS(32), PIXELS(146));
1444 star->actor.velocityY = PIXELS(5);
1445 FieldObject_SetPosition(&star->actor, PIXELS(300), PIXELS(32), PIXELS(154));
1447 Task_Wait(6);
1448 star->actor.x.fixed = 0;
1449 star->actor.y.fixed = 0;
1450 star->actor.z.fixed = 0;
1452 }
1453 // Let the group react as the Venus Star reaches the beacon.
1456 Actor_Get(ACTOR_FELIX)->priorityFlags |= 1;
1462 Event_Wait(20);
1476 if (Event_ChooseYesNo(0, 0) == 0) {
1478 sceneStep = TRUE;
1479 } else {
1482 sceneStep = FALSE;
1483 }
1485 if (sceneStep) {
1487 }
1488 Event_Wait(20);
1489
1493 actor->scaleY = -Q16_ONE;
1494 actor->scaleX = Q16_ONE / 10;
1495 actor->motionFlags = 0;
1496 actor->y.fixed = PIXELS(64);
1497 actor->x.fixed = PIXELS(304);
1498 actor->z.fixed = PIXELS(158);
1502 actor->scaleY = -Q16_ONE;
1503 actor->scaleX = Q16_ONE / 10;
1504 actor->motionFlags = 0;
1505 actor->y.fixed = PIXELS(96);
1506 actor->x.fixed = PIXELS(304);
1507 actor->z.fixed = PIXELS(158);
1518 ColorBuffer_ApplyTarget(0x4063ff, 0);
1520 Task_Wait(20);
1521 ColorBuffer_ApplyTarget(0x7fff, 0);
1523 Task_Wait(60);
1528 ColorBuffer_ApplyTarget(0x4063ff, 0);
1532 Task_Wait(120);
1534 ColorBuffer_ApplyTarget(0x203210, 0);
1536 Task_Wait(120);
1541 Task_Wait(120);
1543
1546 Actor_Get(ACTOR_MENARDI)->scaleX = Q16_ONE;
1547 Actor_Jump(ACTOR_MENARDI, 4, 40);
1639 Event_Wait(20);
1653 Actor_SetSpeed(SHEBA, PIXELS(1), PIXELS(1) / 2);
1656 Event_Wait(20);
1662 // Flash the antagonists and release their matching radial bursts.
1663 ColorBuffer_ApplyTarget(0x40250d, 1);
1673 Event_Wait(20);
1676 Event_Wait(20);
1678 Actor_Jump(MIA, 2, 20);
1683
1684 menardi = Actor_Get(ACTOR_MENARDI);
1685 menardiBurst.palette = 7;
1687 menardiBurst.startScaleX = Q16_ONE;
1688 menardiBurst.startScaleY = Q16_ONE;
1689 for (sceneStep = 0; sceneStep <= 16; sceneStep++) {
1690 VenusLighthouseAerie_AimBurst(velocity, sceneStep << 12);
1691 Effect_Spawn(menardi->x.fixed, menardi->y.fixed, menardi->z.fixed,
1692 velocity[0], velocity[1], velocity[2],
1695 &menardiBurst);
1696 }
1698 Task_Wait(6);
1700 saturos = Actor_Get(ACTOR_SATUROS);
1701 saturosBurst.palette = 7;
1703 saturosBurst.startScaleX = Q16_ONE;
1704 saturosBurst.startScaleY = Q16_ONE;
1705 for (sceneStep = 0; sceneStep <= 16; sceneStep++) {
1706 VenusLighthouseAerie_AimBurst(velocity, sceneStep << 12);
1707 Effect_Spawn(saturos->x.fixed, saturos->y.fixed, saturos->z.fixed,
1708 velocity[0], velocity[1], velocity[2],
1711 &saturosBurst);
1712 }
1714 Actor_Jump(IVAN, 6, 20);
1720 Actor_SetSpeed(ACTOR_SATUROS, PIXELS(1) / 5, PIXELS(1) / 10);
1721 Actor_SetSpeed(ACTOR_MENARDI, PIXELS(1) / 5, PIXELS(1) / 10);
1722 Actor_Get(ACTOR_SATUROS)->steeringFlags &= ~ACTOR_FACES_MOTION;
1723 Actor_Get(ACTOR_MENARDI)->steeringFlags &= ~ACTOR_FACES_MOTION;
1726 // Slide the two transformed actors together, then start the fusion battle.
1734 Event_Wait(20);
1736 Event_Wait(20);
1737 Battle_SetStart(3);
1744 GameFlag_Set(0x351);
1745}
1746
1747/// Flashes the object palette white, then restores the transformation colour.
1752 Engine_TaskWait(4);
1753 Engine_ColorBufferApplyTarget(0x40250d, 1);
1755 Engine_TaskWait(1);
1756}
1757
1758/// Orbits a particle around the upper beam and keeps its target at that
1759/// position.
1760static void
1762 struct FieldActor *effect = &fieldObject->actor;
1763 struct FieldActor *center = Object_GetById(ACTOR_BEAM_1);
1764 u16 angle = effect->timer;
1765
1766 effect->x.fixed =
1767 center->x.fixed + Engine_MathCos(angle) * (effect->speed + 3);
1768 effect->z.fixed = center->z.fixed + Engine_MathSin(angle) * 2;
1769 effect->targetX = effect->x.fixed;
1770 effect->targetZ = effect->z.fixed;
1771 effect->timer -= 0x800;
1772}
1773
1774/// Orbits a particle around the rising beam using its rise counter as a radius.
1775static void
1777 struct FieldActor *actor = &fieldObject->actor;
1779 s32 angle = (u16)actor->timer;
1780 s32 cosine;
1781 s32 sine;
1782 s32 along;
1783 s32 across;
1784
1785 cosine = Engine_MathCos(angle);
1786 along = anchor->x.fixed + cosine * (actor->speed + actor->riseCounter + 6);
1787 actor->x.fixed = along;
1788
1789 sine = Engine_MathSin(angle);
1790 across = anchor->z.fixed + sine * (actor->riseCounter + 4);
1791 actor->z.fixed = across;
1792
1793 actor->targetX = actor->x.fixed;
1794 actor->targetZ = across;
1795
1796 {
1797 s32 next = (u16)actor->timer;
1798 next += 0xfffff800;
1799 actor->timer = next;
1800 }
1801}
1802
1803/// Emits rising particles around the upper beam at the current beacon stage.
1805 struct FieldActor *center;
1806 struct FieldActor *effect;
1807 struct AnimationObject *sprite;
1808 s32 angle;
1809
1812 return;
1813 }
1814 center = Actor_Get(ACTOR_BEAM_1);
1816 effect = Object_Create(284, center->x.fixed,
1817 (s32)((u32)(Random_Next() << 8) >> 16 << 16) +
1818 center->y.fixed - PIXELS(28),
1819 center->z.fixed);
1820 } else {
1821 effect = Object_Create(284, center->x.fixed,
1822 (s32)((u32)(Random_Next() << 6) >> 16 << 16) +
1823 center->y.fixed - PIXELS(28),
1824 center->z.fixed);
1825 }
1826 if (effect != 0) {
1827 sprite = effect->sprite;
1829 ObjectGroup_SetChildValue(effect, 1);
1830 effect->motionFlags = 0;
1831 angle = Random_Next() & 0xffff000;
1832 effect->timer = angle;
1833 effect->work = 0;
1835 effect->speed =
1836 Engine_MathSin((u32)(Random_Next() * 0xffff) >> 20) * 24 >> 16;
1837 sprite->flags = 0;
1838 sprite->image.priority = 1;
1839 }
1840}
1841
1842/// Tests whether all three movement targets are unset.
1843static __inline__ s32 Actor_IsParked(struct FieldActor *actor) {
1844 if (actor->targetX == ACTOR_NO_TARGET && actor->targetY == actor->targetX &&
1845 actor->targetZ == actor->targetY) {
1846 return 1;
1847 }
1848 return 0;
1849}
1850
1851/// Pulses and slides Saturos and Menardi while their beam flags are active.
1853 struct FieldActor *saturos;
1854 struct FieldActor *menardi;
1855 s32 pairParked;
1856
1857 saturos = Object_GetById(ACTOR_SATUROS);
1858 menardi = Object_GetById(ACTOR_MENARDI);
1859 pairParked = Actor_IsParked(saturos); // Overwritten; only the saturos actor's
1860 // test loads remain in the ROM.
1861 pairParked = Actor_IsParked(menardi);
1862 if (pairParked != 0) {
1863 saturos->facing = 0;
1864 menardi->facing = 0;
1868 if (saturos->scaleX < 5 * Q16_ONE / 4) {
1869 saturos->scaleX += Q16_ONE / 128;
1870 saturos->scaleY += Q16_ONE / 128;
1871 menardi->scaleX += Q16_ONE / 128;
1872 menardi->scaleY += Q16_ONE / 128;
1873 }
1874 } else {
1875 if ((*(s32 *)&gFrameCount & 2) != 0) {
1878 } else {
1881 }
1882 }
1884 if (saturos->x.fixed < PIXELS(312)) {
1885 saturos->x.fixed += PIXELS(1) / 16;
1886 menardi->x.fixed += PIXELS(1) / 16;
1887 }
1888 if (saturos->z.fixed > PIXELS(182)) {
1889 saturos->z.fixed += -PIXELS(1) / 16;
1890 menardi->z.fixed += -PIXELS(1) / 16;
1891 }
1892 }
1893 }
1894}
1895
1896/// Plays the antagonists' defeat, the party discussion and the beacon eruption.
1903}
1904
1905/// A look back from the world map: Felix cries out as Sheba clings to the
1906/// broken aerie, then the world map returns with its music still playing.
1912
1915
1920}
1921
1922/// Stages the broken aerie for the fall sequence and the party escape.
1924 struct FieldActor *leader;
1925 struct FieldActor *actor;
1926
1930 Map_CopyCellsTo(102, 4, 74, 4, 18, 23);
1931 Map_CopyCellsTo(39, 72, 11, 72, 16, 20);
1932 Map_CopyCellAttributes(19, 6, 3, 7, 22, 6);
1933 Map_CopyCellAttributes(19, 6, 3, 7, 13, 6);
1934 Map_CopyCellAttributes(19, 6, 3, 7, 22, 13);
1935 Map_CopyCellAttributes(19, 6, 3, 7, 13, 13);
1936 Engine_TaskWait(1);
1937 Camera_MoveTo(PIXELS(192), -PIXELS(64), PIXELS(238), 0);
1938 Engine_TaskWait(1);
1940 Engine_TaskWait(1);
1945 leader->x.fixed = PIXELS(346);
1946 leader->z.fixed = PIXELS(205);
1947 leader->y.fixed = PIXELS(32);
1948 leader->facing = FACING_SOUTHWEST;
1952 actor = Actor_Get(GARET);
1953 actor->x.fixed = PIXELS(356);
1954 actor->z.fixed = PIXELS(192);
1955 actor->facing = FACING_NORTHWEST;
1956 actor->y.fixed = PIXELS(32);
1960 actor = Actor_Get(IVAN);
1961 actor->x.fixed = PIXELS(360);
1962 actor->facing = FACING_SOUTHEAST;
1963 actor->y.fixed = PIXELS(32);
1964 actor->z.fixed = PIXELS(222);
1968 actor = Actor_Get(MIA);
1969 actor->x.fixed = PIXELS(334);
1970 actor->facing = FACING_WEST;
1971 actor->y.fixed = PIXELS(32);
1972 actor->z.fixed = PIXELS(222);
1976 Actor_SetPosition(SHEBA, PIXELS(188), PIXELS(316));
1980 actor->x.fixed -= PIXELS(16);
1983 actor->x.fixed -= PIXELS(16);
1986 actor->x.fixed += PIXELS(16);
1989 actor->x.fixed += PIXELS(16);
1995 Actor_Get(ACTOR_PARTICLE_SOURCE)->y.fixed = PIXELS(40);
2002 Engine_EventWait(40);
2006}
2007
2008/// Shows Saturos and Menardi falling into the beacon after their final defeat.
2010 struct FieldActor *actor;
2011
2013 Map_CopyCellAttributes(17, 10, 4, 2, 17, 8);
2015 Actor_Get(GARET)->facing = FACING_NORTHWEST;
2016 Actor_SetPosition(GARET, PIXELS(328), PIXELS(168));
2017 Actor_Get(IVAN)->facing = FACING_NORTHWEST;
2018 Actor_SetPosition(IVAN, PIXELS(340), PIXELS(196));
2019 Actor_Get(MIA)->facing = FACING_NORTHWEST;
2020 Actor_SetPosition(MIA, PIXELS(326), PIXELS(204));
2024 Actor_SetPosition(SHEBA, PIXELS(200), PIXELS(216));
2029
2033 actor = Actor_Get(ACTOR_BEAM_1);
2034 actor->scaleY = -Q16_ONE;
2035 actor->scaleX = Q16_ONE / 5;
2036 actor->motionFlags = 0;
2037 actor->x.fixed = PIXELS(304);
2038 actor->y.fixed = PIXELS(2);
2039 actor->z.fixed = PIXELS(96);
2040
2044 actor = Actor_Get(ACTOR_BEAM_2);
2045 actor->scaleY = -Q16_ONE;
2046 actor->scaleX = Q16_ONE / 5;
2047 actor->motionFlags = 0;
2048 actor->x.fixed = PIXELS(304);
2049 actor->y.fixed = PIXELS(34);
2050 actor->z.fixed = PIXELS(96);
2051
2055 Camera_MoveTo(PIXELS(304), PIXELS(32), PIXELS(180), 0);
2056 Engine_TaskWait(1);
2058 Engine_TaskWait(1);
2062 Engine_EventWait(40);
2064 Engine_EventWait(10);
2065 // Give Saturos and Menardi their final exchange before they fall.
2066 Engine_EventSetMessage(MsgVenusPairDefeated);
2069 Engine_EventWait(20);
2072
2073 actor = Actor_Get(ACTOR_SATUROS);
2074 actor->x.fixed = PIXELS(308);
2075 actor->y.fixed = PIXELS(28);
2076 actor->z.fixed = PIXELS(152);
2078 Engine_EventWait(20);
2079 actor->x.fixed = PIXELS(306);
2080 actor->y.fixed = PIXELS(28);
2081 actor->z.fixed = PIXELS(152);
2083 Engine_EventWait(12);
2084 actor->x.fixed = PIXELS(304);
2085 actor->y.fixed = PIXELS(21);
2086 actor->z.fixed = PIXELS(152);
2090
2091 actor = Actor_Get(ACTOR_MENARDI);
2092 actor->x.fixed = PIXELS(294);
2093 actor->y.fixed = PIXELS(28);
2094 actor->z.fixed = PIXELS(152);
2096 Engine_EventWait(20);
2097 actor->x.fixed = PIXELS(300);
2098 actor->y.fixed = PIXELS(27);
2099 actor->z.fixed = PIXELS(152);
2101 Engine_EventWait(12);
2102 actor->x.fixed = PIXELS(304);
2103 actor->y.fixed = PIXELS(17);
2104 actor->z.fixed = PIXELS(152);
2108 Engine_EventWait(160);
2109}
2110
2111/// Lets the party discuss the battle while Felix and Sheba remain on the aerie.
2113 s32 answerAccepted;
2114 s32 garetSpeaker;
2115 s32 miaSpeaker;
2116
2118 Engine_EventWait(20);
2121 Engine_EventWait(20);
2125 answerAccepted = 0;
2126 if (Engine_EventChooseYesNo(0, 0) == 0) {
2127 Engine_EventWait(20);
2129 answerAccepted = 1;
2130 } else {
2131 Engine_EventWait(20);
2133 gEventWork->message += 1;
2134 }
2136 if (answerAccepted != 0) {
2137 gEventWork->message += 1;
2138 }
2139 Actor_SetSpeed(GARET, PIXELS(8) / 5, PIXELS(4) / 5);
2140 garetSpeaker = SPEAKER_PORTRAIT_LEFT | GARET;
2141 Actor_WalkToAndWait(GARET, 321, 174);
2167 Engine_ActorJump(IVAN, 4, 60);
2173 Engine_ActorJump(GARET, 4, 40);
2175 Actor_SetSpeed(ACTOR_FELIX, PIXELS(4) / 5, PIXELS(2) / 5);
2177 Actor_SetDestination(SHEBA, 200, 204);
2178 Camera_SetSpeed(PIXELS(16) / 5, PIXELS(2) / 5);
2179 Camera_MoveTo(PIXELS(252), 0, PIXELS(190), 1);
2181 Engine_EventWait(40);
2186 Engine_EventWait(20);
2193 miaSpeaker = SPEAKER_PORTRAIT_RIGHT | MIA;
2194 Engine_EventWait(20);
2198 Engine_EventWait(20);
2218 Engine_ActorJump(MIA, 4, 20);
2219 Event_ShowMessageAndWait(miaSpeaker, 0, 20);
2221}
2222
2225
2226/// Raises the beacon effects and splits the aerie beneath the group.
2228 struct FieldActor *lower;
2229 struct FieldActor *middle;
2230 struct FieldActor *upper;
2231 struct FieldActor *actor;
2232
2249 Engine_EventWait(10);
2251 Camera_MoveTo(PIXELS(304), PIXELS(32), PIXELS(180), 1);
2253 // Open the beacon beam before splitting the surrounding platform.
2260 ColorBuffer_ApplyTarget(0x4063ff, 0);
2262 Engine_TaskWait(20);
2265 Engine_TaskWait(60);
2272 // Stack three more beam segments under the rising upper pair.
2274 lower->scaleY = -Q16_ONE;
2276 lower->motionFlags = 0;
2277 lower->x.fixed = PIXELS(304);
2278 lower->y.fixed = -PIXELS(32);
2279 lower->z.fixed = PIXELS(96);
2282 middle = Object_GetById(ACTOR_BEAM_4);
2283 middle->scaleY = -Q16_ONE;
2285 middle->motionFlags = 0;
2286 middle->x.fixed = PIXELS(304);
2287 middle->y.fixed = 0;
2288 middle->z.fixed = PIXELS(96);
2292 upper->scaleY = -Q16_ONE;
2294 upper->motionFlags = 0;
2295 upper->x.fixed = PIXELS(304);
2296 upper->y.fixed = PIXELS(32);
2297 upper->z.fixed = PIXELS(96);
2298 Map_CopyCellsTo(102, 4, 74, 4, 18, 23);
2299 Map_CopyCellsTo(39, 72, 11, 72, 16, 21);
2300 Map_CopyCellAttributes(19, 6, 3, 7, 22, 6);
2301 Map_CopyCellAttributes(19, 6, 3, 7, 13, 6);
2302 Map_CopyCellAttributes(19, 6, 3, 7, 22, 13);
2303 Map_CopyCellAttributes(19, 6, 3, 7, 13, 13);
2304 Engine_TaskWait(1);
2306 actor->x.fixed -= PIXELS(16);
2309 actor->x.fixed -= PIXELS(16);
2312 actor->x.fixed += PIXELS(16);
2315 actor->x.fixed += PIXELS(16);
2318 actor->x.fixed += PIXELS(16);
2319 actor->z.fixed += PIXELS(16);
2321 actor = Object_GetById(GARET);
2322 actor->x.fixed += PIXELS(16);
2323 actor->z.fixed += PIXELS(16);
2325 actor = Object_GetById(IVAN);
2326 actor->x.fixed += PIXELS(16);
2327 actor->z.fixed += PIXELS(16);
2329 actor = Object_GetById(MIA);
2330 actor->x.fixed += PIXELS(16);
2331 actor->z.fixed += PIXELS(16);
2335 Actor_SetPosition(SHEBA, PIXELS(188), PIXELS(316));
2339 Engine_ColorBufferApplyTarget(0x4063ff, 0);
2346 Engine_TaskWait(120);
2348 Engine_ColorBufferApplyTarget(0x203210, 0);
2350 Engine_TaskWait(120);
2354 Engine_TaskWait(120);
2364 Engine_EventWait(20);
2368 Engine_ActorJump(IVAN, 2, 20);
2372 Engine_EventWait(20);
2375 Actor_SetSpeed(MIA, PIXELS(4) / 5, PIXELS(2) / 5);
2376 Engine_ActorWalkToAndWait(MIA, 326, 220);
2377 Engine_EventWait(40);
2381 actor->riseCounter = 0;
2382 actor->riseEnabled = 1;
2383 actor->riseBaseY = actor->y.fixed;
2384 actor->facing = FACING_NORTHWEST;
2385 actor = Actor_Get(GARET);
2386 actor->riseCounter = 0;
2387 actor->riseEnabled = 1;
2388 actor->facing = FACING_NORTHWEST;
2389 actor->riseBaseY = actor->y.fixed;
2390 actor = Actor_Get(IVAN);
2391 actor->riseCounter = 0;
2392 actor->riseEnabled = 1;
2393 actor->facing = FACING_NORTHWEST;
2394 actor->riseBaseY = actor->y.fixed;
2395 actor = Actor_Get(MIA);
2396 actor->riseCounter = 0;
2397 actor->riseEnabled = 1;
2398 actor->facing = FACING_NORTHWEST;
2399 actor->riseBaseY = actor->y.fixed;
2400 actor = Actor_Get(ACTOR_FELIX);
2401 actor->riseCounter = 0;
2402 actor->riseEnabled = 1;
2403 actor->riseBaseY = actor->y.fixed;
2404 actor = Actor_Get(SHEBA);
2405 actor->riseCounter = 0;
2406 actor->riseEnabled = 1;
2407 actor->riseBaseY = actor->y.fixed;
2412 sTransitionStep = 0;
2413 sTransitionTimer = 240;
2416 do {
2417 Engine_TaskWait(1);
2419 Engine_GameFlagSet(0x101);
2420 Engine_EventWait(30);
2424 {
2425 u16 white = 0x7fff;
2426
2427 PLTT_BACKDROP = white;
2428 }
2432}
2433
2434/// Places the party on the broken platform and resumes its falling effects.
2436 struct FieldActor *actor;
2437
2441 Map_CopyCellAttributes(17, 10, 4, 2, 17, 8);
2442 Map_CopyCellsTo(102, 4, 74, 4, 18, 23);
2443 Map_CopyCellsTo(39, 72, 11, 72, 16, 21);
2444 Map_CopyCellAttributes(19, 6, 3, 7, 22, 6);
2445 Map_CopyCellAttributes(19, 6, 3, 7, 13, 6);
2446 Map_CopyCellAttributes(19, 6, 3, 7, 22, 13);
2447 Map_CopyCellAttributes(19, 6, 3, 7, 13, 13);
2449 Camera_MoveTo(-1, -1, -1, 0);
2452 Engine_TaskWait(1);
2462
2464 actor->x.fixed = PIXELS(346);
2465 actor->y.fixed = PIXELS(32);
2466 actor->z.fixed = PIXELS(205);
2468 actor->riseEnabled = 0;
2469 actor->velocityY = PIXELS(2);
2470
2471 actor = Actor_Get(GARET);
2472 actor->x.fixed = PIXELS(356);
2473 actor->y.fixed = PIXELS(32);
2474 actor->z.fixed = PIXELS(192);
2476 actor->riseEnabled = 0;
2477 actor->velocityY = PIXELS(2);
2478
2479 actor = Actor_Get(IVAN);
2480 actor->x.fixed = PIXELS(360);
2481 actor->y.fixed = PIXELS(32);
2482 actor->z.fixed = PIXELS(222);
2484 actor->riseEnabled = 0;
2485 actor->velocityY = PIXELS(2);
2486
2487 actor = Actor_Get(MIA);
2488 actor->x.fixed = PIXELS(334);
2489 actor->y.fixed = PIXELS(32);
2490 actor->z.fixed = PIXELS(222);
2492 actor->riseEnabled = 0;
2493 actor->velocityY = PIXELS(2);
2494
2495 Actor_Get(ACTOR_FELIX)->riseCounter = 0;
2496 Actor_Get(SHEBA)->riseCounter = 0;
2497 Actor_Get(ACTOR_PARTICLE_SOURCE)->motionFlags |= 4;
2503 ColorBuffer_ApplySource(0x7fff, 0);
2506 Engine_TaskWait(60);
2507}
2508
2509/// Shows Felix urging Sheba to hold on at the edge of the platform.
2511 Engine_EventSetMessage(MsgVenusNoooo);
2515 Camera_SetSpeed(PIXELS(24) / 5, PIXELS(3) / 5);
2516 Camera_SetSpeed(PIXELS(4), PIXELS(1) / 2);
2517 Camera_MoveTo(PIXELS(192), -PIXELS(64), PIXELS(238), 1);
2519 Engine_EventWait(40);
2525 Engine_EventWait(60);
2528 Engine_EventWait(40);
2531}
2532
2533/// Shows Sheba falling, Felix jumping after her and the party escaping.
2535 struct FieldActor *actor;
2536 s32 stepPending;
2537
2538 stepPending = 0;
2539 // Sheba loses her grip while Felix tries to keep her on the platform.
2540 Engine_EventSetMessage(MsgVenusWhyHappeningProtectVenusLighthouse);
2542 Engine_EventWait(20);
2547 Engine_EventWait(10);
2555 Engine_EventWait(20);
2559 Engine_EventWait(160);
2561 Engine_EventWait(20);
2564 Engine_EventWait(80);
2566 Engine_EventWait(40);
2569 Engine_EventWait(10);
2575 actor = Object_GetById(ACTOR_FELIX);
2576 // Felix jumps after Sheba; the remaining party watches from the far side.
2578 actor->facing = FACING_WEST;
2581 Engine_EventWait(120);
2584 Camera_SetSpeed(PIXELS(4), PIXELS(1) / 2);
2585 Camera_MoveTo(PIXELS(342), PIXELS(32), PIXELS(212), 1);
2587 Engine_EventWait(20);
2589 Engine_EventWait(40);
2599 Engine_EventWait(20);
2605 Engine_ActorJump(GARET, 6, 60);
2607 Engine_EventWait(20);
2610 Engine_ActorJump(IVAN, 6, 40);
2613 Engine_ActorJump(MIA, 6, 60);
2629 Engine_EventWait(20);
2639 Actor_SetSpeed(GARET, PIXELS(8) / 5, PIXELS(4) / 5);
2640 Actor_WalkToAndWait(GARET, 333, 194);
2641 Actor_WalkToAndWait(GARET, 333, 206);
2646 Engine_TaskWait(1);
2647 actor->scaleX = Q16_ONE;
2648 actor->scaleY = Q16_ONE;
2649 Engine_EventWait(40);
2652 Engine_ActorJump(GARET, 4, 0);
2656 if (Engine_EventChooseYesNo(0, 0) == 0) {
2657 Engine_EventWait(20);
2664 stepPending = 1;
2665 } else {
2666 gEventWork->message += 3;
2667 Engine_EventWait(60);
2673 }
2674 if (stepPending != 0) {
2675 gEventWork->message += 3;
2676 }
2679 Engine_EventWait(80);
2696 Engine_EventWait(60);
2700 Engine_EventWait(40);
2702 Map_CopyCellsTo(110, 105, 74, 4, 18, 23);
2703 Map_CopyCellsTo(92, 86, 83, 4, 8, 23);
2704 Map_CopyCellsTo(75, 28, 75, 4, 8, 23);
2705 Map_CopyCellsTo(92, 86, 11, 72, 16, 20);
2706 Map_CopyCellsTo(19, 92, 19, 68, 8, 21);
2708 actor->z.fixed -= PIXELS(32);
2709 actor->work = 0;
2711 actor = Object_GetById(GARET);
2712 actor->x.fixed -= PIXELS(4);
2713 actor->z.fixed -= PIXELS(32);
2714 actor->work = 0;
2716 actor = Object_GetById(IVAN);
2717 actor->x.fixed -= PIXELS(4);
2718 actor->z.fixed -= PIXELS(32);
2719 actor->work = 0;
2721 actor = Object_GetById(MIA);
2722 actor->x.fixed -= PIXELS(4);
2723 actor->z.fixed -= PIXELS(18);
2724 actor->work = 0;
2727 Camera_MoveTo(PIXELS(338), PIXELS(32), PIXELS(180), 0);
2729 Engine_TaskWait(1);
2735 Engine_ActorJump(GARET, 6, 0);
2736 Engine_ActorJump(IVAN, 6, 0);
2737 Engine_ActorJump(MIA, 6, 0);
2738 // Shake the party and split away the remaining central floor tiles.
2745 Engine_EventWait(80);
2747 Engine_EventWait(40);
2749 Map_CopyCellAttributes(110, 106, 18, 14, 10, 5);
2750 Map_CopyCellsTo(110, 105, 74, 4, 18, 23);
2751 Map_CopyCellsTo(92, 86, 11, 68, 16, 20);
2753 actor->x.fixed -= PIXELS(16);
2755 actor = Object_GetById(GARET);
2756 actor->x.fixed -= PIXELS(16);
2758 actor = Object_GetById(IVAN);
2759 actor->x.fixed -= PIXELS(16);
2761 actor = Object_GetById(MIA);
2762 actor->x.fixed -= PIXELS(16);
2765 actor->x.fixed += PIXELS(16);
2768 actor->x.fixed += PIXELS(16);
2771 actor->x.fixed -= PIXELS(16);
2774 actor->x.fixed -= PIXELS(16);
2776 Camera_MoveTo(PIXELS(322), PIXELS(32), PIXELS(180), 0);
2778 Engine_TaskWait(1);
2784 Engine_ActorJump(GARET, 6, 0);
2785 Engine_ActorJump(IVAN, 6, 0);
2786 Engine_ActorJump(MIA, 6, 0);
2787 Map_SetShake(-1, -1, 9 * Q16_ONE / 10);
2788 Engine_EventWait(80);
2790 Engine_EventWait(40);
2795 Engine_EventWait(120);
2806 Engine_ActorJump(IVAN, 2, 20);
2811 Engine_EventWait(20);
2816 Engine_EventWait(20);
2817 Actor_SetSpeed(GARET, PIXELS(1), PIXELS(1) / 2);
2818 Actor_SetSpeed(IVAN, PIXELS(1), PIXELS(1) / 2);
2819 Actor_SetSpeed(MIA, PIXELS(1), PIXELS(1) / 2);
2823 Engine_EventWait(60);
2827 Engine_EventWait(80);
2833 Engine_EventWait(80);
2837 0;
2838 UiText_ShowCenteredMessage(MsgVenusDespiteLongTiring, 0, 0);
2840 Engine_EventWait(80);
2841}
2842
2843/// Clears all movement targets and velocities and resets the actor timer.
2845 actor->targetX = ACTOR_NO_TARGET;
2846 actor->targetY = ACTOR_NO_TARGET;
2847 actor->targetZ = ACTOR_NO_TARGET;
2848
2849 SET_VELOCITY(actor, 0, 0, 0);
2850
2851 actor->timer = 0;
2852}
2853
2854/// Advances the beacon rise sequence, its flashes and orbiting particles.
2856 struct FieldActor *center;
2857 struct FieldActor *effect;
2858 struct AnimationObject *sprite;
2859 s32 spawnParticles;
2860 u32 randomHeight;
2861 s32 angle;
2862
2864 spawnParticles = 0;
2865 switch (sTransitionStep) {
2866 case 0:
2869 ColorBuffer_ApplyTarget(0x2063ff, 1);
2871 break;
2872 case 8:
2875 break;
2876 case 16:
2878 break;
2879 // Start the lower beam beneath the floor, then pause each rise stage.
2880
2881 case 24:
2882 center->x.fixed = PIXELS(304);
2883 center->y.fixed = -PIXELS(360);
2884 center->z.fixed = PIXELS(164);
2885 center->scaleX = Q16_ONE;
2886 center->scaleY = Q16_ONE;
2890 break;
2891 case 25:
2893 if (center->y.fixed > 0) {
2894 ColorBuffer_ApplyTarget(0x203210, 0);
2897 Actor_Get(ACTOR_PARTY_LEADER)->riseCounter = 1;
2898 Actor_Get(GARET)->riseCounter = 1;
2899 Actor_Get(IVAN)->riseCounter = 1;
2900 Actor_Get(MIA)->riseCounter = 1;
2901 Actor_Get(ACTOR_FELIX)->riseCounter = 1;
2902 Actor_Get(SHEBA)->riseCounter = 1;
2903 } else {
2904 if ((gFrameCount & 7) == 0)
2906 spawnParticles = 1;
2907 center->y.fixed += PIXELS(9) / 4;
2908 }
2909 break;
2910 case 26:
2912 if (center->y.fixed > (PIXELS(40))) {
2916 } else {
2917 if ((gFrameCount & 7) == 0)
2919 spawnParticles = 1;
2920 center->y.fixed += PIXELS(9) / 4;
2921 }
2922 break;
2923 case 27:
2924 case 28:
2925 case 29:
2926 case 30:
2927 case 31:
2928 case 32:
2929 case 33:
2930 case 34:
2931 spawnParticles = 1;
2932 break;
2933 case 36:
2935 ColorBuffer_ApplyTarget(0x7fff, 0);
2937 break;
2938 case 48:
2941 break;
2942 }
2943 if (spawnParticles) {
2944 randomHeight = ((u32)(Random_Next() * 80) >> 16) << 16;
2945 effect = Object_Create(284, center->x.fixed,
2946 center->y.fixed - randomHeight + -PIXELS(8),
2947 center->z.fixed);
2948 if (effect != 0) {
2949 sprite = effect->sprite;
2951 ObjectGroup_SetChildValue(effect, 1);
2952 effect->motionFlags = 0;
2953 angle = Random_Next() & 0xffff000;
2954 effect->timer = angle;
2955 effect->work = 0;
2956 effect->riseCounter = (u32)Random_Next() >> 13;
2958 effect->speed = Engine_MathSin((u32)(Random_Next() * 0xffff) >> 20) * 24;
2959 effect->speed = center->speed >> 16;
2960 sprite->flags = 0;
2961 sprite->image.priority = 1;
2962 }
2963 }
2971}
2972
2973/// Raises an enabled actor according to its gated rise counter.
2975 if (actor->riseEnabled != 0) {
2976 u8 counter = actor->riseCounter;
2977
2978 actor->y.fixed = actor->riseBaseY + ((counter >> 2) << 16);
2979
2981
2982 if (actor->riseCounter != 0) {
2983 if (actor->riseCounter <= 31) {
2984 ++actor->riseCounter;
2985 }
2986 }
2987 }
2988}
2989
2990/// Emits particles beside the lower beam and links each to its source actor.
2992 union FieldObject *center;
2993 struct FieldActor *effect;
2994 struct AnimationObject *sprite;
2995 struct MapScrollWork *map;
2996 s32 drift;
2997 s32 phase;
2998 s32 angle;
2999
3000 center = OBJ_GET(23);
3001 map = gMapWork[0];
3002 drift = (u32)(Random_Next() * 48) >> 16 << 16;
3003 if ((s16)(map->viewY >> 16) <= 129) {
3004 if (gFrameCount & 1) {
3008 } else {
3010 Actor_Get(ACTOR_PARTICLE_SOURCE)->scaleX = 13 * Q16_ONE / 10;
3011 Actor_Get(ACTOR_PARTICLE_SOURCE)->scaleY = 13 * Q16_ONE / 10;
3012 }
3013 } else {
3015 }
3016 if (center == 0)
3017 return;
3018 phase = gFrameCount & 15;
3019 if (phase != 0)
3020 return;
3021 effect = Object_Create(284, center->actor.x.fixed + PIXELS(8),
3022 center->actor.y.fixed + drift + PIXELS(8),
3023 center->actor.z.fixed);
3024 drift /= PIXELS(6);
3025 drift <<= 16;
3026 if (effect == 0)
3027 return;
3028 sprite = effect->sprite;
3030 ObjectGroup_SetChildValue(effect, 5);
3031 effect->motionFlags = phase;
3032 angle = Random_Next() & 0xffff000;
3033 effect->timer = angle;
3034 effect->work = phase;
3035 effect->linkedObject = &center->actor;
3037 effect->speed = Engine_MathSin((drift & 0xfffff) >> 4) * 24 >> 16;
3038 sprite->flags = 0;
3039 sprite->image.priority = center->actor.sprite->image.priority;
3040}
3041
3042/// Moves a linked particle along its horizontal ellipse and preserves its
3043/// target.
3044static void
3046 struct FieldActor *anchor;
3047 s32 spin;
3048
3049 anchor = object->actor.linkedObject;
3050 spin = object->effect.spin;
3051 object->effect.x =
3052 anchor->x.fixed + Engine_MathCos(spin) * (object->actor.speed + 28);
3053 object->effect.z = Engine_MathSin(spin) * 16 + PIXELS(164);
3054 object->actor.targetX = object->effect.x;
3055 object->actor.targetZ = object->effect.z;
3056 object->effect.spin -= 0x200;
3057}
3058
3060 SC_WAIT(1), SC_LOOP(22, SC_TOP), SC_WAIT(1),
3061 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
3062};
3063
3065 SC_WAIT(1), SC_LOOP(44, SC_TOP), SC_WAIT(1),
3066 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
3067};
3068
3070 SC_WAIT(1), SC_LOOP(126, SC_TOP), SC_WAIT(1),
3071 SC_POS(0, 0, 0), SC_WAIT(1), SC_FREE,
3072};
3073
3078};
3079
3081 SC_ARG(2), SC_MOVE(PIXELS(492), 0, PIXELS(164)),
3082 SC_SYNC, SC_ARG(1),
3083 SC_POS(0, 0, 0), SC_WAIT(1),
3084 SC_END,
3085};
3086
3088 SC_SET(SW_SPEED, PIXELS(1) / 5),
3089 SC_SET(SW_ACCEL, PIXELS(1) / 10),
3090 SC_ARG(2),
3091 SC_MOVE_BY(-PIXELS(8), 0, 0),
3092 SC_SYNC,
3093 SC_END,
3094};
3095
3097 SC_SET(SW_SPEED, PIXELS(1) / 5),
3098 SC_SET(SW_ACCEL, PIXELS(1) / 10),
3099 SC_ARG(2),
3100 SC_MOVE_BY(PIXELS(8), 0, 0),
3101 SC_SYNC,
3102 SC_END,
3103};
3104
3108};
3109
3111 SC_ADD(SW_SCALE_X, Q16_ONE / 16),
3112 SC_WAIT(1),
3113 SC_LOOP(32, SC_TOP),
3114 SC_END,
3115};
3116
3118 SC_ADD(SW_SCALE_X, -896),
3119 SC_WAIT(1),
3120 SC_LOOP(140, SC_TOP),
3121 SC_END,
3122};
3123
3125 SC_ADD(SW_SCALE_X, -896),
3126 SC_WAIT(1),
3127 SC_LOOP(160, SC_TOP),
3128 SC_END,
3129};
3130
3132 SC_ADD(SW_Y, PIXELS(4)), SC_WAIT(1), SC_LOOP(30, SC_TOP),
3133 SC_POS(0, 0, 0), SC_WAIT(1), SC_END,
3134};
3135
3137 SC_ADD(SW_Y, PIXELS(2)), SC_WAIT(1), SC_LOOP(160, SC_TOP),
3138 SC_POS(0, 0, 0), SC_WAIT(1), SC_END,
3139};
3140
3142 SC_SET(SW_SCALE_X, 4 * Q16_ONE / 5),
3143 SC_SET(SW_SCALE_Y, 4 * Q16_ONE / 5),
3144 SC_ARG(1),
3145 SC_LABEL(1),
3146 SC_ADD(SW_Y, PIXELS(1)),
3147 SC_WAIT(1),
3148 SC_LOOP(16, SC_TO(1)),
3149 SC_POS(0, 0, 0),
3150 SC_WAIT(1),
3151 SC_FREE,
3152};
3153
3155 SC_SET(SW_SCALE_X, 4 * Q16_ONE / 5),
3156 SC_SET(SW_SCALE_Y, 4 * Q16_ONE / 5),
3157 SC_ARG(1),
3158 SC_LABEL(1),
3159 SC_ADD(SW_Y, -PIXELS(1)),
3160 SC_WAIT(1),
3161 SC_LOOP(16, SC_TO(1)),
3162 SC_POS(0, 0, 0),
3163 SC_WAIT(1),
3164 SC_FREE,
3165};
3166
3168 SC_ARG(2), SC_MOVE(PIXELS(268), 0, PIXELS(186)),
3169 SC_SYNC, SC_MOVE(PIXELS(268), 0, PIXELS(252)),
3170 SC_SYNC, SC_MOVE(PIXELS(232), 0, PIXELS(222)),
3171 SC_SYNC, SC_MOVE(PIXELS(232), 0, PIXELS(136)),
3172 SC_SYNC, SC_MOVE(PIXELS(200), 0, PIXELS(136)),
3173 SC_SYNC, SC_MOVE(PIXELS(200), 0, PIXELS(200)),
3174 SC_SYNC, SC_ARG(1),
3175 SC_POS(0, 0, 0), SC_WAIT(1),
3176 SC_END,
3177};
3178
3180 SC_LABEL(1),
3181 SC_ADD(SW_SCALE_X, -1536),
3182 SC_WAIT(1),
3183 SC_LOOP(4, SC_TO(1)),
3184 SC_LABEL(2),
3185 SC_ADD(SW_SCALE_X, 1536),
3186 SC_WAIT(1),
3187 SC_LOOP(4, SC_TO(2)),
3189};
3190
3192 SC_ADD(SW_Y, -(PIXELS(3) / 4)),
3193 SC_WAIT(1),
3194 SC_LOOP(120, SC_TOP),
3195 SC_POS(0, 0, 0),
3196 SC_WAIT(1),
3197 SC_END,
3198};
3199
3201 SC_ADD(SW_Y, -(PIXELS(9) / 2)),
3202 SC_WAIT(1),
3203 SC_LOOP(80, SC_TOP),
3204 SC_POS(0, 0, 0),
3205 SC_WAIT(1),
3206 SC_END,
3207};
3208
3210 SC_ARG(2), SC_MOVE(PIXELS(330), 0, PIXELS(173)), SC_SYNC, SC_FREE, SC_END,
3211};
3212
3216};
3217
3219 {0, CONDITION_ALWAYS, 304, 0, 216, FACING_SOUTHEAST + FACING_STEP, 0, 0, 0,
3220 600, 420, 0},
3222 FACING_SOUTHEAST + FACING_STEP, 0, 0, 0, 600, 420, 0},
3224 FACING_WEST, 0, 0, 0, 600, 420, 0},
3226 FACING_WEST, 0, 0, 0, 600, 420, 0},
3228 600, 420, 0},
3230};
3231
3233 SCENE_EXITS(187),
3239};
3240
3241// clang-format off
3243 { 0x102, CONDITION_ALWAYS, ACTOR_STAND,
3244 PIXELS(248), 0, PIXELS(136), FACING_SOUTH, TALK_KEEP_FACING, 0 },
3245 { 0x102, CONDITION_ALWAYS, ACTOR_STAND,
3247 { 0x102, CONDITION_ALWAYS, ACTOR_STAND,
3249 { 0x102, CONDITION_ALWAYS, ACTOR_STAND,
3251 { 0xf2, CONDITION_ALWAYS, 7,
3252 PIXELS(440), 0, PIXELS(252), FACING_SOUTH, TALK_KEEP_FACING, 0 },
3253 { 0xf2, CONDITION_ALWAYS, 7,
3255 { 0xf2, CONDITION_ALWAYS, 7,
3257 { 0xf2, CONDITION_ALWAYS, 7,
3259 { 0xf2, CONDITION_ALWAYS, 7,
3261 { 0xf2, CONDITION_ALWAYS, 7,
3263 { 0xf2, CONDITION_ALWAYS, 7,
3266 PIXELS(504), 0, PIXELS(148), FACING_SOUTH, TALK_KEEP_FACING, 0 },
3268 PIXELS(504), 0, PIXELS(148), FACING_SOUTH, TALK_KEEP_FACING, 0 },
3270 PIXELS(504), 0, PIXELS(148), FACING_SOUTH, TALK_KEEP_FACING, 0 },
3272 PIXELS(280), 0, PIXELS(164), FACING_NORTH + FACING_STEP, TALK_KEEP_FACING, 0 },
3276 PIXELS(248), 0, PIXELS(172), FACING_EAST, TALK_KEEP_FACING, 0 },
3278 PIXELS(264), 0, PIXELS(252), FACING_NORTH + FACING_STEP, TALK_KEEP_FACING, 0 },
3280 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
3282 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
3284 0, 0, 0, FACING_SOUTH, TALK_KEEP_FACING, 0 },
3293 { SCENE_TABLE_END },
3294};
3295// clang-format on
3296
3298
3309};
3310
3312 SC_SET(SW_SCALE_Y, 7 * Q16_ONE / 5),
3313 SC_SET(SW_SCALE_X, 7 * Q16_ONE / 5),
3314 SC_ARG(4),
3315 SC_WAIT(30),
3316 SC_FREE,
3317};
void ObjectGroup_SetChildValue(struct FieldActor *actor, s32 param)
Sets the param byte of every animated part of an actor's sprite.
void Object_RefreshSelectorById(u32 objectId)
Waits, at most 300 frames, for an actor's script to reach its end (command 0x10).
void ObjectMotion_WaitForAnimationChange(u32 objectId)
Waits, at most 90 frames, for an actor's animation to change.
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
void ObjectTable_Snapshot(void)
Saves up to 32 actors (only the party's 8 on the world map) into gObjectSnapshots,...
Definition actors.c:488
s32 AnimationObjects_SelectAnimation(struct AnimationObject *sprite, s32 animation)
Starts animation flags & 0x7f on every layer of a sprite (bit 7 keeps each layer's place and timer),...
Definition animation.c:317
Animated sprites: their layers, frames and colour modes, and the resource slots they draw from.
B5Context, the object context a battle routine reads; most of its fields are still unnamed.
s32 gEffectScript0[]
const s32 * gEffectScripts[]
s32 gEffectScript1[]
s32 gEffectScript2[]
Calls through a function pointer, by argument count.
The task scheduler: tasks, their order and the scheduler's state.
#define GARET
Jerald.
#define MIA
Mary.
#define SHEBA
Sheba.
#define IVAN
Ivan.
The engine calls a scene uses to create an overlay object and set its sprite flags.
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
struct FieldActor * Engine_ObjectCreate(s32, s32, s32, s32)
The engine calls the debug menus import, and their palette swatch tiles.
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
static s32 FieldObject_CheckMovementCollision(struct FieldActor *actor, struct FieldPosition *position)
Definition engine_call.h:66
Scene commands: the all-caps macros the scene scripts are written in.
#define OBJ_GET(no)
Gets an object by index as the same union FieldObject passed to update hooks.
Definition event.h:23
void ObjectSystem_ResumeProjectionAndHideLayers(void)
Resumes the object camera updates and hides BG1-3 and the sprites.
Definition objects.c:566
void ObjectSystem_SuspendProjectionAndShowSprites(void)
Suspends the object camera updates, starts the palette back to normal and, a frame later,...
Definition objects.c:552
Field effects, their scripts and the flags that spawn them.
@ EFFECT_USE_PALETTE
options.palette, as its group child value
@ EFFECT_USE_UPDATE
options.update
@ EFFECT_USE_START_SCALE
options.startScaleX and startScaleY
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
@ ANIM_STAND
Definition field_event.h:43
@ ANIM_NOD
Definition field_event.h:45
@ ANIM_SHAKE_HEAD
Definition field_event.h:46
#define SPEAKER_PORTRAIT_LEFT
Definition field_event.h:54
u32 Math_RemainderUnsigned(u32 dividend, u32 divisor)
static s32 Event_OpenMessage(s32 speaker, s32 flags)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Object_SetMode(struct FieldActor *object, s32 animation)
#define SPEAKER_WINDOW_ABOVE
Definition field_event.h:56
void Engine_ActorsRefresh(void)
void Engine_ActorSetSpritePriority(s32 actor, s32 priority)
static void Event_ShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
s32 Engine_EventChooseYesNo(s32 actor, s32 flags)
void Engine_MessageShowCentered(s32 message, s32 flags)
void Engine_ObjectSetPartPalettes(struct FieldActor *object, s32 palette)
void Engine_EventShowMessageAndWait(s32 speaker, s32 flags, s32 frames)
#define GameFlag_IsSet
#define SPEAKER_PORTRAIT_RIGHT
Definition field_event.h:55
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
static void Camera_SetSpeed(s32 speed, s32 acceleration)
void Engine_CameraMoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
void Engine_ActorMoveToAndWait(s32 actor, s32 x, s32 z)
void Engine_ActorJump(s32 actor, s32 height, s32 frames)
#define EMOTE_IN_FRONT
Definition field_event.h:49
static void Actor_MoveToAndWait(s32 actor, s32 x, s32 z)
s32 Engine_MathSin(s32 angle)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_EventCloseScreen(void)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
static void Actor_RunActionScriptAndWait(s32 actor, const s32 *script)
Runs a script, waiting at most 300 frames for its final command.
static void Map_CopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
void Engine_ActorWalkToAndWait(s32 actor, s32 x, s32 z)
#define SPEAKER_WINDOW_BELOW
Definition field_event.h:57
static void ColorBuffer_ApplyTarget(s32 value, s32 mode)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
void Engine_ActorDestroy(s32 actor)
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_EventOpenScreen(void)
s32 Engine_EventOpenMessage(s32 speaker, s32 flags)
void Engine_GameFlagSet(s32 flag)
void Engine_GameFlagClear(s32 flag)
void Engine_CameraWaitForMove(void)
static void Actor_SetActionScript(s32 actor, const s32 *script)
The engine encodes either a built-in action or an action-script address.
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorStop(s32 actor)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
void Engine_ActorWalkTo(s32 actor, s32 x, s32 z)
static void Event_ShowMessage(s32 speaker, s32 flags)
void Engine_ActorSetAttachedEffect(s32 actor, s32 effect)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
void Engine_ActorSetChildValue(s32 actor, s32 value)
static void Map_SetShake(s32 horizontal, s32 vertical, s32 decay)
Sets shake amplitudes in fixed-point pixels and the per-frame decay factor.
static void Actor_SetChildValue(s32 actor, s32 value)
s32 Engine_GameFlagIsSet(s32 flag)
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static struct FieldActor * Object_Create(s32 type, s32 fixed_x, s32 fixed_y, s32 fixed_z)
struct FieldActor * Engine_EventGetViewCenter(void)
s32 Engine_MathCos(s32 angle)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
@ TASK_PRIORITY_SCENE
Definition field_event.h:40
void Engine_MapRedraw(void)
static s32 Random_Next(void)
void Engine_ColorBufferInterpolate(s32 frames)
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_EventWait(s32 frames)
static void Actor_SetAttachedEffect(s32 actor, s32 effect)
void Engine_ColorBufferApplyTarget(s32 value, s32 mode)
static void Object_SetScript(struct FieldActor *object, const s32 *script)
static struct FieldActor * Actor_Get(s32 actor)
static void ColorBuffer_ApplySource(s32 value, s32 mode)
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
@ ACTOR_PRIORITY_AUTOMATIC
The sprite takes its priority from the map cell under it.
Definition field_obj.h:153
@ ACTOR_FOLLOWS_TERRAIN
moves with the ground height under it
Definition field_obj.h:160
@ ACTOR_FALLS
falls by its gravity and bounces
Definition field_obj.h:161
#define ACTOR_NO_TARGET
A target coordinate that is not set: the object has no target.
Definition field_obj.h:145
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
@ ACTOR_FACES_MOTION
turns toward its velocity, 1/16 turn a frame
Definition field_obj.h:166
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
@ EVENT_TOUCH
@ FACING_STEP
Definition field_scene.h:36
#define SCENE_EXITS(scene)
Definition field_scene.h:72
@ SCENE_WORLD_MAP
Definition field_scene.h:13
#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
#define EVENT_SCRIPT(script)
#define EVENT_TOUCH_WALKING
@ ACTOR_STAND
#define SCENE_EXITS_END
Definition field_scene.h:77
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
@ FACING_NORTHEAST
Definition field_scene.h:33
@ FACING_EAST
Definition field_scene.h:26
@ FACING_SOUTHEAST
Definition field_scene.h:27
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_SOUTHWEST
Definition field_scene.h:29
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static s32 Task_AddCallback(void(*callback)(void), s32 priority)
Calls the main-image scheduler through engine_call.h.
static void Actor_RunRepeatedMotion(s32 actor, s32 repeats)
static struct FieldActor * Event_GetViewCenter(void)
static s32 Vram_Load(s32 block, s32 size, const void *data)
static void Task_Wait(s32 frames)
static void Actor_Stop(s32 actor)
static void Event_Begin(void)
static void Actor_StartRepeatedMotion(s32 actor, s32 repeats)
static void Actor_SetSpriteFlags(struct FieldActor *actor, s32 flags)
static void ColorBuffer_Interpolate(s32 frames)
static void Actor_SetSpritePriority(s32 actor, s32 priority)
static void Map_Redraw(void)
static void Actor_SetAnimation(s32 actor, s32 animation)
static void Actor_SetAnimationAndWait(s32 actor, s32 animation)
static void Event_Wait(s32 frames)
static void Event_WaitForScreen(void)
static void Item_LoadIcon(s32 item)
static void Heap_Release(s32 slot)
static void Actor_Jump(s32 actor, s32 height, s32 frames)
static s32 Event_ChooseYesNo(s32 actor, s32 flags)
static void Event_SetMessage(s32 message)
static void FieldObject_SetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
static void * Heap_Allocate(s32 slot, s32 size)
static void Event_OpenScreen(void)
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_RETURNED_FROM_VENUS_LIGHTHOUSE
The party is back from Venus Lighthouse, by the aerie's exit.
Definition flags.h:272
#define FLAG_SCENE_TEMP_35
Definition flags.h:766
#define FLAG_VENUS_LIGHTHOUSE_LIT
Definition flags.h:29
#define FLAG_KEEP_MUSIC
The next scene keeps the music that is playing; scene.c clears FLAG_KEEP_MUSIC as it does,...
Definition flags.h:35
#define FLAG_SCENE_TEMP_34
Definition flags.h:765
#define FLAG_SCENE_TEMP_37
Definition flags.h:768
#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_SCENE_TEMP_36
Definition flags.h:767
#define FLAG_SCENE_TEMP_50
Definition flags.h:793
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,...
#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.
void * gMapWork[]
void * gEffectWork
Slot 56: points to a scene-specific structure.
The screen blend's globals and the graphics routines.
The heap's work slots and HeapState.
@ HEAP_SLOT_WINDOW
Definition heap_state.h:39
@ HEAP_SLOT_EVENT
Definition heap_state.h:40
#define WORK_SLOT(n)
Reads slots through their own addresses; adjacent slots are reached by offsets.
Definition heap_state.h:14
The main-image routines scene overlays import.
s32 Inventory_AddItem(s32 owner, s32 itemId)
Gives a unit one item, joining its first matching stack (up to 30) or taking the first free slot.
Definition inventory.c:144
s32 PartyInventory_FindOwner(s32 itemId)
Returns who carries itemId, asking the selected character first, or -1.
Definition inventory.c:229
s32 PartyInventory_Remove(s32 itemId)
Removes one itemId from whoever carries it first; always returns 0.
Definition inventory.c:410
The hardware's I/O registers and their bits, as pret names them.
#define PLTT_BACKDROP
Definition io_reg.h:155
Item numbers, named from the English release.
@ ITEM_VENUS_STAR
Definition item_ids.h:63
@ ITEM_SHAMANS_ROD
Definition item_ids.h:20
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
Small statement macros both games use for positions, velocities and bounds.
#define SET_VELOCITY(p, vx, vy, vz)
Definition macros.h:18
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
Definition macros.h:12
The map layers' scroll work and the background scroll values.
void Vector_AddPolarOffset(s32 radius, s32 angle, void *position)
Moves the point position by radius in direction angle on the ground plane: x by the cosine,...
Definition math.c:23
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_LABEL(n)
Branch destination.
Definition objcmd.h:11
#define SC_SET(w, v)
Write a work value.
Definition objcmd.h:37
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_FREE
Release.
Definition objcmd.h:43
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_FOREVER
Definition objcmd.h:14
#define SC_TO(n)
Definition objcmd.h:12
#define SC_ADD(w, v)
Definition objcmd.h:38
#define SC_ARG(v)
Definition objcmd.h:44
#define SC_MOVE(x, y, z)
Move toward the target.
Definition objcmd.h:19
#define SC_WAIT(n)
Wait n frames.
Definition objcmd.h:16
#define SC_TOP
Script start.
Definition objcmd.h:13
#define SC_END
Return to the main script.
Definition objcmd.h:32
#define SC_MOVE_BY(x, y, z)
Move by a relative offset.
Definition objcmd.h:20
@ SW_ACCEL
Definition objcmd.h:68
@ SW_SCALE_Y
Definition objcmd.h:63
@ SW_SPEED
Definition objcmd.h:67
@ SW_Y
Definition objcmd.h:59
@ SW_SCALE_X
Definition objcmd.h:62
#define SC_CALL(fn)
Definition objcmd.h:50
void Event_SetDestination(s32 scene, s32 entrance)
Makes the event leave for the given entrance of the given scene: raises the exit request 999 and writ...
Definition events.c:517
static s32 Scene_LookAboutRandomly(struct ScriptInterpreter *interpreter)
An object script call, each frame: when the actor's countdown (work) runs out, it turns by a random a...
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
Palette fades, the battle effect palette buffers and the colour channel curves.
@ PALETTE_TRANSFORM_PLAIN
each colour unchanged
Definition palbuf.h:72
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_SetDefeatDestination(s32 scene, s32 entrance)
Sets where the party wakes up after losing a battle (gGameState.defeatScene and defeatEntrance).
Definition requests.c:70
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
Scene numbers, named after their places.
char SceneId_WorldMap
char SceneId_VenusLighthouseAerie
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define MUS_054
Definition songs.h:58
#define SE_308
Definition songs.h:296
#define SE_220
Definition songs.h:215
#define MUS_029
Definition songs.h:39
#define MUS_063
Definition songs.h:67
#define SE_131
Definition songs.h:124
#define MUS_062
Definition songs.h:66
#define SE_187
Definition songs.h:182
#define SE_288
Definition songs.h:281
#define MUS_023
Definition songs.h:33
#define MUS_061
Definition songs.h:65
#define SE_309
Definition songs.h:297
#define MUS_017
Definition songs.h:27
#define SE_141
Definition songs.h:134
#define SE_212
Definition songs.h:207
#define MUS_019
Definition songs.h:29
#define SE_ITEM_BREAK
Definition songs.h:131
#define MUS_072
Definition songs.h:74
#define SE_145
Definition songs.h:138
#define SE_161
Definition songs.h:156
#define SE_246
Definition songs.h:241
#define SE_JUMP
An actor jumps: ObjectMotion_Launch plays the high jump above 5 pixels a frame.
Definition songs.h:147
#define SE_289
Definition songs.h:282
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_ActorShowEmote()
void Engine_TaskWait()
void Engine_EventSetMessage()
void Engine_EventShowMessage()
#define NULL
Definition bilibin.h:6
Vale, its home, storm and Babi scenes, Sol Sanctum's eruption and Venus Lighthouse's aerie: Psynergy ...
void Scene_EndCutscenePsynergy(void)
Ends the cutscene's Psynergy and releases its effect work.
void Scene_BeginCutscenePsynergy(void)
Prepares the effect work and spark tiles of Move (ability 140) for the cutscene's Psynergy.
s32 SceneActor_FindNearestSlotOfKindF2(void)
Returns the placed actor drawn with sprite 0xf2 nearest the leader, within 640 pixels,...
The pushable actors' movement probes and footprint bounds.
u8 frame
frame shown, frameBase plus the facing offset; 255 none
Definition animspr.h:53
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
u16 rotation
1/65536 turns
Definition animspr.h:118
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
struct AnimationEntry * entries[4]
its layers; empty ones null
Definition animspr.h:130
u8 count
layers in use, up to the last one present
Definition animspr.h:129
u8 retainCacheEntry
Keeps the VRAM cache entry when it is released or off screen.
Definition animspr.h:114
u16 fullColor
256 colours; set for both parts when created
Definition animspr.h:94
u16 tile
first sprite tile in VRAM
Definition animspr.h:99
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
u16 tileSlot
resource entry holding the spark tiles
Definition fx_scene.h:64
void * child
the target's object, or NULL
Definition fx_scene.h:37
The options of a spawned field effect, each used when its EFFECT_USE_ flag (or EFFECT_SCALE_TO_TARGET...
s32 palette
passed to ObjectGroup_SetChildValue
s32 startScaleY
16.16 fixed point, 0x10000 full size
s32 startScaleX
16.16 fixed point, 0x10000 full size
void(*) update(union FieldObject *object)
replaces the update hook
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
Definition event_work.h:20
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
s32 transitionFrames
frames
Definition event_work.h:45
u16 message
the next message, advanced as each window opens
Definition event_work.h:47
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s16 timer
The parameter its action script reads (a follow distance or an angle to face), the player's frames to...
Definition field_obj.h:109
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
struct FieldActor * linkedObject
The object its action script follows or faces.
Definition field_obj.h:114
u8 steeringFlags
ActorSteeringFlag bits.
Definition field_obj.h:92
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
u8 riseCounter
not read by the engine; scene code's own counter
Definition field_obj.h:105
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 targetZ
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:61
u8 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 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
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
s32 targetY
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:60
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition field_obj.h:40
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
s32 riseBaseY
Zeroed by FieldObject_Create and not read by the engine; scene code keeps a resting height,...
Definition field_obj.h:71
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
s32 velocityZ
16.16 fixed-point pixels per frame
Definition field_obj.h:54
u8 riseEnabled
not read by the engine; scene code's own state
Definition field_obj.h:106
struct Vector3 velocity
Added to x, y and z each frame by the update hooks, in 16.16 fixed-point pixels per frame; FieldActor...
A position on the field.
s16 entrance
Definition game_state.h:37
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
s32 viewY
the view's top left, 16.16 fixed-point pixels
Definition map_scroll.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
The window system's work: the windows' tilemap, the windows, the three text channels,...
Definition window.h:19
u16 speakerVoiceCountdown
characters until the next voice blip
Definition window.h:61
u16 speakerVoiceSound
first of four voice blip sounds; 0 for none
Definition window.h:60
s32 x
Definition vector3.h:22
s32 y
Definition vector3.h:23
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
Values that differ by patch level or language, chosen once for their code.
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define TRUE
Definition types.h:21
#define FALSE
Definition types.h:20
unsigned char u8
Definition types.h:11
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldActor actor
struct FieldEffect effect
void Party_RestorePpOfLitElements(void)
Restores the PP of each party member whose element group has a lit lighthouse: Venus or Mars for grou...
Definition units.c:685
static void VenusLighthouseAerie_UpdateBeamActors(void)
Pulses and slides Saturos and Menardi while their beam flags are active.
static void VenusLighthouseAerie_PlayShebasFall(void)
Shows Sheba falling, Felix jumping after her and the party escaping.
s32 gVenusLighthouseAerie_BeamRiseAction[]
static void VenusLighthouseAerie_FlashActorPalette(struct FieldActor *actor)
Flashes an actor palette and emits paired effects every fifteenth frame.
s32 gVenusLighthouseAerie_LeapAction[]
static void VenusLighthouseAerie_CombineSaturosAndMenardi(void)
Shows the Venus Star lighting the beacon and the antagonists combining.
static void VenusLighthouseAerie_StepSpriteRotation(union FieldObject *fieldObject)
Turns the falling actor sprite until its rotation leaves the negative half-turn.
static void VenusLighthouseAerie_ShowMessage(s32 speaker)
struct ScenePlacement gVenusLighthouseAeriePlacements[]
s32 gVenusLighthouseAerie_BeamNarrowAction[]
s32 gVenusLighthouseAerie_StepBackAction[]
s32 gVenusLighthouseAerie_OrbitParticleScript[]
s32 gVenusLighthouseAerie_PairActionScript[]
s32 gVenusLighthouseAerie_WalkOutAction[]
static s32 VenusLighthouseAerie_PulseActorScale(struct ScriptInterpreter *interpreter)
Pulses the actor scale around the countdown, then chooses its next pause.
static void VenusLighthouseAerie_SpawnLinkedPairEffects(struct FieldActor *parent)
Spawns two vertical effects using the parent position and shared cached tiles.
const u32 * VenusLighthouseAerie_GetExits(void)
static void VenusLighthouseAerie_SpawnSideOrbitParticles(void)
Emits particles beside the lower beam and links each to its source actor.
#define FLAG_SHAMANS_ROD_OWNER
Plus the party member (0 to 3) who carried the Shaman's Rod when it was handed over before the aerie'...
static void VenusLighthouseAerie_EnterAndConfrontAntagonists(void)
Brings the party onto the aerie and reveals the argument over Sheba.
static s32 sTransitionTimer
const struct SceneEvent * VenusLighthouseAerie_GetEvents(void)
Returns the pillar and confrontation triggers.
static void VenusLighthouseAerie_TryToPreventFall(void)
Shows Felix urging Sheba to hold on at the edge of the platform.
static void VenusLighthouseAerie_StopActorMotion(struct FieldActor *actor)
Clears all movement targets and velocities and resets the actor timer.
s32 gVenusLighthouseAerie_PartyHeadingAction[]
static void Event_JumpToNextPillar(void)
Walking off the edge of a pillar: if the ground two tiles ahead is clear, the leader jumps across to ...
static void VenusLighthouseAerie_ShowGroupEmote(s32 emote, s32 waitFrames)
Gives Felix, Sheba and the party the same reaction, then waits after Mia.
s32 gVenusLighthouseAerie_PartyExitAction[]
static void VenusLighthouseAerie_CycleActorPalette(struct FieldActor *actor)
Cycles the actor palette and emits paired effects every fifteenth frame.
static void Event_ConfrontSaturosAndMenardi(void)
Walking up to Saturos and Menardi: they promise not to harm Sheba for the Shaman's Rod,...
const struct SceneRegion * VenusLighthouseAerie_GetRegions(void)
s32 VenusLighthouseAerie_Initialize(void)
Restores the platforms and runs the scene selected by the arrival.
s32 gVenusLighthouseAerie_BeamEndAction[]
static void VenusLighthouseAerie_ShowShebaInDanger(void)
A look back from the world map: Felix cries out as Sheba clings to the broken aerie,...
static __inline__ s32 Actor_IsParked(struct FieldActor *actor)
Tests whether all three movement targets are unset.
static void VenusLighthouseAerie_UpdateOrbitingEffect(union FieldObject *object)
Moves a linked particle along its horizontal ellipse and preserves its target.
static void VenusLighthouseAerie_UpdateBeaconRise(void)
Advances the beacon rise sequence, its flashes and orbiting particles.
const struct ScenePlacement * VenusLighthouseAerie_GetPlacements(void)
Returns the platforms, antagonists, companions and beacon effects.
static void VenusLighthouseAerie_SpawnUpperOrbitParticles(void)
Emits rising particles around the upper beam at the current beacon stage.
static void VenusLighthouseAerie_DiscussSaturosAndMenardiDefeat(void)
Lets the party discuss the battle while Felix and Sheba remain on the aerie.
static void VenusLighthouseAerie_UpdateDriftingParticle(union FieldObject *object)
Moves a particle, damps its horizontal velocity and updates its scale and spin.
static void VenusLighthouseAerie_AimBurst(s32 velocity[3], s32 angle)
Builds the horizontal velocity for an elliptical radial particle burst.
static void VenusLighthouseAerie_UpdateUpperOrbit(union FieldObject *fieldObject)
Orbits a particle around the upper beam and keeps its target at that position.
static void VenusLighthouseAerie_UpdateShebaPalette(void)
static void Event_SteadyPillars(void)
Stepping back onto the floor, and before each jump: the leader walks and falls normally again and the...
struct SceneEntrance gVenusLighthouseAerieEntrances[]
static s32 sTransitionStep
static void VenusLighthouseAerie_AdvanceActorRise(struct FieldActor *actor)
Raises an enabled actor according to its gated rise counter.
s32 gVenusLighthouseAerie_RiseParticleScript[]
static void VenusLighthouseAerie_UpdateRisingOrbit(union FieldObject *fieldObject)
Orbits a particle around the rising beam using its rise counter as a radius.
s32 gSceneAction_EntryPair[]
static void VenusLighthouseAerie_FinishSaturosAndMenardiBattle(void)
Plays the antagonists' defeat, the party discussion and the beacon eruption.
static void Event_LandOnPillar(void)
Landing on a pillar: it dips under the leader and springs back up.
s32 gVenusLighthouseAerie_BeamCloseAction[]
struct SceneEvent gVenusLighthouseAerieEvents[]
static void VenusLighthouseAerie_ShowPartyMember(s32 actor, s32 shown)
Shows or hides one companion, setting its movement speed when shown.
static void VenusLighthouseAerie_RestorePartyOnBrokenAerie(void)
Places the party on the broken platform and resumes its falling effects.
s32 gVenusLighthouseAerie_ScaleStepAction[]
u32 gVenusLighthouseAerieExits[]
static void VenusLighthouseAerie_ShowSaturosAndMenardiFall(void)
Shows Saturos and Menardi falling into the beacon after their final defeat.
static void VenusLighthouseAerie_FlashScreen(void)
Flashes the object palette white, then restores the transformation colour.
s32 gVenusLighthouseAerie_BeamOpenAction[]
s32 gSceneAction_EntryGroup[]
static void VenusLighthouseAerie_FaceActor(s32 actor, s32 facing)
Turns one actor and waits ten frames.
const struct SceneEntrance * VenusLighthouseAerie_GetEntrances(void)
static void VenusLighthouseAerie_StageShebasFall(void)
Stages the broken aerie for the fall sequence and the party escape.
s32 gVenusLighthouseAerie_RiseActionScript[]
s32 gVenusLighthouseAerie_BesideParticleScript[]
static void VenusLighthouseAerie_EruptBeacon(void)
Raises the beacon effects and splits the aerie beneath the group.
s32 gVenusLighthouseAerie_NearestActor
Venus Lighthouse aerie's actors, entrances and exits.
@ AERIE_EXIT_AFTER_DEFEAT
@ AERIE_EXIT_TO_WORLD_MAP
@ AERIE_EXIT_AFTER_SHEBAS_FALL
@ ACTOR_PARTICLE_SOURCE
The light the rising particles circle as the party is lifted away.
@ ACTOR_AERIE_WEST_SECTION_B
@ ACTOR_BEAM_1
The beacon's beam, in five segments from the bottom up; particles circle the first.
@ ACTOR_FIRST_PILLAR
Six pillars the leader jumps across, and the one that carries him up to the aerie.
@ ACTOR_AERIE_EAST_SECTION_A
@ ACTOR_AERIE_WEST_SECTION_A
The aerie floor around the beacon, in four sections: the first two move west and the last two (drawn ...
@ ACTOR_LAST_PILLAR
@ ACTOR_AERIE_EAST_SECTION_B
@ ACTOR_MOVING_PILLAR
@ ACTOR_STAR_CARRIER
What carries the Venus Star to the beacon.
@ WORLD_MAP_ENTRANCE_FROM_AERIE
@ AERIE_ENTRANCE_AFTER_FIRST_BATTLE
Back from the battle with Saturos and Menardi, and from the one with their fused form.
@ AERIE_ENTRANCE_ARRIVAL
Up from Venus Lighthouse: the party rides a pillar up to the aerie.
@ AERIE_ENTRANCE_SHEBA_IN_DANGER
From the world map, after the beacon is lit: a look back at Felix and Sheba on the broken aerie.
@ AERIE_ENTRANCE_DEFEAT
Back from a lost battle.
@ AERIE_ENTRANCE_AFTER_SECOND_BATTLE
@ AERIE_ENTRANCE_SHEBAS_FALL
From the world map, onto the broken aerie: Sheba falls and Felix leaps after her.
Declares nothing of its own: it only includes the window, battle command, resource and VRAM table hea...
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
The sprite VRAM block cache and its owners.
struct VramBlockCacheEntry gVramBlockCache[]
void UiText_ShowCenteredMessage(s32 message, s32 mode, s32 yOffset)
Shows a message centred on the screen (yOffset tiles lower) and waits until it is typed out,...
Definition messages.c:325
The window renderer's work.