diff options
| author | octorock <79596758+octorock@users.noreply.github.com> | 2022-02-14 13:14:34 +0100 |
|---|---|---|
| committer | octorock <79596758+octorock@users.noreply.github.com> | 2022-02-18 20:48:24 +0100 |
| commit | a448d222983a89d0a75ac15993db5e01fb5f5359 (patch) | |
| tree | b060dd711fe3ce9674b96ab6744b24ff9955212b /src/object | |
| parent | 3a27a147ad050ba2eef093d1353e7dd37dff8c8d (diff) | |
Decompile LavaPlatform
Diffstat (limited to 'src/object')
| -rw-r--r-- | src/object/lavaPlatform.c | 307 |
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); + } +} |
