Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MMZ/Piston.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Piston Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPiston *Piston;
11
12
void Piston_Update(void)
13
{
14
RSDK_THIS(Piston);
15
16
if (self->state == Piston_State_WaitForInterval && !((Zone->timer + self->intervalOffset) % self->interval)) {
17
self->timer = self->distance >> 3;
18
self->active = ACTIVE_NORMAL;
19
20
switch (self->pistonType) {
21
default:
22
case PISTON_MOVE_VERTICAL: self->state = Piston_StateMove_Vertical; break;
23
case PISTON_UP: self->state = Piston_StateMove_Up; break;
24
case PISTON_MOVE_DOWN: self->state = Piston_StateMove_Down; break;
25
case PISTON_MOVE_DOWN_REVERSE: self->state = Piston_StateMove_Down_Reverse; break;
26
case PISTON_MOVE_RIGHT: self->state = Piston_StateMove_Right; break;
27
case PISTON_MOVE_LEFT: self->state = Piston_StateMove_Left; break;
28
case PISTON_MOVE_HORIZONTAL: self->state = Piston_StateMove_Horizontal; break;
29
}
30
}
31
32
Platform_Update();
33
}
34
35
void Piston_LateUpdate(void) {}
36
37
void Piston_StaticUpdate(void) {}
38
39
void Piston_Draw(void)
40
{
41
RSDK_THIS(Piston);
42
43
RSDK.DrawSprite(&self->animator, &self->drawPos, false);
44
}
45
46
void Piston_Create(void *data)
47
{
48
RSDK_THIS(Piston);
49
50
self->pistonType = self->type;
51
self->type = PLATFORM_FIXED;
52
self->collision = PLATFORM_C_SOLID;
53
if (self->pistonType > PISTON_MOVE_DOWN_REVERSE)
54
self->size += 3;
55
56
Platform_Create(NULL);
57
if (self->pistonType <= PISTON_MOVE_DOWN_REVERSE) {
58
self->updateRange.x = 0x800000;
59
self->updateRange.y = (self->distance + 0x80) << 16;
60
}
61
else {
62
self->updateRange.x = (self->distance + 0x80) << 16;
63
self->updateRange.y = 0x800000;
64
}
65
66
self->type = self->pistonType;
67
if (self->type == PISTON_MOVE_DOWN_REVERSE) {
68
self->state = Piston_StateActive_WaitForStood;
69
self->stateCollide = Piston_Collide_Solid;
70
}
71
else {
72
self->state = Piston_State_WaitForInterval;
73
}
74
}
75
76
void Piston_StageLoad(void)
77
{
78
Piston->sfxLand = RSDK.GetSfx("MMZ/PistonLand.wav");
79
Piston->sfxLaunch = RSDK.GetSfx("MMZ/PistonLaunch.wav");
80
}
81
82
void Piston_Collide_Solid(void)
83
{
84
Platform_Collision_Solid();
85
86
#if MANIA_USE_PLUS
87
RSDK_THIS(Piston);
88
89
for (int32 i = 0; i < Player->playerCount; ++i) {
90
if (((1 << i) & self->stoodPlayers) != 0) {
91
EntityPlayer *player = RSDK_GET_ENTITY(i, Player);
92
if (player->state == Player_State_MightyHammerDrop)
93
player->state = Player_State_Air;
94
}
95
}
96
#endif
97
}
98
99
void Piston_State_WaitForInterval(void)
100
{
101
// this obj was fun to do and is also very weird
102
// there's so many fucking states but they're so tiny and almost exactly the same thing as other states
103
}
104
105
void Piston_StateMove_Vertical(void)
106
{
107
RSDK_THIS(Piston);
108
109
self->velocity.y = 0x80000;
110
self->drawPos.y += self->reverse ? -0x80000 : 0x80000;
111
112
if (--self->timer <= 0) {
113
self->timer = self->distance;
114
self->state = Piston_StateMove_Vertical_Reverse;
115
}
116
}
117
118
void Piston_StateMove_Vertical_Reverse(void)
119
{
120
RSDK_THIS(Piston);
121
122
self->velocity.y = 0x10000;
123
self->drawPos.y += self->reverse ? -0x10000 : 0x10000;
124
125
if (--self->timer <= 0) {
126
self->active = ACTIVE_BOUNDS;
127
self->state = Piston_State_WaitForInterval;
128
}
129
}
130
131
void Piston_StateMove_Up(void)
132
{
133
RSDK_THIS(Piston);
134
135
self->drawPos.y -= 0x80000;
136
self->velocity.y = 0x80000;
137
138
if (--self->timer <= 0) {
139
for (int32 i = 0; i < Player->playerCount; ++i) {
140
EntityPlayer *player = RSDK_GET_ENTITY(i, Player);
141
if ((1 << i) & self->stoodPlayers) {
142
player->velocity.y = -0x100000;
143
player->state = Player_State_Air;
144
player->onGround = false;
145
RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_TWIRL, &player->animator, true, 0);
146
}
147
}
148
149
self->timer = self->distance;
150
self->state = Piston_StateMove_Up_Reverse;
151
}
152
}
153
154
void Piston_StateMove_Up_Reverse(void)
155
{
156
RSDK_THIS(Piston);
157
158
self->drawPos.y += 0x10000;
159
self->velocity.y = 0x10000;
160
161
if (--self->timer <= 0) {
162
self->active = ACTIVE_BOUNDS;
163
self->state = Piston_State_WaitForInterval;
164
}
165
}
166
167
void Piston_StateMove_Down(void)
168
{
169
RSDK_THIS(Piston);
170
171
self->drawPos.y += 0x80000;
172
self->velocity.y = 0x80000;
173
174
if (--self->timer <= 0) {
175
self->pistonType = PISTON_MOVE_DOWN_REVERSE;
176
self->active = ACTIVE_BOUNDS;
177
self->state = Piston_State_WaitForInterval;
178
}
179
}
180
181
void Piston_StateMove_Down_Reverse(void)
182
{
183
RSDK_THIS(Piston);
184
185
self->drawPos.y -= 0x80000;
186
self->velocity.y = 0x80000;
187
188
if (--self->timer <= 0) {
189
self->pistonType = PISTON_MOVE_DOWN;
190
self->active = ACTIVE_BOUNDS;
191
self->state = Piston_State_WaitForInterval;
192
}
193
}
194
195
void Piston_StateMove_Right(void)
196
{
197
RSDK_THIS(Piston);
198
199
self->drawPos.x += 0x80000;
200
self->velocity.x = 0x80000;
201
202
if (--self->timer <= 0) {
203
self->pistonType = PISTON_MOVE_LEFT;
204
self->active = ACTIVE_BOUNDS;
205
self->state = Piston_State_WaitForInterval;
206
}
207
}
208
209
void Piston_StateMove_Left(void)
210
{
211
RSDK_THIS(Piston);
212
213
self->drawPos.x -= 0x80000;
214
self->velocity.x = 0x80000;
215
216
if (--self->timer <= 0) {
217
self->pistonType = PISTON_MOVE_RIGHT;
218
self->active = ACTIVE_BOUNDS;
219
self->state = Piston_State_WaitForInterval;
220
}
221
}
222
223
void Piston_StateMove_Horizontal(void)
224
{
225
RSDK_THIS(Piston);
226
227
self->velocity.x = 0x80000;
228
self->drawPos.x += self->reverse ? -0x80000 : 0x80000;
229
230
if (--self->timer <= 0) {
231
self->timer = self->distance;
232
self->state = Piston_StateMove_Horizontal_Reverse;
233
}
234
}
235
236
void Piston_StateMove_Horizontal_Reverse(void)
237
{
238
RSDK_THIS(Piston);
239
240
self->velocity.x = 0x10000;
241
self->drawPos.x += self->reverse ? -0x10000 : 0x10000;
242
243
if (--self->timer <= 0) {
244
self->active = ACTIVE_BOUNDS;
245
self->state = Piston_State_WaitForInterval;
246
}
247
}
248
249
void Piston_StateActive_WaitForStood(void)
250
{
251
RSDK_THIS(Piston);
252
253
if (self->stoodPlayers)
254
self->state = Piston_StateActive_PreparingLaunch;
255
}
256
257
void Piston_StateActive_PreparingLaunch(void)
258
{
259
RSDK_THIS(Piston);
260
261
if (self->stoodPlayers) {
262
if (!self->timer)
263
RSDK.PlaySfx(Piston->sfxLand, false, 255);
264
265
self->drawPos.y += 0x10000;
266
self->velocity.y = 0x10000;
267
268
if (++self->timer >= 16) {
269
RSDK.StopSfx(Piston->sfxLand);
270
RSDK.PlaySfx(Piston->sfxLaunch, false, 255);
271
self->state = Piston_StateActive_LaunchPlayers;
272
}
273
}
274
else {
275
self->state = Piston_StateActive_ReturnToStartPos;
276
RSDK.StopSfx(Piston->sfxLand);
277
}
278
}
279
280
void Piston_StateActive_LaunchPlayers(void)
281
{
282
RSDK_THIS(Piston);
283
284
self->drawPos.y -= 0x40000;
285
self->velocity.y = 0x40000;
286
287
self->timer -= 4;
288
if (!self->timer) {
289
for (int32 i = 0; i < Player->playerCount; ++i) {
290
EntityPlayer *player = RSDK_GET_ENTITY(i, Player);
291
if ((1 << i) & self->stoodPlayers) {
292
RSDK.PlaySfx(Piston->sfxLaunch, false, 255);
293
player->velocity.y = -0x100000;
294
player->state = Player_State_Air;
295
player->onGround = false;
296
RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_TWIRL, &player->animator, true, 0);
297
}
298
}
299
300
self->state = Piston_StateActive_WaitForStood;
301
}
302
}
303
304
void Piston_StateActive_ReturnToStartPos(void)
305
{
306
RSDK_THIS(Piston);
307
308
if (self->stoodPlayers) {
309
self->state = Piston_StateActive_PreparingLaunch;
310
}
311
else {
312
self->drawPos.y -= 0x10000;
313
self->velocity.y = 0x10000;
314
315
if (--self->timer <= 0)
316
self->state = Piston_StateActive_WaitForStood;
317
}
318
}
319
320
#if GAME_INCLUDE_EDITOR
321
void Piston_EditorDraw(void)
322
{
323
RSDK_THIS(Piston);
324
325
Piston_Create(NULL);
326
Piston_Draw();
327
328
if (showGizmos()) {
329
RSDK_DRAWING_OVERLAY(true);
330
331
for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < self->childCount; ++i) {
332
Entity *child = RSDK_GET_ENTITY_GEN(s + i);
333
if (!child)
334
continue;
335
336
DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xE0E0E0, INK_NONE, 0xFF);
337
}
338
339
RSDK_DRAWING_OVERLAY(false);
340
}
341
}
342
343
void Piston_EditorLoad(void)
344
{
345
RSDK_ACTIVE_VAR(Piston, type);
346
RSDK_ENUM_VAR("Use move distance (Vertical)", PISTON_MOVE_VERTICAL);
347
RSDK_ENUM_VAR("Move up then down", PISTON_UP);
348
RSDK_ENUM_VAR("Move down then up", PISTON_MOVE_DOWN);
349
RSDK_ENUM_VAR("Launch players when stood on", PISTON_MOVE_DOWN_REVERSE);
350
RSDK_ENUM_VAR("Move right then left", PISTON_MOVE_RIGHT);
351
RSDK_ENUM_VAR("Move left then right", PISTON_MOVE_LEFT);
352
RSDK_ENUM_VAR("Use move distance (Horizontal)", PISTON_MOVE_HORIZONTAL);
353
354
RSDK_ACTIVE_VAR(Piston, size);
355
RSDK_ENUM_VAR("1 Barrel", PISTON_SIZE_1);
356
RSDK_ENUM_VAR("2 Barrels", PISTON_SIZE_2);
357
RSDK_ENUM_VAR("3 Barrels", PISTON_SIZE_3);
358
}
359
#endif
360
361
void Piston_Serialize(void)
362
{
363
RSDK_EDITABLE_VAR(Piston, VAR_ENUM, type);
364
RSDK_EDITABLE_VAR(Piston, VAR_BOOL, reverse);
365
RSDK_EDITABLE_VAR(Piston, VAR_UINT8, size);
366
RSDK_EDITABLE_VAR(Piston, VAR_ENUM, childCount);
367
RSDK_EDITABLE_VAR(Piston, VAR_UINT16, interval);
368
RSDK_EDITABLE_VAR(Piston, VAR_UINT16, intervalOffset);
369
RSDK_EDITABLE_VAR(Piston, VAR_ENUM, distance);
370
}
371
372