Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/CPZ/TippingPlatform.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: TippingPlatform Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectTippingPlatform *TippingPlatform;
11
12
void TippingPlatform_Update(void)
13
{
14
RSDK_THIS(TippingPlatform);
15
16
if (self->bossID) {
17
if (self->animator.frameID) {
18
self->stateCollide = Platform_Collision_None;
19
self->collision = PLATFORM_C_NONE;
20
}
21
else {
22
self->stateCollide = Platform_Collision_Platform;
23
self->collision = PLATFORM_C_PLATFORM;
24
}
25
26
if (!self->stoodAngle && self->bossID > TIPPINGPLATFORM_EGGMAN && self->syringe->activated) {
27
self->stoodAngle = 1;
28
self->timer = self->intervalOffset + 1;
29
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
30
self->state = TippingPlatform_State_Tipping_Delay;
31
}
32
}
33
else {
34
if (self->state == Platform_State_Fixed) {
35
int32 timer = (Zone->timer + self->intervalOffset) % self->interval;
36
if (timer >= self->duration) {
37
if (timer >= self->duration + 22) {
38
RSDK.SetSpriteAnimation(Platform->aniFrames, 2, &self->animator, true, 6);
39
}
40
else {
41
self->active = ACTIVE_NORMAL;
42
RSDK.SetSpriteAnimation(Platform->aniFrames, 2, &self->animator, true, (timer - self->duration) >> 2);
43
self->state = TippingPlatform_State_Restore;
44
}
45
}
46
else {
47
self->active = ACTIVE_NORMAL;
48
self->timer = self->duration - timer;
49
50
if (self->duration - timer < self->duration - 24) {
51
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 6);
52
self->state = TippingPlatform_State_Tipping;
53
}
54
else {
55
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, timer >> 2);
56
self->state = TippingPlatform_State_Tipping;
57
self->animator.timer = (self->duration - self->timer) & 3;
58
}
59
}
60
}
61
62
bool32 isSolid = false;
63
if (self->animator.animationID == 1)
64
isSolid = self->animator.frameID == 0;
65
else
66
isSolid = self->animator.frameID == 6;
67
68
if (isSolid) {
69
self->stateCollide = Platform_Collision_Platform;
70
self->collision = PLATFORM_C_PLATFORM;
71
}
72
else {
73
self->stateCollide = Platform_Collision_None;
74
self->collision = PLATFORM_C_NONE;
75
}
76
}
77
78
Platform_Update();
79
}
80
81
void TippingPlatform_LateUpdate(void) {}
82
83
void TippingPlatform_StaticUpdate(void) {}
84
85
void TippingPlatform_Draw(void)
86
{
87
RSDK_THIS(TippingPlatform);
88
89
RSDK.DrawSprite(&self->animator, &self->drawPos, false);
90
}
91
92
void TippingPlatform_Create(void *data)
93
{
94
RSDK_THIS(TippingPlatform);
95
96
if (!self->interval)
97
self->interval = -16;
98
99
if (!self->duration)
100
self->duration = 120;
101
102
self->collision = PLATFORM_C_PLATFORM;
103
Platform_Create(NULL);
104
105
if (self->bossID) {
106
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
107
self->animator.speed = 0;
108
}
109
else {
110
RSDK.SetSpriteAnimation(Platform->aniFrames, 2, &self->animator, true, 6);
111
}
112
113
self->state = Platform_State_Fixed;
114
if (!SceneInfo->inEditor) {
115
if (self->bossID > TIPPINGPLATFORM_PLAYER) {
116
foreach_all(Syringe, syringe)
117
{
118
if (syringe->tag == self->bossID) {
119
self->syringe = syringe;
120
if (syringe) {
121
self->updateRange.x = abs(self->position.x - syringe->position.x) + 0x400000;
122
self->updateRange.y = abs(self->position.y - syringe->position.y) + 0x400000;
123
}
124
self->stateCollide = Platform_Collision_Solid;
125
self->collision = PLATFORM_C_SOLID;
126
foreach_break;
127
}
128
}
129
}
130
131
if (self->bossID == TIPPINGPLATFORM_PLAYER) {
132
self->direction = FLIP_X;
133
self->drawFX = FX_FLIP;
134
}
135
}
136
}
137
138
void TippingPlatform_StageLoad(void) {}
139
140
void TippingPlatform_State_Tipping_Boss(void)
141
{
142
RSDK_THIS(TippingPlatform);
143
144
if (self->animator.frameID < 6 && ++self->animator.timer == 4) {
145
self->animator.timer = 0;
146
self->animator.frameID++;
147
}
148
149
if (--self->timer <= 0) {
150
self->active = ACTIVE_BOUNDS;
151
if (self->bossID <= TIPPINGPLATFORM_EGGMAN)
152
self->state = TippingPlatform_State_RestorePlatform;
153
else
154
self->state = Platform_State_Fixed;
155
}
156
}
157
158
void TippingPlatform_State_RestorePlatform(void)
159
{
160
RSDK_THIS(TippingPlatform);
161
162
if (self->animator.frameID <= 0) {
163
self->active = ACTIVE_BOUNDS;
164
self->state = Platform_State_Fixed;
165
}
166
else if (++self->animator.timer == 4) {
167
self->animator.timer = 0;
168
self->animator.frameID--;
169
}
170
}
171
172
void TippingPlatform_State_Tipping(void)
173
{
174
RSDK_THIS(TippingPlatform);
175
176
if (--self->timer <= 0) {
177
RSDK.SetSpriteAnimation(Platform->aniFrames, 2, &self->animator, true, 0);
178
self->state = TippingPlatform_State_RestorePlatform;
179
}
180
}
181
182
void TippingPlatform_State_Restore(void)
183
{
184
RSDK_THIS(TippingPlatform);
185
186
if (self->animator.frameID == 6) {
187
self->active = ACTIVE_BOUNDS;
188
self->state = Platform_State_Fixed;
189
}
190
}
191
192
void TippingPlatform_State_Tipping_Delay(void)
193
{
194
RSDK_THIS(TippingPlatform);
195
196
if (--self->timer <= 0)
197
self->state = TippingPlatform_State_Tipping_Boss;
198
}
199
200
#if GAME_INCLUDE_EDITOR
201
void TippingPlatform_EditorDraw(void)
202
{
203
RSDK_THIS(TippingPlatform);
204
205
self->collision = PLATFORM_C_PLATFORM;
206
Platform_Create(NULL);
207
208
if (self->bossID) {
209
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
210
self->animator.speed = 0;
211
}
212
else {
213
RSDK.SetSpriteAnimation(Platform->aniFrames, 2, &self->animator, true, 6);
214
}
215
216
TippingPlatform_Draw();
217
218
if (showGizmos()) {
219
RSDK_DRAWING_OVERLAY(true);
220
221
if (self->bossID > TIPPINGPLATFORM_PLAYER) {
222
foreach_all(Syringe, syringe)
223
{
224
if (syringe->tag == self->bossID) {
225
DrawHelpers_DrawArrow(self->position.x, self->position.y, syringe->position.x, syringe->position.y, 0xFFFF00, INK_NONE, 0xFF);
226
foreach_break;
227
}
228
}
229
}
230
231
for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < self->childCount; ++i) {
232
Entity *child = RSDK_GET_ENTITY_GEN(s + i);
233
if (!child)
234
continue;
235
236
DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xFFFF00, INK_NONE, 0xFF);
237
}
238
239
RSDK_DRAWING_OVERLAY(false);
240
}
241
}
242
243
void TippingPlatform_EditorLoad(void)
244
{
245
246
// bossID = 0: No tag
247
// bossID = 1: Player Boss Platform
248
// bossID = 2: Eggman Boss Platform
249
// bossID 3 and above: match syringe tag
250
}
251
#endif
252
253
void TippingPlatform_Serialize(void)
254
{
255
RSDK_EDITABLE_VAR(TippingPlatform, VAR_ENUM, childCount);
256
RSDK_EDITABLE_VAR(TippingPlatform, VAR_UINT8, interval);
257
RSDK_EDITABLE_VAR(TippingPlatform, VAR_UINT8, intervalOffset);
258
RSDK_EDITABLE_VAR(TippingPlatform, VAR_UINT8, duration);
259
RSDK_EDITABLE_VAR(TippingPlatform, VAR_UINT8, bossID);
260
}
261
262