Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/ERZ/PhantomRider.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: PhantomRider Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPhantomRider *PhantomRider;
11
12
void PhantomRider_Update(void)
13
{
14
RSDK_THIS(PhantomRider);
15
16
if (self->invincibilityTimer > 0)
17
self->invincibilityTimer--;
18
19
StateMachine_Run(self->state);
20
}
21
22
void PhantomRider_LateUpdate(void) {}
23
24
void PhantomRider_StaticUpdate(void) {}
25
26
void PhantomRider_Draw(void)
27
{
28
RSDK_THIS(PhantomRider);
29
30
RSDK.SetActivePalette(4, 0, ScreenInfo[SceneInfo->currentScreenID].size.y);
31
32
if (self->invincibilityTimer & 1)
33
RSDK.CopyPalette(6, 128, 4, 128, 128);
34
35
if (self->stateDraw) {
36
StateMachine_Run(self->stateDraw);
37
}
38
else {
39
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
40
}
41
42
if (self->invincibilityTimer & 1)
43
RSDK.CopyPalette(5, 128, 4, 128, 128);
44
45
RSDK.SetActivePalette(0, 0, ScreenInfo[SceneInfo->currentScreenID].size.y);
46
}
47
48
void PhantomRider_Create(void *data)
49
{
50
RSDK_THIS(PhantomRider);
51
52
if (!SceneInfo->inEditor) {
53
self->visible = true;
54
self->drawGroup = Zone->objectDrawGroup[0];
55
self->updateRange.x = 0x800000;
56
self->updateRange.y = 0x800000;
57
self->type = VOID_TO_INT(data);
58
59
if (data) {
60
if (VOID_TO_INT(data) == PHANTOMRIDER_JIMMY) {
61
self->active = ACTIVE_NORMAL;
62
self->state = PhantomRider_State_Jimmy;
63
}
64
}
65
else {
66
self->active = ACTIVE_BOUNDS;
67
self->drawFX = FX_FLIP;
68
69
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 0, &self->mainAnimator, true, 0);
70
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 4, &self->jimmyAnimator, true, 0);
71
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 5, &self->wheelAnimator, true, 0);
72
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 6, &self->thrustAnimator, true, 0);
73
74
self->direction = FLIP_X;
75
self->collisionPlane = 1;
76
self->collisionLayers = Zone->collisionLayers;
77
self->startPos = self->position;
78
self->tileCollisions = TILECOLLISION_DOWN;
79
80
self->hitbox.left = -24;
81
self->hitbox.top = 0;
82
self->hitbox.right = 24;
83
self->hitbox.bottom = 20;
84
85
self->outerBox.left = -12;
86
self->outerBox.top = 0;
87
self->outerBox.right = 12;
88
self->outerBox.bottom = 30;
89
90
self->innerBox.left = -11;
91
self->innerBox.top = 0;
92
self->innerBox.right = 11;
93
self->innerBox.bottom = 30;
94
95
self->stateDraw = PhantomRider_Draw_Rider;
96
self->state = PhantomRider_State_HandleBegin;
97
}
98
}
99
}
100
101
void PhantomRider_StageLoad(void)
102
{
103
PhantomRider->aniFrames = RSDK.LoadSpriteAnimation("Phantom/PhantomRider.bin", SCOPE_STAGE);
104
105
PhantomRider->sfxRiderLaunch = RSDK.GetSfx("LRZ/RiderLaunch.wav");
106
}
107
108
void PhantomRider_ProcessAutoScroll(void)
109
{
110
if (Zone->autoScrollSpeed > 0x80000) {
111
Zone->autoScrollSpeed -= 0x2000;
112
113
if (Zone->autoScrollSpeed < 0x80000)
114
Zone->autoScrollSpeed = 0x80000;
115
}
116
117
if (Zone->autoScrollSpeed < 0x80000) {
118
Zone->autoScrollSpeed += 0x2000;
119
120
if (Zone->autoScrollSpeed > 0x80000)
121
Zone->autoScrollSpeed = 0x80000;
122
}
123
124
foreach_active(Player, player)
125
{
126
if (player->groundVel < Zone->autoScrollSpeed - 0x20000)
127
player->groundVel = Zone->autoScrollSpeed - 0x20000;
128
129
player->direction = FLIP_NONE;
130
player->topSpeed = Zone->autoScrollSpeed + 0x20000;
131
132
if (player->groundVel > player->topSpeed)
133
player->groundVel = player->topSpeed;
134
}
135
}
136
137
void PhantomRider_Hit(void)
138
{
139
RSDK_THIS(PhantomRider);
140
141
self->invincibilityTimer = 48;
142
RSDK.PlaySfx(PhantomEgg->sfxHit, false, 255);
143
}
144
145
void PhantomRider_Draw_Rider(void)
146
{
147
RSDK_THIS(PhantomRider);
148
149
RSDK.DrawSprite(&self->jimmyAnimator, NULL, false);
150
RSDK.DrawSprite(&self->mainAnimator, NULL, false);
151
RSDK.DrawSprite(&self->wheelAnimator, NULL, false);
152
RSDK.DrawSprite(&self->thrustAnimator, NULL, false);
153
}
154
155
void PhantomRider_State_HandleBegin(void)
156
{
157
RSDK_THIS(PhantomRider);
158
159
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
160
161
if (player1->position.x > self->position.x) {
162
EntityPhantomRider *child = CREATE_ENTITY(PhantomRider, INT_TO_VOID(PHANTOMRIDER_JIMMY), player1->position.x, player1->position.y);
163
164
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
165
camera->target = (Entity *)child;
166
camera->state = Camera_State_FollowXY;
167
168
player1->camera = NULL;
169
Zone->autoScrollSpeed = player1->velocity.x;
170
171
self->groundVel = 0;
172
self->velocity.x = 0;
173
self->child = child;
174
self->active = ACTIVE_NORMAL;
175
self->state = PhantomRider_State_EnterRider;
176
177
foreach_active(PopOut, popOut)
178
{
179
popOut->active = ACTIVE_NORMAL;
180
popOut->drawGroup = 2;
181
}
182
foreach_active(Button, button) { button->active = ACTIVE_NORMAL; }
183
RSDK.PlaySfx(PhantomRider->sfxRiderLaunch, false, 255);
184
}
185
}
186
187
void PhantomRider_State_EnterRider(void)
188
{
189
RSDK_THIS(PhantomRider);
190
191
RSDK.ProcessAnimation(&self->mainAnimator);
192
RSDK.ProcessAnimation(&self->jimmyAnimator);
193
RSDK.ProcessAnimation(&self->wheelAnimator);
194
RSDK.ProcessAnimation(&self->thrustAnimator);
195
196
PhantomRider_ProcessAutoScroll();
197
198
if (++self->timer > 48) {
199
if (self->groundVel < 0xC0000)
200
self->groundVel += 0x40000;
201
}
202
203
if (self->position.x > self->child->position.x + 0x200000) {
204
self->timer = 0;
205
206
RSDK.PlaySfx(PhantomRider->sfxRiderLaunch, false, 0xFF);
207
self->state = PhantomRider_State_InitialRace;
208
}
209
210
if (!self->onGround) {
211
self->velocity.y += 0x3800;
212
213
if (self->velocity.y > 0xC0000)
214
self->velocity.y = 0xC0000;
215
}
216
217
self->prevOnGround = self->onGround;
218
RSDK.ProcessObjectMovement(self, &self->outerBox, &self->innerBox);
219
}
220
221
void PhantomRider_State_InitialRace(void)
222
{
223
RSDK_THIS(PhantomRider);
224
225
RSDK.ProcessAnimation(&self->mainAnimator);
226
RSDK.ProcessAnimation(&self->jimmyAnimator);
227
RSDK.ProcessAnimation(&self->wheelAnimator);
228
RSDK.ProcessAnimation(&self->thrustAnimator);
229
230
PhantomRider_ProcessAutoScroll();
231
232
if (self->groundVel > Zone->autoScrollSpeed - 0x10000) {
233
self->groundVel -= 0x2000;
234
235
if (self->groundVel < Zone->autoScrollSpeed - 0x4000)
236
self->groundVel = Zone->autoScrollSpeed - 0x4000;
237
}
238
239
if (!self->onGround) {
240
self->velocity.y += 0x3800;
241
242
if (self->velocity.y > 0xC0000)
243
self->velocity.y = 0xC0000;
244
}
245
246
self->prevOnGround = self->onGround;
247
RSDK.ProcessObjectMovement(self, &self->outerBox, &self->innerBox);
248
249
EntityPlatformNode *marker = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, PlatformNode);
250
if (self->position.x > marker->position.x)
251
self->state = PhantomRider_State_RacePlayer;
252
}
253
254
void PhantomRider_State_RacePlayer(void)
255
{
256
RSDK_THIS(PhantomRider);
257
258
RSDK.ProcessAnimation(&self->mainAnimator);
259
RSDK.ProcessAnimation(&self->jimmyAnimator);
260
RSDK.ProcessAnimation(&self->wheelAnimator);
261
RSDK.ProcessAnimation(&self->thrustAnimator);
262
263
PhantomRider_ProcessAutoScroll();
264
265
if (!self->onGround) {
266
self->velocity.y += 0x3800;
267
268
if (self->velocity.y > 0xC0000)
269
self->velocity.y = 0xC0000;
270
}
271
272
self->prevOnGround = self->onGround;
273
RSDK.ProcessObjectMovement(self, &self->outerBox, &self->innerBox);
274
275
if (++self->timer == 560) {
276
self->timer = 0;
277
Zone->autoScrollSpeed = 0;
278
279
PhantomEgg_SetupWarpFX();
280
self->state = PhantomRider_State_ExitRider;
281
282
foreach_active(PopOut, popOut) { popOut->shouldAppear = false; }
283
foreach_active(Player, player) { Player_UpdatePhysicsState(player); }
284
}
285
286
foreach_active(Spikes, spikes)
287
{
288
if (RSDK.CheckObjectCollisionTouchBox(self, &self->hitbox, spikes, &spikes->hitbox) == C_TOP) {
289
EntityPopOut *popOut = RSDK_GET_ENTITY(RSDK.GetEntitySlot(spikes) - 1, PopOut);
290
popOut->shouldAppear = false;
291
292
foreach_active(Button, button)
293
{
294
if (button->tag == popOut->tag)
295
button->activated = false;
296
}
297
298
PhantomRider_Hit();
299
}
300
}
301
}
302
303
void PhantomRider_State_ExitRider(void)
304
{
305
RSDK_THIS(PhantomRider);
306
307
if (++self->timer == 60) {
308
self->position.x = self->startPos.x;
309
self->position.y = self->startPos.y;
310
self->timer = 0;
311
self->active = ACTIVE_BOUNDS;
312
destroyEntity(self->child);
313
314
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
315
Camera_SetTargetEntity(0, player1);
316
player1->camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
317
318
foreach_active(PopOut, popOut) { popOut->active = ACTIVE_BOUNDS; }
319
320
foreach_active(Button, button)
321
{
322
button->active = ACTIVE_BOUNDS;
323
button->activated = false;
324
}
325
326
self->state = PhantomRider_State_HandleBegin;
327
}
328
}
329
330
void PhantomRider_State_Jimmy(void)
331
{
332
RSDK_THIS(PhantomRider);
333
334
self->position.x += Zone->autoScrollSpeed;
335
336
if (self->position.y < 0x8A80000)
337
self->position.y += 0x20000;
338
339
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
340
341
if (camera->offset.y > 0)
342
camera->offset.y -= (camera->offset.y >> 4);
343
344
foreach_active(Player, player)
345
{
346
int32 x = self->position.x - (ScreenInfo->center.x << 16) + 0x100000;
347
if (player->position.x < x)
348
player->position.x = x;
349
350
int32 y = ((ScreenInfo->center.x - 16) << 16) + self->position.x;
351
if (player->position.x > y)
352
player->position.x = y;
353
}
354
}
355
356
#if GAME_INCLUDE_EDITOR
357
void PhantomRider_EditorDraw(void)
358
{
359
RSDK_THIS(PhantomRider);
360
361
self->drawFX = FX_FLIP;
362
self->direction = FLIP_X;
363
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 0, &self->mainAnimator, true, 0);
364
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 4, &self->jimmyAnimator, true, 0);
365
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 5, &self->wheelAnimator, true, 0);
366
RSDK.SetSpriteAnimation(PhantomRider->aniFrames, 6, &self->thrustAnimator, true, 0);
367
368
PhantomRider_Draw_Rider();
369
}
370
371
void PhantomRider_EditorLoad(void) { PhantomRider->aniFrames = RSDK.LoadSpriteAnimation("Phantom/PhantomRider.bin", SCOPE_STAGE); }
372
#endif
373
374
void PhantomRider_Serialize(void) {}
375
376