diff --git a/assets/xml/objects/object_crow.xml b/assets/xml/objects/object_crow.xml index 3092d91ec..de51da580 100644 --- a/assets/xml/objects/object_crow.xml +++ b/assets/xml/objects/object_crow.xml @@ -1,24 +1,24 @@  - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/spec b/spec index 82a48366f..3fb3af904 100644 --- a/spec +++ b/spec @@ -2156,8 +2156,7 @@ beginseg name "ovl_En_Crow" compress include "build/src/overlays/actors/ovl_En_Crow/z_en_crow.o" - include "build/data/ovl_En_Crow/ovl_En_Crow.data.o" - include "build/data/ovl_En_Crow/ovl_En_Crow.reloc.o" + include "build/src/overlays/actors/ovl_En_Crow/ovl_En_Crow_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Crow/z_en_crow.c b/src/overlays/actors/ovl_En_Crow/z_en_crow.c index 8293ddd94..bf77b1897 100644 --- a/src/overlays/actors/ovl_En_Crow/z_en_crow.c +++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.c @@ -15,14 +15,18 @@ void EnCrow_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnCrow_Update(Actor* thisx, GlobalContext* globalCtx); void EnCrow_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_8099AC8C(EnCrow* this, GlobalContext* globalCtx); -void func_8099B0CC(EnCrow* this, GlobalContext* globalCtx); -void func_8099B584(EnCrow* this, GlobalContext* globalCtx); -void func_8099B6C4(EnCrow* this, GlobalContext* globalCtx); -void func_8099B838(EnCrow* this, GlobalContext* globalCtx); -void func_8099B9E8(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupFlyIdle(EnCrow* this); +void EnCrow_FlyIdle(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupDiveAttack(EnCrow* this); +void EnCrow_DiveAttack(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_CheckIfFrozen(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_Damaged(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupDie(EnCrow* this); +void EnCrow_Die(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupRespawn(EnCrow* this); +void EnCrow_TurnAway(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_Respawn(EnCrow* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Crow_InitVars = { ACTOR_EN_CROW, ACTORCAT_ENEMY, @@ -35,25 +39,36 @@ const ActorInit En_Crow_InitVars = { (ActorFunc)EnCrow_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8099C070[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_8099C094 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_8099C070, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_8099C0A4 = { 1, 15, 30, 30 }; +static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 30, 30 }; -// static DamageTable sDamageTable = { -static DamageTable D_8099C0AC = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -88,60 +103,470 @@ static DamageTable D_8099C0AC = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8099C0D0[] = { +static s32 D_8099C0CC = 0; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE), ICHAIN_S8(hintId, 88, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP), }; -#endif +void EnCrow_Init(Actor* thisx, GlobalContext* globalCtx) { + EnCrow* this = THIS; -extern ColliderJntSphElementInit D_8099C070[1]; -extern ColliderJntSphInit D_8099C094; -extern CollisionCheckInfoInit D_8099C0A4; -extern DamageTable D_8099C0AC; -extern InitChainEntry D_8099C0D0[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->jointTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderItems); + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); + D_8099C0CC = 0; + if (this->actor.parent != NULL) { + this->actor.flags &= ~ACTOR_FLAG_1; + } + EnCrow_SetupFlyIdle(this); +} -extern UNK_TYPE D_060000F0; +void EnCrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnCrow* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Init.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Destroy.s") +void EnCrow_SetupFlyIdle(EnCrow* this) { + this->timer = 100; + this->collider.base.acFlags |= AC_ON; + this->actionFunc = EnCrow_FlyIdle; + this->skelAnime.playSpeed = 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099AC58.s") +void EnCrow_FlyIdle(EnCrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 dist; + s32 onInitialAnimFrame; + s16 yaw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099AC8C.s") + SkelAnime_Update(&this->skelAnime); + onInitialAnimFrame = Animation_OnFrame(&this->skelAnime, 0.0f); + this->actor.speedXZ = (Rand_ZeroOne() * 1.5f) + 3.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B098.s") + if ((this->actor.parent != NULL) && (this->actor.parent->home.rot.z == 0)) { + this->actor.home.pos.x = this->actor.parent->world.pos.x; + this->actor.home.pos.z = this->actor.parent->world.pos.z; + dist = Actor_XZDistanceToPoint(&this->actor, &this->actor.parent->world.pos); + } else { + dist = 450.0f; + this->actor.flags |= ACTOR_FLAG_1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B0CC.s") + if (this->actor.bgCheckFlags & 8) { + this->aimRotY = this->actor.wallYaw; + } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 300.0f) { + this->aimRotY = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B318.s") + if ((Math_SmoothStepToS(&this->actor.shape.rot.y, this->aimRotY, 5, 0x300, 0x10) == 0) && onInitialAnimFrame && + (Rand_ZeroOne() < 0.1f)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B384.s") + yaw = (Actor_YawToPoint(&this->actor, &this->actor.home.pos) - this->actor.shape.rot.y); + if (yaw > 0) { + this->aimRotY += Rand_S16Offset(0x1000, 0x1000); + } else { + this->aimRotY -= Rand_S16Offset(0x1000, 0x1000); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B584.s") + if ((this->actor.depthInWater > -40.0f) || (this->actor.bgCheckFlags & 1)) { + this->aimRotX = -0x1000; + } else if (this->actor.world.pos.y < (this->actor.home.pos.y - 50.0f)) { + this->aimRotX = -Rand_S16Offset(0x800, 0x800); + } else if (this->actor.world.pos.y > (this->actor.home.pos.y + 50.0f)) { + this->aimRotX = Rand_S16Offset(0x800, 0x800); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B6AC.s") + if ((Math_SmoothStepToS(&this->actor.shape.rot.x, this->aimRotX, 0xA, 0x100, 8) == 0) && onInitialAnimFrame && + (Rand_ZeroOne() < 0.1f)) { + if (this->actor.home.pos.y < this->actor.world.pos.y) { + this->aimRotX -= Rand_S16Offset(0x400, 0x400); + } else { + this->aimRotX += Rand_S16Offset(0x400, 0x400); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B6C4.s") + this->aimRotX = CLAMP(this->aimRotX, -0x1000, 0x1000); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B778.s") + if (this->actor.bgCheckFlags & 1) { + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x100, 0x400); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B838.s") + if (this->timer != 0) { + this->timer--; + } + if ((this->timer == 0) && + (((this->actor.xzDistToPlayer < 300.0f) && !(player->stateFlags1 & 0x800000)) || (dist < 300.0f)) && + (this->actor.depthInWater < -40.0f) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + if (dist < this->actor.xzDistToPlayer) { + this->actor.child = this->actor.parent; + } else { + this->actor.child = &player->actor; + } + EnCrow_SetupDiveAttack(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B8EC.s") +void EnCrow_SetupDiveAttack(EnCrow* this) { + this->timer = 300; + this->actionFunc = EnCrow_DiveAttack; + this->actor.speedXZ = 4.0f; + this->skelAnime.playSpeed = 2.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B9E8.s") +void EnCrow_DiveAttack(EnCrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 isFacingActor; + Vec3f pos; + s16 pitch; + s16 pitchTarget; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099BAB4.s") + SkelAnime_Update(&this->skelAnime); + if (this->timer != 0) { + this->timer--; + } + isFacingActor = Actor_ActorAIsFacingActorB(&this->actor, this->actor.child, 0x2800); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Update.s") + if (isFacingActor) { + if (&player->actor == this->actor.child) { + pos.y = this->actor.child->world.pos.y + 20.0f; + } else { + pos.y = this->actor.child->world.pos.y + 40.0f; + } + pos.x = this->actor.child->world.pos.x; + pos.z = this->actor.child->world.pos.z; + pitch = Actor_PitchToPoint(&this->actor, &pos); + pitchTarget = CLAMP(pitch, -0x3000, 0x3000); + Math_SmoothStepToS(&this->actor.shape.rot.x, pitchTarget, 2, 0x400, 64); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 2, 0x100, 16); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099BE48.s") + if (isFacingActor || (Actor_XZDistanceBetweenActors(&this->actor, this->actor.child) > 80.0f)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, this->actor.child), 4, 0xC00, + 0xC0); + } + if (((this->timer == 0) || ((&player->actor != this->actor.child) && (this->actor.child->home.rot.z != 0)) || + ((&player->actor == this->actor.child) && + ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (player->stateFlags1 & 0x800000))) || + ((this->collider.base.atFlags & AT_HIT) || (this->actor.bgCheckFlags & 9))) || + (this->actor.depthInWater > -40.0f)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099BF20.s") + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_ATTACK); + } + EnCrow_SetupFlyIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Draw.s") +void EnCrow_CheckIfFrozen(EnCrow* this, GlobalContext* globalCtx) { + if (this->deathMode == 10) { + this->deathMode = 0; + this->effectAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->bodyPartsPos, 4, 2, 0.2f, 0.2f); + } +} + +void EnCrow_SetupDamaged(EnCrow* this, GlobalContext* globalCtx) { + f32 scale; + + this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); + this->actor.velocity.y = 0.0f; + Animation_Change(&this->skelAnime, &gGuayFlyAnim, 0.4f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, -3.0f); + this->actor.shape.yOffset = 0.0f; + this->actor.targetArrowOffset = 0.0f; + this->actor.bgCheckFlags &= ~1; + scale = (this->actor.scale.x * 100.0f); + this->actor.world.pos.y += 20.0f * scale; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_DEAD); + + if (this->actor.colChkInfo.damageEffect == 3) { + this->deathMode = 10; // Ice arrows + this->effectAlpha = 1.0f; + this->effectScale = 0.75f; + this->steamScale = 0.5f; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->deathMode = 20; // Light Arrows + this->effectAlpha = 4.0f; + this->steamScale = 0.5f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.elements->info.bumper.hitPos.x, + this->collider.elements->info.bumper.hitPos.y, this->collider.elements->info.bumper.hitPos.z, 0, 0, + 0, CLEAR_TAG_SMALL_LIGHT_RAYS); + } else if (this->actor.colChkInfo.damageEffect == 2) { + this->deathMode = 0; // Fire arrows + this->effectAlpha = 4.0f; + this->steamScale = 0.5f; + } + + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + if (this->actor.flags & ACTOR_FLAG_8000) { + this->actor.speedXZ = 0.0f; + } + + this->collider.base.acFlags &= ~AC_ON; + this->actor.flags |= ACTOR_FLAG_10; + + this->actionFunc = EnCrow_Damaged; +} + +void EnCrow_Damaged(EnCrow* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + this->actor.colorFilterTimer = 40; + + if (!(this->actor.flags & ACTOR_FLAG_8000)) { + if (this->deathMode != 10) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200); + this->actor.shape.rot.z += 0x1780; + } + if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) { + EnCrow_CheckIfFrozen(this, globalCtx); + func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, this->actor.scale.x * 10000.0f, + 0, 0); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + + if (this->actor.parent != NULL) { + Actor_MarkForDeath(&this->actor); + return; + } + EnCrow_SetupDie(this); + } + } +} + +void EnCrow_SetupDie(EnCrow* this) { + this->actor.colorFilterTimer = 0; + this->actionFunc = EnCrow_Die; +} + +void EnCrow_Die(EnCrow* this, GlobalContext* globalCtx) { + f32 stepScale; + + if (this->actor.params != 0) { + stepScale = 0.006f; + } else { + stepScale = 0.002f; + } + if (Math_StepToF(&this->actor.scale.x, 0.0f, stepScale) != 0) { + if (this->actor.params == 0) { + D_8099C0CC++; + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x80); + } else { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); + } + EnCrow_SetupRespawn(this); + } + this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; +} + +void EnCrow_SetupTurnAway(EnCrow* this) { + this->timer = 100; + this->aimRotX = -0x1000; + this->actor.speedXZ = 3.5f; + this->aimRotY = this->actor.yawTowardsPlayer + 0x8000; + this->skelAnime.playSpeed = 2.0f; + if (this->actor.colChkInfo.damageEffect == 1) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + } else { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = EnCrow_TurnAway; +} + +void EnCrow_TurnAway(EnCrow* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (this->actor.bgCheckFlags & 8) { + this->aimRotY = this->actor.wallYaw; + } else { + this->aimRotY = this->actor.yawTowardsPlayer + 0x8000; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->aimRotY, 3, 0xC00, 0xC0); + Math_SmoothStepToS(&this->actor.shape.rot.x, this->aimRotX, 5, 0x100, 0x10); + + if (this->timer != 0) { + this->timer--; + } + + if (this->timer == 0) { + EnCrow_SetupFlyIdle(this); + } +} + +void EnCrow_SetupRespawn(EnCrow* this) { + if (D_8099C0CC == 10) { + this->actor.params = 1; + D_8099C0CC = 0; + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius * 0.03f * 100.0f; + } else { + this->actor.params = 0; + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius; + } + Animation_PlayLoop(&this->skelAnime, &gGuayFlyAnim); + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + this->timer = 300; + this->actor.draw = NULL; + this->actor.shape.yOffset = 2000.0f; + this->actor.targetArrowOffset = 2000.0; + this->effectAlpha = 0.0f; + this->actionFunc = EnCrow_Respawn; +} + +void EnCrow_Respawn(EnCrow* this, GlobalContext* globalCtx) { + f32 target; + + if (this->timer != 0) { + this->timer--; + } + if (this->timer == 0) { + SkelAnime_Update(&this->skelAnime); + this->actor.draw = EnCrow_Draw; + if (this->actor.params != 0) { + target = 0.03f; + } else { + target = 0.01f; + } + if (Math_StepToF(&this->actor.scale.x, target, target * 0.1f)) { + this->actor.flags |= ACTOR_FLAG_1; + this->actor.flags &= ~ACTOR_FLAG_10; + this->actor.colChkInfo.health = 1; + EnCrow_SetupFlyIdle(this); + } + this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; + } +} + +void EnCrow_UpdateDamage(EnCrow* this, GlobalContext* globalCtx) { + + if (this->collider.base.acFlags & AT_HIT) { + this->collider.base.acFlags &= ~AT_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.elements->info); + + if (this->actor.colChkInfo.damageEffect == 1) { + EnCrow_SetupTurnAway(this); + + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->deathMode = 31; // Stunned via deku nuts or zora barrier + this->effectAlpha = 2.0f; + this->steamScale = 0.5f; + EnCrow_SetupTurnAway(this); + + } else { + this->actor.colChkInfo.health = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + EnCrow_SetupDamaged(this, globalCtx); + } + } +} + +void EnCrow_Update(Actor* thisx, GlobalContext* globalCtx) { + f32 pad; + EnCrow* this = (EnCrow*)thisx; + f32 height; + f32 scale; + + EnCrow_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + scale = this->actor.scale.x * 100.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.x = -this->actor.shape.rot.x; + + if (this->actionFunc != EnCrow_Respawn) { + if (this->actor.colChkInfo.health != 0) { + height = 20.0f * scale; + Actor_MoveWithoutGravity(&this->actor); + } else { + height = 0.0f; + Actor_MoveWithGravity(&this->actor); + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f * scale, 25.0f * scale, 50.0f * scale, 7); + } else { + height = 0.0f; + } + + this->collider.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y + height; + this->collider.elements[0].dim.worldSphere.center.z = this->actor.world.pos.z; + + if (this->actionFunc == EnCrow_DiveAttack) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (this->actionFunc != EnCrow_Respawn) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + Actor_SetFocus(&this->actor, height); + + if ((this->actor.colChkInfo.health != 0) && (Animation_OnFrame(&this->skelAnime, 3.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_FLUTTER); + } + if (this->effectAlpha > 0.0f) { + if (this->deathMode != 10) { + Math_StepToF(&this->effectAlpha, 0.0f, 0.05f); + this->steamScale = (this->effectAlpha + 1.0f) * 0.25f; + if (this->steamScale > 0.5f) { + this->steamScale = 0.5f; + } else { + this->steamScale = this->steamScale; + } + } else if (Math_StepToF(&this->effectScale, 0.5f, 0.0125f) == 0) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +s32 EnCrow_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnCrow* this = (EnCrow*)thisx; + + if (this->actor.colChkInfo.health != 0) { + if (limbIndex == OBJECT_CROW_LIMB_UPPER_TAIL) { + rot->y += (s16)(0xC00 * sin_rad(this->skelAnime.curFrame * (M_PI / 4))); + } else if (limbIndex == OBJECT_CROW_LIMB_TAIL) { + rot->y += (s16)(0x1400 * sin_rad((this->skelAnime.curFrame + 2.5f) * (M_PI / 4))); + } + } + return false; +} + +void EnCrow_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnCrow* this = (EnCrow*)thisx; + + if (limbIndex == OBJECT_CROW_LIMB_BODY) { + Matrix_GetStateTranslationAndScaledX(2500.0f, this->bodyPartsPos); + return; + } + if ((limbIndex == OBJECT_CROW_LIMB_RIGHT_WING_TIP) || (limbIndex == OBJECT_CROW_LIMB_LEFT_WING_TIP) || + (limbIndex == OBJECT_CROW_LIMB_TAIL)) { + Matrix_GetStateTranslation(&this->bodyPartsPos[(limbIndex >> 1) - 1]); + } +} + +void EnCrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnCrow* this = (EnCrow*)thisx; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnCrow_OverrideLimbDraw, EnCrow_PostLimbDraw, &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), + this->actor.scale.x * 100.0f * this->steamScale, this->effectScale, this->effectAlpha, + this->deathMode); +} diff --git a/src/overlays/actors/ovl_En_Crow/z_en_crow.h b/src/overlays/actors/ovl_En_Crow/z_en_crow.h index e1d763142..9076a198c 100644 --- a/src/overlays/actors/ovl_En_Crow/z_en_crow.h +++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.h @@ -2,6 +2,7 @@ #define Z_EN_CROW_H #include "global.h" +#include "objects/object_crow/object_crow.h" struct EnCrow; @@ -9,9 +10,20 @@ typedef void (*EnCrowActionFunc)(struct EnCrow*, GlobalContext*); typedef struct EnCrow { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnCrowActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x110]; + /* 0x18C */ u8 deathMode; + /* 0x18E */ s16 timer; + /* 0x190 */ s16 aimRotX; + /* 0x192 */ s16 aimRotY; + /* 0x194 */ Vec3s jointTable[OBJECT_CROW_LIMB_MAX]; + /* 0x1CA */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX]; + /* 0x200 */ ColliderJntSph collider; + /* 0x220 */ ColliderJntSphElement colliderItems[1]; + /* 0x260 */ Vec3f bodyPartsPos[4]; + /* 0x290 */ f32 effectAlpha; + /* 0x294 */ f32 steamScale; + /* 0x298 */ f32 effectScale; } EnCrow; // size = 0x29C extern const ActorInit En_Crow_InitVars; diff --git a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c index 7cfefa59c..c21395ef5 100644 --- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c +++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c @@ -225,7 +225,7 @@ void EnRuppecrow_ShatterIce(EnRuppecrow* this, GlobalContext* globalCtx) { if (this->currentEffect == ENRUPPECROW_EFFECT_ICE) { this->currentEffect = ENRUPPECROW_EFFECT_NONE; this->unk_2C8 = 0.0f; - Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ENRUPPECROW_LIMB_POS_COUNT, 0x2, 0.2f, 0.2f); + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 0x2, 0.2f, 0.2f); } } @@ -440,7 +440,7 @@ void EnRuppecrow_HandleDeath(EnRuppecrow* this) { this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); this->actor.velocity.y = 0.0f; - Animation_Change(&this->skelAnime, &object_crow_Anim_0000F0, 0.4f, 0.0f, 0.0f, 0x1, -3.0f); + Animation_Change(&this->skelAnime, &gGuayFlyAnim, 0.4f, 0.0f, 0.0f, 0x1, -3.0f); this->actor.shape.yOffset = 0.0f; this->actor.targetArrowOffset = 0.0f; @@ -627,8 +627,8 @@ void EnRuppecrow_Init(Actor* thisx, GlobalContext* globalCtx2) { EnRuppecrow* this = THIS; Actor_ProcessInitChain(&this->actor, sInitChain); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_crow_Skel_0010C0, &object_crow_Anim_0000F0, this->joinTable, - this->morphTable, ENRUPPECROW_LIMB_COUNT); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->joinTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); Collider_InitJntSph(globalCtx, &this->collider); diff --git a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h index 4c9cafa67..de9fceac9 100644 --- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h +++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h @@ -2,11 +2,11 @@ #define Z_EN_RUPPECROW_H #include "global.h" +#include "objects/object_crow/object_crow.h" #define ENRUPPECROW_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA) #define ENRUPPECROW_RUPEE_COUNT 20 -#define ENRUPPECROW_LIMB_COUNT 9 #define ENRUPPECROW_LIMB_POS_COUNT 4 struct EnRuppecrow; @@ -19,8 +19,8 @@ typedef struct EnRuppecrow { /* 0x194 */ SkelAnime skelAnime; /* 0x1D8 */ EnRuppecrowActionFunc actionFunc; /* 0x1DC */ UNK_TYPE4 unk_1DC; // unused - /* 0x1E0 */ Vec3s joinTable[ENRUPPECROW_LIMB_COUNT]; - /* 0x216 */ Vec3s morphTable[ENRUPPECROW_LIMB_COUNT]; + /* 0x1E0 */ Vec3s joinTable[OBJECT_CROW_LIMB_MAX]; + /* 0x216 */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX]; /* 0x24C */ Path* path; /* 0x250 */ s32 currentPoint; /* 0x254 */ ColliderJntSph collider; diff --git a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c index e11deb354..23a16debc 100644 --- a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c +++ b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c @@ -95,8 +95,8 @@ void EnSyatekiCrow_Init(Actor* thisx, GlobalContext* globalCtx2) { } Actor_ProcessInitChain(&this->actor, sInitChain); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_crow_Skel_0010C0, &object_crow_Anim_0000F0, - this->jointTable, this->morphTable, 9); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->jointTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); Collider_InitJntSph(globalCtx, &this->unk_23C); Collider_SetJntSph(globalCtx, &this->unk_23C, &this->actor, &sJntSphInit, &this->unk_25C); this->unk_23C.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; @@ -225,7 +225,7 @@ void func_809CAAF8(EnSyatekiCrow* this) { this->unk_1C2 = 0; this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); this->actor.velocity.y = 0.0f; - Animation_Change(&this->skelAnime, &object_crow_Anim_0000F0, 0.4f, 0.0f, 0.0f, 1, -3.0f); + Animation_Change(&this->skelAnime, &gGuayFlyAnim, 0.4f, 0.0f, 0.0f, 1, -3.0f); this->actor.bgCheckFlags &= ~1; Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_DEAD); Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); @@ -290,9 +290,9 @@ s32 EnSyatekiCrow_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx* Actor* thisx) { EnSyatekiCrow* this = THIS; - if (limbIndex == OBJECT_CROW_LIMB_07) { + if (limbIndex == OBJECT_CROW_LIMB_UPPER_TAIL) { rot->y += (s16)(3072.0f * sin_rad(this->skelAnime.curFrame * (M_PI / 4))); - } else if (limbIndex == OBJECT_CROW_LIMB_08) { + } else if (limbIndex == OBJECT_CROW_LIMB_TAIL) { rot->y += (s16)(5120.0f * sin_rad((this->skelAnime.curFrame + 2.5f) * (M_PI / 4))); } @@ -303,11 +303,11 @@ void EnSyatekiCrow_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d EnSyatekiCrow* this = THIS; Vec3f* sp1C; - if (limbIndex == OBJECT_CROW_LIMB_02) { + if (limbIndex == OBJECT_CROW_LIMB_BODY) { Matrix_MultiplyVector3fByState(&D_809CB0D8, &this->unk_144[0]); this->unk_144[0].y -= 20.0f; - } else if ((limbIndex == OBJECT_CROW_LIMB_04) || (limbIndex == OBJECT_CROW_LIMB_06) || - (limbIndex == OBJECT_CROW_LIMB_08)) { + } else if ((limbIndex == OBJECT_CROW_LIMB_RIGHT_WING_TIP) || (limbIndex == OBJECT_CROW_LIMB_LEFT_WING_TIP) || + (limbIndex == OBJECT_CROW_LIMB_TAIL)) { sp1C = &this->unk_144[(limbIndex >> 1) - 1]; Matrix_MultiplyVector3fByState(&D_809CB050, sp1C); sp1C->y -= 20.0f; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 87bc6d1e8..9d7af0b01 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8573,23 +8573,23 @@ 0x8099AA84:("func_8099AA84",), 0x8099AB30:("EnCrow_Init",), 0x8099AC2C:("EnCrow_Destroy",), - 0x8099AC58:("func_8099AC58",), - 0x8099AC8C:("func_8099AC8C",), - 0x8099B098:("func_8099B098",), - 0x8099B0CC:("func_8099B0CC",), - 0x8099B318:("func_8099B318",), - 0x8099B384:("func_8099B384",), - 0x8099B584:("func_8099B584",), - 0x8099B6AC:("func_8099B6AC",), - 0x8099B6C4:("func_8099B6C4",), - 0x8099B778:("func_8099B778",), - 0x8099B838:("func_8099B838",), - 0x8099B8EC:("func_8099B8EC",), - 0x8099B9E8:("func_8099B9E8",), - 0x8099BAB4:("func_8099BAB4",), + 0x8099AC58:("EnCrow_SetupFlyIdle",), + 0x8099AC8C:("EnCrow_FlyIdle",), + 0x8099B098:("EnCrow_SetupDiveAttack",), + 0x8099B0CC:("EnCrow_DiveAttack",), + 0x8099B318:("EnCrow_CheckIfFrozen",), + 0x8099B384:("EnCrow_SetupDamaged",), + 0x8099B584:("EnCrow_Damaged",), + 0x8099B6AC:("EnCrow_SetupDie",), + 0x8099B6C4:("EnCrow_Die",), + 0x8099B778:("EnCrow_SetupTurnAway",), + 0x8099B838:("EnCrow_TurnAway",), + 0x8099B8EC:("EnCrow_SetupRespawn",), + 0x8099B9E8:("EnCrow_Respawn",), + 0x8099BAB4:("EnCrow_UpdateDamage",), 0x8099BB84:("EnCrow_Update",), - 0x8099BE48:("func_8099BE48",), - 0x8099BF20:("func_8099BF20",), + 0x8099BE48:("EnCrow_OverrideLimbDraw",), + 0x8099BF20:("EnCrow_PostLimbDraw",), 0x8099BFA4:("EnCrow_Draw",), 0x8099C290:("func_8099C290",), 0x8099C328:("func_8099C328",),