/** * @file lavaPlatform.c * @ingroup Objects * * @brief Lava Platform object */ #define NENT_DEPRECATED #include "global.h" #include "object.h" #include "functions.h" #include "hitbox.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; 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 & ANIM_DONE) == 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 & ANIM_DONE; 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 & ANIM_DONE) != 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, (u16**)&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, (u16**)&this->unk_78, &this->unk_76); } }