Files
tmc/src/enemy/bowMoblin.c
T

422 lines
10 KiB
C

/**
* @file bowMoblin.c
* @ingroup Enemies
*
* @brief Bow Moblin enemy
*/
#define NENT_DEPRECATED
#include "global.h"
#include "entity.h"
#include "enemy.h"
#include "functions.h"
typedef struct {
Entity base;
u8 filler[0x12];
u8 unk_0x7a;
u8 unk_0x7b;
u8 filter[0x4];
u8 unk_0x80;
u8 unk_0x81;
u8 unk_0x82;
u8 unk_0x83;
} BowMoblinEntity;
void sub_0803C5F0(BowMoblinEntity*);
void sub_0803C690(BowMoblinEntity*);
void sub_0803C4B0(BowMoblinEntity*);
void sub_0803C5C4(BowMoblinEntity*);
void sub_0803C624(BowMoblinEntity*);
void sub_0803C6DC(BowMoblinEntity*);
void sub_0803C714(BowMoblinEntity*);
void sub_0803C634(BowMoblinEntity*);
u32 sub_0803C6F8(BowMoblinEntity*);
u32 sub_0803C568(BowMoblinEntity*);
void sub_0803C664(BowMoblinEntity*);
void (*const BowMoblin_Functions[])(Entity*);
void (*const gUnk_080CFF90[])(BowMoblinEntity*);
const s8 gUnk_080CFFA4[8];
const s8 gUnk_080CFFAC[16];
const u16 gUnk_080CFFBC[4];
const s8 gUnk_080CFFC4[8];
void BowMoblin(Entity* this) {
EnemyFunctionHandler(this, BowMoblin_Functions);
SetChildOffset(this, 0, 1, -0x18);
}
void BowMoblin_OnTick(BowMoblinEntity* this) {
gUnk_080CFF90[super->action](this);
}
void BowMoblin_OnCollision(BowMoblinEntity* this) {
Entity* pEVar1;
if (super->confusedTime != 0) {
Create0x68FX(super, FX_STARS);
}
EnemyFunctionHandlerAfterCollision(super, (EntityActionArray)BowMoblin_Functions);
if ((super->bitfield & 0x80) != 0) {
sub_0803C5F0(this);
pEVar1 = super->child;
if (pEVar1 != NULL) {
pEVar1->field_0xf++;
}
}
}
void BowMoblin_OnGrabbed(BowMoblinEntity* this) {
}
void sub_0803C1E0(BowMoblinEntity* this) {
sub_0804A720(super);
super->action = 1;
this->unk_0x7b = 0;
this->unk_0x80 = 0;
this->unk_0x83 = 0;
this->unk_0x81 = 0;
this->unk_0x7a = 0;
this->unk_0x82 = 1;
if (super->actionDelay) {
super->animationState = super->type2 << 1;
super->actionDelay = 0x1e;
super->speed = 0x80;
super->direction = super->type2 << 3;
sub_0803C690(this);
} else {
super->animationState = 0x10;
sub_0803C4B0(this);
}
}
void sub_0803C234(BowMoblinEntity* this) {
u8 mask;
if (this->unk_0x81) {
this->unk_0x81--;
}
mask = 0xff;
if (((--super->actionDelay) & mask) == 0) {
u8 tmp = ++this->unk_0x80;
if ((tmp) > 0xf) {
sub_0803C5C4(this);
} else if (((this->unk_0x80 & 0x3) == 0) && (Random() & 0x10)) {
sub_0803C624(this);
} else {
sub_0803C4B0(this);
}
} else if (sub_0803C6F8(this)) {
sub_0800417E(super, super->collisions);
super->animationState = ((super->direction + 4) & 0x18) >> 2;
this->unk_0x83++;
sub_0803C690(this);
} else if (sub_0803C568(this)) {
sub_0803C5F0(this);
}
sub_0803C6DC(this);
}
void sub_0803C2DC(BowMoblinEntity* this) {
u32 res;
u32 actionDelay = --super->actionDelay;
if (actionDelay == 0) {
super->action = 3;
this->unk_0x82 = actionDelay;
this->unk_0x80 = actionDelay;
super->animationState = 0x10;
sub_0803C4B0(this);
} else if (res = sub_0803C568(this), res) {
this->unk_0x7b |= 0x1;
}
if (super->field_0xf > 0xb) {
if (this->unk_0x7b != 0) {
sub_0803C5F0(this);
}
} else {
super->field_0xf++;
}
sub_0803C6DC(this);
}
void sub_0803C344(BowMoblinEntity* this) {
if (--super->actionDelay == 0) {
switch (this->unk_0x82) {
case 3: {
super->action = 4;
super->speed = 0x80;
super->direction = sub_08049F84(super, 1);
break;
}
case 5: {
super->action = 4;
super->speed = 0x80;
break;
}
case 2: {
u32 tmp;
super->action = 2;
super->speed = 0;
tmp = Random() & 0x7;
super->actionDelay = (tmp << 1) + tmp + 0x40;
break;
}
case 4: {
super->direction = (super->direction + 0x10) & 0x18;
}
case 0:
case 1:
default: {
u32 tmp;
super->action = 1;
this->unk_0x82 = 1;
super->speed = 0x80;
tmp = (Random() & 0x7);
super->actionDelay = (tmp << 1) + tmp + 0x22;
break;
}
}
super->field_0xf = 0;
super->animationState = ((super->direction + 4) & 0x18) >> 2;
sub_0803C690(this);
}
sub_0803C6DC(this);
}
void sub_0803C400(BowMoblinEntity* this) {
if (super->field_0xf) {
u8 mask;
super->field_0xf--;
mask = 0xff;
if ((super->field_0xf & mask) == 0) {
if (this->unk_0x82 == 3) {
this->unk_0x7a++;
if ((this->unk_0x7a & mask) <= 2) {
if (Random() & 0xc0) {
super->actionDelay = 0;
sub_0803C690(this);
sub_0803C6DC(this);
return;
}
}
}
sub_0803C634(this);
}
} else {
Entity* projectile;
switch (++super->actionDelay) {
case 1:
super->direction = super->animationState << 2;
projectile = CreateProjectileWithParent(super, ARROW_PROJECTILE, super->animationState >> 1);
if (projectile) {
super->child = projectile;
projectile->direction = (super->direction + 4) & 0x18;
projectile->parent = super;
}
break;
case 24:
super->actionDelay = 0;
super->field_0xf = 0x20;
break;
}
sub_0803C6DC(this);
if (super->child != NULL) {
sub_0803C714(this);
}
}
}
void sub_0803C4B0(BowMoblinEntity* this) {
u32 dir;
super->field_0xf = 0;
if (this->unk_0x82 == 1) {
super->actionDelay = gUnk_080CFFA4[Random() & 7];
super->speed = 0x80;
if (sub_08049FA0(super)) {
dir = Random();
dir &= 6;
super->direction = dir << 2;
} else {
dir = sub_08049EE4(super);
if (this->unk_0x83 == 0) {
dir += gUnk_080CFFAC[Random() & 0xf];
} else {
dir += gUnk_080CFFAC[Random() & 0x7];
super->actionDelay += 0x10;
this->unk_0x83--;
}
dir = (super->direction = (dir + 4) & 0x18) >> 2;
}
} else {
super->actionDelay = 0xc;
super->speed = super->field_0xf;
dir = super->direction >> 2;
}
if (dir != super->animationState) {
super->animationState = dir;
sub_0803C690(this);
}
}
u32 sub_0803C568(BowMoblinEntity* this) {
if (this->unk_0x81 == 0) {
Entity* ent = sub_08049DF4(1);
if (ent != NULL) {
if (this->unk_0x82 == 2) {
if (sub_0806FC80(super, ent, 0x30)) {
return 1;
}
}
if (sub_0806FC80(super, ent, 0x40)) {
u32 direction = (GetFacingDirection(super, ent) + 4) & 0x18;
direction = direction >> 2;
if (direction == super->animationState) {
return 1;
}
}
}
}
return 0;
}
void sub_0803C5C4(BowMoblinEntity* this) {
u32 state = ((super->direction + 4) & 0x18) >> 2;
super->animationState = state;
super->direction = state << 2;
this->unk_0x83 >>= 1;
sub_0803C664(this);
this->unk_0x82 = 2;
}
void sub_0803C5F0(BowMoblinEntity* this) {
super->direction = sub_08049F84(super, 1);
super->animationState = ((super->direction + 4) & 0x18) >> 2;
this->unk_0x83 = 0;
this->unk_0x7a = 0;
sub_0803C664(this);
this->unk_0x82 = 3;
}
void sub_0803C624(BowMoblinEntity* this) {
sub_0803C664(this);
this->unk_0x82 = 5;
}
void sub_0803C634(BowMoblinEntity* this) {
super->animationState = ((super->direction + 4) & 0x18) >> 2;
super->direction = super->animationState << 2;
this->unk_0x83 = 0;
sub_0803C664(this);
super->actionDelay <<= 1;
this->unk_0x82 = 4;
}
void sub_0803C664(BowMoblinEntity* this) {
super->action = 3;
super->actionDelay = 0x20;
super->field_0xf = 0;
this->unk_0x80 = 0;
this->unk_0x7b = 0;
super->speed = 0;
this->unk_0x82 = 0;
sub_0803C690(this);
}
void sub_0803C690(BowMoblinEntity* this) {
u32 tmp = super->animationState >> 1;
switch (this->unk_0x82) {
case 1:
case 4: {
tmp += 0x4;
break;
}
case 3:
case 5: {
tmp += 0x8;
break;
}
case 2: {
tmp += 0xc;
break;
}
case 0: {
break;
}
}
InitializeAnimation(super, tmp);
}
void sub_0803C6DC(BowMoblinEntity* this) {
u8 tmp = this->unk_0x82;
if (tmp == 0) {
super->speed = tmp;
}
ProcessMovement0(super);
GetNextFrame(super);
}
u32 sub_0803C6F8(BowMoblinEntity* this) {
u32 tmp = (super->collisions & gUnk_080CFFBC[(super->animationState ^ 1) / 2]);
u32 tmp2 = -tmp;
return (tmp2 | tmp) >> 0x1f;
}
void sub_0803C714(BowMoblinEntity* this) {
Entity* child = super->child;
const s8* tmp;
u32 offsetX;
u32 offsetY;
tmp = &gUnk_080CFFC4[super->animationState];
// TODO fix array access
offsetX = tmp[0] << 0x10;
offsetY = tmp[1] << 0x10;
PositionRelative(super, child, offsetX, offsetY);
}
void (*const BowMoblin_Functions[])(Entity*) = {
(EntityActionPtr)BowMoblin_OnTick,
(EntityActionPtr)BowMoblin_OnCollision,
GenericKnockback,
GenericDeath,
GenericConfused,
(EntityActionPtr)BowMoblin_OnGrabbed,
};
void (*const gUnk_080CFF90[])(BowMoblinEntity*) = {
sub_0803C1E0, sub_0803C234, sub_0803C2DC, sub_0803C344, sub_0803C400,
};
const s8 gUnk_080CFFA4[8] = {
0x18, 0x20, 0x30, 0x40, 0x60, 0x6c, 0x78, 0x91,
};
const s8 gUnk_080CFFAC[16] = {
0xf8, 0xc, 0xf4, 0x8, 0x4, 0xfa, 0x6, 0xfc, 0x0, 0xfd, 0x1, 0x3, 0xff, 0x2, 0x0, 0xfe,
};
const u16 gUnk_080CFFBC[4] = {
0xe,
0xe000,
0xe0,
0xe00,
};
const s8 gUnk_080CFFC4[8] = {
-5, -20, 15, -12, 4, -4, -15, -12,
};