Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/GHZ/GHZCutsceneST.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: GHZCutsceneST Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectGHZCutsceneST *GHZCutsceneST;
11
12
void GHZCutsceneST_Update(void)
13
{
14
RSDK_THIS(GHZCutsceneST);
15
16
if (!self->setupKnuxCutscene) {
17
GHZCutsceneST_SetupKnuxCutscene();
18
self->setupKnuxCutscene = true;
19
}
20
21
if (!self->activated) {
22
foreach_active(Player, player)
23
{
24
if (Player_CheckCollisionTouch(player, self, &self->hitbox) && !player->sidekick) {
25
CutsceneSeq_StartSequence(self, GHZCutsceneST_Cutscene_FadeIn, GHZCutsceneST_Cutscene_FinishRubyWarp, GHZCutsceneST_Cutscene_ExitHBH,
26
GHZCutsceneST_Cutscene_SetupGHZ1, StateMachine_None);
27
28
#if MANIA_USE_PLUS
29
CutsceneSeq_SetSkipTypeCallback(GHZCutsceneST_Cutscene_SkipCB);
30
#endif
31
32
self->activated = true;
33
}
34
}
35
}
36
++self->timer;
37
}
38
39
void GHZCutsceneST_LateUpdate(void) {}
40
41
void GHZCutsceneST_StaticUpdate(void) {}
42
43
void GHZCutsceneST_Draw(void) {}
44
45
void GHZCutsceneST_Create(void *data)
46
{
47
RSDK_THIS(GHZCutsceneST);
48
if (!SceneInfo->inEditor) {
49
INIT_ENTITY(self);
50
CutsceneRules_SetupEntity(self, &self->size, &self->hitbox);
51
self->active = ACTIVE_BOUNDS;
52
53
GHZCutsceneST_SetupObjects();
54
55
SceneInfo->timeEnabled = false;
56
}
57
}
58
59
void GHZCutsceneST_StageLoad(void) {}
60
61
void GHZCutsceneST_SetupObjects(void)
62
{
63
foreach_all(Platform, platform)
64
{
65
if (!platform->frameID) {
66
platform->drawGroup = Zone->objectDrawGroup[1] - 1;
67
GHZCutsceneST->platform = platform;
68
foreach_break;
69
}
70
}
71
72
foreach_all(AIZKingClaw, claw)
73
{
74
GHZCutsceneST->claw = claw;
75
foreach_break;
76
}
77
78
foreach_all(PhantomRuby, phantomRuby)
79
{
80
GHZCutsceneST->phantomRuby = phantomRuby;
81
foreach_break;
82
}
83
84
foreach_all(FXRuby, fxRuby)
85
{
86
GHZCutsceneST->fxRuby = fxRuby;
87
fxRuby->state = StateMachine_None;
88
fxRuby->fadeBlack = 0x200;
89
fxRuby->fadeWhite = 0x200;
90
fxRuby->outerRadius = ScreenInfo->size.x;
91
fxRuby->timer = 64;
92
foreach_break;
93
}
94
95
foreach_all(CutsceneHBH, cutsceneHBH) { GHZCutsceneST->cutsceneHBH[cutsceneHBH->characterID] = cutsceneHBH; }
96
}
97
98
void GHZCutsceneST_SetupKnuxCutscene(void)
99
{
100
if (CHECK_CHARACTER_ID(ID_KNUCKLES, 1)) {
101
EntityPlatform *platform = GHZCutsceneST->platform;
102
EntityAIZKingClaw *claw = GHZCutsceneST->claw;
103
EntityFXRuby *fxRuby = GHZCutsceneST->fxRuby;
104
EntityPhantomRuby *phantomRuby = GHZCutsceneST->phantomRuby;
105
106
GHZCutsceneST->cutsceneHBH[0]->position.y += 704 << 16;
107
GHZCutsceneST->cutsceneHBH[1]->position.y += 704 << 16;
108
GHZCutsceneST->cutsceneHBH[2]->position.y += 704 << 16;
109
GHZCutsceneST->cutsceneHBH[3]->position.y += 704 << 16;
110
GHZCutsceneST->cutsceneHBH[4]->position.y += 704 << 16;
111
fxRuby->position.y += 704 << 16;
112
phantomRuby->position.y += 704 << 16;
113
platform->position.y += 704 << 16;
114
platform->drawPos.x = platform->position.x;
115
platform->drawPos.y = platform->position.y;
116
platform->centerPos.x = platform->position.x;
117
platform->centerPos.y = platform->position.y;
118
claw->position.y += 704 << 16;
119
}
120
}
121
122
#if MANIA_USE_PLUS
123
void GHZCutsceneST_Cutscene_SkipCB(void)
124
{
125
#if MANIA_USE_PLUS
126
if (globals->gameMode == MODE_ENCORE)
127
RSDK.SetScene("Encore Mode", "Green Hill Zone+ 1");
128
else
129
#endif
130
RSDK.SetScene("Mania Mode", "Green Hill Zone 1");
131
}
132
#endif
133
134
bool32 GHZCutsceneST_Cutscene_FadeIn(EntityCutsceneSeq *host)
135
{
136
MANIA_GET_PLAYER(player1, player2, camera);
137
UNUSED(camera);
138
139
EntityFXRuby *fxRuby = GHZCutsceneST->fxRuby;
140
EntityPhantomRuby *ruby = GHZCutsceneST->phantomRuby;
141
142
if (host->timer) {
143
if (host->timer >= 60) {
144
if (fxRuby->fadeBlack <= 0) {
145
if (fxRuby->fadeWhite <= 0) {
146
PhantomRuby_PlaySfx(RUBYSFX_ATTACK4);
147
return true;
148
}
149
fxRuby->fadeWhite -= 16;
150
}
151
else {
152
fxRuby->fadeBlack -= 16;
153
}
154
}
155
}
156
else {
157
player1->position.y = ruby->position.y;
158
player1->state = Player_State_Static;
159
player1->stateInput = StateMachine_None;
160
CutsceneSeq_LockAllPlayerControl();
161
if (player2->classID == Player->classID) {
162
player2->position.y = ruby->position.y;
163
player2->state = Player_State_Static;
164
player2->stateInput = StateMachine_None;
165
}
166
}
167
168
int32 id = 0;
169
for (int32 angle = 0; angle < 0x80; angle += 0x40) {
170
EntityPlayer *player = RSDK_GET_ENTITY(id++, Player);
171
if (!player || player->classID == TYPE_BLANK)
172
break;
173
RSDK.SetSpriteAnimation(player->aniFrames, ANI_FAN, &player->animator, 0, 0);
174
player->position.x += (player->position.x - player->position.x) >> 3;
175
player->position.y += (0xA00 * RSDK.Sin256(2 * (host->timer + angle - host->storedTimer)) + ruby->position.y - player->position.y) >> 3;
176
player->state = Player_State_Static;
177
}
178
179
return false;
180
}
181
bool32 GHZCutsceneST_Cutscene_FinishRubyWarp(EntityCutsceneSeq *host)
182
{
183
MANIA_GET_PLAYER(player1, player2, camera);
184
UNUSED(player2);
185
186
EntityPhantomRuby *ruby = GHZCutsceneST->phantomRuby;
187
EntityFXRuby *fxRuby = GHZCutsceneST->fxRuby;
188
if (!host->timer)
189
fxRuby->state = FXRuby_State_Shrinking;
190
191
EntityPlayer **curPlayer = &player1;
192
if (fxRuby->outerRadius <= 0) {
193
int32 id = 0;
194
for (int32 angle = 0; angle < 0x80; angle += 0x10) {
195
EntityPlayer *player = RSDK_GET_ENTITY(id++, Player);
196
if (!player || player->classID == TYPE_BLANK)
197
break;
198
RSDK.SetSpriteAnimation(player->aniFrames, ANI_FAN, &player->animator, false, 0);
199
int32 x = (player->position.x - player->position.x) >> 3;
200
int32 y = (0xA00 * RSDK.Sin256(2 * (angle + host->timer - host->storedTimer)) + ruby->position.y - player->position.y) >> 3;
201
player->velocity.x = (x >> 8) * (x >> 8);
202
player->velocity.y = (y >> 8) * (y >> 8);
203
player->state = Player_State_Air;
204
player->up = true;
205
player->camera = NULL;
206
++curPlayer;
207
}
208
209
host->values[0] = true;
210
Camera_SetupLerp(CAMERA_LERP_NORMAL, 0, camera->position.x, camera->position.y, 0);
211
return true;
212
}
213
else {
214
int32 id = 0;
215
for (int32 angle = 0; angle < 0x80; angle += 0x10) {
216
EntityPlayer *player = RSDK_GET_ENTITY(id++, Player);
217
if (!player || player->classID == TYPE_BLANK)
218
break;
219
RSDK.SetSpriteAnimation(player->aniFrames, ANI_FAN, &player->animator, 0, 0);
220
player->position.x += (player->position.x - player->position.x) >> 3;
221
player->position.y += (0xA00 * RSDK.Sin256(2 * (host->timer + angle - host->storedTimer)) + ruby->position.y - player->position.y) >> 3;
222
player->state = Player_State_Static;
223
++curPlayer;
224
}
225
return false;
226
}
227
return false;
228
}
229
bool32 GHZCutsceneST_Cutscene_ExitHBH(EntityCutsceneSeq *host)
230
{
231
MANIA_GET_PLAYER(player1, player2, camera);
232
UNUSED(player2);
233
234
EntityPhantomRuby *ruby = GHZCutsceneST->phantomRuby;
235
EntityAIZKingClaw *claw = GHZCutsceneST->claw;
236
EntityPlatform *platform = GHZCutsceneST->platform;
237
238
if (host->timer >= 60) {
239
if (host->timer == 60) {
240
int32 id = 0;
241
for (int32 i = 0; i < 2; ++i) {
242
EntityPlayer *player = RSDK_GET_ENTITY(id++, Player);
243
if (!player || player->classID == TYPE_BLANK)
244
break;
245
player->up = false;
246
}
247
248
Music_FadeOut(0.025);
249
}
250
251
if (host->timer == 180) {
252
player1->camera = camera;
253
Camera_SetTargetEntity(0, player1);
254
return true;
255
}
256
else {
257
claw->velocity.y -= 0x1800;
258
for (int32 hbhChar = 0; hbhChar < 5; ++hbhChar) {
259
EntityCutsceneHBH *hbh = GHZCutsceneST->cutsceneHBH[hbhChar];
260
switch (hbhChar) {
261
case HBH_GUNNER:
262
hbh->velocity.x += 0x800;
263
hbh->velocity.y -= 0x1800;
264
hbh->position.x += hbh->velocity.x;
265
hbh->position.y += hbh->velocity.y;
266
break;
267
268
case HBH_SHINOBI:
269
if (host->timer == 60) {
270
RSDK.SetSpriteAnimation(hbh->aniFrames, 3, &hbh->mainAnimator, true, 0);
271
RSDK.SetSpriteAnimation(-1, 0, &hbh->fxAnimator, true, 0);
272
}
273
hbh->position.x -= 0x4000;
274
hbh->position.y -= 0x40000;
275
break;
276
277
case HBH_MYSTIC:
278
hbh->velocity.x += 0x2000;
279
hbh->velocity.y -= 0x1000;
280
hbh->position.x += hbh->velocity.x;
281
hbh->position.y += hbh->velocity.y;
282
break;
283
284
case HBH_RIDER:
285
case HBH_KING:
286
hbh->position.x += claw->velocity.x;
287
hbh->position.y += claw->velocity.y;
288
break;
289
290
default: break;
291
}
292
}
293
294
ruby->position.x += claw->velocity.x;
295
ruby->position.y += claw->velocity.y;
296
platform->position.x += claw->velocity.x;
297
platform->position.y += claw->velocity.y;
298
platform->drawPos.x = platform->position.x;
299
platform->drawPos.y = platform->position.y;
300
platform->centerPos.x = platform->position.x;
301
platform->centerPos.y = platform->position.y;
302
claw->position.x += claw->velocity.x;
303
claw->position.y += claw->velocity.y;
304
}
305
}
306
307
return false;
308
}
309
310
bool32 GHZCutsceneST_Cutscene_SetupGHZ1(EntityCutsceneSeq *host)
311
{
312
RSDK_THIS(GHZCutsceneST);
313
314
#if MANIA_USE_PLUS
315
if (globals->gameMode == MODE_ENCORE)
316
RSDK.SetScene("Encore Mode", "");
317
else
318
#endif
319
RSDK.SetScene("Mania Mode", "");
320
321
globals->parallaxOffset[0] = self->timer;
322
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
323
player->onGround = true;
324
player->state = Player_State_Ground;
325
Zone_StoreEntities((ScreenInfo->position.x + ScreenInfo->center.x) << 16, (ScreenInfo->size.y + ScreenInfo->position.y) << 16);
326
RSDK.LoadScene();
327
return true;
328
}
329
330
#if GAME_INCLUDE_EDITOR
331
void GHZCutsceneST_EditorDraw(void)
332
{
333
RSDK_THIS(GHZCutsceneST);
334
CutsceneRules_DrawCutsceneBounds(self, &self->size);
335
}
336
337
void GHZCutsceneST_EditorLoad(void) {}
338
#endif
339
340
void GHZCutsceneST_Serialize(void) { RSDK_EDITABLE_VAR(GHZCutsceneST, VAR_VECTOR2, size); }
341
342