diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp index b7e19c18f..691de0f60 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp @@ -212,7 +212,7 @@ struct HealthInfo : BigDNA { AT_DECL_DNA_YAML Value propertyCount; Value health SPECTER_PROPERTY("Health", "Base health for object"); - Value knockbackResistence SPECTER_PROPERTY("Knockback Resistence", ""); + Value knockbackResistance SPECTER_PROPERTY("Knockback Resistance", ""); } SPECTER_PROPERTY("Health Info", ""); struct LightParameters : BigDNA { diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index ec227e8d4..0515bd1a8 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -56,6 +56,7 @@ #include "hecl/CVarManager.hpp" #include "World/CPatterned.hpp" #include "World/CDestroyableRock.hpp" +#include "World/CPathFindSearch.hpp" #include namespace urde { @@ -515,7 +516,15 @@ void CStateManager::BuildDynamicLightListForWorld() { } } -void CStateManager::DrawDebugStuff() const {} +void CStateManager::DrawDebugStuff() const { + for (CEntity* ent : GetActorObjectList()) { + if (TCastToPtr ai = ent) { + if (CPathFindSearch* path = ai->GetSearchPath()) { + path->DebugDraw(); + } + } + } +} void CStateManager::RenderCamerasAndAreaLights() const { x870_cameraManager->RenderCameras(*this); @@ -1558,8 +1567,8 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& pos, const zeus::CVe } float newHp = hInfo->GetHP() - mulDam; - hInfo->SetHP(newHp); bool significant = std::fabs(newHp - hInfo->GetHP()) >= 0.00001; + hInfo->SetHP(newHp); if (player && GetPlayerState()->CanTakeDamage()) { player->TakeDamage(significant, pos, mulDam, weapMode.GetType(), *this); diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index 4faa6625b..e7a59a74c 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -108,7 +108,7 @@ CAssetId CAnimData::GetEventResourceIdForAnimResourceId(CAssetId id) const { } void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet) { - for (std::pair& additive : x434_additiveAnims) + for (auto& additive : x434_additiveAnims) if (additive.second.GetTargetWeight() > 0.00001f) additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet); } @@ -126,7 +126,7 @@ SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt) { SAdvancementDeltas deltas = {}; - for (std::pair& additive : x434_additiveAnims) { + for (auto& additive : x434_additiveAnims) { std::shared_ptr& anim = additive.second.GetAnim(); if (additive.second.IsActive()) { while (time.GreaterThanZero() && std::fabs(time.GetSeconds()) >= 0.00001f) { @@ -181,72 +181,73 @@ SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt) { return AdvanceAdditiveAnims(dt); } -bool CAnimData::IsAdditiveAnimation(u32 idx) const { - u32 animIdx = xc_charInfo.GetAnimationIndex(idx); +bool CAnimData::IsAdditiveAnimation(s32 idx) const { + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); return x0_charFactory->HasAdditiveInfo(animIdx); } -bool CAnimData::IsAdditiveAnimationAdded(u32 idx) const { +bool CAnimData::IsAdditiveAnimationAdded(s32 idx) const { + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), - [&](const std::pair& pair) -> bool { return pair.first == idx; }); - if (search == x434_additiveAnims.cend()) - return false; - return true; + [animIdx](const auto& pair) { return pair.first == animIdx; }); + return search != x434_additiveAnims.cend(); } -const std::shared_ptr& CAnimData::GetAdditiveAnimationTree(u32 idx) const { +const std::shared_ptr& CAnimData::GetAdditiveAnimationTree(s32 idx) const { + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), - [&](const std::pair& pair) -> bool { return pair.first == idx; }); + [animIdx](const auto& pair) { return pair.first == animIdx; }); return search->second.GetAnim(); } -bool CAnimData::IsAdditiveAnimationActive(u32 idx) const { +bool CAnimData::IsAdditiveAnimationActive(s32 idx) const { + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), - [&](const std::pair& pair) -> bool { return pair.first == idx; }); + [animIdx](const auto& pair) { return pair.first == animIdx; }); if (search == x434_additiveAnims.cend()) return false; return search->second.IsActive(); } void CAnimData::DelAdditiveAnimation(s32 idx) { - u32 animIdx = xc_charInfo.GetAnimationIndex(idx); - for (std::pair& anim : x434_additiveAnims) { - if (anim.first == animIdx && anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut && - anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut) { - anim.second.FadeOut(); - return; - } + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); + auto search = + std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(), + [animIdx](const auto& pair) { return pair.first == animIdx; }); + if (search != x434_additiveAnims.cend() && + search->second.GetPhase() != EAdditivePlaybackPhase::FadingOut && + search->second.GetPhase() != EAdditivePlaybackPhase::FadedOut) { + search->second.FadeOut(); } } void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut) { - u32 animIdx = xc_charInfo.GetAnimationIndex(idx); - for (std::pair& anim : x434_additiveAnims) { - if (anim.first == animIdx && anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut && - anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut) { - anim.second.SetActive(active); - anim.second.SetWeight(weight); - anim.second.SetNeedsFadeOut(!anim.second.IsActive() && fadeOut); - return; - } - } - - std::shared_ptr node = + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); + auto search = + std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(), + [animIdx](const auto& pair) { return pair.first == animIdx; }); + if (search != x434_additiveAnims.cend()) { + search->second.SetActive(active); + search->second.SetWeight(weight); + search->second.SetNeedsFadeOut(!search->second.IsActive() && fadeOut); + } else { + std::shared_ptr node = GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders()); - - const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx); - x434_additiveAnims.emplace_back(std::make_pair(idx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut))); + const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx); + x434_additiveAnims.emplace_back(std::make_pair(animIdx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut))); + } } -float CAnimData::GetAdditiveAnimationWeight(u32 idx) const { - u32 animIdx = xc_charInfo.GetAnimationIndex(idx); - for (const std::pair& anim : x434_additiveAnims) { - if (anim.first == animIdx) - return anim.second.GetTargetWeight(); - } +float CAnimData::GetAdditiveAnimationWeight(s32 idx) const { + s32 animIdx = xc_charInfo.GetAnimationIndex(idx); + auto search = + std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), + [animIdx](const auto& pair) { return pair.first == animIdx; }); + if (search != x434_additiveAnims.cend()) + return search->second.GetTargetWeight(); return 0.f; } @@ -618,13 +619,13 @@ void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool noTrans) { x200_speedScale = 1.f; x208_defaultAnim = parms.GetAnimationId(); - u32 animIdxA = xc_charInfo.GetAnimationIndex(parms.GetAnimationId()); + s32 animIdxA = xc_charInfo.GetAnimationIndex(parms.GetAnimationId()); ResetPOILists(); std::shared_ptr blendNode; if (parms.GetSecondAnimationId() != -1) { - u32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId()); + s32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId()); std::shared_ptr treeA = x100_animMgr->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders()); diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index 37eed161a..274d1e1f9 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -108,7 +108,7 @@ private: float x200_speedScale = 1.f; s32 x204_charIdx; - u16 x208_defaultAnim; + s32 x208_defaultAnim; u32 x20c_passedBoolCount = 0; u32 x210_passedIntCount = 0; u32 x214_passedParticleCount = 0; @@ -133,7 +133,7 @@ private: CHierarchyPoseBuilder x2fc_poseBuilder; CAnimPlaybackParms x40c_playbackParms; - rstl::reserved_vector, 8> x434_additiveAnims; + rstl::reserved_vector, 8> x434_additiveAnims; static rstl::reserved_vector g_BoolPOINodes; static rstl::reserved_vector g_Int32POINodes; @@ -158,14 +158,14 @@ public: static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr& anim, const CCharAnimTime& time); SAdvancementDeltas AdvanceAdditiveAnims(float); SAdvancementDeltas UpdateAdditiveAnims(float); - bool IsAdditiveAnimation(u32) const; - bool IsAdditiveAnimationAdded(u32) const; + bool IsAdditiveAnimation(s32) const; + bool IsAdditiveAnimationAdded(s32) const; const std::shared_ptr& GetRootAnimationTree() const { return x1f8_animRoot; } - const std::shared_ptr& GetAdditiveAnimationTree(u32) const; - bool IsAdditiveAnimationActive(u32) const; + const std::shared_ptr& GetAdditiveAnimationTree(s32) const; + bool IsAdditiveAnimationActive(s32) const; void DelAdditiveAnimation(s32); void AddAdditiveAnimation(s32, float, bool, bool); - float GetAdditiveAnimationWeight(u32 idx) const; + float GetAdditiveAnimationWeight(s32 idx) const; std::shared_ptr GetAnimationManager(); const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; } const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); } @@ -229,6 +229,7 @@ public: static void FreeCache(); static void InitializeCache(); CHierarchyPoseBuilder& PoseBuilder() { return x2fc_poseBuilder; } + const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; } const CParticleDatabase& GetParticleDB() const { return x120_particleDB; } CParticleDatabase& GetParticleDB() { return x120_particleDB; } void SetParticleCEXTValue(std::string_view name, int idx, float value); diff --git a/Runtime/Character/CAnimationDatabase.hpp b/Runtime/Character/CAnimationDatabase.hpp index 52d9f477a..8d4cea31b 100644 --- a/Runtime/Character/CAnimationDatabase.hpp +++ b/Runtime/Character/CAnimationDatabase.hpp @@ -11,9 +11,9 @@ class CPrimitive; class CAnimationDatabase { public: - virtual const std::shared_ptr& GetMetaAnim(u32) const = 0; + virtual const std::shared_ptr& GetMetaAnim(s32) const = 0; virtual u32 GetNumMetaAnims() const = 0; - virtual const char* GetMetaAnimName(u32) const = 0; + virtual const char* GetMetaAnimName(s32) const = 0; virtual void GetAllUniquePrimitives(std::vector&) const = 0; virtual void GetUniquePrimitivesFromMetaAnim(std::set&, std::string_view) const = 0; }; diff --git a/Runtime/Character/CAnimationDatabaseGame.cpp b/Runtime/Character/CAnimationDatabaseGame.cpp index 701f1fdef..ed8914413 100644 --- a/Runtime/Character/CAnimationDatabaseGame.cpp +++ b/Runtime/Character/CAnimationDatabaseGame.cpp @@ -11,11 +11,11 @@ CAnimationDatabaseGame::CAnimationDatabaseGame(const std::vector& an x10_anims.emplace_back(anim.GetMetaAnim()); } -const std::shared_ptr& CAnimationDatabaseGame::GetMetaAnim(u32 idx) const { return x10_anims[idx]; } +const std::shared_ptr& CAnimationDatabaseGame::GetMetaAnim(s32 idx) const { return x10_anims[idx]; } u32 CAnimationDatabaseGame::GetNumMetaAnims() const { return x10_anims.size(); } -const char* CAnimationDatabaseGame::GetMetaAnimName(u32 idx) const { +const char* CAnimationDatabaseGame::GetMetaAnimName(s32 idx) const { return "Meta-animation name unavailable in Release mode."; } diff --git a/Runtime/Character/CAnimationDatabaseGame.hpp b/Runtime/Character/CAnimationDatabaseGame.hpp index cc4dbce07..d78ca9dfb 100644 --- a/Runtime/Character/CAnimationDatabaseGame.hpp +++ b/Runtime/Character/CAnimationDatabaseGame.hpp @@ -10,9 +10,9 @@ class CAnimationDatabaseGame final : public CAnimationDatabase { public: CAnimationDatabaseGame(const std::vector& anims); - const std::shared_ptr& GetMetaAnim(u32 idx) const; + const std::shared_ptr& GetMetaAnim(s32 idx) const; u32 GetNumMetaAnims() const; - const char* GetMetaAnimName(u32 idx) const; + const char* GetMetaAnimName(s32 idx) const; void GetAllUniquePrimitives(std::vector& primsOut) const; void GetUniquePrimitivesFromMetaAnim(std::set& primsOut, std::string_view name) const; }; diff --git a/Runtime/Character/CAnimationManager.cpp b/Runtime/Character/CAnimationManager.cpp index a215ccf84..4f5c1ed3b 100644 --- a/Runtime/Character/CAnimationManager.cpp +++ b/Runtime/Character/CAnimationManager.cpp @@ -7,13 +7,13 @@ namespace urde { const CAnimationDatabaseGame* CAnimationManager::GetAnimationDatabase() const { return x0_animDB.GetObj(); } -std::shared_ptr CAnimationManager::GetAnimationTree(u32 animIdx, +std::shared_ptr CAnimationManager::GetAnimationTree(s32 animIdx, const CMetaAnimTreeBuildOrders& orders) const { const std::shared_ptr& anim = x0_animDB->GetMetaAnim(animIdx); return anim->GetAnimationTree(x8_sysCtx, orders); } -const std::shared_ptr& CAnimationManager::GetMetaAnimation(u32 idx) const { +const std::shared_ptr& CAnimationManager::GetMetaAnimation(s32 idx) const { return x0_animDB->GetMetaAnim(idx); } diff --git a/Runtime/Character/CAnimationManager.hpp b/Runtime/Character/CAnimationManager.hpp index 7288af8fb..73217a5a6 100644 --- a/Runtime/Character/CAnimationManager.hpp +++ b/Runtime/Character/CAnimationManager.hpp @@ -20,8 +20,8 @@ public: : x0_animDB(animDB), x8_sysCtx(sysCtx) {} const CAnimationDatabaseGame* GetAnimationDatabase() const; - std::shared_ptr GetAnimationTree(u32, const CMetaAnimTreeBuildOrders& orders) const; - const std::shared_ptr& GetMetaAnimation(u32) const; + std::shared_ptr GetAnimationTree(s32, const CMetaAnimTreeBuildOrders& orders) const; + const std::shared_ptr& GetMetaAnimation(s32) const; }; } // namespace urde diff --git a/Runtime/Character/CBoneTracking.cpp b/Runtime/Character/CBoneTracking.cpp index f5205b89f..9c66fc27a 100644 --- a/Runtime/Character/CBoneTracking.cpp +++ b/Runtime/Character/CBoneTracking.cpp @@ -34,7 +34,7 @@ void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, con if (x14_segId == 0) return; CHierarchyPoseBuilder& pb = animData.PoseBuilder(); - TCastToConstPtr targetAct = mgr.GetObjectById(x34_target); + TCastToConstPtr targetAct = mgr.GetObjectById(x34_target); if (x36_24_active && tracking && (targetAct || x24_targetPosition)) { x36_25_hasTrackedRotation = true; auto layoutInfo = pb.CharLayoutInfo(); diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index e9cfd1dc3..2fb282edd 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -100,7 +100,7 @@ CAssetId CCharacterFactory::GetEventResourceIdForAnimResourceId(CAssetId id) con return search->second; } -const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const { +const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(s32 idx) const { auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx, [](const auto& anim) { return anim.first; }); @@ -109,7 +109,7 @@ const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const return search->second; } -bool CCharacterFactory::HasAdditiveInfo(u32 idx) const { +bool CCharacterFactory::HasAdditiveInfo(s32 idx) const { auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx, [](const auto& anim) { return anim.first; }); return search != x40_additiveInfo.cend(); diff --git a/Runtime/Character/CCharacterFactory.hpp b/Runtime/Character/CCharacterFactory.hpp index b6d8a4a7e..e40888afe 100644 --- a/Runtime/Character/CCharacterFactory.hpp +++ b/Runtime/Character/CCharacterFactory.hpp @@ -65,8 +65,8 @@ public: CAssetId GetEventResourceIdForAnimResourceId(CAssetId animId) const; const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; } - const CAdditiveAnimationInfo& FindAdditiveInfo(u32 idx) const; - bool HasAdditiveInfo(u32 idx) const; + const CAdditiveAnimationInfo& FindAdditiveInfo(s32 idx) const; + bool HasAdditiveInfo(s32 idx) const; }; } // namespace urde diff --git a/Runtime/Character/CGroundMovement.cpp b/Runtime/Character/CGroundMovement.cpp index 083871956..edb6b0131 100644 --- a/Runtime/Character/CGroundMovement.cpp +++ b/Runtime/Character/CGroundMovement.cpp @@ -47,7 +47,7 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto mgr.BuildColliderList(useColliderList, actor, motionVol); CAreaCollisionCache cache(motionVol); float collideDt = dt; - if (actor.GetCollisionPrimitive()->GetPrimType() == FOURCC('OBTG')) { + if (actor.GetCollisionPrimitive()->GetPrimType() != FOURCC('OBTG')) { CGameCollision::BuildAreaCollisionCache(mgr, cache); if (deltaMag > 0.5f * CGameCollision::GetMinExtentForCollisionPrimitive(*actor.GetCollisionPrimitive())) { zeus::CVector3f point = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center(); @@ -59,55 +59,55 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto collideDt = dt * (result.GetT() / deltaMag); newState = actor.PredictMotion_Internal(collideDt); } - actor.MoveCollisionPrimitive(newState.x0_translation); - if (CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(), - actor.GetPrimitiveTransform(), actor.GetMaterialFilter(), - useColliderList, idDetect, collisionList)) { - actor.AddMotionState(newState); - float resolved = 0.f; - if (ResolveUpDown(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, actor.GetStepUpHeight(), 0.f, - resolved, collisionList)) { - actor.SetMotionState(oldState); - MoveGroundColliderXY(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, collideDt); - } + } + } + actor.MoveCollisionPrimitive(newState.x0_translation); + if (CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(), + actor.GetPrimitiveTransform(), actor.GetMaterialFilter(), + useColliderList, idDetect, collisionList)) { + actor.AddMotionState(newState); + float resolved = 0.f; + if (ResolveUpDown(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, actor.GetStepUpHeight(), 0.f, + resolved, collisionList)) { + actor.SetMotionState(oldState); + MoveGroundColliderXY(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, collideDt); + } - } else { - actor.AddMotionState(newState); - } + } else { + actor.AddMotionState(newState); + } - float stepDown = actor.GetStepDownHeight(); - float resolved = 0.f; - collisionList.Clear(); - TUniqueId stepZId = kInvalidUniqueId; - if (stepDown >= 0.f) { - if (MoveGroundColliderZ(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, -stepDown, resolved, - collisionList, stepZId)) { - if (collisionList.GetCount() > 0) { - CCollisionInfoList filteredList; - CollisionUtil::FilterByClosestNormal(zeus::CVector3f{0.f, 0.f, 1.f}, collisionList, filteredList); - if (filteredList.GetCount() > 0) { - if (CGameCollision::IsFloor(filteredList.Front().GetMaterialLeft(), - filteredList.Front().GetNormalLeft())) { - if (TCastToPtr plat = mgr.ObjectById(stepZId)) - mgr.SendScriptMsg(plat.GetPtr(), actor.GetUniqueId(), EScriptObjectMessage::AddPlatformRider); - CGameCollision::SendMaterialMessage(mgr, filteredList.Front().GetMaterialLeft(), actor); - mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor); - } else { - CheckFalling(actor, mgr, dt); - } - } + float stepDown = actor.GetStepDownHeight(); + float resolved = 0.f; + collisionList.Clear(); + TUniqueId stepZId = kInvalidUniqueId; + if (stepDown >= 0.f) { + if (MoveGroundColliderZ(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, -stepDown, resolved, + collisionList, stepZId)) { + if (collisionList.GetCount() > 0) { + CCollisionInfoList filteredList; + CollisionUtil::FilterByClosestNormal(zeus::CVector3f{0.f, 0.f, 1.f}, collisionList, filteredList); + if (filteredList.GetCount() > 0) { + if (CGameCollision::IsFloor(filteredList.Front().GetMaterialLeft(), + filteredList.Front().GetNormalLeft())) { + if (TCastToPtr plat = mgr.ObjectById(stepZId)) + mgr.SendScriptMsg(plat.GetPtr(), actor.GetUniqueId(), EScriptObjectMessage::AddPlatformRider); + CGameCollision::SendMaterialMessage(mgr, filteredList.Front().GetMaterialLeft(), actor); + mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor); + } else { + CheckFalling(actor, mgr, dt); } } - } else { - CheckFalling(actor, mgr, dt); - } - - actor.ClearForcesAndTorques(); - actor.MoveCollisionPrimitive(zeus::CVector3f::skZero); - if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player)) { - CGameCollision::CollisionFailsafe(mgr, cache, actor, *actor.GetCollisionPrimitive(), useColliderList, 0.f, 1); } } + } else { + CheckFalling(actor, mgr, dt); + } + + actor.ClearForcesAndTorques(); + actor.MoveCollisionPrimitive(zeus::CVector3f::skZero); + if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player)) { + CGameCollision::CollisionFailsafe(mgr, cache, actor, *actor.GetCollisionPrimitive(), useColliderList, 0.f, 1); } } diff --git a/Runtime/Character/CHierarchyPoseBuilder.hpp b/Runtime/Character/CHierarchyPoseBuilder.hpp index 7a470b060..753664aa1 100644 --- a/Runtime/Character/CHierarchyPoseBuilder.hpp +++ b/Runtime/Character/CHierarchyPoseBuilder.hpp @@ -19,10 +19,6 @@ class CHierarchyPoseBuilder { CSegId x1_sibling = 0; zeus::CQuaternion x4_rotation; zeus::CVector3f x14_offset; - CTreeNode() = default; - CTreeNode(const zeus::CVector3f& offset) : x14_offset(offset) {} - CTreeNode(const zeus::CQuaternion& quat) : x4_rotation(quat) {} - CTreeNode(const zeus::CQuaternion& quat, const zeus::CVector3f& offset) : x4_rotation(quat), x14_offset(offset) {} }; TSegIdMap x38_treeMap; diff --git a/Runtime/Character/CIkChain.cpp b/Runtime/Character/CIkChain.cpp index cde373bc8..07ff900a1 100644 --- a/Runtime/Character/CIkChain.cpp +++ b/Runtime/Character/CIkChain.cpp @@ -13,30 +13,67 @@ void CIkChain::Update(float dt) { void CIkChain::Deactivate() { x44_24_activated = false; } void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf) { - // const CHierarchyPoseBuilder& posBuilder = animData.GetPoseBuilder(); - x0_ = segId; - - // const TLockedToken& info = posBuilder.CharLayoutInfo(); + x0_bone = segId; + auto info = animData.GetPoseBuilder().CharLayoutInfo(); + x1_p1 = info->GetRootNode()->GetBoneMap()[x0_bone].x0_parentId; + if (x1_p1 != 2) { + x2_p2 = info->GetRootNode()->GetBoneMap()[x1_p1].x0_parentId; + x4_p2p1Dir = info->GetFromParentUnrotated(x1_p1); + x1c_p2p1Length = x4_p2p1Dir.magnitude(); + x4_p2p1Dir = x4_p2p1Dir / x1c_p2p1Length; + x10_p1BoneDir = info->GetFromParentUnrotated(x0_bone); + x20_p1BoneLength = x10_p1BoneDir.magnitude(); + x10_p1BoneDir = x10_p1BoneDir / x20_p1BoneLength; + x34_holdPos = xf.origin; + x24_holdRot = zeus::CQuaternion(xf.basis); + x44_24_activated = true; + } } -void CIkChain::PreRender(CAnimData& animData, const zeus::CTransform& xf, const zeus::CVector3f& scale) {} +void CIkChain::PreRender(CAnimData& animData, const zeus::CTransform& xf, const zeus::CVector3f& scale) { + if (x40_time > 0.f) { + zeus::CTransform p2Xf = animData.GetLocatorTransform(x2_p2, nullptr); + zeus::CVector3f localDelta = xf.transposeRotate(x34_holdPos - xf.origin); + localDelta /= scale; + localDelta = p2Xf.transposeRotate(localDelta - p2Xf.origin); + zeus::CQuaternion p2Rot = animData.PoseBuilder().GetTreeMap()[x2_p2].x4_rotation; + zeus::CQuaternion p1Rot = animData.PoseBuilder().GetTreeMap()[x1_p1].x4_rotation; + zeus::CQuaternion boneRot = animData.PoseBuilder().GetTreeMap()[x0_bone].x4_rotation; + zeus::CQuaternion newP2Rot = p2Rot; + zeus::CQuaternion newP1Rot = p1Rot; + Solve(newP2Rot, newP1Rot, localDelta); + zeus::CQuaternion newBoneRot = + (zeus::CQuaternion((xf * p2Xf).basis) * p2Rot.inverse() * newP2Rot * newP1Rot).inverse() * x24_holdRot; + if (x40_time < 1.f) { + newP2Rot = zeus::CQuaternion::slerpShort(p2Rot, newP2Rot, x40_time); + newP1Rot = zeus::CQuaternion::slerpShort(p1Rot, newP1Rot, x40_time); + newBoneRot = zeus::CQuaternion::slerpShort(boneRot, newBoneRot, x40_time); + } + animData.PoseBuilder().GetTreeMap()[x2_p2].x4_rotation = newP2Rot; + animData.PoseBuilder().GetTreeMap()[x1_p1].x4_rotation = newP1Rot; + animData.PoseBuilder().GetTreeMap()[x0_bone].x4_rotation = newBoneRot; + animData.MarkPoseDirty(); + } +} void CIkChain::Solve(zeus::CQuaternion& q1, zeus::CQuaternion& q2, const zeus::CVector3f& vec) { const float mag = vec.magnitude(); const float magSq = mag * mag; const float twoMag = (2.0f * mag); - float f29 = std::acos(zeus::clamp(-1.f, (((x20_ * magSq) + x20_) - (x1c_ * x1c_)) / (twoMag * x20_), 1.f)); - float f30 = std::acos(zeus::clamp(-1.f, ((x1c_ * (magSq - (x20_ * x20_))) + x1c_) / (twoMag * x1c_), 1.f)); + float f29 = std::acos(zeus::clamp(-1.f, (((x20_p1BoneLength * magSq) + x20_p1BoneLength) - + (x1c_p2p1Length * x1c_p2p1Length)) / (twoMag * x20_p1BoneLength), 1.f)); + float f30 = std::acos(zeus::clamp(-1.f, ((x1c_p2p1Length * (magSq - (x20_p1BoneLength * x20_p1BoneLength))) + + x1c_p2p1Length) / (twoMag * x1c_p2p1Length), 1.f)); - zeus::CVector3f vecA = q2.transform(x10_); - zeus::CVector3f crossVecA = x4_.cross(vecA); + zeus::CVector3f vecA = q2.transform(x10_p1BoneDir); + zeus::CVector3f crossVecA = x4_p2p1Dir.cross(vecA); float crossAMag = crossVecA.magnitude(); crossVecA *= zeus::CVector3f(1.f / crossVecA.magnitude()); float angle = std::asin(zeus::min(crossAMag, 1.f)); - if (x4_.dot(vecA) < 0.f) + if (x4_p2p1Dir.dot(vecA) < 0.f) angle = M_PIF - angle; q2 = zeus::CQuaternion::fromAxisAngle(crossVecA, (f30 + f29) - angle) * q2; - zeus::CVector3f v1 = q1.transform((x1c_ * x4_) + (x20_ * q2.transform(x10_))); + zeus::CVector3f v1 = q1.transform((x1c_p2p1Length * x4_p2p1Dir) + (x20_p1BoneLength * q2.transform(x10_p1BoneDir))); zeus::CVector3f v2 = q1.transform(vec); zeus::CVector3f crossVecB = v1.normalized().cross((1.f / mag) * v2); angle = std::asin(zeus::min(crossVecB.magnitude(), 1.f)); diff --git a/Runtime/Character/CIkChain.hpp b/Runtime/Character/CIkChain.hpp index 28468d09d..deb1efe3c 100644 --- a/Runtime/Character/CIkChain.hpp +++ b/Runtime/Character/CIkChain.hpp @@ -10,15 +10,15 @@ namespace urde { class CAnimData; class CSegId; class CIkChain { - CSegId x0_; - CSegId x1_; - CSegId x2_; - zeus::CVector3f x4_ = zeus::CVector3f::skForward; - zeus::CVector3f x10_ = zeus::CVector3f::skForward; - float x1c_ = 1.f; - float x20_ = 1.f; - zeus::CQuaternion x24_; - zeus::CVector3f x34_; + CSegId x0_bone; + CSegId x1_p1; + CSegId x2_p2; + zeus::CVector3f x4_p2p1Dir = zeus::CVector3f::skForward; + zeus::CVector3f x10_p1BoneDir = zeus::CVector3f::skForward; + float x1c_p2p1Length = 1.f; + float x20_p1BoneLength = 1.f; + zeus::CQuaternion x24_holdRot; + zeus::CVector3f x34_holdPos; float x40_time = 0.f; union { diff --git a/Runtime/Character/CPoseAsTransforms.cpp b/Runtime/Character/CPoseAsTransforms.cpp index c9aaed3f1..35083b2d6 100644 --- a/Runtime/Character/CPoseAsTransforms.cpp +++ b/Runtime/Character/CPoseAsTransforms.cpp @@ -7,9 +7,7 @@ CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) : x1_count(boneCount), xd0_tr bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const { const std::pair& link = x8_links[id]; - if (link.first != 0xff || link.second != 0xff) - return true; - return false; + return link.first != 0xff || link.second != 0xff; } void CPoseAsTransforms::Clear() { @@ -25,21 +23,25 @@ void CPoseAsTransforms::AccumulateScaledTransform(const CSegId& id, zeus::CMatri const zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const { const std::pair& link = x8_links[id]; + assert(link.second != 0xff); return xd0_transformArr[link.second].m_originToAccum; } const zeus::CTransform& CPoseAsTransforms::GetRestToAccumTransform(const CSegId& id) const { const std::pair& link = x8_links[id]; + assert(link.second != 0xff); return xd0_transformArr[link.second].m_restPoseToAccum; } const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const { const std::pair& link = x8_links[id]; + assert(link.second != 0xff); return xd0_transformArr[link.second].m_originToAccum.origin; } const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const { const std::pair& link = x8_links[id]; + assert(link.second != 0xff); return xd0_transformArr[link.second].m_originToAccum.basis; } diff --git a/Runtime/Character/CPoseAsTransforms.hpp b/Runtime/Character/CPoseAsTransforms.hpp index d0e8e1081..5436a1b1c 100644 --- a/Runtime/Character/CPoseAsTransforms.hpp +++ b/Runtime/Character/CPoseAsTransforms.hpp @@ -8,6 +8,7 @@ namespace urde { class CCharLayoutInfo; class CPoseAsTransforms { + friend class CAnimData; public: struct Transform { zeus::CTransform m_originToAccum; diff --git a/Runtime/Collision/CollisionUtil.cpp b/Runtime/Collision/CollisionUtil.cpp index f3bf1a805..4083c7e82 100644 --- a/Runtime/Collision/CollisionUtil.cpp +++ b/Runtime/Collision/CollisionUtil.cpp @@ -308,7 +308,7 @@ void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList } if (idx != -1) - out.Add(in.GetItem(i), false); + out.Add(in.GetItem(idx), false); } static const zeus::CVector3f AABBNormalTable[] = {{-1.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}, diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 56eaefbc9..d3e0ee319 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -20,7 +20,7 @@ class CPoseAsTransforms; class CModel; struct CModelFlags { - u8 x0_blendMode = 0; /* >6: additive, >4: blend, else opaque */ + u8 x0_blendMode = 0; /* 2: add color, >6: additive, >4: blend, else opaque */ u8 x1_matSetIdx = 0; EExtendedShader m_extendedShader = EExtendedShader::Lighting; bool m_noCull = false; diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 77108b852..680c21de3 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -957,6 +957,7 @@ boo::ObjToken CBooModel::UpdateUniformData(const CModelFl lightingOut.colorRegs[1] = CGraphics::g_ColorRegs[1]; lightingOut.colorRegs[2] = CGraphics::g_ColorRegs[2]; lightingOut.mulColor = flags.x4_color; + lightingOut.ambient += flags.addColor; lightingOut.fog = CGraphics::g_Fog; } diff --git a/Runtime/MP1/CSamusHud.cpp b/Runtime/MP1/CSamusHud.cpp index 507ff617c..8c2608ca6 100644 --- a/Runtime/MP1/CSamusHud.cpp +++ b/Runtime/MP1/CSamusHud.cpp @@ -943,8 +943,8 @@ void CSamusHud::UpdateHudDamage(float dt, const CStateManager& mgr, DataSpec::IT x44c_hudLagShakeRot.rotateZ(rand() / float(RAND_MAX) * rotAng); zeus::CVector3f vecs[] = {zeus::CVector3f::skRight, zeus::CVector3f::skForward, zeus::CVector3f::skUp}; for (int i = 0; i < 4; ++i) { - int sel = int(rand() / float(RAND_MAX) * 9.f); - vecs[sel & 0x3][(sel / 3) & 0x3] += (rand() / float(RAND_MAX) - dt) * rotMul; + int sel = rand() % 9; + vecs[sel % 3][sel / 3] += (rand() / float(RAND_MAX) - dt) * rotMul; } x428_decoShakeRotate = zeus::CMatrix3f(vecs[0], vecs[1], vecs[2]).transposed(); transformUpdate = true; diff --git a/Runtime/MP1/World/CSpacePirate.cpp b/Runtime/MP1/World/CSpacePirate.cpp index dbc872ee0..cd1ce8f32 100644 --- a/Runtime/MP1/World/CSpacePirate.cpp +++ b/Runtime/MP1/World/CSpacePirate.cpp @@ -155,7 +155,7 @@ void CPirateRagDoll::PreRender(const zeus::CVector3f& v, CModelData& mData) { aData->PoseBuilder().GetTreeMap()[rootId].x4_rotation = _a4; if (x6c_spacePirate->x7b4_attachedActor == kInvalidUniqueId) { zeus::CVector3f _b0 = aData->GetCharLayoutInfo().GetFromParentUnrotated(x4_particles[1].GetBone()); - aData->PoseBuilder().GetTreeMap()[x4_particles[1].GetBone()] = zeus::CQuaternion::shortestRotationArc( + aData->PoseBuilder().GetTreeMap()[x4_particles[1].GetBone()].x4_rotation = zeus::CQuaternion::shortestRotationArc( _b0, _a4.inverse().transform(x4_particles[1].GetPosition() - x4_particles[0].GetPosition())); } BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 3, 4, @@ -552,7 +552,7 @@ bool CSpacePirate::FireProjectile(float dt, CStateManager& mgr) { void CSpacePirate::UpdateAttacks(float dt, CStateManager& mgr) { bool reset = true; if ((!x400_25_alive || - (x450_bodyController->GetBodyStateInfo().GetCurrentState()->CanShoot() && x637_29_inWallHang && !x634_27_melee && + (x450_bodyController->GetBodyStateInfo().GetCurrentState()->CanShoot() && x637_25_enableAim && !x634_27_melee && !x634_25_ceilingAmbush && !x639_26_started && !x450_bodyController->IsElectrocuting())) && x7c4_burstFire.GetBurstType() != -1) { if (x400_25_alive) { @@ -1008,7 +1008,7 @@ void CSpacePirate::Touch(CActor& other, CStateManager& mgr) { } zeus::CAABox CSpacePirate::GetSortingBounds(const CStateManager& mgr) const { - zeus::CAABox aabb = x64_modelData->GetBounds(); + zeus::CAABox aabb = x64_modelData->GetBounds(x34_transform); zeus::CVector3f radius = aabb.extents() * 0.5f; zeus::CVector3f center = aabb.center(); return zeus::CAABox(center - radius, center + radius); @@ -1280,46 +1280,46 @@ void CSpacePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { x328_24_inPosition = false; x2dc_destObj = cp->GetUniqueId(); x2e0_destPos = cp->GetTranslation(); - if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) { - x2ec_reflectedDestPos = GetTranslation(); - x2e0_destPos = - (GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ? - GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] : - GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()]; - x328_24_inPosition = false; - x450_bodyController->GetCommandMgr().DeliverCmd( - CBCLocomotionCmd(x2e0_destPos - GetTranslation(), zeus::CVector3f::skZero, 1.f)); - } else { - CScriptAiJumpPoint* bestJp = nullptr; - float minDist = FLT_MAX; - for (CEntity* ent : mgr.GetAiWaypointObjectList()) { - if (TCastToPtr jp = ent) { - if (jp->GetActive() && !jp->GetInUse(GetUniqueId()) && jp->GetJumpTarget() == kInvalidUniqueId && - GetAreaIdAlways() == jp->GetAreaIdAlways()) { - zeus::CVector3f toJp = jp->GetTranslation() - GetTranslation(); - float f30 = toJp.magSquared(); - if (f30 > 25.f && jp->GetTransform().basis[1].dot(toJp) > 0.f) { - if (TCastToConstPtr wp = mgr.GetObjectById(jp->GetJumpPoint())) { - if ((wp->GetTranslation().z() - jp->GetTranslation().z()) * - (x2e0_destPos.z() - GetTranslation().z()) > 0.f) { - zeus::CVector3f delta = x2e0_destPos - wp->GetTranslation(); - f30 += 4.f * toJp.z() * toJp.z(); - f30 += delta.magSquared() + delta.z() * delta.z() * 9.f; - if (f30 < minDist && - GetSearchPath()->PathExists(GetTranslation(), jp->GetTranslation()) == - CPathFindSearch::EResult::Success) { - bool r24 = false; - auto res = GetSearchPath()->PathExists(wp->GetTranslation(), x2e0_destPos); - if (res != CPathFindSearch::EResult::Success) - f30 += 1000.f; - if (res == CPathFindSearch::EResult::Success) - r24 = true; - if (f30 < minDist) { - minDist = f30; - bestJp = jp.GetPtr(); - if (r24) - break; - } + } + if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) { + x2ec_reflectedDestPos = GetTranslation(); + x2e0_destPos = + (GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ? + GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] : + GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()]; + x328_24_inPosition = false; + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(x2e0_destPos - GetTranslation(), zeus::CVector3f::skZero, 1.f)); + } else { + CScriptAiJumpPoint* bestJp = nullptr; + float minDist = FLT_MAX; + for (CEntity* ent : mgr.GetAiWaypointObjectList()) { + if (TCastToPtr jp = ent) { + if (jp->GetActive() && !jp->GetInUse(GetUniqueId()) && jp->GetJumpTarget() == kInvalidUniqueId && + GetAreaIdAlways() == jp->GetAreaIdAlways()) { + zeus::CVector3f toJp = jp->GetTranslation() - GetTranslation(); + float f30 = toJp.magSquared(); + if (f30 > 25.f && jp->GetTransform().basis[1].dot(toJp) > 0.f) { + if (TCastToConstPtr wp = mgr.GetObjectById(jp->GetJumpPoint())) { + if ((wp->GetTranslation().z() - jp->GetTranslation().z()) * + (x2e0_destPos.z() - GetTranslation().z()) > 0.f) { + zeus::CVector3f delta = x2e0_destPos - wp->GetTranslation(); + f30 += 4.f * toJp.z() * toJp.z(); + f30 += delta.magSquared() + delta.z() * delta.z() * 9.f; + if (f30 < minDist && + GetSearchPath()->PathExists(GetTranslation(), jp->GetTranslation()) == + CPathFindSearch::EResult::Success) { + bool r24 = false; + auto res = GetSearchPath()->PathExists(wp->GetTranslation(), x2e0_destPos); + if (res != CPathFindSearch::EResult::Success) + f30 += 1000.f; + if (res == CPathFindSearch::EResult::Success) + r24 = true; + if (f30 < minDist) { + minDist = f30; + bestJp = jp.GetPtr(); + if (r24) + break; } } } @@ -1327,32 +1327,32 @@ void CSpacePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { } } } - if (bestJp) { - x2e0_destPos = bestJp->GetTranslation(); - if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) { - x2ec_reflectedDestPos = GetTranslation(); - x2e0_destPos = - (GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ? - GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] : - GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()]; - x328_24_inPosition = false; - x840_jumpPoint = bestJp->GetUniqueId(); - x824_jumpHeight = bestJp->GetJumpApex(); - if (TCastToConstPtr wp = mgr.GetObjectById(bestJp->GetJumpPoint())) { - x828_patrolDestPos = wp->GetTranslation(); - x450_bodyController->GetCommandMgr().DeliverCmd( - CBCLocomotionCmd(x2e0_destPos, zeus::CVector3f::skZero, 1.f)); - x30c_behaviourOrient = EBehaviourOrient::MoveDir; - } + } + if (bestJp) { + x2e0_destPos = bestJp->GetTranslation(); + if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) { + x2ec_reflectedDestPos = GetTranslation(); + x2e0_destPos = + (GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ? + GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] : + GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()]; + x328_24_inPosition = false; + x840_jumpPoint = bestJp->GetUniqueId(); + x824_jumpHeight = bestJp->GetJumpApex(); + if (TCastToConstPtr wp = mgr.GetObjectById(bestJp->GetJumpPoint())) { + x828_patrolDestPos = wp->GetTranslation(); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(x2e0_destPos, zeus::CVector3f::skZero, 1.f)); + x30c_behaviourOrient = EBehaviourOrient::MoveDir; } } } - x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); - if (x637_25_enableAim) - x644_steeringSpeed = 1.f; - x639_27_inRange = false; - x63a_24_normalDodge = true; } + x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); + if (x637_25_enableAim) + x644_steeringSpeed = 1.f; + x639_27_inRange = false; + x63a_24_normalDodge = true; break; case EStateMsg::Update: CPatterned::PathFind(mgr, msg, dt); diff --git a/Runtime/World/CAiFuncMap.cpp b/Runtime/World/CAiFuncMap.cpp index ecc5c99e1..b59c7c8bf 100644 --- a/Runtime/World/CAiFuncMap.cpp +++ b/Runtime/World/CAiFuncMap.cpp @@ -67,6 +67,8 @@ CAiFuncMap::CAiFuncMap() { x10_triggerFuncs["OffLine"] = &CAi::OffLine; x10_triggerFuncs["Attacked"] = &CAi::Attacked; x10_triggerFuncs["PathShagged"] = &CAi::PathShagged; + x10_triggerFuncs["PathOver"] = &CAi::PathOver; + x10_triggerFuncs["PathFound"] = &CAi::PathFound; x10_triggerFuncs["TooClose"] = &CAi::TooClose; x10_triggerFuncs["InRange"] = &CAi::InRange; x10_triggerFuncs["InMaxRange"] = &CAi::InMaxRange; diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index 9119d5b8a..49a908ffc 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -989,6 +989,7 @@ void CGameArea::PostConstructArea() { CAssetId pathId = r.readUint32Big(); x12c_postConstructed->x10ac_pathToken = g_SimplePool->GetObj(SObjectTag{FOURCC('PATH'), pathId}); x12c_postConstructed->x10bc_pathArea = x12c_postConstructed->x10ac_pathToken.GetObj(); + x12c_postConstructed->x10bc_pathArea->SetTransform(xc_transform); ++secIt; } diff --git a/Runtime/World/CPathFindArea.cpp b/Runtime/World/CPathFindArea.cpp index 9817e491f..e480170b5 100644 --- a/Runtime/World/CPathFindArea.cpp +++ b/Runtime/World/CPathFindArea.cpp @@ -73,6 +73,11 @@ bool CPFAreaOctree::IsPointInsidePaddedAABox(const zeus::CVector3f& point, float point.z() >= x4_aabb.min.z() - padding && point.z() <= x4_aabb.max.z() + padding; } +CPFOpenList::CPFOpenList() { + x40_region.SetData(&x90_regionData); + Clear(); +} + void CPFOpenList::Clear() { x40_region.Data()->SetOpenMore(&x40_region); x40_region.Data()->SetOpenLess(&x40_region); diff --git a/Runtime/World/CPathFindArea.hpp b/Runtime/World/CPathFindArea.hpp index 48014df8d..06b4f2454 100644 --- a/Runtime/World/CPathFindArea.hpp +++ b/Runtime/World/CPathFindArea.hpp @@ -48,6 +48,7 @@ class CPFOpenList { CPFRegionData x90_regionData; public: + CPFOpenList(); void Clear(); void Push(CPFRegion* reg); CPFRegion* Pop(); diff --git a/Runtime/World/CPathFindSearch.cpp b/Runtime/World/CPathFindSearch.cpp index 083f61d92..31278ffbd 100644 --- a/Runtime/World/CPathFindSearch.cpp +++ b/Runtime/World/CPathFindSearch.cpp @@ -1,4 +1,5 @@ #include "CPathFindSearch.hpp" +#include "Graphics/CGraphics.hpp" namespace urde { @@ -348,4 +349,17 @@ bool CPathFindSearch::Search(rstl::reserved_vector& regs1, const return reg != nullptr; } +void CPathFindVisualizer::Draw(const CPathFindSearch& path) { + m_spline.Reset(); + for (const auto& wp : path.GetWaypoints()) + m_spline.AddVertex(wp, zeus::CColor::skBlue, 2.f); + m_spline.Render(); +} + +void CPathFindSearch::DebugDraw() const { + if (!m_viz) + m_viz.emplace(); + m_viz->Draw(*this); +} + } // namespace urde diff --git a/Runtime/World/CPathFindSearch.hpp b/Runtime/World/CPathFindSearch.hpp index 0ce0b1037..d55c176c2 100644 --- a/Runtime/World/CPathFindSearch.hpp +++ b/Runtime/World/CPathFindSearch.hpp @@ -2,8 +2,16 @@ #include "RetroTypes.hpp" #include "CPathFindArea.hpp" +#include "Graphics/CLineRenderer.hpp" namespace urde { +class CPathFindSearch; + +class CPathFindVisualizer { + CLineRenderer m_spline = {CLineRenderer::EPrimitiveMode::LineStrip, 16, {}, true}; +public: + void Draw(const CPathFindSearch& path); +}; class CPathFindSearch { public: @@ -19,6 +27,7 @@ private: float xd8_padding = 10.f; u32 xdc_flags; // 0x2: flyer, 0x4: path-always-exists (swimmers) u32 xe0_indexMask; + mutable std::experimental::optional m_viz; bool Search(rstl::reserved_vector& regs1, const zeus::CVector3f& p1, rstl::reserved_vector& regs2, const zeus::CVector3f& p2); void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1, u32 wpIdx) const; @@ -43,6 +52,7 @@ public: float GetCharacterHeight() const { return xd0_chHeight; } void SetCharacterHeight(float h) { xd0_chHeight = h; } float RemainingPathDistance(const zeus::CVector3f& pos) const; + void DebugDraw() const; }; } // namespace urde diff --git a/Runtime/World/CPatterned.cpp b/Runtime/World/CPatterned.cpp index f3c5c959c..a1d3326bd 100644 --- a/Runtime/World/CPatterned.cpp +++ b/Runtime/World/CPatterned.cpp @@ -1501,7 +1501,9 @@ void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { /* Being damaged */ zeus::CColor col2 = col; col2.a() = alpha / 255.f; - xb4_drawFlags = CModelFlags(2, 0, 3, col2); + xb4_drawFlags = CModelFlags(2, 0, 3, zeus::CColor::skWhite); + /* Make color additive */ + xb4_drawFlags.addColor = col2; } else { xb4_drawFlags = CModelFlags(0, 0, 3, zeus::CColor::skWhite); } diff --git a/Runtime/World/CStateMachine.cpp b/Runtime/World/CStateMachine.cpp index 0c9b273a5..6dc4ac785 100644 --- a/Runtime/World/CStateMachine.cpp +++ b/Runtime/World/CStateMachine.cpp @@ -78,6 +78,7 @@ void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta) { if (andPassed && state) { x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f); x4_state = state; + printf("%s %d\n", state->xc_name, int(state - x0_machine->GetStateVector().data())); x8_time = 0.f; x18_24_codeTrigger = false; xc_random = mgr.GetActiveRandom()->Float(); diff --git a/specter b/specter index f81efb25b..e86cce5a6 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit f81efb25b53e90cf9e77c06a09095a433929ddb4 +Subproject commit e86cce5a6f6ad0182d9d2e01fb31bac47f4df882