Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Common/PlatformControl.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: PlatformControl Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPlatformControl *PlatformControl;
11
12
void PlatformControl_Update(void)
13
{
14
RSDK_THIS(PlatformControl);
15
16
self->active = ACTIVE_NORMAL;
17
18
int32 startNodeSlot = RSDK.GetEntitySlot(self) + 1;
19
int32 platformSlot = startNodeSlot + self->nodeCount;
20
21
if (self->isActive) {
22
for (int32 c = 0; c < self->childCount; ++c) {
23
EntityPlatform *platform = RSDK_GET_ENTITY(platformSlot, Platform);
24
EntityPlatformNode *node = RSDK_GET_ENTITY(platform->speed, PlatformNode);
25
26
int32 finishDir = 0;
27
if (platform->velocity.x <= 0) {
28
if (platform->drawPos.x <= node->position.x)
29
finishDir = 1;
30
}
31
else {
32
if (platform->drawPos.x >= node->position.x)
33
finishDir = 1;
34
}
35
36
if (platform->velocity.y <= 0) {
37
if (platform->drawPos.y <= node->position.y)
38
finishDir |= 2;
39
}
40
else {
41
if (platform->drawPos.y >= node->position.y)
42
finishDir |= 2;
43
}
44
45
if (finishDir == (1 | 2)) {
46
platform->timer = node->nodeFlag;
47
48
if (platform->direction < 4) {
49
int32 nodeID = ++platform->speed - startNodeSlot;
50
if (nodeID >= self->nodeCount) {
51
switch (self->type) {
52
case PLATFORMCONTROL_CIRCUIT: platform->speed = startNodeSlot; break;
53
54
case PLATFORMCONTROL_REVERSE:
55
--platform->speed;
56
platform->direction = platform->direction ^ 4;
57
break;
58
59
case PLATFORMCONTROL_TELEPORT: {
60
Entity *startNode = RSDK_GET_ENTITY_GEN(startNodeSlot);
61
platform->drawPos.x = startNode->position.x;
62
platform->drawPos.y = startNode->position.y;
63
platform->speed = startNodeSlot + 1;
64
break;
65
}
66
67
case PLATFORMCONTROL_STOP: self->speed = 0; break;
68
}
69
}
70
}
71
else {
72
int32 nodeID = --platform->speed - startNodeSlot;
73
if (nodeID < 0) {
74
switch (self->type) {
75
default:
76
case PLATFORMCONTROL_STOP: break;
77
78
case PLATFORMCONTROL_CIRCUIT: platform->speed = startNodeSlot + (self->nodeCount - 1); break;
79
80
case PLATFORMCONTROL_REVERSE:
81
platform->direction = platform->direction ^ 4;
82
platform->speed = platform->speed + 1;
83
break;
84
85
case PLATFORMCONTROL_TELEPORT: {
86
Entity *startNode = RSDK_GET_ENTITY_GEN(startNodeSlot + self->nodeCount - 1);
87
platform->drawPos.x = startNode->position.x;
88
platform->drawPos.y = startNode->position.y;
89
platform->speed = startNodeSlot + (self->nodeCount - 2);
90
break;
91
}
92
}
93
}
94
}
95
96
PlatformControl_ManagePlatformVelocity(platform, RSDK_GET_ENTITY(platform->speed, PlatformNode));
97
}
98
99
platformSlot += platform->childCount + 1;
100
}
101
}
102
else {
103
EntityButton *button = self->taggedButton;
104
105
if (button && button->currentlyActive)
106
self->setActive = true;
107
108
if (self->setActive) {
109
for (int32 c = 0; c < self->childCount; ++c) {
110
EntityPlatform *platform = RSDK_GET_ENTITY(platformSlot, Platform);
111
if (platform->state == Platform_State_PathStop)
112
platform->state = Platform_State_Path;
113
114
if (platform->state == Platform_State_PathReact) {
115
self->setActive = false;
116
return;
117
}
118
119
platform->speed += startNodeSlot;
120
platform->active = ACTIVE_NORMAL;
121
PlatformControl_ManagePlatformVelocity(platform, RSDK_GET_ENTITY(platform->speed, PlatformNode));
122
platformSlot += platform->childCount + 1;
123
}
124
125
self->isActive = true;
126
}
127
}
128
129
if (!RSDK.CheckOnScreen(self, NULL)) {
130
self->active = ACTIVE_BOUNDS;
131
132
int32 slot = startNodeSlot + self->nodeCount;
133
for (int32 c = 0; c < self->childCount; ++c) {
134
EntityPlatform *platform = RSDK_GET_ENTITY(slot, Platform);
135
if (platform->state == Platform_State_Path) {
136
platform->speed -= startNodeSlot;
137
platform->state = Platform_State_PathStop;
138
platform->active = ACTIVE_BOUNDS;
139
}
140
slot += platform->childCount + 1;
141
}
142
143
self->isActive = false;
144
}
145
}
146
147
void PlatformControl_LateUpdate(void) {}
148
149
void PlatformControl_StaticUpdate(void) {}
150
151
void PlatformControl_Draw(void) {}
152
153
void PlatformControl_Create(void *data)
154
{
155
RSDK_THIS(PlatformControl);
156
157
if (!SceneInfo->inEditor) {
158
self->active = ACTIVE_BOUNDS;
159
160
int32 id = RSDK.GetEntitySlot(self) + 1;
161
for (int32 i = 0; i < self->nodeCount; ++i) {
162
Entity *node = RSDK_GET_ENTITY_GEN(id++);
163
164
if (abs(node->position.x - self->position.x) > self->updateRange.x)
165
self->updateRange.x = abs(node->position.x - self->position.x);
166
167
if (abs(node->position.y - self->position.y) > self->updateRange.y)
168
self->updateRange.y = abs(node->position.y - self->position.y);
169
}
170
171
if (!self->speed)
172
self->speed = 4;
173
174
self->updateRange.x += TO_FIXED(128);
175
self->updateRange.y += TO_FIXED(128);
176
177
self->taggedButton = NULL;
178
EntityButton *taggedButton = RSDK_GET_ENTITY(RSDK.GetEntitySlot(self) - 1, Button);
179
if (self->buttonTag > 0) {
180
bool32 foundButton = false;
181
if (Button) {
182
foreach_all(Button, button)
183
{
184
if (button->tag == self->buttonTag) {
185
taggedButton = button;
186
foundButton = true;
187
foreach_break;
188
}
189
}
190
}
191
192
if (SDashWheel && !foundButton) {
193
foreach_all(SDashWheel, wheel)
194
{
195
if (wheel->tag == self->buttonTag) {
196
taggedButton = (EntityButton *)wheel;
197
foundButton = true;
198
foreach_break;
199
}
200
}
201
}
202
203
if (PullChain && !taggedButton) {
204
foreach_all(PullChain, chain)
205
{
206
if (chain->tag == self->buttonTag) {
207
taggedButton = (EntityButton *)chain;
208
foundButton = true;
209
foreach_break;
210
}
211
}
212
}
213
}
214
215
if (taggedButton) {
216
if ((Button && taggedButton->classID == Button->classID) || (SDashWheel && taggedButton->classID == SDashWheel->classID)
217
|| (PullChain && taggedButton->classID == PullChain->classID)) {
218
self->taggedButton = taggedButton;
219
if (self->updateRange.x < TO_FIXED(128) + abs(self->position.x - taggedButton->position.x))
220
self->updateRange.x = TO_FIXED(128) + abs(self->position.x - taggedButton->position.x);
221
222
if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - taggedButton->position.y))
223
self->updateRange.y = TO_FIXED(128) + abs(self->position.y - taggedButton->position.y);
224
}
225
}
226
}
227
}
228
229
void PlatformControl_StageLoad(void) {}
230
231
void PlatformControl_ManagePlatformVelocity(EntityPlatform *platform, EntityPlatformNode *node)
232
{
233
RSDK_THIS(PlatformControl);
234
235
int32 distX = abs((node->position.x - platform->drawPos.x) >> 16);
236
int32 distY = abs((node->position.y - platform->drawPos.y) >> 16);
237
238
if (distY >= distX) {
239
if (distY)
240
platform->velocity.x = self->speed * (((distX << 16) / distY) >> 2);
241
else
242
platform->velocity.x = 0;
243
244
platform->velocity.y = self->speed << 14;
245
}
246
else {
247
platform->velocity.x = self->speed << 14;
248
249
if (distX)
250
platform->velocity.y = self->speed * (((distY << 16) / distX) >> 2);
251
else
252
platform->velocity.y = 0;
253
}
254
255
if (node->position.x < platform->drawPos.x)
256
platform->velocity.x = -platform->velocity.x;
257
if (node->position.y < platform->drawPos.y)
258
platform->velocity.y = -platform->velocity.y;
259
}
260
261
#if GAME_INCLUDE_EDITOR
262
void PlatformControl_EditorDraw(void)
263
{
264
RSDK_THIS(PlatformControl);
265
266
if (HUD) {
267
Animator animator;
268
RSDK.SetSpriteAnimation(HUD->aniFrames, 0, &animator, false, 7);
269
RSDK.DrawSprite(&animator, NULL, false);
270
}
271
272
self->updateRange.x = TO_FIXED(128);
273
self->updateRange.y = TO_FIXED(128);
274
275
if (showGizmos()) {
276
self->taggedButton = NULL;
277
EntityButton *taggedButton = RSDK_GET_ENTITY(RSDK.GetEntitySlot(self) - 1, Button);
278
if (self->buttonTag > 0) {
279
bool32 foundButton = false;
280
if (Button) {
281
foreach_all(Button, button)
282
{
283
if (button->tag == self->buttonTag) {
284
taggedButton = button;
285
foundButton = true;
286
foreach_break;
287
}
288
}
289
}
290
291
if (SDashWheel && !foundButton) {
292
foreach_all(SDashWheel, wheel)
293
{
294
if (wheel->tag == self->buttonTag) {
295
taggedButton = (EntityButton *)wheel;
296
foundButton = true;
297
foreach_break;
298
}
299
}
300
}
301
302
if (PullChain && !taggedButton) {
303
foreach_all(PullChain, chain)
304
{
305
if (chain->tag == self->buttonTag) {
306
taggedButton = (EntityButton *)chain;
307
foundButton = true;
308
foreach_break;
309
}
310
}
311
}
312
}
313
314
if (taggedButton) {
315
if ((Button && taggedButton->classID == Button->classID) || (SDashWheel && taggedButton->classID == SDashWheel->classID)
316
|| (PullChain && taggedButton->classID == PullChain->classID)) {
317
self->taggedButton = taggedButton;
318
if (self->updateRange.x < TO_FIXED(128) + abs(self->position.x - taggedButton->position.x))
319
self->updateRange.x = TO_FIXED(128) + abs(self->position.x - taggedButton->position.x);
320
321
if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - taggedButton->position.y))
322
self->updateRange.y = TO_FIXED(128) + abs(self->position.y - taggedButton->position.y);
323
}
324
}
325
326
RSDK_DRAWING_OVERLAY(true);
327
if (self->taggedButton) {
328
DrawHelpers_DrawArrow(self->taggedButton->position.x, self->taggedButton->position.y, self->position.x, self->position.y, 0xFFFF00,
329
INK_NONE, 0xFF);
330
}
331
332
int32 startNodeSlot = RSDK.GetEntitySlot(self) + 1;
333
334
/*EntityPlatformNode *lastNode = RSDK_GET_ENTITY(startNodeSlot, PlatformNode);
335
for (int32 n = 1; n < self->nodeCount; ++n) {
336
EntityPlatformNode *node = RSDK_GET_ENTITY(startNodeSlot + n, PlatformNode);
337
338
if (lastNode && node) {
339
DrawHelpers_DrawArrow(lastNode->position.x, lastNode->position.y, node->position.x, node->position.y, 0xFF0000, INK_NONE, 0xFF);
340
}
341
lastNode = node;
342
}
343
344
if (lastNode) {
345
EntityPlatformNode *node = RSDK_GET_ENTITY(startNodeSlot, PlatformNode);
346
if (node && self->type != PLATFORMCONTROL_STOP) {
347
DrawHelpers_DrawArrow(lastNode->position.x, lastNode->position.y, node->position.x, node->position.y, 0xFF0000, INK_NONE, 0xFF);
348
}
349
}*/
350
351
int32 platformSlot = startNodeSlot + self->nodeCount;
352
for (int32 c = 0; c < self->childCount; ++c) {
353
EntityPlatform *platform = RSDK_GET_ENTITY(platformSlot, Platform);
354
platformSlot++;
355
356
if (platform) {
357
platformSlot += platform->childCount;
358
DrawHelpers_DrawArrow(self->position.x, self->position.y, platform->position.x, platform->position.y, 0xFFFFFF, INK_NONE, 0xFF);
359
}
360
}
361
362
RSDK_DRAWING_OVERLAY(false);
363
}
364
}
365
366
void PlatformControl_EditorLoad(void)
367
{
368
369
RSDK_ACTIVE_VAR(PlatformControl, type);
370
RSDK_ENUM_VAR("Circuit", PLATFORMCONTROL_CIRCUIT);
371
RSDK_ENUM_VAR("Reverse", PLATFORMCONTROL_REVERSE);
372
RSDK_ENUM_VAR("Teleport", PLATFORMCONTROL_TELEPORT);
373
RSDK_ENUM_VAR("Stop", PLATFORMCONTROL_STOP);
374
}
375
#endif
376
377
void PlatformControl_Serialize(void)
378
{
379
RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, nodeCount);
380
RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, childCount);
381
RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, speed);
382
RSDK_EDITABLE_VAR(PlatformControl, VAR_BOOL, setActive);
383
RSDK_EDITABLE_VAR(PlatformControl, VAR_UINT8, type);
384
RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, buttonTag);
385
}
386
387