diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index 046d6191b..5383fb802 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -863,8 +863,9 @@ SAdvancementDeltas CAnimData::Advance(float dt, const zeus::CVector3f& scale, if (suspendParticles) x120_particleDB.SuspendAllActiveEffects(stateMgr); - for (CParticlePOINode& node : g_ParticlePOINodes) + for (int i=0 ; i 0) { - for (CInt32POINode& node : g_Int32POINodes) + for (int i=0 ; isecond; if (info.GetIsActive()) { - if (info.GetState() == EParticleGenState::NotStarted) + if (info.GetType() == EParticleGenType::Normal) { CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName()); if (segId == 0xff) @@ -188,16 +188,16 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p } default: break; } + } - float sec = (info.GetInactiveStartTime() == 0.f) ? 10000000.f : info.GetInactiveStartTime(); - if (info.GetCurrentTime() > sec) - { - info.SetIsActive(false); - info.SetParticleEmission(false, stateMgr); - info.MarkFinishTime(); - if (info.GetFlags() & 1) - info.DestroyParticles(); - } + float sec = (info.GetInactiveStartTime() == 0.f) ? 10000000.f : info.GetInactiveStartTime(); + if (info.GetCurrentTime() > sec) + { + info.SetIsActive(false); + info.SetParticleEmission(false, stateMgr); + info.MarkFinishTime(); + if (info.GetFlags() & 1) + info.DestroyParticles(); } } @@ -404,7 +404,7 @@ void CParticleDatabase::AddAuxiliaryParticleEffect(std::string_view name, int fl newGen = std::make_unique(data.GetTag(), sys, data.GetDuration(), "NOT_A_VALID_LOCATOR", scaleVec, CParticleData::EParentedMode::Initial, flags, mgr, aid, lightId + _getGraphicLightId(sys, *search->second), - EParticleGenState::Started); + EParticleGenType::Auxiliary); newGen->SetGlobalTranslation(data.GetTranslation(), mgr); newGen->SetIsGrabInitialData(false); @@ -450,7 +450,7 @@ void CParticleDatabase::AddParticleEffect(std::string_view name, int flags, cons newGen = std::make_unique(data.GetTag(), sys, data.GetDuration(), data.GetSegmentName(), scaleVec, data.GetParentedMode(), flags, mgr, aid, lightId + _getGraphicLightId(sys, *search->second), - EParticleGenState::NotStarted); + EParticleGenType::Normal); } break; } @@ -462,7 +462,7 @@ void CParticleDatabase::AddParticleEffect(std::string_view name, int flags, cons auto sys = std::make_shared(*search->second, 0); newGen = std::make_unique(data.GetTag(), sys, data.GetDuration(), data.GetSegmentName(), scaleVec, data.GetParentedMode(), flags, mgr, aid, - -1, EParticleGenState::NotStarted); + -1, EParticleGenType::Normal); } break; } @@ -475,7 +475,7 @@ void CParticleDatabase::AddParticleEffect(std::string_view name, int flags, cons newGen = std::make_unique(data.GetTag(), sys, data.GetDuration(), data.GetSegmentName(), scaleVec, data.GetParentedMode(), flags, mgr, aid, lightId + _getGraphicLightId(sys, *search->second), - EParticleGenState::NotStarted); + EParticleGenType::Normal); } break; } diff --git a/Runtime/Character/CParticleGenInfo.cpp b/Runtime/Character/CParticleGenInfo.cpp index 9c208e7fe..eca53cfaf 100644 --- a/Runtime/Character/CParticleGenInfo.cpp +++ b/Runtime/Character/CParticleGenInfo.cpp @@ -12,14 +12,14 @@ namespace urde CParticleGenInfo::CParticleGenInfo(const SObjectTag& part, int frameCount, std::string_view boneName, const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode, - int flags, EParticleGenState state) + int flags, EParticleGenType type) : x4_part(part) , xc_seconds(frameCount / 60.f) , x10_boneName(boneName) , x28_parentMode(parentMode) , x2c_flags(flags) , x30_particleScale(scale) -, x80_state(state) +, x80_type(type) { } @@ -43,7 +43,7 @@ CParticleGenInfoGeneric::CParticleGenInfoGeneric(const SObjectTag& part, const s int frameCount, std::string_view boneName, const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode, int flags, CStateManager& stateMgr, TAreaId areaId, int lightId, - EParticleGenState state) + EParticleGenType state) : CParticleGenInfo(part, frameCount, boneName, scale, parentMode, flags, state), x84_system(system) { if (lightId == -1) diff --git a/Runtime/Character/CParticleGenInfo.hpp b/Runtime/Character/CParticleGenInfo.hpp index e7d516384..a7c9d0ca2 100644 --- a/Runtime/Character/CParticleGenInfo.hpp +++ b/Runtime/Character/CParticleGenInfo.hpp @@ -12,10 +12,10 @@ struct SObjectTag; class CParticleGen; class CStateManager; -enum class EParticleGenState +enum class EParticleGenType { - NotStarted, - Started + Normal, + Auxiliary }; class CParticleGenInfo @@ -32,12 +32,12 @@ class CParticleGenInfo bool x40_grabInitialData = false; zeus::CTransform x44_transform; zeus::CVector3f x74_offset; - EParticleGenState x80_state; + EParticleGenType x80_type; public: CParticleGenInfo(const SObjectTag& part, int frameCount, std::string_view boneName, const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode, - int flags, EParticleGenState state); + int flags, EParticleGenType type); virtual ~CParticleGenInfo() = default; virtual void AddToRenderer() = 0; @@ -77,8 +77,7 @@ public: float GetFinishTime() const { return x3c_finishTime; } float GetCurrentTime() const { return x20_curTime; } void SetCurrentTime(float t) { x20_curTime = t; } - EParticleGenState GetState() const { return x80_state; } - void SetState(EParticleGenState s) { x80_state = s; } + EParticleGenType GetType() const { return x80_type; } CParticleData::EParentedMode GetParentedMode() const { return x28_parentMode; } std::string_view GetLocatorName() const { return x10_boneName; } @@ -93,7 +92,7 @@ public: CParticleGenInfoGeneric(const SObjectTag& part, const std::weak_ptr& system, int frames, std::string_view boneName, const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode, int flags, CStateManager& stateMgr, TAreaId, - int lightId, EParticleGenState state); + int lightId, EParticleGenType state); void AddToRenderer(); void Render(); diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index 05de06977..b0e828a42 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -1316,15 +1316,15 @@ void CElementGen::RenderParticles() } } - zeus::CTransform systemViewPointMatrix(CGraphics::g_ViewMatrix); - systemViewPointMatrix.origin.zeroOut(); - zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation; - systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) * - systemViewPointMatrix) * x178_localScaleTransform; + zeus::CTransform systemModelMatrix(CGraphics::g_ViewMatrix); + systemModelMatrix.origin.zeroOut(); + zeus::CTransform systemCameraMatrix = systemModelMatrix.inverse() * x22c_globalOrientation; + systemModelMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) * + systemModelMatrix) * x178_localScaleTransform; if (x26c_29_ORNT) - CGraphics::SetModelMatrix(systemViewPointMatrix * systemCameraMatrix); + CGraphics::SetModelMatrix(systemModelMatrix * systemCameraMatrix); else - CGraphics::SetModelMatrix(systemViewPointMatrix); + CGraphics::SetModelMatrix(systemModelMatrix); CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); @@ -1475,10 +1475,10 @@ void CElementGen::RenderParticles() { g_instTexData.emplace_back(); SParticleInstanceTex& inst = g_instTexData.back(); - inst.pos[0] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z + size, 1.f}; - inst.pos[1] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z + size, 1.f}; - inst.pos[2] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z - size, 1.f}; - inst.pos[3] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z - size, 1.f}; + inst.pos[0] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z + size, 1.f}; + inst.pos[1] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z + size, 1.f}; + inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f}; + inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f}; inst.color = particle.x34_color; inst.uvs[0] = {uvs.xMax, uvs.yMax}; inst.uvs[1] = {uvs.xMin, uvs.yMax}; @@ -1490,10 +1490,10 @@ void CElementGen::RenderParticles() { g_instNoTexData.emplace_back(); SParticleInstanceNoTex& inst = g_instNoTexData.back(); - inst.pos[0] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z + size, 1.f}; - inst.pos[1] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z + size, 1.f}; - inst.pos[2] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z - size, 1.f}; - inst.pos[3] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z - size, 1.f}; + inst.pos[0] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z + size, 1.f}; + inst.pos[1] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z + size, 1.f}; + inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f}; + inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f}; inst.color = particle.x34_color; break; } @@ -1513,11 +1513,11 @@ void CElementGen::RenderParticles() { g_instTexData.emplace_back(); SParticleInstanceTex& inst = g_instTexData.back(); - inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f}; - inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, 0.f, viewPoint.z + sinT + cosT, 1.f}; - inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT), + inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, viewPoint.y, viewPoint.z + cosT - sinT, 1.f}; + inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, viewPoint.y, viewPoint.z + sinT + cosT, 1.f}; + inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), viewPoint.y, viewPoint.z + (-cosT - sinT), 1.f}; - inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT), + inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), viewPoint.y, viewPoint.z - (cosT - sinT), 1.f}; inst.color = particle.x34_color; inst.uvs[0] = {uvs.xMax, uvs.yMax}; @@ -1530,11 +1530,11 @@ void CElementGen::RenderParticles() { g_instNoTexData.emplace_back(); SParticleInstanceNoTex& inst = g_instNoTexData.back(); - inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f}; - inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, 0.f, viewPoint.z + sinT + cosT, 1.f}; - inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT), + inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, viewPoint.y, viewPoint.z + cosT - sinT, 1.f}; + inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, viewPoint.y, viewPoint.z + sinT + cosT, 1.f}; + inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), viewPoint.y, viewPoint.z + (-cosT - sinT), 1.f}; - inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT), + inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), viewPoint.y, viewPoint.z - (cosT - sinT), 1.f}; inst.color = particle.x34_color; break; diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index da267a1c1..72121a97f 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -152,7 +152,8 @@ void CAreaRenderOctTree::Node::RecursiveBuildOverlaps(u32* bmpOut, { if (testAABB.intersects(curAABB)) { - if (curAABB.inside(testAABB)) + u32 childCount = GetChildCount(); // HACK: Always return the smallest set of intersections + if (curAABB.inside(testAABB) || childCount == 0) { const u32* bmp = &parent.x30_bitmaps[x0_bitmapIdx * parent.x14_bitmapWordCount]; for (u32 c=0 ; cIsFusionEnabled()) + { + switch (suit) + { + case CPlayerState::EPlayerSuit::Power: + return 4; + case CPlayerState::EPlayerSuit::Varia: + return 7; + case CPlayerState::EPlayerSuit::Gravity: + return 6; + case CPlayerState::EPlayerSuit::Phazon: + return 8; + default: + break; + } + } + return u32(suit); +} + +void CScriptPlayerActor::LoadSuit(u32 charIdx) +{ + if (charIdx != x310_loadedCharIdx) + { + TToken fac = g_CharFactoryBuilder->GetFactory(x2e8_suitRes); + const CCharacterInfo& chInfo = fac->GetCharInfo(charIdx); + x324_suitModel = g_SimplePool->GetObj({FOURCC('CMDL'), chInfo.GetModelId()}); + x354_28_ = true; + x310_loadedCharIdx = charIdx; + } +} + +void CScriptPlayerActor::LoadBeam(CPlayerState::EBeamId beam) { } +void CScriptPlayerActor::Think(float dt, CStateManager& mgr) +{ + auto& pState = *mgr.GetPlayerState(); + + if (x354_31_) + { + x354_25_ = true; + x354_31_ = false; + x308_suit = pState.GetCurrentSuitRaw(); + LoadSuit(GetSuitCharIdx(mgr, x308_suit)); + } + + if (x354_30_) + { + if (!(x350_flags & 0x1)) + { + u32 tmpIdx = GetSuitCharIdx(mgr, pState.GetCurrentSuitRaw()); + if (tmpIdx != x310_loadedCharIdx) + { + SetModelData(std::make_unique(CModelData::CModelDataNull())); + LoadSuit(tmpIdx); + x354_25_ = true; + } + } + + LoadBeam(x304_beam != CPlayerState::EBeamId::Invalid ? x304_beam : pState.GetCurrentBeam()); + } +} + void CScriptPlayerActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { } @@ -47,7 +113,7 @@ void CScriptPlayerActor::SetActive(bool active) void CScriptPlayerActor::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { - if (x2e8_.GetCharacterNodeId() == 3) + if (x2e8_suitRes.GetCharacterNodeId() == 3) g_Renderer->AllocatePhazonSuitMaskTexture(); CScriptActor::PreRender(mgr, frustum); } diff --git a/Runtime/World/CScriptPlayerActor.hpp b/Runtime/World/CScriptPlayerActor.hpp index b9bfbddfe..fd0970a93 100644 --- a/Runtime/World/CScriptPlayerActor.hpp +++ b/Runtime/World/CScriptPlayerActor.hpp @@ -2,26 +2,27 @@ #define __URDE_CSCRIPTPLAYERACTOR_HPP__ #include "CScriptActor.hpp" +#include "CPlayerState.hpp" namespace urde { class CScriptPlayerActor : public CScriptActor { - CAnimRes x2e8_; - u32 x304_; - s32 x308_ = -1; + CAnimRes x2e8_suitRes; + CPlayerState::EBeamId x304_beam; + CPlayerState::EPlayerSuit x308_suit = CPlayerState::EPlayerSuit::Invalid; s32 x30c_ = -1; - s32 x310_ = -1; + s32 x310_loadedCharIdx = -1; u32 x314_ = 0; u32 x318_ = 0; u32 x31c_ = 0; u32 x320_ = 0; - u32 x324_ = 0; + TLockedToken x324_suitModel; u8 x334_ = 0; u8 x344_ = 0; u32 x348_ = 0; float x34c_ = 0.f; - u32 x350_; + u32 x350_flags; union { struct @@ -36,13 +37,19 @@ class CScriptPlayerActor : public CScriptActor bool x354_31_ : 1; bool x355_24_ : 1; }; - u8 x355_dummy = 0; + u32 _dummy = 0; }; + u32 GetSuitCharIdx(const CStateManager& mgr, CPlayerState::EPlayerSuit suit) const; + void LoadSuit(u32 charIdx); + void LoadBeam(CPlayerState::EBeamId beam); + public: - CScriptPlayerActor(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, const CAnimRes&, - CModelData&&, const zeus::CAABox&, bool, const CMaterialList&, float, float, - const CHealthInfo&, const CDamageVulnerability&, const CActorParameters&, bool, bool, u32, u32); + CScriptPlayerActor(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, const CAnimRes& animRes, CModelData&& mData, + const zeus::CAABox& aabox, bool b1, const CMaterialList& list, float mass, + float zMomentum, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, + const CActorParameters& aParams, bool loop, bool active, u32 flags, CPlayerState::EBeamId beam); void Think(float, CStateManager &); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &); diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 63b00b453..0cfbd9766 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -1863,7 +1863,7 @@ CEntity* ScriptLoader::LoadPlayerActor(CStateManager& mgr, CInputStream& in, int bool solid = in.readBool(); bool active = in.readBool(); u32 flags = LoadParameterFlags(in); - bool w1 = in.readUint32Big() - 1; + CPlayerState::EBeamId beam = CPlayerState::EBeamId(in.readUint32Big() - 1); FourCC fcc = g_ResFactory->GetResourceTypeById(animParms.GetACSFile()); if (!fcc || fcc != SBIG('ANCS')) @@ -1884,7 +1884,7 @@ CEntity* ScriptLoader::LoadPlayerActor(CStateManager& mgr, CInputStream& in, int CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), aHead.x40_scale, animParms.GetInitialAnimation(), loop), CModelData::CModelDataNull(), aabox, true, list, mass, zMomentum, hInfo, dVuln, - actParms, loop, active, flags, w1); + actParms, loop, active, flags, beam); } CEntity* ScriptLoader::LoadFlaahgra(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)