summaryrefslogtreecommitdiff
path: root/src/object
diff options
context:
space:
mode:
authoroctorock <79596758+octorock@users.noreply.github.com>2022-02-26 14:40:57 +0100
committeroctorock <79596758+octorock@users.noreply.github.com>2022-02-26 14:40:57 +0100
commitdcb6360b4e6e42acaa5643557fef956782e2f646 (patch)
tree03f3eef5c6d3620d2c991027b3aab7de989367bd /src/object
parentabe6053a4f3dcaa511035baba764609464eadc46 (diff)
Decompile Beanstalk
Diffstat (limited to 'src/object')
-rw-r--r--src/object/beanstalk.c353
1 files changed, 353 insertions, 0 deletions
diff --git a/src/object/beanstalk.c b/src/object/beanstalk.c
new file mode 100644
index 00000000..0e748a85
--- /dev/null
+++ b/src/object/beanstalk.c
@@ -0,0 +1,353 @@
+/**
+ * @file beanstalk.c
+ * @ingroup Objects
+ *
+ * @brief Beanstalk object
+ */
+
+#define NENT_DEPRECATED
+#include "global.h"
+#include "object.h"
+#include "functions.h"
+
+typedef struct {
+ /*0x00*/ Entity base;
+ /*0x68*/ u8 unk_68[4];
+ /*0x6c*/ u32 unk_6c;
+ /*0x70*/ u16 unk_70;
+ /*0x72*/ u16 unk_72;
+} BeanstalkEntity;
+
+typedef struct {
+ u8 type;
+ s8 x;
+ s8 y;
+ u8 flipX;
+} struct_08120DFC;
+
+typedef struct {
+ u8 unk_0;
+ u8 unk_1;
+} struct_08120E3C;
+
+void Beanstalk_Action1(BeanstalkEntity*);
+void Beanstalk_Init(BeanstalkEntity*);
+void Beanstalk_Action1Type0(BeanstalkEntity*);
+void Beanstalk_Action1Type1(BeanstalkEntity*);
+void Beanstalk_Action1Type2(BeanstalkEntity*);
+void Beanstalk_Action1Type4(BeanstalkEntity*);
+void Beanstalk_Action1Type7(BeanstalkEntity*);
+void Beanstalk_Action1Type8(BeanstalkEntity*);
+void Beanstalk_Action1Type9(BeanstalkEntity*);
+void Beanstalk_Action1Type0SubAction0(BeanstalkEntity*);
+void Beanstalk_Action1Type0SubAction1(BeanstalkEntity*);
+void Beanstalk_Action1Type0SubAction2(BeanstalkEntity*);
+void Beanstalk_Action1Type8SubAction0(BeanstalkEntity*);
+void Beanstalk_Action1Type8SubAction1(BeanstalkEntity*);
+
+void Beanstalk(BeanstalkEntity* this) {
+ static void (*const Beanstalk_Actions[])(BeanstalkEntity*) = {
+ Beanstalk_Init,
+ Beanstalk_Action1,
+ };
+ Beanstalk_Actions[super->action](this);
+}
+
+const struct_08120DFC gUnk_08120DFC[] = {
+ { 4, -2, 8, 0 }, { 6, 10, 16, 1 }, { 5, -4, 33, 0 }, { 6, -7, 7, 0 }, { 4, 5, 33, 1 }, { 5, 2, 37, 1 },
+};
+void Beanstalk_Init(BeanstalkEntity* this) {
+ static const struct_08120E3C gUnk_08120E14[] = {
+ { 0, 3 }, { 1, 3 }, { 0, 3 }, { 2, 3 }, { 3, 2 }, { 6, 2 }, { 9, 4 }, { 0, 3 }, { 0, 4 }, { 12, 6 },
+ };
+ static const struct_08120E3C gUnk_08120E3C[] = {
+ { 1, 6 }, { 2, 6 }, { 4, 3 }, { 7, 5 }, { 10, 7 },
+ };
+
+ Entity* obj;
+ const struct_08120DFC* ptr;
+
+ super->spriteRendering.b3 = 2;
+ super->spriteOrientation.flipY = 1;
+ SetDefaultPriority(super, 4);
+ if (super->type == 7) {
+#ifndef EU
+ if ((super->flags & ENT_DID_INIT) == 0) {
+ return;
+ }
+#endif
+ if (super->type2 == 0 && super->actionDelay != 0) {
+ if (CheckLocalFlag(super->actionDelay) == 0) {
+ return;
+ }
+ super->spriteOrientation.flipY = 2;
+ }
+ InitializeAnimation(super, gUnk_08120E3C[super->type2].unk_0);
+ super->spritePriority.b0 = gUnk_08120E3C[super->type2].unk_1;
+ } else {
+ if (super->type != 0) {
+ InitializeAnimation(super, gUnk_08120E14[super->type].unk_0);
+ } else {
+ LoadSwapGFX(super, 1, 2);
+ InitAnimationForceUpdate(super, gUnk_08120E14[super->type].unk_0);
+ }
+ super->spritePriority.b0 = gUnk_08120E14[super->type].unk_1;
+ }
+ super->action = 1;
+ super->spriteSettings.draw = 1;
+
+ switch (super->type) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ super->spriteVramOffset = 0x1c0;
+ super->actionDelay = 0;
+ break;
+ case 7:
+ switch (super->type2) {
+ case 0:
+ this->unk_6c = 0x10;
+ super->actionDelay = 0;
+ do {
+ obj = CreateObject(BEANSTALK, 7, 1);
+ super->child = obj;
+ if (obj != NULL) {
+ obj->x.HALF.HI = super->x.HALF.HI;
+ (super->child)->y.HALF.HI = super->y.HALF.HI - (s16)this->unk_6c;
+ super->field_0xf = 4;
+ while (--super->field_0xf != 0) {
+ ptr = &gUnk_08120DFC[super->actionDelay];
+ obj = CreateObject(BEANSTALK, 7, ptr->type - 2);
+ super->child = obj;
+ if (obj != NULL) {
+ obj->x.HALF.HI = super->x.HALF.HI + ptr->x;
+ (super->child)->y.HALF.HI = (super->y.HALF.HI - (s16)this->unk_6c) - ptr->y;
+ super->child->spriteSettings.flipX = ptr->flipX;
+ }
+ super->actionDelay++;
+ }
+ if (super->actionDelay > 5) {
+ super->actionDelay = 0;
+ }
+ }
+ this->unk_6c += 0x38;
+ } while (((s16)(super->y.HALF_U.HI - this->unk_6c)) >= gRoomControls.origin_y);
+ super->actionDelay = 1;
+ break;
+ case 2:
+ case 3:
+ super->spriteRendering.b3 = 1;
+ // fallthrough
+ case 4:
+ super->collisionLayer = 3;
+ }
+ break;
+ }
+ Beanstalk_Action1(this);
+}
+
+void Beanstalk_Action1(BeanstalkEntity* this) {
+ static void (*const Beanstalk_Action1Types[])(BeanstalkEntity*) = {
+ Beanstalk_Action1Type0, Beanstalk_Action1Type1, Beanstalk_Action1Type2, Beanstalk_Action1Type1,
+ Beanstalk_Action1Type4, Beanstalk_Action1Type4, Beanstalk_Action1Type4, Beanstalk_Action1Type7,
+ Beanstalk_Action1Type8, Beanstalk_Action1Type9,
+ };
+ Beanstalk_Action1Types[super->type](this);
+}
+
+void Beanstalk_Action1Type0(BeanstalkEntity* this) {
+ static void (*const Beanstalk_Action1Type0SubActions[])(BeanstalkEntity*) = {
+ Beanstalk_Action1Type0SubAction0,
+ Beanstalk_Action1Type0SubAction1,
+ Beanstalk_Action1Type0SubAction2,
+ };
+ Beanstalk_Action1Type0SubActions[super->subAction](this);
+}
+
+void Beanstalk_Action1Type0SubAction0(BeanstalkEntity* this) {
+ UpdateAnimationSingleFrame(super);
+ if ((super->frame & 0x80) != 0) {
+ if (super->actionDelay < 2) {
+ super->actionDelay++;
+ } else {
+ InitAnimationForceUpdate(super, 1);
+ super->actionDelay = 0x10;
+ super->subAction++;
+ }
+ }
+}
+
+void Beanstalk_Action1Type0SubAction1(BeanstalkEntity* this) {
+ if (super->actionDelay-- == 0) {
+ super->actionDelay = 0x10;
+ SoundReq(SFX_198);
+ }
+ UpdateAnimationSingleFrame(super);
+ if ((super->frame & 0x80) != 0) {
+ Entity* entity = CreateObject(BEANSTALK, 1, 0);
+ super->child = entity;
+ if (entity != NULL) {
+ entity->x.HALF.HI = super->x.HALF.HI;
+ (super->child)->y.HALF.HI = super->y.HALF.HI;
+ }
+ entity = CreateObject(BEANSTALK, 2, 0);
+ super->child = entity;
+ if (entity != NULL) {
+ entity->x.HALF.HI = super->x.HALF.HI;
+ (super->child)->y.HALF.HI = super->y.HALF.HI + -0x10;
+ }
+ super->spriteSettings.draw = 0;
+ super->subAction++;
+ }
+}
+
+void Beanstalk_Action1Type0SubAction2(BeanstalkEntity* this) {
+ if (super->actionDelay-- == 0) {
+ super->actionDelay = 0x10;
+ SoundReq(SFX_198);
+ }
+}
+
+void Beanstalk_Action1Type2(BeanstalkEntity* this) {
+ s32 tmp;
+ const struct_08120DFC* ptr;
+
+ GetNextFrame(super);
+ if ((super->frame & 1) != 0) {
+ ptr = &gUnk_08120DFC[super->actionDelay];
+ super->child = CreateObject(BEANSTALK, ptr->type, 0);
+ if (super->child != NULL) {
+ super->child->x.HALF.HI = super->x.HALF.HI + ptr->x;
+ super->child->y.HALF.HI = super->y.HALF.HI - ptr->y;
+ super->child->spriteSettings.flipX = ptr->flipX;
+ }
+ if (++super->actionDelay > 5) {
+ super->actionDelay = 0;
+ }
+ }
+ if ((super->frame & 0x80) != 0) {
+ super->child = CreateObject(BEANSTALK, 3, 0);
+ if (super->child != NULL) {
+ super->child->x.HALF.HI = super->x.HALF.HI;
+ super->child->y.HALF.HI = super->y.HALF.HI;
+ }
+ tmp = super->y.HALF.HI -= 0x38;
+ if (tmp * 0x10000 < 0) {
+ DeleteEntity(super);
+ }
+ }
+}
+
+void Beanstalk_Action1Type4(BeanstalkEntity* this) {
+ if ((super->frame & 0x80) == 0) {
+ GetNextFrame(super);
+ }
+}
+
+void Beanstalk_Action1Type1(BeanstalkEntity* this) {
+}
+
+void Beanstalk_Action1Type7(BeanstalkEntity* this) {
+ switch (super->type2) {
+ case 0:
+ if (super->actionDelay == 0) {
+ return;
+ }
+ this->unk_6c = gRoomControls.origin_y;
+ this->unk_70 = TILE(super->x.HALF.HI, this->unk_6c);
+ while (TRUE) {
+ this->unk_70 = TILE(super->x.HALF.HI, this->unk_6c);
+ SetTile(0x4017, this->unk_70, 2);
+ SetTile(0x4017, this->unk_70, 1);
+ this->unk_6c += 0x10;
+ if (this->unk_6c >= gRoomControls.origin_y + gRoomControls.height)
+ break;
+ if (this->unk_6c > super->y.HALF.HI) {
+ break;
+ }
+ }
+ super->actionDelay = 0;
+ return;
+ break;
+ case 1:
+ return;
+ case 2:
+ case 3:
+ case 4:
+ if (gPlayerState.floor_type == 0x1e) {
+ if (EntityInRectRadius(super, &gPlayerEntity, 0, 8)) {
+ if ((super->animIndex == (super->type2 - 1) * 3 + 1) && (super->actionDelay == 0)) {
+ super->actionDelay = 1;
+ InitializeAnimation(super, super->animIndex + 1);
+ }
+ } else {
+ super->actionDelay = 0;
+ }
+ } else {
+ super->actionDelay = 0;
+ }
+ GetNextFrame(super);
+ if ((super->frame & 0x80) != 0) {
+ InitializeAnimation(super, (super->type2 - 1) * 3 + 1);
+ }
+ break;
+ }
+}
+
+void Beanstalk_Action1Type8(BeanstalkEntity* this) {
+ static void (*const Beanstalk_Action1Type8SubActions[])(BeanstalkEntity*) = {
+ Beanstalk_Action1Type8SubAction0,
+ Beanstalk_Action1Type8SubAction1,
+ };
+ Beanstalk_Action1Type8SubActions[super->subAction](this);
+}
+
+void Beanstalk_Action1Type8SubAction0(BeanstalkEntity* this) {
+ Entity* obj;
+
+ super->spriteOrientation.flipY = 2;
+ this->unk_70 = COORD_TO_TILE(super);
+ SetTile(0x4017, this->unk_70, 1);
+ super->subAction = 1;
+ obj = CreateObjectWithParent(super, OBJECT_15, 0, 0);
+ if (obj != NULL) {
+ obj->y.HALF.HI = super->y.HALF.HI + 0x38;
+ obj->spriteIndex = super->spriteIndex;
+ obj->spriteVramOffset = super->spriteVramOffset;
+ obj->palette.b.b0 = super->palette.b.b0;
+ obj->animIndex = 2;
+ obj->actionDelay = 0x80;
+ obj->type = 1;
+ obj->spriteRendering.b3 = 2;
+ obj->spritePriority.b0 = 6;
+ obj->spriteOrientation.flipY = 2;
+ }
+ CreateObjectWithParent(super, BEANSTALK, 9, 0);
+}
+
+void Beanstalk_Action1Type8SubAction1(BeanstalkEntity* this) {
+}
+
+void Beanstalk_Action1Type9(BeanstalkEntity* this) {
+ if (super->subAction == 0) {
+ super->subAction = 1;
+ super->y.HALF.HI += 0x28;
+ this->unk_72 = sub_0800029C(super, 0, -0x18);
+ }
+ super->spriteOrientation.flipY = gPlayerEntity.spriteOrientation.flipY;
+ super->spriteRendering.b3 = gPlayerEntity.spriteRendering.b3;
+ if (gPlayerState.floor_type == 0x1e) {
+ super->spritePriority.b0 = 0;
+ if (sub_0800029C(super, 0, -0x18) != 0x4014) {
+ SetTile(0x4014, COORD_TO_TILE_OFFSET(super, 0, 0x18), 1);
+ }
+ } else {
+ super->spritePriority.b0 = 5;
+ if (this->unk_72 != sub_0800029C(super, 0, -0x18)) {
+ SetTile(this->unk_72, COORD_TO_TILE_OFFSET(super, 0, 0x18), 1);
+ }
+ }
+}