diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 17be688a..1d6206c4 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -18382,7 +18382,7 @@ lbl_803E2D48 = .data:0x803E2D48; // type:object size:0x6C jumptable_803E2DB4 = .data:0x803E2DB4; // type:object size:0xCC scope:local jumptable_803E2E80 = .data:0x803E2E80; // type:object size:0x68 scope:local lbl_803E2EE8 = .data:0x803E2EE8; // type:object size:0x20 -lbl_803E2F08 = .data:0x803E2F08; // type:object size:0x2D0 +__vt__10CSpankWeed = .data:0x803E2F08; // type:object size:0x2D0 lbl_803E31D8 = .data:0x803E31D8; // type:object size:0xC data:4byte lbl_803E31E4 = .data:0x803E31E4; // type:object size:0x2D4 __vt__17CScriptPlayerHint = .data:0x803E34B8; // type:object size:0x6C diff --git a/include/Kyoto/Animation/CSegId.hpp b/include/Kyoto/Animation/CSegId.hpp index 95c6109a..c17670f5 100644 --- a/include/Kyoto/Animation/CSegId.hpp +++ b/include/Kyoto/Animation/CSegId.hpp @@ -12,6 +12,9 @@ public: const uchar val() const { return x0_id; } + bool operator==(const CSegId& other) const { return x0_id == other.x0_id; } + bool operator!=(const CSegId& other) const { return x0_id != other.x0_id; } + private: uchar x0_id; }; diff --git a/include/MetroidPrime/Enemies/CSpankWeed.hpp b/include/MetroidPrime/Enemies/CSpankWeed.hpp index 570b8ec8..c99a80cb 100644 --- a/include/MetroidPrime/Enemies/CSpankWeed.hpp +++ b/include/MetroidPrime/Enemies/CSpankWeed.hpp @@ -1,6 +1,7 @@ #ifndef _CSPANKWEED #define _CSPANKWEED +#include "MetroidPrime/Collision/CJointCollisionDescription.hpp" #include "types.h" #include "MetroidPrime/Enemies/CPatterned.hpp" @@ -12,10 +13,9 @@ class CCollisionActorManager; class CSpankWeed : public CPatterned { public: CSpankWeed(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, - const CTransform4f& xf, const CModelData& mData, - const CActorParameters& actParms, const CPatternedInfo& pInfo, - float maxDetectionRange, float maxHearingRange, float maxSightRange, - float hideTime); + const CTransform4f& xf, const CModelData& mData, const CActorParameters& actParms, + const CPatternedInfo& pInfo, float maxDetectionRange, float maxHearingRange, + float maxSightRange, float hideTime); // CEntity ~CSpankWeed() override {} @@ -64,6 +64,8 @@ private: int x5bc_; float GetPlayerDistance(CStateManager& mgr) const; + + static const SSphereJointInfo skSphereJointInfoList[]; }; CHECK_SIZEOF(CSpankWeed, 0x5c0) diff --git a/src/MetroidPrime/Enemies/CSpankWeed.cpp b/src/MetroidPrime/Enemies/CSpankWeed.cpp new file mode 100644 index 00000000..95e1d071 --- /dev/null +++ b/src/MetroidPrime/Enemies/CSpankWeed.cpp @@ -0,0 +1,80 @@ +#include "MetroidPrime/Enemies/CSpankWeed.hpp" + +#include "MetroidPrime/Collision/CJointCollisionDescription.hpp" + +static const char* Arm_2 = "Arm_2"; +static const char* Arm_3 = "Arm_3"; +static const char* Arm_4 = "Arm_4"; +static const char* Arm_5 = "Arm_5"; +static const char* Arm_6 = "Arm_6"; +static const char* Arm_7 = "Arm_7"; +static const char* Arm_8 = "Arm_8"; +static const char* Arm_9 = "Arm_9"; +static const char* Arm_10 = "Arm_10"; +static const char* Arm_11 = "Arm_11"; +static const char* Arm_12 = "Arm_12"; +static const char* Arm_end = "Arm_end"; + +const SSphereJointInfo CSpankWeed::skSphereJointInfoList[] = { + {"Arm_4", 1.5f}, {"Arm_6", 1.f}, {"Arm_7", 1.f}, {"Arm_8", 1.f}, + {"Arm_9", 1.f}, {"Arm_11", 1.f}, {"swoosh_LCTR", 1.5f}, +}; + +static const char* lockon_target_LCTR = "lockon_target_LCTR"; +static const char* Eye = "Eye"; + +CSpankWeed::CSpankWeed(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const CModelData& mData, + const CActorParameters& actParms, const CPatternedInfo& pInfo, + float maxDetectionRange, float maxHearingRange, float maxSightRange, + float hideTime) +: CPatterned(kC_SpankWeed, uid, name, kFT_Zero, info, xf, mData, pInfo, kMT_Flyer, kCT_One, + kBT_Restricted, actParms, kKBV_Medium) +, x568_maxDetectionRange(maxDetectionRange) +, x56c_detectionHeightRange(pInfo.GetDetectionHeightRange()) +, x570_maxHearingRange(maxHearingRange) +, x574_maxSightRange(maxSightRange) +, x578_hideTime(hideTime) +, x57c_canKnockBack(false) +, x580_(0.f) +, x584_retreatOrigin(xf.GetTranslation()) +, x590_(kInvalidUniqueId) +, x598_isHiding(false) +, x59c_lockonOffset(CVector3f::Zero()) +, x5a8_lockonTarget(CVector3f::Zero()) +, x5b4_(-1) +, x5b8_(-1) +, x5bc_(-1) { + SetCallTouch(false); + SetDrawShadow(false); + const CVector3f modelScale = GetModelData()->GetScale(); + if (modelScale.GetX() != modelScale.GetY() || modelScale.GetX() != modelScale.GetZ()) { + const float mag = modelScale.Magnitude(); + const float scale = CMath::SqrtF(3.f); + ModelData()->SetScale(CVector3f(mag / scale, mag / scale, mag / scale)); + char buf[1024]; + sprintf( + buf, + "WARNING: Non-uniform scale (%.2f, %.2f, %.2f) applied to Spank Weed...changing scale to " + "(%.2f, %.2f, %.2f)\n", + modelScale.GetX(), modelScale.GetY(), modelScale.GetZ(), mag, mag, mag); + } + + CMaterialList list = GetMaterialFilter().GetExcludeList(); + list.Add(CMaterialList(kMT_Character, kMT_Player)); + SetMaterialFilter( + CMaterialFilter::MakeIncludeExclude(GetMaterialFilter().GetIncludeList(), list)); + + const CSegId lockonLctr = AnimationData()->GetLocatorSegId(rstl::string_l("lockon_target_LCTR")); + + if (lockonLctr != CSegId()) { + const CTransform4f tmpXf = GetAnimationData()->GetLocatorTransform(lockonLctr, nullptr); + const CVector3f scale = GetModelData()->GetScale(); + const CTransform4f locatorXf = GetTransform() * CTransform4f::Scale(scale) * tmpXf; + + x5a8_lockonTarget = locatorXf.GetTranslation(); + x59c_lockonOffset = locatorXf.GetTranslation() - GetTranslation(); + } + + GetKnockBackCtrl().SetAutoResetImpulse(false); +} \ No newline at end of file