Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MSZ/MSZCutsceneST.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: MSZCutsceneST Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectMSZCutsceneST *MSZCutsceneST;
11
12
void MSZCutsceneST_Update(void)
13
{
14
RSDK_THIS(MSZCutsceneST);
15
16
if (!self->activated && self->pathNode) {
17
MSZCutsceneST->tornadoPath = self->pathNode;
18
MSZCutsceneST_SetupCutscene();
19
self->activated = true;
20
}
21
}
22
23
void MSZCutsceneST_LateUpdate(void) {}
24
25
void MSZCutsceneST_StaticUpdate(void)
26
{
27
if (RSDK_GET_ENTITY(SLOT_PAUSEMENU, PauseMenu)->classID == PauseMenu->classID || !MSZCutsceneST->isMayday) {
28
if (MSZCutsceneST->playingMaydaySfx) {
29
RSDK.StopSfx(MSZCutsceneST->sfxMayday);
30
MSZCutsceneST->playingMaydaySfx = false;
31
}
32
}
33
else if (!MSZCutsceneST->playingMaydaySfx) {
34
RSDK.PlaySfx(MSZCutsceneST->sfxMayday, true, 255);
35
MSZCutsceneST->playingMaydaySfx = true;
36
}
37
}
38
39
void MSZCutsceneST_Draw(void) {}
40
41
void MSZCutsceneST_Create(void *data)
42
{
43
RSDK_THIS(MSZCutsceneST);
44
45
INIT_ENTITY(self);
46
CutsceneRules_SetupEntity(self, &self->size, &self->hitbox);
47
self->active = ACTIVE_NEVER;
48
}
49
50
void MSZCutsceneST_StageLoad(void)
51
{
52
MSZCutsceneST->finishedAct = false;
53
54
foreach_all(SignPost, signPost)
55
{
56
MSZCutsceneST->signPost = signPost;
57
foreach_break;
58
}
59
60
foreach_all(CutsceneHBH, hbh)
61
{
62
if (hbh->characterID == HBH_MYSTIC)
63
MSZCutsceneST->mystic = hbh;
64
65
if (hbh->characterID == HBH_ROGUE_FANG) {
66
MSZCutsceneST->rogues[0] = hbh;
67
MSZCutsceneST->roguePlatforms[0] = RSDK_GET_ENTITY(RSDK.GetEntitySlot(hbh) + 1, Armadiloid);
68
}
69
70
if (hbh->characterID == HBH_ROGUE_BEAN) {
71
MSZCutsceneST->rogues[1] = hbh;
72
MSZCutsceneST->roguePlatforms[1] = RSDK_GET_ENTITY(RSDK.GetEntitySlot(hbh) + 1, Armadiloid);
73
}
74
75
if (hbh->characterID == HBH_ROGUE_BARK) {
76
MSZCutsceneST->rogues[2] = hbh;
77
MSZCutsceneST->roguePlatforms[2] = RSDK_GET_ENTITY(RSDK.GetEntitySlot(hbh) + 1, Armadiloid);
78
}
79
}
80
81
foreach_all(Tornado, tornado)
82
{
83
MSZCutsceneST->tornado = tornado;
84
foreach_break;
85
}
86
87
MSZCutsceneST->sfxExplosion3 = RSDK.GetSfx("Stage/Explosion3.wav");
88
MSZCutsceneST->sfxMayday = RSDK.GetSfx("MSZ/Mayday.wav");
89
MSZCutsceneST->sfxLedgeBreak = RSDK.GetSfx("Stage/LedgeBreak.wav");
90
91
MSZCutsceneST->active = ACTIVE_ALWAYS;
92
}
93
94
void MSZCutsceneST_SetupCutscene(void)
95
{
96
RSDK_THIS(MSZCutsceneST);
97
98
CutsceneSeq_StartSequence(self, MSZCutsceneST_Cutscene_HandleSignPostLand, MSZCutsceneST_Cutscene_AwaitActFinish,
99
MSZCutsceneST_Cutscene_EnterMystic, MSZCutsceneST_Cutscene_PrepareAmbush, MSZCutsceneST_Cutscene_RoguesAmbush,
100
MSZCutsceneST_Cutscene_Mayday, MSZCutsceneST_Cutscene_SetPlayerMSZ2SpawnPos, MSZCutsceneST_Cutscene_PanCameraToPlayer,
101
MSZCutsceneST_Cutscene_SetupMSZ2, StateMachine_None);
102
103
#if MANIA_USE_PLUS
104
CutsceneSeq_SetSkipType(SKIPTYPE_DISABLED);
105
#endif
106
}
107
108
bool32 MSZCutsceneST_Cutscene_HandleSignPostLand(EntityCutsceneSeq *host)
109
{
110
EntitySignPost *signPost = MSZCutsceneST->signPost;
111
EntityCutsceneHBH *mystic = MSZCutsceneST->mystic;
112
113
if (!host->timer) {
114
RSDK.PlaySfx(SignPost->sfxTwinkle, false, 0xFF);
115
signPost->state = SignPost_State_Falling;
116
mystic->visible = true;
117
foreach_all(ParallaxSprite, sprite) { sprite->visible = true; }
118
}
119
120
mystic->position.x = signPost->position.x - 0x30000;
121
122
if (signPost->position.y >= MSZCutsceneST->signPostOffsets[mystic->mainAnimator.frameID] + mystic->position.y - 0x3D0000) {
123
signPost->position.y = MSZCutsceneST->signPostOffsets[mystic->mainAnimator.frameID] + mystic->position.y - 0x3D0000;
124
signPost->state = SignPost_State_Spin;
125
RSDK.PlaySfx(SignPost->sfxSlide, false, 255);
126
signPost->spinCount = 4;
127
signPost->velocity.y = 0;
128
Music_FadeOut(0.025);
129
return true;
130
}
131
132
return false;
133
}
134
135
bool32 MSZCutsceneST_Cutscene_AwaitActFinish(EntityCutsceneSeq *host)
136
{
137
MANIA_GET_PLAYER(player1, player2, camera);
138
UNUSED(player2);
139
UNUSED(camera);
140
141
EntitySignPost *signPost = MSZCutsceneST->signPost;
142
EntityCutsceneHBH *mystic = MSZCutsceneST->mystic;
143
144
signPost->position.y = MSZCutsceneST->signPostOffsets[mystic->mainAnimator.frameID] + mystic->position.y - 0x3D0000;
145
if (signPost->state == SignPost_State_Done) {
146
player1->stateInput = StateMachine_None;
147
CutsceneSeq_LockAllPlayerControl();
148
player1->right = false;
149
player1->left = false;
150
player1->down = false;
151
player1->up = false;
152
player1->jumpPress = false;
153
player1->jumpHold = false;
154
}
155
156
if (MSZCutsceneST->finishedAct) {
157
mystic->oscillate = false;
158
159
TileLayer *fgLow = RSDK.GetTileLayer(Zone->fgLayer[0]);
160
for (int32 i = 0; i < fgLow->scrollInfoCount; ++i) {
161
fgLow->scrollInfo[i].parallaxFactor = 0x100;
162
fgLow->scrollInfo[i].scrollSpeed = 0;
163
}
164
165
#if MANIA_USE_PLUS
166
CutsceneSeq_SetSkipType(SKIPTYPE_NEXTSCENE);
167
#endif
168
return true;
169
}
170
return false;
171
}
172
173
bool32 MSZCutsceneST_Cutscene_EnterMystic(EntityCutsceneSeq *host)
174
{
175
MANIA_GET_PLAYER(player1, player2, camera);
176
UNUSED(player2);
177
UNUSED(camera);
178
179
EntityTornado *tornado = MSZCutsceneST->tornado;
180
EntitySignPost *signPost = MSZCutsceneST->signPost;
181
EntityCutsceneHBH *mystic = MSZCutsceneST->mystic;
182
183
if (!host->timer) {
184
Music_PlayTrack(TRACK_HBHMISCHIEF);
185
RSDK.SetSpriteAnimation(player1->aniFrames, ANI_RIDE, &player1->animator, false, 0);
186
player1->direction = FLIP_NONE;
187
}
188
189
if (!host->values[0]) {
190
int32 x = (tornado->position.x & 0xFFFF0000) + 0x200000;
191
if (player1->position.x != x)
192
player1->position.x += (x - player1->position.x) >> 1;
193
194
if (abs(player1->position.x - x) < 0x10000) {
195
player1->position.x = x;
196
MSZCutsceneST->tornadoStartPos = tornado->position;
197
host->storedTimer = host->timer;
198
host->values[0] = true;
199
}
200
}
201
202
tornado->drawGroup = Zone->playerDrawGroup[0];
203
player1->drawGroup = Zone->playerDrawGroup[1];
204
mystic->velocity.y -= 0x800;
205
mystic->position.y += mystic->velocity.y;
206
mystic->drawGroup = Zone->objectDrawGroup[0];
207
signPost->position.y = mystic->position.y - 0x3D0000 + MSZCutsceneST->signPostOffsets[mystic->mainAnimator.frameID];
208
209
Vector2 range;
210
range.x = ScreenInfo->size.x << 16;
211
range.y = ScreenInfo->size.y << 16;
212
if (!RSDK.CheckOnScreen(mystic, &range)) {
213
host->values[2] = true;
214
destroyEntity(mystic);
215
return true;
216
}
217
return false;
218
}
219
220
bool32 MSZCutsceneST_Cutscene_PrepareAmbush(EntityCutsceneSeq *host)
221
{
222
MANIA_GET_PLAYER(player1, player2, camera);
223
UNUSED(player2);
224
UNUSED(camera);
225
226
EntityTornado *tornado = MSZCutsceneST->tornado;
227
EntityTornadoPath *pathNode = MSZCutsceneST->tornadoPath;
228
int32 x = pathNode->position.x - 0x600000;
229
int32 y = pathNode->position.y + 0x300000;
230
231
if (host->timer - host->storedTimer == 120 && !host->values[1]) {
232
tornado->position.x = x;
233
tornado->position.y = y;
234
host->values[0] = 1;
235
return true;
236
}
237
else {
238
MathHelpers_LerpSin512(&tornado->position, 255 * (host->timer - host->storedTimer) / 120, MSZCutsceneST->tornadoStartPos.x,
239
MSZCutsceneST->tornadoStartPos.y, x, y);
240
tornado->position.x &= 0xFFFF0000;
241
tornado->position.y &= 0xFFFF0000;
242
243
player1->position.x = (tornado->position.x & 0xFFFF0000) + 0x200000;
244
if (player1->characterID == ID_TAILS)
245
player1->position.y = (tornado->position.y & 0xFFFF0000) - 0x2C0000;
246
else
247
player1->position.y = (tornado->position.y & 0xFFFF0000) - 0x300000;
248
}
249
250
return false;
251
}
252
253
bool32 MSZCutsceneST_Cutscene_RoguesAmbush(EntityCutsceneSeq *host)
254
{
255
bool32 (*rogueStates[3])(EntityCutsceneSeq *);
256
rogueStates[0] = MSZCutsceneST_Cutscene_ShowFang;
257
rogueStates[1] = MSZCutsceneST_Cutscene_ShowBean;
258
rogueStates[2] = MSZCutsceneST_Cutscene_ShowBark;
259
260
if (!host->timer) {
261
MSZCutsceneST->rogueID = RSDK.Rand(0, 8) % 3;
262
263
for (int32 i = 0; i < 3; ++i) {
264
if (i != MSZCutsceneST->rogueID) {
265
destroyEntity(MSZCutsceneST->rogues[i]);
266
destroyEntity(MSZCutsceneST->roguePlatforms[i]);
267
}
268
}
269
}
270
271
EntityArmadiloid *armadiloid = MSZCutsceneST->roguePlatforms[MSZCutsceneST->rogueID];
272
armadiloid->drawGroup = Zone->objectDrawGroup[1];
273
armadiloid->boosterAnimator.speed = 1;
274
armadiloid->velocity.x = 0;
275
276
return rogueStates[MSZCutsceneST->rogueID](host);
277
}
278
279
bool32 MSZCutsceneST_Cutscene_ShowFang(EntityCutsceneSeq *host)
280
{
281
EntityTornado *tornado = MSZCutsceneST->tornado;
282
EntityTornadoPath *pathNode = MSZCutsceneST->tornadoPath;
283
EntityCutsceneHBH *rogue = MSZCutsceneST->rogues[MSZCutsceneST->rogueID];
284
EntityArmadiloid *armadiloid = MSZCutsceneST->roguePlatforms[MSZCutsceneST->rogueID];
285
286
if (!host->timer)
287
armadiloid->state = Armadiloid_State_PlatformFlying;
288
289
int32 x = pathNode->position.x + 0x600000;
290
int32 y = armadiloid->startPos.y;
291
292
if (armadiloid->position.x > x) {
293
MathHelpers_Lerp2Sin1024(&armadiloid->position, 255 * host->timer / 180, armadiloid->startPos.x, armadiloid->startPos.y, x, y);
294
armadiloid->position.x &= 0xFFFF0000;
295
armadiloid->position.y &= 0xFFFF0000;
296
}
297
298
if (host->timer == 180) {
299
armadiloid->position.x = x;
300
armadiloid->position.y = y;
301
host->values[0] = 1;
302
}
303
304
if (host->values[0] && !host->values[1]) {
305
if (!rogue->mainAnimator.animationID)
306
RSDK.SetSpriteAnimation(rogue->aniFrames, 1, &rogue->mainAnimator, true, 0);
307
308
if (rogue->mainAnimator.animationID == 1 && rogue->mainAnimator.frameID == rogue->mainAnimator.frameCount - 1
309
&& rogue->mainAnimator.timer == 12) {
310
RSDK.SetSpriteAnimation(rogue->aniFrames, 2, &rogue->mainAnimator, true, 0);
311
rogue->velocity.y = -0x20000;
312
RSDK.PlaySfx(HeavyMystic->sfxPon, false, 255);
313
314
EntityDebris *debris = CREATE_ENTITY(Debris, NULL, rogue->position.x, rogue->position.y - 0x40000);
315
debris->position.x -= 0x180000;
316
debris->velocity.x = -0x20000;
317
debris->drawGroup = Zone->playerDrawGroup[1];
318
debris->state = Debris_State_Move;
319
debris->direction = FLIP_X;
320
debris->drawFX = FX_FLIP;
321
RSDK.SetSpriteAnimation(rogue->aniFrames, 4, &debris->animator, true, 0);
322
323
MSZCutsceneST->projectile = (Entity *)debris;
324
}
325
326
if (rogue->mainAnimator.animationID == 2) {
327
rogue->position.y += rogue->velocity.y;
328
rogue->velocity.y += 0x3800;
329
}
330
}
331
332
rogue->position.x = armadiloid->position.x + 0x20000;
333
if (rogue->position.y > armadiloid->position.y - 0x200000) {
334
rogue->position.y = armadiloid->position.y - 0x200000;
335
rogue->velocity.y = 0;
336
337
if (rogue->mainAnimator.animationID == 2) {
338
RSDK.SetSpriteAnimation(rogue->aniFrames, 1, &rogue->mainAnimator, true, 2);
339
rogue->mainAnimator.loopIndex = 3;
340
host->values[1] = 1;
341
}
342
}
343
344
if (MSZCutsceneST->projectile && MSZCutsceneST->projectile->position.x <= tornado->position.x + 0x300000) {
345
destroyEntity(MSZCutsceneST->projectile);
346
return true;
347
}
348
349
return false;
350
}
351
352
bool32 MSZCutsceneST_Cutscene_ShowBean(EntityCutsceneSeq *host)
353
{
354
EntityTornado *tornado = MSZCutsceneST->tornado;
355
EntityTornadoPath *pathNode = MSZCutsceneST->tornadoPath;
356
EntityCutsceneHBH *rogue = MSZCutsceneST->rogues[MSZCutsceneST->rogueID];
357
EntityArmadiloid *armadiloid = MSZCutsceneST->roguePlatforms[MSZCutsceneST->rogueID];
358
359
int32 x = pathNode->position.x + 0x600000;
360
int32 y = armadiloid->startPos.y;
361
362
if (!host->timer)
363
armadiloid->state = Armadiloid_State_PlatformFlying;
364
365
if (armadiloid->position.x > x) {
366
MathHelpers_Lerp2Sin1024(&armadiloid->position, 255 * host->timer / 180, armadiloid->startPos.x, armadiloid->startPos.y, x, y);
367
armadiloid->position.x &= 0xFFFF0000;
368
armadiloid->position.y &= 0xFFFF0000;
369
}
370
371
if (host->timer == 180) {
372
armadiloid->position.x = x;
373
armadiloid->position.y = y;
374
host->values[0] = 1;
375
}
376
377
if (host->values[0] && !host->values[1]) {
378
if (rogue->mainAnimator.animationID == 5) {
379
RSDK.SetSpriteAnimation(rogue->aniFrames, 7, &rogue->mainAnimator, true, 0);
380
}
381
382
if (rogue->mainAnimator.animationID == 7) {
383
if (rogue->mainAnimator.frameID == 2 && !MSZCutsceneST->projectile) {
384
RSDK.PlaySfx(HeavyMystic->sfxDrop, false, 255);
385
EntityDebris *debris = CREATE_ENTITY(Debris, NULL, rogue->position.x, rogue->position.y - 0x130000);
386
debris->position.x += 0xB0000;
387
debris->velocity.x = -0x48000;
388
debris->velocity.y = -0x40000;
389
debris->gravityStrength = 0x3800;
390
debris->drawGroup = Zone->playerDrawGroup[1];
391
debris->state = Debris_State_Fall;
392
RSDK.SetSpriteAnimation(rogue->aniFrames, 11, &debris->animator, true, 0);
393
MSZCutsceneST->projectile = (Entity *)debris;
394
}
395
396
if (rogue->mainAnimator.animationID == 7 && rogue->mainAnimator.frameID == 5 && rogue->mainAnimator.timer == 2) {
397
RSDK.SetSpriteAnimation(rogue->aniFrames, 5, &rogue->mainAnimator, true, 0);
398
host->values[1] = 1;
399
}
400
}
401
}
402
403
rogue->position.x = armadiloid->position.x + 0x40000;
404
rogue->position.y = armadiloid->position.y - 0x200000;
405
406
if (MSZCutsceneST->projectile && MSZCutsceneST->projectile->position.y >= tornado->position.y - 0x100000) {
407
destroyEntity(MSZCutsceneST->projectile);
408
return true;
409
}
410
411
return false;
412
}
413
414
bool32 MSZCutsceneST_Cutscene_ShowBark(EntityCutsceneSeq *host)
415
{
416
EntityTornado *tornado = MSZCutsceneST->tornado;
417
EntityTornadoPath *pathNode = MSZCutsceneST->tornadoPath;
418
EntityCutsceneHBH *rogue = MSZCutsceneST->rogues[MSZCutsceneST->rogueID];
419
EntityArmadiloid *armadiloid = MSZCutsceneST->roguePlatforms[MSZCutsceneST->rogueID];
420
421
int32 x = pathNode->position.x + 0x600000;
422
int32 y = armadiloid->startPos.y;
423
424
if (!host->timer)
425
armadiloid->state = Armadiloid_State_PlatformFlying;
426
427
if (armadiloid->position.x > x) {
428
MathHelpers_Lerp2Sin1024(&armadiloid->position, 255 * host->timer / 180, armadiloid->startPos.x, armadiloid->startPos.y, x, y);
429
armadiloid->position.x &= 0xFFFF0000;
430
armadiloid->position.y &= 0xFFFF0000;
431
}
432
433
if (host->timer == 180) {
434
armadiloid->position.x = x;
435
armadiloid->position.y = y;
436
host->values[0] = 1;
437
}
438
439
if (host->values[0] && !host->values[1]) {
440
if (rogue->mainAnimator.animationID == 12)
441
RSDK.SetSpriteAnimation(rogue->aniFrames, 14, &rogue->mainAnimator, true, 0);
442
443
if (rogue->mainAnimator.animationID == 14) {
444
if (rogue->mainAnimator.frameID == 3 && rogue->mainAnimator.timer == 1) {
445
RSDK.PlaySfx(HeavyMystic->sfxImpact2, false, 255);
446
Camera_ShakeScreen(0, 0, 2);
447
armadiloid->timer = 0;
448
armadiloid->state = Armadiloid_State_PlatformShoot;
449
RSDK.SetSpriteAnimation(Armadiloid->aniFrames, 2, &armadiloid->headAnimator, true, 0);
450
}
451
452
if (rogue->mainAnimator.animationID == 14 && rogue->mainAnimator.frameID == 7 && rogue->mainAnimator.timer == 2) {
453
RSDK.SetSpriteAnimation(rogue->aniFrames, 12, &rogue->mainAnimator, true, 0);
454
host->values[1] = true;
455
}
456
}
457
}
458
459
if (!MSZCutsceneST->projectile) {
460
foreach_active(Projectile, projectile)
461
{
462
MSZCutsceneST->projectile = (Entity *)projectile;
463
projectile->drawGroup = Zone->playerDrawGroup[1];
464
foreach_break;
465
}
466
}
467
468
rogue->position.x = armadiloid->position.x + 0x40000;
469
rogue->position.y = armadiloid->position.y - 0x2C0000;
470
471
if (MSZCutsceneST->projectile && MSZCutsceneST->projectile->position.x <= tornado->position.x + 0x300000) {
472
destroyEntity(MSZCutsceneST->projectile);
473
return true;
474
}
475
476
return false;
477
}
478
479
bool32 MSZCutsceneST_Cutscene_Mayday(EntityCutsceneSeq *host)
480
{
481
MANIA_GET_PLAYER(player1, player2, camera);
482
UNUSED(camera);
483
484
EntityTornado *tornado = MSZCutsceneST->tornado;
485
EntityTornadoPath *pathNode = MSZCutsceneST->tornadoPath;
486
487
if (!host->timer) {
488
RSDK.PlaySfx(MSZCutsceneST->sfxExplosion3, false, 255);
489
host->fadeWhite = 512;
490
MSZCutsceneST->isMayday = true;
491
RSDK.SetSpriteAnimation(-1, 0, &tornado->animatorPropeller, true, 0);
492
RSDK.SetSpriteAnimation(-1, 0, &tornado->animatorPilot, true, 0);
493
tornado->drawFX |= FX_ROTATE;
494
tornado->state = Tornado_State_Mayday;
495
tornado->rotation = 48;
496
player1->state = Player_State_Static;
497
player1->direction = FLIP_X;
498
RSDK.SetSpriteAnimation(player1->aniFrames, ANI_CLING, &player1->animator, true, 0);
499
player1->rotation = tornado->rotation;
500
tornado->active = ACTIVE_NORMAL;
501
pathNode->state = TornadoPath_State_SetTornadoSpeed;
502
destroyEntity(MSZCutsceneST->rogues[MSZCutsceneST->rogueID]);
503
destroyEntity(MSZCutsceneST->roguePlatforms[MSZCutsceneST->rogueID]);
504
505
TileLayer *background1 = RSDK.GetTileLayer(0);
506
for (int32 i = 0; i < background1->scrollInfoCount; ++i) background1->scrollInfo[i].scrollPos = 0;
507
508
TileLayer *background2 = RSDK.GetTileLayer(1);
509
for (int32 i = 0; i < background2->scrollInfoCount; ++i) background2->scrollInfo[i].scrollPos = 0;
510
511
foreach_active(ParallaxSprite, sprite) { sprite->scrollPos.x = 0; }
512
513
MSZSetup_ReloadBGParallax_Multiply(0x800);
514
}
515
516
if (!host->values[2]) {
517
player1->position.x = tornado->position.x - 0x280000;
518
if (player1->characterID == ID_TAILS)
519
player1->position.y = tornado->position.y - 0x340000;
520
else
521
player1->position.y = tornado->position.y - 0x380000;
522
}
523
524
if (!host->values[0]) {
525
host->fadeWhite = CLAMP(512 - ((host->timer - 45) << 9) / 60, 0, 512);
526
if (!host->fadeWhite)
527
host->values[0] = 1;
528
}
529
530
if (host->timer == 150) {
531
player1->onGround = true;
532
player1->velocity.x = 0;
533
player1->velocity.y = 0;
534
player1->groundVel = 0;
535
player1->nextAirState = StateMachine_None;
536
player1->nextGroundState = StateMachine_None;
537
Player_Action_Jump(player1);
538
player1->direction = FLIP_NONE;
539
player1->velocity.x = 0xE0000;
540
host->values[2] = true;
541
if (player2->classID == Player->classID) {
542
player2->state = MSZSetup_PlayerState_PostCrashJumpIn;
543
player2->active = ACTIVE_NORMAL;
544
}
545
}
546
547
if (TornadoPath->moveVel.y > 0 && !(Zone->timer % 5))
548
Camera_ShakeScreen(0, 2, 2);
549
550
if (TornadoPath->moveVel.y < 0 && !host->values[3]) {
551
MSZCutsceneST->isMayday = false;
552
Camera_ShakeScreen(0, 0, 5);
553
MSZSetup_ReloadBGParallax_Multiply(0x200);
554
host->values[3] = true;
555
tornado->onGround = true;
556
host->storedTimer = host->timer;
557
Music_FadeOut(0.02);
558
RSDK.PlaySfx(MSZCutsceneST->sfxLedgeBreak, false, 255);
559
}
560
561
if (tornado->onGround && !((host->timer - host->storedTimer) % 16)) {
562
EntityDebris *debris = CREATE_ENTITY(Debris, NULL, tornado->position.x, tornado->position.y);
563
debris->position.x += 0x2C0000;
564
debris->position.y += 0xC0000;
565
debris->drawGroup = Zone->objectDrawGroup[0];
566
debris->state = Debris_State_Move;
567
debris->timer = 53;
568
RSDK.SetSpriteAnimation(UberCaterkiller->aniFrames, 4, &debris->animator, true, 0);
569
MSZCutsceneST->projectile = (Entity *)debris;
570
}
571
572
if (TornadoPath->crashFinished) {
573
MSZSetup_ReloadBGParallax_Multiply(0x000);
574
tornado->state = StateMachine_None;
575
return true;
576
}
577
578
return false;
579
}
580
581
bool32 MSZCutsceneST_Cutscene_SetPlayerMSZ2SpawnPos(EntityCutsceneSeq *host)
582
{
583
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
584
585
if (!host->timer) {
586
player1->position.x = 0x3DA00000;
587
player1->position.y = 0x5300000;
588
}
589
590
return host->timer == 90;
591
}
592
593
bool32 MSZCutsceneST_Cutscene_PanCameraToPlayer(EntityCutsceneSeq *host)
594
{
595
MANIA_GET_PLAYER(player1, player2, camera);
596
597
if (!host->timer) {
598
TornadoPath->camera = NULL;
599
camera->boundsB = 0x5A00000;
600
Camera_SetupLerp(CAMERA_LERP_NORMAL, 0, player1->position.x + 0x340000, player1->position.y - 0x140000, 2);
601
MSZSetup_ReloadBGParallax_Multiply(0x400);
602
}
603
604
if (camera->position.x == player1->position.x + 0x340000 && camera->position.y == player1->position.y - 0x140000) {
605
MSZSetup_ReloadBGParallax_Multiply(0x000);
606
607
TileLayer *background1 = RSDK.GetTileLayer(0);
608
for (int32 i = 0; i < background1->scrollInfoCount; ++i) background1->scrollInfo[i].scrollPos &= 0xFFFF0000;
609
610
TileLayer *background2 = RSDK.GetTileLayer(1);
611
for (int32 i = 0; i < background2->scrollInfoCount; ++i) background2->scrollInfo[i].scrollPos &= 0xFFFF0000;
612
613
foreach_active(ParallaxSprite, sprite) { sprite->scrollPos.x &= 0xFFFF0000; }
614
615
Zone->cameraBoundsL[0] = (player1->position.x >> 16) - 160;
616
Zone->cameraBoundsB[0] = (player1->position.y >> 16) - 112;
617
if (player2->classID != Player->classID || player2->onGround)
618
return true;
619
}
620
621
return false;
622
}
623
624
bool32 MSZCutsceneST_Cutscene_SetupMSZ2(EntityCutsceneSeq *host)
625
{
626
if (host->timer == 10) {
627
MSZSetup_State_StoreMSZ1ScrollPos_ST();
628
return true;
629
}
630
631
return false;
632
}
633
634
#if GAME_INCLUDE_EDITOR
635
void MSZCutsceneST_EditorDraw(void)
636
{
637
RSDK_THIS(MSZCutsceneST);
638
639
CutsceneRules_DrawCutsceneBounds(self, &self->size);
640
}
641
642
void MSZCutsceneST_EditorLoad(void) {}
643
#endif
644
645
void MSZCutsceneST_Serialize(void) { RSDK_EDITABLE_VAR(MSZCutsceneST, VAR_VECTOR2, size); }
646
647