summaryrefslogtreecommitdiff
path: root/src/object
diff options
context:
space:
mode:
authoroctorock <79596758+octorock@users.noreply.github.com>2022-02-14 13:14:34 +0100
committeroctorock <79596758+octorock@users.noreply.github.com>2022-02-18 20:48:24 +0100
commita448d222983a89d0a75ac15993db5e01fb5f5359 (patch)
treeb060dd711fe3ce9674b96ab6744b24ff9955212b /src/object
parent3a27a147ad050ba2eef093d1353e7dd37dff8c8d (diff)
Decompile LavaPlatform
Diffstat (limited to 'src/object')
-rw-r--r--src/object/lavaPlatform.c307
1 files changed, 307 insertions, 0 deletions
diff --git a/src/object/lavaPlatform.c b/src/object/lavaPlatform.c
new file mode 100644
index 00000000..9fc23de9
--- /dev/null
+++ b/src/object/lavaPlatform.c
@@ -0,0 +1,307 @@
+/**
+ * @file lavaPlatform.c
+ * @ingroup Objects
+ *
+ * @brief Lava Platform 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 timer;
+ /*0x72*/ u16 wobbleTime; /**< Time the player can stand on the platform. */
+ /*0x74*/ u16 respawnTime; /**< Time until the platform respawns after it has sunk. */
+ /*0x76*/ u16 unk_76;
+ /*0x78*/ Entity* unk_78; // Typed same as second argument of sub_080A2CC0
+} LavaPlatformEntity;
+
+typedef struct {
+ /*0x00*/ Entity* unk_78; // Typed same as second argument of sub_080A2CC0
+ /*0x04*/ s16 x;
+ /*0x06*/ s16 y;
+ /*0x08*/ u8 collisionLayer;
+ /*0x09*/ u8 type2;
+ /*0x0a*/ u16 wobbleTime;
+ /*0x0c*/ u16 respawnTime;
+ /*0x0e*/ u8 unk_e[2];
+} LavaPlatformEntry;
+
+extern void sub_080A2CC0(Entity*, Entity**, u16*);
+extern Hitbox gUnk_080FD280;
+
+void sub_08092278(LavaPlatformEntity*);
+void sub_08092344(LavaPlatformEntity*);
+void LavaPlatform_SpawnPlatforms(LavaPlatformEntity*);
+void sub_080926E4(LavaPlatformEntity*);
+void sub_0809264C(LavaPlatformEntity*);
+void sub_08092620(LavaPlatformEntity*);
+bool32 LavaPlatform_IsPlayerOnPlatform(LavaPlatformEntity*);
+void LavaPlatform_Type0Init(LavaPlatformEntity*);
+void LavaPlatform_Type0Action1(LavaPlatformEntity*);
+void LavaPlatform_Type0Action2(LavaPlatformEntity*);
+void LavaPlatform_Type1Init(LavaPlatformEntity*);
+void LavaPlatform_Type1Action1(LavaPlatformEntity*);
+void LavaPlatform_Type1Action2(LavaPlatformEntity*);
+void LavaPlatform_Type1Action3(LavaPlatformEntity*);
+void LavaPlatform_Type1Action4(LavaPlatformEntity*);
+void LavaPlatform_Type1Action5(LavaPlatformEntity*);
+void LavaPlatform_Type1Action6(LavaPlatformEntity*);
+void LavaPlatform_Type1Action7(LavaPlatformEntity*);
+
+void LavaPlatform(LavaPlatformEntity* this) {
+ if (super->type == 0) {
+ sub_08092278(this);
+ } else {
+ sub_08092344(this);
+ }
+}
+
+void sub_08092278(LavaPlatformEntity* this) {
+ static void (*const LavaPlatform_Type0Actions[])(LavaPlatformEntity*) = {
+ LavaPlatform_Type0Init,
+ LavaPlatform_Type0Action1,
+ LavaPlatform_Type0Action2,
+ };
+ LavaPlatform_Type0Actions[super->action](this);
+}
+
+void LavaPlatform_Type0Init(LavaPlatformEntity* this) {
+ super->action = 1;
+ LavaPlatform_SpawnPlatforms(this);
+}
+
+void LavaPlatform_Type0Action1(LavaPlatformEntity* this) {
+ if (*(u8*)&this->timer != 0) {
+ // Use this entity to show the platform flipping animation.
+ super->action = 2;
+ super->zVelocity = 0x2c000;
+ super->spriteSettings.draw = 1;
+ UpdateSpriteForCollisionLayer(super);
+ InitAnimationForceUpdate(super, (super->child)->animationState);
+ EnqueueSFX(SFX_LAVA_TILE_FLIP);
+ InitializeAnimation(super->child, 3);
+ }
+}
+
+void LavaPlatform_Type0Action2(LavaPlatformEntity* this) {
+ if (GravityUpdate(super, 0x2400) == 0) {
+ // Finished flipping platform.
+ super->action = 1;
+ super->spriteSettings.draw = 0;
+ *(u8*)&this->timer = 0;
+ (super->child)->spriteOffsetY = 0;
+ InitializeAnimation(super->child, super->child->animationState);
+ CreateFx(super, FX_LAVA_SPLASH_HUGE, 0);
+ } else if ((super->zVelocity < 0x18000) && ((super->frame & 0x80) == 0)) {
+ UpdateAnimationSingleFrame(super);
+ }
+}
+
+void sub_08092344(LavaPlatformEntity* this) {
+ static void (*const LavaPlatform_Type1Actions[])(LavaPlatformEntity*) = {
+ LavaPlatform_Type1Init, LavaPlatform_Type1Action1, LavaPlatform_Type1Action2, LavaPlatform_Type1Action3,
+ LavaPlatform_Type1Action4, LavaPlatform_Type1Action5, LavaPlatform_Type1Action6, LavaPlatform_Type1Action7,
+ };
+ super->field_0xf = 0;
+ LavaPlatform_Type1Actions[super->action](this);
+ sub_080926E4(this);
+}
+
+void LavaPlatform_Type1Init(LavaPlatformEntity* this) {
+ super->animationState = super->type2;
+ super->spritePriority.b0 = 7;
+ super->hurtType = 0x48;
+ super->field_0x3c = 7;
+ super->flags2 = 0x81;
+ super->hitbox = (Hitbox*)&gUnk_080FD280;
+ sub_0809264C(this);
+}
+
+void LavaPlatform_Type1Action1(LavaPlatformEntity* this) {
+ if (super->animIndex != 3) {
+ if (super->subAction == 0) {
+ super->subAction = 1;
+ super->animationState ^= 1;
+ InitializeAnimation(super, (u32)super->animationState);
+ }
+ if (--super->spriteOffsetY * 0x1000000 >> 0x18 == -3) {
+ sub_0809264C(this);
+ }
+ }
+}
+
+void LavaPlatform_Type1Action2(LavaPlatformEntity* this) {
+ if (super->bitfield == 0x9d) {
+ sub_08092620(this);
+ } else {
+ if (LavaPlatform_IsPlayerOnPlatform(this)) {
+ super->action = 3;
+ super->flags &= ~ENT_COLLIDE;
+ super->actionDelay = 0x14;
+ gPlayerState.field_0x3f = 0xfd;
+ }
+ }
+}
+
+/** Player is standing on the platform. */
+void LavaPlatform_Type1Action3(LavaPlatformEntity* this) {
+ if (LavaPlatform_IsPlayerOnPlatform(this)) {
+ gPlayerState.field_0x3f = 0xfd;
+ }
+ if (--super->actionDelay == 0) {
+ super->action = 4;
+ this->timer = this->wobbleTime;
+ super->spriteOffsetY = 0;
+ InitializeAnimation(super, 2);
+ EnqueueSFX(SFX_LAVA_TILE_STEP);
+ }
+}
+
+/** Platform begins to wobble */
+void LavaPlatform_Type1Action4(LavaPlatformEntity* this) {
+ u32 tmp;
+ LavaPlatform_IsPlayerOnPlatform(this);
+ if (this->timer != 0) {
+ this->timer--;
+ }
+ if (this->timer < 0x8d) {
+ GetNextFrame(super);
+ tmp = super->frame & 0x80;
+ if (tmp) {
+ // Platform sank
+ super->action = 5;
+ this->timer = this->respawnTime;
+ super->spriteSettings.draw = 0;
+ } else {
+ if ((super->frame & 1) != 0) {
+ super->frame = tmp;
+ EnqueueSFX(SFX_LAVA_TILE_WOBBLE);
+ } else {
+ if ((super->frame & 2) != 0) {
+ super->frame = super->frame & 1;
+ EnqueueSFX(SFX_LAVA_TILE_SINK);
+ }
+ }
+ }
+ }
+}
+
+void LavaPlatform_Type1Action5(LavaPlatformEntity* this) {
+ if (--this->timer == 0) {
+ super->action = 6;
+ super->animationState = super->type2;
+ super->spriteSettings.draw = 1;
+ super->spriteOffsetY = 0;
+ InitializeAnimation(super, super->animationState + 4);
+ if (super->animationState == 0) {
+ LavaPlatform_IsPlayerOnPlatform(this);
+ }
+ }
+}
+
+void LavaPlatform_Type1Action6(LavaPlatformEntity* this) {
+ bool32 tmp;
+
+ if (super->animationState == 0) {
+ tmp = LavaPlatform_IsPlayerOnPlatform(this);
+ } else {
+ tmp = FALSE;
+ }
+ GetNextFrame(super);
+ if ((super->frame & 1) != 0) {
+ super->frame = 0;
+ super->flags |= ENT_COLLIDE;
+ super->hitType = 0xac;
+ } else {
+ if ((super->frame & 0x80) != 0) {
+ sub_0809264C(this);
+ if (tmp) {
+ gPlayerState.field_0x3f = 0xfd;
+ }
+ }
+ }
+}
+
+void LavaPlatform_Type1Action7(LavaPlatformEntity* this) {
+ if (super->bitfield == 0x9d) {
+ sub_08092620(this);
+ }
+}
+
+void LavaPlatform_SpawnPlatforms(LavaPlatformEntity* this) {
+ LavaPlatformEntry* entry = (LavaPlatformEntry*)GetCurrentRoomProperty(super->type2);
+ while (entry->type2 != 0xff) {
+ LavaPlatformEntity* platform = (LavaPlatformEntity*)CreateObject(LAVA_PLATFORM, 1, entry->type2);
+ if (platform != NULL) {
+ (platform->base).direction = 0xff;
+ (platform->base).speed = 0;
+ (platform->base).parent = super;
+ (platform->base).x.HALF.HI = entry->x + gRoomControls.origin_x;
+ (platform->base).y.HALF.HI = entry->y + gRoomControls.origin_y;
+ (platform->base).collisionLayer = entry->collisionLayer;
+ platform->wobbleTime = entry->wobbleTime;
+ platform->respawnTime = entry->respawnTime;
+ platform->unk_78 = entry->unk_78;
+ UpdateSpriteForCollisionLayer((Entity*)platform);
+ sub_080A2CC0(&platform->base, &platform->unk_78, &platform->unk_76);
+ }
+ entry++;
+ }
+}
+
+void sub_08092620(LavaPlatformEntity* this) {
+ LavaPlatformEntity* parent = (LavaPlatformEntity*)super->parent;
+ u32 one;
+ if (*(u8*)&parent->timer == 0) {
+ one = 1;
+ *(u8*)&parent->timer = one;
+ (parent->base).child = super;
+ CopyPosition(super, &parent->base);
+ super->action = one;
+ super->subAction = 0;
+ super->hitType = 0xac;
+ }
+}
+
+void sub_0809264C(LavaPlatformEntity* this) {
+ if ((super->animationState & 1) != 0) {
+ super->action = 7;
+ super->hitType = 0xac;
+ } else {
+ super->action = 2;
+ super->hitType = 1;
+ }
+ super->flags |= ENT_COLLIDE;
+ super->spriteSettings.draw = 1;
+ super->spriteOffsetY = -3;
+ InitializeAnimation(super, super->animationState);
+}
+
+bool32 LavaPlatform_IsPlayerOnPlatform(LavaPlatformEntity* this) {
+ if ((gPlayerState.flags & PL_MINISH) == 0 && EntityInRectRadius(super, &gPlayerEntity, 0x10, 0x10) &&
+ sub_08079F8C()) {
+ gPlayerState.field_0x14 = 1;
+ if (gPlayerEntity.z.HALF.HI == 0) {
+ super->field_0xf = 1;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void sub_080926E4(LavaPlatformEntity* this) {
+ sub_080A2BE4(super, super->field_0xf);
+ if (super->action == 1) {
+ (super->parent)->x.HALF.HI = super->x.HALF.HI;
+ (super->parent)->y.HALF.HI = super->y.HALF.HI;
+ }
+ if (--this->unk_76 == 0) {
+ sub_080A2CC0(super, &this->unk_78, &this->unk_76);
+ }
+}