Files
tmc/src/object/lockedDoor.c
T

333 lines
8.9 KiB
C

/**
* @file lookedDoor.c
* @ingroup Objects
*
* @brief Looked Door object
*/
#include "asm.h"
#include "common.h"
#include "effects.h"
#include "entity.h"
#include "flags.h"
#include "functions.h"
#include "game.h"
#include "global.h"
#include "hitbox.h"
#include "sound.h"
void LockedDoor_Init(Entity*);
void LockedDoor_Action1(Entity*);
void LockedDoor_Action2(Entity*);
void LockedDoor_Action3(Entity*);
void LockedDoor_Action4(Entity*);
void LockedDoor_Action5(Entity*);
void LockedDoor_Action6(Entity*);
void LockedDoor_Action7(Entity*);
void LockedDoor_Action8(Entity*);
void sub_08083638(Entity*);
void sub_08083658(Entity*);
void sub_080836A0(Entity*);
void sub_080836DC(Entity*, u32, u32);
u32 sub_08083734(Entity*, u32);
u32 sub_080837B0(Entity*);
void sub_08083814(Entity*, u32);
void (*const LockedDoor_Actions[])(Entity*) = {
LockedDoor_Init, LockedDoor_Action1, LockedDoor_Action2, LockedDoor_Action3, LockedDoor_Action4,
LockedDoor_Action5, LockedDoor_Action6, LockedDoor_Action7, LockedDoor_Action8,
};
void LockedDoor(Entity* this) {
LockedDoor_Actions[this->action](this);
}
typedef struct PACKED {
s8 x;
s8 y;
} struct_0811F680;
const struct_0811F680 gUnk_0811F680[] = {
{ 0, -2 },
{ 2, 0 },
{ 0, 2 },
{ -2, 0 },
};
const struct_0811F680 gUnk_0811F688[] = {
{ 0, -21 },
{ 21, 0 },
{ 0, 21 },
{ -21, 0 },
};
const u16 gUnk_0811F690[] = {
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,
};
typedef struct {
struct_0811F680 unk_00;
struct_0811F680 unk_02;
} struct_0811F730;
const struct_0811F730 gUnk_0811F730[] = {
{ { 8, 8 }, { -8, 8 } },
{ { -8, 8 }, { -8, -8 } },
{ { 8, -8 }, { -8, -8 } },
{ { 8, 8 }, { 8, -8 } },
};
const u8 gLockedDoorInteractDirections[] = {
0xBE,
0x7D,
0xEB,
0xD7,
};
void LockedDoor_Init(Entity* this) {
if (this->cutsceneBeh.HWORD != 0xFFFF && CheckFlags(this->cutsceneBeh.HWORD)) {
DeleteThisEntity();
}
if (!sub_080837B0(this))
return;
this->type2 = (this->type >> 2) & 3;
this->frameIndex = this->type & 3;
this->speed = 0x300;
this->field_0x70.HALF.LO = this->x.HALF.HI;
this->field_0x70.HALF.HI = this->y.HALF.HI;
this->field_0x7c.BYTES.byte2 = this->type & 3;
this->hitbox = (Hitbox*)&gHitbox_2;
this->spritePriority.b0 = 5;
this->frame = this->type & 0xF;
this->field_0x76.HWORD = TILE(this->x.HALF.HI, this->y.HALF.HI);
this->field_0x74.HWORD = GetTileIndex(this->field_0x76.HWORD, this->collisionLayer);
switch (this->type2) {
case 0:
if (!CheckFlags(this->field_0x86.HWORD)) {
if (this->type & 0x10) {
this->action = 3;
} else {
sub_080836A0(this);
}
} else {
this->type &= ~0x10;
sub_08083638(this);
}
break;
case 1:
if (!CheckFlags(this->field_0x86.HWORD)) {
sub_08083638(this);
} else {
sub_080836A0(this);
}
break;
case 2:
if (!CheckFlags(this->field_0x86.HWORD)) {
this->frameIndex |= 4;
sub_080836DC(this, this->field_0x7c.BYTES.byte2, this->field_0x76.HWORD);
if (!AreaIsDungeon()) {
this->action = 5;
} else {
this->action = 8;
AddInteractableSmallKeyLock(this);
SetInteractableObjectCollision(this, 0, gLockedDoorInteractDirections[this->field_0x7c.BYTES.byte2], NULL);
}
} else {
DeleteThisEntity();
}
break;
default:
DeleteThisEntity();
break;
}
}
void LockedDoor_Action1(Entity* this) {
if (--this->timer == 0) {
this->action = 2;
this->timer = 7;
SetTile(this->field_0x74.HWORD, this->field_0x76.HWORD, this->collisionLayer);
EnqueueSFX(SFX_10B);
}
}
void LockedDoor_Action2(Entity* this) {
LinearMoveUpdate(this);
if (--this->timer == 0) {
if (this->type & 0x80) {
sub_08083638(this);
} else {
DeleteThisEntity();
}
}
}
void LockedDoor_Action3(Entity* this) {
if (sub_08083734(this, this->field_0x7c.BYTES.byte2)) {
this->action = 4;
sub_080836DC(this, this->field_0x7c.BYTES.byte2, this->field_0x76.HWORD);
}
}
void LockedDoor_Action4(Entity* this) {
LinearMoveUpdate(this);
if (!--this->timer) {
if (this->type & 0x10) {
this->type &= ~0x10;
sub_080836A0(this);
} else {
if (this->type & 0x80) {
sub_080836A0(this);
} else {
this->action = 5;
}
}
sub_08083814(this, this->field_0x7c.BYTES.byte2);
EnqueueSFX(SFX_10B);
}
}
void LockedDoor_Action5(Entity* this) {
}
void LockedDoor_Action6(Entity* this) {
if (this->type2 == 0) {
if (!CheckFlags(this->field_0x86.HWORD))
return;
} else {
if (CheckFlags(this->field_0x86.HWORD))
return;
}
sub_08083658(this);
}
void LockedDoor_Action7(Entity* this) {
if (this->type2 == 0) {
if (CheckFlags(this->field_0x86.HWORD))
return;
} else {
if (!CheckFlags(this->field_0x86.HWORD))
return;
}
this->action = 3;
}
void LockedDoor_Action8(Entity* this) {
if (this->interactType == 0 && !CheckFlags(this->field_0x86.HWORD))
return;
this->action = 1;
this->timer = 20;
sub_08083658(this);
SetFlag(this->field_0x86.HWORD);
ModDungeonKeys(-1);
}
void sub_08083638(Entity* this) {
this->action = 7;
this->spriteSettings.draw = 0;
this->x.HALF.HI = this->field_0x70.HALF.LO;
this->y.HALF.HI = this->field_0x70.HALF.HI;
}
void sub_08083658(Entity* this) {
const struct_0811F680* tmp;
this->action = 1;
this->timer = 20;
this->direction = this->field_0x7c.BYTES.byte2 << 3;
tmp = &gUnk_0811F680[this->field_0x7c.BYTES.byte2];
this->x.HALF.HI += tmp->x;
this->y.HALF.HI += tmp->y;
RequestPriorityDuration(this, 60);
SoundReq(SFX_10B);
}
void sub_080836A0(Entity* this) {
this->action = 6;
this->spriteSettings.draw = 1;
this->x.HALF.HI = this->field_0x70.HALF.LO;
this->y.HALF.HI = this->field_0x70.HALF.HI;
SetTile(0x4022, this->field_0x76.HWORD, this->collisionLayer);
}
void sub_080836DC(Entity* this, u32 unk_0, u32 unk_1) {
const struct_0811F680* tmp;
SetTile(0x4022, unk_1, this->collisionLayer);
this->timer = 7;
this->spriteSettings.draw = 1;
this->direction = (unk_0 << 3) ^ 0x10;
tmp = &gUnk_0811F688[unk_0];
if (this->type2 != 2) {
this->x.HALF.HI += tmp->x;
this->y.HALF.HI += tmp->y;
}
}
u32 sub_08083734(Entity* this, u32 unk0) {
switch (unk0) {
case 0:
if (this->field_0x70.HALF_U.HI + 0xd - gPlayerEntity.y.HALF.HI < 0)
return 1;
break;
case 1:
if (gPlayerEntity.x.HALF.HI - (this->field_0x70.HALF_U.LO - 0xb) < 0)
return 1;
break;
case 2:
if (gPlayerEntity.y.HALF.HI - (this->field_0x70.HALF_U.HI - 0x8) < 0)
return 1;
break;
case 3:
if (this->field_0x70.HALF_U.LO + 0xa - gPlayerEntity.x.HALF.HI < 0)
return 1;
break;
}
return 0;
}
u32 sub_080837B0(Entity* this) {
u32 tmp;
u32 tmp2 = gRoomControls.area;
if (tmp2 < 0x40) {
switch (tmp2) {
default:
tmp = 0xA;
break;
case 0x25:
tmp = 0x1e7;
break;
case 0x35:
tmp = 0x1c3;
break;
}
} else {
tmp = gUnk_0811F690[tmp2 - 0x40];
}
if (tmp2 == 0x68) {
ChangeObjPalette(this, 0);
} else {
if (tmp2 == 0x88) {
ChangeObjPalette(this, 1);
}
}
LoadFixedGFX(this, tmp);
}
void sub_08083814(Entity* this, u32 unk0) {
Entity* fx;
const struct_0811F730* tmp = &gUnk_0811F730[unk0];
fx = CreateFx(this, FX_DASH, 0x40);
if (fx) {
fx->x.HALF.HI += tmp->unk_00.x;
fx->y.HALF.HI += tmp->unk_00.y;
}
fx = CreateFx(this, FX_DASH, 0x40);
if (fx) {
fx->x.HALF.HI += tmp->unk_02.x;
fx->y.HALF.HI += tmp->unk_02.y;
}
}