summaryrefslogtreecommitdiff
path: root/src/enemy
diff options
context:
space:
mode:
authornotyourav <65437533+notyourav@users.noreply.github.com>2022-01-29 11:00:24 -0800
committerGitHub <noreply@github.com>2022-01-29 11:00:24 -0800
commit885ce54cec8a99fe670c7ee2ae666575f5c1525f (patch)
treedf9a45e8c3a74d450a178ed74829c34b758ae437 /src/enemy
parentc77d45400bfaf5db78fd886d164ebb363a628555 (diff)
parent1c8f40334047c9cefa52e5ea9a90ea46436d0a96 (diff)
Merge pull request #326 from hatal175/ballchainsolder
Diffstat (limited to 'src/enemy')
-rw-r--r--src/enemy/ballChainSoldier.c342
1 files changed, 342 insertions, 0 deletions
diff --git a/src/enemy/ballChainSoldier.c b/src/enemy/ballChainSoldier.c
new file mode 100644
index 00000000..dad421f3
--- /dev/null
+++ b/src/enemy/ballChainSoldier.c
@@ -0,0 +1,342 @@
+#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 };