diff --git a/Runtime/Camera/CCameraFilter.hpp b/Runtime/Camera/CCameraFilter.hpp index 3bea74ac7..af93ab4c2 100644 --- a/Runtime/Camera/CCameraFilter.hpp +++ b/Runtime/Camera/CCameraFilter.hpp @@ -21,7 +21,8 @@ enum class EFilterType Blend, Widescreen, SceneAdd, - NoColor + NoColor, + InvDstMultiply }; enum class EFilterShape diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index e6ccf1590..5c7a675a3 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -224,7 +224,9 @@ public: SAdvancementDeltas AdvanceIgnoreParticles(float, CRandom16&, bool advTree); void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&); void SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules); + std::shared_ptr GetXRayModel() const { return xf4_xrayModel; } void SetInfraModel(const TLockedToken& model, const TLockedToken& skinRules); + std::shared_ptr GetInfraModel() const { return xf8_infraModel; } const TCachedToken& GetModelData() const { return xd8_modelData; } static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, @@ -253,6 +255,7 @@ public: s32 GetCharacterIndex() const { return x204_charIdx; } u16 GetDefaultAnimation() const { return x208_defaultAnim; } + const TLockedToken& GetIceModel() const { return xe4_iceModelData; } }; } diff --git a/Runtime/Character/CModelData.hpp b/Runtime/Character/CModelData.hpp index acefa36fc..c14fb10c3 100644 --- a/Runtime/Character/CModelData.hpp +++ b/Runtime/Character/CModelData.hpp @@ -158,6 +158,31 @@ public: void SetScale(const zeus::CVector3f& scale) { x0_scale = scale; } bool HasAnimData() const { return x10_animData != nullptr; } bool HasNormalModel() const { return x1c_normalModel; } + bool HasModel(EWhichModel which) + { + if (x10_animData) + { + switch(which) + { + case EWhichModel::Normal: return true; + case EWhichModel::XRay: return x10_animData->GetXRayModel().operator bool(); + case EWhichModel::Thermal: return x10_animData->GetInfraModel().operator bool(); + default: + return false; + } + } + + switch(which) + { + case EWhichModel::Normal: + return x1c_normalModel; + case EWhichModel::XRay: + return x2c_xrayModel; + case EWhichModel::Thermal: + return x3c_infraModel; + default: return false; + } + } }; } diff --git a/Runtime/Character/CSteeringBehaviors.hpp b/Runtime/Character/CSteeringBehaviors.hpp index e0fd8fa18..1eb442fc8 100644 --- a/Runtime/Character/CSteeringBehaviors.hpp +++ b/Runtime/Character/CSteeringBehaviors.hpp @@ -9,6 +9,7 @@ namespace urde class CSteeringBehaviors { + float x0_ = M_PIF / 2.f; public: static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel, const zeus::CVector3f& orbitPoint, float dt, float preThinkDt); diff --git a/Runtime/Graphics/CSimpleShadow.cpp b/Runtime/Graphics/CSimpleShadow.cpp index 2acdfdbba..3e74b3685 100644 --- a/Runtime/Graphics/CSimpleShadow.cpp +++ b/Runtime/Graphics/CSimpleShadow.cpp @@ -39,7 +39,7 @@ void CSimpleShadow::Render(const TLockedToken& tex) const CGraphics::SetModelMatrix(x0_xf); if (!m_filter || m_filter->GetTex().GetObj() != tex.GetObj()) - m_filter.emplace(EFilterType::Blend, tex, CTexturedQuadFilter::ZTest::LEqual); + m_filter.emplace(EFilterType::InvDstMultiply, tex, CTexturedQuadFilter::ZTest::LEqual); float radius = x34_radius * x30_scale; CTexturedQuadFilter::Vert verts[] = diff --git a/Runtime/Graphics/CSimpleShadow.hpp b/Runtime/Graphics/CSimpleShadow.hpp index bb2c32d23..0e3102064 100644 --- a/Runtime/Graphics/CSimpleShadow.hpp +++ b/Runtime/Graphics/CSimpleShadow.hpp @@ -27,6 +27,7 @@ public: bool Valid() const { return x48_24_collision; } zeus::CAABox GetMaxShadowBox(const zeus::CAABox& aabb) const; zeus::CAABox GetBounds() const; + void SetAlwaysCalculateRadius(bool) { x48_25_alwaysCalculateRadius = true; } float GetMaxObjectHeight() const { return x40_maxObjHeight; } void SetUserAlpha(float a) { x38_userAlpha = a; } const zeus::CTransform& GetTransform() const { return x0_xf; } diff --git a/Runtime/Graphics/CVertexMorphEffect.hpp b/Runtime/Graphics/CVertexMorphEffect.hpp index 0baa8ee68..8bf8cf07a 100644 --- a/Runtime/Graphics/CVertexMorphEffect.hpp +++ b/Runtime/Graphics/CVertexMorphEffect.hpp @@ -10,10 +10,14 @@ class CSkinRules; class CVertexMorphEffect { + u32 x0_ = 0; + u32 x4_ = 1; public: void MorphVertices(std::vector>& vn, const float* magnitudes, const TLockedToken& skinRules, const CPoseAsTransforms& pose) const; + + void Update(float) {} }; } diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp b/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp index 0f5b8f064..ea3de1503 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp @@ -109,12 +109,32 @@ static boo::ObjToken s_AlphaPipeline; static boo::ObjToken s_AlphaGEqualPipeline; static boo::ObjToken s_AlphaLEqualPipeline; static boo::ObjToken s_AddPipeline; +static boo::ObjToken s_AddGEqualPipeline; +static boo::ObjToken s_AddLEqualPipeline; +static boo::ObjToken s_SubtractPipeline; +static boo::ObjToken s_SubtractGEqualPipeline; +static boo::ObjToken s_SubtractLEqualPipeline; static boo::ObjToken s_MultPipeline; +static boo::ObjToken s_MultGEqualPipeline; +static boo::ObjToken s_MultLEqualPipeline; +static boo::ObjToken s_InvDstMultPipeline; +static boo::ObjToken s_InvDstMultGEqualPipeline; +static boo::ObjToken s_InvDstMultLEqualPipeline; static boo::ObjToken s_AlphaFlipPipeline; static boo::ObjToken s_AlphaGEqualFlipPipeline; static boo::ObjToken s_AlphaLEqualFlipPipeline; static boo::ObjToken s_AddFlipPipeline; +static boo::ObjToken s_AddGEqualFlipPipeline; +static boo::ObjToken s_AddLEqualFlipPipeline; +static boo::ObjToken s_SubtractFlipPipeline; +static boo::ObjToken s_SubtractGEqualFlipPipeline; +static boo::ObjToken s_SubtractLEqualFlipPipeline; static boo::ObjToken s_MultFlipPipeline; +static boo::ObjToken s_MultGEqualFlipPipeline; +static boo::ObjToken s_MultLEqualFlipPipeline; +static boo::ObjToken s_InvDstMultFlipPipeline; +static boo::ObjToken s_InvDstMultGEqualFlipPipeline; +static boo::ObjToken s_InvDstMultLEqualFlipPipeline; static boo::ObjToken SelectPipeline(EFilterType type, CTexturedQuadFilter::ZTest zTest, bool flip) @@ -122,20 +142,51 @@ static boo::ObjToken SelectPipeline(EFilterType type, switch (zTest) { case CTexturedQuadFilter::ZTest::GEqual: - return flip ? s_AlphaGEqualFlipPipeline : s_AlphaGEqualPipeline; - case CTexturedQuadFilter::ZTest::LEqual: - return flip ? s_AlphaLEqualFlipPipeline : s_AlphaLEqualPipeline; + switch (type) + { + case EFilterType::Blend: + return flip ? s_AlphaGEqualFlipPipeline : s_AlphaGEqualPipeline; + case EFilterType::Add: + return flip ? s_AddGEqualFlipPipeline : s_AddGEqualPipeline; + case EFilterType::Subtract: + return flip ? s_SubtractGEqualFlipPipeline : s_SubtractGEqualPipeline; + case EFilterType::Multiply: + return flip ? s_MultGEqualFlipPipeline : s_MultGEqualPipeline; + default: + break; + } + case CTexturedQuadFilter::ZTest::LEqual: + switch (type) + { + case EFilterType::Blend: + return flip ? s_AlphaLEqualFlipPipeline : s_AlphaLEqualPipeline; + case EFilterType::Add: + return flip ? s_AddLEqualFlipPipeline : s_AddLEqualPipeline; + case EFilterType::Subtract: + return flip ? s_SubtractLEqualFlipPipeline : s_SubtractLEqualPipeline; + case EFilterType::Multiply: + return flip ? s_MultLEqualFlipPipeline : s_MultLEqualPipeline; + case EFilterType::InvDstMultiply: + return flip ? s_InvDstMultLEqualFlipPipeline : s_InvDstMultLEqualPipeline; + default: + break; + } default: break; } + switch (type) { case EFilterType::Blend: return flip ? s_AlphaFlipPipeline : s_AlphaPipeline; case EFilterType::Add: return flip ? s_AddFlipPipeline : s_AddPipeline; + case EFilterType::Subtract: + return flip ? s_SubtractFlipPipeline : s_SubtractPipeline; case EFilterType::Multiply: return flip ? s_MultFlipPipeline : s_MultPipeline; + case EFilterType::InvDstMultiply: + return flip ? s_InvDstMultFlipPipeline : s_InvDstMultPipeline; default: return {}; } @@ -144,7 +195,9 @@ static boo::ObjToken SelectPipeline(EFilterType type, static boo::ObjToken s_AVtxFmt; static boo::ObjToken s_AAlphaPipeline; static boo::ObjToken s_AAddPipeline; +static boo::ObjToken s_ASubtractPipeline; static boo::ObjToken s_AMultPipeline; +static boo::ObjToken s_AInvDstMultPipeline; static boo::ObjToken SelectAlphaPipeline(EFilterType type) { @@ -154,8 +207,12 @@ static boo::ObjToken SelectAlphaPipeline(EFilterType type) return s_AAlphaPipeline; case EFilterType::Add: return s_AAddPipeline; + case EFilterType::Subtract: + return s_ASubtractPipeline; case EFilterType::Multiply: return s_AMultPipeline; + case EFilterType::InvDstMultiply: + return s_AInvDstMultPipeline; default: return {}; } @@ -219,9 +276,39 @@ CTexturedQuadFilter::Initialize(boo::GLDataFactory::Context& ctx) s_AddPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_AddGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_AddLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_SubtractPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_SubtractGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_SubtractLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); s_MultPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_MultGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_MultLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_InvDstMultPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_InvDstMultGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_InvDstMultLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); s_AlphaFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); @@ -234,9 +321,39 @@ CTexturedQuadFilter::Initialize(boo::GLDataFactory::Context& ctx) s_AddFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_AddGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_AddLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_SubtractFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_SubtractGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_SubtractLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); s_MultFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_MultGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_MultLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_InvDstMultFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_InvDstMultGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_InvDstMultLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); return new CTexturedQuadFilterGLDataBindingFactory; } @@ -247,12 +364,32 @@ void CTexturedQuadFilter::Shutdown() s_AlphaGEqualPipeline.reset(); s_AlphaLEqualPipeline.reset(); s_AddPipeline.reset(); + s_AddGEqualPipeline.reset(); + s_AddLEqualPipeline.reset(); + s_SubtractPipeline.reset(); + s_SubtractGEqualPipeline.reset(); + s_SubtractLEqualPipeline.reset(); s_MultPipeline.reset(); + s_MultGEqualPipeline.reset(); + s_MultLEqualPipeline.reset(); + s_InvDstMultPipeline.reset(); + s_InvDstMultGEqualPipeline.reset(); + s_InvDstMultLEqualPipeline.reset(); s_AlphaFlipPipeline.reset(); s_AlphaGEqualFlipPipeline.reset(); s_AlphaLEqualFlipPipeline.reset(); s_AddFlipPipeline.reset(); + s_AddGEqualFlipPipeline.reset(); + s_AddLEqualFlipPipeline.reset(); + s_SubtractFlipPipeline.reset(); + s_SubtractGEqualFlipPipeline.reset(); + s_SubtractLEqualFlipPipeline.reset(); s_MultFlipPipeline.reset(); + s_MultGEqualFlipPipeline.reset(); + s_MultLEqualFlipPipeline.reset(); + s_InvDstMultFlipPipeline.reset(); + s_InvDstMultGEqualFlipPipeline.reset(); + s_InvDstMultLEqualFlipPipeline.reset(); } #if BOO_HAS_VULKAN @@ -277,9 +414,39 @@ CTexturedQuadFilter::Initialize(boo::VulkanDataFactory::Context& ctx) s_AddPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_AddGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_AddLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_SubtractPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_SubtractGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_SubtractLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); s_MultPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_MultGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_MultLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_InvDstMultPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_InvDstMultGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_InvDstMultLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); s_AlphaFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); @@ -292,9 +459,39 @@ CTexturedQuadFilter::Initialize(boo::VulkanDataFactory::Context& ctx) s_AddFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_AddGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_AddLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::One, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_SubtractFlipPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_SubtractGEqualFlipPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_SubtractLEqualFlipPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); s_MultFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_MultGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_MultLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); + s_InvDstMultFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); + s_InvDstMultGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::GEqual, true, true, false, boo::CullMode::None); + s_InvDstMultLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::LEqual, true, true, false, boo::CullMode::None); return new CTexturedQuadFilterVulkanDataBindingFactory; } @@ -306,12 +503,32 @@ void CTexturedQuadFilter::Shutdown() s_AlphaGEqualPipeline.reset(); s_AlphaLEqualPipeline.reset(); s_AddPipeline.reset(); + s_AddGEqualPipeline.reset(); + s_AddLEqualPipeline.reset(); + s_SubtractPipeline.reset(); + s_SubtractGEqualPipeline.reset(); + s_SubtractLEqualPipeline.reset(); s_MultPipeline.reset(); + s_MultGEqualPipeline.reset(); + s_MultLEqualPipeline.reset(); + s_InvDstMultPipeline.reset(); + s_InvDstMultGEqualPipeline.reset(); + s_InvDstMultLEqualPipeline.reset(); s_AlphaFlipPipeline.reset(); s_AlphaGEqualFlipPipeline.reset(); s_AlphaLEqualFlipPipeline.reset(); s_AddFlipPipeline.reset(); + s_AddGEqualFlipPipeline.reset(); + s_AddLEqualFlipPipeline.reset(); + s_SubtractFlipPipeline.reset(); + s_SubtractGEqualFlipPipeline.reset(); + s_SubtractLEqualFlipPipeline.reset(); s_MultFlipPipeline.reset(); + s_MultGEqualFlipPipeline.reset(); + s_MultLEqualFlipPipeline.reset(); + s_InvDstMultFlipPipeline.reset(); + s_InvDstMultGEqualFlipPipeline.reset(); + s_InvDstMultLEqualFlipPipeline.reset(); } #endif @@ -367,9 +584,15 @@ CTexturedQuadFilterAlpha::Initialize(boo::GLDataFactory::Context& ctx) s_AAddPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_ASubtractPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); s_AMultPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); + s_AInvDstMultPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, 1, texNames, 1, uniNames, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, false, boo::CullMode::None); return new CTexturedQuadFilterAlphaGLDataBindingFactory; } @@ -378,7 +601,9 @@ void CTexturedQuadFilterAlpha::Shutdown() { s_AAlphaPipeline.reset(); s_AAddPipeline.reset(); + s_ASubtractPipeline.reset(); s_AMultPipeline.reset(); + s_AInvDstMultPipeline.reset(); } #if BOO_HAS_VULKAN @@ -397,9 +622,15 @@ CTexturedQuadFilterAlpha::Initialize(boo::VulkanDataFactory::Context& ctx) s_AAddPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, s_AVtxFmt, boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); + s_ASubtractPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, s_AVtxFmt, boo::BlendFactor::SrcAlpha, + boo::BlendFactor::Subtract, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, true, boo::CullMode::None); s_AMultPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, s_AVtxFmt, boo::BlendFactor::Zero, boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); + s_AInvDstMultPipeline = ctx.newShaderPipeline(VSNoFlip, FSAlpha, s_AVtxFmt, boo::BlendFactor::Zero, + boo::BlendFactor::InvSrcColor, boo::Primitive::TriStrips, + boo::ZTest::None, false, true, true, boo::CullMode::None); return new CTexturedQuadFilterAlphaVulkanDataBindingFactory; } @@ -409,7 +640,9 @@ void CTexturedQuadFilterAlpha::Shutdown() s_AVtxFmt.reset(); s_AAlphaPipeline.reset(); s_AAddPipeline.reset(); + s_ASubtractPipeline.reset(); s_AMultPipeline.reset(); + s_AInvDstMultPipeline.reset(); } #endif diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index a23bdfbb5..51f11f919 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -2007,7 +2007,7 @@ CFrontEndUI::CFrontEndUI() m->ResetGameState(); g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id)); - g_GameState->CurrentWorldState().SetAreaId(7); + g_GameState->CurrentWorldState().SetAreaId(4); g_GameState->GameOptions().ResetToDefaults(); g_GameState->WriteBackupBuf(); diff --git a/Runtime/MP1/World/CMetaree.hpp b/Runtime/MP1/World/CMetaree.hpp index 8712f8d48..70e71db76 100644 --- a/Runtime/MP1/World/CMetaree.hpp +++ b/Runtime/MP1/World/CMetaree.hpp @@ -45,7 +45,7 @@ public: bool Delay(CStateManager&, float) { - return x338_ == x568_; + return x330_stateMachineState.GetTime() == x568_; } }; } diff --git a/Runtime/World/CActorParameters.hpp b/Runtime/World/CActorParameters.hpp index 5ff85f50b..1f0e6625b 100644 --- a/Runtime/World/CActorParameters.hpp +++ b/Runtime/World/CActorParameters.hpp @@ -74,6 +74,7 @@ public: const CVisorParameters& GetVisorParameters() const { return x54_visorParms; } const CLightParameters& GetLightParameters() const { return x0_lightParms; } bool HasThermalHeat() const { return x58_25_thermalHeat; } + float GetThermalMag() const { return x64_thermalMag; } }; } diff --git a/Runtime/World/CAi.cpp b/Runtime/World/CAi.cpp index 8c61679f3..4533f8e3b 100644 --- a/Runtime/World/CAi.cpp +++ b/Runtime/World/CAi.cpp @@ -2,6 +2,9 @@ #include "Character/CModelData.hpp" #include "CStateManager.hpp" #include "CStateMachine.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "CScriptWater.hpp" namespace urde { @@ -22,7 +25,67 @@ CAi::CAi(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& i actorParams, stepUp, stepDown) , x258_healthInfo(hInfo) , x260_damageVulnerability(dmgVuln) +, x2c8_stateMachine(g_SimplePool->GetObj({FOURCC('AFSM'), fsm})) { + _CreateShadow(); + + if (x94_simpleShadow) + { + CreateShadow(true); + x94_simpleShadow->SetAlwaysCalculateRadius(false); + } + + if (x90_actorLights) + x260_damageVulnerability.SetX38_25(true); +} + +void CAi::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) +{ + if (msg == EScriptObjectMessage::InitializedInArea) + { + CMaterialList exclude = GetMaterialFilter().GetExcludeList(); + CMaterialList include = GetMaterialFilter().GetIncludeList(); + include.Add(EMaterialTypes::AIBlock); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(include, exclude)); + } + + CActor::AcceptScriptMsg(msg, uid, mgr); +} + +EWeaponCollisionResponseTypes CAi::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, + const urde::CWeaponMode&, urde::EProjectileAttrib) const +{ + return EWeaponCollisionResponseTypes::EnemyNormal; +} + +void CAi::FluidFXThink(EFluidState state, CScriptWater& water, urde::CStateManager& mgr) +{ + if (state == EFluidState::EnteredFluid || state == EFluidState::LeftFluid) + { + float dt = mgr.GetFluidPlaneManager()->GetLastSplashDeltaTime(GetUniqueId()); + if (dt >= 0.02f) + { + float vel = (0.5f * GetMass()) * GetVelocity().magSquared(); + + if (vel > 500.f) + { + zeus::CVector3f pos = x34_transform.origin; + pos.z = water.GetTriggerBoundsWR().max.z; + mgr.GetFluidPlaneManager()->CreateSplash(GetUniqueId(), mgr, water, pos, + 0.1f + ((0.4f * zeus::min(vel, 30000.f) - 500.f) / 29500.f), + true); + } + } + } + + if (mgr.GetFluidPlaneManager()->GetLastRippleDeltaTime(GetUniqueId()) < (GetHealthInfo(mgr)->GetHP() > 0.f ? 0.2f : 0.7f)) + return; + + zeus::CVector3f pos = x34_transform.origin; + zeus::CVector3f center = pos; + center.z = water.GetTriggerBoundsWR().max.z; + pos.normalize(); + water.GetFluidPlane().AddRipple(GetMass(), GetUniqueId(), center, GetVelocity(), water, mgr, pos); } CAiStateFunc CAi::GetStateFunc(const char* func) { return m_FuncMap->GetStateFunc(func); } diff --git a/Runtime/World/CAi.hpp b/Runtime/World/CAi.hpp index cf5167590..1b3e127fc 100644 --- a/Runtime/World/CAi.hpp +++ b/Runtime/World/CAi.hpp @@ -30,6 +30,7 @@ enum class EKnockBackType class CAiFuncMap; class CStateManager; +class CScriptWater; class CAi : public CPhysicsActor { static CAiFuncMap* m_FuncMap; @@ -48,16 +49,21 @@ public: const CStateMachine* GetStateMachine() const; - virtual void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {} + virtual void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); virtual CHealthInfo* HealthInfo(CStateManager&) { return &x258_healthInfo; } virtual void Death(CStateManager&, const zeus::CVector3f&, EStateMsg)=0; virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float)=0; virtual const CDamageVulnerability* GetDamageVulnerability() const { return &x260_damageVulnerability; } + virtual const CDamageVulnerability* GetDamageVulnerability() { return &x260_damageVulnerability; } virtual void TakeDamage(const zeus::CVector3f&, float) {} virtual bool CanBeShot(const CStateManager&, int) { return true; } virtual bool IsListening() const { return false; } virtual int Listen(const zeus::CVector3f&, EListenNoiseType) { return 0; } + virtual EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, + const CWeaponMode&, EProjectileAttrib) const; + void FluidFXThink(EFluidState, CScriptWater&, CStateManager&); + virtual zeus::CVector3f GetOrigin() const { return x34_transform.origin; } virtual void Patrol(CStateManager&, EStateMsg, float) {} virtual void FollowPattern(CStateManager&, EStateMsg, float) {} virtual void Dead(CStateManager&, EStateMsg, float) {} diff --git a/Runtime/World/CDamageVulnerability.hpp b/Runtime/World/CDamageVulnerability.hpp index cf67f0f99..d9f6b2aa5 100644 --- a/Runtime/World/CDamageVulnerability.hpp +++ b/Runtime/World/CDamageVulnerability.hpp @@ -35,7 +35,9 @@ class CDamageVulnerability EVulnerability x2c_enemyWp3Lava; EVulnerability x30_enemyWp4; EVulnerability x34_unk1; + /* FIXME: What's going on here? */ EVulnerability x38_unk2; + bool x38_25 : 1; EVulnerability x3c_chargedPower; EVulnerability x40_chargedIce; @@ -79,6 +81,7 @@ public: static const CDamageVulnerability& ImmuneVulnerabilty() { return sImmuneVulnerability; } static const CDamageVulnerability& ReflectVulnerabilty() { return sReflectVulnerability; } static const CDamageVulnerability& PasshThroughVulnerabilty() { return sPassThroughVulnerability; } + void SetX38_25(bool) { x38_25 = true; } }; } diff --git a/Runtime/World/CPatterned.cpp b/Runtime/World/CPatterned.cpp index 939c0fb46..50f44c71b 100644 --- a/Runtime/World/CPatterned.cpp +++ b/Runtime/World/CPatterned.cpp @@ -1,11 +1,19 @@ +#include #include "CPatterned.hpp" #include "CPatternedInfo.hpp" #include "TCastTo.hpp" #include "CActorParameters.hpp" +#include "Character/CPASAnimParmData.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "CPlayer.hpp" +#include "Weapon/CGameProjectile.hpp" +#include "Character/CAnimData.hpp" namespace urde { +const zeus::CColor CPatterned::skDamageColor(0.5f, 0.f, 0.f); CMaterialList gkPatternedGroundMaterialList(EMaterialTypes::Character, EMaterialTypes::Solid, EMaterialTypes::Orbit, EMaterialTypes::GroundCollider, EMaterialTypes::Target); @@ -14,8 +22,9 @@ CMaterialList gkPatternedFlyerMaterialList(EMaterialTypes::Character, EMaterialT CPatterned::CPatterned(ECharacter character, TUniqueId uid, std::string_view name, CPatterned::EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, - const CPatternedInfo& pInfo, CPatterned::EMovementType moveType, CPatterned::EColliderType, - EBodyType, const CActorParameters& actorParms, int variant) + const CPatternedInfo& pInfo, CPatterned::EMovementType moveType, + CPatterned::EColliderType colliderType, EBodyType bodyType, const CActorParameters& actorParms, + int variant) : CAi(uid, pInfo.xf8_active, name, info, xf, std::move(mData), zeus::CAABox(pInfo.xcc_bodyOrigin - zeus::CVector3f{pInfo.xc4_halfExtent, pInfo.xc4_halfExtent, 0.f}, pInfo.xcc_bodyOrigin + @@ -23,7 +32,21 @@ CPatterned::CPatterned(ECharacter character, TUniqueId uid, std::string_view nam pInfo.x0_mass, pInfo.x54_healthInfo, pInfo.x5c_damageVulnerability, moveType == EMovementType::Flyer ? gkPatternedFlyerMaterialList : gkPatternedGroundMaterialList, pInfo.xfc_stateMachineId, actorParms, pInfo.xd8_stepUpHeight, 0.8f), - x34c_character(character) +x2fc_minAttackRange(pInfo.x18_minAttackRange), +x300_maxAttackRange(pInfo.x1c_maxAttackRange), +x304_averageAttackTime(pInfo.x20_averageAttackTime), +x308_attackTimeVariation(pInfo.x24_attackTimeVariation), +x34c_character(character), +x388_anim(pInfo.GetAnimationParameters().GetInitialAnimation()), +x3b4_speed(pInfo.x4_speed), +x3b8_turnSpeed(pInfo.x8_turnSpeed), +x3bc_detectionRange(pInfo.xc_detectionRange), +x3c0_detectionHeightRange(pInfo.x10_detectionHeightRange), +x3c4_detectionAngle(std::cos(zeus::degToRad(pInfo.x14_dectectionAngle))), +x3c8_leashRadius(pInfo.x28_leashRadius), +x3cc_playerLeashRadius(pInfo.x2c_playerLeashRadius), +x3d0_playerLeashTime(pInfo.x30_playerLeashTime), +x3fc_flavor(flavor) { x400_25_ = true; x400_31_ = moveType == CPatterned::EMovementType::Flyer; @@ -31,6 +54,122 @@ CPatterned::CPatterned(ECharacter character, TUniqueId uid, std::string_view nam x402_30_ = x402_31_ = actorParms.HasThermalHeat(); x403_25_ = true; x403_26_ = true; + x404_ = pInfo.x34_damageInfo; + x424_damageWaitTime = pInfo.x50_damageWaitTime; + x454_deathSfx = pInfo.xe8_deathSfx; + x458_iceShatterSfx = pInfo.x134_iceShatterSfx; + x4f4_ = pInfo.x100_; + x4f8_ = pInfo.x104_; + x4fc_ = pInfo.x108_; + x508_colliderType = colliderType; + x50c_thermalMag = actorParms.GetThermalMag(); + x510_.reset(new CVertexMorphEffect); + x514_ = pInfo.x110_particle1Scale; + x540_ = pInfo.x124_particle2Scale; + + if (pInfo.x11c_particle1.IsValid()) + x520_ = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x11c_particle1})}; + + if (pInfo.x120_electric.IsValid()) + x530_ = { g_SimplePool->GetObj({FOURCC('ELSC'), pInfo.x120_electric})}; + + if (pInfo.x130_particle2.IsValid()) + x54c_ = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x130_particle2})}; + + if (x404_.GetRadius() > 0.f) + x404_.SetRadius(0.f); + + xe6_29_renderParticleDBInside = false; + x402_27_ = x64_modelData->HasModel(CModelData::EWhichModel::XRay); + BuildBodyController(bodyType); +} + +void CPatterned::Think(float dt, urde::CStateManager& mgr) +{ + if (!GetActive()) + return; + +#if 0 + if (x402_30_) + sub80077854(x450_bodyController->GetPercentageFrozen() == 0.f); +#endif + + if (x64_modelData->GetAnimationData()->GetIceModel()) + x510_->Update(dt); + + if (x402_26_) + { + float froz = x450_bodyController->GetPercentageFrozen(); + if (froz > 0.8f) + x400_29_ = true; + } +} + +void CPatterned::Touch(CActor& act, CStateManager& mgr) +{ + if (!x400_25_) + return; + + if (TCastToPtr proj = act) + { + if (mgr.GetPlayer().GetUniqueId() == proj->GetOwnerId()) + x400_24_ = true; + } +} + +zeus::CVector3f CPatterned::GetAimPosition(const urde::CStateManager& mgr, float dt) const +{ + zeus::CVector3f offset; + if (dt > 0.f) + offset = PredictMotion(dt).x0_translation; + + CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); + if (segId != 0xFF) + { + zeus::CTransform xf = GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); + zeus::CVector3f scaledOrigin = GetModelData()->GetScale() * xf.origin; + if (GetTouchBounds()) + return offset + GetTouchBounds()->clampToBox(x34_transform * scaledOrigin); + + zeus::CAABox aabox = GetBaseBoundingBox(); + + zeus::CAABox primBox(aabox.min + GetPrimitiveOffset(), aabox.max + GetPrimitiveOffset()); + + return offset + (x34_transform * primBox.clampToBox(scaledOrigin)); + } + + return offset + GetBoundingBox().center(); +} + +void CPatterned::BuildBodyController(EBodyType bodyType) +{ + if (x450_bodyController) + return; + + x450_bodyController.reset(new CBodyController(*this, x3b8_turnSpeed, bodyType)); + auto anim = x450_bodyController->GetPASDatabase().FindBestAnimation(CPASAnimParmData(24, + CPASAnimParm::FromEnum(0)), -1); + /* TODO: Double check this */ + x460_.x81_26_ = anim.first != 0.f; +} + +zeus::CVector3f CPatterned::GetGunEyePos() const +{ + zeus::CVector3f origin = GetOrigin(); + zeus::CAABox baseBox = GetBaseBoundingBox(); + origin.z = 0.6f * (baseBox.max.z - baseBox.min.z) + origin.z; + + return origin; +} + +void CPatterned::SetupPlayerCollision(bool v) +{ + CMaterialList include = GetMaterialFilter().GetIncludeList(); + CMaterialList exclude = GetMaterialFilter().GetExcludeList(); + CMaterialList* modList = (v ? &exclude : &include); + modList->Add(EMaterialTypes::Player); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(include, exclude)); + } } diff --git a/Runtime/World/CPatterned.hpp b/Runtime/World/CPatterned.hpp index e6d6f3647..b9a66b441 100644 --- a/Runtime/World/CPatterned.hpp +++ b/Runtime/World/CPatterned.hpp @@ -3,15 +3,45 @@ #include "CAi.hpp" #include "Character/CBodyController.hpp" +#include "Character/CSteeringBehaviors.hpp" +#include "Graphics/CVertexMorphEffect.hpp" +#include "Particle/CGenDescription.hpp" +#include "Particle/CElectricDescription.hpp" #include "TCastTo.hpp" +#include "CDamageInfo.hpp" namespace urde { class CPatternedInfo; +class CPatternedUnknown2 +{ + friend class CPatterned; + u8 x80_ = 0; + union + { + struct + { + bool x81_24_ : 1; + bool x81_25_ : 1; + bool x81_26_ : 1; + bool x81_27_ : 1; + bool x81_28_ : 1; + bool x81_29_ : 1; + bool x81_30_ : 1; + bool x81_31_ : 1; + bool x82_24_ : 1; + bool x82_25_ : 1; + bool x82_26_ : 1; + }; + u32 dummy = 0; + }; +}; + class CPatterned : public CAi { public: + static const zeus::CColor skDamageColor; enum class ECharacter { AtomicAlpha = 0, @@ -71,6 +101,17 @@ public: }; protected: + u32 x2d8_ = -1; + TUniqueId x2dc_ = kInvalidUniqueId; + zeus::CVector3f x2e0_; + zeus::CVector3f x2ec_; + float x2f8_ = 0.f; + float x2fc_minAttackRange; + float x300_maxAttackRange; + float x304_averageAttackTime; + float x308_attackTimeVariation; + u32 x30c_ = 0; + zeus::CVector3f x310_; union { struct @@ -82,9 +123,46 @@ protected: }; u32 _dummy = 0; }; - ECharacter x34c_character; - float x338_; + u32 x32c_; + CStateMachineState x330_stateMachineState; + ECharacter x34c_character; + zeus::CVector3f x350_; + zeus::CVector3f x35c_; + zeus::CVector3f x368_; + u32 x374_ = 0; + u32 x378_ = 2; + u32 x37c_ = 1; + u32 x380_ = 0; + u32 x384_ = 0; + s32 x388_anim; + /*x38c_*/ + u32 x390_ = 0; + u32 x394_ = 0; + u32 x398_ = 0; + u32 x39c_ = 0; + zeus::CVector3f x3a0_; + TUniqueId x3ac_ = kInvalidUniqueId; + float x3b0_ = 1.f; + float x3b4_speed; + float x3b8_turnSpeed; + float x3bc_detectionRange; + float x3c0_detectionHeightRange; + float x3c4_detectionAngle; + float x3c8_leashRadius; + float x3cc_playerLeashRadius; + float x3d0_playerLeashTime; + float x3d4_ = 0.f; + float x3d8_; + float x3dc_; + float x3e0_; + float x3e4_ = 0.f; + float x3e8_ = 0.f; + float x3ec_ = 0.f; + float x3f0_ = 0.f; + float x3f4_ = 0.f; + u32 x3f8_ = 0; + EFlavorType x3fc_flavor; union { @@ -121,21 +199,36 @@ protected: u32 _dummy2 = 0; }; + CDamageInfo x404_; + float x420_ = 0.f; + float x424_damageWaitTime; + float x428_ = -1.f; + zeus::CColor x42c_ = zeus::CColor::skBlack; + zeus::CColor x430_ = skDamageColor; + CSteeringBehaviors x45c_; std::unique_ptr x450_bodyController; + u32 x454_deathSfx; + u32 x458_iceShatterSfx; - union - { - struct - { - bool x4e1_24_ : 1; - bool x4e1_25_ : 1; - bool x4e1_26_ : 1; - }; - u32 _dummy3 = 0; - }; - + CPatternedUnknown2 x460_; + zeus::CVector3f x4e4_; + float x4f0_ = 0.f; + float x4f4_; + float x4f8_; + float x4fc_; float x500_ = 0.f; float x504_damageDur = 0.f; + EColliderType x508_colliderType; + float x50c_thermalMag; + std::unique_ptr x510_; + zeus::CVector3f x514_; + std::experimental::optional> x520_; + std::experimental::optional> x530_; + zeus::CVector3f x540_; + std::experimental::optional> x54c_; + /* x55c_ */ + /* x560_ */ + /* x564_ */ public: CPatterned(ECharacter character, TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pinfo, @@ -143,8 +236,16 @@ public: const CActorParameters& params, int variant); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {} + void Think(float, CStateManager&); + void Touch(CActor&, CStateManager&); virtual void Death(CStateManager&, const zeus::CVector3f&, EStateMsg) {} virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float) {} + zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const + { + return GetAimPosition(mgr, 0.f); + } + + zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const; template static T* CastTo(CEntity* ent) @@ -184,9 +285,12 @@ public: virtual bool IsOnGround() const { return x328_27_onGround; } virtual float GetGravityConstant() const { return 24.525002f; } float GetDamageDuration() const { return x504_damageDur; } + zeus::CVector3f GetGunEyePos() const; + void BuildBodyController(EBodyType); const CBodyController* GetBodyController() const { return x450_bodyController.get(); } CBodyController* BodyController() { return x450_bodyController.get(); } + void SetupPlayerCollision(bool); }; } diff --git a/Runtime/World/CPatternedInfo.cpp b/Runtime/World/CPatternedInfo.cpp index d5a80acab..955ba3e6e 100644 --- a/Runtime/World/CPatternedInfo.cpp +++ b/Runtime/World/CPatternedInfo.cpp @@ -38,13 +38,13 @@ CPatternedInfo::CPatternedInfo(CInputStream& in, u32 pcount) , x108_(in.readFloatBig()) , x10c_particle1Frames(in.readUint32Big()) , x110_particle1Scale(zeus::CVector3f::ReadBig(in)) -, x11c_particle1(in.readUint32Big()) -, x120_particle2Frames(in.readUint32Big()) +, x11c_particle1(in) +, x120_electric(in) { if (pcount >= 36) x124_particle2Scale.readBig(in); if (pcount >= 37) - x130_particle2 = in.readUint32Big(); + x130_particle2 = CAssetId(in); if (pcount >= 38) x134_iceShatterSfx = CSfxManager::TranslateSFXID(in.readUint32Big()); } diff --git a/Runtime/World/CPatternedInfo.hpp b/Runtime/World/CPatternedInfo.hpp index 4ed3941c3..c580e64d8 100644 --- a/Runtime/World/CPatternedInfo.hpp +++ b/Runtime/World/CPatternedInfo.hpp @@ -50,7 +50,7 @@ class CPatternedInfo zeus::CVector3f x110_particle1Scale; CAssetId x11c_particle1; - u32 x120_particle2Frames; + CAssetId x120_electric; zeus::CVector3f x124_particle2Scale; CAssetId x130_particle2; diff --git a/Runtime/World/CStateMachine.cpp b/Runtime/World/CStateMachine.cpp index c6d197006..2bdaf78a0 100644 --- a/Runtime/World/CStateMachine.cpp +++ b/Runtime/World/CStateMachine.cpp @@ -55,7 +55,7 @@ s32 CStateMachine::GetStateIndex(std::string_view state) const const std::vector& CStateMachine::GetStateVector() const { return x0_states; } -float CStateMachineState::GetTime() const { return 0.f; } +float CStateMachineState::GetTime() const { return x8_time; } void CStateMachineState::SetState(CStateManager &, CAi &, s32 idx) {