Path: blob/master/SonicMania/Objects/UFO/UFO_Ring.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: UFO_Ring Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectUFO_Ring *UFO_Ring;1011void UFO_Ring_Update(void)12{13RSDK_THIS(UFO_Ring);14StateMachine_Run(self->state);15}1617void UFO_Ring_LateUpdate(void)18{19RSDK_THIS(UFO_Ring);2021int32 x = self->position.x >> 8;22int32 y = self->height >> 8;23int32 z = self->position.y >> 8;2425Matrix *m = &UFO_Camera->matWorld;2627self->worldX = m->values[0][3] + (y * m->values[0][1] >> 8) + (z * m->values[0][2] >> 8) + (x * m->values[0][0] >> 8);28self->worldY = m->values[1][3] + (y * m->values[1][1] >> 8) + (z * m->values[1][2] >> 8) + (x * m->values[1][0] >> 8);29self->zdepth = m->values[2][3] + (y * m->values[2][1] >> 8) + (z * m->values[2][2] >> 8) + (x * m->values[2][0] >> 8);30}3132void UFO_Ring_StaticUpdate(void) {}3334void UFO_Ring_Draw(void)35{36RSDK_THIS(UFO_Ring);3738if (self->zdepth >= 0x100) {39self->direction = self->animator.frameID > 8;4041Vector2 drawPos;42drawPos.x = (ScreenInfo->center.x + (self->worldX << 8) / self->zdepth) << 16;43drawPos.y = (ScreenInfo->center.y - (self->worldY << 8) / self->zdepth) << 16;4445self->scale.x = 0x1000000 / self->zdepth;46self->scale.y = 0x1000000 / self->zdepth;47if (self->state == UFO_Ring_State_NormalRing)48self->animator.frameID = UFO_Setup->ringFrame;4950RSDK.DrawSprite(&self->animator, &drawPos, true);51}52}5354void UFO_Ring_Create(void *data)55{56RSDK_THIS(UFO_Ring);5758if (!SceneInfo->inEditor) {59self->visible = true;60self->drawFX = FX_FLIP | FX_SCALE;61self->drawGroup = 4;62self->active = ACTIVE_RBOUNDS;63self->updateRange.x = 0x400;64self->updateRange.y = 0x400;6566if (!self->height)67self->height = 12;68self->height <<= 16;6970self->state = UFO_Ring_State_NormalRing;7172RSDK.SetSpriteAnimation(UFO_Ring->aniFrames, 1, &self->animator, true, 0);73}74}7576void UFO_Ring_StageLoad(void)77{78UFO_Ring->aniFrames = RSDK.LoadSpriteAnimation("Global/Ring.bin", SCOPE_STAGE);7980UFO_Ring->sfxRing = RSDK.GetSfx("Global/Ring.wav");81}8283void UFO_Ring_PlayRingSfx(void)84{85if (UFO_Setup->rings < 999)86UFO_Setup->rings++;8788if (UFO_Setup->ringPan) {89int32 channel = RSDK.PlaySfx(UFO_Ring->sfxRing, false, 0xFF);90RSDK.SetChannelAttributes(channel, 1.0, -1.0, 1.0);91UFO_Setup->ringPan = 0;92}93else {94int32 channel = RSDK.PlaySfx(UFO_Ring->sfxRing, false, 0xFF);95RSDK.SetChannelAttributes(channel, 1.0, 1.0, 1.0);96UFO_Setup->ringPan = 1;97}98}99100void UFO_Ring_LoseRings(EntityUFO_Player *player)101{102int32 ringCount = CLAMP(UFO_Setup->rings, 0, 10);103104UFO_Setup->rings -= 10;105if (UFO_Setup->rings < 0)106UFO_Setup->rings = 0;107108for (int32 r = 0; r < ringCount; ++r) {109EntityUFO_Ring *ring = CREATE_ENTITY(UFO_Ring, NULL, player->position.x, player->position.y);110111ring->height = player->height + 0x80000;112ring->velocity.x = player->velocity.x + RSDK.Rand(-0x40000, 0x40000);113ring->velocity.y = player->velocity.y + RSDK.Rand(-0x40000, 0x40000);114ring->bounceVelocity = RSDK.Rand(0x40000, 0x60000);115ring->inkEffect = INK_ALPHA;116ring->alpha = 0x200;117ring->animator.speed = 0x100;118ring->state = UFO_Ring_State_LoseRing;119}120}121122void UFO_Ring_State_NormalRing(void)123{124RSDK_THIS(UFO_Ring);125126foreach_active(UFO_Player, player)127{128int32 rx = (self->position.x - player->position.x) >> 16;129int32 ry = (self->height - player->height - 0xA0000) >> 16;130int32 rz = (self->position.y - player->position.y) >> 16;131132if (rx * rx + ry * ry + rz * rz < UFO_Player->maxSpeed >> 9) {133RSDK.SetSpriteAnimation(UFO_Ring->aniFrames, 2, &self->animator, true, 4);134++self->drawGroup;135self->state = UFO_Ring_State_Sparkle;136UFO_Ring_PlayRingSfx();137}138}139}140141void UFO_Ring_State_Sparkle(void)142{143RSDK_THIS(UFO_Ring);144145RSDK.ProcessAnimation(&self->animator);146147if (self->animator.frameID == self->animator.frameCount - 1)148destroyEntity(self);149}150151void UFO_Ring_State_LoseRing(void)152{153RSDK_THIS(UFO_Ring);154155RSDK.ProcessAnimation(&self->animator);156157self->position.x += self->velocity.x;158self->position.y += self->velocity.y;159self->bounceVelocity -= 0x3800;160161self->height += self->bounceVelocity;162if (self->height < 0xC0000 && self->bounceVelocity < 0) {163self->height = 0xC0000;164self->bounceVelocity = -(self->bounceVelocity >> 1);165}166167if (self->animator.speed > 0x40)168self->animator.speed--;169170self->alpha -= 4;171if (!self->alpha)172destroyEntity(self);173}174175#if GAME_INCLUDE_EDITOR176void UFO_Ring_EditorDraw(void)177{178RSDK_THIS(UFO_Ring);179180RSDK.SetSpriteAnimation(UFO_Ring->aniFrames, 0, &self->animator, true, 0);181RSDK.DrawSprite(&self->animator, NULL, false);182}183184void UFO_Ring_EditorLoad(void) { UFO_Ring->aniFrames = RSDK.LoadSpriteAnimation("Global/Ring.bin", SCOPE_STAGE); }185#endif186187void UFO_Ring_Serialize(void) { RSDK_EDITABLE_VAR(UFO_Ring, VAR_ENUM, height); }188189190