1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-03 06:24:30 +00:00

EnVali OK and documented, object_vali and object_bl completely analysed and documented (#845)

* OK

* Some naming

* Name more, correct typo in Biri, extract skel

* just Draws need names, fix typos in bili and warp1

* Decompile object_vali and add symbols

* Few more names

* Bari naming done

* object_bl completed, symbols added

* Label object_bl

* Formatter

* delete asm

* review changes

* review changes

* review
This commit is contained in:
EllipticEllipsis 2021-06-14 23:11:14 +01:00 committed by GitHub
parent a4c606c522
commit 566d107e55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 908 additions and 2729 deletions

View file

@ -5,6 +5,7 @@
*/
#include "z_en_bili.h"
#include "objects/object_bl/object_bl.h"
#define FLAGS 0x00005005
@ -112,18 +113,14 @@ static InitChainEntry sInitChain[] = {
ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP),
};
extern AnimationHeader D_06000024;
extern AnimationHeader D_06000064;
extern AnimationHeader D_060000A4;
extern SkeletonHeader D_06005848;
void EnBili_Init(Actor* thisx, GlobalContext* globalCtx) {
EnBili* this = THIS;
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 17.0f);
this->actor.shape.shadowAlpha = 155;
SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005848, &D_060000A4, this->jointTable, this->morphTable, 5);
SkelAnime_Init(globalCtx, &this->skelAnime, &gBiriSkel, &gBiriDefaultAnim, this->jointTable, this->morphTable,
EN_BILI_LIMB_MAX);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
@ -160,7 +157,7 @@ void EnBili_SetupFloatIdle(EnBili* this) {
* Separates the Biri spawned by a dying EnVali.
*/
void EnBili_SetupSpawnedFlyApart(EnBili* this) {
Animation_PlayLoop(&this->skelAnime, &D_060000A4);
Animation_PlayLoop(&this->skelAnime, &gBiriDefaultAnim);
this->timer = 25;
this->actor.velocity.y = 6.0f;
this->actor.gravity = -0.3f;
@ -173,7 +170,7 @@ void EnBili_SetupSpawnedFlyApart(EnBili* this) {
* Used for both touching player/player's shield and being hit with sword. What to do next is determined by params.
*/
void EnBili_SetupDischargeLightning(EnBili* this) {
Animation_PlayLoop(&this->skelAnime, &D_06000024);
Animation_PlayLoop(&this->skelAnime, &gBiriDischargeLightningAnim);
this->timer = 10;
this->actionFunc = EnBili_DischargeLightning;
this->actor.speedXZ = 0.0f;
@ -181,7 +178,7 @@ void EnBili_SetupDischargeLightning(EnBili* this) {
}
void EnBili_SetupClimb(EnBili* this) {
Animation_PlayOnce(&this->skelAnime, &D_06000064);
Animation_PlayOnce(&this->skelAnime, &gBiriClimbAnim);
this->collider.base.atFlags &= ~AT_ON;
this->actionFunc = EnBili_Climb;
this->actor.speedXZ = 0.0f;
@ -194,7 +191,7 @@ void EnBili_SetupApproachPlayer(EnBili* this) {
}
void EnBili_SetupSetNewHomeHeight(EnBili* this) {
Animation_PlayLoop(&this->skelAnime, &D_060000A4);
Animation_PlayLoop(&this->skelAnime, &gBiriDefaultAnim);
this->timer = 96;
this->actor.speedXZ = 0.9f;
this->collider.base.atFlags |= AT_ON;
@ -203,8 +200,8 @@ void EnBili_SetupSetNewHomeHeight(EnBili* this) {
}
void EnBili_SetupRecoil(EnBili* this) {
if (this->skelAnime.animation != &D_060000A4) {
Animation_PlayLoop(&this->skelAnime, &D_060000A4);
if (this->skelAnime.animation != &gBiriDefaultAnim) {
Animation_PlayLoop(&this->skelAnime, &gBiriDefaultAnim);
}
this->actor.world.rot.y = Actor_WorldYawTowardPoint(&this->actor, &this->collider.base.ac->prevPos) + 0x8000;
@ -218,7 +215,7 @@ void EnBili_SetupRecoil(EnBili* this) {
*/
void EnBili_SetupBurnt(EnBili* this) {
if (this->actionFunc == EnBili_Climb) {
Animation_PlayLoop(&this->skelAnime, &D_060000A4);
Animation_PlayLoop(&this->skelAnime, &gBiriDefaultAnim);
}
this->timer = 20;
@ -285,27 +282,27 @@ void EnBili_SetupFrozen(EnBili* this, GlobalContext* globalCtx) {
/**
* Changes the texture displayed on the oral arms limb using the current frame.
*/
void EnBili_UpdateOralArmsIndex(EnBili* this) {
void EnBili_UpdateTentaclesIndex(EnBili* this) {
s16 curFrame = this->skelAnime.curFrame;
s16 temp; // Not strictly necessary, but avoids a few s16 casts
if (this->actionFunc == EnBili_DischargeLightning) {
temp = 3 - curFrame;
this->oralArmsTexIndex = (ABS(temp) + 5) % 8;
this->tentaclesTexIndex = (ABS(temp) + 5) % 8;
} else if (this->actionFunc == EnBili_Climb) {
if (curFrame < 10) {
if (curFrame <= 9) {
temp = curFrame >> 1;
this->oralArmsTexIndex = CLAMP_MAX(temp, 3);
} else if (curFrame < 19) {
this->tentaclesTexIndex = CLAMP_MAX(temp, 3);
} else if (curFrame <= 18) {
temp = 17 - curFrame;
this->oralArmsTexIndex = CLAMP_MIN(temp, 0) >> 1;
} else if (curFrame < 37) {
this->oralArmsTexIndex = ((36 - curFrame) / 3) + 2;
this->tentaclesTexIndex = CLAMP_MIN(temp, 0) >> 1;
} else if (curFrame <= 36) {
this->tentaclesTexIndex = ((36 - curFrame) / 3) + 2;
} else {
this->oralArmsTexIndex = (40 - curFrame) >> 1;
this->tentaclesTexIndex = (40 - curFrame) >> 1;
}
} else {
this->oralArmsTexIndex = curFrame >> 1;
this->tentaclesTexIndex = curFrame >> 1;
}
}
@ -355,6 +352,7 @@ void EnBili_SpawnedFlyApart(EnBili* this, GlobalContext* globalCtx) {
if (this->timer != 0) {
this->timer--;
}
if (this->timer == 0) {
EnBili_SetupFloatIdle(this);
}
@ -383,7 +381,9 @@ void EnBili_DischargeLightning(EnBili* this, GlobalContext* globalCtx) {
if (this->timer != 0) {
this->timer--;
}
this->actor.velocity.y *= -1.0f;
if ((this->timer == 0) && Animation_OnFrame(&this->skelAnime, 0.0f)) {
if (this->actor.params == EN_BILI_TYPE_DYING) {
EnBili_SetupDie(this);
@ -463,6 +463,7 @@ void EnBili_Burnt(EnBili* this, GlobalContext* globalCtx) {
if (this->timer != 0) {
this->timer--;
}
if (this->timer == 0) {
EnBili_SetupDie(this);
}
@ -518,9 +519,11 @@ void EnBili_Stunned(EnBili* this, GlobalContext* globalCtx) {
if (this->timer != 0) {
this->timer--;
}
if (this->actor.bgCheckFlags & 2) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND);
}
if (this->timer == 0) {
EnBili_SetupFloatIdle(this);
}
@ -530,6 +533,7 @@ void EnBili_Frozen(EnBili* this, GlobalContext* globalCtx) {
if (this->timer != 0) {
this->timer--;
}
if (!(this->actor.flags & 0x8000)) {
this->actor.gravity = -1.0f;
}
@ -548,6 +552,7 @@ void EnBili_UpdateDamage(EnBili* this, GlobalContext* globalCtx) {
if ((this->actor.colChkInfo.health != 0) && (this->collider.base.acFlags & AC_HIT)) {
this->collider.base.acFlags &= ~AC_HIT;
func_80035650(&this->actor, &this->collider.info, 1);
if ((this->actor.colChkInfo.damageEffect != 0) || (this->actor.colChkInfo.damage != 0)) {
if (Actor_ApplyDamage(&this->actor) == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_BIRI_DEAD);
@ -579,9 +584,10 @@ void EnBili_UpdateDamage(EnBili* this, GlobalContext* globalCtx) {
EnBili_SetupFrozen(this, globalCtx);
} else if (damageEffect == BIRI_DMGEFF_SLINGSHOT) {
EnBili_SetupRecoil(this);
} else { // Only BIRI_DMGEFF_NONE
} else {
EnBili_SetupBurnt(this);
}
if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x1F820) { // DMG_ARROW
this->actor.flags |= 0x10;
}
@ -602,7 +608,7 @@ void EnBili_Update(Actor* thisx, GlobalContext* globalCtx2) {
this->actionFunc(this, globalCtx);
if (this->actionFunc != EnBili_Die) {
EnBili_UpdateOralArmsIndex(this);
EnBili_UpdateTentaclesIndex(this);
if (Animation_OnFrame(&this->skelAnime, 9.0f)) {
if ((this->actionFunc == EnBili_FloatIdle) || (this->actionFunc == EnBili_SetNewHomeHeight) ||
(this->actionFunc == EnBili_ApproachPlayer) || (this->actionFunc == EnBili_Recoil)) {
@ -635,7 +641,7 @@ void EnBili_Update(Actor* thisx, GlobalContext* globalCtx2) {
}
}
// Draw assaciated functions
// Draw and associated functions
void EnBili_PulseLimb3(EnBili* this, f32 frame, Vec3f* arg2) {
f32 cos;
@ -655,9 +661,10 @@ void EnBili_PulseLimb3(EnBili* this, f32 frame, Vec3f* arg2) {
arg2->y = (0.31f * cos) + 1.0f;
arg2->x = 1.0f - (0.4f * cos);
}
arg2->z = arg2->x;
} else if (this->actionFunc == EnBili_Stunned) {
sin = sinf(this->timer * (M_PI * 0.1f)) * 0.08f;
sin = sinf((M_PI * 0.1f) * this->timer) * 0.08f;
arg2->x -= sin;
arg2->y += sin;
arg2->z -= sin;
@ -686,7 +693,7 @@ void EnBili_PulseLimb2(EnBili* this, f32 frame, Vec3f* arg2) {
}
arg2->z = arg2->x;
} else if (this->actionFunc == EnBili_Stunned) {
sin = sinf(this->timer * (M_PI * 0.1f)) * 0.08f;
sin = sinf((M_PI * 0.1f) * this->timer) * 0.08f;
arg2->x += sin;
arg2->y -= sin;
arg2->z += sin;
@ -722,11 +729,11 @@ s32 EnBili_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList
Vec3f limbScale = { 1.0f, 1.0f, 1.0f };
f32 curFrame = this->skelAnime.curFrame;
if (limbIndex == EN_BILI_LIMB_STOMACH) {
if (limbIndex == EN_BILI_LIMB_OUTER_HOOD) {
EnBili_PulseLimb3(this, curFrame, &limbScale);
} else if (limbIndex == EN_BILI_LIMB_BELL) {
} else if (limbIndex == EN_BILI_LIMB_INNER_HOOD) {
EnBili_PulseLimb2(this, curFrame, &limbScale);
} else if (limbIndex == EN_BILI_LIMB_ORALARMS) {
} else if (limbIndex == EN_BILI_LIMB_TENTACLES) {
EnBili_PulseLimb4(this, curFrame, &limbScale);
rot->y = (Camera_GetCamDirYaw(ACTIVE_CAM) - this->actor.shape.rot.y) + 0x8000;
}
@ -735,8 +742,9 @@ s32 EnBili_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList
return false;
}
static u64* sOralArmsTextures[] = {
0x06000E08, 0x06001708, 0x06002008, 0x06002908, 0x06003208, 0x06003B08, 0x06004408, 0x06004D08,
static void* sTentaclesTextures[] = {
gBiriTentacles0Tex, gBiriTentacles1Tex, gBiriTentacles2Tex, gBiriTentacles3Tex,
gBiriTentacles4Tex, gBiriTentacles5Tex, gBiriTentacles6Tex, gBiriTentacles7Tex,
};
static Gfx D_809C16F0[] = {
@ -757,9 +765,9 @@ void EnBili_Draw(Actor* thisx, GlobalContext* globalCtx) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_bili.c", 1521);
func_80093D84(globalCtx->state.gfxCtx);
this->oralArmsTexIndex = CLAMP_MAX(this->oralArmsTexIndex, 7);
this->tentaclesTexIndex = CLAMP_MAX(this->tentaclesTexIndex, 7);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sOralArmsTextures[this->oralArmsTexIndex]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTentaclesTextures[this->tentaclesTexIndex]));
if ((this->actionFunc == EnBili_DischargeLightning) && ((this->timer & 1) != 0)) {
gSPSegment(POLY_XLU_DISP++, 0x09, &D_809C16F0);

View file

@ -8,15 +8,24 @@ struct EnBili;
typedef void (*EnBiliActionFunc)(struct EnBili*, GlobalContext*);
typedef enum {
/* 0 */ EN_BILI_LIMB_NONE,
/* 1 */ EN_BILI_LIMB_ROOT,
/* 2 */ EN_BILI_LIMB_INNER_HOOD,
/* 3 */ EN_BILI_LIMB_OUTER_HOOD,
/* 4 */ EN_BILI_LIMB_TENTACLES,
/* 5 */ EN_BILI_LIMB_MAX
} EnBiliLimb;
typedef struct EnBili {
/* 0x0000 */ Actor actor;
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ EnBiliActionFunc actionFunc;
/* 0x0194 */ u8 oralArmsTexIndex;
/* 0x0194 */ u8 tentaclesTexIndex;
/* 0x0195 */ u8 playFlySound;
/* 0x0196 */ s16 timer;
/* 0x0198 */ Vec3s jointTable[5];
/* 0x01B6 */ Vec3s morphTable[5];
/* 0x0198 */ Vec3s jointTable[EN_BILI_LIMB_MAX];
/* 0x01B6 */ Vec3s morphTable[EN_BILI_LIMB_MAX];
/* 0x01D4 */ ColliderCylinder collider;
} EnBili; // size = 0x0220
@ -28,12 +37,4 @@ typedef enum {
/* 1 */ EN_BILI_TYPE_DYING
} EnBiliType;
typedef enum {
/* 0 */ EN_BILI_LIMB_NONE,
/* 1 */ EN_BILI_LIMB_1,
/* 2 */ EN_BILI_LIMB_BELL,
/* 3 */ EN_BILI_LIMB_STOMACH,
/* 4 */ EN_BILI_LIMB_ORALARMS
} EnBiliLimb;
#endif

View file

@ -5,6 +5,7 @@
*/
#include "z_en_vali.h"
#include "objects/object_vali/object_vali.h"
#define FLAGS 0x00001015
@ -15,16 +16,21 @@ void EnVali_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnVali_Update(Actor* thisx, GlobalContext* globalCtx);
void EnVali_Draw(Actor* thisx, GlobalContext* globalCtx);
extern UNK_TYPE D_06000710;
extern UNK_TYPE D_06000854;
extern UNK_TYPE D_06000B34;
extern UNK_TYPE D_060014AC;
extern UNK_TYPE D_06002610;
extern UNK_TYPE D_06002740;
extern UNK_TYPE D_060027D8;
extern UNK_TYPE D_06004848;
void EnVali_SetupLurk(EnVali* this);
void EnVali_SetupDropAppear(EnVali* this);
void EnVali_Lurk(EnVali* this, GlobalContext* globalCtx);
void EnVali_DropAppear(EnVali* this, GlobalContext* globalCtx);
void EnVali_FloatIdle(EnVali* this, GlobalContext* globalCtx);
void EnVali_Attacked(EnVali* this, GlobalContext* globalCtx);
void EnVali_Retaliate(EnVali* this, GlobalContext* globalCtx);
void EnVali_MoveArmsDown(EnVali* this, GlobalContext* globalCtx);
void EnVali_Burnt(EnVali* this, GlobalContext* globalCtx);
void EnVali_DivideAndDie(EnVali* this, GlobalContext* globalCtx);
void EnVali_Stunned(EnVali* this, GlobalContext* globalCtx);
void EnVali_Frozen(EnVali* this, GlobalContext* globalCtx);
void EnVali_ReturnToLurk(EnVali* this, GlobalContext* globalCtx);
/*
const ActorInit En_Vali_InitVars = {
ACTOR_EN_VALI,
ACTORCAT_ENEMY,
@ -37,7 +43,7 @@ const ActorInit En_Vali_InitVars = {
(ActorFunc)EnVali_Draw,
};
static ColliderQuadInit D_80B288A0 = {
static ColliderQuadInit sQuadInit = {
{
COLTYPE_NONE,
AT_ON | AT_TYPE_ENEMY,
@ -57,7 +63,7 @@ static ColliderQuadInit D_80B288A0 = {
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
};
static ColliderCylinderInit D_80B288F0 = {
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_HIT8,
AT_ON | AT_TYPE_ENEMY,
@ -76,71 +82,731 @@ static ColliderCylinderInit D_80B288F0 = {
},
{ 17, 35, -15, { 0, 0, 0 } },
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/EnVali_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/EnVali_Destroy.s")
static CollisionCheckInfoInit sColChkInfoInit = { 2, 18, 32, MASS_HEAVY };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26878.s")
typedef enum {
/* 0x0 */ BARI_DMGEFF_NONE,
/* 0x1 */ BARI_DMGEFF_STUN,
/* 0x2 */ BARI_DMGEFF_FIRE,
/* 0x3 */ BARI_DMGEFF_ICE,
/* 0xE */ BARI_DMGEFF_SLINGSHOT = 0xE,
/* 0xF */ BARI_DMGEFF_SWORD
} BariDamageEffect;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B268C8.s")
static DamageTable sDamageTable = {
/* Deku nut */ DMG_ENTRY(0, BARI_DMGEFF_STUN),
/* Deku stick */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Slingshot */ DMG_ENTRY(0, BARI_DMGEFF_SLINGSHOT),
/* Explosive */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Boomerang */ DMG_ENTRY(0, BARI_DMGEFF_STUN),
/* Normal arrow */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Hammer swing */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Hookshot */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Kokiri sword */ DMG_ENTRY(1, BARI_DMGEFF_SWORD),
/* Master sword */ DMG_ENTRY(2, BARI_DMGEFF_SWORD),
/* Giant's Knife */ DMG_ENTRY(4, BARI_DMGEFF_SWORD),
/* Fire arrow */ DMG_ENTRY(4, BARI_DMGEFF_FIRE),
/* Ice arrow */ DMG_ENTRY(4, BARI_DMGEFF_ICE),
/* Light arrow */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Unk arrow 1 */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Unk arrow 2 */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Unk arrow 3 */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Fire magic */ DMG_ENTRY(4, BARI_DMGEFF_FIRE),
/* Ice magic */ DMG_ENTRY(4, BARI_DMGEFF_ICE),
/* Light magic */ DMG_ENTRY(0, BARI_DMGEFF_NONE),
/* Shield */ DMG_ENTRY(0, BARI_DMGEFF_NONE),
/* Mirror Ray */ DMG_ENTRY(0, BARI_DMGEFF_NONE),
/* Kokiri spin */ DMG_ENTRY(1, BARI_DMGEFF_NONE),
/* Giant spin */ DMG_ENTRY(4, BARI_DMGEFF_NONE),
/* Master spin */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Kokiri jump */ DMG_ENTRY(2, BARI_DMGEFF_NONE),
/* Giant jump */ DMG_ENTRY(8, BARI_DMGEFF_NONE),
/* Master jump */ DMG_ENTRY(4, BARI_DMGEFF_NONE),
/* Unknown 1 */ DMG_ENTRY(0, BARI_DMGEFF_NONE),
/* Unblockable */ DMG_ENTRY(0, BARI_DMGEFF_NONE),
/* Hammer jump */ DMG_ENTRY(4, BARI_DMGEFF_NONE),
/* Unknown 2 */ DMG_ENTRY(0, BARI_DMGEFF_NONE),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B268FC.s")
static InitChainEntry sInitChain[] = {
ICHAIN_S8(naviEnemyId, 24, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 5000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26B18.s")
void EnVali_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnVali* this = THIS;
s32 bgId;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26B4C.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 27.0f);
this->actor.shape.shadowAlpha = 155;
SkelAnime_Init(globalCtx, &this->skelAnime, &gBariSkel, &gBariLurkingAnim, this->jointTable, this->morphTable,
EN_VALI_LIMB_MAX);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26BBC.s")
Collider_InitQuad(globalCtx, &this->leftArmCollider);
Collider_SetQuad(globalCtx, &this->leftArmCollider, &this->actor, &sQuadInit);
Collider_InitQuad(globalCtx, &this->rightArmCollider);
Collider_SetQuad(globalCtx, &this->rightArmCollider, &this->actor, &sQuadInit);
Collider_InitCylinder(globalCtx, &this->bodyCollider);
Collider_SetCylinder(globalCtx, &this->bodyCollider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26BF8.s")
EnVali_SetupLurk(this);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26C50.s")
this->actor.flags &= ~1;
this->actor.floorHeight = BgCheck_EntityRaycastFloor4(&globalCtx->colCtx, &this->actor.floorPoly, &bgId,
&this->actor, &this->actor.world.pos);
this->actor.params = BARI_TYPE_NORMAL;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26D54.s")
if (this->actor.floorHeight == BGCHECK_Y_MIN) {
Actor_Kill(&this->actor);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26DE0.s")
void EnVali_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnVali* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26E40.s")
Collider_DestroyQuad(globalCtx, &this->leftArmCollider);
Collider_DestroyQuad(globalCtx, &this->rightArmCollider);
Collider_DestroyCylinder(globalCtx, &this->bodyCollider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B26E9C.s")
void EnVali_SetupLurk(EnVali* this) {
Animation_PlayLoop(&this->skelAnime, &gBariLurkingAnim);
this->actor.draw = NULL;
this->bodyCollider.base.acFlags &= ~AC_ON;
this->actionFunc = EnVali_Lurk;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27098.s")
void EnVali_SetupDropAppear(EnVali* this) {
this->actor.draw = EnVali_Draw;
this->actor.flags |= 1;
this->actor.velocity.y = 1.0f;
this->actionFunc = EnVali_DropAppear;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B270D8.s")
void EnVali_SetupFloatIdle(EnVali* this) {
Animation_MorphToLoop(&this->skelAnime, &gBariWaitingAnim, -3.0f);
this->leftArmCollider.dim.quad[2] = this->leftArmCollider.dim.quad[3] = this->rightArmCollider.dim.quad[2] =
this->rightArmCollider.dim.quad[3] = this->leftArmCollider.dim.quad[0] = this->leftArmCollider.dim.quad[1] =
this->rightArmCollider.dim.quad[0] = this->rightArmCollider.dim.quad[1] = this->actor.world.pos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B2716C.s")
this->leftArmCollider.dim.quad[2].y = this->leftArmCollider.dim.quad[3].y = this->rightArmCollider.dim.quad[2].y =
this->rightArmCollider.dim.quad[3].y = this->leftArmCollider.dim.quad[0].y =
this->leftArmCollider.dim.quad[1].y = this->rightArmCollider.dim.quad[0].y =
this->rightArmCollider.dim.quad[1].y = this->actor.world.pos.y - 10.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27318.s")
this->actor.flags &= ~0x10;
this->bodyCollider.base.acFlags |= AC_ON;
this->slingshotReactionTimer = 0;
this->floatHomeHeight = this->actor.world.pos.y;
this->actionFunc = EnVali_FloatIdle;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B273D0.s")
/**
* Used for both touching player/player's shield and being hit with sword. What to do next is determined by params.
*/
void EnVali_SetupAttacked(EnVali* this) {
this->lightningTimer = 20;
this->actor.flags &= ~1;
this->bodyCollider.base.acFlags &= ~AC_ON;
this->actionFunc = EnVali_Attacked;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B2742C.s")
void EnVali_SetupRetaliate(EnVali* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &gBariRetaliatingAnim, -5.0f);
Actor_SetColorFilter(&this->actor, 0x4000, 150, 0x2000, 30);
this->actor.params = BARI_TYPE_NORMAL;
this->bodyCollider.base.acFlags &= ~AC_ON;
this->actionFunc = EnVali_Retaliate;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27464.s")
void EnVali_SetupMoveArmsDown(EnVali* this) {
Animation_PlayOnce(&this->skelAnime, &gBariMovingArmsDownAnim);
this->actionFunc = EnVali_MoveArmsDown;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B274A0.s")
void EnVali_SetupBurnt(EnVali* this) {
this->timer = 2;
this->bodyCollider.base.acFlags &= ~AC_ON;
Actor_SetColorFilter(&this->actor, 0x4000, 150, 0x2000, 30);
this->actionFunc = EnVali_Burnt;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27654.s")
void EnVali_SetupDivideAndDie(EnVali* this, GlobalContext* globalCtx) {
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27710.s")
for (i = 0; i < 3; i++) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BILI, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, 0);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B278A0.s")
this->actor.world.rot.y += 0x10000 / 3;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B2790C.s")
Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x50);
this->timer = Rand_S16Offset(10, 10);
this->bodyCollider.base.acFlags &= ~AC_ON;
Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_BARI_SPLIT);
this->actor.flags &= ~1;
this->actor.draw = NULL;
this->actionFunc = EnVali_DivideAndDie;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/EnVali_Update.s")
void EnVali_SetupStunned(EnVali* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &gBariWaitingAnim, 10.0f);
this->timer = 80;
this->actor.velocity.y = 0.0f;
Actor_SetColorFilter(&this->actor, 0, 255, 0x2000, 80);
this->bodyCollider.info.bumper.effect = 0;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE);
this->actor.velocity.y = 1.0f;
this->actionFunc = EnVali_Stunned;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27C1C.s")
void EnVali_SetupFrozen(EnVali* this) {
this->actor.velocity.y = 0.0f;
Actor_SetColorFilter(&this->actor, 0, 255, 0x2000, 36);
this->bodyCollider.base.acFlags &= ~AC_ON;
this->timer = 36;
this->actionFunc = EnVali_Frozen;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B27E38.s")
void EnVali_SetupReturnToLurk(EnVali* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &gBariLurkingAnim, 10.0f);
this->actor.flags |= 0x10;
this->actor.flags &= ~1;
this->actionFunc = EnVali_ReturnToLurk;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B28054.s")
void EnVali_DischargeLightning(EnVali* this, GlobalContext* globalCtx) {
static Color_RGBA8 primColor = { 255, 255, 255, 255 };
static Color_RGBA8 envColor = { 200, 255, 255, 255 };
Vec3f pos;
s32 i;
f32 cos;
f32 sin;
s16 yaw;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B281F0.s")
for (i = 0; i < 4; i++) {
cos = -Math_CosS(Camera_GetCamDirYaw(ACTIVE_CAM));
sin = Math_SinS(Camera_GetCamDirYaw(ACTIVE_CAM));
if (!((this->lightningTimer + (i << 1)) % 4)) {
yaw = (s16)Rand_CenteredFloat(12288.0f) + (i * 0x4000) + 0x2000;
pos.x = this->actor.world.pos.x + (Math_SinS(yaw) * 12.0f * cos);
pos.y = this->actor.world.pos.y - (Math_CosS(yaw) * 12.0f) + 10.0f;
pos.z = this->actor.world.pos.z + (Math_SinS(yaw) * 12.0f * sin);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B28280.s")
EffectSsLightning_Spawn(globalCtx, &pos, &primColor, &envColor, 17, yaw, 6, 2);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/func_80B28344.s")
func_8002F974(&this->actor, NA_SE_EN_BIRI_SPARK - SFX_FLAG);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Vali/EnVali_Draw.s")
void EnVali_Lurk(EnVali* this, GlobalContext* globalCtx) {
if (this->actor.xzDistToPlayer < 150.0f) {
EnVali_SetupDropAppear(this);
}
}
void EnVali_DropAppear(EnVali* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
this->actor.velocity.y *= 1.5f;
this->actor.velocity.y = CLAMP_MAX(this->actor.velocity.y, 40.0f);
if (Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight, this->actor.velocity.y)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND);
EnVali_SetupFloatIdle(this);
}
}
void EnVali_FloatIdle(EnVali* this, GlobalContext* globalCtx) {
s32 curFrame;
SkelAnime_Update(&this->skelAnime);
if (this->slingshotReactionTimer != 0) {
this->slingshotReactionTimer--;
}
curFrame = this->skelAnime.curFrame;
Math_StepToF(&this->floatHomeHeight, this->actor.floorHeight + 40.0f, 1.2f);
this->actor.world.pos.y = this->floatHomeHeight - (sinf(curFrame * M_PI * 0.0125f) * 8.0f);
if (this->slingshotReactionTimer) {
this->actor.shape.rot.y += 0x800;
if (((this->slingshotReactionTimer % 6) == 0) && (curFrame > 15) && (curFrame <= 55)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_BARI_ROLL);
}
} else if ((curFrame == 16) || (curFrame == 30) || (curFrame == 42) || (curFrame == 55)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_BARI_ROLL);
}
curFrame = ((curFrame > 40) ? (80 - curFrame) : curFrame);
this->actor.shape.rot.y += (s16)((curFrame + 4) * 0.4f * ( 0x10000 / 360.0f ));
if (this->actor.xzDistToPlayer > 250.0f) {
EnVali_SetupReturnToLurk(this);
}
}
void EnVali_Attacked(EnVali* this, GlobalContext* globalCtx) {
if (this->lightningTimer != 0) {
this->lightningTimer--;
}
EnVali_DischargeLightning(this, globalCtx);
if (this->lightningTimer == 0) {
this->actor.flags |= 1;
this->bodyCollider.base.acFlags |= AC_ON;
if (this->actor.params == BARI_TYPE_SWORD_DAMAGE) {
EnVali_SetupRetaliate(this);
} else {
this->actionFunc = EnVali_FloatIdle;
}
} else if ((this->lightningTimer % 2) != 0) {
this->actor.world.pos.y += 1.0f;
} else {
this->actor.world.pos.y -= 1.0f;
}
}
void EnVali_Retaliate(EnVali* this, GlobalContext* globalCtx) {
if (SkelAnime_Update(&this->skelAnime)) {
if (this->actor.colChkInfo.health != 0) {
EnVali_SetupMoveArmsDown(this);
} else {
EnVali_SetupDivideAndDie(this, globalCtx);
}
}
}
void EnVali_MoveArmsDown(EnVali* this, GlobalContext* globalCtx) {
if (SkelAnime_Update(&this->skelAnime)) {
EnVali_SetupFloatIdle(this);
}
}
void EnVali_Burnt(EnVali* this, GlobalContext* globalCtx) {
if (this->timer != 0) {
this->timer--;
}
if (this->timer == 0) {
EnVali_SetupDivideAndDie(this, globalCtx);
}
}
void EnVali_DivideAndDie(EnVali* this, GlobalContext* globalCtx) {
static Vec3f velocity = { 0.0f, 0.0f, 0.0f };
static Vec3f accel = { 0.0f, 0.0f, 0.0f };
s16 scale;
Vec3f pos;
s32 i;
if (this->timer != 0) {
this->timer--;
}
for (i = 0; i < 2; i++) {
pos.x = this->actor.world.pos.x + Rand_CenteredFloat(20.0f);
pos.y = this->actor.world.pos.y + Rand_CenteredFloat(8.0f);
pos.z = this->actor.world.pos.z + Rand_CenteredFloat(20.0f);
velocity.y = (Rand_ZeroOne() + 1.0f);
scale = Rand_S16Offset(40, 40);
if (Rand_ZeroOne() < 0.7f) {
EffectSsDtBubble_SpawnColorProfile(globalCtx, &pos, &velocity, &accel, scale, 25, 2,
1);
} else {
EffectSsDtBubble_SpawnColorProfile(globalCtx, &pos, &velocity, &accel, scale, 25, 0,
1);
}
}
if (this->timer == 0) {
Actor_Kill(&this->actor);
}
}
void EnVali_Stunned(EnVali* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
if (this->timer != 0) {
this->timer--;
}
if (this->actor.velocity.y != 0.0f) {
if (Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight, this->actor.velocity.y)) {
this->actor.velocity.y = 0.0f;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND);
} else {
this->actor.velocity.y += 1.0f;
}
}
if (this->timer == 0) {
this->bodyCollider.info.bumper.effect = 1; // Shock?
EnVali_SetupFloatIdle(this);
}
}
void EnVali_Frozen(EnVali* this, GlobalContext* globalCtx) {
Vec3f pos;
s32 temp_v0;
s32 temp_v1;
if (this->timer != 0) {
this->timer--;
}
temp_v1 = this->timer - 20;
this->actor.colorFilterTimer = 36;
if (temp_v1 > 0) {
temp_v0 = temp_v1 >> 1;
if ((this->timer % 2) != 0) {
pos.y = this->actor.world.pos.y - 20.0f + (-temp_v0 * 5 + 40);
pos.x = this->actor.world.pos.x + ((temp_v0 & 2) ? 12.0f : -12.0f);
pos.z = this->actor.world.pos.z + ((temp_v0 & 1) ? 12.0f : -12.0f);
EffectSsEnIce_SpawnFlyingVec3f(globalCtx, &this->actor, &pos, 150, 150, 150, 250, 235, 245, 255,
(Rand_ZeroOne() * 0.2f) + 1.3f);
}
} else if (this->timer == 0) {
this->actor.velocity.y += 1.0f;
if (Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight, this->actor.velocity.y)) {
EnVali_SetupDivideAndDie(this, globalCtx);
this->actor.colorFilterTimer = 0;
}
}
}
void EnVali_ReturnToLurk(EnVali* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.5f, 15.0f, 0.1f) < 0.01f) {
EnVali_SetupLurk(this);
}
}
void EnVali_UpdateDamage(EnVali* this, GlobalContext* globalCtx) {
if (this->bodyCollider.base.acFlags & AC_HIT) {
this->bodyCollider.base.acFlags &= ~AC_HIT;
func_80035650(&this->actor, &this->bodyCollider.info, 1);
if ((this->actor.colChkInfo.damageEffect != BARI_DMGEFF_NONE) || (this->actor.colChkInfo.damage != 0)) {
if (Actor_ApplyDamage(&this->actor) == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_BARI_DEAD);
func_80032C7C(globalCtx, &this->actor);
this->actor.flags &= ~1;
} else if ((this->actor.colChkInfo.damageEffect != BARI_DMGEFF_STUN) &&
(this->actor.colChkInfo.damageEffect != BARI_DMGEFF_SLINGSHOT)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_BARI_DAMAGE);
}
if (this->actor.colChkInfo.damageEffect == BARI_DMGEFF_STUN) {
if (this->actionFunc != EnVali_Stunned) {
EnVali_SetupStunned(this);
}
} else if (this->actor.colChkInfo.damageEffect == BARI_DMGEFF_SWORD) {
if (this->actionFunc != EnVali_Stunned) {
Actor_SetColorFilter(&this->actor, 0x4000, 150, 0x2000, 30);
this->actor.params = BARI_TYPE_SWORD_DAMAGE;
EnVali_SetupAttacked(this);
} else {
EnVali_SetupRetaliate(this);
}
} else if (this->actor.colChkInfo.damageEffect == BARI_DMGEFF_FIRE) {
EnVali_SetupBurnt(this);
} else if (this->actor.colChkInfo.damageEffect == BARI_DMGEFF_ICE) {
EnVali_SetupFrozen(this);
} else if (this->actor.colChkInfo.damageEffect == BARI_DMGEFF_SLINGSHOT) {
if (this->slingshotReactionTimer == 0) {
this->slingshotReactionTimer = 20;
}
} else {
EnVali_SetupRetaliate(this);
}
}
}
}
void EnVali_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnVali* this = THIS;
if ((this->bodyCollider.base.atFlags & AT_HIT) || (this->leftArmCollider.base.atFlags & AT_HIT) ||
(this->rightArmCollider.base.atFlags & AT_HIT)) {
this->leftArmCollider.base.atFlags &= ~AT_HIT;
this->rightArmCollider.base.atFlags &= ~AT_HIT;
this->bodyCollider.base.atFlags &= ~AT_HIT;
EnVali_SetupAttacked(this);
}
EnVali_UpdateDamage(this, globalCtx);
this->actionFunc(this, globalCtx);
if ((this->actionFunc != EnVali_DivideAndDie) && (this->actionFunc != EnVali_Lurk)) {
Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
if (this->actionFunc == EnVali_FloatIdle) {
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->leftArmCollider.base);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->rightArmCollider.base);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base);
}
if (this->bodyCollider.base.acFlags & AC_ON) {
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base);
}
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base);
Actor_SetFocus(&this->actor, 0.0f);
}
}
// Draw and associated functions
void EnVali_PulseOutside(EnVali* this, f32 curFrame, Vec3f* scale) {
f32 scaleChange;
if (this->actionFunc == EnVali_Attacked) {
s32 scalePhase = 20 - (this->lightningTimer % 20);
if (scalePhase >= 10) {
scalePhase -= 10;
}
scale->y -= 0.2f * sinf((M_PI / 10) * scalePhase);
} else if (this->actionFunc == EnVali_Retaliate) {
scaleChange = sinf((M_PI / 10) * curFrame);
scale->y -= 0.24f * scaleChange;
scale->x -= 0.13f * scaleChange;
scale->z = scale->x;
} else if (this->actionFunc == EnVali_MoveArmsDown) {
scaleChange = cosf((M_PI / 50) * curFrame);
scale->y -= 0.24f * scaleChange;
scale->x -= 0.13f * scaleChange;
scale->z = scale->x;
} else if (this->actionFunc == EnVali_Stunned) {
scaleChange = sinf((M_PI / 10) * this->timer) * 0.08f;
scale->x += scaleChange;
scale->y -= scaleChange;
scale->z += scaleChange;
} else {
if (curFrame >= 40.0f) {
curFrame -= 40.0f;
}
scale->y -= 0.2f * sinf((M_PI / 40) * curFrame);
}
}
void EnVali_PulseInsides(EnVali* this, f32 curFrame, Vec3f* scale) {
f32 scaleChange;
if (this->actionFunc == EnVali_Attacked) {
s32 scalePhase = 20 - (this->lightningTimer % 20);
if (scalePhase >= 10) {
scalePhase -= 10;
}
scale->y -= 0.13f * sinf((M_PI / 10) * scalePhase);
} else if (this->actionFunc == EnVali_Retaliate) {
scaleChange = sinf((M_PI / 10) * curFrame);
scale->y -= 0.18f * scaleChange;
scale->x -= 0.1f * scaleChange;
scale->z = scale->x;
} else if (this->actionFunc == EnVali_MoveArmsDown) {
scaleChange = cosf((M_PI / 50) * curFrame);
scale->y -= 0.18f * scaleChange;
scale->x -= 0.1f * scaleChange;
scale->z = scale->x;
} else if (this->actionFunc == EnVali_Stunned) {
scaleChange = sinf((M_PI / 10) * this->timer) * 0.08f;
scale->x -= scaleChange;
scale->y += scaleChange;
scale->z -= scaleChange;
} else {
if (curFrame >= 40.0f) {
curFrame -= 40.0f;
}
scale->y -= 0.13f * sinf((M_PI / 40) * curFrame);
}
}
s32 EnVali_SetArmLength(EnVali* this, f32 curFrame) {
f32 targetArmScale;
if (this->actionFunc == EnVali_FloatIdle) {
if (curFrame <= 10.0f) {
targetArmScale = curFrame * 0.05f + 1.0f;
} else if (curFrame > 70.0f) {
targetArmScale = (80.0f - curFrame) * 0.05f + 1.0f;
} else {
targetArmScale = 1.5f;
}
} else if (this->actionFunc == EnVali_Retaliate) {
targetArmScale = 1.0f - sinf((M_PI / 10) * curFrame) * 0.35f;
} else if (this->actionFunc == EnVali_MoveArmsDown) {
targetArmScale = 1.0f - cosf((M_PI / 50) * curFrame) * 0.35f;
} else if ((this->actionFunc == EnVali_Attacked) || (this->actionFunc == EnVali_Frozen)) {
targetArmScale = this->armScale;
} else {
targetArmScale = 1.0f;
}
Math_StepToF(&this->armScale, targetArmScale, 0.1f);
if (this->armScale == 1.0f) {
return false;
} else {
return true;
}
}
s32 EnVali_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx,
Gfx** gfx) {
EnVali* this = THIS;
f32 curFrame;
if ((limbIndex == EN_VALI_LIMB_NUCLEUS) || (limbIndex == EN_VALI_LIMB_OUTER_HOOD) ||
(limbIndex == EN_VALI_LIMB_INNER_HOOD)) {
*dList = NULL;
return false;
} else {
curFrame = this->skelAnime.curFrame;
if ((limbIndex == EN_VALI_LIMB_LEFT_ARM_BASE) || (limbIndex == EN_VALI_LIMB_RIGHT_ARM_BASE)) {
if (EnVali_SetArmLength(this, curFrame)) {
Matrix_Scale(this->armScale, 1.0f, 1.0f, MTXMODE_APPLY);
}
}
return false;
}
}
void EnVali_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx, Gfx** gfx) {
static Vec3f D_80B28970 = { 3000.0f, 0.0f, 0.0f };
static Vec3f D_80B2897C = { -1000.0f, 0.0f, 0.0f };
Vec3f sp3C;
Vec3f sp30;
EnVali* this = THIS;
if (this->actionFunc == EnVali_FloatIdle) {
if ((limbIndex == EN_VALI_LIMB_LEFT_FOREARM_BASE) || (limbIndex == EN_VALI_LIMB_RIGHT_FOREARM_BASE)) {
Matrix_MultVec3f(&D_80B28970, &sp3C);
Matrix_MultVec3f(&D_80B2897C, &sp30);
if (limbIndex == EN_VALI_LIMB_LEFT_FOREARM_BASE) {
Collider_SetQuadVertices(&this->leftArmCollider, &sp30, &sp3C, &this->leftArmCollider.dim.quad[0],
&this->leftArmCollider.dim.quad[1]);
} else {
Collider_SetQuadVertices(&this->rightArmCollider, &sp30, &sp3C, &this->rightArmCollider.dim.quad[0],
&this->rightArmCollider.dim.quad[1]);
}
}
}
}
void EnVali_DrawBody(EnVali* this, GlobalContext* globalCtx) {
MtxF mtx;
f32 cos;
f32 sin;
f32 curFrame;
Vec3f scale = { 1.0f, 1.0f, 1.0f };
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_vali.c", 1428);
Matrix_Get(&mtx);
curFrame = this->skelAnime.curFrame;
EnVali_PulseInsides(this, curFrame, &scale);
Matrix_Scale(scale.x, scale.y, scale.z, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_vali.c", 1436),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBariInnerHoodDL);
Matrix_Put(&mtx);
Matrix_RotateY(-this->actor.shape.rot.y * (M_PI / 32768.0f), MTXMODE_APPLY);
cos = Math_CosS(this->actor.shape.rot.y);
sin = Math_SinS(this->actor.shape.rot.y);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_vali.c", 1446),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBariNucleusDL);
Matrix_Translate((506.0f * cos) + (372.0f * sin), 1114.0f, (372.0f * cos) - (506.0f * sin), MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_vali.c", 1455),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBariNucleusDL);
Matrix_Translate((-964.0f * cos) - (804.0f * sin), -108.0f, (-804.0f * cos) + (964.0f * sin), MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_vali.c", 1463),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBariNucleusDL);
Matrix_Put(&mtx);
scale.x = scale.y = scale.z = 1.0f;
EnVali_PulseOutside(this, curFrame, &scale);
Matrix_Scale(scale.x, scale.y, scale.z, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_vali.c", 1471),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBariOuterHoodDL);
Matrix_Put(&mtx);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_vali.c", 1477);
}
static Gfx D_80B28998[] = {
gsDPSetCombineLERP(1, TEXEL0, SHADE, 0, TEXEL0, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0, TEXEL1, 0,
PRIM_LOD_FRAC, COMBINED),
gsSPEndDisplayList(),
};
static Gfx D_80B289A8[] = {
gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, TEXEL0, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0, TEXEL1, 0,
PRIM_LOD_FRAC, COMBINED),
gsSPEndDisplayList(),
};
void EnVali_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnVali* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_vali.c", 1505);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TexScroll(globalCtx->state.gfxCtx, 0, (127 - (globalCtx->gameplayFrames * 12)) % 128, 32, 32));
if ((this->lightningTimer % 2) != 0) {
gSPSegment(POLY_XLU_DISP++, 0x09, D_80B28998);
} else {
gSPSegment(POLY_XLU_DISP++, 0x09, D_80B289A8);
}
EnVali_DrawBody(this, globalCtx);
POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
EnVali_OverrideLimbDraw, EnVali_PostLimbDraw, this, POLY_XLU_DISP);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_vali.c", 1538);
}

View file

@ -6,11 +6,62 @@
struct EnVali;
typedef void (*EnValiActionFunc)(struct EnVali*, GlobalContext*);
typedef enum {
/* 0x00 */ EN_VALI_LIMB_NONE,
/* 0x01 */ EN_VALI_LIMB_NUCLEUS_BASE,
/* 0x02 */ EN_VALI_LIMB_NUCLEUS,
/* 0x03 */ EN_VALI_LIMB_RIGHT_MANDIBLE_BASE_BASE,
/* 0x04 */ EN_VALI_LIMB_RIGHT_MANDIBLE_BASE,
/* 0x05 */ EN_VALI_LIMB_RIGHT_MANDIBLE,
/* 0x06 */ EN_VALI_LIMB_LEFT_MANDIBLE_BASE_BASE,
/* 0x07 */ EN_VALI_LIMB_LEFT_MANDIBLE_BASE,
/* 0x08 */ EN_VALI_LIMB_LEFT_MANDIBLE,
/* 0x09 */ EN_VALI_LIMB_LEFT_ARM_BASE,
/* 0x0A */ EN_VALI_LIMB_LEFT_UPPER_ARM_BASE,
/* 0x0B */ EN_VALI_LIMB_LEFT_FOREARM_BASE,
/* 0x0C */ EN_VALI_LIMB_LEFT_CLAW_BODY_BASE,
/* 0x0D */ EN_VALI_LIMB_LEFT_CLAW_TIP_BASE,
/* 0x0E */ EN_VALI_LIMB_LEFT_CLAW_TIP,
/* 0x0F */ EN_VALI_LIMB_LEFT_CLAW_BODY,
/* 0x10 */ EN_VALI_LIMB_LEFT_FOREARM,
/* 0x11 */ EN_VALI_LIMB_LEFT_UPPER_ARM,
/* 0x12 */ EN_VALI_LIMB_RIGHT_ARM_BASE,
/* 0x13 */ EN_VALI_LIMB_RIGHT_UPPER_ARM_BASE,
/* 0x14 */ EN_VALI_LIMB_RIGHT_FOREARM_BASE,
/* 0x15 */ EN_VALI_LIMB_RIGHT_CLAW_BODY_BASE,
/* 0x16 */ EN_VALI_LIMB_RIGHT_CLAW_TIP_BASE,
/* 0x17 */ EN_VALI_LIMB_RIGHT_CLAW_TIP,
/* 0x18 */ EN_VALI_LIMB_RIGHT_CLAW_BODY,
/* 0x19 */ EN_VALI_LIMB_RIGHT_FOREARM,
/* 0x1A */ EN_VALI_LIMB_RIGHT_UPPER_ARM,
/* 0x1B */ EN_VALI_LIMB_INNER_HOOD,
/* 0x1C */ EN_VALI_LIMB_OUTER_HOOD,
/* 0x1D */ EN_VALI_LIMB_MAX
} EnValiLimb;
typedef struct EnVali {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x2FC];
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ EnValiActionFunc actionFunc;
/* 0x0194 */ u8 lightningTimer;
/* 0x0195 */ u8 slingshotReactionTimer;
/* 0x0196 */ s16 timer;
/* 0x0198 */ Vec3s jointTable[EN_VALI_LIMB_MAX];
/* 0x0246 */ Vec3s morphTable[EN_VALI_LIMB_MAX];
/* 0x02F4 */ f32 armScale;
/* 0x02F8 */ f32 floatHomeHeight; // Used as a centre for floating when visible (home is used for the lurk height)
/* 0x02FC */ ColliderQuad leftArmCollider;
/* 0x037C */ ColliderQuad rightArmCollider;
/* 0x03FC */ ColliderCylinder bodyCollider;
} EnVali; // size = 0x0448
extern const ActorInit En_Vali_InitVars;
typedef enum {
/* 0 */ BARI_TYPE_NORMAL,
/* 1 */ BARI_TYPE_SWORD_DAMAGE
} EnValiType;
#endif