#define NENT_DEPRECATED #include "global.h" #include "entity.h" #include "object.h" #include "functions.h" typedef struct { Entity base; u32 unk_68; u8 unk_6c[0x1C]; } SpecialFxObject; typedef struct { u8 unk_00 : 4; u8 unk_00_4 : 4; u8 unk_01; u16 unk_02; } struct_0811F960; // way more legible like this than if clang-format were to put multiple elements on each line // clang-format off const struct_0811F960 gUnk_0811F960[] = { {0x1, 0x0, 0x00, 0x12D}, {0x0, 0x0, 0x00, 0x0FD}, {0x0, 0x0, 0x00, 0x124}, {0x0, 0x1, 0x11, 0x123}, {0x0, 0x1, 0x12, 0x164}, {0x0, 0x1, 0x13, 0x10D}, {0x0, 0x0, 0x00, 0x0FF}, {0x5, 0x1, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x2, 0x1, 0x00, 0x084}, {0x2, 0x1, 0x00, 0x084}, {0x0, 0x0, 0x00, 0x195}, {0x0, 0x0, 0x00, 0x164}, {0x0, 0x0, 0x00, 0x10D}, {0x0, 0x1, 0x00, 0x074}, {0x0, 0x0, 0x00, 0x10C}, {0x5, 0x0, 0x00, 0x000}, {0x0, 0x0, 0x10, 0x123}, {0x5, 0x1, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x164}, {0x0, 0x1, 0x14, 0x1A8}, {0x0, 0x1, 0x10, 0x088}, {0x0, 0x0, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x3, 0x0, 0x00, 0x197}, {0x3, 0x0, 0x00, 0x000}, {0x6, 0x1, 0x00, 0x074}, {0x3, 0x0, 0x00, 0x074}, {0x0, 0x0, 0x00, 0x074}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x7, 0x0, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x3, 0x1, 0x00, 0x000}, {0x8, 0x1, 0x00, 0x000}, {0x9, 0x1, 0x00, 0x15F}, {0x0, 0x0, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x2, 0x1, 0x00, 0x084}, {0x0, 0x0, 0x00, 0x074}, {0x0, 0x0, 0x00, 0x164}, {0xA, 0x1, 0x00, 0x000}, {0xA, 0x1, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x9, 0x1, 0x00, 0x15F}, {0x9, 0x1, 0x00, 0x15F}, {0x9, 0x1, 0x00, 0x15F}, {0x0, 0x0, 0x00, 0x000}, {0x2, 0x0, 0x00, 0x17F}, {0x0, 0x1, 0x11, 0x123}, {0x0, 0x1, 0x11, 0x123}, {0x0, 0x1, 0x11, 0x123}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x1B4}, {0x0, 0x1, 0x13, 0x164}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x10, 0x088}, {0x0, 0x1, 0x10, 0x088}, {0x0, 0x1, 0x10, 0x088}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x11D}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x0, 0x00, 0x164}, {0x0, 0x0, 0x00, 0x0FD}, {0x0, 0x0, 0x00, 0x0FD}, {0x0, 0x0, 0x00, 0x0FD}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0xB, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x000}, {0x0, 0x1, 0x00, 0x0FD}, {0x2, 0x1, 0x00, 0x084}, #ifndef EU {0x0, 0x0, 0x18, 0x124}, #else {0x0, 0x0, 0x16, 0x124}, #endif {0xC, 0x0, 0x00, 0x124}, {0x0, 0x0, 0x00, 0x0FD}, {0xD, 0x1, 0x00, 0x000}, {0xD, 0x1, 0x00, 0x000}, }; // clang-format on void SpecialFx(Entity*); void sub_080844E0(SpecialFxObject*); void sub_080845B8(SpecialFxObject*); void sub_080845DC(SpecialFxObject*); void sub_080845F8(SpecialFxObject*); void sub_08084630(SpecialFxObject*); void sub_08084680(SpecialFxObject*); void sub_08084694(SpecialFxObject*); void sub_080846B0(SpecialFxObject*); void sub_0808471C(SpecialFxObject*); void sub_08084770(SpecialFxObject*); void sub_08084784(SpecialFxObject*); void sub_08084798(SpecialFxObject*); void sub_080847BC(SpecialFxObject*); void sub_080847D0(SpecialFxObject*); void sub_080847E0(SpecialFxObject*); void SpecialFx(Entity* this) { static void (*const gUnk_0811FAC0[])(SpecialFxObject*) = { sub_080844E0, sub_080845B8, }; gUnk_0811FAC0[this->action]((SpecialFxObject*)this); } void sub_080844E0(SpecialFxObject* this) { static const u8 gUnk_0811FAC8[] = { 0x03, 0x37, 0x38, 0x39 }; static const u8 gUnk_0811FACC[] = { 0x17, 0x3e, 0x3f, 0x40 }; const struct_0811F960* ptr; super->action = 1; super->flags &= ~0x80; super->spriteSettings.draw = 1; SetDefaultPriority(super, 6); if (super->collisionLayer == 0) { ResolveCollisionLayer(super); } if (super->type == 0x20) { super->flags |= 0x20; } if (super->type == 0x3) { super->type = gUnk_0811FAC8[Random() & 3]; } if (super->type == 0x17) { super->type = gUnk_0811FACC[Random() & 3]; } InitializeAnimation(super, super->type); ptr = &gUnk_0811F960[super->type]; if (ptr->unk_00 == 6) { super->speed = 0x40; } if (ptr->unk_02 && !(super->type2 & 0x40)) { EnqueueSFX(ptr->unk_02); } if (super->type2 & 0x80) { CreateRandomItemDrop(super, ptr->unk_01); } if (super->type2 & 0x20) { super->spriteRendering.b3 = 1; } } void sub_080845B8(SpecialFxObject* this) { static void (*const gUnk_0811FAD0[])(SpecialFxObject*) = { sub_080845DC, sub_080845F8, sub_08084630, sub_08084694, (void (*)(SpecialFxObject*))DeleteEntity, sub_08084680, sub_080846B0, sub_0808471C, sub_08084770, sub_08084798, sub_080847BC, sub_08084784, sub_080847D0, sub_080847E0, }; gUnk_0811FAD0[gUnk_0811F960[super->type].unk_00](this); } void sub_080845DC(SpecialFxObject* this) { GetNextFrame(super); if (super->frame & 0x80) { DeleteThisEntity(); } } void sub_080845F8(SpecialFxObject* this) { if (((8 - (super->x.HALF.HI & 0xF)) | (8 - (super->y.HALF.HI & 0xF))) != 0) { super->direction = sub_080045DA((8 - (super->x.HALF.HI & 0xF)), (8 - (super->y.HALF.HI & 0xF))) >> 3; LinearMoveUpdate(super); } sub_08084630(this); } void sub_08084630(SpecialFxObject* this) { GetNextFrame(super); if (super->frame & 0x80) { if ((super->type2 & 1) && (super->child != 0)) { ((GenericEntity*)super->child)->field_0x6a.HWORD--; if (this->unk_68 != 0) { ((GenericEntity*)super->child)->field_0x6c.HWORD &= ~(1 << ((this->unk_68 - 1) & 0x1F)); } } DeleteThisEntity(); } } void sub_08084680(SpecialFxObject* this) { super->z.WORD += 0x4000; sub_080845DC(this); } void sub_08084694(SpecialFxObject* this) { if (!super->parent || !super->parent->next) { DeleteThisEntity(); } GetNextFrame(super); } void sub_080846B0(SpecialFxObject* this) { s32 tmp; if (super->actionDelay != 0) { if (super->speed != 0) { super->speed -= 0x10; } LinearMoveUpdate(super); sub_080845DC(this); } else { super->actionDelay = 1; if ((super->animationState | 2) == 2) { super->direction = 0x1e; } else { super->direction = 2; } if (super->field_0xf != 0) { super->spriteVramOffset++; tmp = (super->direction > 0x17 ? -1 : 1); super->direction += tmp; super->speed = 0x280; } else { super->speed = 0x300; } } } void sub_0808471C(SpecialFxObject* this) { static const s8 gUnk_0811FB08[] = { -8, -8, 8, -8, -8, 8, 8, 8 }; GetNextFrame(super); if (super->frame & 0x80) { u32 i; for (i = 0; i < 4; i++) { Entity* fx = CreateFx(super, 0x24, 0); if (fx) { const s8* ptr = &gUnk_0811FB08[2 * i]; fx->x.HALF.HI += ptr[0]; fx->y.HALF.HI += ptr[1]; } } DeleteThisEntity(); } } void sub_08084770(SpecialFxObject* this) { super->z.WORD -= 0x4000; sub_080845DC(this); } void sub_08084784(SpecialFxObject* this) { super->z.WORD += 0x4000; sub_080845DC(this); } void sub_08084798(SpecialFxObject* this) { GetNextFrame(super); if ((super->frame & 0x80) || !super->child->next) { DeleteThisEntity(); } } void sub_080847BC(SpecialFxObject* this) { super->z.WORD -= 0x2000; sub_080845DC(this); } void sub_080847D0(SpecialFxObject* this) { LinearMoveUpdate(super); sub_080845DC(this); } void sub_080847E0(SpecialFxObject* this) { if (gRoomControls.reload_flags == 1) { DeleteThisEntity(); } PositionRelative(&gPlayerEntity, super, 0, -0x30000); super->z.HALF.HI = -3; SortEntityAbove(&gPlayerEntity, super); sub_080845DC(this); }