mirror of https://github.com/zeldaret/tmc.git
144 lines
3.3 KiB
C
144 lines
3.3 KiB
C
/**
|
|
* @file mask.c
|
|
* @ingroup Objects
|
|
*
|
|
* @brief Mask object
|
|
*/
|
|
#define NENT_DEPRECATED
|
|
#include "functions.h"
|
|
#include "object.h"
|
|
|
|
typedef struct {
|
|
/*0x00*/ Entity base;
|
|
/*0x68*/ u8 unused1[16];
|
|
/*0x78*/ u16 unk_78;
|
|
/*0x7a*/ u16 unk_7a;
|
|
/*0x7c*/ u16 unk_7c;
|
|
/*0x7e*/ u16 unk_7e;
|
|
/*0x80*/ u8 unused2[6];
|
|
/*0x86*/ u16 unk_86;
|
|
} MaskEntity;
|
|
|
|
void Mask_Init(MaskEntity* this);
|
|
void Mask_Action1(MaskEntity* this);
|
|
void Mask_Action2(MaskEntity* this);
|
|
void Mask_Delete(MaskEntity* this);
|
|
|
|
void Mask(MaskEntity* this) {
|
|
static void (*const Mask_Actions[])(MaskEntity*) = {
|
|
Mask_Init,
|
|
Mask_Action1,
|
|
Mask_Action2,
|
|
Mask_Delete,
|
|
};
|
|
Mask_Actions[super->action](this);
|
|
}
|
|
|
|
void Mask_Init(MaskEntity* this) {
|
|
if (super->type2 & 0xC0) {
|
|
if (CheckFlags(this->unk_86)) {
|
|
s32 field_0x0a;
|
|
|
|
switch (super->type2 & 0xC0) {
|
|
case 0x40:
|
|
field_0x0a = gRoomTransition.stairs_idx;
|
|
|
|
switch (field_0x0a) {
|
|
case 0x44D ... 0x44F:
|
|
case 0x182:
|
|
DeleteThisEntity();
|
|
break;
|
|
default:
|
|
ClearFlag(this->unk_86);
|
|
}
|
|
|
|
break;
|
|
case 0x80:
|
|
DeleteThisEntity();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
super->action = 1;
|
|
super->zVelocity = Q_16_16(1.5);
|
|
|
|
this->unk_78 = ((Random() & 7) << 10) | 0x2000;
|
|
|
|
super->subtimer = super->timer >> 1;
|
|
super->timer = 0;
|
|
|
|
super->frameIndex = super->type2 & 0x3f;
|
|
|
|
this->unk_7e = COORD_TO_TILE(super);
|
|
this->unk_7c = GetTileIndex(this->unk_7e, 1);
|
|
|
|
this->unk_7a = sub_080B1B44(this->unk_7e, 1);
|
|
|
|
SetTile(0x4022, this->unk_7e, 1);
|
|
}
|
|
|
|
// Probably related to knocking it down
|
|
void Mask_Action1(MaskEntity* this) {
|
|
// Check for the first frame of bonking animation
|
|
if (gPlayerEntity.action != PLAYER_BOUNCE) {
|
|
return;
|
|
}
|
|
|
|
if (gPlayerEntity.animationState != 0) {
|
|
return;
|
|
}
|
|
|
|
// Check if link is close enough to the mask
|
|
if (super->y.HALF.HI + 40 < gPlayerEntity.y.HALF.HI) {
|
|
return;
|
|
}
|
|
|
|
if (super->x.HALF.HI - gPlayerEntity.x.HALF.HI >= super->subtimer ||
|
|
super->x.HALF.HI - gPlayerEntity.x.HALF.HI <= -super->subtimer) {
|
|
return;
|
|
}
|
|
|
|
// Presumably, make the mask fall
|
|
SetTile(this->unk_7c, this->unk_7e, 1);
|
|
|
|
sub_08000148(this->unk_7a, this->unk_7e, 1);
|
|
|
|
super->action = 2;
|
|
|
|
super->z.HALF.HI -= 0x20;
|
|
super->y.HALF.HI += 0x20;
|
|
|
|
super->spriteRendering.b3 = 2;
|
|
}
|
|
|
|
// Probably falling down
|
|
void Mask_Action2(MaskEntity* this) {
|
|
if (super->timer == 1) {
|
|
super->action = 3;
|
|
|
|
super->timer = 0;
|
|
switch (super->type2 & 0xC0) {
|
|
case 0x80:
|
|
EnqueueSFX(SFX_SECRET);
|
|
case 0x40:
|
|
SetFlag(this->unk_86);
|
|
break;
|
|
}
|
|
|
|
CreateFx(super, FX_POT_SHATTER, 0);
|
|
|
|
CreateRandomItemDrop(super, 3);
|
|
} else {
|
|
sub_080044EC(super, this->unk_78);
|
|
|
|
if (super->z.HALF.HI == 0) {
|
|
super->timer++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Mask_Delete(MaskEntity* this) {
|
|
DeleteThisEntity();
|
|
}
|