/** * @file smallIceBlock.c * @ingroup Objects * * @brief Small Ice Block 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[0x4]; /*0x6c*/ u16 unk_6c; /*0x6e*/ u8 unk_6e[0x2]; /*0x70*/ u16 unk_70; /*0x72*/ u8 unk_72[0x14]; /*0x86*/ u16 unk_86; } SmallIceBlockEntity; extern const s16 gUnk_080B4488[]; void sub_080996AC(SmallIceBlockEntity*); void sub_08099468(SmallIceBlockEntity*); bool32 sub_0809963C(SmallIceBlockEntity*); u32 sub_08099618(u32); void sub_080994B8(SmallIceBlockEntity*); void SmallIceBlock_Action3(SmallIceBlockEntity*); bool32 sub_0809953C(SmallIceBlockEntity*); void sub_0809969C(SmallIceBlockEntity*); extern void (*const gUnk_08123734[])(SmallIceBlockEntity*); extern const u16 gUnk_08123748[]; extern const u16 gUnk_08123750[]; void SmallIceBlock(SmallIceBlockEntity* this) { if (super->type < 3) { gUnk_08123734[super->action](this); } else { sub_080996AC(this); } } void SmallIceBlock_Init(SmallIceBlockEntity* this) { Entity* obj; switch (super->type) { case 0: case 1: case 2: if (CheckFlags(this->unk_86)) { DeleteThisEntity(); } } super->action = 1; super->flags |= 0x80; super->updatePriority = 3; super->field_0x3c = 7; super->hurtType = 0x48; super->hitType = 1; super->flags2 = 0x80; super->hitbox = (Hitbox*)&gUnk_080FD408; sub_08099468(this); InitializeAnimation(super, super->type); obj = CreateObject(SMALL_ICE_BLOCK, 3, 0); if (obj != NULL) { obj->parent = super; } } void SmallIceBlock_Action1(SmallIceBlockEntity* this) { u32 tileType; Entity* obj; if (sub_0809963C(this)) { super->action = 3; super->actionDelay = 0; EnqueueSFX(SFX_ICE_BLOCK_MELT); SmallIceBlock_Action3(this); if (super->type == 0) { SetFlag(this->unk_86); } } else { if (!sub_0800442E(super)) { tileType = GetTileType(this->unk_70, super->collisionLayer); if (tileType != 0x405a) { switch (sub_08099618(tileType)) { case 1: super->action = 2; super->actionDelay = 0x16; super->direction = ((tileType - 0x5b) & 3) << 3; super->speed = 0x20; sub_080994B8(this); break; case 0: obj = CreateObject(SPECIAL_FX, 0xd, 0); if (obj != NULL) { CopyPosition(super, obj); } SetTile(this->unk_6c, this->unk_70, super->collisionLayer); DeleteEntity(super); break; case 2: this->unk_6c = (u16)tileType; break; } } } } } void SmallIceBlock_Action2(SmallIceBlockEntity* this) { if (sub_0809953C(this)) { super->action = 1; sub_08099468(this); EnqueueSFX(SFX_ICE_BLOCK_STOP); } } void SmallIceBlock_Action3(SmallIceBlockEntity* this) { if (sub_0809963C(this) == 0) { if (super->actionDelay >= 2) { super->actionDelay -= 2; } else { super->actionDelay = 0; } if (super->actionDelay == 0) { super->action = 1; sub_0805EC60(super); return; } } else { super->actionDelay++; } sub_0805EC9C(super, 0x100, gUnk_08123748[super->actionDelay >> 5], 0); if (super->type == 1) { CreateGroundItemWithFlags(super, 0x53, 0, this->unk_86); SoundReq(SFX_SECRET); } else if (super->type == 2) { CreateGroundItemWithFlags(super, 0x52, 0, this->unk_86); SoundReq(SFX_SECRET); } super->action = 4; super->actionDelay = 0x3c; super->flags &= 0x7f; } void SmallIceBlock_Action4(SmallIceBlockEntity* this) { Entity* obj; s32 rand; s32 x; s32 y; if (--super->actionDelay == 0) { DeleteThisEntity(); } else { if (super->actionDelay == 0x30) { SetTile(this->unk_6c, this->unk_70, super->collisionLayer); } sub_0805EC9C(super, 0x100, (0x3c - super->actionDelay) * 0x20 + 0x100, 0); if ((super->actionDelay & 1) != 0) { obj = CreateObject(SPECIAL_FX, 0x11, 0x40); if (obj != NULL) { rand = Random(); x = ((rand >> 0x10) % 9) - 4; y = rand & 0xf; obj->spritePriority.b0 = 3; PositionRelative(super, obj, x * 0x10000, -y * 0x10000); } } } } void sub_08099468(SmallIceBlockEntity* this) { this->unk_70 = COORD_TO_TILE(super); this->unk_6c = GetTileIndex(this->unk_70, super->collisionLayer); SetTile(0x405a, this->unk_70, super->collisionLayer); } void sub_080994B8(SmallIceBlockEntity* this) { u16 tileType; EnqueueSFX(SFX_ICE_BLOCK_SLIDE); SetTile(this->unk_6c, this->unk_70, super->collisionLayer); if ((super->collisionLayer == 2) && (GetTileType(this->unk_70, 1) == 0x405a)) { sub_08000152(0x310, this->unk_70, 1); } tileType = GetTileType(this->unk_70 + gUnk_080B4488[super->direction >> 3], super->collisionLayer); if (tileType == 0x79 || tileType == 0x77) { super->spriteOffsetY = -2; } } bool32 sub_0809953C(SmallIceBlockEntity* this) { u8 bVar1; u8 uVar2; u32 uVar3; u16 uVar4; uVar3 = sub_0800442E(super); if (uVar3 != 0) { return 0; } ProcessMovement2(super); sub_0800445C(super); if (super->actionDelay != 0) { super->speed += 0x10; if (--super->actionDelay == 0) { super->speed = 0x200; } } switch (super->direction >> 3) { case 0: if ((super->collisions & 0xe) == 0) { return 0; } if ((u32)(super->y.HALF.HI & 0xf) - 7 < 3) { super->y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8; return 1; } sub_0809969C(this); break; case 1: if ((super->collisions & 0xe000) == 0) { return FALSE; } if ((u32)(super->x.HALF.HI & 0xf) - 7 < 3) { super->x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8; return TRUE; } sub_0809969C(this); break; case 2: if ((super->collisions & 0xe0) == 0) { return FALSE; } if ((u32)(super->y.HALF.HI & 0xf) - 7 < 3) { super->y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8; return TRUE; } sub_0809969C(this); break; default: if ((super->collisions & 0xe00) != 0) { if ((u32)(super->x.HALF.HI & 0xf) - 7 < 3) { super->x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8; return TRUE; } sub_0809969C(this); } break; } return FALSE; } u32 sub_08099618(u32 param_1) { const u16* it; for (it = gUnk_08123750; *it != 0; it += 2) { if (*it == param_1) { return it[1]; } } return 0; } bool32 sub_0809963C(SmallIceBlockEntity* this) { u16* var; u16 x; u16 y; if (super->type2 != 0) { var = (u16*)GetCurrentRoomProperty(super->type2); if (CheckFlags(var[0])) { x = var[1] + gRoomControls.origin_x; y = var[2] + gRoomControls.origin_y; if (var[3] >= (u32)(super->x.HALF.HI - x) && var[4] >= (u32)(super->y.HALF.HI - y)) { return TRUE; } } } if (super->bitfield == 0x87) { return TRUE; } return FALSE; } void sub_0809969C(SmallIceBlockEntity* this) { CreateFx(super, 0xd, 0); DeleteThisEntity(); } void sub_080996AC(SmallIceBlockEntity* this) { if ((super->parent)->next == NULL) { DeleteThisEntity(); } if (super->action == 0) { super->action = 1; InitializeAnimation(super, 3); } if ((super->parent)->action < 3) { super->spriteSettings.draw = 1; if ((super->frame & 1) != 0) { super->frame = 0; super->frameDuration = (Random() & 0x78) + 0x78; } GetNextFrame(super); CopyPositionAndSpriteOffset(super->parent, super); super->y.HALF.HI += 1; super->spriteOffsetY -= 0x11; } else { super->spriteSettings.draw = 0; } } void (*const gUnk_08123734[])(SmallIceBlockEntity*) = { SmallIceBlock_Init, SmallIceBlock_Action1, SmallIceBlock_Action2, SmallIceBlock_Action3, SmallIceBlock_Action4, }; const u16 gUnk_08123748[] = { 256, 264, 271, 277, }; const u16 gUnk_08123750[] = { 0x405b, 1, 0x405c, 1, 0x405d, 1, 0x405e, 1, 0x7a, 2, 0x78, 2, 0, };