Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/FBZ/FlameSpring.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: FlameSpring Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectFlameSpring *FlameSpring;
11
12
void FlameSpring_Update(void)
13
{
14
RSDK_THIS(FlameSpring);
15
16
StateMachine_Run(self->state);
17
}
18
19
void FlameSpring_LateUpdate(void) {}
20
21
void FlameSpring_StaticUpdate(void) {}
22
23
void FlameSpring_Draw(void)
24
{
25
RSDK_THIS(FlameSpring);
26
27
StateMachine_Run(self->stateDraw);
28
}
29
30
void FlameSpring_Create(void *data)
31
{
32
RSDK_THIS(FlameSpring);
33
34
self->drawFX = FX_FLIP;
35
if (!SceneInfo->inEditor) {
36
self->active = ACTIVE_BOUNDS;
37
self->updateRange.x = 0x800000;
38
self->updateRange.y = 0x800000;
39
self->visible = true;
40
self->drawGroup = Zone->objectDrawGroup[0] + 1;
41
42
if (data) {
43
RSDK.SetSpriteAnimation(FlameSpring->aniFrames, 2, &self->mainAnimator, true, 0);
44
self->state = FlameSpring_State_Flame;
45
self->stateDraw = FlameSpring_Draw_Flame;
46
}
47
else {
48
if (!(self->force & 1))
49
self->velocity.y = -0xA0000;
50
else
51
self->velocity.y = -0x100000;
52
RSDK.SetSpriteAnimation(FlameSpring->aniFrames, 0, &self->mainAnimator, true, 0);
53
RSDK.SetSpriteAnimation(FlameSpring->aniFrames, 1, &self->nozzleAnimator, true, 0);
54
55
self->flamePosL.x = self->position.x - 0x300 * RSDK.Sin1024(0x100);
56
self->flamePosL.y = self->position.y - 0x40000;
57
self->flamePosR.x = 0x300 * RSDK.Sin1024(0x100) + self->position.x;
58
self->flamePosR.y = self->position.y - 0x40000;
59
60
if (self->type > FLAMESPRING_LEFT)
61
self->mainAnimator.frameID = 2;
62
63
self->type = self->type % 3;
64
self->state = FlameSpring_State_Spring;
65
self->stateDraw = FlameSpring_Draw_Spring;
66
}
67
}
68
}
69
70
void FlameSpring_StageLoad(void)
71
{
72
if (RSDK.CheckSceneFolder("FBZ"))
73
FlameSpring->aniFrames = RSDK.LoadSpriteAnimation("FBZ/FlameSpring.bin", SCOPE_STAGE);
74
75
FlameSpring->hitboxSpring.left = -16;
76
FlameSpring->hitboxSpring.top = -8;
77
FlameSpring->hitboxSpring.right = 16;
78
FlameSpring->hitboxSpring.bottom = 8;
79
80
FlameSpring->hitboxFlame.left = -4;
81
FlameSpring->hitboxFlame.top = -4;
82
FlameSpring->hitboxFlame.right = 4;
83
FlameSpring->hitboxFlame.bottom = 4;
84
85
FlameSpring->sfxSpring = RSDK.GetSfx("Global/Spring.wav");
86
FlameSpring->sfxFlame = RSDK.GetSfx("Stage/Flame2.wav");
87
}
88
89
void FlameSpring_State_Spring(void)
90
{
91
RSDK_THIS(FlameSpring);
92
93
self->spittingFire = false;
94
foreach_active(Player, playerPtr)
95
{
96
if (Player_CheckCollisionBox(playerPtr, self, &FlameSpring->hitboxSpring) == C_TOP && playerPtr->velocity.y >= 0) {
97
if (!self->mainAnimator.frameID) {
98
self->timer = 0;
99
self->mainAnimator.frameID = 1;
100
}
101
102
if (self->mainAnimator.frameID <= 1)
103
self->spittingFire = true;
104
}
105
}
106
107
if (self->mainAnimator.frameID == 1) {
108
if (self->spittingFire) {
109
if (++self->timer >= 60) {
110
foreach_active(Player, player)
111
{
112
if (Player_CheckCollisionBox(player, self, &FlameSpring->hitboxSpring) == C_TOP) {
113
int32 anim = player->animator.animationID;
114
if (anim == ANI_WALK || (anim > ANI_AIR_WALK && anim <= ANI_DASH))
115
player->animationReserve = player->animator.animationID;
116
else
117
player->animationReserve = ANI_WALK;
118
119
if (self->playerAni)
120
RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_TWIRL, &player->animator, true, 0);
121
else
122
RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_DIAGONAL, &player->animator, true, 0);
123
124
player->state = Player_State_Air;
125
player->onGround = false;
126
player->velocity.y = self->velocity.y;
127
if (player->underwater)
128
player->velocity.y >>= 1;
129
RSDK.PlaySfx(FlameSpring->sfxSpring, false, 255);
130
}
131
}
132
}
133
}
134
else {
135
self->mainAnimator.frameID = 0;
136
}
137
}
138
else {
139
if (!(Zone->timer & 7))
140
RSDK.PlaySfx(FlameSpring->sfxFlame, false, 255);
141
142
int32 timer = Zone->timer + self->offset;
143
if (!self->type) {
144
self->flamePosL.x = self->position.x - 0x300 * RSDK.Sin1024(((4 * timer) & 0x1FF) + 0x100);
145
self->flamePosR.x = 0x300 * RSDK.Sin1024(((4 * timer) & 0x1FF) + 0x100) + self->position.x;
146
}
147
148
if (!(Zone->timer & 3)) {
149
EntityFlameSpring *flame = NULL;
150
switch (self->type) {
151
case FLAMESPRING_BOTH:
152
flame = CREATE_ENTITY(FlameSpring, INT_TO_VOID(true), self->flamePosL.x, self->flamePosL.y);
153
flame->drawGroup = Zone->objectDrawGroup[0];
154
flame->velocity.x = -0x100 * RSDK.Sin1024(((4 * timer) & 0x1FF) + 0x100);
155
156
flame = CREATE_ENTITY(FlameSpring, INT_TO_VOID(1), self->flamePosR.x, self->flamePosR.y);
157
flame->velocity.x = (RSDK.Sin1024(((4 * timer) & 0x1FF) + 256) << 8);
158
break;
159
160
case FLAMESPRING_RIGHT:
161
flame = CREATE_ENTITY(FlameSpring, INT_TO_VOID(true), self->flamePosR.x, self->flamePosR.y);
162
flame->drawGroup = Zone->objectDrawGroup[0];
163
if (0xC00 * RSDK.Sin1024((timer & 0x1FF) + 0x100) >= 0)
164
flame->velocity.x = (0x44000 - 0xC0 * RSDK.Sin1024((timer & 0x1FF) + 0x100));
165
else
166
flame->velocity.x = (0x44000 - -0xC0 * RSDK.Sin1024((timer & 0x1FF) + 0x100));
167
break;
168
169
case FLAMESPRING_LEFT:
170
flame = CREATE_ENTITY(FlameSpring, INT_TO_VOID(true), self->flamePosL.x, self->flamePosL.y);
171
flame->drawGroup = Zone->objectDrawGroup[0];
172
if (-0xC0 * RSDK.Sin1024((timer & 0x1FF) + 0x100) >= 0)
173
flame->velocity.x = (-0xC0 * RSDK.Sin1024((timer & 0x1FF) + 0x100) - 0x44000);
174
else
175
flame->velocity.x = (0xC0 * RSDK.Sin1024((timer & 0x1FF) + 0x100) - 0x44000);
176
break;
177
}
178
}
179
}
180
}
181
182
void FlameSpring_State_Flame(void)
183
{
184
RSDK_THIS(FlameSpring);
185
186
self->position.x += self->velocity.x;
187
foreach_active(Player, player)
188
{
189
if (Player_CheckCollisionTouch(player, self, &FlameSpring->hitboxFlame)) {
190
Player_ElementHurt(player, self, SHIELD_FIRE);
191
}
192
}
193
194
RSDK.ProcessAnimation(&self->mainAnimator);
195
if (self->mainAnimator.frameID == self->mainAnimator.frameCount - 1)
196
destroyEntity(self);
197
}
198
199
void FlameSpring_Draw_Spring(void)
200
{
201
RSDK_THIS(FlameSpring);
202
203
if (self->mainAnimator.frameID != 1 && self->type != FLAMESPRING_RIGHT) {
204
self->nozzleAnimator.frameID = self->flamePosL.x > self->position.x;
205
RSDK.DrawSprite(&self->nozzleAnimator, &self->flamePosL, false);
206
}
207
208
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
209
210
if (self->mainAnimator.frameID != 1 && self->type != FLAMESPRING_LEFT) {
211
self->nozzleAnimator.frameID = self->flamePosR.x > self->position.x;
212
RSDK.DrawSprite(&self->nozzleAnimator, &self->flamePosR, false);
213
}
214
}
215
216
void FlameSpring_Draw_Flame(void)
217
{
218
RSDK_THIS(FlameSpring);
219
220
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
221
}
222
223
#if GAME_INCLUDE_EDITOR
224
void FlameSpring_EditorDraw(void)
225
{
226
RSDK_THIS(FlameSpring);
227
228
self->flamePosL.x = self->position.x - 0x300 * RSDK.Sin1024(0x100);
229
self->flamePosL.y = self->position.y - 0x40000;
230
self->flamePosR.x = 0x300 * RSDK.Sin1024(0x100) + self->position.x;
231
self->flamePosR.y = self->position.y - 0x40000;
232
233
RSDK.SetSpriteAnimation(FlameSpring->aniFrames, 0, &self->mainAnimator, true, 0);
234
RSDK.SetSpriteAnimation(FlameSpring->aniFrames, 1, &self->nozzleAnimator, true, 0);
235
if (self->type > FLAMESPRING_LEFT)
236
self->mainAnimator.frameID = 2;
237
238
uint8 type = self->type % 3;
239
if (self->mainAnimator.frameID != 1 && type != FLAMESPRING_RIGHT) {
240
self->nozzleAnimator.frameID = self->flamePosL.x > self->position.x;
241
RSDK.DrawSprite(&self->nozzleAnimator, &self->flamePosL, false);
242
}
243
244
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
245
246
if (self->mainAnimator.frameID != 1 && type != FLAMESPRING_LEFT) {
247
self->nozzleAnimator.frameID = self->flamePosR.x > self->position.x;
248
RSDK.DrawSprite(&self->nozzleAnimator, &self->flamePosR, false);
249
}
250
}
251
252
void FlameSpring_EditorLoad(void)
253
{
254
FlameSpring->aniFrames = RSDK.LoadSpriteAnimation("FBZ/FlameSpring.bin", SCOPE_STAGE);
255
256
RSDK_ACTIVE_VAR(FlameSpring, type);
257
RSDK_ENUM_VAR("Circle", FLAMESPRING_BOTH);
258
RSDK_ENUM_VAR("Right", FLAMESPRING_RIGHT);
259
RSDK_ENUM_VAR("Left", FLAMESPRING_LEFT);
260
RSDK_ENUM_VAR("Both Sides (No Spring)", FLAMESPRING_BOTH_NOSPRING);
261
RSDK_ENUM_VAR("Right Only (No Spring)", FLAMESPRING_RIGHT_NOSPRING);
262
RSDK_ENUM_VAR("Left Only (No Spring)", FLAMESPRING_LEFT_NOSPRING);
263
264
RSDK_ACTIVE_VAR(FlameSpring, force);
265
RSDK_ENUM_VAR("Weak", FLAMESPRING_FORCE_WEAK);
266
RSDK_ENUM_VAR("Strong", FLAMESPRING_FORCE_STRONG);
267
268
RSDK_ACTIVE_VAR(FlameSpring, playerAni);
269
RSDK_ENUM_VAR("Spring Diagonal", FLAMESPRING_PANI_DIAGONAL);
270
RSDK_ENUM_VAR("Spring Twirl", FLAMESPRING_PANI_TWIRL);
271
}
272
#endif
273
274
void FlameSpring_Serialize(void)
275
{
276
RSDK_EDITABLE_VAR(FlameSpring, VAR_ENUM, type);
277
RSDK_EDITABLE_VAR(FlameSpring, VAR_ENUM, force);
278
RSDK_EDITABLE_VAR(FlameSpring, VAR_UINT8, playerAni);
279
RSDK_EDITABLE_VAR(FlameSpring, VAR_UINT8, offset);
280
}
281
282