Shipwright/soh/src/overlays/actors/ovl_En_Bx/z_en_bx.c

254 lines
8.6 KiB
C

/*
* File: z_en_bx.c
* Overlay: ovl_En_Bx
* Description: Jabu-Jabu Electrified Tentacle
*/
#include "z_en_bx.h"
#include "objects/object_bxa/object_bxa.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
void EnBx_Init(Actor* thisx, GlobalContext* globalCtx);
void EnBx_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnBx_Update(Actor* thisx, GlobalContext* globalCtx);
void EnBx_Draw(Actor* thisx, GlobalContext* globalCtx);
const ActorInit En_Bx_InitVars = {
ACTOR_EN_BX,
ACTORCAT_ENEMY,
FLAGS,
OBJECT_BXA,
sizeof(EnBx),
(ActorFunc)EnBx_Init,
(ActorFunc)EnBx_Destroy,
(ActorFunc)EnBx_Update,
(ActorFunc)EnBx_Draw,
NULL,
};
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_HIT6,
AT_ON | AT_TYPE_ENEMY,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
OC2_NONE,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK1,
{ 0xFFCFFFFF, 0x03, 0x04 },
{ 0xFFCFFFFF, 0x01, 0x00 },
TOUCH_ON | TOUCH_SFX_NORMAL,
BUMP_ON,
OCELEM_NONE,
},
{ 60, 100, 100, { 0, 0, 0 } },
};
static ColliderQuadInit sQuadInit = {
{
COLTYPE_NONE,
AT_ON | AT_TYPE_ENEMY,
AC_NONE,
OC1_NONE,
OC2_NONE,
COLSHAPE_QUAD,
},
{
ELEMTYPE_UNK0,
{ 0xFFCFFFFF, 0x03, 0x04 },
{ 0x00000000, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NORMAL,
BUMP_NONE,
OCELEM_NONE,
},
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
};
void EnBx_Init(Actor* thisx, GlobalContext* globalCtx) {
EnBx* this = (EnBx*)thisx;
Vec3f sp48 = { 0.015f, 0.015f, 0.015f };
Vec3f sp3C = { 0.0f, 0.0f, 0.0f };
static InitChainEntry sInitChain[] = {
ICHAIN_F32(targetArrowOffset, 5300, ICHAIN_STOP),
};
s32 i;
s32 pad;
Actor_ProcessInitChain(&this->actor, sInitChain);
thisx->scale.x = thisx->scale.z = 0.01f;
thisx->scale.y = 0.03f;
thisx->world.pos.y = thisx->world.pos.y - 100.0f;
for (i = 0; i < 4; i++) {
this->unk_184[i] = sp48;
if (i == 0) {
this->unk_1B4[i].x = thisx->shape.rot.x - 0x4000;
}
this->unk_154[i] = thisx->world.pos;
this->unk_154[i].y = thisx->world.pos.y + ((i + 1) * 140.0f);
}
ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 48.0f);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
Collider_InitQuad(globalCtx, &this->colliderQuad);
Collider_SetQuad(globalCtx, &this->colliderQuad, &this->actor, &sQuadInit);
thisx->colChkInfo.mass = MASS_IMMOVABLE;
this->unk_14C = 0;
thisx->uncullZoneDownward = 2000.0f;
if (Flags_GetSwitch(globalCtx, (thisx->params >> 8) & 0xFF)) {
Actor_Kill(&this->actor);
}
thisx->params &= 0xFF;
this->epoch++;
}
void EnBx_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnBx* this = (EnBx*)thisx;
Collider_DestroyCylinder(globalCtx, &this->collider);
}
void func_809D1D0C(Actor* thisx, GlobalContext* globalCtx) {
Vec3f sp5C = { 8000.0f, 15000.0f, 2500.0f };
Vec3f sp50 = { 8000.0f, 10000.0f, 2500.0f };
static Vec3f D_809D2540 = { -8000.0f, 15000.0f, 2500.0f };
static Vec3f D_809D254C = { -8000.0f, 10000.0f, 2500.0f };
Vec3f sp44;
Vec3f sp38;
EnBx* this = (EnBx*)thisx;
Matrix_MultVec3f(&D_809D2540, &sp44);
Matrix_MultVec3f(&D_809D254C, &sp38);
Matrix_MultVec3f(&sp5C, &this->colliderQuad.dim.quad[1]);
Matrix_MultVec3f(&sp50, &this->colliderQuad.dim.quad[0]);
Collider_SetQuadVertices(&this->colliderQuad, &sp38, &sp44, &this->colliderQuad.dim.quad[0],
&this->colliderQuad.dim.quad[1]);
}
void EnBx_Update(Actor* thisx, GlobalContext* globalCtx) {
EnBx* this = (EnBx*)thisx;
Player* player = GET_PLAYER(globalCtx);
s32 i;
s16 tmp32;
s32 tmp33;
if ((thisx->xzDistToPlayer <= 70.0f) || (this->collider.base.atFlags & AT_HIT) ||
(this->collider.base.acFlags & AC_HIT) || (this->colliderQuad.base.atFlags & AT_HIT)) {
if ((thisx->xzDistToPlayer <= 70.0f) || (&player->actor == this->collider.base.at) ||
(&player->actor == this->collider.base.ac) || (&player->actor == this->colliderQuad.base.at)) {
tmp33 = player->invincibilityTimer & 0xFF;
tmp32 = thisx->world.rot.y;
if (!(thisx->params & 0x80)) {
tmp32 = thisx->yawTowardsPlayer;
}
if ((&player->actor != this->collider.base.at) && (&player->actor != this->collider.base.ac) &&
(&player->actor != this->colliderQuad.base.at) && (player->invincibilityTimer <= 0)) {
if (player->invincibilityTimer < -39) {
player->invincibilityTimer = 0;
} else {
player->invincibilityTimer = 0;
globalCtx->damagePlayer(globalCtx, -4);
}
}
func_8002F71C(globalCtx, &this->actor, 6.0f, tmp32, 6.0f);
player->invincibilityTimer = tmp33;
}
this->collider.base.atFlags &= ~AT_HIT;
this->collider.base.acFlags &= ~AC_HIT;
this->colliderQuad.base.atFlags &= ~AT_HIT;
this->colliderQuad.base.at = NULL;
this->collider.base.ac = NULL;
this->collider.base.at = NULL;
this->unk_14C = 0x14;
}
if (this->unk_14C != 0) {
this->unk_14C--;
for (i = 0; i < 4; i++) {
if (!((this->unk_14C + (i << 1)) % 4)) {
static Color_RGBA8 primColor = { 255, 255, 255, 255 };
static Color_RGBA8 envColor = { 200, 255, 255, 255 };
Vec3f pos;
s16 yaw;
yaw = (s32)Rand_CenteredFloat(12288.0f);
yaw = (yaw + (i * 0x4000)) + 0x2000;
pos.x = Rand_CenteredFloat(5.0f) + thisx->world.pos.x;
pos.y = Rand_CenteredFloat(30.0f) + thisx->world.pos.y + 170.0f;
pos.z = Rand_CenteredFloat(5.0f) + thisx->world.pos.z;
EffectSsLightning_Spawn(globalCtx, &pos, &primColor, &envColor, 230, yaw, 6, 0);
}
}
Audio_PlayActorSound2(thisx, NA_SE_EN_BIRI_SPARK - SFX_FLAG);
}
thisx->focus.pos = thisx->world.pos;
Collider_UpdateCylinder(thisx, &this->collider);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
if (thisx->params & 0x80) {
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderQuad.base);
}
}
void EnBx_Draw(Actor* thisx, GlobalContext* globalCtx) {
static void* D_809D2560[] = {
object_bxa_Tex_0024F0,
object_bxa_Tex_0027F0,
object_bxa_Tex_0029F0,
};
EnBx* this = (EnBx*)thisx;
s32 pad;
Mtx* mtx = Graph_Alloc(globalCtx->state.gfxCtx, 4 * sizeof(Mtx));
s16 i;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x0C, mtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_809D2560[this->actor.params & 0x7F]));
gSPSegment(POLY_OPA_DISP++, 0x09,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 16, 16, 1, 0, (globalCtx->gameplayFrames * -10) % 128,
32, 32));
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
if (this->actor.params & 0x80) {
func_809D1D0C(&this->actor, globalCtx);
}
this->unk_14E -= 0xBB8;
thisx->scale.z = thisx->scale.x = (Math_CosS(this->unk_14E) * 0.0075f) + 0.015f;
for (i = 3; i >= 0; i--) {
s16 off = (0x2000 * i);
this->unk_184[i].z = this->unk_184[i].x = (Math_CosS(this->unk_14E + off) * 0.0075f) + 0.015f;
this->unk_1B4[i].x = thisx->shape.rot.x;
this->unk_1B4[i].y = thisx->shape.rot.y;
this->unk_1B4[i].z = thisx->shape.rot.z;
}
for (i = 0; i < 4; i++, mtx++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate(this->unk_154[i].x, this->unk_154[i].y, this->unk_154[i].z, MTXMODE_NEW);
Matrix_RotateZYX(this->unk_1B4[i].x, this->unk_1B4[i].y, this->unk_1B4[i].z, MTXMODE_APPLY);
Matrix_Scale(this->unk_184[i].x, this->unk_184[i].y, this->unk_184[i].z, MTXMODE_APPLY);
MATRIX_TOMTX(mtx);
FrameInterpolation_RecordCloseChild();
}
gSPDisplayList(POLY_OPA_DISP++, object_bxa_DL_0022F0);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}