Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Common/Platform.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Platform Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPlatform *Platform;
11
12
void Platform_Update(void)
13
{
14
RSDK_THIS(Platform);
15
16
#if MANIA_USE_PLUS
17
if (Zone->teleportActionActive) {
18
self->pushPlayersL = false;
19
self->pushPlayersR = false;
20
}
21
#endif
22
23
self->position.x = self->drawPos.x & 0xFFFF0000;
24
self->position.y = self->drawPos.y & 0xFFFF0000;
25
26
if (self->hasTension) {
27
if (self->stood && self->stoodAngle < 64)
28
self->stoodAngle += 4;
29
else if (!self->stood && self->stoodAngle > 0)
30
self->stoodAngle -= 4;
31
}
32
33
self->collisionOffset.x = -self->position.x;
34
self->collisionOffset.y = -self->position.y;
35
36
StateMachine_Run(self->state);
37
38
if (self->classID) {
39
self->stood = false;
40
self->collisionOffset.x += self->drawPos.x & 0xFFFF0000;
41
self->collisionOffset.y += self->drawPos.y & 0xFFFF0000;
42
if (self->state != Platform_State_Falling2 && self->state != Platform_State_Hold) {
43
StateMachine_Run(self->stateCollide);
44
}
45
46
self->position.x = self->centerPos.x;
47
self->position.y = self->centerPos.y;
48
for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < self->childCount; ++i) {
49
Entity *child = RSDK_GET_ENTITY_GEN(s++);
50
if (child->classID == ItemBox->classID) {
51
if (!child->scale.y) {
52
EntityItemBox *itemBox = (EntityItemBox *)child;
53
#if MANIA_USE_PLUS
54
itemBox->parent = (Entity *)self;
55
#else
56
itemBox->groundVel = RSDK.GetEntitySlot(self);
57
#endif
58
itemBox->scale.x = itemBox->position.x - self->centerPos.x;
59
itemBox->scale.y = itemBox->position.y - self->centerPos.y;
60
itemBox->position.x = itemBox->scale.x + self->drawPos.x;
61
itemBox->position.y = itemBox->scale.y + self->drawPos.y;
62
itemBox->updateRange.x = self->updateRange.x;
63
itemBox->updateRange.y = self->updateRange.y;
64
}
65
}
66
else {
67
child->position.x += self->collisionOffset.x;
68
child->position.y += self->collisionOffset.y;
69
70
if (child->classID == Spikes->classID) {
71
EntitySpikes *spikes = (EntitySpikes *)child;
72
spikes->collisionOffset.x = self->collisionOffset.x;
73
spikes->collisionOffset.y = self->collisionOffset.y;
74
}
75
else if (child->classID == Platform->classID) {
76
EntityPlatform *platform = (EntityPlatform *)child;
77
platform->centerPos.x += self->collisionOffset.x;
78
platform->centerPos.y += self->collisionOffset.y;
79
}
80
else if (Ice && child->classID == Ice->classID) {
81
EntityIce *ice = (EntityIce *)child;
82
ice->playerMoveOffset = self->collisionOffset;
83
}
84
else if (TurboTurtle && child->classID == TurboTurtle->classID) {
85
EntityTurboTurtle *turboTurtle = (EntityTurboTurtle *)child;
86
turboTurtle->startPos.x += self->collisionOffset.x;
87
turboTurtle->startPos.y += self->collisionOffset.y;
88
}
89
}
90
}
91
92
if (self->animator.frameDuration)
93
RSDK.ProcessAnimation(&self->animator);
94
}
95
}
96
97
void Platform_LateUpdate(void) {}
98
99
void Platform_StaticUpdate(void)
100
{
101
for (int32 i = 0; i < PLAYER_COUNT; ++i) {
102
Platform->stoodPos[i].x = 0;
103
Platform->stoodPos[i].y = 0;
104
}
105
}
106
107
void Platform_Draw(void)
108
{
109
RSDK_THIS(Platform);
110
Vector2 drawPos;
111
112
if (self->frameID >= 0) {
113
if ((self->state == Platform_State_Circular && self->hasTension)
114
|| (self->state == Platform_State_Swing || self->state == Platform_State_Clacker || self->type == PLATFORM_SWING_REACT)) {
115
int32 ang = self->angle;
116
if (self->state == Platform_State_Circular && self->hasTension)
117
ang = self->speed * Zone->timer + 4 * self->angle;
118
119
int32 fxStore = self->drawFX;
120
self->drawFX |= FX_FLIP | FX_ROTATE;
121
int32 cnt = (self->amplitude.y >> 10) - 1;
122
int32 angle = 0x400;
123
self->direction = FLIP_NONE;
124
self->animator.frameID = self->frameID + 1;
125
126
int32 rot = ang >> 1;
127
for (int32 i = 0; i < cnt; ++i) {
128
drawPos.x = angle * RSDK.Cos1024(ang) + self->centerPos.x;
129
drawPos.y = angle * RSDK.Sin1024(ang) + self->centerPos.y;
130
RSDK.DrawSprite(&self->animator, &drawPos, false);
131
angle += 0x400;
132
self->direction ^= FLIP_X;
133
self->rotation = rot;
134
}
135
136
self->drawFX = fxStore;
137
self->animator.frameID = self->frameID + 2;
138
RSDK.DrawSprite(&self->animator, &self->centerPos, false);
139
140
self->animator.frameID = self->frameID;
141
}
142
143
if (Platform->aniFrames == (uint16)-1)
144
RSDK.DrawRect(self->drawPos.x - TO_FIXED(32), self->drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, 255, INK_NONE, false);
145
else
146
RSDK.DrawSprite(&self->animator, &self->drawPos, false);
147
}
148
}
149
150
void Platform_Create(void *data)
151
{
152
RSDK_THIS(Platform);
153
154
self->amplitude.x >>= 10;
155
self->amplitude.y >>= 10;
156
self->active = ACTIVE_BOUNDS;
157
self->visible = true;
158
self->drawGroup = Zone->objectDrawGroup[0] + 1;
159
self->centerPos = self->position;
160
self->drawPos = self->position;
161
RSDK.SetSpriteAnimation(Platform->aniFrames, 0, &self->animator, true, 0);
162
self->animator.frameID = self->frameID;
163
164
if (!SceneInfo->inEditor && RSDK.GetFrameID(&self->animator) == 'l')
165
self->drawGroup = Zone->objectDrawGroup[0];
166
167
switch (self->type) {
168
default:
169
case PLATFORM_FIXED:
170
self->state = Platform_State_Fixed;
171
self->updateRange.x = TO_FIXED(128);
172
self->updateRange.y = TO_FIXED(128);
173
break;
174
175
case PLATFORM_FALL:
176
self->state = Platform_State_Fall;
177
self->updateRange.x = TO_FIXED(128);
178
self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;
179
break;
180
181
case PLATFORM_LINEAR:
182
self->state = Platform_State_Linear;
183
self->updateRange.x = (abs(self->amplitude.x) + 0x2000) << 10;
184
self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;
185
self->rotation = self->angle;
186
self->angle = 0;
187
break;
188
189
case PLATFORM_CIRCULAR:
190
self->updateRange.x = (abs(self->amplitude.x) + 0x2000) << 10;
191
self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;
192
self->state = Platform_State_Circular;
193
break;
194
195
case PLATFORM_PATH:
196
case PLATFORM_PATH_REACT:
197
self->active = ACTIVE_BOUNDS;
198
if (self->type == PLATFORM_PATH)
199
self->state = Platform_State_PathStop;
200
else
201
self->state = Platform_State_PathReact;
202
self->updateRange.x = TO_FIXED(128);
203
self->updateRange.y = TO_FIXED(128);
204
break;
205
206
case PLATFORM_PUSH:
207
self->updateRange.x = TO_FIXED(128);
208
self->updateRange.y = TO_FIXED(128);
209
if (!SceneInfo->inEditor) {
210
self->speed <<= 11;
211
self->position.x += 0x8000;
212
}
213
self->state = Platform_State_Push_Init;
214
break;
215
216
case PLATFORM_REACT:
217
self->amplitude.x <<= 10;
218
self->updateRange.x = TO_FIXED(128) + abs(self->amplitude.x);
219
self->updateRange.y = TO_FIXED(128) + abs(self->amplitude.x);
220
if (self->speed < 0)
221
self->direction = FLIP_X;
222
self->state = Platform_State_React;
223
break;
224
225
case PLATFORM_HOVER_REACT:
226
self->amplitude.x <<= 10;
227
self->updateRange.x = TO_FIXED(128) + abs(self->amplitude.x);
228
self->updateRange.y = TO_FIXED(128) + abs(self->amplitude.x);
229
if (self->speed < 0)
230
self->direction = FLIP_X;
231
self->state = Platform_State_Hover_React;
232
break;
233
234
case PLATFORM_DOORSLIDE:
235
self->amplitude.x <<= 10;
236
self->updateRange.x = TO_FIXED(128) + abs(self->amplitude.x);
237
self->updateRange.y = TO_FIXED(128) + abs(self->amplitude.x);
238
239
if (self->speed < 0) {
240
self->direction = FLIP_X;
241
self->speed = -self->speed;
242
}
243
self->state = Platform_State_DoorSlide;
244
break;
245
246
case PLATFORM_SWING_REACT:
247
self->timer = 88;
248
// [Fallthrough]
249
case PLATFORM_SWING:
250
self->updateRange.x = (abs(self->amplitude.y) + 0x200) << 14;
251
self->updateRange.y = (abs(self->amplitude.y) + 0x200) << 14;
252
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
253
254
self->amplitude.y <<= 4;
255
self->groundVel = 4 * self->angle;
256
self->angle = self->groundVel + 0x100 + (self->amplitude.x * RSDK.Sin1024(self->speed * self->timer) >> 14);
257
self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
258
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
259
if (self->type == PLATFORM_SWING) {
260
self->state = Platform_State_Swing;
261
}
262
else {
263
if (self->groundVel >= 0)
264
self->drawPos.x -= TO_FIXED(32);
265
else
266
self->drawPos.x += TO_FIXED(32);
267
self->state = Platform_State_SwingReact;
268
}
269
break;
270
271
case PLATFORM_TRACK_REACT:
272
if (self->direction) {
273
self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9);
274
self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9);
275
}
276
else {
277
self->drawPos.x = self->centerPos.x - (self->amplitude.x << 9);
278
self->drawPos.y = self->centerPos.y - (self->amplitude.y << 9);
279
}
280
// [Fallthrough]
281
case PLATFORM_TRACK:
282
self->updateRange.x = (abs(self->amplitude.x) + 0x4000) << 9;
283
self->updateRange.y = (abs(self->amplitude.y) + 0x4000) << 9;
284
if (self->speed < 0)
285
self->direction = FLIP_X;
286
287
if (self->type == PLATFORM_TRACK)
288
self->state = Platform_State_Track;
289
else
290
self->state = Platform_State_TrackReact;
291
break;
292
293
case PLATFORM_CLACKER:
294
self->updateRange.x = (abs(self->amplitude.y) + 0x200) << 14;
295
self->updateRange.y = (abs(self->amplitude.y) + 0x200) << 14;
296
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
297
self->amplitude.y <<= 4;
298
self->groundVel = 4 * self->angle;
299
self->angle = self->groundVel + 0x100 + (self->amplitude.x * RSDK.Sin1024(self->speed * self->timer) >> 14);
300
self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
301
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
302
self->state = Platform_State_Clacker;
303
break;
304
305
case PLATFORM_CHILD:
306
self->state = Platform_State_Child;
307
self->updateRange.x = TO_FIXED(128);
308
self->updateRange.y = TO_FIXED(128);
309
break;
310
311
case PLATFORM_DIPROCK:
312
self->updateRange.x = TO_FIXED(128);
313
self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;
314
if (!self->speed)
315
self->speed = 1;
316
self->amplitude.y = self->amplitude.y << 10;
317
self->velocity.y = self->speed << 16;
318
self->state = Platform_State_DipRock;
319
break;
320
}
321
322
if (self->frameID >= 0) {
323
int32 f = self->frameID;
324
int32 anim = 0;
325
while (f >= self->animator.frameCount) {
326
if (!self->animator.frameCount)
327
break;
328
f -= self->animator.frameCount;
329
RSDK.SetSpriteAnimation(Platform->aniFrames, ++anim, &self->animator, true, 0);
330
}
331
self->frameID = f;
332
self->animator.frameID = f;
333
}
334
else {
335
RSDK.SetSpriteAnimation(-1, 0, &self->animator, true, 0);
336
}
337
338
if (!SceneInfo->inEditor) {
339
if (self->collision != PLATFORM_C_NONE) {
340
Hitbox *hitbox = RSDK.GetHitbox(&self->animator, self->collision != PLATFORM_C_PLATFORM);
341
if (Platform->aniFrames != (uint16)-1 && hitbox) {
342
self->hitbox.left = hitbox->left;
343
self->hitbox.top = hitbox->top;
344
self->hitbox.right = hitbox->right;
345
self->hitbox.bottom = hitbox->bottom;
346
}
347
else {
348
self->hitbox.left = -32;
349
self->hitbox.top = -16;
350
self->hitbox.right = -8;
351
self->hitbox.bottom = 32;
352
}
353
}
354
355
switch (self->collision) {
356
case PLATFORM_C_PLATFORM:
357
self->stateCollide = Platform_Collision_Platform;
358
self->hitbox.bottom = self->hitbox.top + 8;
359
break;
360
361
default:
362
case PLATFORM_C_SOLID: self->stateCollide = Platform_Collision_Solid; break;
363
364
case PLATFORM_C_TILED: self->stateCollide = Platform_Collision_Tiles; break;
365
case PLATFORM_C_HURT: self->stateCollide = Platform_Collision_Hurt; break;
366
case PLATFORM_C_NONE: self->stateCollide = Platform_Collision_None; break;
367
case PLATFORM_C_SOLID_HURT_SIDES: self->stateCollide = Platform_Collision_Solid_Hurt_Sides; break;
368
case PLATFORM_C_SOLID_HURT_BOTTOM: self->stateCollide = Platform_Collision_Solid_Hurt_Bottom; break;
369
case PLATFORM_C_SOLID_HURT_TOP: self->stateCollide = Platform_Collision_Solid_Hurt_Top; break;
370
case PLATFORM_C_SOLID_HOLD: self->stateCollide = Platform_Collision_Solid_Hold; break;
371
372
case PLATFORM_C_SOLID_STICKY:
373
case PLATFORM_C_STICKY_TOP:
374
case PLATFORM_C_STICKY_LEFT:
375
case PLATFORM_C_STICKY_RIGHT:
376
case PLATFORM_C_STICKY_BOTTOM: self->stateCollide = Platform_Collision_Sticky; break;
377
378
case PLATFORM_C_SOLID_BARREL: self->stateCollide = Platform_Collision_Solid_Barrel; break;
379
case PLATFORM_C_SOLID_NOCRUSH: self->stateCollide = Platform_Collision_Solid_NoCrush; break;
380
}
381
382
for (int32 i = 0; i < self->childCount; ++i) {
383
EntityPlatform *child = RSDK_GET_ENTITY((i + RSDK.GetEntitySlot(self) + 1), Platform);
384
child->tileCollisions = TILECOLLISION_NONE;
385
if (HangPoint && child->classID == HangPoint->classID) {
386
EntityHangPoint *hang = (EntityHangPoint *)child;
387
if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - (hang->length << 16) - hang->position.y))
388
self->updateRange.y = TO_FIXED(128) + abs(self->position.y - (hang->length << 16) - hang->position.y);
389
}
390
else {
391
if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - child->position.y))
392
self->updateRange.y = TO_FIXED(128) + abs(self->position.y - child->position.y);
393
}
394
}
395
}
396
}
397
398
void Platform_StageLoad(void)
399
{
400
Platform->useClack = false;
401
if (RSDK.CheckSceneFolder("GHZ")) {
402
Platform->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Platform.bin", SCOPE_STAGE);
403
}
404
else if (RSDK.CheckSceneFolder("GHZCutscene")) {
405
Platform->aniFrames = RSDK.LoadSpriteAnimation("GHZCutscene/Platform.bin", SCOPE_STAGE);
406
}
407
else if (RSDK.CheckSceneFolder("CPZ")) {
408
Platform->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Platform.bin", SCOPE_STAGE);
409
}
410
else if (RSDK.CheckSceneFolder("SPZ1")) {
411
Platform->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Platform.bin", SCOPE_STAGE);
412
}
413
else if (RSDK.CheckSceneFolder("SPZ2")) {
414
Platform->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/Platform.bin", SCOPE_STAGE);
415
}
416
else if (RSDK.CheckSceneFolder("FBZ")) {
417
Platform->aniFrames = RSDK.LoadSpriteAnimation("FBZ/Platform.bin", SCOPE_STAGE);
418
Platform->sfxClack = RSDK.GetSfx("Stage/Clack2.wav");
419
Platform->useClack = true;
420
}
421
else if (RSDK.CheckSceneFolder("PSZ1")) {
422
Platform->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Platform.bin", SCOPE_STAGE);
423
}
424
else if (RSDK.CheckSceneFolder("PSZ2")) {
425
Platform->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/Platform.bin", SCOPE_STAGE);
426
}
427
else if (RSDK.CheckSceneFolder("SSZ1")) {
428
Platform->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/Platform.bin", SCOPE_STAGE);
429
}
430
else if (RSDK.CheckSceneFolder("SSZ2")) {
431
Platform->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/Platform.bin", SCOPE_STAGE);
432
}
433
else if (RSDK.CheckSceneFolder("HCZ")) {
434
Platform->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Platform.bin", SCOPE_STAGE);
435
Platform->sfxClack = RSDK.GetSfx("Stage/Clack2.wav");
436
Platform->useClack = true;
437
}
438
else if (RSDK.CheckSceneFolder("MSZ")) {
439
Platform->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Platform.bin", SCOPE_STAGE);
440
}
441
else if (RSDK.CheckSceneFolder("OOZ1") || RSDK.CheckSceneFolder("OOZ2")) {
442
Platform->aniFrames = RSDK.LoadSpriteAnimation("OOZ/Platform.bin", SCOPE_STAGE);
443
}
444
else if (RSDK.CheckSceneFolder("LRZ1")) {
445
Platform->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Platform.bin", SCOPE_STAGE);
446
}
447
else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3")) {
448
Platform->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/Platform.bin", SCOPE_STAGE);
449
}
450
else if (RSDK.CheckSceneFolder("MMZ")) {
451
Platform->aniFrames = RSDK.LoadSpriteAnimation("MMZ/Platform.bin", SCOPE_STAGE);
452
}
453
else if (RSDK.CheckSceneFolder("TMZ1") || RSDK.CheckSceneFolder("TMZ2")) {
454
Platform->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/Platform.bin", SCOPE_STAGE);
455
}
456
else if (RSDK.CheckSceneFolder("AIZ")) {
457
Platform->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Platform.bin", SCOPE_STAGE);
458
}
459
else if (RSDK.CheckSceneFolder("SBZ")) { // SBZ once was a planned zone?
460
Platform->aniFrames = RSDK.LoadSpriteAnimation("SBZ/Platform.bin", SCOPE_STAGE);
461
}
462
else if (RSDK.CheckSceneFolder("Blueprint")) {
463
Platform->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/Platform.bin", SCOPE_STAGE);
464
}
465
466
Platform->sfxClacker = RSDK.GetSfx("Stage/Clacker.wav");
467
Platform->sfxClang = RSDK.GetSfx("Stage/Clang.wav");
468
Platform->sfxPush = RSDK.GetSfx("Global/Push.wav");
469
470
if (Platform->playingPushSfx) {
471
RSDK.StopSfx(Platform->sfxPush);
472
Platform->playingPushSfx = false;
473
}
474
}
475
476
void Platform_State_PathStop(void)
477
{
478
RSDK_THIS(Platform);
479
480
self->velocity.x = 0;
481
self->velocity.y = 0;
482
}
483
484
void Platform_State_Fixed(void)
485
{
486
RSDK_THIS(Platform);
487
488
self->drawPos.x = self->centerPos.x;
489
self->drawPos.y = self->centerPos.y;
490
self->drawPos.y += RSDK.Sin256(self->stoodAngle) << 10;
491
492
self->velocity.x = 0;
493
self->velocity.y = 0;
494
}
495
496
void Platform_State_Linear(void)
497
{
498
RSDK_THIS(Platform);
499
500
int32 drawX = -self->drawPos.x;
501
int32 drawY = -self->drawPos.y;
502
503
self->drawPos.x = self->amplitude.x * RSDK.Sin1024(self->speed * (self->rotation + Zone->timer)) + self->centerPos.x;
504
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->speed * (self->rotation + Zone->timer)) + self->centerPos.y;
505
self->drawPos.y += RSDK.Sin256(self->stoodAngle) << 10;
506
507
self->velocity.x = self->drawPos.x + drawX;
508
self->velocity.y = self->drawPos.y + drawY;
509
}
510
511
void Platform_State_Swing(void)
512
{
513
RSDK_THIS(Platform);
514
515
int32 drawX = -self->drawPos.x;
516
int32 drawY = -self->drawPos.y;
517
518
self->angle = self->groundVel + 0x100 + ((self->amplitude.x * RSDK.Sin1024(self->speed * Zone->timer) + 0x200) >> 14);
519
self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
520
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
521
522
self->velocity.x = self->drawPos.x + drawX;
523
self->velocity.y = self->drawPos.y + drawY;
524
}
525
526
void Platform_State_React(void)
527
{
528
RSDK_THIS(Platform);
529
530
if (self->stood) {
531
if (self->hasTension)
532
self->timer = 120;
533
self->rotation = 0;
534
self->tileOrigin.x = 0;
535
self->tileOrigin.y = 0;
536
self->active = ACTIVE_NORMAL;
537
self->state = Platform_State_ReactMove;
538
}
539
540
self->velocity.y = 0;
541
self->velocity.x = 0;
542
}
543
544
void Platform_State_Hover_React(void)
545
{
546
RSDK_THIS(Platform);
547
548
self->rotation += 4;
549
self->drawPos.y = self->centerPos.y + (RSDK.Sin1024(self->rotation) << 9);
550
if (self->stood) {
551
if (self->hasTension)
552
self->timer = 120;
553
self->tileOrigin.x = self->drawPos.x - self->centerPos.x;
554
self->centerPos.x = self->drawPos.x;
555
self->tileOrigin.y = RSDK.Sin1024(self->rotation) << 9;
556
self->centerPos.y = self->drawPos.y;
557
self->active = ACTIVE_NORMAL;
558
self->state = Platform_State_ReactMove;
559
}
560
561
self->velocity.y = 0;
562
self->velocity.x = 0;
563
}
564
565
void Platform_State_Push_Init(void)
566
{
567
RSDK_THIS(Platform);
568
569
self->active = ACTIVE_NORMAL;
570
self->updateRange.x = TO_FIXED(512);
571
self->updateRange.y = TO_FIXED(512);
572
self->state = Platform_State_Push;
573
self->velocity.x = 0;
574
self->velocity.y = 0;
575
}
576
577
void Platform_State_Falling(void)
578
{
579
RSDK_THIS(Platform);
580
581
if (--self->timer <= 0) {
582
self->timer = 0;
583
self->state = Platform_State_Falling2;
584
foreach_active(Player, player)
585
{
586
if ((1 << RSDK.GetEntitySlot(player)) & self->stoodPlayers)
587
player->velocity.y = self->velocity.y - TO_FIXED(1);
588
}
589
}
590
591
self->drawPos.y += self->velocity.y;
592
self->velocity.y += 0x3800;
593
self->velocity.x = 0;
594
}
595
596
void Platform_State_DoorSlide(void)
597
{
598
RSDK_THIS(Platform);
599
600
int32 drawX = -self->drawPos.x;
601
int32 drawY = -self->drawPos.y;
602
603
bool32 activated = false;
604
foreach_active(Player, player)
605
{
606
if (!player->sidekick) {
607
Vector2 pivotPos = player->position;
608
Zone_RotateOnPivot(&pivotPos, &self->centerPos, ((self->angle & 0xFF) + 0x80) & 0xFF);
609
610
if (abs(player->position.x - self->centerPos.x) <= TO_FIXED(1024)) {
611
if (abs(player->position.y - self->centerPos.y) <= TO_FIXED(1024)) {
612
if (pivotPos.y < self->centerPos.y && self->centerPos.y - pivotPos.y < TO_FIXED(256))
613
activated = true;
614
}
615
}
616
}
617
}
618
619
if (!activated) {
620
if (self->amplitude.y > 0) {
621
self->amplitude.y -= (self->speed << 16);
622
if (self->amplitude.y <= 0) {
623
self->amplitude.y = 0;
624
if (self->onScreen && Platform->useClack)
625
RSDK.PlaySfx(Platform->sfxClack, false, 0xFF);
626
}
627
}
628
}
629
else {
630
if (self->amplitude.y < self->amplitude.x) {
631
self->amplitude.y += (self->speed << 16);
632
if (self->amplitude.y >= self->amplitude.x) {
633
self->amplitude.y = self->amplitude.x;
634
if (self->onScreen && Platform->useClack)
635
RSDK.PlaySfx(Platform->sfxClack, false, 0xFF);
636
}
637
}
638
}
639
640
if (self->direction) {
641
self->drawPos.x = (-self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
642
self->drawPos.y = (-self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
643
}
644
else {
645
self->drawPos.x = (self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
646
self->drawPos.y = (self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
647
}
648
649
self->velocity.x = self->drawPos.x + drawX;
650
self->velocity.y = self->drawPos.y + drawY;
651
}
652
653
void Platform_State_ReactMove(void)
654
{
655
RSDK_THIS(Platform);
656
657
int32 drawX = -self->drawPos.x;
658
int32 drawY = -self->drawPos.y;
659
self->amplitude.y += self->groundVel;
660
661
self->drawPos.x = (self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
662
self->drawPos.y = (self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
663
664
int32 speed16 = self->speed << 16;
665
if (self->groundVel == speed16) {
666
if (self->amplitude.y >= self->amplitude.x) {
667
self->amplitude.y = self->amplitude.x;
668
self->groundVel = self->groundVel - (self->speed << 11);
669
self->state = Platform_State_ReactSlow;
670
}
671
}
672
else {
673
self->groundVel += (self->speed << 10);
674
if (self->groundVel >= speed16) {
675
self->groundVel = speed16;
676
self->centerPos.x += ((self->amplitude.y + self->groundVel) >> 8) * RSDK.Cos256(self->angle);
677
self->centerPos.y += ((self->groundVel + self->amplitude.y) >> 8) * RSDK.Sin256(self->angle);
678
self->amplitude.y = -self->groundVel;
679
}
680
}
681
682
self->velocity.x = self->drawPos.x + drawX;
683
self->velocity.y = self->drawPos.y + drawY;
684
}
685
686
void Platform_State_Push(void)
687
{
688
RSDK_THIS(Platform);
689
690
self->velocity.x = 0;
691
self->velocity.y = 0;
692
693
foreach_active(Player, playerLoop)
694
{
695
uint8 id = 1 << RSDK.GetEntitySlot(playerLoop);
696
if (id & self->pushPlayersL)
697
self->velocity.x += self->speed;
698
if (id & self->pushPlayersR)
699
self->velocity.x -= self->speed;
700
}
701
702
if (self->velocity.x > 0 || self->velocity.x < 0) {
703
if (!Platform->playingPushSfx) {
704
RSDK.PlaySfx(Platform->sfxPush, true, 255);
705
Platform->playingPushSfx = true;
706
}
707
}
708
709
if (self->velocity.x) {
710
if (self->timer > 0) {
711
self->timer--;
712
self->velocity.x = 0;
713
}
714
}
715
else {
716
if (Platform->playingPushSfx) {
717
RSDK.StopSfx(Platform->sfxPush);
718
Platform->playingPushSfx = false;
719
}
720
if (self->timer < 4) {
721
self->timer++;
722
}
723
}
724
725
self->drawPos.x += self->velocity.x;
726
self->position.x = self->drawPos.x;
727
self->position.y = self->drawPos.y;
728
foreach_active(Player, player)
729
{
730
Hitbox *playerHitbox = Player_GetHitbox(player);
731
int32 bitID = 1 << RSDK.GetEntitySlot(player);
732
if (bitID & self->pushPlayersL)
733
player->position.x = self->drawPos.x + ((self->hitbox.left - playerHitbox->right) << 16);
734
if (bitID & self->pushPlayersR)
735
player->position.x = self->drawPos.x + ((self->hitbox.right - playerHitbox->left - 1) << 16);
736
}
737
738
bool32 collided =
739
RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.left + 16), TO_FIXED(self->hitbox.bottom), 4);
740
int32 y = self->position.y;
741
742
collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(0), TO_FIXED(self->hitbox.bottom), 4);
743
if (self->position.y < y)
744
y = self->position.y;
745
746
collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.right - 16), TO_FIXED(self->hitbox.bottom), 4);
747
if (self->position.y < y)
748
y = self->position.y;
749
750
self->position.y = y;
751
self->drawPos.y = y;
752
753
if (!collided) {
754
self->velocity.x <<= 1;
755
if (!self->velocity.x) {
756
self->state = Platform_State_Push_Fall;
757
}
758
else {
759
if (self->velocity.x > 0)
760
self->state = Platform_State_Push_SlideOffL;
761
else
762
self->state = Platform_State_Push_SlideOffR;
763
}
764
}
765
766
RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, TO_FIXED(self->hitbox.left), TO_FIXED(self->hitbox.bottom - 8), true);
767
RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, TO_FIXED(self->hitbox.right), TO_FIXED(self->hitbox.bottom - 8), true);
768
RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, TO_FIXED(self->hitbox.left), TO_FIXED(self->hitbox.top + 8), true);
769
RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, TO_FIXED(self->hitbox.right), TO_FIXED(self->hitbox.top + 8), true);
770
771
self->drawPos.x = self->position.x;
772
self->drawPos.y = self->position.y;
773
if (!RSDK.CheckOnScreen(self, &self->updateRange)) {
774
self->speed >>= 11;
775
self->drawPos.x = self->centerPos.x;
776
self->drawPos.y = self->centerPos.y;
777
self->velocity.x = 0;
778
self->velocity.y = 0;
779
self->visible = false;
780
if (Platform->playingPushSfx) {
781
RSDK.StopSfx(Platform->sfxPush);
782
Platform->playingPushSfx = false;
783
}
784
self->state = Platform_State_Hold;
785
}
786
}
787
788
void Platform_State_Hold(void)
789
{
790
RSDK_THIS(Platform);
791
792
if (!RSDK.CheckOnScreen(self, &self->updateRange))
793
Platform_Create(NULL);
794
795
self->velocity.y = 0;
796
self->velocity.x = 0;
797
}
798
799
void Platform_State_Track(void)
800
{
801
RSDK_THIS(Platform);
802
803
int32 drawX = -self->drawPos.x;
804
int32 drawY = -self->drawPos.y;
805
int32 move = Zone->timer * (self->speed << 7);
806
807
if (((move >> 16) & 1) == self->direction) {
808
self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * self->amplitude.x >> 6) - (self->amplitude.x << 9);
809
self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * self->amplitude.y >> 6) - (self->amplitude.y << 9);
810
}
811
else {
812
self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9) - ((move & 0xFFFF) * self->amplitude.x >> 6);
813
self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9) - ((move & 0xFFFF) * self->amplitude.y >> 6);
814
}
815
816
if (((move >> 16) & 1) != self->hasTension) {
817
if (self->onScreen)
818
RSDK.PlaySfx(Platform->sfxClang, false, 255);
819
820
self->hasTension = (move >> 16) & 1;
821
}
822
823
self->velocity.x = self->drawPos.x + drawX;
824
self->velocity.y = self->drawPos.y + drawY;
825
}
826
827
void Platform_State_Falling2(void)
828
{
829
RSDK_THIS(Platform);
830
831
self->drawPos.y += self->velocity.y;
832
self->velocity.y += 0x3800;
833
834
self->position.x = self->drawPos.x;
835
self->position.y = self->drawPos.y;
836
837
if (RSDK.CheckOnScreen(self, &self->updateRange)) {
838
self->position.x = self->centerPos.x;
839
self->position.y = self->centerPos.y;
840
self->velocity.x = 0;
841
}
842
else {
843
if (self->amplitude.x) {
844
destroyEntity(self);
845
}
846
else {
847
self->drawPos.x = self->centerPos.x;
848
self->drawPos.y = self->centerPos.y;
849
self->velocity.y = 0;
850
self->visible = false;
851
self->state = Platform_State_Hold;
852
}
853
854
self->velocity.x = 0;
855
}
856
}
857
858
void Platform_State_Fall(void)
859
{
860
RSDK_THIS(Platform);
861
862
if (self->timer) {
863
if (!--self->timer) {
864
self->active = ACTIVE_NORMAL;
865
self->state = Platform_State_Falling;
866
self->timer = 30;
867
}
868
}
869
870
self->drawPos.x = self->centerPos.x;
871
self->drawPos.y = self->centerPos.y;
872
self->drawPos.y += RSDK.Sin256(self->stoodAngle) << 10;
873
874
self->velocity.x = 0;
875
}
876
877
void Platform_State_Circular(void)
878
{
879
RSDK_THIS(Platform);
880
881
int32 drawX = -self->drawPos.x;
882
int32 drawY = -self->drawPos.y;
883
884
self->drawPos.x = self->amplitude.x * RSDK.Cos1024(self->speed * Zone->timer + 4 * self->angle) + self->centerPos.x;
885
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->speed * Zone->timer + 4 * self->angle) + self->centerPos.y;
886
887
self->velocity.x = self->drawPos.x + drawX;
888
self->velocity.y = self->drawPos.y + drawY;
889
}
890
891
void Platform_State_SwingReact(void)
892
{
893
RSDK_THIS(Platform);
894
895
self->velocity.x = 0;
896
self->velocity.y = 0;
897
898
if (self->stood)
899
self->state = Platform_State_Swing2;
900
}
901
902
void Platform_State_TrackReact(void)
903
{
904
RSDK_THIS(Platform);
905
906
self->velocity.x = 0;
907
self->velocity.y = 0;
908
909
if (self->stood)
910
self->state = Platform_State_Track2;
911
}
912
913
void Platform_State_Clacker(void)
914
{
915
RSDK_THIS(Platform);
916
917
int32 drawX = -self->drawPos.x;
918
int32 drawY = -self->drawPos.y;
919
920
int32 prevAngle = self->angle;
921
int32 maxAngle = self->groundVel + 0x100;
922
self->angle = self->groundVel + ((self->amplitude.x * RSDK.Sin1024(self->speed * Zone->timer) + 0x200) >> 14) + 0x100;
923
924
if (!self->hasTension) {
925
if (self->angle >= maxAngle) {
926
if (!self->onScreen || prevAngle >= maxAngle) {
927
self->angle = self->groundVel + 0x100;
928
}
929
else {
930
RSDK.PlaySfx(Platform->sfxClacker, false, 255);
931
self->angle = self->groundVel + 0x100;
932
}
933
}
934
}
935
else if (self->angle <= maxAngle) {
936
if (!self->onScreen || prevAngle <= maxAngle) {
937
self->angle = self->groundVel + 0x100;
938
}
939
else {
940
RSDK.PlaySfx(Platform->sfxClacker, false, 255);
941
self->angle = self->groundVel + 0x100;
942
}
943
}
944
945
self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
946
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
947
self->velocity.x = self->drawPos.x + drawX;
948
self->velocity.y = self->drawPos.y + drawY;
949
}
950
951
void Platform_State_Child(void)
952
{
953
RSDK_THIS(Platform);
954
955
int32 drawX = -self->drawPos.x;
956
int32 drawY = -self->drawPos.y;
957
958
self->drawPos.x = self->centerPos.x;
959
self->drawPos.y = self->centerPos.y;
960
961
self->velocity.x = self->drawPos.x + drawX;
962
self->velocity.y = self->drawPos.y + drawY;
963
}
964
965
void Platform_State_DipRock(void)
966
{
967
RSDK_THIS(Platform);
968
969
if (self->stood) {
970
self->drawPos.y += self->velocity.y;
971
if (self->drawPos.y > self->centerPos.y + self->amplitude.y)
972
self->drawPos.y = self->centerPos.y + self->amplitude.y;
973
}
974
else {
975
self->drawPos.y -= self->velocity.y;
976
if (self->drawPos.y < self->centerPos.y)
977
self->drawPos.y = self->centerPos.y;
978
}
979
}
980
981
void Platform_State_Push_SlideOffL(void)
982
{
983
RSDK_THIS(Platform);
984
985
self->drawPos.x += self->velocity.x;
986
987
int32 storeX = self->position.x;
988
int32 storeY = self->position.y;
989
990
self->position.x = self->drawPos.x;
991
self->position.y = self->drawPos.y;
992
if (!RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.left), TO_FIXED(self->hitbox.bottom), false))
993
self->state = Platform_State_Push_Fall;
994
995
self->position.x = storeX;
996
self->position.y = storeY;
997
}
998
999
void Platform_State_Push_SlideOffR(void)
1000
{
1001
RSDK_THIS(Platform);
1002
1003
self->drawPos.x += self->velocity.x;
1004
1005
int32 storeX = self->position.x;
1006
int32 storeY = self->position.y;
1007
1008
self->position.x = self->drawPos.x;
1009
self->position.y = self->drawPos.y;
1010
1011
if (!RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.right), TO_FIXED(self->hitbox.bottom), false))
1012
self->state = Platform_State_Push_Fall;
1013
1014
self->position.x = storeX;
1015
self->position.y = storeY;
1016
}
1017
1018
void Platform_State_Push_Fall(void)
1019
{
1020
RSDK_THIS(Platform);
1021
1022
int32 storeX = self->position.x;
1023
int32 storeY = self->position.y;
1024
1025
self->drawPos.y += self->velocity.y;
1026
self->velocity.y += 0x3800;
1027
1028
self->position.x = self->drawPos.x;
1029
self->position.y = self->drawPos.y;
1030
1031
bool32 collided =
1032
RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.left + 16), TO_FIXED(self->hitbox.bottom), 4);
1033
int32 y = self->position.y;
1034
1035
collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(0), TO_FIXED(self->hitbox.bottom), 4);
1036
if (self->position.y < y)
1037
y = self->position.y;
1038
1039
collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.right - 16), TO_FIXED(self->hitbox.bottom), 4);
1040
if (self->position.y < y)
1041
y = self->position.y;
1042
1043
if (collided) {
1044
self->velocity.y = 0;
1045
self->state = Platform_State_Push;
1046
}
1047
else {
1048
self->position.y = y;
1049
self->drawPos.y = y;
1050
}
1051
1052
self->position.x = storeX;
1053
self->position.y = storeY;
1054
1055
self->velocity.x = 0;
1056
}
1057
1058
void Platform_State_Path(void)
1059
{
1060
RSDK_THIS(Platform);
1061
1062
self->drawPos.x += self->velocity.x;
1063
self->drawPos.y += self->velocity.y;
1064
EntityPlatformNode *node = RSDK_GET_ENTITY(self->speed, PlatformNode);
1065
1066
if (self->velocity.y <= 0) {
1067
if (self->drawPos.y < node->position.y)
1068
self->drawPos.y = node->position.y;
1069
}
1070
else {
1071
if (self->drawPos.y > node->position.y)
1072
self->drawPos.y = node->position.y;
1073
}
1074
1075
if (self->velocity.x <= 0) {
1076
if (self->drawPos.x < node->position.x)
1077
self->drawPos.x = node->position.x;
1078
}
1079
else {
1080
if (self->drawPos.x > node->position.x)
1081
self->drawPos.x = node->position.x;
1082
}
1083
}
1084
1085
void Platform_State_ReactSlow(void)
1086
{
1087
RSDK_THIS(Platform);
1088
1089
int32 drawX = -self->drawPos.x;
1090
int32 drawY = -self->drawPos.y;
1091
1092
self->amplitude.y += self->groundVel;
1093
self->drawPos.x = (self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
1094
self->drawPos.y = (self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
1095
1096
if (self->groundVel <= 0) {
1097
self->centerPos.x = self->drawPos.x - self->tileOrigin.x;
1098
self->centerPos.y = self->drawPos.y - self->tileOrigin.y;
1099
self->groundVel = 0;
1100
self->amplitude.y = 0;
1101
self->angle = -self->angle;
1102
1103
if (self->timer == -1) {
1104
self->timer = 0;
1105
if (self->type == PLATFORM_HOVER_REACT)
1106
self->state = Platform_State_Hover_React;
1107
else
1108
self->state = Platform_State_React;
1109
}
1110
else {
1111
if (self->hasTension) {
1112
self->state = Platform_State_ReactWait;
1113
}
1114
else {
1115
self->active = ACTIVE_BOUNDS;
1116
if (self->type == PLATFORM_HOVER_REACT)
1117
self->state = Platform_State_Hover;
1118
else
1119
self->state = Platform_State_Fixed;
1120
}
1121
}
1122
}
1123
else {
1124
self->groundVel -= self->speed << 10;
1125
}
1126
1127
self->velocity.x = drawX + self->drawPos.x;
1128
self->velocity.y = drawY + self->drawPos.y;
1129
}
1130
1131
void Platform_State_Hover(void)
1132
{
1133
RSDK_THIS(Platform);
1134
1135
self->rotation += 4;
1136
self->drawPos.y = (RSDK.Sin1024(self->rotation) << 9) + self->centerPos.y;
1137
self->velocity.x = 0;
1138
self->velocity.y = 0;
1139
}
1140
1141
void Platform_State_ReactWait(void)
1142
{
1143
RSDK_THIS(Platform);
1144
1145
if (self->type == PLATFORM_HOVER_REACT) {
1146
self->rotation += 4;
1147
self->drawPos.y = (RSDK.Sin1024(self->rotation) << 9) + self->centerPos.y;
1148
}
1149
1150
if (self->stood) {
1151
self->timer = 120;
1152
self->velocity.x = 0;
1153
self->velocity.y = 0;
1154
}
1155
else {
1156
if (--self->timer) {
1157
self->tileOrigin.x = self->drawPos.x - self->centerPos.x;
1158
self->tileOrigin.y = self->drawPos.y - self->centerPos.y;
1159
self->centerPos.x = self->drawPos.x;
1160
self->centerPos.y = self->drawPos.y;
1161
self->timer = -1;
1162
self->active = ACTIVE_NORMAL;
1163
self->state = Platform_State_ReactMove;
1164
}
1165
self->velocity.x = 0;
1166
self->velocity.y = 0;
1167
}
1168
}
1169
1170
void Platform_State_PathReact(void)
1171
{
1172
RSDK_THIS(Platform);
1173
1174
if (!self->stood) {
1175
self->velocity.x = 0;
1176
self->velocity.y = 0;
1177
}
1178
else {
1179
int32 slot = SceneInfo->entitySlot - 1;
1180
EntityPlatformControl *controller = RSDK_GET_ENTITY(slot, PlatformControl);
1181
if (controller->classID == PlatformControl->classID) {
1182
controller->setActive = true;
1183
self->state = Platform_State_Path;
1184
self->velocity.x = 0;
1185
self->velocity.y = 0;
1186
}
1187
else {
1188
while (controller->classID == Platform->classID || controller->classID == PlatformNode->classID) {
1189
controller = RSDK_GET_ENTITY(slot--, PlatformControl);
1190
if (controller->classID == PlatformControl->classID) {
1191
controller->setActive = true;
1192
self->state = Platform_State_Path;
1193
self->velocity.x = 0;
1194
self->velocity.y = 0;
1195
break;
1196
}
1197
}
1198
}
1199
}
1200
}
1201
1202
void Platform_State_Swing2(void)
1203
{
1204
RSDK_THIS(Platform);
1205
1206
int32 drawX = -self->drawPos.x;
1207
int32 drawY = -self->drawPos.y;
1208
self->angle = self->groundVel + 0x100 + ((self->amplitude.x * RSDK.Sin1024(self->timer * self->speed) + 0x200) >> 14);
1209
1210
if (self->timer++ == 256 && self->hasTension) {
1211
self->timer = 119;
1212
self->state = Platform_State_SwingWait;
1213
}
1214
self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
1215
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
1216
1217
if (self->groundVel < 0)
1218
self->drawPos.x += TO_FIXED(32);
1219
else
1220
self->drawPos.x -= TO_FIXED(32);
1221
1222
self->velocity.x = drawX + self->drawPos.x;
1223
self->velocity.y = drawY + self->drawPos.y;
1224
}
1225
1226
void Platform_State_SwingWait(void)
1227
{
1228
RSDK_THIS(Platform);
1229
1230
if (self->stood) {
1231
self->timer = 120;
1232
self->velocity.x = 0;
1233
self->velocity.y = 0;
1234
}
1235
else {
1236
if (!--self->timer) {
1237
self->timer = 257;
1238
self->active = ACTIVE_NORMAL;
1239
self->state = Platform_State_SwingReturn;
1240
}
1241
self->velocity.x = 0;
1242
self->velocity.y = 0;
1243
}
1244
}
1245
1246
void Platform_State_SwingReturn(void)
1247
{
1248
RSDK_THIS(Platform);
1249
1250
int32 drawX = -self->drawPos.x;
1251
int32 drawY = -self->drawPos.y;
1252
int32 amp = self->amplitude.x * RSDK.Sin1024(self->timer-- * self->speed);
1253
self->angle = self->groundVel + 0x100 + ((amp + 0x200) >> 14);
1254
1255
if (self->timer == 88)
1256
self->state = Platform_State_SwingReact;
1257
1258
self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
1259
self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
1260
if (self->groundVel < 0)
1261
self->drawPos.x += TO_FIXED(32);
1262
else
1263
self->drawPos.x -= TO_FIXED(32);
1264
self->velocity.x = drawX + self->drawPos.x;
1265
self->velocity.y = drawY + self->drawPos.y;
1266
}
1267
1268
void Platform_State_Track2(void)
1269
{
1270
RSDK_THIS(Platform);
1271
1272
int32 drawX = -self->drawPos.x;
1273
int32 drawY = -self->drawPos.y;
1274
int32 move = self->angle++ * (self->speed << 7);
1275
1276
if (self->hasTension) {
1277
if (move < TO_FIXED(1)) {
1278
if (move <= 0)
1279
move = 0;
1280
}
1281
else {
1282
move = TO_FIXED(1);
1283
self->timer = 120;
1284
self->state = Platform_State_TrackWait;
1285
}
1286
}
1287
1288
if (((move >> 16) & 1) == self->direction) {
1289
self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * self->amplitude.x >> 6) - (self->amplitude.x << 9);
1290
self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * self->amplitude.y >> 6) - (self->amplitude.y << 9);
1291
}
1292
else {
1293
self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9) - ((move & 0xFFFF) * self->amplitude.x >> 6);
1294
self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9) - ((move & 0xFFFF) * self->amplitude.y >> 6);
1295
}
1296
1297
self->velocity.x = drawX + self->drawPos.x;
1298
self->velocity.y = drawY + self->drawPos.y;
1299
}
1300
1301
void Platform_State_TrackWait(void)
1302
{
1303
RSDK_THIS(Platform);
1304
1305
if (self->stoodPlayers) {
1306
self->timer = 120;
1307
self->velocity.x = 0;
1308
self->velocity.y = 0;
1309
}
1310
else {
1311
if (!--self->timer) {
1312
self->active = ACTIVE_NORMAL;
1313
self->state = Platform_State_TrackReturn;
1314
}
1315
self->velocity.x = 0;
1316
self->velocity.y = 0;
1317
}
1318
}
1319
1320
void Platform_State_TrackReturn(void)
1321
{
1322
RSDK_THIS(Platform);
1323
1324
int32 drawX = -self->drawPos.x;
1325
int32 drawY = -self->drawPos.y;
1326
int32 move = self->angle-- * (self->speed << 7);
1327
1328
if (move > 0) {
1329
if (move >= TO_FIXED(1))
1330
move = TO_FIXED(1);
1331
}
1332
else {
1333
move = 0;
1334
self->state = Platform_State_TrackReact;
1335
}
1336
1337
if (((move >> 16) & 1) == self->direction) {
1338
self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * self->amplitude.x >> 6) - (self->amplitude.x << 9);
1339
self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * self->amplitude.y >> 6) - (self->amplitude.y << 9);
1340
}
1341
else {
1342
self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9) - ((move & 0xFFFF) * self->amplitude.x >> 6);
1343
self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9) - ((move & 0xFFFF) * self->amplitude.y >> 6);
1344
}
1345
1346
self->velocity.x = drawX + self->drawPos.x;
1347
self->velocity.y = drawY + self->drawPos.y;
1348
}
1349
1350
// Collision States
1351
void Platform_Collision_Solid(void)
1352
{
1353
RSDK_THIS(Platform);
1354
1355
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1356
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1357
int32 stoodPlayers = self->stoodPlayers;
1358
1359
self->stoodPlayers = 0;
1360
self->pushPlayersL = 0;
1361
self->pushPlayersR = 0;
1362
foreach_active(Player, player)
1363
{
1364
int32 playerID = RSDK.GetEntitySlot(player);
1365
Player_CheckCollisionPlatform(player, self, platformHitbox);
1366
1367
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1368
case C_TOP:
1369
Platform_HandleStood(self, player, playerID, stoodPlayers);
1370
1371
if (self->velocity.y <= 0)
1372
player->collisionFlagV |= 1;
1373
break;
1374
1375
case C_LEFT:
1376
if (player->onGround && player->right)
1377
self->pushPlayersL |= 1 << playerID;
1378
1379
if (self->velocity.x <= 0) {
1380
if (player->left) {
1381
player->groundVel = self->velocity.x;
1382
player->velocity.x = player->groundVel;
1383
player->velocity.x -= player->acceleration;
1384
}
1385
player->collisionFlagH |= 1;
1386
}
1387
break;
1388
1389
case C_RIGHT:
1390
if (player->onGround && player->left)
1391
self->pushPlayersR |= 1 << playerID;
1392
1393
if (self->velocity.x >= 0) {
1394
if (player->right) {
1395
player->groundVel = self->velocity.x;
1396
player->velocity.x = player->groundVel;
1397
player->velocity.x += player->acceleration;
1398
}
1399
player->collisionFlagH |= 2;
1400
}
1401
break;
1402
1403
case C_BOTTOM:
1404
if (self->velocity.y >= 0)
1405
player->collisionFlagV |= 2;
1406
break;
1407
1408
default: break;
1409
}
1410
}
1411
}
1412
void Platform_Collision_Hurt(void)
1413
{
1414
RSDK_THIS(Platform);
1415
1416
if (self->timer)
1417
self->timer--;
1418
1419
foreach_active(Player, player)
1420
{
1421
if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {
1422
#if MANIA_USE_PLUS
1423
if (!Player_CheckMightyUnspin(player, 0x400, self->type == PLATFORM_CIRCULAR, &player->uncurlTimer))
1424
#endif
1425
Player_Hurt(player, self);
1426
}
1427
}
1428
}
1429
void Platform_Collision_Solid_Hurt_Bottom(void)
1430
{
1431
RSDK_THIS(Platform);
1432
1433
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1434
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1435
1436
self->stoodPlayers = 0;
1437
self->pushPlayersL = 0;
1438
self->pushPlayersR = 0;
1439
1440
foreach_active(Player, player)
1441
{
1442
int32 playerID = RSDK.GetEntitySlot(player);
1443
Player_CheckCollisionPlatform(player, self, platformHitbox);
1444
1445
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1446
case C_TOP:
1447
Platform_HandleStood(self, player, playerID, 0xFF);
1448
1449
if (self->velocity.y <= 0)
1450
player->collisionFlagV |= 1;
1451
break;
1452
1453
case C_LEFT:
1454
if (player->onGround && player->right)
1455
self->pushPlayersL |= 1 << playerID;
1456
1457
if (self->velocity.x <= 0) {
1458
if (player->left) {
1459
player->groundVel = self->velocity.x;
1460
player->velocity.x = player->groundVel;
1461
player->velocity.x -= player->acceleration;
1462
}
1463
player->collisionFlagH |= 1;
1464
}
1465
break;
1466
1467
case C_RIGHT:
1468
if (player->onGround && player->left)
1469
self->pushPlayersR |= 1 << playerID;
1470
1471
if (self->velocity.x >= 0) {
1472
if (player->right) {
1473
player->groundVel = self->velocity.x;
1474
player->velocity.x = player->groundVel;
1475
player->velocity.x += player->acceleration;
1476
}
1477
player->collisionFlagH |= 2;
1478
}
1479
break;
1480
1481
case C_BOTTOM:
1482
if (self->velocity.y >= 0)
1483
player->collisionFlagV |= 2;
1484
1485
#if MANIA_USE_PLUS
1486
if (!Player_CheckMightyUnspin(player, 0x400, 0, &player->uncurlTimer))
1487
#endif
1488
Player_Hurt(player, self);
1489
break;
1490
1491
default: break;
1492
}
1493
}
1494
}
1495
void Platform_Collision_Solid_Hurt_Sides(void)
1496
{
1497
RSDK_THIS(Platform);
1498
1499
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1500
1501
self->stoodPlayers = 0;
1502
self->pushPlayersL = 0;
1503
self->pushPlayersR = 0;
1504
foreach_active(Player, player)
1505
{
1506
uint16 playerID = RSDK.GetEntitySlot(player);
1507
1508
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1509
case C_TOP:
1510
Platform_HandleStood(self, player, playerID, 0xFF);
1511
1512
if (self->velocity.y <= 0)
1513
player->collisionFlagV |= 1;
1514
break;
1515
1516
case C_LEFT:
1517
if (
1518
#if MANIA_USE_PLUS
1519
Player_CheckMightyUnspin(player, 1024, 0, &player->uncurlTimer) ||
1520
#endif
1521
Player_Hurt(player, self)) {
1522
player->velocity.x += self->velocity.x;
1523
}
1524
1525
if (!player->blinkTimer || player->velocity.x >= self->velocity.x) {
1526
if (player->onGround && player->right)
1527
self->pushPlayersL |= 1 << playerID;
1528
1529
if (self->velocity.x < 0 && player->velocity.x >= self->velocity.x && player->left) {
1530
player->groundVel = self->velocity.x;
1531
player->velocity.x = player->groundVel;
1532
player->velocity.x -= player->acceleration;
1533
}
1534
}
1535
1536
if (self->velocity.x <= 0)
1537
player->collisionFlagH |= 1;
1538
break;
1539
1540
case C_RIGHT:
1541
if (
1542
#if MANIA_USE_PLUS
1543
Player_CheckMightyUnspin(player, 0x400, 0, &player->uncurlTimer) ||
1544
#endif
1545
Player_Hurt(player, self)) {
1546
player->velocity.x += self->velocity.x;
1547
}
1548
1549
if (!player->blinkTimer || player->velocity.x <= self->velocity.x) {
1550
if (player->onGround && player->left)
1551
self->pushPlayersR |= 1 << playerID;
1552
1553
if (self->velocity.x > 0 && player->velocity.x <= self->velocity.x && player->right) {
1554
player->groundVel = self->velocity.x;
1555
player->velocity.x = player->groundVel;
1556
player->velocity.x += player->acceleration;
1557
}
1558
}
1559
1560
if (self->velocity.x >= 0)
1561
player->collisionFlagH |= 2;
1562
break;
1563
1564
case C_BOTTOM:
1565
if (self->velocity.y >= 0)
1566
player->collisionFlagV |= 2;
1567
break;
1568
1569
default: break;
1570
}
1571
}
1572
}
1573
void Platform_Collision_Tiles(void)
1574
{
1575
RSDK_THIS(Platform);
1576
1577
self->stoodPlayers = 0;
1578
self->pushPlayersL = 0;
1579
self->pushPlayersR = 0;
1580
foreach_active(Player, player)
1581
{
1582
int32 playerID = RSDK.GetEntitySlot(player);
1583
1584
Hitbox hitbox;
1585
hitbox.left = self->hitbox.left - 16;
1586
hitbox.top = self->hitbox.top - 16;
1587
hitbox.right = self->hitbox.right + 16;
1588
hitbox.bottom = self->hitbox.bottom + 16;
1589
1590
if (Player_CheckCollisionTouch(player, self, &hitbox)) {
1591
player->collisionLayers |= Zone->moveLayerMask;
1592
player->moveLayerPosition.x = self->tileOrigin.x - self->drawPos.x;
1593
player->moveLayerPosition.y = self->tileOrigin.y - self->drawPos.y;
1594
if (player->animator.animationID == ANI_PUSH && player->onGround) {
1595
if (player->right)
1596
self->pushPlayersL |= 1 << playerID;
1597
1598
if (player->onGround && player->left)
1599
self->pushPlayersR |= 1 << playerID;
1600
}
1601
1602
bool32 isClimbing = false;
1603
if (player->state == Player_State_KnuxWallClimb || player->state == Player_State_KnuxLedgePullUp) {
1604
isClimbing = true;
1605
1606
if (player->state == Player_State_KnuxLedgePullUp)
1607
hitbox.top -= 16;
1608
1609
if (player->position.x >= self->position.x) {
1610
hitbox.top += 16;
1611
hitbox.left += 16;
1612
}
1613
else {
1614
hitbox.top += 16;
1615
hitbox.right -= 16;
1616
}
1617
1618
hitbox.bottom -= 16;
1619
}
1620
else {
1621
switch (player->collisionMode) {
1622
case CMODE_FLOOR:
1623
hitbox.right -= 16;
1624
hitbox.left += 16;
1625
hitbox.bottom -= 16;
1626
break;
1627
1628
case CMODE_LWALL:
1629
hitbox.top += 16;
1630
hitbox.right -= 16;
1631
hitbox.bottom -= 16;
1632
break;
1633
1634
case CMODE_ROOF:
1635
hitbox.top += 16;
1636
hitbox.left += 16;
1637
hitbox.right -= 16;
1638
break;
1639
1640
case CMODE_RWALL:
1641
hitbox.top += 16;
1642
hitbox.left += 16;
1643
hitbox.bottom -= 16;
1644
break;
1645
1646
default: break;
1647
}
1648
}
1649
1650
if (Player_CheckCollisionTouch(player, self, &hitbox) && (player->onGround || isClimbing)) {
1651
Platform_HandleStood_Tiles(self, player, playerID);
1652
}
1653
}
1654
}
1655
}
1656
void Platform_Collision_Sticky(void)
1657
{
1658
RSDK_THIS(Platform);
1659
1660
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1661
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1662
1663
self->pushPlayersL = 0;
1664
self->pushPlayersR = 0;
1665
foreach_active(Player, player)
1666
{
1667
uint16 playerID = RSDK.GetEntitySlot(player);
1668
Player_CheckCollisionPlatform(player, self, platformHitbox);
1669
1670
int32 side = Player_CheckCollisionBox(player, self, solidHitbox);
1671
1672
Platform_HandleStood_Sticky(self, player, playerID, side);
1673
}
1674
}
1675
void Platform_Collision_Solid_Hurt_Top(void)
1676
{
1677
RSDK_THIS(Platform);
1678
1679
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1680
1681
self->stoodPlayers = 0;
1682
self->pushPlayersL = 0;
1683
self->pushPlayersR = 0;
1684
foreach_active(Player, player)
1685
{
1686
uint16 playerID = RSDK.GetEntitySlot(player);
1687
1688
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1689
case C_TOP: Platform_HandleStood(self, player, playerID, 0xFF);
1690
1691
#if MANIA_USE_PLUS
1692
if (!Player_CheckMightyUnspin(player, 0x400, 0, &player->uncurlTimer))
1693
#endif
1694
Player_Hurt(player, self);
1695
1696
if (self->velocity.y <= 0)
1697
player->collisionFlagV |= 1;
1698
break;
1699
1700
case C_LEFT:
1701
if (player->onGround && player->right)
1702
self->pushPlayersL |= 1 << playerID;
1703
1704
if (self->velocity.x <= 0) {
1705
if (player->left) {
1706
player->groundVel = self->velocity.x;
1707
player->velocity.x = player->groundVel;
1708
player->velocity.x -= player->acceleration;
1709
}
1710
player->collisionFlagH |= 1;
1711
}
1712
break;
1713
1714
case C_RIGHT:
1715
if (player->onGround && player->left)
1716
self->pushPlayersR |= 1 << playerID;
1717
1718
if (self->velocity.x >= 0) {
1719
if (player->right) {
1720
player->groundVel = self->velocity.x;
1721
player->velocity.x = player->groundVel;
1722
player->velocity.x += player->acceleration;
1723
}
1724
player->collisionFlagH |= 2;
1725
}
1726
break;
1727
1728
case C_BOTTOM:
1729
if (self->velocity.y >= 0)
1730
player->collisionFlagV |= 2;
1731
break;
1732
1733
default: break;
1734
}
1735
}
1736
}
1737
void Platform_Collision_Platform(void)
1738
{
1739
RSDK_THIS(Platform);
1740
1741
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1742
int32 stoodPlayers = self->stoodPlayers;
1743
1744
self->stoodPlayers = 0;
1745
foreach_active(Player, player)
1746
{
1747
uint16 playerID = RSDK.GetEntitySlot(player);
1748
int32 yVel = player->velocity.y;
1749
1750
if (self->collisionOffset.y < 0)
1751
player->velocity.y -= self->collisionOffset.y;
1752
1753
if (Player_CheckCollisionPlatform(player, self, platformHitbox)) {
1754
Platform_HandleStood(self, player, playerID, stoodPlayers);
1755
}
1756
else {
1757
player->velocity.y = yVel;
1758
}
1759
}
1760
}
1761
void Platform_Collision_Solid_Barrel(void)
1762
{
1763
RSDK_THIS(Platform);
1764
1765
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1766
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1767
int32 stoodPlayers = self->stoodPlayers;
1768
1769
self->stoodPlayers = 0;
1770
self->pushPlayersL = 0;
1771
self->pushPlayersR = 0;
1772
foreach_active(Player, player)
1773
{
1774
uint16 playerID = RSDK.GetEntitySlot(player);
1775
Player_CheckCollisionPlatform(player, self, platformHitbox);
1776
1777
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1778
case C_TOP: self->stood = true;
1779
#if MANIA_USE_PLUS
1780
if (player->characterID != ID_MIGHTY || player->state != Player_State_MightyHammerDrop) {
1781
#endif
1782
1783
Platform_HandleStood_Barrel(self, player, playerID, stoodPlayers);
1784
1785
if (self->velocity.y <= 0)
1786
player->collisionFlagV |= 1;
1787
#if MANIA_USE_PLUS
1788
}
1789
#endif
1790
break;
1791
1792
case C_LEFT:
1793
if (player->onGround && player->right)
1794
self->pushPlayersL |= 1 << playerID;
1795
1796
if (self->velocity.x <= 0) {
1797
if (player->left) {
1798
player->groundVel = self->velocity.x;
1799
player->velocity.x = player->groundVel;
1800
player->velocity.x -= player->acceleration;
1801
}
1802
1803
player->collisionFlagH |= 1;
1804
}
1805
break;
1806
1807
case C_RIGHT:
1808
if (player->onGround && player->left)
1809
self->pushPlayersR |= 1 << playerID;
1810
1811
if (self->velocity.x >= 0) {
1812
if (player->right) {
1813
player->groundVel = self->velocity.x;
1814
player->velocity.x = player->groundVel;
1815
player->velocity.x += player->acceleration;
1816
}
1817
1818
player->collisionFlagH |= 2;
1819
}
1820
break;
1821
1822
case C_BOTTOM:
1823
if (self->velocity.y >= 0)
1824
player->collisionFlagV |= 2;
1825
break;
1826
1827
default: break;
1828
}
1829
}
1830
}
1831
void Platform_Collision_Solid_Hold(void)
1832
{
1833
RSDK_THIS(Platform);
1834
1835
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1836
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1837
int32 stoodPlayers = self->stoodPlayers;
1838
1839
self->stoodPlayers = 0;
1840
self->pushPlayersL = 0;
1841
self->pushPlayersR = 0;
1842
foreach_active(Player, player)
1843
{
1844
uint16 playerID = RSDK.GetEntitySlot(player);
1845
Player_CheckCollisionPlatform(player, self, platformHitbox);
1846
1847
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1848
case C_NONE:
1849
if ((1 << playerID) & stoodPlayers) {
1850
if (player->state == Player_State_Static) {
1851
player->state = Player_State_Air;
1852
RSDK.SetSpriteAnimation(player->aniFrames, ANI_AIR_WALK, &player->animator, false, 0);
1853
}
1854
}
1855
break;
1856
1857
case C_TOP:
1858
#if MANIA_USE_PLUS
1859
if (player->characterID != ID_MIGHTY || player->state != Player_State_MightyHammerDrop) {
1860
#endif
1861
1862
Platform_HandleStood_Hold(self, player, playerID, stoodPlayers);
1863
1864
if (self->velocity.y <= 0)
1865
player->collisionFlagV |= 1;
1866
#if MANIA_USE_PLUS
1867
}
1868
#endif
1869
break;
1870
1871
case C_LEFT:
1872
if (player->onGround && player->right)
1873
self->pushPlayersL |= 1 << playerID;
1874
1875
if (self->velocity.x <= 0) {
1876
if (player->left) {
1877
player->groundVel = self->velocity.x;
1878
player->velocity.x = player->groundVel;
1879
player->velocity.x -= player->acceleration;
1880
}
1881
1882
player->collisionFlagH |= 1;
1883
}
1884
break;
1885
1886
case C_RIGHT:
1887
if (player->onGround && player->left)
1888
self->pushPlayersR |= 1 << playerID;
1889
1890
if (self->velocity.x >= 0) {
1891
if (player->right) {
1892
player->groundVel = self->velocity.x;
1893
player->velocity.x = player->groundVel;
1894
player->velocity.x += player->acceleration;
1895
}
1896
1897
player->collisionFlagH |= 2;
1898
}
1899
1900
break;
1901
1902
case C_BOTTOM:
1903
if (self->velocity.y >= 0)
1904
player->collisionFlagV |= 2;
1905
break;
1906
1907
default: break;
1908
}
1909
}
1910
}
1911
void Platform_Collision_None(void)
1912
{
1913
// hehe
1914
}
1915
void Platform_Collision_Solid_NoCrush(void)
1916
{
1917
RSDK_THIS(Platform);
1918
1919
Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);
1920
Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);
1921
int32 stoodPlayers = self->stoodPlayers;
1922
1923
self->stoodPlayers = 0;
1924
self->pushPlayersL = 0;
1925
self->pushPlayersR = 0;
1926
foreach_active(Player, player)
1927
{
1928
uint16 playerID = RSDK.GetEntitySlot(player);
1929
Player_CheckCollisionPlatform(player, self, platformHitbox);
1930
1931
switch (Player_CheckCollisionBox(player, self, solidHitbox)) {
1932
default:
1933
case C_NONE: break;
1934
1935
case C_TOP: Platform_HandleStood(self, player, playerID, stoodPlayers); break;
1936
1937
case C_LEFT:
1938
if (player->onGround && player->right)
1939
self->pushPlayersL |= 1 << playerID;
1940
1941
if (self->velocity.x <= 0 && player->left) {
1942
player->groundVel = self->velocity.x;
1943
player->velocity.x = player->groundVel;
1944
player->velocity.x -= player->acceleration;
1945
}
1946
break;
1947
1948
case C_RIGHT:
1949
if (player->onGround && player->left)
1950
self->pushPlayersR |= 1 << playerID;
1951
1952
if (self->velocity.x >= 0) {
1953
if (player->right) {
1954
player->groundVel = self->velocity.x;
1955
player->velocity.x = player->groundVel;
1956
player->velocity.x += player->acceleration;
1957
}
1958
}
1959
break;
1960
1961
case C_BOTTOM: break;
1962
}
1963
}
1964
}
1965
1966
void Platform_HandleStood(EntityPlatform *self, EntityPlayer *player, int32 playerID, int32 stoodPlayers)
1967
{
1968
self->stood = true;
1969
1970
// if stoodPlayers is 0xFF thats the "ignore stoodPlayers" flag
1971
bool32 isStood = ((1 << playerID) & stoodPlayers) != 0;
1972
isStood &= stoodPlayers != 0xFF;
1973
1974
if (!isStood && !player->sidekick && self->state == Platform_State_Fall && !self->timer) {
1975
#if MANIA_USE_PLUS
1976
if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)
1977
self->timer = 1;
1978
else
1979
#endif
1980
self->timer = 30;
1981
}
1982
1983
self->stoodPlayers |= 1 << playerID;
1984
1985
if (Platform->stoodPos[playerID].x) {
1986
player->position.x = Platform->stoodPos[playerID].x;
1987
player->position.y = Platform->stoodPos[playerID].y;
1988
}
1989
else {
1990
Platform->stoodPos[playerID].x = player->position.x;
1991
Platform->stoodPos[playerID].y = player->position.y;
1992
}
1993
1994
player->position.x += self->collisionOffset.x;
1995
player->position.y += self->collisionOffset.y;
1996
player->position.y &= 0xFFFF0000;
1997
}
1998
void Platform_HandleStood_Tiles(EntityPlatform *self, EntityPlayer *player, int32 playerID)
1999
{
2000
if (!player->sidekick) {
2001
self->stood = true;
2002
if (self->state == Platform_State_Fall && !self->timer) {
2003
#if MANIA_USE_PLUS
2004
if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)
2005
self->timer = 1;
2006
else
2007
#endif
2008
self->timer = 30;
2009
}
2010
}
2011
2012
self->stoodPlayers |= 1 << playerID;
2013
2014
player->position.x += self->collisionOffset.x;
2015
player->position.y += self->collisionOffset.y;
2016
player->position.y &= 0xFFFF0000;
2017
}
2018
void Platform_HandleStood_Hold(EntityPlatform *self, EntityPlayer *player, int32 playerID, int32 stoodPlayers)
2019
{
2020
if (!((1 << playerID) & stoodPlayers)) {
2021
player->state = Player_State_Static;
2022
player->nextGroundState = StateMachine_None;
2023
player->nextAirState = StateMachine_None;
2024
player->velocity.x = 0;
2025
player->velocity.y = 0;
2026
player->groundVel = 0;
2027
2028
if (self->classID == Platform->classID)
2029
RSDK.SetSpriteAnimation(player->aniFrames, ANI_TWISTER, &player->animator, false, 0);
2030
2031
player->animator.speed = 64;
2032
player->direction = FLIP_X;
2033
if (!player->sidekick) {
2034
self->stood = true;
2035
}
2036
}
2037
2038
bool32 stoodStore = self->stood;
2039
Platform_HandleStood(self, player, playerID, stoodPlayers);
2040
self->stood = stoodStore;
2041
2042
if ((player->position.x ^ self->position.x) & 0xFFFF0000) {
2043
if (player->position.x >= self->position.x)
2044
player->position.x -= TO_FIXED(1);
2045
else
2046
player->position.x += TO_FIXED(1);
2047
}
2048
2049
if (player->jumpPress)
2050
Player_Action_Jump(player);
2051
}
2052
void Platform_HandleStood_Barrel(EntityPlatform *self, EntityPlayer *player, int32 playerID, int32 stoodPlayers)
2053
{
2054
if (!((1 << playerID) & stoodPlayers)) {
2055
player->state = Player_State_Static;
2056
player->nextGroundState = StateMachine_None;
2057
player->nextAirState = StateMachine_None;
2058
player->velocity.x = 0;
2059
player->velocity.y = 0;
2060
player->groundVel = 0;
2061
2062
if (self->classID == Platform->classID)
2063
RSDK.SetSpriteAnimation(player->aniFrames, ANI_TURNTABLE, &player->animator, false, 0);
2064
2065
player->animator.speed = 64;
2066
player->direction = FLIP_NONE;
2067
}
2068
2069
Platform_HandleStood(self, player, playerID, stoodPlayers);
2070
2071
if ((player->position.x ^ self->position.x) & 0xFFFF0000) {
2072
if (player->position.x >= self->position.x)
2073
player->position.x -= TO_FIXED(1);
2074
else
2075
player->position.x += TO_FIXED(1);
2076
}
2077
2078
if (player->jumpPress)
2079
Player_Action_Jump(player);
2080
}
2081
void Platform_HandleStood_Sticky(EntityPlatform *self, EntityPlayer *player, int32 playerID, uint8 cSide)
2082
{
2083
2084
bool32 isStuck = false;
2085
if ((self->collision == PLATFORM_C_SOLID_STICKY || self->collision == PLATFORM_C_SOLID_STICKY + cSide) && cSide)
2086
isStuck = true;
2087
2088
if (player->state != Player_State_Static && isStuck) {
2089
player->state = Player_State_Static;
2090
player->nextGroundState = StateMachine_None;
2091
player->nextAirState = StateMachine_None;
2092
player->velocity.x = 0;
2093
player->velocity.y = 0;
2094
player->groundVel = 0;
2095
player->animator.speed = 0;
2096
2097
switch (cSide) {
2098
case C_TOP: player->angle = 0x00; break;
2099
2100
case C_LEFT:
2101
player->angle = 0xC0;
2102
player->onGround = false;
2103
break;
2104
2105
case C_RIGHT: player->angle = 0x40; break;
2106
2107
case C_BOTTOM: player->angle = 0x80; break;
2108
2109
default: break;
2110
}
2111
2112
player->tileCollisions = TILECOLLISION_NONE;
2113
if (!player->sidekick) {
2114
self->stood = true;
2115
if (self->state == Platform_State_Fall && !self->timer) {
2116
#if MANIA_USE_PLUS
2117
if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)
2118
self->timer = 1;
2119
else
2120
#endif
2121
self->timer = 30;
2122
}
2123
}
2124
2125
self->stoodPlayers |= 1 << playerID;
2126
}
2127
else if ((1 << playerID) & self->stoodPlayers) {
2128
if (player->state == Player_State_Static) {
2129
if (Platform->stoodPos[playerID].x) {
2130
player->position.x = Platform->stoodPos[playerID].x;
2131
player->position.y = Platform->stoodPos[playerID].y;
2132
}
2133
else {
2134
Platform->stoodPos[playerID].x = player->position.x;
2135
Platform->stoodPos[playerID].y = player->position.y;
2136
}
2137
2138
player->position.x += self->collisionOffset.x;
2139
player->position.y += self->collisionOffset.y;
2140
player->position.y &= 0xFFFF0000;
2141
2142
if (player->jumpPress) {
2143
player->tileCollisions = TILECOLLISION_DOWN;
2144
Player_Action_Jump(player);
2145
}
2146
}
2147
else {
2148
self->stoodPlayers &= ~(1 << playerID);
2149
}
2150
}
2151
else if (cSide == C_TOP) {
2152
if (Platform->stoodPos[playerID].x) {
2153
player->position.x = Platform->stoodPos[playerID].x;
2154
player->position.y = Platform->stoodPos[playerID].y;
2155
}
2156
else {
2157
Platform->stoodPos[playerID].x = player->position.x;
2158
Platform->stoodPos[playerID].y = player->position.y;
2159
}
2160
2161
player->position.x += self->collisionOffset.x;
2162
player->position.y += self->collisionOffset.y;
2163
player->position.y &= 0xFFFF0000;
2164
}
2165
}
2166
2167
#if GAME_INCLUDE_EDITOR
2168
void Platform_EditorDraw_Normal(void)
2169
{
2170
RSDK_THIS(Platform);
2171
2172
if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)
2173
RSDK.DrawRect(self->drawPos.x - TO_FIXED(32), self->drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,
2174
self->inkEffect, false);
2175
else
2176
RSDK.DrawSprite(&self->animator, &self->drawPos, false);
2177
}
2178
2179
void Platform_EditorDraw_Swinging(Vector2 amplitude)
2180
{
2181
RSDK_THIS(Platform);
2182
2183
int32 frame = self->animator.frameID;
2184
2185
int32 ang = self->angle;
2186
if (self->type == PLATFORM_CIRCULAR && self->hasTension)
2187
ang = 4 * self->angle;
2188
2189
int32 fxStore = self->drawFX;
2190
self->drawFX |= FX_FLIP | FX_ROTATE;
2191
int32 cnt = (amplitude.y >> 10) - 1;
2192
int32 angle = 0x400;
2193
self->direction = FLIP_NONE;
2194
self->animator.frameID = frame + 1;
2195
2196
int32 rot = ang >> 1;
2197
Vector2 drawPos;
2198
for (int32 i = 0; i < cnt; ++i) {
2199
drawPos.x = angle * RSDK.Cos1024(ang) + self->centerPos.x;
2200
drawPos.y = angle * RSDK.Sin1024(ang) + self->centerPos.y;
2201
if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)
2202
RSDK.DrawRect(drawPos.x - TO_FIXED(32), drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,
2203
self->inkEffect, false);
2204
else
2205
RSDK.DrawSprite(&self->animator, &drawPos, false);
2206
angle += 0x400;
2207
self->direction ^= FLIP_X;
2208
self->rotation = rot;
2209
}
2210
2211
self->drawFX = fxStore;
2212
self->animator.frameID = frame + 2;
2213
if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)
2214
RSDK.DrawRect(self->centerPos.x - TO_FIXED(32), self->centerPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,
2215
self->inkEffect, false);
2216
else
2217
RSDK.DrawSprite(&self->animator, &self->centerPos, false);
2218
2219
self->animator.frameID = frame;
2220
if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)
2221
RSDK.DrawRect(self->drawPos.x - TO_FIXED(32), self->drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,
2222
self->inkEffect, false);
2223
else
2224
RSDK.DrawSprite(&self->animator, &self->drawPos, false);
2225
}
2226
2227
void Platform_EditorDraw(void)
2228
{
2229
RSDK_THIS(Platform);
2230
2231
self->drawPos = self->position;
2232
self->centerPos = self->position;
2233
self->drawFX = FX_NONE;
2234
self->inkEffect = INK_NONE;
2235
self->alpha = 0xFF;
2236
self->direction = FLIP_NONE;
2237
2238
RSDK.SetSpriteAnimation(Platform->aniFrames, 0, &self->animator, true, 0);
2239
self->animator.frameID = self->frameID;
2240
if (self->frameID >= 0) {
2241
int32 f = self->frameID;
2242
int32 anim = 0;
2243
while (f >= self->animator.frameCount) {
2244
if (!self->animator.frameCount)
2245
break;
2246
f -= self->animator.frameCount;
2247
RSDK.SetSpriteAnimation(Platform->aniFrames, ++anim, &self->animator, true, 0);
2248
}
2249
self->animator.frameID = f;
2250
}
2251
else {
2252
RSDK.SetSpriteAnimation(-1, 0, &self->animator, true, 0);
2253
}
2254
2255
Vector2 amplitude;
2256
Vector2 drawPos;
2257
2258
amplitude.x = self->amplitude.x >> 10;
2259
amplitude.y = self->amplitude.y >> 10;
2260
2261
switch (self->type) {
2262
case PLATFORM_FIXED:
2263
default:
2264
self->updateRange.x = TO_FIXED(128);
2265
self->updateRange.y = TO_FIXED(128);
2266
2267
Platform_EditorDraw_Normal();
2268
break;
2269
2270
case PLATFORM_FALL:
2271
self->updateRange.x = TO_FIXED(128);
2272
self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;
2273
2274
Platform_EditorDraw_Normal();
2275
break;
2276
2277
case PLATFORM_LINEAR:
2278
self->updateRange.x = (abs(amplitude.x) + 0x2000) << 10;
2279
self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;
2280
2281
Platform_EditorDraw_Normal();
2282
2283
if (showGizmos() && (amplitude.x || amplitude.y)) {
2284
RSDK_DRAWING_OVERLAY(true);
2285
2286
self->inkEffect = INK_BLEND;
2287
2288
// start pos
2289
self->drawPos.x = amplitude.x * RSDK.Sin1024(self->angle) + self->centerPos.x;
2290
self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
2291
Platform_EditorDraw_Normal();
2292
2293
// right max
2294
self->drawPos.x = amplitude.x * RSDK.Sin1024(0x100) + self->centerPos.x;
2295
self->drawPos.y = amplitude.y * RSDK.Sin1024(0x100) + self->centerPos.y;
2296
drawPos = self->drawPos;
2297
Platform_EditorDraw_Normal();
2298
2299
// left max
2300
self->drawPos.x = amplitude.x * RSDK.Sin1024(0x300) + self->centerPos.x;
2301
self->drawPos.y = amplitude.y * RSDK.Sin1024(0x300) + self->centerPos.y;
2302
Platform_EditorDraw_Normal();
2303
2304
DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2305
DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2306
2307
self->inkEffect = INK_NONE;
2308
2309
RSDK_DRAWING_OVERLAY(false);
2310
}
2311
break;
2312
2313
case PLATFORM_CIRCULAR:
2314
self->updateRange.x = (abs(amplitude.x) + 0x2000) << 10;
2315
self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;
2316
2317
if (self->hasTension) {
2318
self->drawPos.x = amplitude.x * RSDK.Cos1024(4 * self->angle) + self->centerPos.x;
2319
self->drawPos.y = amplitude.y * RSDK.Sin1024(4 * self->angle) + self->centerPos.y;
2320
Platform_EditorDraw_Swinging(amplitude);
2321
}
2322
else {
2323
Platform_EditorDraw_Normal();
2324
}
2325
2326
if (showGizmos() && !self->hasTension && (amplitude.x || amplitude.y)) {
2327
RSDK_DRAWING_OVERLAY(true);
2328
2329
self->inkEffect = INK_BLEND;
2330
2331
// start pos
2332
self->drawPos.x = amplitude.x * RSDK.Cos1024(4 * self->angle) + self->centerPos.x;
2333
self->drawPos.y = amplitude.y * RSDK.Sin1024(4 * self->angle) + self->centerPos.y;
2334
Platform_EditorDraw_Normal();
2335
2336
self->inkEffect = INK_NONE;
2337
2338
RSDK_DRAWING_OVERLAY(false);
2339
}
2340
break;
2341
2342
case PLATFORM_PATH:
2343
case PLATFORM_PATH_REACT:
2344
self->updateRange.x = TO_FIXED(128);
2345
self->updateRange.y = TO_FIXED(128);
2346
2347
// PLATFORM_PATH_REACT activates control in prev slot
2348
// Note: will go back through platforms if not found
2349
// e.g. if entity is slot 3, and platform control is slot 0, with slot 1 and 2 being platform/platformNode, it'll work
2350
// if slot 1 or 2 ISNT a platform/platformNode, it will not work
2351
2352
// self->speed = starting node
2353
2354
Platform_EditorDraw_Normal();
2355
break;
2356
2357
case PLATFORM_PUSH:
2358
self->updateRange.x = TO_FIXED(128);
2359
self->updateRange.y = TO_FIXED(128);
2360
2361
Platform_EditorDraw_Normal();
2362
break;
2363
2364
case PLATFORM_REACT:
2365
case PLATFORM_HOVER_REACT:
2366
amplitude.x <<= 10;
2367
self->updateRange.x = TO_FIXED(128) + abs(amplitude.x);
2368
self->updateRange.y = TO_FIXED(128) + abs(amplitude.x);
2369
if (self->speed < 0)
2370
self->direction = FLIP_X;
2371
2372
Platform_EditorDraw_Normal();
2373
2374
if (showGizmos()) {
2375
RSDK_DRAWING_OVERLAY(true);
2376
2377
drawPos = self->drawPos;
2378
self->groundVel = 0;
2379
bool32 reachedEnd = false;
2380
uint8 type = 0;
2381
2382
while (self->speed) {
2383
if (!reachedEnd) {
2384
amplitude.y += self->groundVel;
2385
2386
self->drawPos.x = (amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
2387
self->drawPos.y = (amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
2388
2389
int32 speed16 = self->speed << 16;
2390
if (self->groundVel == speed16) {
2391
if (amplitude.y >= amplitude.x) {
2392
amplitude.y = amplitude.x;
2393
self->groundVel -= (self->speed << 11);
2394
reachedEnd = true;
2395
}
2396
}
2397
else {
2398
self->groundVel += (self->speed << 10);
2399
if (self->groundVel >= speed16) {
2400
self->groundVel = speed16;
2401
self->centerPos.x += ((amplitude.y + self->groundVel) >> 8) * RSDK.Cos256(self->angle);
2402
self->centerPos.y += ((self->groundVel + amplitude.y) >> 8) * RSDK.Sin256(self->angle);
2403
amplitude.y = -self->groundVel;
2404
}
2405
}
2406
}
2407
else {
2408
amplitude.y += self->groundVel;
2409
self->drawPos.x = (amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
2410
self->drawPos.y = (amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
2411
2412
if (self->groundVel <= 0) {
2413
if (self->hasTension) {
2414
// draw double arrow (auto returns)
2415
type = 1;
2416
}
2417
else {
2418
// draw one arrow (one way)
2419
type = 0;
2420
}
2421
break;
2422
}
2423
else {
2424
self->groundVel -= self->speed << 10;
2425
}
2426
}
2427
}
2428
2429
self->inkEffect = INK_BLEND;
2430
Platform_EditorDraw_Normal();
2431
2432
self->inkEffect = INK_NONE;
2433
DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2434
if (type)
2435
DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2436
2437
RSDK_DRAWING_OVERLAY(false);
2438
}
2439
break;
2440
2441
case PLATFORM_DOORSLIDE:
2442
amplitude.x <<= 10;
2443
self->updateRange.x = TO_FIXED(128) + abs(amplitude.x);
2444
self->updateRange.y = TO_FIXED(128) + abs(amplitude.x);
2445
2446
if (self->speed < 0)
2447
self->direction = FLIP_X;
2448
2449
Platform_EditorDraw_Normal();
2450
2451
if (showGizmos()) {
2452
RSDK_DRAWING_OVERLAY(true);
2453
2454
self->inkEffect = INK_BLEND;
2455
2456
drawPos = self->drawPos;
2457
amplitude.y = 0;
2458
while (self->speed && amplitude.x) {
2459
if (amplitude.y < amplitude.x) {
2460
amplitude.y += (abs(self->speed) << 16);
2461
if (amplitude.y >= amplitude.x) {
2462
amplitude.y = amplitude.x;
2463
break;
2464
}
2465
}
2466
2467
if (self->direction) {
2468
self->drawPos.x = (-amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
2469
self->drawPos.y = (-amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
2470
}
2471
else {
2472
self->drawPos.x = (amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;
2473
self->drawPos.y = (amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;
2474
}
2475
}
2476
2477
Platform_EditorDraw_Normal();
2478
2479
self->inkEffect = INK_NONE;
2480
2481
DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2482
DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2483
2484
RSDK_DRAWING_OVERLAY(false);
2485
}
2486
2487
break;
2488
2489
case PLATFORM_SWING_REACT:
2490
case PLATFORM_SWING: {
2491
self->timer = 0;
2492
if (self->type == PLATFORM_SWING_REACT)
2493
self->timer = 88;
2494
2495
self->updateRange.x = (abs(amplitude.y) + 0x200) << 14;
2496
self->updateRange.y = (abs(amplitude.y) + 0x200) << 14;
2497
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
2498
amplitude.y <<= 4;
2499
if (self->type != PLATFORM_SWING) {
2500
if (self->groundVel >= 0)
2501
self->drawPos.x -= TO_FIXED(32);
2502
else
2503
self->drawPos.x += TO_FIXED(32);
2504
}
2505
2506
int32 angle = self->angle;
2507
self->groundVel = 4 * self->angle;
2508
self->angle = self->groundVel + 0x100 + (self->amplitude.x * RSDK.Sin1024(0x000 + self->timer) >> 14);
2509
self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
2510
self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
2511
Platform_EditorDraw_Swinging(amplitude);
2512
2513
if (showGizmos() && (amplitude.x || amplitude.y)) {
2514
RSDK_DRAWING_OVERLAY(true);
2515
2516
if (self->type == PLATFORM_SWING) {
2517
self->inkEffect = INK_BLEND;
2518
2519
// right max
2520
self->angle = self->groundVel + 0x100 + ((amplitude.x * RSDK.Sin1024(0x100) + 0x200) >> 14);
2521
2522
self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
2523
self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
2524
drawPos = self->drawPos;
2525
Platform_EditorDraw_Swinging(amplitude);
2526
2527
// left max
2528
self->angle = self->groundVel + 0x100 + ((amplitude.x * RSDK.Sin1024(0x300) + 0x200) >> 14);
2529
self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
2530
self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
2531
Platform_EditorDraw_Swinging(amplitude);
2532
2533
self->inkEffect = INK_NONE;
2534
}
2535
2536
RSDK_DRAWING_OVERLAY(false);
2537
}
2538
self->angle = angle;
2539
break;
2540
}
2541
2542
case PLATFORM_TRACK_REACT:
2543
if (self->direction) {
2544
self->drawPos.x = self->centerPos.x + (amplitude.x << 9);
2545
self->drawPos.y = self->centerPos.y + (amplitude.y << 9);
2546
}
2547
else {
2548
self->drawPos.x = self->centerPos.x - (amplitude.x << 9);
2549
self->drawPos.y = self->centerPos.y - (amplitude.y << 9);
2550
}
2551
2552
self->updateRange.x = (abs(amplitude.x) + 0x4000) << 9;
2553
self->updateRange.y = (abs(amplitude.y) + 0x4000) << 9;
2554
if (self->speed < 0)
2555
self->direction = FLIP_X;
2556
2557
Platform_EditorDraw_Normal();
2558
if (showGizmos()) {
2559
RSDK_DRAWING_OVERLAY(true);
2560
2561
drawPos = self->drawPos;
2562
self->drawPos = self->centerPos;
2563
2564
self->inkEffect = INK_BLEND;
2565
2566
Platform_EditorDraw_Normal();
2567
2568
self->inkEffect = INK_NONE;
2569
2570
DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2571
DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2572
2573
RSDK_DRAWING_OVERLAY(false);
2574
}
2575
break;
2576
2577
case PLATFORM_TRACK:
2578
self->updateRange.x = (abs(amplitude.x) + 0x4000) << 9;
2579
self->updateRange.y = (abs(amplitude.y) + 0x4000) << 9;
2580
if (self->speed < 0)
2581
self->direction = FLIP_X;
2582
2583
Platform_EditorDraw_Normal();
2584
2585
if (showGizmos() && (amplitude.x || amplitude.y)) {
2586
RSDK_DRAWING_OVERLAY(true);
2587
2588
Vector2 storePos = self->drawPos;
2589
drawPos = self->drawPos;
2590
2591
uint8 finishDirs = 0;
2592
int8 last = -1;
2593
int32 timer = 0;
2594
while (finishDirs != 2) {
2595
int32 move = timer++ * (self->speed << 7);
2596
2597
if (((move >> 16) & 1) == self->direction) {
2598
if (last > 0)
2599
finishDirs++;
2600
2601
if (finishDirs != 2) {
2602
self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * amplitude.x >> 6) - (amplitude.x << 9);
2603
self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * amplitude.y >> 6) - (amplitude.y << 9);
2604
storePos = self->drawPos;
2605
}
2606
last = 0;
2607
}
2608
else {
2609
if (!last)
2610
finishDirs++;
2611
2612
if (finishDirs != 2) {
2613
self->drawPos.x = self->centerPos.x + (amplitude.x << 9) - ((move & 0xFFFF) * amplitude.x >> 6);
2614
self->drawPos.y = self->centerPos.y + (amplitude.y << 9) - ((move & 0xFFFF) * amplitude.y >> 6);
2615
drawPos = self->drawPos;
2616
}
2617
last = 1;
2618
}
2619
}
2620
2621
self->inkEffect = INK_BLEND;
2622
2623
self->drawPos = drawPos;
2624
Platform_EditorDraw_Normal();
2625
2626
self->drawPos = storePos;
2627
Platform_EditorDraw_Normal();
2628
2629
self->inkEffect = INK_NONE;
2630
2631
DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2632
DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2633
2634
RSDK_DRAWING_OVERLAY(false);
2635
}
2636
2637
break;
2638
2639
case PLATFORM_CLACKER: {
2640
self->updateRange.x = (abs(amplitude.y) + 0x200) << 14;
2641
self->updateRange.y = (abs(amplitude.y) + 0x200) << 14;
2642
RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);
2643
amplitude.y <<= 4;
2644
self->groundVel = 4 * self->angle;
2645
self->angle = self->groundVel + 0x100 + (amplitude.x * RSDK.Sin1024(self->hasTension ? 0x100 : 0) >> 14);
2646
self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
2647
self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
2648
2649
Platform_EditorDraw_Swinging(amplitude);
2650
2651
if (showGizmos() && (amplitude.x || amplitude.y)) {
2652
RSDK_DRAWING_OVERLAY(true);
2653
2654
self->inkEffect = INK_BLEND;
2655
2656
// max
2657
self->angle = self->groundVel + 0x100 + (amplitude.x * RSDK.Sin1024(self->hasTension ? 0 : -0x100) >> 14);
2658
self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;
2659
self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;
2660
Platform_EditorDraw_Swinging(amplitude);
2661
2662
self->inkEffect = INK_NONE;
2663
self->angle = self->groundVel / 4;
2664
2665
RSDK_DRAWING_OVERLAY(false);
2666
}
2667
break;
2668
}
2669
2670
case PLATFORM_CHILD:
2671
self->updateRange.x = TO_FIXED(128);
2672
self->updateRange.y = TO_FIXED(128);
2673
2674
Platform_EditorDraw_Normal();
2675
break;
2676
2677
case PLATFORM_DIPROCK:
2678
self->updateRange.x = TO_FIXED(128);
2679
self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;
2680
2681
Platform_EditorDraw_Normal();
2682
2683
if (showGizmos() && (amplitude.x || amplitude.y)) {
2684
RSDK_DRAWING_OVERLAY(true);
2685
2686
self->inkEffect = INK_BLEND;
2687
2688
// max
2689
self->drawPos.y += amplitude.y;
2690
Platform_EditorDraw_Normal();
2691
2692
DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y - amplitude.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);
2693
2694
self->inkEffect = INK_NONE;
2695
2696
RSDK_DRAWING_OVERLAY(false);
2697
}
2698
break;
2699
}
2700
2701
if (showGizmos()) {
2702
RSDK_DRAWING_OVERLAY(true);
2703
2704
for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < self->childCount; ++i) {
2705
Entity *child = RSDK_GET_ENTITY_GEN(s + i);
2706
if (!child)
2707
continue;
2708
2709
DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xE0E0E0, INK_NONE, 0xFF);
2710
}
2711
2712
RSDK_DRAWING_OVERLAY(false);
2713
}
2714
}
2715
2716
void Platform_EditorLoad(void)
2717
{
2718
Platform_StageLoad();
2719
2720
RSDK_ACTIVE_VAR(Platform, type);
2721
RSDK_ENUM_VAR("Fixed", PLATFORM_FIXED);
2722
RSDK_ENUM_VAR("Fall", PLATFORM_FALL);
2723
RSDK_ENUM_VAR("Linear", PLATFORM_LINEAR);
2724
RSDK_ENUM_VAR("Circlular", PLATFORM_CIRCULAR);
2725
RSDK_ENUM_VAR("Swing", PLATFORM_SWING);
2726
RSDK_ENUM_VAR("Path", PLATFORM_PATH);
2727
RSDK_ENUM_VAR("Push", PLATFORM_PUSH);
2728
RSDK_ENUM_VAR("Track", PLATFORM_TRACK);
2729
RSDK_ENUM_VAR("React", PLATFORM_REACT);
2730
RSDK_ENUM_VAR("Hover-React", PLATFORM_HOVER_REACT);
2731
RSDK_ENUM_VAR("Door Slide", PLATFORM_DOORSLIDE);
2732
RSDK_ENUM_VAR("Path-React", PLATFORM_PATH_REACT);
2733
RSDK_ENUM_VAR("Swing-React", PLATFORM_SWING_REACT);
2734
RSDK_ENUM_VAR("Track-React", PLATFORM_TRACK_REACT);
2735
RSDK_ENUM_VAR("Clacker", PLATFORM_CLACKER);
2736
RSDK_ENUM_VAR("Child", PLATFORM_CHILD);
2737
RSDK_ENUM_VAR("Dip Rock", PLATFORM_DIPROCK);
2738
2739
RSDK_ACTIVE_VAR(Platform, collision);
2740
RSDK_ENUM_VAR("Platform", PLATFORM_C_PLATFORM);
2741
RSDK_ENUM_VAR("Solid", PLATFORM_C_SOLID);
2742
RSDK_ENUM_VAR("Tiled", PLATFORM_C_TILED);
2743
RSDK_ENUM_VAR("Hurt", PLATFORM_C_HURT);
2744
RSDK_ENUM_VAR("None", PLATFORM_C_NONE);
2745
RSDK_ENUM_VAR("Solid Hurt Sides", PLATFORM_C_SOLID_HURT_SIDES);
2746
RSDK_ENUM_VAR("Solid Hurt Bottom", PLATFORM_C_SOLID_HURT_BOTTOM);
2747
RSDK_ENUM_VAR("Solid Hurt Top", PLATFORM_C_SOLID_HURT_TOP);
2748
RSDK_ENUM_VAR("Solid Hold", PLATFORM_C_SOLID_HOLD);
2749
RSDK_ENUM_VAR("Solid Sticky", PLATFORM_C_SOLID_STICKY);
2750
RSDK_ENUM_VAR("Sticky Top", PLATFORM_C_STICKY_TOP);
2751
RSDK_ENUM_VAR("Sticky Left", PLATFORM_C_STICKY_LEFT);
2752
RSDK_ENUM_VAR("Sticky Right", PLATFORM_C_STICKY_RIGHT);
2753
RSDK_ENUM_VAR("Sticky Bottom", PLATFORM_C_STICKY_BOTTOM);
2754
RSDK_ENUM_VAR("Solid Barrel", PLATFORM_C_SOLID_BARREL);
2755
RSDK_ENUM_VAR("Solid No Crush", PLATFORM_C_SOLID_NOCRUSH);
2756
}
2757
#endif
2758
2759
void Platform_Serialize(void)
2760
{
2761
RSDK_EDITABLE_VAR(Platform, VAR_ENUM, type);
2762
RSDK_EDITABLE_VAR(Platform, VAR_VECTOR2, amplitude);
2763
RSDK_EDITABLE_VAR(Platform, VAR_ENUM, speed);
2764
RSDK_EDITABLE_VAR(Platform, VAR_BOOL, hasTension);
2765
RSDK_EDITABLE_VAR(Platform, VAR_INT8, frameID);
2766
RSDK_EDITABLE_VAR(Platform, VAR_UINT8, collision);
2767
RSDK_EDITABLE_VAR(Platform, VAR_VECTOR2, tileOrigin);
2768
RSDK_EDITABLE_VAR(Platform, VAR_ENUM, childCount);
2769
RSDK_EDITABLE_VAR(Platform, VAR_INT32, angle);
2770
}
2771
2772