Path: blob/master/SonicMania/Objects/UFO/UFO_Sphere.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: UFO_Sphere Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectUFO_Sphere *UFO_Sphere;1011void UFO_Sphere_Update(void)12{13RSDK_THIS(UFO_Sphere);1415StateMachine_Run(self->state);1617RSDK.ProcessAnimation(&self->animator);18}1920void UFO_Sphere_LateUpdate(void)21{22RSDK_THIS(UFO_Sphere);2324int32 x = self->position.x >> 8;25int32 y = self->height >> 8;26int32 z = self->position.y >> 8;2728Matrix *mat = &UFO_Camera->matWorld;2930self->worldPos.x = mat->values[0][3] + (y * mat->values[0][1] >> 8) + (z * mat->values[0][2] >> 8) + (x * mat->values[0][0] >> 8);31self->worldPos.y = mat->values[1][3] + (y * mat->values[1][1] >> 8) + (z * mat->values[1][2] >> 8) + (x * mat->values[1][0] >> 8);32self->zdepth = mat->values[2][3] + (y * mat->values[2][1] >> 8) + (z * mat->values[2][2] >> 8) + (x * mat->values[2][0] >> 8);33}3435void UFO_Sphere_StaticUpdate(void) {}3637void UFO_Sphere_Draw(void)38{39RSDK_THIS(UFO_Sphere);4041if (self->drawGroup == 4 && self->zdepth >= 0x100) {42self->direction = self->animator.frameID > 8;43self->drawPos.x = (ScreenInfo->center.x + (self->worldPos.x << 8) / self->zdepth) << 16;44self->drawPos.y = (ScreenInfo->center.y - (self->worldPos.y << 8) / self->zdepth) << 16;45self->scale.x = self->scaleFactor / self->zdepth;46self->scale.y = self->scaleFactor / self->zdepth;47}4849RSDK.DrawSprite(&self->animator, &self->drawPos, true);50}5152void UFO_Sphere_Create(void *data)53{54RSDK_THIS(UFO_Sphere);5556if (!SceneInfo->inEditor) {57self->visible = true;58self->drawFX = FX_SCALE | FX_FLIP;59self->drawGroup = 4;60self->active = ACTIVE_RBOUNDS;61self->updateRange.x = 0x400;62self->updateRange.y = 0x400;6364self->scaleFactor = 0x1000000;6566if (!self->height)67self->height = UFO_Sphere->defaultHeights[self->type];68self->height <<= 16;6970switch (self->behavior) {71default:72case UFO_SPHERE_B_NONE: // static73self->state = UFO_Sphere_State_Fixed;74break;7576case UFO_SPHERE_B_BOUNCE:77self->velocity.y = 0x20000;78self->state = UFO_Sphere_State_Bouncing;79break;8081case UFO_SPHERE_B_MOVE:82self->amplitude.x >>= 8;83self->amplitude.y >>= 8;84self->startPos.x = self->position.x;85self->startPos.y = self->position.y;86self->startHeight = self->height;87self->state = UFO_Sphere_State_Moving;8889Matrix matrix;90RSDK.MatrixRotateX(&matrix, self->matAngle.x);91RSDK.MatrixRotateY(&self->matrix, self->matAngle.y);92RSDK.MatrixMultiply(&self->matrix, &matrix, &self->matrix);93break;94}9596RSDK.SetSpriteAnimation(UFO_Sphere->aniFrames, self->type, &self->animator, true, 0);97}98}99100void UFO_Sphere_StageLoad(void)101{102UFO_Sphere->aniFrames = RSDK.LoadSpriteAnimation("SpecialUFO/Spheres.bin", SCOPE_STAGE);103104UFO_Sphere->sfxMachSpeed = RSDK.GetSfx("Special/MachSpeed.wav");105UFO_Sphere->sfxLedgeBreak = RSDK.GetSfx("Stage/LedgeBreak.wav");106}107108void UFO_Sphere_State_Fixed(void)109{110RSDK_THIS(UFO_Sphere);111112switch (self->type) {113case UFO_SPHERE_BLUE: {114foreach_active(UFO_Player, player)115{116int32 rx = (self->position.x - player->position.x) >> 16;117int32 ry = (self->height - player->height - 0xA0000) >> 16;118int32 rz = (self->position.y - player->position.y) >> 16;119120if (rx * rx + ry * ry + rz * rz < UFO_Player->maxSpeed >> 9) {121self->drawGroup = 12;122123self->state = UFO_Sphere_State_Collected;124UFO_Setup_PlaySphereSfx();125}126}127128if (UFO_Setup->machLevel == 2)129self->animator.speed = 1;130break;131}132133case UFO_SPHERE_RED:134// unused135break;136137case UFO_SPHERE_MINE: {138foreach_active(UFO_Player, player)139{140if (player->state != UFO_Player_State_Trip && player->state != UFO_Player_State_Springboard141&& player->state != UFO_Player_State_UFOCaught_Charge && player->state != UFO_Player_State_UFOCaught_Released) {142int32 rx = (self->position.x - player->position.x) >> 16;143int32 ry = (self->height - player->height - 0xA0000) >> 16;144int32 rz = (self->position.y - player->position.y) >> 16;145146if (rx * rx + ry * ry + rz * rz < 0x180) {147RSDK.SetModelAnimation(UFO_Player->tumbleModel, &player->animator, 80, 0, false, 0);148149player->state = UFO_Player_State_Trip;150151if (UFO_Setup->rings > 0)152RSDK.PlaySfx(UFO_Player->sfxLoseRings, false, 255);153154UFO_Ring_LoseRings(player);155156RSDK.SetSpriteAnimation(UFO_Sphere->aniFrames, 4, &self->animator, true, 0);157self->scaleFactor = 0x1800000;158self->state = UFO_Sphere_State_AnimateAndDestroy;159RSDK.PlaySfx(UFO_Sphere->sfxLedgeBreak, false, 255);160}161}162}163break;164}165case UFO_SPHERE_SPIKES: {166foreach_active(UFO_Player, player)167{168if (player->state != UFO_Player_State_Trip && player->state != UFO_Player_State_Springboard169&& player->state != UFO_Player_State_UFOCaught_Charge && player->state != UFO_Player_State_UFOCaught_Released) {170int32 rx = (self->position.x - player->position.x) >> 16;171int32 ry = (self->height - player->height - 0xA0000) >> 16;172int32 rz = (self->position.y - player->position.y) >> 16;173174if (rx * rx + ry * ry + rz * rz < 0x180) {175RSDK.SetModelAnimation(UFO_Player->tumbleModel, &player->animator, 80, 0, false, 0);176177player->state = UFO_Player_State_Trip;178179if (UFO_Setup->rings > 0)180RSDK.PlaySfx(UFO_Player->sfxLoseRings, false, 255);181182UFO_Ring_LoseRings(player);183}184}185}186break;187}188}189}190191void UFO_Sphere_State_Bouncing(void)192{193RSDK_THIS(UFO_Sphere);194195self->velocity.y -= 0x3800;196self->height += self->velocity.y;197198if (self->height < 0xC0000) {199self->velocity.y = 0x20000;200self->height = 0xC0000;201}202203UFO_Sphere_State_Fixed();204}205206void UFO_Sphere_State_Moving(void)207{208RSDK_THIS(UFO_Sphere);209210Matrix *m = &self->matrix;211212self->position.x = self->amplitude.x * RSDK.Cos256(self->angle + (UFO_Setup->timer << self->speed));213self->position.y = self->amplitude.y * RSDK.Sin256(self->angle + (UFO_Setup->timer << self->speed));214self->height = 0;215216self->position.x = m->values[0][3] + (self->position.y >> 8) * m->values[0][2] + m->values[0][0] * (self->position.x >> 8);217self->height = m->values[1][3] + (self->position.y >> 8) * m->values[1][2] + m->values[1][0] * (self->position.x >> 8);218self->position.y = m->values[2][3] + (self->position.y >> 8) * m->values[2][2] + m->values[2][0] * (self->position.x >> 8)219+ m->values[2][1] * (self->height >> 8);220221self->position.x += self->startPos.x;222self->position.y += self->startPos.y;223self->height += self->startHeight;224225UFO_Sphere_State_Fixed();226}227228void UFO_Sphere_State_Collected(void)229{230RSDK_THIS(UFO_Sphere);231232self->drawPos.x += ((((ScreenInfo->center.x - 38) << 16) - self->drawPos.x) >> 3);233self->drawPos.y += ((0x1C0000 - self->drawPos.y) >> 3);234235self->scale.x = self->scale.x + ((0x80 - self->scale.x) >> 3);236self->scale.y = self->scale.x + ((0x80 - self->scale.x) >> 3);237238if (self->drawPos.y < 0x200000) {239++UFO_Setup->machPoints;240UFO_HUD_CheckLevelUp();241242self->timer = UFO_Setup->timer;243self->visible = false;244self->state = UFO_Sphere_State_HandleRespawn;245}246}247248void UFO_Sphere_State_HandleRespawn(void)249{250RSDK_THIS(UFO_Sphere);251252if (abs(self->timer - UFO_Setup->timer) > 240) {253self->visible = true;254self->drawGroup = 4;255256switch (self->behavior) {257default:258case UFO_SPHERE_B_NONE: self->state = UFO_Sphere_State_Fixed; break;259260case UFO_SPHERE_B_BOUNCE: self->state = UFO_Sphere_State_Bouncing; break;261262case UFO_SPHERE_B_MOVE: self->state = UFO_Sphere_State_Moving; break;263}264}265}266267void UFO_Sphere_State_AnimateAndDestroy(void)268{269RSDK_THIS(UFO_Sphere);270271if (self->animator.frameID == self->animator.frameCount - 1)272destroyEntity(self);273}274275#if GAME_INCLUDE_EDITOR276void UFO_Sphere_EditorDraw(void)277{278RSDK_THIS(UFO_Sphere);279280RSDK.SetSpriteAnimation(UFO_Sphere->aniFrames, 5, &self->animator, true, self->type);281282RSDK.DrawSprite(&self->animator, NULL, false);283284if (showGizmos() && self->behavior == UFO_SPHERE_B_MOVE) {285Vector2 amplitude;286287amplitude.x = self->amplitude.x >> 8;288amplitude.y = self->amplitude.y >> 8;289self->startPos.x = self->position.x;290self->startPos.y = self->position.y;291292self->inkEffect = INK_BLEND;293294Vector2 start, end;295296// start pos297self->position.x = amplitude.x * RSDK.Cos256(self->angle) + self->startPos.x;298self->position.y = amplitude.y * RSDK.Sin256(self->angle) + self->startPos.y;299RSDK.DrawSprite(&self->animator, NULL, false);300301// right max302self->position.x = amplitude.x * RSDK.Cos256(0x00) + self->startPos.x;303self->position.y = amplitude.y * RSDK.Sin256(0x00) + self->startPos.y;304start = self->position;305RSDK.DrawSprite(&self->animator, NULL, false);306307// left max308self->position.x = amplitude.x * RSDK.Cos256(0x80) + self->startPos.x;309self->position.y = amplitude.y * RSDK.Sin256(0x80) + self->startPos.y;310end = self->position;311RSDK.DrawSprite(&self->animator, NULL, false);312313DrawHelpers_DrawArrow(start.x, start.y, end.x, end.y, 0x00FF00, INK_NONE, 0xFF);314DrawHelpers_DrawArrow(end.x, end.y, start.x, start.y, 0x00FF00, INK_NONE, 0xFF);315316self->inkEffect = INK_NONE;317}318}319320void UFO_Sphere_EditorLoad(void)321{322UFO_Sphere->aniFrames = RSDK.LoadSpriteAnimation("SpecialUFO/Spheres.bin", SCOPE_STAGE);323324RSDK_ACTIVE_VAR(UFO_Sphere, type);325RSDK_ENUM_VAR("Blue", UFO_SPHERE_BLUE);326RSDK_ENUM_VAR("Red (Unused)", UFO_SPHERE_RED);327RSDK_ENUM_VAR("Mine", UFO_SPHERE_MINE);328RSDK_ENUM_VAR("Spikes", UFO_SPHERE_SPIKES);329330RSDK_ACTIVE_VAR(UFO_Sphere, behavior);331RSDK_ENUM_VAR("None", UFO_SPHERE_B_NONE);332RSDK_ENUM_VAR("Bouncing", UFO_SPHERE_B_BOUNCE);333RSDK_ENUM_VAR("Moving", UFO_SPHERE_B_MOVE);334}335#endif336337void UFO_Sphere_Serialize(void)338{339RSDK_EDITABLE_VAR(UFO_Sphere, VAR_ENUM, type);340RSDK_EDITABLE_VAR(UFO_Sphere, VAR_ENUM, behavior);341RSDK_EDITABLE_VAR(UFO_Sphere, VAR_ENUM, height);342RSDK_EDITABLE_VAR(UFO_Sphere, VAR_ENUM, speed);343RSDK_EDITABLE_VAR(UFO_Sphere, VAR_ENUM, angle);344RSDK_EDITABLE_VAR(UFO_Sphere, VAR_VECTOR2, matAngle);345RSDK_EDITABLE_VAR(UFO_Sphere, VAR_VECTOR2, amplitude);346}347348349