diff options
| author | Sirius902 <10891979+Sirius902@users.noreply.github.com> | 2020-10-12 15:45:16 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-12 18:45:16 -0400 |
| commit | 5c631e31703df73c366c83f0bacc84edce2b7f6f (patch) | |
| tree | b24e47bf4559ce8957d55df814dad0b6334114bb /src | |
| parent | fff616d2be4566e28a08fae7d2ab1b51ce455f9b (diff) | |
ovl_En_Horse_Normal (#403)
* merge upstream
* Merge upstream
* Match EnHorseNormal_Init
* Work on EnHorseNormal_Draw (probably finish depending functions first)
* func_80A6CC88
* Work on EnHorseNormal_Draw
* Clang format
* Properly use OPEN_DISPS
* Stop using thisx lol
* Use the funny angle number
* Use &D_04049AD0 because it's not a display list?
* Stop using fun macros to fix stack
* EnHorseNormal_Draw
* EnHorseNormal_Destroy
* EnHorseNormal_Update
* Use disp macros EnHorseNormal_Draw
* Correctly type D_04049AD0
* func_80A6C570
* Name some draw stuff
* Fix names
* Make if condition more readable
* func_80A6B30C and fix incorrect pointer types
* Function prototypes
* func_80A6B250
* Add header comment
* Move skin function to functions.h
* Change to stable
* Cleanup a little
* Match some more
* Work on func_80A6BE6C (won't compile yet)
* Work on func_80A6BE6C again
* Progress
* func_80A6CAFC
* Match all but one :)
* Work on func_80A6BE6C
* Work more on func_80A6BE6C
* Multiply floating point by integer lol
* Reorder assignment to almost match
* func_80A6BE6C
* Fix warning and remove unnecessary forward declarations
* Data section
* Cleanup data a bit
* More cleanup and clang format
* Clang format is a little confused
* More cleanup
* Formatting
* Revert formatting on z_bg_spot01_objects2.c
* Name unk_14C
* Add clone comment
* Name clonePos
* Name and cleanup
* Name some animation related stuff
* Remove unnecessary assignment
* Name cloneRotY
* Use ARRAY_COUNT for sAnimations
* Add more to unknown struct layout
* Use u8 for last struct member
* Use s32 for length
* Add padding disclaimer
* Update src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
* Update src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
* Update src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
* Update src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
* Update src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
* Various suggestions
* Replace 10430.378f
* Remove padding because alignment
* Move function array out of function
* Remove struct name being present twice unecessarily
* Oops forgot the s
* Don't separate static vars from others
* Some cleanup
* Use ARRAY_COUNT(sJntSphItemsInit)
* Minor cleanup
* Rename enum members
* Oops forgot to rename enum
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/code/z_actor.c | 2 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c | 663 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h | 23 |
3 files changed, 663 insertions, 25 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 4c90d800a..129463573 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -67,7 +67,7 @@ void ActorShadow_DrawFunc_WhiteCircle(Actor* actor, Lights* lights, GlobalContex } void ActorShadow_DrawFunc_Squiggly(Actor* actor, Lights* lights, GlobalContext* globalCtx) { - func_8002B200(actor, lights, globalCtx, &D_04049AD0, NULL); + func_8002B200(actor, lights, globalCtx, D_04049AD0, NULL); } void func_8002B66C(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, f32 arg4, f32 arg5, f32 arg6) { diff --git a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c index 62a3996ca..e7dc6549f 100644 --- a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c +++ b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c @@ -1,15 +1,44 @@ +/* + * File: z_en_horse_normal.c + * Overlay: ovl_En_Horse_Normal + * Description: Non-rideable horses (Lon Lon Ranch and Stable) + */ + #include "z_en_horse_normal.h" #define FLAGS 0x00000000 #define THIS ((EnHorseNormal*)thisx) +typedef struct { + Vec3s pos; + u8 unk_06; // this may be a s16 if the always-0 following byte is actually not padding +} EnHorseNormalUnkStruct1; + +typedef struct { + s32 len; + EnHorseNormalUnkStruct1* items; +} EnHorseNormalUnkStruct2; + +typedef enum { + /* 0x00 */ HORSE_CYCLE_ANIMATIONS, + /* 0x01 */ HORSE_WANDER, + /* 0x02 */ HORSE_WAIT, + /* 0x03 */ HORSE_WAIT_CLONE, + /* 0x04 */ HORSE_FOLLOW_PATH +} EnHorseNormalAction; + void EnHorseNormal_Init(Actor* thisx, GlobalContext* globalCtx); void EnHorseNormal_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHorseNormal_Update(Actor* thisx, GlobalContext* globalCtx); void EnHorseNormal_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void func_80A6B91C(EnHorseNormal* this, GlobalContext* globalCtx); +void func_80A6BC48(EnHorseNormal* this); +void func_80A6BCEC(EnHorseNormal* this); +void func_80A6C4CC(EnHorseNormal* this); +void func_80A6C6B0(EnHorseNormal* this); + const ActorInit En_Horse_Normal_InitVars = { ACTOR_EN_HORSE_NORMAL, ACTORTYPE_BG, @@ -21,45 +50,633 @@ const ActorInit En_Horse_Normal_InitVars = { (ActorFunc)EnHorseNormal_Update, (ActorFunc)EnHorseNormal_Draw, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6B250.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6B30C.s") +extern AnimationHeader D_06000608; +extern AnimationHeader D_06000C20; +extern AnimationHeader D_060013A8; +extern AnimationHeader D_06001A1C; +extern AnimationHeader D_06002458; +extern AnimationHeader D_060035D4; +extern AnimationHeader D_06004580; +extern AnimationHeader D_06004C20; +extern AnimationHeader D_060054BC; + +extern SkeletonHeader D_06009FAC; + +static AnimationHeader* sAnimations[] = { + &D_06004580, &D_06004C20, &D_060035D4, &D_06002458, &D_060054BC, &D_06001A1C, &D_06000608, &D_06000C20, &D_060013A8, +}; + +static ColliderCylinderInit sCylinderInit1 = { + { COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x10, COLSHAPE_CYLINDER }, + { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 }, + { 40, 100, 0, { 0, 0, 0 } }, +}; + +static ColliderCylinderInit sCylinderInit2 = { + { COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x10, COLSHAPE_CYLINDER }, + { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 }, + { 60, 100, 0, { 0, 0, 0 } }, +}; + +static ColliderJntSphItemInit sJntSphItemsInit[] = { + { + { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 }, + { 11, { { 0, 0, 0 }, 20 }, 100 }, + }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/EnHorseNormal_Init.s") +static ColliderJntSphInit sJntSphInit = { + { COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x10, COLSHAPE_JNTSPH }, + ARRAY_COUNT(sJntSphItemsInit), + sJntSphItemsInit, +}; + +static CollisionCheckInfoInit sColChkInfoInit = { 10, 35, 100, 0xFE }; + +// Unused +static EnHorseNormalUnkStruct1 D_80A6D428[] = { + { { 1058, 1, 384 }, 7 }, { { 1653, 39, -381 }, 6 }, { { 1606, 1, -1048 }, 6 }, { { 1053, 1, -1620 }, 6 }, + { { -1012, 1, -1633 }, 7 }, { { -1655, 1, -918 }, 6 }, { { -1586, 1, -134 }, 6 }, { { -961, 1, 403 }, 7 }, +}; + +// Unused +static EnHorseNormalUnkStruct2 D_80A6D468 = { ARRAY_COUNT(D_80A6D428), D_80A6D428 }; + +// Unused +static EnHorseNormalUnkStruct1 D_80A6D470[] = { + { { 88, 0, 2078 }, 10 }, { { 2482, 376, 4631 }, 7 }, { { 2228, -28, 6605 }, 12 }, + { { 654, -100, 8864 }, 7 }, { { -297, -500, 10667 }, 12 }, { { -5303, -420, 10640 }, 10 }, + { { -6686, -500, 7760 }, 10 }, { { -5260, 100, 5411 }, 7 }, { { -3573, -269, 3893 }, 10 }, +}; + +// Unused +static EnHorseNormalUnkStruct2 D_80A6D4B8 = { ARRAY_COUNT(D_80A6D470), D_80A6D470 }; + +void func_80A6B250(EnHorseNormal* this) { + static s32 D_80A6D4C0[] = { 0, 16 }; + + if (D_80A6D4C0[this->unk_200] < this->skin.skelAnime.animCurrentFrame && + ((this->unk_200 != 0) || !(D_80A6D4C0[1] < this->skin.skelAnime.animCurrentFrame))) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); + this->unk_200++; + if (this->unk_200 >= ARRAY_COUNT(D_80A6D4C0)) { + this->unk_200 = 0; + } + } +} + +f32 func_80A6B30C(EnHorseNormal* this) { + static f32 D_80A6D4C8[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.5f, 1.5f, 1.5f, 1.5f, 1.0f }; + f32 result; + + if (this->animationIdx == 4) { + result = D_80A6D4C8[this->animationIdx] * this->actor.speedXZ * (1 / 2.0f); + } else if (this->animationIdx == 5) { + result = D_80A6D4C8[this->animationIdx] * this->actor.speedXZ * (1 / 3.0f); + } else if (this->animationIdx == 6) { + result = D_80A6D4C8[this->animationIdx] * this->actor.speedXZ * (1 / 5.0f); + } else { + result = D_80A6D4C8[this->animationIdx]; + } + + return result; +} + +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneScale, 1200, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/EnHorseNormal_Destroy.s") +void EnHorseNormal_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHorseNormal* this = THIS; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6B91C.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + Actor_SetScale(&this->actor, 0.01f); + this->actor.gravity = -3.5f; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Squiggly, 20.0f); + this->actor.speedXZ = 0.0f; + this->actor.posRot2.pos = this->actor.posRot.pos; + this->actor.posRot2.pos.y += 70.0f; + this->action = HORSE_CYCLE_ANIMATIONS; + this->animationIdx = 0; + Collider_InitCylinder(globalCtx, &this->bodyCollider); + Collider_SetCylinder(globalCtx, &this->bodyCollider, &this->actor, &sCylinderInit1); + Collider_InitJntSph(globalCtx, &this->headCollider); + Collider_SetJntSph(globalCtx, &this->headCollider, &this->actor, &sJntSphInit, this->headColliderItems); + Collider_InitCylinder(globalCtx, &this->cloneCollider); + Collider_SetCylinder(globalCtx, &this->cloneCollider, &this->actor, &sCylinderInit2); + func_80061ED4(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + if (globalCtx->sceneNum == SCENE_SPOT20) { + if (this->actor.posRot.rot.z == 0 || gSaveContext.nightFlag) { + Actor_Kill(&this->actor); + return; + } + if (LINK_IS_CHILD) { + if (Flags_GetEventChkInf(0x14)) { + if (this->actor.posRot.rot.z != 3) { + Actor_Kill(&this->actor); + return; + } + } else if (this->actor.posRot.rot.z != 1) { + Actor_Kill(&this->actor); + return; + } + } else if (Flags_GetEventChkInf(0x18) || (DREG(1) != 0)) { + if (this->actor.posRot.rot.z != 7) { + Actor_Kill(&this->actor); + return; + } + } else if (this->actor.posRot.rot.z != 5) { + Actor_Kill(&this->actor); + return; + } + this->actor.initPosRot.rot.z = this->actor.posRot.rot.z = this->actor.shape.rot.z = 0; + func_800A663C(globalCtx, &this->skin, &D_06009FAC, &D_06004580); + SkelAnime_ChangeAnimDefaultStop(&this->skin.skelAnime, sAnimations[this->animationIdx]); + if ((this->actor.posRot.pos.x == -730.0f && this->actor.posRot.pos.y == 0.0f && + this->actor.posRot.pos.z == -1100.0f) || + (this->actor.posRot.pos.x == 880.0f && this->actor.posRot.pos.y == 0.0f && + this->actor.posRot.pos.z == -1170.0f)) { + func_80A6C6B0(this); + return; + } + } else if (globalCtx->sceneNum == SCENE_MALON_STABLE) { + if (!gSaveContext.nightFlag) { + Actor_Kill(&this->actor); + return; + } else { + func_800A663C(globalCtx, &this->skin, &D_06009FAC, &D_06004580); + SkelAnime_ChangeAnimDefaultStop(&this->skin.skelAnime, sAnimations[this->animationIdx]); + func_80A6C6B0(this); + return; + } + } else if (globalCtx->sceneNum == SCENE_SPOT12) { + if (this->actor.posRot.pos.x == 3707.0f && this->actor.posRot.pos.y == 1413.0f && + this->actor.posRot.pos.z == -665.0f) { + func_800A663C(globalCtx, &this->skin, &D_06009FAC, &D_06004580); + SkelAnime_ChangeAnimDefaultStop(&this->skin.skelAnime, sAnimations[this->animationIdx]); + func_80A6C4CC(this); + return; + } + func_800A663C(globalCtx, &this->skin, &D_06009FAC, &D_06004580); + SkelAnime_ChangeAnimDefaultStop(&this->skin.skelAnime, sAnimations[this->animationIdx]); + } else { + func_800A663C(globalCtx, &this->skin, &D_06009FAC, &D_06004580); + SkelAnime_ChangeAnimDefaultStop(&this->skin.skelAnime, sAnimations[this->animationIdx]); + } + if ((this->actor.params & 0xF0) == 0x10 && (this->actor.params & 0xF) != 0xF) { + func_80A6B91C(this, globalCtx); + } else { + func_80A6BC48(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6B9D0.s") +void EnHorseNormal_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHorseNormal* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6BBAC.s") + func_800A6888(globalCtx, &this->skin); + Collider_DestroyCylinder(globalCtx, &this->bodyCollider); + Collider_DestroyCylinder(globalCtx, &this->cloneCollider); + Collider_DestroyJntSph(globalCtx, &this->headCollider); +} + +void func_80A6B91C(EnHorseNormal* this, GlobalContext* globalCtx) { + this->actor.flags |= 0x10; + this->action = HORSE_FOLLOW_PATH; + this->animationIdx = 6; + this->waypoint = 0; + this->actor.speedXZ = 7.0f; + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); +} + +void EnHorseNormal_FollowPath(EnHorseNormal* this, GlobalContext* globalCtx) { + Path* path = &globalCtx->setupPathList[this->actor.params & 0xF]; + Vec3s* pointPos = SEGMENTED_TO_VIRTUAL(path->points); + f32 dx; + f32 dz; + s32 pad; + + pointPos += this->waypoint; + dx = pointPos->x - this->actor.posRot.pos.x; + dz = pointPos->z - this->actor.posRot.pos.z; + Math_SmoothScaleMaxMinS(&this->actor.posRot.rot.y, Math_atan2f(dx, dz) * (0x8000 / M_PI), 0xA, 0x7D0, 1); + this->actor.shape.rot.y = this->actor.posRot.rot.y; + if (SQ(dx) + SQ(dz) < 600.0f) { + this->waypoint++; + if (this->waypoint >= path->count) { + this->waypoint = 0; + } + } + this->skin.skelAnime.animPlaybackSpeed = func_80A6B30C(this); + if (SkelAnime_FrameUpdateMatrix(&this->skin.skelAnime)) { + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); + func_80A6BCEC(this); + } +} + +void EnHorseNormal_NextAnimation(EnHorseNormal* this) { + this->action = HORSE_CYCLE_ANIMATIONS; + this->animationIdx++; + + if (this->animationIdx >= ARRAY_COUNT(sAnimations)) { + this->animationIdx = 0; + } + + SkelAnime_ChangeAnimDefaultStop(&this->skin.skelAnime, sAnimations[this->animationIdx]); +} + +void EnHorseNormal_CycleAnimations(EnHorseNormal* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + + if (SkelAnime_FrameUpdateMatrix(&this->skin.skelAnime)) { + EnHorseNormal_NextAnimation(this); + } +} + +void func_80A6BC48(EnHorseNormal* this) { + this->action = HORSE_WANDER; + this->animationIdx = 0; + this->unk_21C = 0; + this->unk_21E = 0; + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); +} + +void func_80A6BCEC(EnHorseNormal* this) { + if (this->animationIdx == 5) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (this->animationIdx == 6) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } +} + +void func_80A6BD7C(EnHorseNormal* this) { + f32 frame = this->skin.skelAnime.animCurrentFrame; + + if (this->animationIdx == 0 && frame > 28.0f && !(this->unk_1E4 & 1)) { + this->unk_1E4 |= 1; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); + } else if (this->animationIdx == 3 && frame > 25.0f && !(this->unk_1E4 & 2)) { + this->unk_1E4 |= 2; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, + &D_801333E8); + } +} + +void EnHorseNormal_Wander(EnHorseNormal* this, GlobalContext* globalCtx) { + static s32 D_80A6D4F4[] = { 0, 1, 4, 5, 6, 2, 3 }; + static s32 D_80A6D510[] = { 0, 0, 2, 2, 1, 1, 1, 3, 3 }; + s32 phi_t0 = this->animationIdx; + s32 pad; + + switch (D_80A6D510[this->animationIdx]) { + case 0: + func_80A6BD7C(this); + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + break; + case 1: + if (Math_Rand_ZeroOne() < 0.1f) { + this->unk_218 = 2.0f * Math_Rand_ZeroOne() - 1.0f; + } + this->actor.speedXZ += this->unk_218; + if (this->actor.speedXZ <= 0.0f) { + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + phi_t0 = 0; + } else if (this->actor.speedXZ < 3.0f) { + func_80A6B250(this); + phi_t0 = 4; + } else if (this->actor.speedXZ < 6.0f) { + phi_t0 = 5; + } else if (this->actor.speedXZ < 8.0f) { + phi_t0 = 6; + } else { + this->actor.speedXZ = 8.0f; + phi_t0 = 6; + } + if (Math_Rand_ZeroOne() < 0.1f || + (this->unk_21E == 0 && (this->actor.bgCheckFlags & 8 || this->bodyCollider.base.maskA & 2 || + this->headCollider.base.maskA & 2))) { + this->unk_21E += (Math_Rand_ZeroOne() * 30.0f) - 15.0f; + if (this->unk_21E > 50) { + this->unk_21E = 50; + } else if (this->unk_21E < -50) { + this->unk_21E = -50; + } + } + this->unk_21C += this->unk_21E; + if (this->unk_21C < -300) { + this->unk_21C = -300; + } else if (this->unk_21C > 300) { + this->unk_21C = 300; + } else if (Math_Rand_ZeroOne() < 0.25f && fabsf(this->unk_21C) < 100.0f) { + this->unk_21C = 0; + this->unk_21E = 0; + } + this->actor.posRot.rot.y += this->unk_21C; + this->actor.shape.rot.y = this->actor.posRot.rot.y; + break; + case 2: + case 3: + break; + } + + if (phi_t0 != this->animationIdx || SkelAnime_FrameUpdateMatrix(&this->skin.skelAnime)) { + if (phi_t0 != this->animationIdx) { + this->animationIdx = phi_t0; + this->unk_1E4 &= ~1; + this->unk_1E4 &= ~2; + if (phi_t0 == 1) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (phi_t0 == 3) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else { + func_80A6BCEC(this); + } + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, -3.0f); + } else { + switch (D_80A6D510[this->animationIdx]) { + case 0: + if (Math_Rand_ZeroOne() < 0.25f) { + this->unk_218 = 1.0f; + phi_t0 = 4; + } else { + phi_t0 = D_80A6D4F4[(s32)(Math_Rand_ZeroOne() * 2)]; + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + } + break; + case 1: + case 2: + case 3: + break; + } + + this->unk_1E4 &= ~1; + this->unk_1E4 &= ~2; + if (phi_t0 == 1) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (phi_t0 == 3) { + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else { + func_80A6BCEC(this); + } + if (phi_t0 != this->animationIdx) { + this->animationIdx = phi_t0; + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, + -3.0f); + } else { + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); + } + } + } +} + +void func_80A6C4CC(EnHorseNormal* this) { + this->action = HORSE_WAIT; + this->animationIdx = 0; + this->unk_21C = 0; + this->unk_21E = 0; + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); +} + +void EnHorseNormal_Wait(EnHorseNormal* this, GlobalContext* globalCtx) { + if (SkelAnime_FrameUpdateMatrix(&this->skin.skelAnime)) { + f32 rand = Math_Rand_ZeroOne(); + + if (rand < 0.4f) { + this->animationIdx = 0; + } else if (rand < 0.8f) { + this->animationIdx = 1; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else { + this->animationIdx = 3; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } + + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); + } +} + +void func_80A6C6B0(EnHorseNormal* this) { + this->action = HORSE_WAIT_CLONE; + this->animationIdx = 0; + this->unk_21C = 0; + this->unk_21E = 0; + this->actor.flags |= 0x30; + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); +} + +void EnHorseNormal_WaitClone(EnHorseNormal* this, GlobalContext* globalCtx) { + func_80A6BD7C(this); + + if (SkelAnime_FrameUpdateMatrix(&this->skin.skelAnime)) { + f32 rand = Math_Rand_ZeroOne(); + + if (rand < 0.4f) { + this->animationIdx = 0; + } else if (rand < 0.8f) { + this->animationIdx = 1; + this->unk_1E4 |= 0x20; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else { + this->animationIdx = 3; + this->unk_1E4 |= 0x20; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } + + SkelAnime_ChangeAnim(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, + SkelAnime_GetFrameCount(&sAnimations[this->animationIdx]->genericHeader), 2, 0.0f); + + this->unk_1E4 &= ~1; + this->unk_1E4 &= ~2; + this->unk_1E4 &= ~8; + this->unk_1E4 &= ~0x10; + } +} + +void func_80A6C8E0(EnHorseNormal* this, GlobalContext* globalCtx) { + s32 pad; + CollisionPoly* sp38; + s32 pad2; + Vec3f sp28; + s32 sp24; + + sp28.x = (Math_Sins(this->actor.shape.rot.y) * 30.0f) + this->actor.posRot.pos.x; + sp28.y = this->actor.posRot.pos.y + 60.0f; + sp28.z = (Math_Coss(this->actor.shape.rot.y) * 30.0f) + this->actor.posRot.pos.z; + this->unk_220 = func_8003C940(&globalCtx->colCtx, &sp38, &sp24, &sp28); + this->actor.shape.rot.x = Math_atan2f(this->actor.posRot.pos.y - this->unk_220, 30.0f) * (0x8000 / M_PI); +} + +static EnHorseNormalActionFunc sActionFuncs[] = { + EnHorseNormal_CycleAnimations, EnHorseNormal_Wander, EnHorseNormal_Wait, + EnHorseNormal_WaitClone, EnHorseNormal_FollowPath, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6BC00.s") +void EnHorseNormal_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHorseNormal* this = THIS; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6BC48.s") + sActionFuncs[this->action](this, globalCtx); + Actor_MoveForward(&this->actor); + func_8002E4B4(globalCtx, &this->actor, 20.0f, 35.0f, 100.0f, 0x1D); + if (globalCtx->sceneNum == SCENE_SPOT20 && this->actor.posRot.pos.z < -2400.0f) { + this->actor.posRot.pos.z = -2400.0f; + } + this->actor.posRot2.pos = this->actor.posRot.pos; + this->actor.posRot2.pos.y += 70.0f; + this->unk_204 = this->actor.projectedPos; + this->unk_204.y += 120.0f; + Collider_CylinderUpdate(&this->actor, &this->bodyCollider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base); + if (this->actor.speedXZ == 0.0f) { + this->actor.colChkInfo.mass = 0xFF; + } else { + this->actor.colChkInfo.mass = 0xFE; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6BCEC.s") +void func_80A6CAFC(Actor* thisx, GlobalContext* globalCtx, ColliderJntSphItem* collider) { + Vec3f sp4C; + Vec3f sp40; + EnHorseNormal* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6BD7C.s") + for (i = 0; i < this->headCollider.count; i++) { + sp4C.x = this->headCollider.list[i].dim.modelSphere.center.x; + sp4C.y = this->headCollider.list[i].dim.modelSphere.center.y; + sp4C.z = this->headCollider.list[i].dim.modelSphere.center.z; + func_800A6408(collider, this->headCollider.list[i].dim.joint, &sp4C, &sp40); + this->headCollider.list[i].dim.worldSphere.center.x = sp40.x; + this->headCollider.list[i].dim.worldSphere.center.y = sp40.y; + this->headCollider.list[i].dim.worldSphere.center.z = sp40.z; + this->headCollider.list[i].dim.worldSphere.radius = + this->headCollider.list[i].dim.modelSphere.radius * this->headCollider.list[i].dim.scale; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6BE6C.s") + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->headCollider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6C4CC.s") +void func_80A6CC88(GlobalContext* globalCtx, EnHorseNormal* this, Vec3f* arg2) { + f32 animCurrentFrame = this->skin.skelAnime.animCurrentFrame; + f32 wDest; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6C570.s") + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->mf_11D60, arg2, &this->unk_1E8, &wDest); + this->unk_1F4 = this->unk_1E8; + this->unk_1F4.y += 120.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6C6B0.s") + if (this->animationIdx == 0 && animCurrentFrame > 28.0f && !(this->unk_1E4 & 8)) { + this->unk_1E4 |= 8; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->unk_1E8, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (this->animationIdx == 3 && animCurrentFrame > 25.0f && !(this->unk_1E4 & 0x10)) { + this->unk_1E4 |= 0x10; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->unk_1E8, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (this->animationIdx == 3 && this->unk_1E4 & 0x20) { + this->unk_1E4 &= ~0x20; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_1F4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (this->animationIdx == 1 && this->unk_1E4 & 0x20) { + this->unk_1E4 &= ~0x20; + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_1F4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6C760.s") +void EnHorseNormal_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHorseNormal* this = THIS; + Mtx* mtx2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6C8E0.s") + OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_horse_normal.c", 2224); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/EnHorseNormal_Update.s") + if (globalCtx->sceneNum != SCENE_SPOT20 || globalCtx->sceneNum != SCENE_MALON_STABLE) { + func_80A6C8E0(this, globalCtx); + } + func_80093D18(globalCtx->state.gfxCtx); + func_800A6330(&this->actor, globalCtx, &this->skin, func_80A6CAFC, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6CAFC.s") + if (this->action == HORSE_WAIT_CLONE) { + MtxF skinMtx; + Mtx* mtx1; + Vec3f clonePos = { 0.0f, 0.0f, 0.0f }; + s16 cloneRotY; + f32 distFromGround = this->actor.posRot.pos.y - this->actor.groundY; + f32 temp_f0_4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/func_80A6CC88.s") + if (globalCtx->sceneNum == SCENE_MALON_STABLE) { + if (this->actor.posRot.pos.x == 355.0f && this->actor.posRot.pos.y == 0.0f && + this->actor.posRot.pos.z == -245.0f) { + clonePos.x = 235.0f; + clonePos.y = 0.0f; + clonePos.z = 100.0f; + cloneRotY = 0x7FFF; + } else if (this->actor.posRot.pos.x == 238.0f && this->actor.posRot.pos.y == 0.0f && + this->actor.posRot.pos.z == -245.0f) { + clonePos.x = 478.0f; + clonePos.y = 0.0f; + clonePos.z = 100.0f; + cloneRotY = 0x7FFF; + } + } else if (globalCtx->sceneNum == SCENE_SPOT20) { + if (this->actor.posRot.pos.x == -730.0f && this->actor.posRot.pos.y == 0.0f && + this->actor.posRot.pos.z == -1100.0f) { + clonePos.x = 780.0f; + clonePos.y = 0.0f; + clonePos.z = -80.0f; + cloneRotY = 0; + } else if (this->actor.posRot.pos.x == 880.0f && this->actor.posRot.pos.y == 0.0f && + this->actor.posRot.pos.z == -1170.0f) { + clonePos.x = -1000.0f; + clonePos.y = 0.0f; + clonePos.z = -70.0f; + cloneRotY = 0; + } + } + func_80A6CC88(globalCtx, this, &clonePos); + SkinMatrix_SetScaleRotateYRPTranslate(&skinMtx, this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, + this->actor.shape.rot.x, cloneRotY, this->actor.shape.rot.z, clonePos.x, + (this->actor.shape.unk_08 * this->actor.scale.y) + clonePos.y, + clonePos.z); + mtx1 = SkinMatrix_MtxFToNewMtx(globalCtx->state.gfxCtx, &skinMtx); + if (mtx1 == NULL) { + return; + } + gSPMatrix(oGfxCtx->polyOpa.p++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(oGfxCtx->polyOpa.p++, mtx1, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_800A63CC(&this->actor, globalCtx, &this->skin, 0, 0, 1, 0, 3); + this->cloneCollider.dim.pos.x = clonePos.x; + this->cloneCollider.dim.pos.y = clonePos.y; + this->cloneCollider.dim.pos.z = clonePos.z; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->cloneCollider.base); + func_80094044(globalCtx->state.gfxCtx); + gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0, 0, 0, 0, 0, 255); + Matrix_Translate(clonePos.x, clonePos.y, clonePos.z, MTXMODE_NEW); + temp_f0_4 = (1.0f - (distFromGround * 0.01f)) * this->actor.shape.unk_10; + Matrix_Scale(this->actor.scale.x * temp_f0_4, 1.0f, this->actor.scale.z * temp_f0_4, MTXMODE_APPLY); + Matrix_RotateY(cloneRotY * (2.0f * M_PI / 0x10000), MTXMODE_APPLY); + mtx2 = Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_horse_normal.c", 2329); + if (mtx2 != NULL) { + gSPMatrix(oGfxCtx->polyXlu.p++, mtx2, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(oGfxCtx->polyXlu.p++, D_04049AD0); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Normal/EnHorseNormal_Draw.s") + CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_horse_normal.c", 2339); +} diff --git a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h index 8ccc1357b..e34efe07e 100644 --- a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h +++ b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h @@ -6,9 +6,30 @@ struct EnHorseNormal; +typedef void (*EnHorseNormalActionFunc)(struct EnHorseNormal*, GlobalContext*); + typedef struct EnHorseNormal { /* 0x0000 */ Actor actor; - /* 0x014C */ char unk_14C[0x1DC]; + /* 0x014C */ s32 action; + /* 0x0150 */ s32 animationIdx; + /* 0x0154 */ PSkinAwb skin; + /* 0x01E4 */ u16 unk_1E4; + /* 0x01E8 */ Vec3f unk_1E8; + /* 0x01F4 */ Vec3f unk_1F4; + /* 0x0200 */ s32 unk_200; + /* 0x0204 */ Vec3f unk_204; + /* 0x0210 */ char unk_210[0x08]; + /* 0x0218 */ f32 unk_218; + /* 0x021C */ s16 unk_21C; + /* 0x021E */ s16 unk_21E; + /* 0x0220 */ f32 unk_220; + /* 0x0224 */ char unk_224[0x04]; + /* 0x0228 */ ColliderCylinder bodyCollider; + /* 0x0274 */ ColliderJntSph headCollider; + /* 0x0294 */ ColliderJntSphItem headColliderItems[1]; + /* 0x02D4 */ ColliderCylinder cloneCollider; + /* 0x0320 */ char unk_320[0x04]; + /* 0x0324 */ s32 waypoint; } EnHorseNormal; // size = 0x0328 extern const ActorInit En_Horse_Normal_InitVars; |
