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