Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/PGZ/PSZ2Outro.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: PSZ2Outro Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPSZ2Outro *PSZ2Outro;
11
12
void PSZ2Outro_Update(void)
13
{
14
RSDK_THIS(PSZ2Outro);
15
16
CutsceneSeq_StartSequence(self, PSZ2Outro_Cutscene_SetupCameraMove, PSZ2Outro_Cutscene_HandleCameraMovement, PSZ2Outro_Cutscene_WalkIntoPlace,
17
PSZ2Outro_Cutscene_EnterRuby, PSZ2Outro_Cutscene_RubyActivated, PSZ2Outro_Cutscene_RubyWarp,
18
PSZ2Outro_Cutscene_LoadSSZ1, StateMachine_None);
19
20
#if MANIA_USE_PLUS
21
CutsceneSeq_SetSkipType(SKIPTYPE_RELOADSCN);
22
#endif
23
24
HUD_MoveOut();
25
self->active = ACTIVE_NEVER;
26
}
27
28
void PSZ2Outro_LateUpdate(void) {}
29
30
void PSZ2Outro_StaticUpdate(void) {}
31
32
void PSZ2Outro_Draw(void) {}
33
34
void PSZ2Outro_Create(void *data)
35
{
36
RSDK_THIS(PSZ2Outro);
37
38
if (!SceneInfo->inEditor) {
39
foreach_all(PSZEggman, eggman) { self->eggman = eggman; }
40
41
self->active = ACTIVE_NORMAL;
42
self->visible = false;
43
}
44
}
45
46
void PSZ2Outro_StageLoad(void) {}
47
48
bool32 PSZ2Outro_Cutscene_SetupCameraMove(EntityCutsceneSeq *host)
49
{
50
RSDK_THIS(PSZ2Outro);
51
52
EntityPSZEggman *eggman = self->eggman;
53
54
foreach_active(Player, player)
55
{
56
if (!player->sidekick) {
57
player->stateInput = StateMachine_None;
58
CutsceneSeq_LockAllPlayerControl();
59
player->left = false;
60
player->right = false;
61
player->up = false;
62
player->down = false;
63
player->jumpPress = false;
64
}
65
}
66
67
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
68
camera->position.x = (camera->boundsR + camera->boundsL) << 15;
69
camera->boundsR += 512;
70
Zone->playerBoundActiveR[0] = false;
71
Zone->playerBoundActiveR[1] = false;
72
73
FXRuby_SetupLayerDeformation();
74
Camera_SetupLerp(CAMERA_LERP_SIN512, 0, eggman->position.x - 0x600000, camera->position.y, 2);
75
Music_PlayTrack(TRACK_STAGE);
76
77
return true;
78
}
79
80
bool32 PSZ2Outro_Cutscene_HandleCameraMovement(EntityCutsceneSeq *host)
81
{
82
RSDK_THIS(PSZ2Outro);
83
84
EntityPSZEggman *eggman = self->eggman;
85
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
86
87
if (host->timer == 180) {
88
foreach_active(Player, player)
89
{
90
player->position.x = camera->position.x - (ScreenInfo->center.x << 16) - 0x400000;
91
player->position.y = eggman->position.y;
92
player->state = Player_State_Ground;
93
94
if (!player->sidekick)
95
player->right = true;
96
}
97
98
return true;
99
}
100
101
return false;
102
}
103
104
bool32 PSZ2Outro_Cutscene_WalkIntoPlace(EntityCutsceneSeq *host)
105
{
106
RSDK_THIS(PSZ2Outro);
107
108
EntityPSZEggman *eggman = self->eggman;
109
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
110
111
foreach_active(Player, player)
112
{
113
player->direction = FLIP_NONE;
114
115
if (player->groundVel > 0x30000)
116
player->groundVel = 0x30000;
117
118
if (!player->sidekick) {
119
if (camera->position.x - player->position.x >= 0x600000) {
120
player->left = false;
121
player->right = true;
122
}
123
else {
124
if (!player->skidding) {
125
RSDK.SetSpriteAnimation(PSZEggman->aniFrames, 1, &eggman->eggmanAnimator, false, 0);
126
eggman->state = PSZEggman_State_TurnRound;
127
player->skidding = 24;
128
}
129
130
player->right = false;
131
}
132
}
133
}
134
135
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
136
if (player1->skidding == 4) {
137
foreach_active(Player, playerPtr)
138
{
139
playerPtr->groundVel = 0;
140
playerPtr->skidding = false;
141
}
142
143
return true;
144
}
145
146
return false;
147
}
148
149
bool32 PSZ2Outro_Cutscene_EnterRuby(EntityCutsceneSeq *host)
150
{
151
RSDK_THIS(PSZ2Outro);
152
EntityPlayer *player2 = RSDK_GET_ENTITY(SLOT_PLAYER2, Player);
153
154
if (RSDK.GetEntityCount(PhantomRuby->classID, true) > 0) {
155
foreach_active(PhantomRuby, ruby) { self->ruby = ruby; }
156
}
157
158
if (self->ruby && self->ruby->state == PhantomRuby_State_Oscillate) {
159
if (player2->classID == Player->classID) {
160
player2->state = Player_State_Static;
161
RSDK.SetSpriteAnimation(player2->aniFrames, ANI_SKID, &player2->animator, false, 0);
162
}
163
164
return true;
165
}
166
167
return false;
168
}
169
170
bool32 PSZ2Outro_Cutscene_RubyActivated(EntityCutsceneSeq *host)
171
{
172
RSDK_THIS(PSZ2Outro);
173
174
EntityPhantomRuby *ruby = self->ruby;
175
176
if (!host->timer)
177
PhantomRuby_SetupFlash(ruby);
178
179
if (ruby->flashFinished) {
180
PhantomRuby_PlaySfx(RUBYSFX_REDCUBE);
181
return true;
182
}
183
184
return false;
185
}
186
187
bool32 PSZ2Outro_Cutscene_RubyWarp(EntityCutsceneSeq *host)
188
{
189
RSDK_THIS(PSZ2Outro);
190
191
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player); \
192
EntityPlayer *player2 = RSDK_GET_ENTITY(SLOT_PLAYER2, Player); \
193
194
EntityPhantomRuby *ruby = self->ruby;
195
EntityFXRuby *fxRuby = NULL;
196
if (host->timer) {
197
fxRuby = self->fxRuby;
198
}
199
else {
200
fxRuby = CREATE_ENTITY(FXRuby, NULL, ruby->position.x, ruby->position.y);
201
fxRuby->drawGroup = Zone->playerDrawGroup[1];
202
self->fxRuby = fxRuby;
203
Camera_ShakeScreen(0, 4, 4);
204
player1->drawGroup = Zone->playerDrawGroup[1] + 1;
205
if (player2->classID == Player->classID)
206
player2->drawGroup = Zone->playerDrawGroup[1] + 1;
207
}
208
209
if (!host->values[0]) {
210
if (fxRuby->fullyExpanded) {
211
if (host->storedTimer) {
212
if (host->timer == host->storedTimer + 48) {
213
fxRuby->delay = 64;
214
fxRuby->state = FXRuby_State_IncreaseStageDeform;
215
PhantomRuby_PlaySfx(RUBYSFX_ATTACK4);
216
Camera_ShakeScreen(0, 4, 4);
217
}
218
else if (host->timer == host->storedTimer + 180) {
219
fxRuby->delay = 32;
220
fxRuby->state = FXRuby_State_IncreaseStageDeform;
221
PhantomRuby_PlaySfx(RUBYSFX_ATTACK1);
222
Camera_ShakeScreen(0, 4, 4);
223
Music_FadeOut(0.025);
224
host->storedTimer = host->timer;
225
host->values[0] = true;
226
}
227
}
228
else {
229
host->storedTimer = host->timer;
230
}
231
232
if (host->timer >= host->storedTimer + 52) {
233
EntityPlayer *players[2] = {player1, player2};
234
for (int32 i = 0; i < 2; ++i) {
235
EntityPlayer *player = players[i];
236
if (player->classID == Player->classID) {
237
RSDK.SetSpriteAnimation(player->aniFrames, ANI_FAN, &player->animator, false, 0);
238
239
int32 valX = (player->position.x - player->position.x) >> 3;
240
int32 valY =
241
(0xA00 * RSDK.Sin256(2 * ((i * 0x40) + host->timer - host->storedTimer)) + (ruby->position.y - 0x200000) - player->position.y)
242
>> 3;
243
244
player->position.x += valX;
245
player->position.y += valY;
246
player->state = Player_State_Static;
247
player->tileCollisions = TILECOLLISION_NONE;
248
player->onGround = false;
249
}
250
}
251
}
252
}
253
}
254
else {
255
if (fxRuby->fadeWhite >= 512) {
256
if (fxRuby->fadeBlack >= 512) {
257
if (host->timer == host->storedTimer + 150)
258
return true;
259
}
260
else {
261
fxRuby->fadeBlack += 16;
262
}
263
}
264
else {
265
fxRuby->fadeWhite += 16;
266
}
267
}
268
269
return false;
270
}
271
272
bool32 PSZ2Outro_Cutscene_LoadSSZ1(EntityCutsceneSeq *host)
273
{
274
if (host->timer == 16) {
275
RSDK.LoadScene();
276
return true;
277
}
278
279
return false;
280
}
281
282
#if GAME_INCLUDE_EDITOR
283
void PSZ2Outro_EditorDraw(void)
284
{
285
RSDK_THIS(PSZ2Outro);
286
CutsceneRules_DrawCutsceneBounds(self, &self->size);
287
}
288
289
void PSZ2Outro_EditorLoad(void) {}
290
#endif
291
292
void PSZ2Outro_Serialize(void) { RSDK_EDITABLE_VAR(PSZ2Outro, VAR_VECTOR2, size); }
293
294