summaryrefslogtreecommitdiff
path: root/src/object
diff options
context:
space:
mode:
authornotyourav <65437533+notyourav@users.noreply.github.com>2022-02-01 18:47:18 -0800
committerGitHub <noreply@github.com>2022-02-01 18:47:18 -0800
commitfccda2459d676e7dc30f0d76c6c0fbd65d409d57 (patch)
tree20e2e812b6d23ea460ae4c25e2bbfd492d412641 /src/object
parent3c81dd4103225af8781ac92b4a866832d1b17700 (diff)
parentfb9174c0d3ddd1b7544670257e38c85bbb612adf (diff)
Merge pull request #337 from octorock/push-and-pull
Diffstat (limited to 'src/object')
-rw-r--r--src/object/bigIceBlock.c331
-rw-r--r--src/object/blockPushed.c181
-rw-r--r--src/object/jailBars.c2
-rw-r--r--src/object/mask.c6
-rw-r--r--src/object/object49.c1
-rw-r--r--src/object/octorokBossObject.c2
-rw-r--r--src/object/pullableMushroom.c316
-rw-r--r--src/object/pushableFurniture.c401
-rw-r--r--src/object/pushableGrave.c213
-rw-r--r--src/object/pushableRock.c123
-rw-r--r--src/object/pushableStatue.c277
-rw-r--r--src/object/smallIceBlock.c330
12 files changed, 2174 insertions, 9 deletions
diff --git a/src/object/bigIceBlock.c b/src/object/bigIceBlock.c
new file mode 100644
index 00000000..dc9539bb
--- /dev/null
+++ b/src/object/bigIceBlock.c
@@ -0,0 +1,331 @@
+/**
+ * @file bigIceBlock.c
+ * @ingroup Objects
+ *
+ * @brief Big Ice Block object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[0x4];
+ /*0x6c*/ u16 unk_6c;
+ /*0x6e*/ u16 unk_6e;
+ /*0x70*/ u8 unk_70[0x16];
+ /*0x86*/ u16 unk_86;
+} BigIceBlockEntity;
+
+extern const Hitbox gUnk_080FD190;
+
+extern void (*const BigIceBlock_Actions[])(BigIceBlockEntity*);
+extern const u16 gUnk_081237B0[];
+
+void sub_08099D30(BigIceBlockEntity*);
+void sub_08099910(BigIceBlockEntity*);
+extern bool32 sub_0809963C(BigIceBlockEntity*);
+void BigIceBlock_Action2(BigIceBlockEntity*);
+extern bool32 sub_0809963C(BigIceBlockEntity*);
+void sub_08099C18(BigIceBlockEntity*);
+
+void BigIceBlock(BigIceBlockEntity* this) {
+ if (super->type < 4) {
+ BigIceBlock_Actions[super->action](this);
+ } else {
+ sub_08099D30(this);
+ }
+}
+
+void BigIceBlock_Init(BigIceBlockEntity* this) {
+ Entity* obj;
+
+ if (CheckFlags(this->unk_86)) {
+ DeleteThisEntity();
+ }
+ super->action = 1;
+ super->flags |= 0x80;
+ super->updatePriority = 3;
+ super->field_0x3c = 7;
+ super->hurtType = 0x48;
+ super->hitType = 1;
+ super->flags2 = 0x80;
+ super->hitbox = (Hitbox*)&gUnk_080FD190;
+ sub_08099910(this);
+ InitializeAnimation(super, super->type);
+ obj = CreateObject(BIG_ICE_BLOCK, 4, 0);
+ if (obj != NULL) {
+ obj->parent = super;
+ }
+}
+
+void BigIceBlock_Action1(BigIceBlockEntity* this) {
+ if (sub_0809963C(this)) {
+ super->action = 2;
+ super->actionDelay = 0;
+ EnqueueSFX(SFX_ICE_BLOCK_MELT);
+ BigIceBlock_Action2(this);
+ }
+}
+
+void BigIceBlock_Action2(BigIceBlockEntity* this) {
+ u32 tmp;
+ if (!sub_0809963C(this)) {
+ if (super->actionDelay >= 2) {
+ super->actionDelay -= 2;
+ } else {
+ super->actionDelay = 0;
+ }
+ if (super->actionDelay == 0) {
+ super->action = 1;
+ sub_0805EC60(super);
+ return;
+ }
+ } else {
+ super->actionDelay += 1;
+ }
+ tmp = gUnk_081237B0[super->actionDelay >> 5];
+ sub_0805EC9C(super, 0x100, tmp, 0);
+ if (super->type != 1) {
+ if (super->type != 2) {
+ SetFlag(this->unk_86);
+ } else {
+ sub_080A2A3C(super, 0x53, 0, this->unk_86);
+ }
+ }
+ super->action = 3;
+ super->actionDelay = 0x3c;
+ super->flags &= 0x7f;
+}
+
+NONMATCH("asm/non_matching/bigIceBlock/sub_08099880.inc", void sub_08099880(BigIceBlockEntity* this)) {
+ Entity* obj;
+ s32 rand;
+ u8 uVar3;
+ u32 uVar4;
+ s32 x;
+ s32 y;
+
+ if (--super->actionDelay == 0) {
+ DeleteThisEntity();
+ } else {
+ if (super->actionDelay == 0x30) {
+ sub_08099C18(this);
+ }
+ uVar4 = (0x3c - super->actionDelay) * 0x20 + 0x100;
+ sub_0805EC9C(super, 0x100, uVar4, 0);
+ sub_0806FCF4(super, uVar4, 2, 0);
+ obj = CreateObject(SPECIAL_FX, 0x11, 0x40);
+ if (obj != NULL) {
+ rand = Random();
+ x = ((rand >> 0x10) % 0x21) - 0x10;
+ y = (rand & 0xf) - 4;
+ obj->spritePriority.b0 = 3;
+ PositionRelative(super, obj, x * 0x10000, y * 0x10000);
+ }
+ }
+}
+END_NONMATCH
+
+void sub_08099910(BigIceBlockEntity* this) {
+ u32 uVar2;
+ s32 iVar1;
+ u32 uVar3;
+ u32 position;
+
+ position = COORD_TO_TILE(super);
+ this->unk_6e = position;
+ uVar2 = (((super->x.HALF.HI & 8)) >> 0x3) + ((super->y.HALF.HI & 8) >> 2);
+ this->unk_6c = uVar2;
+
+ switch (uVar2) {
+ default:
+ SetTile(0x4022, position - 0x41, super->collisionLayer);
+ SetTile(0x4022, position - 0x40, super->collisionLayer);
+ SetTile(0x4022, position - 1, super->collisionLayer);
+ SetTile(0x4022, position, super->collisionLayer);
+ break;
+ case 1:
+ iVar1 = sub_080002C8(position - 0x41, super->collisionLayer);
+ uVar3 = 0x4024;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4079;
+ }
+ SetTile(uVar3, position - 0x41, super->collisionLayer);
+ SetTile(0x4022, position - 0x40, super->collisionLayer);
+ iVar1 = sub_080002C8(position - 0x3f, super->collisionLayer);
+ uVar3 = 0x4025;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407b;
+ }
+ SetTile(uVar3, position - 0x3f, super->collisionLayer);
+ iVar1 = sub_080002C8(position - 1, super->collisionLayer);
+ uVar3 = 0x4024;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4079;
+ }
+ SetTile(uVar3, position - 1, super->collisionLayer);
+ SetTile(0x4022, position, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 1, super->collisionLayer);
+ uVar3 = 0x4025;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407b;
+ }
+ SetTile(uVar3, position + 1, super->collisionLayer);
+ return;
+ break;
+ case 2:
+ iVar1 = sub_080002C8(position - 0x41, super->collisionLayer);
+ uVar3 = 0x4023;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4077;
+ }
+ SetTile(uVar3, position - 0x41, super->collisionLayer);
+ iVar1 = sub_080002C8(position - 0x40, super->collisionLayer);
+ uVar3 = 0x4023;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4077;
+ }
+ SetTile(uVar3, position - 0x40, super->collisionLayer);
+ SetTile(0x4022, position - 1, super->collisionLayer);
+ SetTile(0x4022, position, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 0x3f, super->collisionLayer);
+ uVar3 = 0x4026;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407c;
+ }
+ SetTile(uVar3, position + 0x3f, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 0x40, super->collisionLayer);
+ uVar3 = 0x4026;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407c;
+ }
+ SetTile(uVar3, position + 0x40, super->collisionLayer);
+ break;
+ case 3:
+ iVar1 = sub_080002C8(position - 0x41, super->collisionLayer);
+ uVar3 = 0x4027;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4075;
+ }
+ SetTile(uVar3, position - 0x41, super->collisionLayer);
+ iVar1 = sub_080002C8(position - 0x40, super->collisionLayer);
+ uVar3 = 0x4023;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4077;
+ }
+ SetTile(uVar3, position - 0x40, super->collisionLayer);
+ iVar1 = sub_080002C8(position - 0x3f, super->collisionLayer);
+ uVar3 = 0x4028;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4076;
+ }
+ SetTile(uVar3, position - 0x3f, super->collisionLayer);
+ iVar1 = sub_080002C8(position - 1, super->collisionLayer);
+ uVar3 = 0x4024;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4079;
+ }
+ SetTile(uVar3, position - 1, super->collisionLayer);
+ SetTile(0x4022, position, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 1, super->collisionLayer);
+ uVar3 = 0x4025;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407b;
+ }
+ SetTile(uVar3, position + 1, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 0x3f, super->collisionLayer);
+ uVar3 = 0x4029;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x4078;
+ }
+ SetTile(uVar3, position + 0x3f, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 0x40, super->collisionLayer);
+ uVar3 = 0x4026;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407c;
+ }
+ SetTile(uVar3, position + 0x40, super->collisionLayer);
+ iVar1 = sub_080002C8(position + 0x41, super->collisionLayer);
+ uVar3 = 0x402a;
+ if (iVar1 == 0x12) {
+ uVar3 = 0x407a;
+ }
+ SetTile(uVar3, position + 0x41, super->collisionLayer);
+ break;
+ }
+}
+
+void sub_08099C18(BigIceBlockEntity* this) {
+ u32 tmp = this->unk_6e;
+ switch (this->unk_6c) {
+ default:
+ sub_0807BA8C(tmp - 0x41, super->collisionLayer);
+ sub_0807BA8C(tmp - 0x40, super->collisionLayer);
+ sub_0807BA8C(tmp - 1, super->collisionLayer);
+ sub_0807BA8C(tmp, super->collisionLayer);
+ break;
+ case 1:
+ sub_0807BA8C(tmp - 0x41, super->collisionLayer);
+ sub_0807BA8C(tmp - 0x40, super->collisionLayer);
+ sub_0807BA8C(tmp - 0x3f, super->collisionLayer);
+ sub_0807BA8C(tmp - 1, super->collisionLayer);
+ sub_0807BA8C(tmp, super->collisionLayer);
+ sub_0807BA8C(tmp + 1, super->collisionLayer);
+ break;
+ case 2:
+ sub_0807BA8C(tmp - 0x41, super->collisionLayer);
+ sub_0807BA8C(tmp - 0x40, super->collisionLayer);
+ sub_0807BA8C(tmp - 1, super->collisionLayer);
+ sub_0807BA8C(tmp, super->collisionLayer);
+ sub_0807BA8C(tmp + 0x3f, super->collisionLayer);
+ sub_0807BA8C(tmp + 0x40, super->collisionLayer);
+ break;
+ case 3:
+ sub_0807BA8C(tmp - 0x41, super->collisionLayer);
+ sub_0807BA8C(tmp - 0x40, super->collisionLayer);
+ sub_0807BA8C(tmp - 0x3f, super->collisionLayer);
+ sub_0807BA8C(tmp - 1, super->collisionLayer);
+ sub_0807BA8C(tmp, super->collisionLayer);
+ sub_0807BA8C(tmp + 1, super->collisionLayer);
+ sub_0807BA8C(tmp + 0x3f, super->collisionLayer);
+ sub_0807BA8C(tmp + 0x40, super->collisionLayer);
+ sub_0807BA8C(tmp + 0x41, super->collisionLayer);
+ break;
+ }
+}
+
+void sub_08099D30(BigIceBlockEntity* this) {
+ if ((super->parent)->next == NULL) {
+ DeleteThisEntity();
+ }
+ if (super->action == 0) {
+ super->action = 1;
+ InitializeAnimation(super, 4);
+ CopyPositionAndSpriteOffset(super->parent, super);
+ super->y.HALF.HI++;
+ super->spriteOffsetY--;
+ }
+ if ((super->parent)->action < 2) {
+ super->spriteSettings.draw = 1;
+ if ((super->frame & 1) != 0) {
+ super->frame = 0;
+ super->frameDuration = (Random() & 0x78) + 0x78;
+ }
+ GetNextFrame(super);
+ } else {
+ super->spriteSettings.draw = 0;
+ }
+}
+
+void (*const BigIceBlock_Actions[])(BigIceBlockEntity*) = {
+ BigIceBlock_Init,
+ BigIceBlock_Action1,
+ BigIceBlock_Action2,
+ sub_08099880,
+};
+const u16 gUnk_081237B0[] = {
+ 256, 266, 275, 284, 293,
+};
diff --git a/src/object/blockPushed.c b/src/object/blockPushed.c
new file mode 100644
index 00000000..f79a0ae0
--- /dev/null
+++ b/src/object/blockPushed.c
@@ -0,0 +1,181 @@
+/**
+ * @file blockPushed.c
+ * @ingroup Objects
+ *
+ * @brief Block Pushed object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u32 unk_68;
+} BlockPushedEntity;
+
+extern void (*const gUnk_0811F624[])(BlockPushedEntity*);
+extern const Hitbox* const gUnk_0811F64C[];
+
+void sub_080832D8(u32, BlockPushedEntity*);
+void sub_080830B8(BlockPushedEntity*);
+
+void BlockPushed(BlockPushedEntity* this) {
+ gUnk_0811F624[super->action](this);
+}
+
+void sub_08082EB4(BlockPushedEntity* this) {
+ u16 tmp;
+ u32 pos;
+
+ if (gRoomControls.area == 0x11) {
+ sub_080AE068(super);
+ if (LoadFixedGFX(super, 0x1c1) == 0) {
+ super->spriteSettings.draw = 0;
+ return;
+ }
+ super->spriteSettings.draw = 1;
+ }
+ super->action = 1;
+ super->actionDelay = 0x20;
+ super->speed = 0x80;
+ super->spritePriority.b0 = 6;
+ pos = COORD_TO_TILE(super);
+ tmp = super->type * 8;
+ super->x.HALF.HI += tmp;
+ super->y.HALF.HI += tmp;
+ super->hitbox = (Hitbox*)gUnk_0811F64C[super->type];
+ this->unk_68 = GetTileType(pos, (u32)super->collisionLayer);
+ switch (super->type) {
+ case 0:
+ sub_080832D8(pos, this);
+ break;
+ case 1:
+ sub_080832D8(pos, this);
+ sub_080832D8(pos + 1, this);
+ sub_080832D8(pos + 0x40, this);
+ sub_080832D8(pos + 0x41, this);
+ break;
+ case 2:
+ sub_080832D8(pos, this);
+ sub_080832D8(pos + 1, this);
+ sub_080832D8(pos + 2, this);
+ sub_080832D8(pos + 0x40, this);
+ sub_080832D8(pos + 0x41, this);
+ sub_080832D8(pos + 0x42, this);
+ sub_080832D8(pos + 0x80, this);
+ sub_080832D8(pos + 0x81, this);
+ sub_080832D8(pos + 0x82, this);
+ break;
+ default:
+ sub_080832D8(pos, this);
+ sub_080832D8(pos + 1, this);
+ sub_080832D8(pos + 2, this);
+ sub_080832D8(pos + 3, this);
+ sub_080832D8(pos + 0x40, this);
+ sub_080832D8(pos + 0x41, this);
+ sub_080832D8(pos + 0x42, this);
+ sub_080832D8(pos + 0x43, this);
+ sub_080832D8(pos + 0x80, this);
+ sub_080832D8(pos + 0x81, this);
+ sub_080832D8(pos + 0x82, this);
+ sub_080832D8(pos + 0x83, this);
+ sub_080832D8(pos + 0xc0, this);
+ sub_080832D8(pos + 0xc1, this);
+ sub_080832D8(pos + 0xc2, this);
+ sub_080832D8(pos + 0xc3, this);
+ break;
+ }
+ EnqueueSFX(SFX_10F);
+}
+
+void sub_08083094(BlockPushedEntity* this) {
+ LinearMoveUpdate(super);
+ sub_0800445C(super);
+ if (--super->actionDelay == 0) {
+ sub_080830B8(this);
+ }
+}
+
+void sub_080830B8(BlockPushedEntity* this) {
+ s32 offset = super->type * 8;
+ u32 pos = COORD_TO_TILE_OFFSET(super, offset, offset);
+
+ switch (super->type) {
+ case 0:
+ if (sub_0800442E(super)) {
+ return;
+ }
+ sub_0807B7D8(0x365, pos, super->collisionLayer);
+ break;
+ case 1:
+ sub_0807B7D8(this->unk_68, pos, super->collisionLayer);
+ sub_0807B7D8(0x36f, pos + 1, super->collisionLayer);
+ sub_0807B7D8(0x370, pos + 0x40, super->collisionLayer);
+ sub_0807B7D8(0x371, pos + 0x41, super->collisionLayer);
+ break;
+ case 2:
+ sub_0807B7D8(this->unk_68, pos, super->collisionLayer);
+ sub_0807B7D8(0x372, pos + 1, super->collisionLayer);
+ sub_0807B7D8(0x36f, pos + 2, super->collisionLayer);
+ sub_0807B7D8(0x374, pos + 0x40, super->collisionLayer);
+ sub_0807B7D8(0x376, pos + 0x41, super->collisionLayer);
+ sub_0807B7D8(0x375, pos + 0x42, super->collisionLayer);
+ sub_0807B7D8(0x370, pos + 0x80, super->collisionLayer);
+ sub_0807B7D8(0x373, pos + 0x81, super->collisionLayer);
+ sub_0807B7D8(0x371, pos + 0x82, super->collisionLayer);
+ break;
+ default:
+ sub_0807B7D8(this->unk_68, pos, super->collisionLayer);
+ sub_0807B7D8(0x372, pos + 1, super->collisionLayer);
+ sub_0807B7D8(0x372, pos + 2, super->collisionLayer);
+ sub_0807B7D8(0x36f, pos + 3, super->collisionLayer);
+ sub_0807B7D8(0x374, pos + 0x40, super->collisionLayer);
+ sub_0807B7D8(0x376, pos + 0x41, super->collisionLayer);
+ sub_0807B7D8(0x376, pos + 0x42, super->collisionLayer);
+ sub_0807B7D8(0x375, pos + 0x43, super->collisionLayer);
+ sub_0807B7D8(0x374, pos + 0x80, super->collisionLayer);
+ sub_0807B7D8(0x376, pos + 0x81, super->collisionLayer);
+ sub_0807B7D8(0x376, pos + 0x82, super->collisionLayer);
+ sub_0807B7D8(0x375, pos + 0x83, super->collisionLayer);
+ sub_0807B7D8(0x370, pos + 0xc0, super->collisionLayer);
+ sub_0807B7D8(0x373, pos + 0xc1, super->collisionLayer);
+ sub_0807B7D8(0x373, pos + 0xc2, super->collisionLayer);
+ sub_0807B7D8(0x371, pos + 0xc3, super->collisionLayer);
+ break;
+ }
+ DeleteEntity(super);
+}
+
+void sub_080832D8(u32 param_1, BlockPushedEntity* this) {
+ if (super->collisionLayer != 2) {
+ if ((super->direction & 8) != 0) {
+ sub_0807B7D8(0x21, param_1, super->collisionLayer);
+ } else {
+ sub_0807B7D8(0x20, param_1, super->collisionLayer);
+ }
+ } else {
+ if ((super->direction & 8) != 0) {
+ sub_0807B7D8(0x2f, param_1, super->collisionLayer);
+ } else {
+ sub_0807B7D8(0x2e, param_1, super->collisionLayer);
+ }
+ }
+}
+
+void (*const gUnk_0811F624[])(BlockPushedEntity*) = {
+ sub_08082EB4,
+ sub_08083094,
+};
+const Hitbox gUnk_0811F62C = { 0, 0, { 0, 0, 0, 0 }, 5, 4 };
+const Hitbox gUnk_0811F634 = { 0, 0, { 0, 0, 0, 0 }, 13, 12 };
+const Hitbox gUnk_0811F63C = { 0, 0, { 0, 0, 0, 0 }, 21, 20 };
+const Hitbox gUnk_0811F644 = { 0, 0, { 0, 0, 0, 0 }, 29, 28 };
+
+const Hitbox* const gUnk_0811F64C[] = {
+ &gUnk_0811F62C,
+ &gUnk_0811F634,
+ &gUnk_0811F63C,
+ &gUnk_0811F644,
+};
diff --git a/src/object/jailBars.c b/src/object/jailBars.c
index 84b44b61..7a36f0e2 100644
--- a/src/object/jailBars.c
+++ b/src/object/jailBars.c
@@ -3,9 +3,9 @@
#include "flags.h"
#include "room.h"
#include "sound.h"
+#include "functions.h"
extern void sub_080A0960(Entity*, u32);
-extern void sub_0801AF18(u8*, u32, u32);
extern void (*const gUnk_08124950[])(Entity*);
extern u8 gUnk_08124960;
diff --git a/src/object/mask.c b/src/object/mask.c
index 00c9e957..1b960d7a 100644
--- a/src/object/mask.c
+++ b/src/object/mask.c
@@ -3,10 +3,6 @@
extern void (*MaskActionFuncs[])(Entity*);
-extern void sub_08000148(u16, u16, u32);
-
-extern void sub_0805457C(Entity*, s32);
-
void Mask(Entity* this) {
MaskActionFuncs[this->action](this);
}
@@ -79,7 +75,7 @@ void sub_08092A94(Entity* this) {
// Presumably, make the mask fall
SetTile(this->field_0x7c.HALF_U.LO, this->field_0x7c.HALF_U.HI, 1);
- sub_08000148(this->field_0x7a.HWORD, this->field_0x7c.HALF.HI, 1);
+ sub_08000148(this->field_0x7a.HWORD, (u16)this->field_0x7c.HALF.HI, 1);
this->action = 2;
diff --git a/src/object/object49.c b/src/object/object49.c
index c65b41bf..aaecd05b 100644
--- a/src/object/object49.c
+++ b/src/object/object49.c
@@ -5,7 +5,6 @@ static void sub_0808F2B0(Entity*);
void sub_0808F14C(Entity*);
void sub_0808F244(Entity*);
-extern void sub_0806FCF4(Entity*, u32, u32, u32);
extern void sub_0808F5EC(Entity*);
extern void (*const gUnk_08121E5C[])(Entity*);
diff --git a/src/object/octorokBossObject.c b/src/object/octorokBossObject.c
index cd527a72..ef2f279a 100644
--- a/src/object/octorokBossObject.c
+++ b/src/object/octorokBossObject.c
@@ -2,8 +2,6 @@
#include "object.h"
#include "game.h"
-extern void sub_0807B9B8(s32, s32, s32);
-
extern void (*const OctorokBossObject_Actions[])(Entity*);
extern const u16 gUnk_0812384C[];
extern const u16 gUnk_0812388C[];
diff --git a/src/object/pullableMushroom.c b/src/object/pullableMushroom.c
new file mode 100644
index 00000000..9a878236
--- /dev/null
+++ b/src/object/pullableMushroom.c
@@ -0,0 +1,316 @@
+/**
+ * @file pullableMushroom.c
+ * @ingroup Objects
+ *
+ * @brief Pullable Mushroom object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+#include "game.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[0x8];
+ /*0x70*/ u32 unk_70;
+ /*0x74*/ u32 unk_74;
+ /*0x78*/ u32 unk_78;
+ /*0x7c*/ u32 unk_7c;
+} PullableMushroomEntity;
+
+extern const Hitbox gUnk_080FD224;
+extern const u8 gUnk_08126EE4[];
+
+extern void (*const gUnk_081211A4[])(PullableMushroomEntity*);
+extern void (*const gUnk_081211B4[])(PullableMushroomEntity*);
+extern void (*const gUnk_081211C0[])(PullableMushroomEntity*);
+extern const u16 gUnk_081211CC[];
+extern void (*const gUnk_081211DC[])(PullableMushroomEntity*);
+extern const u16 gUnk_081211E4[];
+extern void (*const gUnk_081211EC[])(PullableMushroomEntity*);
+extern const u8 gUnk_081211F4[];
+extern const u8 gUnk_081211FC[];
+
+void sub_0808AB68(PullableMushroomEntity*);
+void sub_0808B168(PullableMushroomEntity*, u32);
+u32 sub_0808B1F0(PullableMushroomEntity*, Entity*);
+bool32 sub_0808B21C(PullableMushroomEntity*, u32);
+
+void PullableMushroom(PullableMushroomEntity* this) {
+ gUnk_081211A4[super->action](this);
+ super->bitfield = 0;
+}
+
+void sub_0808AA1C(PullableMushroomEntity* this) {
+ super->action = 1;
+ if (AreaIsDungeon() == 0) {
+ ChangeObjPalette(super, 0);
+ }
+ switch (super->type) {
+ case 0:
+ super->spritePriority.b0 = 4;
+ super->hitbox = (Hitbox*)&gUnk_080FD224;
+ super->field_0x16 = 1;
+ SetTile(0x4022, COORD_TO_TILE(super), super->collisionLayer);
+ super->health = 1;
+ super->field_0x3c = 7;
+ super->hitType = 0x6e;
+ super->flags2 = 0x0e;
+ super->field_0x1c = 1;
+ super->flags |= 0x80;
+ super->spriteOffsetY = 4;
+ break;
+ case 1:
+ super->spritePriority.b0 = 4;
+ if (super->type2 != 0) {
+ super->hitbox = (Hitbox*)&gUnk_080FD224;
+ super->flags |= 0x80;
+ super->health = 1;
+ super->field_0x3c = 7;
+ super->hitType = 0x6e;
+ super->flags2 = 4;
+ super->field_0x1c = 1;
+ super->action = 3;
+ }
+ InitializeAnimation(super, super->animationState + 9);
+ break;
+ case 2:
+ super->spritePriority.b0 = 5;
+ super->spriteRendering.b0 = 3;
+ if ((super->animationState & 1)) {
+ this->unk_74 = 0x200;
+ this->unk_78 = 0x100;
+ } else {
+ this->unk_78 = 0x200;
+ this->unk_74 = 0x100;
+ }
+ break;
+ }
+ sub_0808AB68(this);
+}
+
+void sub_0808AB68(PullableMushroomEntity* this) {
+ gUnk_081211B4[super->type](this);
+}
+
+void sub_0808AB80(PullableMushroomEntity* this) {
+ gUnk_081211C0[super->subAction](this);
+}
+
+void sub_0808AB98(PullableMushroomEntity* this) {
+ if (*(u16*)&super->parent->action == 0x201) {
+ super->parent->child = NULL;
+ DeleteThisEntity();
+ } else if (super->parent->action == 2) {
+ sub_0808B168(this, 0);
+ }
+}
+
+ASM_FUNC("asm/non_matching/pullableMushroom/sub_0808ABC4.inc", void sub_0808ABC4(PullableMushroomEntity* this))
+
+ASM_FUNC("asm/non_matching/pullableMushroom/sub_0808ACEC.inc", void sub_0808ACEC(PullableMushroomEntity* this))
+
+void sub_0808ADA0(PullableMushroomEntity* this) {
+ if ((sub_0808B1F0(this, super->child) < 8) || (super->child == NULL)) {
+ super->subAction += 1;
+ super->actionDelay = 2;
+ super->flags |= 0x80;
+ super->animationState ^= 2;
+ super->spritePriority.b0 = 4;
+ } else {
+ super->child->speed = 0x400;
+ LinearMoveUpdate(super->child);
+ }
+}
+
+void sub_0808ADF0(PullableMushroomEntity* this) {
+ if (super->animationState + 0xd == super->animIndex) {
+ if ((super->frame & 0x80) != 0) {
+ super->subAction = 0;
+ super->flags |= 0x80;
+ } else {
+ GetNextFrame(super);
+ }
+ } else {
+ if (super->animationState + 1 != super->animIndex) {
+ InitializeAnimation(super, super->animationState + 1);
+ if (super->animationState == 3) {
+ super->spriteSettings.flipX = 0;
+ } else {
+ super->spriteSettings.flipX = 1;
+ }
+ SoundReq(SFX_12E);
+ } else {
+ GetNextFrame(super);
+ if (((super->frame & 0x80) != 0) && (--super->actionDelay == 0xff)) {
+ InitializeAnimation(super, super->animationState + 0xd);
+ }
+ }
+ }
+}
+
+void sub_0808AE84(PullableMushroomEntity* this) {
+ if (gPlayerState.heldObject == 0) {
+ super->subAction = 6;
+ }
+ gUnk_081211DC[super->subAction - 5](this);
+}
+
+void sub_0808AEB0(PullableMushroomEntity* this) {
+ u32 uVar1;
+ if (super->actionDelay != 0) {
+ uVar1 = sub_0808B1F0(this, super->child);
+ if ((gPlayerState.field_0x90 & gUnk_081211E4[super->animationState]) != 0) {
+ GetNextFrame(super);
+ if (uVar1 < 0x40) {
+ sub_080044AE(&gPlayerEntity, 0x40, super->direction);
+ if (--this->unk_7c == 0xffffffff) {
+ this->unk_7c = 4;
+ SoundReq(SFX_12F);
+ }
+ }
+ super->field_0xf = 1;
+
+ } else {
+ if (((super->field_0xf != 0) && (gPlayerEntity.action == 1)) && (gPlayerState.swim_state == 0)) {
+ gPlayerState.queued_action = 0x1b;
+ gPlayerState.field_0x38 = uVar1;
+ gPlayerState.field_0x39 = super->direction ^ 0x10;
+ gPlayerState.field_0x3a = sub_0808B1F0(this, &gPlayerEntity);
+ super->subAction++;
+ }
+ }
+ } else {
+ super->actionDelay = 1;
+ this->unk_7c = 1;
+ super->animationState = gPlayerEntity.animationState >> 1 ^ 2;
+ super->direction = (super->animationState << 3);
+ super->flags &= 0x7f;
+ super->spriteSettings.flipX = gPlayerEntity.spriteSettings.flipX;
+ InitializeAnimation(super, super->animationState + 5);
+ if (sub_0808B21C(this, 0)) {
+ sub_0808B168((PullableMushroomEntity*)super->child, 0);
+ }
+ if ((super->animationState & 1) != 0) {
+ gPlayerEntity.y.HALF.HI = super->y.HALF.HI;
+ } else {
+ gPlayerEntity.x.HALF.HI = super->x.HALF.HI;
+ }
+ }
+}
+
+void sub_0808AFD4(PullableMushroomEntity* this) {
+ super->action = 1;
+ super->subAction = 1;
+ (super->child)->direction = super->direction ^ 0x10;
+ SoundReq(SFX_130);
+}
+
+void sub_0808AFF0(PullableMushroomEntity* this) {
+ gUnk_081211EC[super->subAction](this);
+ if ((((gPlayerState.field_0x1c & 0xf) != 1) || ((super->bitfield & 0x7f) != 0x13)) && (super->type == 1)) {
+ (super->parent)->action = 1;
+ (super->parent)->subAction = 1;
+ super->direction = super->parent->direction ^ 0x10;
+ super->parent->flags &= 0x7f;
+ super->flags &= 0x7f;
+ super->action = 1;
+ SoundReq(SFX_130);
+ }
+}
+
+void sub_0808B05C(PullableMushroomEntity* this) {
+ if (super->type == 0) {
+ super->animationState = gPlayerEntity.animationState >> 1 ^ 2;
+ super->direction = super->animationState << 3;
+ super->spriteSettings.flipX = gPlayerEntity.spriteSettings.flipX;
+ super->flags &= 0x7f;
+ InitializeAnimation(super, super->animationState + 5);
+ if (sub_0808B21C(this, 1)) {
+ sub_0808B168((PullableMushroomEntity*)super->child, 1);
+ }
+ }
+ super->subAction++;
+}
+
+ASM_FUNC("asm/non_matching/pullableMushroom/sub_0808B0BC.inc", void sub_0808B0BC(PullableMushroomEntity* this))
+
+ASM_FUNC("asm/non_matching/pullableMushroom/sub_0808B168.inc",
+ void sub_0808B168(PullableMushroomEntity* this, u32 param_2))
+
+u32 sub_0808B1F0(PullableMushroomEntity* this, Entity* other) {
+ s32 sVar1;
+ s32 sVar2;
+ u32 uVar3;
+
+ if ((super->animationState & 1) != 0) {
+ sVar1 = super->x.HALF.HI;
+ sVar2 = other->x.HALF.HI;
+ } else {
+ sVar1 = super->y.HALF.HI;
+ sVar2 = other->y.HALF.HI;
+ }
+ uVar3 = (s32)sVar1 - (s32)sVar2;
+ if ((s32)uVar3 < 0) {
+ uVar3 = -uVar3;
+ }
+ return uVar3;
+}
+
+bool32 sub_0808B21C(PullableMushroomEntity* this, u32 param_2) {
+ Entity* obj;
+
+ super->spritePriority.b0 = 6;
+ obj = CreateObjectWithParent(super, PULLABLE_MUSHROOM, 1, 0);
+ super->child = obj;
+ if (obj != NULL) {
+ obj->animationState = super->animationState;
+ (super->child)->direction = super->direction;
+ super->child->spriteSettings.flipX = super->spriteSettings.flipX;
+ (super->child)->parent = super;
+ (super->child)->type2 = (u8)param_2;
+ }
+ obj = CreateObjectWithParent(super, PULLABLE_MUSHROOM, 2, 0);
+ super->parent = obj;
+ if (obj != NULL) {
+ obj->animationState = super->animationState;
+ (super->parent)->child = super->child;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void (*const gUnk_081211A4[])(PullableMushroomEntity*) = {
+ sub_0808AA1C,
+ sub_0808AB68,
+ sub_0808AE84,
+ sub_0808AFF0,
+};
+void (*const gUnk_081211B4[])(PullableMushroomEntity*) = {
+ sub_0808AB80,
+ sub_0808AB98,
+ sub_0808ABC4,
+};
+void (*const gUnk_081211C0[])(PullableMushroomEntity*) = {
+ sub_0808ACEC,
+ sub_0808ADA0,
+ sub_0808ADF0,
+};
+const u16 gUnk_081211CC[] = { 32768, 64000, 0, 64517, 0, 0, 32768, 64763 };
+void (*const gUnk_081211DC[])(PullableMushroomEntity*) = {
+ sub_0808AEB0,
+ sub_0808AFD4,
+};
+const u16 gUnk_081211E4[] = { 1024, 256, 2048, 512 };
+void (*const gUnk_081211EC[])(PullableMushroomEntity*) = {
+ sub_0808B05C,
+ sub_0808B0BC,
+};
+const u8 gUnk_081211F4[] = {
+ 0, 8, 248, 252, 0, 248, 8, 252,
+};
+const u8 gUnk_081211FC[] = {
+ 0, 3, 248, 252, 0, 244, 8, 252,
+};
diff --git a/src/object/pushableFurniture.c b/src/object/pushableFurniture.c
new file mode 100644
index 00000000..01bf646f
--- /dev/null
+++ b/src/object/pushableFurniture.c
@@ -0,0 +1,401 @@
+/**
+ * @file pushableFurniture.c
+ * @ingroup Objects
+ *
+ * @brief Pushable Furniture object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[0x8];
+ /*0x70*/ u16 unk_70;
+ /*0x72*/ u16 unk_72;
+ /*0x74*/ u16 unk_74;
+ /*0x76*/ u16 unk_76;
+ /*0x78*/ u8 unk_78[0x2];
+ /*0x7a*/ u16 unk_7a;
+ /*0x7c*/ u16 unk_7c;
+ /*0x7e*/ u16 unk_7e;
+ /*0x80*/ u8 unk_80;
+ /*0x81*/ u8 unk_81;
+ /*0x82*/ u8 unk_82;
+ /*0x83*/ u8 unk_83;
+ /*0x84*/ u8 unk_84[0x2];
+ /*0x86*/ u16 unk_86;
+} PushableFurnitureEntity;
+
+extern const s16 gUnk_080B4488[];
+
+extern void (*const PushableFurniture_Actions[])(PushableFurnitureEntity*);
+extern const u16 gUnk_08121EE4[];
+extern const u16 gUnk_08121EF0[];
+
+void sub_08090514(PushableFurnitureEntity*);
+void sub_0808FF50(PushableFurnitureEntity*);
+void sub_0808FBFC(PushableFurnitureEntity*);
+void sub_0808FB68(PushableFurnitureEntity*);
+bool32 sub_0808FECC(PushableFurnitureEntity*);
+void sub_0808FF20(PushableFurnitureEntity*);
+void nullsub_1(PushableFurnitureEntity*);
+void sub_0808FD44(PushableFurnitureEntity*, u32);
+void sub_0808FDE8(PushableFurnitureEntity*);
+bool32 sub_0808FC5C(PushableFurnitureEntity*);
+void sub_08090498(PushableFurnitureEntity*);
+void sub_08090254(PushableFurnitureEntity*);
+void sub_08090094(PushableFurnitureEntity*, u32, u32);
+void sub_0809028C(PushableFurnitureEntity*, u32);
+void sub_08090480(u32, u32);
+
+void PushableFurniture(PushableFurnitureEntity* this) {
+ PushableFurniture_Actions[super->action](this);
+ if (super->action != 0) {
+ sub_08090514(this);
+ }
+}
+
+ASM_FUNC("asm/non_matching/pushableFurniture/sub_0808F990.inc", void sub_0808F990(PushableFurnitureEntity* this))
+
+void PushableFurniture_Action1(PushableFurnitureEntity* this) {
+ if (this->unk_81 == 0) {
+ if (this->unk_80 == 0) {
+ sub_0808FBFC(this);
+ } else {
+ sub_0808FB68(this);
+ }
+ } else {
+ if (super->actionDelay != 0 && --super->actionDelay == 0) {
+ EnqueueSFX(SFX_BUTTON_PRESS);
+ }
+ }
+ switch (super->type) {
+ case 2:
+ case 4:
+ switch (super->subAction) {
+ case 0:
+ if (sub_0808FECC(this)) {
+ super->subAction = 1;
+ super->actionDelay = 0xc;
+ }
+ break;
+ case 1:
+ if (--super->actionDelay == 0) {
+ super->frameIndex = 1;
+ super->subAction = 2;
+ EnqueueSFX(SFX_80);
+ sub_0808FF20(this);
+ }
+ break;
+ case 2:
+ nullsub_1(this);
+ break;
+ }
+ }
+}
+
+void sub_0808FB68(PushableFurnitureEntity* this) {
+ u32 tileIndex = GetTileIndex(this->unk_70, super->collisionLayer);
+ switch (tileIndex) {
+ case 0x4030:
+ case 0x4031:
+ super->action = 2;
+ super->direction = (((tileIndex - 0x30) & 1) << 4) | 8;
+ SetPlayerControl(CONTROL_1);
+ sub_0808FD44(this, 0);
+ break;
+ default:
+ tileIndex = GetTileIndex(this->unk_72, super->collisionLayer);
+ switch (tileIndex) {
+ case 0x4030:
+ case 0x4031:
+ super->action = 2;
+ super->direction = (((tileIndex - 0x30) & 1) << 4) | 8;
+ SetPlayerControl(CONTROL_1);
+ sub_0808FD44(this, 1);
+ break;
+ }
+ sub_0808FDE8(this);
+ break;
+ }
+}
+
+void sub_0808FBFC(PushableFurnitureEntity* this) {
+ u32 tileIndex = GetTileIndex(this->unk_7c, super->collisionLayer);
+ if (tileIndex != 0x404a) {
+ super->action = 2;
+ super->direction = ((tileIndex - 0x4bU) & 3) << 3;
+ SetPlayerControl(CONTROL_1);
+ sub_0808FD44(this, 0);
+ }
+}
+
+void PushableFurniture_Action2(PushableFurnitureEntity* this) {
+ sub_0800445C(super);
+ if (sub_0808FC5C(this)) {
+ super->action = 1;
+ SetPlayerControl(CONTROL_ENABLED);
+ }
+}
+
+bool32 sub_0808FC5C(PushableFurnitureEntity* this) {
+ bool32 bVar2;
+ u8* puVar5;
+
+ LinearMoveUpdate(super);
+ if (--super->actionDelay == 0) {
+ if ((super->type == 2) || (super->type == 4)) {
+ super->spriteOffsetY = 0xfe;
+ } else {
+ super->spriteOffsetY = 0;
+ }
+ if (sub_080002D0(super)) {
+ return 0;
+ }
+ if (super->field_0xf == 0) {
+ sub_0808FF50(this);
+ return TRUE;
+ }
+ bVar2 = FALSE;
+ if (*(u16*)&super->type == 0x101) {
+ if (super->y.HALF.HI != this->unk_7e)
+ goto _0808FCC8;
+ } else {
+ if (super->x.HALF.HI == this->unk_7e) {
+ bVar2 = TRUE;
+ }
+ _0808FCC8:
+ if (!bVar2) {
+ sub_0808FF50(this);
+ return TRUE;
+ }
+ }
+ this->unk_81 = 1;
+ if (super->parent == NULL) {
+ SetFlag((u32)this->unk_86);
+ } else {
+ if ((this->unk_82 & 0x80) != 0) {
+ puVar5 = super->parent->spriteAnimation + 2;
+ *puVar5 = (1 << (this->unk_7a)) | *puVar5;
+ } else {
+ SetLocalFlag((u32)this->unk_82);
+ }
+ }
+ if (this->unk_80 == 0) {
+ super->actionDelay = 4;
+ } else {
+ super->actionDelay = 0x18;
+ }
+ if ((gPlayerState.flags & 0x80) == 0) {
+ super->actionDelay += 0x10;
+ }
+ sub_0808FF50(this);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+void sub_0808FD44(PushableFurnitureEntity* this, u32 param_2) {
+ u32 tmp;
+
+ if (this->unk_80 == 1) {
+ if (this->unk_83 != 0) {
+ sub_08090498(this);
+ }
+ if (param_2 != 0) {
+ tmp = this->unk_72;
+ } else {
+ tmp = this->unk_70;
+ }
+ if ((gPlayerState.flags & 0x80) != 0) {
+ super->speed = 0x40;
+ super->actionDelay = 0x20;
+ } else {
+ super->speed = 0x80;
+ super->actionDelay = 0x10;
+ }
+ } else {
+ tmp = this->unk_7c;
+ if ((gPlayerState.flags & 0x80) != 0) {
+ super->speed = 0x40;
+ super->actionDelay = 0x40;
+ } else {
+ super->speed = 0x80;
+ super->actionDelay = 0x20;
+ }
+ }
+ EnqueueSFX(SFX_10F);
+ sub_08090254(this);
+ GetTileIndex(tmp + gUnk_080B4488[super->direction >> 3], super->collisionLayer);
+}
+
+void sub_0808FDE8(PushableFurnitureEntity* this) {
+ u32 uVar1;
+ s32 iVar2;
+ u32 uVar3;
+
+ uVar3 = (u32)this->unk_70;
+ uVar1 = sub_080002E0(uVar3 - 1, 1);
+ iVar2 = GetTileIndex(uVar3, 1);
+ if (iVar2 == 0x402e) {
+ if ((((uVar1 & 0xf0) != 0) && ((uVar1 & 0xf0) != 0x50)) || ((uVar1 & 5) == 0)) {
+ SetTile(0x402c, uVar3, 1);
+ }
+ } else {
+ iVar2 = sub_080002E0(uVar3, 1);
+ if ((iVar2 == 5) && ((((uVar1 & 0xf0) == 0 || ((uVar1 & 0xf0) == 0x50)) && ((uVar1 & 5) != 0)))) {
+ SetTile(0x402e, uVar3, 1);
+ }
+ }
+ uVar3 = (u32)this->unk_72;
+ uVar1 = sub_080002E0(uVar3 + 1, 1);
+ iVar2 = GetTileIndex(uVar3, 1);
+ if (iVar2 == 0x402f) {
+ if ((((uVar1 & 0xf0) != 0) && ((uVar1 & 0xf0) != 0x50)) || ((uVar1 & 10) == 0)) {
+ SetTile(0x402d, uVar3, 1);
+ }
+ } else {
+ iVar2 = sub_080002E0(uVar3, 1);
+ if (((iVar2 == 10) && (((uVar1 & 0xf0) == 0 || ((uVar1 & 0xf0) == 0x50)))) && ((uVar1 & 10) != 0)) {
+ SetTile(0x402f, uVar3, 1);
+ }
+ }
+}
+
+bool32 sub_0808FECC(PushableFurnitureEntity* this) {
+ bool32 result = TRUE;
+
+ if (!((gPlayerState.flags & 0x80) == 0 && (gPlayerEntity.action == 6) && (gPlayerEntity.animationState == 0) &&
+ (gPlayerEntity.y.HALF.HI - super->y.HALF.HI < 0x14) && (super->x.HALF.HI + 0xc > gPlayerEntity.x.HALF.HI) &&
+ (super->x.HALF.HI - 12 < gPlayerEntity.x.HALF.HI))) {
+ result = FALSE;
+ }
+ return result;
+}
+
+void sub_0808FF20(PushableFurnitureEntity* this) {
+ Entity* obj;
+ switch (super->type2) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ obj = CreateObject(OBJECT_63, super->type2 - 1, 0);
+ if (obj != NULL) {
+ obj->parent = super;
+ CopyPosition(super, obj);
+ }
+ break;
+ }
+}
+
+void nullsub_1(PushableFurnitureEntity* this) {
+}
+
+void sub_0808FF50(PushableFurnitureEntity* this) {
+ u32 tmp;
+ u32 position;
+ u32 tmp2;
+ this->unk_7c = COORD_TO_TILE(super);
+ tmp2 = super->x.HALF.HI & 0xf;
+ tmp = this->unk_7c;
+ position = tmp;
+ switch (this->unk_80) {
+ case 0:
+ this->unk_70 = tmp;
+ this->unk_74 = GetTileIndex(this->unk_70, 1);
+ SetTile(0x404a, tmp, 1);
+ break;
+ case 1:
+ if ((tmp2 & 8) != 0) {
+ this->unk_70 = this->unk_7c;
+ this->unk_74 = GetTileIndex(this->unk_70, 1);
+ SetTile(gUnk_08121EE4[this->unk_81], position, 1);
+ this->unk_72 = tmp + 1;
+ this->unk_76 = GetTileIndex(this->unk_72, 1);
+ sub_08090094(this, gUnk_08121EE4[this->unk_81 + 4], this->unk_72);
+ sub_0809028C(this, 1);
+ } else {
+ this->unk_72 = this->unk_7c;
+ this->unk_76 = GetTileIndex(this->unk_72, 1);
+ SetTile(gUnk_08121EE4[this->unk_81], position, 1);
+ this->unk_70 = tmp - 1;
+ this->unk_74 = GetTileIndex(this->unk_70, 1);
+ sub_08090094(this, gUnk_08121EE4[this->unk_81 + 2], this->unk_70);
+ sub_0809028C(this, 0);
+ }
+ break;
+ }
+}
+
+ASM_FUNC("asm/non_matching/pushableFurniture/sub_08090094.inc",
+ void sub_08090094(PushableFurnitureEntity* this, u32 param_2, u32 param_3))
+
+void sub_08090254(PushableFurnitureEntity* this) {
+ sub_0807B9B8(this->unk_74, this->unk_70, super->collisionLayer);
+ if (this->unk_80 == 1) {
+ sub_0807B9B8(this->unk_76, this->unk_72, super->collisionLayer);
+ }
+}
+
+ASM_FUNC("asm/non_matching/pushableFurniture/sub_0809028C.inc",
+ void sub_0809028C(PushableFurnitureEntity* this, u32 param_2))
+
+void sub_08090480(u32 param_1, u32 param_2) {
+ SetTile(gUnk_08121EF0[param_1], param_2, 1);
+}
+
+void sub_08090498(PushableFurnitureEntity* this) {
+ u32 tmp = this->unk_70 - 0x80;
+ sub_0807BA8C(tmp, 1);
+ if (((this->unk_83 & 1) != 0) && (GetTileType(tmp, 2) == 0x306)) {
+ sub_08000148(0x62, tmp, 1);
+ }
+ tmp = this->unk_72 - 0x80;
+ sub_0807BA8C(tmp, 1);
+ if (((this->unk_83 & 2) != 0) && (GetTileType(tmp, 2) == 0x308)) {
+ sub_08000148(99, tmp, 1);
+ }
+}
+
+void sub_08090514(PushableFurnitureEntity* this) {
+ if (super->parent != NULL) {
+ switch (super->parent->subAction) {
+ case 0:
+ super->spriteRendering.b3 = 2;
+ super->spritePriority.b0 = 4;
+ break;
+ case 1:
+ super->spriteRendering.b3 = 3;
+ super->spritePriority.b0 = 4;
+ break;
+ case 2:
+ super->spriteRendering.b3 = 2;
+ super->spritePriority.b0 = 5;
+ break;
+ case 3:
+ super->spriteRendering.b3 = 2;
+ super->spritePriority.b0 = 3;
+ break;
+ }
+ }
+}
+
+void (*const PushableFurniture_Actions[])(PushableFurnitureEntity*) = {
+ sub_0808F990,
+ PushableFurniture_Action1,
+ PushableFurniture_Action2,
+};
+const u16 gUnk_08121EE4[] = {
+ 0x402b, 0x4022, 0x402c, 0x4024, 0x402d, 0x4025,
+};
+const u16 gUnk_08121EF0[] = {
+ 0x4026,
+ 0x4065,
+ 0x4066,
+ 0,
+};
diff --git a/src/object/pushableGrave.c b/src/object/pushableGrave.c
new file mode 100644
index 00000000..8d9d4a92
--- /dev/null
+++ b/src/object/pushableGrave.c
@@ -0,0 +1,213 @@
+/**
+ * @file pushableGrave.c
+ * @ingroup Objects
+ *
+ * @brief Pushable Grave object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u16 unk_68;
+ /*0x6a*/ u16 unk_6a;
+ /*0x6c*/ u16 unk_6c;
+ /*0x6e*/ u16 unk_6e;
+ /*0x70*/ u16 unk_70;
+ /*0x72*/ u16 unk_72;
+ /*0x74*/ u16 unk_74;
+ /*0x76*/ u16 unk_76;
+ /*0x78*/ u16 unk_78;
+ /*0x7a*/ u16 unk_7a;
+ /*0x7c*/ s8 unk_7c[0xa];
+ /*0x86*/ u16 pushedFlag;
+} PushableGraveEntity;
+
+extern const Hitbox gUnk_080FD578;
+extern const Hitbox gUnk_080FD570;
+
+extern void (*const gUnk_081232AC[])(PushableGraveEntity*);
+extern const u8 gUnk_081232C0[];
+extern const u16 PushableGrave_Tiles[];
+
+bool32 sub_0809798C(PushableGraveEntity*);
+void sub_080977F4(PushableGraveEntity*);
+bool32 sub_0809785C(PushableGraveEntity*);
+
+void PushableGrave(PushableGraveEntity* this) {
+ gUnk_081232AC[super->action](this);
+}
+
+void PushableGrave_Init(PushableGraveEntity* this) {
+ u32 tilePosition;
+ u32 tileIndex;
+
+ super->spriteSettings.draw = 1;
+ super->frameIndex = super->type;
+ super->updatePriority = 3;
+ tilePosition = COORD_TO_TILE(super);
+ this->unk_6a = GetTileIndex(tilePosition - 0x41, super->collisionLayer);
+ this->unk_6c = GetTileIndex(tilePosition - 0x40, super->collisionLayer);
+ this->unk_6e = GetTileIndex(tilePosition - 0x3f, super->collisionLayer);
+ this->unk_70 = GetTileIndex(tilePosition - 1, super->collisionLayer);
+ this->unk_72 = GetTileIndex(tilePosition, super->collisionLayer);
+ this->unk_74 = GetTileIndex(tilePosition + 1, super->collisionLayer);
+ this->unk_76 = GetTileIndex(tilePosition + 0x3f, super->collisionLayer);
+ this->unk_78 = GetTileIndex(tilePosition + 0x40, super->collisionLayer);
+ this->unk_7a = GetTileIndex(tilePosition + 0x41, super->collisionLayer);
+ if (sub_0809798C(this)) {
+ if (super->type == 0) {
+ super->y.HALF.HI -= 0x16;
+ } else {
+ super->y.HALF.HI -= 0x10;
+ }
+ sub_080977F4(this);
+
+ } else {
+ super->action = 1;
+ tilePosition = COORD_TO_TILE(super);
+ this->unk_68 = tilePosition;
+ tileIndex = PushableGrave_Tiles[super->type2];
+ if (super->type == 0) {
+ super->hitbox = (Hitbox*)&gUnk_080FD578;
+ SetTile(tileIndex, tilePosition - 1, super->collisionLayer);
+ SetTile(tileIndex, tilePosition, super->collisionLayer);
+ super->y.HALF.HI += 2;
+ } else {
+ super->hitbox = (Hitbox*)&gUnk_080FD570;
+ SetTile(tileIndex, tilePosition, super->collisionLayer);
+ if (super->type2 == 2) {
+ sub_0801AF18((u8*)gUnk_081232C0, tilePosition, super->collisionLayer);
+ }
+ }
+ }
+}
+
+void PushableGrave_Action1(PushableGraveEntity* this) {
+ if (sub_0809785C(this)) {
+ RequestPriorityDuration(super, super->actionDelay);
+ }
+}
+
+void PushableGrave_Action2(PushableGraveEntity* this) {
+ if (super->subAction == 0) {
+ if (--super->field_0xf == 0) {
+ super->subAction = 1;
+ super->field_0xf = 0x78;
+ gRoomControls.camera_target = super;
+ gRoomControls.unk5 = 2;
+ }
+ } else {
+ if (--super->field_0xf == 0) {
+ super->action = 3;
+ super->actionDelay = 0x60;
+ super->field_0xf = 0x14;
+ RequestPriorityDuration(super, 0x60);
+ SoundReq(SFX_10F);
+ }
+ }
+}
+
+void PushableGrave_Action3(PushableGraveEntity* this) {
+ if (super->actionDelay != 0) {
+ super->actionDelay--;
+ LinearMoveUpdate(super);
+ sub_0800445C(super);
+ } else {
+ if (super->field_0xf != 0) {
+ super->field_0xf--;
+ } else {
+ EnqueueSFX(SFX_SECRET);
+ sub_080977F4(this);
+ if (super->type == 0) {
+ gRoomControls.camera_target = &gPlayerEntity;
+ gRoomControls.unk5 = 4;
+ }
+ }
+ }
+}
+
+void PushableGrave_Action4(PushableGraveEntity* this) {
+}
+
+void sub_080977F4(PushableGraveEntity* this) {
+ u32 tilePosition;
+ super->action = 4;
+ super->spriteOffsetY = 0;
+ tilePosition = COORD_TO_TILE(super);
+ SetTile(0x4022, tilePosition, super->collisionLayer);
+ if (super->type == 0) {
+ SetTile(0x4022, tilePosition - 1, super->collisionLayer);
+ }
+ if (this->pushedFlag != 0) {
+ SetFlag(this->pushedFlag);
+ }
+}
+
+bool32 sub_0809785C(PushableGraveEntity* this) {
+ u32 tilePosition;
+
+ if (super->type != 0) {
+ if (super->type2 != 0) {
+ if ((CheckFlags(this->pushedFlag) != 0) || GetTileType(this->unk_68, super->collisionLayer) == 0x403f) {
+ super->action = 3;
+ super->actionDelay = 0x40;
+ super->field_0xf = 0;
+ super->direction = 0;
+ super->speed = 0x40;
+ tilePosition = this->unk_68;
+ sub_0807B9B8(this->unk_72, tilePosition, super->collisionLayer);
+ if (super->type2 == 2) {
+ sub_0807B9B8(this->unk_6a, tilePosition - 0x41, super->collisionLayer);
+ sub_0807B9B8(this->unk_6c, tilePosition - 0x40, super->collisionLayer);
+ sub_0807B9B8(this->unk_6e, tilePosition - 0x3f, super->collisionLayer);
+ sub_0807B9B8(this->unk_70, tilePosition - 1, super->collisionLayer);
+ sub_0807B9B8(this->unk_74, tilePosition + 1, super->collisionLayer);
+ sub_0807B9B8(this->unk_76, tilePosition + 0x3f, super->collisionLayer);
+ sub_0807B9B8(this->unk_78, tilePosition + 0x40, super->collisionLayer);
+ sub_0807B9B8(this->unk_7a, tilePosition + 0x41, super->collisionLayer);
+ }
+ SoundReq(SFX_10F);
+ return TRUE;
+ }
+ }
+
+ } else {
+ if (CheckFlags(this->pushedFlag) != 0) {
+ super->action = 2;
+ super->subAction = 0;
+ super->actionDelay = 0xf0;
+ super->field_0xf = 0x3c;
+ super->direction = 0;
+ super->speed = 0x40;
+ sub_0807BA8C(this->unk_68, super->collisionLayer);
+ sub_0807BA8C(this->unk_68 - 1, super->collisionLayer);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool32 sub_0809798C(PushableGraveEntity* this) {
+ bool32 result = FALSE;
+ if (((super->type == 0) || (super->type2 != 0)) && CheckFlags(this->pushedFlag)) {
+ result = TRUE;
+ }
+ return result;
+}
+
+void (*const gUnk_081232AC[])(PushableGraveEntity*) = {
+ PushableGrave_Init, PushableGrave_Action1, PushableGrave_Action2, PushableGrave_Action3, PushableGrave_Action4,
+};
+const u8 gUnk_081232C0[] = {
+ 61, 64, 191, 255, 61, 64, 192, 255, 61, 64, 193, 255, 61, 64, 255,
+ 255, 61, 64, 1, 0, 61, 64, 63, 0, 61, 64, 65, 0, 255, 255,
+};
+const u16 PushableGrave_Tiles[] = {
+ 0x4022,
+ 0x403e,
+ 0x403e,
+};
diff --git a/src/object/pushableRock.c b/src/object/pushableRock.c
new file mode 100644
index 00000000..a176e2da
--- /dev/null
+++ b/src/object/pushableRock.c
@@ -0,0 +1,123 @@
+/**
+ * @file pushableRock.c
+ * @ingroup Objects
+ *
+ * @brief Pushable Rock object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[8];
+ /*0x70*/ u16 tileIndex;
+ /*0x72*/ u8 unk_72;
+ /*0x73*/ u8 unk_73;
+ /*0x74*/ u16 tilePosition;
+ /*0x76*/ u8 unk_76[0x10];
+ /*0x86*/ u16 pushedFlag;
+} PushableRockEntity;
+
+extern void (*const PushableRock_Actions[])(PushableRockEntity*);
+extern const u16 PushableRock_Speeds[];
+
+void sub_0808A644(PushableRockEntity*);
+
+void PushableRock(PushableRockEntity* this) {
+ PushableRock_Actions[super->action](this);
+}
+
+void PushableRock_Init(PushableRockEntity* this) {
+ super->spriteSettings.draw = 1;
+ super->action += 1;
+ super->spriteRendering.b3 = 2;
+ super->spritePriority.b0 = 4;
+ super->spritePriority.b1 = 3;
+ sub_0808A644(this);
+}
+
+void PushableRock_Action1(PushableRockEntity* this) {
+ u32 tileType;
+ u32 tmp;
+
+ tileType = GetTileType(this->tilePosition, super->collisionLayer);
+ switch (tileType) {
+ case 0x401c:
+ case 0x401d:
+ case 0x401e:
+ case 0x401f:
+ tmp = (tileType - 0x1c);
+ super->animationState = tmp * 2;
+ super->direction = tmp * 8;
+ if ((u8)(tmp * 2) == 2) {
+ super->spriteSettings.flipX = 1;
+ } else {
+ super->spriteSettings.flipX = 0;
+ }
+ SetTile(this->tileIndex, this->tilePosition, super->collisionLayer);
+ super->action = 2;
+ InitializeAnimation(super, (super->animationState >> 1) + 1);
+ EnqueueSFX(SFX_10F);
+ break;
+ default:
+ if (super->animIndex) {
+ InitializeAnimation(super, 0);
+ }
+ break;
+ }
+}
+
+void PushableRock_Action2(PushableRockEntity* this) {
+ sub_0800445C(super);
+ super->speed = PushableRock_Speeds[super->frame & 0xf];
+ LinearMoveUpdate(super);
+ GetNextFrame(super);
+ if (super->frame & 0x80) {
+ super->action = 0;
+ }
+}
+
+void PushableRock_Action3(PushableRockEntity* this) {
+ if ((super->frame & 0x80) == 0) {
+ GetNextFrame(super);
+ } else {
+ super->spritePriority.b0 = 7;
+ }
+}
+
+void sub_0808A644(PushableRockEntity* this) {
+ u32 tmp;
+ this->tilePosition = COORD_TO_TILE(super);
+ this->tileIndex = GetTileIndex(this->tilePosition, super->collisionLayer);
+ this->unk_72 = sub_080002E0(this->tilePosition, super->collisionLayer);
+ tmp = sub_080002C8(this->tilePosition, super->collisionLayer);
+ if ((tmp == 0x19) || (tmp == 0xf0)) {
+ SetTile(0x4015, this->tilePosition, super->collisionLayer);
+ super->action = 3;
+ if (!CheckFlags(this->pushedFlag)) {
+ SetFlag(this->pushedFlag);
+ SoundReq(SFX_TASK_COMPLETE);
+ InitializeAnimation(super, 5);
+ } else {
+ InitializeAnimation(super, 6);
+ }
+ } else {
+ SetTile(0x401b, this->tilePosition, super->collisionLayer);
+ }
+}
+
+void (*const PushableRock_Actions[])(PushableRockEntity*) = {
+ PushableRock_Init,
+ PushableRock_Action1,
+ PushableRock_Action2,
+ PushableRock_Action3,
+};
+const u16 PushableRock_Speeds[] = {
+ 0,
+ 256,
+ 96,
+ 64,
+};
diff --git a/src/object/pushableStatue.c b/src/object/pushableStatue.c
new file mode 100644
index 00000000..c77436ae
--- /dev/null
+++ b/src/object/pushableStatue.c
@@ -0,0 +1,277 @@
+/**
+ * @file pushableStatue.c
+ * @ingroup Objects
+ *
+ * @brief Pushable Statue object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[0x18];
+ /*0x80*/ u16 unk_80;
+ /*0x82*/ u8 unk_82;
+ /*0x83*/ u8 unk_83;
+ /*0x84*/ u16 unk_84;
+ /*0x86*/ u16 unk_86;
+} PushableStatueEntity;
+
+extern u8* GetLayerByIndex(u32);
+extern const Hitbox gUnk_080FD1F4;
+extern const s16 gUnk_080B4488[];
+extern const s16 gUnk_080B4468[];
+
+extern void (*const PushableStatue_Actions[])(PushableStatueEntity*);
+extern void (*const PushableStatue_SubActions[])(PushableStatueEntity*);
+extern const s8 gUnk_08120CB4[];
+extern const u16 gUnk_08120CBC[];
+extern const u16 gUnk_08120CCC[];
+extern const u16 gUnk_08120D6C[];
+
+u32 sub_0808968C(u32);
+bool32 sub_0808965C(PushableStatueEntity*);
+void sub_08089454(PushableStatueEntity*);
+void sub_080894C8(PushableStatueEntity*);
+void sub_08089538(PushableStatueEntity*);
+void sub_080894FC(PushableStatueEntity*);
+bool32 sub_080895C0(PushableStatueEntity*);
+bool32 sub_080896B0(void);
+
+void PushableStatue(PushableStatueEntity* this) {
+ PushableStatue_Actions[super->action](this);
+}
+
+void PushableStatue_Init(PushableStatueEntity* this) {
+ if (sub_0808965C(this)) {
+ super->action = 1;
+ super->speed = 0x80;
+ super->updatePriority = 3;
+ super->hitbox = (Hitbox*)&gUnk_080FD1F4;
+ super->field_0x16 = 1;
+ this->unk_86 = 0;
+ sub_08089454(this);
+ sub_080894C8(this);
+ InitializeAnimation(super, 0);
+ }
+}
+
+void PushableStatue_Action1(PushableStatueEntity* this) {
+ u16 tileType;
+ Entity* obj;
+
+ if (sub_0800442E(super) == 0) {
+ tileType = GetTileType(this->unk_84, super->collisionLayer);
+ if (tileType != 0x400b) {
+ switch (sub_0808968C(tileType)) {
+ case 1:
+ super->action = 3;
+ super->direction = ((tileType - 0xc) & 3) << 3;
+ sub_08089538(this);
+ break;
+ case 0:
+ obj = CreateObject(SPECIAL_FX, 4, 0);
+ if (obj != NULL) {
+ CopyPosition(super, obj);
+ }
+ sub_080894FC(this);
+ break;
+ case 2:
+ this->unk_80 = tileType;
+ break;
+ }
+ } else {
+ sub_08078930(super);
+ }
+ }
+}
+
+void PushableStatue_Action2(PushableStatueEntity* this) {
+ if (this->unk_86 != 0) {
+ sub_080895C0(this);
+ } else {
+ if (gPlayerState.heldObject == 0) {
+ super->subAction = 6;
+ }
+ PushableStatue_SubActions[super->subAction - 5](this);
+ }
+}
+
+void PushableStatue_SubAction0(PushableStatueEntity* this) {
+ u16 tileType;
+ Entity* obj;
+ u32 index;
+ const s8* ptr;
+
+ if (this->unk_83 == 0) {
+ this->unk_83 = 1;
+ index = gPlayerEntity.animationState;
+ ptr = &gUnk_08120CB4[index];
+ PositionRelative(super, &gPlayerEntity, *(ptr) << 0x10, *(ptr + 1) << 0x10);
+ }
+ tileType = GetTileType(this->unk_84, super->collisionLayer);
+ if (tileType != 0x400b) {
+ switch (sub_0808968C(tileType)) {
+ case 1:
+ super->direction = (((tileType - 0xc) & 3) << 3);
+ sub_08089538(this);
+ break;
+ case 0:
+ obj = CreateObject(SPECIAL_FX, 4, 0);
+ if (obj != NULL) {
+ CopyPosition(super, obj);
+ }
+ sub_080894FC(this);
+ return;
+ case 2:
+ this->unk_80 = tileType;
+ break;
+ }
+ }
+ if (sub_080896B0()) {
+ gPlayerState.queued_action = 0x10;
+ gPlayerState.field_0x38 = 0x20;
+ gPlayerState.flags |= 1;
+ gPlayerEntity.x.HALF.LO = 0;
+ gPlayerEntity.y.HALF.LO = 0;
+ super->direction = (gPlayerEntity.animationState ^ 4) << 2;
+ sub_08089538(this);
+ }
+}
+
+void PushableStatue_SubAction1(PushableStatueEntity* this) {
+ super->action = 1;
+ this->unk_83 = 0;
+}
+
+void PushableStatue_Action3(PushableStatueEntity* this) {
+ if (sub_080895C0(this)) {
+ super->action = 1;
+ }
+}
+
+void PushableStatue_Action4(PushableStatueEntity* this) {
+ if (--super->actionDelay != 0) {
+ super->spriteSettings.draw ^= 1;
+ } else {
+ super->spriteSettings.draw = 1;
+ super->action = 1;
+ SetTile(0x400b, this->unk_84, super->collisionLayer);
+ sub_080894C8(this);
+ }
+}
+
+void sub_08089454(PushableStatueEntity* this) {
+ this->unk_84 = COORD_TO_TILE(super);
+ this->unk_80 = GetTileIndex(this->unk_84, super->collisionLayer);
+ SetTile(0x400b, this->unk_84, super->collisionLayer);
+ if (super->collisionLayer == 2 && GetTileType(this->unk_84, 1) == 0x310) {
+ SetTile(0x400b, this->unk_84, 1);
+ }
+}
+
+void sub_080894C8(PushableStatueEntity* this) {
+ u32 index;
+ for (index = 0; index < 8; index++) {
+ if (gRoomVars.field_0xac[index] == NULL) {
+ gRoomVars.field_0xac[index] = this;
+ break;
+ }
+ }
+}
+
+void sub_080894FC(PushableStatueEntity* this) {
+ u32 index;
+ for (index = 0; index <= 7; index++) {
+ if (this == (PushableStatueEntity*)gRoomVars.field_0xac[index]) {
+ gRoomVars.field_0xac[index] = NULL;
+ break;
+ }
+ }
+ DeleteEntity(super);
+}
+
+void sub_08089538(PushableStatueEntity* this) {
+ u16 tileType;
+ this->unk_86 = 0x20;
+ EnqueueSFX(SFX_10F);
+ SetTile(this->unk_80, this->unk_84, super->collisionLayer);
+ if ((super->collisionLayer == 2) && (GetTileType(this->unk_84, 1) == 0x400b)) {
+ sub_08000152(0x310, this->unk_84, 1);
+ }
+ tileType = GetTileType(this->unk_84 + gUnk_080B4488[super->direction >> 3], super->collisionLayer);
+ if ((tileType == 0x79) || (tileType == 0x77)) {
+ super->spriteOffsetY = -2;
+ }
+}
+
+bool32 sub_080895C0(PushableStatueEntity* this) {
+ Entity* obj;
+
+ LinearMoveUpdate(super);
+ if ((--this->unk_86 == 0) && (sub_0800442E(super) == 0)) {
+ super->spriteOffsetY = 0;
+ if (!sub_080002D0(super)) {
+ sub_08089454(this);
+ return TRUE;
+ }
+ obj = CreateObject(SPECIAL_FX, 4, 0);
+ if (obj != NULL) {
+ CopyPosition(super, obj);
+ }
+ super->spriteSettings.draw = 0;
+ super->x.HALF.HI += gUnk_08120CBC[super->direction >> 2];
+ super->y.HALF.HI += gUnk_08120CBC[(super->direction >> 2) + 1];
+ sub_08089454(this);
+ super->action = 4;
+ super->actionDelay = 0x3c;
+ }
+ sub_0800445C(super);
+ return FALSE;
+}
+
+bool32 sub_0808965C(PushableStatueEntity* this) {
+ if (gRoomControls.area < 0x40) {
+ return LoadFixedGFX(super, 0xe9);
+ } else {
+ return LoadFixedGFX(super, gUnk_08120CCC[gRoomControls.area - 0x40]);
+ }
+}
+
+u32 sub_0808968C(u32 param_1) {
+ const u16* it;
+
+ for (it = gUnk_08120D6C; *it != 0; it += 2) {
+ if (*it == param_1) {
+ return it[1];
+ }
+ }
+ return 0;
+}
+
+ASM_FUNC("asm/non_matching/pushableStatue/sub_080896B0.inc", bool32 sub_080896B0(void))
+
+void (*const PushableStatue_Actions[])(PushableStatueEntity*) = {
+ PushableStatue_Init, PushableStatue_Action1, PushableStatue_Action2, PushableStatue_Action3, PushableStatue_Action4,
+};
+void (*const PushableStatue_SubActions[])(PushableStatueEntity*) = {
+ PushableStatue_SubAction0,
+ PushableStatue_SubAction1,
+};
+const s8 gUnk_08120CB4[] = {
+ 0, 14, -14, 2, 0, -14, 14, 2,
+};
+const u16 gUnk_08120CBC[] = {
+ 0, 16, 65520, 0, 0, 65520, 16, 0,
+};
+const u16 gUnk_08120CCC[] = {
+ 29, 29, 29, 29, 29, 29, 29, 29, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75,
+ 75, 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78,
+ 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81,
+};
+const u16 gUnk_08120D6C[] = {
+ 0x400c, 1, 0x400d, 1, 0x400e, 1, 0x400f, 1, 0x7a, 2, 0x78, 2, 0,
+};
diff --git a/src/object/smallIceBlock.c b/src/object/smallIceBlock.c
new file mode 100644
index 00000000..63542a02
--- /dev/null
+++ b/src/object/smallIceBlock.c
@@ -0,0 +1,330 @@
+/**
+ * @file smallIceBlock.c
+ * @ingroup Objects
+ *
+ * @brief Small Ice Block object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[0x4];
+ /*0x6c*/ u16 unk_6c;
+ /*0x6e*/ u8 unk_6e[0x2];
+ /*0x70*/ u16 unk_70;
+ /*0x72*/ u8 unk_72[0x14];
+ /*0x86*/ u16 unk_86;
+} SmallIceBlockEntity;
+
+extern const Hitbox gUnk_080FD408;
+extern const s16 gUnk_080B4488[];
+
+void sub_080996AC(SmallIceBlockEntity*);
+void sub_08099468(SmallIceBlockEntity*);
+bool32 sub_0809963C(SmallIceBlockEntity*);
+u32 sub_08099618(u32);
+void sub_080994B8(SmallIceBlockEntity*);
+void SmallIceBlock_Action3(SmallIceBlockEntity*);
+bool32 sub_0809953C(SmallIceBlockEntity*);
+void sub_0809969C(SmallIceBlockEntity*);
+
+extern void (*const gUnk_08123734[])(SmallIceBlockEntity*);
+extern const u16 gUnk_08123748[];
+extern const u16 gUnk_08123750[];
+
+void SmallIceBlock(SmallIceBlockEntity* this) {
+ if (super->type < 3) {
+ gUnk_08123734[super->action](this);
+ } else {
+ sub_080996AC(this);
+ }
+}
+
+void SmallIceBlock_Init(SmallIceBlockEntity* this) {
+ Entity* obj;
+
+ switch (super->type) {
+ case 0:
+ case 1:
+ case 2:
+ if (CheckFlags(this->unk_86)) {
+ DeleteThisEntity();
+ }
+ }
+ super->action = 1;
+ super->flags |= 0x80;
+ super->updatePriority = 3;
+ super->field_0x3c = 7;
+ super->hurtType = 0x48;
+ super->hitType = 1;
+ super->flags2 = 0x80;
+ super->hitbox = (Hitbox*)&gUnk_080FD408;
+ sub_08099468(this);
+ InitializeAnimation(super, super->type);
+ obj = CreateObject(SMALL_ICE_BLOCK, 3, 0);
+ if (obj != NULL) {
+ obj->parent = super;
+ }
+}
+
+void SmallIceBlock_Action1(SmallIceBlockEntity* this) {
+ u32 tileType;
+ Entity* obj;
+
+ if (sub_0809963C(this)) {
+ super->action = 3;
+ super->actionDelay = 0;
+ EnqueueSFX(SFX_ICE_BLOCK_MELT);
+ SmallIceBlock_Action3(this);
+ if (super->type == 0) {
+ SetFlag(this->unk_86);
+ }
+ } else {
+ if (!sub_0800442E(super)) {
+ tileType = GetTileType(this->unk_70, super->collisionLayer);
+ if (tileType != 0x405a) {
+ switch (sub_08099618(tileType)) {
+ case 1:
+ super->action = 2;
+ super->actionDelay = 0x16;
+ super->direction = ((tileType - 0x5b) & 3) << 3;
+ super->speed = 0x20;
+ sub_080994B8(this);
+ break;
+ case 0:
+ obj = CreateObject(SPECIAL_FX, 0xd, 0);
+ if (obj != NULL) {
+ CopyPosition(super, obj);
+ }
+ SetTile(this->unk_6c, this->unk_70, super->collisionLayer);
+ DeleteEntity(super);
+ break;
+
+ case 2:
+ this->unk_6c = (u16)tileType;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void SmallIceBlock_Action2(SmallIceBlockEntity* this) {
+ if (sub_0809953C(this)) {
+ super->action = 1;
+ sub_08099468(this);
+ EnqueueSFX(SFX_ICE_BLOCK_STOP);
+ }
+}
+
+void SmallIceBlock_Action3(SmallIceBlockEntity* this) {
+ if (sub_0809963C(this) == 0) {
+ if (super->actionDelay >= 2) {
+ super->actionDelay -= 2;
+ } else {
+ super->actionDelay = 0;
+ }
+ if (super->actionDelay == 0) {
+ super->action = 1;
+ sub_0805EC60(super);
+ return;
+ }
+ } else {
+ super->actionDelay++;
+ }
+ sub_0805EC9C(super, 0x100, gUnk_08123748[super->actionDelay >> 5], 0);
+ if (super->type == 1) {
+ sub_080A2A3C(super, 0x53, 0, this->unk_86);
+ SoundReq(SFX_SECRET);
+ } else if (super->type == 2) {
+ sub_080A2A3C(super, 0x52, 0, this->unk_86);
+ SoundReq(SFX_SECRET);
+ }
+ super->action = 4;
+ super->actionDelay = 0x3c;
+ super->flags &= 0x7f;
+}
+
+void SmallIceBlock_Action4(SmallIceBlockEntity* this) {
+ Entity* obj;
+ s32 rand;
+ s32 x;
+ s32 y;
+
+ if (--super->actionDelay == 0) {
+ DeleteThisEntity();
+ } else {
+ if (super->actionDelay == 0x30) {
+ SetTile(this->unk_6c, this->unk_70, super->collisionLayer);
+ }
+ sub_0805EC9C(super, 0x100, (0x3c - super->actionDelay) * 0x20 + 0x100, 0);
+ if ((super->actionDelay & 1) != 0) {
+ obj = CreateObject(SPECIAL_FX, 0x11, 0x40);
+ if (obj != NULL) {
+ rand = Random();
+ x = ((rand >> 0x10) % 9) - 4;
+ y = rand & 0xf;
+ obj->spritePriority.b0 = 3;
+ PositionRelative(super, obj, x * 0x10000, -y * 0x10000);
+ }
+ }
+ }
+}
+
+void sub_08099468(SmallIceBlockEntity* this) {
+ this->unk_70 = COORD_TO_TILE(super);
+ this->unk_6c = GetTileIndex(this->unk_70, super->collisionLayer);
+ SetTile(0x405a, this->unk_70, super->collisionLayer);
+}
+
+void sub_080994B8(SmallIceBlockEntity* this) {
+ u16 tileType;
+
+ EnqueueSFX(SFX_ICE_BLOCK_SLIDE);
+ SetTile(this->unk_6c, this->unk_70, super->collisionLayer);
+ if ((super->collisionLayer == 2) && (GetTileType(this->unk_70, 1) == 0x405a)) {
+ sub_08000152(0x310, this->unk_70, 1);
+ }
+ tileType = GetTileType(this->unk_70 + gUnk_080B4488[super->direction >> 3], super->collisionLayer);
+ if (tileType == 0x79 || tileType == 0x77) {
+ super->spriteOffsetY = -2;
+ }
+}
+
+bool32 sub_0809953C(SmallIceBlockEntity* this) {
+ u8 bVar1;
+ u8 uVar2;
+ u32 uVar3;
+ u16 uVar4;
+
+ uVar3 = sub_0800442E(super);
+ if (uVar3 != 0) {
+ return 0;
+ }
+ sub_080AEFE0(super);
+ sub_0800445C(super);
+ if (super->actionDelay != 0) {
+ super->speed += 0x10;
+ if (--super->actionDelay == 0) {
+ super->speed = 0x200;
+ }
+ }
+ switch (super->direction >> 3) {
+ case 0:
+ if ((super->collisions & 0xe) == 0) {
+ return 0;
+ }
+ if ((u32)(super->y.HALF.HI & 0xf) - 7 < 3) {
+ super->y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8;
+ return 1;
+ }
+ sub_0809969C(this);
+ break;
+ case 1:
+ if ((super->collisions & 0xe000) == 0) {
+ return FALSE;
+ }
+ if ((u32)(super->x.HALF.HI & 0xf) - 7 < 3) {
+ super->x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8;
+ return TRUE;
+ }
+ sub_0809969C(this);
+ break;
+ case 2:
+ if ((super->collisions & 0xe0) == 0) {
+ return FALSE;
+ }
+ if ((u32)(super->y.HALF.HI & 0xf) - 7 < 3) {
+ super->y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8;
+ return TRUE;
+ }
+ sub_0809969C(this);
+ break;
+ default:
+ if ((super->collisions & 0xe00) != 0) {
+ if ((u32)(super->x.HALF.HI & 0xf) - 7 < 3) {
+ super->x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8;
+ return TRUE;
+ }
+ sub_0809969C(this);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+u32 sub_08099618(u32 param_1) {
+ const u16* it;
+ for (it = gUnk_08123750; *it != 0; it += 2) {
+ if (*it == param_1) {
+ return it[1];
+ }
+ }
+ return 0;
+}
+
+bool32 sub_0809963C(SmallIceBlockEntity* this) {
+ u16* var;
+ u16 x;
+ u16 y;
+
+ if (super->type2 != 0) {
+ var = (u16*)GetCurrentRoomProperty(super->type2);
+ if (CheckFlags(var[0])) {
+ x = var[1] + gRoomControls.origin_x;
+ y = var[2] + gRoomControls.origin_y;
+ if (var[3] >= (u32)(super->x.HALF.HI - x) && var[4] >= (u32)(super->y.HALF.HI - y)) {
+ return TRUE;
+ }
+ }
+ }
+ if (super->bitfield == 0x87) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_0809969C(SmallIceBlockEntity* this) {
+ CreateFx(super, 0xd, 0);
+ DeleteThisEntity();
+}
+
+void sub_080996AC(SmallIceBlockEntity* this) {
+ if ((super->parent)->next == NULL) {
+ DeleteThisEntity();
+ }
+ if (super->action == 0) {
+ super->action = 1;
+ InitializeAnimation(super, 3);
+ }
+ if ((super->parent)->action < 3) {
+ super->spriteSettings.draw = 1;
+ if ((super->frame & 1) != 0) {
+ super->frame = 0;
+ super->frameDuration = (Random() & 0x78) + 0x78;
+ }
+ GetNextFrame(super);
+ CopyPositionAndSpriteOffset(super->parent, super);
+ super->y.HALF.HI += 1;
+ super->spriteOffsetY -= 0x11;
+ } else {
+ super->spriteSettings.draw = 0;
+ }
+}
+
+void (*const gUnk_08123734[])(SmallIceBlockEntity*) = {
+ SmallIceBlock_Init, SmallIceBlock_Action1, SmallIceBlock_Action2, SmallIceBlock_Action3, SmallIceBlock_Action4,
+};
+const u16 gUnk_08123748[] = {
+ 256,
+ 264,
+ 271,
+ 277,
+};
+const u16 gUnk_08123750[] = {
+ 0x405b, 1, 0x405c, 1, 0x405d, 1, 0x405e, 1, 0x7a, 2, 0x78, 2, 0,
+};