tmc/src/object/chestSpawner.c

318 lines
9.8 KiB
C

/**
* @file chestSpawner.c
* @ingroup Objects
*
* @brief Chest Spawner object
*/
#define NENT_DEPRECATED
#include "global.h"
#include "object.h"
#include "functions.h"
#include "screen.h"
#include "structures.h"
#include "item.h"
typedef struct {
/*0x00*/ Entity base;
/*0x68*/ u8 unk_68[8];
/*0x70*/ u16 tilePosition;
/*0x72*/ u16 unk_72;
/*0x74*/ u8 unk_74[0x12];
/*0x86*/ u16 unk_86;
} ChestSpawnerEntity;
extern const Hitbox gUnk_0811F8A8;
extern const Hitbox gUnk_0811F8B0;
void sub_080842D8(ChestSpawnerEntity*);
void sub_08078828(ChestSpawnerEntity*);
void sub_08083E20(ChestSpawnerEntity*);
void sub_08084074(u32);
void sub_080840A8(s32, s32);
void ChestSpawner_Type0(ChestSpawnerEntity*);
void ChestSpawner_Type2(ChestSpawnerEntity*);
void ChestSpawner_Type0Init(ChestSpawnerEntity*);
void ChestSpawner_Type0Action1(ChestSpawnerEntity*);
void ChestSpawner_Type0Action2(ChestSpawnerEntity*);
void ChestSpawner_Type0Action3(ChestSpawnerEntity*);
void ChestSpawner_Type2Init(ChestSpawnerEntity*);
void ChestSpawner_Type2Action1(ChestSpawnerEntity*);
void ChestSpawner_Type2Action2(ChestSpawnerEntity*);
void ChestSpawner_Type2Action3(ChestSpawnerEntity*);
void ChestSpawner_Type2Action4(ChestSpawnerEntity*);
void ChestSpawner_Type2Action5(ChestSpawnerEntity*);
void ChestSpawner_Type2Action6(ChestSpawnerEntity*);
void ChestSpawner_Type2Action7(ChestSpawnerEntity*);
void ChestSpawner(ChestSpawnerEntity* this) {
static void (*const ChestSpawner_Types[])(ChestSpawnerEntity*) = {
ChestSpawner_Type0, ChestSpawner_Type0, ChestSpawner_Type2, ChestSpawner_Type2,
ChestSpawner_Type2, ChestSpawner_Type2, ChestSpawner_Type0, ChestSpawner_Type0,
};
ChestSpawner_Types[super->type](this);
}
void ChestSpawner_Type0(ChestSpawnerEntity* this) {
static void (*const ChestSpawner_Type0Actions[])(ChestSpawnerEntity*) = {
ChestSpawner_Type0Init,
ChestSpawner_Type0Action1,
ChestSpawner_Type0Action2,
ChestSpawner_Type0Action3,
};
ChestSpawner_Type0Actions[super->action](this);
}
void ChestSpawner_Type2(ChestSpawnerEntity* this) {
static void (*const ChestSpawner_Type2Actions[])(ChestSpawnerEntity*) = {
ChestSpawner_Type2Init, ChestSpawner_Type2Action1, ChestSpawner_Type2Action2, ChestSpawner_Type2Action3,
ChestSpawner_Type2Action4, ChestSpawner_Type2Action5, ChestSpawner_Type2Action6, ChestSpawner_Type2Action7,
};
ChestSpawner_Type2Actions[super->action](this);
}
void sub_08083E20(ChestSpawnerEntity* this) {
super->action = 3;
super->spriteSettings.draw = 1;
super->spriteRendering.alphaBlend = 0;
sub_080842D8(this);
sub_08078828(this);
}
void ChestSpawner_Type2Init(ChestSpawnerEntity* this) {
super->hitbox = (Hitbox*)&gUnk_0811F8B0;
if (CheckLocalFlag(super->type2)) {
super->spriteSettings.draw = 1;
super->action = 5;
sub_080842D8(this);
InitializeAnimation(super, 1);
} else {
if (CheckFlags(this->unk_86) || super->type == 4) {
sub_08083E20(this);
} else {
super->action = 1;
}
InitializeAnimation(super, 0);
}
}
void ChestSpawner_Type2Action1(ChestSpawnerEntity* this) {
if (CheckFlags(this->unk_86)) {
gScreen.controls.layerFXControl = 0xf40;
gScreen.controls.alphaBlend = 0x1000;
gUnk_02034490.unk0 = 1;
super->action = 2;
super->subAction = 0;
super->field_0xf = 0x1e;
super->spriteSettings.draw = 1;
super->spriteRendering.alphaBlend = 1;
RequestPriorityDuration(super, 0x1e);
sub_0805BC4C();
}
}
void ChestSpawner_Type2Action2(ChestSpawnerEntity* this) {
u32 tmp;
SetPriorityTimer(0x1e);
switch (super->subAction) {
case 0:
if (EntityInRectRadius(super, &gPlayerEntity, 0x10, 8)) {
sub_08078AC0(0x10, 0, 0);
gPlayerEntity.direction = 0x10;
}
super->subAction = 1;
break;
case 1:
if ((super->type == 5) || (gPlayerEntity.action == 1)) {
super->subAction = 2;
super->actionDelay = 8;
super->field_0xf = 0;
SoundReq(SFX_14A);
}
break;
default:
sub_0800445C(super);
CreateMagicSparkles(super->x.HALF.HI, super->y.HALF.HI, 2);
if (--super->actionDelay == 0) {
super->actionDelay = 8;
tmp = ++super->field_0xf;
gScreen.controls.alphaBlend = (((0x10 - tmp) * 0x100) & 0xff00) | tmp;
if (gScreen.controls.alphaBlend == 0x10) {
gUnk_02034490.unk0 = 0;
gScreen.controls.layerFXControl = 0;
sub_08083E20(this);
SoundReq(SFX_SECRET_BIG);
}
}
break;
}
}
void ChestSpawner_Type2Action3(ChestSpawnerEntity* this) {
sub_0800445C(super);
if (super->interactType != 0) {
super->action = 4;
super->field_0xf = 0x1e;
sub_080788E0(super);
RequestPriorityDuration(super, 0x3c);
SoundReq(SFX_CHEST_OPEN);
}
}
void ChestSpawner_Type2Action4(ChestSpawnerEntity* this) {
sub_0800445C(super);
GetNextFrame(super);
if ((super->frame & ANIM_DONE) != 0) {
if (--super->field_0xf == 0) {
if (super->actionDelay == 0x18) {
super->action = 6;
super->actionDelay = 8;
super->field_0xf = 0x10;
} else {
super->action = 5;
sub_08084074(super->type2);
}
}
SetLocalFlag(super->type2);
}
}
void sub_08084074(u32 param_1) {
u8* arr = (u8*)GetCurrentRoomProperty(3);
if (arr != NULL) {
for (; arr[0] != 0; arr += 8) {
if ((arr[0] == 3) && (param_1 == arr[1])) {
CreateItemEntity(arr[2], arr[3], 0);
return;
}
}
}
}
void sub_080840A8(s32 param_1, s32 param_2) {
static const u8 gUnk_0811F838[] = { 84, 84, 84, 84, 85, 85, 85, 86 };
static const s32 gUnk_0811F840[] = { 393216, 458752, 524288, 589824 };
static const s8 gUnk_0811F850[] = { -6, 0, 0, 6 };
Entity* obj = CreateObject(GROUND_ITEM, gUnk_0811F838[Random() & 7], 0);
if (obj != NULL) {
obj->actionDelay = 6;
obj->direction = ((Random() & 7) + 0xc) | 0x80;
obj->speed = (Random() & 0xf) * 2 + 0x20;
obj->zVelocity = gUnk_0811F840[Random() & 3];
obj->x.HALF.HI = gUnk_0811F850[Random() & 3] + param_1;
obj->y.HALF.HI = param_2 + 1;
obj->z.HALF.HI = 0xfff8;
ResolveCollisionLayer(obj);
obj = CreateFx(obj, FX_DASH, 0);
if (obj != NULL) {
SoundReq(SFX_124);
}
}
}
void ChestSpawner_Type2Action6(ChestSpawnerEntity* this) {
if (--super->actionDelay == 0) {
super->actionDelay = 8;
if (--super->field_0xf != 0) {
sub_080840A8(super->x.HALF.HI, super->y.HALF.HI);
} else {
super->action = 5;
}
}
}
void ChestSpawner_Type2Action5(ChestSpawnerEntity* this) {
sub_0800445C(super);
}
void ChestSpawner_Type2Action7(ChestSpawnerEntity* this) {
}
void ChestSpawner_Type0Init(ChestSpawnerEntity* this) {
super->action++;
this->tilePosition = COORD_TO_TILE(super);
super->hitbox = (Hitbox*)&gUnk_0811F8A8;
if (GetTileTypeByEntity(super) == 0x74) {
DeleteThisEntity();
}
if (CheckFlags(this->unk_86)) {
super->action = 3;
sub_0807B7D8(0x73, this->tilePosition, super->collisionLayer);
if ((super->type & 1) == 0) {
DeleteThisEntity();
}
}
}
void ChestSpawner_Type0Action1(ChestSpawnerEntity* this) {
if (CheckFlags(this->unk_86)) {
super->action = 2;
}
}
void ChestSpawner_Type0Action2(ChestSpawnerEntity* this) {
sub_0807B7D8(0x73, this->tilePosition, super->collisionLayer);
switch (super->type) {
case 6:
case 7:
SoundReq(SFX_215);
break;
default:
SoundReq(SFX_SECRET);
CreateDust(super);
break;
}
super->action = 3;
this->unk_72 = super->actionDelay * 0x3c;
if ((super->type & 1) == 0) {
DeleteThisEntity();
}
}
void ChestSpawner_Type0Action3(ChestSpawnerEntity* this) {
if ((super->type == 1) || (super->type == 7)) {
if (GetTileTypeByEntity(super) == 0x74) {
DeleteEntity(super);
} else {
if (!CheckFlags(this->unk_86)) {
if (this->unk_72 != 0) {
this->unk_72--;
} else {
super->action = 1;
sub_0807BA8C(this->tilePosition, super->collisionLayer);
CreateDust(super);
}
}
}
}
}
void sub_080842D8(ChestSpawnerEntity* this) {
static const u8 gUnk_0811F854[] = {
35, 64, 191, 255, 35, 64, 192, 255, 38, 64, 255, 255, 38, 64, 0, 0, 255, 255,
};
static const u8 gUnk_0811F866[] = {
39, 64, 191, 255, 35, 64, 192, 255, 40, 64, 193, 255, 41, 64, 255, 255, 38, 64, 0, 0, 42, 64, 1, 0, 255, 255,
};
static const u8 gUnk_0811F880[] = {
34, 64, 255, 255, 34, 64, 0, 0, 255, 255,
};
static const u8 gUnk_0811F88A[] = {
36, 64, 255, 255, 34, 64, 0, 0, 37, 64, 1, 0, 255, 255,
};
static const u8* const gUnk_0811F898[] = {
gUnk_0811F854,
gUnk_0811F866,
gUnk_0811F880,
gUnk_0811F88A,
};
s32 index = -(-(super->x.HALF.HI & 8) >> 0x1f);
if ((super->y.HALF.HI & 8) != 0) {
index += 2;
}
SetMultipleTiles((u16*)gUnk_0811F898[index], COORD_TO_TILE(super), super->collisionLayer);
}
const Hitbox gUnk_0811F8A8 = { 0, -3, { 0, 0, 0, 0 }, 6, 6 };
const Hitbox gUnk_0811F8B0 = { 0, -3, { 0, 0, 0, 0 }, 12, 6 };