Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/FBZ/FBZSinkTrash.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: FBZSinkTrash Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectFBZSinkTrash *FBZSinkTrash;
11
12
void FBZSinkTrash_Update(void)
13
{
14
RSDK_THIS(FBZSinkTrash);
15
16
switch (self->type) {
17
case FBZSINKTRASH_SINK: {
18
foreach_active(Player, player)
19
{
20
if (Player_CheckCollisionTouch(player, self, &self->hitboxTrash)) {
21
if (player->velocity.y >= 0) {
22
#if MANIA_USE_PLUS
23
if (player->state == Player_State_MightyHammerDrop) {
24
player->velocity.y = player->velocity.y - (player->velocity.y >> 5) - (player->velocity.y >> 4);
25
if (player->velocity.y >= 0x30000) {
26
int32 speed = abs(player->velocity.y + player->velocity.x);
27
if (speed > 0x10000 && !(Zone->timer & 7)) {
28
int32 x = player->position.x + RSDK.Rand(-0x40000, 0x40000);
29
int32 y = player->position.y + 0x40000 + RSDK.Rand(-0x40000, 0x40000);
30
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);
31
32
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, RSDK.Rand(0, 2) + 9, &debris->animator, false, 0);
33
debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);
34
debris->velocity.y = -0x20000;
35
debris->gravityStrength = 0x3800;
36
debris->updateRange.y = 0x200000;
37
debris->updateRange.x = 0x200000;
38
debris->drawGroup = Zone->objectDrawGroup[0];
39
}
40
}
41
else {
42
player->state = Player_State_Air;
43
player->onGround = true;
44
player->velocity.y = 0;
45
player->collisionMode = CMODE_FLOOR;
46
player->angle = 0;
47
player->position.y += 0x10000;
48
int32 speed = abs(player->velocity.y + player->velocity.x);
49
if (speed > 0x10000 && !(Zone->timer & 7)) {
50
int32 x = player->position.x + RSDK.Rand(-0x40000, 0x40000);
51
int32 y = player->position.y + 0x40000 + RSDK.Rand(-0x40000, 0x40000);
52
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);
53
54
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, RSDK.Rand(0, 2) + 9, &debris->animator, false, 0);
55
debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);
56
debris->velocity.y = -0x20000;
57
debris->gravityStrength = 0x3800;
58
debris->updateRange.y = 0x200000;
59
debris->updateRange.x = 0x200000;
60
debris->drawGroup = Zone->objectDrawGroup[0];
61
}
62
}
63
}
64
else {
65
#endif
66
player->onGround = true;
67
player->velocity.y = 0;
68
player->collisionMode = CMODE_FLOOR;
69
player->angle = 0;
70
player->position.y += 0x10000;
71
int32 speed = abs(player->velocity.y + player->velocity.x);
72
if (speed > 0x10000 && !(Zone->timer & 7)) {
73
int32 x = player->position.x + RSDK.Rand(-0x40000, 0x40000);
74
int32 y = player->position.y + 0x40000 + RSDK.Rand(-0x40000, 0x40000);
75
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);
76
77
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, RSDK.Rand(0, 2) + 9, &debris->animator, false, 0);
78
debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);
79
debris->velocity.y = -0x20000;
80
debris->gravityStrength = 0x3800;
81
debris->updateRange.y = 0x200000;
82
debris->updateRange.x = 0x200000;
83
debris->drawGroup = Zone->objectDrawGroup[0];
84
}
85
#if MANIA_USE_PLUS
86
}
87
#endif
88
}
89
}
90
else if (Player_CheckCollisionTouch(player, self, &self->hitboxDebris)) {
91
#if MANIA_USE_PLUS
92
if (player->state == Player_State_MightyHammerDrop) {
93
player->velocity.y = player->velocity.y - (player->velocity.y >> 5) - (player->velocity.y >> 4);
94
if (player->velocity.y < 0x30000) {
95
player->state = Player_State_Air;
96
player->onGround = true;
97
player->velocity.y = 0;
98
player->collisionMode = 0;
99
player->angle = 0;
100
player->position.y += 0x10000;
101
}
102
}
103
#endif
104
105
if (!(Zone->timer & 7)) {
106
EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, player->position.x + RSDK.Rand(-0x40000, 0x40000),
107
player->position.y + RSDK.Rand(-0x100000, 0));
108
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 0, &debris->animator, false, RSDK.Rand(0, 20));
109
debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);
110
debris->velocity.y = player->velocity.y;
111
debris->gravityStrength = 0x3800;
112
debris->updateRange.y = 0x200000;
113
debris->updateRange.x = 0x200000;
114
debris->drawGroup = Zone->objectDrawGroup[0];
115
}
116
}
117
}
118
break;
119
}
120
121
default:
122
case FBZSINKTRASH_SOLID: {
123
foreach_active(Player, player) { Player_CheckCollisionPlatform(player, self, &self->hitboxTrash); }
124
125
foreach_active(SignPost, signPost)
126
{
127
if (signPost->state == SignPost_State_Falling && signPost->position.y + 0x180000 > self->position.y - (self->size.y >> 1)) {
128
RSDK.PlaySfx(SignPost->sfxSlide, false, 255);
129
signPost->spinCount = 4;
130
signPost->position.y = self->position.y - (self->size.y >> 1) - 0x180000;
131
signPost->velocity.y = 0;
132
Music_FadeOut(0.025);
133
signPost->state = SignPost_State_Spin;
134
}
135
}
136
break;
137
}
138
139
case FBZSINKTRASH_DECOR: break;
140
}
141
}
142
143
void FBZSinkTrash_LateUpdate(void) {}
144
145
void FBZSinkTrash_StaticUpdate(void) {}
146
147
void FBZSinkTrash_Draw(void)
148
{
149
RSDK_THIS(FBZSinkTrash);
150
Vector2 drawPos;
151
152
self->direction = FLIP_NONE;
153
int32 drawX = self->position.x - (self->size.x >> 1);
154
155
SpriteFrame *frame = RSDK.GetFrame(FBZSinkTrash->aniFrames, 11, 0);
156
drawPos.x = self->position.x - (self->size.x >> 1);
157
drawPos.y = self->position.y - (self->size.y >> 1);
158
frame->width = 64;
159
for (int32 i = 0; i < self->size.x; i += 0x400000) {
160
if (self->size.x - i < 0x400000)
161
frame->width = (self->size.x - i) >> 16;
162
163
RSDK.DrawSprite(&self->topAnimator, &drawPos, false);
164
165
drawPos.x += 0x400000;
166
}
167
168
frame = RSDK.GetFrame(FBZSinkTrash->aniFrames, 11, 1);
169
frame->height = 64;
170
for (int32 i = 0; i < self->size.y; i += 0x400000) {
171
drawPos.x = drawX;
172
173
frame->width = 64;
174
if (self->size.y - i < 0x400000)
175
frame->height = (self->size.y - i) >> 16;
176
177
for (int32 x = 0; x < self->size.x; x += 0x400000) {
178
if (self->size.x - x < 0x400000)
179
frame->width = (self->size.x - x) >> 16;
180
181
RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);
182
183
drawPos.x += 0x400000;
184
}
185
drawPos.y += 0x400000;
186
}
187
188
frame = RSDK.GetFrame(FBZSinkTrash->aniFrames, 11, 0);
189
self->direction = FLIP_Y;
190
drawPos.x = drawX;
191
frame->width = 64;
192
193
for (int32 i = 0; i < self->size.x; i += 0x400000) {
194
if (self->size.x - i < 0x400000)
195
frame->width = (self->size.x - i) >> 16;
196
197
RSDK.DrawSprite(&self->topAnimator, &drawPos, false);
198
199
drawPos.x += 0x400000;
200
}
201
202
if (self->type < FBZSINKTRASH_SOLID) {
203
for (int32 i = 0; i < 64; ++i) {
204
drawPos.x = self->position.x + self->trashPos[i].x;
205
drawPos.y = self->position.y + self->trashPos[i].y;
206
self->trashAnimator.frameID = self->trashFrame[i];
207
self->direction = self->trashDir[i];
208
RSDK.DrawSprite(&self->trashAnimator, &drawPos, false);
209
}
210
211
self->direction = FLIP_NONE;
212
}
213
}
214
215
void FBZSinkTrash_Create(void *data)
216
{
217
RSDK_THIS(FBZSinkTrash);
218
if (!SceneInfo->inEditor) {
219
self->updateRange.x = self->size.x >> 1;
220
self->updateRange.y = (self->size.y >> 1) + 0x400000;
221
self->active = ACTIVE_BOUNDS;
222
self->visible = true;
223
self->drawFX = FX_FLIP;
224
self->drawGroup = self->type == FBZSINKTRASH_SINK ? (Zone->objectDrawGroup[1] - 2) : Zone->objectDrawGroup[0];
225
226
self->hitboxTrash.left = -(self->size.x >> 17);
227
self->hitboxTrash.top = -(self->size.y >> 17);
228
self->hitboxTrash.right = self->size.x >> 17;
229
self->hitboxTrash.bottom = 24 - (self->size.y >> 17);
230
231
self->hitboxDebris.left = -(self->size.x >> 17);
232
self->hitboxDebris.top = (self->size.y >> 17) - 16;
233
self->hitboxDebris.right = self->size.x >> 17;
234
self->hitboxDebris.bottom = self->size.y >> 17;
235
236
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 0, &self->trashAnimator, true, 0);
237
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 11, &self->topAnimator, true, 0);
238
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 11, &self->mainAnimator, true, 1);
239
240
for (int32 i = 0; i < 64; ++i) {
241
self->trashPos[i].x = RSDK.Rand(-(self->size.x >> 1), self->size.x >> 1);
242
self->trashPos[i].y = RSDK.Rand(-(self->size.y >> 1), self->size.y >> 1);
243
self->trashFrame[i] = RSDK.Rand(0, 22);
244
self->trashDir[i] = RSDK.Rand(FLIP_NONE, FLIP_XY + 1);
245
}
246
}
247
}
248
249
void FBZSinkTrash_StageLoad(void) { FBZSinkTrash->aniFrames = RSDK.LoadSpriteAnimation("FBZ/Trash.bin", SCOPE_STAGE); }
250
251
#if GAME_INCLUDE_EDITOR
252
void FBZSinkTrash_EditorDraw(void)
253
{
254
RSDK_THIS(FBZSinkTrash);
255
256
self->updateRange.x = self->size.x >> 1;
257
self->updateRange.y = (self->size.y >> 1) + 0x400000;
258
self->drawFX = FX_FLIP;
259
self->direction = FLIP_NONE;
260
261
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 0, &self->trashAnimator, true, 0);
262
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 11, &self->topAnimator, true, 0);
263
RSDK.SetSpriteAnimation(FBZSinkTrash->aniFrames, 11, &self->mainAnimator, true, 1);
264
265
// this is pretty nasty but I didn't wanna make new vars and I needed smth to store it
266
int32 *prevX = (int32 *)&self->hitboxTrash.left;
267
int32 *prevY = (int32 *)&self->hitboxTrash.right;
268
269
if (*prevX != self->size.x || *prevY != self->size.y) {
270
for (int32 i = 0; i < 64; ++i) {
271
self->trashPos[i].x = RSDK.Rand(-(self->size.x >> 1), self->size.x >> 1);
272
self->trashPos[i].y = RSDK.Rand(-(self->size.y >> 1), self->size.y >> 1);
273
self->trashFrame[i] = RSDK.Rand(0, 22);
274
self->trashDir[i] = RSDK.Rand(0, 4);
275
}
276
277
*prevX = self->size.x;
278
*prevY = self->size.y;
279
}
280
281
// Draw everything except the trash, we'll do that seperately so it's part of the overlay, not the base sprite
282
int32 type = self->type;
283
self->type = FBZSINKTRASH_SOLID;
284
FBZSinkTrash_Draw();
285
self->type = type;
286
287
if (self->type < FBZSINKTRASH_SOLID) {
288
RSDK_DRAWING_OVERLAY(true);
289
Vector2 drawPos;
290
for (int32 i = 0; i < 64; ++i) {
291
drawPos.x = self->position.x + self->trashPos[i].x;
292
drawPos.y = self->position.y + self->trashPos[i].y;
293
self->trashAnimator.frameID = self->trashFrame[i];
294
self->direction = self->trashDir[i];
295
RSDK.DrawSprite(&self->trashAnimator, &drawPos, false);
296
}
297
298
self->direction = FLIP_NONE;
299
RSDK_DRAWING_OVERLAY(false);
300
}
301
302
DrawHelpers_DrawRectOutline(self->position.x, self->position.y, self->size.x, self->size.y, 0xFFFF00);
303
}
304
305
void FBZSinkTrash_EditorLoad(void)
306
{
307
FBZSinkTrash->aniFrames = RSDK.LoadSpriteAnimation("FBZ/Trash.bin", SCOPE_STAGE);
308
309
RSDK_ACTIVE_VAR(FBZSinkTrash, type);
310
RSDK_ENUM_VAR("Sink Trash", FBZSINKTRASH_SINK);
311
RSDK_ENUM_VAR("Solid", FBZSINKTRASH_SOLID);
312
RSDK_ENUM_VAR("Decoration", FBZSINKTRASH_DECOR);
313
}
314
#endif
315
316
void FBZSinkTrash_Serialize(void)
317
{
318
RSDK_EDITABLE_VAR(FBZSinkTrash, VAR_ENUM, type);
319
RSDK_EDITABLE_VAR(FBZSinkTrash, VAR_VECTOR2, size);
320
}
321
322