Document `object_po_fusen` (Poe Balloon from romani ranch) (#1167)

* PoFusen: Documented object

* PoFusen: Cleaning and docs

* Apply suggestions from code review

Co-authored-by: Tom Overton <tom-overton@users.noreply.github.com>

* PoFusen: fixes for requested changes, and additional changes

* PoSisters: replace NONEFFECT with NONE

* Fusen/Sisters: requested changes

* Fusen: more requested changes

* Fusen: removed documentation at request

* Apply suggestions from code review

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

* Po Fusen/Sisters: fix dmgeff naming

* Po Fuse/Sisters: more enum/define/limb name cohesive

* Apply suggestions from code review

Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>

* PoSisters: comment caplitalization

---------

Co-authored-by: Tom Overton <tom-overton@users.noreply.github.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
This commit is contained in:
Isghj 2023-02-21 12:09:08 -08:00 committed by GitHub
parent 50bd6056e2
commit 4c4c0d7307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 361 additions and 344 deletions

View File

@ -1,32 +1,39 @@
<Root>
<!-- Assets for Poe Balloon archery target in Romani Ranch. -->
<File Name="object_po_fusen" Segment="6">
<Animation Name="object_po_fusen_Anim_000040" Offset="0x40" />
<DList Name="object_po_fusen_DL_0008C0" Offset="0x8C0" />
<DList Name="object_po_fusen_DL_000AF8" Offset="0xAF8" />
<DList Name="object_po_fusen_DL_000B90" Offset="0xB90" />
<DList Name="object_po_fusen_DL_000C48" Offset="0xC48" />
<DList Name="object_po_fusen_DL_000CD8" Offset="0xCD8" />
<DList Name="object_po_fusen_DL_000D70" Offset="0xD70" />
<DList Name="object_po_fusen_DL_000E28" Offset="0xE28" />
<DList Name="object_po_fusen_DL_000EB8" Offset="0xEB8" />
<Texture Name="object_po_fusen_TLUT_0010E0" OutName="tlut_0010E0" Format="rgba16" Width="16" Height="16" Offset="0x10E0" />
<Texture Name="object_po_fusen_Tex_0012E0" OutName="tex_0012E0" Format="rgba16" Width="16" Height="16" Offset="0x12E0" />
<Texture Name="object_po_fusen_Tex_0014E0" OutName="tex_0014E0" Format="rgba16" Width="16" Height="16" Offset="0x14E0" />
<Texture Name="object_po_fusen_Tex_0016E0" OutName="tex_0016E0" Format="rgba16" Width="16" Height="16" Offset="0x16E0" />
<Texture Name="object_po_fusen_Tex_0018E0" OutName="tex_0018E0" Format="ci8" Width="16" Height="16" Offset="0x18E0" />
<Texture Name="object_po_fusen_Tex_0019E0" OutName="tex_0019E0" Format="i4" Width="16" Height="16" Offset="0x19E0" />
<Texture Name="object_po_fusen_Tex_001A60" OutName="tex_001A60" Format="rgba16" Width="16" Height="16" Offset="0x1A60" />
<Texture Name="object_po_fusen_Tex_001C60" OutName="tex_001C60" Format="rgba16" Width="32" Height="16" Offset="0x1C60" />
<Texture Name="object_po_fusen_Tex_002060" OutName="tex_002060" Format="rgba16" Width="16" Height="32" Offset="0x2060" />
<Limb Name="object_po_fusen_Standardlimb_002460" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_01" Offset="0x2460" />
<Limb Name="object_po_fusen_Standardlimb_00246C" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_02" Offset="0x246C" />
<Limb Name="object_po_fusen_Standardlimb_002478" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_03" Offset="0x2478" />
<Limb Name="object_po_fusen_Standardlimb_002484" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_04" Offset="0x2484" />
<Limb Name="object_po_fusen_Standardlimb_002490" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_05" Offset="0x2490" />
<Limb Name="object_po_fusen_Standardlimb_00249C" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_06" Offset="0x249C" />
<Limb Name="object_po_fusen_Standardlimb_0024A8" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_07" Offset="0x24A8" />
<Limb Name="object_po_fusen_Standardlimb_0024B4" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_08" Offset="0x24B4" />
<Limb Name="object_po_fusen_Standardlimb_0024C0" Type="Standard" EnumName="OBJECT_PO_FUSEN_LIMB_09" Offset="0x24C0" />
<Skeleton Name="object_po_fusen_Skel_0024F0" Type="Flex" LimbType="Standard" LimbNone="OBJECT_PO_FUSEN_LIMB_NONE" LimbMax="OBJECT_PO_FUSEN_LIMB_MAX" EnumName="ObjectPoFusenLimb" Offset="0x24F0" />
<!-- Empty: PoFusen is animated directly from its code. -->
<Animation Name="gPoeBalloonEmptyAnim" Offset="0x40" />
<DList Name="gPoeBalloonChainAndLanternDL" Offset="0x8C0" />
<DList Name="gPoeBalloonLeftHandDL" Offset="0xAF8" />
<DList Name="gPoeBalloonLeftForearmDL" Offset="0xB90" />
<DList Name="gPoeBalloonLeftUpperArmDL" Offset="0xC48" />
<DList Name="gPoeBalloonRightHandDL" Offset="0xCD8" />
<DList Name="gPoeBalloonRightForearmDL" Offset="0xD70" />
<DList Name="gPoeBalloonRightUpperArmDL" Offset="0xE28" />
<DList Name="gPoeBalloonBodyDL" Offset="0xEB8" />
<Texture Name="gPoeBalloonTLUT" OutName="balloon_tlut" Format="rgba16" Width="16" Height="16" Offset="0x10E0" />
<!-- The tattered cloth along the eyes are part of the face texture, but not below the chin. -->
<Texture Name="gPoeBalloonTatteredChinTex" OutName="tattered_chin" Format="rgba16" Width="16" Height="16" Offset="0x12E0" />
<Texture Name="gPoeBalloonLanternTopTex" OutName="lantern_top" Format="rgba16" Width="16" Height="16" Offset="0x14E0" />
<Texture Name="gPoeBalloonLanternStandTex" OutName="lantern_stand" Format="rgba16" Width="16" Height="16" Offset="0x16E0" />
<Texture Name="gPoeBalloonLanternGlassTex" OutName="lantern_glass" Format="ci8" Width="16" Height="16" Offset="0x18E0" />
<Texture Name="gPoeBalloonHandTex" OutName="the_hand" Format="i4" Width="16" Height="16" Offset="0x19E0" />
<Texture Name="gPoeBalloonOrangeSkinTex" OutName="orange_skin" Format="rgba16" Width="16" Height="16" Offset="0x1A60" />
<Texture Name="gPoeBalloonFaceTex" OutName="face" Format="rgba16" Width="32" Height="16" Offset="0x1C60" />
<Texture Name="gPoeBalloonChainLinkTex" OutName="chain_link" Format="rgba16" Width="16" Height="32" Offset="0x2060" />
<Limb Name="gPoeBalloonRootLimb" Type="Standard" EnumName="POE_BALLOON_LIMB_ROOT" Offset="0x2460" />
<Limb Name="gPoeBalloonBodyLimb" Type="Standard" EnumName="POE_BALLOON_LIMB_BODY" Offset="0x246C" />
<Limb Name="gPoeBalloonRightUpperArmLimb" Type="Standard" EnumName="POE_BALLOON_RIGHT_UPPER_ARM" Offset="0x2478" />
<Limb Name="gPoeBalloonRightForearmLimb" Type="Standard" EnumName="POE_BALLOON_RIGHT_FOREARM" Offset="0x2484" />
<Limb Name="gPoeBalloonRightHandLimb" Type="Standard" EnumName="POE_BALLOON_RIGHT_HAND" Offset="0x2490" />
<Limb Name="gPoeBalloonLeftUpperArmLimb" Type="Standard" EnumName="POE_BALLOON_LEFT_UPPER_ARM" Offset="0x249C" />
<Limb Name="gPoeBalloonLeftForearmLimb" Type="Standard" EnumName="POE_BALLOON_LEFT_FOREARM" Offset="0x24A8" />
<Limb Name="gPoeBalloonLeftHandLimb" Type="Standard" EnumName="POE_BALLOON_LEFT_HAND" Offset="0x24B4" />
<Limb Name="gPoeBalloonChainAndLanternLimb" Type="Standard" EnumName="POE_BALLOON_LIMB_CHAIN_AND_LANTERN" Offset="0x24C0" />
<Skeleton Name="gPoeBalloonSkel" Type="Flex" LimbType="Standard" LimbNone="POE_BALLOON_LIMB_NONE" LimbMax="POE_BALLOON_LIMB_MAX" EnumName="PoeBalloonLimb" Offset="0x24F0" />
</File>
</Root>

View File

@ -3,68 +3,68 @@
<!-- Joelle is red, Beth is blue, Ami is green, and Meg is purple -->
<File Name="object_po_sisters" Segment="6">
<!-- PoSister Animations -->
<Animation Name="gPoSistersAttackAnim" Offset="0x114" />
<Animation Name="gPoeSistersAttackAnim" Offset="0x114" />
<Animation Name="gPoeSistersMegCryAnim" Offset="0x680" />
<Animation Name="gPoeSistersDamagedAnim" Offset="0x8C0" />
<Animation Name="gPoSistersFleeAnim" Offset="0xA54" />
<Animation Name="gPoeSistersFleeAnim" Offset="0xA54" />
<Animation Name="gPoeSistersFloatAnim" Offset="0xD40" />
<Animation Name="gPoeSistersAppearDisappearAnim" Offset="0x119C" />
<Animation Name="gPoeSistersSwayAnim" Offset="0x14CC" />
<!-- PoSister DisplayLists -->
<DList Name="gPoSistersMegFaceDL" Offset="0x1CB0" />
<DList Name="gPoSistersMegBodyDL" Offset="0x1DE0" />
<DList Name="gPoSistersLowerBodyDL" Offset="0x24A8" />
<DList Name="gPoeSistersMegFaceDL" Offset="0x1CB0" />
<DList Name="gPoeSistersMegBodyDL" Offset="0x1DE0" />
<DList Name="gPoeSistersLowerBodyDL" Offset="0x24A8" />
<!--- unknown? wont draw, DL contents doesn't give enough hints -->
<DList Name="gPoSisters_DL_002570" Offset="0x2570" />
<DList Name="gPoSistersDrawArmShortDL" Offset="0x25E8" />
<DList Name="gPoSistersDrawArmMedDL" Offset="0x2680" />
<DList Name="gPoSistersDrawArmLongDL" Offset="0x2718" />
<DList Name="gPoSistersDrawTorchDL" Offset="0x27B0" />
<DList Name="gPoeSisters_DL_002570" Offset="0x2570" />
<DList Name="gPoeSistersDrawArmShortDL" Offset="0x25E8" />
<DList Name="gPoeSistersDrawArmMedDL" Offset="0x2680" />
<DList Name="gPoeSistersDrawArmLongDL" Offset="0x2718" />
<DList Name="gPoeSistersDrawTorchDL" Offset="0x27B0" />
<!--- unknown? wont draw, DL contents doesn't give enough hints -->
<DList Name="gPoSisters_DL_002870" Offset="0x2870" />
<DList Name="gPoSistersJoelleFaceDL" Offset="0x2EB8" />
<DList Name="gPoSistersJoelleBodyDL" Offset="0x2F88" />
<DList Name="gPoSistersBethBodyDL" Offset="0x3628" />
<DList Name="gPoSistersBethFaceDL" Offset="0x3880" />
<DList Name="gPoSistersAmyBodyDL" Offset="0x3DC8" />
<DList Name="gPoSistersAmyFaceDL" Offset="0x4020" />
<DList Name="gPoSistersBurnBodyDL" Offset="0x46E0" />
<DList Name="gPoeSisters_DL_002870" Offset="0x2870" />
<DList Name="gPoeSistersJoelleFaceDL" Offset="0x2EB8" />
<DList Name="gPoeSistersJoelleBodyDL" Offset="0x2F88" />
<DList Name="gPoeSistersBethBodyDL" Offset="0x3628" />
<DList Name="gPoeSistersBethFaceDL" Offset="0x3880" />
<DList Name="gPoeSistersAmyBodyDL" Offset="0x3DC8" />
<DList Name="gPoeSistersAmyFaceDL" Offset="0x4020" />
<DList Name="gPoeSistersBurnBodyDL" Offset="0x46E0" />
<!-- PoSister Textures -->
<Texture Name="gPoSistersTorchTex" OutName="torch" Format="rgba16" Width="16" Height="16" Offset="0x48D8" />
<Texture Name="gPoSistersTatteredRobeTex" OutName="tattered_robe" Format="rgba16" Width="32" Height="32" Offset="0x4AD8" />
<Texture Name="gPoSistersArmTex" OutName="arm" Format="rgba16" Width="32" Height="16" Offset="0x52D8" />
<Texture Name="gPoSistersMegJoelleEyeTex" OutName="meg_joelle_eye" Format="rgba16" Width="16" Height="16" Offset="0x56D8" />
<Texture Name="gPoSistersMainRobeGradientTex" OutName="robe_gradient" Format="rgba16" Width="4" Height="4" Offset="0x58D8" />
<Texture Name="gPoSistersMegTiaraTex" OutName="meg_tiara" Format="rgba16" Width="16" Height="16" Offset="0x58F8" />
<Texture Name="gPoSistersMegHairTex" OutName="meg_hair" Format="rgba16" Width="16" Height="16" Offset="0x5AF8" />
<Texture Name="gPoSistersJoelleHairBandtex" OutName="joelle_hair_tie" Format="rgba16" Width="8" Height="8" Offset="0x5CF8" />
<Texture Name="gPoSistersJoelleAmyHairTex" OutName="joelle_amy_hair" Format="rgba16" Width="16" Height="16" Offset="0x5D78" />
<Texture Name="gPoSistersBethAmyEyesTex" OutName="beth_amy_eye" Format="rgba16" Width="16" Height="8" Offset="0x5F78" />
<Texture Name="gPoSistersBethHatAndHairTex" OutName="beth_hat_and_hair" Format="rgba16" Width="16" Height="16" Offset="0x6078" />
<Texture Name="gPoSistersBethHatEdgeTex" OutName="beth_hat_edge" Format="rgba16" Width="8" Height="8" Offset="0x6278" />
<Texture Name="gPoSistersAmyHairTieTex" OutName="amy_hair_tie" Format="rgba16" Width="4" Height="4" Offset="0x62F8" />
<Texture Name="gPoSistersCrispBodyTex" OutName="crisp_body" Format="rgba16" Width="16" Height="16" Offset="0x6318" />
<Texture Name="gPoeSistersTorchTex" OutName="torch" Format="rgba16" Width="16" Height="16" Offset="0x48D8" />
<Texture Name="gPoeSistersTatteredRobeTex" OutName="tattered_robe" Format="rgba16" Width="32" Height="32" Offset="0x4AD8" />
<Texture Name="gPoeSistersArmTex" OutName="arm" Format="rgba16" Width="32" Height="16" Offset="0x52D8" />
<Texture Name="gPoeSistersMegJoelleEyeTex" OutName="meg_joelle_eye" Format="rgba16" Width="16" Height="16" Offset="0x56D8" />
<Texture Name="gPoeSistersMainRobeGradientTex" OutName="robe_gradient" Format="rgba16" Width="4" Height="4" Offset="0x58D8" />
<Texture Name="gPoeSistersMegTiaraTex" OutName="meg_tiara" Format="rgba16" Width="16" Height="16" Offset="0x58F8" />
<Texture Name="gPoeSistersMegHairTex" OutName="meg_hair" Format="rgba16" Width="16" Height="16" Offset="0x5AF8" />
<Texture Name="gPoeSistersJoelleHairBandtex" OutName="joelle_hair_tie" Format="rgba16" Width="8" Height="8" Offset="0x5CF8" />
<Texture Name="gPoeSistersJoelleAmyHairTex" OutName="joelle_amy_hair" Format="rgba16" Width="16" Height="16" Offset="0x5D78" />
<Texture Name="gPoeSistersBethAmyEyesTex" OutName="beth_amy_eye" Format="rgba16" Width="16" Height="8" Offset="0x5F78" />
<Texture Name="gPoeSistersBethHatAndHairTex" OutName="beth_hat_and_hair" Format="rgba16" Width="16" Height="16" Offset="0x6078" />
<Texture Name="gPoeSistersBethHatEdgeTex" OutName="beth_hat_edge" Format="rgba16" Width="8" Height="8" Offset="0x6278" />
<Texture Name="gPoeSistersAmyHairTieTex" OutName="amy_hair_tie" Format="rgba16" Width="4" Height="4" Offset="0x62F8" />
<Texture Name="gPoeSistersCrispBodyTex" OutName="crisp_body" Format="rgba16" Width="16" Height="16" Offset="0x6318" />
<!-- PoSister Limbs -->
<Limb Name="gPoSistersMainRootLimb" Type="Standard" EnumName="POSISTERS_LIMB_ROOT" Offset="0x6518" />
<Limb Name="gPoSistersLeftArmLimb" Type="Standard" EnumName="POSISTERS_LIMB_LEFT_ARM" Offset="0x6524" />
<!--- won't draw, uses gPoSisters_DL_002870 -->
<Limb Name="gPoSisters_limb_006530" Type="Standard" EnumName="POSISTERS_LIMB_UNK3" Offset="0x6530" />
<Limb Name="gPoSistersRightUpperArmLimb" Type="Standard" EnumName="POSISTERS_LIMB_RIGHT_UPPER_ARM" Offset="0x653C" />
<Limb Name="gPoSistersRightForArmLimb" Type="Standard" EnumName="POSISTERS_LIMB_RIGHT_FORARM" Offset="0x6548" />
<Limb Name="gPoeSistersMainRootLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_ROOT" Offset="0x6518" />
<Limb Name="gPoeSistersLeftArmLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_LEFT_ARM" Offset="0x6524" />
<!--- won't draw, uses gPoeSisters_DL_002870 -->
<Limb Name="gPoeSisters_limb_006530" Type="Standard" EnumName="POE_SISTERS_LIMB_UNK3" Offset="0x6530" />
<Limb Name="gPoeSistersRightUpperArmLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_RIGHT_UPPER_ARM" Offset="0x653C" />
<Limb Name="gPoeSistersRightForArmLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_RIGHT_FORARM" Offset="0x6548" />
<!--- no DL -->
<Limb Name="gPoSisters_limb_006554" Type="Standard" EnumName="POSISTERS_LIMB_UNK6" Offset="0x6554" />
<!--- won't draw, uses gPoSisters_DL_002570 -->
<Limb Name="gPoSisters_limb_006560" Type="Standard" EnumName="POSISTERS_LIMB_UNK7" Offset="0x6560" />
<Limb Name="gPoSistersTorchLimb" Type="Standard" EnumName="POSISTERS_LIMB_TORCH" Offset="0x656C" />
<Limb Name="gPoSistersMainBodyLimb" Type="Standard" EnumName="POSISTERS_LIMB_MAIN_BODY" Offset="0x6578" />
<Limb Name="gPoSistersFaceLimb" Type="Standard" EnumName="POSISTERS_LIMB_FACE" Offset="0x6584" />
<Limb Name="gPoSistersLowerBodyLimb" Type="Standard" EnumName="POSISTERS_LIMB_LOWER_BODY" Offset="0x6590" />
<Limb Name="gPoeSisters_limb_006554" Type="Standard" EnumName="POE_SISTERS_LIMB_UNK6" Offset="0x6554" />
<!--- won't draw, uses gPoeSisters_DL_002570 -->
<Limb Name="gPoeSisters_limb_006560" Type="Standard" EnumName="POE_SISTERS_LIMB_UNK7" Offset="0x6560" />
<Limb Name="gPoeSistersTorchLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_TORCH" Offset="0x656C" />
<Limb Name="gPoeSistersMainBodyLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_MAIN_BODY" Offset="0x6578" />
<Limb Name="gPoeSistersFaceLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_FACE" Offset="0x6584" />
<Limb Name="gPoeSistersLowerBodyLimb" Type="Standard" EnumName="POE_SISTERS_LIMB_LOWER_BODY" Offset="0x6590" />
<!-- PoSister Skeleton -->
<Skeleton Name="gPoSistersSkel" Type="Normal" LimbType="Standard" LimbNone="POSISTERS_LIMB_NONE" LimbMax="POSISTERS_LIMB_MAX" EnumName="PoSistersLimb" Offset="0x65C8" />
<Skeleton Name="gPoeSistersSkel" Type="Normal" LimbType="Standard" LimbNone="POE_SISTERS_LIMB_NONE" LimbMax="POE_SISTERS_LIMB_MAX" EnumName="PoeSistersLimb" Offset="0x65C8" />
</File>
</Root>

View File

@ -6,7 +6,6 @@
#include "z_en_po_fusen.h"
#include "overlays/actors/ovl_En_Ma4/z_en_ma4.h"
#include "objects/object_po_fusen/object_po_fusen.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_100000 | ACTOR_FLAG_80000000)
@ -57,44 +56,49 @@ static ColliderSphereInit sSphereInit = {
{ 0, { { 0, 0, 0 }, 200 }, 100 },
};
typedef enum {
/* 0x0 */ POE_BALLOON_DMGEFF_NONE,
/* 0xF */ POE_BALLOON_DMGEFF_POP = 0xF,
} PoeBalloonDamageEffect;
static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x0),
/* Deku Stick */ DMG_ENTRY(0, 0x0),
/* Horse trample */ DMG_ENTRY(0, 0x0),
/* Explosives */ DMG_ENTRY(0, 0x0),
/* Zora boomerang */ DMG_ENTRY(0, 0x0),
/* Normal arrow */ DMG_ENTRY(1, 0xF),
/* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
/* Hookshot */ DMG_ENTRY(0, 0x0),
/* Goron punch */ DMG_ENTRY(0, 0x0),
/* Sword */ DMG_ENTRY(0, 0x0),
/* Goron pound */ DMG_ENTRY(0, 0x0),
/* Fire arrow */ DMG_ENTRY(1, 0xF),
/* Ice arrow */ DMG_ENTRY(1, 0xF),
/* Light arrow */ DMG_ENTRY(1, 0xF),
/* Goron spikes */ DMG_ENTRY(1, 0xF),
/* Deku spin */ DMG_ENTRY(0, 0x0),
/* Deku bubble */ DMG_ENTRY(0, 0x0),
/* Deku launch */ DMG_ENTRY(0, 0x0),
/* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0),
/* Zora barrier */ DMG_ENTRY(0, 0x0),
/* Normal shield */ DMG_ENTRY(0, 0x0),
/* Light ray */ DMG_ENTRY(0, 0x0),
/* Thrown object */ DMG_ENTRY(0, 0x0),
/* Zora punch */ DMG_ENTRY(0, 0x0),
/* Spin attack */ DMG_ENTRY(0, 0x0),
/* Sword beam */ DMG_ENTRY(0, 0x0),
/* Normal Roll */ DMG_ENTRY(0, 0x0),
/* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
/* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
/* Unblockable */ DMG_ENTRY(0, 0x0),
/* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
/* Powder Keg */ DMG_ENTRY(0, 0x0),
/* Deku Nut */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Deku Stick */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Horse trample */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Explosives */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Zora boomerang */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Normal arrow */ DMG_ENTRY(1, POE_BALLOON_DMGEFF_POP),
/* UNK_DMG_0x06 */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Hookshot */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Goron punch */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Sword */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Goron pound */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Fire arrow */ DMG_ENTRY(1, POE_BALLOON_DMGEFF_POP),
/* Ice arrow */ DMG_ENTRY(1, POE_BALLOON_DMGEFF_POP),
/* Light arrow */ DMG_ENTRY(1, POE_BALLOON_DMGEFF_POP),
/* Goron spikes */ DMG_ENTRY(1, POE_BALLOON_DMGEFF_POP),
/* Deku spin */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Deku bubble */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Deku launch */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* UNK_DMG_0x12 */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Zora barrier */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Normal shield */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Light ray */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Thrown object */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Zora punch */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Spin attack */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Sword beam */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Normal Roll */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* UNK_DMG_0x1B */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* UNK_DMG_0x1C */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Unblockable */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* UNK_DMG_0x1E */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
/* Powder Keg */ DMG_ENTRY(0, POE_BALLOON_DMGEFF_NONE),
};
void EnPoFusen_Init(Actor* thisx, PlayState* play) {
EnPoFusen* this = THIS;
f32 heightTemp;
f32 flyingHeightMin;
this->actor.scale.x = this->actor.scale.y = this->actor.scale.z = 0.007f;
this->actor.targetMode = 6;
@ -103,10 +107,9 @@ void EnPoFusen_Init(Actor* thisx, PlayState* play) {
Collider_InitSphere(play, &this->collider);
Collider_SetSphere(play, &this->collider, &this->actor, &sSphereInit);
if (0) {}
this->collider.dim.worldSphere.radius = 40;
SkelAnime_InitFlex(play, &this->anime, &object_po_fusen_Skel_0024F0, &object_po_fusen_Anim_000040, this->jointTable,
this->morphTable, 10);
SkelAnime_InitFlex(play, &this->anime, &gPoeBalloonSkel, &gPoeBalloonEmptyAnim, this->jointTable, this->morphTable,
POE_BALLOON_LIMB_MAX);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f);
Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 0x4);
@ -114,27 +117,26 @@ void EnPoFusen_Init(Actor* thisx, PlayState* play) {
Actor_Kill(&this->actor);
}
heightTemp = this->actor.floorHeight + 90.0f;
if (this->actor.home.pos.y < heightTemp) {
this->actor.home.pos.y = heightTemp;
flyingHeightMin = this->actor.floorHeight + 90.0f;
if (this->actor.home.pos.y < flyingHeightMin) {
this->actor.home.pos.y = flyingHeightMin;
}
this->randScaleChange = (Rand_Next() % 0xFFFE) - 0x7FFF;
this->randYRotChange = (Rand_Next() % 0x4B0) - 0x258;
this->avgBaseRotation = 0x10000 / 12;
this->limb3Rot = 0;
this->limbRotYRightUpperArm = 0;
this->limb46Rot = 0;
this->limb57Rot = 0;
this->limb8Rot = 0;
this->limb9Rot = 0x71C;
this->limbRotLeftHand = 0;
this->limbRotChainAndLantern = 0x71C;
this->randBaseRotChange = 0;
if (ENPOFUSEN_IS_FUSE_TYPE(&this->actor)) {
if (POE_BALLOON_IS_FUSE_TYPE(&this->actor)) {
EnPoFusen_InitFuse(this);
return;
} else {
EnPoFusen_InitNoFuse(this);
}
EnPoFusen_InitNoFuse(this);
}
void EnPoFusen_Destroy(Actor* thisx, PlayState* play) {
@ -143,20 +145,22 @@ void EnPoFusen_Destroy(Actor* thisx, PlayState* play) {
Collider_DestroySphere(play, &this->collider);
}
/**
* Search for Romani's actor, beacuse it's PoFusen's job to update her actor on pop.
*/
u16 EnPoFusen_CheckParent(EnPoFusen* this, PlayState* play) {
Actor* actorPtr;
Actor* actorIter = play->actorCtx.actorLists[ACTORCAT_NPC].first;
actorPtr = play->actorCtx.actorLists[ACTORCAT_NPC].first;
if (ENPOFUSEN_IS_FUSE_TYPE(&this->actor)) {
if (POE_BALLOON_IS_FUSE_TYPE(&this->actor)) {
return true;
}
while (actorPtr != NULL) {
if (actorPtr->id == ACTOR_EN_MA4) {
this->actor.parent = actorPtr;
while (actorIter != NULL) {
if (actorIter->id == ACTOR_EN_MA4) {
this->actor.parent = actorIter;
return true;
}
actorPtr = actorPtr->next;
actorIter = actorIter->next;
}
return false;
@ -171,7 +175,7 @@ u16 EnPoFusen_CheckCollision(EnPoFusen* this, PlayState* play) {
this->collider.dim.worldSphere.center.y = this->actor.world.pos.y + 20.0f;
this->collider.dim.worldSphere.center.z = this->actor.world.pos.z;
if ((this->collider.base.acFlags & AC_HIT) && (this->actor.colChkInfo.damageEffect == 0xF)) {
if ((this->collider.base.acFlags & AC_HIT) && (this->actor.colChkInfo.damageEffect == POE_BALLOON_DMGEFF_POP)) {
this->collider.base.acFlags &= ~AC_HIT;
return true;
}
@ -204,16 +208,16 @@ void EnPoFusen_Idle(EnPoFusen* this, PlayState* play) {
this->actor.shape.rot.z = (Math_SinS(this->randBaseRotChange) * 910.0f);
if ((this->randScaleChange < 0x4000) && (this->randScaleChange >= -0x3FFF)) {
Math_SmoothStepToS(&this->limb9Rot, 0x38E, 0x14, 0xBB8, 0x64);
Math_SmoothStepToS(&this->limbRotChainAndLantern, 0x38E, 0x14, 0xBB8, 0x64);
} else {
Math_SmoothStepToS(&this->limb9Rot, 0x71C, 0x8, 0xBB8, 0x64);
Math_SmoothStepToS(&this->limbRotChainAndLantern, 0x71C, 0x8, 0xBB8, 0x64);
}
this->avgBaseRotation = this->limb9Rot * 3;
this->limb3Rot = (Math_SinS(this->randBaseRotChange + 0x38E3) * this->avgBaseRotation);
this->avgBaseRotation = this->limbRotChainAndLantern * 3;
this->limbRotYRightUpperArm = (Math_SinS(this->randBaseRotChange + 0x38E3) * this->avgBaseRotation);
this->limb46Rot = (Math_SinS(this->randBaseRotChange) * this->avgBaseRotation);
this->limb57Rot = (Math_SinS(this->randBaseRotChange - 0x38E3) * this->avgBaseRotation);
this->limb8Rot = (Math_SinS(this->randBaseRotChange - 0x71C6) * this->avgBaseRotation);
this->limbRotLeftHand = (Math_SinS(this->randBaseRotChange - 0x71C6) * this->avgBaseRotation);
shadowScaleTmp = ((1.0f - Math_SinS(this->randScaleChange)) * 10.0f) + 50.0f;
shadowAlphaTmp = ((1.0f - Math_SinS(this->randScaleChange)) * 75.0f) + 100.0f;
@ -223,10 +227,9 @@ void EnPoFusen_Idle(EnPoFusen* this, PlayState* play) {
void EnPoFusen_IncrementRomaniPop(EnPoFusen* this) {
Actor* parent = this->actor.parent;
EnMa4* romani;
if ((parent != NULL) && (parent->id == ACTOR_EN_MA4)) {
romani = (EnMa4*)parent;
EnMa4* romani = (EnMa4*)parent;
romani->poppedBalloonCounter++;
}
@ -243,7 +246,8 @@ void EnPoFusen_Pop(EnPoFusen* this, PlayState* play) {
void EnPoFusen_InitFuse(EnPoFusen* this) {
s16 rotZ = this->actor.shape.rot.z;
this->fuse = ENPOFUSEN_GET_FUSE_LEN(&this->actor);
this->fuse = POE_BALLOON_GET_FUSE_LEN(&this->actor);
this->actor.shape.rot.z = 0;
this->randScaleChange = rotZ & 0xFFFF;
this->actionFunc = EnPoFusen_IdleFuse;
@ -258,6 +262,7 @@ void EnPoFusen_IdleFuse(EnPoFusen* this, PlayState* play) {
void EnPoFusen_Update(Actor* thisx, PlayState* play) {
EnPoFusen* this = THIS;
this->actionFunc(this, play);
if (EnPoFusen_CheckCollision(this, play)) {
EnPoFusen_IncrementRomaniPop(this);
@ -266,39 +271,38 @@ void EnPoFusen_Update(Actor* thisx, PlayState* play) {
s32 EnPoFusen_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
EnPoFusen* this = THIS;
f32 zScale;
f32 yScale;
f32 xScale;
s16 pad;
s16 zRot;
s16 pad2;
s16 xRot;
if (limbIndex == 2) {
zScale = (Math_CosS(this->randScaleChange) * 0.08f) + 1.0f;
xScale = zScale;
if (!zScale) {}
if (limbIndex == POE_BALLOON_LIMB_BODY) {
f32 zScale = (Math_CosS(this->randScaleChange) * 0.08f) + 1.0f;
f32 yScale;
f32 xScale = zScale;
s16 pad;
s16 zRot;
s16 pad2;
s16 xRot;
yScale = (Math_SinS(this->randScaleChange) * 0.08f) + 1.0f;
yScale = yScale * yScale;
yScale = SQ(yScale);
xRot = ((Math_SinS(this->randXZRotChange) * 2730.0f));
zRot = ((Math_CosS(this->randXZRotChange) * 2730.0f));
Matrix_RotateZYX(xRot, 0, zRot, MTXMODE_APPLY);
Matrix_Scale(xScale, yScale, zScale, MTXMODE_APPLY);
Matrix_RotateZS(-zRot, MTXMODE_APPLY);
Matrix_RotateXS(-xRot, MTXMODE_APPLY);
} else if (limbIndex == 3) {
rot->y += this->limb3Rot;
} else if (limbIndex == 6) {
} else if (limbIndex == POE_BALLOON_RIGHT_UPPER_ARM) {
rot->y += this->limbRotYRightUpperArm;
} else if (limbIndex == POE_BALLOON_LEFT_UPPER_ARM) {
rot->y += this->limb46Rot;
} else if (limbIndex == 4) {
} else if (limbIndex == POE_BALLOON_RIGHT_FOREARM) {
rot->z += this->limb46Rot;
} else if ((limbIndex == 5) || (limbIndex == 7)) {
} else if ((limbIndex == POE_BALLOON_RIGHT_HAND) || (limbIndex == POE_BALLOON_LEFT_FOREARM)) {
rot->z += this->limb57Rot;
} else if (limbIndex == 8) {
rot->z += this->limb8Rot;
} else if (limbIndex == 9) {
rot->y += (s16)(this->limb9Rot * Math_SinS(this->randBaseRotChange));
rot->z += (s16)(this->limb9Rot * Math_CosS(this->randBaseRotChange));
} else if (limbIndex == POE_BALLOON_LEFT_HAND) {
rot->z += this->limbRotLeftHand;
} else if (limbIndex == POE_BALLOON_LIMB_CHAIN_AND_LANTERN) {
rot->y += (s16)(this->limbRotChainAndLantern * Math_SinS(this->randBaseRotChange));
rot->z += (s16)(this->limbRotChainAndLantern * Math_CosS(this->randBaseRotChange));
}
return false;
}
@ -311,6 +315,7 @@ void EnPoFusen_TransformLimbDraw(PlayState* play, s32 limbIndex, Actor* thisx) {
void EnPoFusen_Draw(Actor* thisx, PlayState* play) {
EnPoFusen* this = THIS;
func_8012C28C(play->state.gfxCtx);
SkelAnime_DrawTransformFlexOpa(play, this->anime.skeleton, this->anime.jointTable, this->anime.dListCount,
EnPoFusen_OverrideLimbDraw, EnPoFusen_PostLimbDraw, EnPoFusen_TransformLimbDraw,

View File

@ -2,11 +2,13 @@
#define Z_EN_PO_FUSEN_H
#include "global.h"
#include "objects/object_po_fusen/object_po_fusen.h"
struct EnPoFusen;
#define ENPOFUSEN_GET_FUSE_LEN(thisx) ((thisx)->params & 0x3FF)
#define ENPOFUSEN_IS_FUSE_TYPE(thisx) ((thisx)->params & 0x8000)
// The version used in the credits, where we see romani shoot three in a row, are on timer, this is the fuse length.
#define POE_BALLOON_GET_FUSE_LEN(thisx) ((thisx)->params & 0x3FF)
#define POE_BALLOON_IS_FUSE_TYPE(thisx) ((thisx)->params & 0x8000)
typedef void (*EnPoFusenActionFunc)(struct EnPoFusen*, PlayState*);
@ -15,17 +17,17 @@ typedef struct EnPoFusen {
/* 0x144 */ SkelAnime anime;
/* 0x188 */ EnPoFusenActionFunc actionFunc;
/* 0x18C */ ColliderSphere collider;
/* 0x1E4 */ Vec3s jointTable[0xA];
/* 0x220 */ Vec3s morphTable[0xA];
/* 0x1E4 */ Vec3s jointTable[POE_BALLOON_LIMB_MAX];
/* 0x220 */ Vec3s morphTable[POE_BALLOON_LIMB_MAX];
/* 0x25C */ s16 randScaleChange;
/* 0x25E */ s16 randXZRotChange;
/* 0x260 */ s16 randYRotChange;
/* 0x262 */ s16 avgBaseRotation;
/* 0x264 */ s16 limb3Rot;
/* 0x264 */ s16 limbRotYRightUpperArm;
/* 0x266 */ s16 limb46Rot;
/* 0x268 */ s16 limb57Rot;
/* 0x26A */ s16 limb8Rot;
/* 0x26C */ s16 limb9Rot;
/* 0x26A */ s16 limbRotLeftHand;
/* 0x26C */ s16 limbRotChainAndLantern;
/* 0x26E */ s16 randBaseRotChange;
/* 0x270 */ s16 fuse;
} EnPoFusen; // size = 0x274

View File

@ -97,46 +97,46 @@ static ColliderCylinderInit sCylinderInit = {
static CollisionCheckInfoInit sColChkInfoInit = { 6, 25, 60, 50 };
typedef enum {
/* 0x0 */ POSISTERS_DAMAGEEFFECT_NOEFFECT,
/* 0x1 */ POSISTERS_DAMAGEEFFECT_UNKDMG12, // set in DamageTable, but unused
/* 0x4 */ POSISTERS_DAMAGEEFFECT_LIGHTARROWS = 0x4,
/* 0xE */ POSISTERS_DAMAGEEFFECT_SPINATTACK = 0xE,
/* 0xF */ POSISTERS_DAMAGEEFFECT_DEKUNUT = 0xF,
} PoSisterDamageEffect;
/* 0x0 */ POE_SISTERS_DMGEFF_NONE,
/* 0x1 */ POE_SISTERS_DMGEFF_UNKDMG12, // set in DamageTable, but unused
/* 0x4 */ POE_SISTERS_DMGEFF_LIGHTARROWS = 0x4,
/* 0xE */ POE_SISTERS_DMGEFF_SPINATTACK = 0xE,
/* 0xF */ POE_SISTERS_DMGEFF_DEKUNUT = 0xF,
} PoeSisterDamageEffect;
static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_DEKUNUT),
/* Deku Stick */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Horse trample */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Explosives */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Zora boomerang */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Normal arrow */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* UNK_DMG_0x06 */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Hookshot */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Goron punch */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Sword */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Goron pound */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Fire arrow */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Ice arrow */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Light arrow */ DMG_ENTRY(2, POSISTERS_DAMAGEEFFECT_LIGHTARROWS),
/* Goron spikes */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Deku spin */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Deku bubble */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Deku launch */ DMG_ENTRY(2, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* UNK_DMG_0x12 */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_UNKDMG12),
/* Zora barrier */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Normal shield */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Light ray */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Thrown object */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Zora punch */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Spin attack */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_SPINATTACK),
/* Sword beam */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Normal Roll */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* UNK_DMG_0x1B */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* UNK_DMG_0x1C */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Unblockable */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* UNK_DMG_0x1E */ DMG_ENTRY(0, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Powder Keg */ DMG_ENTRY(1, POSISTERS_DAMAGEEFFECT_NOEFFECT),
/* Deku Nut */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_DEKUNUT),
/* Deku Stick */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Horse trample */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Explosives */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Zora boomerang */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Normal arrow */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* UNK_DMG_0x06 */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Hookshot */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Goron punch */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Sword */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Goron pound */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Fire arrow */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Ice arrow */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Light arrow */ DMG_ENTRY(2, POE_SISTERS_DMGEFF_LIGHTARROWS),
/* Goron spikes */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Deku spin */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Deku bubble */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Deku launch */ DMG_ENTRY(2, POE_SISTERS_DMGEFF_NONE),
/* UNK_DMG_0x12 */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_UNKDMG12),
/* Zora barrier */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Normal shield */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Light ray */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Thrown object */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Zora punch */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
/* Spin attack */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_SPINATTACK),
/* Sword beam */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Normal Roll */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* UNK_DMG_0x1B */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* UNK_DMG_0x1C */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Unblockable */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* UNK_DMG_0x1E */ DMG_ENTRY(0, POE_SISTERS_DMGEFF_NONE),
/* Powder Keg */ DMG_ENTRY(1, POE_SISTERS_DMGEFF_NONE),
};
static InitChainEntry sInitChain[] = {
@ -146,15 +146,15 @@ static InitChainEntry sInitChain[] = {
// clang-format off
// PoSisters have their own flags variable for cross function behavior detection
#define POSISTERS_FLAG_CLEAR (0)
#define POSISTERS_FLAG_CHECK_AC (1 << 0)
#define POSISTERS_FLAG_UPDATE_SHAPE_ROT (1 << 1)
#define POSISTERS_FLAG_CHECK_Z_TARGET (1 << 2) // meg doesnt go invis if you ztarget her for too long
#define POSISTERS_FLAG_MATCH_PLAYER_HEIGHT (1 << 3) // the po is attempting to level with player's height
#define POSISTERS_FLAG_UPDATE_BGCHECK_INFO (1 << 4)
#define POSISTERS_FLAG_UPDATE_FIRES (1 << 5) // firePos updated to match limb in PostLimbDraw
#define POSISTERS_FLAG_REAL_MEG_ROTATION (1 << 6) // real meg rotates different than her clones for one cycle
#define POSISTERS_FLAG_DRAW_TORCH (1 << 7)
#define POE_SISTERS_FLAG_CLEAR (0)
#define POE_SISTERS_FLAG_CHECK_AC (1 << 0)
#define POE_SISTERS_FLAG_UPDATE_SHAPE_ROT (1 << 1)
#define POE_SISTERS_FLAG_CHECK_Z_TARGET (1 << 2) // Meg doesnt go invisible if you ztarget her for too long
#define POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT (1 << 3) // The Poe is attempting to level with player's height
#define POE_SISTERS_FLAG_UPDATE_BGCHECK_INFO (1 << 4)
#define POE_SISTERS_FLAG_UPDATE_FIRES (1 << 5) // firePos updated to match limb in PostLimbDraw
#define POE_SISTERS_FLAG_REAL_MEG_ROTATION (1 << 6) // Real Meg rotates different than her clones for one cycle
#define POE_SISTERS_FLAG_DRAW_TORCH (1 << 7)
// clang-format on
void EnPoSisters_Init(Actor* thisx, PlayState* play) {
@ -163,8 +163,8 @@ void EnPoSisters_Init(Actor* thisx, PlayState* play) {
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 50.0f);
SkelAnime_Init(play, &this->skelAnime, &gPoSistersSkel, &gPoeSistersSwayAnim, this->jointTable, this->morphTable,
POSISTERS_LIMB_MAX);
SkelAnime_Init(play, &this->skelAnime, &gPoeSistersSkel, &gPoeSistersSwayAnim, this->jointTable, this->morphTable,
POE_SISTERS_LIMB_MAX);
this->color.r = 255;
this->color.g = 255;
@ -176,21 +176,21 @@ void EnPoSisters_Init(Actor* thisx, PlayState* play) {
Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
this->type = ENPOSISTERS_GET_TYPE(thisx);
this->type = POE_SISTERS_GET_TYPE(thisx);
this->actor.hintId = this->type + TATL_HINT_ID_POE_SISTER_MEG;
this->megCloneId = ENPOSISTERS_GET_MEG_CLONE_ID(thisx);
this->megCloneId = POE_SISTERS_GET_MEG_CLONE_ID(thisx);
this->floatingBobbingTimer = 32;
this->zTargetTimer = 20;
this->fireCount = 1;
this->poSisterFlags = POSISTERS_FLAG_UPDATE_FIRES;
this->poSisterFlags = POE_SISTERS_FLAG_UPDATE_FIRES;
this->megDistToPlayer = 110.0f;
thisx->flags &= ~ACTOR_FLAG_1;
if (ENPOSISTERS_GET_OBSERVER_FLAG(&this->actor)) {
// if flagged observer, they are a floating prop spawned by EnGb2 (po hut proprieter)
if (POE_SISTERS_GET_OBSERVER_FLAG(&this->actor)) {
// "Flagged observer": non-enemy floating prop spawned by EnGb2 (Poe Hut Proprieter) for display
EnPoSisters_SetupObserverIdle(this);
} else if (this->type == POSISTER_TYPE_MEG) {
if (this->megCloneId == POSISTER_MEG_REAL) {
} else if (this->type == POE_SISTERS_TYPE_MEG) {
if (this->megCloneId == POE_SISTERS_MEG_REAL) {
this->actor.colChkInfo.health = 8;
this->collider.info.toucher.damage = 16;
this->collider.base.ocFlags1 = (OC1_TYPE_PLAYER | OC1_ON);
@ -242,7 +242,7 @@ void EnPoSisters_MatchPlayerXZ(EnPoSisters* this, PlayState* play) {
Player* player = GET_PLAYER(play);
f32 dist;
if (this->megCloneId == POSISTER_MEG_REAL || this->actionFunc != EnPoSisters_DamageFlinch) {
if (this->megCloneId == POE_SISTERS_MEG_REAL || this->actionFunc != EnPoSisters_DamageFlinch) {
if ((player->meleeWeaponState == 0 || player->meleeWeaponAnimation >= PLAYER_MWA_SPIN_ATTACK_1H) &&
((player->actor.world.pos.y - player->actor.floorHeight) < 1.0f)) {
Math_StepToF(&this->megDistToPlayer, 110.0f, 3.0f);
@ -250,7 +250,7 @@ void EnPoSisters_MatchPlayerXZ(EnPoSisters* this, PlayState* play) {
Math_StepToF(&this->megDistToPlayer, 170.0f, 10.0f);
}
dist = this->megDistToPlayer;
} else if (this->megCloneId != POSISTER_MEG_REAL) {
} else if (this->megCloneId != POE_SISTERS_MEG_REAL) {
dist = this->actor.parent->xzDistToPlayer;
}
@ -353,7 +353,8 @@ void EnPoSisters_SetupAimlessIdleFlying(EnPoSisters* this) {
Animation_MorphToLoop(&this->skelAnime, &gPoeSistersFloatAnim, -3.0f);
}
this->idleFlyingAnimationCounter = Rand_S16Offset(15, 3);
this->poSisterFlags |= (POSISTERS_FLAG_CHECK_Z_TARGET | POSISTERS_FLAG_UPDATE_SHAPE_ROT | POSISTERS_FLAG_CHECK_AC);
this->poSisterFlags |=
(POE_SISTERS_FLAG_CHECK_Z_TARGET | POE_SISTERS_FLAG_UPDATE_SHAPE_ROT | POE_SISTERS_FLAG_CHECK_AC);
this->actionFunc = EnPoSisters_AimlessIdleFlying;
}
@ -418,10 +419,10 @@ void EnPoSisters_SetupSpinUp(EnPoSisters* this) {
this->collider.base.acFlags |= AC_HARD;
}
Animation_MorphToLoop(&this->skelAnime, &gPoSistersAttackAnim, -5.0f);
Animation_MorphToLoop(&this->skelAnime, &gPoeSistersAttackAnim, -5.0f);
this->actor.speedXZ = 0.0f;
this->spinupTimer = Animation_GetLastFrame(&gPoSistersAttackAnim.common) * 3 + 3;
this->poSisterFlags &= ~POSISTERS_FLAG_UPDATE_SHAPE_ROT;
this->spinupTimer = Animation_GetLastFrame(&gPoeSistersAttackAnim.common) * 3 + 3;
this->poSisterFlags &= ~POE_SISTERS_FLAG_UPDATE_SHAPE_ROT;
this->actionFunc = EnPoSisters_SpinUp;
}
@ -438,15 +439,15 @@ void EnPoSisters_SpinUp(EnPoSisters* this, PlayState* play) {
void EnPoSisters_SetupSpinAttack(EnPoSisters* this) {
this->actor.speedXZ = 5.0f;
if (this->type == POSISTER_TYPE_MEG) {
if (this->type == POE_SISTERS_TYPE_MEG) {
this->collider.base.colType = COLTYPE_METAL;
this->collider.base.acFlags |= AC_HARD;
Animation_MorphToLoop(&this->skelAnime, &gPoSistersAttackAnim, -5.0f);
Animation_MorphToLoop(&this->skelAnime, &gPoeSistersAttackAnim, -5.0f);
}
this->spinTimer = 5;
this->actor.world.rot.y = this->actor.yawTowardsPlayer;
this->poSisterFlags |= POSISTERS_FLAG_MATCH_PLAYER_HEIGHT;
this->poSisterFlags |= POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT;
this->actionFunc = EnPoSisters_SpinAttack;
}
@ -462,7 +463,7 @@ void EnPoSisters_SpinAttack(EnPoSisters* this, PlayState* play) {
s16 rotY = this->actor.shape.rot.y - this->actor.world.rot.y;
if (ABS_ALT(rotY) < 0x1000) {
if (this->type != POSISTER_TYPE_MEG) {
if (this->type != POE_SISTERS_TYPE_MEG) {
this->collider.base.colType = COLTYPE_HIT3;
this->collider.base.acFlags &= ~AC_HARD;
EnPoSisters_SetupAimlessIdleFlying(this);
@ -484,7 +485,7 @@ void EnPoSisters_SpinAttack(EnPoSisters* this, PlayState* play) {
void EnPoSisters_SetupAttackConnect(EnPoSisters* this) {
Animation_MorphToLoop(&this->skelAnime, &gPoeSistersFloatAnim, -3.0f);
this->actor.world.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer);
if (this->type != POSISTER_TYPE_MEG) {
if (this->type != POE_SISTERS_TYPE_MEG) {
this->collider.base.colType = COLTYPE_HIT3;
this->collider.base.acFlags &= ~AC_HARD;
}
@ -498,7 +499,7 @@ void EnPoSisters_AttackConnectDrift(EnPoSisters* this, PlayState* play) {
if (Math_StepToF(&this->actor.speedXZ, 0.0f, 0.1f)) { // wait to stop moving
this->actor.world.rot.y = this->actor.shape.rot.y;
if (this->type != POSISTER_TYPE_MEG) {
if (this->type != POE_SISTERS_TYPE_MEG) {
EnPoSisters_SetupAimlessIdleFlying(this);
} else {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2);
@ -513,12 +514,12 @@ void EnPoSisters_SetupDamageFlinch(EnPoSisters* this) {
func_800BE504(&this->actor, &this->collider);
}
if (this->type != POSISTER_TYPE_MEG) {
if (this->type != POE_SISTERS_TYPE_MEG) {
this->actor.speedXZ = 10.0f;
}
this->poSisterFlags &=
~(POSISTERS_FLAG_MATCH_PLAYER_HEIGHT | POSISTERS_FLAG_UPDATE_SHAPE_ROT | POSISTERS_FLAG_CHECK_AC);
~(POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT | POE_SISTERS_FLAG_UPDATE_SHAPE_ROT | POE_SISTERS_FLAG_CHECK_AC);
Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 16);
this->actionFunc = EnPoSisters_DamageFlinch;
}
@ -526,9 +527,9 @@ void EnPoSisters_SetupDamageFlinch(EnPoSisters* this) {
void EnPoSisters_DamageFlinch(EnPoSisters* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime) && !(this->actor.flags & ACTOR_FLAG_8000)) {
if (this->actor.colChkInfo.health != 0) {
if (this->type != POSISTER_TYPE_MEG) {
if (this->type != POE_SISTERS_TYPE_MEG) {
EnPoSisters_SetupFlee(this);
} else if (this->megCloneId != POSISTER_MEG_REAL) {
} else if (this->megCloneId != POE_SISTERS_MEG_REAL) {
EnPoSisters_MegCloneVanish(this, NULL);
} else {
EnPoSisters_MegCloneVanish(this, play);
@ -538,27 +539,27 @@ void EnPoSisters_DamageFlinch(EnPoSisters* this, PlayState* play) {
}
}
if (this->megCloneId != POSISTER_MEG_REAL) {
if (this->megCloneId != POE_SISTERS_MEG_REAL) {
s32 alpha;
Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.parent->shape.rot.y,
(this->megCloneId == POSISTER_MEG_CLONE2) ? 0x800 : 0x400);
(this->megCloneId == POE_SISTERS_MEG_CLONE2) ? 0x800 : 0x400);
alpha = ((this->skelAnime.endFrame - this->skelAnime.curFrame) * 255.0f) / this->skelAnime.endFrame;
this->color.a = CLAMP(alpha, 0, 255);
this->actor.world.pos.y = this->actor.parent->world.pos.y;
EnPoSisters_MatchPlayerXZ(this, play);
} else if (this->type != POSISTER_TYPE_MEG) {
} else if (this->type != POE_SISTERS_TYPE_MEG) {
Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f);
}
}
void EnPoSisters_SetupFlee(EnPoSisters* this) {
Animation_MorphToLoop(&this->skelAnime, &gPoSistersFleeAnim, -3.0f);
Animation_MorphToLoop(&this->skelAnime, &gPoeSistersFleeAnim, -3.0f);
this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y);
this->fleeTimer = 5;
this->poSisterFlags |=
(POSISTERS_FLAG_MATCH_PLAYER_HEIGHT | POSISTERS_FLAG_UPDATE_SHAPE_ROT | POSISTERS_FLAG_CHECK_AC);
(POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT | POE_SISTERS_FLAG_UPDATE_SHAPE_ROT | POE_SISTERS_FLAG_CHECK_AC);
this->actor.speedXZ = 5.0f;
this->actionFunc = EnPoSisters_Flee;
}
@ -572,7 +573,7 @@ void EnPoSisters_Flee(EnPoSisters* this, PlayState* play) {
if (this->actor.bgCheckFlags & 8) { // touching a wall
this->actor.world.rot.y = this->actor.shape.rot.y;
this->poSisterFlags |= POSISTERS_FLAG_UPDATE_SHAPE_ROT;
this->poSisterFlags |= POE_SISTERS_FLAG_UPDATE_SHAPE_ROT;
EnPoSisters_SetupSpinToInvis(this);
} else if (this->fleeTimer == 0 && this->actor.xzDistToPlayer > 480.0f) {
this->actor.world.rot.y = this->actor.shape.rot.y;
@ -586,7 +587,7 @@ void EnPoSisters_SetupSpinToInvis(EnPoSisters* this) {
this->invisibleTimer = 100; // 5 seconds
this->actor.speedXZ = 0.0f;
this->actor.world.rot.y = this->actor.shape.rot.y;
this->poSisterFlags &= ~(POSISTERS_FLAG_CHECK_Z_TARGET | POSISTERS_FLAG_CHECK_AC);
this->poSisterFlags &= ~(POE_SISTERS_FLAG_CHECK_Z_TARGET | POE_SISTERS_FLAG_CHECK_AC);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DISAPPEAR);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2);
this->actionFunc = EnPoSisters_SpinToInvis;
@ -607,7 +608,7 @@ void EnPoSisters_SpinToInvis(EnPoSisters* this, PlayState* play) {
void EnPoSisters_SetupSpinBackToVisible(EnPoSisters* this, PlayState* play) {
Animation_Change(&this->skelAnime, &gPoeSistersAppearDisappearAnim, 1.5f, 0.0f,
Animation_GetLastFrame(&gPoeSistersAppearDisappearAnim.common), ANIMMODE_ONCE, -3.0f);
if (this->type == POSISTER_TYPE_MEG) {
if (this->type == POE_SISTERS_TYPE_MEG) {
this->megDistToPlayer = 110.0f;
EnPoSisters_MatchPlayerXZ(this, play);
this->color.a = 0;
@ -619,15 +620,15 @@ void EnPoSisters_SetupSpinBackToVisible(EnPoSisters* this, PlayState* play) {
this->spinInvisibleTimer = 15;
this->actor.speedXZ = 0.0f;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR);
this->poSisterFlags &= ~POSISTERS_FLAG_CHECK_AC;
this->poSisterFlags &= ~POE_SISTERS_FLAG_CHECK_AC;
this->actionFunc = EnPoSisters_SpinBackToVisible;
}
void EnPoSisters_SpinBackToVisible(EnPoSisters* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
this->color.a = 255; // fully visible
if (this->type != POSISTER_TYPE_MEG) {
this->poSisterFlags |= POSISTERS_FLAG_CHECK_AC;
if (this->type != POE_SISTERS_TYPE_MEG) {
this->poSisterFlags |= POE_SISTERS_FLAG_CHECK_AC;
this->collider.info.bumper.dmgFlags = ~(0x8000000 | 0x200000 | 0x100000 | 0x40000 | 0x1);
DECR(this->spinInvisibleTimer);
@ -643,7 +644,7 @@ void EnPoSisters_SpinBackToVisible(EnPoSisters* this, PlayState* play) {
s32 alpha = (this->skelAnime.curFrame * 255.0f) / this->skelAnime.endFrame;
this->color.a = CLAMP(alpha, 0, 255);
if (this->type == POSISTER_TYPE_MEG) {
if (this->type == POE_SISTERS_TYPE_MEG) {
EnPoSisters_MatchPlayerXZ(this, play);
}
}
@ -655,7 +656,7 @@ void EnPoSisters_SetupDeathStage1(EnPoSisters* this) {
this->actor.world.pos.y += 42.0f;
this->actor.shape.yOffset = -6000.0f;
this->actor.flags &= ~ACTOR_FLAG_1;
this->poSisterFlags = POSISTERS_FLAG_CLEAR;
this->poSisterFlags = POE_SISTERS_FLAG_CLEAR;
this->actionFunc = EnPoSisters_DeathStage1;
}
@ -724,15 +725,15 @@ void EnPoSisters_DeathStage2(EnPoSisters* this, PlayState* play) {
void EnPoSisters_SpawnMegClones(EnPoSisters* this, PlayState* play) {
Actor* clone1 = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_PO_SISTERS,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0,
0, ENPOSISTERS_PARAMS(false, POSISTER_MEG_CLONE1, POSISTER_TYPE_MEG));
0, POE_SISTERS_PARAMS(false, POE_SISTERS_MEG_CLONE1, POE_SISTERS_TYPE_MEG));
Actor* clone2 = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_PO_SISTERS,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0,
0, ENPOSISTERS_PARAMS(false, POSISTER_MEG_CLONE2, POSISTER_TYPE_MEG));
0, POE_SISTERS_PARAMS(false, POE_SISTERS_MEG_CLONE2, POE_SISTERS_TYPE_MEG));
Actor* clone3 = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_PO_SISTERS,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0,
0, ENPOSISTERS_PARAMS(false, POSISTER_MEG_CLONE3, POSISTER_TYPE_MEG));
0, POE_SISTERS_PARAMS(false, POE_SISTERS_MEG_CLONE3, POE_SISTERS_TYPE_MEG));
// if we cannot spawn all clones: abort
// If we cannot spawn all clones: Abort
if ((clone1 == NULL) || (clone2 == NULL) || (clone3 == NULL)) {
if (clone1 != NULL) {
Actor_Kill(clone1);
@ -759,7 +760,7 @@ void EnPoSisters_MegCloneVanish(EnPoSisters* this, PlayState* play) {
this->actor.draw = NULL;
this->actor.flags &= ~ACTOR_FLAG_1;
this->invisibleTimer = 100; // 5 seconds
this->poSisterFlags = POSISTERS_FLAG_UPDATE_FIRES;
this->poSisterFlags = POE_SISTERS_FLAG_UPDATE_FIRES;
this->collider.base.colType = COLTYPE_HIT3;
this->collider.base.acFlags &= ~AC_HARD;
@ -767,10 +768,10 @@ void EnPoSisters_MegCloneVanish(EnPoSisters* this, PlayState* play) {
pos.x = this->actor.world.pos.x;
pos.y = this->actor.world.pos.y + 45.0f;
pos.z = this->actor.world.pos.z;
func_800B3030(play, &pos, &gZeroVec3f, &gZeroVec3f, 150, 0, 3); // spawns EffectSsDeadDb
func_800B3030(play, &pos, &gZeroVec3f, &gZeroVec3f, 150, 0, 3); // Spawns EffectSsDeadDb (flame effects)
}
Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0); // light OFF
Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0); // Light OFF
this->actionFunc = EnPoSisters_MegCloneWaitForSpinBack;
}
@ -778,7 +779,7 @@ void EnPoSisters_MegCloneWaitForSpinBack(EnPoSisters* this, PlayState* play) {
Player* player = GET_PLAYER(play);
EnPoSisters* parent = (EnPoSisters*)this->actor.parent;
if (this->megCloneId == POSISTER_MEG_REAL) {
if (this->megCloneId == POE_SISTERS_MEG_REAL) {
DECR(this->invisibleTimer);
if (this->invisibleTimer == 0) {
s32 rand = Rand_ZeroFloat(4.0f);
@ -803,7 +804,7 @@ void EnPoSisters_SetupMegSurroundPlayer(EnPoSisters* this) {
this->color.a = 255;
this->megSurroundTimer = 300; // 15 seconds
this->megClonesRemaining = 3;
this->poSisterFlags |= (POSISTERS_FLAG_MATCH_PLAYER_HEIGHT | POSISTERS_FLAG_CHECK_AC);
this->poSisterFlags |= (POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT | POE_SISTERS_FLAG_CHECK_AC);
this->actor.flags |= ACTOR_FLAG_1;
this->actionFunc = EnPoSisters_MegSurroundPlayer;
}
@ -815,47 +816,48 @@ void EnPoSisters_MegSurroundPlayer(EnPoSisters* this, PlayState* play) {
if (this->megClonesRemaining > 0 && this->megSurroundTimer >= 16) {
SkelAnime_Update(&this->skelAnime);
if (this->megCloneId == POSISTER_MEG_REAL) {
if (this->megCloneId == POE_SISTERS_MEG_REAL) {
if (ABS_ALT(16 - this->floatingBobbingTimer) < 14) {
// every x frames rotate around player, the fewer meg clones remaining the faster they spin
// Every N frames rotate around player. The fewer Meg clones remaining the faster they spin.
this->actor.shape.rot.y += (s16)((0x580 - (this->megClonesRemaining * 0x180)) *
fabsf(Math_SinS(this->floatingBobbingTimer * 0x800)));
}
// twirl the real meg backwards for a bit for visual tell to player
// Twirl the real Meg backwards for a bit for a visual tell to player.
if ((this->megSurroundTimer >= 284) || (this->megSurroundTimer <= 30)) {
this->poSisterFlags |= POSISTERS_FLAG_REAL_MEG_ROTATION;
this->poSisterFlags |= POE_SISTERS_FLAG_REAL_MEG_ROTATION;
} else {
this->poSisterFlags &= ~POSISTERS_FLAG_REAL_MEG_ROTATION;
this->poSisterFlags &= ~POE_SISTERS_FLAG_REAL_MEG_ROTATION;
}
} else {
this->actor.shape.rot.y = this->actor.parent->shape.rot.y + (this->megCloneId * 0x4000);
}
}
if (this->megCloneId == POSISTER_MEG_REAL) {
if (this->megCloneId == POE_SISTERS_MEG_REAL) {
if ((this->megSurroundTimer >= 284) || ((this->megSurroundTimer <= 30) && (this->megSurroundTimer >= 16))) {
this->poSisterFlags |= POSISTERS_FLAG_REAL_MEG_ROTATION;
this->poSisterFlags |= POE_SISTERS_FLAG_REAL_MEG_ROTATION;
} else {
this->poSisterFlags &= ~POSISTERS_FLAG_REAL_MEG_ROTATION;
this->poSisterFlags &= ~POE_SISTERS_FLAG_REAL_MEG_ROTATION;
}
}
if (this->megSurroundTimer == 0) {
if (this->megCloneId == POSISTER_MEG_REAL) {
if (this->megCloneId == POE_SISTERS_MEG_REAL) {
EnPoSisters_SetupSpinAttack(this);
} else {
EnPoSisters_MegCloneVanish(this, play);
}
} else if (this->megCloneId != POSISTER_MEG_REAL) {
} else if (this->megCloneId != POE_SISTERS_MEG_REAL) {
parent = (EnPoSisters*)this->actor.parent;
if (parent->actionFunc == EnPoSisters_DamageFlinch) {
// flinch clones if you hit the real meg
// Clones flinch if you hit the real Meg
EnPoSisters_SetupDamageFlinch(this);
}
} else if (this->megClonesRemaining == 0) {
// all meg clones have been killed, meg waits 15 frames then spin attacks
// timer is negative because megClonesRemaining and megAttackTimer are the same union'd variable
// All Meg clones have been killed: Real Meg waits 15 frames then spin attacks in retaliation
// Timer is negative (inrecrements to zero)
// because megClonesRemaining and megAttackTimer are the same union'd variable
this->megAttackTimer = -15;
} else if (this->megAttackTimer < 0) {
this->megAttackTimer++;
@ -874,7 +876,7 @@ void EnPoSisters_SetupSpawnPo(EnPoSisters* this) {
Animation_PlayOnce(&this->skelAnime, &gPoeSistersAppearDisappearAnim);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR);
this->color.a = 0;
this->poSisterFlags = POSISTERS_FLAG_UPDATE_FIRES;
this->poSisterFlags = POE_SISTERS_FLAG_UPDATE_FIRES;
this->actionFunc = EnPoSisters_PoeSpawn;
}
@ -882,8 +884,8 @@ void EnPoSisters_PoeSpawn(EnPoSisters* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
this->color.a = 255;
this->actor.flags |= ACTOR_FLAG_1;
this->poSisterFlags |= (POSISTERS_FLAG_UPDATE_BGCHECK_INFO | POSISTERS_FLAG_MATCH_PLAYER_HEIGHT);
if (this->type == POSISTER_TYPE_MEG) {
this->poSisterFlags |= (POE_SISTERS_FLAG_UPDATE_BGCHECK_INFO | POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT);
if (this->type == POE_SISTERS_TYPE_MEG) {
EnPoSisters_MegCloneVanish(this, play);
} else {
EnPoSisters_SetupAimlessIdleFlying(this);
@ -903,7 +905,7 @@ void EnPoSisters_CheckCollision(EnPoSisters* this, PlayState* play) {
this->collider.base.acFlags &= ~AC_HIT;
Actor_SetDropFlag(&this->actor, &this->collider.info);
if (this->megCloneId != POSISTER_MEG_REAL) {
if (this->megCloneId != POE_SISTERS_MEG_REAL) {
((EnPoSisters*)this->actor.parent)->megClonesRemaining--;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2);
EnPoSisters_MegCloneVanish(this, play);
@ -914,16 +916,16 @@ void EnPoSisters_CheckCollision(EnPoSisters* this, PlayState* play) {
Item_DropCollectible(play, &pos, ITEM00_ARROWS_10);
}
} else if (this->collider.base.colType != 9) {
if (this->actor.colChkInfo.damageEffect == POSISTERS_DAMAGEEFFECT_DEKUNUT) {
if (this->actor.colChkInfo.damageEffect == POE_SISTERS_DMGEFF_DEKUNUT) {
this->actor.world.rot.y = this->actor.shape.rot.y;
this->poSisterFlags |= POSISTERS_FLAG_UPDATE_SHAPE_ROT;
this->poSisterFlags |= POE_SISTERS_FLAG_UPDATE_SHAPE_ROT;
EnPoSisters_SetupSpinBackToVisible(this, play);
} else if ((this->type == POSISTER_TYPE_MEG) &&
(this->actor.colChkInfo.damageEffect == POSISTERS_DAMAGEEFFECT_SPINATTACK) &&
} else if ((this->type == POE_SISTERS_TYPE_MEG) &&
(this->actor.colChkInfo.damageEffect == POE_SISTERS_DMGEFF_SPINATTACK) &&
(this->actionFunc == EnPoSisters_MegSurroundPlayer)) {
if (this->megClonesRemaining == 0) {
// all meg clones have been killed, meg waits 45 frames then spin attacks
// timer is negative because megClonesRemaining and megAttackTimer are the same union'd variable
// All Meg clones have been killed: Real Meg waits 45 frames then spin attacks
// Timer is negative because megClonesRemaining and megAttackTimer are the same union'd variable
this->megAttackTimer = -45;
}
} else {
@ -934,7 +936,7 @@ void EnPoSisters_CheckCollision(EnPoSisters* this, PlayState* play) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_SISTER_DEAD);
}
if (this->actor.colChkInfo.damageEffect == POSISTERS_DAMAGEEFFECT_LIGHTARROWS) {
if (this->actor.colChkInfo.damageEffect == POE_SISTERS_DMGEFF_LIGHTARROWS) {
this->drawDmgEffAlpha = 4.0f;
this->drawDmgEffScale = 0.5f;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->collider.info.bumper.hitPos.x,
@ -960,19 +962,19 @@ void EnPoSisters_Update(Actor* thisx, PlayState* play) {
}
EnPoSisters_CheckCollision(this, play);
if (this->poSisterFlags & POSISTERS_FLAG_CHECK_Z_TARGET) {
if (this->poSisterFlags & POE_SISTERS_FLAG_CHECK_Z_TARGET) {
EnPoSisters_CheckZTarget(this, play);
}
this->actionFunc(this, play);
if (this->poSisterFlags & POSISTERS_FLAG_MATCH_PLAYER_HEIGHT) {
if (this->poSisterFlags & POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT) {
EnPoSisters_MatchPlayerY(this, play);
}
Actor_MoveWithGravity(&this->actor);
if (this->poSisterFlags & POSISTERS_FLAG_UPDATE_BGCHECK_INFO) {
if (this->poSisterFlags & POE_SISTERS_FLAG_UPDATE_BGCHECK_INFO) {
Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 0.0f, 5);
} else {
checkPos.x = this->actor.world.pos.x;
@ -999,8 +1001,8 @@ void EnPoSisters_Update(Actor* thisx, PlayState* play) {
}
if (this->poSisterFlags &
(POSISTERS_FLAG_UPDATE_BGCHECK_INFO | POSISTERS_FLAG_MATCH_PLAYER_HEIGHT | POSISTERS_FLAG_CHECK_Z_TARGET |
POSISTERS_FLAG_UPDATE_SHAPE_ROT | POSISTERS_FLAG_CHECK_AC)) {
(POE_SISTERS_FLAG_UPDATE_BGCHECK_INFO | POE_SISTERS_FLAG_MATCH_PLAYER_HEIGHT | POE_SISTERS_FLAG_CHECK_Z_TARGET |
POE_SISTERS_FLAG_UPDATE_SHAPE_ROT | POE_SISTERS_FLAG_CHECK_AC)) {
Collider_UpdateCylinder(&this->actor, &this->collider);
if ((this->actionFunc == EnPoSisters_SpinAttack) || (this->actionFunc == EnPoSisters_SpinUp)) {
this->fireCount++;
@ -1014,7 +1016,7 @@ void EnPoSisters_Update(Actor* thisx, PlayState* play) {
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
}
if (this->poSisterFlags & POSISTERS_FLAG_CHECK_AC) {
if (this->poSisterFlags & POE_SISTERS_FLAG_CHECK_AC) {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
}
@ -1024,23 +1026,23 @@ void EnPoSisters_Update(Actor* thisx, PlayState* play) {
if (this->actionFunc == EnPoSisters_Flee) {
this->actor.shape.rot.y = BINANG_ROT180(this->actor.world.rot.y);
} else if (this->poSisterFlags & POSISTERS_FLAG_UPDATE_SHAPE_ROT) {
} else if (this->poSisterFlags & POE_SISTERS_FLAG_UPDATE_SHAPE_ROT) {
this->actor.shape.rot.y = this->actor.world.rot.y;
}
}
}
void EnPoSisters_UpdateColors(EnPoSisters* this) {
if (this->skelAnime.animation == &gPoSistersAttackAnim) {
if (this->skelAnime.animation == &gPoeSistersAttackAnim) {
this->color.r = CLAMP_MAX(this->color.r + 5, 255);
this->color.g = CLAMP_MIN(this->color.g - 5, 50);
this->color.b = CLAMP_MIN(this->color.b - 5, 0);
} else if (this->skelAnime.animation == &gPoSistersFleeAnim) {
} else if (this->skelAnime.animation == &gPoeSistersFleeAnim) {
this->color.r = CLAMP_MAX(this->color.r + 5, 80);
this->color.g = CLAMP_MAX(this->color.g + 5, 255);
this->color.b = CLAMP_MAX(this->color.b + 5, 225);
} else if (this->skelAnime.animation == &gPoeSistersDamagedAnim) {
// flash every other frame after taking damage
// Flash every other frame after taking damage
if (this->actor.colorFilterTimer & 0x2) {
this->color.r = 0;
this->color.g = 0;
@ -1067,16 +1069,16 @@ void EnPoSisters_UpdateColors(EnPoSisters* this) {
s32 EnPoSisters_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx,
Gfx** gfx) {
static Gfx* gPoSisterBodyDisplayLists[] = {
gPoSistersMegBodyDL,
gPoSistersJoelleBodyDL,
gPoSistersBethBodyDL,
gPoSistersAmyBodyDL,
gPoeSistersMegBodyDL,
gPoeSistersJoelleBodyDL,
gPoeSistersBethBodyDL,
gPoeSistersAmyBodyDL,
};
static Gfx* gPoSisterFaceDisplayLists[] = {
gPoSistersMegFaceDL,
gPoSistersJoelleFaceDL,
gPoSistersBethFaceDL,
gPoSistersAmyFaceDL,
gPoeSistersMegFaceDL,
gPoeSistersJoelleFaceDL,
gPoeSistersBethFaceDL,
gPoeSistersAmyFaceDL,
};
static Color_RGBA8 gPoSisterColors[] = {
{ 80, 0, 100, 0 },
@ -1086,7 +1088,7 @@ s32 EnPoSisters_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Ve
};
EnPoSisters* this = THIS;
if (limbIndex == POSISTERS_LIMB_ROOT && (this->poSisterFlags & POSISTERS_FLAG_REAL_MEG_ROTATION)) {
if (limbIndex == POE_SISTERS_LIMB_ROOT && (this->poSisterFlags & POE_SISTERS_FLAG_REAL_MEG_ROTATION)) {
if (this->megSurroundTimer >= 284) {
rot->x += (this->megSurroundTimer - 284) * 0x1000;
} else {
@ -1094,17 +1096,17 @@ s32 EnPoSisters_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Ve
}
}
if ((this->color.a == 0) || (limbIndex == POSISTERS_LIMB_TORCH) ||
if ((this->color.a == 0) || (limbIndex == POE_SISTERS_LIMB_TORCH) ||
((this->actionFunc == EnPoSisters_DeathStage1) && (this->deathTimer >= 8))) {
*dList = NULL;
} else if (limbIndex == POSISTERS_LIMB_MAIN_BODY) {
} else if (limbIndex == POE_SISTERS_LIMB_MAIN_BODY) {
*dList = gPoSisterBodyDisplayLists[this->type];
} else if (limbIndex == POSISTERS_LIMB_FACE) {
} else if (limbIndex == POE_SISTERS_LIMB_FACE) {
*dList = gPoSisterFaceDisplayLists[this->type];
gDPPipeSync((*gfx)++);
gDPSetEnvColor((*gfx)++, this->color.r, this->color.g, this->color.b, this->color.a);
} else if (limbIndex == POSISTERS_LIMB_LOWER_BODY) {
} else if (limbIndex == POE_SISTERS_LIMB_LOWER_BODY) {
Color_RGBA8* color = &gPoSisterColors[this->type];
gDPPipeSync((*gfx)++);
@ -1114,46 +1116,47 @@ s32 EnPoSisters_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Ve
return false;
}
#define POSISTER_LIMBPOS_INVALID -1
#define POE_SISTERS_LIMBPOS_INVALID -1
void EnPoSisters_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) {
static Vec3f D_80B1DAFC = { 1000.0f, -1700.0f, 0.0f };
static s8 D_80B1DB08[] = {
POSISTER_LIMBPOS_INVALID,
POSISTER_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
0,
1,
2,
POSISTER_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
3,
POSISTER_LIMBPOS_INVALID,
POSISTER_LIMBPOS_INVALID,
POSISTER_LIMBPOS_INVALID,
POSISTER_LIMBPOS_INVALID,
POSISTER_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
POE_SISTERS_LIMBPOS_INVALID,
};
EnPoSisters* this = THIS;
s32 end;
f32 brightness;
if (D_80B1DB08[limbIndex] != POSISTER_LIMBPOS_INVALID) {
if (D_80B1DB08[limbIndex] != POE_SISTERS_LIMBPOS_INVALID) {
Matrix_MultZero(&this->limbPos[D_80B1DB08[limbIndex]]);
} else if (limbIndex == POSISTERS_LIMB_MAIN_BODY) {
} else if (limbIndex == POE_SISTERS_LIMB_MAIN_BODY) {
Matrix_MultVecY(-2500.0f, &this->limbPos[4]);
Matrix_MultVecY(3000.0f, &this->limbPos[5]);
} else if (limbIndex == POSISTERS_LIMB_FACE) {
} else if (limbIndex == POE_SISTERS_LIMB_FACE) {
Matrix_MultVecY(-4000.0f, &this->limbPos[6]);
} else if (limbIndex == POSISTERS_LIMB_LOWER_BODY) {
} else if (limbIndex == POE_SISTERS_LIMB_LOWER_BODY) {
Matrix_MultVecX(3000.0f, &this->limbPos[7]);
}
if (this->actionFunc == EnPoSisters_DeathStage1 && this->deathTimer >= 8 && limbIndex == POSISTERS_LIMB_MAIN_BODY) {
if (this->actionFunc == EnPoSisters_DeathStage1 && this->deathTimer >= 8 &&
limbIndex == POE_SISTERS_LIMB_MAIN_BODY) {
gSPMatrix((*gfx)++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList((*gfx)++, gPoSistersBurnBodyDL);
gSPDisplayList((*gfx)++, gPoeSistersBurnBodyDL);
}
if (limbIndex == POSISTERS_LIMB_TORCH) {
if (this->poSisterFlags & POSISTERS_FLAG_UPDATE_FIRES) {
if (limbIndex == POE_SISTERS_LIMB_TORCH) {
if (this->poSisterFlags & POE_SISTERS_FLAG_UPDATE_FIRES) {
for (end = this->fireCount - 1; end > 0; end--) {
this->firePos[end] = this->firePos[end - 1];
}
@ -1164,7 +1167,7 @@ void EnPoSisters_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s
if (this->fireCount > 0) {
Color_RGBA8* flameColor = &sPoSisterFlameColors[this->type];
brightness = Rand_ZeroFloat(0.3f) + 0.7f; // flickering torch light level
brightness = Rand_ZeroFloat(0.3f) + 0.7f; // Flickering torch light level
if (this->actionFunc == EnPoSisters_DeathStage2) {
Lights_PointNoGlowSetInfo(&this->lightInfo, this->firePos[0].x, this->firePos[0].y + 15.0f,
@ -1179,7 +1182,7 @@ void EnPoSisters_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s
Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0);
}
if (!(this->poSisterFlags & POSISTERS_FLAG_DRAW_TORCH)) {
if (!(this->poSisterFlags & POE_SISTERS_FLAG_DRAW_TORCH)) {
Matrix_Get(&this->mtxf);
}
}
@ -1203,23 +1206,23 @@ void EnPoSisters_Draw(Actor* thisx, PlayState* play) {
if ((this->color.a == 255) || (this->color.a == 0)) {
gDPSetEnvColor(POLY_OPA_DISP++, this->color.r, this->color.g, this->color.b, this->color.a);
gSPSegment(POLY_OPA_DISP++, 0x09, D_801AEFA0); // empty
gSPSegment(POLY_OPA_DISP++, 0x09, D_801AEFA0); // Empty DL
POLY_OPA_DISP =
SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable, EnPoSisters_OverrideLimbDraw,
EnPoSisters_PostLimbDraw, &this->actor, POLY_OPA_DISP);
} else {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->color.a);
gSPSegment(POLY_XLU_DISP++, 0x09, D_801AEF88); // xlu only DL
gSPSegment(POLY_XLU_DISP++, 0x09, D_801AEF88); // XLU only DL
POLY_XLU_DISP =
SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable, EnPoSisters_OverrideLimbDraw,
EnPoSisters_PostLimbDraw, &this->actor, POLY_XLU_DISP);
}
if (!(this->poSisterFlags & POSISTERS_FLAG_DRAW_TORCH)) {
if (!(this->poSisterFlags & POE_SISTERS_FLAG_DRAW_TORCH)) {
Matrix_Put(&this->mtxf);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gPoSistersDrawTorchDL);
gSPDisplayList(POLY_OPA_DISP++, gPoeSistersDrawTorchDL);
}
gSPSegment(

View File

@ -8,24 +8,24 @@ struct EnPoSisters;
typedef void (*EnPoSistersActionFunc)(struct EnPoSisters*, PlayState*);
#define ENPOSISTERS_GET_OBSERVER_FLAG(thisx) ((thisx)->params & 0x1000)
#define ENPOSISTERS_GET_MEG_CLONE_ID(thisx) (((thisx)->params >> 0xA) & 3)
#define ENPOSISTERS_GET_TYPE(thisx) (((thisx)->params >> 8) & 3)
#define POE_SISTERS_GET_OBSERVER_FLAG(thisx) ((thisx)->params & 0x1000)
#define POE_SISTERS_GET_MEG_CLONE_ID(thisx) (((thisx)->params >> 0xA) & 3)
#define POE_SISTERS_GET_TYPE(thisx) (((thisx)->params >> 8) & 3)
#define ENPOSISTERS_PARAMS(observerFlag, megClone, type) (((observerFlag) << 0xC) | ((megClone & 3) << 0xA) | ((type & 3) << 8))
#define POE_SISTERS_PARAMS(observerFlag, megClone, type) (((observerFlag) << 0xC) | ((megClone & 3) << 0xA) | ((type & 3) << 8))
typedef enum {
/* 0 */ POSISTER_TYPE_MEG, // purple
/* 1 */ POSISTER_TYPE_JO, // red
/* 2 */ POSISTER_TYPE_BETH, // blue
/* 3 */ POSISTER_TYPE_AMY, // green
/* 0 */ POE_SISTERS_TYPE_MEG, // purple
/* 1 */ POE_SISTERS_TYPE_JO, // red
/* 2 */ POE_SISTERS_TYPE_BETH, // blue
/* 3 */ POE_SISTERS_TYPE_AMY, // green
} EnPoSisterType;
typedef enum {
/* 0 */ POSISTER_MEG_REAL,
/* 1 */ POSISTER_MEG_CLONE1,
/* 2 */ POSISTER_MEG_CLONE2,
/* 3 */ POSISTER_MEG_CLONE3,
/* 0 */ POE_SISTERS_MEG_REAL,
/* 1 */ POE_SISTERS_MEG_CLONE1,
/* 2 */ POE_SISTERS_MEG_CLONE2,
/* 3 */ POE_SISTERS_MEG_CLONE3,
} EnPoSisterMegCloneID;
typedef struct EnPoSisters {
@ -54,8 +54,8 @@ typedef struct EnPoSisters {
s16 megAttackTimer; // delay until meg spin attacks player (negative frames counting up to 0)
s16 megClonesRemaining; // positive count of meg clones remaining
};
/* 0x196 */ Vec3s jointTable[POSISTERS_LIMB_MAX];
/* 0x1DE */ Vec3s morphTable[POSISTERS_LIMB_MAX];
/* 0x196 */ Vec3s jointTable[POE_SISTERS_LIMB_MAX];
/* 0x1DE */ Vec3s morphTable[POE_SISTERS_LIMB_MAX];
/* 0x226 */ Color_RGBA8 color;
/* 0x22C */ Vec3f firePos[8];
/* 0x28C */ Vec3f limbPos[8]; // passed to Actor_DrawDamageEffects