`EnNwc` OK and three objects documented (`object_niw` and `object_nwc` and `object_hs`) and some Actor docs( `EnNiw` and `EnAttackNiw` and `EnHg`) (#715)

* EnNwc: OK and some Niw Docs

* Update src/overlays/actors/ovl_En_Nwc/z_en_nwc.c

Co-authored-by: Parker Burnett <burnettparker@gmail.com>

* Update src/overlays/actors/ovl_En_Nwc/z_en_nwc.c

Co-authored-by: Parker Burnett <burnettparker@gmail.com>

* Update src/overlays/actors/ovl_En_Nwc/z_en_nwc.c

Co-authored-by: Parker Burnett <burnettparker@gmail.com>

* EnNwc: Overwrite->Override

* EnAttackNiw: fix merges

* AttackNiw and Niw: some docs

* formater pass

* EnNwc: fixed savecontext change

* Niw and Attackniw: more docs

* Apply suggestions from code review

Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>

* Nwc,Niw: requested doc changes

* Nwc: extracted and marked broken texture

* Apply suggestions from code review

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* EnNwc: more requested changes

* Nwc: more requested changes

* Apply suggestions from code review

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* EnHs: object_hs documented, some ovl_En_Hs docs

* EnHs: animation names

* EnHs: some text docs

* EnHs: fear anim changed to shivering now that we know it was used in OOT

* EnHs: more docs and format pass

* Apply suggestions from code review

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* EnHs: more docs and updates to var name changes

* Niw,Nwc,Hs: added description to object files

* Hs: changed from playerOffset to offset

Co-authored-by: Isghj8 <isghj8@gmail.com>
Co-authored-by: Parker Burnett <burnettparker@gmail.com>
Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
This commit is contained in:
Isghj 2022-05-25 19:19:38 -07:00 committed by GitHub
parent f1d1d83206
commit 12b995093f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1411 additions and 846 deletions

View File

@ -1,8 +1,9 @@
<Root>
<!-- Grog: the Cucco keeper, you raise his Cucco chicks into adults to earn the Bunny Hood mask -->
<File Name="object_hs" Segment="6">
<Animation Name="object_hs_Anim_000304" Offset="0x304" />
<Animation Name="object_hs_Anim_000528" Offset="0x528" />
<Animation Name="object_hs_Anim_0005C0" Offset="0x5C0" />
<Animation Name="gHsShiveringAnim" Offset="0x304" /> <!-- unused, "h_purupuru" japanese onomatopoeic for 'shivering' -->
<Animation Name="gHsPleadingAnim" Offset="0x528" /> <!-- unused, "h_tanomuu" japanese for 'to beg' -->
<Animation Name="gHsIdleAnim" Offset="0x5C0" /> <!-- "h_matsu" japanese for 'to wait' -->
<DList Name="object_hs_DL_003760" Offset="0x3760" />
<DList Name="object_hs_DL_003AB0" Offset="0x3AB0" />
<DList Name="object_hs_DL_004140" Offset="0x4140" />
@ -13,35 +14,38 @@
<DList Name="object_hs_DL_004960" Offset="0x4960" />
<DList Name="object_hs_DL_004AB8" Offset="0x4AB8" />
<DList Name="object_hs_DL_004BF0" Offset="0x4BF0" />
<DList Name="object_hs_DL_004CF0" Offset="0x4CF0" />
<DList Name="gHsEndDL" Offset="0x4CF0" />
<DList Name="object_hs_DL_004CF8" Offset="0x4CF8" />
<Texture Name="object_hs_TLUT_004E50" OutName="tlut_004E50" Format="rgba16" Width="16" Height="16" Offset="0x4E50" />
<Texture Name="object_hs_Tex_005050" OutName="tex_005050" Format="ci8" Width="16" Height="32" Offset="0x5050" />
<Texture Name="object_hs_Tex_005250" OutName="tex_005250" Format="ci8" Width="8" Height="8" Offset="0x5250" />
<Texture Name="object_hs_Tex_005290" OutName="tex_005290" Format="ci8" Width="32" Height="16" Offset="0x5290" />
<Texture Name="object_hs_Tex_005490" OutName="tex_005490" Format="rgba16" Width="32" Height="16" Offset="0x5490" />
<Texture Name="object_hs_Tex_005890" OutName="tex_005890" Format="ci8" Width="16" Height="16" Offset="0x5890" />
<Texture Name="object_hs_Tex_005990" OutName="tex_005990" Format="ci8" Width="16" Height="16" Offset="0x5990" />
<Texture Name="object_hs_Tex_005A90" OutName="tex_005A90" Format="rgba16" Width="4" Height="4" Offset="0x5A90" />
<Texture Name="object_hs_Tex_005AB0" OutName="tex_005AB0" Format="ci8" Width="8" Height="8" Offset="0x5AB0" />
<Texture Name="object_hs_Tex_005AF0" OutName="tex_005AF0" Format="ci8" Width="32" Height="32" Offset="0x5AF0" />
<Texture Name="object_hs_Tex_005EF0" OutName="tex_005EF0" Format="ci8" Width="8" Height="16" Offset="0x5EF0" />
<Texture Name="object_hs_Tex_005F70" OutName="tex_005F70" Format="ci8" Width="16" Height="32" Offset="0x5F70" />
<Limb Name="object_hs_Standardlimb_006170" Type="Standard" EnumName="OBJECT_HS_LIMB_01" Offset="0x6170" />
<Limb Name="object_hs_Standardlimb_00617C" Type="Standard" EnumName="OBJECT_HS_LIMB_02" Offset="0x617C" />
<Limb Name="object_hs_Standardlimb_006188" Type="Standard" EnumName="OBJECT_HS_LIMB_03" Offset="0x6188" />
<Limb Name="object_hs_Standardlimb_006194" Type="Standard" EnumName="OBJECT_HS_LIMB_04" Offset="0x6194" />
<Limb Name="object_hs_Standardlimb_0061A0" Type="Standard" EnumName="OBJECT_HS_LIMB_05" Offset="0x61A0" />
<Limb Name="object_hs_Standardlimb_0061AC" Type="Standard" EnumName="OBJECT_HS_LIMB_06" Offset="0x61AC" />
<Limb Name="object_hs_Standardlimb_0061B8" Type="Standard" EnumName="OBJECT_HS_LIMB_07" Offset="0x61B8" />
<Limb Name="object_hs_Standardlimb_0061C4" Type="Standard" EnumName="OBJECT_HS_LIMB_08" Offset="0x61C4" />
<Limb Name="object_hs_Standardlimb_0061D0" Type="Standard" EnumName="OBJECT_HS_LIMB_09" Offset="0x61D0" />
<Limb Name="object_hs_Standardlimb_0061DC" Type="Standard" EnumName="OBJECT_HS_LIMB_0A" Offset="0x61DC" />
<Limb Name="object_hs_Standardlimb_0061E8" Type="Standard" EnumName="OBJECT_HS_LIMB_0B" Offset="0x61E8" />
<Texture Name="gHsRibsTex" OutName="ribs" Format="ci8" Width="16" Height="32" Offset="0x5050" />
<Texture Name="gHsEarTex" OutName="ear" Format="ci8" Width="8" Height="8" Offset="0x5250" />
<Texture Name="gHsMouthTex" OutName="mouth" Format="ci8" Width="32" Height="16" Offset="0x5290" />
<Texture Name="gHsEyeTex" OutName="eye" Format="rgba16" Width="32" Height="16" Offset="0x5490" />
<Texture Name="gHsPantsTex" OutName="pants" Format="ci8" Width="16" Height="16" Offset="0x5890" />
<Texture Name="gHsFingersTex" OutName="fingers" Format="ci8" Width="16" Height="16" Offset="0x5990" />
<Texture Name="gHsBraceletTex" OutName="bracelet" Format="rgba16" Width="4" Height="4" Offset="0x5A90" />
<Texture Name="gHsCuccoFeedBagTex" OutName="cucco_feed_bag" Format="ci8" Width="8" Height="8" Offset="0x5AB0" />
<Texture Name="gHsChairBoxTex" OutName="chair_box" Format="ci8" Width="32" Height="32" Offset="0x5AF0" />
<Texture Name="gHsAbsTex" OutName="abs" Format="ci8" Width="8" Height="16" Offset="0x5EF0" />
<Texture Name="gHsBackTex" OutName="back" Format="ci8" Width="16" Height="32" Offset="0x5F70" />
<Limb Name="gHsRootLimb" Type="Standard" EnumName="HS_LIMB_ROOT" Offset="0x6170" />
<Limb Name="gHsLeftUpperArmLimb" Type="Standard" EnumName="HS_LIMB_LEFT_UPPER_ARM" Offset="0x617C" />
<Limb Name="gHsLeftForarmLimb" Type="Standard" EnumName="HS_LIMB_LEFT_FORARM" Offset="0x6188" />
<Limb Name="gHsLeftHandLimb" Type="Standard" EnumName="HS_LIMB_LEFT_HAND" Offset="0x6194" />
<Limb Name="gHsRightUpperArmLimb" Type="Standard" EnumName="HS_LIMB_RIGHT_UPPER_ARM" Offset="0x61A0" />
<Limb Name="gHsRightForarmLimb" Type="Standard" EnumName="HS_LIMB_RIGHT_FORARM" Offset="0x61AC" />
<Limb Name="gHsRightHandLimb" Type="Standard" EnumName="HS_LIMB_RIGHT_HAND" Offset="0x61B8" />
<Limb Name="gHsHeadRoot" Type="Standard" EnumName="HS_LIMB_HEAD_ROOT" Offset="0x61C4" />
<Limb Name="gHsHeadLimb" Type="Standard" EnumName="HS_LIMB_HEAD" Offset="0x61D0" />
<Limb Name="gHsHairSpikesLimb" Type="Standard" EnumName="HS_LIMB_HAIR_SPIKES" Offset="0x61DC" />
<!-- this limb is nulled in the override limb function -->
<Limb Name="gHsHiddenHairLimb" Type="Standard" EnumName="HS_LIMB_HIDDEN_HAIR" Offset="0x61E8" />
<!-- both of these use the same display list, which is just an end display list, unfinished content? -->
<Limb Name="object_hs_Standardlimb_0061F4" Type="Standard" EnumName="OBJECT_HS_LIMB_0C" Offset="0x61F4" />
<Limb Name="object_hs_Standardlimb_006200" Type="Standard" EnumName="OBJECT_HS_LIMB_0D" Offset="0x6200" />
<Limb Name="object_hs_Standardlimb_00620C" Type="Standard" EnumName="OBJECT_HS_LIMB_0E" Offset="0x620C" />
<Limb Name="object_hs_Standardlimb_006218" Type="Standard" EnumName="OBJECT_HS_LIMB_0F" Offset="0x6218" />
<Skeleton Name="object_hs_Skel_006260" Type="Flex" LimbType="Standard" LimbNone="OBJECT_HS_LIMB_NONE" LimbMax="OBJECT_HS_LIMB_MAX" EnumName="object_hs_Limbs" Offset="0x6260" />
<!-- shoulders down to toes plus box hes sitting on -->
<Limb Name="gHsChestAndLowerBodyPlusBox" Type="Standard" EnumName="HS_LIMB_LOWER_BODY_PLUS_BOX" Offset="0x620C" />
<Limb Name="gHsCuccoFeedBagsLimb" Type="Standard" EnumName="HS_LIMB_CUCCO_FEED_BAGS" Offset="0x6218" />
<Skeleton Name="gHsSkeleton" Type="Flex" LimbType="Standard" LimbNone="OBJECT_HS_LIMB_NONE" LimbMax="OBJECT_HS_LIMB_MAX" EnumName="object_hs_Limbs" Offset="0x6260" />
</File>
</Root>

View File

@ -1,38 +1,40 @@
<Root>
<!-- Cucco: zelda name for chicken, "Niw" likely short for "Niwatori" -->
<File Name="object_niw" Segment="6">
<Animation Name="object_niw_Anim_0000E8" Offset="0xE8" />
<DList Name="object_niw_DL_0009C0" Offset="0x9C0" />
<DList Name="object_niw_DL_000A98" Offset="0xA98" />
<DList Name="object_niw_DL_000DF0" Offset="0xDF0" />
<DList Name="object_niw_DL_000FD0" Offset="0xFD0" />
<DList Name="object_niw_DL_001088" Offset="0x1088" />
<DList Name="object_niw_DL_001128" Offset="0x1128" />
<DList Name="object_niw_DL_0011E0" Offset="0x11E0" />
<Texture Name="object_niw_Tex_001280" OutName="tex_001280" Format="rgba16" Width="16" Height="16" Offset="0x1280" />
<Texture Name="object_niw_Tex_001480" OutName="tex_001480" Format="rgba16" Width="8" Height="16" Offset="0x1480" />
<Texture Name="object_niw_Tex_001580" OutName="tex_001580" Format="rgba16" Width="8" Height="8" Offset="0x1580" />
<Texture Name="object_niw_Tex_001600" OutName="tex_001600" Format="rgba16" Width="8" Height="8" Offset="0x1600" />
<Texture Name="object_niw_Tex_001680" OutName="tex_001680" Format="rgba16" Width="16" Height="16" Offset="0x1680" />
<Texture Name="object_niw_Tex_001880" OutName="tex_001880" Format="rgba16" Width="32" Height="32" Offset="0x1880" />
<Texture Name="object_niw_Tex_002080" OutName="tex_002080" Format="rgba16" Width="8" Height="16" Offset="0x2080" />
<Texture Name="object_niw_Tex_002180" OutName="tex_002180" Format="rgba16" Width="16" Height="16" Offset="0x2180" />
<Animation Name="gNiwIdleAnim" Offset="0xE8" />
<DList Name="gNiwNeckDL" Offset="0x9C0" />
<DList Name="gNiwHeadDL" Offset="0xA98" />
<DList Name="gNiwTailDL" Offset="0xDF0" />
<DList Name="gNiwWingLeftDL" Offset="0xFD0" />
<DList Name="gNiwFootLeftDL" Offset="0x1088" />
<DList Name="gNiwWingRightDL" Offset="0x1128" />
<DList Name="gNiwFootRightDL" Offset="0x11E0" />
<Texture Name="gNiwEyeTex" OutName="eye" Format="rgba16" Width="16" Height="16" Offset="0x1280" />
<Texture Name="gNiwHeadFeathersTex" OutName="head_feathers" Format="rgba16" Width="8" Height="16" Offset="0x1480" />
<Texture Name="gNiwBaseFeathersTex" OutName="base_feathers" Format="rgba16" Width="8" Height="8" Offset="0x1580" />
<Texture Name="gNiwBeakTex" OutName="beak" Format="rgba16" Width="8" Height="8" Offset="0x1600" />
<Texture Name="gNiwCombTex" OutName="comb" Format="rgba16" Width="16" Height="16" Offset="0x1680" />
<Texture Name="gNiwTailFeathersTex" OutName="tail_feathers" Format="rgba16" Width="32" Height="32" Offset="0x1880" />
<Texture Name="gNiwFootTex" OutName="foot" Format="rgba16" Width="8" Height="16" Offset="0x2080" />
<Texture Name="gNiwFeatherTex" OutName="feather" Format="rgba16" Width="16" Height="16" Offset="0x2180" />
<DList Name="gNiwFeatherMaterialDL" Offset="0x23B0" />
<DList Name="gNiwFeatherDL" Offset="0x2428" />
<Limb Name="object_niw_Standardlimb_002440" Type="Standard" EnumName="OBJECT_NIW_LIMB_01" Offset="0x2440" />
<Limb Name="object_niw_Standardlimb_00244C" Type="Standard" EnumName="OBJECT_NIW_LIMB_02" Offset="0x244C" />
<Limb Name="object_niw_Standardlimb_002458" Type="Standard" EnumName="OBJECT_NIW_LIMB_03" Offset="0x2458" />
<Limb Name="object_niw_Standardlimb_002464" Type="Standard" EnumName="OBJECT_NIW_LIMB_04" Offset="0x2464" />
<Limb Name="object_niw_Standardlimb_002470" Type="Standard" EnumName="OBJECT_NIW_LIMB_05" Offset="0x2470" />
<Limb Name="object_niw_Standardlimb_00247C" Type="Standard" EnumName="OBJECT_NIW_LIMB_06" Offset="0x247C" />
<Limb Name="object_niw_Standardlimb_002488" Type="Standard" EnumName="OBJECT_NIW_LIMB_07" Offset="0x2488" />
<Limb Name="object_niw_Standardlimb_002494" Type="Standard" EnumName="OBJECT_NIW_LIMB_08" Offset="0x2494" />
<Limb Name="object_niw_Standardlimb_0024A0" Type="Standard" EnumName="OBJECT_NIW_LIMB_09" Offset="0x24A0" />
<Limb Name="object_niw_Standardlimb_0024AC" Type="Standard" EnumName="OBJECT_NIW_LIMB_0A" Offset="0x24AC" />
<Limb Name="object_niw_Standardlimb_0024B8" Type="Standard" EnumName="OBJECT_NIW_LIMB_0B" Offset="0x24B8" />
<Limb Name="object_niw_Standardlimb_0024C4" Type="Standard" EnumName="OBJECT_NIW_LIMB_0C" Offset="0x24C4" />
<Limb Name="object_niw_Standardlimb_0024D0" Type="Standard" EnumName="OBJECT_NIW_LIMB_0D" Offset="0x24D0" />
<Limb Name="object_niw_Standardlimb_0024DC" Type="Standard" EnumName="OBJECT_NIW_LIMB_0E" Offset="0x24DC" />
<Limb Name="object_niw_Standardlimb_0024E8" Type="Standard" EnumName="OBJECT_NIW_LIMB_0F" Offset="0x24E8" />
<Skeleton Name="object_niw_Skel_002530" Type="Flex" LimbType="Standard" LimbNone="OBJECT_NIW_LIMB_NONE" LimbMax="OBJECT_NIW_LIMB_MAX" EnumName="object_niw_Limbs" Offset="0x2530" />
<Limb Name="gNiwRootLimb" LimbType="Standard" EnumName="NIW_LIMB_ROOT" Offset="0x2440"/>
<Limb Name="gNiwLimb_244C" LimbType="Standard" EnumName="NIW_LIMB_2" Offset="0x244C"/>
<Limb Name="gNiwLimb_2458" LimbType="Standard" EnumName="NIW_LIMB_3" Offset="0x2458"/>
<Limb Name="gNiwTailAndUndersideLimb" LimbType="Standard" EnumName="NIW_LIMB_UNDER_SIDE" Offset="0x2464"/>
<Limb Name="gNiwLeftFootRootLimb" LimbType="Standard" EnumName="NIW_LIMB_LEFT_FOOT_ROOT" Offset="0x2470"/>
<Limb Name="gNiwLeftFootLimb" LimbType="Standard" EnumName="NIW_LIMB_LEFT_FOOT" Offset="0x247C"/>
<Limb Name="gNiwLeftWingRootLimb" LimbType="Standard" EnumName="NIW_LIMB_LEFT_WING_ROOT" Offset="0x2488"/>
<Limb Name="gNiwLeftWingLimb" LimbType="Standard" EnumName="NIW_LIMB_LEFT_WING" Offset="0x2494"/>
<Limb Name="gNiwRightFootRootLimb" LimbType="Standard" EnumName="NIW_LIMB_RIGHT_FOOT_ROOT" Offset="0x24A0"/>
<Limb Name="gNiwRightFootLimb" LimbType="Standard" EnumName="NIW_LIMB_RIGHT_FOOT" Offset="0x24AC"/>
<Limb Name="gNiwRightWingRootLimb" LimbType="Standard" EnumName="NIW_LIMB_RIGHT_WING_ROOT" Offset="0x24B8"/>
<Limb Name="gNiwRightWingLimb" LimbType="Standard" EnumName="NIW_LIMB_RIGHT_WING" Offset="0x24C4"/>
<Limb Name="gNiwUpperBodyRootLimb" LimbType="Standard" EnumName="NIW_LIMB_UPPER_BODY" Offset="0x24D0"/>
<Limb Name="gNiwNeckLimb" LimbType="Standard" EnumName="NIW_LIMB_NECK" Offset="0x24DC"/>
<Limb Name="gNiwHeadLimb" LimbType="Standard" EnumName="NIW_LIMB_HEAD" Offset="0x24E8"/>
<Skeleton Name="gNiwSkeleton" Type="Flex" LimbType="Standard" LimbNone="NIW_LIMB_NONE" LimbMax="NIW_LIMB_MAX" EnumName="ObjectNiwLimbs" Offset="0x2530" />
</File>
</Root>

View File

@ -1,29 +1,57 @@
<Root>
<!-- Cucco Chick: the little baby Cucco you find and raise in the Cucco Shack -->
<File Name="object_nwc" Segment="6">
<DList Name="object_nwc_DL_0002E0" Offset="0x2E0" />
<DList Name="object_nwc_DL_0002E8" Offset="0x2E8" />
<Texture Name="object_nwc_Tex_0004D0" OutName="tex_0004D0" Format="rgba16" Width="8" Height="8" Offset="0x4D0" />
<Texture Name="object_nwc_Tex_000550" OutName="tex_000550" Format="rgba16" Width="8" Height="8" Offset="0x550" />
<Texture Name="object_nwc_Tex_0005D0" OutName="tex_0005D0" Format="rgba16" Width="16" Height="16" Offset="0x5D0" />
<Texture Name="object_nwc_Tex_0007D0" OutName="tex_0007D0" Format="rgba16" Width="16" Height="16" Offset="0x7D0" />
<Texture Name="object_nwc_Tex_0009D0" OutName="tex_0009D0" Format="rgba16" Width="16" Height="16" Offset="0x9D0" />
<TextureAnimation Name="object_nwc_Matanimheader_000BEC" Offset="0xBEC" />
<DList Name="gNwcEndDL" Offset="0x2E0" />
<DList Name="gNwcBodyDL" Offset="0x2E8" />
<Texture Name="gNwcBodyTex" OutName="body" Format="rgba16" Width="8" Height="8" Offset="0x4D0" />
<Texture Name="gNwcBeakTex" OutName="beak" Format="rgba16" Width="8" Height="8" Offset="0x550" />
<!-- Wing texture is reused for tail feathers -->
<Texture Name="gNwcWingTex" OutName="wing" Format="rgba16" Width="16" Height="16" Offset="0x5D0" />
<Texture Name="gNwcEyeOpenTex" OutName="eye_opened" Format="rgba16" Width="16" Height="16" Offset="0x7D0" />
<Texture Name="gNwcEyeClosedTex" OutName="eye_closed" Format="rgba16" Width="16" Height="16" Offset="0x9D0" />
<!-- **************************************************************************************** -->
<!-- *** Beyond this point is unused content, including broken display lists and textures *** -->
<!-- **************************************************************************************** -->
<!-- this blinking animated texture seems unused, as the actor cycles through blinking with code -->
<TextureAnimation Name="gNwcBlinkTexAnim" Offset="0xBEC" />
<!-- unused multi-colored texture? -->
<Texture Name="object_nwc_Tex_000C00" OutName="tex_000C00" Format="rgba16" Width="32" Height="32" Offset="0xC00" />
<DList Name="object_nwc_DL_001440" Offset="0x1440" />
<DList Name="object_nwc_DL_0014B8" Offset="0x14B8" />
<DList Name="object_nwc_DL_001520" Offset="0x1520" />
<!-- dark gold ball texture -->
<Texture Name="object_nwc_Tex_001550" OutName="tex_001550" Format="rgba16" Width="16" Height="16" Offset="0x1550" />
<!-- gold color pallet? -->
<Texture Name="object_nwc_Tex_001750" OutName="tex_001750" Format="rgba16" Width="4" Height="4" Offset="0x1750" />
<!-- both of these display lists use the dark gold ball texture -->
<DList Name="object_nwc_DL_001860" Offset="0x1860" />
<DList Name="object_nwc_DL_0018D0" Offset="0x18D0" />
<!-- draws two untextured triangles like jack-o-lantern eyes -->
<DList Name="object_nwc_DL_001940" Offset="0x1940" />
<!-- both of these display lists use the yellow pallet texture -->
<DList Name="object_nwc_DL_001960" Offset="0x1960" />
<DList Name="object_nwc_DL_0019B8" Offset="0x19B8" />
<!-- in z64utils draws a un-textured tetrahedron -->
<DList Name="object_nwc_DL_001A10" Offset="0x1A10" />
<!-- <Blob Name="object_nwc_Blob_001A38" Size="0x108" Offset="0x1A38" /> -->
<!-- contains an unsupported texture (i16) used in an unused display list ( @ 0x1B80 ) -->
<!-- is type G_IM_FMT_I, G_IM_SIZ_16b, dimensions are best guesses from Texture64 renders -->
<Texture Name="object_nwc_Tex_001A40" OutName="broken_tex_gimfmti_001A40" Format="ia16" Width="8" Height="16" Offset="0x1A40" />
<!-- Z64Utils throws an error for this DL because of the above texture -->
<DList Name="object_nwc_DL_001B80" Offset="0x1B80" />
<!-- requires unassigned segment 0x01 matrix to render, no idea what its doing -->
<DList Name="object_nwc_DL_001BE8" Offset="0x1BE8" />
<!-- loads a dark spot from gameplay keep -->
<DList Name="object_nwc_DL_001C10" Offset="0x1C10" />
<!-- unused DL produces a yellow textured triangle -->
<DList Name="object_nwc_DL_001C58" Offset="0x1C58" />
</File>
</Root>

View File

@ -3498,7 +3498,7 @@ void func_801A0238(s32 arg0, s32 arg1);
// void func_801A05F0(void);
void func_801A0654(Vec3f* arg0, u16 sfxId, s32 arg2);
void func_801A0810(Vec3f* arg0, u16 sfxId, u8 arg2);
// void func_801A0868(void);
void func_801A0868(Vec3f* pos, u16 sfxId, u8 val);
// void func_801A09D4(void);
// void Audio_SplitBgmChannels(void);
// void func_801A0E44(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7);

3
spec
View File

@ -1510,8 +1510,7 @@ beginseg
name "ovl_En_Nwc"
compress
include "build/src/overlays/actors/ovl_En_Nwc/z_en_nwc.o"
include "build/data/ovl_En_Nwc/ovl_En_Nwc.data.o"
include "build/data/ovl_En_Nwc/ovl_En_Nwc.reloc.o"
include "build/src/overlays/actors/ovl_En_Nwc/ovl_En_Nwc_reloc.o"
endseg
beginseg

View File

@ -1,7 +1,7 @@
/*
* File: z_en_attack_niw.c
* Overlay: ovl_En_Attack_Niw
* Description: Attacking cucco
* Description: Attacking Cucco
*/
#include "z_en_attack_niw.h"
@ -16,9 +16,9 @@ void EnAttackNiw_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnAttackNiw_Update(Actor* thisx, GlobalContext* globalCtx);
void EnAttackNiw_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_80958634(EnAttackNiw* this, GlobalContext* globalCtx);
void func_80958974(EnAttackNiw* this, GlobalContext* globalCtx);
void func_80958BE4(EnAttackNiw* this, GlobalContext* globalCtx);
void EnAttackNiw_EnterViewFromOffscreen(EnAttackNiw* this, GlobalContext* globalCtx);
void EnAttackNiw_AimAtPlayer(EnAttackNiw* this, GlobalContext* globalCtx);
void EnAttackNiw_FlyAway(EnAttackNiw* this, GlobalContext* globalCtx);
const ActorInit En_Attack_Niw_InitVars = {
ACTOR_EN_ATTACK_NIW,
@ -43,289 +43,305 @@ void EnAttackNiw_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_niw_Skel_002530, &object_niw_Anim_0000E8, this->jointTable,
this->morphTable, OBJECT_NIW_LIMB_MAX);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gNiwSkeleton, &gNiwIdleAnim, this->jointTable, this->morphTable,
NIW_LIMB_MAX);
// probably copy pasted from EnNiw, which has this same code, but AttackNiw has no params
if (this->actor.params < 0) {
this->actor.params = 0;
this->actor.params = ATTACK_NIW_REGULAR;
}
Actor_SetScale(&this->actor, 0.01f);
this->actor.gravity = 0.0f;
this->unk_290.x = randPlusMinusPoint5Scaled(100.0f);
this->unk_290.y = randPlusMinusPoint5Scaled(10.0f);
this->unk_290.z = randPlusMinusPoint5Scaled(100.0f);
this->randomTargetCenterOffset.x = randPlusMinusPoint5Scaled(100.0f);
this->randomTargetCenterOffset.y = randPlusMinusPoint5Scaled(10.0f);
this->randomTargetCenterOffset.z = randPlusMinusPoint5Scaled(100.0f);
Actor_SetScale(&this->actor, 0.01f);
this->actor.flags &= ~ACTOR_FLAG_1;
this->actor.flags &= ~ACTOR_FLAG_1; // Unnecessary: this actor does not start with this flag
this->actor.shape.rot.y = this->actor.world.rot.y = (Rand_ZeroOne() - 0.5f) * 60000.0f;
this->actionFunc = func_80958634;
this->actionFunc = EnAttackNiw_EnterViewFromOffscreen;
}
void EnAttackNiw_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnAttackNiw* this = THIS;
EnNiw* parent = (EnNiw*)this->actor.parent;
if ((thisx->parent != NULL) && (thisx->parent->update != NULL)) {
if (parent->unk290 > 0) {
parent->unk290--;
if (this->actor.parent != NULL && this->actor.parent->update != NULL) {
if (parent->attackNiwCount > 0) {
parent->attackNiwCount--;
}
}
}
void func_80958228(EnAttackNiw* this, GlobalContext* globalCtx, s16 arg2) {
if (this->unk_24C == 0) {
if (arg2 == 0) {
this->unk_25C = 0.0f;
/**
* Summary: instead of using SkelAnime animations AttackNiw modifies head+wings directly to create animations
*
* EnNiw has its own version of this function, probably copy paste since AttackNiw only uses two animationState (2/5)
*/
void EnAttackNiw_AnimateWingHead(EnAttackNiw* this, GlobalContext* globalCtx, s16 animationState) {
if (this->unkTimer24C == 0) {
if (animationState == 0) {
this->targetBodyRotY = 0.0f;
} else {
this->unk_25C = -10000.0f;
this->targetBodyRotY = -10000.0f;
}
this->unk_286++;
this->unk_24C = 3;
if ((this->unk_286 % 2) == 0) {
this->unk_25C = 0.0f;
if (arg2 == 0) {
this->unk_24C = Rand_ZeroFloat(30.0f);
this->clearRotYToggleTimer++;
this->unkTimer24C = 3;
if ((this->clearRotYToggleTimer % 2) == 0) {
this->targetBodyRotY = 0.0f;
if (animationState == 0) {
this->unkTimer24C = Rand_ZeroFloat(30.0f);
}
}
}
if (this->unk_250 == 0) {
this->unk_28A++;
this->unk_28A &= 1;
if (this->unkTimer250 == 0) {
this->unkToggle28A++;
this->unkToggle28A &= 1;
switch (arg2) {
case 0:
this->unk_264 = 0.0f;
this->unk_260 = 0.0f;
switch (animationState) { // only case 2 and 5 are ever called in AttackNiw
case NIW_ANIMATION_STILL:
this->targetLeftWingRotZ = 0.0f;
this->targetRightWingRotZ = 0.0f;
break;
case 1:
this->unk_250 = 3;
this->unk_264 = 7000.0f;
this->unk_260 = 7000.0f;
if (this->unk_28A == 0) {
this->unk_264 = 0.0f;
this->unk_260 = 0.0f;
case NIW_ANIMATION_HEAD_PECKING:
this->unkTimer250 = 3;
this->targetLeftWingRotZ = 7000.0f;
this->targetRightWingRotZ = 7000.0f;
if (this->unkToggle28A == 0) {
this->targetLeftWingRotZ = 0.0f;
this->targetRightWingRotZ = 0.0f;
}
break;
case 2:
this->unk_250 = 2;
this->unk_264 = -10000.0f;
this->unk_260 = -10000.0f;
this->unk_278 = 25000.0f;
this->unk_270 = 25000.0f;
this->unk_27C = 6000.0f;
this->unk_274 = 6000.0f;
if (this->unk_28A == 0) {
this->unk_270 = 8000.0f;
this->unk_278 = 8000.0f;
case NIW_ANIMATION_PECKING_AND_WAVING:
this->unkTimer250 = 2;
this->targetLeftWingRotZ = -10000.0f;
this->targetRightWingRotZ = -10000.0f;
this->targetLeftWingRotY = 25000.0f;
this->targetRightWingRotY = 25000.0f;
this->targetLeftWingRotX = 6000.0f;
this->targetRightWingRotX = 6000.0f;
if (this->unkToggle28A == 0) {
this->targetRightWingRotY = 8000.0f;
this->targetLeftWingRotY = 8000.0f;
}
break;
case 3:
this->unk_250 = 2;
this->unk_270 = 10000.0f;
this->unk_278 = 10000.0f;
if (this->unk_28A == 0) {
this->unk_270 = 3000.0f;
this->unk_278 = 3000.0f;
case NIW_ANIMATION_PECKING_AND_FORFLAPPING:
this->unkTimer250 = 2;
this->targetRightWingRotY = 10000.0f;
this->targetLeftWingRotY = 10000.0f;
if (this->unkToggle28A == 0) {
this->targetRightWingRotY = 3000.0f;
this->targetLeftWingRotY = 3000.0f;
}
break;
case 4:
this->unk_24E = 5;
this->unk_24C = this->unk_24E;
case NIW_ANIMATION_FREEZE:
this->unusedTimer24E = 5;
this->unkTimer24C = this->unusedTimer24E;
break;
case 5:
this->unk_250 = 5;
this->unk_270 = 14000.0f;
this->unk_278 = 14000.0f;
if (this->unk_28A == 0) {
this->unk_270 = 10000.0f;
this->unk_278 = 10000.0f;
case NIW_ANIMATION_PECKING_SLOW_FORFLAPPING:
this->unkTimer250 = 5;
this->targetRightWingRotY = 14000.0f;
this->targetLeftWingRotY = 14000.0f;
if (this->unkToggle28A == 0) {
this->targetRightWingRotY = 10000.0f;
this->targetLeftWingRotY = 10000.0f;
}
break;
}
}
if (this->unk_280 != this->unk_2B8) {
Math_ApproachF(&this->unk_2B8, this->unk_280, 0.5f, 4000.0f);
if (this->targetHeadRotZ != this->headRotZ) {
Math_ApproachF(&this->headRotZ, this->targetHeadRotZ, 0.5f, 4000.0f);
}
if (this->unk_25C != this->unk_2B4) {
Math_ApproachF(&this->unk_2B4, this->unk_25C, 0.5f, 4000.0f);
if (this->targetBodyRotY != this->upperBodyRotY) {
Math_ApproachF(&this->upperBodyRotY, this->targetBodyRotY, 0.5f, 4000.0f);
}
if (this->unk_264 != this->unk_29C) {
Math_ApproachF(&this->unk_29C, this->unk_264, 0.8f, 7000.0f);
if (this->targetLeftWingRotZ != this->leftWingRotZ) {
Math_ApproachF(&this->leftWingRotZ, this->targetLeftWingRotZ, 0.8f, 7000.0f);
}
if (this->unk_278 != this->unk_2A0) {
Math_ApproachF(&this->unk_2A0, this->unk_278, 0.8f, 7000.0f);
if (this->targetLeftWingRotY != this->leftWingRotY) {
Math_ApproachF(&this->leftWingRotY, this->targetLeftWingRotY, 0.8f, 7000.0f);
}
if (this->unk_27C != this->unk_2A4) {
Math_ApproachF(&this->unk_2A4, this->unk_27C, 0.8f, 7000.0f);
if (this->targetLeftWingRotX != this->leftWingRotX) {
Math_ApproachF(&this->leftWingRotX, this->targetLeftWingRotX, 0.8f, 7000.0f);
}
if (this->unk_260 != this->unk_2A8) {
Math_ApproachF(&this->unk_2A8, this->unk_260, 0.8f, 7000.0f);
if (this->targetRightWingRotZ != this->rightWingRotZ) {
Math_ApproachF(&this->rightWingRotZ, this->targetRightWingRotZ, 0.8f, 7000.0f);
}
if (this->unk_270 != this->unk_2AC) {
Math_ApproachF(&this->unk_2AC, this->unk_270, 0.8f, 7000.0f);
if (this->targetRightWingRotY != this->rightWingRotY) {
Math_ApproachF(&this->rightWingRotY, this->targetRightWingRotY, 0.8f, 7000.0f);
}
if (this->unk_274 != this->unk_2B0) {
Math_ApproachF(&this->unk_2B0, this->unk_274, 0.8f, 7000.0f);
if (this->targetRightWingRotX != this->rightWingRotX) {
Math_ApproachF(&this->rightWingRotX, this->targetRightWingRotX, 0.8f, 7000.0f);
}
}
s32 func_809585B0(EnAttackNiw* this, GlobalContext* globalCtx) {
s16 sp1E;
s16 sp1C;
s32 EnAttackNiw_IsOnScreen(EnAttackNiw* this, GlobalContext* globalCtx) {
s16 posX;
s16 posY;
Actor_SetFocus(&this->actor, this->unk_2DC);
Actor_GetScreenPos(globalCtx, &this->actor, &sp1E, &sp1C);
Actor_SetFocus(&this->actor, this->targetHeight);
Actor_GetScreenPos(globalCtx, &this->actor, &posX, &posY);
if ((this->actor.projectedPos.z < -20.0f) || (sp1E < 0) || (sp1E > SCREEN_WIDTH) || (sp1C < 0) ||
(sp1C > SCREEN_HEIGHT)) {
if ((this->actor.projectedPos.z < -20.0f) || (posX < 0) || (posX > SCREEN_WIDTH) || (posY < 0) ||
(posY > SCREEN_HEIGHT)) {
return false;
}
return true;
}
void func_80958634(EnAttackNiw* this, GlobalContext* globalCtx) {
s16 sp4E;
s16 sp4C;
Vec3f temp;
Vec3f sp34;
void EnAttackNiw_EnterViewFromOffscreen(EnAttackNiw* this, GlobalContext* globalCtx) {
s16 posX;
s16 posY;
Vec3f viewOffset;
Vec3f flightTarget;
s32 pad;
this->actor.speedXZ = 10.0f;
temp.x = (this->unk_290.x + globalCtx->view.at.x) - globalCtx->view.eye.x;
temp.y = (this->unk_290.y + globalCtx->view.at.y) - globalCtx->view.eye.y;
temp.z = (this->unk_290.z + globalCtx->view.at.z) - globalCtx->view.eye.z;
// randomTargetCenterOffset is set in _Init, only needs to be set once
// but the view is moving, so now we need to re-calculate the spot in space
viewOffset.x = this->randomTargetCenterOffset.x + globalCtx->view.at.x - globalCtx->view.eye.x;
viewOffset.y = this->randomTargetCenterOffset.y + globalCtx->view.at.y - globalCtx->view.eye.y;
viewOffset.z = this->randomTargetCenterOffset.z + globalCtx->view.at.z - globalCtx->view.eye.z;
sp34.x = globalCtx->view.at.x + temp.x;
sp34.y = globalCtx->view.at.y + temp.y;
sp34.z = globalCtx->view.at.z + temp.z;
// this is the 3D spot in space where the cucco is trying to fly into (until it lands or gets close)
flightTarget.x = globalCtx->view.at.x + viewOffset.x;
flightTarget.y = globalCtx->view.at.y + viewOffset.y;
flightTarget.z = globalCtx->view.at.z + viewOffset.z;
this->unk_2CC = Math_Vec3f_Yaw(&this->actor.world.pos, &sp34);
this->unk_2C8 = Math_Vec3f_Pitch(&this->actor.world.pos, &sp34) * -1.0f;
this->targetRotY = Math_Vec3f_Yaw(&this->actor.world.pos, &flightTarget);
this->targetRotX = Math_Vec3f_Pitch(&this->actor.world.pos, &flightTarget) * -1.0f;
Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2CC, 5, this->unk_2D4, 0);
Math_SmoothStepToS(&this->actor.world.rot.x, this->unk_2C8, 5, this->unk_2D4, 0);
Math_ApproachF(&this->unk_2D4, 5000.0f, 1.0f, 100.0f);
Math_SmoothStepToS(&this->actor.world.rot.y, this->targetRotY, 5, this->rotStep, 0);
Math_SmoothStepToS(&this->actor.world.rot.x, this->targetRotX, 5, this->rotStep, 0);
Math_ApproachF(&this->rotStep, 5000.0f, 1.0f, 100.0f);
Actor_SetFocus(&this->actor, this->unk_2DC);
Actor_GetScreenPos(globalCtx, &this->actor, &sp4E, &sp4C);
Actor_SetFocus(&this->actor, this->targetHeight);
Actor_GetScreenPos(globalCtx, &this->actor, &posX, &posY);
if (this->actor.bgCheckFlags & 8) {
this->unk_2CC = this->actor.yawTowardsPlayer;
this->unk_2C8 = this->actor.world.rot.x - 3000.0f;
this->unk_252 = 0;
this->unk_254 = 100;
this->unk_2D4 = 0.0f;
this->unk_27C = 0.0f;
this->unk_274 = 0.0f;
this->unk_250 = this->unk_252;
this->unk_24E = this->unk_252;
this->unk_24C = this->unk_252;
if (this->actor.bgCheckFlags & 8) { // touching a wall
this->targetRotY = this->actor.yawTowardsPlayer;
this->targetRotX = this->actor.world.rot.x - 3000.0f;
this->hopTimer = 0;
this->randomAngleChangeTimer = 100;
this->rotStep = 0.0f;
this->targetLeftWingRotX = 0.0f;
this->targetRightWingRotX = 0.0f;
this->unkTimer250 = this->hopTimer;
this->unusedTimer24E = this->hopTimer;
this->unkTimer24C = this->hopTimer;
this->actor.gravity = -0.2f;
this->unk_280 = 0.0f;
this->actionFunc = func_80958974;
this->unk_2D8 = 5.0f;
} else if (((this->actor.projectedPos.z > 0.0f) && (fabsf(sp34.x - this->actor.world.pos.x) < 50.0f) &&
(fabsf(sp34.y - this->actor.world.pos.y) < 50.0f) &&
(fabsf(sp34.z - this->actor.world.pos.z) < 50.0f)) ||
(this->actor.bgCheckFlags & 1)) {
this->unk_252 = 0;
this->unk_250 = this->unk_252;
this->unk_24E = this->unk_252;
this->unk_24C = this->unk_252;
this->unk_2D4 = 0.0f;
this->unk_274 = 0.0f;
this->unk_27C = 0.0f;
this->unk_2CC = this->actor.yawTowardsPlayer;
this->unk_2C8 = this->actor.world.rot.x - 2000.0f;
this->actor.gravity = -0.2f;
this->unk_280 = 0.0f;
this->actionFunc = func_80958974;
this->unk_2D8 = 5.0f;
} else {
this->unk_24C = 10;
this->unk_25C = -10000.0f;
this->unk_280 = -3000.0f;
func_80958228(this, globalCtx, 2);
this->targetHeadRotZ = 0.0f;
this->actionFunc = EnAttackNiw_AimAtPlayer;
this->targetXZSpeed = 5.0f;
} else if (((this->actor.projectedPos.z > 0.0f) && (fabsf(flightTarget.x - this->actor.world.pos.x) < 50.0f) &&
(fabsf(flightTarget.y - this->actor.world.pos.y) < 50.0f) &&
(fabsf(flightTarget.z - this->actor.world.pos.z) < 50.0f)) ||
(this->actor.bgCheckFlags & 1)) { // touching ground or with close distance of target
// reset state
this->hopTimer = 0;
this->unkTimer250 = this->hopTimer;
this->unusedTimer24E = this->hopTimer;
this->unkTimer24C = this->hopTimer;
this->rotStep = 0.0f;
this->targetRightWingRotX = 0.0f;
this->targetLeftWingRotX = 0.0f;
this->targetRotY = this->actor.yawTowardsPlayer; // start turn to face player
this->targetRotX = this->actor.world.rot.x - 2000.0f; // bank into the turn
this->actor.gravity = -0.2f; // start gentle decent (no longer flying without gravity)
this->targetHeadRotZ = 0.0f;
this->actionFunc = EnAttackNiw_AimAtPlayer;
this->targetXZSpeed = 5.0f;
} else { // keep flying at the flightTarget for now
this->unkTimer24C = 10;
this->targetBodyRotY = -10000.0f;
this->targetHeadRotZ = -3000.0f;
EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING);
}
}
void func_80958974(EnAttackNiw* this, GlobalContext* globalCtx) {
if (!func_809585B0(this, globalCtx)) {
void EnAttackNiw_AimAtPlayer(EnAttackNiw* this, GlobalContext* globalCtx) {
if (!EnAttackNiw_IsOnScreen(this, globalCtx)) {
Actor_MarkForDeath(&this->actor);
return;
}
if (this->actor.bgCheckFlags & 1) {
if (this->unk_252 == 0) {
this->unk_252 = 3;
if (this->actor.bgCheckFlags & 1) { // touching floor
if (this->hopTimer == 0) {
this->hopTimer = 3;
this->actor.velocity.y = 3.5f;
}
if (this->actor.gravity != -2.0f) {
this->unk_2CC = this->actor.yawTowardsPlayer;
this->unk_25A = 50;
this->unk_254 = 100;
this->unk_270 = 14000.0f;
this->unk_278 = 14000.0f;
this->unk_274 = 0.0f;
this->unk_27C = 0.0f;
this->unk_260 = 0.0f;
this->unk_264 = 0.0f;
this->unk_2C8 = 0.0f;
if (this->actor.gravity != -2.0f) { // first landing
this->targetRotY = this->actor.yawTowardsPlayer;
this->unkTimer25A = 50;
this->randomAngleChangeTimer = 100;
this->targetRightWingRotY = 14000.0f;
this->targetLeftWingRotY = 14000.0f;
this->targetRightWingRotX = 0.0f;
this->targetLeftWingRotX = 0.0f;
this->targetRightWingRotZ = 0.0f;
this->targetLeftWingRotZ = 0.0f;
this->targetRotX = 0.0f;
this->actor.gravity = -2.0f;
}
}
if (this->unk_254 == 50) {
this->unk_2CC = randPlusMinusPoint5Scaled(200.0f) + this->actor.yawTowardsPlayer;
if (this->randomAngleChangeTimer == 50) {
this->targetRotY = randPlusMinusPoint5Scaled(200.0f) + this->actor.yawTowardsPlayer;
}
Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2CC, 2, this->unk_2D4, 0);
Math_SmoothStepToS(&this->actor.world.rot.x, this->unk_2C8, 2, this->unk_2D4, 0);
Math_ApproachF(&this->unk_2D4, 10000.0f, 1.0f, 1000.0f);
Math_ApproachF(&this->actor.speedXZ, this->unk_2D8, 0.9f, 1.0f);
Math_SmoothStepToS(&this->actor.world.rot.y, this->targetRotY, 2, this->rotStep, 0);
Math_SmoothStepToS(&this->actor.world.rot.x, this->targetRotX, 2, this->rotStep, 0);
Math_ApproachF(&this->rotStep, 10000.0f, 1.0f, 1000.0f);
Math_ApproachF(&this->actor.speedXZ, this->targetXZSpeed, 0.9f, 1.0f);
if ((this->actor.gravity == -2.0f) && (this->unk_25A == 0) &&
((this->actor.bgCheckFlags & 8) || (this->unk_254 == 0))) {
this->unk_2D8 = 0.0f;
if (this->actor.gravity == -2.0f && this->unkTimer25A == 0 &&
(this->actor.bgCheckFlags & 8 || this->randomAngleChangeTimer == 0)) {
this->targetXZSpeed = 0.0f;
this->actor.gravity = 0.0f;
this->unk_2D4 = 0.0f;
this->unk_2C8 = this->actor.world.rot.x - 5000.0f;
this->actionFunc = func_80958BE4;
} else if (this->actor.bgCheckFlags & 1) {
func_80958228(this, globalCtx, 5);
this->rotStep = 0.0f;
this->targetRotX = this->actor.world.rot.x - 5000.0f;
this->actionFunc = EnAttackNiw_FlyAway;
} else if (this->actor.bgCheckFlags & 1) { // touching floor
EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_SLOW_FORFLAPPING);
} else {
func_80958228(this, globalCtx, 2);
EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING);
}
}
void func_80958BE4(EnAttackNiw* this, GlobalContext* globalCtx) {
if (!func_809585B0(this, globalCtx)) {
void EnAttackNiw_FlyAway(EnAttackNiw* this, GlobalContext* globalCtx) {
if (!EnAttackNiw_IsOnScreen(this, globalCtx)) {
Actor_MarkForDeath(&this->actor);
return;
}
Math_SmoothStepToS(&this->actor.world.rot.x, this->unk_2C8, 5, this->unk_2D4, 0);
Math_ApproachF(&this->unk_2D4, 5000.0f, 1.0f, 100.0f);
Math_SmoothStepToS(&this->actor.world.rot.x, this->targetRotX, 5, this->rotStep, 0);
Math_ApproachF(&this->rotStep, 5000.0f, 1.0f, 100.0f);
Math_ApproachF(&this->actor.velocity.y, 5.0f, 0.3f, 1.0f);
func_80958228(this, globalCtx, 2);
EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING);
}
void EnAttackNiw_Update(Actor* thisx, GlobalContext* globalCtx) {
@ -334,37 +350,17 @@ void EnAttackNiw_Update(Actor* thisx, GlobalContext* globalCtx) {
EnNiw* parent;
Player* player = GET_PLAYER(globalCtx);
s32 pad2;
Vec3f sp30;
Vec3f splashPos;
this->unk_284++;
this->unusedCounter284++;
if (this->unk_24C != 0) {
this->unk_24C--;
}
if (this->unk_250 != 0) {
this->unk_250--;
}
if (this->unk_252 != 0) {
this->unk_252--;
}
if (this->unk_256 != 0) {
this->unk_256--;
}
if (this->unk_258 != 0) {
this->unk_258--;
}
if (this->unk_254 != 0) {
this->unk_254--;
}
if (this->unk_25A != 0) {
this->unk_25A--;
}
DECR(this->unkTimer24C);
DECR(this->unkTimer250);
DECR(this->hopTimer);
DECR(this->crySfxTimer);
DECR(this->flutterSfxTimer);
DECR(this->randomAngleChangeTimer);
DECR(this->unkTimer25A);
this->actor.shape.rot = this->actor.world.rot;
this->actor.shape.shadowScale = 15.0f;
@ -373,45 +369,48 @@ void EnAttackNiw_Update(Actor* thisx, GlobalContext* globalCtx) {
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D);
if (this->actionFunc == func_80958634) {
if (this->actionFunc == EnAttackNiw_EnterViewFromOffscreen) {
Actor_MoveWithoutGravity(&this->actor);
} else {
Actor_MoveWithGravity(&this->actor);
}
if (this->actor.floorHeight <= -32000.0f) {
if (this->actor.floorHeight <= BGCHECK_Y_MIN) { // under the world
Actor_MarkForDeath(&this->actor);
} else if ((this->actor.bgCheckFlags & 0x20) && (this->actionFunc != func_80958BE4)) {
Math_Vec3f_Copy(&sp30, &this->actor.world.pos);
sp30.y += this->actor.depthInWater;
EffectSsGSplash_Spawn(globalCtx, &sp30, NULL, NULL, 0, 400);
this->unk_2D4 = 0.0f;
} else if ((this->actor.bgCheckFlags & 0x20) && // on or below water
(this->actionFunc != EnAttackNiw_FlyAway)) {
Math_Vec3f_Copy(&splashPos, &this->actor.world.pos);
splashPos.y += this->actor.depthInWater;
EffectSsGSplash_Spawn(globalCtx, &splashPos, NULL, NULL, 0, 400);
this->rotStep = 0.0f;
this->actor.gravity = 0.0f;
this->unk_2D8 = 0.0f;
this->unk_2C8 = this->actor.world.rot.x - 5000.0f;
this->actionFunc = func_80958BE4;
this->targetXZSpeed = 0.0f;
this->targetRotX = this->actor.world.rot.x - 5000.0f;
this->actionFunc = EnAttackNiw_FlyAway;
} else {
f32 temp = 20.0f;
f32 viewOffset = 20.0f;
label:
if (this->actor.xyzDistToPlayerSq < SQ(temp)) {
if (this->actor.xyzDistToPlayerSq < SQ(viewOffset)) {
parent = (EnNiw*)this->actor.parent;
if ((this->actor.parent->update != NULL) && (this->actor.parent != NULL) && (parent != NULL) &&
(parent->unusedTimer25E == 0) && (player->invincibilityTimer == 0)) {
(parent->unkAttackNiwTimer == 0) && (player->invincibilityTimer == 0)) {
// this updates some player values based on what we pass, need player decomp to know what this is doing
func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.world.rot.y, 0.0f, 0x10);
parent->unusedTimer25E = 70;
parent->unkAttackNiwTimer = 70;
}
}
if (this->unk_256 == 0) {
this->unk_256 = 30;
if (this->crySfxTimer == 0) {
this->crySfxTimer = 30;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_A);
}
if (this->unk_258 == 0) {
this->unk_258 = 7;
if (this->flutterSfxTimer == 0) {
this->flutterSfxTimer = 7;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_CHICKEN_FLUTTER);
}
}
@ -421,24 +420,24 @@ s32 EnAttackNiw_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx**
Actor* thisx) {
EnAttackNiw* this = THIS;
if (limbIndex == OBJECT_NIW_LIMB_0D) {
rot->y += (s16)this->unk_2B4;
if (limbIndex == NIW_LIMB_UPPER_BODY) {
rot->y += (s16)this->upperBodyRotY;
}
if (limbIndex == OBJECT_NIW_LIMB_0F) {
rot->z += (s16)this->unk_2B8;
if (limbIndex == NIW_LIMB_HEAD) {
rot->z += (s16)this->headRotZ;
}
if (limbIndex == OBJECT_NIW_LIMB_0B) {
rot->x += (s16)this->unk_2B0;
rot->y += (s16)this->unk_2AC;
rot->z += (s16)this->unk_2A8;
if (limbIndex == NIW_LIMB_RIGHT_WING_ROOT) {
rot->x += (s16)this->rightWingRotX;
rot->y += (s16)this->rightWingRotY;
rot->z += (s16)this->rightWingRotZ;
}
if (limbIndex == OBJECT_NIW_LIMB_07) {
rot->x += (s16)this->unk_2A4;
rot->y += (s16)this->unk_2A0;
rot->z += (s16)this->unk_29C;
if (limbIndex == NIW_LIMB_LEFT_WING_ROOT) {
rot->x += (s16)this->leftWingRotX;
rot->y += (s16)this->leftWingRotY;
rot->z += (s16)this->leftWingRotZ;
}
return false;
}

View File

@ -11,49 +11,52 @@ typedef void (*EnAttackNiwActionFunc)(struct EnAttackNiw*, GlobalContext*);
typedef struct EnAttackNiw {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelAnime;
/* 0x188 */ Vec3s jointTable[OBJECT_NIW_LIMB_MAX];
/* 0x1E8 */ Vec3s morphTable[OBJECT_NIW_LIMB_MAX];
/* 0x188 */ Vec3s jointTable[NIW_LIMB_MAX];
/* 0x1E8 */ Vec3s morphTable[NIW_LIMB_MAX];
/* 0x248 */ EnAttackNiwActionFunc actionFunc;
/* 0x24C */ s16 unk_24C;
/* 0x24E */ s16 unk_24E;
/* 0x250 */ s16 unk_250;
/* 0x252 */ s16 unk_252;
/* 0x254 */ s16 unk_254;
/* 0x256 */ s16 unk_256;
/* 0x258 */ s16 unk_258;
/* 0x25A */ s16 unk_25A;
/* 0x25C */ f32 unk_25C;
/* 0x260 */ f32 unk_260;
/* 0x264 */ f32 unk_264;
/* 0x268 */ UNK_TYPE1 unk268[8];
/* 0x270 */ f32 unk_270;
/* 0x274 */ f32 unk_274;
/* 0x278 */ f32 unk_278;
/* 0x27C */ f32 unk_27C;
/* 0x280 */ f32 unk_280;
/* 0x284 */ s16 unk_284;
/* 0x286 */ s16 unk_286;
/* 0x288 */ UNK_TYPE1 unk288[2];
/* 0x28A */ s16 unk_28A;
/* 0x28C */ UNK_TYPE1 unk28C[4];
/* 0x290 */ Vec3f unk_290;
/* 0x29C */ f32 unk_29C;
/* 0x2A0 */ f32 unk_2A0;
/* 0x2A4 */ f32 unk_2A4;
/* 0x2A8 */ f32 unk_2A8;
/* 0x2AC */ f32 unk_2AC;
/* 0x2B0 */ f32 unk_2B0;
/* 0x2B4 */ f32 unk_2B4;
/* 0x2B8 */ f32 unk_2B8;
/* 0x2BC */ UNK_TYPE1 unk2BC[0xC];
/* 0x2C8 */ f32 unk_2C8;
/* 0x2CC */ f32 unk_2CC;
/* 0x2D0 */ UNK_TYPE1 unk2D0[4];
/* 0x2D4 */ f32 unk_2D4;
/* 0x2D8 */ f32 unk_2D8;
/* 0x2DC */ f32 unk_2DC;
/* 0x24C */ s16 unkTimer24C; // control behavior in _UpdateRotations
/* 0x24E */ s16 unusedTimer24E; // set never read
/* 0x250 */ s16 unkTimer250; // control behavior in _UpdateRotations
/* 0x252 */ s16 hopTimer;
/* 0x254 */ s16 randomAngleChangeTimer;
/* 0x256 */ s16 crySfxTimer;
/* 0x258 */ s16 flutterSfxTimer;
/* 0x25A */ s16 unkTimer25A; // set to 50 in run at player, locks fly away without water?
/* 0x25C */ f32 targetBodyRotY;
/* 0x260 */ f32 targetRightWingRotZ;
/* 0x264 */ f32 targetLeftWingRotZ;
/* 0x268 */ f32 unusedRotations[2]; // in EnNiw this is an array of targetRot
/* 0x270 */ f32 targetRightWingRotY;
/* 0x274 */ f32 targetRightWingRotX;
/* 0x278 */ f32 targetLeftWingRotY;
/* 0x27C */ f32 targetLeftWingRotX;
/* 0x280 */ f32 targetHeadRotZ;
/* 0x284 */ s16 unusedCounter284; // incremented in _Update, never read
/* 0x286 */ s16 clearRotYToggleTimer;
/* 0x288 */ UNK_TYPE1 pad288[2];
/* 0x28A */ s16 unkToggle28A;
/* 0x28C */ UNK_TYPE1 pad28C[4];
/* 0x290 */ Vec3f randomTargetCenterOffset; // see EnAttackNiw_EnterViewFromOffscreen
/* 0x29C */ f32 leftWingRotZ;
/* 0x2A0 */ f32 leftWingRotY;
/* 0x2A4 */ f32 leftWingRotX;
/* 0x2A8 */ f32 rightWingRotZ;
/* 0x2AC */ f32 rightWingRotY;
/* 0x2B0 */ f32 rightWingRotX;
/* 0x2B4 */ f32 upperBodyRotY;
/* 0x2B8 */ f32 headRotZ;
/* 0x2BC */ UNK_TYPE1 pad2BC[0xC]; // unused rotations?
/* 0x2C8 */ f32 targetRotX;
/* 0x2CC */ f32 targetRotY;
/* 0x2D0 */ UNK_TYPE1 pad2D0[4];
/* 0x2D4 */ f32 rotStep;
/* 0x2D8 */ f32 targetXZSpeed;
/* 0x2DC */ f32 targetHeight; // never set, but sent to Actor_SetFocus
} EnAttackNiw; // size = 0x2E0
extern const ActorInit En_Attack_Niw_InitVars;
#define ATTACK_NIW_REGULAR 0 // spawned by EnNiw
#endif // Z_EN_ATTACK_NIW_H

View File

@ -18,8 +18,8 @@ void EnHs_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_80952FE0(EnHs* this, GlobalContext* globalCtx);
void func_80953098(EnHs* this, GlobalContext* globalCtx);
void func_80953180(EnHs* this, GlobalContext* globalCtx);
void func_809532C0(EnHs* this, GlobalContext* globalCtx);
void func_809532D0(EnHs* this, GlobalContext* globalCtx);
void EnHs_DoNothing(EnHs* this, GlobalContext* globalCtx);
void EnHs_SceneTransitToBunnyHoodDialogue(EnHs* this, GlobalContext* globalCtx);
void func_80953354(EnHs* this, GlobalContext* globalCtx);
void func_8095345C(EnHs* this, GlobalContext* globalCtx);
@ -61,12 +61,12 @@ void func_80952C50(EnHs* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
s32 i;
for (i = 0; i < ARRAY_COUNT(this->unk_2A4); i++) {
Math_Vec3f_Copy(&this->unk_2A4[i], &player->actor.world.pos);
for (i = 0; i < ARRAY_COUNT(this->nwcPos); i++) {
Math_Vec3f_Copy(&this->nwcPos[i], &player->actor.world.pos);
}
this->actor.home.rot.x = 0;
this->actor.home.rot.z = 0;
this->actor.home.rot.x = 0; // reset adult transformed count
this->actor.home.rot.z = 0; // reset chick count
}
void EnHs_Init(Actor* thisx, GlobalContext* globalCtx) {
@ -74,17 +74,19 @@ void EnHs_Init(Actor* thisx, GlobalContext* globalCtx) {
EnHs* this = THIS;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_hs_Skel_006260, &object_hs_Anim_0005C0, this->jointTable,
this->morphTable, OBJECT_HS_LIMB_MAX);
Animation_PlayLoop(&this->skelAnime, &object_hs_Anim_0005C0);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gHsSkeleton, &gHsIdleAnim, this->jointTable, this->morphTable,
OBJECT_HS_LIMB_MAX);
Animation_PlayLoop(&this->skelAnime, &gHsIdleAnim);
Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
Actor_SetScale(&this->actor, 0.01f);
this->actionFunc = func_8095345C;
if (globalCtx->curSpawn == 1) {
this->actor.flags |= ACTOR_FLAG_10000;
}
this->unk_2A0 = 0;
this->stateFlags = 0;
this->actor.targetMode = 6;
func_80952C50(this, globalCtx);
}
@ -102,56 +104,56 @@ void func_80952DFC(GlobalContext* globalCtx) {
func_80151BB4(globalCtx, 0x10);
}
void func_80952E50(Vec3f* dst, Vec3f src, f32 arg2) {
Vec3f sp1C;
f32 temp_f0;
void EnHs_UpdateChickPos(Vec3f* dst, Vec3f src, f32 offset) {
Vec3f diff;
f32 distance;
Math_Vec3f_Diff(&src, dst, &sp1C);
Math_Vec3f_Diff(&src, dst, &diff);
temp_f0 = SQ(sp1C.x) + SQ(sp1C.z);
distance = SQ(diff.x) + SQ(diff.z); // gets un-squared after we check if we are too close
if (SQ(arg2) > temp_f0) {
if (SQ(offset) > distance) {
return;
}
temp_f0 = sqrtf(temp_f0);
sp1C.x *= (temp_f0 - arg2) / temp_f0;
sp1C.z *= (temp_f0 - arg2) / temp_f0;
distance = sqrtf(distance);
diff.x *= (distance - offset) / distance;
diff.z *= (distance - offset) / distance;
dst->x += sp1C.x;
dst->z += sp1C.z;
dst->x += diff.x;
dst->z += diff.z;
}
void func_80952F00(EnHs* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
s32 i;
f32 phi_f20;
f32 offset;
if (this->actor.home.rot.z >= 20) {
phi_f20 = 15.0f;
if (this->actor.home.rot.z >= 20) { // current chick count >= 10
offset = 15.0f;
} else {
phi_f20 = 10.0f;
offset = 10.0f;
}
func_80952E50(&this->unk_2A4[0], player->actor.world.pos, phi_f20);
EnHs_UpdateChickPos(&this->nwcPos[0], player->actor.world.pos, offset);
for (i = 1; i < ARRAY_COUNT(this->unk_2A4); i++) {
func_80952E50(&this->unk_2A4[i], this->unk_2A4[i - 1], phi_f20);
for (i = 1; i < ARRAY_COUNT(this->nwcPos); i++) {
EnHs_UpdateChickPos(&this->nwcPos[i], this->nwcPos[i - 1], offset);
}
}
void func_80952FE0(EnHs* this, GlobalContext* globalCtx) {
if (this->unk_2A2 < 40) {
Math_SmoothStepToS(&this->unk_294.y, 0x1F40, 6, 0x1838, 0x64);
} else if (this->unk_2A2 < 80) {
Math_SmoothStepToS(&this->unk_294.y, -0x1F40, 6, 0x1838, 0x64);
if (this->stateTimer < 40) {
Math_SmoothStepToS(&this->headRot.y, 0x1F40, 6, 0x1838, 0x64);
} else if (this->stateTimer < 80) {
Math_SmoothStepToS(&this->headRot.y, -0x1F40, 6, 0x1838, 0x64);
} else {
this->actionFunc = func_80953180;
this->unk_2A0 &= ~4;
this->stateFlags &= ~4;
func_80151938(globalCtx, 0x33F6);
func_80952DFC(globalCtx);
}
this->unk_2A2++;
this->stateTimer++;
}
void func_80953098(EnHs* this, GlobalContext* globalCtx) {
@ -159,10 +161,10 @@ void func_80953098(EnHs* this, GlobalContext* globalCtx) {
this->actor.parent = NULL;
this->actionFunc = func_8095345C;
this->actor.flags |= ACTOR_FLAG_10000;
this->unk_2A0 |= 0x10;
this->stateFlags |= 0x10;
func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1);
} else {
this->unk_2A0 |= 8;
this->stateFlags |= 8;
if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) {
Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_RED, 10000.0f, 50.0f);
} else {
@ -174,31 +176,31 @@ void func_80953098(EnHs* this, GlobalContext* globalCtx) {
void func_80953180(EnHs* this, GlobalContext* globalCtx) {
if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.currentTextId) {
case 0x33F4:
case 0x33F6:
case 0x33F4: // text: laughing that they are all roosters (!)
case 0x33F6: // text: Grog regrets not being able to see his chicks reach adult hood
func_801477B4(globalCtx);
this->actionFunc = func_8095345C;
break;
case 0x33F7:
case 0x33F7: // text: notice his chicks are grown up, happy, wants to give you bunny hood
this->actor.flags &= ~ACTOR_FLAG_10000;
func_801477B4(globalCtx);
this->actionFunc = func_80953098;
func_80953098(this, globalCtx);
break;
case 0x33F9:
case 0x33F9: // text: laughing that they are all roosters (.)
this->actor.flags &= ~ACTOR_FLAG_10000;
func_801477B4(globalCtx);
this->actionFunc = func_8095345C;
break;
case 0x33F5:
case 0x33F5: // He heard from his gramps (?) the moon is going to fall
globalCtx->msgCtx.unk11F10 = 0;
this->actionFunc = func_80952FE0;
this->unk_2A2 = 0;
this->unk_294.z = 0;
this->unk_2A0 |= 4;
this->stateTimer = 0;
this->headRot.z = 0;
this->stateFlags |= 4;
break;
default:
@ -209,34 +211,34 @@ void func_80953180(EnHs* this, GlobalContext* globalCtx) {
}
}
void func_809532C0(EnHs* this, GlobalContext* globalCtx) {
void EnHs_DoNothing(EnHs* this, GlobalContext* globalCtx) {
}
void func_809532D0(EnHs* this, GlobalContext* globalCtx) {
if (DECR(this->unk_2A2) == 0) {
globalCtx->nextEntranceIndex = globalCtx->setupExitList[ENHS_GET_F(&this->actor)];
void EnHs_SceneTransitToBunnyHoodDialogue(EnHs* this, GlobalContext* globalCtx) {
if (DECR(this->stateTimer) == 0) {
globalCtx->nextEntranceIndex = globalCtx->setupExitList[HS_GET_EXIT_INDEX(&this->actor)];
globalCtx->sceneLoadFlag = 0x14;
gSaveContext.save.weekEventReg[25] |= 8;
this->actionFunc = func_809532C0;
this->actionFunc = EnHs_DoNothing;
}
}
void func_80953354(EnHs* this, GlobalContext* globalCtx) {
if (!Play_InCsMode(globalCtx)) {
func_800B7298(globalCtx, &this->actor, 7);
this->actionFunc = func_809532D0;
this->actionFunc = EnHs_SceneTransitToBunnyHoodDialogue;
}
}
void func_809533A0(EnHs* this, GlobalContext* globalCtx) {
u16 sp1E;
if ((globalCtx->curSpawn == 1) && !(this->unk_2A0 & 0x20)) {
if ((globalCtx->curSpawn == 1) && !(this->stateFlags & 0x20)) {
sp1E = 0x33F7;
this->unk_2A0 |= 0x20;
} else if (this->unk_2A0 & 0x10) {
this->stateFlags |= 0x20;
} else if (this->stateFlags & 0x10) {
sp1E = 0x33F9;
this->unk_2A0 &= ~0x10;
this->stateFlags &= ~0x10;
} else if (gSaveContext.save.weekEventReg[25] & 8) {
sp1E = 0x33F4;
} else {
@ -254,21 +256,21 @@ void func_8095345C(EnHs* this, GlobalContext* globalCtx) {
if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) {
this->actionFunc = func_80953180;
func_809533A0(this, globalCtx);
if (this->unk_2A0 & 8) {
if (this->stateFlags & 8) {
func_80952DFC(globalCtx);
this->unk_2A0 &= ~8;
this->stateFlags &= ~8;
}
} else if (this->actor.home.rot.x >= 20) {
} else if (this->actor.home.rot.x >= 20) { // chicks turned adult >= 10
this->actionFunc = func_80953354;
this->unk_2A2 = 40;
this->stateTimer = 40;
} else if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_10000)) {
func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1);
this->unk_2A0 |= 1;
this->stateFlags |= 1;
} else if ((this->actor.xzDistToPlayer < 120.0f) && Player_IsFacingActor(&this->actor, 0x2000, globalCtx)) {
func_800B8614(&this->actor, globalCtx, 130.0f);
this->unk_2A0 |= 1;
this->stateFlags |= 1;
} else {
this->unk_2A0 &= ~1;
this->stateFlags &= ~1;
}
}
@ -290,17 +292,17 @@ void EnHs_Update(Actor* thisx, GlobalContext* globalCtx) {
func_80952F00(this, globalCtx);
if (this->unk_2A0 & 4) {
Math_SmoothStepToS(&this->unk_294.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unk_29A.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unk_29A.y, 0, 6, 0x1838, 0x64);
} else if (this->unk_2A0 & 1) {
func_800E9250(globalCtx, &this->actor, &this->unk_294, &this->unk_29A, this->actor.focus.pos);
if (this->stateFlags & 4) {
Math_SmoothStepToS(&this->headRot.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unusedRot.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unusedRot.y, 0, 6, 0x1838, 0x64);
} else if (this->stateFlags & 1) {
func_800E9250(globalCtx, &this->actor, &this->headRot, &this->unusedRot, this->actor.focus.pos);
} else {
Math_SmoothStepToS(&this->unk_294.x, 0x3200, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unk_294.y, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unk_29A.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unk_29A.y, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->headRot.x, 0x3200, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->headRot.y, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unusedRot.x, 0, 6, 0x1838, 0x64);
Math_SmoothStepToS(&this->unusedRot.y, 0, 6, 0x1838, 0x64);
}
}
@ -308,29 +310,33 @@ s32 EnHs_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList,
EnHs* this = THIS;
switch (limbIndex) {
case OBJECT_HS_LIMB_09:
rot->x += this->unk_294.y;
rot->z += this->unk_294.x;
case HS_LIMB_HEAD:
rot->x += this->headRot.y;
rot->z += this->headRot.x;
break;
case OBJECT_HS_LIMB_0A:
rot->x += this->unk_294.y;
rot->z += this->unk_294.x;
case HS_LIMB_HAIR_SPIKES:
rot->x += this->headRot.y;
rot->z += this->headRot.x;
break;
case OBJECT_HS_LIMB_0B:
case HS_LIMB_HIDDEN_HAIR:
// for some reason this hair is always removed here in the Override limb
// if you do re-enable, make sure you add the head rot like above
*dList = NULL;
return false;
// these two limbs both have empty enddisplaylist, they do nothing
// at the same time (params == HS_TYPE_UNK1) is always false, because vanilla params is 0xFE01
case OBJECT_HS_LIMB_0C:
if (this->actor.params == ENHS_1) {
if (this->actor.params == HS_TYPE_UNK1) {
*dList = NULL;
return false;
}
break;
case OBJECT_HS_LIMB_0D:
if (this->actor.params == ENHS_1) {
if (this->actor.params == HS_TYPE_UNK1) {
*dList = NULL;
return false;
}
@ -342,7 +348,7 @@ s32 EnHs_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList,
void EnHs_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
EnHs* this = THIS;
if (limbIndex == OBJECT_HS_LIMB_09) {
if (limbIndex == HS_LIMB_HEAD) {
Matrix_MultiplyVector3fByState(&D_8095393C, &this->actor.focus.pos);
}
}

View File

@ -8,9 +8,17 @@ struct EnHs;
typedef void (*EnHsActionFunc)(struct EnHs*, GlobalContext*);
#define ENHS_GET_F(thisx) ((thisx)->params & 0xF)
#define HS_GET_EXIT_INDEX(thisx) ((thisx)->params & 0xF)
#define ENHS_1 1
#define HS_TYPE_UNK1 1
// params mystery: Vanilla Grog is 0xFE01
// 0xFE00 space is never checked in Grog code
// at the same time, type UNK1 is only checked directly with params == 1, no &F
// so HS_TYPE_UNK1 is never valid and is unused, as 0xFE00 is still present even if its not doing anything else
// The count of [chicks following the player] is stored in [this->actor.home.rot.z] (incremented by 2)
// The count of [chicks transformed into adult] is stored in [this->actor.home.rot.x] (incremented by 2)
typedef struct EnHs {
/* 0x0000 */ Actor actor;
@ -18,11 +26,11 @@ typedef struct EnHs {
/* 0x0190 */ SkelAnime skelAnime;
/* 0x01D4 */ Vec3s jointTable[OBJECT_HS_LIMB_MAX];
/* 0x0234 */ Vec3s morphTable[OBJECT_HS_LIMB_MAX];
/* 0x0294 */ Vec3s unk_294;
/* 0x029A */ Vec3s unk_29A;
/* 0x02A0 */ u16 unk_2A0;
/* 0x02A2 */ s16 unk_2A2;
/* 0x02A4 */ Vec3f unk_2A4[20];
/* 0x0294 */ Vec3s headRot;
/* 0x029A */ Vec3s unusedRot; // probably not chest, as chest is same limb as lower body
/* 0x02A0 */ u16 stateFlags;
/* 0x02A2 */ s16 stateTimer; // reused for different actionFunc
/* 0x02A4 */ Vec3f nwcPos[20]; // actual chick position are even values, odd values seem to be extra values for smoother chain
/* 0x0394 */ EnHsActionFunc actionFunc;
} EnHs; // size = 0x398

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
#define Z_EN_NIW_H
#include "global.h"
#include "objects/object_niw/object_niw.h"
struct EnNiw;
@ -19,55 +20,67 @@ typedef struct {
/* 0x0034 */ u8 timer;
} EnNiwFeather; // size = 0x38
#define ENNIW_LIMBCOUNT 16
#define ENNIW_FEATHERCOUNT 20
#define NIW_FEATHER_COUNT 20
typedef struct EnNiw {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelanime;
/* 0x188 */ Vec3s jointTable[ENNIW_LIMBCOUNT];
/* 0x1E8 */ Vec3s morphTable[ENNIW_LIMBCOUNT];
/* 0x188 */ Vec3s jointTable[NIW_LIMB_MAX];
/* 0x1E8 */ Vec3s morphTable[NIW_LIMB_MAX];
/* 0x248 */ EnNiwActionFunc actionFunc;
/* 0x24C */ s16 unkTimer24C;
/* 0x24C */ s16 unkTimer24C; // set to 10, checked in mystery func
/* 0x24E */ s16 unkTimer24E;
/* 0x250 */ s16 unkTimer250;
/* 0x252 */ s16 unkTimer252;
/* 0x254 */ s16 unkTimer254;
/* 0x250 */ union {
s16 generalTimer1; // default name for reset/decr
s16 hopTimer; // every 3 frames while running/idling
s16 swimRippleTimer; // how often swimming cucco spawns ripples
s16 heldTimer; // timer until updating unk29E
s16 unkIdleTimer; // not sure what _Idle is doing with it yet
};
/* 0x252 */ union {
s16 generalTimer2; // default name for reset/decr
s16 hoppingTimer; // hopping after being thrown before running
s16 attackNiwSpawnTimer; // delay between re-attempting to spawn more attack_niw
s16 runningDirectionTimer; // delay between direction changes when running
s16 cuccoStormTimer; // delay between stages of summoning the storm
s16 unkIdleTimer2; // not sure what _Idle is doing with it yet
};
/* 0x254 */ s16 runAwayTimer;
/* 0x256 */ s16 sfxTimer1;
/* 0x258 */ s16 flutterSfxTimer;
/* 0x25A */ s16 unusedTimer25A;
/* 0x25C */ s16 yawTimer; // every 70 frames rechecks yawToPlayer
/* 0x25E */ s16 unusedTimer25E;
/* 0x260 */ s16 unkTimer260;
/* 0x264 */ f32 unk264[10];
/* 0x25C */ s16 yawTimer; // every 70 frames rechecks yawToPlayer
/* 0x25E */ s16 unkAttackNiwTimer; // every 70 frames, updates some player unk values
/* 0x260 */ s16 iframeTimer;
/* 0x264 */ f32 targetLimbRots[10];
/* 0x28C */ s16 unusedCounter28C;
/* 0x28E */ s16 unknownState28E;
/* 0x290 */ s16 unk290;
/* 0x28E */ s16 niwState;
/* 0x290 */ s16 attackNiwCount;
/* 0x292 */ s16 unk292;
/* 0x294 */ s16 pad294;
/* 0x296 */ s16 unk296;
/* 0x296 */ s16 unkToggle296;
/* 0x298 */ s16 unk298;
/* 0x29C */ s16 unk29A;
/* 0x29C */ u16 unk29C;
/* 0x29E */ s16 unk29E;
/* 0x2A0 */ s16 isStormActive;
/* 0x29C */ s16 isRunningRight; // toggle (direction cucco is turning while running)
/* 0x29C */ u16 nextAnimation;
/* 0x29E */ s16 unk29E; // three states 0/1/2
/* 0x2A0 */ s16 isStormActive; // we have a data value shared between all cucco, this shouldn't need to exist
/* 0x2A2 */ s16 niwType;
/* 0x2A4 */ Vec3f unk2A4;
/* 0x2B0 */ Vec3f unk2B0;
/* 0x2BC */ Vec3f unk2BC;
/* 0x2C8 */ f32 limb7Rotz;
/* 0x2CC */ f32 limb7Roty;
/* 0x2D0 */ f32 limb7Rotx;
/* 0x2D4 */ f32 limbBRotz;
/* 0x2D8 */ f32 limbBRoty;
/* 0x2DC */ f32 limbBRotx;
/* 0x2E0 */ f32 limbDRot;
/* 0x2E4 */ f32 limbFRot;
/* 0x2BC */ Vec3f unk2BC; // init from data (90000 on all three)
/* 0x2C8 */ f32 leftWingRotZ;
/* 0x2CC */ f32 leftWingRotY;
/* 0x2D0 */ f32 leftWingRotX;
/* 0x2D4 */ f32 rightWingRotZ;
/* 0x2D8 */ f32 rightWingRotY;
/* 0x2DC */ f32 rightWingRotX;
/* 0x2E0 */ f32 upperBodyRotY;
/* 0x2E4 */ f32 headRotY;
/* 0x2E8 */ s16 yawTowardsPlayer;
/* 0x2EA */ s16 unk2EA;
/* 0x2EA */ s16 headRotationToggle;
/* 0x2EC */ s16 unk2EC;
/* 0x2EE */ UNK_TYPE1 pad2EE[0x6];
/* 0x2F4 */ f32 unusedFloat2F4;
/* 0x2F4 */ f32 unusedFloat2F4; // set in EnNiw_Update if Cucco falls off map, never read
/* 0x2F8 */ f32 unusedFloat2F8;
/* 0x2FC */ f32 unusedFloat2FC;
/* 0x300 */ f32 unk300;
@ -75,16 +88,26 @@ typedef struct EnNiw {
/* 0x308 */ f32 unk308;
/* 0x30C */ s32 pad30C;
/* 0x310 */ ColliderCylinder collider;
/* 0x35C */ EnNiwFeather feathers[ENNIW_FEATHERCOUNT];
/* 0x35C */ EnNiwFeather feathers[NIW_FEATHER_COUNT];
} EnNiw; // size = 0x7BC
// in init, any value below zero becomes zero
// however, in vanilla, only 0xFFFF (-1) exists
#define ENNIW_TYPE_VANILLA 0xFFFF
#define ENNIW_TYPE_REGULAR 0
#define ENNIW_TYPE_UNK1 1
#define ENNIW_TYPE_UNK2 2
// the attacking cuccos are not here, they are a different actor:
// ovl_En_Attack_Niw
// however, in vanilla, only 0xFFFF (-1) exists in scene spawns, actors can spawn 0x0
#define NIW_TYPE_VANILLA 0xFFFF
#define NIW_TYPE_REGULAR 0
#define NIW_TYPE_UNK1 1
#define NIW_TYPE_HELD 2 // spawns held by the bomber kid in east clock town during hide and seek
// the attacking cuccos are not here, they are a different actor: [ ovl_En_Attack_Niw ]
typedef enum {
/* 0 */ NIW_ANIMATION_STILL,
/* 1 */ NIW_ANIMATION_HEAD_PECKING, // forward and backward, feeding
/* 2 */ NIW_ANIMATION_PECKING_AND_WAVING, // wings move along their axis, like human hand waving
/* 3 */ NIW_ANIMATION_PECKING_AND_FORFLAPPING, // (unused) low (yaw based) flapping, forward and back
/* 4 */ NIW_ANIMATION_FREEZE, // used during Cucco Storm
/* 5 */ NIW_ANIMATION_PECKING_SLOW_FORFLAPPING, // wing speed half that of 3
} EnNiwHeadAndWingAnimationState;
#endif // Z_EN_NIW_H

View File

@ -2,9 +2,14 @@
* File: z_en_nwc.c
* Overlay: ovl_En_Nwc
* Description: Cucco chick
*
* This actor requires object_niw to be present for the transformation during Breman Mask March
* EnHs (Grog) must also be present to maintain the count of the EnNwc in the march
*/
#include "z_en_nwc.h"
#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
#include "objects/object_nwc/object_nwc.h"
#define FLAGS (ACTOR_FLAG_10)
@ -15,15 +20,27 @@ void EnNwc_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnNwc_Update(Actor* thisx, GlobalContext* globalCtx);
void EnNwc_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_809448A4(EnNwc* this, GlobalContext* globalCtx);
void func_809449D0(EnNwc* this, GlobalContext* globalCtx);
void func_80944A50(EnNwc* this, GlobalContext* globalCtx);
void func_80944E44(EnNwc* this, GlobalContext* globalCtx);
void func_80944EFC(EnNwc* this, GlobalContext* globalCtx);
void func_80944FA8(EnNwc* this, GlobalContext* globalCtx);
void func_8094506C(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_LoadNiwSkeleton(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_CrowAtTheEnd(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_Follow(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_HopForward(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_RunAway(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_Turn(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_CheckForBreman(EnNwc* this, GlobalContext* globalCtx);
void EnNwc_DrawAdultBody(Actor* thisx, GlobalContext* globalCtx);
s32 EnNwc_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx);
EnHs* EnNwc_FindGrog(GlobalContext* globalCtx);
enum EnNiwState {
/* -1 */ NWC_STATE_NIW_LOADED = -1, // set after loading object_niw
/* 0 */ NWC_STATE_CHECK_BREMAN = 0, // checking for breman mask
/* 1 */ NWC_STATE_TURNING, // turning to face a new direction to explore
/* 2 */ NWC_STATE_HOPPING_FORWARD, // hopping to go explore
/* 3 */ NWC_STATE_FOLLOWING, // following the player
/* 4 */ NWC_STATE_RUNNING, // running from the player after failed breman march
};
#if 0
const ActorInit En_Nwc_InitVars = {
ACTOR_EN_NWC,
ACTORCAT_PROP,
@ -36,47 +53,474 @@ const ActorInit En_Nwc_InitVars = {
(ActorFunc)EnNwc_Draw,
};
#endif
Color_RGBA8 sPrimColor = { 255, 255, 255, 255 };
extern UNK_TYPE D_060000E8;
extern UNK_TYPE D_060002E8;
Color_RGBA8 sEnvColor = { 80, 80, 80, 255 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Init.s")
void EnNwc_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 niwObjectIndex;
EnNwc* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Destroy.s")
niwObjectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_NIW);
if (niwObjectIndex < 0) {
// niw object does not exist, we need it for tranformation, despawn
Actor_MarkForDeath(&this->actor);
return;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944320.s")
if (gSaveContext.save.weekEventReg[25] & 8) {
// if breman mask was already used, replace with adult EnNiw
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_NIW, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, NIW_TYPE_REGULAR);
Actor_MarkForDeath(&this->actor);
return;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944554.s")
this->niwObjectIndex = niwObjectIndex;
this->nwcObjectIndex = this->actor.objBankIndex;
this->grog = EnNwc_FindGrog(globalCtx);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944590.s")
this->footRotY = this->footRotZ = 0;
Actor_SetScale(&this->actor, 0.01f);
this->actionFunc = EnNwc_LoadNiwSkeleton;
this->hasGrownUp = false;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 6.0f);
this->actor.velocity.y = 0.0f;
this->actor.terminalVelocity = -9.0f;
this->actor.gravity = -1.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809445D4.s")
void EnNwc_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnNwc* this = THIS;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944630.s")
void EnNwc_SpawnDust(EnNwc* this, GlobalContext* globalCtx) {
Vec3f pos;
Vec3f vec5;
Vec3f vel;
Vec3f accel;
s16 yaw;
s16 pitch;
Vec3f eye = GET_ACTIVE_CAM(globalCtx)->eye;
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809447A8.s")
yaw = Math_Vec3f_Yaw(&eye, &this->actor.world.pos);
pitch = -Math_Vec3f_Pitch(&eye, &this->actor.world.pos);
vec5.x = this->actor.world.pos.x - 5.0f * Math_SinS(yaw) * Math_CosS(pitch);
vec5.y = this->actor.world.pos.y - 5.0f * Math_SinS(pitch);
vec5.z = this->actor.world.pos.z - 5.0f * Math_CosS(yaw) * Math_CosS(pitch);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944818.s")
for (i = 0; i < 5; i++) {
vel.x = randPlusMinusPoint5Scaled(4.0f);
vel.y = randPlusMinusPoint5Scaled(4.0f);
vel.z = randPlusMinusPoint5Scaled(4.0f);
accel.x = -vel.x * 0.1f;
accel.y = -vel.y * 0.1f;
accel.z = -vel.z * 0.1f;
pos.x = vec5.x + vel.x;
pos.y = vec5.y + vel.y;
pos.z = vec5.z + vel.z;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809448A4.s")
func_800B0F80(globalCtx, &pos, &vel, &accel, &sPrimColor, &sEnvColor, 300, 30, 10);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809449D0.s")
EnHs* EnNwc_FindGrog(GlobalContext* globalCtx) {
Actor* grogSearch = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944A50.s")
while (grogSearch != NULL) {
if (grogSearch->id == ACTOR_EN_HS) {
return (EnHs*)grogSearch;
}
grogSearch = grogSearch->next;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944E44.s")
return NULL;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944EFC.s")
s32 EnNwc_PlayerReleasedBremanMarch(EnNwc* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944FA8.s")
// Weird: home.rot.x holds count of chicks having transformed into adult.
// Weird: Its incremented by 1 unlike chicks following, so it should max at 10.
if (this->grog->actor.home.rot.x >= 20) {
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_8094506C.s")
if (player->stateFlags3 & 0x20000000) { // breman mask march
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Update.s")
return true;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Draw.s")
/**
* Summary: Checks 1) if grog exists, 2) player is using breman mask, 3) and within range.
* Used to identify if the chick should be captured by breman mask.
*/
s32 EnNwc_IsFound(EnNwc* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_8094529C.s")
if (this->grog == NULL) {
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80945310.s")
if (player->stateFlags3 & 0x20000000 && // breman mask march
this->actor.xzDistToPlayer < 100.0f) {
return true;
}
return false;
}
void EnNwc_ChangeState(EnNwc* this, s16 newState) {
this->actor.speedXZ = 0.0f;
switch (newState) {
case NWC_STATE_CHECK_BREMAN:
this->stateTimer = 10;
this->actionFunc = EnNwc_CheckForBreman;
break;
case NWC_STATE_TURNING:
this->stateTimer = Rand_ZeroFloat(20.0f) + 15.0f;
this->actionFunc = EnNwc_Turn;
this->fallingRotY = (s16)(s32)randPlusMinusPoint5Scaled(65536.0f);
break;
case NWC_STATE_HOPPING_FORWARD:
this->stateTimer = Rand_ZeroFloat(20.0f) + 15.0f;
this->actionFunc = EnNwc_HopForward;
break;
case NWC_STATE_FOLLOWING:
this->actionFunc = EnNwc_Follow;
this->transformTimer = 0;
this->randomRot = (s16)(s32)randPlusMinusPoint5Scaled(10000.0f);
break;
case NWC_STATE_RUNNING:
this->actor.world.rot.y = this->actor.home.rot.z * 0x3000 & 0xFFFF; // Fake Match?: & 0xFFFF
this->actor.shape.rot.y = this->actor.world.rot.y;
this->stateTimer = Rand_ZeroFloat(40.0f) + 120.0f;
this->actionFunc = EnNwc_RunAway;
break;
}
this->state = newState;
}
/**
* Summary: Changes the current actor state
* If previously random behavior -> check if breman mask is active
* If previously checking for breman -> select random (NWC_STATE_TURNING, NWC_STATE_HOPPING_FORWARD)
*/
void EnNwc_ToggleState(EnNwc* this) {
this->actor.speedXZ = 0.0f;
if (this->state != NWC_STATE_CHECK_BREMAN) {
EnNwc_ChangeState(this, NWC_STATE_CHECK_BREMAN);
} else {
EnNwc_ChangeState(this, Rand_ZeroFloat(2.0f) + 1.0f);
}
}
void EnNwc_CheckFound(EnNwc* this, GlobalContext* globalCtx) {
if (EnNwc_IsFound(this, globalCtx)) {
u8 currentChickCount = (this->grog->actor.home.rot.z / 2);
if (currentChickCount > 9) {
currentChickCount = 9;
}
// save our current chick order
this->actor.home.rot.z = this->grog->actor.home.rot.z + 1;
// if < 10 chicks, increment grog's chick counter
if (this->grog->actor.home.rot.z < 20) {
this->grog->actor.home.rot.z += 2;
}
EnNwc_ChangeState(this, NWC_STATE_FOLLOWING);
func_801A0868(&D_801DB4A4, NA_SE_SY_CHICK_JOIN_CHIME, currentChickCount);
}
}
void EnNwc_LoadNiwSkeleton(EnNwc* this, GlobalContext* globalCtx) {
if (Object_IsLoaded(&globalCtx->objectCtx, this->niwObjectIndex)) {
gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->niwObjectIndex].segment);
SkelAnime_InitFlex(globalCtx, &this->niwSkeleton, &gNiwSkeleton, &gNiwIdleAnim, this->jointTable,
this->morphTable, NIW_LIMB_MAX);
Animation_Change(&this->niwSkeleton, &gNiwIdleAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gNiwIdleAnim), 0, 0.0f);
gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->nwcObjectIndex].segment);
this->state = NWC_STATE_NIW_LOADED;
EnNwc_ToggleState(this);
}
}
void EnNwc_CrowAtTheEnd(EnNwc* this, GlobalContext* globalCtx) {
// I guess grog handles the scene transit?
Math_SmoothStepToS(&this->upperBodyRotY, 0x2710, 2, 0x1B58, 0x3E8);
Math_SmoothStepToS(&this->footRotZ, 0, 2, 0x1B58, 0x3E8);
Math_SmoothStepToS(&this->footRotY, 0x36B0, 2, 0x1B58, 0x3E8);
}
/**
* Summary: Controls the Chick when following Breman Mask.
*
* ActionFunc for NWC Type: NWC_STATE_FOLLOWING
*/
void EnNwc_Follow(EnNwc* this, GlobalContext* globalCtx) {
Vec3f* chickCoords = this->grog->nwcPos;
Vec3f targetVector;
s32 pad;
s16 newRotY;
this->stateTimer++;
if (this->hasGrownUp & 1) {
s16 targetUpperBodyRot = 0;
s16 targetFootRot = 0;
if (this->actor.speedXZ > 0.0f) {
if (this->stateTimer & 4) {
targetFootRot = 0x1B58;
targetUpperBodyRot = -0x2710;
}
if ((this->stateTimer & 3) == 3) {
this->actor.velocity.y = 2.0f; // hop up and down
}
}
Math_SmoothStepToS(&this->footRotZ, targetFootRot, 2, 0x1B58, 0x3E8);
Math_SmoothStepToS(&this->upperBodyRotY, targetUpperBodyRot, 2, 0x1B58, 0x3E8);
} else { // NOT grown up
if ((this->stateTimer & 3) == 3 && this->stateTimer & 20) {
this->actor.velocity.y = 2.0f; // hop up and down
}
if ((this->stateTimer & 0x1B) == 24) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG);
}
}
if (this->grog->actor.home.rot.z >= 20 && // all 10 chicks have been found
(this->hasGrownUp & 1) == false) {
this->transformTimer += 2;
if (this->transformTimer >= (s32)(s16)((this->actor.home.rot.z * 0x1E) + 0x1E)) {
// it is our turn to transform
this->hasGrownUp |= 1;
this->grog->actor.home.rot.x += 2; // increment grog's adult tranformation counter
EnNwc_SpawnDust(this, globalCtx);
Actor_SetScale(&this->actor, 0.002f);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_TO_CHICKEN);
}
}
Math_Vec3f_Diff(&chickCoords[this->actor.home.rot.z], &this->actor.world.pos, &targetVector);
if (SQXZ(targetVector) < SQ(5.0f)) { // too close to keep moving, stop
this->actor.speedXZ = 0.0f;
// first nwc in the line follows player, the rest follow the previous one
if (this->actor.home.rot.z == 1) {
newRotY = this->actor.yawTowardsPlayer;
} else {
// for some reason the array is 10 * 2, incremented by 2, so this is "index - 1"
newRotY = Math_Vec3f_Yaw(&this->actor.world.pos, &chickCoords[this->actor.home.rot.z - 2]);
}
} else { // not too close: keep moving
this->randomRot += (s16)randPlusMinusPoint5Scaled(1500.0f);
if (this->randomRot > 0x1388) {
this->randomRot = 0x1388;
} else if (this->randomRot < -0x1388) {
this->randomRot = -0x1388;
}
this->actor.speedXZ = 2.0f;
newRotY = Math_Vec3f_Yaw(&this->actor.world.pos, &chickCoords[this->actor.home.rot.z]) + this->randomRot;
}
this->actor.world.rot.y = newRotY;
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 0xBB8, 0xC8);
if (EnNwc_PlayerReleasedBremanMarch(this, globalCtx)) {
this->grog->actor.home.rot.x = 0; // reset adult count
this->grog->actor.home.rot.z = 0; // reset chick follow count
EnNwc_ChangeState(this, NWC_STATE_RUNNING);
if (this->hasGrownUp & 1) {
EnNwc_SpawnDust(this, globalCtx);
}
this->hasGrownUp &= ~1;
Actor_SetScale(&this->actor, 0.01f);
}
if (this->actor.scale.x < 0.01f) {
this->actor.scale.x += 0.002f;
Actor_SetScale(&this->actor, this->actor.scale.x);
}
if (this->grog->actor.home.rot.x >= 20) { // all chicks have turned into adult cucco, stop and crow
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M);
this->actionFunc = EnNwc_CrowAtTheEnd;
this->actor.speedXZ = 0.0f;
Actor_SetScale(&this->actor, 0.01f);
}
}
/**
* Summary: Chick is Walking (Hopping) in a straight line.
*
* ActionFunc for NWC Type: NWC_STATE_HOPPING_FORWARD
*/
void EnNwc_HopForward(EnNwc* this, GlobalContext* globalCtx) {
if (DECR(this->stateTimer) == 0) {
EnNwc_ToggleState(this);
return;
}
if ((this->stateTimer & 3) == 3) {
this->actor.velocity.y = 2.0f; // hop up and down
}
if ((this->stateTimer & 0xB) == 8) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG);
}
// they only move forward while off the ground, which gives the visual of them hopping to move
if (this->actor.bgCheckFlags & 0x1) { // touching floor
this->actor.speedXZ = 0.0f;
} else {
this->actor.speedXZ = 2.0f;
}
}
/**
* Summary: Chick is Running Away from player (Breman Mask was dropped).
*
* ActionFunc for NWC Type: NWC_STATE_RUNNING
*/
void EnNwc_RunAway(EnNwc* this, GlobalContext* globalCtx) {
if (DECR(this->stateTimer) == 0) {
EnNwc_ToggleState(this);
return;
}
if ((this->stateTimer & 3) == 3) {
this->actor.velocity.y = 2.0f; // hop up and down
}
if ((this->stateTimer & 0xB) == 8) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG);
}
this->actor.speedXZ = 2.0f;
if (this->actor.bgCheckFlags & 0x8) { // touching wall
EnNwc_ToggleState(this);
}
}
/**
* Summary: Chick is turning to face a new direction.
*
* ActionFunc for NWC Type: NWC_STATE_TURNING
*/
void EnNwc_Turn(EnNwc* this, GlobalContext* globalCtx) {
if (DECR(this->stateTimer) == 0) {
EnNwc_ToggleState(this);
return;
}
if ((this->stateTimer & 7) == 7) {
this->actor.velocity.y = 2.0f; // vertical hop
}
if ((this->stateTimer & 0xB) == 8) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG);
}
// they only rotate when off the ground, giving the visual that they turn by hopping
if (!(this->actor.bgCheckFlags & 0x1)) { // NOT touching floor
Math_SmoothStepToS(&this->actor.shape.rot.y, this->fallingRotY, 0xA, 0x1000, 0x800);
this->actor.world.rot.y = this->actor.shape.rot.y;
}
}
/**
* Summary: Chick is standing still.
* Looking around, can see the player with the Breman Mask
*
* ActionFunc for NWC Type: NWC_STATE_CHECK_BREMAN
*/
void EnNwc_CheckForBreman(EnNwc* this, GlobalContext* globalCtx) {
if (DECR(this->stateTimer) == 0) {
EnNwc_ToggleState(this);
}
EnNwc_CheckFound(this, globalCtx);
}
void EnNwc_Update(Actor* thisx, GlobalContext* globalCtx) {
EnNwc* this = THIS;
Actor_MoveWithGravity(&this->actor);
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 5);
this->actionFunc(this, globalCtx);
if (this->hasGrownUp & 1) {
this->actor.objBankIndex = this->niwObjectIndex;
this->actor.draw = EnNwc_DrawAdultBody;
this->actor.shape.shadowScale = 15.0f;
} else {
this->actor.objBankIndex = this->nwcObjectIndex;
this->actor.draw = EnNwc_Draw;
this->actor.shape.shadowScale = 6.0f;
}
if (DECR(this->blinkTimer) == 0) {
this->blinkTimer = Rand_S16Offset(0x3C, 0x3C);
}
if (this->blinkTimer == 1 || this->blinkTimer == 3) {
this->blinkState = true;
} else {
this->blinkState = false;
}
}
void EnNwc_Draw(Actor* thisx, GlobalContext* globalCtx) {
TexturePtr eyeTextures[] = { gNwcEyeOpenTex, gNwcEyeClosedTex };
EnNwc* this = THIS;
Gfx* dispHead;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_8012C28C(globalCtx->state.gfxCtx);
dispHead = POLY_OPA_DISP;
gSPSegment(&dispHead[0], 0x08, Lib_SegmentedToVirtual(eyeTextures[this->blinkState]));
gSPMatrix(&dispHead[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(&dispHead[2], &gNwcBodyDL);
POLY_OPA_DISP = &dispHead[3];
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
s32 EnNwc_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
EnNwc* this = THIS;
if (limbIndex == NIW_LIMB_UPPER_BODY) {
rot->y += this->upperBodyRotY;
}
if (limbIndex == NIW_LIMB_RIGHT_WING_ROOT || limbIndex == NIW_LIMB_LEFT_WING_ROOT) {
rot->y += this->footRotY;
rot->z += this->footRotZ;
}
return false;
}
void EnNwc_DrawAdultBody(Actor* thisx, GlobalContext* globalCtx) {
EnNwc* this = THIS;
func_8012C28C(globalCtx->state.gfxCtx);
SkelAnime_DrawFlexOpa(globalCtx, this->niwSkeleton.skeleton, this->niwSkeleton.jointTable,
this->niwSkeleton.dListCount, EnNwc_OverrideLimbDraw, NULL, &this->actor);
}

View File

@ -2,15 +2,37 @@
#define Z_EN_NWC_H
#include "global.h"
#include "objects/object_niw/object_niw.h"
#include "overlays/actors/ovl_En_Hs/z_en_hs.h" // grog
struct EnNwc;
typedef void (*EnNwcActionFunc)(struct EnNwc*, GlobalContext*);
typedef struct EnNwc {
/* 0x0000 */ Actor actor;
/* 0x0144 */ char unk_144[0x120];
/* 0x0264 */ EnNwcActionFunc actionFunc;
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime niwSkeleton; // this skeleton is for when the chicks grow up into adults during the breman march
/* 0x188 */ Vec3s jointTable[NIW_LIMB_MAX];
/* 0x1E8 */ Vec3s morphTable[NIW_LIMB_MAX];
/* 0x248 */ s8 niwObjectIndex;
/* 0x249 */ s8 nwcObjectIndex;
/* 0x24A */ s16 blinkState;
/* 0x24C */ s16 blinkTimer;
/* 0x250 */ EnHs* grog;
/* 0x254 */ s16 stateTimer; // count frames to next state change
/* 0x256 */ union {
s16 mixedValue256; // default name for reset
s16 transformTimer; // frames since transformation sequence started
s16 fallingRotY; // target rotation if off the ground in state 1
};
/* 0x258 */ s16 randomRot;
/* 0x25A */ s16 state;
/* 0x25C */ u16 hasGrownUp; // treated as both a boolean and a flag variable (0x1)
/* 0x25E */ s16 footRotY;
/* 0x260 */ s16 footRotZ;
/* 0x262 */ s16 upperBodyRotY;
/* 0x264 */ EnNwcActionFunc actionFunc;
} EnNwc; // size = 0x268
extern const ActorInit En_Nwc_InitVars;

View File

@ -5424,9 +5424,9 @@
0x808908D0:("func_808908D0",),
0x80891060:("EnNiw_Init",),
0x808912E8:("EnNiw_Destroy",),
0x80891320:("func_80891320",),
0x80891320:("EnNiw_AnimateWingHead",),
0x808916B0:("EnNiw_SpawnAttackNiw",),
0x808917F8:("func_808917F8",),
0x808917F8:("EnNiw_UpdateRunning",),
0x80891974:("EnNiw_SetupIdle",),
0x808919E8:("EnNiw_Idle",),
0x80891D78:("EnNiw_Held",),
@ -7514,24 +7514,24 @@
0x80943EE4:("EnDaiku_Draw",),
0x809441E0:("EnNwc_Init",),
0x80944310:("EnNwc_Destroy",),
0x80944320:("func_80944320",),
0x80944554:("func_80944554",),
0x80944590:("func_80944590",),
0x809445D4:("func_809445D4",),
0x80944630:("func_80944630",),
0x809447A8:("func_809447A8",),
0x80944818:("func_80944818",),
0x809448A4:("func_809448A4",),
0x809449D0:("func_809449D0",),
0x80944A50:("func_80944A50",),
0x80944E44:("func_80944E44",),
0x80944EFC:("func_80944EFC",),
0x80944FA8:("func_80944FA8",),
0x8094506C:("func_8094506C",),
0x80944320:("EnNwc_SpawnDust",),
0x80944554:("EnNwc_FindGrog",),
0x80944590:("EnNwc_PlayerReleasedBremanMarch",),
0x809445D4:("EnNwc_IsFound",),
0x80944630:("EnNwc_ChangeState",),
0x809447A8:("EnNwc_ToggleState",),
0x80944818:("EnNwc_CheckFound",),
0x809448A4:("EnNwc_LoadNiwSkeleton",),
0x809449D0:("EnNwc_CrowAtTheEnd",),
0x80944A50:("EnNwc_Follow",),
0x80944E44:("EnNwc_HopForward",),
0x80944EFC:("EnNwc_RunAway",),
0x80944FA8:("EnNwc_Turn",),
0x8094506C:("EnNwc_CheckForBreman",),
0x809450C0:("EnNwc_Update",),
0x809451D8:("EnNwc_Draw",),
0x8094529C:("func_8094529C",),
0x80945310:("func_80945310",),
0x8094529C:("EnNwc_OverrideLimbDraw",),
0x80945310:("EnNwc_DrawAdultBody",),
0x809454F0:("ItemInbox_Init",),
0x80945524:("ItemInbox_Destroy",),
0x80945534:("ItemInbox_Idle",),
@ -7641,13 +7641,13 @@
0x80952CC8:("EnHs_Init",),
0x80952DD0:("EnHs_Destroy",),
0x80952DFC:("func_80952DFC",),
0x80952E50:("func_80952E50",),
0x80952E50:("EnHs_UpdateChickPos",),
0x80952F00:("func_80952F00",),
0x80952FE0:("func_80952FE0",),
0x80953098:("func_80953098",),
0x80953180:("func_80953180",),
0x809532C0:("func_809532C0",),
0x809532D0:("func_809532D0",),
0x809532C0:("EnHs_DoNothing",),
0x809532D0:("EnHs_SceneTransitToBunnyHoodDialogue",),
0x80953354:("func_80953354",),
0x809533A0:("func_809533A0",),
0x8095345C:("func_8095345C",),
@ -7680,11 +7680,11 @@
0x80956954:("EnKanban_Draw",),
0x809580C0:("EnAttackNiw_Init",),
0x809581F4:("EnAttackNiw_Destroy",),
0x80958228:("func_80958228",),
0x809585B0:("func_809585B0",),
0x80958634:("func_80958634",),
0x80958974:("func_80958974",),
0x80958BE4:("func_80958BE4",),
0x80958228:("EnAttackNiw_AnimateWingHead",),
0x809585B0:("EnAttackNiw_IsOnScreen",),
0x80958634:("EnAttackNiw_EnterViewFromOffscreen",),
0x80958974:("EnAttackNiw_AimAtPlayer",),
0x80958BE4:("EnAttackNiw_FlyAway",),
0x80958CA8:("EnAttackNiw_Update",),
0x80958F6C:("EnAttackNiw_OverrideLimbDraw",),
0x8095909C:("EnAttackNiw_Draw",),