Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/CPZ/StickyPlatform.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: StickyPlatform Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectStickyPlatform *StickyPlatform;
11
12
void StickyPlatform_Update(void)
13
{
14
RSDK_THIS(StickyPlatform);
15
16
self->active = ACTIVE_NORMAL;
17
StateMachine_Run(self->state);
18
19
self->position.x = self->amplitude.x * RSDK.Cos1024(self->angle) + self->centerPos.x;
20
self->position.y = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.y;
21
22
StickyPlatform_Interact();
23
24
RSDK.ProcessAnimation(&self->animator);
25
26
int32 anim = self->animator.animationID % 3;
27
if (anim) {
28
if (anim == 2 && self->animator.frameID == self->animator.frameCount - 1) {
29
RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1), &self->animator, false, 0);
30
self->animator.speed = 0;
31
}
32
}
33
else if (self->animator.frameID == self->animator.frameCount - 3) {
34
RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1) + 1, &self->animator, false, 0);
35
}
36
37
if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->centerPos, &self->updateRange)) {
38
self->position = self->centerPos;
39
self->angle = 0;
40
self->activePlayers = 0;
41
self->state = self->oscillate ? StickyPlatform_State_Oscillating : StickyPlatform_State_HandleMovement;
42
}
43
}
44
45
void StickyPlatform_LateUpdate(void) {}
46
47
void StickyPlatform_StaticUpdate(void) {}
48
49
void StickyPlatform_Draw(void)
50
{
51
RSDK_THIS(StickyPlatform);
52
53
RSDK.DrawSprite(&self->animator, NULL, false);
54
}
55
56
void StickyPlatform_Create(void *data)
57
{
58
RSDK_THIS(StickyPlatform);
59
60
self->drawFX = FX_FLIP;
61
if (!SceneInfo->inEditor) {
62
self->visible = true;
63
self->active = ACTIVE_BOUNDS;
64
self->drawGroup = Zone->objectDrawGroup[1] - 2;
65
self->updateRange.x = 0x800000;
66
self->updateRange.y = 0x800000;
67
68
RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, self->type > STICKYPLATFORM_DOWN ? 3 : 0, &self->animator, true, 0);
69
switch (self->type) {
70
case STICKYPLATFORM_UP:
71
self->direction = FLIP_NONE;
72
self->rotation = 0;
73
74
self->hitbox.left = -16;
75
self->hitbox.top = -16;
76
self->hitbox.right = 16;
77
self->hitbox.bottom = 8;
78
break;
79
80
case STICKYPLATFORM_DOWN:
81
self->direction = FLIP_Y;
82
self->rotation = 0x80;
83
84
self->hitbox.left = -16;
85
self->hitbox.top = -8;
86
self->hitbox.right = 16;
87
self->hitbox.bottom = 16;
88
break;
89
90
case STICKYPLATFORM_RIGHT:
91
self->direction = FLIP_NONE;
92
self->rotation = 0x40;
93
94
self->hitbox.left = -8;
95
self->hitbox.top = -16;
96
self->hitbox.right = 16;
97
self->hitbox.bottom = 16;
98
break;
99
100
case STICKYPLATFORM_LEFT:
101
self->direction = FLIP_X;
102
self->rotation = 0xC0;
103
104
self->hitbox.left = -16;
105
self->hitbox.top = -16;
106
self->hitbox.right = 8;
107
self->hitbox.bottom = 16;
108
break;
109
110
default: break;
111
}
112
113
self->animator.speed = 0;
114
115
self->centerPos.x = self->position.x;
116
self->centerPos.y = self->position.y;
117
self->position.x += self->amplitude.x;
118
self->position.y += self->amplitude.y;
119
self->amplitude.x >>= 10;
120
self->amplitude.y >>= 10;
121
122
if (!self->speed)
123
self->speed = 4;
124
125
self->state = self->oscillate ? StickyPlatform_State_Oscillating : StickyPlatform_State_HandleMovement;
126
}
127
}
128
129
void StickyPlatform_StageLoad(void)
130
{
131
StickyPlatform->aniFrames = RSDK.LoadSpriteAnimation("CPZ/StickyPlatform.bin", SCOPE_STAGE);
132
133
StickyPlatform->sfxLand = RSDK.GetSfx("Puyo/Land.wav");
134
}
135
136
void StickyPlatform_Interact(void)
137
{
138
RSDK_THIS(StickyPlatform);
139
140
if (Player->playerCount > 0) {
141
for (int32 i = 0; i < Player->playerCount; i++) {
142
EntityPlayer *player = RSDK_GET_ENTITY(i, Player);
143
144
if (Player_CheckValidState(player) && player->interaction) {
145
if (((1 << i) & self->activePlayers)) {
146
if (player->state == Player_State_Static) {
147
if (player->jumpPress) {
148
player->angle = self->rotation;
149
player->groundVel = 0;
150
Player_Action_Jump(player);
151
152
player->velocity.x = (320 * player->velocity.x) >> 8;
153
player->velocity.y = (320 * player->velocity.y) >> 8;
154
self->activePlayers &= ~(1 << i);
155
self->playerTimer[i] = 16;
156
RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1) + 2, &self->animator, false, 0);
157
}
158
else {
159
Hitbox *playerHitbox = Player_GetHitbox(player);
160
161
uint16 animID = 0;
162
switch (self->type) {
163
case STICKYPLATFORM_UP:
164
player->position.x = self->position.x;
165
player->position.y = self->position.y - (playerHitbox->bottom << 16);
166
animID = 10;
167
break;
168
169
case STICKYPLATFORM_DOWN:
170
player->position.x = self->position.x;
171
player->position.y = self->position.y - (playerHitbox->top << 16);
172
animID = 10;
173
break;
174
175
case STICKYPLATFORM_RIGHT:
176
player->position.y = self->position.y;
177
player->position.x = self->position.x + ((8 - playerHitbox->left) << 16);
178
player->direction = FLIP_NONE;
179
animID = 36;
180
break;
181
182
case STICKYPLATFORM_LEFT:
183
player->position.y = self->position.y;
184
player->position.x = self->position.x - ((playerHitbox->right + 8) << 16);
185
player->direction = FLIP_X;
186
animID = 36;
187
break;
188
189
default: break;
190
}
191
RSDK.SetSpriteAnimation(player->aniFrames, animID, &player->animator, false, 0);
192
}
193
}
194
else {
195
self->activePlayers &= ~(1 << i);
196
}
197
}
198
else {
199
if (!Player_CheckCollisionTouch(player, self, &self->hitbox) || self->playerTimer[i]) {
200
if (self->playerTimer[i])
201
self->playerTimer[i]--;
202
continue;
203
}
204
205
self->activePlayers |= 1 << i;
206
RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1), &self->animator, true, 0);
207
self->animator.speed = 1;
208
player->state = Player_State_Static;
209
player->velocity.x = 0;
210
player->velocity.y = 0;
211
player->groundVel = 0;
212
player->rotation = 0;
213
214
RSDK.PlaySfx(StickyPlatform->sfxLand, false, 255);
215
}
216
}
217
}
218
}
219
}
220
221
void StickyPlatform_State_HandleMovement(void)
222
{
223
RSDK_THIS(StickyPlatform);
224
225
if (self->angle) {
226
if (!self->activePlayers)
227
self->state = StickyPlatform_State_MoveBackForth;
228
}
229
else if (self->activePlayers > 0) {
230
self->state = StickyPlatform_State_MoveBack;
231
}
232
}
233
234
void StickyPlatform_State_MoveBack(void)
235
{
236
RSDK_THIS(StickyPlatform);
237
238
self->angle += self->speed;
239
if (self->angle >= 0x200) {
240
self->angle = 0x200;
241
self->state = StickyPlatform_State_HandleMovement;
242
}
243
}
244
245
void StickyPlatform_State_MoveBackForth(void)
246
{
247
RSDK_THIS(StickyPlatform);
248
249
self->angle += self->speed;
250
if (self->angle >= 0x400) {
251
self->angle = 0;
252
self->state = StickyPlatform_State_HandleMovement;
253
}
254
}
255
256
void StickyPlatform_State_Oscillating(void)
257
{
258
RSDK_THIS(StickyPlatform);
259
260
self->angle = (self->angle + self->speed) & 0x3FF;
261
}
262
263
#if GAME_INCLUDE_EDITOR
264
void StickyPlatform_EditorDraw(void)
265
{
266
RSDK_THIS(StickyPlatform);
267
268
self->updateRange.x = 0x800000;
269
self->updateRange.y = 0x800000;
270
271
RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, self->type > STICKYPLATFORM_DOWN ? 3 : 0, &self->animator, true, 0);
272
switch (self->type) {
273
case STICKYPLATFORM_UP: self->direction = FLIP_NONE; break;
274
case STICKYPLATFORM_DOWN: self->direction = FLIP_Y; break;
275
case STICKYPLATFORM_RIGHT: self->direction = FLIP_NONE; break;
276
case STICKYPLATFORM_LEFT: self->direction = FLIP_X; break;
277
default: break;
278
}
279
280
StickyPlatform_Draw();
281
282
if (showGizmos()) {
283
RSDK_DRAWING_OVERLAY(true);
284
285
self->centerPos = self->position;
286
Vector2 amplitude;
287
amplitude.x = self->amplitude.x >> 10;
288
amplitude.y = self->amplitude.y >> 10;
289
290
self->inkEffect = INK_BLEND;
291
292
// start pos
293
self->position.x = amplitude.x * RSDK.Cos1024(self->angle) + self->centerPos.x;
294
self->position.y = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.y;
295
StickyPlatform_Draw();
296
297
// right max
298
self->position.x = amplitude.x * RSDK.Cos1024(0x000) + self->centerPos.x;
299
self->position.y = amplitude.y * RSDK.Cos1024(0x000) + self->centerPos.y;
300
Vector2 drawPos = self->position;
301
StickyPlatform_Draw();
302
303
// left max
304
self->position.x = amplitude.x * RSDK.Cos1024(0x200) + self->centerPos.x;
305
self->position.y = amplitude.y * RSDK.Cos1024(0x200) + self->centerPos.y;
306
StickyPlatform_Draw();
307
308
DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->position.x, self->position.y, 0x00FF00, INK_NONE, 0xFF);
309
DrawHelpers_DrawArrow(self->position.x, self->position.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);
310
311
self->inkEffect = INK_NONE;
312
313
self->position = self->centerPos;
314
RSDK_DRAWING_OVERLAY(false);
315
}
316
}
317
318
void StickyPlatform_EditorLoad(void)
319
{
320
StickyPlatform->aniFrames = RSDK.LoadSpriteAnimation("CPZ/StickyPlatform.bin", SCOPE_STAGE);
321
322
RSDK_ACTIVE_VAR(StickyPlatform, type);
323
RSDK_ENUM_VAR("Up", STICKYPLATFORM_UP);
324
RSDK_ENUM_VAR("Down", STICKYPLATFORM_DOWN);
325
RSDK_ENUM_VAR("Right", STICKYPLATFORM_RIGHT);
326
RSDK_ENUM_VAR("Left", STICKYPLATFORM_LEFT);
327
}
328
#endif
329
330
void StickyPlatform_Serialize(void)
331
{
332
RSDK_EDITABLE_VAR(StickyPlatform, VAR_ENUM, type);
333
RSDK_EDITABLE_VAR(StickyPlatform, VAR_VECTOR2, amplitude);
334
RSDK_EDITABLE_VAR(StickyPlatform, VAR_ENUM, speed);
335
RSDK_EDITABLE_VAR(StickyPlatform, VAR_BOOL, oscillate);
336
}
337