mirror of https://github.com/zeldaret/tmc.git
347 lines
8.8 KiB
C
347 lines
8.8 KiB
C
/**
|
|
* @file bobomb.c
|
|
* @ingroup Enemies
|
|
*
|
|
* @brief Bobomb enemy
|
|
*/
|
|
#include "asm.h"
|
|
#include "collision.h"
|
|
#include "enemy.h"
|
|
#include "functions.h"
|
|
#include "object.h"
|
|
#include "sound.h"
|
|
|
|
typedef struct {
|
|
/*0x00*/ Entity base;
|
|
/*0x68*/ u8 unused1[24];
|
|
/*0x80*/ u8 unk_80;
|
|
/*0x81*/ u8 unk_81;
|
|
/*0x82*/ u8 unk_82;
|
|
/*0x83*/ u8 unk_83;
|
|
} BobombEntity;
|
|
|
|
void sub_0802CB68(BobombEntity* this);
|
|
void sub_0802CBC4(BobombEntity* this);
|
|
void sub_0802CC18(BobombEntity* this);
|
|
|
|
extern void (*const Bobomb_Functions[])(BobombEntity*);
|
|
extern void (*const gUnk_080CD5EC[])(BobombEntity*);
|
|
extern void (*const gUnk_080CD600[])(BobombEntity*);
|
|
extern void (*const gUnk_080CD618[])(BobombEntity*);
|
|
|
|
void Bobomb(BobombEntity* this) {
|
|
EnemyFunctionHandler(super, (EntityActionArray)Bobomb_Functions);
|
|
}
|
|
|
|
void Bobomb_OnTick(BobombEntity* this) {
|
|
gUnk_080CD5EC[super->action](this);
|
|
}
|
|
|
|
void Bobomb_OnCollision(BobombEntity* this) {
|
|
if (super->contactFlags & 0x80) {
|
|
switch (super->contactFlags & 0x7f) {
|
|
case 0:
|
|
case 1:
|
|
if (this->unk_82) {
|
|
super->knockbackDuration = 0;
|
|
gPlayerEntity.base.knockbackDuration = 4;
|
|
}
|
|
return;
|
|
case 0xe:
|
|
case 0x14:
|
|
case 0x15:
|
|
case 0x16:
|
|
super->action = 3;
|
|
super->knockbackDuration = 0;
|
|
sub_0802CBC4(this);
|
|
return;
|
|
}
|
|
this->unk_82++;
|
|
this->unk_80 = 28;
|
|
switch (this->unk_82) {
|
|
case 1:
|
|
sub_0802CB68(this);
|
|
EnqueueSFX(SFX_14D);
|
|
break;
|
|
case 2:
|
|
super->action = 3;
|
|
super->hitType = 0x6e;
|
|
super->subtimer = 1;
|
|
super->zVelocity = Q_16_16(1.5);
|
|
super->speed = 0;
|
|
this->unk_81 = 1;
|
|
InitializeAnimation(super, super->direction >> 4 | IdleWest);
|
|
break;
|
|
}
|
|
}
|
|
EnemyFunctionHandlerAfterCollision(super, Bobomb_Functions);
|
|
}
|
|
|
|
void Bobomb_OnGrabbed(BobombEntity* this) {
|
|
if (super->subAction < 3 && !sub_0806F520(super)) {
|
|
super->subAction = 0;
|
|
super->subtimer = 1;
|
|
super->z.HALF.HI = 0;
|
|
if (this->unk_82 != 2) {
|
|
super->speed = this->unk_82 ? 0x200 : 0x80;
|
|
}
|
|
super->zVelocity = Q_16_16(1.5);
|
|
this->unk_83 = 0;
|
|
this->unk_81 = 0;
|
|
} else {
|
|
super->z.HALF.HI = -1;
|
|
gUnk_080CD600[super->subAction](this);
|
|
if (super->timer != 0) {
|
|
GetNextFrame(super);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0802C820(BobombEntity* this) {
|
|
super->subAction = 1;
|
|
super->gustJarTolerance = 60;
|
|
}
|
|
|
|
void sub_0802C82C(BobombEntity* this) {
|
|
sub_0806F4E8(super);
|
|
}
|
|
|
|
void sub_0802C834(BobombEntity* this) {
|
|
sub_0806F3E4(super);
|
|
}
|
|
|
|
void sub_0802C83C(BobombEntity* this) {
|
|
if (this->unk_82) {
|
|
if (--super->timer == 0) {
|
|
super->action = 3;
|
|
switch (gPlayerEntity.base.animationState & 6) {
|
|
case 2:
|
|
super->x.HALF.HI -= 6;
|
|
break;
|
|
case 6:
|
|
super->x.HALF.HI += 6;
|
|
break;
|
|
}
|
|
sub_0802CBC4(this);
|
|
} else {
|
|
sub_0802CC18(this);
|
|
COLLISION_OFF(super);
|
|
super->hitType = 0x6e;
|
|
}
|
|
} else {
|
|
this->unk_82 = 2;
|
|
super->timer = 120;
|
|
InitializeAnimation(super, (super->direction >> 4) | IdleWest);
|
|
COLLISION_OFF(super);
|
|
super->hitType = 0x6e;
|
|
}
|
|
}
|
|
|
|
void nullsub_149(BobombEntity* this) {
|
|
/* ... */
|
|
}
|
|
|
|
void sub_0802C8B8(BobombEntity* this) {
|
|
super->action = 3;
|
|
sub_0802CBC4(this);
|
|
}
|
|
|
|
void Bobomb_OnDeath(BobombEntity* this) {
|
|
GenericDeath(super);
|
|
super->spriteSettings.draw = 0;
|
|
}
|
|
|
|
void sub_0802C8D8(BobombEntity* this) {
|
|
super->action = 1;
|
|
super->timer = 60;
|
|
super->subtimer = 0;
|
|
super->direction = (Random() & 0x18) | DIR_DIAGONAL;
|
|
super->carryFlags = 0;
|
|
super->gustJarFlags = 0x12;
|
|
this->unk_82 = 0;
|
|
this->unk_83 = 0;
|
|
this->unk_80 = 0;
|
|
this->unk_81 = 0;
|
|
InitializeAnimation(super, super->direction >> 4);
|
|
}
|
|
|
|
void sub_0802C91C(BobombEntity* this) {
|
|
GetNextFrame(super);
|
|
ProcessMovement0(super);
|
|
if (this->unk_82) {
|
|
if (super->collisions != COL_NONE) {
|
|
sub_0800417E(super, super->collisions);
|
|
InitializeAnimation(super, (super->direction >> 4) | IdleEast);
|
|
}
|
|
if (--super->timer == 0) {
|
|
sub_0802CBC4(this);
|
|
} else {
|
|
if ((super->timer & 0xf) == 8) {
|
|
CreateDustSmall(super);
|
|
}
|
|
sub_0802CC18(this);
|
|
}
|
|
} else {
|
|
if (super->collisions != COL_NONE) {
|
|
sub_0800417E(super, super->collisions);
|
|
InitializeAnimation(super, super->direction >> 4);
|
|
}
|
|
if (--super->timer == 0) {
|
|
super->timer = 60;
|
|
super->direction = (super->direction + 8) & (DirectionWest | DIR_DIAGONAL);
|
|
InitializeAnimation(super, super->direction >> 4);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0802C9B8(BobombEntity* this) {
|
|
gUnk_080CD618[super->subAction](this);
|
|
}
|
|
|
|
void sub_0802C9D0(BobombEntity* this) {
|
|
super->subAction = 1;
|
|
COLLISION_OFF(super);
|
|
super->spritePriority.b1 = 0;
|
|
this->unk_83 = 1;
|
|
sub_0802CC18(this);
|
|
InitializeAnimation(super, (super->direction >> 4) | IdleWest);
|
|
GetNextFrame(super);
|
|
}
|
|
|
|
void sub_0802CA10(BobombEntity* this) {
|
|
if (gPlayerState.heldObject != 5) {
|
|
if (--super->timer == 0) {
|
|
sub_0802CBC4(this);
|
|
} else {
|
|
sub_0802CC18(this);
|
|
GetNextFrame(super);
|
|
}
|
|
} else {
|
|
this->unk_83 = 2;
|
|
super->direction = (((gPlayerEntity.base.animationState) << 2) | IdleSouth) & (DIR_DIAGONAL | DirectionWest);
|
|
sub_0802CC18(this);
|
|
GetNextFrame(super);
|
|
}
|
|
}
|
|
|
|
void sub_0802CA6C(BobombEntity* this) {
|
|
if (--super->timer == 0) {
|
|
sub_0802CBC4(this);
|
|
} else {
|
|
sub_0802CC18(this);
|
|
GetNextFrame(super);
|
|
}
|
|
}
|
|
|
|
void sub_0802CA94(BobombEntity* this) {
|
|
super->action = 3;
|
|
COLLISION_OFF(super);
|
|
super->subtimer = 1;
|
|
super->spritePriority.b1 = 1;
|
|
super->zVelocity = Q_16_16(1.5);
|
|
super->speed = 0;
|
|
this->unk_83 = 0;
|
|
this->unk_81 = 0;
|
|
super->direction = ((gPlayerEntity.base.animationState << 2) | IdleSouth) & (DirectionWest | DIR_DIAGONAL);
|
|
InitializeAnimation(super, (super->direction >> 4) | IdleWest);
|
|
}
|
|
|
|
void sub_0802CAF8(BobombEntity* this) {
|
|
if (--super->timer == 0) {
|
|
sub_0802CBC4(this);
|
|
} else {
|
|
if (this->unk_81 && sub_080044EC(super, 0x2800) == 1) {
|
|
EnqueueSFX(SFX_PLACE_OBJ);
|
|
}
|
|
sub_0802CC18(this);
|
|
RegisterCarryEntity(super);
|
|
if (super->subtimer && super->z.HALF.HI == 0) {
|
|
super->subtimer = 0;
|
|
COLLISION_ON(super);
|
|
super->hitType = 0x6e;
|
|
}
|
|
GetNextFrame(super);
|
|
}
|
|
}
|
|
|
|
void nullsub_150(BobombEntity* this) {
|
|
/* ... */
|
|
}
|
|
|
|
void sub_0802CB68(BobombEntity* this) {
|
|
super->action = 1;
|
|
super->subAction = 0;
|
|
super->direction = Random() & 0x18;
|
|
super->direction |= IdleSouth;
|
|
COLLISION_ON(super);
|
|
if (this->unk_82) {
|
|
super->timer = 200;
|
|
super->speed = 0x200;
|
|
InitializeAnimation(super, (super->direction >> 4) | 2);
|
|
} else {
|
|
super->timer = 60;
|
|
super->speed = 0x80;
|
|
InitializeAnimation(super, super->direction >> 4);
|
|
}
|
|
}
|
|
|
|
void sub_0802CBC4(BobombEntity* this) {
|
|
Entity* entity;
|
|
|
|
super->action = 4;
|
|
super->spriteSettings.draw = 0;
|
|
COLLISION_OFF(super);
|
|
super->health = 0;
|
|
if (this->unk_83) {
|
|
PlayerDropHeldObject();
|
|
}
|
|
FreeCarryEntity(super);
|
|
|
|
entity = CreateObjectWithParent(super, SMOKE_PARTICLE, 0, 0);
|
|
if (entity != NULL) {
|
|
entity->collisionLayer = super->collisionLayer;
|
|
}
|
|
}
|
|
|
|
void sub_0802CC18(BobombEntity* this) {
|
|
if (--this->unk_80 == 0) {
|
|
this->unk_80 = 28;
|
|
EnqueueSFX(SFX_14D);
|
|
}
|
|
}
|
|
|
|
// clang-format off
|
|
void (*const Bobomb_Functions[])(BobombEntity*) = {
|
|
Bobomb_OnTick,
|
|
Bobomb_OnCollision,
|
|
(void (*)(BobombEntity*))GenericKnockback,
|
|
Bobomb_OnDeath,
|
|
(void (*)(BobombEntity*))GenericConfused,
|
|
Bobomb_OnGrabbed,
|
|
};
|
|
|
|
void (*const gUnk_080CD5EC[])(BobombEntity*) = {
|
|
sub_0802C8D8,
|
|
sub_0802C91C,
|
|
sub_0802C9B8,
|
|
sub_0802CAF8,
|
|
nullsub_150,
|
|
};
|
|
|
|
void (*const gUnk_080CD600[])(BobombEntity*) = {
|
|
sub_0802C820,
|
|
sub_0802C82C,
|
|
sub_0802C834,
|
|
sub_0802C83C,
|
|
nullsub_149,
|
|
sub_0802C8B8,
|
|
};
|
|
|
|
void (*const gUnk_080CD618[])(BobombEntity*) = {
|
|
sub_0802C9D0,
|
|
sub_0802CA10,
|
|
sub_0802CA6C,
|
|
sub_0802CA94,
|
|
};
|
|
// clang-format on
|