Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/OOZ/PushSpring.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: PushSpring Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPushSpring *PushSpring;
11
12
void PushSpring_Update(void)
13
{
14
RSDK_THIS(PushSpring);
15
16
StateMachine_Run(self->state);
17
18
self->beingPushed = false;
19
StateMachine_Run(self->stateCollide);
20
}
21
22
void PushSpring_LateUpdate(void) {}
23
24
void PushSpring_StaticUpdate(void) {}
25
26
void PushSpring_Draw(void)
27
{
28
RSDK_THIS(PushSpring);
29
30
if (self->pushOffset) {
31
StateMachine_Run(self->stateDraw);
32
}
33
else {
34
self->animator.frameID = 0;
35
RSDK.DrawSprite(&self->animator, NULL, false);
36
}
37
}
38
39
void PushSpring_Create(void *data)
40
{
41
RSDK_THIS(PushSpring);
42
43
self->drawFX = FX_FLIP;
44
if (!SceneInfo->inEditor) {
45
self->active = ACTIVE_BOUNDS;
46
self->visible = true;
47
self->drawGroup = Zone->objectDrawGroup[0];
48
self->updateRange.x = 0x800000;
49
self->updateRange.y = 0x800000;
50
51
RSDK.SetSpriteAnimation(PushSpring->aniFrames, self->type, &self->animator, true, 0);
52
53
if (self->type != PUSHSPRING_V) {
54
if (self->direction) {
55
self->stateDraw = PushSpring_Draw_Left;
56
self->stateCollide = PushSpring_Collide_Left;
57
}
58
else {
59
self->stateDraw = PushSpring_Draw_Right;
60
self->stateCollide = PushSpring_Collide_Right;
61
}
62
63
self->groundVel = 0x4000;
64
65
self->hitbox.left = -20;
66
self->hitbox.top = -16;
67
self->hitbox.right = 20;
68
self->hitbox.bottom = 16;
69
70
self->state = PushSpring_State_WaitForPushed;
71
}
72
else {
73
if (self->direction) {
74
self->direction = FLIP_Y;
75
self->stateDraw = PushSpring_Draw_Bottom;
76
self->stateCollide = PushSpring_Collide_Bottom;
77
}
78
else {
79
self->stateDraw = PushSpring_Draw_Top;
80
self->stateCollide = PushSpring_Collide_Top;
81
}
82
83
self->groundVel = 0x20000;
84
85
self->hitbox.left = -16;
86
self->hitbox.top = -20;
87
self->hitbox.right = 16;
88
self->hitbox.bottom = 20;
89
90
self->state = PushSpring_State_WaitForPushed;
91
}
92
}
93
}
94
95
void PushSpring_StageLoad(void)
96
{
97
if (RSDK.CheckSceneFolder("OOZ1") || RSDK.CheckSceneFolder("OOZ2"))
98
PushSpring->aniFrames = RSDK.LoadSpriteAnimation("OOZ/PushSpring.bin", SCOPE_STAGE);
99
100
PushSpring->sfxPush = RSDK.GetSfx("Stage/Push.wav");
101
PushSpring->sfxSpring = RSDK.GetSfx("Global/Spring.wav");
102
}
103
104
void PushSpring_Collide_Top(void)
105
{
106
RSDK_THIS(PushSpring);
107
108
self->hitbox.top = (self->pushOffset >> 16) - 22;
109
110
foreach_active(Player, player)
111
{
112
if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_TOP) {
113
player->position.y += 0x20000;
114
self->beingPushed |= true;
115
116
if (self->pushOffset >= 0x120000) {
117
player->collisionMode = 0;
118
player->onGround = false;
119
player->state = Player_State_Air;
120
player->velocity.y = -0xA0000;
121
122
int32 anim = player->animator.animationID;
123
if (anim == ANI_WALK || (anim > ANI_AIR_WALK && anim <= ANI_DASH))
124
player->animationReserve = player->animator.animationID;
125
else
126
player->animationReserve = ANI_WALK;
127
128
RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_DIAGONAL, &player->animator, true, 0);
129
RSDK.PlaySfx(PushSpring->sfxSpring, false, 255);
130
self->state = PushSpring_State_PushRecoil;
131
}
132
}
133
}
134
}
135
136
void PushSpring_Collide_Bottom(void)
137
{
138
RSDK_THIS(PushSpring);
139
140
self->hitbox.top = (self->pushOffset >> 16) - 22;
141
142
foreach_active(Player, player)
143
{
144
int32 yvel = player->velocity.y;
145
146
if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_BOTTOM) {
147
if (yvel < 0) {
148
player->velocity.y = yvel + 0x3800;
149
player->position.y -= 0x20000;
150
self->beingPushed |= true;
151
}
152
153
if (self->pushOffset >= 0x120000) {
154
player->collisionMode = 0;
155
player->onGround = false;
156
player->state = Player_State_Air;
157
player->velocity.y = 0xA0000;
158
RSDK.PlaySfx(PushSpring->sfxSpring, false, 255);
159
self->state = PushSpring_State_PushRecoil;
160
}
161
}
162
}
163
}
164
165
void PushSpring_Collide_Left(void)
166
{
167
RSDK_THIS(PushSpring);
168
169
self->hitbox.right = 22 - (self->pushOffset >> 16);
170
171
foreach_active(Player, player)
172
{
173
if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_LEFT) {
174
if (player->direction == FLIP_NONE)
175
player->position.x += 0x20000;
176
177
if (player->right)
178
self->beingPushed |= true;
179
180
if (self->state == PushSpring_State_PushRecoil) {
181
if (self->pushOffset > 0x10000) {
182
player->groundVel = -12 * self->pushOffset / 18;
183
player->velocity.x = player->groundVel;
184
player->collisionMode = 0;
185
player->controlLock = 16;
186
player->pushing = false;
187
player->direction = self->direction;
188
player->state = Player_State_Ground;
189
RSDK.PlaySfx(PushSpring->sfxSpring, false, 255);
190
}
191
}
192
}
193
}
194
}
195
196
void PushSpring_Collide_Right(void)
197
{
198
RSDK_THIS(PushSpring);
199
200
self->hitbox.right = 22 - (self->pushOffset >> 16);
201
202
foreach_active(Player, player)
203
{
204
if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_RIGHT) {
205
if (player->direction == FLIP_X)
206
player->position.x -= 0x20000;
207
208
if (player->left)
209
self->beingPushed |= true;
210
211
if (self->state == PushSpring_State_PushRecoil) {
212
if (self->pushOffset > 0x10000) {
213
player->groundVel = 12 * self->pushOffset / 18;
214
player->velocity.x = player->groundVel;
215
player->collisionMode = 0;
216
player->controlLock = 16;
217
player->pushing = false;
218
player->direction = self->direction;
219
player->state = Player_State_Ground;
220
RSDK.PlaySfx(PushSpring->sfxSpring, false, 255);
221
}
222
}
223
}
224
}
225
}
226
227
void PushSpring_Draw_Top(void)
228
{
229
RSDK_THIS(PushSpring);
230
231
Vector2 drawPos = self->position;
232
drawPos.y += self->pushOffset;
233
self->animator.frameID = 1;
234
RSDK.DrawSprite(&self->animator, &drawPos, false);
235
236
drawPos.y = self->position.y + 2 * self->pushOffset / 3;
237
self->animator.frameID = 2;
238
RSDK.DrawSprite(&self->animator, &drawPos, false);
239
240
drawPos.y = self->position.y + self->pushOffset / 3;
241
self->animator.frameID = 3;
242
RSDK.DrawSprite(&self->animator, &drawPos, false);
243
244
self->animator.frameID = 4;
245
RSDK.DrawSprite(&self->animator, NULL, false);
246
}
247
248
void PushSpring_Draw_Bottom(void)
249
{
250
RSDK_THIS(PushSpring);
251
252
Vector2 drawPos = self->position;
253
drawPos.y -= self->pushOffset;
254
self->animator.frameID = 1;
255
RSDK.DrawSprite(&self->animator, &drawPos, false);
256
257
drawPos.y = self->position.y - 2 * self->pushOffset / 3;
258
self->animator.frameID = 2;
259
RSDK.DrawSprite(&self->animator, &drawPos, false);
260
261
drawPos.y = self->position.y - self->pushOffset / 3;
262
self->animator.frameID = 3;
263
RSDK.DrawSprite(&self->animator, &drawPos, false);
264
265
self->animator.frameID = 4;
266
RSDK.DrawSprite(&self->animator, 0, false);
267
}
268
269
void PushSpring_Draw_Left(void)
270
{
271
RSDK_THIS(PushSpring);
272
273
Vector2 drawPos = self->position;
274
drawPos.x += self->pushOffset;
275
self->animator.frameID = 1;
276
RSDK.DrawSprite(&self->animator, &drawPos, false);
277
278
drawPos.x = self->position.x + 2 * self->pushOffset / 3;
279
self->animator.frameID = 2;
280
RSDK.DrawSprite(&self->animator, &drawPos, false);
281
282
drawPos.x = self->position.x + self->pushOffset / 3;
283
self->animator.frameID = 3;
284
RSDK.DrawSprite(&self->animator, &drawPos, false);
285
286
self->animator.frameID = 4;
287
RSDK.DrawSprite(&self->animator, NULL, false);
288
}
289
290
void PushSpring_Draw_Right(void)
291
{
292
RSDK_THIS(PushSpring);
293
294
Vector2 drawPos = self->position;
295
drawPos.x -= self->pushOffset;
296
self->animator.frameID = 1;
297
RSDK.DrawSprite(&self->animator, &drawPos, false);
298
299
drawPos.x = self->position.x - 2 * self->pushOffset / 3;
300
self->animator.frameID = 2;
301
RSDK.DrawSprite(&self->animator, &drawPos, false);
302
303
drawPos.x = self->position.x - self->pushOffset / 3;
304
self->animator.frameID = 3;
305
RSDK.DrawSprite(&self->animator, &drawPos, false);
306
307
self->animator.frameID = 4;
308
RSDK.DrawSprite(&self->animator, NULL, false);
309
}
310
311
void PushSpring_State_WaitForPushed(void)
312
{
313
RSDK_THIS(PushSpring);
314
315
if (self->beingPushed) {
316
self->timer = 0;
317
self->state = PushSpring_State_BeingPushed;
318
}
319
}
320
321
void PushSpring_State_BeingPushed(void)
322
{
323
RSDK_THIS(PushSpring);
324
325
if (self->beingPushed) {
326
self->pushOffset += self->groundVel;
327
328
if (self->pushOffset < 0x120000) {
329
if (!(self->timer % 10))
330
RSDK.PlaySfx(PushSpring->sfxPush, false, 0xFF);
331
}
332
else {
333
self->pushOffset = 0x120000;
334
}
335
336
++self->timer;
337
}
338
else {
339
self->state = PushSpring_State_PushRecoil;
340
}
341
}
342
343
void PushSpring_State_PushRecoil(void)
344
{
345
RSDK_THIS(PushSpring);
346
347
if (self->beingPushed) {
348
self->timer = 0;
349
self->state = PushSpring_State_BeingPushed;
350
}
351
else {
352
self->pushOffset -= 0x20000;
353
354
if (self->pushOffset <= 0) {
355
self->pushOffset = 0;
356
self->state = PushSpring_State_WaitForPushed;
357
}
358
}
359
}
360
361
#if GAME_INCLUDE_EDITOR
362
void PushSpring_EditorDraw(void)
363
{
364
RSDK_THIS(PushSpring);
365
366
int32 dir = self->direction;
367
368
RSDK.SetSpriteAnimation(PushSpring->aniFrames, self->type, &self->animator, false, 0);
369
370
if (self->type == PUSHSPRING_V)
371
self->direction *= FLIP_Y;
372
373
RSDK.DrawSprite(&self->animator, NULL, false);
374
375
self->direction = dir;
376
}
377
378
void PushSpring_EditorLoad(void)
379
{
380
PushSpring->aniFrames = RSDK.LoadSpriteAnimation("OOZ/PushSpring.bin", SCOPE_STAGE);
381
382
RSDK_ACTIVE_VAR(PushSpring, type);
383
RSDK_ENUM_VAR("Vertical", PUSHSPRING_V);
384
RSDK_ENUM_VAR("Horizontal", PUSHSPRING_H);
385
386
RSDK_ACTIVE_VAR(PushSpring, direction);
387
RSDK_ENUM_VAR("No Flip", FLIP_NONE);
388
RSDK_ENUM_VAR("Flipped", FLIP_X);
389
}
390
#endif
391
392
void PushSpring_Serialize(void)
393
{
394
RSDK_EDITABLE_VAR(PushSpring, VAR_UINT8, type);
395
RSDK_EDITABLE_VAR(PushSpring, VAR_UINT8, direction);
396
}
397
398