Path: blob/master/SonicMania/Objects/Common/Platform.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Platform Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPlatform *Platform;1011void Platform_Update(void)12{13RSDK_THIS(Platform);1415#if MANIA_USE_PLUS16if (Zone->teleportActionActive) {17self->pushPlayersL = false;18self->pushPlayersR = false;19}20#endif2122self->position.x = self->drawPos.x & 0xFFFF0000;23self->position.y = self->drawPos.y & 0xFFFF0000;2425if (self->hasTension) {26if (self->stood && self->stoodAngle < 64)27self->stoodAngle += 4;28else if (!self->stood && self->stoodAngle > 0)29self->stoodAngle -= 4;30}3132self->collisionOffset.x = -self->position.x;33self->collisionOffset.y = -self->position.y;3435StateMachine_Run(self->state);3637if (self->classID) {38self->stood = false;39self->collisionOffset.x += self->drawPos.x & 0xFFFF0000;40self->collisionOffset.y += self->drawPos.y & 0xFFFF0000;41if (self->state != Platform_State_Falling2 && self->state != Platform_State_Hold) {42StateMachine_Run(self->stateCollide);43}4445self->position.x = self->centerPos.x;46self->position.y = self->centerPos.y;47for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < self->childCount; ++i) {48Entity *child = RSDK_GET_ENTITY_GEN(s++);49if (child->classID == ItemBox->classID) {50if (!child->scale.y) {51EntityItemBox *itemBox = (EntityItemBox *)child;52#if MANIA_USE_PLUS53itemBox->parent = (Entity *)self;54#else55itemBox->groundVel = RSDK.GetEntitySlot(self);56#endif57itemBox->scale.x = itemBox->position.x - self->centerPos.x;58itemBox->scale.y = itemBox->position.y - self->centerPos.y;59itemBox->position.x = itemBox->scale.x + self->drawPos.x;60itemBox->position.y = itemBox->scale.y + self->drawPos.y;61itemBox->updateRange.x = self->updateRange.x;62itemBox->updateRange.y = self->updateRange.y;63}64}65else {66child->position.x += self->collisionOffset.x;67child->position.y += self->collisionOffset.y;6869if (child->classID == Spikes->classID) {70EntitySpikes *spikes = (EntitySpikes *)child;71spikes->collisionOffset.x = self->collisionOffset.x;72spikes->collisionOffset.y = self->collisionOffset.y;73}74else if (child->classID == Platform->classID) {75EntityPlatform *platform = (EntityPlatform *)child;76platform->centerPos.x += self->collisionOffset.x;77platform->centerPos.y += self->collisionOffset.y;78}79else if (Ice && child->classID == Ice->classID) {80EntityIce *ice = (EntityIce *)child;81ice->playerMoveOffset = self->collisionOffset;82}83else if (TurboTurtle && child->classID == TurboTurtle->classID) {84EntityTurboTurtle *turboTurtle = (EntityTurboTurtle *)child;85turboTurtle->startPos.x += self->collisionOffset.x;86turboTurtle->startPos.y += self->collisionOffset.y;87}88}89}9091if (self->animator.frameDuration)92RSDK.ProcessAnimation(&self->animator);93}94}9596void Platform_LateUpdate(void) {}9798void Platform_StaticUpdate(void)99{100for (int32 i = 0; i < PLAYER_COUNT; ++i) {101Platform->stoodPos[i].x = 0;102Platform->stoodPos[i].y = 0;103}104}105106void Platform_Draw(void)107{108RSDK_THIS(Platform);109Vector2 drawPos;110111if (self->frameID >= 0) {112if ((self->state == Platform_State_Circular && self->hasTension)113|| (self->state == Platform_State_Swing || self->state == Platform_State_Clacker || self->type == PLATFORM_SWING_REACT)) {114int32 ang = self->angle;115if (self->state == Platform_State_Circular && self->hasTension)116ang = self->speed * Zone->timer + 4 * self->angle;117118int32 fxStore = self->drawFX;119self->drawFX |= FX_FLIP | FX_ROTATE;120int32 cnt = (self->amplitude.y >> 10) - 1;121int32 angle = 0x400;122self->direction = FLIP_NONE;123self->animator.frameID = self->frameID + 1;124125int32 rot = ang >> 1;126for (int32 i = 0; i < cnt; ++i) {127drawPos.x = angle * RSDK.Cos1024(ang) + self->centerPos.x;128drawPos.y = angle * RSDK.Sin1024(ang) + self->centerPos.y;129RSDK.DrawSprite(&self->animator, &drawPos, false);130angle += 0x400;131self->direction ^= FLIP_X;132self->rotation = rot;133}134135self->drawFX = fxStore;136self->animator.frameID = self->frameID + 2;137RSDK.DrawSprite(&self->animator, &self->centerPos, false);138139self->animator.frameID = self->frameID;140}141142if (Platform->aniFrames == (uint16)-1)143RSDK.DrawRect(self->drawPos.x - TO_FIXED(32), self->drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, 255, INK_NONE, false);144else145RSDK.DrawSprite(&self->animator, &self->drawPos, false);146}147}148149void Platform_Create(void *data)150{151RSDK_THIS(Platform);152153self->amplitude.x >>= 10;154self->amplitude.y >>= 10;155self->active = ACTIVE_BOUNDS;156self->visible = true;157self->drawGroup = Zone->objectDrawGroup[0] + 1;158self->centerPos = self->position;159self->drawPos = self->position;160RSDK.SetSpriteAnimation(Platform->aniFrames, 0, &self->animator, true, 0);161self->animator.frameID = self->frameID;162163if (!SceneInfo->inEditor && RSDK.GetFrameID(&self->animator) == 'l')164self->drawGroup = Zone->objectDrawGroup[0];165166switch (self->type) {167default:168case PLATFORM_FIXED:169self->state = Platform_State_Fixed;170self->updateRange.x = TO_FIXED(128);171self->updateRange.y = TO_FIXED(128);172break;173174case PLATFORM_FALL:175self->state = Platform_State_Fall;176self->updateRange.x = TO_FIXED(128);177self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;178break;179180case PLATFORM_LINEAR:181self->state = Platform_State_Linear;182self->updateRange.x = (abs(self->amplitude.x) + 0x2000) << 10;183self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;184self->rotation = self->angle;185self->angle = 0;186break;187188case PLATFORM_CIRCULAR:189self->updateRange.x = (abs(self->amplitude.x) + 0x2000) << 10;190self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;191self->state = Platform_State_Circular;192break;193194case PLATFORM_PATH:195case PLATFORM_PATH_REACT:196self->active = ACTIVE_BOUNDS;197if (self->type == PLATFORM_PATH)198self->state = Platform_State_PathStop;199else200self->state = Platform_State_PathReact;201self->updateRange.x = TO_FIXED(128);202self->updateRange.y = TO_FIXED(128);203break;204205case PLATFORM_PUSH:206self->updateRange.x = TO_FIXED(128);207self->updateRange.y = TO_FIXED(128);208if (!SceneInfo->inEditor) {209self->speed <<= 11;210self->position.x += 0x8000;211}212self->state = Platform_State_Push_Init;213break;214215case PLATFORM_REACT:216self->amplitude.x <<= 10;217self->updateRange.x = TO_FIXED(128) + abs(self->amplitude.x);218self->updateRange.y = TO_FIXED(128) + abs(self->amplitude.x);219if (self->speed < 0)220self->direction = FLIP_X;221self->state = Platform_State_React;222break;223224case PLATFORM_HOVER_REACT:225self->amplitude.x <<= 10;226self->updateRange.x = TO_FIXED(128) + abs(self->amplitude.x);227self->updateRange.y = TO_FIXED(128) + abs(self->amplitude.x);228if (self->speed < 0)229self->direction = FLIP_X;230self->state = Platform_State_Hover_React;231break;232233case PLATFORM_DOORSLIDE:234self->amplitude.x <<= 10;235self->updateRange.x = TO_FIXED(128) + abs(self->amplitude.x);236self->updateRange.y = TO_FIXED(128) + abs(self->amplitude.x);237238if (self->speed < 0) {239self->direction = FLIP_X;240self->speed = -self->speed;241}242self->state = Platform_State_DoorSlide;243break;244245case PLATFORM_SWING_REACT:246self->timer = 88;247// [Fallthrough]248case PLATFORM_SWING:249self->updateRange.x = (abs(self->amplitude.y) + 0x200) << 14;250self->updateRange.y = (abs(self->amplitude.y) + 0x200) << 14;251RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);252253self->amplitude.y <<= 4;254self->groundVel = 4 * self->angle;255self->angle = self->groundVel + 0x100 + (self->amplitude.x * RSDK.Sin1024(self->speed * self->timer) >> 14);256self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;257self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;258if (self->type == PLATFORM_SWING) {259self->state = Platform_State_Swing;260}261else {262if (self->groundVel >= 0)263self->drawPos.x -= TO_FIXED(32);264else265self->drawPos.x += TO_FIXED(32);266self->state = Platform_State_SwingReact;267}268break;269270case PLATFORM_TRACK_REACT:271if (self->direction) {272self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9);273self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9);274}275else {276self->drawPos.x = self->centerPos.x - (self->amplitude.x << 9);277self->drawPos.y = self->centerPos.y - (self->amplitude.y << 9);278}279// [Fallthrough]280case PLATFORM_TRACK:281self->updateRange.x = (abs(self->amplitude.x) + 0x4000) << 9;282self->updateRange.y = (abs(self->amplitude.y) + 0x4000) << 9;283if (self->speed < 0)284self->direction = FLIP_X;285286if (self->type == PLATFORM_TRACK)287self->state = Platform_State_Track;288else289self->state = Platform_State_TrackReact;290break;291292case PLATFORM_CLACKER:293self->updateRange.x = (abs(self->amplitude.y) + 0x200) << 14;294self->updateRange.y = (abs(self->amplitude.y) + 0x200) << 14;295RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);296self->amplitude.y <<= 4;297self->groundVel = 4 * self->angle;298self->angle = self->groundVel + 0x100 + (self->amplitude.x * RSDK.Sin1024(self->speed * self->timer) >> 14);299self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;300self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;301self->state = Platform_State_Clacker;302break;303304case PLATFORM_CHILD:305self->state = Platform_State_Child;306self->updateRange.x = TO_FIXED(128);307self->updateRange.y = TO_FIXED(128);308break;309310case PLATFORM_DIPROCK:311self->updateRange.x = TO_FIXED(128);312self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 10;313if (!self->speed)314self->speed = 1;315self->amplitude.y = self->amplitude.y << 10;316self->velocity.y = self->speed << 16;317self->state = Platform_State_DipRock;318break;319}320321if (self->frameID >= 0) {322int32 f = self->frameID;323int32 anim = 0;324while (f >= self->animator.frameCount) {325if (!self->animator.frameCount)326break;327f -= self->animator.frameCount;328RSDK.SetSpriteAnimation(Platform->aniFrames, ++anim, &self->animator, true, 0);329}330self->frameID = f;331self->animator.frameID = f;332}333else {334RSDK.SetSpriteAnimation(-1, 0, &self->animator, true, 0);335}336337if (!SceneInfo->inEditor) {338if (self->collision != PLATFORM_C_NONE) {339Hitbox *hitbox = RSDK.GetHitbox(&self->animator, self->collision != PLATFORM_C_PLATFORM);340if (Platform->aniFrames != (uint16)-1 && hitbox) {341self->hitbox.left = hitbox->left;342self->hitbox.top = hitbox->top;343self->hitbox.right = hitbox->right;344self->hitbox.bottom = hitbox->bottom;345}346else {347self->hitbox.left = -32;348self->hitbox.top = -16;349self->hitbox.right = -8;350self->hitbox.bottom = 32;351}352}353354switch (self->collision) {355case PLATFORM_C_PLATFORM:356self->stateCollide = Platform_Collision_Platform;357self->hitbox.bottom = self->hitbox.top + 8;358break;359360default:361case PLATFORM_C_SOLID: self->stateCollide = Platform_Collision_Solid; break;362363case PLATFORM_C_TILED: self->stateCollide = Platform_Collision_Tiles; break;364case PLATFORM_C_HURT: self->stateCollide = Platform_Collision_Hurt; break;365case PLATFORM_C_NONE: self->stateCollide = Platform_Collision_None; break;366case PLATFORM_C_SOLID_HURT_SIDES: self->stateCollide = Platform_Collision_Solid_Hurt_Sides; break;367case PLATFORM_C_SOLID_HURT_BOTTOM: self->stateCollide = Platform_Collision_Solid_Hurt_Bottom; break;368case PLATFORM_C_SOLID_HURT_TOP: self->stateCollide = Platform_Collision_Solid_Hurt_Top; break;369case PLATFORM_C_SOLID_HOLD: self->stateCollide = Platform_Collision_Solid_Hold; break;370371case PLATFORM_C_SOLID_STICKY:372case PLATFORM_C_STICKY_TOP:373case PLATFORM_C_STICKY_LEFT:374case PLATFORM_C_STICKY_RIGHT:375case PLATFORM_C_STICKY_BOTTOM: self->stateCollide = Platform_Collision_Sticky; break;376377case PLATFORM_C_SOLID_BARREL: self->stateCollide = Platform_Collision_Solid_Barrel; break;378case PLATFORM_C_SOLID_NOCRUSH: self->stateCollide = Platform_Collision_Solid_NoCrush; break;379}380381for (int32 i = 0; i < self->childCount; ++i) {382EntityPlatform *child = RSDK_GET_ENTITY((i + RSDK.GetEntitySlot(self) + 1), Platform);383child->tileCollisions = TILECOLLISION_NONE;384if (HangPoint && child->classID == HangPoint->classID) {385EntityHangPoint *hang = (EntityHangPoint *)child;386if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - (hang->length << 16) - hang->position.y))387self->updateRange.y = TO_FIXED(128) + abs(self->position.y - (hang->length << 16) - hang->position.y);388}389else {390if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - child->position.y))391self->updateRange.y = TO_FIXED(128) + abs(self->position.y - child->position.y);392}393}394}395}396397void Platform_StageLoad(void)398{399Platform->useClack = false;400if (RSDK.CheckSceneFolder("GHZ")) {401Platform->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Platform.bin", SCOPE_STAGE);402}403else if (RSDK.CheckSceneFolder("GHZCutscene")) {404Platform->aniFrames = RSDK.LoadSpriteAnimation("GHZCutscene/Platform.bin", SCOPE_STAGE);405}406else if (RSDK.CheckSceneFolder("CPZ")) {407Platform->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Platform.bin", SCOPE_STAGE);408}409else if (RSDK.CheckSceneFolder("SPZ1")) {410Platform->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Platform.bin", SCOPE_STAGE);411}412else if (RSDK.CheckSceneFolder("SPZ2")) {413Platform->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/Platform.bin", SCOPE_STAGE);414}415else if (RSDK.CheckSceneFolder("FBZ")) {416Platform->aniFrames = RSDK.LoadSpriteAnimation("FBZ/Platform.bin", SCOPE_STAGE);417Platform->sfxClack = RSDK.GetSfx("Stage/Clack2.wav");418Platform->useClack = true;419}420else if (RSDK.CheckSceneFolder("PSZ1")) {421Platform->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Platform.bin", SCOPE_STAGE);422}423else if (RSDK.CheckSceneFolder("PSZ2")) {424Platform->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/Platform.bin", SCOPE_STAGE);425}426else if (RSDK.CheckSceneFolder("SSZ1")) {427Platform->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/Platform.bin", SCOPE_STAGE);428}429else if (RSDK.CheckSceneFolder("SSZ2")) {430Platform->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/Platform.bin", SCOPE_STAGE);431}432else if (RSDK.CheckSceneFolder("HCZ")) {433Platform->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Platform.bin", SCOPE_STAGE);434Platform->sfxClack = RSDK.GetSfx("Stage/Clack2.wav");435Platform->useClack = true;436}437else if (RSDK.CheckSceneFolder("MSZ")) {438Platform->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Platform.bin", SCOPE_STAGE);439}440else if (RSDK.CheckSceneFolder("OOZ1") || RSDK.CheckSceneFolder("OOZ2")) {441Platform->aniFrames = RSDK.LoadSpriteAnimation("OOZ/Platform.bin", SCOPE_STAGE);442}443else if (RSDK.CheckSceneFolder("LRZ1")) {444Platform->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Platform.bin", SCOPE_STAGE);445}446else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3")) {447Platform->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/Platform.bin", SCOPE_STAGE);448}449else if (RSDK.CheckSceneFolder("MMZ")) {450Platform->aniFrames = RSDK.LoadSpriteAnimation("MMZ/Platform.bin", SCOPE_STAGE);451}452else if (RSDK.CheckSceneFolder("TMZ1") || RSDK.CheckSceneFolder("TMZ2")) {453Platform->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/Platform.bin", SCOPE_STAGE);454}455else if (RSDK.CheckSceneFolder("AIZ")) {456Platform->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Platform.bin", SCOPE_STAGE);457}458else if (RSDK.CheckSceneFolder("SBZ")) { // SBZ once was a planned zone?459Platform->aniFrames = RSDK.LoadSpriteAnimation("SBZ/Platform.bin", SCOPE_STAGE);460}461else if (RSDK.CheckSceneFolder("Blueprint")) {462Platform->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/Platform.bin", SCOPE_STAGE);463}464465Platform->sfxClacker = RSDK.GetSfx("Stage/Clacker.wav");466Platform->sfxClang = RSDK.GetSfx("Stage/Clang.wav");467Platform->sfxPush = RSDK.GetSfx("Global/Push.wav");468469if (Platform->playingPushSfx) {470RSDK.StopSfx(Platform->sfxPush);471Platform->playingPushSfx = false;472}473}474475void Platform_State_PathStop(void)476{477RSDK_THIS(Platform);478479self->velocity.x = 0;480self->velocity.y = 0;481}482483void Platform_State_Fixed(void)484{485RSDK_THIS(Platform);486487self->drawPos.x = self->centerPos.x;488self->drawPos.y = self->centerPos.y;489self->drawPos.y += RSDK.Sin256(self->stoodAngle) << 10;490491self->velocity.x = 0;492self->velocity.y = 0;493}494495void Platform_State_Linear(void)496{497RSDK_THIS(Platform);498499int32 drawX = -self->drawPos.x;500int32 drawY = -self->drawPos.y;501502self->drawPos.x = self->amplitude.x * RSDK.Sin1024(self->speed * (self->rotation + Zone->timer)) + self->centerPos.x;503self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->speed * (self->rotation + Zone->timer)) + self->centerPos.y;504self->drawPos.y += RSDK.Sin256(self->stoodAngle) << 10;505506self->velocity.x = self->drawPos.x + drawX;507self->velocity.y = self->drawPos.y + drawY;508}509510void Platform_State_Swing(void)511{512RSDK_THIS(Platform);513514int32 drawX = -self->drawPos.x;515int32 drawY = -self->drawPos.y;516517self->angle = self->groundVel + 0x100 + ((self->amplitude.x * RSDK.Sin1024(self->speed * Zone->timer) + 0x200) >> 14);518self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;519self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;520521self->velocity.x = self->drawPos.x + drawX;522self->velocity.y = self->drawPos.y + drawY;523}524525void Platform_State_React(void)526{527RSDK_THIS(Platform);528529if (self->stood) {530if (self->hasTension)531self->timer = 120;532self->rotation = 0;533self->tileOrigin.x = 0;534self->tileOrigin.y = 0;535self->active = ACTIVE_NORMAL;536self->state = Platform_State_ReactMove;537}538539self->velocity.y = 0;540self->velocity.x = 0;541}542543void Platform_State_Hover_React(void)544{545RSDK_THIS(Platform);546547self->rotation += 4;548self->drawPos.y = self->centerPos.y + (RSDK.Sin1024(self->rotation) << 9);549if (self->stood) {550if (self->hasTension)551self->timer = 120;552self->tileOrigin.x = self->drawPos.x - self->centerPos.x;553self->centerPos.x = self->drawPos.x;554self->tileOrigin.y = RSDK.Sin1024(self->rotation) << 9;555self->centerPos.y = self->drawPos.y;556self->active = ACTIVE_NORMAL;557self->state = Platform_State_ReactMove;558}559560self->velocity.y = 0;561self->velocity.x = 0;562}563564void Platform_State_Push_Init(void)565{566RSDK_THIS(Platform);567568self->active = ACTIVE_NORMAL;569self->updateRange.x = TO_FIXED(512);570self->updateRange.y = TO_FIXED(512);571self->state = Platform_State_Push;572self->velocity.x = 0;573self->velocity.y = 0;574}575576void Platform_State_Falling(void)577{578RSDK_THIS(Platform);579580if (--self->timer <= 0) {581self->timer = 0;582self->state = Platform_State_Falling2;583foreach_active(Player, player)584{585if ((1 << RSDK.GetEntitySlot(player)) & self->stoodPlayers)586player->velocity.y = self->velocity.y - TO_FIXED(1);587}588}589590self->drawPos.y += self->velocity.y;591self->velocity.y += 0x3800;592self->velocity.x = 0;593}594595void Platform_State_DoorSlide(void)596{597RSDK_THIS(Platform);598599int32 drawX = -self->drawPos.x;600int32 drawY = -self->drawPos.y;601602bool32 activated = false;603foreach_active(Player, player)604{605if (!player->sidekick) {606Vector2 pivotPos = player->position;607Zone_RotateOnPivot(&pivotPos, &self->centerPos, ((self->angle & 0xFF) + 0x80) & 0xFF);608609if (abs(player->position.x - self->centerPos.x) <= TO_FIXED(1024)) {610if (abs(player->position.y - self->centerPos.y) <= TO_FIXED(1024)) {611if (pivotPos.y < self->centerPos.y && self->centerPos.y - pivotPos.y < TO_FIXED(256))612activated = true;613}614}615}616}617618if (!activated) {619if (self->amplitude.y > 0) {620self->amplitude.y -= (self->speed << 16);621if (self->amplitude.y <= 0) {622self->amplitude.y = 0;623if (self->onScreen && Platform->useClack)624RSDK.PlaySfx(Platform->sfxClack, false, 0xFF);625}626}627}628else {629if (self->amplitude.y < self->amplitude.x) {630self->amplitude.y += (self->speed << 16);631if (self->amplitude.y >= self->amplitude.x) {632self->amplitude.y = self->amplitude.x;633if (self->onScreen && Platform->useClack)634RSDK.PlaySfx(Platform->sfxClack, false, 0xFF);635}636}637}638639if (self->direction) {640self->drawPos.x = (-self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;641self->drawPos.y = (-self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;642}643else {644self->drawPos.x = (self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;645self->drawPos.y = (self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;646}647648self->velocity.x = self->drawPos.x + drawX;649self->velocity.y = self->drawPos.y + drawY;650}651652void Platform_State_ReactMove(void)653{654RSDK_THIS(Platform);655656int32 drawX = -self->drawPos.x;657int32 drawY = -self->drawPos.y;658self->amplitude.y += self->groundVel;659660self->drawPos.x = (self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;661self->drawPos.y = (self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;662663int32 speed16 = self->speed << 16;664if (self->groundVel == speed16) {665if (self->amplitude.y >= self->amplitude.x) {666self->amplitude.y = self->amplitude.x;667self->groundVel = self->groundVel - (self->speed << 11);668self->state = Platform_State_ReactSlow;669}670}671else {672self->groundVel += (self->speed << 10);673if (self->groundVel >= speed16) {674self->groundVel = speed16;675self->centerPos.x += ((self->amplitude.y + self->groundVel) >> 8) * RSDK.Cos256(self->angle);676self->centerPos.y += ((self->groundVel + self->amplitude.y) >> 8) * RSDK.Sin256(self->angle);677self->amplitude.y = -self->groundVel;678}679}680681self->velocity.x = self->drawPos.x + drawX;682self->velocity.y = self->drawPos.y + drawY;683}684685void Platform_State_Push(void)686{687RSDK_THIS(Platform);688689self->velocity.x = 0;690self->velocity.y = 0;691692foreach_active(Player, playerLoop)693{694uint8 id = 1 << RSDK.GetEntitySlot(playerLoop);695if (id & self->pushPlayersL)696self->velocity.x += self->speed;697if (id & self->pushPlayersR)698self->velocity.x -= self->speed;699}700701if (self->velocity.x > 0 || self->velocity.x < 0) {702if (!Platform->playingPushSfx) {703RSDK.PlaySfx(Platform->sfxPush, true, 255);704Platform->playingPushSfx = true;705}706}707708if (self->velocity.x) {709if (self->timer > 0) {710self->timer--;711self->velocity.x = 0;712}713}714else {715if (Platform->playingPushSfx) {716RSDK.StopSfx(Platform->sfxPush);717Platform->playingPushSfx = false;718}719if (self->timer < 4) {720self->timer++;721}722}723724self->drawPos.x += self->velocity.x;725self->position.x = self->drawPos.x;726self->position.y = self->drawPos.y;727foreach_active(Player, player)728{729Hitbox *playerHitbox = Player_GetHitbox(player);730int32 bitID = 1 << RSDK.GetEntitySlot(player);731if (bitID & self->pushPlayersL)732player->position.x = self->drawPos.x + ((self->hitbox.left - playerHitbox->right) << 16);733if (bitID & self->pushPlayersR)734player->position.x = self->drawPos.x + ((self->hitbox.right - playerHitbox->left - 1) << 16);735}736737bool32 collided =738RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.left + 16), TO_FIXED(self->hitbox.bottom), 4);739int32 y = self->position.y;740741collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(0), TO_FIXED(self->hitbox.bottom), 4);742if (self->position.y < y)743y = self->position.y;744745collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.right - 16), TO_FIXED(self->hitbox.bottom), 4);746if (self->position.y < y)747y = self->position.y;748749self->position.y = y;750self->drawPos.y = y;751752if (!collided) {753self->velocity.x <<= 1;754if (!self->velocity.x) {755self->state = Platform_State_Push_Fall;756}757else {758if (self->velocity.x > 0)759self->state = Platform_State_Push_SlideOffL;760else761self->state = Platform_State_Push_SlideOffR;762}763}764765RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, TO_FIXED(self->hitbox.left), TO_FIXED(self->hitbox.bottom - 8), true);766RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, TO_FIXED(self->hitbox.right), TO_FIXED(self->hitbox.bottom - 8), true);767RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, TO_FIXED(self->hitbox.left), TO_FIXED(self->hitbox.top + 8), true);768RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, TO_FIXED(self->hitbox.right), TO_FIXED(self->hitbox.top + 8), true);769770self->drawPos.x = self->position.x;771self->drawPos.y = self->position.y;772if (!RSDK.CheckOnScreen(self, &self->updateRange)) {773self->speed >>= 11;774self->drawPos.x = self->centerPos.x;775self->drawPos.y = self->centerPos.y;776self->velocity.x = 0;777self->velocity.y = 0;778self->visible = false;779if (Platform->playingPushSfx) {780RSDK.StopSfx(Platform->sfxPush);781Platform->playingPushSfx = false;782}783self->state = Platform_State_Hold;784}785}786787void Platform_State_Hold(void)788{789RSDK_THIS(Platform);790791if (!RSDK.CheckOnScreen(self, &self->updateRange))792Platform_Create(NULL);793794self->velocity.y = 0;795self->velocity.x = 0;796}797798void Platform_State_Track(void)799{800RSDK_THIS(Platform);801802int32 drawX = -self->drawPos.x;803int32 drawY = -self->drawPos.y;804int32 move = Zone->timer * (self->speed << 7);805806if (((move >> 16) & 1) == self->direction) {807self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * self->amplitude.x >> 6) - (self->amplitude.x << 9);808self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * self->amplitude.y >> 6) - (self->amplitude.y << 9);809}810else {811self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9) - ((move & 0xFFFF) * self->amplitude.x >> 6);812self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9) - ((move & 0xFFFF) * self->amplitude.y >> 6);813}814815if (((move >> 16) & 1) != self->hasTension) {816if (self->onScreen)817RSDK.PlaySfx(Platform->sfxClang, false, 255);818819self->hasTension = (move >> 16) & 1;820}821822self->velocity.x = self->drawPos.x + drawX;823self->velocity.y = self->drawPos.y + drawY;824}825826void Platform_State_Falling2(void)827{828RSDK_THIS(Platform);829830self->drawPos.y += self->velocity.y;831self->velocity.y += 0x3800;832833self->position.x = self->drawPos.x;834self->position.y = self->drawPos.y;835836if (RSDK.CheckOnScreen(self, &self->updateRange)) {837self->position.x = self->centerPos.x;838self->position.y = self->centerPos.y;839self->velocity.x = 0;840}841else {842if (self->amplitude.x) {843destroyEntity(self);844}845else {846self->drawPos.x = self->centerPos.x;847self->drawPos.y = self->centerPos.y;848self->velocity.y = 0;849self->visible = false;850self->state = Platform_State_Hold;851}852853self->velocity.x = 0;854}855}856857void Platform_State_Fall(void)858{859RSDK_THIS(Platform);860861if (self->timer) {862if (!--self->timer) {863self->active = ACTIVE_NORMAL;864self->state = Platform_State_Falling;865self->timer = 30;866}867}868869self->drawPos.x = self->centerPos.x;870self->drawPos.y = self->centerPos.y;871self->drawPos.y += RSDK.Sin256(self->stoodAngle) << 10;872873self->velocity.x = 0;874}875876void Platform_State_Circular(void)877{878RSDK_THIS(Platform);879880int32 drawX = -self->drawPos.x;881int32 drawY = -self->drawPos.y;882883self->drawPos.x = self->amplitude.x * RSDK.Cos1024(self->speed * Zone->timer + 4 * self->angle) + self->centerPos.x;884self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->speed * Zone->timer + 4 * self->angle) + self->centerPos.y;885886self->velocity.x = self->drawPos.x + drawX;887self->velocity.y = self->drawPos.y + drawY;888}889890void Platform_State_SwingReact(void)891{892RSDK_THIS(Platform);893894self->velocity.x = 0;895self->velocity.y = 0;896897if (self->stood)898self->state = Platform_State_Swing2;899}900901void Platform_State_TrackReact(void)902{903RSDK_THIS(Platform);904905self->velocity.x = 0;906self->velocity.y = 0;907908if (self->stood)909self->state = Platform_State_Track2;910}911912void Platform_State_Clacker(void)913{914RSDK_THIS(Platform);915916int32 drawX = -self->drawPos.x;917int32 drawY = -self->drawPos.y;918919int32 prevAngle = self->angle;920int32 maxAngle = self->groundVel + 0x100;921self->angle = self->groundVel + ((self->amplitude.x * RSDK.Sin1024(self->speed * Zone->timer) + 0x200) >> 14) + 0x100;922923if (!self->hasTension) {924if (self->angle >= maxAngle) {925if (!self->onScreen || prevAngle >= maxAngle) {926self->angle = self->groundVel + 0x100;927}928else {929RSDK.PlaySfx(Platform->sfxClacker, false, 255);930self->angle = self->groundVel + 0x100;931}932}933}934else if (self->angle <= maxAngle) {935if (!self->onScreen || prevAngle <= maxAngle) {936self->angle = self->groundVel + 0x100;937}938else {939RSDK.PlaySfx(Platform->sfxClacker, false, 255);940self->angle = self->groundVel + 0x100;941}942}943944self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;945self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;946self->velocity.x = self->drawPos.x + drawX;947self->velocity.y = self->drawPos.y + drawY;948}949950void Platform_State_Child(void)951{952RSDK_THIS(Platform);953954int32 drawX = -self->drawPos.x;955int32 drawY = -self->drawPos.y;956957self->drawPos.x = self->centerPos.x;958self->drawPos.y = self->centerPos.y;959960self->velocity.x = self->drawPos.x + drawX;961self->velocity.y = self->drawPos.y + drawY;962}963964void Platform_State_DipRock(void)965{966RSDK_THIS(Platform);967968if (self->stood) {969self->drawPos.y += self->velocity.y;970if (self->drawPos.y > self->centerPos.y + self->amplitude.y)971self->drawPos.y = self->centerPos.y + self->amplitude.y;972}973else {974self->drawPos.y -= self->velocity.y;975if (self->drawPos.y < self->centerPos.y)976self->drawPos.y = self->centerPos.y;977}978}979980void Platform_State_Push_SlideOffL(void)981{982RSDK_THIS(Platform);983984self->drawPos.x += self->velocity.x;985986int32 storeX = self->position.x;987int32 storeY = self->position.y;988989self->position.x = self->drawPos.x;990self->position.y = self->drawPos.y;991if (!RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.left), TO_FIXED(self->hitbox.bottom), false))992self->state = Platform_State_Push_Fall;993994self->position.x = storeX;995self->position.y = storeY;996}997998void Platform_State_Push_SlideOffR(void)999{1000RSDK_THIS(Platform);10011002self->drawPos.x += self->velocity.x;10031004int32 storeX = self->position.x;1005int32 storeY = self->position.y;10061007self->position.x = self->drawPos.x;1008self->position.y = self->drawPos.y;10091010if (!RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.right), TO_FIXED(self->hitbox.bottom), false))1011self->state = Platform_State_Push_Fall;10121013self->position.x = storeX;1014self->position.y = storeY;1015}10161017void Platform_State_Push_Fall(void)1018{1019RSDK_THIS(Platform);10201021int32 storeX = self->position.x;1022int32 storeY = self->position.y;10231024self->drawPos.y += self->velocity.y;1025self->velocity.y += 0x3800;10261027self->position.x = self->drawPos.x;1028self->position.y = self->drawPos.y;10291030bool32 collided =1031RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.left + 16), TO_FIXED(self->hitbox.bottom), 4);1032int32 y = self->position.y;10331034collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(0), TO_FIXED(self->hitbox.bottom), 4);1035if (self->position.y < y)1036y = self->position.y;10371038collided |= RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(self->hitbox.right - 16), TO_FIXED(self->hitbox.bottom), 4);1039if (self->position.y < y)1040y = self->position.y;10411042if (collided) {1043self->velocity.y = 0;1044self->state = Platform_State_Push;1045}1046else {1047self->position.y = y;1048self->drawPos.y = y;1049}10501051self->position.x = storeX;1052self->position.y = storeY;10531054self->velocity.x = 0;1055}10561057void Platform_State_Path(void)1058{1059RSDK_THIS(Platform);10601061self->drawPos.x += self->velocity.x;1062self->drawPos.y += self->velocity.y;1063EntityPlatformNode *node = RSDK_GET_ENTITY(self->speed, PlatformNode);10641065if (self->velocity.y <= 0) {1066if (self->drawPos.y < node->position.y)1067self->drawPos.y = node->position.y;1068}1069else {1070if (self->drawPos.y > node->position.y)1071self->drawPos.y = node->position.y;1072}10731074if (self->velocity.x <= 0) {1075if (self->drawPos.x < node->position.x)1076self->drawPos.x = node->position.x;1077}1078else {1079if (self->drawPos.x > node->position.x)1080self->drawPos.x = node->position.x;1081}1082}10831084void Platform_State_ReactSlow(void)1085{1086RSDK_THIS(Platform);10871088int32 drawX = -self->drawPos.x;1089int32 drawY = -self->drawPos.y;10901091self->amplitude.y += self->groundVel;1092self->drawPos.x = (self->amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;1093self->drawPos.y = (self->amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;10941095if (self->groundVel <= 0) {1096self->centerPos.x = self->drawPos.x - self->tileOrigin.x;1097self->centerPos.y = self->drawPos.y - self->tileOrigin.y;1098self->groundVel = 0;1099self->amplitude.y = 0;1100self->angle = -self->angle;11011102if (self->timer == -1) {1103self->timer = 0;1104if (self->type == PLATFORM_HOVER_REACT)1105self->state = Platform_State_Hover_React;1106else1107self->state = Platform_State_React;1108}1109else {1110if (self->hasTension) {1111self->state = Platform_State_ReactWait;1112}1113else {1114self->active = ACTIVE_BOUNDS;1115if (self->type == PLATFORM_HOVER_REACT)1116self->state = Platform_State_Hover;1117else1118self->state = Platform_State_Fixed;1119}1120}1121}1122else {1123self->groundVel -= self->speed << 10;1124}11251126self->velocity.x = drawX + self->drawPos.x;1127self->velocity.y = drawY + self->drawPos.y;1128}11291130void Platform_State_Hover(void)1131{1132RSDK_THIS(Platform);11331134self->rotation += 4;1135self->drawPos.y = (RSDK.Sin1024(self->rotation) << 9) + self->centerPos.y;1136self->velocity.x = 0;1137self->velocity.y = 0;1138}11391140void Platform_State_ReactWait(void)1141{1142RSDK_THIS(Platform);11431144if (self->type == PLATFORM_HOVER_REACT) {1145self->rotation += 4;1146self->drawPos.y = (RSDK.Sin1024(self->rotation) << 9) + self->centerPos.y;1147}11481149if (self->stood) {1150self->timer = 120;1151self->velocity.x = 0;1152self->velocity.y = 0;1153}1154else {1155if (--self->timer) {1156self->tileOrigin.x = self->drawPos.x - self->centerPos.x;1157self->tileOrigin.y = self->drawPos.y - self->centerPos.y;1158self->centerPos.x = self->drawPos.x;1159self->centerPos.y = self->drawPos.y;1160self->timer = -1;1161self->active = ACTIVE_NORMAL;1162self->state = Platform_State_ReactMove;1163}1164self->velocity.x = 0;1165self->velocity.y = 0;1166}1167}11681169void Platform_State_PathReact(void)1170{1171RSDK_THIS(Platform);11721173if (!self->stood) {1174self->velocity.x = 0;1175self->velocity.y = 0;1176}1177else {1178int32 slot = SceneInfo->entitySlot - 1;1179EntityPlatformControl *controller = RSDK_GET_ENTITY(slot, PlatformControl);1180if (controller->classID == PlatformControl->classID) {1181controller->setActive = true;1182self->state = Platform_State_Path;1183self->velocity.x = 0;1184self->velocity.y = 0;1185}1186else {1187while (controller->classID == Platform->classID || controller->classID == PlatformNode->classID) {1188controller = RSDK_GET_ENTITY(slot--, PlatformControl);1189if (controller->classID == PlatformControl->classID) {1190controller->setActive = true;1191self->state = Platform_State_Path;1192self->velocity.x = 0;1193self->velocity.y = 0;1194break;1195}1196}1197}1198}1199}12001201void Platform_State_Swing2(void)1202{1203RSDK_THIS(Platform);12041205int32 drawX = -self->drawPos.x;1206int32 drawY = -self->drawPos.y;1207self->angle = self->groundVel + 0x100 + ((self->amplitude.x * RSDK.Sin1024(self->timer * self->speed) + 0x200) >> 14);12081209if (self->timer++ == 256 && self->hasTension) {1210self->timer = 119;1211self->state = Platform_State_SwingWait;1212}1213self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;1214self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;12151216if (self->groundVel < 0)1217self->drawPos.x += TO_FIXED(32);1218else1219self->drawPos.x -= TO_FIXED(32);12201221self->velocity.x = drawX + self->drawPos.x;1222self->velocity.y = drawY + self->drawPos.y;1223}12241225void Platform_State_SwingWait(void)1226{1227RSDK_THIS(Platform);12281229if (self->stood) {1230self->timer = 120;1231self->velocity.x = 0;1232self->velocity.y = 0;1233}1234else {1235if (!--self->timer) {1236self->timer = 257;1237self->active = ACTIVE_NORMAL;1238self->state = Platform_State_SwingReturn;1239}1240self->velocity.x = 0;1241self->velocity.y = 0;1242}1243}12441245void Platform_State_SwingReturn(void)1246{1247RSDK_THIS(Platform);12481249int32 drawX = -self->drawPos.x;1250int32 drawY = -self->drawPos.y;1251int32 amp = self->amplitude.x * RSDK.Sin1024(self->timer-- * self->speed);1252self->angle = self->groundVel + 0x100 + ((amp + 0x200) >> 14);12531254if (self->timer == 88)1255self->state = Platform_State_SwingReact;12561257self->drawPos.x = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;1258self->drawPos.y = self->amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;1259if (self->groundVel < 0)1260self->drawPos.x += TO_FIXED(32);1261else1262self->drawPos.x -= TO_FIXED(32);1263self->velocity.x = drawX + self->drawPos.x;1264self->velocity.y = drawY + self->drawPos.y;1265}12661267void Platform_State_Track2(void)1268{1269RSDK_THIS(Platform);12701271int32 drawX = -self->drawPos.x;1272int32 drawY = -self->drawPos.y;1273int32 move = self->angle++ * (self->speed << 7);12741275if (self->hasTension) {1276if (move < TO_FIXED(1)) {1277if (move <= 0)1278move = 0;1279}1280else {1281move = TO_FIXED(1);1282self->timer = 120;1283self->state = Platform_State_TrackWait;1284}1285}12861287if (((move >> 16) & 1) == self->direction) {1288self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * self->amplitude.x >> 6) - (self->amplitude.x << 9);1289self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * self->amplitude.y >> 6) - (self->amplitude.y << 9);1290}1291else {1292self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9) - ((move & 0xFFFF) * self->amplitude.x >> 6);1293self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9) - ((move & 0xFFFF) * self->amplitude.y >> 6);1294}12951296self->velocity.x = drawX + self->drawPos.x;1297self->velocity.y = drawY + self->drawPos.y;1298}12991300void Platform_State_TrackWait(void)1301{1302RSDK_THIS(Platform);13031304if (self->stoodPlayers) {1305self->timer = 120;1306self->velocity.x = 0;1307self->velocity.y = 0;1308}1309else {1310if (!--self->timer) {1311self->active = ACTIVE_NORMAL;1312self->state = Platform_State_TrackReturn;1313}1314self->velocity.x = 0;1315self->velocity.y = 0;1316}1317}13181319void Platform_State_TrackReturn(void)1320{1321RSDK_THIS(Platform);13221323int32 drawX = -self->drawPos.x;1324int32 drawY = -self->drawPos.y;1325int32 move = self->angle-- * (self->speed << 7);13261327if (move > 0) {1328if (move >= TO_FIXED(1))1329move = TO_FIXED(1);1330}1331else {1332move = 0;1333self->state = Platform_State_TrackReact;1334}13351336if (((move >> 16) & 1) == self->direction) {1337self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * self->amplitude.x >> 6) - (self->amplitude.x << 9);1338self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * self->amplitude.y >> 6) - (self->amplitude.y << 9);1339}1340else {1341self->drawPos.x = self->centerPos.x + (self->amplitude.x << 9) - ((move & 0xFFFF) * self->amplitude.x >> 6);1342self->drawPos.y = self->centerPos.y + (self->amplitude.y << 9) - ((move & 0xFFFF) * self->amplitude.y >> 6);1343}13441345self->velocity.x = drawX + self->drawPos.x;1346self->velocity.y = drawY + self->drawPos.y;1347}13481349// Collision States1350void Platform_Collision_Solid(void)1351{1352RSDK_THIS(Platform);13531354Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);1355Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);1356int32 stoodPlayers = self->stoodPlayers;13571358self->stoodPlayers = 0;1359self->pushPlayersL = 0;1360self->pushPlayersR = 0;1361foreach_active(Player, player)1362{1363int32 playerID = RSDK.GetEntitySlot(player);1364Player_CheckCollisionPlatform(player, self, platformHitbox);13651366switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1367case C_TOP:1368Platform_HandleStood(self, player, playerID, stoodPlayers);13691370if (self->velocity.y <= 0)1371player->collisionFlagV |= 1;1372break;13731374case C_LEFT:1375if (player->onGround && player->right)1376self->pushPlayersL |= 1 << playerID;13771378if (self->velocity.x <= 0) {1379if (player->left) {1380player->groundVel = self->velocity.x;1381player->velocity.x = player->groundVel;1382player->velocity.x -= player->acceleration;1383}1384player->collisionFlagH |= 1;1385}1386break;13871388case C_RIGHT:1389if (player->onGround && player->left)1390self->pushPlayersR |= 1 << playerID;13911392if (self->velocity.x >= 0) {1393if (player->right) {1394player->groundVel = self->velocity.x;1395player->velocity.x = player->groundVel;1396player->velocity.x += player->acceleration;1397}1398player->collisionFlagH |= 2;1399}1400break;14011402case C_BOTTOM:1403if (self->velocity.y >= 0)1404player->collisionFlagV |= 2;1405break;14061407default: break;1408}1409}1410}1411void Platform_Collision_Hurt(void)1412{1413RSDK_THIS(Platform);14141415if (self->timer)1416self->timer--;14171418foreach_active(Player, player)1419{1420if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {1421#if MANIA_USE_PLUS1422if (!Player_CheckMightyUnspin(player, 0x400, self->type == PLATFORM_CIRCULAR, &player->uncurlTimer))1423#endif1424Player_Hurt(player, self);1425}1426}1427}1428void Platform_Collision_Solid_Hurt_Bottom(void)1429{1430RSDK_THIS(Platform);14311432Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);1433Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);14341435self->stoodPlayers = 0;1436self->pushPlayersL = 0;1437self->pushPlayersR = 0;14381439foreach_active(Player, player)1440{1441int32 playerID = RSDK.GetEntitySlot(player);1442Player_CheckCollisionPlatform(player, self, platformHitbox);14431444switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1445case C_TOP:1446Platform_HandleStood(self, player, playerID, 0xFF);14471448if (self->velocity.y <= 0)1449player->collisionFlagV |= 1;1450break;14511452case C_LEFT:1453if (player->onGround && player->right)1454self->pushPlayersL |= 1 << playerID;14551456if (self->velocity.x <= 0) {1457if (player->left) {1458player->groundVel = self->velocity.x;1459player->velocity.x = player->groundVel;1460player->velocity.x -= player->acceleration;1461}1462player->collisionFlagH |= 1;1463}1464break;14651466case C_RIGHT:1467if (player->onGround && player->left)1468self->pushPlayersR |= 1 << playerID;14691470if (self->velocity.x >= 0) {1471if (player->right) {1472player->groundVel = self->velocity.x;1473player->velocity.x = player->groundVel;1474player->velocity.x += player->acceleration;1475}1476player->collisionFlagH |= 2;1477}1478break;14791480case C_BOTTOM:1481if (self->velocity.y >= 0)1482player->collisionFlagV |= 2;14831484#if MANIA_USE_PLUS1485if (!Player_CheckMightyUnspin(player, 0x400, 0, &player->uncurlTimer))1486#endif1487Player_Hurt(player, self);1488break;14891490default: break;1491}1492}1493}1494void Platform_Collision_Solid_Hurt_Sides(void)1495{1496RSDK_THIS(Platform);14971498Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);14991500self->stoodPlayers = 0;1501self->pushPlayersL = 0;1502self->pushPlayersR = 0;1503foreach_active(Player, player)1504{1505uint16 playerID = RSDK.GetEntitySlot(player);15061507switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1508case C_TOP:1509Platform_HandleStood(self, player, playerID, 0xFF);15101511if (self->velocity.y <= 0)1512player->collisionFlagV |= 1;1513break;15141515case C_LEFT:1516if (1517#if MANIA_USE_PLUS1518Player_CheckMightyUnspin(player, 1024, 0, &player->uncurlTimer) ||1519#endif1520Player_Hurt(player, self)) {1521player->velocity.x += self->velocity.x;1522}15231524if (!player->blinkTimer || player->velocity.x >= self->velocity.x) {1525if (player->onGround && player->right)1526self->pushPlayersL |= 1 << playerID;15271528if (self->velocity.x < 0 && player->velocity.x >= self->velocity.x && player->left) {1529player->groundVel = self->velocity.x;1530player->velocity.x = player->groundVel;1531player->velocity.x -= player->acceleration;1532}1533}15341535if (self->velocity.x <= 0)1536player->collisionFlagH |= 1;1537break;15381539case C_RIGHT:1540if (1541#if MANIA_USE_PLUS1542Player_CheckMightyUnspin(player, 0x400, 0, &player->uncurlTimer) ||1543#endif1544Player_Hurt(player, self)) {1545player->velocity.x += self->velocity.x;1546}15471548if (!player->blinkTimer || player->velocity.x <= self->velocity.x) {1549if (player->onGround && player->left)1550self->pushPlayersR |= 1 << playerID;15511552if (self->velocity.x > 0 && player->velocity.x <= self->velocity.x && player->right) {1553player->groundVel = self->velocity.x;1554player->velocity.x = player->groundVel;1555player->velocity.x += player->acceleration;1556}1557}15581559if (self->velocity.x >= 0)1560player->collisionFlagH |= 2;1561break;15621563case C_BOTTOM:1564if (self->velocity.y >= 0)1565player->collisionFlagV |= 2;1566break;15671568default: break;1569}1570}1571}1572void Platform_Collision_Tiles(void)1573{1574RSDK_THIS(Platform);15751576self->stoodPlayers = 0;1577self->pushPlayersL = 0;1578self->pushPlayersR = 0;1579foreach_active(Player, player)1580{1581int32 playerID = RSDK.GetEntitySlot(player);15821583Hitbox hitbox;1584hitbox.left = self->hitbox.left - 16;1585hitbox.top = self->hitbox.top - 16;1586hitbox.right = self->hitbox.right + 16;1587hitbox.bottom = self->hitbox.bottom + 16;15881589if (Player_CheckCollisionTouch(player, self, &hitbox)) {1590player->collisionLayers |= Zone->moveLayerMask;1591player->moveLayerPosition.x = self->tileOrigin.x - self->drawPos.x;1592player->moveLayerPosition.y = self->tileOrigin.y - self->drawPos.y;1593if (player->animator.animationID == ANI_PUSH && player->onGround) {1594if (player->right)1595self->pushPlayersL |= 1 << playerID;15961597if (player->onGround && player->left)1598self->pushPlayersR |= 1 << playerID;1599}16001601bool32 isClimbing = false;1602if (player->state == Player_State_KnuxWallClimb || player->state == Player_State_KnuxLedgePullUp) {1603isClimbing = true;16041605if (player->state == Player_State_KnuxLedgePullUp)1606hitbox.top -= 16;16071608if (player->position.x >= self->position.x) {1609hitbox.top += 16;1610hitbox.left += 16;1611}1612else {1613hitbox.top += 16;1614hitbox.right -= 16;1615}16161617hitbox.bottom -= 16;1618}1619else {1620switch (player->collisionMode) {1621case CMODE_FLOOR:1622hitbox.right -= 16;1623hitbox.left += 16;1624hitbox.bottom -= 16;1625break;16261627case CMODE_LWALL:1628hitbox.top += 16;1629hitbox.right -= 16;1630hitbox.bottom -= 16;1631break;16321633case CMODE_ROOF:1634hitbox.top += 16;1635hitbox.left += 16;1636hitbox.right -= 16;1637break;16381639case CMODE_RWALL:1640hitbox.top += 16;1641hitbox.left += 16;1642hitbox.bottom -= 16;1643break;16441645default: break;1646}1647}16481649if (Player_CheckCollisionTouch(player, self, &hitbox) && (player->onGround || isClimbing)) {1650Platform_HandleStood_Tiles(self, player, playerID);1651}1652}1653}1654}1655void Platform_Collision_Sticky(void)1656{1657RSDK_THIS(Platform);16581659Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);1660Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);16611662self->pushPlayersL = 0;1663self->pushPlayersR = 0;1664foreach_active(Player, player)1665{1666uint16 playerID = RSDK.GetEntitySlot(player);1667Player_CheckCollisionPlatform(player, self, platformHitbox);16681669int32 side = Player_CheckCollisionBox(player, self, solidHitbox);16701671Platform_HandleStood_Sticky(self, player, playerID, side);1672}1673}1674void Platform_Collision_Solid_Hurt_Top(void)1675{1676RSDK_THIS(Platform);16771678Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);16791680self->stoodPlayers = 0;1681self->pushPlayersL = 0;1682self->pushPlayersR = 0;1683foreach_active(Player, player)1684{1685uint16 playerID = RSDK.GetEntitySlot(player);16861687switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1688case C_TOP: Platform_HandleStood(self, player, playerID, 0xFF);16891690#if MANIA_USE_PLUS1691if (!Player_CheckMightyUnspin(player, 0x400, 0, &player->uncurlTimer))1692#endif1693Player_Hurt(player, self);16941695if (self->velocity.y <= 0)1696player->collisionFlagV |= 1;1697break;16981699case C_LEFT:1700if (player->onGround && player->right)1701self->pushPlayersL |= 1 << playerID;17021703if (self->velocity.x <= 0) {1704if (player->left) {1705player->groundVel = self->velocity.x;1706player->velocity.x = player->groundVel;1707player->velocity.x -= player->acceleration;1708}1709player->collisionFlagH |= 1;1710}1711break;17121713case C_RIGHT:1714if (player->onGround && player->left)1715self->pushPlayersR |= 1 << playerID;17161717if (self->velocity.x >= 0) {1718if (player->right) {1719player->groundVel = self->velocity.x;1720player->velocity.x = player->groundVel;1721player->velocity.x += player->acceleration;1722}1723player->collisionFlagH |= 2;1724}1725break;17261727case C_BOTTOM:1728if (self->velocity.y >= 0)1729player->collisionFlagV |= 2;1730break;17311732default: break;1733}1734}1735}1736void Platform_Collision_Platform(void)1737{1738RSDK_THIS(Platform);17391740Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);1741int32 stoodPlayers = self->stoodPlayers;17421743self->stoodPlayers = 0;1744foreach_active(Player, player)1745{1746uint16 playerID = RSDK.GetEntitySlot(player);1747int32 yVel = player->velocity.y;17481749if (self->collisionOffset.y < 0)1750player->velocity.y -= self->collisionOffset.y;17511752if (Player_CheckCollisionPlatform(player, self, platformHitbox)) {1753Platform_HandleStood(self, player, playerID, stoodPlayers);1754}1755else {1756player->velocity.y = yVel;1757}1758}1759}1760void Platform_Collision_Solid_Barrel(void)1761{1762RSDK_THIS(Platform);17631764Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);1765Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);1766int32 stoodPlayers = self->stoodPlayers;17671768self->stoodPlayers = 0;1769self->pushPlayersL = 0;1770self->pushPlayersR = 0;1771foreach_active(Player, player)1772{1773uint16 playerID = RSDK.GetEntitySlot(player);1774Player_CheckCollisionPlatform(player, self, platformHitbox);17751776switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1777case C_TOP: self->stood = true;1778#if MANIA_USE_PLUS1779if (player->characterID != ID_MIGHTY || player->state != Player_State_MightyHammerDrop) {1780#endif17811782Platform_HandleStood_Barrel(self, player, playerID, stoodPlayers);17831784if (self->velocity.y <= 0)1785player->collisionFlagV |= 1;1786#if MANIA_USE_PLUS1787}1788#endif1789break;17901791case C_LEFT:1792if (player->onGround && player->right)1793self->pushPlayersL |= 1 << playerID;17941795if (self->velocity.x <= 0) {1796if (player->left) {1797player->groundVel = self->velocity.x;1798player->velocity.x = player->groundVel;1799player->velocity.x -= player->acceleration;1800}18011802player->collisionFlagH |= 1;1803}1804break;18051806case C_RIGHT:1807if (player->onGround && player->left)1808self->pushPlayersR |= 1 << playerID;18091810if (self->velocity.x >= 0) {1811if (player->right) {1812player->groundVel = self->velocity.x;1813player->velocity.x = player->groundVel;1814player->velocity.x += player->acceleration;1815}18161817player->collisionFlagH |= 2;1818}1819break;18201821case C_BOTTOM:1822if (self->velocity.y >= 0)1823player->collisionFlagV |= 2;1824break;18251826default: break;1827}1828}1829}1830void Platform_Collision_Solid_Hold(void)1831{1832RSDK_THIS(Platform);18331834Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);1835Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);1836int32 stoodPlayers = self->stoodPlayers;18371838self->stoodPlayers = 0;1839self->pushPlayersL = 0;1840self->pushPlayersR = 0;1841foreach_active(Player, player)1842{1843uint16 playerID = RSDK.GetEntitySlot(player);1844Player_CheckCollisionPlatform(player, self, platformHitbox);18451846switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1847case C_NONE:1848if ((1 << playerID) & stoodPlayers) {1849if (player->state == Player_State_Static) {1850player->state = Player_State_Air;1851RSDK.SetSpriteAnimation(player->aniFrames, ANI_AIR_WALK, &player->animator, false, 0);1852}1853}1854break;18551856case C_TOP:1857#if MANIA_USE_PLUS1858if (player->characterID != ID_MIGHTY || player->state != Player_State_MightyHammerDrop) {1859#endif18601861Platform_HandleStood_Hold(self, player, playerID, stoodPlayers);18621863if (self->velocity.y <= 0)1864player->collisionFlagV |= 1;1865#if MANIA_USE_PLUS1866}1867#endif1868break;18691870case C_LEFT:1871if (player->onGround && player->right)1872self->pushPlayersL |= 1 << playerID;18731874if (self->velocity.x <= 0) {1875if (player->left) {1876player->groundVel = self->velocity.x;1877player->velocity.x = player->groundVel;1878player->velocity.x -= player->acceleration;1879}18801881player->collisionFlagH |= 1;1882}1883break;18841885case C_RIGHT:1886if (player->onGround && player->left)1887self->pushPlayersR |= 1 << playerID;18881889if (self->velocity.x >= 0) {1890if (player->right) {1891player->groundVel = self->velocity.x;1892player->velocity.x = player->groundVel;1893player->velocity.x += player->acceleration;1894}18951896player->collisionFlagH |= 2;1897}18981899break;19001901case C_BOTTOM:1902if (self->velocity.y >= 0)1903player->collisionFlagV |= 2;1904break;19051906default: break;1907}1908}1909}1910void Platform_Collision_None(void)1911{1912// hehe1913}1914void Platform_Collision_Solid_NoCrush(void)1915{1916RSDK_THIS(Platform);19171918Hitbox *solidHitbox = RSDK.GetHitbox(&self->animator, 1);1919Hitbox *platformHitbox = RSDK.GetHitbox(&self->animator, 0);1920int32 stoodPlayers = self->stoodPlayers;19211922self->stoodPlayers = 0;1923self->pushPlayersL = 0;1924self->pushPlayersR = 0;1925foreach_active(Player, player)1926{1927uint16 playerID = RSDK.GetEntitySlot(player);1928Player_CheckCollisionPlatform(player, self, platformHitbox);19291930switch (Player_CheckCollisionBox(player, self, solidHitbox)) {1931default:1932case C_NONE: break;19331934case C_TOP: Platform_HandleStood(self, player, playerID, stoodPlayers); break;19351936case C_LEFT:1937if (player->onGround && player->right)1938self->pushPlayersL |= 1 << playerID;19391940if (self->velocity.x <= 0 && player->left) {1941player->groundVel = self->velocity.x;1942player->velocity.x = player->groundVel;1943player->velocity.x -= player->acceleration;1944}1945break;19461947case C_RIGHT:1948if (player->onGround && player->left)1949self->pushPlayersR |= 1 << playerID;19501951if (self->velocity.x >= 0) {1952if (player->right) {1953player->groundVel = self->velocity.x;1954player->velocity.x = player->groundVel;1955player->velocity.x += player->acceleration;1956}1957}1958break;19591960case C_BOTTOM: break;1961}1962}1963}19641965void Platform_HandleStood(EntityPlatform *self, EntityPlayer *player, int32 playerID, int32 stoodPlayers)1966{1967self->stood = true;19681969// if stoodPlayers is 0xFF thats the "ignore stoodPlayers" flag1970bool32 isStood = ((1 << playerID) & stoodPlayers) != 0;1971isStood &= stoodPlayers != 0xFF;19721973if (!isStood && !player->sidekick && self->state == Platform_State_Fall && !self->timer) {1974#if MANIA_USE_PLUS1975if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)1976self->timer = 1;1977else1978#endif1979self->timer = 30;1980}19811982self->stoodPlayers |= 1 << playerID;19831984if (Platform->stoodPos[playerID].x) {1985player->position.x = Platform->stoodPos[playerID].x;1986player->position.y = Platform->stoodPos[playerID].y;1987}1988else {1989Platform->stoodPos[playerID].x = player->position.x;1990Platform->stoodPos[playerID].y = player->position.y;1991}19921993player->position.x += self->collisionOffset.x;1994player->position.y += self->collisionOffset.y;1995player->position.y &= 0xFFFF0000;1996}1997void Platform_HandleStood_Tiles(EntityPlatform *self, EntityPlayer *player, int32 playerID)1998{1999if (!player->sidekick) {2000self->stood = true;2001if (self->state == Platform_State_Fall && !self->timer) {2002#if MANIA_USE_PLUS2003if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)2004self->timer = 1;2005else2006#endif2007self->timer = 30;2008}2009}20102011self->stoodPlayers |= 1 << playerID;20122013player->position.x += self->collisionOffset.x;2014player->position.y += self->collisionOffset.y;2015player->position.y &= 0xFFFF0000;2016}2017void Platform_HandleStood_Hold(EntityPlatform *self, EntityPlayer *player, int32 playerID, int32 stoodPlayers)2018{2019if (!((1 << playerID) & stoodPlayers)) {2020player->state = Player_State_Static;2021player->nextGroundState = StateMachine_None;2022player->nextAirState = StateMachine_None;2023player->velocity.x = 0;2024player->velocity.y = 0;2025player->groundVel = 0;20262027if (self->classID == Platform->classID)2028RSDK.SetSpriteAnimation(player->aniFrames, ANI_TWISTER, &player->animator, false, 0);20292030player->animator.speed = 64;2031player->direction = FLIP_X;2032if (!player->sidekick) {2033self->stood = true;2034}2035}20362037bool32 stoodStore = self->stood;2038Platform_HandleStood(self, player, playerID, stoodPlayers);2039self->stood = stoodStore;20402041if ((player->position.x ^ self->position.x) & 0xFFFF0000) {2042if (player->position.x >= self->position.x)2043player->position.x -= TO_FIXED(1);2044else2045player->position.x += TO_FIXED(1);2046}20472048if (player->jumpPress)2049Player_Action_Jump(player);2050}2051void Platform_HandleStood_Barrel(EntityPlatform *self, EntityPlayer *player, int32 playerID, int32 stoodPlayers)2052{2053if (!((1 << playerID) & stoodPlayers)) {2054player->state = Player_State_Static;2055player->nextGroundState = StateMachine_None;2056player->nextAirState = StateMachine_None;2057player->velocity.x = 0;2058player->velocity.y = 0;2059player->groundVel = 0;20602061if (self->classID == Platform->classID)2062RSDK.SetSpriteAnimation(player->aniFrames, ANI_TURNTABLE, &player->animator, false, 0);20632064player->animator.speed = 64;2065player->direction = FLIP_NONE;2066}20672068Platform_HandleStood(self, player, playerID, stoodPlayers);20692070if ((player->position.x ^ self->position.x) & 0xFFFF0000) {2071if (player->position.x >= self->position.x)2072player->position.x -= TO_FIXED(1);2073else2074player->position.x += TO_FIXED(1);2075}20762077if (player->jumpPress)2078Player_Action_Jump(player);2079}2080void Platform_HandleStood_Sticky(EntityPlatform *self, EntityPlayer *player, int32 playerID, uint8 cSide)2081{20822083bool32 isStuck = false;2084if ((self->collision == PLATFORM_C_SOLID_STICKY || self->collision == PLATFORM_C_SOLID_STICKY + cSide) && cSide)2085isStuck = true;20862087if (player->state != Player_State_Static && isStuck) {2088player->state = Player_State_Static;2089player->nextGroundState = StateMachine_None;2090player->nextAirState = StateMachine_None;2091player->velocity.x = 0;2092player->velocity.y = 0;2093player->groundVel = 0;2094player->animator.speed = 0;20952096switch (cSide) {2097case C_TOP: player->angle = 0x00; break;20982099case C_LEFT:2100player->angle = 0xC0;2101player->onGround = false;2102break;21032104case C_RIGHT: player->angle = 0x40; break;21052106case C_BOTTOM: player->angle = 0x80; break;21072108default: break;2109}21102111player->tileCollisions = TILECOLLISION_NONE;2112if (!player->sidekick) {2113self->stood = true;2114if (self->state == Platform_State_Fall && !self->timer) {2115#if MANIA_USE_PLUS2116if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)2117self->timer = 1;2118else2119#endif2120self->timer = 30;2121}2122}21232124self->stoodPlayers |= 1 << playerID;2125}2126else if ((1 << playerID) & self->stoodPlayers) {2127if (player->state == Player_State_Static) {2128if (Platform->stoodPos[playerID].x) {2129player->position.x = Platform->stoodPos[playerID].x;2130player->position.y = Platform->stoodPos[playerID].y;2131}2132else {2133Platform->stoodPos[playerID].x = player->position.x;2134Platform->stoodPos[playerID].y = player->position.y;2135}21362137player->position.x += self->collisionOffset.x;2138player->position.y += self->collisionOffset.y;2139player->position.y &= 0xFFFF0000;21402141if (player->jumpPress) {2142player->tileCollisions = TILECOLLISION_DOWN;2143Player_Action_Jump(player);2144}2145}2146else {2147self->stoodPlayers &= ~(1 << playerID);2148}2149}2150else if (cSide == C_TOP) {2151if (Platform->stoodPos[playerID].x) {2152player->position.x = Platform->stoodPos[playerID].x;2153player->position.y = Platform->stoodPos[playerID].y;2154}2155else {2156Platform->stoodPos[playerID].x = player->position.x;2157Platform->stoodPos[playerID].y = player->position.y;2158}21592160player->position.x += self->collisionOffset.x;2161player->position.y += self->collisionOffset.y;2162player->position.y &= 0xFFFF0000;2163}2164}21652166#if GAME_INCLUDE_EDITOR2167void Platform_EditorDraw_Normal(void)2168{2169RSDK_THIS(Platform);21702171if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)2172RSDK.DrawRect(self->drawPos.x - TO_FIXED(32), self->drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,2173self->inkEffect, false);2174else2175RSDK.DrawSprite(&self->animator, &self->drawPos, false);2176}21772178void Platform_EditorDraw_Swinging(Vector2 amplitude)2179{2180RSDK_THIS(Platform);21812182int32 frame = self->animator.frameID;21832184int32 ang = self->angle;2185if (self->type == PLATFORM_CIRCULAR && self->hasTension)2186ang = 4 * self->angle;21872188int32 fxStore = self->drawFX;2189self->drawFX |= FX_FLIP | FX_ROTATE;2190int32 cnt = (amplitude.y >> 10) - 1;2191int32 angle = 0x400;2192self->direction = FLIP_NONE;2193self->animator.frameID = frame + 1;21942195int32 rot = ang >> 1;2196Vector2 drawPos;2197for (int32 i = 0; i < cnt; ++i) {2198drawPos.x = angle * RSDK.Cos1024(ang) + self->centerPos.x;2199drawPos.y = angle * RSDK.Sin1024(ang) + self->centerPos.y;2200if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)2201RSDK.DrawRect(drawPos.x - TO_FIXED(32), drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,2202self->inkEffect, false);2203else2204RSDK.DrawSprite(&self->animator, &drawPos, false);2205angle += 0x400;2206self->direction ^= FLIP_X;2207self->rotation = rot;2208}22092210self->drawFX = fxStore;2211self->animator.frameID = frame + 2;2212if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)2213RSDK.DrawRect(self->centerPos.x - TO_FIXED(32), self->centerPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,2214self->inkEffect, false);2215else2216RSDK.DrawSprite(&self->animator, &self->centerPos, false);22172218self->animator.frameID = frame;2219if (Platform->aniFrames == (uint16)-1 || self->frameID == -1)2220RSDK.DrawRect(self->drawPos.x - TO_FIXED(32), self->drawPos.y - TO_FIXED(16), TO_FIXED(64), TO_FIXED(32), 0x8080A0, self->alpha,2221self->inkEffect, false);2222else2223RSDK.DrawSprite(&self->animator, &self->drawPos, false);2224}22252226void Platform_EditorDraw(void)2227{2228RSDK_THIS(Platform);22292230self->drawPos = self->position;2231self->centerPos = self->position;2232self->drawFX = FX_NONE;2233self->inkEffect = INK_NONE;2234self->alpha = 0xFF;2235self->direction = FLIP_NONE;22362237RSDK.SetSpriteAnimation(Platform->aniFrames, 0, &self->animator, true, 0);2238self->animator.frameID = self->frameID;2239if (self->frameID >= 0) {2240int32 f = self->frameID;2241int32 anim = 0;2242while (f >= self->animator.frameCount) {2243if (!self->animator.frameCount)2244break;2245f -= self->animator.frameCount;2246RSDK.SetSpriteAnimation(Platform->aniFrames, ++anim, &self->animator, true, 0);2247}2248self->animator.frameID = f;2249}2250else {2251RSDK.SetSpriteAnimation(-1, 0, &self->animator, true, 0);2252}22532254Vector2 amplitude;2255Vector2 drawPos;22562257amplitude.x = self->amplitude.x >> 10;2258amplitude.y = self->amplitude.y >> 10;22592260switch (self->type) {2261case PLATFORM_FIXED:2262default:2263self->updateRange.x = TO_FIXED(128);2264self->updateRange.y = TO_FIXED(128);22652266Platform_EditorDraw_Normal();2267break;22682269case PLATFORM_FALL:2270self->updateRange.x = TO_FIXED(128);2271self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;22722273Platform_EditorDraw_Normal();2274break;22752276case PLATFORM_LINEAR:2277self->updateRange.x = (abs(amplitude.x) + 0x2000) << 10;2278self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;22792280Platform_EditorDraw_Normal();22812282if (showGizmos() && (amplitude.x || amplitude.y)) {2283RSDK_DRAWING_OVERLAY(true);22842285self->inkEffect = INK_BLEND;22862287// start pos2288self->drawPos.x = amplitude.x * RSDK.Sin1024(self->angle) + self->centerPos.x;2289self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;2290Platform_EditorDraw_Normal();22912292// right max2293self->drawPos.x = amplitude.x * RSDK.Sin1024(0x100) + self->centerPos.x;2294self->drawPos.y = amplitude.y * RSDK.Sin1024(0x100) + self->centerPos.y;2295drawPos = self->drawPos;2296Platform_EditorDraw_Normal();22972298// left max2299self->drawPos.x = amplitude.x * RSDK.Sin1024(0x300) + self->centerPos.x;2300self->drawPos.y = amplitude.y * RSDK.Sin1024(0x300) + self->centerPos.y;2301Platform_EditorDraw_Normal();23022303DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);2304DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);23052306self->inkEffect = INK_NONE;23072308RSDK_DRAWING_OVERLAY(false);2309}2310break;23112312case PLATFORM_CIRCULAR:2313self->updateRange.x = (abs(amplitude.x) + 0x2000) << 10;2314self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;23152316if (self->hasTension) {2317self->drawPos.x = amplitude.x * RSDK.Cos1024(4 * self->angle) + self->centerPos.x;2318self->drawPos.y = amplitude.y * RSDK.Sin1024(4 * self->angle) + self->centerPos.y;2319Platform_EditorDraw_Swinging(amplitude);2320}2321else {2322Platform_EditorDraw_Normal();2323}23242325if (showGizmos() && !self->hasTension && (amplitude.x || amplitude.y)) {2326RSDK_DRAWING_OVERLAY(true);23272328self->inkEffect = INK_BLEND;23292330// start pos2331self->drawPos.x = amplitude.x * RSDK.Cos1024(4 * self->angle) + self->centerPos.x;2332self->drawPos.y = amplitude.y * RSDK.Sin1024(4 * self->angle) + self->centerPos.y;2333Platform_EditorDraw_Normal();23342335self->inkEffect = INK_NONE;23362337RSDK_DRAWING_OVERLAY(false);2338}2339break;23402341case PLATFORM_PATH:2342case PLATFORM_PATH_REACT:2343self->updateRange.x = TO_FIXED(128);2344self->updateRange.y = TO_FIXED(128);23452346// PLATFORM_PATH_REACT activates control in prev slot2347// Note: will go back through platforms if not found2348// e.g. if entity is slot 3, and platform control is slot 0, with slot 1 and 2 being platform/platformNode, it'll work2349// if slot 1 or 2 ISNT a platform/platformNode, it will not work23502351// self->speed = starting node23522353Platform_EditorDraw_Normal();2354break;23552356case PLATFORM_PUSH:2357self->updateRange.x = TO_FIXED(128);2358self->updateRange.y = TO_FIXED(128);23592360Platform_EditorDraw_Normal();2361break;23622363case PLATFORM_REACT:2364case PLATFORM_HOVER_REACT:2365amplitude.x <<= 10;2366self->updateRange.x = TO_FIXED(128) + abs(amplitude.x);2367self->updateRange.y = TO_FIXED(128) + abs(amplitude.x);2368if (self->speed < 0)2369self->direction = FLIP_X;23702371Platform_EditorDraw_Normal();23722373if (showGizmos()) {2374RSDK_DRAWING_OVERLAY(true);23752376drawPos = self->drawPos;2377self->groundVel = 0;2378bool32 reachedEnd = false;2379uint8 type = 0;23802381while (self->speed) {2382if (!reachedEnd) {2383amplitude.y += self->groundVel;23842385self->drawPos.x = (amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;2386self->drawPos.y = (amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;23872388int32 speed16 = self->speed << 16;2389if (self->groundVel == speed16) {2390if (amplitude.y >= amplitude.x) {2391amplitude.y = amplitude.x;2392self->groundVel -= (self->speed << 11);2393reachedEnd = true;2394}2395}2396else {2397self->groundVel += (self->speed << 10);2398if (self->groundVel >= speed16) {2399self->groundVel = speed16;2400self->centerPos.x += ((amplitude.y + self->groundVel) >> 8) * RSDK.Cos256(self->angle);2401self->centerPos.y += ((self->groundVel + amplitude.y) >> 8) * RSDK.Sin256(self->angle);2402amplitude.y = -self->groundVel;2403}2404}2405}2406else {2407amplitude.y += self->groundVel;2408self->drawPos.x = (amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;2409self->drawPos.y = (amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;24102411if (self->groundVel <= 0) {2412if (self->hasTension) {2413// draw double arrow (auto returns)2414type = 1;2415}2416else {2417// draw one arrow (one way)2418type = 0;2419}2420break;2421}2422else {2423self->groundVel -= self->speed << 10;2424}2425}2426}24272428self->inkEffect = INK_BLEND;2429Platform_EditorDraw_Normal();24302431self->inkEffect = INK_NONE;2432DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);2433if (type)2434DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);24352436RSDK_DRAWING_OVERLAY(false);2437}2438break;24392440case PLATFORM_DOORSLIDE:2441amplitude.x <<= 10;2442self->updateRange.x = TO_FIXED(128) + abs(amplitude.x);2443self->updateRange.y = TO_FIXED(128) + abs(amplitude.x);24442445if (self->speed < 0)2446self->direction = FLIP_X;24472448Platform_EditorDraw_Normal();24492450if (showGizmos()) {2451RSDK_DRAWING_OVERLAY(true);24522453self->inkEffect = INK_BLEND;24542455drawPos = self->drawPos;2456amplitude.y = 0;2457while (self->speed && amplitude.x) {2458if (amplitude.y < amplitude.x) {2459amplitude.y += (abs(self->speed) << 16);2460if (amplitude.y >= amplitude.x) {2461amplitude.y = amplitude.x;2462break;2463}2464}24652466if (self->direction) {2467self->drawPos.x = (-amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;2468self->drawPos.y = (-amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;2469}2470else {2471self->drawPos.x = (amplitude.y >> 8) * RSDK.Cos256(self->angle) + self->centerPos.x;2472self->drawPos.y = (amplitude.y >> 8) * RSDK.Sin256(self->angle) + self->centerPos.y;2473}2474}24752476Platform_EditorDraw_Normal();24772478self->inkEffect = INK_NONE;24792480DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);2481DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);24822483RSDK_DRAWING_OVERLAY(false);2484}24852486break;24872488case PLATFORM_SWING_REACT:2489case PLATFORM_SWING: {2490self->timer = 0;2491if (self->type == PLATFORM_SWING_REACT)2492self->timer = 88;24932494self->updateRange.x = (abs(amplitude.y) + 0x200) << 14;2495self->updateRange.y = (abs(amplitude.y) + 0x200) << 14;2496RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);2497amplitude.y <<= 4;2498if (self->type != PLATFORM_SWING) {2499if (self->groundVel >= 0)2500self->drawPos.x -= TO_FIXED(32);2501else2502self->drawPos.x += TO_FIXED(32);2503}25042505int32 angle = self->angle;2506self->groundVel = 4 * self->angle;2507self->angle = self->groundVel + 0x100 + (self->amplitude.x * RSDK.Sin1024(0x000 + self->timer) >> 14);2508self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;2509self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;2510Platform_EditorDraw_Swinging(amplitude);25112512if (showGizmos() && (amplitude.x || amplitude.y)) {2513RSDK_DRAWING_OVERLAY(true);25142515if (self->type == PLATFORM_SWING) {2516self->inkEffect = INK_BLEND;25172518// right max2519self->angle = self->groundVel + 0x100 + ((amplitude.x * RSDK.Sin1024(0x100) + 0x200) >> 14);25202521self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;2522self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;2523drawPos = self->drawPos;2524Platform_EditorDraw_Swinging(amplitude);25252526// left max2527self->angle = self->groundVel + 0x100 + ((amplitude.x * RSDK.Sin1024(0x300) + 0x200) >> 14);2528self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;2529self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;2530Platform_EditorDraw_Swinging(amplitude);25312532self->inkEffect = INK_NONE;2533}25342535RSDK_DRAWING_OVERLAY(false);2536}2537self->angle = angle;2538break;2539}25402541case PLATFORM_TRACK_REACT:2542if (self->direction) {2543self->drawPos.x = self->centerPos.x + (amplitude.x << 9);2544self->drawPos.y = self->centerPos.y + (amplitude.y << 9);2545}2546else {2547self->drawPos.x = self->centerPos.x - (amplitude.x << 9);2548self->drawPos.y = self->centerPos.y - (amplitude.y << 9);2549}25502551self->updateRange.x = (abs(amplitude.x) + 0x4000) << 9;2552self->updateRange.y = (abs(amplitude.y) + 0x4000) << 9;2553if (self->speed < 0)2554self->direction = FLIP_X;25552556Platform_EditorDraw_Normal();2557if (showGizmos()) {2558RSDK_DRAWING_OVERLAY(true);25592560drawPos = self->drawPos;2561self->drawPos = self->centerPos;25622563self->inkEffect = INK_BLEND;25642565Platform_EditorDraw_Normal();25662567self->inkEffect = INK_NONE;25682569DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);2570DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);25712572RSDK_DRAWING_OVERLAY(false);2573}2574break;25752576case PLATFORM_TRACK:2577self->updateRange.x = (abs(amplitude.x) + 0x4000) << 9;2578self->updateRange.y = (abs(amplitude.y) + 0x4000) << 9;2579if (self->speed < 0)2580self->direction = FLIP_X;25812582Platform_EditorDraw_Normal();25832584if (showGizmos() && (amplitude.x || amplitude.y)) {2585RSDK_DRAWING_OVERLAY(true);25862587Vector2 storePos = self->drawPos;2588drawPos = self->drawPos;25892590uint8 finishDirs = 0;2591int8 last = -1;2592int32 timer = 0;2593while (finishDirs != 2) {2594int32 move = timer++ * (self->speed << 7);25952596if (((move >> 16) & 1) == self->direction) {2597if (last > 0)2598finishDirs++;25992600if (finishDirs != 2) {2601self->drawPos.x = self->centerPos.x + ((move & 0xFFFF) * amplitude.x >> 6) - (amplitude.x << 9);2602self->drawPos.y = self->centerPos.y + ((move & 0xFFFF) * amplitude.y >> 6) - (amplitude.y << 9);2603storePos = self->drawPos;2604}2605last = 0;2606}2607else {2608if (!last)2609finishDirs++;26102611if (finishDirs != 2) {2612self->drawPos.x = self->centerPos.x + (amplitude.x << 9) - ((move & 0xFFFF) * amplitude.x >> 6);2613self->drawPos.y = self->centerPos.y + (amplitude.y << 9) - ((move & 0xFFFF) * amplitude.y >> 6);2614drawPos = self->drawPos;2615}2616last = 1;2617}2618}26192620self->inkEffect = INK_BLEND;26212622self->drawPos = drawPos;2623Platform_EditorDraw_Normal();26242625self->drawPos = storePos;2626Platform_EditorDraw_Normal();26272628self->inkEffect = INK_NONE;26292630DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);2631DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);26322633RSDK_DRAWING_OVERLAY(false);2634}26352636break;26372638case PLATFORM_CLACKER: {2639self->updateRange.x = (abs(amplitude.y) + 0x200) << 14;2640self->updateRange.y = (abs(amplitude.y) + 0x200) << 14;2641RSDK.SetSpriteAnimation(Platform->aniFrames, 1, &self->animator, true, 0);2642amplitude.y <<= 4;2643self->groundVel = 4 * self->angle;2644self->angle = self->groundVel + 0x100 + (amplitude.x * RSDK.Sin1024(self->hasTension ? 0x100 : 0) >> 14);2645self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;2646self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;26472648Platform_EditorDraw_Swinging(amplitude);26492650if (showGizmos() && (amplitude.x || amplitude.y)) {2651RSDK_DRAWING_OVERLAY(true);26522653self->inkEffect = INK_BLEND;26542655// max2656self->angle = self->groundVel + 0x100 + (amplitude.x * RSDK.Sin1024(self->hasTension ? 0 : -0x100) >> 14);2657self->drawPos.x = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.x;2658self->drawPos.y = amplitude.y * RSDK.Sin1024(self->angle) + self->centerPos.y;2659Platform_EditorDraw_Swinging(amplitude);26602661self->inkEffect = INK_NONE;2662self->angle = self->groundVel / 4;26632664RSDK_DRAWING_OVERLAY(false);2665}2666break;2667}26682669case PLATFORM_CHILD:2670self->updateRange.x = TO_FIXED(128);2671self->updateRange.y = TO_FIXED(128);26722673Platform_EditorDraw_Normal();2674break;26752676case PLATFORM_DIPROCK:2677self->updateRange.x = TO_FIXED(128);2678self->updateRange.y = (abs(amplitude.y) + 0x2000) << 10;26792680Platform_EditorDraw_Normal();26812682if (showGizmos() && (amplitude.x || amplitude.y)) {2683RSDK_DRAWING_OVERLAY(true);26842685self->inkEffect = INK_BLEND;26862687// max2688self->drawPos.y += amplitude.y;2689Platform_EditorDraw_Normal();26902691DrawHelpers_DrawArrow(self->drawPos.x, self->drawPos.y - amplitude.y, self->drawPos.x, self->drawPos.y, 0x00FF00, INK_NONE, 0xFF);26922693self->inkEffect = INK_NONE;26942695RSDK_DRAWING_OVERLAY(false);2696}2697break;2698}26992700if (showGizmos()) {2701RSDK_DRAWING_OVERLAY(true);27022703for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < self->childCount; ++i) {2704Entity *child = RSDK_GET_ENTITY_GEN(s + i);2705if (!child)2706continue;27072708DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xE0E0E0, INK_NONE, 0xFF);2709}27102711RSDK_DRAWING_OVERLAY(false);2712}2713}27142715void Platform_EditorLoad(void)2716{2717Platform_StageLoad();27182719RSDK_ACTIVE_VAR(Platform, type);2720RSDK_ENUM_VAR("Fixed", PLATFORM_FIXED);2721RSDK_ENUM_VAR("Fall", PLATFORM_FALL);2722RSDK_ENUM_VAR("Linear", PLATFORM_LINEAR);2723RSDK_ENUM_VAR("Circlular", PLATFORM_CIRCULAR);2724RSDK_ENUM_VAR("Swing", PLATFORM_SWING);2725RSDK_ENUM_VAR("Path", PLATFORM_PATH);2726RSDK_ENUM_VAR("Push", PLATFORM_PUSH);2727RSDK_ENUM_VAR("Track", PLATFORM_TRACK);2728RSDK_ENUM_VAR("React", PLATFORM_REACT);2729RSDK_ENUM_VAR("Hover-React", PLATFORM_HOVER_REACT);2730RSDK_ENUM_VAR("Door Slide", PLATFORM_DOORSLIDE);2731RSDK_ENUM_VAR("Path-React", PLATFORM_PATH_REACT);2732RSDK_ENUM_VAR("Swing-React", PLATFORM_SWING_REACT);2733RSDK_ENUM_VAR("Track-React", PLATFORM_TRACK_REACT);2734RSDK_ENUM_VAR("Clacker", PLATFORM_CLACKER);2735RSDK_ENUM_VAR("Child", PLATFORM_CHILD);2736RSDK_ENUM_VAR("Dip Rock", PLATFORM_DIPROCK);27372738RSDK_ACTIVE_VAR(Platform, collision);2739RSDK_ENUM_VAR("Platform", PLATFORM_C_PLATFORM);2740RSDK_ENUM_VAR("Solid", PLATFORM_C_SOLID);2741RSDK_ENUM_VAR("Tiled", PLATFORM_C_TILED);2742RSDK_ENUM_VAR("Hurt", PLATFORM_C_HURT);2743RSDK_ENUM_VAR("None", PLATFORM_C_NONE);2744RSDK_ENUM_VAR("Solid Hurt Sides", PLATFORM_C_SOLID_HURT_SIDES);2745RSDK_ENUM_VAR("Solid Hurt Bottom", PLATFORM_C_SOLID_HURT_BOTTOM);2746RSDK_ENUM_VAR("Solid Hurt Top", PLATFORM_C_SOLID_HURT_TOP);2747RSDK_ENUM_VAR("Solid Hold", PLATFORM_C_SOLID_HOLD);2748RSDK_ENUM_VAR("Solid Sticky", PLATFORM_C_SOLID_STICKY);2749RSDK_ENUM_VAR("Sticky Top", PLATFORM_C_STICKY_TOP);2750RSDK_ENUM_VAR("Sticky Left", PLATFORM_C_STICKY_LEFT);2751RSDK_ENUM_VAR("Sticky Right", PLATFORM_C_STICKY_RIGHT);2752RSDK_ENUM_VAR("Sticky Bottom", PLATFORM_C_STICKY_BOTTOM);2753RSDK_ENUM_VAR("Solid Barrel", PLATFORM_C_SOLID_BARREL);2754RSDK_ENUM_VAR("Solid No Crush", PLATFORM_C_SOLID_NOCRUSH);2755}2756#endif27572758void Platform_Serialize(void)2759{2760RSDK_EDITABLE_VAR(Platform, VAR_ENUM, type);2761RSDK_EDITABLE_VAR(Platform, VAR_VECTOR2, amplitude);2762RSDK_EDITABLE_VAR(Platform, VAR_ENUM, speed);2763RSDK_EDITABLE_VAR(Platform, VAR_BOOL, hasTension);2764RSDK_EDITABLE_VAR(Platform, VAR_INT8, frameID);2765RSDK_EDITABLE_VAR(Platform, VAR_UINT8, collision);2766RSDK_EDITABLE_VAR(Platform, VAR_VECTOR2, tileOrigin);2767RSDK_EDITABLE_VAR(Platform, VAR_ENUM, childCount);2768RSDK_EDITABLE_VAR(Platform, VAR_INT32, angle);2769}277027712772