Path: blob/master/SonicMania/Objects/TMZ/LaunchSpring.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: LaunchSpring Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectLaunchSpring *LaunchSpring;1011void LaunchSpring_Update(void)12{13RSDK_THIS(LaunchSpring);1415StateMachine_Run(self->state);16}1718void LaunchSpring_LateUpdate(void) {}1920void LaunchSpring_StaticUpdate(void) {}2122void LaunchSpring_Draw(void)23{24RSDK_THIS(LaunchSpring);2526RSDK.GetFrame(LaunchSpring->aniFrames, 2, 0)->pivotY = -8 - self->springPivot;27RSDK.DrawSprite(&self->springAnimator, NULL, false);2829self->mainAnimator.frameID = 0;30RSDK.DrawSprite(&self->jointAnimator, NULL, false);3132SpriteFrame *frame = RSDK.GetFrame(LaunchSpring->aniFrames, 0, 0);33RSDK.DrawSprite(&self->mainAnimator, NULL, false);3435frame->pivotY = self->timer - 55;36self->direction = FLIP_X;37RSDK.DrawSprite(&self->mainAnimator, NULL, false);3839frame->pivotY = -55;40self->direction = FLIP_NONE;41}4243void LaunchSpring_Create(void *data)44{45RSDK_THIS(LaunchSpring);4647if (!self->rotSpeed)48self->rotSpeed = 4;4950self->drawFX = FX_ROTATE | FX_FLIP;51self->rotation = self->angle << 6;5253if (!SceneInfo->inEditor) {54self->active = ACTIVE_BOUNDS;55self->visible = RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2");56self->updateRange.x = 0x800000;57self->updateRange.y = 0x800000;5859RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 0, &self->mainAnimator, true, 0);60RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 1, &self->jointAnimator, true, 0);61RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 2, &self->springAnimator, true, 0);62self->drawGroup = Zone->objectDrawGroup[1];6364switch (self->type) {65case LAUNCHSPRING_SPINNING:66self->timer = 47;67self->state = LaunchSpring_State_Spinning;68break;6970case LAUNCHSPRING_CANNON:71self->state = LaunchSpring_State_Cannon;72self->springAnimator.frameID = 1;73break;7475case LAUNCHSPRING_ROTATE_45DEG:76self->minAngle = self->rotation - 0x40;77self->maxAngle = self->rotation + 0x40;78self->state = LaunchSpring_State_Rotating;79self->springAnimator.frameID = 1;80break;8182case LAUNCHSPRING_ROTATE_90DEG:83self->minAngle = self->rotation - 0x80;84self->maxAngle = self->rotation + 0x80;85self->state = LaunchSpring_State_Rotating;86self->springAnimator.frameID = 1;87break;8889case LAUNCHSPRING_ROTATE_135DEG:90self->minAngle = self->rotation - 0xC0;91self->maxAngle = self->rotation + 0xC0;92self->state = LaunchSpring_State_Rotating;93self->springAnimator.frameID = 1;94break;9596case LAUNCHSPRING_ROTATE_180DEG:97self->minAngle = self->rotation - 0x100;98self->maxAngle = self->rotation + 0x100;99self->state = LaunchSpring_State_Rotating;100self->springAnimator.frameID = 1;101break;102103default: break;104}105106// What's this doin here...? Isn't this supposed to be StageLoad code?107108LaunchSpring->sfxGrab = RSDK.GetSfx("Global/Grab.wav");109110if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2")) {111LaunchSpring->isTMZ = false;112LaunchSpring->sfxClack = RSDK.GetSfx("Stage/Clack.wav");113LaunchSpring->sfxSpeedBooster = RSDK.GetSfx("Stage/SpeedBooster.wav");114}115else if (RSDK.CheckSceneFolder("TMZ1") || RSDK.CheckSceneFolder("TMZ2")) {116LaunchSpring->isTMZ = true;117LaunchSpring->sfxSpeedBooster = RSDK.GetSfx("Stage/CannonFire.wav");118}119}120}121122void LaunchSpring_StageLoad(void)123{124if (RSDK.CheckSceneFolder("SSZ1"))125LaunchSpring->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/LaunchSpring.bin", SCOPE_STAGE);126else if (RSDK.CheckSceneFolder("SSZ2"))127LaunchSpring->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/LaunchSpring.bin", SCOPE_STAGE);128129LaunchSpring->hitbox.top = -24;130LaunchSpring->hitbox.left = -24;131LaunchSpring->hitbox.right = 24;132LaunchSpring->hitbox.bottom = 24;133}134135bool32 LaunchSpring_CheckFireworkActive(EntityPlayer *player)136{137if (!Firework)138return false;139140int32 playerID = RSDK.GetEntitySlot(player);141bool32 fireworkActive = false;142143foreach_active(Firework, firework)144{145if ((1 << playerID) & firework->activePlayers) {146fireworkActive = true;147foreach_break;148}149}150151return fireworkActive;152}153154void LaunchSpring_CheckPlayerCollisions(void *nextState)155{156RSDK_THIS(LaunchSpring);157158foreach_active(Player, player)159{160if (!player->sidekick && !LaunchSpring_CheckFireworkActive(player)) {161if (Player_CheckCollisionTouch(player, self, &LaunchSpring->hitbox)) {162RSDK.PlaySfx(LaunchSpring->sfxGrab, false, 255);163RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);164165player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);166player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);167168player->velocity.x = 0;169player->velocity.y = 0;170player->groundVel = 0;171player->onGround = false;172player->state = Player_State_Static;173player->nextGroundState = StateMachine_None;174player->nextAirState = StateMachine_None;175176self->springAnimator.frameID = 1;177self->playerPtr = player;178self->state = nextState;179foreach_break;180}181}182}183}184185void LaunchSpring_LaunchPlayer(void)186{187RSDK_THIS(LaunchSpring);188189EntityPlayer *player = self->playerPtr;190191if (player->state == Player_State_Static) {192RSDK.PlaySfx(LaunchSpring->sfxSpeedBooster, false, 0xFF);193194if (self->strict) {195self->rotation = (self->rotation + 0x40) & 0x1C0;196197player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);198player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);199}200201player->applyJumpCap = false;202player->jumpAbilityState = 0;203player->velocity.x = RSDK.Cos512(self->rotation - 0x80) << 11;204player->velocity.y = RSDK.Sin512(self->rotation - 0x80) << 11;205player->state = Player_State_Air;206}207}208209void LaunchSpring_State_Spinning(void)210{211RSDK_THIS(LaunchSpring);212213self->rotation = (self->rotation - self->rotSpeed) & 0x1FF;214215LaunchSpring_CheckPlayerCollisions(LaunchSpring_State_Spinning_GrabbedPlayer);216}217218void LaunchSpring_State_Spinning_GrabbedPlayer(void)219{220RSDK_THIS(LaunchSpring);221222EntityPlayer *player = self->playerPtr;223224player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);225player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);226227if (!--self->timer) {228RSDK.PlaySfx(LaunchSpring->sfxClack, false, 0xFF);229self->state = LaunchSpring_State_Spinning_ReadyToFire;230}231}232233void LaunchSpring_State_Spinning_ReadyToFire(void)234{235RSDK_THIS(LaunchSpring);236EntityPlayer *player = self->playerPtr;237238if (player->state == Player_State_Static) {239self->rotation = (self->rotation - self->rotSpeed) & 0x1FF;240241player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);242player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);243244if (player->jumpPress) {245LaunchSpring_LaunchPlayer();246self->state = LaunchSpring_State_Spinning_FiredPlayer;247}248}249else {250self->playerPtr = NULL;251self->state = LaunchSpring_State_Spinning_FiredPlayer;252}253}254255void LaunchSpring_State_Spinning_FiredPlayer(void)256{257RSDK_THIS(LaunchSpring);258259RSDK.ProcessAnimation(&self->springAnimator);260261if (self->springAnimator.frameID == self->springAnimator.frameCount - 1) {262RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 2, &self->springAnimator, true, 0);263self->state = LaunchSpring_State_Spinning_ReadyUp;264}265}266267void LaunchSpring_State_Spinning_ReadyUp(void)268{269RSDK_THIS(LaunchSpring);270271self->timer += 2;272if (self->timer >= 47) {273self->timer = 47;274self->state = LaunchSpring_State_Spinning;275}276}277278void LaunchSpring_State_Cannon(void)279{280RSDK_THIS(LaunchSpring);281282if (self->manual)283LaunchSpring_CheckPlayerCollisions(LaunchSpring_State_Cannon_Fire_Manual);284else285LaunchSpring_CheckPlayerCollisions(LaunchSpring_State_Cannon_Fire_Automatic);286}287288void LaunchSpring_State_Cannon_Fire_Automatic(void)289{290RSDK_THIS(LaunchSpring);291292EntityPlayer *player = self->playerPtr;293294if (player->state == Player_State_Static) {295player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);296player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);297298if (++self->autoFireTimer == 60) {299self->autoFireTimer = 0;300LaunchSpring_LaunchPlayer();301self->state = LaunchSpring_State_Cannon_FiredPlayer;302}303}304else {305self->playerPtr = NULL;306self->state = LaunchSpring_State_Cannon_FiredPlayer;307}308}309310void LaunchSpring_State_Cannon_Fire_Manual(void)311{312RSDK_THIS(LaunchSpring);313314EntityPlayer *player = self->playerPtr;315316if (player->state == Player_State_Static) {317player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);318player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);319320if (player->jumpPress) {321LaunchSpring_LaunchPlayer();322self->autoFireTimer = 0;323self->state = LaunchSpring_State_Cannon_FiredPlayer;324}325}326else {327self->playerPtr = NULL;328self->state = LaunchSpring_State_Cannon_FiredPlayer;329}330}331332void LaunchSpring_State_Cannon_FiredPlayer(void)333{334RSDK_THIS(LaunchSpring);335336if (LaunchSpring->isTMZ) {337if (self->autoFireTimer >= 30)338self->state = LaunchSpring_State_Cannon;339else340self->autoFireTimer++;341}342else {343RSDK.ProcessAnimation(&self->springAnimator);344345if (self->springAnimator.frameID == self->springAnimator.frameCount - 1) {346RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 2, &self->springAnimator, true, 0);347self->springAnimator.frameID = 1;348self->state = LaunchSpring_State_Cannon;349}350}351}352353void LaunchSpring_State_Rotating(void)354{355RSDK_THIS(LaunchSpring);356357if (self->rotDir) {358self->rotation -= self->rotSpeed;359360if (self->rotation <= self->minAngle) {361self->rotDir = 0;362self->rotation = self->minAngle;363}364}365else {366self->rotation += self->rotSpeed;367368if (self->rotation >= self->maxAngle) {369self->rotDir = 1;370self->rotation = self->maxAngle;371}372}373374if (self->manual)375LaunchSpring_CheckPlayerCollisions(LaunchSpring_State_Rotate_Fire_Manual);376else377LaunchSpring_CheckPlayerCollisions(LaunchSpring_State_Rotate_Fire_Automatic);378}379380void LaunchSpring_State_Rotate_Fire_Automatic(void)381{382RSDK_THIS(LaunchSpring);383384EntityPlayer *player = self->playerPtr;385386if (player->state == Player_State_Static) {387if (self->strict)388self->rotation = (self->rotation + 0x20) & 0xC0;389390player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);391player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);392393if (++self->autoFireTimer == 60) {394self->autoFireTimer = 0;395LaunchSpring_LaunchPlayer();396self->state = LaunchSpring_State_Rotating_FiredPlayer;397}398}399else {400self->playerPtr = NULL;401self->state = LaunchSpring_State_Rotating_FiredPlayer;402}403}404405void LaunchSpring_State_Rotate_Fire_Manual(void)406{407RSDK_THIS(LaunchSpring);408EntityPlayer *player = self->playerPtr;409410if (player->state == Player_State_Static) {411if (self->rotDir) {412self->rotation -= self->rotSpeed;413414if (self->rotation <= self->minAngle) {415self->rotation = self->minAngle;416self->rotDir = FLIP_NONE;417}418}419else {420self->rotation += self->rotSpeed;421422if (self->rotation >= self->maxAngle) {423self->rotation = self->maxAngle;424self->rotDir = FLIP_X;425}426}427428player->position.x = self->position.x + (RSDK.Cos512(self->rotation - 0x80) << 12);429player->position.y = self->position.y + (RSDK.Sin512(self->rotation - 0x80) << 12);430431if (player->jumpPress) {432LaunchSpring_LaunchPlayer();433self->state = LaunchSpring_State_Rotating_FiredPlayer;434}435}436else {437self->playerPtr = NULL;438self->state = LaunchSpring_State_Rotating_FiredPlayer;439}440}441442void LaunchSpring_State_Rotating_FiredPlayer(void)443{444RSDK_THIS(LaunchSpring);445446RSDK.ProcessAnimation(&self->springAnimator);447448if (self->springAnimator.frameID == self->springAnimator.frameCount - 1) {449RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 2, &self->springAnimator, true, 0);450self->springAnimator.frameID = 1;451self->state = LaunchSpring_State_Rotating;452}453}454455#if GAME_INCLUDE_EDITOR456void LaunchSpring_EditorDraw(void)457{458RSDK_THIS(LaunchSpring);459460if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2")) {461RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 0, &self->mainAnimator, true, 0);462RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 1, &self->jointAnimator, true, 0);463RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 2, &self->springAnimator, true, 0);464465self->rotation = self->angle << 6;466467LaunchSpring_Draw();468}469else {470RSDK.SetSpriteAnimation(LaunchSpring->aniFrames, 0, &self->mainAnimator, true, 4);471472RSDK.DrawSprite(&self->mainAnimator, NULL, false);473}474}475476void LaunchSpring_EditorLoad(void)477{478if (RSDK.CheckSceneFolder("SSZ1"))479LaunchSpring->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/LaunchSpring.bin", SCOPE_STAGE);480else if (RSDK.CheckSceneFolder("SSZ2"))481LaunchSpring->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/LaunchSpring.bin", SCOPE_STAGE);482else483LaunchSpring->aniFrames = RSDK.LoadSpriteAnimation("Global/PlaneSwitch.bin", SCOPE_STAGE);484485RSDK_ACTIVE_VAR(LaunchSpring, type);486RSDK_ENUM_VAR("Spinning", LAUNCHSPRING_SPINNING);487RSDK_ENUM_VAR("Cannon", LAUNCHSPRING_CANNON);488RSDK_ENUM_VAR("Rotating (45 Degrees)", LAUNCHSPRING_ROTATE_45DEG);489RSDK_ENUM_VAR("Rotating (90 Degrees)", LAUNCHSPRING_ROTATE_90DEG);490RSDK_ENUM_VAR("Rotating (135 Degrees)", LAUNCHSPRING_ROTATE_135DEG);491RSDK_ENUM_VAR("Rotating (180 Degrees)", LAUNCHSPRING_ROTATE_180DEG);492493RSDK_ACTIVE_VAR(LaunchSpring, rotDir);494RSDK_ENUM_VAR("Right", FLIP_NONE);495RSDK_ENUM_VAR("Left", FLIP_X);496497RSDK_ACTIVE_VAR(LaunchSpring, angle);498RSDK_ENUM_VAR("Up", 0);499RSDK_ENUM_VAR("Left", 1);500RSDK_ENUM_VAR("Down", 2);501RSDK_ENUM_VAR("Right", 3);502}503#endif504505void LaunchSpring_Serialize(void)506{507RSDK_EDITABLE_VAR(LaunchSpring, VAR_UINT8, type);508RSDK_EDITABLE_VAR(LaunchSpring, VAR_UINT8, rotDir);509RSDK_EDITABLE_VAR(LaunchSpring, VAR_UINT8, rotSpeed);510RSDK_EDITABLE_VAR(LaunchSpring, VAR_INT32, angle);511RSDK_EDITABLE_VAR(LaunchSpring, VAR_BOOL, manual);512RSDK_EDITABLE_VAR(LaunchSpring, VAR_BOOL, strict);513}514515516