Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/LRZ/LRZ1Intro.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: LRZ1Intro Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
#if MANIA_USE_PLUS
11
ObjectLRZ1Intro *LRZ1Intro;
12
13
void LRZ1Intro_Update(void)
14
{
15
RSDK_THIS(LRZ1Intro);
16
17
StateMachine_Run(self->state);
18
}
19
20
void LRZ1Intro_LateUpdate(void) {}
21
22
void LRZ1Intro_StaticUpdate(void) {}
23
24
void LRZ1Intro_Draw(void)
25
{
26
RSDK_THIS(LRZ1Intro);
27
28
RSDK.SetActivePalette(6, 0, ScreenInfo->size.y);
29
30
RSDK.DrawSprite(&self->animator, NULL, false);
31
32
RSDK.SetActivePalette(0, 0, ScreenInfo->size.y);
33
}
34
35
void LRZ1Intro_Create(void *data)
36
{
37
RSDK_THIS(LRZ1Intro);
38
39
if (!SceneInfo->inEditor) {
40
self->active = ACTIVE_NORMAL;
41
self->visible = true;
42
self->drawGroup = Zone->objectDrawGroup[0];
43
self->updateRange.x = 0x1000000;
44
self->updateRange.y = 0x1000000;
45
RSDK.SetSpriteAnimation(LRZ1Intro->aniFrames, 0, &self->animator, true, 0);
46
self->state = LRZ1Intro_State_SetupActors;
47
}
48
}
49
50
void LRZ1Intro_StageLoad(void)
51
{
52
LRZ1Intro->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/IntroSub.bin", SCOPE_STAGE);
53
54
LRZ1Intro->sfxSubLand = RSDK.GetSfx("LRZ/SubLand.wav");
55
LRZ1Intro->sfxWalkerLegs2 = RSDK.GetSfx("LRZ/WalkerLegs2.wav");
56
LRZ1Intro->sfxLava = RSDK.GetSfx("Stage/Lava.wav");
57
}
58
59
void LRZ1Intro_HandlePlayerCollisions(void)
60
{
61
RSDK_THIS(LRZ1Intro);
62
63
Hitbox *hitboxTopDeck = RSDK.GetHitbox(&self->animator, 0);
64
Hitbox *hitboxBottomDeck = RSDK.GetHitbox(&self->animator, 1);
65
66
foreach_active(Player, player)
67
{
68
if (Player_CheckCollisionPlatform(player, self, hitboxTopDeck))
69
player->position.y += 0x20000;
70
71
if (Player_CheckCollisionPlatform(player, self, hitboxBottomDeck))
72
player->position.y += 0x20000;
73
}
74
}
75
76
void LRZ1Intro_HandlePlayerMovement(void)
77
{
78
RSDK_THIS(LRZ1Intro);
79
80
foreach_active(Player, player)
81
{
82
player->velocity.x = 0;
83
player->velocity.y = 0;
84
85
player->position.x = self->position.x + self->playerOffset[player->playerID].x;
86
player->position.y = self->position.y + self->playerOffset[player->playerID].y;
87
}
88
}
89
90
void LRZ1Intro_HandleLavaContact(void)
91
{
92
RSDK_THIS(LRZ1Intro);
93
94
if (!(Zone->timer & 3)) {
95
int32 x = self->position.x + 0xE00000;
96
int32 y = self->spawnPosY + RSDK.Rand(0x400000, 0x580000);
97
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), x, y)->drawGroup = Zone->objectDrawGroup[1];
98
}
99
100
if (self->velocity.y <= 0x10000) {
101
if (!(Zone->timer % 6)) {
102
EntityLavaGeyser *geyser = CREATE_ENTITY(LavaGeyser, NULL, self->position.x, self->spawnPosY + 0x4C0000);
103
geyser->visible = true;
104
geyser->active = ACTIVE_NORMAL;
105
geyser->velocity.y = 0x40000;
106
107
RSDK.SetSpriteAnimation(LavaGeyser->aniFrames, 1, &geyser->plumeAnimator, true, 0);
108
RSDK.SetSpriteAnimation(LavaGeyser->aniFrames, 0, &geyser->flowAnimator, true, 0);
109
RSDK.SetSpriteAnimation(LavaGeyser->aniFrames, 1, &geyser->plumeLoopAnimator, true, 16);
110
111
geyser->state = LavaGeyser_State_Erupting;
112
}
113
}
114
}
115
116
void LRZ1Intro_HandleExplosions(void)
117
{
118
RSDK_THIS(LRZ1Intro);
119
120
if (!(Zone->timer & 3)) {
121
int32 x = self->position.x + RSDK.Rand(-0xE00000, 0xE00000);
122
int32 y = self->spawnPosY + RSDK.Rand(0x400000, 0x580000);
123
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), x, y);
124
}
125
}
126
127
void LRZ1Intro_State_SetupActors(void)
128
{
129
RSDK_THIS(LRZ1Intro);
130
131
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
132
133
Hitbox *playerHitbox = Player_GetHitbox(player1);
134
player1->state = Player_State_Static;
135
RSDK.SetSpriteAnimation(player1->aniFrames, ANI_BALANCE_2, &player1->animator, false, 0);
136
137
self->playerOffset[0].x = 0x600000;
138
self->playerOffset[0].y = -0x10000 * playerHitbox->bottom;
139
140
for (int32 p = 1; p < Player->playerCount; ++p) {
141
EntityPlayer *playerPtr = RSDK_GET_ENTITY(p, Player);
142
143
if (playerPtr->classID == Player->classID) {
144
Hitbox *hitbox = Player_GetHitbox(playerPtr);
145
self->playerOffset[p].x = 0x400000;
146
self->playerOffset[p].y = -0x10000 * hitbox->bottom;
147
playerPtr->state = Player_State_Static;
148
RSDK.SetSpriteAnimation(playerPtr->aniFrames, ANI_BALANCE_2, &playerPtr->animator, false, 0);
149
}
150
}
151
152
foreach_all(Player, player)
153
{
154
player->position.x = self->position.x;
155
player->position.y = self->position.y;
156
157
if (player->camera) {
158
player->camera->position.x = self->position.x;
159
player->camera->position.y = self->position.y;
160
}
161
}
162
163
Zone->playerBoundActiveL[0] = false;
164
self->state = LRZ1Intro_State_IntroDelay;
165
}
166
167
void LRZ1Intro_State_IntroDelay(void)
168
{
169
RSDK_THIS(LRZ1Intro);
170
171
if (++self->timer == 32) {
172
self->timer = 0;
173
self->velocity.x = 0x100000;
174
self->state = LRZ1Intro_State_EnterSub;
175
176
RSDK.PlaySfx(LRZ1Intro->sfxSubLand, false, 255);
177
178
Zone->cameraBoundsL[0] = 2732;
179
Zone->cameraBoundsL[1] = 2732;
180
Zone->cameraBoundsL[2] = 2732;
181
Zone->cameraBoundsL[3] = 2732;
182
}
183
184
LRZ1Intro_HandlePlayerMovement();
185
}
186
187
void LRZ1Intro_State_EnterSub(void)
188
{
189
RSDK_THIS(LRZ1Intro);
190
191
if (self->velocity.y < 0x100000)
192
self->velocity.y += 0x3800;
193
194
self->position.x += self->velocity.x;
195
self->position.y += self->velocity.y;
196
197
EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);
198
if (self->velocity.y > 0x60000)
199
camera->lookPos.y += 3;
200
201
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, true)) {
202
Zone->playerBoundActiveL[0] = true;
203
self->spawnPosY = self->position.y + 0x380000;
204
self->state = LRZ1Intro_State_RidingSub;
205
206
Camera_ShakeScreen(0, 0, 6);
207
camera->lookPos.y &= 0xFFFE;
208
209
RSDK.PlaySfx(LRZ1Intro->sfxWalkerLegs2, false, 255);
210
}
211
212
LRZ1Intro_HandlePlayerMovement();
213
}
214
215
void LRZ1Intro_State_RidingSub(void)
216
{
217
RSDK_THIS(LRZ1Intro);
218
219
self->velocity.x -= 0x1000;
220
if (self->velocity.x < 0)
221
self->velocity.x = 0;
222
223
self->velocity.y = (200 * self->velocity.y) >> 8;
224
225
self->position.x += self->velocity.x;
226
self->position.y += self->velocity.y;
227
228
if (!(Zone->timer & 0xF))
229
RSDK.PlaySfx(LRZ1Intro->sfxLava, false, 255);
230
231
if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, 0x1000000, 0x600000, true)) {
232
Camera_ShakeScreen(0, 0, 6);
233
self->state = LRZ1Intro_State_CrashedSub;
234
RSDK.PlaySfx(LRZ1Intro->sfxWalkerLegs2, false, 255);
235
}
236
237
LRZ1Intro_HandleLavaContact();
238
LRZ1Intro_HandlePlayerMovement();
239
}
240
241
void LRZ1Intro_State_CrashedSub(void)
242
{
243
RSDK_THIS(LRZ1Intro);
244
245
if (++self->timer == 24) {
246
foreach_active(Player, player) { player->state = Player_State_Ground; }
247
self->timer = 0;
248
self->originY = self->position.y;
249
self->state = LRZ1Intro_State_SubSinking;
250
}
251
}
252
253
void LRZ1Intro_State_SubSinking(void)
254
{
255
RSDK_THIS(LRZ1Intro);
256
257
self->originY += 0x4000;
258
self->position.y = (RSDK.Sin256(self->timer) << 10) + self->originY;
259
260
LRZ1Intro_HandleExplosions();
261
LRZ1Intro_HandlePlayerCollisions();
262
263
self->timer += 2;
264
if (self->timer == 1024 || !RSDK.CheckOnScreen(self, NULL))
265
destroyEntity(self);
266
}
267
268
#if GAME_INCLUDE_EDITOR
269
void LRZ1Intro_EditorDraw(void) {}
270
271
void LRZ1Intro_EditorLoad(void) {}
272
#endif
273
274
void LRZ1Intro_Serialize(void) {}
275
#endif
276
277