/** * @file objectOnPillar.c * @ingroup Objects * * @brief Object on Pillar object */ #define NENT_DEPRECATED #include "global.h" #include "object.h" #include "functions.h" typedef struct { /*0x00*/ Entity base; /*0x68*/ u8 unk_68[8]; /*0x70*/ u16 tileIndex; /*0x72*/ u16 unk_72; /*0x74*/ u16 tilePosition; /*0x76*/ u16 unk_76; /*0x78*/ u8 unk_78[0x4]; /*0x7c*/ u8 unk_7c; /*0x7d*/ u8 unk_7d; /*0x7e*/ u8 unk_7e; /*0x7f*/ u8 unk_7f; /*0x80*/ u8 unk_80[0x4]; /*0x84*/ u16 hitFlag; /*0x86*/ u16 unk_86; } ObjectOnPillarEntity; extern bool32 sub_080896B0(void); // pushableStatue extern Hitbox gUnk_080FD1F4; extern s16 gUnk_080B4488[]; typedef struct { /*0x00*/ Entity base; /*0x68*/ u8 unk_68[10 + 0x14]; /*0x86*/ u16 hitFlag; } EntityWithHitFlag; typedef struct { u16 key; u16 value; } KeyValuePair; void sub_080970F4(ObjectOnPillarEntity*); void sub_080971E0(ObjectOnPillarEntity*); bool32 sub_08097194(ObjectOnPillarEntity*); bool32 sub_08097008(ObjectOnPillarEntity*); bool32 sub_08097144(ObjectOnPillarEntity*); void sub_08097098(ObjectOnPillarEntity*); u32 sub_08097074(u32); bool32 sub_08097348(u32); void ObjectOnPillar_Init(ObjectOnPillarEntity*); void ObjectOnPillar_Action1(ObjectOnPillarEntity*); void ObjectOnPillar_Action2(ObjectOnPillarEntity*); void ObjectOnPillar_Action3(ObjectOnPillarEntity*); void ObjectOnPillar_Action4(ObjectOnPillarEntity*); void ObjectOnPillar_SubAction0(ObjectOnPillarEntity*); void ObjectOnPillar_SubAction1(ObjectOnPillarEntity*); void ObjectOnPillar(ObjectOnPillarEntity* this) { static void (*const ObjectOnPillar_Actions[])(ObjectOnPillarEntity*) = { ObjectOnPillar_Init, ObjectOnPillar_Action1, ObjectOnPillar_Action2, ObjectOnPillar_Action3, ObjectOnPillar_Action4, }; ObjectOnPillar_Actions[super->action](this); } void ObjectOnPillar_Init(ObjectOnPillarEntity* this) { static const u8 gUnk_08123264[] = { 0, 2, 4, 3, 7, 5, 0, 0, }; if (CheckFlags(this->unk_86) == 0) { super->action = 1; super->speed = 0x80; super->updatePriority = 3; super->spriteSettings.draw = 1; super->spritePriority.b1 = 1; super->spriteSettings.shadow = 1; super->spriteOffsetY = 4; super->hitbox = (Hitbox*)&gUnk_080FD1F4; super->field_0x16 = 1; this->unk_72 = 0; super->collisionLayer = this->unk_7d >> 4; UpdateSpriteForCollisionLayer(super); sub_080970F4(this); super->frameIndex = gUnk_08123264[super->type]; } else { super->x.HALF.HI = (this->unk_7c | ((this->unk_7d & 0xf) << 8)) + gRoomControls.origin_x; super->y.HALF.HI = (this->unk_7e | ((this->unk_7f & 0xf) << 8)) + gRoomControls.origin_y; super->collisionLayer = this->unk_7f >> 4; sub_080971E0(this); } } void ObjectOnPillar_Action1(ObjectOnPillarEntity* this) { if (sub_08097194(this) == FALSE) { if (sub_08097008(this)) { super->action = 3; } else { sub_08078930(super); } } } void ObjectOnPillar_Action2(ObjectOnPillarEntity* this) { static void (*const ObjectOnPillar_SubActions[])(ObjectOnPillarEntity*) = { ObjectOnPillar_SubAction0, ObjectOnPillar_SubAction1, }; if (this->unk_76 != 0) { sub_08097144(this); } else { if (gPlayerState.heldObject == 0) { super->subAction = 6; } ObjectOnPillar_SubActions[super->subAction - 5](this); } } void ObjectOnPillar_SubAction0(ObjectOnPillarEntity* this) { static const s8 gUnk_08123274[] = { 0, 14, -14, 2, 0, -14, 14, 2 }; const s8* ptr; if (this->unk_72 == 0) { this->unk_72 = 1; ptr = &gUnk_08123274[gPlayerEntity.animationState]; PositionRelative(super, &gPlayerEntity, ptr[0] << 0x10, ptr[1] << 0x10); } sub_08097008(this); if (sub_080896B0()) { gPlayerState.queued_action = 0x10; gPlayerState.field_0x38 = 0x20; gPlayerState.flags |= PL_BUSY; gPlayerEntity.x.HALF.LO = 0; gPlayerEntity.y.HALF.LO = 0; super->direction = ((gPlayerEntity.animationState ^ 4) << 2); sub_08097098(this); } } void ObjectOnPillar_SubAction1(ObjectOnPillarEntity* this) { super->action = 1; this->unk_72 = 0; } void ObjectOnPillar_Action3(ObjectOnPillarEntity* this) { if (sub_08097144(this)) { super->action = 1; } } void ObjectOnPillar_Action4(ObjectOnPillarEntity* this) { } bool32 sub_08097008(ObjectOnPillarEntity* this) { Entity* effect; u32 tileType = GetTileType(this->tilePosition, super->collisionLayer); if (tileType != 0x4036) { switch (sub_08097074(tileType)) { case 1: super->direction = (((tileType - 0x37) & 3) << 3); sub_08097098(this); return TRUE; case 2: this->tileIndex = tileType; break; default: effect = CreateObject(SPECIAL_FX, 4, 0); if (effect != NULL) { CopyPosition(super, effect); } DeleteEntity(super); break; } } return FALSE; } u32 sub_08097074(u32 tileType) { static const KeyValuePair gUnk_0812327C[] = { { 0x4037, 1 }, { 0x4038, 1 }, { 0x4039, 1 }, { 0x403a, 1 }, { 0x7a, 2 }, { 0x78, 2 }, { 0, 0 }, }; const KeyValuePair* entry = gUnk_0812327C; for (; entry->key != 0; entry++) { if (entry->key == tileType) { return entry->value; } } return 0; } void sub_08097098(ObjectOnPillarEntity* this) { u16 tileType; this->unk_76 = 0x20; EnqueueSFX(SFX_10F); SetTile(this->tileIndex, this->tilePosition, super->collisionLayer); tileType = GetTileType(gUnk_080B4488[super->direction >> 3] + this->tilePosition, super->collisionLayer); if ((tileType == 0x79) || tileType == 0x77) { super->spriteOffsetY = 2; } } void sub_080970F4(ObjectOnPillarEntity* this) { this->tilePosition = COORD_TO_TILE(super); this->tileIndex = GetTileIndex(this->tilePosition, super->collisionLayer); SetTile(0x4036, this->tilePosition, super->collisionLayer); } bool32 sub_08097144(ObjectOnPillarEntity* this) { LinearMoveUpdate(super); sub_0800445C(super); if (sub_080002B8(super) == 0x19) { super->spriteOffsetY = 2; } if ((--this->unk_76 == 0) && sub_08097194(this) == FALSE) { super->spriteOffsetY = 4; sub_080970F4(this); return TRUE; } else { return FALSE; } } bool32 sub_08097194(ObjectOnPillarEntity* this) { if (sub_0800442E(super)) { return TRUE; } else { u32 tileType = GetTileTypeByEntity(super); if (tileType == 0x71 || tileType == 0x72 || (tileType == 0x4020)) { SetFlag(this->unk_86); EnqueueSFX(SFX_10B); sub_080971E0(this); return TRUE; } else { return FALSE; } } return FALSE; } void sub_080971E0(ObjectOnPillarEntity* this) { EntityWithHitFlag* entity; u32 tilePosition; entity = (EntityWithHitFlag*)CreateObject(SPECIAL_FX, 0x11, 0x40); if (entity != NULL) { PositionRelative(super, &entity->base, -0x80000, 0x20000); } entity = (EntityWithHitFlag*)CreateObject(SPECIAL_FX, 0x11, 0x40); if (entity != NULL) { PositionRelative(super, &entity->base, 0x80000, 0x20000); } switch (super->type) { case 0: default: super->action = 4; super->frameIndex = 1; super->spritePriority.b0 = 7; SetTile(0, COORD_TO_TILE(super), super->collisionLayer); DeleteThisEntity(); break; case 1: tilePosition = COORD_TO_TILE(super); if (sub_08097348(tilePosition) == 0) { SetTileType(0x73, tilePosition, super->collisionLayer); } DeleteThisEntity(); break; case 2: entity = (EntityWithHitFlag*)CreateObject(HITTABLE_LEVER, 0, 0); if (entity != NULL) { (entity->base).x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8; (entity->base).y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8; (entity->base).collisionLayer = super->collisionLayer; entity->hitFlag = this->hitFlag; } DeleteThisEntity(); break; case 3: entity = (EntityWithHitFlag*)CreateObject(HITTABLE_LEVER, 1, 0); if (entity != NULL) { (entity->base).x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8; (entity->base).y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8; (entity->base).collisionLayer = super->collisionLayer; entity->hitFlag = this->hitFlag; } DeleteThisEntity(); break; } } bool32 sub_08097348(u32 tilePosition) { u32 index; TileEntity* tileEntity = gSmallChests; for (index = 0; index < 8; index++, tileEntity++) { if (tileEntity->_4 == tilePosition) { return CheckLocalFlag(tileEntity->_1); } } return FALSE; }