tmc/src/enemy/mazaalBracelet.c

1398 lines
38 KiB
C

/**
* @file mazaalBracelet.c
* @ingroup Enemies
*
* @brief Mazaal Bracelet enemy
*/
#include "enemy.h"
#include "object.h"
#include "functions.h"
#include "hitbox.h"
void sub_0803B538(Entity*);
u32 sub_0803B4E4(Entity*);
void sub_0803B55C(Entity*);
void sub_0803B4D4(Entity*);
void sub_0803B59C(Entity*);
void sub_0803B5C0(Entity*);
u32 sub_0803B610(Entity*);
void sub_0803B63C(Entity*);
void sub_0803B6A4(Entity*);
u32 sub_0803B6F4(Entity*);
void sub_0803B8E8(Entity*, u32);
u32 sub_0803B870(Entity*);
void sub_0803B824(Entity*);
void sub_0803B804(Entity*);
void sub_0803B798(void);
void sub_0803BA8C(Entity*, u32);
void sub_0803B724(Entity*);
extern void SoundReqClipped(Entity*, u32);
void MazaalBracelet_OnTick(Entity*);
void MazaalBracelet_OnCollision(Entity*);
void MazaalBracelet_OnGrabbed(Entity*);
void sub_0803A254(Entity*);
void sub_0803B8F8(Entity*);
void sub_0803A274(Entity*);
void sub_0803A364(Entity*);
void sub_0803A548(Entity*);
void sub_0803A58C(Entity*);
void sub_0803A5D0(Entity*);
void sub_0803A60C(Entity*);
void sub_0803A660(Entity*);
void sub_0803A6E8(Entity*);
void sub_0803A720(Entity*);
void sub_0803A740(Entity*);
void sub_0803A780(Entity*);
void sub_0803A7AC(Entity*);
void sub_0803A7CC(Entity*);
void sub_0803A814(Entity*);
void sub_0803A86C(Entity*);
void sub_0803A8B8(Entity*);
void sub_0803A90C(Entity*);
void sub_0803A978(Entity*);
void sub_0803AA00(Entity*);
void sub_0803AA98(Entity*);
void sub_0803AB10(Entity*);
void sub_0803AB5C(Entity*);
void sub_0803ABB4(Entity*);
void sub_0803AC1C(Entity*);
void sub_0803AC60(Entity*);
void sub_0803ACC0(Entity*);
void sub_0803ADAC(Entity*);
void sub_0803ADF4(Entity*);
void sub_0803AE48(Entity*);
void sub_0803AEC4(Entity*);
void sub_0803AF18(Entity*);
void sub_0803AF50(Entity*);
void sub_0803AF7C(Entity*);
void sub_0803AF9C(Entity*);
void sub_0803AFC8(Entity*);
void sub_0803AFE0(Entity*);
void sub_0803B01C(Entity*);
void sub_0803B04C(Entity*);
void sub_0803B074(Entity*);
void sub_0803B0D4(Entity*);
void sub_0803B100(Entity*);
void sub_0803B144(Entity*);
void sub_0803B17C(Entity*);
void sub_0803B1B8(Entity*);
void sub_0803B2D0(Entity*);
void sub_0803B30C(Entity*);
void sub_0803B338(Entity*);
void sub_0803B35C(Entity*);
void sub_0803B398(Entity*);
void sub_0803B3F4(Entity*);
void sub_0803B480(Entity*);
void sub_0803B910(Entity*);
void sub_0803B978(Entity*);
void sub_0803BA6C(Entity*);
void sub_0803BA80(Entity*);
void (*const MazaalBracelet_Functions[])(Entity*) = { MazaalBracelet_OnTick, MazaalBracelet_OnCollision,
GenericKnockback, GenericDeath,
GenericConfused, MazaalBracelet_OnGrabbed };
void (*const gUnk_080CFC2C[])(Entity*) = { sub_0803A254, sub_0803A254, sub_0803B8F8, sub_0803B8F8 };
void (*const gUnk_080CFC3C[])(Entity*) = {
sub_0803A274, sub_0803A364, sub_0803A548, sub_0803A58C, sub_0803A5D0, sub_0803A60C, sub_0803A660, sub_0803A6E8,
sub_0803A720, sub_0803A740, sub_0803A780, sub_0803A7AC, sub_0803A7CC, sub_0803A814, sub_0803A86C, sub_0803A8B8,
sub_0803A90C, sub_0803A978, sub_0803AA00, sub_0803AA98, sub_0803AB10, sub_0803AB5C, sub_0803ABB4, sub_0803AC1C,
sub_0803AC60, sub_0803ACC0, sub_0803ADAC, sub_0803ADF4, sub_0803AE48, sub_0803AEC4, sub_0803AF18, sub_0803AF50,
sub_0803AF7C, sub_0803AF9C, sub_0803AFC8, sub_0803AFE0, sub_0803B01C, sub_0803B04C, sub_0803B074, sub_0803B0D4,
sub_0803B100, sub_0803B144, sub_0803B17C, sub_0803B1B8, sub_0803B2D0, sub_0803B30C, sub_0803B338, sub_0803B35C,
sub_0803B398, sub_0803B3F4, sub_0803B480
};
const s8 gUnk_080CFD08[] = { 10, -10 };
const s8 gUnk_080CFD0A[] = { 0x30, -0x30 };
const u8 gUnk_080CFD0C[] = { 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0c };
const s8 gUnk_080CFD19[] = { 0x10, -0x10 };
const s8 gUnk_080CFD1B[] = { -0x38, 0x38 };
const s8 gUnk_080CFD1D[] = { -0x11, 0x11 };
void (*const gUnk_080CFD20[])(Entity*) = { sub_0803B910, sub_0803B978, sub_0803BA6C, sub_0803BA80 };
const u16 gUnk_080CFD30[] = { 0xdb, 0xdd, 0xdf, 0xe1, 0xdf, 0xdd, 0xdb, 0xe3, 0xe5, 0xe3 };
const u16 gUnk_080CFD44[] = { 0xdc, 0xde, 0xe0, 0xe2, 0xe0, 0xde, 0xdc, 0xe4, 0xe6, 0xe4 };
const u16 gUnk_080CFD58[] = { 0xe5, 0xe6 };
const u16 gUnk_080CFD5C[] = { 0xe7, 0xe8 };
extern s8 gUnk_080CED6C[8];
void MazaalBracelet(Entity* this) {
MazaalBracelet_Functions[GetNextFunction(this)](this);
}
void MazaalBracelet_OnTick(Entity* this) {
gUnk_080CFC2C[this->type](this);
}
void MazaalBracelet_OnCollision(Entity* this) {
Entity* ent;
if (this->type < 2) {
if (this->action != 0x2b) {
if ((0 < this->iframes) && ((this->contactFlags == 0x95 || (this->contactFlags == 0x8e)))) {
this->action = 0x28;
COLLISION_OFF(this);
ent = this->parent;
ent->field_0x7c.BYTES.byte1 = ent->field_0x7c.BYTES.byte1 | (this->type == 0 ? 1 : 2);
ent->field_0x80.HALF.LO = (this->type == 0 ? 1 : 2) | ent->field_0x80.HALF.LO;
ent = this->child;
ent->iframes = this->iframes;
ent = (*(Entity**)&this->field_0x74);
ent->iframes = this->iframes;
SoundReq(SFX_BOSS_HIT);
}
} else {
ent = this->child;
ent->iframes = this->iframes;
ent = (*(Entity**)&this->field_0x74);
ent->iframes = this->iframes;
InitializeAnimation(this, 0x18);
InitAnimationForceUpdate(this->child, 9);
SoundReq(SFX_BOSS_HIT);
}
}
EnemyFunctionHandlerAfterCollision(this, MazaalBracelet_Functions);
}
void MazaalBracelet_OnGrabbed(Entity* this) {
}
void sub_0803A254(Entity* this) {
gUnk_080CFC3C[this->action](this);
sub_0803B538(this);
}
void sub_0803A274(Entity* this) {
Entity* pEVar1;
if (gEntCount < 0x45) {
if (this->type == 0) {
pEVar1 = CreateEnemy(MAZAAL_HAND, 0);
pEVar1->parent = this;
this->child = pEVar1;
pEVar1 = CreateEnemy(MAZAAL_BRACELET, 2);
pEVar1->parent = this;
*(Entity**)&this->field_0x74 = pEVar1;
pEVar1 = CreateObject(MAZAAL_OBJECT, 1, 0);
pEVar1->parent = this;
pEVar1->child = this->child;
PositionRelative(this->parent, this, Q_16_16(16.0), Q_16_16(32.0));
} else {
pEVar1 = CreateEnemy(MAZAAL_HAND, 1);
pEVar1->parent = this;
this->child = pEVar1;
pEVar1 = CreateEnemy(MAZAAL_BRACELET, 3);
pEVar1->parent = this;
*(Entity**)&this->field_0x74 = pEVar1;
pEVar1 = CreateObject(MAZAAL_OBJECT, 2, 0);
pEVar1->parent = this;
pEVar1->child = this->child;
this->spriteSettings.flipX = 1;
PositionRelative(this->parent, this, Q_16_16(-16.0), Q_16_16(32.0));
}
if (gRoomTransition.field_0x38 != 0) {
this->action = 3;
COLLISION_ON(this);
this->spriteSettings.draw = 1;
this->child->spriteSettings.draw = 1;
InitializeAnimation(this, 0x10);
} else {
this->action = 1;
InitializeAnimation(this, 4);
}
}
}
void sub_0803A364(Entity* this) {
u8 uVar1;
Entity* pEVar3;
u32 index;
s8* ptr;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
switch (this->subAction & 0x7f) {
case 0:
case 2:
break;
case 1:
this->subAction = 2;
pEVar3 = this->child;
pEVar3->spriteSettings.draw = 1;
pEVar3->spriteRendering.alphaBlend = 1;
break;
case 3:
this->subAction = 4;
this->spriteSettings.draw = 1;
this->child->spriteRendering.alphaBlend = 0;
break;
case 4:
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->subAction = 5;
}
break;
case 5:
if (sub_0803B4E4(this) == 0) {
LinearMoveUpdate(this);
return;
}
this->type2 = 0;
uVar1 = 6;
this->subAction = uVar1;
this->timer = 30;
break;
case 6:
this->timer--;
if (this->timer == 0) {
this->subAction = 7;
InitializeAnimation(this, 5);
}
break;
case 7:
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->subAction = 8;
this->spriteSettings.draw = 0;
InitAnimationForceUpdate(this->child, 8);
SoundReq(SFX_16E);
}
break;
case 8:
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) == 0) {
return;
}
uVar1 = 9;
this->subAction = uVar1;
this->timer = 30;
break;
case 9:
this->timer--;
if (this->timer == 0) {
this->subAction = 10;
InitAnimationForceUpdate(this->child, 6);
}
break;
case 10:
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) != 0) {
this->subAction = 0xb;
this->spriteSettings.draw = 1;
InitializeAnimation(this, 4);
}
break;
case 0xb:
GetNextFrame(this);
if ((this->frame & ANIM_DONE) == 0) {
return;
}
if (this->type2 != 0) {
uVar1 = 0xc;
this->subAction = uVar1;
this->timer = 30;
} else {
this->type2 = 1;
this->subAction = 6;
this->timer = 10;
}
break;
default:
this->timer--;
if (this->timer == 0) {
COLLISION_ON(this);
sub_0803B4D4(this);
}
break;
}
}
void sub_0803A548(Entity* this) {
u32 index;
s8* ptr;
sub_0803B5C0(this);
UpdateAnimationSingleFrame(this);
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B4E4(this) == 0) {
LinearMoveUpdate(this);
}
}
void sub_0803A58C(Entity* this) {
u32 index;
s8* ptr;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B4E4(this) != 0) {
sub_0803B59C(this);
} else {
LinearMoveUpdate(this);
}
}
void sub_0803A5D0(Entity* this) {
u32 index;
s8* ptr;
this->action = 5;
COLLISION_OFF(this);
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
InitializeAnimation(this, 5);
}
void sub_0803A60C(Entity* this) {
u32 index;
s8* ptr;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->action = 6;
this->spriteSettings.draw = 0;
InitAnimationForceUpdate(this->child, 8);
}
}
void sub_0803A660(Entity* this) {
u32 uVar2;
u8* pbVar3;
s8* ptr;
u32 index;
pbVar3 = &this->child->frame;
if ((*pbVar3 & 0x80) != 0) {
if (this->z.HALF.HI > -0x50) {
this->z.HALF.HI = this->z.HALF.HI - 2;
} else {
this->action = 7;
this->timer = 0;
uVar2 = GetFacingDirection(this, &gPlayerEntity);
this->direction = (u8)uVar2;
this->speed = 0x280;
return;
}
} else {
sub_0803B55C(this);
if ((*pbVar3 & 0x80) != 0) {
SoundReq(SFX_157);
}
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
}
}
void sub_0803A6E8(Entity* this) {
s32 y;
if (sub_0803B610(this)) {
this->action = 8;
this->timer = 10;
} else {
sub_0803B63C(this);
LinearMoveUpdate(this);
y = this->parent->y.HALF.HI + 8;
if (y > this->y.HALF.HI) {
this->y.HALF.HI = y;
}
}
}
void sub_0803A720(Entity* this) {
if (--this->timer == 0) {
this->action = 9;
sub_0803B8E8(this, 0x16);
}
}
void sub_0803A740(Entity* this) {
u16 height;
height = this->z.HALF.HI + 4;
this->z.HALF.HI += 4;
if (-1 < height * 0x10000) {
this->z.HALF.HI = 0;
this->action = 10;
this->timer = 10;
this->parent->field_0x7c.BYTES.byte1 |= 0x40;
sub_0803B8E8(this, 0x13);
InitScreenShake(10, 0);
SoundReq(SFX_158);
}
}
void sub_0803A780(Entity* this) {
if (--this->timer == 0) {
if (--this->field_0x7c.BYTES.byte0) {
this->action = 6;
} else {
this->action = 0xb;
}
}
}
void sub_0803A7AC(Entity* this) {
if (this->z.HALF.HI > -6) {
this->z.HALF.HI--;
} else {
this->action = 0xc;
}
}
void sub_0803A7CC(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B4E4(this)) {
this->action = 0xd;
InitAnimationForceUpdate(this->child, 6);
} else {
LinearMoveUpdate(this);
}
}
void sub_0803A814(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) != 0) {
this->action = 0xe;
this->spriteSettings.draw = 1;
InitializeAnimation(this, 4);
}
}
void sub_0803A86C(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
COLLISION_ON(this);
sub_0803B59C(this);
}
}
void sub_0803A8B8(Entity* this) {
s8* ptr;
u32 index;
this->action = 0x10;
this->timer = 30;
this->direction = 0;
this->speed = 0x80;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
InitializeAnimation(this, 6);
InitAnimationForceUpdate(this->child, 1);
SoundReq(SFX_153);
}
void sub_0803A90C(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
sub_0803B55C(this);
LinearMoveUpdate(this);
this->timer--;
if (this->timer == 0) {
this->action = 0x11;
this->direction = this->type * 0x10 + 8;
this->speed = 0x200;
InitializeAnimation(this, 7);
InitAnimationForceUpdate(this->child, 2);
}
}
void sub_0803A978(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
sub_0803B55C(this);
if ((++this->timer & 3) == 0) {
sub_08004596(this, 0x10);
}
LinearMoveUpdate(this);
if (this->direction == 0x10) {
this->action = 0x12;
this->timer = 3;
COLLISION_OFF(this);
*(u8*)(*(int*)&this->field_0x74 + 0x10) &= ~0x80;
InitializeAnimation(this, 8);
InitAnimationForceUpdate(this->child, 3);
}
}
void sub_0803AA00(Entity* this) {
u32 direction;
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B870(this) == 0) {
direction = (this->type ^ 1) * 0x10 + 8;
if ((++this->timer & 3) == 0) {
sub_08004596(this, direction);
}
LinearMoveUpdate(this);
if ((this->direction == direction) || (this->y.HALF.HI >= gPlayerEntity.y.HALF.HI)) {
this->action = 0x13;
this->spriteSettings.draw = 0;
this->direction = direction;
this->field_0x80.HWORD = gPlayerEntity.x.HALF.HI;
InitAnimationForceUpdate(this->child, 4);
}
}
}
void sub_0803AA98(Entity* this) {
Entity* temp;
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B870(this) == 0) {
LinearMoveUpdate(this);
if (sub_0803B6F4(this) != 0) {
this->action = 0x14;
this->speed = 0x40;
InitializeAnimation(this, 10);
temp = (*(Entity**)&this->field_0x74);
temp->flags |= ENT_COLLIDE;
temp = this->child;
temp->hitType = 0x13;
InitAnimationForceUpdate(temp, 5);
SoundReq(SFX_16E);
}
}
}
void sub_0803AB10(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
LinearMoveUpdate(this);
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) != 0) {
this->action = 0x15;
this->timer = 15;
}
}
void sub_0803AB5C(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (--this->timer == 0) {
this->action = 0x16;
this->spriteSettings.draw = 1;
InitializeAnimation(this, 0xb);
InitAnimationForceUpdate(this->child, 6);
}
}
void sub_0803ABB4(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) != 0) {
this->action = 0x17;
COLLISION_ON(this);
this->speed = 0x180;
InitializeAnimation(this, 0x10);
InitAnimationForceUpdate(this->child, 0);
}
}
void sub_0803AC1C(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B4E4(this)) {
sub_0803B59C(this);
} else {
LinearMoveUpdate(this);
}
}
void sub_0803AC60(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
if (!this->timer) {
if (sub_0803B4E4(this) != 0) {
this->action = 0x19;
this->subAction = 0;
this->timer = 30;
} else {
LinearMoveUpdate(this);
}
} else {
this->timer--;
}
sub_0803B824(this);
}
void sub_0803ACC0(Entity* this) {
u16 uVar2;
switch (this->subAction) {
default:
if (--this->timer == 0) {
this->subAction = 1;
}
break;
case 1:
if (--this->z.HALF.HI * 0x10000 >> 0x10 < -0x20) {
this->subAction = 2;
}
break;
case 2:
uVar2 = this->z.HALF.HI += 4;
if (-1 < (uVar2 * 0x10000)) {
this->z.HALF.HI = 0;
this->timer = 12;
this->subAction = 3;
InitScreenShake(8, 0);
SoundReq(SFX_158);
sub_0803B804(this);
}
break;
case 3:
if (--this->timer == 0) {
this->subAction = 4;
}
break;
case 4:
uVar2 = this->z.HALF.HI -= 2;
if (uVar2 * 0x10000 >> 0x10 < -0x28) {
this->subAction = 5;
}
break;
case 5:
uVar2 = this->z.HALF.HI += 4;
if (-1 < (uVar2 * 0x10000)) {
this->z.HALF.HI = 0;
this->action = 0x1a;
this->timer = 60;
InitScreenShake(30, 0);
SoundReq(SFX_158);
sub_0803B804(this);
return;
}
break;
}
sub_0803B824(this);
}
void sub_0803ADAC(Entity* this) {
if (--this->timer == 0) {
this->action = 0x16;
this->spriteSettings.draw = 1;
(*(Entity**)&this->field_0x74)->flags |= ENT_COLLIDE;
InitializeAnimation(this, 0xb);
InitAnimationForceUpdate(this->child, 6);
sub_0803B798();
} else {
sub_0803B824(this);
}
}
void sub_0803ADF4(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
UpdateAnimationSingleFrame(this);
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->action = 0x1c;
this->timer = 30;
this->spriteSettings.draw = 0;
}
}
void sub_0803AE48(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
UpdateAnimationSingleFrame(this);
if (((this->timer == 0) || (--this->timer == 0)) && ((this->parent->field_0x7c.BYTES.byte1 & 3) != 0)) {
this->action = 0x1d;
this->spriteSettings.draw = 1;
InitializeAnimation(this, 4);
} else {
if (sub_0803B4E4(this) == 0) {
LinearMoveUpdate(this);
}
}
}
void sub_0803AEC4(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
UpdateAnimationSingleFrame(this);
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
COLLISION_ON(this);
sub_0803B59C(this);
}
}
void sub_0803AF18(Entity* this) {
this->action = 0x1f;
COLLISION_OFF(this);
InitializeAnimation(this, 5);
this->z.HALF.HI = gUnk_080CED6C[(this->parent->subtimer >> 4) & 7] + 4;
}
void sub_0803AF50(Entity* this) {
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->action = 0x20;
this->spriteSettings.draw = 0;
InitAnimationForceUpdate(this->child, 8);
}
}
void sub_0803AF7C(Entity* this) {
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) != 0) {
this->action = 0x21;
this->timer = 15;
}
}
void sub_0803AF9C(Entity* this) {
if (this->timer != 0) {
this->timer--;
} else {
if (-0x20 < this->z.HALF.HI) {
this->z.HALF.HI -= 2;
} else {
this->action = 0x22;
this->timer = 10;
}
}
}
void sub_0803AFC8(Entity* this) {
if (--this->timer == 0) {
this->action = 0x23;
}
}
void sub_0803AFE0(Entity* this) {
if (this->z.HALF.HI < 0) {
this->z.HALF.HI += 4;
} else {
this->action = 0x24;
this->timer = 240;
*(u8*)&this->cutsceneBeh = 3;
this->z.HALF.HI = 0;
InitScreenShake(160, 0);
SoundReq(SFX_158);
}
}
void sub_0803B01C(Entity* this) {
if (--this->timer == 0) {
this->action = 0x25;
} else {
if ((this->timer > 70) && ((this->timer & 0xF) == 0)) {
sub_0803B724(this);
}
}
}
void sub_0803B04C(Entity* this) {
if (this->z.HALF.HI > -6) {
this->z.HALF.HI--;
} else {
this->action = 0x26;
InitAnimationForceUpdate(this->child, 6);
}
}
void sub_0803B074(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
sub_0803B55C(this);
if ((this->child->frame & ANIM_DONE) != 0) {
this->action = 0x27;
this->spriteSettings.draw = 1;
InitializeAnimation(this, 4);
InitAnimationForceUpdate(this->child, 0);
}
}
void sub_0803B0D4(Entity* this) {
UpdateAnimationSingleFrame(this);
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
COLLISION_ON(this);
sub_0803B59C(this);
}
}
void sub_0803B100(Entity* this) {
Entity* temp;
this->action = 0x29;
this->zVelocity = Q_16_16(1.25);
if (this->type == 0) {
this->hitbox = (Hitbox*)&gUnk_080FD364;
} else {
this->hitbox = (Hitbox*)&gUnk_080FD374;
}
temp = *(Entity**)&this->field_0x74;
temp->action = 3;
temp->field_0x74.HALF.LO = 0x20;
InitAnimationForceUpdate(this->child, 9);
SoundReq(SFX_14F);
}
void sub_0803B144(Entity* this) {
UpdateAnimationSingleFrame(this->child);
if (GravityUpdate(this, Q_8_8(32.0)) == 0) {
this->action = 0x2a;
InitializeAnimation(this, 0x16);
sub_0803B8E8(this, 0x14);
InitScreenShake(8, 0);
}
}
void sub_0803B17C(Entity* this) {
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->action = 0x2b;
COLLISION_ON(this);
this->hitType = 0x18;
this->health = 0xff;
this->field_0x7c.HALF.HI = 600;
}
}
void sub_0803B1B8(Entity* this) {
Entity* temp;
u16 val;
if ((this->frame & ANIM_DONE) == 0) {
GetNextFrame(this);
UpdateAnimationSingleFrame(this->child);
}
if (this->health < 0xf5) {
this->action = 0x32;
this->field_0x7c.HALF.HI = 0x5dc;
this->spriteSettings.draw = 0;
this->hitType = 0x14;
temp = CreateFx(this, FX_GIANT_EXPLOSION4, 0);
if (temp != (Entity*)0x0) {
temp->x.HALF.HI += this->hitbox->offset_x;
temp->y.HALF.HI += this->hitbox->offset_y;
temp->spritePriority.b0 = 3;
}
temp = CreateObject(GROUND_ITEM, 0x5e, 0);
if (temp != (Entity*)0x0) {
temp->timer = 0;
temp->direction = 0x90;
PositionRelative(this, temp, Q_16_16(this->hitbox->offset_x), Q_16_16(this->hitbox->offset_y));
}
temp = *(Entity**)&this->field_0x74;
temp->field_0x74.HALF.LO = 0x40;
temp = this->parent;
temp->field_0x80.HALF.LO |= (this->type == 0) ? 4 : 8;
if ((temp->field_0x80.HALF.LO & 0xc) == 0xc) {
temp->action = 0xb;
temp->timer = 120;
temp->zVelocity = 0;
(*(Entity**)&temp->field_0x74)->field_0x7c.HALF_U.HI = 0x708;
(*(Entity**)&temp->field_0x78)->field_0x7c.HALF_U.HI = 0x708;
}
} else {
if (--this->field_0x7c.HALF.HI == 0) {
sub_0803B6A4(this);
}
}
}
void sub_0803B2D0(Entity* this) {
Entity* entity;
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->action = 0x2d;
this->spriteSettings.draw = 0;
entity = *(Entity**)&this->field_0x74;
entity->action = 2;
entity->field_0x74.HALF.LO = 0;
entity->field_0x78.HWORD = 0;
InitializeAnimation(entity, 3);
}
}
void sub_0803B30C(Entity* this) {
Entity* entity;
entity = *(Entity**)&this->field_0x74;
if ((entity->frame & ANIM_DONE) != 0) {
this->action = 0x2e;
sub_0803B8E8(this, 0x13);
InitializeAnimation(entity, 0);
}
}
void sub_0803B338(Entity* this) {
if (this->z.HALF.HI > -10) {
this->z.HALF.HI--;
} else {
this->action = 0x2f;
this->timer = 15;
}
}
void sub_0803B35C(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (--this->timer == 0) {
this->action = 0x30;
}
}
void sub_0803B398(Entity* this) {
s8* ptr;
u32 index;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
if (sub_0803B4E4(this) != 0) {
this->action = 0x31;
this->spriteSettings.draw = 1;
InitializeAnimation(this, 4);
InitAnimationForceUpdate(this->child, 0);
} else {
LinearMoveUpdate(this);
}
}
void sub_0803B3F4(Entity* this) {
u8 value;
s8* ptr;
u32 index;
Entity* temp;
ptr = gUnk_080CED6C;
index = ((this->parent->subtimer >> 4) + 3);
this->z.HALF.HI = ptr[(index + (u32)this->type * 2) & 7] + 4;
GetNextFrame(this);
if ((this->frame & ANIM_DONE) != 0) {
this->hitType = 0x17;
if (this->type == 0) {
this->hitbox = (Hitbox*)&gUnk_080FD35C;
} else {
this->hitbox = (Hitbox*)&gUnk_080FD36C;
}
temp = this->parent;
value = (this->type == 0) ? 1 : 2;
temp->field_0x80.HALF.LO &= ~(((this->type == 0) ? 0x10 : 0x20) | value);
sub_0803B59C(this);
}
}
void sub_0803B480(Entity* this) {
Entity* target;
if (((this->field_0x7c.HALF.HI & 0x1f) == 0) && (target = CreateObject(SMOKE, 1, 0), target != (Entity*)0x0)) {
PositionRelative(this, target, Q_16_16(gUnk_080CFD08[this->type]), 0);
}
if (--this->field_0x7c.HALF.HI == 0) {
sub_0803B6A4(this);
}
}
void sub_0803B4D4(Entity* this) {
this->action = 3;
InitializeAnimation(this, 0x10);
}
u32 sub_0803B4E4(Entity* this) {
u32 xoff;
u32 yoff;
xoff = this->parent->x.HALF.HI + gUnk_080CFD0A[this->type];
yoff = this->parent->y.HALF.HI + 0x10;
if (EntityWithinDistance(this, xoff, yoff, 2)) {
this->x.HALF.HI = xoff;
this->y.HALF.HI = yoff;
return 1;
} else {
this->direction = CalculateDirectionTo(this->x.HALF.HI, this->y.HALF.HI, xoff, yoff);
return 0;
}
}
void sub_0803B538(Entity* this) {
PositionRelative(this, this->child, 0, Q_16_16(-1.0));
PositionRelative(this, *(Entity**)&this->field_0x74, 0, Q_16_16(-2.0));
}
void sub_0803B55C(Entity* this) {
Entity* entity;
Entity* pEVar1;
pEVar1 = *(Entity**)&this->field_0x74;
entity = this->child;
UpdateAnimationSingleFrame(entity);
if ((entity->frame & 0x10) != 0) {
if (pEVar1->animIndex != 1) {
InitializeAnimation(pEVar1, 1);
}
} else {
if (pEVar1->animIndex != 0) {
InitializeAnimation(pEVar1, 0);
}
}
}
void sub_0803B59C(Entity* this) {
this->action = 2;
this->parent->field_0x7c.BYTES.byte1 |= (this->type == 0) ? 1 : 2;
}
void sub_0803B5C0(Entity* this) {
u32 direction;
u32 temp;
direction = GetFacingDirection(this, &gPlayerEntity);
if (direction < 10) {
direction = 10;
}
if (direction > 0x16) {
direction = 0x16;
}
if (this->type == 0) {
temp = gUnk_080CFD0C[direction - 10];
} else {
temp = gUnk_080CFD0C[0x16 - direction];
}
if (this->frame != temp) {
InitializeAnimation(this, temp);
}
}
u32 sub_0803B610(Entity* this) {
return EntityWithinDistance(this, gPlayerEntity.x.HALF.HI + gUnk_080CFD19[this->type],
gPlayerEntity.y.HALF.HI - 0xc, 8);
}
// sub_0803B698 was the tail of this function
void sub_0803B63C(Entity* this) {
int y;
int x;
x = gPlayerEntity.x.HALF.HI;
x += gUnk_080CFD19[this->type];
y = gPlayerEntity.y.HALF.HI - 0xc;
if (this->timer++ > 180) {
this->direction = CalculateDirectionTo(this->x.HALF.HI, this->y.HALF.HI, x, y);
} else {
sub_08004596(this, CalculateDirectionTo(this->x.HALF.HI, this->y.HALF.HI, x, y));
}
}
void sub_0803B6A4(Entity* this) {
Entity* temp;
this->action = 0x2c;
this->hitType = 0x14;
temp = this->parent;
temp->field_0x80.HALF.LO |= (this->type == 0) ? 0x10 : 0x20;
temp->field_0x80.HALF.LO &= (this->type == 0) ? -5 : -9;
InitializeAnimation(this, 0x17);
}
u32 sub_0803B6F4(Entity* this) {
if (this->type == 0) {
if (this->field_0x80.HWORD > this->x.HALF.HI) {
return 1;
}
} else {
if (this->field_0x80.HWORD < this->x.HALF.HI) {
return 1;
}
}
return 0;
}
void sub_0803B724(Entity* param_1) {
Entity* pEVar1;
u32 random_value;
u8 temp;
if (((param_1->subtimer < 3) && (param_1->cutsceneBeh.HALF.LO != 0)) &&
(pEVar1 = CreateEnemy(BEETLE, 1), pEVar1 != (Entity*)0x0)) {
pEVar1->type2 = 1;
random_value = Random();
temp = gUnk_080CFD1B[param_1->type];
pEVar1->x.HALF.HI = (random_value & 0x70) + temp + gRoomControls.origin_x;
pEVar1->y.HALF.HI = ((random_value >> 0x10) & 7) * 10 + 0x5c + gRoomControls.origin_y;
pEVar1->parent = param_1;
ResolveCollisionLayer(pEVar1);
param_1->subtimer++;
param_1->cutsceneBeh.HALF.LO--;
}
}
void sub_0803B798(void) {
gPlayerState.jump_status = 0x41;
gPlayerState.field_0xa = 0;
gPlayerState.flags &= ~(0xffff0000 | PL_CAPTURED);
gPlayerEntity.flags |= ENT_COLLIDE;
gPlayerEntity.zVelocity = Q_16_16(1.5);
gPlayerEntity.z.HALF.HI = -10;
gPlayerEntity.direction = 0x10;
gPlayerEntity.animationState = 4;
gPlayerEntity.spritePriority.b1 = 1;
gPlayerEntity.spriteOffsetY = 0;
gPlayerEntity.speed = 0x140;
gPlayerEntity.iframes = -0x1e;
}
void sub_0803B804(Entity* this) {
gPlayerEntity.iframes = 30;
ModHealth(-4);
SoundReqClipped(&gPlayerEntity, SFX_PLY_VO6);
}
void sub_0803B824(Entity* this) {
ResetActiveItems();
gPlayerState.mobility |= 0x80;
sub_0806FA90(this, &gPlayerEntity, gUnk_080CFD1D[this->type], 1);
gPlayerEntity.spriteOffsetY = -6;
gPlayerEntity.spritePriority.b1 = 0;
}
u32 sub_0803B870(Entity* this) {
Entity* entity;
entity = this->child;
if ((entity->contactFlags & 0x80) != 0 && (gPlayerState.flags & PL_CAPTURED)) {
this->action = 0x18;
this->timer = 68;
this->spriteSettings.draw = 0;
gPlayerEntity.flags &= ~ENT_COLLIDE;
gPlayerEntity.iframes = -0x10;
sub_0803B824(this);
entity->hitType = 0x13;
InitAnimationForceUpdate(entity, 7);
SoundReq(SFX_16E);
return 1;
} else {
entity->hitType = 0x15;
return 0;
}
}
void sub_0803B8E8(Entity* this, u32 unk) {
Entity* entity;
entity = this->child;
entity->hitType = unk;
entity = (*(Entity**)&this->field_0x74);
entity->hitType = unk;
}
void sub_0803B8F8(Entity* this) {
gUnk_080CFD20[this->action](this);
}
void sub_0803B910(Entity* this) {
if (gRoomTransition.field_0x38 != 0) {
this->action = 2;
this->spriteSettings.draw = 1;
*(u8*)&this->field_0x74 = 0;
sub_0803BA8C(this, 10);
} else {
this->action = 1;
*(u8*)&this->field_0x74 = 0x80;
}
this->spriteSettings.flipX = (this->type - 2);
InitializeAnimation(this, 0);
CopyPositionAndSpriteOffset(this->parent, this);
}
void sub_0803B978(Entity* this) {
switch (this->subAction) {
case 0:
return;
case 1:
this->subAction = 2;
this->timer = 2;
this->subtimer = 30;
this->field_0x74.HALF.LO = 0;
SoundReq(SFX_1A9);
case 2:
sub_0803BA8C(this, this->subtimer);
if ((this->field_0x74.HALF.HI | this->field_0x74.HALF.LO) == 0) {
SoundReq(SFX_1A9);
}
if (this->field_0x74.HALF.LO != 0) {
return;
}
if (--this->timer != 0) {
return;
}
this->timer = 2;
this->subtimer -= 4;
if (this->subtimer != 10) {
return;
}
this->parent->parent->subAction = 3;
this->subAction = 3;
return;
case 3:
break;
case 4:
this->subAction = 5;
this->spriteSettings.draw = 1;
this->spriteRendering.alphaBlend = 1;
break;
default:
this->action = 2;
this->spriteRendering.alphaBlend = 0;
case 5:
GetNextFrame(this);
}
sub_0803BA8C(this, 0x10);
if ((this->field_0x74.HALF.HI | this->field_0x74.HALF.LO) == 0) {
SoundReq(SFX_1A9);
}
}
void sub_0803BA6C(Entity* this) {
sub_0803BA8C(this, 10);
GetNextFrame(this);
}
void sub_0803BA80(Entity* this) {
sub_0803BA8C(this, 10);
}
void sub_0803BA8C(Entity* this, u32 unk) {
u32 sVar2;
u32 tmp;
sVar2 = 0;
tmp = this->field_0x74.HALF.LO & 0xe0;
if ((this->field_0x74.HALF.LO & 0xe0) == 0) {
if (this->field_0x74.HALF.LO == 0) {
if (9 < ++this->field_0x74.HALF.HI) {
this->field_0x74.HALF.HI = 0;
}
if (this->type == 2) {
sVar2 = gUnk_080CFD30[this->field_0x74.HALF.HI];
} else {
sVar2 = gUnk_080CFD44[this->field_0x74.HALF.HI];
}
}
this->field_0x74.HALF.LO++;
if (unk <= this->field_0x74.HALF.LO) {
this->field_0x74.HALF.LO = 0;
}
} else {
if ((tmp & 0x80) == 0) {
this->field_0x74.HALF.LO |= 0x80;
if ((tmp & 0x20) != 0) {
sVar2 = gUnk_080CFD58[this->type - 2];
} else {
sVar2 = gUnk_080CFD5C[this->type - 2];
}
}
}
if (sVar2 != 0) {
ChangeObjPalette(this, sVar2);
(*(Entity**)&this->parent->field_0x78)->palette.b.b0 = this->palette.raw << 0x1c >> 0x1c;
(*(Entity**)&this->parent->field_0x78)->palette.b.b4 = this->palette.b.b0;
this->parent->child->palette.b.b0 = this->palette.raw << 0x1c >> 0x1c;
this->parent->child->palette.b.b4 = this->palette.b.b0;
}
}