Path: blob/master/SonicMania/Objects/CPZ/AmoebaDroid.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: AmoebaDroid Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectAmoebaDroid *AmoebaDroid;1011void AmoebaDroid_Update(void)12{13RSDK_THIS(AmoebaDroid);1415StateMachine_Run(self->state);16}1718void AmoebaDroid_LateUpdate(void) {}1920void AmoebaDroid_StaticUpdate(void) {}2122void AmoebaDroid_Draw(void)23{24RSDK_THIS(AmoebaDroid);2526if (self->stateDraw) {27StateMachine_Run(self->stateDraw);28}29else {30RSDK.DrawSprite(&self->animator, NULL, false);31}32}3334void AmoebaDroid_Create(void *data)35{36RSDK_THIS(AmoebaDroid);3738if (!SceneInfo->inEditor) {39if (globals->gameMode < MODE_TIMEATTACK) {40self->active = ACTIVE_BOUNDS;41self->updateRange.x = 0x800000;42self->updateRange.y = 0x800000;4344self->type = VOID_TO_INT(data);45switch (self->type) {46case AMOEBADROID_BOSS:47self->visible = false;48self->drawGroup = Zone->objectDrawGroup[0];49self->drawFX = FX_FLIP;50self->health = 6;5152self->hitbox.left = -22;53self->hitbox.top = -22;54self->hitbox.right = 22;55self->hitbox.bottom = 22;5657RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 0, &self->animator, true, 0);58RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 1, &self->attractorTopAnimator, true, 0);59RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 2, &self->attractorSideAnimator, true, 0);6061self->stateDraw = AmoebaDroid_Draw_AmoebaDroid;62self->state = AmoebaDroid_State_SetupArena;63break;6465case AMOEBADROID_BLOB_BIG:66self->visible = true;67self->drawGroup = Zone->objectDrawGroup[1];6869self->hitbox.left = -40;70self->hitbox.top = -40;71self->hitbox.right = 40;72self->hitbox.bottom = 40;7374self->drawFX = FX_SCALE;75self->inkEffect = INK_ALPHA;76self->scale.y = 0x200;77RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 3, &self->animator, true, 0);7879self->stateDraw = AmoebaDroid_Draw_BigBlob;80self->state = AmoebaDroid_State_BigBlob;81break;8283case AMOEBADROID_BLOB_SMALL:84self->active = ACTIVE_NORMAL;85self->visible = true;86self->drawGroup = Zone->objectDrawGroup[1];8788self->hitbox.left = -8;89self->hitbox.top = -8;90self->hitbox.right = 8;91self->hitbox.bottom = 8;9293self->updateRange.x = 0x200000;94self->updateRange.y = 0x200000;95self->inkEffect = INK_ALPHA;96RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 4, &self->animator, true, 0);9798self->state = AmoebaDroid_State_SmallBlob;99break;100101case AMOEBADROID_POOLSPLASH:102self->active = ACTIVE_NORMAL;103self->visible = true;104self->drawGroup = Zone->hudDrawGroup - 2;105106RSDK.SetSpriteAnimation(AmoebaDroid->waterFrames, 1, &self->animator, true, 0);107108self->state = AmoebaDroid_State_PoolSplash;109break;110111case AMOEBADROID_POOLSPLASH_DELAY:112self->active = ACTIVE_NORMAL;113self->drawGroup = Zone->hudDrawGroup - 2;114RSDK.SetSpriteAnimation(AmoebaDroid->waterFrames, 1, &self->animator, true, 0);115116self->state = AmoebaDroid_State_PoolSplash_Delayed;117break;118119default: break;120}121}122else {123destroyEntity(self);124}125}126}127128void AmoebaDroid_StageLoad(void)129{130AmoebaDroid->aniFrames = RSDK.LoadSpriteAnimation("CPZ/AmoebaDroid.bin", SCOPE_STAGE);131AmoebaDroid->waterFrames = RSDK.LoadSpriteAnimation("Global/Water.bin", SCOPE_STAGE);132133AmoebaDroid->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");134AmoebaDroid->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");135AmoebaDroid->sfxGather = RSDK.GetSfx("CPZ/DroidGather.wav");136AmoebaDroid->sfxBounce = RSDK.GetSfx("CPZ/DroidBounce.wav");137AmoebaDroid->sfxRelease = RSDK.GetSfx("CPZ/DroidRelease.wav");138}139140void AmoebaDroid_HandleSmallBlobMovement(void)141{142RSDK_THIS(AmoebaDroid);143144int32 angle = self->blobAngleX;145self->blobRadius = (self->blobAmplitude * RSDK.Cos256(self->blobAngleY)) >> 8;146147for (int32 i = 0; i < AMOEBADROID_BLOB_COUNT; ++i) {148EntityAmoebaDroid *smallBlob = self->blobs[i];149150smallBlob->velocity = smallBlob->position;151smallBlob->position.x = self->blobAmplitude * RSDK.Cos256(angle) + self->position.x;152smallBlob->velocity.x = smallBlob->position.x - smallBlob->velocity.x;153smallBlob->position.y = self->blobRadius * RSDK.Sin256(angle) + self->position.y;154smallBlob->velocity.y = (self->blobRadius * RSDK.Sin256(angle) + self->position.y) - smallBlob->velocity.y;155if ((self->blobAngleX & 0x7F) && angle < 0x80)156smallBlob->drawGroup = Zone->objectDrawGroup[0] - 1;157else158smallBlob->drawGroup = Zone->objectDrawGroup[0];159angle = (angle + 32) & 0xFF;160}161}162163void AmoebaDroid_HandleSmallBlobRelease(bool32 interact)164{165RSDK_THIS(AmoebaDroid);166167for (int32 i = 0; i < AMOEBADROID_BLOB_COUNT; ++i) {168EntityAmoebaDroid *smallBlob = self->blobs[i];169if (smallBlob) {170smallBlob->velocity.y -= 0x20000;171smallBlob->onGround = true;172smallBlob->interaction = interact;173self->blobs[i] = NULL;174}175}176}177178void AmoebaDroid_Hit(void)179{180RSDK_THIS(AmoebaDroid);181182if (--self->health <= 0) {183AmoebaDroid_HandleSmallBlobRelease(false);184self->state = AmoebaDroid_State_Destroyed;185self->timer = 0;186SceneInfo->timeEnabled = false;187Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);188}189else {190self->invincibleTimer = 48;191RSDK.PlaySfx(AmoebaDroid->sfxHit, false, 0xFF);192}193}194195void AmoebaDroid_Explode(void)196{197RSDK_THIS(AmoebaDroid);198199if (!(Zone->timer % 3)) {200RSDK.PlaySfx(AmoebaDroid->sfxExplosion, false, 255);201202if (Zone->timer & 4) {203int32 x = (RSDK.Rand(self->hitbox.left, self->hitbox.right) << 16) + self->position.x;204int32 y = (RSDK.Rand(self->hitbox.top, self->hitbox.bottom) << 16) + self->position.y;205CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y)->drawGroup = Zone->objectDrawGroup[1];206}207}208}209210void AmoebaDroid_CheckHit(void)211{212RSDK_THIS(AmoebaDroid);213214if (self->invincibleTimer > 0)215self->invincibleTimer--;216217foreach_active(Player, player)218{219if (!self->invincibleTimer && Player_CheckBadnikTouch(player, self, &self->hitbox) && Player_CheckBossHit(player, self))220AmoebaDroid_Hit();221}222}223224void AmoebaDroid_CheckPlayerHit(void)225{226RSDK_THIS(AmoebaDroid);227228foreach_active(Player, player)229{230if (!self->invincibleTimer) {231if (Player_CheckCollisionTouch(player, self, &self->hitbox))232Player_Hurt(player, self);233}234}235}236237void AmoebaDroid_Draw_AmoebaDroid(void)238{239RSDK_THIS(AmoebaDroid);240241if (self->invincibleTimer & 1) {242RSDK.CopyPalette(1, 16, 0, 128, 10);243244self->direction = FLIP_NONE;245RSDK.DrawSprite(&self->animator, NULL, false);246RSDK.DrawSprite(&self->attractorTopAnimator, NULL, false);247RSDK.DrawSprite(&self->attractorSideAnimator, NULL, false);248249self->direction = FLIP_X;250RSDK.DrawSprite(&self->attractorSideAnimator, NULL, false);251252RSDK.CopyPalette(1, 0, 0, 128, 10);253}254else {255self->direction = FLIP_NONE;256RSDK.DrawSprite(&self->animator, NULL, false);257RSDK.DrawSprite(&self->attractorTopAnimator, NULL, false);258RSDK.DrawSprite(&self->attractorSideAnimator, NULL, false);259260self->direction = FLIP_X;261RSDK.DrawSprite(&self->attractorSideAnimator, NULL, false);262}263}264265void AmoebaDroid_Draw_BigBlob(void)266{267RSDK_THIS(AmoebaDroid);268Vector2 drawPos = self->position;269270SpriteFrame *frame = RSDK.GetFrame(AmoebaDroid->aniFrames, 3, 0);271int32 angle = self->angle;272int32 sprY = frame->sprY;273274int32 maxY = (frame->sprY + 96) << 8;275frame->height = 1;276drawPos.y -= RSDK.Sin256(self->angle) << 10;277278for (int32 y = sprY << 8; y < maxY; angle += 2) {279self->scale.x = 0x200 + (RSDK.Sin256(frame->sprY + 2 * angle) >> 2);280frame->sprY = y >> 8;281282if ((y >> 8) >= sprY)283RSDK.DrawSprite(&self->animator, &drawPos, false);284285drawPos.y += 0x10000;286y += 0x100 + (RSDK.Sin256(angle) >> 1);287}288289frame->sprY = sprY;290}291292void AmoebaDroid_State_SetupArena(void)293{294RSDK_THIS(AmoebaDroid);295296if (++self->timer >= 8) {297self->timer = 0;298Zone->playerBoundActiveL[0] = true;299Zone->playerBoundActiveR[0] = true;300Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;301Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;302Zone->cameraBoundsT[0] = (self->position.y >> 16) - ScreenInfo->size.y;303Zone->cameraBoundsB[0] = (self->position.y >> 16);304AmoebaDroid->boundsL = (Zone->cameraBoundsL[0] + 64) << 16;305AmoebaDroid->boundsR = (Zone->cameraBoundsR[0] - 64) << 16;306AmoebaDroid->boundsM = self->position.x;307AmoebaDroid->boundsT = (Zone->cameraBoundsT[0] + 48) << 16;308AmoebaDroid->boundsB = (Zone->cameraBoundsB[0] - 8) << 16;309self->state = AmoebaDroid_State_SetupWaterLevel;310}311}312313void AmoebaDroid_State_SetupWaterLevel(void)314{315RSDK_THIS(AmoebaDroid);316317if (self->timer) {318self->timer++;319if (self->timer == 120) {320self->timer = 0;321self->visible = true;322self->position.y += -0x400000 - (ScreenInfo->size.y << 16);323self->state = AmoebaDroid_State_DropIn;324}325}326else {327if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x > self->position.x) {328Music_TransitionTrack(TRACK_MINIBOSS, 0.0125);329++self->timer;330}331332Water->waterLevel = 0x7FFFFFFF;333Water->newWaterLevel = 0x7FFFFFFF;334Water->targetWaterLevel = 0x7FFFFFFF;335Water->waterMoveSpeed = 0;336foreach_active(Water, water)337{338if (water->type == WATER_HEIGHT_TRIGGER)339destroyEntity(water);340}341RSDK.SetDrawGroupProperties(0, false, StateMachine_None);342RSDK.SetDrawGroupProperties(Zone->hudDrawGroup, false, StateMachine_None);343}344}345346void AmoebaDroid_State_DropIn(void)347{348RSDK_THIS(AmoebaDroid);349350self->position.y += 0x8000;351if (++self->timer == 90) {352self->timer = 0;353self->velocity.y = 0x8000;354self->state = AmoebaDroid_State_DropIntoPool;355}356357AmoebaDroid_CheckHit();358}359360void AmoebaDroid_State_DropIntoPool(void)361{362RSDK_THIS(AmoebaDroid);363364self->velocity.y += 0x1800;365self->position.y += self->velocity.y;366367if (self->position.y > AmoebaDroid->boundsB) {368self->velocity.y = self->velocity.y >> 2;369self->state = AmoebaDroid_State_SurfaceFromPool;370ChemicalPool_SetDeform(self->position.x, 0x100000);371CREATE_ENTITY(AmoebaDroid, INT_TO_VOID(AMOEBADROID_POOLSPLASH), self->position.x, self->position.y);372RSDK.PlaySfx(Water->sfxSplash, false, 255);373}374AmoebaDroid_CheckHit();375}376377void AmoebaDroid_State_SurfaceFromPool(void)378{379RSDK_THIS(AmoebaDroid);380381self->velocity.y -= 0x2800;382self->position.y += self->velocity.y;383384if (self->position.y <= AmoebaDroid->boundsB) {385self->position.y = AmoebaDroid->boundsB;386self->offsetPos = self->position;387self->velocity.y = 0;388self->state = AmoebaDroid_State_ChooseAttack;389}390AmoebaDroid_CheckHit();391}392393void AmoebaDroid_State_ChooseAttack(void)394{395RSDK_THIS(AmoebaDroid);396397self->position.y = BadnikHelpers_Oscillate(self->offsetPos.y, 2, 10);398399if (++self->timer == 48) {400self->timer = 3;401if (RSDK.Rand(0, 256) > 128)402self->state = AmoebaDroid_State_SwimLeft;403else404self->state = AmoebaDroid_State_SwimRight;405406EntityAmoebaDroid *part = CREATE_ENTITY(AmoebaDroid, INT_TO_VOID(AMOEBADROID_BLOB_BIG), self->position.x, self->position.y);407part->parent = self;408self->blobs[0] = part;409}410AmoebaDroid_CheckHit();411}412413void AmoebaDroid_State_SwimLeft(void)414{415RSDK_THIS(AmoebaDroid);416417RSDK.ProcessAnimation(&self->attractorTopAnimator);418RSDK.ProcessAnimation(&self->attractorSideAnimator);419420self->position.y = BadnikHelpers_Oscillate(self->offsetPos.y, 2, 10);421422self->velocity.x -= 0x2000;423if (self->velocity.x < -0x40000)424self->velocity.x = -0x40000;425self->position.x += self->velocity.x;426427if (self->timer <= 0) {428if (self->timer <= 0) {429self->velocity.x = 0;430self->velocity.y = 0;431self->state = AmoebaDroid_State_ExitPool;432ChemicalPool_SetDeform(self->position.x, -0xC0000);433CREATE_ENTITY(AmoebaDroid, INT_TO_VOID(AMOEBADROID_POOLSPLASH_DELAY), self->position.x, self->position.y);434RSDK.PlaySfx(Water->sfxSplash, false, 255);435}436}437else if (self->position.x < AmoebaDroid->boundsL + 0x400000) {438self->state = AmoebaDroid_State_SwimRight;439self->timer--;440}441442if (!(Zone->timer & 0xF))443RSDK.PlaySfx(AmoebaDroid->sfxGather, false, 255);444445ChemicalPool_SetDeform(self->position.x, -0x8000);446}447448void AmoebaDroid_State_SwimRight(void)449{450RSDK_THIS(AmoebaDroid);451452RSDK.ProcessAnimation(&self->attractorTopAnimator);453RSDK.ProcessAnimation(&self->attractorSideAnimator);454455self->position.y = BadnikHelpers_Oscillate(self->offsetPos.y, 2, 10);456457self->velocity.x += 0x2000;458if (self->velocity.x > 0x40000)459self->velocity.x = 0x40000;460self->position.x += self->velocity.x;461462if (self->timer <= 0) {463if (self->timer >= 0) {464self->velocity.x = 0;465self->velocity.y = 0;466self->state = AmoebaDroid_State_ExitPool;467ChemicalPool_SetDeform(self->position.x, -0xC0000);468CREATE_ENTITY(AmoebaDroid, INT_TO_VOID(AMOEBADROID_POOLSPLASH_DELAY), self->position.x, self->position.y);469RSDK.PlaySfx(Water->sfxSplash, false, 255);470}471}472else if (self->position.x > AmoebaDroid->boundsR - 0x400000) {473self->state = AmoebaDroid_State_SwimLeft;474self->timer--;475}476477if (!(Zone->timer & 0xF))478RSDK.PlaySfx(AmoebaDroid->sfxGather, false, 255);479480ChemicalPool_SetDeform(self->position.x, -0x8000);481}482483void AmoebaDroid_State_ExitPool(void)484{485RSDK_THIS(AmoebaDroid);486487RSDK.ProcessAnimation(&self->attractorTopAnimator);488RSDK.ProcessAnimation(&self->attractorSideAnimator);489490self->velocity.y -= 0x1800;491self->position.y += self->velocity.y;492493if (self->position.y < AmoebaDroid->boundsT + 0x400000) {494self->timer = 3;495self->state = AmoebaDroid_State_BounceAttack;496}497AmoebaDroid_CheckHit();498}499500void AmoebaDroid_State_BounceAttack(void)501{502RSDK_THIS(AmoebaDroid);503504RSDK.ProcessAnimation(&self->attractorTopAnimator);505RSDK.ProcessAnimation(&self->attractorSideAnimator);506507self->velocity.y += 0x2000;508self->position.y += self->velocity.y;509510EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);511if (self->position.x < player1->position.x)512self->position.x = self->position.x + 0x10000;513else if (self->position.x > player1->position.x)514self->position.x = self->position.x - 0x10000;515516if (self->velocity.y > 0 && RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, self->collisionPlane, 0, 0x180000, true)) {517if (--self->timer <= 0) {518EntityAmoebaDroid *bigBlob = self->blobs[0];519RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 6, &bigBlob->animator, false, 0);520bigBlob->drawFX = FX_NONE;521bigBlob->stateDraw = StateMachine_None;522bigBlob->state = AmoebaDroid_State_BigBlob_Disappear;523524self->state = StateMachine_None;525for (int32 i = 0; i < AMOEBADROID_BLOB_COUNT; ++i) {526self->blobs[i] = CREATE_ENTITY(AmoebaDroid, INT_TO_VOID(AMOEBADROID_BLOB_SMALL), self->position.x, self->position.y);527}528529self->timer = 0;530self->blobAngleY = 196;531self->blobAmplitude = 0x2800;532self->state = AmoebaDroid_State_GatherBlobs;533RSDK.PlaySfx(AmoebaDroid->sfxRelease, false, 255);534}535else {536self->velocity.y = MIN(-self->velocity.y, -0x20000);537for (int32 i = 0; i < AMOEBADROID_BLOB_COUNT; ++i) {538int32 x = self->position.x + RSDK.Rand(-0x200000, 0x200000);539int32 y = self->position.y + RSDK.Rand(0x100000, 0x180000);540EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);541542RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 5, &debris->animator, false, 0);543debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);544debris->velocity.y = RSDK.Rand(-0x40000, -0x20000);545debris->gravityStrength = 0x3800;546debris->inkEffect = INK_BLEND;547debris->drawGroup = Zone->objectDrawGroup[0];548debris->updateRange.x = 0x200000;549debris->updateRange.y = 0x200000;550}551552RSDK.PlaySfx(AmoebaDroid->sfxBounce, false, 255);553}554}555556AmoebaDroid_CheckHit();557}558559void AmoebaDroid_State_GatherBlobs(void)560{561RSDK_THIS(AmoebaDroid);562563RSDK.ProcessAnimation(&self->attractorTopAnimator);564RSDK.ProcessAnimation(&self->attractorSideAnimator);565566AmoebaDroid_HandleSmallBlobMovement();567self->blobAngleX = (self->blobAngleX + 4) & 0xFF;568569if (self->timer == 60) {570self->position.x += self->velocity.x;571self->position.y += self->velocity.y;572573if (self->position.y <= AmoebaDroid->boundsT) {574self->offsetPos.x = self->position.x;575self->offsetPos.y = self->position.y;576self->timer = 0;577self->angle = 0;578self->position.y = AmoebaDroid->boundsT;579self->state = AmoebaDroid_State_SpinBlobs;580}581}582else {583self->position.y -= 0x8000;584585if (++self->timer == 60) {586self->velocity.x = (AmoebaDroid->boundsM - self->position.x + RSDK.Rand(-0x800000, 0x800000)) >> 6;587self->velocity.y = (AmoebaDroid->boundsT - self->position.y) >> 6;588}589}590591AmoebaDroid_CheckHit();592}593594void AmoebaDroid_State_SpinBlobs(void)595{596RSDK_THIS(AmoebaDroid);597598self->position.y = BadnikHelpers_Oscillate(self->offsetPos.y, 2, 10);599600if (self->timer < 120) {601AmoebaDroid_HandleSmallBlobMovement();602if (self->offsetPos.x <= AmoebaDroid->boundsM)603self->blobAngleY -= 2;604else605self->blobAngleY += 2;606self->blobAngleY &= 0xFF;607self->blobAngleX = (self->blobAngleX + 4) & 0xFF;608RSDK.ProcessAnimation(&self->attractorTopAnimator);609RSDK.ProcessAnimation(&self->attractorSideAnimator);610}611612AmoebaDroid_CheckHit();613614if (++self->timer == 120) {615AmoebaDroid_HandleSmallBlobRelease(true);616RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 1, &self->attractorTopAnimator, true, 0);617RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 2, &self->attractorSideAnimator, true, 0);618RSDK.PlaySfx(AmoebaDroid->sfxRelease, false, 255);619}620else if (self->timer == 240) {621self->timer = 0;622self->angle = 0;623self->velocity.y = -0x20000;624self->state = AmoebaDroid_State_DropIntoPool;625}626}627628void AmoebaDroid_State_BigBlob(void)629{630RSDK_THIS(AmoebaDroid);631632EntityAmoebaDroid *parent = self->parent;633self->angle = (self->angle + 4) & 0xFF;634if (parent->state == AmoebaDroid_State_DropSignPost || parent->state == AmoebaDroid_State_Destroyed) {635if (self->alpha > 0) {636self->alpha -= 4;637if (self->alpha <= 0)638destroyEntity(self);639}640}641else {642AmoebaDroid_CheckPlayerHit();643644if (self->alpha < 0x80) {645self->alpha++;646self->position.x = parent->position.x;647self->position.y = parent->position.y;648}649}650651self->position.x = parent->position.x;652self->position.y = parent->position.y;653}654655void AmoebaDroid_State_SmallBlob(void)656{657RSDK_THIS(AmoebaDroid);658659if (self->alpha < 0xC0)660self->alpha += 4;661662if (self->onGround) {663self->velocity.y += 0x2000;664self->position.x += self->velocity.x;665self->position.y += self->velocity.y;666667if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, self->collisionPlane, 0, 0x60000, true)) {668for (int32 i = 0; i < 4; ++i) {669int32 x = self->position.x + RSDK.Rand(-0x40000, 0x40000);670int32 y = self->position.y + RSDK.Rand(-0x40000, 0x40000);671EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);672673RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 5, &debris->animator, false, 0);674debris->velocity.x = RSDK.Rand(-0x20000, 0x20000);675debris->velocity.y = -0x20000;676debris->gravityStrength = 0x3800;677debris->inkEffect = INK_BLEND;678debris->drawGroup = Zone->objectDrawGroup[0];679debris->updateRange.x = 0x200000;680debris->updateRange.y = 0x200000;681}682683destroyEntity(self);684}685}686687if (self->classID == AmoebaDroid->classID) {688if (self->interaction && self->drawGroup == Zone->objectDrawGroup[0])689AmoebaDroid_CheckPlayerHit();690691if (!RSDK.CheckOnScreen(self, NULL))692destroyEntity(self);693}694}695696void AmoebaDroid_State_BigBlob_Disappear(void)697{698RSDK_THIS(AmoebaDroid);699700EntityAmoebaDroid *parent = self->parent;701if (parent) {702self->position.x = parent->position.x;703self->position.y = parent->position.y;704}705706RSDK.ProcessAnimation(&self->animator);707708if (self->animator.frameID == self->animator.frameCount - 1)709destroyEntity(self);710}711712void AmoebaDroid_State_PoolSplash_Delayed(void)713{714RSDK_THIS(AmoebaDroid);715716if (++self->timer == 16) {717self->timer = 0;718self->visible = true;719self->state = AmoebaDroid_State_PoolSplash;720}721}722723void AmoebaDroid_State_PoolSplash(void)724{725RSDK_THIS(AmoebaDroid);726727int32 pos = (self->position.x + 0x80000) >> 20;728foreach_active(ChemicalPool, pool)729{730if (pos >= pool->leftEdge && pos < pool->rightEdge)731self->position.y = pool->offsetY + ChemicalPool->surfaceDeformation[pos];732}733734RSDK.ProcessAnimation(&self->animator);735736if (self->animator.frameID == self->animator.frameCount - 1)737destroyEntity(self);738}739740void AmoebaDroid_State_Destroyed(void)741{742RSDK_THIS(AmoebaDroid);743744AmoebaDroid_Explode();745746++self->timer;747if (self->timer == 30) {748Debris_CreateFromEntries(AmoebaDroid->aniFrames, AmoebaDroid->debrisInfo2, 7);749RSDK.SetSpriteAnimation(-1, 0, &self->attractorTopAnimator, true, 0);750RSDK.SetSpriteAnimation(-1, 0, &self->attractorSideAnimator, true, 0);751}752else if (self->timer == 60) {753Debris_CreateFromEntries(AmoebaDroid->aniFrames, AmoebaDroid->debrisInfo1, 7);754RSDK.SetSpriteAnimation(-1, 0, &self->animator, true, 0);755}756else if (self->timer == 90) {757Music_TransitionTrack(TRACK_STAGE, 0.0125);758self->timer = 0;759self->visible = false;760self->state = AmoebaDroid_State_DropSignPost;761}762}763764void AmoebaDroid_State_DropSignPost(void)765{766RSDK_THIS(AmoebaDroid);767768if (++self->timer == 60) {769foreach_all(SignPost, signPost)770{771signPost->position.x = self->position.x;772signPost->active = ACTIVE_NORMAL;773signPost->state = SignPost_State_Falling;774RSDK.PlaySfx(SignPost->sfxTwinkle, false, 255);775}776777destroyEntity(self);778}779}780781#if GAME_INCLUDE_EDITOR782void AmoebaDroid_EditorDraw(void)783{784RSDK_THIS(AmoebaDroid);785786self->drawFX = FX_FLIP;787RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 0, &self->animator, true, 0);788RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 1, &self->attractorTopAnimator, true, 0);789RSDK.SetSpriteAnimation(AmoebaDroid->aniFrames, 2, &self->attractorSideAnimator, true, 0);790791AmoebaDroid_Draw_AmoebaDroid();792793if (showGizmos()) {794RSDK_DRAWING_OVERLAY(true);795796DrawHelpers_DrawArenaBounds(-WIDE_SCR_XCENTER, -SCREEN_YSIZE, WIDE_SCR_XCENTER, 0, 1 | 2 | 4 | 8, 0x00C0F0);797798RSDK_DRAWING_OVERLAY(false);799}800}801802void AmoebaDroid_EditorLoad(void)803{804AmoebaDroid->aniFrames = RSDK.LoadSpriteAnimation("CPZ/AmoebaDroid.bin", SCOPE_STAGE);805AmoebaDroid->waterFrames = RSDK.LoadSpriteAnimation("Global/Water.bin", SCOPE_STAGE);806807RSDK_ACTIVE_VAR(AmoebaDroid, type);808RSDK_ENUM_VAR("Boss", AMOEBADROID_BOSS);809}810#endif811812void AmoebaDroid_Serialize(void) { RSDK_EDITABLE_VAR(AmoebaDroid, VAR_ENUM, type); }813814815