Alchemy
Loading...
Searching...
No Matches

object_staged_actor.h

Go to the documentation of this file.
1#include "unit/field/field.h"
2#include "battle.h"
3#include "engine_call.h"
4#include "debug.h"
5#include "field.h"
6#include "game.h"
7#include "graphics.h"
8#include "menu.h"
9#include "minigame.h"
10#include "sound.h"
11#include "system.h"
12#include "global_cells.h"
13#include "mapcopy.h"
14#include "staged_actor.h"
16#include "iwram_call.h"
17#include "call.h"
18#include "field_runtime.h"
19#include "map.h"
20#include "map_scroll.h"
21#include "field_event.h"
22#include "types.h"
23#include "songs.h"
24
25// Seventeen scenes with things the leader pushes (Altmiller Cave, Babi
26// Lighthouse, Crossbone Isle and its rooms, Goma Cave's pillar room, Gondowan
27// Cave, Kolima's forest bridge, clearing and river, Lunpa's fortress, Mercury
28// Lighthouse and its entrance, Mogall Forest, the Tunnel Ruins, Vale and its
29// cave): blocks pushed a cell at a time, and logs and other large things that
30// roll until they meet something, redrawn into the map where they stop.
31//
32// A large thing is one of six footprints, by its sprite's animation
33// (gStagedActor_FootprintKinds): its bounds in gStagedActor_FootprintBounds
34// are four words a footprint, the left, top, right and bottom edges in pixels
35// from its position.
36
37/// Pixel step by direction: X in the upper halfword, Z in the lower.
40
41#include "object_distance.h"
42
43/// Returns the placed actor on the cell of the 16.16 position and at its height
44/// (in whole pixels), or 0. origin is not read.
45static struct FieldActor *
47 const struct FieldActor *origin) {
48 struct FieldWork *work = (struct FieldWork *)gEventWork;
49 struct FieldActor **slots = work->actors;
50 u32 i;
51
52 for (i = ACTOR_FIRST_PLACED;
53 i < sizeof(work->actors) / sizeof(work->actors[0]); i++) {
54 struct FieldActor *actor = (struct FieldActor *)slots[i];
55
56 // UB: ObjectTable_ClearAll leaves unfilled slots null. The guard grows
57 // this helper from 0x58 to 0x5c bytes in the native English trial.
58#ifdef UBFIX
59 if (actor == NULL)
60 continue;
61#endif
62 if ((position->x >> 20) == (actor->x.fixed >> 20) &&
63 (position->y / 0x10000) == (actor->y.fixed / 0x10000) &&
64 (position->z >> 20) == (actor->z.fixed >> 20)) {
65 return actor;
66 }
67 }
68 return 0;
69}
70
71/// The leader pushes the block in front of them a cell on, unless something
72/// solid is beyond it or on top of it, the ground beyond refuses it or it is
73/// still moving: after a quarter second's push (mode 8) the block and the
74/// leader slide one cell together, with SE_185.
76 struct FieldPosition dst;
77 struct FieldActor *lead;
78 struct FieldActor *next;
79 struct FieldActor *blocker;
80 s32 dir;
81 u32 step;
82 s32 rate;
83
84 lead = Object_GetById(0);
85 dir = lead->facing >> 12;
87 dst.x = lead->x.fixed + (step & 0xffff0000);
88 dst.y = lead->y.fixed;
89 step <<= 16;
90 dst.z = lead->z.fixed + step;
91 next = StagedActor_FindAtTile(&dst, lead);
92 if (next == 0)
93 return;
94
96 dst.x = next->x.fixed + (step & 0xffff0000);
97 dst.y = next->y.fixed;
98 step <<= 16;
99 dst.z = next->z.fixed + step;
100 blocker = StagedActor_FindAtTile(&dst, next);
101 if (blocker != 0 && (blocker->collisionFlags & 1) != 0)
102 return;
103
104 dst.x = next->x.fixed;
105 dst.y = next->y.fixed + 0x100000;
106 dst.z = next->z.fixed;
107 blocker = StagedActor_FindAtTile(&dst, next);
108 if (blocker != 0 && (blocker->collisionFlags & 1) != 0)
109 return;
110
111 next->terrainId = 2;
112 step = gStagedActor_DirectionSteps[dir];
113 dst.x = next->x.fixed + (step & 0xffff0000);
114 dst.y = next->y.fixed;
115 step <<= 16;
116 dst.z = next->z.fixed + step;
117 if (FieldObject_CheckMovementCollision(next, &dst) > 0)
118 return;
119
120 if (next->riseCounter != 0)
121 return;
122
123 Object_SetMode(lead, 8);
124 rate = 0x3333;
125 Engine_TaskWait(15);
127 next->speed = rate;
128 next->acceleration = rate;
129 Engine_ObjectSetPosition(next, dst.x, dst.y, dst.z);
130 lead->speed = rate;
131 lead->acceleration = rate;
132 Engine_ObjectSetPosition(lead, dst.x, dst.y, dst.z);
135 next->x.fixed = dst.x;
136 next->z.fixed = dst.z;
137 next->velocityX = 0;
138 next->velocityZ = 0;
139 lead->targetX = 0x80000000;
140 lead->targetZ = 0x80000000;
141 lead->velocityX = 0;
142 lead->velocityZ = 0;
143 lead->x.fixed = lead->x.part.pixel << 16;
144 lead->z.fixed = lead->z.part.pixel << 16;
145 Object_SetMode(lead, 1);
146}
147
148/// Sets the collision code of a width by height rectangle of cells, from cell
149/// (x, z), to value, on map layer 0 to 2, or (3 and up) in gMapCellBuffer.
151 u32 width, u32 height,
152 s32 value) {
153 struct MapScrollWork *map = gMapWork[0];
154 struct MapCell *cells;
155 u32 row;
156 u32 column;
157
158 if (map != 0) {
159 if (layer <= 2) {
160 cells = map->layers[layer].cells;
161 } else {
162 cells = (struct MapCell *)gMapCellBuffer;
163 }
164 cells += x + (z << 7);
165 for (row = 0; row < height; row++) {
166 struct MapCell *cell = cells + (row << 7);
167
168 for (column = 0; column < width; column++) {
169 cell->collisionCode = value;
170 cell++;
171 }
172 }
173 }
174 return 0;
175}
176
177// UB: the native s32 callback is called through FieldActor's void hook. The
178// void form keeps 0xa4 bytes in Altmiller English but changes the return move.
179#ifdef UBFIX
180/// The leader's movement callback while pushing a large thing: stop the leader
181/// when another actor that is not a large thing, or a wall, is in the way.
182static void StagedActor_StopBlockedMotion(union FieldObject *object) {
183 struct FieldActor *actor = (struct FieldActor *)object;
184#else
185/// The leader's movement callback while pushing a large thing: stop the leader
186/// when another actor that is not a large thing, or a wall, is in the way.
188#endif
189 struct FieldPosition probe;
190 u32 dir;
191 s32 step;
192 struct FieldActor *target;
193
194 dir = actor->facing >> 12;
195 step = gStagedActor_DirectionSteps[dir];
196 probe.x = actor->x.fixed + (step & 0xffff0000);
197 probe.y = actor->y.fixed;
198 step <<= 16;
199 probe.z = actor->z.fixed + step;
200 target = StagedActor_FindAtTile(&probe, actor);
201 if (target != 0) {
202 u32 i = 0;
203 s32 kind = target->sprite->entries[0]->animId;
205
206 do {
207 if (kind == *kinds++) {
208#ifdef UBFIX
209 return;
210#else
211 return 0;
212#endif
213 }
214 i++;
215 } while (i <= 5);
216 actor->velocityX = 0;
217 actor->velocityZ = 0;
218 actor->targetX = 0x80000000;
219 actor->targetZ = 0x80000000;
220 }
221 step = gStagedActor_DirectionSteps[dir];
222 probe.x = actor->x.fixed + (step & 0xffff0000);
223 probe.y = actor->y.fixed;
224 step <<= 16;
225 probe.z = actor->z.fixed + step;
226 if (FieldObject_CheckMovementCollision(actor, &probe) > 0) {
227 actor->velocityX = 0;
228 actor->velocityZ = 0;
229 actor->targetX = 0x80000000;
230 actor->targetZ = 0x80000000;
231 }
232#ifndef UBFIX
233 return 0;
234#endif
235}
236
237/// Returns the large thing whose footprint covers the cell ahead of the leader
238/// (the leader not standing in line with its first column or row), with the
239/// leader's direction, its actor number and its footprint; or NULL.
240static struct FieldActor *FieldScene_FindActorRegion(s32 *direction, s32 *slot,
241 s32 *footprint) {
242 struct FieldWork *work = (struct FieldWork *)gEventWork;
243 struct FieldActor *player = Object_GetById(0);
244 struct FieldActor **list;
245 u32 i, j;
246
247 *direction = player->facing >> 12;
248 list = work->actors + ACTOR_FIRST_PLACED;
249 for (i = ACTOR_FIRST_PLACED;
250 i < sizeof(work->actors) / sizeof(work->actors[0]); list++, i++) {
251 struct FieldActor *actor = (struct FieldActor *)*list;
252 s32 kind;
253 j = 0;
254 // UB: the same empty slots are scanned here; the null guard grows the
255 // native English helper from 0x128 to 0x134 bytes.
256#ifdef UBFIX
257 if (actor == NULL)
258 continue;
259#endif
260 kind = actor->sprite->entries[0]->animId;
261 for (j = 0; j < 6; j++) {
262 if (kind == gStagedActor_FootprintKinds[j]) {
263 s32 x, z, left, top, right, bottom;
264 *footprint = j;
265 x = ((player->x.fixed >> 16) +
266 (gStagedActor_DirectionSteps[*direction] >> 16)) >>
267 4;
268 z = ((player->z.fixed >> 16) +
269 (s16)gStagedActor_DirectionSteps[*direction]) >>
270 4;
271 left =
272 (actor->x.part.pixel + gStagedActor_FootprintBounds[j * 4 + 0]) >>
273 4;
274 top = (actor->z.part.pixel + gStagedActor_FootprintBounds[j * 4 + 1]) >>
275 4;
276 right =
277 (actor->x.part.pixel + gStagedActor_FootprintBounds[j * 4 + 2]) >>
278 4;
279 bottom =
280 (actor->z.part.pixel + gStagedActor_FootprintBounds[j * 4 + 3]) >>
281 4;
282 if (left <= x && x < right && top <= z && z < bottom) {
283 if (j & 1) {
284 if (left != (player->x.fixed >> 20)) {
285 *slot = i;
286 return actor;
287 }
288 } else if (top != (player->z.fixed >> 20)) {
289 *slot = i;
290 return actor;
291 }
292 }
293 }
294 }
295 }
296 return NULL;
297}
298
299/// Finds where the large thing ahead of the leader would roll to: step its
300/// footprint on, a cell at a time the way the leader faces, until a cell of it
301/// meets something (a collision result of 2). Fills probe with the thing, its
302/// footprint and that position; returns 0 when there is no thing or it cannot
303/// move.
304UNUSED static s32
306 s32 direction;
307 struct FieldPosition position;
308 struct FieldActor *actor;
309 s32 steps;
310 s32 width, height;
311 u8 *mode;
312 s32 column, row;
313 s32 nearEdge, farEdge;
314 s32 offset;
315
316 probe->callback = 0;
317 actor = FieldScene_FindActorRegion(&direction, &probe->actorSlot,
318 &probe->footprintIndex);
319 if (actor == 0) {
320 return 0;
321 }
322 mode = &actor->terrainId;
323 *mode = 2;
324 {
325 s32 footprint = probe->footprintIndex;
326
327 steps = 0;
328 offset = footprint * 4;
329 nearEdge = gStagedActor_FootprintBounds[offset + 1];
330 if (nearEdge < 0) {
331 nearEdge = -nearEdge;
332 }
333 farEdge = gStagedActor_FootprintBounds[offset + 3];
334 if (farEdge < 0) {
335 farEdge = -farEdge;
336 }
337 height = (nearEdge + farEdge) >> 4;
338 nearEdge = gStagedActor_FootprintBounds[offset];
339 if (nearEdge < 0) {
340 nearEdge = -nearEdge;
341 }
342 farEdge = gStagedActor_FootprintBounds[offset + 2];
343 if (farEdge < 0) {
344 farEdge = -farEdge;
345 }
346 width = (nearEdge + farEdge) >> 4;
347 }
348 position.x =
349 actor->x.fixed + (gStagedActor_DirectionSteps[direction] & 0xffff0000);
350 {
351 s32 y = actor->y.fixed;
352
353 position.y = y;
354 position.z =
355 actor->z.fixed + (gStagedActor_DirectionSteps[direction] << 16);
356 probe->position.y = y;
357 }
358 for (;;) {
359 probe->position.z =
360 position.z +
361 (gStagedActor_FootprintBounds[probe->footprintIndex * 4 + 1] << 16);
362 for (row = 0; row < height; row++) {
363 probe->position.x =
364 position.x +
366 for (column = 0; column < width; column++) {
367 if (FieldObject_CheckMovementCollision(actor, &probe->position) == 2) {
368 goto found;
369 }
370 probe->position.x += 0x100000;
371 }
372 probe->position.z += 0x100000;
373 }
374 steps++;
375 position.x += gStagedActor_DirectionSteps[direction] & 0xffff0000;
376 position.z += gStagedActor_DirectionSteps[direction] << 16;
377 }
378found:
379 *mode = 0;
380 if (steps == 0) {
381 return 0;
382 }
383 probe->position.x =
384 actor->x.fixed +
385 (gStagedActor_DirectionSteps[direction] & 0xffff0000) * steps;
386 probe->position.y = actor->y.fixed;
387 probe->position.z =
388 actor->z.fixed + (gStagedActor_DirectionSteps[direction] << 16) * steps;
389 return 1;
390}
391
392/// Rolls the large thing to the position probe found: the leader pushes
393/// (animation 8), the thing rolls (mode 3 or 2 by the direction) with SE_239
394/// while the leader follows half a cell, and it stops with SE_288 and SE_213.
395/// Its cells are blocked (collision 255) at its new place, through the map's
396/// layer 1 offset, and its old place is given back what was under it.
398 struct MapScrollWork *workspace;
399 struct FieldActor *actor;
400 struct FieldPosition originalPosition;
401 struct FieldPosition tilePosition;
402 u8 *footprintTable;
403 s32 direction;
404 s32 horizontalExtent;
405 s32 verticalExtent;
406
407 // UB: reading the pointer slot through u32 aliases its declared type. The
408 // direct pointer read moves ahead of the probe stores in native English.
409#ifdef UBFIX
410 workspace = gMapWork[0];
411#else
412 workspace = (struct MapScrollWork *)*(u32 *)gMapWork;
413#endif
414 direction = (Object_GetById(0))->facing >> 12;
415 actor = Object_GetById(probe.actorSlot);
416 footprintTable = (u8 *)gStagedActor_FootprintBounds;
417 {
418 s32 extentA = gStagedActor_FootprintBounds[probe.footprintIndex * 4 + 1];
419 s32 extentB;
420
421 if (extentA < 0)
422 extentA = -extentA;
423 extentB = gStagedActor_FootprintBounds[probe.footprintIndex * 4 + 3];
424 if (extentB < 0)
425 extentB = -extentB;
426 verticalExtent = (extentA + extentB) >> 4;
427 extentA = gStagedActor_FootprintBounds[probe.footprintIndex * 4 + 0];
428 if (extentA < 0)
429 extentA = -extentA;
430 extentB = gStagedActor_FootprintBounds[probe.footprintIndex * 4 + 2];
431 if (extentB < 0)
432 extentB = -extentB;
433 horizontalExtent = (extentA + extentB) >> 4;
434 }
435
436 actor->speed = 0x8000;
437 actor->acceleration = 0x1999;
438 originalPosition.x = actor->x.fixed;
439 originalPosition.z = actor->z.fixed;
440 {
441 s32 tableOffset = probe.footprintIndex << 4;
442 tilePosition.x =
443 (actor->x.fixed + (*(s32 *)(footprintTable + tableOffset) << 16));
444 tableOffset += 4;
445 tilePosition.z =
446 (actor->z.fixed + (*(s32 *)(footprintTable + tableOffset) << 16));
447 tilePosition.x >>= 20;
448 tilePosition.z >>= 20;
449 }
450
451 StagedActor_FillGridAttributeRectangle(0, tilePosition.x, tilePosition.z,
452 horizontalExtent, verticalExtent, 0);
453 Engine_ActorSetSpeed(0, 0x8000, 0x1999);
456
457 {
458 s32 horizontalDelta = probe.position.x - originalPosition.x;
459 if (horizontalDelta < 0)
460 horizontalDelta += 0x1ffff;
461 horizontalDelta >>= 17;
462 {
463 s32 verticalDelta = probe.position.z - originalPosition.z;
464 if (verticalDelta < 0)
465 verticalDelta += 0x1ffff;
466 verticalDelta >>= 17;
467 Engine_ActorSetDestinationOffset(0, horizontalDelta, verticalDelta);
468 }
469 }
470
471#ifdef UBFIX
473#else
476#endif
478 if ((u32)(direction - 6) <= 7)
480 else
482
485 probe.position.z);
488 Actor_SetSpeed(0, 0x4ccc, 0x1999);
489
490 {
491 s32 packedOrientation = gStagedActor_DirectionSteps[direction];
492 Engine_ActorSetDestinationOffset(0, ((s16)(packedOrientation >> 16)) / 2,
493 ((s16)packedOrientation) / 2);
494 }
495 if (probe.callback != 0)
496 probe.callback();
497
504
505 actor->x.fixed = probe.position.x;
506 actor->z.fixed = probe.position.z;
507 actor->velocityX = 0;
508 actor->velocityZ = 0;
510
511 {
513 s32 horizontalOrigin;
514 s32 verticalOrigin;
515
516 {
517 s32 tableOffset = probe.footprintIndex << 4;
518 probe.position.x =
519 (probe.position.x + (*(s32 *)(table + tableOffset) << 16));
520 tableOffset += 4;
521 probe.position.z =
522 (probe.position.z + (*(s32 *)(table + tableOffset) << 16));
523 probe.position.x >>= 20;
524 probe.position.z >>= 20;
525 }
526 horizontalOrigin = workspace->layers[1].offsetX >> 20;
527 verticalOrigin = workspace->layers[1].offsetY >> 20;
528
529 Map_CopyCellAttributes(probe.position.x, probe.position.z, horizontalExtent,
530 verticalExtent, horizontalOrigin + probe.position.x,
531 verticalOrigin + probe.position.z);
533 probe.position.z, horizontalExtent,
534 verticalExtent, 255);
536 probe.position.z, horizontalExtent,
537 verticalExtent, 255);
538
539 {
540 s32 tableOffset = probe.footprintIndex << 4;
541 originalPosition.x =
542 (originalPosition.x + (*(s32 *)(table + tableOffset) << 16));
543 tableOffset += 4;
544 originalPosition.z =
545 (originalPosition.z + (*(s32 *)(table + tableOffset) << 16));
546 originalPosition.x >>= 20;
547 originalPosition.z >>= 20;
548 }
549 horizontalOrigin += originalPosition.x;
550 verticalOrigin += originalPosition.z;
551
552 Engine_MapCopyCellAttributes(horizontalOrigin, verticalOrigin,
553 horizontalExtent, verticalExtent,
554 originalPosition.x, originalPosition.z);
555 StagedActor_FillGridAttributeRectangle(2, originalPosition.x,
556 originalPosition.z, horizontalExtent,
557 verticalExtent, 0);
558 }
560}
561
562/// Block large thing id's cells (collision 255) where it stands, through the
563/// map's layer 1 offset; returns 0 when its sprite is no large thing.
565 struct MapScrollWork *work = gMapWork[0];
566 struct FieldActor *actor = Object_GetById(id);
567 struct StagedActorProbe probe;
568 u32 idx = 0;
569 s32 offset;
570 s32 width;
571 s32 height;
572 s32 x0;
573 s32 x1;
574 s32 z0;
575 s32 z1;
576 s32 dstZ;
577
578 for (idx = 0; idx <= 5; idx++) {
579 if (actor->sprite->entries[0]->animId == gStagedActor_FootprintKinds[idx]) {
580 probe.footprintIndex = idx;
581 break;
582 }
583 probe.footprintIndex = 7;
584 }
585
586 if ((u32)probe.footprintIndex > 6)
587 return 0;
588 probe.position.x = actor->x.fixed;
589 probe.position.y = actor->y.fixed;
590 probe.position.z = actor->z.fixed;
591 offset = probe.footprintIndex * 4;
592 z0 = gStagedActor_FootprintBounds[offset + 1];
593 if (z0 < 0)
594 z0 = -z0;
595 z1 = gStagedActor_FootprintBounds[offset + 3];
596 if (z1 < 0)
597 z1 = -z1;
598 height = (z0 + z1) >> 4;
599 x0 = gStagedActor_FootprintBounds[offset];
600 if (x0 < 0)
601 x0 = -x0;
602 x1 = gStagedActor_FootprintBounds[offset + 2];
603 if (x1 < 0)
604 x1 = -x1;
605 width = (x0 + x1) >> 4;
606 probe.position.x += gStagedActor_FootprintBounds[offset] << 16;
607 probe.position.z += gStagedActor_FootprintBounds[offset + 1] << 16;
608 probe.position.x >>= 20;
609 probe.position.z >>= 20;
610 idx = work->layers[1].offsetX >> 20;
611 dstZ = work->layers[1].offsetY >> 20;
613 height, idx + probe.position.x,
614 dstZ + probe.position.z);
616 width, height, 255);
618 width, height, 255);
619 return 1;
620}
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
s32 gStagedActor_DirectionSteps[]
Pixel step by direction: X in the upper halfword, Z in the lower.
s32 gStagedActor_FootprintBounds[]
u32 gStagedActor_FootprintKinds[]
Calls through a function pointer, by argument count.
The engine calls the debug menus import, and their palette swatch tiles.
The engine call layer: one typed inline for each of the thirteen main-image routines below that the s...
static s32 FieldObject_CheckMovementCollision(struct FieldActor *actor, struct FieldPosition *position)
Definition engine_call.h:66
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 Engine_MapCopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_ActorSetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_EventWait(s32 frames)
The field's runtime work: map cells, scene records and regions, map markers and FieldWork.
@ ACTOR_FIRST_PLACED
FixedPointPosition, a position in 16.16 fixed point.
The work slots of gWorkSlot, read through their own names.
struct EffectStep gMapCellBuffer[]
Map cells; battle effects reuse this as a particle array.
void * gMapWork[]
The screen blend's globals and the graphics routines.
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
Maps: their cells, layers, animations and blend scripts, and the map state.
The map layers' scroll work and the background scroll values.
Declares nothing of its own: it only includes edition.h and types.h.
The reel game's title lettering.
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 struct FieldActor * FieldScene_FindActorRegion(s32 *direction, s32 *slot, s32 *footprint)
Returns the large thing whose footprint covers the cell ahead of the leader (the leader not standing ...
static struct FieldActor * StagedActor_FindAtTile(const struct FieldPosition *position, const struct FieldActor *origin)
Returns the placed actor on the cell of the 16.16 position and at its height (in whole pixels),...
static UNUSED s32 FieldScene_RedrawActorFootprint(s32 id)
Block large thing id's cells (collision 255) where it stands, through the map's layer 1 offset; retur...
static UNUSED void StagedActor_AdvancePair(void)
The leader pushes the block in front of them a cell on, unless something solid is beyond it or on top...
static UNUSED void SceneActor_MoveAndRedraw(struct StagedActorProbe probe)
Rolls the large thing to the position probe found: the leader pushes (animation 8),...
static s32 StagedActor_StopBlockedMotion(struct FieldActor *actor)
The leader's movement callback while pushing a large thing: stop the leader when another actor that i...
static UNUSED s32 StagedActor_FindClearPosition(struct StagedActorProbe *probe)
Finds where the large thing ahead of the leader would roll to: step its footprint on,...
static s32 StagedActor_FillGridAttributeRectangle(u32 layer, s32 x, s32 z, u32 width, u32 height, s32 value)
Sets the collision code of a width by height rectangle of cells, from cell (x, z),...
void BattleFx_PlayQueuedSound(void)
Plays the sound BattleFx_SetQueuedSoundAndPlay remembered, if any.
Definition requests.c:102
Song and sound effect ids, indices into gSound_SongTable.
#define SE_213
Definition songs.h:208
#define SE_239
Definition songs.h:234
#define SE_185
Definition songs.h:180
#define SE_288
Definition songs.h:281
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_AudioPlayCue()
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
The pushable actors' movement probes and footprint bounds.
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
s32 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
u8 riseCounter
not read by the engine; scene code's own counter
Definition field_obj.h:105
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 targetZ
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:61
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
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
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
u8 collisionFlags
bits: 7 refuses to move into a solid object | 4 nearer for Psynergy targets | 3 never a talk or Psyne...
Definition field_obj.h:91
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 position on the field.
s32 z
16.16 fixed-point pixels
Full event work allocated by Field_RunScene (heap slot 27).
One cell of a map layer: its metatile and flags, its collision code and an attribute indexing the col...
Definition map.h:13
u8 collisionCode
The step code: 1 to 239 scene events, 240 and 241 encounter ground, 250 hazard, 252 to 254 for Field_...
Definition map.h:18
struct MapCell * cells
the layer's first cell in the map cell buffer
Definition map_scroll.h:21
s32 offsetY
16.16 fixed-point pixels
Definition map_scroll.h:16
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
struct MapLayerScroll layers[3]
BG3, BG2 and BG1, in that order.
Definition map_scroll.h:49
Where a large thing ahead of the leader would roll to: its footprint, its actor, that position,...
struct FieldPosition position
16.16 pixels while moving; converted to cells by footprint redraws.
void(*) callback(void)
Run as the leader follows the rolling thing, when not null; the probe clears it.
s32 actorSlot
the large thing's actor number, 8 to 65
s32 footprintIndex
The large thing's row in gStagedActor_FootprintKinds and gStagedActor_FootprintBounds,...
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldActor actor