Path: blob/master/SonicMania/Objects/LRZ/KingAttack.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: KingAttack Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectKingAttack *KingAttack;1011void KingAttack_Update(void)12{13RSDK_THIS(KingAttack);1415StateMachine_Run(self->state);16}1718void KingAttack_LateUpdate(void) {}1920void KingAttack_StaticUpdate(void) {}2122void KingAttack_Draw(void)23{24RSDK_THIS(KingAttack);2526int32 x = ScreenInfo->position.x << 16;27int32 y = ScreenInfo->position.y << 16;2829switch (self->type) {30case KINGATTACK_LASER:31for (int32 i = 0; i < 6; i += 2) {32Vector2 vertices[4];33color colors[4];3435vertices[0].x = self->laserVertPostions[i].x - x;36vertices[0].y = self->laserVertPostions[i].y - y;37colors[0] = self->laserColors[i];3839vertices[1].x = self->laserVertPostions[i + 1].x - x;40vertices[1].y = self->laserVertPostions[i + 1].y - y;41colors[1] = self->laserColors[i + 1];4243vertices[2].x = self->laserVertPostions[i + 3].x - x;44vertices[2].y = self->laserVertPostions[i + 3].y - y;45colors[2] = self->laserColors[i + 3];4647vertices[3].x = self->laserVertPostions[i + 2].x - x;48vertices[3].y = self->laserVertPostions[i + 2].y - y;49colors[3] = self->laserColors[i + 2];5051RSDK.DrawBlendedFace(vertices, colors, 4, self->alpha, INK_ADD);52}53//[Fallthrough]54default: RSDK.DrawSprite(&self->animator, NULL, false); break;5556case KINGATTACK_ENERGYLINE:57RSDK.DrawLine(self->position.x, self->position.y, self->targetPos.x, self->targetPos.y, 0x0080F0, self->alpha, INK_ADD, false);58break;59}60}6162void KingAttack_Create(void *data)63{64RSDK_THIS(KingAttack);6566if (!SceneInfo->inEditor) {67self->drawGroup = Zone->objectDrawGroup[1];68self->active = ACTIVE_NORMAL;69self->updateRange.x = 0x800000;70self->updateRange.y = 0x800000;71self->type = VOID_TO_INT(data);7273switch (self->type) {74case KINGATTACK_LASER:75self->inkEffect = INK_ADD;76self->visible = true;77self->laserColors = KingAttack->laserColors;78self->state = KingAttack_State_Laser;7980KingAttack->laserEruptActive = false;8182RSDK.PlaySfx(KingAttack->sfxLaserSweep, false, 255);83RSDK.SetSpriteAnimation(KingAttack->aniFrames, 21, &self->animator, true, 0);84break;8586case KINGATTACK_LASERBLAST:87RSDK.SetSpriteAnimation(KingAttack->aniFrames, 23, &self->animator, true, 0);88self->state = KingAttack_State_LaserBlast_Delay;89self->drawFX = FX_FLIP;9091self->hitbox.left = -16;92self->hitbox.top = -64;93self->hitbox.right = 16;94self->hitbox.bottom = 0;95break;9697case KINGATTACK_ORBIT:98self->drawFX = FX_SCALE;99self->visible = true;100RSDK.SetSpriteAnimation(KingAttack->aniFrames, 20, &self->animator, true, RSDK.Rand(0, 6));101102self->state = KingAttack_State_OrbitAppear;103104self->hitbox.left = -10;105self->hitbox.top = -10;106self->hitbox.right = 10;107self->hitbox.bottom = 10;108break;109110case KINGATTACK_TRAIL:111self->drawGroup = Zone->objectDrawGroup[0];112self->inkEffect = INK_ADD;113self->visible = true;114self->alpha = 0xC0;115RSDK.SetSpriteAnimation(KingAttack->aniFrames, 24, &self->animator, true, 0);116117self->state = KingAttack_State_Trail;118break;119120case KINGATTACK_LARGEBULLET:121self->drawFX = FX_SCALE;122self->visible = true;123124RSDK.SetSpriteAnimation(KingAttack->aniFrames, 20, &self->animator, true, RSDK.Rand(0, 6));125126self->scale.x = 0x100;127self->scale.y = 0x100;128self->state = KingAttack_State_LargeBullet_Appear;129break;130131case KINGATTACK_ENERGYLINE:132self->drawGroup = Zone->objectDrawGroup[0];133self->visible = true;134135self->state = KingAttack_State_EnergyLine;136137self->angle = RSDK.Rand(0, 256);138self->timer = 0x4000;139self->alpha = 0x100;140break;141142case KINGATTACK_SMALLBULLET:143self->drawGroup = Zone->objectDrawGroup[0];144self->drawFX = FX_ROTATE;145self->visible = true;146147RSDK.SetSpriteAnimation(KingAttack->aniFrames, 21, &self->animator, true, 0);148self->state = KingAttack_State_SmallBullet;149150self->hitbox.left = -4;151self->hitbox.top = -4;152self->hitbox.right = 4;153self->hitbox.bottom = 4;154break;155156default: break;157}158}159}160161void KingAttack_StageLoad(void)162{163KingAttack->aniFrames = RSDK.LoadSpriteAnimation("LRZ3/HeavyKing.bin", SCOPE_STAGE);164165KingAttack->sfxLaserSweep = RSDK.GetSfx("LRZ/LaserSweep.wav");166KingAttack->sfxLaserErupt = RSDK.GetSfx("LRZ/LaserErupt.wav");167168KingAttack->laserEruptActive = false;169170KingAttack->sfxElecPulse = RSDK.GetSfx("Stage/ElecPulse.wav");171KingAttack->sfxTwinShot = RSDK.GetSfx("LRZ/TwinShot.wav");172173int32 sfxID = Soundboard_LoadSfx("LRZ/ElecIdle.wav", true, KingAttack_SfxCheck_ElecIdle, StateMachine_None);174if (sfxID >= 0)175Soundboard->sfxFadeOutDuration[sfxID] = 30;176}177178bool32 KingAttack_SfxCheck_ElecIdle(void)179{180int32 count = 0;181182foreach_active(KingAttack, attack)183{184if (attack->type == KINGATTACK_ORBIT)185count++;186}187188return count > 0;189}190191void KingAttack_CheckPlayerCollisions(void)192{193RSDK_THIS(KingAttack);194195foreach_active(Player, player)196{197if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {198Player_Hurt(player, self);199}200}201}202203void KingAttack_HandleLaserPositions(void)204{205RSDK_THIS(KingAttack);206207EntityHeavyKing *king = (EntityHeavyKing *)self->parent;208209int32 x = 0;210if (king->direction)211x = king->position.x - 0x240000;212else213x = king->position.x + 0x240000;214int32 y = king->position.y - 0x300000;215216self->laserVertPostions[0].x = x - 0x40000;217self->laserVertPostions[1].x = self->position.x - 0x40000;218self->laserVertPostions[2].x = x - 0x20000;219self->laserVertPostions[3].x = self->position.x - 0x20000;220self->laserVertPostions[4].x = x + 0x20000;221self->laserVertPostions[5].x = self->position.x + 0x20000;222self->laserVertPostions[6].x = x + 0x40000;223self->laserVertPostions[7].x = self->position.x + 0x40000;224225self->laserVertPostions[0].y = y;226self->laserVertPostions[1].y = HeavyKing->spinRaySpawnPos;227self->laserVertPostions[2].y = y;228self->laserVertPostions[3].y = HeavyKing->spinRaySpawnPos;229self->laserVertPostions[4].y = y;230self->laserVertPostions[5].y = HeavyKing->spinRaySpawnPos;231self->laserVertPostions[6].y = y;232self->laserVertPostions[7].y = HeavyKing->spinRaySpawnPos;233}234235void KingAttack_State_Laser(void)236{237RSDK_THIS(KingAttack);238239RSDK.ProcessAnimation(&self->animator);240241self->position.x += self->velocity.x;242++self->timer;243244KingAttack_HandleLaserPositions();245246if (self->timer < 16) {247if (self->alpha < 0xC0)248self->alpha += 0x10;249}250else if (self->timer > 48) {251if (self->alpha > 0)252self->alpha -= 0x10;253}254255if (!(self->timer & 3)) {256EntityKingAttack *attack = CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_LASERBLAST), self->position.x, self->position.y);257attack->direction = (self->timer >> 3) & 1;258}259260if (self->timer == 64)261destroyEntity(self);262}263264void KingAttack_State_LaserBlast_Delay(void)265{266RSDK_THIS(KingAttack);267268if (++self->timer == 30) {269self->timer = 0;270self->visible = true;271272if (KingAttack->laserEruptActive) {273KingAttack->laserEruptActive = false;274}275else {276Camera_ShakeScreen(0, 0, 5);277RSDK.PlaySfx(KingAttack->sfxLaserErupt, false, 255);278KingAttack->laserEruptActive = true;279}280281self->state = KingAttack_State_LaserBlast_Erupt;282}283}284285void KingAttack_State_LaserBlast_Erupt(void)286{287RSDK_THIS(KingAttack);288289RSDK.ProcessAnimation(&self->animator);290291if (self->animator.frameID > 8 && self->animator.frameID < 16)292KingAttack_CheckPlayerCollisions();293294if (self->animator.frameID == self->animator.frameCount - 1)295destroyEntity(self);296}297298void KingAttack_State_OrbitAppear(void)299{300RSDK_THIS(KingAttack);301302EntityHeavyKing *king = (EntityHeavyKing *)self->parent;303304RSDK.ProcessAnimation(&self->animator);305306self->angle = (self->angle + 12) & 0x3FF;307if (self->scale.x < 512) {308self->scale.x += 0x20;309self->scale.y = self->scale.x;310}311312self->velocity.x = self->position.x;313self->velocity.y = self->position.y;314315int32 x = 0;316if (king->direction)317x = RSDK.Cos1024(self->angle) - 0x240;318else319x = RSDK.Cos1024(self->angle) + 0x240;320321self->position.x = (x << 12) + king->position.x;322self->position.y = (((RSDK.Sin1024(self->angle) - 0x300) << 12) + king->position.y);323324self->velocity.x = self->position.x - self->velocity.x;325self->velocity.y = self->position.y - self->velocity.y;326327KingAttack_CheckPlayerCollisions();328329if (++self->timer == 120) {330self->timer = 0;331self->targetPos = king->position;332self->state = KingAttack_State_Orbiting;333}334}335336void KingAttack_State_Orbiting(void)337{338RSDK_THIS(KingAttack);339340EntityHeavyKing *king = (EntityHeavyKing *)self->parent;341342RSDK.ProcessAnimation(&self->animator);343344self->position.x += king->position.x - self->targetPos.x;345self->position.y += king->position.y - self->targetPos.y;346347if (self->position.x <= king->position.x) {348if (self->position.x < king->position.x)349self->velocity.x += 0x4000;350}351else {352self->velocity.x -= 0x4000;353}354355if (self->position.y <= king->position.y) {356if (self->position.y < king->position.y)357self->velocity.y += 0x3800;358}359else {360self->velocity.y -= 0x3800;361}362363if (self->velocity.x >= -0x50000) {364if (self->velocity.x > 0x50000)365self->velocity.x = 0x50000;366}367else {368self->velocity.x = -0x50000;369}370371if (self->velocity.y >= -0x50000) {372if (self->velocity.y > 0x50000)373self->velocity.y = 0x50000;374}375else {376self->velocity.y = -0x50000;377}378379self->position.x += self->velocity.x;380self->position.y += self->velocity.y;381382self->targetPos = king->position;383384self->angle = (self->angle + 12) & 0x3FF;385386self->scale.x += (0x180 - self->scale.x - (RSDK.Sin1024(self->angle) >> 3)) >> 3;387self->scale.y = self->scale.x;388389KingAttack_CheckPlayerCollisions();390391if (self->angle < 512)392self->drawGroup = Zone->objectDrawGroup[0] - 1;393else394self->drawGroup = Zone->objectDrawGroup[0];395}396397void KingAttack_State_OrbitLaunched(void)398{399RSDK_THIS(KingAttack);400401RSDK.ProcessAnimation(&self->animator);402403++self->timer;404if (!(self->timer & 3))405CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_TRAIL), self->position.x, self->position.y);406407if (self->scale.x < 512) {408self->scale.x += 0x20;409self->scale.y = self->scale.x;410}411412self->velocity.x += ((self->targetVelocity.x - self->velocity.x) >> 3);413self->velocity.y += ((self->targetVelocity.y - self->velocity.y) >> 3);414415self->position.x += self->velocity.x;416self->position.y += self->velocity.y;417418KingAttack_CheckPlayerCollisions();419420if (!RSDK.CheckOnScreen(self, NULL))421destroyEntity(self);422}423424void KingAttack_State_Trail(void)425{426RSDK_THIS(KingAttack);427428if (self->timer++ >= 8) {429self->alpha -= 8;430431if (self->alpha <= 0)432destroyEntity(self);433}434}435436void KingAttack_State_LargeBullet_Appear(void)437{438RSDK_THIS(KingAttack);439440EntityHeavyKing *king = (EntityHeavyKing *)self->parent;441442RSDK.ProcessAnimation(&self->animator);443444if (self->scale.x < 0x400)445self->scale.x += 4;446447self->scale.y = self->scale.x;448449++self->timer;450451self->position = king->position;452if (king->direction)453self->position.x -= 0x240000;454else455self->position.x += 0x240000;456self->position.y -= 0x300000;457458if (!(self->timer & 3)) {459EntityKingAttack *attack = CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_ENERGYLINE), self->position.x, self->position.y);460attack->parent = (Entity *)self;461}462463if (self->timer == 120) {464self->timer = 0;465self->state = KingAttack_State_LargeBullet_TwinShot;466}467}468469void KingAttack_State_EnergyLine(void)470{471RSDK_THIS(KingAttack);472473EntityKingAttack *parent = (EntityKingAttack *)self->parent;474475self->position.x = self->timer * RSDK.Cos256(self->angle);476self->position.y = self->timer * RSDK.Sin256(self->angle);477478self->targetPos.x = self->position.x - (self->position.x >> 3);479self->targetPos.y = self->position.y - (self->position.y >> 3);480481self->position.x += parent->position.x;482self->position.y += parent->position.y;483484self->targetPos.x += parent->position.x;485self->targetPos.y += parent->position.y;486487self->alpha -= 16;488self->timer -= 0x200;489490if (self->timer < 0x400)491destroyEntity(self);492}493494void KingAttack_State_LargeBullet_TwinShot(void)495{496RSDK_THIS(KingAttack);497498EntityHeavyKing *king = (EntityHeavyKing *)self->parent;499500RSDK.ProcessAnimation(&self->animator);501502self->position = king->position;503504if (king->direction)505self->position.x -= 0x240000;506else507self->position.x += 0x240000;508self->position.y -= 0x300000;509510++self->timer;511if (!(self->timer & 6))512RSDK.PlaySfx(KingAttack->sfxTwinShot, false, 255);513514if (!(self->timer & 3)) {515EntityKingAttack *attack = CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_SMALLBULLET), self->position.x, self->position.y);516attack->velocity.x = RSDK.Sin1024(self->angle) << 9;517attack->velocity.y = RSDK.Cos1024(self->angle) << 9;518attack->rotation = self->angle >> 1;519520attack = CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_SMALLBULLET), self->position.x, self->position.y);521attack->velocity.x = RSDK.Sin1024(self->angle + 0x200) << 9;522attack->velocity.y = RSDK.Cos1024(self->angle + 0x200) << 9;523attack->rotation = self->angle >> 1;524}525526self->angle += 4;527if (self->timer > 60) {528self->scale.x -= 4;529self->scale.y = self->scale.x;530531if (!self->scale.x)532destroyEntity(self);533}534}535536void KingAttack_State_SmallBullet(void)537{538RSDK_THIS(KingAttack);539540RSDK.ProcessAnimation(&self->animator);541542self->rotation = (self->rotation + 16) & 0x1FF;543544self->position.x += self->velocity.x;545self->position.y += self->velocity.y;546547KingAttack_CheckPlayerCollisions();548549foreach_active(HPZEmerald, emerald)550{551if (emerald->type && RSDK.CheckObjectCollisionPlatform(emerald, emerald->hitbox, self, &self->hitbox, true)) {552RSDK.SetSpriteAnimation(KingAttack->aniFrames, 22, &self->animator, false, 0);553self->position.y += 0x40000;554self->state = KingAttack_State_SmallBullet_Impact;555foreach_break;556}557}558559if (self->state == KingAttack_State_SmallBullet) {560if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x40000, true)) {561RSDK.SetSpriteAnimation(KingAttack->aniFrames, 22, &self->animator, false, 0);562self->state = KingAttack_State_SmallBullet_Impact;563self->position.y += 0x40000;564}565566if (!RSDK.CheckOnScreen(self, NULL))567destroyEntity(self);568}569}570571void KingAttack_State_SmallBullet_Impact(void)572{573RSDK_THIS(KingAttack);574575RSDK.ProcessAnimation(&self->animator);576577if (self->animator.frameID == self->animator.frameCount - 1)578destroyEntity(self);579}580581#if GAME_INCLUDE_EDITOR582void KingAttack_EditorDraw(void)583{584RSDK_THIS(KingAttack);585586RSDK.SetSpriteAnimation(KingAttack->aniFrames, 20, &self->animator, true, 0);587588RSDK.DrawSprite(&self->animator, NULL, false);589}590591void KingAttack_EditorLoad(void) { KingAttack->aniFrames = RSDK.LoadSpriteAnimation("LRZ3/HeavyKing.bin", SCOPE_STAGE); }592#endif593594void KingAttack_Serialize(void) {}595596597