tmc/src/object/lavaPlatform.c

306 lines
9.5 KiB
C

/**
* @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);
}
}