ovl_Bg_Dy_Yoseizo and related docs (#1390)

* Add ido setting to permuter

* OK

* Data imported & named, change spec

* Some easy naming

* Cleanup

* More object stuff and enums

* Document EnDyExtra

* Document DemoGetitem

* Document DemoEffect

* Some work on Elforg

* Elforg params macro, some more on Elfgrp

* Defines for number of fairies

* Tweak some flags wording

* Label beam

* Elfgrp: Name most of the stray fairy handling stuff

* cleanup

* fix typo

* GreatFairyAnimation

* name animations

* BgDyYoseizo_TrainPlayer

* Choose behaviour?

* fix merge

* format

* self review

* WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK

* jenkins

* review

* Update src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c

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

* review

* Update src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c

Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>

* Update src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c

Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>

* Update src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c

Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>

* Update src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c

* review

---------

Co-authored-by: Elliptic Ellipsis <elliptic.ellipsis@gmail.com>
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
This commit is contained in:
Anghelo Carvajal 2023-10-03 18:13:22 -03:00 committed by GitHub
parent f6a2f4492a
commit f08a69a2cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1467 additions and 635 deletions

View File

@ -1,51 +1,62 @@
<Root>
<!-- Great Fairy assets -->
<File Name="object_dy_obj" Segment="6">
<Animation Name="object_dy_obj_Anim_00129C" Offset="0x129C" /> <!-- Original name is "be_mahoukousi" -->
<Animation Name="object_dy_obj_Anim_002338" Offset="0x2338" /> <!-- Original name is "be_mahoukousi_loop" -->
<Animation Name="object_dy_obj_Anim_0027B0" Offset="0x27B0" /> <!-- Original name is "be_syutugen" -->
<Animation Name="object_dy_obj_Anim_0045FC" Offset="0x45FC" /> <!-- Original name is "be_utubuse" -->
<Animation Name="object_dy_obj_Anim_005238" Offset="0x5238" /> <!-- Original name is "be_utubuse_loop" -->
<Animation Name="object_dy_obj_Anim_005E20" Offset="0x5E20" /> <!-- Original name is "bigelf_denjyu" -->
<Animation Name="object_dy_obj_Anim_006DE4" Offset="0x6DE4" /> <!-- Original name is "bigelf_hakusyu" -->
<Animation Name="object_dy_obj_Anim_008090" Offset="0x8090" /> <!-- Original name is "bigelf_itemdasu" -->
<Animation Name="object_dy_obj_Anim_00C500" Offset="0xC500" /> <!-- Original name is "bigelf_syutugen" -->
<Animation Name="object_dy_obj_Anim_00D15C" Offset="0xD15C" /> <!-- Original name is "bigelf_udegumi" -->
<DList Name="object_dy_obj_DL_00D1B0" Offset="0xD1B0" />
<DList Name="object_dy_obj_DL_00D228" Offset="0xD228" />
<Texture Name="object_dy_obj_Tex_00D240" OutName="tex_00D240" Format="i4" Width="32" Height="32" Offset="0xD240" />
<Texture Name="object_dy_obj_Tex_00D440" OutName="tex_00D440" Format="i8" Width="16" Height="16" Offset="0xD440" />
<Texture Name="object_dy_obj_Tex_00D540" OutName="tex_00D540" Format="i8" Width="32" Height="64" Offset="0xD540" />
<Array Name="object_dy_obj_Vtx_00DD40" Count="27" Offset="0xDD40">
<!-- Great Fairy animations -->
<Animation Name="gGreatFairyStartGivingUpgradeAnim" Offset="0x129C" /> <!-- Original name is "be_mahoukousi" -->
<Animation Name="gGreatFairyGivingUpgradeAnim" Offset="0x2338" /> <!-- Original name is "be_mahoukousi_loop" -->
<Animation Name="gGreatFairyAnim_0027B0" Offset="0x27B0" /> <!-- Original name is "be_syutugen" --> <!-- unused -->
<Animation Name="gGreatFairyLayDownTransitionAnim" Offset="0x45FC" /> <!-- Original name is "be_utubuse" -->
<Animation Name="gGreatFairyLayingDownAnim" Offset="0x5238" /> <!-- Original name is "be_utubuse_loop" -->
<Animation Name="gGreatFairyTeachSpinAttackAnim" Offset="0x5E20" /> <!-- Original name is "bigelf_denjyu" ("instruction") -->
<Animation Name="gGreatFairyClappingAnim" Offset="0x6DE4" /> <!-- Original name is "bigelf_hakusyu" ("applause") -->
<Animation Name="gGreatFairyShowingItemAnim" Offset="0x8090" /> <!-- Original name is "bigelf_itemdasu" -->
<Animation Name="gGreatFairySpinLayDownAnim" Offset="0xC500" /> <!-- Original name is "bigelf_syutugen" -->
<Animation Name="gGreatFairyArmsFoldedAnim" Offset="0xD15C" /> <!-- Original name is "bigelf_udegumi" ("arms crossed") -->
<!-- Great Fairy particles -->
<DList Name="gGreatFairyParticleSetupDL" Offset="0xD1B0" />
<DList Name="gGreatFairyParticleDL" Offset="0xD228" />
<Texture Name="gGreatFairyParticleTex" OutName="great_fairy_particle" Format="i4" Width="32" Height="32" Offset="0xD240" />
<!-- Great Fairy spiral beam -->
<Texture Name="gGreatFairySpiralBeamPatternTex" OutName="spiral_beam_pattern" Format="i8" Width="16" Height="16" Offset="0xD440" />
<Texture Name="gGreatFairySpiralBeamGradientTex" OutName="spiral_beam_gradient" Format="i8" Width="32" Height="64" Offset="0xD540" />
<Array Name="gGreatFairySpiralBeamVtx" Count="27" Offset="0xDD40">
<Vtx/>
</Array>
<DList Name="object_dy_obj_DL_00DEF0" Offset="0xDEF0" /> <!-- Original name is "efc_g_fairly_modelT" -->
<DList Name="object_dy_obj_DL_013810" Offset="0x13810" />
<DList Name="object_dy_obj_DL_013928" Offset="0x13928" />
<DList Name="object_dy_obj_DL_013CF8" Offset="0x13CF8" />
<DList Name="object_dy_obj_DL_0142E0" Offset="0x142E0" />
<DList Name="object_dy_obj_DL_0143F0" Offset="0x143F0" />
<DList Name="object_dy_obj_DL_014578" Offset="0x14578" />
<DList Name="object_dy_obj_DL_014670" Offset="0x14670" />
<DList Name="object_dy_obj_DL_014760" Offset="0x14760" />
<DList Name="object_dy_obj_DL_014908" Offset="0x14908" />
<DList Name="object_dy_obj_DL_014A00" Offset="0x14A00" />
<DList Name="object_dy_obj_DL_014B88" Offset="0x14B88" />
<DList Name="object_dy_obj_DL_014C78" Offset="0x14C78" />
<DList Name="object_dy_obj_DL_014E08" Offset="0x14E08" />
<DList Name="object_dy_obj_DL_014F08" Offset="0x14F08" />
<DList Name="object_dy_obj_DL_015008" Offset="0x15008" />
<DList Name="object_dy_obj_DL_0150F8" Offset="0x150F8" />
<DList Name="object_dy_obj_DL_015220" Offset="0x15220" />
<DList Name="object_dy_obj_DL_0153B8" Offset="0x153B8" />
<DList Name="object_dy_obj_DL_015598" Offset="0x15598" />
<DList Name="object_dy_obj_DL_0156C0" Offset="0x156C0" />
<DList Name="object_dy_obj_DL_0158E8" Offset="0x158E8" />
<DList Name="object_dy_obj_DL_015AC8" Offset="0x15AC8" />
<DList Name="object_dy_obj_DL_015E88" Offset="0x15E88" />
<DList Name="object_dy_obj_DL_015FE8" Offset="0x15FE8" />
<DList Name="object_dy_obj_DL_0160F8" Offset="0x160F8" />
<DList Name="object_dy_obj_DL_016360" Offset="0x16360" />
<DList Name="object_dy_obj_DL_0164B8" Offset="0x164B8" />
<DList Name="gGreatFairySpiralBeamDL" Offset="0xDEF0" /> <!-- Original name is "efc_g_fairly_modelT" -->
<!-- Great Fairy model -->
<!-- Displaylists -->
<DList Name="gGreatFairyWaistDL" Offset="0x13810" />
<DList Name="gGreatFairyTorsoDL" Offset="0x13928" />
<DList Name="gGreatFairyHeadDL" Offset="0x13CF8" />
<DList Name="gGreatFairyRightHairLowerPartDL" Offset="0x142E0" />
<DList Name="gGreatFairyRightHairMiddlePartDL" Offset="0x143F0" />
<DList Name="gGreatFairyRightHairUpperPartDL" Offset="0x14578" />
<DList Name="gGreatFairyRightHairTipDL" Offset="0x14670" />
<DList Name="gGreatFairyLeftHairLowerPartDL" Offset="0x14760" />
<DList Name="gGreatFairyLeftHairMiddlePartDL" Offset="0x14908" />
<DList Name="gGreatFairyLeftHairUpperPartDL" Offset="0x14A00" />
<DList Name="gGreatFairyLeftHairTipDL" Offset="0x14B88" />
<DList Name="gGreatFairyMiddleHairLowerPartDL" Offset="0x14C78" />
<DList Name="gGreatFairyMiddleHairMiddlePartDL" Offset="0x14E08" />
<DList Name="gGreatFairyMiddleHairUpperPartDL" Offset="0x14F08" />
<DList Name="gGreatFairyMiddleHairTipDL" Offset="0x15008" />
<DList Name="gGreatFairyRightUpperArmDL" Offset="0x150F8" />
<DList Name="gGreatFairyRightForearmDL" Offset="0x15220" />
<DList Name="gGreatFairyRightHandDL" Offset="0x153B8" />
<DList Name="gGreatFairyLeftUpperArmDL" Offset="0x15598" />
<DList Name="gGreatFairyLeftForearmDL" Offset="0x156C0" />
<DList Name="gGreatFairyLeftHandDL" Offset="0x158E8" />
<DList Name="gGreatFairyRightThighDL" Offset="0x15AC8" />
<DList Name="gGreatFairyRightLowerLegDL" Offset="0x15E88" />
<DList Name="gGreatFairyRightFoot" Offset="0x15FE8" />
<DList Name="gGreatFairyLeftThighDL" Offset="0x160F8" />
<DList Name="gGreatFairyLeftLowerLegDL" Offset="0x16360" />
<DList Name="gGreatFairyLeftFootDL" Offset="0x164B8" />
<!-- Textures -->
<Texture Name="object_dy_obj_TLUT_0165C8" OutName="tlut_0165C8" Format="rgba16" Width="16" Height="16" Offset="0x165C8" />
<Texture Name="object_dy_obj_Tex_0167C8" OutName="tex_0167C8" Format="ci8" Width="8" Height="8" Offset="0x167C8" />
<Texture Name="object_dy_obj_Tex_016808" OutName="tex_016808" Format="ci8" Width="8" Height="8" Offset="0x16808" />
@ -55,42 +66,46 @@
<Texture Name="object_dy_obj_Tex_017488" OutName="tex_017488" Format="ci8" Width="32" Height="32" Offset="0x17488" />
<Texture Name="object_dy_obj_Tex_017888" OutName="tex_017888" Format="ci8" Width="16" Height="16" Offset="0x17888" />
<Texture Name="object_dy_obj_Tex_017988" OutName="tex_017988" Format="rgba16" Width="32" Height="16" Offset="0x17988" />
<Texture Name="object_dy_obj_Tex_017D88" OutName="tex_017D88" Format="rgba16" Width="32" Height="32" Offset="0x17D88" />
<Texture Name="object_dy_obj_Tex_018588" OutName="tex_018588" Format="rgba16" Width="32" Height="32" Offset="0x18588" />
<Texture Name="object_dy_obj_Tex_018D88" OutName="tex_018D88" Format="rgba16" Width="32" Height="32" Offset="0x18D88" />
<Texture Name="object_dy_obj_Tex_019588" OutName="tex_019588" Format="rgba16" Width="32" Height="32" Offset="0x19588" />
<Texture Name="object_dy_obj_Tex_019D88" OutName="tex_019D88" Format="rgba16" Width="32" Height="32" Offset="0x19D88" />
<Texture Name="object_dy_obj_Tex_01A588" OutName="tex_01A588" Format="rgba16" Width="64" Height="32" Offset="0x1A588" />
<Texture Name="object_dy_obj_Tex_01B588" OutName="tex_01B588" Format="rgba16" Width="64" Height="32" Offset="0x1B588" />
<Texture Name="gGreatFairyMouthClosedTex" OutName="great_fairy_mouth_closed" Format="rgba16" Width="64" Height="32" Offset="0x1A588" />
<Texture Name="gGreatFairyMouthOpenTex" OutName="great_fairy_mouth_open" Format="rgba16" Width="64" Height="32" Offset="0x1B588" />
<Texture Name="object_dy_obj_Tex_01C588" OutName="tex_01C588" Format="i8" Width="16" Height="16" Offset="0x1C588" />
<TextureAnimation Name="object_dy_obj_Matanimheader_01C6F4" Offset="0x1C6F4" />
<Limb Name="object_dy_obj_Standardlimb_01C704" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_01" Offset="0x1C704" />
<Limb Name="object_dy_obj_Standardlimb_01C710" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_02" Offset="0x1C710" />
<Limb Name="object_dy_obj_Standardlimb_01C71C" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_03" Offset="0x1C71C" />
<Limb Name="object_dy_obj_Standardlimb_01C728" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_04" Offset="0x1C728" />
<Limb Name="object_dy_obj_Standardlimb_01C734" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_05" Offset="0x1C734" />
<Limb Name="object_dy_obj_Standardlimb_01C740" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_06" Offset="0x1C740" />
<Limb Name="object_dy_obj_Standardlimb_01C74C" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_07" Offset="0x1C74C" />
<Limb Name="object_dy_obj_Standardlimb_01C758" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_08" Offset="0x1C758" />
<Limb Name="object_dy_obj_Standardlimb_01C764" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_09" Offset="0x1C764" />
<Limb Name="object_dy_obj_Standardlimb_01C770" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_0A" Offset="0x1C770" />
<Limb Name="object_dy_obj_Standardlimb_01C77C" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_0B" Offset="0x1C77C" />
<Limb Name="object_dy_obj_Standardlimb_01C788" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_0C" Offset="0x1C788" />
<Limb Name="object_dy_obj_Standardlimb_01C794" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_0D" Offset="0x1C794" />
<Limb Name="object_dy_obj_Standardlimb_01C7A0" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_0E" Offset="0x1C7A0" />
<Limb Name="object_dy_obj_Standardlimb_01C7AC" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_0F" Offset="0x1C7AC" />
<Limb Name="object_dy_obj_Standardlimb_01C7B8" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_10" Offset="0x1C7B8" />
<Limb Name="object_dy_obj_Standardlimb_01C7C4" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_11" Offset="0x1C7C4" />
<Limb Name="object_dy_obj_Standardlimb_01C7D0" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_12" Offset="0x1C7D0" />
<Limb Name="object_dy_obj_Standardlimb_01C7DC" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_13" Offset="0x1C7DC" />
<Limb Name="object_dy_obj_Standardlimb_01C7E8" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_14" Offset="0x1C7E8" />
<Limb Name="object_dy_obj_Standardlimb_01C7F4" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_15" Offset="0x1C7F4" />
<Limb Name="object_dy_obj_Standardlimb_01C800" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_16" Offset="0x1C800" />
<Limb Name="object_dy_obj_Standardlimb_01C80C" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_17" Offset="0x1C80C" />
<Limb Name="object_dy_obj_Standardlimb_01C818" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_18" Offset="0x1C818" />
<Limb Name="object_dy_obj_Standardlimb_01C824" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_19" Offset="0x1C824" />
<Limb Name="object_dy_obj_Standardlimb_01C830" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_1A" Offset="0x1C830" />
<Limb Name="object_dy_obj_Standardlimb_01C83C" Type="Standard" EnumName="OBJECT_DY_OBJ_LIMB_1B" Offset="0x1C83C" />
<Skeleton Name="object_dy_obj_Skel_01C8B4" Type="Flex" LimbType="Standard" LimbNone="OBJECT_DY_OBJ_LIMB_NONE" LimbMax="OBJECT_DY_OBJ_LIMB_MAX" EnumName="ObjectDyObjLimb" Offset="0x1C8B4" />
<TextureAnimation Name="gGreatFairyAppearenceTexAnim" Offset="0x1C6F4" />
<!-- Great Fairy Skeleton -->
<Limb Name="gGreatFairyWaistLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_WAIST" Offset="0x1C704" />
<Limb Name="gGreatFairyLeftThighLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_THIGH" Offset="0x1C710" />
<Limb Name="gGreatFairyLeftLowerLegLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_LOWER_LEG" Offset="0x1C71C" />
<Limb Name="gGreatFairyLeftFootLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_FOOT" Offset="0x1C728" />
<Limb Name="gGreatFairyRightThighLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_THIGH" Offset="0x1C734" />
<Limb Name="gGreatFairyRightLowerLegLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_LOWER_LEG" Offset="0x1C740" />
<Limb Name="gGreatFairyRightFootLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_FOOT" Offset="0x1C74C" />
<Limb Name="gGreatFairyTorsoLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_TORSO" Offset="0x1C758" />
<Limb Name="gGreatFairyLeftUpperArmLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_UPPER_ARM" Offset="0x1C764" />
<Limb Name="gGreatFairyLeftForearmLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_FOREARM" Offset="0x1C770" />
<Limb Name="gGreatFairyLeftHandLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_HAND" Offset="0x1C77C" />
<Limb Name="gGreatFairyRightUpperArmLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_UPPER_ARM" Offset="0x1C788" />
<Limb Name="gGreatFairyRightForearmLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_FOREARM" Offset="0x1C794" />
<Limb Name="gGreatFairyRightHandLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_HAND" Offset="0x1C7A0" />
<Limb Name="gGreatFairyHeadLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_HEAD" Offset="0x1C7AC" />
<Limb Name="gGreatFairyMiddleHairLowerPartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_MIDDLE_HAIR_LOWER_PART" Offset="0x1C7B8" />
<Limb Name="gGreatFairyMiddleHairMiddlePartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_MIDDLE_HAIR_MIDDLE_PART" Offset="0x1C7C4" />
<Limb Name="gGreatFairyMiddleHairUpperPartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_MIDDLE_HAIR_UPPER_PART" Offset="0x1C7D0" />
<Limb Name="gGreatFairyMiddleHairTipLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_MIDDLE_HAIR_TIP" Offset="0x1C7DC" />
<Limb Name="gGreatFairyLeftHairLowerPartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_HAIR_LOWER_PART" Offset="0x1C7E8" />
<Limb Name="gGreatFairyLeftHairMiddlePartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_HAIR_MIDDLE_PART" Offset="0x1C7F4" />
<Limb Name="gGreatFairyLeftHairUpperPartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_HAIR_UPPER_PART" Offset="0x1C800" />
<Limb Name="gGreatFairyLeftHairTipLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_LEFT_HAIR_TIP" Offset="0x1C80C" />
<Limb Name="gGreatFairyRightHairLowerPartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_HAIR_LOWER_PART" Offset="0x1C818" />
<Limb Name="gGreatFairyRightHairMiddlePartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_HAIR_MIDDLE_PART" Offset="0x1C824" />
<Limb Name="gGreatFairyRightHairUpperPartLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_HAIR_UPPER_PART" Offset="0x1C830" />
<Limb Name="gGreatFairyRightHairTipLimb" Type="Standard" EnumName="GREAT_FAIRY_LIMB_RIGHT_HAIR_TIP" Offset="0x1C83C" />
<Skeleton Name="gGreatFairySkel" Type="Flex" LimbType="Standard" LimbNone="GREAT_FAIRY_LIMB_NONE" LimbMax="GREAT_FAIRY_LIMB_MAX" EnumName="GreatFairyLimb" Offset="0x1C8B4" />
</File>
</Root>

View File

@ -1,13 +1,16 @@
<Root>
<File Name="object_efc_tw" Segment="6">
<CurveAnimation Name="object_efc_tw_CurveAnim_000050" SkelOffset="0x12E8" Offset="0x50" />
<Array Name="object_efc_tw_Vtx_000060" Count="21" Offset="0x60" >
<CurveAnimation Name="gTimewarpAnim" SkelOffset="0x12E8" Offset="0x50" />
<Array Name="gTimewarpVtx" Count="21" Offset="0x60" >
<Vtx/>
</Array>
<DList Name="object_efc_tw_DL_0001B0" Offset="0x1B0" /> <!-- Original name is "top_fc_mdl" -->
<Texture Name="object_efc_tw_Tex_0002C8" OutName="tex_0002C8" Format="i8" Width="64" Height="64" Offset="0x2C8" />
<Limb Name="object_efc_tw_Curvelimb_0012C8" Type="Curve" EnumName="OBJECT_EFC_TW_LIMB_01" Offset="0x12C8" />
<Limb Name="object_efc_tw_Curvelimb_0012D4" Type="Curve" EnumName="OBJECT_EFC_TW_LIMB_02" Offset="0x12D4" />
<Skeleton Name="object_efc_tw_Skel_0012E8" Type="Curve" LimbType="Curve" LimbNone="OBJECT_EFC_TW_LIMB_NONE" LimbMax="OBJECT_EFC_TW_LIMB_MAX" EnumName="ObjectEfcTwLimb" Offset="0x12E8" />
<DList Name="gTimewarpDL" Offset="0x1B0" /> <!-- Original name is "top_fc_mdl" -->
<Texture Name="gTimewarpTex" OutName="timewarp" Format="i8" Width="64" Height="64" Offset="0x2C8" />
<Limb Name="gTimewarp1Limb" Type="Curve" EnumName="TIMEWARP_LIMB_1" Offset="0x12C8" />
<Limb Name="gTimewarp2Limb" Type="Curve" EnumName="TIMEWARP_LIMB_2" Offset="0x12D4" />
<Skeleton Name="gTimewarpSkel" Type="Curve" LimbType="Curve" LimbNone="TIMEWARP_LIMB_NONE" LimbMax="TIMEWARP_LIMB_MAX" EnumName="TimewarpLimb" Offset="0x12E8" />
</File>
</Root>

View File

@ -650,11 +650,14 @@ typedef enum {
#define WEEKEVENTREG_CLOCK_TOWER_OPENED PACK_WEEKEVENTREG_FLAG(8, 0x40)
#define WEEKEVENTREG_08_80 PACK_WEEKEVENTREG_FLAG(8, 0x80)
// This 5 flags are managed in a special way by EnElfgrp
#define WEEKEVENTREG_09_01 PACK_WEEKEVENTREG_FLAG(9, 0x01)
#define WEEKEVENTREG_09_02 PACK_WEEKEVENTREG_FLAG(9, 0x02)
#define WEEKEVENTREG_09_04 PACK_WEEKEVENTREG_FLAG(9, 0x04)
#define WEEKEVENTREG_09_08 PACK_WEEKEVENTREG_FLAG(9, 0x08)
#define WEEKEVENTREG_09_10 PACK_WEEKEVENTREG_FLAG(9, 0x10)
#define WEEKEVENTREG_09_20 PACK_WEEKEVENTREG_FLAG(9, 0x20)
#define WEEKEVENTREG_09_40 PACK_WEEKEVENTREG_FLAG(9, 0x40)
#define WEEKEVENTREG_09_80 PACK_WEEKEVENTREG_FLAG(9, 0x80)
@ -795,7 +798,7 @@ typedef enum {
#define WEEKEVENTREG_22_40 PACK_WEEKEVENTREG_FLAG(22, 0x40)
#define WEEKEVENTREG_22_80 PACK_WEEKEVENTREG_FLAG(22, 0x80)
#define WEEKEVENTREG_23_01 PACK_WEEKEVENTREG_FLAG(23, 0x01)
#define WEEKEVENTREG_23_02 PACK_WEEKEVENTREG_FLAG(23, 0x02)
#define WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK PACK_WEEKEVENTREG_FLAG(23, 0x02)
#define WEEKEVENTREG_23_04 PACK_WEEKEVENTREG_FLAG(23, 0x04)
#define WEEKEVENTREG_23_08 PACK_WEEKEVENTREG_FLAG(23, 0x08)
#define WEEKEVENTREG_23_10 PACK_WEEKEVENTREG_FLAG(23, 0x10)
@ -1631,6 +1634,9 @@ typedef enum {
/* 3 */ DUNGEON_INDEX_STONE_TOWER_TEMPLE // Also applies to Inverted Stone Tower Temple
} DungeonIndex;
#define STRAY_FAIRY_TOTAL 25 // total number of stray fairies, including those already in the Great Fairy Fountain
#define STRAY_FAIRY_SCATTERED_TOTAL 15 // original number of stray fairies in one dungeon area
void Sram_ActivateOwl(u8 owlId);
void Sram_ClearFlagsAtDawnOfTheFirstDay(void);
void Sram_SaveEndOfCycle(struct PlayState* play);

3
spec
View File

@ -2365,8 +2365,7 @@ beginseg
name "ovl_Bg_Dy_Yoseizo"
compress
include "build/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.o"
include "build/data/ovl_Bg_Dy_Yoseizo/ovl_Bg_Dy_Yoseizo.data.o"
include "build/data/ovl_Bg_Dy_Yoseizo/ovl_Bg_Dy_Yoseizo.reloc.o"
include "build/src/overlays/actors/ovl_Bg_Dy_Yoseizo/ovl_Bg_Dy_Yoseizo_reloc.o"
endseg
beginseg

View File

@ -725,7 +725,7 @@ void Target_Update(TargetContext* targetCtx, Player* player, Actor* lockOnActor,
/* Start of Flags section */
/**
* Tests if current scene switch flag is set.
* Tests if a current scene switch flag is set.
*/
s32 Flags_GetSwitch(PlayState* play, s32 flag) {
if ((flag >= 0) && (flag < 0x80)) {
@ -735,7 +735,7 @@ s32 Flags_GetSwitch(PlayState* play, s32 flag) {
}
/**
* Sets current scene switch flag.
* Sets a current scene switch flag.
*/
void Flags_SetSwitch(PlayState* play, s32 flag) {
if ((flag >= 0) && (flag < 0x80)) {
@ -744,7 +744,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) {
}
/**
* Unsets current scene switch flag.
* Unsets a current scene switch flag.
*/
void Flags_UnsetSwitch(PlayState* play, s32 flag) {
if ((flag >= 0) && (flag < 0x80)) {
@ -753,77 +753,77 @@ void Flags_UnsetSwitch(PlayState* play, s32 flag) {
}
/**
* Tests if current scene chest flag is set.
* Tests if a current scene chest flag is set.
*/
s32 Flags_GetTreasure(PlayState* play, s32 flag) {
return play->actorCtx.sceneFlags.chest & (1 << flag);
}
/**
* Sets current scene chest flag.
* Sets a current scene chest flag.
*/
void Flags_SetTreasure(PlayState* play, s32 flag) {
play->actorCtx.sceneFlags.chest |= (1 << flag);
}
/**
* Overrides the all the chest flags.
* Overrides all the current scene chest flags.
*/
void Flags_SetAllTreasure(PlayState* play, s32 flag) {
play->actorCtx.sceneFlags.chest = flag;
}
/**
* Returns all the chest flags.
* Returns all the current scene chest flags.
*/
s32 Flags_GetAllTreasure(PlayState* play) {
return play->actorCtx.sceneFlags.chest;
}
/**
* Tests if current scene clear flag is set.
* Tests if a current scene clear flag is set.
*/
s32 Flags_GetClear(PlayState* play, s32 roomNumber) {
return play->actorCtx.sceneFlags.clearedRoom & (1 << roomNumber);
}
/**
* Sets current scene clear flag.
* Sets a current scene clear flag.
*/
void Flags_SetClear(PlayState* play, s32 roomNumber) {
play->actorCtx.sceneFlags.clearedRoom |= (1 << roomNumber);
}
/**
* Unsets current scene clear flag.
* Unsets a current scene clear flag.
*/
void Flags_UnsetClear(PlayState* play, s32 roomNumber) {
play->actorCtx.sceneFlags.clearedRoom &= ~(1 << roomNumber);
}
/**
* Tests if current scene temp clear flag is set.
* Tests if a current scene temp clear flag is set.
*/
s32 Flags_GetClearTemp(PlayState* play, s32 roomNumber) {
return play->actorCtx.sceneFlags.clearedRoomTemp & (1 << roomNumber);
}
/**
* Sets current scene temp clear flag.
* Sets a current scene temp clear flag.
*/
void Flags_SetClearTemp(PlayState* play, s32 roomNumber) {
play->actorCtx.sceneFlags.clearedRoomTemp |= (1 << roomNumber);
}
/**
* Unsets current scene temp clear flag.
* Unsets a current scene temp clear flag.
*/
void Flags_UnsetClearTemp(PlayState* play, s32 roomNumber) {
play->actorCtx.sceneFlags.clearedRoomTemp &= ~(1 << roomNumber);
}
/**
* Tests if current scene collectible flag is set.
* Tests if a current scene collectible flag is set.
*/
s32 Flags_GetCollectible(PlayState* play, s32 flag) {
if ((flag > 0) && (flag < 0x80)) {
@ -833,7 +833,7 @@ s32 Flags_GetCollectible(PlayState* play, s32 flag) {
}
/**
* Sets current scene collectible flag.
* Sets a current scene collectible flag.
*/
void Flags_SetCollectible(PlayState* play, s32 flag) {
if ((flag > 0) && (flag < 0x80)) {

View File

@ -1,4 +1,5 @@
#include "global.h"
#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_gi_hearts/object_gi_hearts.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
@ -935,9 +936,9 @@ Actor* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, u32 params) {
SoundSource_PlaySfxAtFixedWorldPos(play, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);
}
} else {
spawnedActor =
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0,
0, STRAY_FAIRY_PARAMS(((param7F00 >> 8) & 0x7F), 0, STRAY_FAIRY_TYPE_COLLECTIBLE));
spawnedActor = Actor_Spawn(
&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0,
STRAY_FAIRY_PARAMS((param7F00 >> 8) & 0x7F, STRAY_FAIRY_AREA_CLOCK_TOWN, STRAY_FAIRY_TYPE_COLLECTIBLE));
if (param20000 == 0) {
if (!Flags_GetCollectible(play, (param7F00 >> 8) & 0x7F)) {
SoundSource_PlaySfxAtFixedWorldPos(play, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);
@ -993,9 +994,9 @@ Actor* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s32 params) {
spawnedActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f,
spawnPos->z, 0, 0, 0, FAIRY_PARAMS(FAIRY_TYPE_2, true, param7F00 >> 8));
} else {
spawnedActor =
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0,
0, STRAY_FAIRY_PARAMS(((param7F00 >> 8) & 0x7F), 0, STRAY_FAIRY_TYPE_COLLECTIBLE));
spawnedActor = Actor_Spawn(
&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0,
STRAY_FAIRY_PARAMS((param7F00 >> 8) & 0x7F, STRAY_FAIRY_AREA_CLOCK_TOWN, STRAY_FAIRY_TYPE_COLLECTIBLE));
}
if (Flags_GetCollectible(play, (param7F00 >> 8) & 0x7F) == 0) {
SoundSource_PlaySfxAtFixedWorldPos(play, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY);

View File

@ -97,7 +97,8 @@ u16 sPersistentCycleWeekEventRegs[ARRAY_COUNT(gSaveContext.save.saveInfo.weekEve
/* 20 */ 0,
/* 21 */ 0,
/* 22 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_22_02) | PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_22_80),
/* 23 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_23_02) | PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_23_80),
/* 23 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK) |
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_23_80),
/* 24 */ PERSISTENT_WEEKEVENTREG_ALT(WEEKEVENTREG_24_02) | PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_24_80),
/* 25 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_25_01),
/* 26 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_26_40),

View File

@ -5,6 +5,7 @@
*/
#include "z_bg_dy_yoseizo.h"
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000)
@ -13,19 +14,17 @@
void BgDyYoseizo_Init(Actor* thisx, PlayState* play);
void BgDyYoseizo_Destroy(Actor* thisx, PlayState* play);
void BgDyYoseizo_Update(Actor* thisx, PlayState* play);
void BgDyYoseizo_Draw(Actor* thisx, PlayState* play);
void func_80A0AE1C(BgDyYoseizo* this, PlayState* play);
void func_80A0B078(BgDyYoseizo* this, PlayState* play);
void func_80A0B184(BgDyYoseizo* this, PlayState* play);
void func_80A0B290(BgDyYoseizo* this, PlayState* play);
void func_80A0B35C(BgDyYoseizo* this, PlayState* play);
void func_80A0B500(BgDyYoseizo* this, PlayState* play);
void func_80A0B5F0(BgDyYoseizo* this, PlayState* play);
void func_80A0B75C(BgDyYoseizo* this, PlayState* play);
void func_80A0B8CC(BgDyYoseizo* this, PlayState* play);
void func_80A0BB08(BgDyYoseizo* this, PlayState* play);
#if 0
/* Effects functions */
void BgDyYoseizo_SpawnEffect(BgDyYoseizo* this, Vec3f* initPos, Vec3f* initVelocity, Vec3f* accel,
Color_RGB8* primColor, Color_RGB8* envColor, f32 scale, s16 life, s16 type);
void BgDyYoseizo_UpdateEffects(BgDyYoseizo* this, PlayState* play);
void BgDyYoseizo_DrawEffects(BgDyYoseizo* this, PlayState* play);
ActorInit Bg_Dy_Yoseizo_InitVars = {
ACTOR_BG_DY_YOSEIZO,
ACTORCAT_PROP,
@ -38,56 +37,730 @@ ActorInit Bg_Dy_Yoseizo_InitVars = {
(ActorFunc)NULL,
};
#endif
typedef enum GreatFairyAnimation {
/* 0 */ GREATFAIRY_ANIM_START_GIVING_UPGRADE,
/* 1 */ GREATFAIRY_ANIM_GIVING_UPGRADE,
/* 2 */ GREATFAIRY_ANIM_SPIN_LAY_DOWN,
/* 3 */ GREATFAIRY_ANIM_LAY_DOWN_TRANSITION,
/* 4 */ GREATFAIRY_ANIM_LAYING_DOWN,
/* 5 */ GREATFAIRY_ANIM_SHOWING_ITEM,
/* 6 */ GREATFAIRY_ANIM_ARMS_FOLDED,
/* 7 */ GREATFAIRY_ANIM_CLAPPING,
/* 8 */ GREATFAIRY_ANIM_TEACH_SPIN_ATTACK,
/* 9 */ GREATFAIRY_ANIM_MAX
} GreatFairyAnimation;
extern UNK_TYPE D_06008090;
extern UNK_TYPE D_0600D228;
extern UNK_TYPE D_0601C6F4;
static AnimationHeader* sAnimations[GREATFAIRY_ANIM_MAX] = {
&gGreatFairyStartGivingUpgradeAnim, // GREATFAIRY_ANIM_START_GIVING_UPGRADE
&gGreatFairyGivingUpgradeAnim, // GREATFAIRY_ANIM_GIVING_UPGRADE
&gGreatFairySpinLayDownAnim, // GREATFAIRY_ANIM_SPIN_LAY_DOWN
&gGreatFairyLayDownTransitionAnim, // GREATFAIRY_ANIM_LAY_DOWN_TRANSITION
&gGreatFairyLayingDownAnim, // GREATFAIRY_ANIM_LAYING_DOWN
&gGreatFairyShowingItemAnim, // GREATFAIRY_ANIM_SHOWING_ITEM
&gGreatFairyArmsFoldedAnim, // GREATFAIRY_ANIM_ARMS_FOLDED
&gGreatFairyClappingAnim, // GREATFAIRY_ANIM_CLAPPING
&gGreatFairyTeachSpinAttackAnim, // GREATFAIRY_ANIM_TEACH_SPIN_ATTACK
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/BgDyYoseizo_Init.s")
void BgDyYoseizo_Init(Actor* thisx, PlayState* play) {
BgDyYoseizo* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/BgDyYoseizo_Destroy.s")
this->unk2EC = this->actor.world.pos.y + 40.0f;
this->actor.focus.pos = this->actor.world.pos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0A96C.s")
SkelAnime_InitFlex(play, &this->skelAnime, &gGreatFairySkel, &gGreatFairyShowingItemAnim, this->jointTable,
this->morphTable, GREAT_FAIRY_LIMB_MAX);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0A9E4.s")
this->actionFunc = func_80A0BB08;
Actor_SetScale(&this->actor, 0.0f);
this->eyeIndex = 0;
this->mouthIndex = 0;
this->blinkTimer = 0;
this->unk2F8 = 0;
GREAT_FAIRY_ROTZ(&this->actor) = 1;
this->unk302 = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0AA40.s")
void BgDyYoseizo_Destroy(Actor* thisx, PlayState* play) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0AD50.s")
// Has no visible effect since no segment is set for manually-controllable eye textures
void BgDyYoseizo_UpdateEyes(BgDyYoseizo* this) {
if (this->blinkTimer != 0) {
this->blinkTimer--;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0AE1C.s")
if (this->blinkTimer == 0) {
this->eyeIndex++;
if (this->eyeIndex >= 3) {
this->eyeIndex = 0;
this->blinkTimer = (s32)Rand_ZeroFloat(60.0f) + 20;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0AFDC.s")
void BgDyYoseizo_Bob(BgDyYoseizo* this, PlayState* play) {
this->actor.shape.yOffset = Math_SinS(play->gameplayFrames * 1000) * 15.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B078.s")
typedef enum GreatFairyEffectTrajectory {
/* 0 */ GREAT_FAIRY_EFFECT_TRAJECTORY_RADIANT, // Dispersing particles, in the Great Fairy's signature colour.
/* 2 */ GREAT_FAIRY_EFFECT_TRAJECTORY_FAST_RADIANT = 2, // As above, but initially move 10 times faster.
/* 5 */ GREAT_FAIRY_EFFECT_TRAJECTORY_CONVERGE_ON_PLAYER = 5 // Similar to OoT's healing effect, fixed colour.
} GreatFairyEffectTrajectory;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B184.s")
/**
* Spawn particle effects; see `GreatFairyEffectTrajectory` enum for details
*
* @param trajectoryType use the `GreatFairyEffectTrajectory` enum.
* @param count number to spawn.
*/
void BgDyYoseizo_SpawnEffects(BgDyYoseizo* this, s16 trajectoryType, s32 count) {
static Color_RGB8 sEffectPrimColors[] = {
{ 255, 235, 220 }, // Magic
{ 255, 220, 220 }, // Power
{ 220, 255, 220 }, // Wisdom
{ 220, 220, 255 }, // Courage
{ 255, 255, 200 }, // Kindness
{ 255, 255, 170 }, // GREAT_FAIRY_EFFECT_TRAJECTORY_CONVERGE_ON_PLAYER
};
static Color_RGB8 sEffectEnvColors[] = {
{ 255, 150, 0 }, // Magic
{ 255, 0, 0 }, // Power
{ 0, 255, 0 }, // Wisdom
{ 0, 0, 255 }, // Courage
{ 255, 255, 0 }, // Kindness
{ 255, 100, 255 }, // GREAT_FAIRY_EFFECT_TRAJECTORY_CONVERGE_ON_PLAYER
};
Vec3f velocity;
Vec3f accel;
Vec3f pos;
Color_RGB8 primColor;
Color_RGB8 envColor;
f32 spawnHeightVariation;
f32 scale;
s32 effectType;
s32 life;
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B290.s")
if (this->actor.scale.y < 0.01f) {
return;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B35C.s")
spawnHeightVariation = this->actor.scale.y * 3500.0f;
accel.x = Rand_ZeroOne() - 0.5f;
accel.y = Rand_ZeroOne() - 0.5f;
accel.z = Rand_ZeroOne() - 0.5f;
velocity.x = accel.x * 10.0f;
velocity.y = accel.y * 10.0f;
velocity.z = accel.z * 10.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B500.s")
for (i = 0; i < count; i++) {
switch (trajectoryType) {
case GREAT_FAIRY_EFFECT_TRAJECTORY_FAST_RADIANT:
scale = 1.0f;
life = 90;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B5F0.s")
velocity.x = accel.x * 100.0f;
velocity.y = accel.y * 100.0f;
velocity.z = accel.z * 100.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B75C.s")
effectType = GREAT_FAIRY_GET_TYPE(&this->actor);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B834.s")
pos.x = this->actor.world.pos.x;
pos.y = this->actor.world.pos.y + spawnHeightVariation +
(Rand_ZeroOne() - 0.5f) * (spawnHeightVariation * 0.5f);
pos.z = this->actor.world.pos.z + 30.0f;
break;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0B8CC.s")
case GREAT_FAIRY_EFFECT_TRAJECTORY_RADIANT:
scale = 1.0f;
life = 90;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0BB08.s")
effectType = GREAT_FAIRY_GET_TYPE(&this->actor);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/BgDyYoseizo_Update.s")
pos.x = this->actor.world.pos.x;
pos.y = this->actor.world.pos.y + spawnHeightVariation +
(Rand_ZeroOne() - 0.5f) * (spawnHeightVariation * 0.5f);
pos.z = this->actor.world.pos.z + 30.0f;
break;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0BCD8.s")
default: // all become convergent type
scale = 0.2f;
life = 50;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0BD40.s")
effectType = GREAT_FAIRY_EFFECT_TRAJECTORY_CONVERGE_ON_PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0BE60.s")
pos.x = Rand_CenteredFloat(10.0f) + this->actor.world.pos.x;
pos.y = this->actor.world.pos.y + spawnHeightVariation + 50.0f +
(Rand_ZeroOne() - 0.5f) * (spawnHeightVariation * 0.1f);
pos.z = this->actor.world.pos.z + 30.0f;
break;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0BF70.s")
primColor.r = sEffectPrimColors[effectType].r;
primColor.g = sEffectPrimColors[effectType].g;
primColor.b = sEffectPrimColors[effectType].b;
envColor.r = sEffectEnvColors[effectType].r;
envColor.g = sEffectEnvColors[effectType].g;
envColor.b = sEffectEnvColors[effectType].b;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dy_Yoseizo/func_80A0C270.s")
BgDyYoseizo_SpawnEffect(this, &pos, &velocity, &accel, &primColor, &envColor, scale, life, effectType);
}
}
void func_80A0AD50(BgDyYoseizo* this) {
f32 scale = this->actor.scale.x;
f32 heightTarget = this->actor.home.pos.y + 40.0f;
Math_ApproachF(&this->actor.world.pos.y, heightTarget, this->unk2F0, 100.0f);
Math_ApproachF(&scale, 0.035f, this->unk2F4, 0.005f);
Math_ApproachF(&this->unk2F0, 0.8f, 0.1f, 0.02f);
Math_ApproachF(&this->unk2F4, 0.2f, 0.03f, 0.05f);
BgDyYoseizo_SpawnEffects(this, GREAT_FAIRY_EFFECT_TRAJECTORY_RADIANT, 2);
Actor_SetScale(&this->actor, scale);
}
void func_80A0AE1C(BgDyYoseizo* this, PlayState* play) {
f32 scale = this->actor.scale.x;
f32 heightTarget = this->actor.home.pos.y;
if (scale < 0.003f) {
this->actionFunc = func_80A0BB08;
Actor_SetScale(&this->actor, 0.0f);
this->unk2F0 = 0.0f;
this->unk2F4 = 0.0f;
this->unk2F8 = 0;
if (GREAT_FAIRY_GET_TYPE(&this->actor) <= GREAT_FAIRY_TYPE_COURAGE) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, this->actor.world.pos.x,
this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, 0, 0, 0,
GREAT_FAIRY_GET_TYPE(&this->actor) + DEMO_EFFECT_TYPE_LIGHT_BASE);
} else {
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, this->actor.world.pos.x,
this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, 0, 0, 0,
DEMO_EFFECT_TYPE_LIGHT_DARK_YELLOW);
}
Audio_PlaySfx(NA_SE_SY_WHITE_OUT_T);
} else {
Math_ApproachF(&this->actor.world.pos.y, heightTarget, this->unk2F0, 100.0f);
Math_ApproachZeroF(&scale, this->unk2F4, 0.005f);
Math_ApproachF(&this->unk2F0, 0.8f, 0.1f, 0.02f);
Math_ApproachF(&this->unk2F4, 0.2f, 0.03f, 0.05f);
this->actor.shape.rot.y += this->unk2F8;
if (this->unk2F8 < 0x1770) {
this->unk2F8 += 0x12C;
}
BgDyYoseizo_SpawnEffects(this, GREAT_FAIRY_EFFECT_TRAJECTORY_RADIANT, 2);
Actor_SetScale(&this->actor, scale);
}
}
void func_80A0AFDC(BgDyYoseizo* this) {
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_SPIN_LAY_DOWN], 0.0f, 46.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_SPIN_LAY_DOWN]), ANIMMODE_ONCE, 0.0f);
this->actionFunc = func_80A0AE1C;
Actor_PlaySfx(&this->actor, NA_SE_VO_FR_LAUGH_0);
Actor_PlaySfx(&this->actor, NA_SE_EV_GREAT_FAIRY_VANISH);
this->unk2F8 = 0;
this->actor.velocity.y = 0.0f;
this->unk2F0 = 0.0f;
this->unk2F4 = 0.0f;
this->actor.shape.yOffset = 0.0f;
}
void func_80A0B078(BgDyYoseizo* this, PlayState* play) {
BgDyYoseizo_Bob(this, play);
SkelAnime_Update(&this->skelAnime);
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 7)) {
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_LAYING_DOWN], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_LAYING_DOWN]), ANIMMODE_LOOP, 0.0f);
this->actionFunc = func_80A0B184;
} else if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 6)) {
func_80A0AFDC(this);
}
}
void func_80A0B184(BgDyYoseizo* this, PlayState* play) {
BgDyYoseizo_Bob(this, play);
SkelAnime_Update(&this->skelAnime);
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 8)) {
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_SHOWING_ITEM], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_SHOWING_ITEM]), ANIMMODE_LOOP, 0.0f);
this->actionFunc = func_80A0B078;
} else if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 6)) {
func_80A0AFDC(this);
}
}
void func_80A0B290(BgDyYoseizo* this, PlayState* play) {
BgDyYoseizo_Bob(this, play);
SkelAnime_Update(&this->skelAnime);
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 7)) {
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_LAYING_DOWN], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_LAYING_DOWN]), ANIMMODE_LOOP, -10.0f);
this->actionFunc = func_80A0B184;
this->mouthIndex = 0;
}
}
void func_80A0B35C(BgDyYoseizo* this, PlayState* play) {
BgDyYoseizo_Bob(this, play);
SkelAnime_Update(&this->skelAnime);
if (this->timer == 60) {
if (!Flags_GetSwitch(play, GREAT_FAIRY_GET_SWITCHFLAG(&this->actor))) {
switch (GREAT_FAIRY_GET_TYPE(&this->actor)) {
case GREAT_FAIRY_TYPE_MAGIC:
if (gSaveContext.save.saveInfo.playerData.isMagicAcquired != true) {
gSaveContext.save.saveInfo.playerData.isMagicAcquired = true;
gSaveContext.magicFillTarget = MAGIC_NORMAL_METER;
}
break;
case GREAT_FAIRY_TYPE_WISDOM:
if (gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired != true) {
gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired = true;
gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER;
gSaveContext.save.saveInfo.playerData.magicLevel = 0;
}
break;
case GREAT_FAIRY_TYPE_COURAGE:
if (gSaveContext.save.saveInfo.playerData.doubleDefense != true) {
gSaveContext.save.saveInfo.playerData.doubleDefense = true;
}
break;
default:
break;
}
}
Interface_SetHudVisibility(9);
}
if ((this->timer < 50) && (GREAT_FAIRY_GET_TYPE(&this->actor) == GREAT_FAIRY_TYPE_COURAGE)) {
if (gSaveContext.save.saveInfo.inventory.defenseHearts < 20) {
gSaveContext.save.saveInfo.inventory.defenseHearts++;
}
}
if (this->timer == 50) {
gSaveContext.healthAccumulator = 0x140;
Magic_Add(play, MAGIC_FILL_TO_CAPACITY);
}
if (this->timer == 0) {
this->beam->trigger = true;
this->actionFunc = func_80A0B290;
}
}
void func_80A0B500(BgDyYoseizo* this, PlayState* play) {
Player* player = GET_PLAYER(play);
BgDyYoseizo_Bob(this, play);
if (SkelAnime_Update(&this->skelAnime)) {
Vec3f pos;
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_GIVING_UPGRADE], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_GIVING_UPGRADE]), ANIMMODE_LOOP, 0.0f);
this->actionFunc = func_80A0B35C;
pos.x = player->actor.world.pos.x;
pos.y = player->actor.world.pos.y + 200.0f;
pos.z = player->actor.world.pos.z;
this->beam = (EnDyExtra*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_DY_EXTRA, pos.x,
pos.y, pos.z, 0, 0, 0, GREAT_FAIRY_GET_TYPE(&this->actor));
this->timer = 120;
}
}
void func_80A0B5F0(BgDyYoseizo* this, PlayState* play) {
BgDyYoseizo_Bob(this, play);
if (SkelAnime_Update(&this->skelAnime)) {
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_LAYING_DOWN], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_LAYING_DOWN]), ANIMMODE_LOOP, 0.0f);
}
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 5)) {
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_START_GIVING_UPGRADE], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_START_GIVING_UPGRADE]), ANIMMODE_ONCE,
-5.0f);
Actor_PlaySfx(&this->actor, NA_SE_VO_FR_SMILE_0);
this->mouthIndex = 1;
this->eyeIndex = 0;
this->actionFunc = func_80A0B500;
}
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 6)) {
func_80A0AFDC(this);
}
BgDyYoseizo_UpdateEyes(this);
}
void func_80A0B75C(BgDyYoseizo* this, PlayState* play) {
func_80A0AD50(this);
SkelAnime_Update(&this->skelAnime);
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 4)) {
this->actor.shape.rot.y = 0;
this->actionFunc = func_80A0B5F0;
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_LAY_DOWN_TRANSITION], 1.0f, 2.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_LAY_DOWN_TRANSITION]), ANIMMODE_ONCE, 0.0f);
Actor_PlaySfx(&this->actor, NA_SE_VO_FR_SMILE_0);
this->unk2F8 = 0;
}
}
void func_80A0B834(BgDyYoseizo* this) {
this->actor.draw = BgDyYoseizo_Draw;
Animation_Change(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_SPIN_LAY_DOWN], 1.0f, 0.0f,
Animation_GetLastFrame(sAnimations[GREATFAIRY_ANIM_SPIN_LAY_DOWN]), ANIMMODE_ONCE, 0.0f);
Actor_PlaySfx(&this->actor, NA_SE_VO_FR_LAUGH_0);
Actor_PlaySfx(&this->actor, NA_SE_EV_GREAT_FAIRY_APPEAR);
BgDyYoseizo_SpawnEffects(this, GREAT_FAIRY_EFFECT_TRAJECTORY_FAST_RADIANT, 30);
}
void BgDyYoseizo_TrainPlayer(BgDyYoseizo* this, PlayState* play) {
s16 csId;
s32 pad;
Player* player = GET_PLAYER(play);
SkelAnime_Update(&this->skelAnime);
csId = 0;
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103)) {
csId = play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id;
Cutscene_ActorTranslateAndYaw(&this->actor, play, Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103));
} else {
if (GREAT_FAIRY_ROTZ(&this->actor) != 0) {
this->actor.home.pos.x = player->actor.world.pos.x;
this->actor.home.pos.z = player->actor.world.pos.z;
GREAT_FAIRY_ROTZ(&this->actor) = 0;
} else {
player->actor.world.pos.x = this->actor.home.pos.x;
player->actor.world.pos.z = this->actor.home.pos.z;
}
if (this->unk302 & 1) {
if (this->timer == 0) {
if (CutsceneManager_IsNext(this->actor.csId)) {
CutsceneManager_StartWithPlayerCs(this->actor.csId, &this->actor);
this->unk302 &= ~1;
} else {
CutsceneManager_Queue(this->actor.csId);
}
}
} else if (!(this->unk302 & 2) && (player->meleeWeaponState != 0)) {
if (player->meleeWeaponAnimation >= PLAYER_MWA_SPIN_ATTACK_1H) {
if (player->unk_B08 >= 0.85f) {
this->unk302 |= 1;
this->unk302 |= 2;
if (play->msgCtx.currentTextId == 0x59A) {
Message_CloseTextbox(play);
}
this->timer = 20;
return;
}
}
if (play->msgCtx.currentTextId != 0x59A) {
// "Hold B and then release"
Message_StartTextbox(play, 0x59A, &this->actor);
}
}
}
if (csId != this->csId) {
switch (csId) {
case 9:
Animation_PlayLoop(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_ARMS_FOLDED]);
break;
case 10:
Animation_PlayLoop(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_CLAPPING]);
break;
case 11:
Animation_PlayOnce(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_TEACH_SPIN_ATTACK]);
break;
default:
break;
}
this->csId = csId;
}
}
// Choose behaviour?
void func_80A0BB08(BgDyYoseizo* this, PlayState* play) {
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 2)) {
func_80A0B834(this);
this->actionFunc = func_80A0B75C;
}
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 7)) {
this->actor.draw = BgDyYoseizo_Draw;
Animation_PlayLoop(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_LAYING_DOWN]);
this->actionFunc = func_80A0B184;
this->mouthIndex = 0;
this->actor.world.pos.y = this->actor.home.pos.y + 40.0f;
Actor_SetScale(&this->actor, 0.035f);
this->unk2F8 = 0;
}
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_103)]->id == 9)) {
Actor_SetScale(&this->actor, 0.01f);
Animation_PlayLoop(&this->skelAnime, sAnimations[GREATFAIRY_ANIM_ARMS_FOLDED]);
this->csId = 9;
this->actionFunc = BgDyYoseizo_TrainPlayer;
this->actor.draw = BgDyYoseizo_Draw;
}
}
void BgDyYoseizo_Update(Actor* thisx, PlayState* play) {
BgDyYoseizo* this = THIS;
this->actionFunc(this, play);
Actor_MoveWithGravity(&this->actor);
DECR(this->timer);
BgDyYoseizo_UpdateEffects(this, play);
}
s32 BgDyYoseizo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
BgDyYoseizo* this = THIS;
if (limbIndex == GREAT_FAIRY_LIMB_TORSO) {
rot->x += this->torsoRot.y;
}
if (limbIndex == GREAT_FAIRY_LIMB_HEAD) {
rot->x += this->headRot.y;
rot->z += this->headRot.z;
}
return false;
}
/* Colour and shape of eyebrows, hair colour. */
typedef enum GreatFairyAppearance {
/* 0 */ GREAT_FAIRY_APPEARANCE_MAGIC, // Orange
/* 1 */ GREAT_FAIRY_APPEARANCE_WISDOM, // Green
/* 2 */ GREAT_FAIRY_APPEARANCE_POWER, // Pink
/* 3 */ GREAT_FAIRY_APPEARANCE_COURAGE, // Purple
/* 4 */ GREAT_FAIRY_APPEARANCE_KINDNESS // Yellow
} GreatFairyAppearance;
void BgDyYoseizo_Draw(Actor* thisx, PlayState* play) {
static TexturePtr sMouthTextures[] = {
gGreatFairyMouthClosedTex,
gGreatFairyMouthOpenTex,
};
BgDyYoseizo* this = THIS;
GreatFairyAppearance appearance = GREAT_FAIRY_APPEARANCE_MAGIC;
// The differing eyes and hair colours
switch (GREAT_FAIRY_GET_TYPE(&this->actor)) {
case GREAT_FAIRY_TYPE_POWER:
appearance = GREAT_FAIRY_APPEARANCE_POWER;
break;
case GREAT_FAIRY_TYPE_WISDOM:
appearance = GREAT_FAIRY_APPEARANCE_WISDOM;
break;
case GREAT_FAIRY_TYPE_COURAGE:
case GREAT_FAIRY_TYPE_KINDNESS:
appearance = GREAT_FAIRY_GET_TYPE(&this->actor);
break;
default: // GREAT_FAIRY_APPEARANCE_MAGIC
break;
}
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL25_Opa(play->state.gfxCtx);
// Set eyes and hair colour, not actually animated.
AnimatedMat_DrawStepOpa(play, Lib_SegmentedToVirtual(gGreatFairyAppearenceTexAnim), appearance);
// Draw mouth
{
Gfx* gfx = POLY_OPA_DISP;
s16 index = this->mouthIndex;
TexturePtr mouthTex = Lib_SegmentedToVirtual(sMouthTextures[index]);
gSPSegment(&gfx[0], 0x09, mouthTex);
POLY_OPA_DISP = &gfx[1];
}
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
BgDyYoseizo_OverrideLimbDraw, NULL, &this->actor);
CLOSE_DISPS(play->state.gfxCtx);
BgDyYoseizo_DrawEffects(this, play);
}
/* Effects functions */
void BgDyYoseizo_SpawnEffect(BgDyYoseizo* this, Vec3f* initPos, Vec3f* initVelocity, Vec3f* accel,
Color_RGB8* primColor, Color_RGB8* envColor, f32 scale, s16 life, s16 type) {
BgDyYoseizoEffect* effect = this->effects;
s16 i;
for (i = 0; i < BG_DY_YOSEIZO_EFFECT_COUNT; i++, effect++) {
if (!effect->alive) {
effect->alive = true;
effect->pos = *initPos;
effect->velocity = *initVelocity;
effect->accel = *accel;
effect->primColor = *primColor;
effect->alpha = 0;
effect->envColor = *envColor;
effect->scale = scale;
effect->timer = life;
effect->type = type;
effect->pitch = 0;
effect->yaw = TRUNCF_BINANG(Rand_CenteredFloat(30000.0f));
effect->roll = 0;
return;
}
}
}
void BgDyYoseizo_UpdateEffects(BgDyYoseizo* this, PlayState* play) {
BgDyYoseizoEffect* effect = this->effects;
Player* player = GET_PLAYER(play);
Vec3f sp94;
Vec3f sp88;
s32 pad[2];
f32 targetPitch;
f32 targetYaw;
f32 floatAngle;
s16 i = 0;
for (i = 0; i < BG_DY_YOSEIZO_EFFECT_COUNT; i++, effect++) {
if (effect->alive) {
effect->roll += 3000;
if (effect->type < GREAT_FAIRY_EFFECT_TRAJECTORY_CONVERGE_ON_PLAYER) {
effect->pos.x += effect->velocity.x;
effect->pos.y += effect->velocity.y;
effect->pos.z += effect->velocity.z;
effect->velocity.x += effect->accel.x;
effect->velocity.y += effect->accel.y;
effect->velocity.z += effect->accel.z;
} else {
Actor_PlaySfx(&this->actor, NA_SE_EV_HEALING - SFX_FLAG);
sp94 = player->actor.world.pos;
sp94.y = player->actor.world.pos.y - 150.0f;
sp94.z = player->actor.world.pos.z - 50.0f;
targetPitch = Math_Vec3f_Pitch(&effect->pos, &sp94);
targetYaw = Math_Vec3f_Yaw(&effect->pos, &sp94);
floatAngle = effect->pitch;
Math_ApproachF(&floatAngle, targetPitch, 0.9f, 5000.0f);
effect->pitch = floatAngle;
floatAngle = effect->yaw;
Math_ApproachF(&floatAngle, targetYaw, 0.9f, 5000.0f);
effect->yaw = floatAngle;
Matrix_Push();
Matrix_RotateYS(effect->yaw, MTXMODE_NEW);
Matrix_RotateXS(effect->pitch, MTXMODE_APPLY);
sp94.x = sp94.y = sp94.z = 3.0f;
Matrix_MultVec3f(&sp94, &sp88);
Matrix_Pop();
effect->pos.x += sp88.x;
effect->pos.y += sp88.y;
effect->pos.z += sp88.z;
}
}
// fade up, fade down, vanish and reset
if (effect->timer != 0) {
effect->timer--;
effect->alpha += 30;
if (effect->alpha > 255) {
effect->alpha = 255;
}
} else {
effect->alpha -= 30;
if (effect->alpha <= 0) {
effect->alpha = 0;
effect->alive = false;
}
}
}
}
void BgDyYoseizo_DrawEffects(BgDyYoseizo* this, PlayState* play) {
static f32 sStretchFactors[] = {
1.0f, 1.1f, 1.15f, 1.1f, 1.0f, 0.9f, 0.85f, 0.9f,
};
GraphicsContext* gfxCtx = play->state.gfxCtx;
u8 setup = 0;
BgDyYoseizoEffect* effect = this->effects;
f32 stretchFactor = sStretchFactors[play->gameplayFrames % ARRAY_COUNT(sStretchFactors)];
s16 i;
OPEN_DISPS(gfxCtx);
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
for (i = 0; i < BG_DY_YOSEIZO_EFFECT_COUNT; i++, effect++) {
if (effect->alive == true) {
if (setup == 0) {
gSPDisplayList(POLY_XLU_DISP++, gGreatFairyParticleSetupDL);
gDPPipeSync(POLY_XLU_DISP++);
setup++;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, effect->primColor.r, effect->primColor.g, effect->primColor.b,
effect->alpha);
gDPSetEnvColor(POLY_XLU_DISP++, effect->envColor.r, effect->envColor.g, effect->envColor.b, 0);
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(effect->scale, effect->scale * stretchFactor, 1.0f, MTXMODE_APPLY);
Matrix_RotateZS(effect->roll, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gGreatFairyParticleDL);
}
}
CLOSE_DISPS(gfxCtx);
}

View File

@ -2,15 +2,65 @@
#define Z_BG_DY_YOSEIZO_H
#include "global.h"
#include "overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.h"
#include "objects/object_dy_obj/object_dy_obj.h"
struct BgDyYoseizo;
typedef void (*BgDyYoseizoActionFunc)(struct BgDyYoseizo*, PlayState*);
#define GREAT_FAIRY_GET_SWITCHFLAG(thisx) (((thisx)->params & 0xFE00) >> 9)
#define GREAT_FAIRY_GET_TYPE(thisx) ((thisx)->params & 0xF)
#define GREAT_FAIRY_ROTZ(thisx) ((thisx)->home.rot.z)
typedef enum GreatFairyType {
/* 0 */ GREAT_FAIRY_TYPE_MAGIC,
/* 1 */ GREAT_FAIRY_TYPE_POWER,
/* 2 */ GREAT_FAIRY_TYPE_WISDOM,
/* 3 */ GREAT_FAIRY_TYPE_COURAGE,
/* 4 */ GREAT_FAIRY_TYPE_KINDNESS
} GreatFairyType;
#define BG_DY_YOSEIZO_EFFECT_COUNT 200
typedef struct BgDyYoseizoEffect {
/* 0x00 */ u8 alive; // drawn if 1, respawn if 0
/* 0x04 */ Vec3f pos;
/* 0x10 */ Vec3f velocity;
/* 0x1C */ Vec3f accel;
/* 0x28 */ Color_RGB8 primColor;
/* 0x2B */ Color_RGB8 envColor;
/* 0x2E */ s16 alpha;
/* 0x30 */ f32 scale;
/* 0x34 */ s16 timer; // lifetime
/* 0x36 */ s16 type; // 0 is general radiance, else is directed towards Player
/* 0x38 */ s16 pitch;
/* 0x3A */ s16 yaw;
/* 0x3C */ s16 roll; // all three are f32 in OoT
} BgDyYoseizoEffect; // size = 0x40
typedef struct BgDyYoseizo {
/* 0x0000 */ Actor actor;
/* 0x0144 */ BgDyYoseizoActionFunc actionFunc;
/* 0x0148 */ char unk_148[0x33BC];
/* 0x0148 */ SkelAnime skelAnime;
/* 0x018C */ Vec3s jointTable[GREAT_FAIRY_LIMB_MAX];
/* 0x0234 */ Vec3s morphTable[GREAT_FAIRY_LIMB_MAX];
/* 0x02DC */ Vec3s headRot;
/* 0x02DC */ Vec3s torsoRot;
/* 0x02E8 */ EnDyExtra* beam;
/* 0x02EC */ f32 unk2EC; // unused
/* 0x02F0 */ f32 unk2F0;
/* 0x02F4 */ f32 unk2F4;
/* 0x02F8 */ union {
s16 unk2F8;
s16 csId; // used on BgDyYoseizo_TrainPlayer
};
/* 0x02FA */ s16 eyeIndex;
/* 0x02FC */ s16 mouthIndex;
/* 0x02FE */ s16 blinkTimer;
/* 0x0300 */ s16 timer;
/* 0x0302 */ u16 unk302;
/* 0x0304 */ BgDyYoseizoEffect effects[BG_DY_YOSEIZO_EFFECT_COUNT];
} BgDyYoseizo; // size = 0x3504
#endif // Z_BG_DY_YOSEIZO_H

View File

@ -16,14 +16,13 @@ void DemoEffect_Init(Actor* thisx, PlayState* play);
void DemoEffect_Destroy(Actor* thisx, PlayState* play);
void DemoEffect_Update(Actor* thisx, PlayState* play);
void func_808CD940(DemoEffect* this, PlayState* play);
void func_808CD998(DemoEffect* this, PlayState* play);
void func_808CDBDC(DemoEffect* this, PlayState* play);
void func_808CDCEC(DemoEffect* this, PlayState* play);
void func_808CDD70(DemoEffect* this, PlayState* play);
void func_808CDDE0(DemoEffect* this, PlayState* play);
void func_808CDFF8(Actor* thisx, PlayState* play);
void func_808CE078(Actor* thisx, PlayState* play2);
void DemoEffect_WaitForObject(DemoEffect* this, PlayState* play);
void DemoEffect_SetupTimewarp(DemoEffect* this, PlayState* play);
void DemoEffect_StartTimewarp(DemoEffect* this, PlayState* play);
void DemoEffect_ShrinkLight(DemoEffect* this, PlayState* play);
void DemoEffect_ExpandLight(DemoEffect* this, PlayState* play);
void DemoEffect_DrawTimewarp(Actor* thisx, PlayState* play);
void DemoEffect_DrawLight(Actor* thisx, PlayState* play2);
ActorInit Demo_Effect_InitVars = {
ACTOR_DEMO_EFFECT,
@ -47,8 +46,12 @@ void DemoEffect_Init(Actor* thisx, PlayState* play) {
s32 type = DEMO_EFFECT_GET_TYPE(&this->actor);
s32 objectIndex;
s32 pad2;
Color_RGB8 colors[] = {
{ 200, 200, 0 }, { 255, 40, 100 }, { 50, 255, 0 }, { 0, 0, 255 }, { 255, 255, 80 },
Color_RGB8 lightColors[] = {
{ 200, 200, 0 }, // Yellow
{ 255, 40, 100 }, // Pink
{ 50, 255, 0 }, // Light green
{ 0, 0, 255 }, // Blue
{ 255, 255, 80 }, // Light Yellow
};
if (sEffectTypeObjects[type] == GAMEPLAY_KEEP) {
@ -66,14 +69,14 @@ void DemoEffect_Init(Actor* thisx, PlayState* play) {
Actor_SetScale(&this->actor, 0.2f);
switch (type) {
case DEMO_EFFECT_TYPE_0:
case DEMO_EFFECT_TYPE_1:
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_LARGE:
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_SMALL:
this->actor.flags |= ACTOR_FLAG_2000000;
case DEMO_EFFECT_TYPE_2:
case DEMO_EFFECT_TYPE_3:
this->initDrawFunc = func_808CDFF8;
this->initActionFunc = func_808CD998;
// FALLTHROUGH
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_LARGE:
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_VERY_LARGE:
this->initDrawFunc = DemoEffect_DrawTimewarp;
this->initActionFunc = DemoEffect_SetupTimewarp;
this->envXluColor[0] = 0;
this->envXluColor[1] = 100;
this->envXluColor[2] = 255;
@ -81,17 +84,17 @@ void DemoEffect_Init(Actor* thisx, PlayState* play) {
this->timer = 0;
break;
case DEMO_EFFECT_TYPE_4:
case DEMO_EFFECT_TYPE_5:
case DEMO_EFFECT_TYPE_6:
case DEMO_EFFECT_TYPE_7:
case DEMO_EFFECT_TYPE_8:
this->envXluColor[0] = colors[type - 4].r;
this->envXluColor[1] = colors[type - 4].g;
this->envXluColor[2] = colors[type - 4].b;
case DEMO_EFFECT_TYPE_LIGHT_DARK_YELLOW:
case DEMO_EFFECT_TYPE_LIGHT_PINK:
case DEMO_EFFECT_TYPE_LIGHT_GREEN:
case DEMO_EFFECT_TYPE_LIGHT_BLUE:
case DEMO_EFFECT_TYPE_LIGHT_YELLOW:
this->envXluColor[0] = lightColors[type - DEMO_EFFECT_TYPE_LIGHT_BASE].r;
this->envXluColor[1] = lightColors[type - DEMO_EFFECT_TYPE_LIGHT_BASE].g;
this->envXluColor[2] = lightColors[type - DEMO_EFFECT_TYPE_LIGHT_BASE].b;
Actor_SetScale(&this->actor, 0.0f);
this->initDrawFunc = func_808CE078;
this->initActionFunc = func_808CDDE0;
this->initDrawFunc = DemoEffect_DrawLight;
this->initActionFunc = DemoEffect_ExpandLight;
this->timer = 0;
break;
@ -100,17 +103,17 @@ void DemoEffect_Init(Actor* thisx, PlayState* play) {
}
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
this->actionFunc = func_808CD940;
this->actionFunc = DemoEffect_WaitForObject;
}
void DemoEffect_Destroy(Actor* thisx, PlayState* play) {
DemoEffect* this = THIS;
switch (DEMO_EFFECT_GET_TYPE(&this->actor)) {
case DEMO_EFFECT_TYPE_0:
case DEMO_EFFECT_TYPE_1:
case DEMO_EFFECT_TYPE_2:
case DEMO_EFFECT_TYPE_3:
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_LARGE:
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_SMALL:
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_LARGE:
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_VERY_LARGE:
SkelCurve_Destroy(play, &this->skelCurve);
break;
@ -119,7 +122,7 @@ void DemoEffect_Destroy(Actor* thisx, PlayState* play) {
}
}
void func_808CD940(DemoEffect* this, PlayState* play) {
void DemoEffect_WaitForObject(DemoEffect* this, PlayState* play) {
if (Object_IsLoaded(&play->objectCtx, this->initObjectIndex)) {
this->actor.objBankIndex = this->initObjectIndex;
this->actor.draw = this->initDrawFunc;
@ -127,41 +130,41 @@ void func_808CD940(DemoEffect* this, PlayState* play) {
}
}
void func_808CD998(DemoEffect* this, PlayState* play) {
void DemoEffect_SetupTimewarp(DemoEffect* this, PlayState* play) {
s32 type = DEMO_EFFECT_GET_TYPE(&this->actor);
if (SkelCurve_Init(play, &this->skelCurve, &object_efc_tw_Skel_0012E8, &object_efc_tw_CurveAnim_000050)) {}
if (SkelCurve_Init(play, &this->skelCurve, &gTimewarpSkel, &gTimewarpAnim)) {}
SkelCurve_SetAnim(&this->skelCurve, &object_efc_tw_CurveAnim_000050, 1.0f, 59.0f, 1.0f, 1.7f);
SkelCurve_SetAnim(&this->skelCurve, &gTimewarpAnim, 1.0f, 59.0f, 1.0f, 1.7f);
SkelCurve_Update(play, &this->skelCurve);
this->actionFunc = func_808CDCEC;
this->actionFunc = DemoEffect_StartTimewarp;
switch (type) {
case DEMO_EFFECT_TYPE_0:
Actor_SetScale(&this->actor, 0.16800001f);
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_LARGE:
Actor_SetScale(&this->actor, 168.0f * 0.001f);
break;
case DEMO_EFFECT_TYPE_1:
Actor_SetScale(&this->actor, 0.08400001f);
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_SMALL:
Actor_SetScale(&this->actor, 84.0f * 0.001f);
break;
case DEMO_EFFECT_TYPE_2:
Actor_SetScale(&this->actor, 0.16800001f);
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_LARGE:
Actor_SetScale(&this->actor, 168.0f * 0.001f);
break;
case DEMO_EFFECT_TYPE_3:
Actor_SetScale(&this->actor, 0.28f);
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_VERY_LARGE:
Actor_SetScale(&this->actor, 280.0f * 0.001f);
break;
default:
Actor_SetScale(&this->actor, 0.014f);
Actor_SetScale(&this->actor, 14.0f * 0.001f);
break;
}
}
void func_808CDAD0(f32 alphaScale) {
void DemoEffect_SetPerVertexAlpha(f32 alphaScale) {
static u8 sAlphaTypes[] = { 1, 1, 2, 0, 1, 1, 2, 0, 1, 2, 0, 2, 1, 0, 1, 0, 2, 0, 2, 2, 0 };
Vtx* vtx = Lib_SegmentedToVirtual(object_efc_tw_Vtx_000060);
Vtx* vtx = Lib_SegmentedToVirtual(gTimewarpVtx);
s32 i;
u8 alphas[3];
@ -176,7 +179,10 @@ void func_808CDAD0(f32 alphaScale) {
}
}
void func_808CDBDC(DemoEffect* this, PlayState* play) {
/**
* Shrink and fade linearly for 100 frames then remove.
*/
void DemoEffect_FinishTimewarp(DemoEffect* this, PlayState* play) {
s32 type = DEMO_EFFECT_GET_TYPE(&this->actor);
f32 scale;
f32 alphaScale;
@ -187,19 +193,19 @@ void func_808CDBDC(DemoEffect* this, PlayState* play) {
scale = alphaScale * 0.14f;
switch (type) {
case DEMO_EFFECT_TYPE_0:
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_LARGE:
scale *= 1.2f;
break;
case DEMO_EFFECT_TYPE_1:
case DEMO_EFFECT_TIMEWARP_TIMEBLOCK_SMALL:
scale *= 0.6f;
break;
case DEMO_EFFECT_TYPE_2:
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_LARGE:
scale *= 1.2f;
break;
case DEMO_EFFECT_TYPE_3:
case DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_VERY_LARGE:
scale *= 2.0f;
break;
@ -209,25 +215,31 @@ void func_808CDBDC(DemoEffect* this, PlayState* play) {
this->actor.scale.x = scale;
this->actor.scale.z = scale;
func_808CDAD0(alphaScale);
DemoEffect_SetPerVertexAlpha(alphaScale);
Actor_PlaySfx_FlaggedCentered3(&this->actor, NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG);
} else {
func_808CDAD0(1.0f);
DemoEffect_SetPerVertexAlpha(1.0f);
Actor_Kill(&this->actor);
}
}
void func_808CDCEC(DemoEffect* this, PlayState* play) {
/**
* Runs until animation plays to frame 59 and pauses it on frame 59.
*/
void DemoEffect_StartTimewarp(DemoEffect* this, PlayState* play) {
Actor_PlaySfx_FlaggedCentered3(&this->actor, NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG);
if (SkelCurve_Update(play, &this->skelCurve)) {
SkelCurve_SetAnim(&this->skelCurve, &object_efc_tw_CurveAnim_000050, 1.0f, 60.0f, 59.0f, 0.0f);
this->actionFunc = func_808CDBDC;
SkelCurve_SetAnim(&this->skelCurve, &gTimewarpAnim, 1.0f, 60.0f, 59.0f, 0.0f);
this->actionFunc = DemoEffect_FinishTimewarp;
this->timer = 0;
}
}
void func_808CDD70(DemoEffect* this, PlayState* play) {
/**
* Take scale to 0 linearly, when scale is small enough, remove.
*/
void DemoEffect_ShrinkLight(DemoEffect* this, PlayState* play) {
Actor_SetScale(&this->actor, this->actor.scale.x - 0.02f);
this->timer++;
@ -236,12 +248,16 @@ void func_808CDD70(DemoEffect* this, PlayState* play) {
}
}
void func_808CDDE0(DemoEffect* this, PlayState* play) {
/**
* Changes scale for 3 frames, scale is successively 0.0f, 0.2f, 0.3f, 0.35f (would converge to 0.4 exponentially if run
* for a long time).
*/
void DemoEffect_ExpandLight(DemoEffect* this, PlayState* play) {
Actor_SetScale(&this->actor, (this->actor.scale.x * 0.5f) + 0.2f);
this->timer++;
if (this->timer >= 3) {
this->actionFunc = func_808CDD70;
this->actionFunc = DemoEffect_ShrinkLight;
}
}
@ -251,7 +267,7 @@ void DemoEffect_Update(Actor* thisx, PlayState* play) {
this->actionFunc(this, play);
}
s32 func_808CDE78(PlayState* play, SkelCurve* skelCurve, s32 limbIndex, Actor* thisx) {
s32 DemoEffect_OverrideLimbDrawTimewarp(PlayState* play, SkelCurve* skelCurve, s32 limbIndex, Actor* thisx) {
s32 pad;
DemoEffect* this = THIS;
u32 frames = play->gameplayFrames;
@ -278,7 +294,7 @@ s32 func_808CDE78(PlayState* play, SkelCurve* skelCurve, s32 limbIndex, Actor* t
return true;
}
void func_808CDFF8(Actor* thisx, PlayState* play) {
void DemoEffect_DrawTimewarp(Actor* thisx, PlayState* play) {
GraphicsContext* gfxCtx = play->state.gfxCtx;
DemoEffect* this = THIS;
@ -287,12 +303,12 @@ void func_808CDFF8(Actor* thisx, PlayState* play) {
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_25);
Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY);
SkelCurve_Draw(&this->actor, play, &this->skelCurve, func_808CDE78, NULL, 1, &this->actor);
SkelCurve_Draw(&this->actor, play, &this->skelCurve, DemoEffect_OverrideLimbDrawTimewarp, NULL, 1, &this->actor);
CLOSE_DISPS(gfxCtx);
}
void func_808CE078(Actor* thisx, PlayState* play2) {
void DemoEffect_DrawLight(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
DemoEffect* this = THIS;
s16 zRot = (this->timer * 0x400) & 0xFFFF;

View File

@ -11,15 +11,16 @@ typedef void (*DemoEffectActionFunc)(struct DemoEffect*, PlayState*);
#define DEMO_EFFECT_GET_TYPE(thisx) ((thisx)->params & 0xFF)
typedef enum {
/* 0 */ DEMO_EFFECT_TYPE_0,
/* 1 */ DEMO_EFFECT_TYPE_1,
/* 2 */ DEMO_EFFECT_TYPE_2,
/* 3 */ DEMO_EFFECT_TYPE_3,
/* 4 */ DEMO_EFFECT_TYPE_4,
/* 5 */ DEMO_EFFECT_TYPE_5,
/* 6 */ DEMO_EFFECT_TYPE_6,
/* 7 */ DEMO_EFFECT_TYPE_7,
/* 8 */ DEMO_EFFECT_TYPE_8
/* 0 */ DEMO_EFFECT_TIMEWARP_TIMEBLOCK_LARGE,
/* 1 */ DEMO_EFFECT_TIMEWARP_TIMEBLOCK_SMALL,
/* 2 */ DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_LARGE,
/* 3 */ DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_VERY_LARGE,
/* 4 */ DEMO_EFFECT_TYPE_LIGHT_BASE,
/* 4 */ DEMO_EFFECT_TYPE_LIGHT_DARK_YELLOW = DEMO_EFFECT_TYPE_LIGHT_BASE,
/* 5 */ DEMO_EFFECT_TYPE_LIGHT_PINK,
/* 6 */ DEMO_EFFECT_TYPE_LIGHT_GREEN,
/* 7 */ DEMO_EFFECT_TYPE_LIGHT_BLUE,
/* 8 */ DEMO_EFFECT_TYPE_LIGHT_YELLOW // Unused
} DemoEffectType;
typedef struct DemoEffect {

View File

@ -1,7 +1,7 @@
/*
* File: z_demo_getitem.c
* Overlay: ovl_Demo_Getitem
* Description: Cutscene objectIndex for Great Fairy's Mask and Great Fairy's Sword
* Description: Cutscene objects for Great Fairy's Mask and Great Fairy's Sword
*/
#include "z_demo_getitem.h"
@ -14,8 +14,8 @@ void DemoGetitem_Init(Actor* thisx, PlayState* play);
void DemoGetitem_Destroy(Actor* thisx, PlayState* play);
void DemoGetitem_Update(Actor* thisx, PlayState* play);
void func_80A4FB10(DemoGetitem* this, PlayState* play);
void func_80A4FB68(DemoGetitem* this, PlayState* play2);
void DemoGetitem_Wait(DemoGetitem* this, PlayState* play);
void DemoGetitem_PerformCutsceneActions(DemoGetitem* this, PlayState* play);
void DemoGetitem_Draw(Actor* thisx, PlayState* play);
ActorInit Demo_Getitem_InitVars = {
@ -36,20 +36,27 @@ static s16 sGetItemDraws[] = { GID_MASK_GREAT_FAIRY, GID_SWORD_GREAT_FAIRY };
static u16 sCueTypes[] = { CS_CMD_ACTOR_CUE_110, CS_CMD_ACTOR_CUE_566 };
typedef enum GreatFairyRewardItem {
/* 0 */ DEMOGETITEM_ITEM_MASK_GREAT_FAIRY,
/* 1 */ DEMOGETITEM_ITEM_SWORD_GREAT_FAIRY
} GreatFairyRewardItem;
void DemoGetitem_Init(Actor* thisx, PlayState* play) {
s32 pad;
s32 objectIndex;
s32 itemIndex;
DemoGetitem* this = THIS;
itemIndex = 0;
if (DEMOGETITEM_GET_F(thisx) == 1) {
itemIndex = 1;
itemIndex = DEMOGETITEM_ITEM_MASK_GREAT_FAIRY;
if (DEMOGETITEM_GET_F(&this->actor) == 1) {
itemIndex = DEMOGETITEM_ITEM_SWORD_GREAT_FAIRY;
}
Actor_SetScale(&this->actor, 0.25f);
this->actionFunc = func_80A4FB10;
this->item = sGetItemDraws[itemIndex];
this->actionFunc = DemoGetitem_Wait;
this->getItemDrawId = sGetItemDraws[itemIndex];
this->cueType = sCueTypes[itemIndex];
objectIndex = Object_GetIndex(&play->objectCtx, sObjectBankIndices[itemIndex]);
if (objectIndex < 0) {
Actor_Kill(&this->actor);
@ -62,22 +69,23 @@ void DemoGetitem_Init(Actor* thisx, PlayState* play) {
void DemoGetitem_Destroy(Actor* thisx, PlayState* play) {
}
void func_80A4FB10(DemoGetitem* this, PlayState* play) {
void DemoGetitem_Wait(DemoGetitem* this, PlayState* play) {
if (Object_IsLoaded(&play->objectCtx, this->objectIndex)) {
this->actor.draw = NULL;
this->actor.objBankIndex = this->objectIndex;
this->actionFunc = func_80A4FB68;
this->actionFunc = DemoGetitem_PerformCutsceneActions;
}
}
void func_80A4FB68(DemoGetitem* this, PlayState* play2) {
PlayState* play = play2;
u16 sp22 = (play->gameplayFrames * 1000) & 0xFFFF;
void DemoGetitem_PerformCutsceneActions(DemoGetitem* this, PlayState* play) {
s32 pad;
u16 bobPhase = (play->gameplayFrames * 1000) % 0x10000;
if (Cutscene_IsCueInChannel(play, this->cueType)) {
if (play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id != 4) {
this->actor.shape.yOffset = 0.0f;
}
switch (play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id) {
case 2:
this->actor.draw = DemoGetitem_Draw;
@ -92,7 +100,7 @@ void func_80A4FB68(DemoGetitem* this, PlayState* play2) {
case 4:
this->actor.draw = DemoGetitem_Draw;
Cutscene_ActorTranslateAndYaw(&this->actor, play, Cutscene_GetCueChannel(play, this->cueType));
this->actor.shape.yOffset = Math_SinS(sp22) * 15.0f;
this->actor.shape.yOffset = Math_SinS(bobPhase) * 15.0f;
break;
default:
@ -115,5 +123,5 @@ void DemoGetitem_Draw(Actor* thisx, PlayState* play) {
func_800B8050(&this->actor, play, 0);
func_800B8118(&this->actor, play, 0);
GetItem_Draw(play, this->item);
GetItem_Draw(play, this->getItemDrawId);
}

View File

@ -11,7 +11,7 @@ typedef void (*DemoGetitemActionFunc)(struct DemoGetitem*, PlayState*);
typedef struct DemoGetitem {
/* 0x000 */ Actor actor;
/* 0x144 */ s16 item;
/* 0x144 */ s16 getItemDrawId;
/* 0x146 */ u16 cueType;
/* 0x148 */ s8 objectIndex;
/* 0x14C */ DemoGetitemActionFunc actionFunc;

View File

@ -539,7 +539,8 @@ void EnBox_Open(EnBox* this, PlayState* play) {
Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_ELFORG, this->dyna.actor.world.pos.x,
this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.world.rot.x,
this->dyna.actor.world.rot.y, this->dyna.actor.world.rot.z,
STRAY_FAIRY_PARAMS(ENBOX_GET_CHEST_FLAG(&this->dyna.actor), 0, STRAY_FAIRY_TYPE_CHEST));
STRAY_FAIRY_PARAMS(ENBOX_GET_CHEST_FLAG(&this->dyna.actor), STRAY_FAIRY_AREA_CLOCK_TOWN,
STRAY_FAIRY_TYPE_CHEST));
} else if (this->movementFlags & ENBOX_MOVE_0x40) {
this->movementFlags &= ~ENBOX_MOVE_0x40;
}

View File

@ -16,8 +16,8 @@ void EnDyExtra_Destroy(Actor* thisx, PlayState* play);
void EnDyExtra_Update(Actor* thisx, PlayState* play);
void EnDyExtra_Draw(Actor* thisx, PlayState* play);
void func_80A61334(EnDyExtra* this, PlayState* play);
void func_80A613C8(EnDyExtra* this, PlayState* play);
void EnDyExtra_WaitForTrigger(EnDyExtra* this, PlayState* play);
void EnDyExtra_Fall(EnDyExtra* this, PlayState* play);
ActorInit En_Dy_Extra_InitVars = {
ACTOR_EN_DY_EXTRA,
@ -41,35 +41,35 @@ void EnDyExtra_Init(Actor* thisx, PlayState* play) {
this->actor.scale.x = 0.025f;
this->actor.scale.y = 0.039f;
this->actor.scale.z = 0.025f;
this->unk160 = this->actor.world.pos;
this->initPos = this->actor.world.pos;
this->actor.gravity = -0.2f;
this->unk150 = 1.0f;
this->unk14C = 0x3C;
this->actionFunc = func_80A61334;
this->alphaScale = 1.0f;
this->timer = 60;
this->actionFunc = EnDyExtra_WaitForTrigger;
}
void func_80A61334(EnDyExtra* this, PlayState* play) {
void EnDyExtra_WaitForTrigger(EnDyExtra* this, PlayState* play) {
Math_ApproachF(&this->actor.gravity, 0.0f, 0.1f, 0.005f);
if (this->actor.world.pos.y < -85.0f) {
this->actor.velocity.y = 0.0f;
}
if ((this->unk14C == 0) && (this->unk14A != 0)) {
this->unk14C = 0x32;
this->actionFunc = func_80A613C8;
if ((this->timer == 0) && this->trigger) {
this->timer = 50;
this->actionFunc = EnDyExtra_Fall;
}
}
void func_80A613C8(EnDyExtra* this, PlayState* play) {
void EnDyExtra_Fall(EnDyExtra* this, PlayState* play) {
Math_ApproachF(&this->actor.gravity, 0.0f, 0.1f, 0.005f);
if ((this->unk14C == 0) || (this->unk150 < 0.02f)) {
if ((this->timer == 0) || (this->alphaScale < 0.02f)) {
Actor_Kill(&this->actor);
return;
}
this->unk150 -= 0.02f;
this->alphaScale -= 0.02f;
if (this->actor.world.pos.y < -85.0f) {
this->actor.velocity.y = 0.0f;
@ -79,40 +79,40 @@ void func_80A613C8(EnDyExtra* this, PlayState* play) {
void EnDyExtra_Update(Actor* thisx, PlayState* play) {
EnDyExtra* this = THIS;
DECR(this->unk14C);
DECR(this->timer);
Actor_PlaySfx(&this->actor, NA_SE_PL_SPIRAL_HEAL_BEAM - SFX_FLAG);
this->actionFunc(this, play);
Actor_MoveWithGravity(&this->actor);
}
static Color_RGBA8 D_80A61740[] = {
static Color_RGBA8 sPrimColors[] = {
{ 255, 255, 170, 255 }, { 255, 170, 255, 255 }, { 255, 255, 170, 255 },
{ 170, 255, 255, 255 }, { 255, 255, 170, 255 },
};
static Color_RGBA8 D_80A61754[] = {
static Color_RGBA8 sEnvColors[] = {
{ 255, 100, 0, 255 }, { 255, 0, 100, 255 }, { 100, 255, 0, 255 }, { 0, 100, 255, 255 }, { 255, 230, 0, 255 }
};
static u8 D_80A61768[] = {
2, 1, 1, 2, 0, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2, 0, 0,
static u8 sAlphaTypeIndices[] = {
2, 1, 1, 2, 0, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2, 0,
};
void EnDyExtra_Draw(Actor* thisx, PlayState* play) {
EnDyExtra* this = THIS;
s32 pad;
EnDyExtra* this = THIS;
GraphicsContext* gfxCtx = play->state.gfxCtx;
Vtx* vertices = Lib_SegmentedToVirtual(object_dy_obj_Vtx_00DD40);
Vtx* vertices = Lib_SegmentedToVirtual(gGreatFairySpiralBeamVtx);
s32 i;
u8 unk[3];
u8 alphas[3];
unk[0] = 0.0f;
unk[1] = (s8)(this->unk150 * 240.0f);
unk[2] = (s8)(this->unk150 * 255.0f);
alphas[0] = 0.0f;
alphas[1] = (s32)(this->alphaScale * 240.0f);
alphas[2] = (s32)(this->alphaScale * 255.0f);
for (i = 0; i < 27; i++) {
if (D_80A61768[i]) {
vertices[i].v.cn[3] = unk[D_80A61768[i]];
for (i = 0; i < ARRAY_COUNT(sAlphaTypeIndices); i++) {
if (sAlphaTypeIndices[i]) {
vertices[i].v.cn[3] = alphas[sAlphaTypeIndices[i]];
}
}
@ -124,10 +124,10 @@ void EnDyExtra_Draw(Actor* thisx, PlayState* play) {
play->state.frames * -8, 0x10, 0x10));
gDPPipeSync(POLY_XLU_DISP++);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, D_80A61740[this->type].r, D_80A61740[this->type].g,
D_80A61740[this->type].b, 255);
gDPSetEnvColor(POLY_XLU_DISP++, D_80A61754[this->type].r, D_80A61754[this->type].g, D_80A61754[this->type].b, 128);
gSPDisplayList(POLY_XLU_DISP++, object_dy_obj_DL_00DEF0);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, sPrimColors[this->type].r, sPrimColors[this->type].g,
sPrimColors[this->type].b, 255);
gDPSetEnvColor(POLY_XLU_DISP++, sEnvColors[this->type].r, sEnvColors[this->type].g, sEnvColors[this->type].b, 128);
gSPDisplayList(POLY_XLU_DISP++, gGreatFairySpiralBeamDL);
CLOSE_DISPS(gfxCtx);
}

View File

@ -11,12 +11,11 @@ typedef struct EnDyExtra {
/* 0x000 */ Actor actor;
/* 0x144 */ EnDyExtraActionFunc actionFunc;
/* 0x148 */ s16 type;
/* 0x14A */ s16 unk14A;
/* 0x14C */ s16 unk14C;
/* 0x14E */ s16 unk14E;
/* 0x150 */ f32 unk150;
/* 0x154 */ UNK_TYPE1 unk154[0xC];
/* 0x160 */ Vec3f unk160;
/* 0x14A */ s16 trigger;
/* 0x14C */ s16 timer;
/* 0x150 */ f32 alphaScale;
/* 0x154 */ Vec3f scale; // not used, leftover from OoT
/* 0x160 */ Vec3f initPos; // set and not used
} EnDyExtra; // size = 0x16C
#endif // Z_EN_DY_EXTRA_H

View File

@ -744,7 +744,7 @@ void func_8088E0F0(EnElf* this, PlayState* play) {
if (this->unk_250 < 2.0f) {
this->unk_250 += 0.1f;
} else {
gSaveContext.healthAccumulator = 160;
gSaveContext.healthAccumulator = 0xA0;
this->unk_246++;
}
break;

View File

@ -73,10 +73,11 @@ void EnElfbub_Init(Actor* thisx, PlayState* play) {
Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
childActor = Actor_SpawnAsChild(
&play->actorCtx, &this->actor, play, ACTOR_EN_ELFORG, this->actor.world.pos.x, this->actor.world.pos.y + 12.0f,
this->actor.world.pos.z, this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z,
STRAY_FAIRY_PARAMS(ENELFBUB_GET_SWITCHFLAG(&this->actor), 0, STRAY_FAIRY_TYPE_BUBBLE));
childActor = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_ELFORG, this->actor.world.pos.x,
this->actor.world.pos.y + 12.0f, this->actor.world.pos.z, this->actor.world.rot.x,
this->actor.world.rot.y, this->actor.world.rot.z,
STRAY_FAIRY_PARAMS(ENELFBUB_GET_SWITCHFLAG(&this->actor),
STRAY_FAIRY_AREA_CLOCK_TOWN, STRAY_FAIRY_TYPE_BUBBLE));
if (childActor != NULL) {
childActor->parent = &this->actor;
}
@ -140,6 +141,7 @@ void EnElfbub_Idle(EnElfbub* this, PlayState* play) {
void EnElfbub_Update(Actor* thisx, PlayState* play) {
EnElfbub* this = THIS;
Collider_UpdateCylinder(&this->actor, &this->collider);
this->actionFunc(this, play);
Actor_SetFocus(&this->actor, this->actor.shape.yOffset);

View File

@ -1,11 +1,38 @@
/*
* File: z_en_elfgrp.c
/**
* @file z_en_elfgrp.c
* Overlay: ovl_En_Elfgrp
* Description: Group of Stray Fairies in Fairy Fountain
* Description: Manager for group of Stray Fairies and Great Fairy in Fairy's Fountains
*
* There are many different quantities associated to the Stray Fairies in each of the 3 places (missing, in the
* Fountain, held by Player)
* - Total number of fairies (always 25 in the original game)
* - Original number in the Fountain (24 for Clock Town Fairy Fountain, 10 for the other 4)
* - Current number in the Fountain (bitpacked in Fountain scene flags, see below)
* - Total number found (stored in save context)
* - Current number held (i.e. found but not returned)
*
* The permanentSceneFlags for Fairy Fountains used in this actor are of the form
* ```c
* struct {
* u32 clockTown : 1;
* u32 fountains[4] : 5;
* } FairyFountains;
* ```
* where arg1 is:
* - 0: Clock Town
* - 1: Woodfall,
* - 2: Snowhead,
* - 3: Great Bay,
* - 4: Ikana
*
* Clock Town is handled separately, and then the fountains are looked up with manual array indexing
*
* @note Clock Town is handled separately in a number of places
*/
#include "z_en_elfgrp.h"
#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h"
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#define FLAGS (ACTOR_FLAG_10)
@ -17,24 +44,28 @@ void EnElfgrp_Init(Actor* thisx, PlayState* play);
void EnElfgrp_Destroy(Actor* thisx, PlayState* play);
void EnElfgrp_Update(Actor* thisx, PlayState* play);
s32 func_80A39BD0(PlayState* play, s32 arg2);
s32 func_80A39C1C(PlayState* play, s32 arg1);
void func_80A39DC8(EnElfgrp* this, PlayState* play, s32 arg2, s32 arg3);
void func_80A3A0AC(EnElfgrp* this, PlayState* play);
void func_80A3A0F4(EnElfgrp* this, PlayState* play);
void func_80A3A210(EnElfgrp* this, PlayState* play);
void func_80A3A274(EnElfgrp* this, PlayState* play);
s32 EnElfgrp_GetHeldFairiesCount(PlayState* play, s32 type);
s32 EnElfgrp_GetFountainFairiesCount(PlayState* play, s32 type);
void EnElfgrp_SpawnStrayFairies(EnElfgrp* this, PlayState* play, s32 count, s32 fairyType);
void func_80A3A398(EnElfgrp* this, PlayState* play);
void func_80A3A484(EnElfgrp* this, PlayState* play);
void func_80A3A4AC(EnElfgrp* this, PlayState* play);
void func_80A3A520(EnElfgrp* this, PlayState* play);
void func_80A3A600(EnElfgrp* this, PlayState* play);
void func_80A3A610(EnElfgrp* this, PlayState* play);
void func_80A3A6F4(EnElfgrp* this, PlayState* play);
void func_80A3A77C(EnElfgrp* this, PlayState* play);
void EnElfgrp_DoNothing(EnElfgrp* this, PlayState* play);
void func_80A3A7FC(EnElfgrp* this, PlayState* play);
void func_80A3A8F8(EnElfgrp* this, PlayState* play);
// State flags
#define ELFGRP_STATE_0 (1 << 0)
#define ELFGRP_STATE_1 (1 << 1)
#define ELFGRP_STATE_2 (1 << 2)
#define ELFGRP_STATE_3 (1 << 3)
#define ELFGRP_STATE_4 (1 << 4)
// Used for the type in EnElfgrp_SpawnStrayFairies
typedef enum ElfgrpSpawnedFairyTypes {
/* 0 */ SPAWNED_STRAY_FAIRY_TYPE_PRESENT, // STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN
/* 1 */ SPAWNED_STRAY_FAIRY_TYPE_RETURNING // STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN
} ElfgrpSpawnedFairyTypes;
ActorInit En_Elfgrp_InitVars = {
ACTOR_EN_ELFGRP,
ACTORCAT_PROP,
@ -47,7 +78,15 @@ ActorInit En_Elfgrp_InitVars = {
(ActorFunc)NULL,
};
void func_80A396B0(EnElfgrp* this, s32 numCutscenes) {
/**
* Set the actor's cutscene id to a later one, or -1 if run out.
*
* @note This is only expected to be called in Init when this actor has the first cutscene set, but can also work for
* later cutscenes if \p numCutscenes is set correcly.
*
* @param numCutscenes Number of cutscenes in the list to skip forward to set this one.
*/
void EnElfgrp_SetCutscene(EnElfgrp* this, s32 numCutscenes) {
while (numCutscenes > 0) {
if (this->actor.csId == CS_ID_NONE) {
break;
@ -61,113 +100,118 @@ void func_80A396B0(EnElfgrp* this, s32 numCutscenes) {
void EnElfgrp_Init(Actor* thisx, PlayState* play) {
s32 pad;
EnElfgrp* this = THIS;
s32 sp24;
s32 numberInFountain;
this->unk_147 = ENELFGRP_GET(&this->actor);
this->type = ENELFGRP_GET_TYPE(&this->actor);
this->unk_148 = 0;
this->unk_14A = 0;
this->stateFlags = 0;
this->actor.focus.pos.y += 40.0f;
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
switch (this->unk_147) {
case ENELFGRP_1:
case ENELFGRP_2:
case ENELFGRP_3:
case ENELFGRP_4:
this->unk_148 = this->unk_147 - 1;
sp24 = func_80A39C1C(play, this->unk_147);
this->unk_146 = 1 << this->unk_147;
switch (this->type) {
case ENELFGRP_TYPE_POWER:
case ENELFGRP_TYPE_WISDOM:
case ENELFGRP_TYPE_COURAGE:
case ENELFGRP_TYPE_KINDNESS:
this->unk_148 = this->type - 1;
numberInFountain = EnElfgrp_GetFountainFairiesCount(play, this->type);
this->talkedOnceFlag = 1 << this->type;
if (sp24 < 25) {
func_80A39DC8(this, play, sp24, 0);
if (numberInFountain < STRAY_FAIRY_TOTAL) {
EnElfgrp_SpawnStrayFairies(this, play, numberInFountain, SPAWNED_STRAY_FAIRY_TYPE_PRESENT);
}
if (sp24 >= 25) {
if (numberInFountain >= STRAY_FAIRY_TOTAL) {
this->actionFunc = func_80A3A520;
func_80A396B0(this, 2);
return;
EnElfgrp_SetCutscene(this, 2);
break;
}
if ((func_80A39BD0(play, this->unk_147) + sp24) >= 25) {
if ((EnElfgrp_GetHeldFairiesCount(play, this->type) + numberInFountain) >= STRAY_FAIRY_TOTAL) {
this->actionFunc = func_80A3A398;
switch (this->unk_147) {
case ENELFGRP_1:
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_23_02)) {
func_80A396B0(this, 1);
switch (this->type) {
case ENELFGRP_TYPE_POWER:
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK)) {
EnElfgrp_SetCutscene(this, 1);
} else {
this->unk_14A |= 4;
this->stateFlags |= ELFGRP_STATE_2;
}
break;
case ENELFGRP_2:
case ENELFGRP_TYPE_WISDOM:
if (gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired == true) {
func_80A396B0(this, 1);
EnElfgrp_SetCutscene(this, 1);
}
break;
case ENELFGRP_3:
case ENELFGRP_TYPE_COURAGE:
if (gSaveContext.save.saveInfo.playerData.doubleDefense) {
func_80A396B0(this, 1);
EnElfgrp_SetCutscene(this, 1);
}
break;
case ENELFGRP_4:
case ENELFGRP_TYPE_KINDNESS:
if (INV_CONTENT(ITEM_SWORD_GREAT_FAIRY) == ITEM_SWORD_GREAT_FAIRY) {
func_80A396B0(this, 1);
EnElfgrp_SetCutscene(this, 1);
} else {
this->unk_14A |= 0x10;
this->stateFlags |= ELFGRP_STATE_4;
}
break;
default:
break;
}
} else if (func_80A39BD0(play, this->unk_147)) {
} else if (EnElfgrp_GetHeldFairiesCount(play, this->type)) {
this->actionFunc = func_80A3A7FC;
this->actor.textId = (this->unk_147 * 3) + 0x581;
this->actor.textId = (this->type * 3) + 0x581;
} else {
this->actionFunc = func_80A3A8F8;
if ((gSaveContext.save.saveInfo.weekEventReg[9] & this->unk_146)) {
this->actor.textId = (this->unk_147 * 3) + 0x580;
if ((gSaveContext.save.saveInfo.weekEventReg[9] & this->talkedOnceFlag)) { // talked for first time
this->actor.textId = (this->type * 3) + 0x580;
} else {
this->actor.textId = (this->unk_147 * 3) + 0x57F;
this->actor.textId = (this->type * 3) + 0x57F;
}
}
break;
default:
sp24 = func_80A39C1C(play, 0);
this->unk_146 = ENELFGRP_1;
if (sp24 >= 25) {
default: // ENELFGRP_TYPE_MAGIC
numberInFountain = EnElfgrp_GetFountainFairiesCount(play, ENELFGRP_TYPE_MAGIC);
this->talkedOnceFlag = 1 << ENELFGRP_TYPE_MAGIC;
if (numberInFountain >= STRAY_FAIRY_TOTAL) {
this->actionFunc = func_80A3A520;
if ((this->actor.home.rot.z != 0) && Flags_GetSwitch(play, this->actor.home.rot.z)) {
this->actionFunc = func_80A3A600;
if ((ENELFGRP_GET_SWITCHFLAG_ROT(&this->actor) != 0) &&
Flags_GetSwitch(play, ENELFGRP_GET_SWITCHFLAG_ROT(&this->actor))) {
this->actionFunc = EnElfgrp_DoNothing;
} else if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) {
func_80A396B0(this, 4);
EnElfgrp_SetCutscene(this, 4);
} else if (INV_CONTENT(ITEM_MASK_DEKU) != ITEM_MASK_DEKU) {
func_80A396B0(this, 5);
EnElfgrp_SetCutscene(this, 5);
} else {
this->unk_14A |= 2;
func_80A396B0(this, 6);
this->stateFlags |= ELFGRP_STATE_1;
EnElfgrp_SetCutscene(this, 6);
}
} else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_08_80)) {
func_80A39DC8(this, play, 24, 0);
EnElfgrp_SpawnStrayFairies(this, play, STRAY_FAIRY_TOTAL - 1, SPAWNED_STRAY_FAIRY_TYPE_PRESENT);
this->actionFunc = func_80A3A398;
if (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU) {
if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) {
func_80A396B0(this, 2);
EnElfgrp_SetCutscene(this, 2);
} else {
func_80A396B0(this, 3);
this->unk_14A |= 2;
EnElfgrp_SetCutscene(this, 3);
this->stateFlags |= ELFGRP_STATE_1;
}
} else if (gSaveContext.save.saveInfo.playerData.isMagicAcquired == true) {
func_80A396B0(this, 1);
EnElfgrp_SetCutscene(this, 1);
}
} else {
func_80A39DC8(this, play, 24, 0);
EnElfgrp_SpawnStrayFairies(this, play, STRAY_FAIRY_TOTAL - 1, SPAWNED_STRAY_FAIRY_TYPE_PRESENT);
this->actionFunc = func_80A3A8F8;
if ((gSaveContext.save.saveInfo.weekEventReg[9] & this->unk_146)) {
if ((gSaveContext.save.saveInfo.weekEventReg[9] & this->talkedOnceFlag)) {
this->actor.textId = 0x580;
} else {
this->actor.textId = 0x578;
@ -181,116 +225,119 @@ void EnElfgrp_Init(Actor* thisx, PlayState* play) {
void EnElfgrp_Destroy(Actor* thisx, PlayState* play) {
}
s32 func_80A39BD0(PlayState* play, s32 arg2) {
if ((arg2 < 1) || (arg2 >= 5)) {
// Number of Stray Fairies currently held by Player
s32 EnElfgrp_GetHeldFairiesCount(PlayState* play, s32 type) {
if ((type <= ENELFGRP_TYPE_MAGIC) || (type > ENELFGRP_TYPE_KINDNESS)) {
return 0;
}
return (((void)0, gSaveContext.save.saveInfo.inventory.strayFairies[arg2 - 1]) - func_80A39C1C(play, arg2)) + 10;
// Number in fountain originally + total number collected - number currently in fountain
return (STRAY_FAIRY_TOTAL - STRAY_FAIRY_SCATTERED_TOTAL) +
((void)0, gSaveContext.save.saveInfo.inventory.strayFairies[type - 1]) -
EnElfgrp_GetFountainFairiesCount(play, type);
}
s32 func_80A39C1C(PlayState* play, s32 arg1) {
// the permanentSceneFlags access here is in the form
// struct {
// u32 clockTown : 1;
// u32 fountains[4] : 5;
// } FairyFountains;
// where arg1 is:
// 0: clocktown
// 1: woodfall,
// 2: snowhead,
// 3: great bay,
// 4: stone tower
// clocktown is handled separately, and then the fountains are looked up as array indexing
// Number of Stray Fairies in currently in Fountain
s32 EnElfgrp_GetFountainFairiesCount(PlayState* play, s32 type) {
s32 numberInFountain;
s32 temp_v1;
if ((arg1 < 0) || (arg1 >= 5)) {
if ((type < ENELFGRP_TYPE_MAGIC) || (type > ENELFGRP_TYPE_KINDNESS)) {
return 0;
}
if (arg1 == 0) {
if (type == ENELFGRP_TYPE_MAGIC) {
if (gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 & 1) {
return 25;
return STRAY_FAIRY_TOTAL;
} else {
return STRAY_FAIRY_TOTAL - 1;
}
return 24;
}
temp_v1 = (gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 >> (((arg1 - 1) * 5) + 1)) & 0x1F;
if (temp_v1 < 10) {
temp_v1 = 10;
} else if (temp_v1 > 25) {
temp_v1 = 25;
numberInFountain =
(gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 >> (((type - 1) * 5) + 1)) & 0x1F;
if (numberInFountain < STRAY_FAIRY_TOTAL - STRAY_FAIRY_SCATTERED_TOTAL) {
numberInFountain = STRAY_FAIRY_TOTAL - STRAY_FAIRY_SCATTERED_TOTAL;
} else if (numberInFountain > STRAY_FAIRY_TOTAL) {
numberInFountain = STRAY_FAIRY_TOTAL;
}
return temp_v1;
return numberInFountain;
}
void func_80A39CD4(PlayState* play, s32 arg1, s32 arg2) {
if ((arg1 < 0) || (arg1 > 4) || (arg2 < 10) || (arg2 > 25)) {
// Update number of Stray Fairies in Fountain
void EnElfgrp_SetFountainFairiesCount(PlayState* play, s32 type, s32 newCount) {
if ((type < ENELFGRP_TYPE_MAGIC) || (type > ENELFGRP_TYPE_KINDNESS) ||
(newCount < (STRAY_FAIRY_TOTAL - STRAY_FAIRY_SCATTERED_TOTAL)) || (newCount > STRAY_FAIRY_TOTAL)) {
return;
}
if (arg1 == 0) {
if (arg2 == 25) {
if (type == ENELFGRP_TYPE_MAGIC) {
if (newCount == STRAY_FAIRY_TOTAL) {
gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 |= 1;
} else {
gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 &= ~1;
}
} else {
gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 &= ~(0x1F << ((arg1 * 5) - 4));
gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 |= arg2 << ((arg1 * 5) - 4);
gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 &= ~(0x1F << ((type * 5) - 4));
gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 |= newCount << ((type * 5) - 4);
}
}
void func_80A39DC8(EnElfgrp* this, PlayState* play, s32 arg2, s32 arg3) {
void EnElfgrp_SpawnStrayFairies(EnElfgrp* this, PlayState* play, s32 count, s32 fairyType) {
s32 pad;
s32 i;
Actor* elforg;
s32 params;
Vec3f sp6C;
Actor* strayFairy;
s32 strayFairyParams;
Vec3f spawnCenterPos;
Player* player = GET_PLAYER(play);
if (arg3 == 0) {
this->unk_14A |= 8;
if (fairyType == 0) {
this->stateFlags |= ELFGRP_STATE_3;
}
if (arg3 == 0) {
sp6C = this->actor.world.pos;
sp6C.y += 20.0f;
params = STRAY_FAIRY_PARAMS(0, this->unk_147, STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN);
if (fairyType == 0) {
spawnCenterPos = this->actor.world.pos;
spawnCenterPos.y += 20.0f;
strayFairyParams = STRAY_FAIRY_PARAMS(0, this->type, STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN);
} else {
sp6C = player->actor.world.pos;
sp6C.y += 20.0f;
params = STRAY_FAIRY_PARAMS(0, this->unk_147, STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN);
spawnCenterPos = player->actor.world.pos;
spawnCenterPos.y += 20.0f;
strayFairyParams = STRAY_FAIRY_PARAMS(0, this->type, STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN);
}
for (i = 0; i < arg2; i++) {
elforg = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, Rand_CenteredFloat(20.0f) + sp6C.x, sp6C.y,
Rand_CenteredFloat(20.0f) + sp6C.z, 0, 0, 0, params);
if (elforg == NULL) {
for (i = 0; i < count; i++) {
strayFairy =
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, Rand_CenteredFloat(20.0f) + spawnCenterPos.x,
spawnCenterPos.y, Rand_CenteredFloat(20.0f) + spawnCenterPos.z, 0, 0, 0, strayFairyParams);
if (strayFairy == NULL) {
continue;
}
elforg->home.pos.x = this->actor.home.pos.x;
elforg->home.pos.y = this->actor.home.pos.y + 20.0f;
elforg->home.pos.z = this->actor.home.pos.z;
strayFairy->home.pos.x = this->actor.home.pos.x;
strayFairy->home.pos.y = this->actor.home.pos.y + 20.0f;
strayFairy->home.pos.z = this->actor.home.pos.z;
}
}
s32 func_80A39F50(PlayState* play) {
/**
* Tell any spawned Stray Fairies to come to the Fountain center.
*
* @return s32 always 0
*/
s32 EnElfgrp_SummonStrayFairies(PlayState* play) {
Actor* itemAction = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first;
EnElforg* elfOrg;
EnElforg* strayFairy;
while (itemAction != NULL) {
if ((itemAction->id != ACTOR_EN_ELFORG) ||
((STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN) &&
(STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN))) {
(STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN))) {
itemAction = itemAction->next;
continue;
}
elfOrg = (EnElforg*)itemAction;
if (!(elfOrg->strayFairyFlags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME)) {
elfOrg->strayFairyFlags |= STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME;
strayFairy = (EnElforg*)itemAction;
if (!(strayFairy->strayFairyFlags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME)) {
strayFairy->strayFairyFlags |= STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME;
}
itemAction = itemAction->next;
}
@ -298,50 +345,58 @@ s32 func_80A39F50(PlayState* play) {
return 0;
}
s32 func_80A39FBC(PlayState* play) {
/**
* Make the Stray Fairies in the fountain spin quickly when healing Player.
*
* @return s32 time to spend in healing action.
*/
s32 EnElfgrp_SpinStrayFairies(PlayState* play) {
Actor* itemAction = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first;
EnElforg* elfOrg;
s32 phi_v1 = 30;
EnElforg* strayFairy;
s32 timer = 30;
while (itemAction != NULL) {
if ((itemAction->id != ACTOR_EN_ELFORG) ||
((STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN) &&
(STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN))) {
(STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN))) {
itemAction = itemAction->next;
continue;
}
elfOrg = (EnElforg*)itemAction;
if (!(elfOrg->strayFairyFlags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN)) {
elfOrg->strayFairyFlags |= STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN;
if (phi_v1 >= 100) {
return phi_v1;
strayFairy = (EnElforg*)itemAction;
if (!(strayFairy->strayFairyFlags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN)) {
strayFairy->strayFairyFlags |= STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN;
if (timer >= 100) {
return timer;
}
elfOrg->secondaryTimer = phi_v1;
phi_v1 += 5;
strayFairy->secondaryTimer = timer;
timer += 5;
}
itemAction = itemAction->next;
}
return phi_v1;
return timer;
}
void func_80A3A044(PlayState* play) {
/**
* Tell the Stray Fairies to disappear, before reviving the Great Fairy
*/
void EnElfgrp_VanishStrayFairies(PlayState* play) {
Actor* itemAction = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first;
EnElforg* elfOrg;
EnElforg* strayFairy;
while (itemAction != NULL) {
if ((itemAction->id != ACTOR_EN_ELFORG) ||
((STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN) &&
(STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN))) {
(STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN))) {
itemAction = itemAction->next;
continue;
}
elfOrg = (EnElforg*)itemAction;
elfOrg->actor.home.rot.x = 0x14;
elfOrg->strayFairyFlags |= STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS;
strayFairy = (EnElforg*)itemAction;
STRAY_FAIRY_SPARKLE_COUNT(&strayFairy->actor) = 20;
strayFairy->strayFairyFlags |= STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS;
itemAction = itemAction->next;
}
@ -349,68 +404,70 @@ void func_80A3A044(PlayState* play) {
void func_80A3A0AC(EnElfgrp* this, PlayState* play) {
if (!Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_100)) {
this->actionFunc = func_80A3A600;
this->actionFunc = EnElfgrp_DoNothing;
CutsceneManager_Stop(this->actor.csId);
}
}
void func_80A3A0F4(EnElfgrp* this, PlayState* play) {
if (this->unk_144 == 10) {
if (this->timer == 10) {
Audio_PlaySfx(NA_SE_SY_WHITE_OUT_T);
if (ENELFGRP_GET(&this->actor) < ENELFGRP_4) {
if (ENELFGRP_GET_TYPE(&this->actor) < ENELFGRP_TYPE_KINDNESS) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, this->actor.world.pos.x,
this->actor.world.pos.y + 30.0f, this->actor.world.pos.z, 0, 0, 0,
ENELFGRP_GET(&this->actor) + ENELFGRP_4);
} else {
ENELFGRP_GET_TYPE(&this->actor) + DEMO_EFFECT_TYPE_LIGHT_BASE);
} else { // ENELFGRP_TYPE_KINDNESS
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, this->actor.world.pos.x,
this->actor.world.pos.y + 30.0f, this->actor.world.pos.z, 0, 0, 0, 4);
this->actor.world.pos.y + 30.0f, this->actor.world.pos.z, 0, 0, 0,
DEMO_EFFECT_TYPE_LIGHT_DARK_YELLOW);
}
}
if ((this->unk_144 > 10) && (this->unk_14A & 1)) {
if ((this->timer > 10) && (this->stateFlags & ELFGRP_STATE_0)) {
Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_FAIRY_GROUP_FRY - SFX_FLAG);
}
if (this->unk_144 == 0) {
if (this->timer == 0) {
this->actionFunc = func_80A3A0AC;
}
}
void func_80A3A210(EnElfgrp* this, PlayState* play) {
if (this->unk_144 == 0) {
if (this->timer == 0) {
this->actionFunc = func_80A3A0F4;
func_80A3A044(play);
this->unk_144 = 30;
EnElfgrp_VanishStrayFairies(play);
this->timer = 30;
}
if (this->unk_14A & 1) {
if (this->stateFlags & ELFGRP_STATE_0) {
Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_FAIRY_GROUP_FRY - SFX_FLAG);
}
}
void func_80A3A274(EnElfgrp* this, PlayState* play) {
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_100)) {
if (this->unk_14A & 1) {
if (this->stateFlags & ELFGRP_STATE_0) {
Actor_PlaySfx_Flagged(&this->actor, NA_SE_PL_CHIBI_FAIRY_HEAL - SFX_FLAG);
}
switch (play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_100)]->id) {
case 2:
if (!(this->unk_14A & 1)) {
if (this->unk_147 == ENELFGRP_0) {
func_80A39DC8(this, play, 1, 1);
if (!(this->stateFlags & ELFGRP_STATE_0)) {
if (this->type == ENELFGRP_TYPE_MAGIC) { // Clock Town
EnElfgrp_SpawnStrayFairies(this, play, 1, SPAWNED_STRAY_FAIRY_TYPE_RETURNING);
} else {
func_80A39DC8(this, play, func_80A39BD0(play, this->unk_147), 1);
EnElfgrp_SpawnStrayFairies(this, play, EnElfgrp_GetHeldFairiesCount(play, this->type),
SPAWNED_STRAY_FAIRY_TYPE_RETURNING);
}
this->unk_14A |= 1;
func_80A39CD4(play, this->unk_147, 25);
this->stateFlags |= ELFGRP_STATE_0;
EnElfgrp_SetFountainFairiesCount(play, this->type, STRAY_FAIRY_TOTAL);
}
break;
case 3:
func_80A39F50(play);
EnElfgrp_SummonStrayFairies(play);
this->actionFunc = func_80A3A210;
this->unk_144 = 90;
this->timer = 90;
break;
default:
@ -423,28 +480,30 @@ void func_80A3A398(EnElfgrp* this, PlayState* play) {
if (CutsceneManager_IsNext(this->actor.csId)) {
CutsceneManager_StartWithPlayerCs(this->actor.csId, &this->actor);
this->actionFunc = func_80A3A274;
Flags_UnsetSwitch(play, ENELFGRP_GET_FE00(&this->actor));
if (this->unk_14A & 2) {
Flags_UnsetSwitch(play, ENELFGRP_GET_SWITCHFLAG_PARAMS(&this->actor));
if (this->stateFlags & ELFGRP_STATE_1) {
Item_Give(play, ITEM_MASK_GREAT_FAIRY);
}
if ((this->unk_14A & 4) != 0) {
SET_WEEKEVENTREG(WEEKEVENTREG_23_02);
if (this->stateFlags & ELFGRP_STATE_2) {
SET_WEEKEVENTREG(WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK);
}
if (this->unk_14A & 0x10) {
if (this->stateFlags & ELFGRP_STATE_4) {
Item_Give(play, ITEM_SWORD_GREAT_FAIRY);
}
this->unk_14A &= ~8;
this->stateFlags &= ~ELFGRP_STATE_3;
} else if (this->actor.xzDistToPlayer < 350.0f) {
CutsceneManager_Queue(this->actor.csId);
}
}
void func_80A3A484(EnElfgrp* this, PlayState* play) {
if (this->unk_144 == 0) {
if (this->timer == 0) {
this->actionFunc = func_80A3A0F4;
this->unk_144 = 30;
this->timer = 30;
}
}
@ -454,51 +513,51 @@ void func_80A3A4AC(EnElfgrp* this, PlayState* play) {
if (cueId == 3) {
this->actionFunc = func_80A3A484;
this->unk_144 = 90;
this->timer = 90;
}
}
}
void func_80A3A520(EnElfgrp* this, PlayState* play) {
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_103)) {
this->actionFunc = func_80A3A600;
this->actionFunc = EnElfgrp_DoNothing;
} else if (CutsceneManager_IsNext(this->actor.csId)) {
CutsceneManager_StartWithPlayerCs(this->actor.csId, &this->actor);
this->actionFunc = func_80A3A4AC;
Flags_SetSwitch(play, ENELFGRP_GET_FE00(&this->actor));
Flags_SetSwitch(play, ENELFGRP_GET_SWITCHFLAG_PARAMS(&this->actor));
if (this->unk_14A & 2) {
if (this->stateFlags & ELFGRP_STATE_1) {
Item_Give(play, ITEM_MASK_GREAT_FAIRY);
}
if (this->actor.home.rot.z != 0) {
Flags_SetSwitch(play, this->actor.home.rot.z);
if (ENELFGRP_GET_SWITCHFLAG_ROT(&this->actor) != 0) {
Flags_SetSwitch(play, ENELFGRP_GET_SWITCHFLAG_ROT(&this->actor));
}
} else if (this->actor.xzDistToPlayer < 350.0f) {
CutsceneManager_Queue(this->actor.csId);
}
}
void func_80A3A600(EnElfgrp* this, PlayState* play) {
void EnElfgrp_DoNothing(EnElfgrp* this, PlayState* play) {
}
void func_80A3A610(EnElfgrp* this, PlayState* play) {
void EnElfgrp_HealPlayer(EnElfgrp* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (this->unk_144 == 60) {
if (this->timer == 60) {
Magic_Add(play, MAGIC_FILL_TO_CAPACITY);
gSaveContext.healthAccumulator = 320;
gSaveContext.healthAccumulator = 0x140;
}
if (this->unk_144 > 0) {
if (this->timer > 0) {
player->actor.freezeTimer = 100;
player->stateFlags1 |= PLAYER_STATE1_20000000;
Actor_PlaySfx(&this->actor, NA_SE_EV_FAIRY_GROUP_HEAL - SFX_FLAG);
} else {
player->actor.freezeTimer = 0;
player->stateFlags1 &= ~PLAYER_STATE1_20000000;
this->actionFunc = func_80A3A600;
this->unk_14A |= 8;
this->actionFunc = EnElfgrp_DoNothing;
this->stateFlags |= ELFGRP_STATE_3;
}
}
@ -509,9 +568,9 @@ void func_80A3A6F4(EnElfgrp* this, PlayState* play) {
if (Actor_TextboxIsClosing(&this->actor, play)) {
player->actor.freezeTimer = 100;
player->stateFlags1 |= PLAYER_STATE1_20000000;
this->unk_144 = func_80A39FBC(play);
this->actionFunc = func_80A3A610;
this->unk_14A &= ~8;
this->timer = EnElfgrp_SpinStrayFairies(play);
this->actionFunc = EnElfgrp_HealPlayer;
this->stateFlags &= ~ELFGRP_STATE_3;
}
}
@ -521,25 +580,27 @@ void func_80A3A77C(EnElfgrp* this, PlayState* play) {
player->actor.freezeTimer = 100;
player->stateFlags1 |= PLAYER_STATE1_20000000;
if (Actor_TextboxIsClosing(&this->actor, play)) {
this->unk_144 = func_80A39FBC(play);
this->actionFunc = func_80A3A610;
this->unk_14A &= ~8;
this->timer = EnElfgrp_SpinStrayFairies(play);
this->actionFunc = EnElfgrp_HealPlayer;
this->stateFlags &= ~ELFGRP_STATE_3;
}
}
void func_80A3A7FC(EnElfgrp* this, PlayState* play) {
s32 temp_s0;
s32 curTotalFairies;
if (Actor_ProcessTalkRequest(&this->actor, &play->state)) {
gSaveContext.save.saveInfo.weekEventReg[9] |= this->unk_146;
gSaveContext.save.saveInfo.weekEventReg[9] |= this->talkedOnceFlag;
this->actionFunc = func_80A3A6F4;
temp_s0 = func_80A39BD0(play, this->unk_147);
func_80A39DC8(this, play, temp_s0, 1);
temp_s0 += func_80A39C1C(play, this->unk_147);
if (temp_s0 > 25) {
temp_s0 = 25;
curTotalFairies = EnElfgrp_GetHeldFairiesCount(play, this->type);
EnElfgrp_SpawnStrayFairies(this, play, curTotalFairies, SPAWNED_STRAY_FAIRY_TYPE_RETURNING);
curTotalFairies += EnElfgrp_GetFountainFairiesCount(play, this->type);
if (curTotalFairies > STRAY_FAIRY_TOTAL) {
curTotalFairies = STRAY_FAIRY_TOTAL;
}
func_80A39CD4(play, this->unk_147, temp_s0);
EnElfgrp_SetFountainFairiesCount(play, this->type, curTotalFairies);
} else if (this->actor.xzDistToPlayer < 280.0f) {
this->actor.flags |= ACTOR_FLAG_10000;
Actor_OfferTalk(&this->actor, play, 300.0f);
@ -551,13 +612,13 @@ void func_80A3A8F8(EnElfgrp* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (Actor_ProcessTalkRequest(&this->actor, &play->state)) {
gSaveContext.save.saveInfo.weekEventReg[9] |= this->unk_146;
gSaveContext.save.saveInfo.weekEventReg[9] |= this->talkedOnceFlag;
this->actionFunc = func_80A3A6F4;
return;
}
if (this->unk_147 != ENELFGRP_0) {
if (func_80A39BD0(play, this->unk_147) > 0) {
if (this->type != ENELFGRP_TYPE_MAGIC) {
if (EnElfgrp_GetHeldFairiesCount(play, this->type) > 0) {
this->actionFunc = func_80A3A7FC;
return;
}
@ -570,7 +631,7 @@ void func_80A3A8F8(EnElfgrp* this, PlayState* play) {
player->stateFlags1 |= PLAYER_STATE1_20000000;
Message_StartTextbox(play, this->actor.textId, &this->actor);
this->actionFunc = func_80A3A77C;
gSaveContext.save.saveInfo.weekEventReg[9] |= this->unk_146;
gSaveContext.save.saveInfo.weekEventReg[9] |= this->talkedOnceFlag;
} else {
this->actor.flags |= ACTOR_FLAG_10000;
Actor_OfferTalk(&this->actor, play, 100.0f);
@ -585,11 +646,11 @@ void EnElfgrp_Update(Actor* thisx, PlayState* play) {
this->actionFunc(this, play);
if (this->unk_14A & 8) {
if (this->stateFlags & ELFGRP_STATE_3) {
Actor_PlaySfx(&this->actor, NA_SE_EV_FAIRY_GROUP_FRY - SFX_FLAG);
}
if (this->unk_144 != 0) {
this->unk_144--;
if (this->timer != 0) {
this->timer--;
}
}

View File

@ -2,29 +2,32 @@
#define Z_EN_ELFGRP_H
#include "global.h"
#include "overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
struct EnElfgrp;
typedef void (*EnElfgrpActionFunc)(struct EnElfgrp*, PlayState*);
#define ENELFGRP_GET(thisx) ((thisx)->params & 0xF)
#define ENELFGRP_GET_FE00(thisx) (((thisx)->params & 0xFE00) >> 9)
#define ENELFGRP_GET_TYPE(thisx) ((thisx)->params & 0xF) //!< Same type as Great Fairies
#define ENELFGRP_GET_SWITCHFLAG_PARAMS(thisx) (((thisx)->params & 0xFE00) >> 9)
#define ENELFGRP_GET_SWITCHFLAG_ROT(thisx) ((thisx)->home.rot.z)
typedef enum {
/* 0 */ ENELFGRP_0,
/* 2 */ ENELFGRP_1,
/* 2 */ ENELFGRP_2,
/* 3 */ ENELFGRP_3,
/* 4 */ ENELFGRP_4
} EnElfgrpParam;
typedef enum ElfgrpType {
/* 0 */ ENELFGRP_TYPE_MAGIC = GREAT_FAIRY_TYPE_MAGIC,
/* 1 */ ENELFGRP_TYPE_POWER = GREAT_FAIRY_TYPE_POWER,
/* 2 */ ENELFGRP_TYPE_WISDOM = GREAT_FAIRY_TYPE_WISDOM,
/* 3 */ ENELFGRP_TYPE_COURAGE = GREAT_FAIRY_TYPE_COURAGE,
/* 4 */ ENELFGRP_TYPE_KINDNESS = GREAT_FAIRY_TYPE_KINDNESS,
/* 5 */ ENELFGRP_TYPE_MAX
} ElfgrpType;
typedef struct EnElfgrp {
/* 0x000 */ Actor actor;
/* 0x144 */ s16 unk_144;
/* 0x146 */ u8 unk_146;
/* 0x147 */ u8 unk_147;
/* 0x148 */ s8 unk_148;
/* 0x14A */ u16 unk_14A;
/* 0x144 */ s16 timer;
/* 0x146 */ u8 talkedOnceFlag;
/* 0x147 */ u8 type;
/* 0x148 */ s8 unk_148; // set and not used
/* 0x14A */ u16 stateFlags;
/* 0x14C */ EnElfgrpActionFunc actionFunc;
} EnElfgrp; // size = 0x150

View File

@ -96,7 +96,7 @@ void EnElforg_Init(Actor* thisx, PlayState* play) {
case STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN:
case STRAY_FAIRY_TYPE_BUBBLE:
case STRAY_FAIRY_TYPE_CHEST:
case STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN:
case STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN:
break;
default:
@ -121,7 +121,7 @@ void EnElforg_Init(Actor* thisx, PlayState* play) {
this->targetDistanceFromHome = Rand_ZeroFloat(100.0f) + 50.0f;
break;
case STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN:
case STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN:
EnElforg_InitializeParams(this);
this->actionFunc = EnElforg_TurnInFairy;
this->secondaryTimer = 60;
@ -324,6 +324,7 @@ void EnElforg_TurnInFairy(EnElforg* this, PlayState* play) {
void EnElforg_QuicklyCircleFairyFountain(EnElforg* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
EnElforg_MoveToTargetFairyFountain(this, &this->actor.home.pos);
if (this->secondaryTimer <= 30) {
this->actionFunc = EnElforg_TurnInFairy;
}
@ -367,9 +368,9 @@ void EnElforg_FreeFloatingFairyFountain(EnElforg* this, PlayState* play) {
if (this->strayFairyFlags & STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS) {
// This happens right before the Great Fairy appears once all
// Stray Fairies are saved.
if (this->actor.home.rot.x > 0) {
if (STRAY_FAIRY_SPARKLE_COUNT(&this->actor) > 0) {
EnElforg_SpawnSparkles(this, play, 10);
this->actor.home.rot.x--;
STRAY_FAIRY_SPARKLE_COUNT(&this->actor)--;
}
Actor_SetScale(&this->actor, this->actor.scale.x * 0.9f);
@ -383,22 +384,24 @@ void EnElforg_CirclePlayer(EnElforg* this, PlayState* play) {
s32 pad;
Actor* playerActor = &GET_PLAYER(play)->actor;
Player* player = GET_PLAYER(play);
f32 distanceFromPlayer;
f32 orbitRadius;
if (GET_PLAYER_FORM == PLAYER_FORM_GORON) {
distanceFromPlayer = 40.0f;
orbitRadius = 40.0f;
} else {
distanceFromPlayer = 20.0f;
orbitRadius = 20.0f;
}
this->actor.world.pos.x = (Math_SinS(this->timer * 0x1000) * distanceFromPlayer) + playerActor->world.pos.x;
this->actor.world.pos.z = (Math_CosS(this->timer * 0x1000) * distanceFromPlayer) + playerActor->world.pos.z;
this->actor.world.pos.x = (Math_SinS(this->timer * 0x1000) * orbitRadius) + playerActor->world.pos.x;
this->actor.world.pos.z = (Math_CosS(this->timer * 0x1000) * orbitRadius) + playerActor->world.pos.z;
this->actor.world.pos.y = player->bodyPartsPos[PLAYER_BODYPART_WAIST].y;
EnElforg_SpawnSparkles(this, play, 16);
}
void EnElforg_FairyCollected(EnElforg* this, PlayState* play) {
EnElforg_CirclePlayer(this, play);
if (this->timer > 80) {
Actor_Kill(&this->actor);
return;
@ -424,8 +427,10 @@ void EnElforg_ClockTownFairyCollected(EnElforg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
EnElforg_CirclePlayer(this, play);
player->actor.freezeTimer = 100;
player->stateFlags1 |= PLAYER_STATE1_20000000;
if (Actor_TextboxIsClosing(&this->actor, play)) {
player->actor.freezeTimer = 0;
player->stateFlags1 &= ~PLAYER_STATE1_20000000;
@ -451,6 +456,7 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
SkelAnime_Update(&this->skelAnime);
if (Player_GetMask(play) == PLAYER_MASK_GREAT_FAIRY) {
pos = player->bodyPartsPos[PLAYER_BODYPART_WAIST];
this->targetSpeedXZ = 5.0f;
@ -461,10 +467,12 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) {
}
scaledYDistance = this->actor.playerHeightRel - (this->actor.shape.yOffset * this->actor.scale.y);
if (!Player_InCsMode(play)) {
if ((this->actor.xzDistToPlayer < 30.0f) && (scaledYDistance < 12.0f) && (scaledYDistance > -68.0f)) {
EnElforg_SetupFairyCollected(this, play);
Health_ChangeBy(play, 0x30);
switch (STRAY_FAIRY_TYPE(&this->actor)) {
case STRAY_FAIRY_TYPE_COLLECTIBLE:
Flags_SetCollectible(play, STRAY_FAIRY_FLAG(&this->actor));
@ -493,7 +501,8 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) {
gSaveContext.save.saveInfo.inventory.strayFairies[gSaveContext.dungeonIndex]++;
// You found a Stray Fairy!
Message_StartTextbox(play, 0x11, NULL);
if (gSaveContext.save.saveInfo.inventory.strayFairies[(void)0, gSaveContext.dungeonIndex] >= 15) {
if (gSaveContext.save.saveInfo.inventory.strayFairies[(void)0, gSaveContext.dungeonIndex] >=
STRAY_FAIRY_SCATTERED_TOTAL) {
Audio_PlayFanfare(NA_BGM_GET_ITEM | 0x900);
}
}
@ -502,6 +511,7 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) {
Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f,
UPDBGCHECKINFO_FLAG_1 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_4);
func_80ACCBB8(this, play);
if (Player_GetMask(play) == PLAYER_MASK_GREAT_FAIRY) {
if (!(this->strayFairyFlags & STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED)) {
Audio_PlaySfx(NA_SE_SY_FAIRY_MASK_SUCCESS);
@ -627,6 +637,7 @@ void EnElforg_Draw(Actor* thisx, PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
switch (this->area) {
case STRAY_FAIRY_AREA_WOODFALL:
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyWoodfallTexAnim));
@ -644,7 +655,7 @@ void EnElforg_Draw(Actor* thisx, PlayState* play) {
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyStoneTowerTexAnim));
break;
default:
default: // STRAY_FAIRY_AREA_CLOCK_TOWN
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyClockTownTexAnim));
break;
}

View File

@ -2,19 +2,23 @@
#define Z_EN_ELFORG_H
#include "global.h"
#include "overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#define STRAY_FAIRY_TYPE(thisx) ((thisx)->params & 0xF)
#define STRAY_FAIRY_GET_NON_DUNGEON_AREA(thisx) (((thisx)->params & 0x1C0) >> 6)
#define STRAY_FAIRY_FLAG(thisx) (((thisx)->params & 0xFE00) >> 9)
#define STRAY_FAIRY_PARAMS(flag, nonDungeonArea, type) (((flag & 0x7F) << 9) | ((nonDungeonArea & 7) << 6) | (type & 0xF))
#define STRAY_FAIRY_SPARKLE_COUNT(thisx) ((thisx)->home.rot.x)
//! @note `nonDungeonArea` does not always use the enum
#define STRAY_FAIRY_PARAMS(flag, nonDungeonArea, type) ((((flag) & 0x7F) << 9) | (((nonDungeonArea) & 7) << 6) | ((type) & 0xF))
#define STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME (1 << 0)
#define STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS (1 << 1)
#define STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN (1 << 2)
#define STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED (1 << 3)
typedef enum {
typedef enum StrayFairyType {
/* 0 */ STRAY_FAIRY_TYPE_FREE_FLOATING, // The ones just floating around
/* 1 */ STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN, // The ones already present when you enter a Fairy Fountain
/* 2 */ STRAY_FAIRY_TYPE_BUBBLE, // The ones trapped in bubbles
@ -23,15 +27,16 @@ typedef enum {
/* 5 */ STRAY_FAIRY_TYPE_COLLIDER, // Unused in retail. The fairy is hidden until the collider is hit
/* 6 */ STRAY_FAIRY_TYPE_CHEST, // The ones in treasure chests
/* 7 */ STRAY_FAIRY_TYPE_COLLECTIBLE, // The ones in boxes, pots, beehives, etc.
/* 8 */ STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN // The ones you "turn in" by walking into a Fairy Fountain
/* 8 */ STRAY_FAIRY_TYPE_RETURNING_TO_FOUNTAIN // The ones you "turn in" by walking into a Fairy Fountain
} StrayFairyType;
typedef enum {
/* 0 */ STRAY_FAIRY_AREA_CLOCK_TOWN,
/* 1 */ STRAY_FAIRY_AREA_WOODFALL,
/* 2 */ STRAY_FAIRY_AREA_SNOWHEAD,
/* 3 */ STRAY_FAIRY_AREA_GREAT_BAY,
/* 4 */ STRAY_FAIRY_AREA_STONE_TOWER,
// Corresponds to the Great Fairy types
typedef enum StrayFairyArea {
/* 0 */ STRAY_FAIRY_AREA_CLOCK_TOWN = GREAT_FAIRY_TYPE_MAGIC,
/* 1 */ STRAY_FAIRY_AREA_WOODFALL = GREAT_FAIRY_TYPE_POWER,
/* 2 */ STRAY_FAIRY_AREA_SNOWHEAD = GREAT_FAIRY_TYPE_WISDOM,
/* 3 */ STRAY_FAIRY_AREA_GREAT_BAY = GREAT_FAIRY_TYPE_COURAGE,
/* 4 */ STRAY_FAIRY_AREA_STONE_TOWER = GREAT_FAIRY_TYPE_KINDNESS,
/* 5 */ STRAY_FAIRY_AREA_MAX
} StrayFairyArea;

View File

@ -143,7 +143,7 @@ void EnMThunder_Init(Actor* thisx, PlayState* play) {
player->stateFlags2 &= ~PLAYER_STATE2_20000;
this->isCharging = false;
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_23_02)) {
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK)) {
player->unk_B08 = 1.0f;
this->collider.info.toucher.damage = sDamages[this->type + ENMTHUNDER_TYPE_MAX];
this->subtype = ENMTHUNDER_SUBTYPE_SPIN_GREAT;

View File

@ -255,7 +255,7 @@ void func_80A1BA44(ObjFlowerpot* this, PlayState* play) {
}
EffectSsKakera_Spawn(play, &spC4, &spB8, &spC4, -600, phi_s0, 30, 0, 0, (Rand_ZeroOne() * 12.0f) + 16.6f,
phi_s1, 0, 35, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0015B0);
phi_s1, 0, 35, -1, OBJECT_FLOWERPOT, object_flowerpot_DL_0015B0);
}
spD0.y += 20.0f;
@ -298,7 +298,7 @@ void func_80A1BD80(ObjFlowerpot* this, PlayState* play) {
}
EffectSsKakera_Spawn(play, &spBC, &spB0, &spBC, -240, phi_s0, 40, 0, 0, (Rand_ZeroOne() * 20.0f) + 10.6f, 0, 0,
42, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0015B0);
42, -1, OBJECT_FLOWERPOT, object_flowerpot_DL_0015B0);
}
spBC.y = this->actor.world.pos.y + this->actor.depthInWater;
@ -338,7 +338,7 @@ void func_80A1C0FC(ObjFlowerpot* this, PlayState* play) {
Math_Vec3f_Sum(&spB8, &spC4, &spB8);
EffectSsKakera_Spawn(play, &spB8, &spAC, &spB8, -100, 64, 40, 0, 0, (Rand_ZeroOne() * 16.0f) + 14.0f, 0, 0, 80,
-1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0014F0);
-1, OBJECT_FLOWERPOT, object_flowerpot_DL_0014F0);
}
}
@ -365,7 +365,7 @@ void func_80A1C328(ObjFlowerpot* this, PlayState* play) {
Math_Vec3f_Sum(&spB8, &spC4, &spB8);
EffectSsKakera_Spawn(play, &spB8, &spAC, &spB8, -80, 64, 44, 0, 0, (Rand_ZeroOne() * 16.0f) + 14.0f, 0, 0, 80,
-1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0014F0);
-1, OBJECT_FLOWERPOT, object_flowerpot_DL_0014F0);
}
}

View File

@ -5,6 +5,7 @@
*/
#include "z_obj_lightblock.h"
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#include "objects/object_lightblock/object_lightblock.h"
#define FLAGS 0x00000000
@ -15,12 +16,12 @@ void ObjLightblock_Init(Actor* thisx, PlayState* play);
void ObjLightblock_Destroy(Actor* thisx, PlayState* play);
void ObjLightblock_Update(Actor* thisx, PlayState* play);
void ObjLightblock_Draw(Actor* thisx, PlayState* play);
void func_80AF3AC8(ObjLightblock* this);
void func_80AF3ADC(ObjLightblock* this, PlayState* play);
void func_80AF3B8C(ObjLightblock* this);
void func_80AF3BA0(ObjLightblock* this, PlayState* play);
void func_80AF3C18(ObjLightblock* this);
void func_80AF3C34(ObjLightblock* this, PlayState* play);
void ObjLightblock_SetupWait(ObjLightblock* this);
void ObjLightblock_Wait(ObjLightblock* this, PlayState* play);
void ObjLightblock_SetupPlayCutscene(ObjLightblock* this);
void ObjLightblock_PlayCutscene(ObjLightblock* this, PlayState* play);
void ObjLightblock_SetupFadeAway(ObjLightblock* this);
void ObjLightblock_FadeAway(ObjLightblock* this, PlayState* play);
ActorInit Obj_Lightblock_InitVars = {
ACTOR_OBJ_LIGHTBLOCK,
@ -54,17 +55,17 @@ static ColliderCylinderInit sCylinderInit = {
{ 84, 120, 0, { 0, 0, 0 } },
};
typedef struct {
typedef struct LightblockTypeVars {
/* 0x0 */ f32 scale;
/* 0x4 */ s16 radius;
/* 0x6 */ s16 height;
/* 0x8 */ s16 yShift;
/* 0xC */ s32 params;
/* 0xC */ s32 effectParams;
} LightblockTypeVars; // size = 0x10
static LightblockTypeVars sLightblockTypeVars[] = {
{ 0.1f, 76, 80, 19, 2 },
{ (1.0f / 6), 126, 144, 19, 3 },
{ 0.1f, 76, 80, 19, DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_LARGE },
{ (1.0f / 6.0f), 126, 144, 19, DEMO_EFFECT_TIMEWARP_LIGHTBLOCK_VERY_LARGE },
};
static InitChainEntry sInitChain[] = {
@ -76,11 +77,11 @@ static InitChainEntry sInitChain[] = {
extern Gfx D_801AEF88[];
extern Gfx D_801AEFA0[];
void func_80AF3910(ObjLightblock* this, PlayState* play) {
void ObjLightblock_SpawnEffect(ObjLightblock* this, PlayState* play) {
LightblockTypeVars* typeVars = &sLightblockTypeVars[LIGHTBLOCK_TYPE(&this->dyna.actor)];
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_EFFECT, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y,
this->dyna.actor.world.pos.z, 0, 0, 0, typeVars->params);
this->dyna.actor.world.pos.z, 0, 0, 0, typeVars->effectParams);
}
void ObjLightblock_Init(Actor* thisx, PlayState* play) {
@ -104,7 +105,7 @@ void ObjLightblock_Init(Actor* thisx, PlayState* play) {
this->collider.dim.height = typeVars->height;
this->collider.dim.yShift = typeVars->yShift;
this->alpha = 255;
func_80AF3AC8(this);
ObjLightblock_SetupWait(this);
}
void ObjLightblock_Destroy(Actor* thisx, PlayState* play) {
@ -114,11 +115,14 @@ void ObjLightblock_Destroy(Actor* thisx, PlayState* play) {
Collider_DestroyCylinder(play, &this->collider);
}
void func_80AF3AC8(ObjLightblock* this) {
this->actionFunc = func_80AF3ADC;
void ObjLightblock_SetupWait(ObjLightblock* this) {
this->actionFunc = ObjLightblock_Wait;
}
void func_80AF3ADC(ObjLightblock* this, PlayState* play) {
/**
* Wait for a single collision from a Light Arrow or 8 frames of Mirror Shield ray collision.
*/
void ObjLightblock_Wait(ObjLightblock* this, PlayState* play) {
if (this->collider.base.acFlags & AC_HIT) {
this->collider.base.acFlags &= ~AC_HIT;
// light arrows
@ -135,39 +139,36 @@ void func_80AF3ADC(ObjLightblock* this, PlayState* play) {
if (this->collisionCounter >= 8) {
CutsceneManager_Queue(this->dyna.actor.csId);
func_80AF3B8C(this);
ObjLightblock_SetupPlayCutscene(this);
} else {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
}
}
void func_80AF3B8C(ObjLightblock* this) {
this->actionFunc = func_80AF3BA0;
void ObjLightblock_SetupPlayCutscene(ObjLightblock* this) {
this->actionFunc = ObjLightblock_PlayCutscene;
}
void func_80AF3BA0(ObjLightblock* this, PlayState* play) {
void ObjLightblock_PlayCutscene(ObjLightblock* this, PlayState* play) {
if (CutsceneManager_IsNext(this->dyna.actor.csId)) {
CutsceneManager_StartWithPlayerCs(this->dyna.actor.csId, &this->dyna.actor);
Flags_SetSwitch(play, LIGHTBLOCK_DESTROYED(&this->dyna.actor));
func_80AF3910(this, play);
func_80AF3C18(this);
ObjLightblock_SpawnEffect(this, play);
ObjLightblock_SetupFadeAway(this);
} else {
CutsceneManager_Queue(this->dyna.actor.csId);
}
}
void func_80AF3C18(ObjLightblock* this) {
void ObjLightblock_SetupFadeAway(ObjLightblock* this) {
this->timer = 80;
this->actionFunc = func_80AF3C34;
this->actionFunc = ObjLightblock_FadeAway;
}
void func_80AF3C34(ObjLightblock* this, PlayState* play) {
s8 csId;
void ObjLightblock_FadeAway(ObjLightblock* this, PlayState* play) {
this->timer--;
if (this->timer <= 0) {
csId = this->dyna.actor.csId;
CutsceneManager_Stop(csId);
CutsceneManager_Stop(this->dyna.actor.csId);
Actor_Kill(&this->dyna.actor);
return;
}

View File

@ -10374,7 +10374,7 @@ void func_80840EC0(Player* this, PlayState* play) {
// Spin attack size
void func_80840F34(Player* this) {
Math_StepToF(&this->unk_B08, (CHECK_WEEKEVENTREG(WEEKEVENTREG_23_02)) ? 1.0f : 0.5f, 0.02f);
Math_StepToF(&this->unk_B08, CHECK_WEEKEVENTREG(WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK) ? 1.0f : 0.5f, 0.02f);
}
s32 func_80840F90(PlayState* play, Player* this, CsCmdActorCue* cue, f32 arg3, s16 arg4, s32 arg5) {

View File

@ -19,7 +19,7 @@ void KaleidoScope_DrawDungeonStrayFairyCount(PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
// Get digits for max number of stray fairies
counterDigits[1] = 15;
counterDigits[1] = STRAY_FAIRY_SCATTERED_TOTAL;
counterDigits[0] = counterDigits[1] / 10;
counterDigits[1] -= (s16)(counterDigits[0] * 10);

View File

@ -6263,17 +6263,17 @@
0x808CD238:("EnVm_Draw",),
0x808CD740:("DemoEffect_Init",),
0x808CD8E8:("DemoEffect_Destroy",),
0x808CD940:("func_808CD940",),
0x808CD998:("func_808CD998",),
0x808CDAD0:("func_808CDAD0",),
0x808CDBDC:("func_808CDBDC",),
0x808CDCEC:("func_808CDCEC",),
0x808CDD70:("func_808CDD70",),
0x808CDDE0:("func_808CDDE0",),
0x808CD940:("DemoEffect_WaitForObject",),
0x808CD998:("DemoEffect_SetupTimewarp",),
0x808CDAD0:("DemoEffect_SetPerVertexAlpha",),
0x808CDBDC:("DemoEffect_FinishTimewarp",),
0x808CDCEC:("DemoEffect_StartTimewarp",),
0x808CDD70:("DemoEffect_ShrinkLight",),
0x808CDDE0:("DemoEffect_ExpandLight",),
0x808CDE54:("DemoEffect_Update",),
0x808CDE78:("func_808CDE78",),
0x808CDFF8:("func_808CDFF8",),
0x808CE078:("func_808CE078",),
0x808CDE78:("DemoEffect_OverrideLimbDrawTimewarp",),
0x808CDFF8:("DemoEffect_DrawTimewarp",),
0x808CE078:("DemoEffect_DrawLight",),
0x808CE450:("DemoKankyo_SetupAction",),
0x808CE45C:("func_808CE45C",),
0x808CF06C:("func_808CF06C",),
@ -9573,9 +9573,9 @@
0x80A07740:("func_80A07740",),
0x80A0A8A0:("BgDyYoseizo_Init",),
0x80A0A95C:("BgDyYoseizo_Destroy",),
0x80A0A96C:("func_80A0A96C",),
0x80A0A9E4:("func_80A0A9E4",),
0x80A0AA40:("func_80A0AA40",),
0x80A0A96C:("BgDyYoseizo_UpdateEyes",),
0x80A0A9E4:("BgDyYoseizo_Bob",),
0x80A0AA40:("BgDyYoseizo_SpawnEffects",),
0x80A0AD50:("func_80A0AD50",),
0x80A0AE1C:("func_80A0AE1C",),
0x80A0AFDC:("func_80A0AFDC",),
@ -9587,14 +9587,14 @@
0x80A0B5F0:("func_80A0B5F0",),
0x80A0B75C:("func_80A0B75C",),
0x80A0B834:("func_80A0B834",),
0x80A0B8CC:("func_80A0B8CC",),
0x80A0B8CC:("BgDyYoseizo_TrainPlayer",),
0x80A0BB08:("func_80A0BB08",),
0x80A0BC84:("BgDyYoseizo_Update",),
0x80A0BCD8:("func_80A0BCD8",),
0x80A0BD40:("func_80A0BD40",),
0x80A0BE60:("func_80A0BE60",),
0x80A0BF70:("func_80A0BF70",),
0x80A0C270:("func_80A0C270",),
0x80A0BCD8:("BgDyYoseizo_OverrideLimbDraw",),
0x80A0BD40:("BgDyYoseizo_Draw",),
0x80A0BE60:("BgDyYoseizo_SpawnEffect",),
0x80A0BF70:("BgDyYoseizo_UpdateEffects",),
0x80A0C270:("BgDyYoseizo_DrawEffects",),
0x80A0C780:("EnBoj05_Init",),
0x80A0C790:("EnBoj05_Destroy",),
0x80A0C7A0:("EnBoj05_Update",),
@ -10266,16 +10266,16 @@
0x80A38FB4:("EnRu_OverrideLimbdraw",),
0x80A390F8:("EnRu_PostLimbdraw",),
0x80A39204:("EnRu_Draw",),
0x80A396B0:("func_80A396B0",),
0x80A396B0:("EnElfgrp_SetCutscene",),
0x80A3970C:("EnElfgrp_Init",),
0x80A39BC0:("EnElfgrp_Destroy",),
0x80A39BD0:("func_80A39BD0",),
0x80A39C1C:("func_80A39C1C",),
0x80A39CD4:("func_80A39CD4",),
0x80A39DC8:("func_80A39DC8",),
0x80A39F50:("func_80A39F50",),
0x80A39FBC:("func_80A39FBC",),
0x80A3A044:("func_80A3A044",),
0x80A39BD0:("EnElfgrp_GetHeldFairiesCount",),
0x80A39C1C:("EnElfgrp_GetFountainFairiesCount",),
0x80A39CD4:("EnElfgrp_SetFountainFairiesCount",),
0x80A39DC8:("EnElfgrp_SpawnStrayFairies",),
0x80A39F50:("EnElfgrp_SummonStrayFairies",),
0x80A39FBC:("EnElfgrp_SpinStrayFairies",),
0x80A3A044:("EnElfgrp_VanishStrayFairies",),
0x80A3A0AC:("func_80A3A0AC",),
0x80A3A0F4:("func_80A3A0F4",),
0x80A3A210:("func_80A3A210",),
@ -10284,8 +10284,8 @@
0x80A3A484:("func_80A3A484",),
0x80A3A4AC:("func_80A3A4AC",),
0x80A3A520:("func_80A3A520",),
0x80A3A600:("func_80A3A600",),
0x80A3A610:("func_80A3A610",),
0x80A3A600:("EnElfgrp_DoNothing",),
0x80A3A610:("EnElfgrp_HealPlayer",),
0x80A3A6F4:("func_80A3A6F4",),
0x80A3A77C:("func_80A3A77C",),
0x80A3A7FC:("func_80A3A7FC",),
@ -10546,8 +10546,8 @@
0x80A4F4C8:("func_80A4F4C8",),
0x80A4FA40:("DemoGetitem_Init",),
0x80A4FB00:("DemoGetitem_Destroy",),
0x80A4FB10:("func_80A4FB10",),
0x80A4FB68:("func_80A4FB68",),
0x80A4FB10:("DemoGetitem_Wait",),
0x80A4FB68:("DemoGetitem_PerformCutsceneActions",),
0x80A4FCCC:("DemoGetitem_Update",),
0x80A4FCF0:("DemoGetitem_Draw",),
0x80A4FDD0:("func_80A4FDD0",),
@ -10752,8 +10752,8 @@
0x80A61040:("BgSpoutFire_Draw",),
0x80A612B0:("EnDyExtra_Destroy",),
0x80A612C0:("EnDyExtra_Init",),
0x80A61334:("func_80A61334",),
0x80A613C8:("func_80A613C8",),
0x80A61334:("EnDyExtra_WaitForTrigger",),
0x80A613C8:("EnDyExtra_Fall",),
0x80A61470:("EnDyExtra_Update",),
0x80A614C4:("EnDyExtra_Draw",),
0x80A61810:("EnBal_Init",),
@ -12656,15 +12656,15 @@
0x80AF3144:("EnTest7_Update",),
0x80AF31D0:("func_80AF31D0",),
0x80AF3248:("EnTest7_Draw",),
0x80AF3910:("func_80AF3910",),
0x80AF3910:("ObjLightblock_SpawnEffect",),
0x80AF397C:("ObjLightblock_Init",),
0x80AF3A80:("ObjLightblock_Destroy",),
0x80AF3AC8:("func_80AF3AC8",),
0x80AF3ADC:("func_80AF3ADC",),
0x80AF3B8C:("func_80AF3B8C",),
0x80AF3BA0:("func_80AF3BA0",),
0x80AF3C18:("func_80AF3C18",),
0x80AF3C34:("func_80AF3C34",),
0x80AF3AC8:("ObjLightblock_SetupWait",),
0x80AF3ADC:("ObjLightblock_Wait",),
0x80AF3B8C:("ObjLightblock_SetupPlayCutscene",),
0x80AF3BA0:("ObjLightblock_PlayCutscene",),
0x80AF3C18:("ObjLightblock_SetupFadeAway",),
0x80AF3C34:("ObjLightblock_FadeAway",),
0x80AF3CC0:("ObjLightblock_Update",),
0x80AF3CE4:("ObjLightblock_Draw",),
0x80AF3F70:("func_80AF3F70",),

View File

@ -10574,27 +10574,11 @@
0x80A0A88C:("D_80A0A88C","UNK_TYPE4","",0x4),
0x80A0A890:("D_80A0A890","UNK_TYPE4","",0x4),
0x80A0C4A0:("Bg_Dy_Yoseizo_InitVars","UNK_TYPE1","",0x1),
0x80A0C4C0:("D_80A0C4C0","UNK_TYPE4","",0x4),
0x80A0C4C4:("D_80A0C4C4","UNK_TYPE4","",0x4),
0x80A0C4C8:("D_80A0C4C8","UNK_TYPE4","",0x4),
0x80A0C4CC:("D_80A0C4CC","UNK_TYPE4","",0x4),
0x80A0C4D0:("D_80A0C4D0","UNK_TYPE4","",0x4),
0x80A0C4D8:("D_80A0C4D8","UNK_TYPE4","",0x4),
0x80A0C4DC:("D_80A0C4DC","UNK_TYPE4","",0x4),
0x80A0C4E0:("D_80A0C4E0","UNK_TYPE4","",0x4),
0x80A0C4E4:("D_80A0C4E4","UNK_TYPE1","",0x1),
0x80A0C4F8:("D_80A0C4F8","UNK_TYPE1","",0x1),
0x80A0C50C:("D_80A0C50C","UNK_TYPE1","",0x1),
0x80A0C514:("D_80A0C514","UNK_TYPE1","",0x1),
0x80A0C540:("D_80A0C540","f32","",0x4),
0x80A0C544:("D_80A0C544","f32","",0x4),
0x80A0C548:("D_80A0C548","f32","",0x4),
0x80A0C54C:("D_80A0C54C","f32","",0x4),
0x80A0C550:("D_80A0C550","f32","",0x4),
0x80A0C554:("D_80A0C554","f32","",0x4),
0x80A0C558:("D_80A0C558","f32","",0x4),
0x80A0C55C:("D_80A0C55C","f32","",0x4),
0x80A0C560:("D_80A0C560","f32","",0x4),
0x80A0C4C0:("sAnimations","AnimationHeader*","9",0x24),
0x80A0C4E4:("sEffectPrimColors","Color_RGB8","6",0x12),
0x80A0C4F8:("sEffectEnvColors","Color_RGB8","6",0x12),
0x80A0C50C:("sMouthTextures","UNK_TYPE1","2",0x8),
0x80A0C514:("sStretchFactors","f32","8",0x20),
0x80A0C7C0:("En_Boj_05_InitVars","UNK_TYPE1","",0x1),
0x80A10860:("sAnimationsBombShopkeeper","UNK_PTR","",0x4),
0x80A10890:("En_Sob1_InitVars","UNK_TYPE1","",0x1),

View File

@ -189,7 +189,7 @@ weekEventReg = {
(22 << 8) | 0x40: "WEEKEVENTREG_22_40",
(22 << 8) | 0x80: "WEEKEVENTREG_22_80",
(23 << 8) | 0x01: "WEEKEVENTREG_23_01",
(23 << 8) | 0x02: "WEEKEVENTREG_23_02",
(23 << 8) | 0x02: "WEEKEVENTREG_OBTAINED_GREAT_SPIN_ATTACK",
(23 << 8) | 0x04: "WEEKEVENTREG_23_04",
(23 << 8) | 0x08: "WEEKEVENTREG_23_08",
(23 << 8) | 0x10: "WEEKEVENTREG_23_10",

View File

@ -191,14 +191,6 @@ D_050089D0 = 0x050089D0;
D_060002C8 = 0x060002C8;
D_060005C4 = 0x060005C4;
// ovl_Bg_Dy_Yoseizo
D_06008090 = 0x06008090;
D_0600D1B0 = 0x0600D1B0;
D_0600D228 = 0x0600D228;
D_0601C6F4 = 0x0601C6F4;
D_0601C8B4 = 0x0601C8B4;
// ovl_Bg_Lotus
D_06000A20 = 0x06000A20;