Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/FBZ/FBZ1Outro.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: FBZ1Outro Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectFBZ1Outro *FBZ1Outro;
11
12
void FBZ1Outro_Update(void)
13
{
14
RSDK_THIS(FBZ1Outro);
15
16
if (!self->activated) {
17
FBZ1Outro_StartCutscene();
18
self->activated = true;
19
}
20
}
21
22
void FBZ1Outro_LateUpdate(void) {}
23
24
void FBZ1Outro_StaticUpdate(void) {}
25
26
void FBZ1Outro_Draw(void) {}
27
28
void FBZ1Outro_Create(void *data)
29
{
30
RSDK_THIS(FBZ1Outro);
31
32
INIT_ENTITY(self);
33
CutsceneRules_SetupEntity(self, &self->size, &self->hitbox);
34
self->active = ACTIVE_NEVER;
35
}
36
37
void FBZ1Outro_StageLoad(void)
38
{
39
foreach_all(BigSqueeze, boss)
40
{
41
switch (boss->type) {
42
default: break;
43
44
case BIGSQUEEZE_CRUSHER_L: FBZ1Outro->bossBorderL = boss; break;
45
case BIGSQUEEZE_CRUSHER_R: FBZ1Outro->bossBorderR = boss; break;
46
case BIGSQUEEZE_MANAGER: FBZ1Outro->bossManager = boss; break;
47
}
48
}
49
50
foreach_all(CollapsingPlatform, platform)
51
{
52
if (platform->eventOnly) {
53
FBZ1Outro->collapsingPlatform = platform;
54
foreach_break;
55
}
56
}
57
58
foreach_all(Crane, crane)
59
{
60
if (crane->position.x == 0x33400000 && crane->position.y == 0x9100000)
61
FBZ1Outro->craneP1 = crane;
62
63
if (crane->position.x == 0x33640000 && crane->position.y == 0x9100000)
64
FBZ1Outro->craneP2 = crane;
65
}
66
67
FBZ1Outro->sfxDrop = RSDK.GetSfx("Stage/Drop.wav");
68
}
69
70
void FBZ1Outro_StartCutscene(void)
71
{
72
RSDK_THIS(FBZ1Outro);
73
74
CutsceneSeq_StartSequence(self, FBZ1Outro_Cutscene_CrushTrash, FBZ1Outro_Cutscene_TrashDrop, FBZ1Outro_Cutscene_CraneRide,
75
FBZ1Outro_Cutscene_PrepareFBZ2, StateMachine_None);
76
77
#if MANIA_USE_PLUS
78
CutsceneSeq_SetSkipType(SKIPTYPE_RELOADSCN);
79
#endif
80
}
81
82
void FBZ1Outro_HandleTrash(void)
83
{
84
foreach_active(FBZTrash, trash) { trash->velocity.y = 0; }
85
foreach_active(FBZSinkTrash, sinkTrash) { sinkTrash->velocity.y = 0; }
86
87
foreach_active(SignPost, signPost)
88
{
89
signPost->velocity.x = 0;
90
signPost->velocity.y = 0;
91
signPost->position.y = BigSqueeze->boundsB - 0x180000;
92
93
int32 boundsL = BigSqueeze->crusherX[BIGSQUEEZE_CRUSHER_L] + 0x180000;
94
int32 boundsR = BigSqueeze->crusherX[BIGSQUEEZE_CRUSHER_R] - 0x180000;
95
96
signPost->position.x = CLAMP(signPost->position.x, boundsL, boundsR);
97
}
98
}
99
100
void FBZ1Outro_DispenseTrash(void)
101
{
102
foreach_active(FBZTrash, trash)
103
{
104
trash->state = StateMachine_None;
105
trash->position.y += trash->velocity.y;
106
trash->velocity.y += 0x3800;
107
}
108
109
foreach_active(FBZSinkTrash, sinkTrash)
110
{
111
sinkTrash->position.y += sinkTrash->velocity.y;
112
sinkTrash->velocity.y += 0x3800;
113
sinkTrash->type = FBZSINKTRASH_DECOR;
114
}
115
116
foreach_active(SignPost, signPost)
117
{
118
signPost->position.y += signPost->velocity.y;
119
signPost->velocity.y += 0x3800;
120
signPost->type = SIGNPOST_COMP;
121
}
122
}
123
124
bool32 FBZ1Outro_Cutscene_CrushTrash(EntityCutsceneSeq *host)
125
{
126
RSDK_THIS(FBZ1Outro);
127
128
MANIA_GET_PLAYER(player1, player2, camera);
129
UNUSED(camera);
130
131
EntityBigSqueeze *bossBorderL = FBZ1Outro->bossBorderL;
132
EntityBigSqueeze *bossBorderR = FBZ1Outro->bossBorderR;
133
EntityBigSqueeze *bossManager = FBZ1Outro->bossManager;
134
135
EntityCollapsingPlatform *platform = FBZ1Outro->collapsingPlatform;
136
137
if (!host->timer) {
138
player1->stateInput = StateMachine_None;
139
RSDK.SetSpriteAnimation(player1->aniFrames, ANI_BALANCE_1, &player1->animator, false, 0);
140
141
player1->state = Player_State_Static;
142
CutsceneSeq_LockPlayerControl(player1);
143
144
if (player2->classID == Player->classID) {
145
RSDK.SetSpriteAnimation(player2->aniFrames, ANI_BALANCE_1, &player2->animator, false, 0);
146
147
player2->state = Player_State_Static;
148
CutsceneSeq_LockPlayerControl(player2);
149
}
150
}
151
152
player1->nextGroundState = StateMachine_None;
153
player1->nextAirState = StateMachine_None;
154
if (player2->classID == Player->classID) {
155
player2->nextGroundState = StateMachine_None;
156
player2->nextAirState = StateMachine_None;
157
}
158
159
if (BigSqueeze->crusherX[BIGSQUEEZE_CRUSHER_R] - BigSqueeze->crusherX[BIGSQUEEZE_CRUSHER_L] <= 0xB00000) {
160
BigSqueeze->isCrushing = false;
161
RSDK.SetSpriteAnimation(player1->aniFrames, ANI_HURT, &player1->animator, false, 0);
162
player1->state = Player_State_Air;
163
player1->onGround = false;
164
if (player2->classID == Player->classID) {
165
RSDK.SetSpriteAnimation(player2->aniFrames, ANI_HURT, &player2->animator, false, 0);
166
player2->state = Player_State_Air;
167
player2->onGround = false;
168
}
169
else {
170
destroyEntity(FBZ1Outro->craneP2);
171
self->grabbedPlayers |= 2;
172
}
173
174
bossBorderL->setupTimer = 0;
175
bossBorderL->state = BigSqueeze_StateCrusher_BeginCrushing;
176
bossBorderR->setupTimer = 0;
177
bossBorderR->state = BigSqueeze_StateCrusher_BeginCrushing;
178
bossManager->state = BigSqueeze_StateManager_HandleOutro;
179
Zone->cameraBoundsB[0] = 2660;
180
Zone->cameraBoundsB[1] = 2660;
181
Zone->cameraBoundsR[0] = 14080;
182
Zone->cameraBoundsR[1] = 14080;
183
platform->stoodPos.x = 1;
184
RSDK.PlaySfx(FBZ1Outro->sfxDrop, false, 255);
185
186
return true;
187
}
188
else {
189
BigSqueeze->isCrushing = true;
190
FBZ1Outro_HandleTrash();
191
if (host->values[0])
192
host->values[0] = true;
193
194
bossBorderL->setupTimer = 0;
195
bossBorderL->state = BigSqueeze_StateCrusher_Crushing;
196
bossBorderR->setupTimer = 0;
197
bossBorderR->state = BigSqueeze_StateCrusher_Crushing;
198
}
199
200
return false;
201
}
202
bool32 FBZ1Outro_Cutscene_TrashDrop(EntityCutsceneSeq *host)
203
{
204
RSDK_THIS(FBZ1Outro);
205
206
MANIA_GET_PLAYER(player1, player2, camera);
207
UNUSED(camera);
208
209
EntityBigSqueeze *bossBorderL = FBZ1Outro->bossBorderL;
210
EntityBigSqueeze *bossBorderR = FBZ1Outro->bossBorderR;
211
bossBorderL->setupTimer = 0;
212
bossBorderL->state = BigSqueeze_StateCrusher_BeginCrushing;
213
bossBorderR->setupTimer = 0;
214
bossBorderR->state = BigSqueeze_StateCrusher_BeginCrushing;
215
216
EntityCrane *craneP1 = FBZ1Outro->craneP1;
217
craneP1->position.x = player1->position.x;
218
if (craneP1->state == Crane_State_RiseUp) {
219
craneP1->startPos.x = player1->position.x;
220
craneP1->startPos.y = craneP1->position.y;
221
self->grabbedPlayers |= 1;
222
}
223
224
if (player2->classID == Player->classID) {
225
EntityCrane *craneP2 = FBZ1Outro->craneP2;
226
craneP2->position.x = player2->position.x;
227
if (craneP2->state == Crane_State_RiseUp) {
228
craneP2->startPos.x = craneP2->position.x;
229
craneP2->startPos.y = craneP2->position.y;
230
self->grabbedPlayers |= 2;
231
}
232
}
233
234
if (self->grabbedPlayers == (1 | 2))
235
return true;
236
237
FBZ1Outro_DispenseTrash();
238
239
return false;
240
}
241
bool32 FBZ1Outro_Cutscene_CraneRide(EntityCutsceneSeq *host)
242
{
243
MANIA_GET_PLAYER(player1, player2, camera);
244
UNUSED(camera);
245
246
FBZ1Outro_DispenseTrash();
247
248
return player1->onGround && (player2->classID != Player->classID || player2->onGround);
249
}
250
bool32 FBZ1Outro_Cutscene_PrepareFBZ2(EntityCutsceneSeq *host)
251
{
252
MANIA_GET_PLAYER(player1, player2, camera);
253
254
if (!host->timer) {
255
Zone->cameraBoundsL[0] = 13568;
256
Zone->cameraBoundsL[1] = 13568;
257
Zone->cameraBoundsB[0] = 2660;
258
Zone->cameraBoundsB[0] = 2660;
259
Zone->playerBoundActiveL[0] = true;
260
}
261
262
RSDK.SetSpriteAnimation(player1->aniFrames, ANI_IDLE, &player1->animator, false, 0);
263
if (player2->classID == Player->classID)
264
RSDK.SetSpriteAnimation(player2->aniFrames, ANI_IDLE, &player2->animator, false, 0);
265
266
if (camera->offset.x || ScreenInfo->position.x < Zone->cameraBoundsL[0] || host->timer < 30) {
267
if (ScreenInfo->position.x < Zone->cameraBoundsL[0])
268
ScreenInfo->position.x++;
269
if (camera->offset.x > 0)
270
camera->offset.x -= 0x10000;
271
}
272
else {
273
Zone_StoreEntities(13780 << 16, 2660 << 16);
274
RSDK.LoadScene();
275
276
int32 id = 0;
277
TileLayer *layer = RSDK.GetTileLayer(1);
278
for (int32 i = 0; i < layer->scrollInfoCount; ++i) {
279
globals->parallaxOffset[id++] = layer->scrollInfo[i].scrollPos + layer->scrollInfo[i].parallaxFactor * ScreenInfo->position.x;
280
}
281
282
foreach_all(ParallaxSprite, parallaxSprite)
283
{
284
globals->parallaxOffset[id++] = parallaxSprite->scrollPos.x + parallaxSprite->parallaxFactor.x * ScreenInfo->position.x;
285
}
286
287
return true;
288
}
289
return false;
290
}
291
292
#if GAME_INCLUDE_EDITOR
293
void FBZ1Outro_EditorDraw(void)
294
{
295
RSDK_THIS(FBZ1Outro);
296
CutsceneRules_DrawCutsceneBounds(self, &self->size);
297
}
298
299
void FBZ1Outro_EditorLoad(void) {}
300
#endif
301
302
void FBZ1Outro_Serialize(void) { RSDK_EDITABLE_VAR(FBZ1Outro, VAR_VECTOR2, size); }
303
304