Path: blob/master/SonicMania/Objects/CPZ/Spiny.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Spiny Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectSpiny *Spiny;1011void Spiny_Update(void)12{13RSDK_THIS(Spiny);1415StateMachine_Run(self->state);16}1718void Spiny_LateUpdate(void) {}1920void Spiny_StaticUpdate(void) {}2122void Spiny_Draw(void)23{24RSDK_THIS(Spiny);2526RSDK.DrawSprite(&self->animator, NULL, false);27}2829void Spiny_Create(void *data)30{31RSDK_THIS(Spiny);3233self->visible = true;34self->drawGroup = Zone->objectDrawGroup[0];35self->active = ACTIVE_BOUNDS;36self->updateRange.x = 0x800000;37self->updateRange.y = 0x800000;3839if (data) {40self->drawGroup = Zone->objectDrawGroup[0] - 1;41RSDK.SetSpriteAnimation(Spiny->aniFrames, 4, &self->animator, true, 0);42self->state = Spiny_State_Shot;43}44else {45self->startPos = self->position;46self->startDir = self->direction;47self->drawFX = FX_FLIP;4849if (self->type == SPINY_FLOOR) {50RSDK.SetSpriteAnimation(Spiny->aniFrames, 0, &self->animator, true, 0);51self->state = Spiny_State_Init;5253if (!(self->direction & FLIP_X))54self->velocity.x = -0x4000;55else56self->velocity.x = 0x4000;57}58else {59RSDK.SetSpriteAnimation(Spiny->aniFrames, 2, &self->animator, true, 0);60self->state = Spiny_State_Init;6162if (!(self->direction & FLIP_Y))63self->velocity.y = -0x4000;64else65self->velocity.y = 0x4000;66}67}68}6970void Spiny_StageLoad(void)71{72Spiny->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Spiny.bin", SCOPE_STAGE);7374Spiny->hitboxSpiny.left = -12;75Spiny->hitboxSpiny.top = -15;76Spiny->hitboxSpiny.right = 12;77Spiny->hitboxSpiny.bottom = 15;7879Spiny->hitboxRange.left = -96;80Spiny->hitboxRange.top = -256;81Spiny->hitboxRange.right = 96;82Spiny->hitboxRange.bottom = 256;8384Spiny->hitboxShot.left = -4;85Spiny->hitboxShot.top = -4;86Spiny->hitboxShot.right = 4;87Spiny->hitboxShot.bottom = 4;8889DEBUGMODE_ADD_OBJ(Spiny);9091Spiny->sfxShot = RSDK.GetSfx("Stage/Shot.wav");92}9394void Spiny_DebugSpawn(void)95{96RSDK_THIS(Spiny);9798EntitySpiny *spiny = CREATE_ENTITY(Spiny, NULL, self->position.x, self->position.y);99spiny->direction = self->direction;100}101102void Spiny_DebugDraw(void)103{104RSDK.SetSpriteAnimation(Spiny->aniFrames, 0, &DebugMode->animator, true, 0);105RSDK.DrawSprite(&DebugMode->animator, NULL, false);106}107108void Spiny_CheckPlayerCollisions(void)109{110RSDK_THIS(Spiny);111112foreach_active(Player, player)113{114if (Player_CheckBadnikTouch(player, self, &Spiny->hitboxSpiny))115Player_CheckBadnikBreak(player, self, true);116}117}118119void Spiny_CheckOffScreen(void)120{121RSDK_THIS(Spiny);122123if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {124self->position = self->startPos;125self->dirChangeTimer = 0;126self->moveTimer = 128;127self->direction = self->startDir;128Spiny_Create(NULL);129}130}131132void Spiny_State_Init(void)133{134RSDK_THIS(Spiny);135136self->active = ACTIVE_NORMAL;137if (self->type == SPINY_FLOOR) {138self->state = Spiny_State_Floor;139Spiny_State_Floor();140}141else {142self->state = Spiny_State_Wall;143Spiny_State_Wall();144}145}146147void Spiny_State_Floor(void)148{149RSDK_THIS(Spiny);150151RSDK.ProcessAnimation(&self->animator);152153if (++self->dirChangeTimer >= 256) {154self->dirChangeTimer = 0;155self->direction ^= FLIP_X;156self->moveTimer = 128;157self->velocity.x = -self->velocity.x;158}159160int32 distance = 0x7FFFFFFF;161self->position.x += self->velocity.x;162163if (!self->moveTimer) {164foreach_active(Player, player)165{166if (Player_CheckCollisionTouch(player, self, &Spiny->hitboxRange)) {167self->moveTimer = 40;168self->state = Spiny_State_Shoot_Floor;169RSDK.SetSpriteAnimation(Spiny->aniFrames, 1, &self->animator, true, 0);170171if (abs(player->position.x - self->position.x) < distance) {172distance = abs(player->position.x - self->position.x);173if (player->position.x > self->position.x)174self->shotVelocity = 0x10000;175else176self->shotVelocity = -0x10000;177}178}179}180}181else {182self->moveTimer--;183}184185Spiny_CheckPlayerCollisions();186Spiny_CheckOffScreen();187}188189void Spiny_State_Shoot_Floor(void)190{191RSDK_THIS(Spiny);192193RSDK.ProcessAnimation(&self->animator);194195if (--self->moveTimer == 20) {196RSDK.PlaySfx(Spiny->sfxShot, false, 0xFF);197198EntitySpiny *shot = CREATE_ENTITY(Spiny, INT_TO_VOID(true), self->position.x, self->position.y);199shot->velocity.x = self->shotVelocity;200if (!(self->direction & 2))201shot->velocity.y = -0x30000;202else203shot->velocity.y = 0x20000;204}205else {206if (self->moveTimer < 0) {207RSDK.SetSpriteAnimation(Spiny->aniFrames, 0, &self->animator, true, 0);208self->moveTimer = 64;209self->state = Spiny_State_Floor;210}211}212213Spiny_CheckPlayerCollisions();214Spiny_CheckOffScreen();215}216217void Spiny_State_Wall(void)218{219RSDK_THIS(Spiny);220221RSDK.ProcessAnimation(&self->animator);222223if (++self->dirChangeTimer >= 256) {224self->dirChangeTimer = 0;225self->direction ^= FLIP_Y;226self->moveTimer = 128;227self->velocity.y = -self->velocity.y;228}229230self->position.y += self->velocity.y;231232if (!self->moveTimer) {233foreach_active(Player, player)234{235if (Player_CheckCollisionTouch(player, self, &Spiny->hitboxRange)) {236self->moveTimer = 40;237self->state = Spiny_State_Shoot_Wall;238RSDK.SetSpriteAnimation(Spiny->aniFrames, 3, &self->animator, true, 0);239240if (!(self->direction & 1))241self->shotVelocity = -0x30000;242else243self->shotVelocity = 0x30000;244}245}246}247else {248self->moveTimer--;249}250251Spiny_CheckPlayerCollisions();252Spiny_CheckOffScreen();253}254255void Spiny_State_Shoot_Wall(void)256{257RSDK_THIS(Spiny);258259RSDK.ProcessAnimation(&self->animator);260261if (--self->moveTimer == 20) {262RSDK.PlaySfx(Spiny->sfxShot, false, 0xFF);263CREATE_ENTITY(Spiny, INT_TO_VOID(true), self->position.x, self->position.y)->velocity.x = self->shotVelocity;264}265else {266if (self->moveTimer < 0) {267RSDK.SetSpriteAnimation(Spiny->aniFrames, 2, &self->animator, true, 0);268self->moveTimer = 64;269self->state = Spiny_State_Wall;270}271}272273Spiny_CheckPlayerCollisions();274Spiny_CheckOffScreen();275}276277void Spiny_State_Shot(void)278{279RSDK_THIS(Spiny);280281self->position.x += self->velocity.x;282self->position.y += self->velocity.y;283self->velocity.y += 0x2000;284285if (RSDK.CheckOnScreen(self, &self->updateRange)) {286RSDK.ProcessAnimation(&self->animator);287288if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0, true)) {289self->inkEffect |= INK_ADD;290self->alpha = 0x100;291self->state = Spiny_State_ShotDisappear;292}293294foreach_active(Player, player)295{296if (Player_CheckCollisionTouch(player, self, &Spiny->hitboxShot))297Player_ProjectileHurt(player, self);298}299}300else {301destroyEntity(self);302}303}304305void Spiny_State_ShotDisappear(void)306{307RSDK_THIS(Spiny);308309RSDK.ProcessAnimation(&self->animator);310311self->position.x += self->velocity.x;312self->position.y += self->velocity.y;313314self->alpha -= 0x20;315if (self->alpha <= 0)316destroyEntity(self);317}318319#if GAME_INCLUDE_EDITOR320void Spiny_EditorDraw(void)321{322RSDK_THIS(Spiny);323self->drawFX = FX_FLIP;324325if (self->type == SPINY_FLOOR)326RSDK.SetSpriteAnimation(Spiny->aniFrames, 0, &self->animator, false, 0);327else328RSDK.SetSpriteAnimation(Spiny->aniFrames, 2, &self->animator, false, 0);329330Spiny_Draw();331}332333void Spiny_EditorLoad(void)334{335Spiny->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Spiny.bin", SCOPE_STAGE);336337RSDK_ACTIVE_VAR(Spiny, type);338RSDK_ENUM_VAR("Floor", SPINY_FLOOR);339RSDK_ENUM_VAR("Wall", SPINY_WALL);340341RSDK_ACTIVE_VAR(Spiny, direction);342RSDK_ENUM_VAR("No Flip", FLIP_NONE);343RSDK_ENUM_VAR("Flip X", FLIP_X);344RSDK_ENUM_VAR("Flip Y", FLIP_Y);345RSDK_ENUM_VAR("Flip XY", FLIP_XY);346}347#endif348349void Spiny_Serialize(void)350{351RSDK_EDITABLE_VAR(Spiny, VAR_UINT8, type);352RSDK_EDITABLE_VAR(Spiny, VAR_UINT8, direction);353}354355356