summaryrefslogtreecommitdiff
path: root/src/enemy
diff options
context:
space:
mode:
authorBehemoth <Luisscheurenbrand@gmail.com>2020-08-24 18:39:40 +0200
committerBehemoth <Luisscheurenbrand@gmail.com>2020-08-24 18:39:40 +0200
commit73497fd8c26f5c5f19dc0f7769d0cd8be6f3027c (patch)
tree2b1f36aa1ef2fd7111057ad2e676ab9459d5bc76 /src/enemy
parent30137c802fd95afe8807a2d9ef120ecb3d78d03a (diff)
- decompile slime and fireball guy
- continue percy decompile - move entity function definitions to entity header
Diffstat (limited to 'src/enemy')
-rw-r--r--src/enemy/fireballGuy.c121
-rw-r--r--src/enemy/miniSlime.c95
-rw-r--r--src/enemy/slime.c169
3 files changed, 293 insertions, 92 deletions
diff --git a/src/enemy/fireballGuy.c b/src/enemy/fireballGuy.c
new file mode 100644
index 00000000..b194ed07
--- /dev/null
+++ b/src/enemy/fireballGuy.c
@@ -0,0 +1,121 @@
+#include "global.h"
+#include "entity.h"
+#include "functions.h"
+
+typedef struct {
+ s8 h, v;
+} PACKED PosOffset;
+
+extern void sub_08045524(Entity*);
+void sub_08045178(Entity*, Entity*, int, int);
+
+extern void (*const gUnk_080D17E8[])(Entity*);
+extern void (*const gUnk_080D1800[])(Entity*);
+extern u8 gUnk_080D180C[4]; // Entity count per form
+extern PosOffset gUnk_080D1810[4];
+
+extern u8 gEntCount;
+
+void FireballGuy(Entity* this) {
+ EnemyFunctionHandler(this, gUnk_080D17E8);
+}
+
+void sub_080453A4(Entity* this) {
+ gUnk_080D1800[this->action](this);
+}
+
+void sub_080453BC(Entity* this) {
+ if (this->currentHealth && this->cutsceneBeh.HALF.LO != this->currentHealth) {
+ this->action = 2;
+ } else {
+ sub_0804AA30(this, gUnk_080D17E8);
+ }
+}
+
+void nullsub_172(void) {
+}
+
+void sub_080453E8(Entity* this) {
+ this->action = 1;
+ this->actionDelay = 0;
+ this->spriteSettings.b.draw = 1;
+ this->nonPlanarMovement = 0x80;
+ this->cutsceneBeh.HALF.LO = this->currentHealth;
+ this->field_0x3c |= 0x10;
+ sub_0804A720(this);
+ InitializeAnimation(this, 0);
+ sub_08045524(this);
+}
+
+void sub_08045430(Entity* this) {
+ sub_080AEFE0(this);
+ GetNextFrame(this);
+ if (sub_08003FC4(this, 0x1800) == 0)
+ sub_08045524(this);
+}
+
+/* Split FireballGuy into new ones */
+void sub_08045454(Entity* this) {
+ Entity* entities[4];
+ Entity* ent;
+ s32 count, i;
+ PosOffset* off;
+ u32 tmp;
+
+ /* Can we create enough new entities? */
+ count = gUnk_080D180C[this->entityType.form];
+ if (72 - count <= gEntCount)
+ return;
+
+ /* Create 2-5 new MiniFireballGuy */
+ for (i = 0; i < count; i++)
+ entities[i] = CreateEnemy(0x59, this->entityType.form);
+
+ off = gUnk_080D1810;
+ for (i = 0; i < count; i++) {
+ ent = entities[i];
+ ent->attachedEntity = entities[(i + 1) % count];
+ ent->parent = entities[(i + count - 1) % count];
+ tmp = 0;
+ ent->entityType.parameter = 1;
+ ent->height.HALF.HI = tmp;
+ ent->hurtBlinkTime = -0x10;
+
+ /* Set MiniFireballGuy offset relative to killed slime. */
+ sub_08045178(this, ent, off->h, off->v);
+ off++;
+ }
+
+ ent = CreateFx(this, 2, 0);
+ if (ent)
+ CopyPosition(this, ent);
+
+ DeleteEntity(this);
+}
+
+u32 sub_0804A024(Entity*, u32, u32);
+
+void sub_08045524(Entity *this) {
+ u32 tmp, tmp1, tmp2;
+
+ this->field_0x20 = 0x1c000;
+ tmp = sub_0804A024(this,1,8);
+ if (tmp != 0xff && (Random() & 3) == 0) {
+ this->actionDelay = Random() & 3;
+ this->direction = tmp & 0x18;
+ } else {
+ if (this->actionDelay) {
+ this->actionDelay--;
+ return;
+ }
+ this->actionDelay = Random() & 3;
+ if (sub_08049FA0(this) == 0 && (Random() & 3)) {
+ tmp1 = sub_08049EE4(this);
+ tmp2 = Random() & 8;
+ tmp2 += 0xfc;
+ this->direction = (tmp1 + tmp2) & 0x18;
+ } else {
+ this->direction = Random() & 0x18;
+ }
+ }
+}
diff --git a/src/enemy/miniSlime.c b/src/enemy/miniSlime.c
new file mode 100644
index 00000000..eac2e020
--- /dev/null
+++ b/src/enemy/miniSlime.c
@@ -0,0 +1,95 @@
+#include "global.h"
+#include "entity.h"
+#include "room.h"
+#include "functions.h"
+
+void sub_08045374(Entity*);
+
+extern u32 sub_0806FA04(u32, u32);
+extern void sub_0804A720();
+extern void sub_080452E4();
+extern void sub_0804A9FC();
+extern void sub_0804AA30();
+extern void ReplaceMonitoredEntity(Entity*, Entity*);
+extern void sub_0804A7D4(Entity*);
+
+extern void (*const gUnk_080D17C0[])(Entity*);
+extern void (*const gUnk_080D17D8[])(Entity*);
+
+void MiniSlime(Entity* this) {
+ EnemyFunctionHandler(this, gUnk_080D17C0);
+ SetChildOffset(this, 0, 1, -8);
+}
+
+void sub_08045220(Entity* this) {
+ gUnk_080D17D8[this->action](this);
+}
+
+void sub_08045238(Entity* this) {
+ if (this->field_0x43)
+ sub_0804A9FC(this, 0x1c);
+
+ sub_0804AA30(this, gUnk_080D17C0);
+}
+
+void sub_0804525C(Entity* this) {
+ Entity* parent = this->parent;
+ if (this != parent && parent) {
+ this->field_0x6c.HALF.LO &= 0x7f;
+ this->parent->attachedEntity = this->attachedEntity;
+ this->attachedEntity->parent = this->parent;
+ if (this->field_0x6c.HALF.HI & 0x40)
+ ReplaceMonitoredEntity(this, parent);
+ }
+ sub_0804A7D4(this);
+}
+
+void nullsub_22(void) {
+}
+
+void sub_080452A4(Entity* this) {
+ this->action = 1;
+ this->spriteSettings.b.draw = 1;
+ this->nonPlanarMovement = 0x100;
+ sub_0804A720(this);
+ InitializeAnimation(this, 6);
+ if (this->entityType.parameter) {
+ this->action = 2;
+ this->actionDelay = 1;
+ } else {
+ sub_080452E4(this);
+ }
+}
+
+void sub_080452E4(Entity* this) {
+ this->action = 2;
+ this->actionDelay = (Random() & 0x1f) + 1;
+}
+
+void sub_080452FC(Entity *this) {
+ u32 cVar2, bVar3;
+ GetNextFrame(this);
+ if (--this->actionDelay == 0) {
+ this->action = 3;
+ this->actionDelay = 1;
+ if (0 < this->nonPlanarMovement)
+ this->actionDelay = sub_0806FA04(0x1000, this->nonPlanarMovement) >> 0x8;
+
+ if (sub_08049FA0(this) == 0 && (Random() & 3)) {
+ cVar2 = sub_08049EE4(this);
+ bVar3 = Random() & 8;
+ bVar3 += 0xfc;
+ this->direction = (cVar2 + bVar3) & 0x18;
+ } else {
+ this->direction = Random() & 0x18;
+ sub_08045374(this);
+ }
+ }
+}
+
+void sub_08045374(Entity* this) {
+ sub_080AEF88(this);
+ GetNextFrame(this);
+ if (--this->actionDelay == 0)
+ this->action = 1;
+}
diff --git a/src/enemy/slime.c b/src/enemy/slime.c
index 42a5d952..74343df7 100644
--- a/src/enemy/slime.c
+++ b/src/enemy/slime.c
@@ -1,5 +1,7 @@
#include "global.h"
#include "entity.h"
+#include "room.h"
+#include "functions.h"
typedef struct {
void* field_0x0;
@@ -7,28 +9,31 @@ typedef struct {
u8 freezeTime;
} EntityHandler;
-extern void EnemyFunctionHandler(Entity*, void*);
-extern void SetChildOffset(Entity*, u32, u32, u32);
-extern void sub_0804AA30(Entity*, void*);
+typedef struct {
+ s8 h, v;
+} PACKED PosOffset;
+
+void sub_08044FF8(Entity*);
+void sub_08045178(Entity*, Entity*, int, int);
+
extern void sub_0804A9FC(Entity*, u32);
extern void sub_0804A720(Entity*);
-extern void sub_08044FF8(Entity*);
-extern u32 Random(void);
extern u32 sub_0806FA04(u32, u32);
extern u32 sub_08049FA0(Entity*);
extern u32 sub_08049EE4(Entity*);
-extern u32 sub_080AEF88(void);
+extern void sub_0804A4E4(Entity*, Entity*);
+extern u32 sub_080002CC(Entity*, s32, s32);
-extern void (*gUnk_080D16BC[])(Entity*);
-extern void (*gUnk_080D16A4[])(Entity*);
+extern void (*const gUnk_080D16BC[])(Entity*);
+extern void (*const gUnk_080D16A4[])(Entity*);
+extern u8 gUnk_080D16D0[4]; // Entity count per form
+extern PosOffset gUnk_080D16D4[4];
-extern u8 gUnk_080D16D0;
+extern u8 gEntCount;
extern EntityHandler gUnk_03003DB8;
-void Slime(Entity* this)
-
-{
- EnemyFunctionHandler(this, &gUnk_080D16A4);
+void Slime(Entity* this) {
+ EnemyFunctionHandler(this, gUnk_080D16A4);
SetChildOffset(this, 0, 1, -12);
}
@@ -40,7 +45,7 @@ void sub_08044F88(Entity* this) {
if ((this->currentHealth != 0) && (this->cutsceneBeh.HALF.LO != this->currentHealth)) {
this->action = 4;
} else {
- sub_0804AA30(this, &gUnk_080D16A4);
+ sub_0804AA30(this, gUnk_080D16A4);
}
if (this->field_0x43 != 0) {
@@ -61,32 +66,21 @@ void sub_08044FC8(Entity* this) {
}
void sub_08044FF8(Entity* this) {
- u32 bVar1;
-
this->action = 2;
- bVar1 = Random();
- this->actionDelay = (bVar1 & 31) + 30;
+ this->actionDelay = (Random() & 31) + 30;
this->cutsceneBeh.HALF.LO = this->currentHealth;
}
void sub_08045018(Entity* this) {
- u32 cVar1;
- u32 param3;
- u32 iVar3;
- u32 randValue;
-
GetNextFrame(this);
- param3 = this->actionDelay -= 1;
- if (param3 == 0) {
+ if (--this->actionDelay == 0) {
this->action = 3;
this->actionDelay = 1;
if (0 < this->nonPlanarMovement) {
this->actionDelay = sub_0806FA04(4096, this->nonPlanarMovement) >> 8;
}
- iVar3 = sub_08049FA0(this);
- if ((iVar3 == 0) && (randValue = Random(), (randValue & 3) != 0)) {
- cVar1 = sub_08049EE4(this);
- this->direction = (cVar1 + 0xfc + (Random() & 8)) & 24;
+ if (sub_08049FA0(this) == 0 && (Random() & 3)) {
+ this->direction = (sub_08049EE4(this) + 0xfc + (Random() & 8)) & 24;
return;
}
this->direction = Random() & 24;
@@ -94,74 +88,65 @@ void sub_08045018(Entity* this) {
}
void sub_08045088(Entity* this) {
- u8 bVar1;
-
- sub_080AEF88();
+ sub_080AEF88(this);
GetNextFrame(this);
- bVar1 = this->actionDelay -= 1;
- if (bVar1 == 0) {
+ if (--this->actionDelay == 0) {
this->action = 1;
}
}
-#ifdef NON_MATCHING
-void sub_080450A8(Entity* this)
-
-{
- u8 bVar1;
- u32 uVar2;
- s32 iVar3;
- s32 iVar4;
- Entity* pEVar5;
- Entity** ppEVar6;
- s32 dividend;
- u32 uVar7;
- Entity* local_r6_72;
- u32 divisor;
- u8* pcVar8;
- Entity* local_2c[4];
-
- ppEVar6 = local_2c;
- bVar1 = (&gUnk_080D16D0)[(this->entityType).form];
- divisor = (u32)bVar1;
- if ((int)gUnk_03003DB8.entityCount < (int)(72 - divisor)) {
- uVar7 = divisor;
- if (bVar1 != 0) {
- do {
- uVar2 = CreateEnemy(87, this->entityType.form);
- *ppEVar6 = uVar2;
- ppEVar6 = ppEVar6 + 1;
- uVar7 = uVar7 - 1;
- } while (uVar7 != 0);
- }
- pcVar8 = "\x06";
- iVar4 = 0;
- if (bVar1 != 0) {
- do {
- local_r6_72 = local_2c[iVar4];
- dividend = iVar4 + 1;
- iVar3 = Div(dividend, divisor);
- local_r6_72->attachedEntity = local_2c[iVar3];
- iVar4 = Div(iVar4 + divisor + -1, divisor);
- local_r6_72->parent = local_2c[iVar4];
- (local_r6_72->entityType).parameter = 1;
- local_r6_72->height.WORD = 0;
- local_r6_72->hurtBlinkTime = 240;
- sub_08045178(this, local_r6_72, *pcVar8, pcVar8[1]);
- pcVar8 = pcVar8 + 2;
- iVar4 = dividend;
- } while (dividend < divisor);
- }
- pEVar5 = CreateFx(this, 2, 0);
- if (pEVar5 != NULL) {
- CopyPosition(this, pEVar5);
- }
- DeleteEnemy(this);
+/* Split slime into new ones */
+void sub_080450A8(Entity* this) {
+ Entity* entities[4];
+ Entity* ent;
+ s32 count, i;
+ PosOffset* off;
+
+ /* Can we create enough new entities? */
+ count = gUnk_080D16D0[this->entityType.form];
+ if (72 - count <= gEntCount)
+ return;
+
+ /* Create 2-4 new MiniSlime */
+ for (i = 0; i < count; i++)
+ entities[i] = CreateEnemy(0x57, this->entityType.form);
+
+ off = gUnk_080D16D4;
+ for (i = 0; i < count; i++) {
+ ent = entities[i];
+ ent->attachedEntity = entities[(i + 1) % count];
+ ent->parent = entities[(i + count - 1) % count];
+ ent->entityType.parameter = 1;
+ ent->height.HALF.HI = 0;
+ ent->hurtBlinkTime = -0x10;
+
+ /* Set MiniSlime offset relative to killed slime. */
+ sub_08045178(this, ent, off->h, off->v);
+ off++;
}
+
+ ent = CreateFx(this, 2, 0);
+ if (ent)
+ CopyPosition(this, ent);
+
+ DeleteEntity(this);
}
-#else
-NAKED
-void sub_080450A8(Entity* this) {
- asm(".include \"asm/non_matching/slime/sub_080450A8.inc\"");
+
+void sub_08045178(Entity* this, Entity* child, int h, int v) {
+ int x, y;
+
+ if (child == NULL)
+ return;
+
+ sub_0804A4E4(this, child);
+ if (sub_080002CC(child, h, v))
+ return;
+
+ x = child->x.HALF.HI + h;
+ if (0 <= x && x < (gRoomControls.roomOriginX + gRoomControls.width))
+ child->x.HALF.HI = x;
+
+ y = child->y.HALF.HI + v;
+ if (0 <= y && y < (gRoomControls.roomOriginY + gRoomControls.height))
+ child->y.HALF.HI = y;
}
-#endif