Space pirate bug fixes

This commit is contained in:
Jack Andersen 2018-12-14 20:29:41 -10:00
parent ccf87925b9
commit dac8fc3eb5
32 changed files with 294 additions and 210 deletions

View File

@ -212,7 +212,7 @@ struct HealthInfo : BigDNA {
AT_DECL_DNA_YAML
Value<atUint32> propertyCount;
Value<float> health SPECTER_PROPERTY("Health", "Base health for object");
Value<float> knockbackResistence SPECTER_PROPERTY("Knockback Resistence", "");
Value<float> knockbackResistance SPECTER_PROPERTY("Knockback Resistance", "");
} SPECTER_PROPERTY("Health Info", "");
struct LightParameters : BigDNA {

View File

@ -56,6 +56,7 @@
#include "hecl/CVarManager.hpp"
#include "World/CPatterned.hpp"
#include "World/CDestroyableRock.hpp"
#include "World/CPathFindSearch.hpp"
#include <cmath>
namespace urde {
@ -515,7 +516,15 @@ void CStateManager::BuildDynamicLightListForWorld() {
}
}
void CStateManager::DrawDebugStuff() const {}
void CStateManager::DrawDebugStuff() const {
for (CEntity* ent : GetActorObjectList()) {
if (TCastToPtr<CPatterned> 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);

View File

@ -108,7 +108,7 @@ CAssetId CAnimData::GetEventResourceIdForAnimResourceId(CAssetId id) const {
}
void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet) {
for (std::pair<u32, CAdditiveAnimPlayback>& 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<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims) {
for (auto& additive : x434_additiveAnims) {
std::shared_ptr<CAnimTreeNode>& 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<u32, CAdditiveAnimPlayback>& 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<CAnimTreeNode>& CAnimData::GetAdditiveAnimationTree(u32 idx) const {
const std::shared_ptr<CAnimTreeNode>& 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<u32, CAdditiveAnimPlayback>& 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<u32, CAdditiveAnimPlayback>& 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<u32, CAdditiveAnimPlayback>& 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<u32, CAdditiveAnimPlayback>& 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<CAnimTreeNode> 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<CAnimTreeNode> 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<u32, CAdditiveAnimPlayback>& 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<CAnimTreeNode> blendNode;
if (parms.GetSecondAnimationId() != -1) {
u32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId());
s32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId());
std::shared_ptr<CAnimTreeNode> treeA =
x100_animMgr->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders());

View File

@ -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<std::pair<u32, CAdditiveAnimPlayback>, 8> x434_additiveAnims;
rstl::reserved_vector<std::pair<s32, CAdditiveAnimPlayback>, 8> x434_additiveAnims;
static rstl::reserved_vector<CBoolPOINode, 8> g_BoolPOINodes;
static rstl::reserved_vector<CInt32POINode, 16> g_Int32POINodes;
@ -158,14 +158,14 @@ public:
static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& 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<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; }
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
bool IsAdditiveAnimationActive(u32) const;
const std::shared_ptr<CAnimTreeNode>& 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<CAnimationManager> 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);

View File

@ -11,9 +11,9 @@ class CPrimitive;
class CAnimationDatabase {
public:
virtual const std::shared_ptr<IMetaAnim>& GetMetaAnim(u32) const = 0;
virtual const std::shared_ptr<IMetaAnim>& 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<CPrimitive>&) const = 0;
virtual void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>&, std::string_view) const = 0;
};

View File

@ -11,11 +11,11 @@ CAnimationDatabaseGame::CAnimationDatabaseGame(const std::vector<CAnimation>& an
x10_anims.emplace_back(anim.GetMetaAnim());
}
const std::shared_ptr<IMetaAnim>& CAnimationDatabaseGame::GetMetaAnim(u32 idx) const { return x10_anims[idx]; }
const std::shared_ptr<IMetaAnim>& 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.";
}

View File

@ -10,9 +10,9 @@ class CAnimationDatabaseGame final : public CAnimationDatabase {
public:
CAnimationDatabaseGame(const std::vector<CAnimation>& anims);
const std::shared_ptr<IMetaAnim>& GetMetaAnim(u32 idx) const;
const std::shared_ptr<IMetaAnim>& GetMetaAnim(s32 idx) const;
u32 GetNumMetaAnims() const;
const char* GetMetaAnimName(u32 idx) const;
const char* GetMetaAnimName(s32 idx) const;
void GetAllUniquePrimitives(std::vector<CPrimitive>& primsOut) const;
void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>& primsOut, std::string_view name) const;
};

View File

@ -7,13 +7,13 @@ namespace urde {
const CAnimationDatabaseGame* CAnimationManager::GetAnimationDatabase() const { return x0_animDB.GetObj(); }
std::shared_ptr<CAnimTreeNode> CAnimationManager::GetAnimationTree(u32 animIdx,
std::shared_ptr<CAnimTreeNode> CAnimationManager::GetAnimationTree(s32 animIdx,
const CMetaAnimTreeBuildOrders& orders) const {
const std::shared_ptr<IMetaAnim>& anim = x0_animDB->GetMetaAnim(animIdx);
return anim->GetAnimationTree(x8_sysCtx, orders);
}
const std::shared_ptr<IMetaAnim>& CAnimationManager::GetMetaAnimation(u32 idx) const {
const std::shared_ptr<IMetaAnim>& CAnimationManager::GetMetaAnimation(s32 idx) const {
return x0_animDB->GetMetaAnim(idx);
}

View File

@ -20,8 +20,8 @@ public:
: x0_animDB(animDB), x8_sysCtx(sysCtx) {}
const CAnimationDatabaseGame* GetAnimationDatabase() const;
std::shared_ptr<CAnimTreeNode> GetAnimationTree(u32, const CMetaAnimTreeBuildOrders& orders) const;
const std::shared_ptr<IMetaAnim>& GetMetaAnimation(u32) const;
std::shared_ptr<CAnimTreeNode> GetAnimationTree(s32, const CMetaAnimTreeBuildOrders& orders) const;
const std::shared_ptr<IMetaAnim>& GetMetaAnimation(s32) const;
};
} // namespace urde

View File

@ -34,7 +34,7 @@ void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, con
if (x14_segId == 0)
return;
CHierarchyPoseBuilder& pb = animData.PoseBuilder();
TCastToConstPtr<CPatterned> targetAct = mgr.GetObjectById(x34_target);
TCastToConstPtr<CActor> targetAct = mgr.GetObjectById(x34_target);
if (x36_24_active && tracking && (targetAct || x24_targetPosition)) {
x36_25_hasTrackedRotation = true;
auto layoutInfo = pb.CharLayoutInfo();

View File

@ -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();

View File

@ -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

View File

@ -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<CScriptPlatform> 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<CScriptPlatform> 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);
}
}

View File

@ -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<CTreeNode> x38_treeMap;

View File

@ -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<CCharLayoutInfo>& 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));

View File

@ -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 {

View File

@ -7,9 +7,7 @@ CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) : x1_count(boneCount), xd0_tr
bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const {
const std::pair<CSegId, CSegId>& 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<CSegId, CSegId>& 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<CSegId, CSegId>& 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<CSegId, CSegId>& 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<CSegId, CSegId>& link = x8_links[id];
assert(link.second != 0xff);
return xd0_transformArr[link.second].m_originToAccum.basis;
}

View File

@ -8,6 +8,7 @@ namespace urde {
class CCharLayoutInfo;
class CPoseAsTransforms {
friend class CAnimData;
public:
struct Transform {
zeus::CTransform m_originToAccum;

View File

@ -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},

View File

@ -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;

View File

@ -957,6 +957,7 @@ boo::ObjToken<boo::IGraphicsBufferD> 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;
}

View File

@ -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;

View File

@ -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<CScriptAiJumpPoint> 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<CScriptWaypoint> 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<CScriptAiJumpPoint> 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<CScriptWaypoint> 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<CScriptWaypoint> 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<CScriptWaypoint> 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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -48,6 +48,7 @@ class CPFOpenList {
CPFRegionData x90_regionData;
public:
CPFOpenList();
void Clear();
void Push(CPFRegion* reg);
CPFRegion* Pop();

View File

@ -1,4 +1,5 @@
#include "CPathFindSearch.hpp"
#include "Graphics/CGraphics.hpp"
namespace urde {
@ -348,4 +349,17 @@ bool CPathFindSearch::Search(rstl::reserved_vector<CPFRegion*, 4>& 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

View File

@ -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<CPathFindVisualizer> m_viz;
bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1,
rstl::reserved_vector<CPFRegion*, 4>& 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

View File

@ -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);
}

View File

@ -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();

@ -1 +1 @@
Subproject commit f81efb25b53e90cf9e77c06a09095a433929ddb4
Subproject commit e86cce5a6f6ad0182d9d2e01fb31bac47f4df882