diff --git a/include/functions.h b/include/functions.h index 37e0afd47..929dc9b19 100644 --- a/include/functions.h +++ b/include/functions.h @@ -681,7 +681,7 @@ void EffectSsEnIce_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 scale, Vec3f* // void EffectSsFireTail_Spawn(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, UNK_TYPE4 uParm4, Vec3f* param_5, UNK_TYPE2 param_6, Color_RGBA8* param_7, Color_RGBA8* param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE4 param_11); // void EffectSsFireTail_SpawnFlame(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6); // void EffectSsFireTail_SpawnFlameOnPlayer(void); -// void EffectSsEnFire_SpawnVec3f(UNK_TYPE4 uParm1, Actor* pzParm2, Vec3f* pzParm3, UNK_TYPE2 uParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7); +void EffectSsEnFire_SpawnVec3f(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, s16 scale, s16 arg4, s16 flags, s16 bodyPart); // void EffectSsEnFire_SpawnVec3s(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7); // void EffectSsExtra_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); void EffectSsDeadDb_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim, Color_RGBA8* env, @@ -887,7 +887,7 @@ void func_800BBA88(GlobalContext* globalCtx, Actor* actor); // void func_800BBAC0(void); void func_800BBB74(s16* arg1, UNK_TYPE1 arg2, UNK_TYPE1 arg3, UNK_TYPE4 arg4); // void func_800BBC20(void); -// void func_800BBCEC(void); +void func_800BBCEC(Actor* actor, GlobalContext* globalCtx, s16 arg2, Gfx** dList); // void func_800BBDAC(GlobalContext* globalCtx, UNK_PTR param_2, UNK_PTR param_3, f32 param_4, UNK_TYPE4 param_5, f32 param_6, s16 param_7, s16 param_8, u8 param_9); void func_800BBFB0(GlobalContext* globalCtx, Vec3f* position, f32 param3, s32 param_4, s16 param_5, s16 param_6, u8 param_7); void func_800BC154(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actor, u8 actorCategory); @@ -904,7 +904,7 @@ Actor* func_800BC270(GlobalContext* globalCtx, Actor* actor, f32 arg2, UNK_TYPE4 // void func_800BC848(void); // void func_800BC8B8(void); // void func_800BCB50(void); -void func_800BCB70(Actor* actor, s16 arg1, u8 arg2, u8 arg3, u8 arg4); +void func_800BCB70(Actor* actor, s16 arg1, u8 arg2, s16 arg3, u8 arg4); void func_800BCBF4(Vec3f* uParm1, GlobalContext* globalCtx); void func_800BCC68(Vec3f* param_1, GlobalContext* globalCtx); UNK_RET func_800BCCDC(Vec3s* points, u8 pathcount, Vec3f* pos1, Vec3f* pos2, UNK_TYPE parm5); diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 8afb1b698..1d962e7d0 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -1785,9 +1785,9 @@ SECTIONS ovl_En_Sb : AT(RomLocation) { build/src/overlays/actors/ovl_En_Sb/z_en_sb.o(.text) - build/asm/overlays/ovl_En_Sb_data.o(.data) + build/src/overlays/actors/ovl_En_Sb/z_en_sb.o(.data) build/src/overlays/actors/ovl_En_Sb/z_en_sb.o(.rodata) - build/asm/overlays/ovl_En_Sb_rodata.o(.rodata) + build/src/overlays/actors/ovl_En_Sb/z_en_sb_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 2825a0e93..b90ccbd9e 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -504,3 +504,11 @@ D_05007890 = 0x05007890; D_05007980 = 0x05007980; D_06001180 = 0x06001180; D_06001A70 = 0x06001A70; + +/* z_en_sb */ +D_06000194 = 0x06000194; +D_0600004C = 0x0600004C; +D_06000124 = 0x06000124; +D_06002C8C = 0x06002C8C; +D_060000B4 = 0x060000B4; +D_06002BF0 = 0x06002BF0; \ No newline at end of file diff --git a/src/overlays/actors/ovl_En_Sb/z_en_sb.c b/src/overlays/actors/ovl_En_Sb/z_en_sb.c index 7e2164149..734de9843 100644 --- a/src/overlays/actors/ovl_En_Sb/z_en_sb.c +++ b/src/overlays/actors/ovl_En_Sb/z_en_sb.c @@ -1,3 +1,9 @@ +/* + * File: z_en_sb.c + * Overlay: ovl_En_Sb + * Description: Shellblade + */ + #include "z_en_sb.h" #define FLAGS 0x00000005 @@ -9,7 +15,15 @@ void EnSb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSb_Update(Actor* thisx, GlobalContext* globalCtx); void EnSb_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void EnSb_SetupWaitClosed(EnSb* this); +void EnSb_Idle(EnSb* this, GlobalContext* globalCtx); +void EnSb_Open(EnSb* this, GlobalContext* globalCtx); +void EnSb_WaitOpen(EnSb* this, GlobalContext* globalCtx); +void EnSb_TurnAround(EnSb* this, GlobalContext* globalCtx); +void EnSb_Lunge(EnSb* this, GlobalContext* globalCtx); +void EnSb_Bounce(EnSb* this, GlobalContext* globalCtx); +void EnSb_ReturnToIdle(EnSb* this, GlobalContext* globalCtx); + const ActorInit En_Sb_InitVars = { ACTOR_EN_SB, ACTORCAT_ENEMY, @@ -21,44 +35,363 @@ const ActorInit En_Sb_InitVars = { (ActorFunc)EnSb_Update, (ActorFunc)EnSb_Draw, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/EnSb_Init.asm") +static ColliderCylinderInitType1 sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { 30, 40, 0, { 0, 0, 0 } }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/EnSb_Destroy.asm") +static DamageTable sDamageTable = { + 0x00, 0x00, 0x00, 0xF1, 0xF1, 0xF1, 0x00, 0xF1, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0xF1, 0x00, 0x00, + 0xF1, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E401C.asm") +static InitChainEntry sInitChain[] = { + ICHAIN_S8(hintId, 39, ICHAIN_CONTINUE), + ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 30, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E40CC.asm") +static Vec3f sFlamePosOffsets[] = { + { 5.0f, 0.0f, 0.0f }, + { -5.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 5.0f }, + { 0.0f, 0.0f, -5.0f }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4144.asm") +extern FlexSkeletonHeader D_06002BF0; +extern AnimationHeader D_06000194; +extern AnimationHeader D_0600004C; +extern AnimationHeader D_06000124; +extern AnimationHeader D_06002C8C; +extern AnimationHeader D_060000B4; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E41C0.asm") +void EnSb_Init(Actor* thisx, GlobalContext* globalCtx) { + EnSb* this = THIS; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4234.asm") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.colChkInfo.mass = 0xA; + this->actor.colChkInfo.health = 2; + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06002BF0, &D_06000194, this->limbDrawTable, + this->transitionDrawTable, 9); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->isDead = false; + this->actor.colChkInfo.mass = 0x5A; + this->actor.shape.rot.y = 0; + this->actor.speedXZ = 0.0f; + this->actor.gravity = -0.35f; + this->fireCount = 0; + this->unk_252 = 0; + this->actor.velocity.y = -1.0f; + Actor_SetScale(&this->actor, 0.006f); + EnSb_SetupWaitClosed(this); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E42DC.asm") +void EnSb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSb* this = THIS; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4354.asm") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4458.asm") +void EnSb_SpawnBubbles(GlobalContext* globalCtx, EnSb* this) { + s32 bubbleCount; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E44D4.asm") + if (this->actor.yDistToWater > 0.0f) { + for (bubbleCount = 0; bubbleCount < 10; bubbleCount++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 10.0f, 10.0f, 30.0f, 0.25f); + } + } +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E45A0.asm") +void EnSb_SetupWaitClosed(EnSb* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_0600004C, 1.0f, 0, SkelAnime_GetFrameCount(&D_0600004C.common), 2, 0.0f); + this->state = SHELLBLADE_WAIT_CLOSED; + this->actionFunc = EnSb_Idle; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4654.asm") +void EnSb_SetupOpen(EnSb* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_06000194, 1.0f, 0, SkelAnime_GetFrameCount(&D_06000194.common), 2, 0.0f); + this->state = SHELLBLADE_OPEN; + this->actionFunc = EnSb_Open; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4740.asm") +void EnSb_SetupWaitOpen(EnSb* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_06002C8C, 1.0f, 0, SkelAnime_GetFrameCount(&D_06002C8C.common), 0, 0.0f); + this->state = SHELLBLADE_WAIT_OPEN; + this->actionFunc = EnSb_WaitOpen; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E47E8.asm") +void EnSb_SetupLunge(EnSb* this) { + f32 frameCount = SkelAnime_GetFrameCount(&D_06000124.common); + f32 playbackSpeed = this->actor.yDistToWater > 0.0f ? 1.0f : 0.0f; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E491C.asm") + SkelAnime_ChangeAnim(&this->skelAnime, &D_06000124, playbackSpeed, 0.0f, frameCount, 2, 0); + this->state = SHELLBLADE_LUNGE; + this->actionFunc = EnSb_Lunge; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4984.asm") +void EnSb_SetupBounce(EnSb* this) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_060000B4, 1.0f, 0, SkelAnime_GetFrameCount(&D_060000B4.common), 2, 0.0f); + this->state = SHELLBLADE_BOUNCE; + this->actionFunc = EnSb_Bounce; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/EnSb_Update.asm") +void EnSb_SetupIdle(EnSb* this, s32 changeSpeed) { + f32 frameCount = SkelAnime_GetFrameCount(&D_0600004C.common); -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/func_808E4C18.asm") + if (this->state != SHELLBLADE_WAIT_CLOSED) { + SkelAnime_ChangeAnim(&this->skelAnime, &D_0600004C, 1.0f, 0, frameCount, 2, 0.0f); + } + this->state = SHELLBLADE_WAIT_CLOSED; + if (changeSpeed) { + if (this->actor.yDistToWater > 0.0f) { + this->actor.speedXZ = -5.0f; + if (this->actor.velocity.y < 0.0f) { + this->actor.velocity.y = 2.1f; + } + } else { + this->actor.speedXZ = -6.0f; + if (this->actor.velocity.y < 0.0f) { + this->actor.velocity.y = 1.4f; + } + } + } + this->attackTimer = 60; + this->actionFunc = EnSb_ReturnToIdle; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Sb_0x808E3EF0/EnSb_Draw.asm") +void EnSb_Idle(EnSb* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x7D0, 0); + if (this->actor.xzDistToPlayer <= 240.0f && this->actor.xzDistToPlayer > 0.0f) { + EnSb_SetupOpen(this); + } +} + +void EnSb_Open(EnSb* this, GlobalContext* globalCtx) { + f32 currentFrame = this->skelAnime.animCurrentFrame; + + if (SkelAnime_GetFrameCount(&D_06000194.common) <= currentFrame) { + this->vulnerableTimer = 20; + EnSb_SetupWaitOpen(this); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x7D0, 0); + if (this->actor.xzDistToPlayer > 240.0f || this->actor.xzDistToPlayer <= 40.0f) { + this->vulnerableTimer = 0; + EnSb_SetupWaitClosed(this); + } + } +} + +void EnSb_WaitOpen(EnSb* this, GlobalContext* globalCtx) { + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x7D0, 0); + if (this->actor.xzDistToPlayer > 240.0f || this->actor.xzDistToPlayer <= 40.0f) { + this->vulnerableTimer = 0; + EnSb_SetupWaitClosed(this); + } + if (this->vulnerableTimer > 0) { + this->vulnerableTimer--; + } else { + this->vulnerableTimer = 0; + this->attackTimer = 0; + this->yawAngle = this->actor.yawTowardsPlayer; + this->actionFunc = EnSb_TurnAround; + } +} + +void EnSb_TurnAround(EnSb* this, GlobalContext* globalCtx) { + s16 invertedYaw = this->yawAngle + 0x8000; + + Math_SmoothStepToS(&this->actor.shape.rot.y, invertedYaw, 1, 0x1F40, 0xA); + if (this->actor.shape.rot.y == invertedYaw) { + this->actor.world.rot.y = this->yawAngle; + if (this->actor.yDistToWater > 0.0f) { + this->actor.velocity.y = 3.0f; + this->actor.speedXZ = 5.0f; + this->actor.gravity = -0.35f; + } else { + this->actor.velocity.y = 2.0f; + this->actor.speedXZ = 6.0f; + this->actor.gravity = -2.0f; + } + EnSb_SpawnBubbles(globalCtx, this); + this->bounceCounter = 3; + EnSb_SetupLunge(this); + } +} + +void EnSb_Lunge(EnSb* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); + if (this->actor.velocity.y <= -0.1f || this->actor.bgCheckFlags & 2) { + if (!(this->actor.yDistToWater > 0.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + this->actor.bgCheckFlags &= ~2; + EnSb_SetupBounce(this); + } +} + +void EnSb_Bounce(EnSb* this, GlobalContext* globalCtx) { + s32 pad; + f32 currentFrame = currentFrame = this->skelAnime.animCurrentFrame; + f32 frameCount = frameCount = SkelAnime_GetFrameCount(&D_060000B4.common); + + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); + if (currentFrame == frameCount) { + if (this->bounceCounter != 0) { + this->bounceCounter--; + this->attackTimer = 1; + if (this->actor.yDistToWater > 0.0f) { + this->actor.velocity.y = 3.0f; + this->actor.speedXZ = 5.0f; + this->actor.gravity = -0.35f; + } else { + this->actor.velocity.y = 2.0f; + this->actor.speedXZ = 6.0f; + this->actor.gravity = -2.0f; + } + EnSb_SpawnBubbles(globalCtx, this); + EnSb_SetupLunge(this); + } else if (this->actor.bgCheckFlags & 1) { + this->actor.bgCheckFlags &= ~2; + this->actor.speedXZ = 0.0f; + this->attackTimer = 1; + EnSb_SetupWaitClosed(this); + } + } +} + +void EnSb_ReturnToIdle(EnSb* this, GlobalContext* globalCtx) { + if (this->attackTimer != 0) { + this->attackTimer--; + if (this->actor.bgCheckFlags & 1) { + this->actor.bgCheckFlags &= ~1; + this->actor.speedXZ = 0.0f; + } + } else if (this->actor.bgCheckFlags & 1) { + this->actor.bgCheckFlags &= ~1; + this->actionFunc = EnSb_Idle; + this->actor.speedXZ = 0.0f; + } +} + +void EnSb_UpdateDamage(EnSb* this, GlobalContext* globalCtx) { + Vec3f hitPoint; + + if (this->collider.base.acFlags & AC_HIT) { + s32 hitPlayer = 0; + this->collider.base.acFlags &= ~AC_HIT; + if (this->actor.colChkInfo.damageEffect == 0xF) { + hitPlayer = 0; + if (this->vulnerableTimer != 0) { + func_800BE22C(&this->actor); + func_800BCB70(&this->actor, 0x4000, 0xFF, 0x2000, 80); + hitPlayer = 1; + } + } + if (hitPlayer) { + this->unk_252 = 0; + if ((this->actor.draw != NULL) && (this->isDrawn == false)) { + this->isDrawn = true; + } + this->isDead = true; + func_800BBA88(globalCtx, &this->actor); + func_800F0568(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EN_BEE_FLY); + return; + } + hitPoint.x = this->collider.info.bumper.hitPos.x; + hitPoint.y = this->collider.info.bumper.hitPos.y; + hitPoint.z = this->collider.info.bumper.hitPos.z; + CollisionCheck_SpawnShieldParticlesMetal2(globalCtx, &hitPoint); + return; + } + if (this->collider.base.atFlags & AT_HIT) { + EnSb_SetupIdle(this, 1); + } +} + +void EnSb_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSb* this = THIS; + ActorPlayer* player = PLAYER; + + if (this->isDead) { + if (this->actor.yDistToWater > 0.0f) { + this->actor.params = 4; + } else { + this->actor.params = 1; + } + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x80); + Actor_MarkForDeath(&this->actor); + } else { + Actor_SetHeight(&this->actor, 20.0f); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + this->actionFunc(this, globalCtx); + func_800B78B8(globalCtx, &this->actor, 20.0f, 25.0f, 20.0f, 5); + EnSb_UpdateDamage(this, globalCtx); + if (player->stateFlags1 & 0x8000000) { + Collider_UpdateCylinder(&this->actor, &this->collider); + if (this->vulnerableTimer == 0) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colCheckCtx, &this->collider.base); + } + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + } +} + +void EnSb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s8 phi_a2; + EnSb* this = THIS; + + if (this->isDrawn != false) { + if (limbIndex < 7) { + phi_a2 = (this->actor.yDistToWater > 0) ? 4 : 1; + func_800BBCEC(thisx, globalCtx, phi_a2, dList); + } + if (limbIndex == 6) { + this->isDrawn = false; + this->actor.draw = NULL; + } + } +} + +void EnSb_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSb* this = THIS; + Vec3f flamePos; + Vec3f* offset; + s16 fireDecr; + + func_800B8050(&this->actor, globalCtx, 1); + SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, NULL, + EnSb_PostLimbDraw, &this->actor); + if (this->fireCount != 0) { + this->actor.colorFilterTimer++; + fireDecr = this->fireCount - 1; + if (!(fireDecr & 1)) { + offset = &sFlamePosOffsets[fireDecr & 3]; + flamePos.x = randPlusMinusPoint5Scaled(5.0f) + (this->actor.world.pos.x + offset->x); + flamePos.y = randPlusMinusPoint5Scaled(5.0f) + (this->actor.world.pos.y + offset->y); + flamePos.z = randPlusMinusPoint5Scaled(5.0f) + (this->actor.world.pos.z + offset->z); + EffectSsEnFire_SpawnVec3f(globalCtx, &this->actor, &flamePos, 100, 0, 0, -1); + } + } +} \ No newline at end of file diff --git a/src/overlays/actors/ovl_En_Sb/z_en_sb.h b/src/overlays/actors/ovl_En_Sb/z_en_sb.h index 2c313c05b..7813cc7c0 100644 --- a/src/overlays/actors/ovl_En_Sb/z_en_sb.h +++ b/src/overlays/actors/ovl_En_Sb/z_en_sb.h @@ -5,9 +5,32 @@ struct EnSb; +typedef void (*EnSbActionFunc)(struct EnSb*, GlobalContext*); + +typedef enum { + /* 0x00 */ SHELLBLADE_OPEN, + /* 0x01 */ SHELLBLADE_WAIT_CLOSED, + /* 0x02 */ SHELLBLADE_WAIT_OPEN, + /* 0x03 */ SHELLBLADE_LUNGE, + /* 0x04 */ SHELLBLADE_BOUNCE +} ShellbladeState; + typedef struct EnSb { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x110]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s limbDrawTable[9]; + /* 0x1BE */ Vec3s transitionDrawTable[9]; + /* 0x1F4 */ EnSbActionFunc actionFunc; + /* 0x1F8 */ ColliderCylinder collider; + /* 0x244 */ s16 fireCount; + /* 0x246 */ s16 state; + /* 0x248 */ s16 isDead; + /* 0x24A */ s16 attackTimer; + /* 0x24C */ s16 vulnerableTimer; + /* 0x24E */ s16 yawAngle; + /* 0x250 */ s16 bounceCounter; + /* 0x252 */ u8 unk_252; + /* 0x253 */ u8 isDrawn; } EnSb; // size = 0x254 extern const ActorInit En_Sb_InitVars; diff --git a/tables/functions.txt b/tables/functions.txt index ae3df7579..154fee4d1 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -6565,23 +6565,23 @@ 0x808E3984:("func_808E3984",), 0x808E3EF0:("EnSb_Init",), 0x808E3FF0:("EnSb_Destroy",), - 0x808E401C:("func_808E401C",), - 0x808E40CC:("func_808E40CC",), - 0x808E4144:("func_808E4144",), - 0x808E41C0:("func_808E41C0",), - 0x808E4234:("func_808E4234",), - 0x808E42DC:("func_808E42DC",), - 0x808E4354:("func_808E4354",), - 0x808E4458:("func_808E4458",), - 0x808E44D4:("func_808E44D4",), - 0x808E45A0:("func_808E45A0",), - 0x808E4654:("func_808E4654",), - 0x808E4740:("func_808E4740",), - 0x808E47E8:("func_808E47E8",), - 0x808E491C:("func_808E491C",), - 0x808E4984:("func_808E4984",), + 0x808E401C:("EnSb_SpawnBubbles",), + 0x808E40CC:("EnSb_SetupWaitClosed",), + 0x808E4144:("EnSb_SetupOpen",), + 0x808E41C0:("EnSb_SetupWaitOpen",), + 0x808E4234:("EnSb_SetupLunge",), + 0x808E42DC:("EnSb_SetupBounce",), + 0x808E4354:("EnSb_SetupIdle",), + 0x808E4458:("EnSb_Idle",), + 0x808E44D4:("EnSb_Open",), + 0x808E45A0:("EnSb_WaitOpen",), + 0x808E4654:("EnSb_TurnAround",), + 0x808E4740:("EnSb_Lunge",), + 0x808E47E8:("EnSb_Bounce",), + 0x808E491C:("EnSb_ReturnToIdle",), + 0x808E4984:("EnSb_UpdateDamage",), 0x808E4AC8:("EnSb_Update",), - 0x808E4C18:("func_808E4C18",), + 0x808E4C18:("EnSb_PostLimbDraw",), 0x808E4CB0:("EnSb_Draw",), 0x808E4FC0:("EnBigslime_Init",), 0x808E530C:("EnBigslime_Destroy",),