Path: blob/master/SonicMania/Objects/PGZ/Dragonfly.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Dragonfly Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectDragonfly *Dragonfly;1011void Dragonfly_Update(void)12{13RSDK_THIS(Dragonfly);1415StateMachine_Run(self->state);16}1718void Dragonfly_LateUpdate(void) {}1920void Dragonfly_StaticUpdate(void) {}2122void Dragonfly_Draw(void)23{24RSDK_THIS(Dragonfly);2526if (self->animator.animationID == 3) {27RSDK.DrawSprite(&self->animator, NULL, false);28}29else {30for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {31self->bodyAnimator.frameID = i == 0;32self->direction = self->directions[i];33RSDK.DrawSprite(&self->bodyAnimator, &self->positions[i], false);34}3536self->direction = false;37RSDK.DrawSprite(&self->animator, NULL, false);3839self->inkEffect = INK_ALPHA;40RSDK.DrawSprite(&self->wingAnimator, NULL, false);4142self->inkEffect = INK_NONE;43}44}4546void Dragonfly_Create(void *data)47{48RSDK_THIS(Dragonfly);4950self->visible = true;51self->drawGroup = Zone->objectDrawGroup[0];5253if (!SceneInfo->inEditor) {54if (!self->speed) {55self->dist = 0x40;56self->speed = 0x04;57}58self->drawFX |= FX_FLIP;5960if (data) {61self->active = ACTIVE_NORMAL;62self->updateRange.x = 0x100000;63self->updateRange.y = 0x100000;64RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 3, &self->animator, true, 0);65self->state = Dragonfly_State_Debris;66}67else {68self->active = ACTIVE_BOUNDS;69self->updateRange.x = 0x800000;70self->updateRange.y = (self->dist + 0x80) << 16;71self->startPos = self->position;72self->alpha = 0x80;7374RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 2, &self->wingAnimator, true, 0);75RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 3, &self->bodyAnimator, true, 0);76self->state = Dragonfly_State_Init;77}78}79}8081void Dragonfly_StageLoad(void)82{83if (RSDK.CheckSceneFolder("PSZ1"))84Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Dragonfly.bin", SCOPE_STAGE);85else if (RSDK.CheckSceneFolder("PSZ2"))86Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/Dragonfly.bin", SCOPE_STAGE);8788Dragonfly->hitboxBadnik.left = -8;89Dragonfly->hitboxBadnik.top = -8;90Dragonfly->hitboxBadnik.right = 8;91Dragonfly->hitboxBadnik.bottom = 8;9293Dragonfly->hitboxSpine.left = -5;94Dragonfly->hitboxSpine.top = -3;95Dragonfly->hitboxSpine.right = 5;96Dragonfly->hitboxSpine.bottom = 2;9798DEBUGMODE_ADD_OBJ(Dragonfly);99}100101void Dragonfly_DebugDraw(void)102{103RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &DebugMode->animator, true, 0);104RSDK.DrawSprite(&DebugMode->animator, NULL, false);105}106107// rdc would probably not shut the fuck up if i didn't add this /hj108void Dragonfly_CheckOffScreen(void)109{110RSDK_THIS(Dragonfly);111112if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {113self->position.x = self->startPos.x;114self->position.y = self->startPos.y;115Dragonfly_Create(NULL);116}117}118119void Dragonfly_DebugSpawn(void)120{121RSDK_THIS(Dragonfly);122123CREATE_ENTITY(Dragonfly, NULL, self->position.x, self->position.y);124}125126void Dragonfly_CheckPlayerCollisions(void)127{128RSDK_THIS(Dragonfly);129130foreach_active(Player, player)131{132if (Player_CheckBadnikTouch(player, self, &Dragonfly->hitboxBadnik)) {133if (Player_CheckBadnikBreak(player, self, false)) {134for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {135EntityDragonfly *child = CREATE_ENTITY(Dragonfly, INT_TO_VOID(true), self->positions[i].x, self->positions[i].y);136child->animator.frameID = i == 0;137child->velocity.x = RSDK.Rand(-4, 4) << 15;138child->velocity.y = RSDK.Rand(-5, 1) << 15;139}140141destroyEntity(self);142}143}144else {145Vector2 storePos = self->position;146for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {147self->position = self->positions[i];148if (Player_CheckCollisionTouch(player, self, &Dragonfly->hitboxSpine)) {149self->position = storePos;150Player_Hurt(player, self);151}152}153154self->position = storePos;155}156}157}158159void Dragonfly_State_Init(void)160{161RSDK_THIS(Dragonfly);162self->active = ACTIVE_NORMAL;163164if (!self->dir) {165self->angle = 0;166RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &self->animator, true, 0);167}168else {169self->angle = 0x200;170RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 1, &self->animator, true, 0);171}172173self->state = Dragonfly_State_Move;174Dragonfly_State_Move();175}176177void Dragonfly_State_Move(void)178{179RSDK_THIS(Dragonfly);180181self->angle += self->speed;182183self->position.x = self->startPos.x + 0xC00 * RSDK.Cos256(self->angle + 0x40);184self->position.y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(self->angle);185186int32 currentAngle = self->angle - (((DRAGONFLY_SPINE_COUNT * 13) + 13) - 1);187for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {188self->directions[i] = ((currentAngle + 0x100) & 0x3FF) < 0x200 ? 2 : 0;189190self->positions[i].x = self->startPos.x + 0xC00 * RSDK.Cos256(currentAngle + 0x40);191self->positions[i].y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(currentAngle);192193currentAngle += 13;194}195196bool32 dir = ((self->angle + 0x100) & 0x3FF) < 0x200;197if (self->animator.animationID == 1) {198if (dir)199RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &self->animator, true, 0);200}201else if (!dir)202RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 1, &self->animator, true, 0);203204RSDK.ProcessAnimation(&self->animator);205RSDK.ProcessAnimation(&self->wingAnimator);206207Dragonfly_CheckPlayerCollisions();208Dragonfly_CheckOffScreen();209}210211void Dragonfly_State_Debris(void)212{213RSDK_THIS(Dragonfly);214215self->position.x += self->velocity.x;216self->position.y += self->velocity.y;217self->velocity.y += 0x3800;218219self->visible ^= true;220221if (!RSDK.CheckOnScreen(self, NULL))222destroyEntity(self);223}224225#if GAME_INCLUDE_EDITOR226void Dragonfly_EditorDraw(void)227{228RSDK_THIS(Dragonfly);229230self->active = ACTIVE_BOUNDS;231self->updateRange.x = 0x800000;232self->updateRange.y = (self->dist + 0x80) << 16;233self->startPos = self->position;234self->alpha = 0x80;235236RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 2, &self->wingAnimator, true, 0);237RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 3, &self->bodyAnimator, true, 0);238239if (!self->dir) {240self->angle = 0;241RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 0, &self->animator, true, 4);242}243else {244self->angle = 0x200;245RSDK.SetSpriteAnimation(Dragonfly->aniFrames, 1, &self->animator, true, 4);246}247248self->position.x = self->startPos.x + 0xC00 * RSDK.Cos256(self->angle + 0x40);249self->position.y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(self->angle);250251int32 currentAngle = self->angle - (((DRAGONFLY_SPINE_COUNT * 13) + 13) - 1);252for (int32 i = 0; i < DRAGONFLY_SPINE_COUNT; ++i) {253self->directions[i] = ((currentAngle + 0x100) & 0x3FF) < 0x200 ? 2 : 0;254255self->positions[i].x = self->startPos.x + 0xC00 * RSDK.Cos256(currentAngle + 0x40);256self->positions[i].y = self->startPos.y + (self->dist << 6) * RSDK.Sin1024(currentAngle);257currentAngle += 13;258}259260Dragonfly_Draw();261262self->position = self->startPos;263}264265void Dragonfly_EditorLoad(void)266{267if (RSDK.CheckSceneFolder("PSZ1"))268Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Dragonfly.bin", SCOPE_STAGE);269else if (RSDK.CheckSceneFolder("PSZ2"))270Dragonfly->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/Dragonfly.bin", SCOPE_STAGE);271272RSDK_ACTIVE_VAR(Dragonfly, dir);273RSDK_ENUM_VAR("Down", FLIP_NONE);274RSDK_ENUM_VAR("Up", FLIP_X);275}276#endif277278void Dragonfly_Serialize(void)279{280RSDK_EDITABLE_VAR(Dragonfly, VAR_UINT8, dir);281RSDK_EDITABLE_VAR(Dragonfly, VAR_UINT8, dist);282RSDK_EDITABLE_VAR(Dragonfly, VAR_UINT8, speed);283}284285