Alchemy
Loading...
Searching...
No Matches

effect_spawn.h

Go to the documentation of this file.
1#include "types.h"
2#include "field_effect.h"
3#include "objdisp.h"
4#include "field_scene.h"
5#include "fixed_math.h"
6
7// Twenty-four scenes, and the main image's Psynergy effects (whirlwind.c, with
8// EFFECT_SPAWN_RESIDENT): Effect_Spawn, which places a small effect moving at
9// a velocity, its script one of gEffectScripts and its options chosen by the
10// EFFECT_USE_ flags.
11
12/// Integrates linear motion, scale changes and rotation once per effect frame.
14 object->effect.x += object->effect.velocity.x;
15 object->effect.y += object->effect.velocity.y;
16 object->effect.z += object->effect.velocity.z;
17 object->effect.scaleX += object->effect.scaleRateX;
18 object->effect.scaleY += object->effect.scaleRateY;
19 object->effect.sprite->rotation += object->effect.spin;
20}
21
22// Compile the effect-spawning body once for the resident far-call version
23// and once for each overlay's direct-call version.
24
25extern const s32 *gEffectScripts[];
26
27enum {
29 EFFECT_OPTION_MASK = 0xffff0000,
31};
32
33/// Starts with linear motion and the leader's draw order; options can override
34/// it.
35static inline void Effect_InitializeMotion(struct FieldEffect *effect,
36 struct AnimationObject *sprite,
37 struct FieldActor *leader,
38 s32 velocityX, s32 velocityY,
39 s32 velocityZ) {
40 effect->velocity.x = velocityX;
41 effect->velocity.y = velocityY;
42 effect->velocity.z = velocityZ;
43 // The sprite slot is read by its offset, the plain-C form of leader->sprite
44 // this site matches with (scene/README.md): as the field, the pointer's
45 // reload moves after the velocity.z store.
46 sprite->image.priority =
47 (*(struct AnimationObject **)((u8 *)leader +
48 offsetof(struct FieldActor, sprite)))
49 ->image.priority;
50 effect->scaleRateX = 0;
51 effect->scaleRateY = 0;
52 effect->spin = 0;
53}
54
55#define EFFECT_SPAWN(name, create, set_mode, set_script) \
56 void name(s32 x, s32 y, s32 z, s32 velocityX, s32 velocityY, s32 velocityZ, \
57 u32 flags, const struct EffectOptions *options) { \
58 struct FieldActor *party = Actor_Get(ACTOR_PARTY_LEADER); \
59 struct FieldEffect *effect; \
60 struct AnimationObject *sprite; \
61 const s32 *script; \
62 \
63 if ((flags & EFFECT_USE_TYPE) != 0 && options != 0) \
64 effect = (struct FieldEffect *)create(options->type, x, y, z); \
65 else \
66 effect = (struct FieldEffect *)create(EFFECT_DEFAULT_TYPE, x, y, z); \
67 if (effect == 0) \
68 return; \
69 \
70 sprite = effect->sprite; \
71 set_mode((struct FieldActor *)effect, (flags + 1) & EFFECT_SCRIPT_MASK); \
72 set_script((void *)effect, gEffectScripts[flags & EFFECT_SCRIPT_MASK]); \
73 effect->motionFlags = 0; \
74 sprite->flags = 0; \
75 effect->update = BattleFx_UpdateObjectMotionScaleAndLinkedAngle; \
76 Effect_InitializeMotion(effect, sprite, party, velocityX, velocityY, \
77 velocityZ); \
78 \
79 if ((flags & EFFECT_OPTION_MASK) == 0 || options == 0) \
80 return; \
81 if ((flags & EFFECT_USE_PALETTE) != 0) \
82 ObjectGroup_SetChildValue((struct FieldActor *)effect, \
83 options->palette); \
84 if ((flags & EFFECT_USE_PRIORITY) != 0) { \
85 effect->priorityFlags &= ~ACTOR_PRIORITY_AUTOMATIC; \
86 sprite->image.priority = options->priority; \
87 } \
88 if ((flags & EFFECT_USE_START_SCALE) != 0) { \
89 effect->scaleX = options->startScaleX; \
90 effect->scaleY = options->startScaleY; \
91 } \
92 if ((flags & EFFECT_SCALE_TO_TARGET) != 0) { \
93 script = gEffectScripts[flags & EFFECT_SCRIPT_MASK]; \
94 if ((flags & EFFECT_USE_START_SCALE) != 0) { \
95 effect->scaleRateX = (options->targetScaleX - effect->scaleX) / \
96 script[EFFECT_SCRIPT_REPEAT_COUNT]; \
97 effect->scaleRateY = (options->targetScaleY - effect->scaleY) / \
98 script[EFFECT_SCRIPT_REPEAT_COUNT]; \
99 } else { \
100 effect->scaleRateX = (options->targetScaleX - Q16_ONE) / \
101 script[EFFECT_SCRIPT_REPEAT_COUNT]; \
102 effect->scaleRateY = (options->targetScaleY - Q16_ONE) / \
103 script[EFFECT_SCRIPT_REPEAT_COUNT]; \
104 } \
105 } \
106 if ((flags & EFFECT_USE_SCRIPT) != 0) { \
107 set_mode((struct FieldActor *)effect, 1); \
108 set_script((void *)effect, options->script); \
109 } \
110 if ((flags & EFFECT_USE_ROTATION) != 0) \
111 sprite->rotation = options->rotation; \
112 if ((flags & EFFECT_USE_SPIN) != 0) \
113 effect->spin = options->spin; \
114 if ((flags & EFFECT_USE_UPDATE) != 0) \
115 effect->update = options->update; \
116 }
117
118#ifdef EFFECT_SPAWN_RESIDENT
119/// The resident version uses far calls to the engine.
122#else
123/// Each overlay includes its own copy of this version.
125#endif
const s32 * gEffectScripts[]
struct ObjectRuntime * Object_CreateFar(s32 id, s32 x, s32 y, s32 z)
Far call to FieldObject_Create.
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
void ObjectDispatch_InitializeFar(struct DispatchObject *obj, const s32 *script)
Field effects, their scripts and the flags that spawn them.
void Effect_SpawnResident(s32 x, s32 y, s32 z, s32 velocityX, s32 velocityY, s32 velocityZ, u32 flags, const struct EffectOptions *options)
void Object_SetMode(struct FieldActor *object, s32 animation)
static struct FieldActor * Object_Create(s32 type, s32 fixed_x, s32 fixed_y, s32 fixed_z)
static void Object_SetScript(struct FieldActor *object, const s32 *script)
The scene table formats: entrances, exits, placements and events, and the macros that write them.
16.16 fixed-point constants, sine and cosine, and the library division.
The object dispatcher's forward declaration.
@ EFFECT_SCRIPT_REPEAT_COUNT
@ EFFECT_DEFAULT_TYPE
@ EFFECT_OPTION_MASK
#define EFFECT_SPAWN(name, create, set_mode, set_script)
static void Effect_InitializeMotion(struct FieldEffect *effect, struct AnimationObject *sprite, struct FieldActor *leader, s32 velocityX, s32 velocityY, s32 velocityZ)
Starts with linear motion and the leader's draw order; options can override it.
void BattleFx_UpdateObjectMotionScaleAndLinkedAngle(union FieldObject *object)
Integrates linear motion, scale changes and rotation once per effect frame.
#define offsetof(type, member)
Definition stddef.h:19
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
u16 priority
2 when created
Definition animspr.h:100
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
A field effect: a small object on the field that moves at its velocity and grows and spins at its rat...
struct Vector3 velocity
Added to x, y and z each frame by the update hooks, in 16.16 fixed-point pixels per frame; FieldActor...
s32 scaleRateX
Added to scaleX each frame by the update hooks, in 16.16 fixed point a frame; zeroed by the spawner.
s32 scaleRateY
as scaleRateX, for scaleY
u16 spin
Added to the sprite's rotation each frame by the update hooks, in 1/65536 turns per frame; Imil's ris...
s32 z
Definition vector3.h:24
s32 x
Definition vector3.h:22
s32 y
Definition vector3.h:23
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned char u8
Definition types.h:11
An object on the field, read as an actor or as an effect.