Path: blob/master/SonicMania/Objects/Common/BreakableWall.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: BreakableWall Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectBreakableWall *BreakableWall;1011void BreakableWall_Update(void)12{13RSDK_THIS(BreakableWall);1415StateMachine_Run(self->state);16}1718void BreakableWall_LateUpdate(void) {}1920void BreakableWall_StaticUpdate(void) {}2122void BreakableWall_Draw(void)23{24RSDK_THIS(BreakableWall);2526StateMachine_Run(self->stateDraw);27}2829void BreakableWall_Create(void *data)30{31RSDK_THIS(BreakableWall);3233self->gravityStrength = 0x3800;3435if (data) {36int32 type = VOID_TO_INT(data);37self->visible = true;38self->updateRange.x = TO_FIXED(16);39self->updateRange.y = TO_FIXED(16);40self->active = ACTIVE_NORMAL;41self->drawFX = FX_FLIP | (self->velocity.x != 0 ? FX_ROTATE : FX_NONE);42self->tileRotation = RSDK.Rand(-8, 8);4344switch (type) {45case BREAKWALL_TILE_FIXED:46self->state = BreakableWall_State_Tile;47self->stateDraw = BreakableWall_Draw_Tile;48break;4950default:51case BREAKWALL_TILE_DYNAMIC:52self->state = BreakableWall_State_FallingTile;53self->stateDraw = StateMachine_None;54break;55}56}57else {58self->drawFX |= FX_FLIP;5960if (!SceneInfo->inEditor) {61self->visible = false;62self->drawGroup = Zone->objectDrawGroup[1];63self->active = ACTIVE_BOUNDS;64self->updateRange.x = TO_FIXED(128);65self->updateRange.y = TO_FIXED(128);66self->priority = self->priority == BREAKWALL_PRIO_HIGH ? Zone->fgLayer[1] : Zone->fgLayer[0];6768self->size.x >>= 0x10;69self->size.y >>= 0x10;7071switch (self->type) {72case BREAKWALL_TYPE_WALL:73if (!self->size.x) {74self->size.x = 2;75self->size.y = 4;76}7778self->state = BreakableWall_State_Wall;79self->stateDraw = BreakableWall_Draw_Wall;80break;8182case BREAKWALL_TYPE_FLOOR:83if (!self->size.x) {84self->size.x = 2;85self->size.y = 2;86}8788self->state = BreakableWall_State_Floor;89self->stateDraw = BreakableWall_Draw_Floor;90break;9192case BREAKWALL_TYPE_BURROWFLOOR:93case BREAKWALL_TYPE_BURROWFLOOR_B:94if (!self->size.x)95self->size.x = 2;9697self->state = BreakableWall_State_BurrowFloor;98self->stateDraw = BreakableWall_Draw_Floor;99break;100101case BREAKWALL_TYPE_BURROWFLOORUP:102if (!self->size.x)103self->size.x = 2;104105self->state = BreakableWall_State_BurrowFloorUp;106self->stateDraw = BreakableWall_Draw_Floor;107break;108109case BREAKWALL_TYPE_CEILING:110if (!self->size.x) {111self->size.x = 2;112self->size.y = 2;113}114115self->state = BreakableWall_State_Ceiling;116self->stateDraw = BreakableWall_Draw_Floor;117break;118119default: break;120}121122self->hitbox.left = -(8 * self->size.x);123self->hitbox.top = -(8 * self->size.y);124self->hitbox.right = 8 * self->size.x;125self->hitbox.bottom = 8 * self->size.y;126}127}128}129130void BreakableWall_StageLoad(void)131{132BreakableWall->aniFrames = RSDK.LoadSpriteAnimation("Global/TicMark.bin", SCOPE_STAGE);133RSDK.SetSpriteAnimation(BreakableWall->aniFrames, 0, &BreakableWall->animator, true, 0);134135if (RSDK.CheckSceneFolder("AIZ"))136BreakableWall->sfxBreak = RSDK.GetSfx("Stage/LedgeBreak3.wav");137else138BreakableWall->sfxBreak = RSDK.GetSfx("Stage/LedgeBreak.wav");139140BreakableWall->farPlaneLayer = RSDK.GetTileLayerID("Far Plane");141}142143// States144void BreakableWall_State_BurrowFloorUp(void)145{146RSDK_THIS(BreakableWall);147148self->visible = DebugMode->debugActive;149150BreakableWall_CheckBreak_BurrowFloorUp();151}152void BreakableWall_State_Ceiling(void)153{154RSDK_THIS(BreakableWall);155156self->visible = DebugMode->debugActive;157158BreakableWall_CheckBreak_Ceiling();159}160void BreakableWall_State_FallingTile(void)161{162RSDK_THIS(BreakableWall);163164if (--self->timer <= 0) {165RSDK.SetTile(self->targetLayer, self->tilePos.x, self->tilePos.y, -1);166167if (self->drawGroup < Zone->objectDrawGroup[0] && BreakableWall->farPlaneLayer != (uint16)-1) {168RSDK.SetTile(BreakableWall->farPlaneLayer, self->tilePos.x, self->tilePos.y, -1);169}170171self->state = BreakableWall_State_Tile;172self->stateDraw = BreakableWall_Draw_Tile;173}174}175void BreakableWall_State_Wall(void)176{177RSDK_THIS(BreakableWall);178179self->visible = DebugMode->debugActive;180181BreakableWall_CheckBreak_Wall();182}183void BreakableWall_State_Tile(void)184{185RSDK_THIS(BreakableWall);186187self->position.x += self->velocity.x;188self->position.y += self->velocity.y;189self->velocity.y += self->gravityStrength;190191if (self->velocity.x)192self->rotation += self->tileRotation;193194if (self->drawGroup >= Zone->objectDrawGroup[0]) {195if (!RSDK.CheckOnScreen(self, &self->updateRange))196destroyEntity(self);197}198else {199if (++self->timer == 120)200destroyEntity(self);201}202}203void BreakableWall_State_Floor(void)204{205RSDK_THIS(BreakableWall);206207self->visible = DebugMode->debugActive;208209BreakableWall_CheckBreak_Floor();210}211void BreakableWall_State_BurrowFloor(void)212{213RSDK_THIS(BreakableWall);214215self->visible = DebugMode->debugActive;216217BreakableWall_CheckBreak_BurrowFloor();218}219220// Draw States221void BreakableWall_Draw_Wall(void)222{223RSDK_THIS(BreakableWall);224225Vector2 drawPos;226drawPos.x = self->position.x - (self->size.x << 19);227drawPos.y = self->position.y - (self->size.y << 19);228229RSDK.DrawLine(drawPos.x - 0x10000, drawPos.y - 0x10000, drawPos.x + (self->size.x << 20), drawPos.y - 0x10000, 0xE0E0E0, 0, INK_NONE, false);230RSDK.DrawLine(drawPos.x - 0x10000, drawPos.y + (self->size.y << 20), drawPos.x + (self->size.x << 20), drawPos.y + (self->size.y << 20), 0xE0E0E0,2310, INK_NONE, false);232RSDK.DrawLine(drawPos.x - 0x10000, drawPos.y - 0x10000, drawPos.x - 0x10000, drawPos.y + (self->size.y << 20), 0xE0E0E0, 0, INK_NONE, false);233RSDK.DrawLine(drawPos.x + (self->size.x << 20), drawPos.y - 0x10000, drawPos.x + (self->size.x << 20), drawPos.y + (self->size.y << 20), 0xE0E0E0,2340, INK_NONE, false);235236self->direction = FLIP_NONE;237RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);238239drawPos.x += self->size.x << 20;240self->direction = FLIP_X;241RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);242243drawPos.y += self->size.y << 20;244self->direction = FLIP_XY;245RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);246247drawPos.x -= self->size.x << 20;248self->direction = FLIP_Y;249RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);250}251252// The... same function as above?253void BreakableWall_Draw_Floor(void)254{255RSDK_THIS(BreakableWall);256257Vector2 drawPos;258drawPos.x = self->position.x - (self->size.x << 19);259drawPos.y = self->position.y - (self->size.y << 19);260261RSDK.DrawLine(drawPos.x - TO_FIXED(1), drawPos.y - TO_FIXED(1), drawPos.x + (self->size.x << 20), drawPos.y - TO_FIXED(1), 0xE0E0E0, 0x00,262INK_NONE, false);263RSDK.DrawLine(drawPos.x - TO_FIXED(1), drawPos.y + (self->size.y << 20), drawPos.x + (self->size.x << 20), drawPos.y + (self->size.y << 20),2640xE0E0E0, 0x00, INK_NONE, false);265RSDK.DrawLine(drawPos.x - TO_FIXED(1), drawPos.y - TO_FIXED(1), drawPos.x - TO_FIXED(1), drawPos.y + (self->size.y << 20), 0xE0E0E0, 0x00,266INK_NONE, false);267RSDK.DrawLine(drawPos.x + (self->size.x << 20), drawPos.y - TO_FIXED(1), drawPos.x + (self->size.x << 20), drawPos.y + (self->size.y << 20),2680xE0E0E0, 0x00, INK_NONE, false);269270self->direction = FLIP_NONE;271RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);272273drawPos.x += self->size.x << 20;274self->direction = FLIP_X;275RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);276277drawPos.y += self->size.y << 20;278self->direction = FLIP_XY;279RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);280281drawPos.x -= self->size.x << 20;282self->direction = FLIP_Y;283RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);284}285void BreakableWall_Draw_Tile(void)286{287RSDK_THIS(BreakableWall);288289self->angle = self->rotation;290RSDK.DrawTile(&self->tileInfo, 1, 1, NULL, NULL, false);291}292293// Breaking294void BreakableWall_CheckBreak_Wall(void)295{296RSDK_THIS(BreakableWall);297298foreach_active(Player, player)299{300#if MANIA_USE_PLUS301if (self->onlyMighty) {302if (player->characterID != ID_MIGHTY && (!self->onlyKnux || player->characterID != ID_KNUCKLES)) {303Player_CheckCollisionBox(player, self, &self->hitbox);304continue;305}306}307else {308if (self->onlyKnux && player->characterID != ID_KNUCKLES && (!self->onlyMighty || player->characterID != ID_MIGHTY)) {309Player_CheckCollisionBox(player, self, &self->hitbox);310continue;311}312}313#else314if (self->onlyKnux && player->characterID != ID_KNUCKLES) {315Player_CheckCollisionBox(player, self, &self->hitbox);316continue;317}318#endif319320bool32 canBreak = abs(player->groundVel) >= 0x48000 && player->onGround && player->animator.animationID == ANI_JUMP;321322if (player->shield == SHIELD_FIRE) {323EntityShield *shield = RSDK_GET_ENTITY(Player->playerCount + RSDK.GetEntitySlot(player), Shield);324canBreak |= shield->shieldAnimator.animationID == SHIELDANI_FIREATTACK;325}326327switch (player->characterID) {328default: break;329330case ID_SONIC: canBreak |= player->superState == SUPERSTATE_SUPER; break;331332case ID_KNUCKLES: canBreak = true; break;333}334335if (player->state == Ice_PlayerState_Frozen)336canBreak |= abs(player->groundVel) >= 0x48000;337338if (canBreak && !player->sidekick) {339if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {340BreakableWall_Break(self, player->position.x > self->position.x);341342if (player->characterID == ID_KNUCKLES) {343if (player->animator.animationID == ANI_GLIDE) {344player->abilitySpeed -= player->abilitySpeed >> 2;345player->velocity.x -= player->velocity.x >> 2;346if (abs(player->velocity.x) <= 0x30000) {347RSDK.SetSpriteAnimation(player->aniFrames, ANI_GLIDE_DROP, &player->animator, false, 0);348player->state = Player_State_KnuxGlideDrop;349}350}351else if (player->animator.animationID == ANI_GLIDE_SLIDE) {352player->abilitySpeed -= player->abilitySpeed >> 2;353player->velocity.x -= player->velocity.x >> 2;354}355}356357RSDK.PlaySfx(BreakableWall->sfxBreak, false, 255);358destroyEntity(self);359}360continue; // skip to next loop, so we dont do the box collision361}362363Player_CheckCollisionBox(player, self, &self->hitbox);364}365}366void BreakableWall_CheckBreak_Floor(void)367{368RSDK_THIS(BreakableWall);369370foreach_active(Player, player)371{372#if MANIA_USE_PLUS373int32 velY = player->velocity.y;374#endif375376if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_TOP) {377#if MANIA_USE_PLUS378if (self->onlyMighty) {379if ((player->characterID != ID_MIGHTY || player->animator.animationID != ANI_HAMMERDROP)380&& (!self->onlyKnux || player->characterID != ID_KNUCKLES)) {381Player_CheckCollisionBox(player, self, &self->hitbox);382continue;383}384}385else {386if (self->onlyKnux && player->characterID != ID_KNUCKLES && (!self->onlyMighty || player->characterID != ID_MIGHTY)) {387Player_CheckCollisionBox(player, self, &self->hitbox);388continue;389}390}391#else392if (self->onlyKnux && player->characterID != ID_KNUCKLES) {393Player_CheckCollisionBox(player, self, &self->hitbox);394continue;395}396#endif397398bool32 canBreak = player->animator.animationID == ANI_JUMP;399400switch (player->characterID) {401default: break;402403case ID_SONIC:404if (!canBreak)405canBreak = player->animator.animationID == ANI_DROPDASH;406break;407408case ID_KNUCKLES: canBreak = true; break;409410#if MANIA_USE_PLUS411case ID_MIGHTY:412if (!canBreak)413canBreak = player->state == Player_State_MightyHammerDrop;414break;415#endif416}417418if (player->groundedStore && player->collisionMode != CMODE_LWALL && player->collisionMode != CMODE_RWALL)419canBreak = false;420421if (canBreak && !player->sidekick) {422player->onGround = false;423424BreakableWall_Break(self, FLIP_Y);425426RSDK.PlaySfx(BreakableWall->sfxBreak, false, 255);427BreakableWall_GiveScoreBonus(player);428429#if MANIA_USE_PLUS430if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)431player->velocity.y = velY - TO_FIXED(1);432else433#endif434player->velocity.y = -TO_FIXED(3);435436destroyEntity(self);437438continue; // skip to next loop, so we dont do the box collision439}440}441442Player_CheckCollisionBox(player, self, &self->hitbox);443}444}445void BreakableWall_CheckBreak_BurrowFloor(void)446{447RSDK_THIS(BreakableWall);448449foreach_active(Player, player)450{451#if MANIA_USE_PLUS452int32 velY = player->velocity.y;453#endif454bool32 onGround = player->onGround;455456if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_TOP && !player->sidekick457&& ((player->collisionPlane == 1 && self->type == BREAKWALL_TYPE_BURROWFLOOR_B) || self->type == BREAKWALL_TYPE_BURROWFLOOR)) {458#if MANIA_USE_PLUS459if (self->onlyMighty) {460if ((player->characterID != ID_MIGHTY || player->animator.animationID != ANI_HAMMERDROP)461&& (!self->onlyKnux || player->characterID != ID_KNUCKLES))462continue;463}464else {465if (self->onlyKnux && player->characterID != ID_KNUCKLES && (!self->onlyMighty || player->characterID != ID_MIGHTY))466continue;467}468#else469if (self->onlyKnux && player->characterID != ID_KNUCKLES)470continue;471#endif472473bool32 canBreak = player->animator.animationID == ANI_JUMP;474475switch (player->characterID) {476default: break;477478case ID_SONIC:479if (!canBreak)480canBreak = player->animator.animationID == ANI_DROPDASH;481break;482483#if MANIA_USE_PLUS484case ID_MIGHTY:485if (!canBreak)486canBreak = player->state == Player_State_MightyHammerDrop;487break;488#endif489}490491if (onGround && player->collisionMode != CMODE_LWALL && player->collisionMode != CMODE_RWALL)492canBreak = false;493494if (canBreak && !player->sidekick) {495player->onGround = false;496497int32 sizeX = self->size.x;498int32 sizeY = self->size.y;499int32 posX = self->position.x;500int32 posY = self->position.y;501502self->size.y = 1;503self->position.y += 0x80000 - (sizeY << 19);504505BreakableWall_Break(self, FLIP_Y);506507self->size.x = sizeX;508self->size.y = sizeY;509self->position.x = posX;510self->position.y = posY;511RSDK.PlaySfx(BreakableWall->sfxBreak, false, 255);512513BreakableWall_GiveScoreBonus(player);514515#if MANIA_USE_PLUS516if (player->characterID == ID_MIGHTY && player->state == Player_State_MightyHammerDrop)517player->velocity.y = velY - TO_FIXED(1);518else519#endif520player->velocity.y = 0;521522self->hitbox.top += 8;523self->hitbox.bottom -= 8;524--self->size.y;525self->position.y += TO_FIXED(8);526527if (self->size.y <= 0)528destroyEntity(self);529}530}531}532}533void BreakableWall_CheckBreak_BurrowFloorUp(void)534{535RSDK_THIS(BreakableWall);536537foreach_active(Player, player)538{539int32 velY = player->velocity.y;540if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_BOTTOM) {541#if MANIA_USE_PLUS542if (self->onlyMighty) {543if ((player->characterID != ID_MIGHTY) && (!self->onlyKnux || player->characterID != ID_KNUCKLES))544continue;545}546else {547if (self->onlyKnux && player->characterID != ID_KNUCKLES && (!self->onlyMighty || player->characterID != ID_MIGHTY))548continue;549}550#else551if (self->onlyKnux && player->characterID != ID_KNUCKLES)552continue;553#endif554555if (!player->sidekick) {556int32 sizeX = self->size.x;557int32 sizeY = self->size.y;558int32 posX = self->position.x;559int32 posY = self->position.y;560561if (sizeY > 2)562self->size.y = 2;563self->position.y += (sizeY - self->size.y) << 19;564565BreakableWall_Break(self, FLIP_Y);566567self->size.x = sizeX;568self->size.y = sizeY;569self->position.x = posX;570self->position.y = posY;571RSDK.PlaySfx(BreakableWall->sfxBreak, false, 255);572573player->velocity.y = 0;574575if (self->size.y < 2) {576self->hitbox.top += 8;577self->size.y -= 1;578self->hitbox.bottom -= 8;579self->position.y -= TO_FIXED(8);580}581else {582self->hitbox.top += 16;583self->size.y -= 2;584self->hitbox.bottom -= 16;585self->position.y -= TO_FIXED(16);586}587588if (self->size.y <= 0)589destroyEntity(self);590591player->velocity.y = velY;592}593}594}595}596void BreakableWall_CheckBreak_Ceiling(void)597{598RSDK_THIS(BreakableWall);599600foreach_active(Player, player)601{602int32 velY = player->velocity.y;603if (Player_CheckCollisionBox(player, self, &self->hitbox) == C_BOTTOM) {604#if MANIA_USE_PLUS605if (self->onlyMighty) {606if ((player->characterID != ID_MIGHTY) && (!self->onlyKnux || player->characterID != ID_KNUCKLES))607continue;608}609else {610if (self->onlyKnux && player->characterID != ID_KNUCKLES && (!self->onlyMighty || player->characterID != ID_MIGHTY))611continue;612}613#else614if (self->onlyKnux && player->characterID != ID_KNUCKLES)615continue;616#endif617player->onGround = false;618619BreakableWall_Break(self, FLIP_Y);620621RSDK.PlaySfx(BreakableWall->sfxBreak, false, 0xFF);622player->velocity.y = velY;623destroyEntity(self);624}625}626}627void BreakableWall_Break(EntityBreakableWall *self, uint8 direction)628{629int32 startX = self->position.x;630int32 startY = self->position.y;631int32 endX = self->position.x - (self->size.x << 19) + TO_FIXED(8);632int32 endY = self->position.y - (self->size.y << 19) + TO_FIXED(8);633634switch (direction) {635case FLIP_NONE: startX += self->size.x << 19; break;636case FLIP_X: startX -= self->size.x << 19; break;637case FLIP_Y: startY += self->size.y << 19; break;638case FLIP_XY: startY -= self->size.y << 19; break;639default: break;640}641642int32 curY = endY - startY;643for (int32 y = 0; y < self->size.y; ++y) {644int32 curX = endX - startX;645int32 tileY = (curY + startY) >> 20;646int32 angleX = 2 * (endX - startX);647648for (int32 x = 0; x < self->size.x; ++x) {649int32 tileX = (curX + startX) >> 20;650EntityBreakableWall *tile = CREATE_ENTITY(BreakableWall, INT_TO_VOID(BREAKWALL_TILE_FIXED), curX + startX, curY + startY);651tile->tileInfo = RSDK.GetTile(self->priority, tileX, tileY);652tile->drawGroup = self->drawGroup;653654switch (direction) {655case FLIP_NONE:656case FLIP_X: {657int32 angle = RSDK.ATan2(angleX, curY);658int32 angle2 = 0;659if (abs(curX) > 0x80000) {660if (curX + startX >= startX)661angle2 = RSDK.ATan2(TO_FIXED(8), curY);662else663angle2 = RSDK.ATan2(-TO_FIXED(8), curY);664}665else {666angle2 = RSDK.ATan2(curX, curY);667}668669tile->velocity.x = direction == FLIP_NONE ? -TO_FIXED(1) : TO_FIXED(1);670tile->velocity.y = TO_FIXED(1);671tile->velocity.x += 40 * (((self->size.y << 19) + 3 * abs(curX) - abs(curY)) >> 18) * RSDK.Cos256(angle);672tile->velocity.y += 32 * ((abs(curY) + abs(curX) + 2 * abs(curY)) >> 18) * RSDK.Sin256(angle2);673break;674}675676case FLIP_Y: {677int32 angle = RSDK.ATan2(angleX, curY);678int32 velocity = (abs(curX) + 3 * abs(curY)) >> 18;679680tile->velocity.x += 40 * velocity * RSDK.Cos256(angle);681tile->velocity.y += 40 * velocity * RSDK.Sin256(angle);682break;683}684}685686RSDK.SetTile(self->priority, tileX, tileY, -1);687if (self->drawGroup < Zone->objectDrawGroup[0]) {688if (BreakableWall->farPlaneLayer != (uint16)-1)689RSDK.SetTile(BreakableWall->farPlaneLayer, tileX, tileY, -1);690}691692curX += TO_FIXED(16);693angleX += TO_FIXED(32);694}695696curY += TO_FIXED(16);697}698}699700// Misc701void BreakableWall_GiveScoreBonus(EntityPlayer *player)702{703RSDK_THIS(BreakableWall);704705EntityScoreBonus *scoreBonus = CREATE_ENTITY(ScoreBonus, NULL, self->position.x, self->position.y);706scoreBonus->drawGroup = Zone->objectDrawGroup[1];707scoreBonus->animator.frameID = player->scoreBonus;708709switch (player->scoreBonus) {710case 0: Player_GiveScore(player, 100); break;711case 1: Player_GiveScore(player, 200); break;712case 2: Player_GiveScore(player, 500); break;713714case 3:715case 4:716case 5:717case 6:718case 7:719case 8:720case 9:721case 10:722case 11:723case 12:724case 13:725case 14: Player_GiveScore(player, 1000); break;726727case 15: Player_GiveScore(player, 10000); break;728729default: break;730}731732if (player->scoreBonus < 15)733player->scoreBonus++;734}735736#if GAME_INCLUDE_EDITOR737void BreakableWall_EditorDraw(void)738{739RSDK_THIS(BreakableWall);740741int32 sizeX = self->size.x;742int32 sizeY = self->size.y;743744switch (self->type) {745case BREAKWALL_TYPE_WALL:746if (!sizeX) {747sizeX = TO_FIXED(2);748sizeY = TO_FIXED(4);749}750break;751752case BREAKWALL_TYPE_FLOOR:753if (!sizeX) {754sizeX = TO_FIXED(2);755sizeY = TO_FIXED(2);756}757break;758759case BREAKWALL_TYPE_BURROWFLOOR:760case BREAKWALL_TYPE_BURROWFLOOR_B:761if (!sizeX)762sizeX = TO_FIXED(2);763break;764765case BREAKWALL_TYPE_BURROWFLOORUP:766if (!sizeX)767sizeX = TO_FIXED(2);768break;769770case BREAKWALL_TYPE_CEILING:771if (!sizeX) {772sizeX = TO_FIXED(2);773sizeY = TO_FIXED(2);774}775break;776777default: break;778}779780sizeX <<= 4;781sizeY <<= 4;782783Vector2 drawPos;784drawPos.x = self->position.x - sizeX;785drawPos.y = self->position.y - sizeY;786787DrawHelpers_DrawRectOutline(self->position.x, self->position.y, sizeX, sizeY, 0xFFFF00);788789drawPos.x += sizeX >> 1;790drawPos.y += sizeY >> 1;791792self->direction = FLIP_NONE;793RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);794795drawPos.x += sizeX;796self->direction = FLIP_X;797RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);798799drawPos.y += sizeY;800self->direction = FLIP_XY;801RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);802803drawPos.x -= sizeX;804self->direction = FLIP_Y;805RSDK.DrawSprite(&BreakableWall->animator, &drawPos, false);806}807808void BreakableWall_EditorLoad(void)809{810BreakableWall->aniFrames = RSDK.LoadSpriteAnimation("Global/TicMark.bin", SCOPE_STAGE);811RSDK.SetSpriteAnimation(BreakableWall->aniFrames, 0, &BreakableWall->animator, true, 0);812813RSDK_ACTIVE_VAR(BreakableWall, type);814RSDK_ENUM_VAR("Wall", BREAKWALL_TYPE_WALL);815RSDK_ENUM_VAR("Floor", BREAKWALL_TYPE_FLOOR);816RSDK_ENUM_VAR("Burrow Floor", BREAKWALL_TYPE_BURROWFLOOR);817RSDK_ENUM_VAR("Burrow Floor (Plane B Only)", BREAKWALL_TYPE_BURROWFLOOR_B);818RSDK_ENUM_VAR("Burrow Floor Up", BREAKWALL_TYPE_BURROWFLOORUP);819RSDK_ENUM_VAR("Ceiling", BREAKWALL_TYPE_CEILING);820821RSDK_ACTIVE_VAR(BreakableWall, priority);822RSDK_ENUM_VAR("FG High", BREAKWALL_PRIO_HIGH);823RSDK_ENUM_VAR("FG Low", BREAKWALL_PRIO_LOW);824}825#endif826827void BreakableWall_Serialize(void)828{829RSDK_EDITABLE_VAR(BreakableWall, VAR_UINT8, type);830RSDK_EDITABLE_VAR(BreakableWall, VAR_BOOL, onlyKnux);831RSDK_EDITABLE_VAR(BreakableWall, VAR_BOOL, onlyMighty);832RSDK_EDITABLE_VAR(BreakableWall, VAR_ENUM, priority);833RSDK_EDITABLE_VAR(BreakableWall, VAR_VECTOR2, size);834}835836837