mirror of https://github.com/zeldaret/tmc.git
207 lines
5.1 KiB
C
207 lines
5.1 KiB
C
/**
|
|
* @file rope.c
|
|
* @ingroup Enemies
|
|
*
|
|
* @brief Rope enemy
|
|
*/
|
|
|
|
#include "enemy.h"
|
|
#include "physics.h"
|
|
|
|
void Rope_OnTick(Entity*);
|
|
void Rope_OnCollision(Entity*);
|
|
void Rope_OnGrabbed(Entity*);
|
|
void sub_08031434(Entity*);
|
|
void sub_08031480(Entity*);
|
|
void sub_080314FC(Entity*);
|
|
void sub_080315BC(Entity*);
|
|
void sub_0803140C(Entity*);
|
|
void sub_08031418(Entity*);
|
|
void sub_08031420(Entity*);
|
|
|
|
static void (*const Rope_Functions[6])(Entity*) = {
|
|
Rope_OnTick, Rope_OnCollision, GenericKnockback, GenericDeath, GenericConfused, Rope_OnGrabbed,
|
|
};
|
|
|
|
extern Entity* gUnk_020000B0;
|
|
|
|
void sub_08031600(Entity*);
|
|
u32 sub_0803163C(Entity*);
|
|
|
|
void Rope(Entity* this) {
|
|
EnemyFunctionHandler(this, Rope_Functions);
|
|
SetChildOffset(this, 0, 1, -16);
|
|
}
|
|
|
|
void Rope_OnTick(Entity* this) {
|
|
static void (*const actionFuncs[4])(Entity*) = {
|
|
sub_08031434,
|
|
sub_08031480,
|
|
sub_080314FC,
|
|
sub_080315BC,
|
|
};
|
|
actionFuncs[this->action](this);
|
|
}
|
|
|
|
void Rope_OnCollision(Entity* this) {
|
|
if (this->action == 3) {
|
|
this->subtimer = 30;
|
|
this->field_0x78.HALF.LO = 0x3c;
|
|
sub_08031600(this);
|
|
}
|
|
if (this->confusedTime) {
|
|
Create0x68FX(this, FX_STARS);
|
|
}
|
|
EnemyFunctionHandlerAfterCollision(this, Rope_Functions);
|
|
}
|
|
|
|
void Rope_OnGrabbed(Entity* this) {
|
|
static void (*const subActionFuncs[3])(Entity*) = {
|
|
sub_0803140C,
|
|
sub_08031418,
|
|
sub_08031420,
|
|
};
|
|
if (sub_0806F520(this)) {
|
|
subActionFuncs[this->subAction](this);
|
|
}
|
|
}
|
|
|
|
void sub_0803140C(Entity* this) {
|
|
this->subAction = 1;
|
|
this->gustJarTolerance = 0x3c;
|
|
}
|
|
|
|
void sub_08031418(Entity* this) {
|
|
sub_0806F4E8(this);
|
|
}
|
|
|
|
void sub_08031420(Entity* this) {
|
|
if (sub_0806F3E4(this)) {
|
|
GenericDeath(this);
|
|
}
|
|
}
|
|
|
|
void sub_08031434(Entity* this) {
|
|
|
|
sub_0804A720(this);
|
|
this->animationState = 0xff;
|
|
this->gustJarFlags = 1;
|
|
this->field_0x7a.HWORD = this->speed;
|
|
if (!(this->type)) {
|
|
sub_08031600(this);
|
|
} else {
|
|
this->action = 1;
|
|
this->subAction = 0;
|
|
this->spriteSettings.draw = (this->spriteSettings.draw & 0xfc);
|
|
this->z.HALF.HI = -0x80;
|
|
this->frameIndex = 0xff;
|
|
}
|
|
}
|
|
|
|
void sub_08031480(Entity* this) {
|
|
if (this->subAction == 0) {
|
|
if (this->timer != 0) {
|
|
this->timer--;
|
|
} else {
|
|
sub_08031600(this);
|
|
this->action = 1;
|
|
this->subAction = 1;
|
|
this->spriteSettings.draw = 3;
|
|
this->spriteRendering.b3 = 1;
|
|
this->spriteOrientation.flipY = 1;
|
|
SoundReq(SFX_12D);
|
|
}
|
|
} else {
|
|
if (GravityUpdate(this, Q_8_8(24.0)) == 0) {
|
|
this->action = 2;
|
|
this->subtimer = 15;
|
|
this->spriteSettings.draw = 1;
|
|
UpdateSpriteForCollisionLayer(this);
|
|
EnqueueSFX(SFX_WATER_SPLASH);
|
|
}
|
|
}
|
|
}
|
|
void sub_080314FC(Entity* this) {
|
|
u32 u;
|
|
|
|
GetNextFrame(this);
|
|
if (this->subtimer) {
|
|
this->subtimer--;
|
|
} else {
|
|
if (this->field_0x78.HALF.LO) {
|
|
this->field_0x78.HALF.LO--;
|
|
}
|
|
if (sub_08049FA0(this)) {
|
|
if (!(this->field_0x78.HALF.LO)) {
|
|
if (sub_08049FDC(this, 1)) {
|
|
u = sub_0804A044(this, gUnk_020000B0, 0xc);
|
|
if (u != 0xff) {
|
|
this->action = 3;
|
|
this->timer = 30;
|
|
this->field_0x7a.HWORD = this->speed = 0x1a0;
|
|
this->direction = u;
|
|
this->animationState = this->direction >> 3;
|
|
InitializeAnimation(this, this->animationState + 4);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if ((Random() & 1)) {
|
|
this->direction = DirectionRoundUp(sub_08049EE4(this));
|
|
u = this->direction >> 3;
|
|
if (u != this->animationState) {
|
|
this->animationState = u;
|
|
InitializeAnimation(this, u);
|
|
}
|
|
}
|
|
}
|
|
if (--this->timer == 0) {
|
|
sub_08031600(this);
|
|
}
|
|
sub_0803163C(this);
|
|
}
|
|
}
|
|
|
|
void sub_080315BC(Entity* this) {
|
|
if (this->timer != 0) {
|
|
this->timer--;
|
|
UpdateAnimationVariableFrames(this, 2);
|
|
} else {
|
|
if (sub_08049FA0(this)) {
|
|
GetNextFrame(this);
|
|
if (sub_0803163C(this)) {
|
|
return;
|
|
}
|
|
}
|
|
this->field_0x78.HALF.LO = 0x1e;
|
|
sub_08031600(this);
|
|
}
|
|
}
|
|
|
|
void sub_08031600(Entity* this) {
|
|
u32 r;
|
|
this->action = 2;
|
|
this->timer = (Random() & 0x30) + 60;
|
|
this->speed = 0x80;
|
|
this->field_0x7a.HWORD = 0x80;
|
|
r = Random() & 0x18;
|
|
this->direction = r;
|
|
r = r / 8;
|
|
if (r != this->animationState) {
|
|
this->animationState = r;
|
|
InitializeAnimation(this, r);
|
|
}
|
|
}
|
|
|
|
u32 sub_0803163C(Entity* this) {
|
|
u32 h;
|
|
if (GetTileUnderEntity(this) == 0x13) {
|
|
h = this->field_0x7a.HWORD / 2;
|
|
} else {
|
|
h = this->field_0x7a.HWORD;
|
|
}
|
|
this->speed = h;
|
|
return ProcessMovement0(this);
|
|
}
|