tmc/src/enemy/ballChainSoldier.c

343 lines
8.9 KiB
C

#define NENT_DEPRECATED
#include "entity.h"
#include "enemy.h"
#include "functions.h"
typedef struct {
Entity base;
u8 filler[0x10];
u16 unk_78;
u8 unk_7a;
u8 unk_7b;
u8 unk_7c;
u8 unk_7d;
u8 unk_7e;
u8 unk_7f;
} BallChainSoldierEntity;
extern Entity* gUnk_020000B0;
void (*const gUnk_080D06E0[])(BallChainSoldierEntity*);
void (*const gUnk_080D06F8[])(BallChainSoldierEntity*);
const u8 gUnk_080D0724[];
const u16 gUnk_080D0728[];
const u16 gUnk_080D0730[];
extern u32 sub_0804A044(Entity*, Entity*, u32);
extern void sub_0803E86C(BallChainSoldierEntity*);
extern void sub_0803E9A4(BallChainSoldierEntity*);
extern bool32 sub_0803E9D4(BallChainSoldierEntity*);
extern void sub_0803E8CC(BallChainSoldierEntity*);
extern void sub_0803E92C(BallChainSoldierEntity*);
extern bool32 sub_0803EA64(BallChainSoldierEntity*);
extern void sub_0803E94C(BallChainSoldierEntity*, u32);
extern bool32 sub_0803EAD0(BallChainSoldierEntity*, u32);
void BallChainSoldier(Entity* this) {
EnemyFunctionHandler(this, (EntityActionArray)gUnk_080D06E0);
}
void sub_0803E538(BallChainSoldierEntity* this) {
gUnk_080D06F8[super->action](this);
}
void sub_0803E550(BallChainSoldierEntity* this) {
sub_0804AA30(super, gUnk_080D06E0);
}
void sub_0803E560(BallChainSoldierEntity* this) {
sub_08001324(super);
sub_0803E538(this);
}
void BallChainSoldier_CreateDeathFx(BallChainSoldierEntity* this) {
CreateDeathFx(super, 0xff, 0x57);
}
void nullsub_20(BallChainSoldierEntity* this) {
}
void BallChainSoldier_Init(BallChainSoldierEntity* this) {
Entity* ent;
sub_0804A720(super);
ent = CreateProjectileWithParent(super, BALL_AND_CHAIN, 0);
if (ent == NULL)
return;
ent->parent = super;
super->child = ent;
COLLISION_ON(super);
super->spriteSettings.draw = 1;
super->animationState = Random() & 3;
this->unk_7b = 0;
this->unk_7c = 0;
this->unk_7e = 0x20;
this->unk_7f = 0xfe;
InitAnimationForceUpdate(super, super->animationState << 2);
sub_0803E86C(this);
}
void sub_0803E5E8(BallChainSoldierEntity* this) {
this->unk_7c -= 0xa;
sub_0803E9A4(this);
if (sub_0803E9D4(this) == 0) {
if (--this->unk_78 == 0) {
sub_0803E8CC(this);
}
}
}
void sub_0803E61C(BallChainSoldierEntity* this) {
this->unk_7c -= 0xa;
sub_0803E9A4(this);
if (sub_0803E9D4(this) == 0) {
if (super->knockbackDuration == 0) {
if (ProcessMovement(super) == 0) {
sub_0803E86C(this);
return;
}
}
if (--this->unk_78 == 0) {
sub_0803E92C(this);
}
}
}
void sub_0803E66C(BallChainSoldierEntity* this) {
this->unk_7c -= 0x10;
sub_0803E9A4(this);
if (this->unk_7e <= 0x21) {
this->unk_7e++;
}
if (!sub_08049FDC(super, 1) || sub_0803EA64(this) == 0) {
super->action = 4;
this->unk_7b = 0;
}
}
void sub_0803E6B4(BallChainSoldierEntity* this) {
this->unk_7c -= 0xa;
sub_0803E9A4(this);
if (this->unk_7e > 0x20) {
this->unk_7e--;
} else {
sub_0803E86C(this);
}
}
void sub_0803E6E0(BallChainSoldierEntity* this) {
this->unk_7c -= 0xc;
sub_0803E9A4(this);
this->unk_7e -= 4;
if ((s8)this->unk_7e <= 0) {
this->unk_7e = 0;
super->action = 6;
super->actionDelay = 0x1e;
InitAnimationForceUpdate(super, super->animationState + 0x20);
}
}
void sub_0803E71C(BallChainSoldierEntity* this) {
if (--super->actionDelay == 0) {
super->action = 7;
super->actionDelay = 1;
this->unk_7c = gUnk_080D0724[super->animationState];
this->unk_7b = 0;
this->unk_7f = 0xf6;
EnqueueSFX(SFX_15B);
}
}
void sub_0803E75C(BallChainSoldierEntity* this) {
if ((super->frame & 0x80) == 0) {
UpdateAnimationSingleFrame(super);
} else {
if (--super->actionDelay == 0) {
super->actionDelay = 2;
this->unk_7f++;
}
if (this->unk_7f) {
this->unk_7e += 5;
} else {
super->action = 8;
super->actionDelay = 0x1e;
InitScreenShake(8, 0);
}
}
}
void sub_0803E7B4(BallChainSoldierEntity* this) {
if (--super->actionDelay == 0) {
super->action = 9;
}
}
void sub_0803E7CC(BallChainSoldierEntity* this) {
this->unk_7e -= 2;
if (this->unk_7e <= 0xa) {
super->action = 0xa;
super->actionDelay = 0x5a;
super->direction = DirectionFromAnimationState(super->animationState);
this->unk_7c = 0;
this->unk_7f = 0xfe;
sub_0803E94C(this, 0x10);
} else if (this->unk_7e <= 0x12) {
COLLISION_OFF(super->child);
}
}
void sub_0803E818(BallChainSoldierEntity* this) {
if (super->actionDelay) {
if (--super->actionDelay == 0) {
COLLISION_ON(super->child);
sub_0803E94C(this, 0);
}
} else {
this->unk_7c -= 0xa;
sub_0803E9A4(this);
if (++this->unk_7e > 0x1f) {
sub_0803E86C(this);
}
}
}
void sub_0803E86C(BallChainSoldierEntity* this) {
if (sub_08049FDC(super, 1) && sub_0803EAD0(this, 0x50)) {
super->direction = DirectionRoundUp(GetFacingDirection(super, gUnk_020000B0));
}
super->action = 1;
this->unk_78 = gUnk_080D0728[Random() & 3];
this->unk_7a = 4;
sub_0803E94C(this, 0);
}
void sub_0803E8CC(BallChainSoldierEntity* this) {
u32 rand = Random();
u32 temp;
u32 dir;
if (sub_08049FA0(super) == 0 && (rand & 3)) {
dir = sub_08049EE4(super) + 4;
temp = 0x18;
} else {
temp = 0x18;
dir = rand;
}
super->direction = dir & temp;
super->action = 2;
this->unk_78 = gUnk_080D0730[(rand >> 0x10) & 3];
this->unk_7a = 4;
sub_0803E94C(this, 0x10);
}
void sub_0803E92C(BallChainSoldierEntity* this) {
if (Random() & 1) {
sub_0803E86C(this);
} else {
sub_0803E8CC(this);
}
}
void sub_0803E94C(BallChainSoldierEntity* this, u32 arg2) {
s32 animationState = DirectionToAnimationState(super->direction);
if ((super->animIndex & 0x10) == arg2) {
u32 dir = super->direction & 7;
s32 currentAnimationState = super->animationState;
if (dir == 4) {
if (((currentAnimationState - (super->direction >> 3)) & 3) <= 1)
return;
}
if (animationState == currentAnimationState)
return;
}
super->animationState = animationState;
animationState = arg2 + (super->animIndex & 3) + animationState * 4;
InitAnimationForceUpdate(super, animationState);
}
void sub_0803E9A4(BallChainSoldierEntity* this) {
s32 val = ((this->unk_7c + 0x20) & 0xff) >> 6;
if ((super->animIndex & 3) == val)
return;
InitAnimationForceUpdate(super, val + (super->animIndex & -4));
}
bool32 sub_0803E9D4(BallChainSoldierEntity* this) {
u32 dir;
if (sub_08049FDC(super, 1)) {
if (sub_0803EAD0(this, 0x38)) {
super->action = 3;
super->direction = DirectionRoundUp(GetFacingDirection(super, gUnk_020000B0));
this->unk_7b = 1;
sub_0803E94C(this, 0);
return 1;
} else if (sub_0803EAD0(this, 0x4e)) {
dir = sub_0804A044(super, gUnk_020000B0, 0x12);
if (dir != 0xff) {
if (--this->unk_7a != 0)
return 0;
super->action = 5;
super->direction = dir;
this->unk_7a = 4;
sub_0803E94C(this, 0);
return 1;
}
}
}
this->unk_7a = 4;
return 0;
}
bool32 sub_0803EA64(BallChainSoldierEntity* this) {
u32 dir;
if (sub_08049FDC(super, 1)) {
if (sub_0803EAD0(this, 0x4e)) {
dir = sub_0804A044(super, gUnk_020000B0, 0x12);
if (dir != 0xff) {
if (--this->unk_7a != 0)
return 1;
super->action = 5;
super->direction = dir;
sub_0803E94C(this, 0);
return 1;
}
}
if (sub_0803EAD0(this, 0x38))
return 1;
}
this->unk_7a = 4;
return 0;
}
bool32 sub_0803EAD0(BallChainSoldierEntity* this, u32 distance) {
return EntityWithinDistance(super, gUnk_020000B0->x.HALF.HI, gUnk_020000B0->y.HALF.HI - 4, distance);
}
void (*const gUnk_080D06E0[])(BallChainSoldierEntity*) = {
sub_0803E538,
sub_0803E550,
sub_0803E560,
BallChainSoldier_CreateDeathFx,
(void (*const)(BallChainSoldierEntity*))sub_08001242,
nullsub_20,
};
void (*const gUnk_080D06F8[])(BallChainSoldierEntity*) = {
BallChainSoldier_Init, sub_0803E5E8, sub_0803E61C, sub_0803E66C, sub_0803E6B4, sub_0803E6E0,
sub_0803E71C, sub_0803E75C, sub_0803E7B4, sub_0803E7CC, sub_0803E818,
};
const u8 gUnk_080D0724[] = { 0, 0x44, 0x80, 0xBC };
const u16 gUnk_080D0728[] = { 0x1E, 0x32, 0x46, 0x5A };
const u16 gUnk_080D0730[] = { 0x3C, 0x5A, 0x78, 0x96 };