Path: blob/master/SonicMania/Objects/SPZ/RockemSockem.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: RockemSockem Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectRockemSockem *RockemSockem;1011void RockemSockem_Update(void)12{13RSDK_THIS(RockemSockem);1415RSDK.ProcessAnimation(&self->ballAnimator);1617if (self->bounceTimer > 0) {18if (!--self->bounceTimer)19RSDK.SetSpriteAnimation(RockemSockem->aniFrames, 2, &self->ballAnimator, true, self->ballAnimator.frameID);20}2122if (self->reboundTimer > 0) {23if (!--self->reboundTimer) {24self->position.x = self->startPos.x;25self->position.y = self->startPos.y;26self->velocity.x = 0;27self->velocity.y = 0;28self->active = ACTIVE_BOUNDS;29}30}3132self->position.x += self->velocity.x;33self->position.y += self->velocity.y;34self->velocity.x = self->velocity.x + ((self->startPos.x - self->position.x) >> 6) - (self->velocity.x >> 4);35self->velocity.y = self->velocity.y + ((self->startPos.y - self->position.y) >> 6) - (self->velocity.y >> 4);3637foreach_active(Player, player)38{39if (Player_CheckBadnikTouch(player, self, &RockemSockem->hitbox)) {40int32 vel = abs(player->velocity.x) <= abs(player->velocity.y) ? abs(player->velocity.y) : abs(player->velocity.x);4142int32 angle = RSDK.ATan2((player->position.x - self->position.x) / 3, player->position.y - self->position.y);43int32 distX = abs(self->position.x - self->startPos.x);44int32 distY = abs(self->position.y - self->startPos.y);45self->reboundTimer = 120;4647int32 dx = (distX >> 16) * (distX >> 16);48int32 dy = (distY >> 16) * (distY >> 16);4950if (dx + dy < 0x100 && !self->bounceTimer) {51if ((angle - 0x20) & 0xC0) {52self->velocity.x -= vel * RSDK.Cos256(angle) >> 8;53self->velocity.y -= vel * RSDK.Sin256(angle) >> 8;54}55else {56self->velocity.x -= vel * RSDK.Cos256(angle) >> 9;57self->velocity.y -= 0x2000;58}5960self->velocity.x = CLAMP(self->velocity.x, -0x40000, 0x40000);61player->velocity.x -= player->velocity.x >> 4;62if (player->velocity.y <= 0)63player->velocity.y -= player->velocity.y >> 5;64else65player->velocity.y -= player->velocity.y >> 4;6667self->active = ACTIVE_NORMAL;68}69else if (player->velocity.y < 0) {70self->active = ACTIVE_NORMAL;71}72else {73int32 angleVal = ((angle - 0x20) >> 6) & 3;7475int32 anim = player->animator.animationID;76switch (angleVal) {77default:78case 0:79player->velocity.x = ((RSDK.Cos256(angle) << 9) + player->velocity.x) >> 1;80player->velocity.y = -(abs(RSDK.Sin256(angle)) * 0x400);8182if (anim != ANI_JUMP && anim != ANI_JOG && anim != ANI_RUN && anim != ANI_DASH)83player->animator.animationID = ANI_WALK;84break;8586case 1:87player->velocity.x = (0x500 * RSDK.Cos256(angle) + player->velocity.x) >> 1;88player->velocity.y = -(abs(RSDK.Sin256(angle)) * 0x500);8990RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_CS, &player->animator, false, 0);91break;9293case 2:94player->velocity.x = (0x700 * RSDK.Cos256(angle) + player->velocity.x) >> 1;95player->velocity.y = -(abs(RSDK.Sin256(angle)) * 0x700);9697RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_CS, &player->animator, false, 0);98break;99100case 3: break;101}102103if (self->ballAnimator.animationID != 3)104RSDK.PlaySfx(RockemSockem->sfxRockemSockem, false, 0xFF);105106// Bug Details:107// this one's actually the opposite of normal, since its fixed in release builds108// but if you comment out this Player_State_Air line and glide into the rockem sockem as knux109// you'll get the funny anim bug they showed off at SDCC 2017110player->state = Player_State_Air;111player->onGround = false;112RSDK.SetSpriteAnimation(RockemSockem->aniFrames, 3, &self->ballAnimator, true, self->ballAnimator.frameID);113self->bounceTimer = 16;114self->active = ACTIVE_NORMAL;115}116}117}118119if (self->position.y > self->drawPos.y - 0xE0000) {120self->position.y = self->drawPos.y - 0xE0000;121self->bounceTimer = 16;122}123124self->angleVel = 0;125if (abs(self->startPos.x - self->position.x) > 0x10000)126self->angleVel = (self->startPos.x - self->position.x) >> 17;127128RockemSockem_HandleJointPositions();129}130131void RockemSockem_LateUpdate(void) {}132133void RockemSockem_StaticUpdate(void) {}134135void RockemSockem_Draw(void)136{137RSDK_THIS(RockemSockem);138139for (int32 i = 0; i < ROCKEMSOCKEM_COIL_COUNT; ++i) {140self->rotation = self->jointRotations[i];141RSDK.DrawSprite(&self->jointAnimator, &self->jointPositions[i], false);142}143144RSDK.DrawSprite(&self->baseAnimator, &self->drawPos, false);145146if (self->ballAnimator.frameID > 9)147self->direction = FLIP_X;148RSDK.DrawSprite(&self->ballAnimator, NULL, false);149150self->direction = FLIP_NONE;151}152153void RockemSockem_Create(void *data)154{155RSDK_THIS(RockemSockem);156157RSDK.SetSpriteAnimation(RockemSockem->aniFrames, 0, &self->baseAnimator, true, 0);158RSDK.SetSpriteAnimation(RockemSockem->aniFrames, 1, &self->jointAnimator, true, 0);159RSDK.SetSpriteAnimation(RockemSockem->aniFrames, 2, &self->ballAnimator, true, 0);160161if (!SceneInfo->inEditor) {162self->drawPos = self->position;163self->position.y -= (0xE0000 + (0x50000 * ROCKEMSOCKEM_COIL_COUNT));164self->startPos = self->position;165self->angle = 0x80;166self->active = ACTIVE_BOUNDS;167self->updateRange.x = 0x800000;168self->updateRange.y = 0x800000;169self->visible = true;170self->drawGroup = Zone->objectDrawGroup[0];171self->drawFX = FX_ROTATE | FX_FLIP;172}173}174175void RockemSockem_StageLoad(void)176{177if (RSDK.CheckSceneFolder("SPZ1"))178RockemSockem->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/RockemSockem.bin", SCOPE_STAGE);179else180RockemSockem->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/RockemSockem.bin", SCOPE_STAGE);181182RockemSockem->hitbox.left = -16;183RockemSockem->hitbox.top = -14;184RockemSockem->hitbox.right = 16;185RockemSockem->hitbox.bottom = 14;186187RockemSockem->sfxRockemSockem = RSDK.GetSfx("Stage/RockemSockem.wav");188}189190void RockemSockem_HandleJointPositions(void)191{192RSDK_THIS(RockemSockem);193194int32 x = (RSDK.Sin256(self->angle) << 11) + self->drawPos.x;195int32 y = (RSDK.Cos256(self->angle) << 11) + self->drawPos.y;196197int32 ang = RSDK.ATan2(y - self->position.y, (RSDK.Sin256(self->angle) << 11) + self->drawPos.x - self->position.x);198int32 posX = (0xC00 * RSDK.Sin256(ang) + self->position.x) & 0xFFFF0000;199int32 posY = (0xC00 * RSDK.Cos256(ang) + self->position.y) & 0xFFFF0000;200201int32 angle = self->angle;202x >>= 16;203y >>= 16;204posX >>= 16;205posY >>= 16;206207self->jointRotations[0] = 2 * (640 - angle);208self->jointPositions[0].x = 0x10002 * x;209self->jointPositions[0].y = 0x10002 * y;210211angle += self->angleVel;212self->jointRotations[1] = 2 * (640 - angle);213self->jointPositions[1].x = 0x2AAB * (x + posX + 4 * x);214self->jointPositions[1].y = 0x2AAB * (y + posY + 4 * y);215216angle += self->angleVel;217self->jointRotations[2] = 2 * (640 - angle);218self->jointPositions[2].x = 0x5556 * (posX + 2 * x);219self->jointPositions[2].y = 0x5556 * (posY + 2 * y);220221angle += self->angleVel;222self->jointRotations[3] = 2 * (640 - angle);223self->jointPositions[3].x = 0x8001 * (x + posX);224self->jointPositions[3].y = 0x8001 * (y + posY);225226angle += self->angleVel;227self->jointRotations[4] = 2 * (640 - angle);228self->jointPositions[4].x = 0x5556 * (x + 2 * posX);229self->jointPositions[4].y = 0x5556 * (y + 2 * posY);230231angle -= self->angleVel;232self->jointRotations[5] = 2 * (640 - angle);233self->jointPositions[5].x = 0x2AAB * (posX + x + 4 * posX);234self->jointPositions[5].y = 0x2AAB * (posY + y + 4 * posY);235}236237#if GAME_INCLUDE_EDITOR238void RockemSockem_EditorDraw(void)239{240RSDK_THIS(RockemSockem);241242self->drawPos = self->position;243self->position.y -= (0xE0000 + (0x50000 * ROCKEMSOCKEM_COIL_COUNT));244self->startPos = self->position;245self->angle = 0x80;246self->active = ACTIVE_BOUNDS;247self->updateRange.x = 0x800000;248self->updateRange.y = 0x800000;249self->visible = true;250self->drawGroup = Zone->objectDrawGroup[0];251self->drawFX = FX_ROTATE | FX_FLIP;252253self->angleVel = 0;254if (abs(self->startPos.x - self->position.x) > 0x10000)255self->angleVel = (self->startPos.x - self->position.x) >> 17;256257RockemSockem_HandleJointPositions();258259RockemSockem_Draw();260}261262void RockemSockem_EditorLoad(void)263{264if (RSDK.CheckSceneFolder("SPZ1"))265RockemSockem->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/RockemSockem.bin", SCOPE_STAGE);266else267RockemSockem->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/RockemSockem.bin", SCOPE_STAGE);268}269#endif270271void RockemSockem_Serialize(void) {}272273