tmc/src/enemy/mulldozer.c

487 lines
12 KiB
C

/**
* @file mulldozer.c
* @ingroup Enemies
*
* @brief Mulldozer enemy
*/
#define NENT_DEPRECATED
#include "global.h"
#include "collision.h"
#include "enemy.h"
typedef struct {
/*0x00*/ Entity base;
/*0x68*/ u8 filler[0x18];
/*0x80*/ u8 unk_80;
/*0x81*/ u8 unk_81;
/*0x82*/ u8 unk_82;
/*0x83*/ u8 unk_83;
} MulldozerEntity;
extern Entity* gUnk_020000B0;
extern void (*const Mulldozer_Functions[])(MulldozerEntity*);
extern void (*const Mulldozer_Actions[])(MulldozerEntity*);
extern const u8 gUnk_080CEA50[];
extern const u8 gUnk_080CEA54[];
extern const s8 gUnk_080CEA56[];
void sub_08033174(MulldozerEntity*);
void sub_08032F24(MulldozerEntity*);
void sub_080331E8(MulldozerEntity*);
void sub_08033058(MulldozerEntity*);
bool32 sub_08033364(MulldozerEntity*);
void sub_080330C0(MulldozerEntity*);
void sub_08033100(MulldozerEntity*);
void sub_08032F64(MulldozerEntity*);
void sub_08032F48(MulldozerEntity*);
void sub_080331B4(MulldozerEntity*);
void sub_08032F90(MulldozerEntity*);
void sub_08033000(MulldozerEntity*);
void sub_08033320(MulldozerEntity*);
void sub_080332A8(MulldozerEntity*);
void sub_08033280(MulldozerEntity*);
void sub_080332E8(MulldozerEntity*, s32);
void Mulldozer(MulldozerEntity* this) {
EnemyFunctionHandler(super, (EntityActionArray)Mulldozer_Functions);
SetChildOffset(super, 0, 1, -0x10);
}
void Mulldozer_OnInit(MulldozerEntity* this) {
Mulldozer_Actions[super->action](this);
}
void sub_08032CAC(MulldozerEntity* this) {
if (super->confusedTime != 0) {
Create0x68FX(super, 0x1c);
}
EnemyFunctionHandlerAfterCollision(super, Mulldozer_Functions);
if ((super->contactFlags & 0x80) != 0) {
switch (super->contactFlags & 0x3f) {
case 2:
case 3:
super->action = 6;
super->timer = (super->type != 0) ? 90 : 200;
super->subtimer = 2;
this->unk_80 = 3;
super->direction = super->knockbackDirection;
super->direction += ((Random() & 0x40) != 0) ? 4 : 0x1C;
super->direction &= 0x1f;
super->speed = 0;
break;
default:
super->action = 5;
super->subtimer = 4;
sub_08033174(this);
break;
}
}
}
void sub_08032D3C(MulldozerEntity* this) {
if (--super->subtimer == 0) {
super->subtimer = 2;
super->animationState = (super->animationState + 1) & 7;
sub_08032F24(this);
sub_080331E8(this);
}
GenericKnockback(super);
}
void nullsub_157(MulldozerEntity* this) {
}
void Mulldozer_Init(MulldozerEntity* this) {
sub_0804A720(super);
sub_08033058(this);
}
void Mulldozer_Action1(MulldozerEntity* this) {
if (--super->timer == 0) {
sub_080330C0(this);
} else {
if (sub_08033364(this)) {
sub_08033100(this);
}
}
sub_08032F64(this);
}
void Mulldozer_Action2(MulldozerEntity* this) {
if (--super->timer == 0) {
sub_08033058(this);
}
sub_08032F48(this);
}
void Mulldozer_Action3(MulldozerEntity* this) {
if (--super->timer == 0) {
super->action = 4;
super->subtimer = 8;
super->speed = 0x1e0;
sub_080331B4(this);
if ((this->unk_82 & 0x80) != 0) {
super->direction = (super->direction + 0x1c) & 0x1c;
this->unk_82 = this->unk_82 & 0x7f;
} else {
super->direction = (super->direction + 4) & 0x1c;
this->unk_82 = this->unk_82 | 0x80;
}
super->animationState = super->direction >> 2;
InitializeAnimation(super, super->animationState + 4);
} else {
sub_08032F90(this);
sub_080331E8(this);
sub_08032F64(this);
}
}
void Mulldozer_Action4(MulldozerEntity* this) {
if (--super->timer == 0) {
super->action = 5;
super->subtimer = 4;
sub_08033174(this);
} else {
sub_08033000(this);
sub_080331E8(this);
sub_08032F64(this);
}
}
void Mulldozer_Action5(MulldozerEntity* this) {
if (--super->timer == 0) {
sub_08033320(this);
sub_080330C0(this);
} else if ((super->type == 0) && (--super->subtimer == 0)) {
super->subtimer = 4;
sub_080332A8(this);
}
sub_080331E8(this);
ProcessMovement0(super);
}
void Mulldozer_Action6(MulldozerEntity* this) {
ProcessMovement0(super);
sub_08032F48(this);
if (--super->subtimer == 0) {
super->subtimer = 2;
super->animationState = (super->animationState + 1) & 7;
sub_08032F24(this);
sub_080331E8(this);
}
if (--super->timer == 0) {
super->action = 5;
super->subtimer = 4;
sub_08033174(this);
}
}
void sub_08032F24(MulldozerEntity* this) {
u32 tmpA;
u32 tmpB;
if (this->unk_80 == 0) {
tmpA = 0;
tmpB = super->animationState >> 1;
} else {
tmpA = 4;
tmpB = super->animationState;
}
InitializeAnimation(super, tmpA + tmpB);
}
void sub_08032F48(MulldozerEntity* this) {
if (this->unk_80 == 2) {
GetNextFrame(super);
}
GetNextFrame(super);
}
void sub_08032F64(MulldozerEntity* this) {
if (super->collisions != COL_NONE) {
sub_0800417E(super, super->collisions);
super->animationState = super->direction >> 2;
sub_08032F24(this);
}
sub_08032F48(this);
ProcessMovement0(super);
}
void sub_08032F90(MulldozerEntity* this) {
if (super->type == 0) {
if (super->timer == 16) {
this->unk_80 = 2;
}
if (--super->subtimer == 0) {
super->subtimer = 8;
sub_08033280(this);
}
} else {
if (--super->subtimer == 0) {
super->subtimer = 4;
if ((this->unk_82 & 0x80) != 0) {
super->direction = (super->direction + 0x1c) & 0x1c;
} else {
super->direction = (super->direction + 4) & 0x1c;
}
super->animationState = super->direction >> 2;
InitializeAnimation(super, super->animationState + 4);
}
}
}
void sub_08033000(MulldozerEntity* this) {
if (--super->subtimer == 0) {
super->subtimer = 16;
if ((this->unk_82 & 0x80) != 0) {
super->direction = (super->direction + 0x18) & 0x1c;
this->unk_82 &= 0x7f;
} else {
super->direction = (super->direction + 8) & 0x1c;
this->unk_82 |= 0x80;
}
super->animationState = super->direction >> 2;
InitializeAnimation(super, super->animationState + 4);
}
}
void sub_08033058(MulldozerEntity* this) {
u32 uVar2;
u32 uVar3;
super->action = 1;
this->unk_80 = 1;
super->timer = gUnk_080CEA50[Random() & 3];
if ((sub_08049FA0(super) == 0) && ((Random() & 3) != 0)) {
uVar2 = sub_08049EE4(super);
uVar3 = Random();
super->direction = (gUnk_080CEA54[uVar3 & 1] + uVar2) & 0x18;
} else {
super->direction = (Random()) & 0x18;
}
super->animationState = super->direction >> 2;
sub_08032F24(this);
}
void sub_080330C0(MulldozerEntity* this) {
super->action = 2;
this->unk_80 = 0;
if (super->type == 0) {
super->timer = (Random() & 0x38) + 24;
} else {
super->timer = 6;
}
super->speed = 0x60;
super->direction = (super->direction + 4) & 0x18;
super->animationState = super->direction >> 2;
sub_08032F24(this);
}
void sub_08033100(MulldozerEntity* this) {
super->action = 3;
if (super->type == 0) {
this->unk_80 = 1;
super->timer = 48;
super->subtimer = 8;
super->speed = 0;
super->direction = (sub_08049F84(super, 1) + 2) & 0x1c;
} else {
this->unk_80 = 2;
sub_080331B4(this);
super->timer += 16;
super->subtimer = 4;
super->speed = 0x160;
}
this->unk_83 = 0;
this->unk_82 = Random() & 0x80;
super->animationState = super->direction >> 2;
sub_08032F24(this);
}
void sub_08033174(MulldozerEntity* this) {
this->unk_80 = 1;
this->unk_81 = super->direction;
this->unk_82 = 0;
this->unk_83 = 0;
if (super->type == 0) {
super->timer = (Random() & 0x18) + 24;
} else {
super->timer = 12;
}
super->speed = 0xa0;
sub_08032F24(this);
}
void sub_080331B4(MulldozerEntity* this) {
u32 rand = Random() & 0xf0;
u8 timer = 30;
if ((rand & 0x80) != 0) {
timer = 60;
} else {
if ((rand & 0x40) != 0) {
timer = 45;
}
if ((rand & 0x20) != 0) {
timer = 75;
}
}
super->timer = timer;
}
void sub_080331E8(MulldozerEntity* this) {
bool32 createEffect;
u32 unaff_r6;
const s8* ptr;
createEffect = FALSE;
if (super->action != 5) {
this->unk_83 = this->unk_83 + 1U;
if (this->unk_80 != 2) {
this->unk_83 &= 0xf;
} else {
this->unk_83 &= 0x7;
}
if (this->unk_83 == 0) {
createEffect = TRUE;
unaff_r6 = super->animationState << 1;
}
} else {
this->unk_83 = (this->unk_83 + 1) & 0xf;
if (this->unk_83 == 0) {
createEffect = TRUE;
unaff_r6 = super->direction >> 1;
}
}
if (createEffect) {
Entity* effect = CreateFx(super, 2, 0x40);
if (effect != NULL) {
ptr = &gUnk_080CEA56[unaff_r6];
super->frame ^= 0x20;
effect->x.HALF.HI += ptr[0];
effect->y.HALF.HI += ptr[1];
EnqueueSFX(SFX_BUTTON_PRESS);
}
}
}
void sub_08033280(MulldozerEntity* this) {
u32 direction;
super->direction = (sub_08049F84(super, 1) + 2) & 0x1c;
direction = super->direction >> 2;
if (direction != super->animationState) {
super->animationState = direction;
InitializeAnimation(super, direction + 4);
}
}
void sub_080332A8(MulldozerEntity* this) {
s32 oldDirection = super->direction;
super->direction = this->unk_81;
sub_08004596(super, sub_08049F84(super, 1));
this->unk_81 = super->direction;
super->direction = oldDirection;
oldDirection = ((this->unk_81 + 2) & 0x1c) >> 2;
if (oldDirection != super->animationState) {
sub_080332E8(this, oldDirection);
}
}
void sub_080332E8(MulldozerEntity* this, s32 param_2) {
s32 tmp;
this->unk_82 = 0;
tmp = param_2 - super->animationState;
if (tmp >= 1) {
if (tmp < 5) {
this->unk_82 = 1;
} else {
this->unk_82 = 2;
}
} else {
if (tmp < -4) {
this->unk_82 = 1;
} else {
this->unk_82 = 2;
}
}
super->animationState = param_2;
InitializeAnimation(super, param_2 + 4);
}
void sub_08033320(MulldozerEntity* this) {
u32 bVar4;
int temp;
bVar4 = super->animationState * 4;
if ((bVar4 & 4) != 0) {
switch (this->unk_82 & 3) {
case 1:
temp = 4;
break;
case 2:
temp = 0x1c;
break;
default:
temp = ((Random() & 0x10)) ? 4 : 0x1c;
break;
}
super->direction = (temp + bVar4) & 0x18;
} else {
super->direction = bVar4;
}
}
NONMATCH("asm/non_matching/mulldozer/sub_08033364.inc", bool32 sub_08033364(MulldozerEntity* this)) {
Entity* entity;
u32 radius;
u32 tmp;
entity = (Entity*)sub_08049DF4(1);
if (entity != NULL) {
if (super->type != 0) {
radius = 0x48;
} else {
radius = 0x38;
}
if (EntityInRectRadius(super, entity, radius, radius) != 0) {
if (super->type != 0) {
return TRUE;
}
if (((GetFacingDirection(super, gUnk_020000B0) + 2) & 0x1c) >> 2 == super->animationState) {
return TRUE;
}
}
}
return FALSE;
}
END_NONMATCH
void (*const Mulldozer_Functions[])(MulldozerEntity*) = {
Mulldozer_OnInit,
sub_08032CAC,
sub_08032D3C,
(void (*)(MulldozerEntity*))GenericDeath,
(void (*)(MulldozerEntity*))GenericConfused,
nullsub_157,
};
void (*const Mulldozer_Actions[])(MulldozerEntity*) = {
Mulldozer_Init, Mulldozer_Action1, Mulldozer_Action2, Mulldozer_Action3,
Mulldozer_Action4, Mulldozer_Action5, Mulldozer_Action6,
};
const u8 gUnk_080CEA50[] = {
30,
45,
60,
90,
};
const u8 gUnk_080CEA54[] = {
252,
4,
};
const s8 gUnk_080CEA56[] = { 0, 6, -3, 3, -6, 0, -3, -3, 0, -6, 3, -3, 6, 0, 3, 3 };