mirror of https://github.com/zeldaret/tmc.git
220 lines
5.6 KiB
C
220 lines
5.6 KiB
C
/**
|
|
* @file tektite.c
|
|
* @ingroup Enemies
|
|
*
|
|
* @brief Tektite enemy
|
|
*/
|
|
|
|
#include "collision.h"
|
|
#include "enemy.h"
|
|
#include "functions.h"
|
|
|
|
static void sub_0802F45C(Entity* this);
|
|
static void Tektite_OnTick(Entity*);
|
|
static void Tektite_OnCollision(Entity*);
|
|
static void Tektite_OnConfused(Entity*);
|
|
static void Tektite_OnGrabbed(Entity*);
|
|
static void sub_0802F210(Entity*);
|
|
static void sub_0802F284(Entity*);
|
|
static void sub_0802F300(Entity*);
|
|
static void sub_0802F3F4(Entity*);
|
|
|
|
static void (*const Tektite_Functions[])(Entity*) = {
|
|
Tektite_OnTick, Tektite_OnCollision, GenericKnockback, GenericDeath, Tektite_OnConfused, Tektite_OnGrabbed,
|
|
};
|
|
|
|
void Tektite(Entity* this) {
|
|
EnemyFunctionHandler(this, Tektite_Functions);
|
|
SetChildOffset(this, 0, 1, -0x10);
|
|
}
|
|
|
|
void Tektite_OnTick(Entity* this) {
|
|
static void (*const actionFuncs[])(Entity*) = {
|
|
sub_0802F210,
|
|
sub_0802F284,
|
|
sub_0802F300,
|
|
sub_0802F3F4,
|
|
};
|
|
actionFuncs[this->action](this);
|
|
}
|
|
|
|
static const u8 gUnk_080CDEF8[] = {
|
|
0x18,
|
|
0x28,
|
|
0x38,
|
|
0x48,
|
|
};
|
|
|
|
void Tektite_OnCollision(Entity* this) {
|
|
u32 bVar1;
|
|
u32 uVar2;
|
|
|
|
if (this->confusedTime != 0) {
|
|
Create0x68FX(this, FX_STARS);
|
|
}
|
|
EnemyFunctionHandlerAfterCollision(this, Tektite_Functions);
|
|
if ((this->contactFlags & 0x80) != 0) {
|
|
switch (this->contactFlags & 0x3f) {
|
|
case 0x14:
|
|
this->action = 1;
|
|
this->subAction = 0;
|
|
if (this->type != 0) {
|
|
this->timer = 192;
|
|
} else {
|
|
this->timer = gUnk_080CDEF8[Random() & 3];
|
|
}
|
|
this->subtimer = 0;
|
|
*(u8*)&this->field_0x7c = 0;
|
|
if (this->z.HALF.HI != 0) {
|
|
this->zVelocity >>= 2;
|
|
} else {
|
|
this->zVelocity = 0;
|
|
}
|
|
InitializeAnimation(this, 0);
|
|
break;
|
|
case 0xe:
|
|
case 0x15:
|
|
this->health = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Tektite_OnGrabbed(Entity* this) {
|
|
}
|
|
|
|
void Tektite_OnConfused(Entity* this) {
|
|
GenericConfused(this);
|
|
if (this->z.HALF.HI != 0) {
|
|
GravityUpdate(this, this->field_0x80.HWORD);
|
|
}
|
|
}
|
|
|
|
void sub_0802F210(Entity* this) {
|
|
u32 temp;
|
|
u32 temp2;
|
|
|
|
sub_0804A720(this);
|
|
this->action = 1;
|
|
this->subAction = 0;
|
|
this->timer = gUnk_080CDEF8[Random() & 3];
|
|
this->timer += (Random() & 0x1f);
|
|
this->subtimer = 0;
|
|
*(u8*)&this->field_0x7c = 0;
|
|
|
|
this->field_0x80.HWORD = this->type == 0 ? Q_8_8(24.0) : Q_8_8(40.0);
|
|
|
|
this->field_0x82.HWORD = this->type == 0 ? (Q_16_16(2.5) >> 4) : (Q_16_16(3.0) >> 4);
|
|
|
|
InitializeAnimation(this, 0);
|
|
}
|
|
|
|
void sub_0802F284(Entity* this) {
|
|
if (this->timer > 0x60) {
|
|
UpdateAnimationVariableFrames(this, 2);
|
|
} else {
|
|
GetNextFrame(this);
|
|
}
|
|
if (this->timer != 0) {
|
|
this->timer--;
|
|
} else if (this->subtimer != 0) {
|
|
if (this->frame & ANIM_DONE) {
|
|
this->action = 2;
|
|
this->timer = 16;
|
|
this->subtimer = this->type;
|
|
this->zVelocity = this->field_0x82.HWORD << 4;
|
|
sub_0802F45C(this);
|
|
InitializeAnimation(this, 2);
|
|
}
|
|
} else if (this->frame & ANIM_DONE) {
|
|
this->subtimer = 64;
|
|
InitializeAnimation(this, 1);
|
|
}
|
|
}
|
|
|
|
void sub_0802F300(Entity* this) {
|
|
s32 temp;
|
|
u32 rand;
|
|
|
|
GetNextFrame(this);
|
|
ProcessMovement0(this);
|
|
temp = this->z.HALF.HI;
|
|
rand = Random() & 0xf;
|
|
|
|
if (sub_080044EC(this, this->field_0x80.HWORD) == 1) {
|
|
this->action = 3;
|
|
this->subAction = 0;
|
|
if (this->type != 0) {
|
|
rand = 0;
|
|
}
|
|
|
|
if (rand == 0) {
|
|
this->timer = 192;
|
|
} else {
|
|
this->timer = gUnk_080CDEF8[rand & 3] + rand;
|
|
}
|
|
this->subtimer = 0;
|
|
InitializeAnimation(this, 3);
|
|
return;
|
|
} else if (this->collisions != COL_NONE) {
|
|
sub_0800417E(this, this->collisions);
|
|
} else if ((GetVvvAtEntity(this) & 0xf0) == 0x50) { // VVV_240 and VVV_241?
|
|
this->direction = (this->direction + 0x10) & 0x1f;
|
|
}
|
|
|
|
if (--this->timer == 0) {
|
|
this->timer = 16;
|
|
if (this->subtimer != 0) {
|
|
this->subtimer--;
|
|
sub_0802F45C(this);
|
|
}
|
|
}
|
|
|
|
if ((this->subAction == 0) && (temp < this->z.HALF.HI)) {
|
|
InitializeAnimation(this, 4);
|
|
this->subAction = 1;
|
|
}
|
|
|
|
if (temp < -0xc) {
|
|
this->spriteRendering.b3 = 1;
|
|
this->spriteOrientation.flipY = 1;
|
|
} else {
|
|
this->spriteRendering.b3 = 2;
|
|
this->spriteOrientation.flipY = 2;
|
|
}
|
|
}
|
|
|
|
void sub_0802F3F4(Entity* this) {
|
|
|
|
GetNextFrame(this);
|
|
|
|
if (this->frame & ANIM_DONE) {
|
|
if ((*(u8*)&this->field_0x7c.HALF.LO < 2) && ((this->type % 2) != 0)) {
|
|
this->action = 2;
|
|
this->timer = 16;
|
|
this->subtimer = this->type;
|
|
this->zVelocity = this->field_0x82.HWORD << 4;
|
|
(*(u8*)&this->field_0x7c.HALF.LO)++;
|
|
sub_0802F45C(this);
|
|
InitializeAnimation(this, 2);
|
|
} else {
|
|
this->action = 1;
|
|
*(u8*)&this->field_0x7c.HALF.LO = 0;
|
|
InitializeAnimation(this, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void sub_0802F45C(Entity* this) {
|
|
u32 temp;
|
|
|
|
if (sub_08049FA0(this) == 0) {
|
|
this->direction = sub_08049EE4(this);
|
|
} else if (sub_08049FDC(this, 1) != 0) {
|
|
this->direction = sub_08049F84(this, 1);
|
|
} else {
|
|
temp = (Random() & 0xf) + 0x18;
|
|
this->direction = (temp + this->direction) & 0x1f;
|
|
}
|
|
}
|