Alchemy
Loading...
Searching...
No Matches

venus.c

Go to the documentation of this file.
1/// @file
2/// A Venus Djinni joining the party.
3/// Part of psynergy_effects.c, compiled only through it.
4
6
7/// A Venus Djinni joins the party: it hops twice, spins and leaps, then
8/// shrinks away; the leader turns to the camera and plays animation 28 while
9/// 24 particles rise round it (BattleFx_UpdateRadialSpread). Then 24 motes
10/// spiral down onto the leader from 120 pixels above
11/// (BattleFx_UpdateDescendingOrbitObject) and 8 sparks burst from the leader.
12/// Called by Djinn_JoinParty for a Venus Djinni, which then clears the
13/// Djinni's actor slot. Uses all 24 effect slots, tints the field palette green
14/// and fades it back at the end.
16 struct CaptureObject *leader;
17 struct CaptureObject *djinni;
18 struct BattleFxScene *effectScene;
19 struct EffectSlot *slot;
20 s8 *slotState;
21 s32 remaining;
22 s32 scale;
23 struct EffectVector position;
24
26 djinni = (struct CaptureObject *)Object_GetById(djinniId);
27 if (djinni == NULL)
28 return;
29
31 effectScene = gEffectWork;
32 // Tint the screen green: PALETTE_TRANSFORM_TINT | RGB(4, 16, 4), the form
33 // mercury.c spells out for its blue.
35 WaitFrames(30);
36 djinni->visible = 0;
38 ObjectMotion_Launch(djinniId, 4, 15);
40 ObjectMotion_Launch(djinniId, 4, 15);
41 // Spin and leap, then shrink away while the screen shakes (1.3 pixels).
42 WaitFrames(30);
45 ObjectMotion_Launch(djinniId, 8, 22);
47 Map_SetScreenShakeFar(0x14ccc, 0x14ccc, 0x10000);
50 // The leader turns to face the camera (angle 0x4000).
51 WaitFrames(90);
53 WaitFrames(20);
55 28);
56 WaitFrames(30);
57 Map_SetScreenShakeFar(0x19999, 0x19999, 0x10000);
58
59 position.x = djinni->x;
60 position.y = djinni->y;
61 position.z = djinni->z;
62 Camera_WorldToScreen(&position);
63
64 // One rising particle a frame into each of the 24 effect slots.
65 slot = effectScene->slots;
66 remaining = 23;
67 do {
68 EffectSlot_Initialize(slot, 284, position.x, position.z);
72 slot->scaleX = 0x8000;
73 slot->scaleY = Random16() + 0x18000;
74 remaining--;
75 WaitFrames(1);
76 slot++;
77 } while (remaining >= 0);
78
79 // After 140 frames every particle still in use stops rising (state 2).
80 WaitFrames(140);
81 // Walking whole slots instead of their state bytes grows native English
82 // from 0x2dc to 0x2e0 bytes.
83 {
84 s32 nextState;
85
86 nextState = 2;
87 slotState = (s8 *)effectScene;
88 slotState += offsetof(struct BattleFxScene, slots) +
89 offsetof(struct EffectSlot, state);
90 remaining = 23;
91 do {
92 if (slotState[5] != 0)
93 slotState[0] = nextState;
94 remaining--;
95 slotState += sizeof(struct EffectSlot);
96 } while (remaining >= 0);
97 }
98
99 // A shake of 1/65536 pixel: in effect the shake stops.
100 WaitFrames(20);
101 Map_SetScreenShakeFar(1, 1, 1);
102 WaitFrames(30);
103
104 // 24 motes, evenly spread round a circle, 120 pixels above the leader.
105 for (remaining = 0; remaining <= 23; remaining++) {
106 position.x = leader->x;
107 position.y = leader->y + 0x780000;
108 position.z = leader->z;
109 djinni = (struct CaptureObject *)Object_Spawn(284, position.x, position.y,
110 position.z);
111 if (djinni != NULL) {
112 scale = Random16() / 3 + 0x10000;
113 djinni->scaleY = scale;
114 djinni->scaleX = scale;
115 djinni->timer = 100;
116 djinni->angle = (remaining << 16) / 24;
118 djinni->mode = 0;
120 Animation_ApplyChildValuesFar((struct DispatchObject *)djinni, 11);
121 }
122 }
123
124 WaitFrames(100);
126 WaitFrames(1);
128 position.x = leader->x;
129 position.y = leader->y + 0x120000;
130 position.z = leader->z;
131 // 8 sparks from 18 pixels above the leader, each thrown 32 pixels in a
132 // random direction; stop at the first that cannot be spawned.
133 for (remaining = 0; remaining <= 7; remaining++) {
134 djinni = (struct CaptureObject *)Object_Spawn(284, position.x, position.y,
135 position.z);
136 if (djinni == NULL)
137 break;
138 djinni->scaleY = 0x9999;
139 djinni->scaleX = 0x9999;
140 djinni->mode = 2;
141 djinni->gravity = 0x50000;
142 djinni->baseY = djinni->y;
143 djinni->speed = Random16() + 0x16666;
145 0x200000, Random16());
146 Animation_ApplyChildValuesFar((struct DispatchObject *)djinni, 11);
147 djinni->lifetime = 8;
150 }
151
152 WaitFrames(15);
155}
156
157/// Effect slot callback of a Mercury Djinni's droplets: each falls from 100
158/// pixels above to a random point near the leader (state 0), and where it
159/// lands splashes 12 pixels in a random direction with SE_143. In state 1 it
160/// then falls again 6 frames later (back to state 0); once
161/// BattleFx_RunMercuryDjinnCapture sets state 2, its next splash is its last
162/// (state 3, which frees it).
164 struct ObjectRuntime *source;
165 struct EffectVector position;
166 s8 *statePointer;
167 s32 state;
168
170 statePointer = &effect->state;
171 state = *statePointer;
172
173 if (state == 0) {
174 position.x = source->x;
175 position.y = source->y + Random16() * 5 + 0xf0000;
176 position.z = source->z;
177 Camera_WorldToScreen(&position);
178 Vector_AddPolarOffset(Random16() * 6 + 0x20000, Random16(), &position);
179
180 effect->targetX = position.x;
181 effect->targetZ = position.z;
182 effect->x = position.x;
183 effect->z = position.z - 0x640000;
184 effect->acceleration = 0x30000;
185 effect->maxSpeed = Random16() * 3 + 0x30000;
186 effect->scaleX = 0x10000;
187 effect->scaleY = 0x10000;
188 effect->limitTurnStep = state;
189 effect->stopAtTarget = 1;
190 (*statePointer)++;
191 } else if ((u8)(effect->state - 1) <= 1) {
192 if (EffectSlot_HasPendingTarget(effect) == 0) {
193 position.x = effect->x;
194 position.z = effect->z;
195 Vector_AddPolarOffset(0xc0000, Random16(), &position);
196 effect->targetX = position.x;
197 effect->targetZ = position.z;
198 effect->stopAtTarget = 0;
199 effect->speed = 0x10000;
200 effect->acceleration = 0;
201 effect->maxSpeed = Random16() + 0x23333;
202 effect->scaleX = 0x8000;
203 effect->scaleY = 0x8000;
205
206 if (*statePointer == 1)
207 (*statePointer)--;
208 else
209 (*statePointer)++;
210 effect->callbackDelay = 6;
211 }
212 } else if (state == 3) {
214 }
215}
216
217/// Per-frame update of an afterimage: closes half the distance to the object
218/// it is linked to. Set on the Mercury Djinni's afterimages by
219/// BattleFx_RunMercuryDjinnCapture.
221 BattleFx_MoveAfterimageHalfway(fieldObject);
222}
void ObjectMotion_Launch(u32 objectId, s32 speed, s32 frames)
The event command "actor jump": throws the actor upward at speed pixels per frame with a jump sound (...
void ObjectMotion_ArmCallback(s32 objectId, s32 angle, s32 wait)
The event command "actor face direction": the actor turns toward angle (0x10000 a full turn; ObjectMo...
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
void BattleFx_InitializeSlots(void)
Allocates and clears the effect slots (heap block 56) and starts their update callback.
Definition djinni.c:261
void BattleFx_AdvanceSpinAngle(union FieldObject *fieldObject)
Per-frame update: spins an object 1/8 turn a frame.
Definition djinni.c:287
void BattleFx_ClearActiveSlotsAndScheduleUpdates(void)
Stops the effect slots: removes their callback, frees every slot still in use and releases their heap...
Definition djinni.c:271
u32 EffectSlot_HasPendingTarget(struct EffectSlot *effect)
Returns nonzero while an effect slot that stops at its target still has one (it has not arrived),...
void BattleFx_ClearOwnedSlot(struct EffectSlot *slot)
Frees an effect slot and its sprite.
void EffectSlot_Initialize(struct EffectSlot *effect, s32 kind, s32 x, s32 z)
Fills an effect slot with a new sprite of kind at (x, z): stopping at its target, top speed 2,...
void EffectSlot_SetCallback(struct EffectSlot *effect, EffectCallback callback)
Gives an effect slot its per-frame callback, starting at state 0.
void EffectSlot_SetObjectMode(struct EffectSlot *effect, s32 mode)
Sets the animation of an effect slot's sprite.
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
void ObjectDispatch_InitializeFar(struct DispatchObject *obj, const s32 *script)
void Animation_ApplyChildValuesFar(struct DispatchObject *obj, u32 val)
void ObjectGroup_SetChildValueUnlessFifteenFar(void *raw_parent, u32 value)
void Map_SetScreenShakeFar(s32 value0, s32 value1, s32 value2)
void Shop_RestoreFieldPaletteFar(void)
void Shop_SaveAndTintFieldPaletteFar(s32 layer)
void AudioCommand_PlayFar(s32 id)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
const s32 gBattleFx_CommonParticleScript[]
[0] only frees the actor, +1 waits for it to arrive and frees it; +3 is gBattleFx_SourceHoldScript,...
Definition fxdata.c:444
struct GameState gGameState
void * gEffectWork
Slot 56: points to a scene-specific structure.
void BattleFx_ShrinkObjectAndDestroyFast(union FieldObject *fieldObject)
Spins and shrinks an object by 0x400 a frame, then releases it.
Definition mars.c:137
void BattleFx_UpdateDescendingOrbitObject(union FieldObject *fieldObject)
Per-frame update of a Venus Djinni's falling motes: each circles the leader on a shrinking spiral (ra...
Definition mars.c:143
void BattleFx_UpdateRadialSpread(struct EffectSlot *effect)
Effect slot callback of a Venus Djinni's particles: each starts on screen at a random point 10 to 20 ...
Definition mars.c:174
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
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void Motion_SetTargetPositionFromMagnitudeAngle(struct ObjectRuntime *object, s32 magnitude, s32 angle)
Sends an object toward the point magnitude (16.16 pixels) away from it in direction angle: sets its m...
Definition dispatch.c:308
struct ObjectRuntime * Object_Spawn(s32 kind, s32 x, s32 y, s32 z)
Creates an object for an effect, at the caster's ground height, with sprite priority 0 and animation ...
Definition dispatch.c:371
void Camera_WorldToScreen(struct EffectVector *position)
Converts a world position (16.16 pixels) to the screen: x and z receive the screen's x and y and y be...
Definition setup.c:293
What every part of psynergy_effects.c shares: its includes and the macros and types more than one par...
#define SE_143
Definition songs.h:136
#define SE_288
Definition songs.h:281
#define SE_151
Definition songs.h:144
#define SE_140
Definition songs.h:133
#define SE_JUMP
An actor jumps: ObjectMotion_Launch plays the high jump above 5 pixels a frame.
Definition songs.h:147
#define SE_HIGH_JUMP
Definition songs.h:148
#define NULL
Definition bilibin.h:6
#define offsetof(type, member)
Definition stddef.h:19
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
struct EffectSlot slots[24]
Definition fx_scene.h:73
A FieldActor seen with the halfword at 0x5e (lifetime), which FieldActor does not name.
void(*) callback(union FieldObject *object)
A field object as the object dispatcher's far calls take it.
A particle a Psynergy effect moves and draws: its sprite, its position and target,...
Definition effect_slot.h:18
s16 callbackDelay
frames
Definition effect_slot.h:35
s32 speed
16.16 fixed-point pixels per frame
Definition effect_slot.h:26
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition effect_slot.h:30
s8 state
the callback's own step; 0 when it is given
Definition effect_slot.h:38
void * object
the slot's sprite, released with the slot
Definition effect_slot.h:19
s32 z
16.16 fixed-point pixels
Definition effect_slot.h:21
s32 x
16.16 fixed-point pixels
Definition effect_slot.h:20
s8 limitTurnStep
Clamp steering to maxTurnStep; zero faces the target directly.
Definition effect_slot.h:40
s32 targetZ
16.16 fixed-point pixels; EFFECT_NO_TARGET at rest
Definition effect_slot.h:23
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition effect_slot.h:29
s32 targetX
16.16 fixed-point pixels; EFFECT_NO_TARGET at rest
Definition effect_slot.h:22
s32 maxSpeed
16.16 fixed-point pixels per frame
Definition effect_slot.h:27
s8 stopAtTarget
nonzero: lands on the target within 8 pixels
Definition effect_slot.h:39
s32 acceleration
16.16 fixed-point pixels per frame, each frame
Definition effect_slot.h:28
A world position, as Camera_WorldToScreen converts it to the screen.
Definition battle.h:73
s32 y
16.16 fixed-point pixels
Definition battle.h:75
s32 z
16.16 fixed-point pixels
Definition battle.h:76
s32 x
16.16 fixed-point pixels
Definition battle.h:74
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
One of the 64 field objects in the object pool (heap slot 5): its script, position,...
s32 z
16.16 fixed-point pixels
s32 x
16.16 fixed-point pixels
s32 y
16.16 fixed-point pixels
signed int s32
Definition types.h:14
signed char s8
Definition types.h:10
unsigned char u8
Definition types.h:11
An object on the field, read as an actor or as an effect.
void BattleFx_UpdateRandomTargetParticle(struct EffectSlot *effect)
Effect slot callback of a Mercury Djinni's droplets: each falls from 100 pixels above to a random poi...
Definition venus.c:163
void BattleFx_HalveDistanceToTarget(union FieldObject *fieldObject)
Per-frame update of an afterimage: closes half the distance to the object it is linked to.
Definition venus.c:220
void BattleFx_RunVenusDjinnCapture(s32 djinniId)
A Venus Djinni joins the party: it hops twice, spins and leaps, then shrinks away; the leader turns t...
Definition venus.c:15