diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index e0c88ce2e..661dcaedf 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -29,6 +29,7 @@ set(MP1_WORLD_SOURCES CNewIntroBoss.hpp CNewIntroBoss.cpp COmegaPirate.hpp COmegaPirate.cpp CParasite.hpp CParasite.cpp + CPhazonHealingNodule.hpp CPhazonHealingNodule.cpp CPuddleSpore.hpp CPuddleSpore.cpp CPuddleToadGamma.hpp CPuddleToadGamma.cpp CPuffer.hpp CPuffer.cpp diff --git a/Runtime/MP1/World/CPhazonHealingNodule.cpp b/Runtime/MP1/World/CPhazonHealingNodule.cpp new file mode 100644 index 000000000..f8b3c79af --- /dev/null +++ b/Runtime/MP1/World/CPhazonHealingNodule.cpp @@ -0,0 +1,23 @@ +#include "Runtime/MP1/World/CPhazonHealingNodule.hpp" + +#include "Runtime/CSimplePool.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/World/CPatternedInfo.hpp" + +namespace urde::MP1 { +CPhazonHealingNodule::CPhazonHealingNodule(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, + const CActorParameters& actParams, const CPatternedInfo& pInfo, + CAssetId particleDescId, std::string str) +: CPatterned(ECharacter::PhazonHealingNodule, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, + EMovementType::Flyer, EColliderType::One, EBodyType::Restricted, actParams, EKnockBackVariant::Medium) +, x570_(g_SimplePool->GetObj(SObjectTag{SBIG('ELSC'), particleDescId})) +, x580_(pInfo.GetHealthInfo()) +, x58c_(std::move(str)) { + const CMaterialFilter& filter = GetMaterialFilter(); + CMaterialList include = filter.GetIncludeList(); + CMaterialList exclude = filter.GetExcludeList(); + exclude.Add(EMaterialTypes::Character); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(include, exclude)); +} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CPhazonHealingNodule.hpp b/Runtime/MP1/World/CPhazonHealingNodule.hpp new file mode 100644 index 000000000..d8e6274fe --- /dev/null +++ b/Runtime/MP1/World/CPhazonHealingNodule.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "Runtime/World/CPatterned.hpp" +#include "Runtime/Particle/CParticleElectric.hpp" + +namespace urde::MP1 { +class CPhazonHealingNodule : public CPatterned { +private: + int x568_ = 0; + u8 x56c_ = 0; + TUniqueId x56e_ = kInvalidUniqueId; + TCachedToken x570_; + std::unique_ptr x57c_; // was rstl::rc_ptr + CHealthInfo x580_; + int x588_ = 0; // not init in ctr + std::string x58c_; + // u32 x59c_; + +public: + CPhazonHealingNodule(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& actParams, const CPatternedInfo& pInfo, + CAssetId particleDescId, std::string str); +}; +} // namespace urde::MP1 diff --git a/Runtime/Particle/CParticleElectric.hpp b/Runtime/Particle/CParticleElectric.hpp index 880ec2be3..9da641f06 100644 --- a/Runtime/Particle/CParticleElectric.hpp +++ b/Runtime/Particle/CParticleElectric.hpp @@ -10,7 +10,9 @@ #include "Runtime/CToken.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Graphics/CLineRenderer.hpp" +#include "Runtime/Particle/CElementGen.hpp" #include "Runtime/Particle/CParticleGen.hpp" +#include "Runtime/Particle/CParticleSwoosh.hpp" #include #include @@ -19,8 +21,6 @@ namespace urde { class CElectricDescription; -class CElementGen; -class CParticleSwoosh; class CParticleElectric : public CParticleGen { static u16 g_GlobalSeed; diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index b754dfbbd..09cc33cf2 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -33,6 +33,7 @@ #include "Runtime/MP1/World/CNewIntroBoss.hpp" #include "Runtime/MP1/World/COmegaPirate.hpp" #include "Runtime/MP1/World/CParasite.hpp" +#include "Runtime/MP1/World/CPhazonHealingNodule.hpp" #include "Runtime/MP1/World/CPuddleSpore.hpp" #include "Runtime/MP1/World/CPuddleToadGamma.hpp" #include "Runtime/MP1/World/CPuffer.hpp" @@ -3672,7 +3673,32 @@ CEntity* ScriptLoader::LoadPhazonPool(CStateManager& mgr, CInputStream& in, int CEntity* ScriptLoader::LoadPhazonHealingNodule(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 9, "PhazonHealingNodule")) { + return nullptr; + } + + SScaledActorHead actHead = LoadScaledActorHead(in, mgr); + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + if (!pair.first) { + return nullptr; + } + + CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + + in.readBool(); + CAssetId w1{in}; + std::string w2 = in.readString(); + + if (!pInfo.GetAnimationParameters().GetACSFile().IsValid()) { + return nullptr; + } + + CModelData mData(CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(), + actHead.x40_scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true)); + + return new MP1::CPhazonHealingNodule(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, + std::move(mData), actParms, pInfo, w1, std::move(w2)); } CEntity* ScriptLoader::LoadNewCameraShaker(CStateManager& mgr, CInputStream& in, int propCount,