Path: blob/master/SonicMania/Objects/SPZ/MicDrop.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: MicDrop Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectMicDrop *MicDrop;1011void MicDrop_Update(void)12{13RSDK_THIS(MicDrop);1415StateMachine_Run(self->state);16}1718void MicDrop_LateUpdate(void) {}1920void MicDrop_StaticUpdate(void) {}2122void MicDrop_Draw(void)23{24RSDK_THIS(MicDrop);2526SpriteFrame *frame = RSDK.GetFrame(MicDrop->aniFrames, 1, self->wireAnimator.frameID);27SpriteFrame *otherFrame = RSDK.GetFrame(MicDrop->aniFrames, 1, self->wireAnimator.frameID + 4);2829if (self->wireAnimator.frameID == 3) {30RSDK.DrawLine(self->startPos.x, self->startPos.y, self->position.x, self->position.y, 0x081828, 0, INK_NONE, false);31RSDK.DrawLine(self->startPos.x - 0x10000, self->startPos.y, self->position.x - 0x10000, self->position.y, 0x204078, 0, INK_NONE, false);32}33else {34int32 distance = (self->position.y - self->startPos.y) >> 16;35if (distance > 58) {36frame->height = otherFrame->height;37frame->pivotY = otherFrame->pivotY;38frame->sprY = otherFrame->sprY;39RSDK.DrawLine(self->startPos.x, self->startPos.y, self->position.x, self->position.y - (58 << 16), 0x081828, 0, INK_NONE, false);40RSDK.DrawLine(self->startPos.x - 0x10000, self->startPos.y, self->position.x - 0x10000, self->position.y - (58 << 16), 0x204078, 0,41INK_NONE, false);42}43else {44frame->height = distance + 2;45frame->pivotY = 1 - distance;46frame->sprY = otherFrame->sprY - distance + 58;47}48}4950RSDK.DrawSprite(&self->wireAnimator, NULL, false);51RSDK.DrawSprite(&self->bodyAnimator, NULL, false);52}5354void MicDrop_Create(void *data)55{56RSDK_THIS(MicDrop);5758self->visible = true;59self->drawGroup = Zone->objectDrawGroup[0];60self->startPos = self->position;61self->active = ACTIVE_BOUNDS;62self->updateRange.x = 0x800000;63self->updateRange.y = 0x800000;64self->drawFX = FX_ROTATE | FX_FLIP;6566RSDK.SetSpriteAnimation(MicDrop->aniFrames, 0, &self->bodyAnimator, true, 0);67RSDK.SetSpriteAnimation(MicDrop->aniFrames, 1, &self->wireAnimator, true, 0);68self->state = MicDrop_State_Init;69}7071void MicDrop_StageLoad(void)72{73if (RSDK.CheckSceneFolder("SPZ1"))74MicDrop->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/MicDrop.bin", SCOPE_STAGE);75else76MicDrop->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/MicDrop.bin", SCOPE_STAGE);7778MicDrop->hitboxBadnik.left = -12;79MicDrop->hitboxBadnik.top = -15;80MicDrop->hitboxBadnik.right = 12;81MicDrop->hitboxBadnik.bottom = 15;8283MicDrop->hitboxRange.left = -128;84MicDrop->hitboxRange.top = 0;85MicDrop->hitboxRange.right = 128;86MicDrop->hitboxRange.bottom = 256;8788DEBUGMODE_ADD_OBJ(MicDrop);8990MicDrop->sfxElectrify = RSDK.GetSfx("Stage/Electrify.wav");91}9293void MicDrop_DebugSpawn(void)94{95RSDK_THIS(DebugMode);9697EntityMicDrop *micDrop = CREATE_ENTITY(MicDrop, NULL, self->position.x, self->position.y);98micDrop->distance = 128;99}100101void MicDrop_DebugDraw(void)102{103RSDK.SetSpriteAnimation(MicDrop->aniFrames, 0, &DebugMode->animator, true, 0);104RSDK.DrawSprite(&DebugMode->animator, NULL, false);105}106107void MicDrop_CheckPlayerCollisions(void)108{109RSDK_THIS(MicDrop);110111int32 storeX = self->position.x;112int32 storeY = self->position.y;113114self->position.x = (((self->radius + 25) * RSDK.Cos512(self->angle + 128)) << 7) + self->startPos.x;115self->position.y = (((self->radius + 25) * RSDK.Sin512(self->angle + 128)) << 7) + self->startPos.y;116117foreach_active(Player, player)118{119if (Player_CheckBadnikTouch(player, self, &MicDrop->hitboxBadnik)) {120if (self->bodyAnimator.animationID != 3 || player->shield == SHIELD_LIGHTNING || player->invincibleTimer || player->blinkTimer)121Player_CheckBadnikBreak(player, self, true);122else123Player_Hurt(player, self);124}125}126127self->position.x = storeX;128self->position.y = storeY;129}130131void MicDrop_CheckOffScreen(void)132{133RSDK_THIS(MicDrop);134135if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {136self->position.x = self->startPos.x;137self->position.y = self->startPos.y;138MicDrop_Create(NULL);139}140}141142void MicDrop_State_Init(void)143{144RSDK_THIS(MicDrop);145146self->active = ACTIVE_NORMAL;147self->velocity.y = 0;148self->direction = FLIP_NONE;149self->timer = 0;150self->swingPos = 0;151self->angle = 0;152self->rotation = 0;153154self->state = MicDrop_State_CheckForPlayer;155MicDrop_State_CheckForPlayer();156}157158void MicDrop_State_CheckForPlayer(void)159{160RSDK_THIS(MicDrop);161162foreach_active(Player, player)163{164if (Player_CheckCollisionTouch(player, self, &MicDrop->hitboxRange))165self->state = MicDrop_State_DropDown;166}167168MicDrop_CheckPlayerCollisions();169}170171void MicDrop_State_DropDown(void)172{173RSDK_THIS(MicDrop);174175self->position.y += self->velocity.y;176self->velocity.y += 0x3800;177178self->radius = (self->position.y - self->startPos.y) >> 16;179if (self->radius >= 0x20000)180self->bodyAnimator.frameID = 3;181182if (self->radius >= self->distance) {183self->radius = self->distance;184self->position.y = self->startPos.y + (self->distance << 16);185self->bodyAnimator.frameID = 4;186self->state = MicDrop_State_DropRecoil;187}188189MicDrop_CheckPlayerCollisions();190}191192void MicDrop_State_DropRecoil(void)193{194RSDK_THIS(MicDrop);195196switch (++self->timer) {197case 2:198self->wireAnimator.frameID = 1;199self->bodyAnimator.frameID = 5;200break;201202case 4:203self->wireAnimator.frameID = 2;204self->bodyAnimator.frameID = 1;205break;206207case 6:208self->wireAnimator.frameID = 3;209self->bodyAnimator.frameID = 0;210211self->timer = 0;212self->state = MicDrop_State_Idle;213break;214}215216MicDrop_CheckPlayerCollisions();217MicDrop_CheckOffScreen();218}219220void MicDrop_State_Idle(void)221{222RSDK_THIS(MicDrop);223224if (++self->timer >= 30) {225self->swingSpeed = 64;226self->swingVel = 4;227self->state = MicDrop_State_Swinging;228}229230MicDrop_CheckPlayerCollisions();231MicDrop_CheckOffScreen();232}233234void MicDrop_State_Swinging(void)235{236RSDK_THIS(MicDrop);237238self->swingPos += self->swingSpeed;239if (self->swingPos < 0) {240self->swingVel = 1;241self->swingPos -= self->swingSpeed;242self->swingSpeed >>= 1;243244self->state = MicDrop_State_Electrify;245MicDrop_State_Electrify();246}247else {248self->rotation = self->swingPos >> 4;249self->angle = self->rotation >> 2;250self->swingSpeed -= self->swingVel;251self->position.x = self->startPos.x + (self->radius << 7) * RSDK.Cos512(self->angle + 0x80);252self->position.y = self->startPos.y + (self->radius << 7) * RSDK.Sin512(self->angle + 0x80);253254MicDrop_CheckPlayerCollisions();255MicDrop_CheckOffScreen();256}257}258259void MicDrop_State_Electrify(void)260{261RSDK_THIS(MicDrop);262263self->swingPos += self->swingSpeed;264self->angle = self->swingPos >> 4;265self->rotation = self->angle;266if (self->angle >= 0)267self->swingSpeed -= self->swingVel;268else269self->swingSpeed += self->swingVel;270271self->position.x = self->startPos.x + (self->radius << 7) * RSDK.Cos512(self->angle + 0x80);272self->position.y = self->startPos.y + (self->radius << 7) * RSDK.Sin512(self->angle + 0x80);273274switch (++self->timer) {275case 60: RSDK.SetSpriteAnimation(MicDrop->aniFrames, 2, &self->bodyAnimator, true, 0); break;276277case 90:278RSDK.PlaySfx(MicDrop->sfxElectrify, false, 0xFF);279RSDK.SetSpriteAnimation(MicDrop->aniFrames, 3, &self->bodyAnimator, true, 0);280break;281282case 120:283self->timer = 0;284RSDK.SetSpriteAnimation(MicDrop->aniFrames, 0, &self->bodyAnimator, true, 0);285break;286}287288if (self->timer >= 60)289RSDK.ProcessAnimation(&self->bodyAnimator);290291MicDrop_CheckPlayerCollisions();292MicDrop_CheckOffScreen();293}294295#if GAME_INCLUDE_EDITOR296void MicDrop_EditorDraw(void)297{298RSDK_THIS(MicDrop);299300self->startPos.y = self->position.y;301self->position.y = self->startPos.y + (self->distance << 16);302303MicDrop_Draw();304305self->position.y = self->startPos.y;306}307308void MicDrop_EditorLoad(void)309{310if (RSDK.CheckSceneFolder("SPZ1"))311MicDrop->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/MicDrop.bin", SCOPE_STAGE);312else313MicDrop->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/MicDrop.bin", SCOPE_STAGE);314}315#endif316317void MicDrop_Serialize(void) { RSDK_EDITABLE_VAR(MicDrop, VAR_UINT16, distance); }318319320