/** * @file spikedBeetle.c * @ingroup Enemies * * @brief Spiked Beetle enemy */ #include "enemy.h" #include "functions.h" extern u32 sub_0804A024(Entity*, u32, u32); extern Entity* gUnk_020000B0; void sub_0802B9B4(Entity*); void sub_0802B7A4(Entity*); void sub_0802B960(Entity*); extern void (*const SpikedBeetle_Functions[])(Entity*); extern void (*const gUnk_080CD2F0[])(Entity*); extern const u8 gUnk_080CD314[]; extern const s8 gUnk_080CD318[]; void SpikedBeetle(Entity* this) { EnemyFunctionHandler(this, SpikedBeetle_Functions); SetChildOffset(this, 0, 1, -0x10); } void SpikedBeetle_OnTick(Entity* this) { gUnk_080CD2F0[this->action](this); } void SpikedBeetle_OnCollision(Entity* this) { switch (this->contactFlags & 0x7f) { case 0: case 4: case 5: case 6: case 8: case 9: case 10: case 0xb: case 0xc: if (this->action == 4) { this->timer = 1; } break; case 2: case 3: case 0x16: case 0x18: case 0x19: case 0x1a: case 0x1d: if (this->action < 6) { this->action = 6; this->zVelocity = Q_16_16(1.5); this->speed = 0xc0; this->direction = this->knockbackDirection; this->knockbackDuration = 0; this->iframes = -8; this->hitType = 100; InitializeAnimation(this, 9); } } if (this->confusedTime) { Create0x68FX(this, FX_STARS); } EnemyFunctionHandlerAfterCollision(this, SpikedBeetle_Functions); } void SpikedBeetle_OnGrabbed(Entity* this) { /* ... */ } void sub_0802B72C(Entity* this) { sub_0804A720(this); this->timer = 1; this->animationState = 0xff; sub_0802B7A4(this); } void sub_0802B744(Entity* this) { u32 direction; GetNextFrame(this); if (sub_08049FDC(this, 1) && (direction = sub_0804A024(this, 1, 0xc), direction != 0xff)) { this->action = 3; this->timer = 0x1e; this->direction = DirectionRound(direction); InitializeAnimation(this, 8); } else { if (--this->timer == 0) { this->action = 2; this->timer = 0x1e; } else { if (!ProcessMovement0(this)) { this->timer = 1; } } } } void sub_0802B7A4(Entity* this) { if (--this->timer == 0) { this->action = 1; this->timer = gUnk_080CD314[Random() & 3]; this->speed = 0x60; sub_0802B960(this); if (this->direction != 0xff) { u32 animation = this->direction >> 3; if (animation != this->animationState) { this->animationState = animation & 3; InitializeAnimation(this, animation); } } } } void sub_0802B7FC(Entity* this) { GetNextFrame(this); if (--this->timer == 0) { this->action = 4; this->timer = 0x78; this->speed = 0x1c0; } } void sub_0802B820(Entity* this) { if (!ProcessMovement2(this)) { this->timer = 1; } GetNextFrame(this); if (--this->timer == 0) { sub_0802B9B4(this); } else if (sub_08049FDC(this, 1)) { if ((this->timer & 0xf) == 0) { sub_08004596(this, GetFacingDirection(this, gUnk_020000B0)); } } else { sub_0802B9B4(this); } } void sub_0802B880(Entity* this) { if (--this->timer == 0) { this->action = 2; this->timer = 0x3c; this->animationState = DirectionToAnimationState(this->direction); InitializeAnimation(this, this->animationState); } } void sub_0802B8B0(Entity* this) { ProcessMovement2(this); switch (sub_080044EC(this, 0x1800)) { case 0: this->action = 7; this->timer = 0x96; /* fallthrough */ case 1: EnqueueSFX(SFX_12B); break; } } void sub_0802B8E0(Entity* this) { if (--this->timer) { if (this->timer < 0x3c && (this->timer & 1)) { this->spriteOffsetX += gUnk_080CD318[(this->timer >> 1) & 3]; } } else { this->action = 8; this->zVelocity = Q_16_16(1.0); this->speed = 0x60; this->hitType = 99; InitializeAnimation(this, this->animationState); EnqueueSFX(SFX_12B); } } void sub_0802B948(Entity* this) { if (!GravityUpdate(this, 0x1800)) { this->action = 1; this->timer = 1; } } void sub_0802B960(Entity* this) { if (sub_08049FDC(this, 1)) { if ((Random() & 7) == 0) { this->direction = DirectionRoundUp(sub_08049F84(this, 1)); return; } } else if (!sub_08049FA0(this)) { if ((Random() & 3) == 0) { this->direction = DirectionRoundUp(sub_08049EE4(this)); return; } } this->direction = DirectionRound(Random()); } void sub_0802B9B4(Entity* this) { this->action = 5; this->timer = 0x3c; this->animationState = (this->direction >> 3) & 3; InitializeAnimation(this, this->animationState + 4); } // clang-format off void (*const SpikedBeetle_Functions[])(Entity*) = { SpikedBeetle_OnTick, SpikedBeetle_OnCollision, GenericKnockback, GenericDeath, GenericConfused, SpikedBeetle_OnGrabbed, }; void (*const gUnk_080CD2F0[])(Entity*) = { sub_0802B72C, sub_0802B744, sub_0802B7A4, sub_0802B7FC, sub_0802B820, sub_0802B880, sub_0802B8B0, sub_0802B8E0, sub_0802B948, }; const u8 gUnk_080CD314[] = { 0x30, 0x48, 0x60, 0x78, }; const s8 gUnk_080CD318[] = { 1, -1, -1, 1, }; // clang-format on