mirror of https://github.com/AxioDL/metaforce.git
Implement additive body states, rstl::binary_find
This commit is contained in:
parent
7e85ab932b
commit
daef773f39
|
@ -72,18 +72,18 @@ public:
|
||||||
|
|
||||||
ResId TranslateOriginalToNew(ResId id) const
|
ResId TranslateOriginalToNew(ResId id) const
|
||||||
{
|
{
|
||||||
auto search = std::lower_bound(m_origToNew.cbegin(), m_origToNew.cend(), id,
|
auto search = rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id,
|
||||||
[](const auto& id, ResId test) -> bool { return id.first < test; });
|
[](const auto& id) { return id.first; });
|
||||||
if (search == m_origToNew.cend() || search->first != id)
|
if (search == m_origToNew.cend())
|
||||||
return -1;
|
return -1;
|
||||||
return search->second;
|
return search->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResId TranslateNewToOriginal(ResId id) const
|
ResId TranslateNewToOriginal(ResId id) const
|
||||||
{
|
{
|
||||||
auto search = std::lower_bound(m_newToOrig.cbegin(), m_newToOrig.cend(), id,
|
auto search = rstl::binary_find(m_newToOrig.cbegin(), m_newToOrig.cend(), id,
|
||||||
[](const auto& id, ResId test) -> bool { return id.first < test; });
|
[](const auto& id) { return id.first; });
|
||||||
if (search == m_newToOrig.cend() || search->first != id)
|
if (search == m_newToOrig.cend())
|
||||||
return -1;
|
return -1;
|
||||||
return search->second;
|
return search->second;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
#include "CAdditiveBodyState.hpp"
|
||||||
|
#include "CBodyController.hpp"
|
||||||
|
#include "Character/CPASDatabase.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
#include "CAnimTreeNode.hpp"
|
||||||
|
#include "CPASAnimParmData.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
void CABSAim::Start(CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
const CBCAdditiveAimCmd* cmd =
|
||||||
|
static_cast<const CBCAdditiveAimCmd*>(bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveAim));
|
||||||
|
const CPASAnimState* aimState = bc.GetPASDatabase().GetAnimState(22);
|
||||||
|
|
||||||
|
// Left, Right, Up, Down
|
||||||
|
for (int i=0 ; i<4 ; ++i)
|
||||||
|
{
|
||||||
|
CPASAnimParmData parms(22, CPASAnimParm::FromEnum(i));
|
||||||
|
std::pair<float, s32> best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1);
|
||||||
|
x8_anims[i] = best.second;
|
||||||
|
x18_angles[i] = zeus::degToRad(aimState->GetAnimParmData(x8_anims[i], 1).GetReal32Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
const CAnimData& animData = *bc.GetOwner().GetModelData()->GetAnimationData();
|
||||||
|
x28_hWeight = -animData.GetAdditiveAnimationWeight(x8_anims[0]);
|
||||||
|
x28_hWeight += animData.GetAdditiveAnimationWeight(x8_anims[1]);
|
||||||
|
x30_vWeight = -animData.GetAdditiveAnimationWeight(x8_anims[2]);
|
||||||
|
x30_vWeight += animData.GetAdditiveAnimationWeight(x8_anims[3]);
|
||||||
|
|
||||||
|
x4_needsIdle = false;
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveIdle))
|
||||||
|
x4_needsIdle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSAim::GetBodyStateTransition(float dt, CBodyController& bc)
|
||||||
|
{
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveReaction))
|
||||||
|
return pas::EAnimationState::AdditiveReaction;
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveFlinch))
|
||||||
|
return pas::EAnimationState::AdditiveFlinch;
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveIdle) || x4_needsIdle)
|
||||||
|
return pas::EAnimationState::AdditiveIdle;
|
||||||
|
return pas::EAnimationState::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSAim::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||||
|
if (st == pas::EAnimationState::Invalid)
|
||||||
|
{
|
||||||
|
const zeus::CVector3f& target = bc.GetCommandMgr().GetAdditiveTargetVector();
|
||||||
|
if (target.canBeNormalized())
|
||||||
|
{
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
|
||||||
|
float hAngle = zeus::clamp(-x18_angles[0], std::atan2(target.x, target.y), x18_angles[1]);
|
||||||
|
hAngle *= 0.63661975f;
|
||||||
|
hAngle = zeus::clamp(-3.f, (hAngle - x28_hWeight) * 0.25f / dt, 3.f);
|
||||||
|
x2c_hWeightVel += dt * zeus::clamp(-10.f, (hAngle - x2c_hWeightVel) / dt, 10.f);
|
||||||
|
|
||||||
|
float hypotenuse = std::sqrt(target.y * target.y + target.x * target.x);
|
||||||
|
float vAngle = zeus::clamp(-x18_angles[3], std::atan2(target.z, hypotenuse), x18_angles[2]);
|
||||||
|
vAngle *= 0.63661975f;
|
||||||
|
vAngle = zeus::clamp(-3.f, (vAngle - x30_vWeight) * 0.25f / dt, 3.f);
|
||||||
|
x34_vWeightVel += dt * zeus::clamp(-10.f, (vAngle - x34_vWeightVel) / dt, 10.f);
|
||||||
|
|
||||||
|
float newHWeight = dt * x2c_hWeightVel + x28_hWeight;
|
||||||
|
if (newHWeight != x28_hWeight)
|
||||||
|
{
|
||||||
|
if (std::fabs(x28_hWeight) > 0.f && x28_hWeight * newHWeight <= 0.f)
|
||||||
|
animData.DelAdditiveAnimation(x8_anims[x28_hWeight < 0.f ? 0 : 1]);
|
||||||
|
float absWeight = std::fabs(newHWeight);
|
||||||
|
if (absWeight > 0.f)
|
||||||
|
animData.AddAdditiveAnimation(x8_anims[newHWeight < 0.f ? 0 : 1], absWeight, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
float newVWeight = dt * x34_vWeightVel + x30_vWeight;
|
||||||
|
if (newVWeight != x30_vWeight)
|
||||||
|
{
|
||||||
|
if (std::fabs(x30_vWeight) > 0.f && x30_vWeight * newVWeight <= 0.f)
|
||||||
|
animData.DelAdditiveAnimation(x8_anims[x30_vWeight > 0.f ? 2 : 3]);
|
||||||
|
float absWeight = std::fabs(newVWeight);
|
||||||
|
if (absWeight > 0.f)
|
||||||
|
animData.AddAdditiveAnimation(x8_anims[newVWeight > 0.f ? 2 : 3], absWeight, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
x28_hWeight = newHWeight;
|
||||||
|
x30_vWeight = newVWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CABSAim::Shutdown(CBodyController& bc)
|
||||||
|
{
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
|
||||||
|
if (x28_hWeight != 0.f)
|
||||||
|
animData.DelAdditiveAnimation(x8_anims[x28_hWeight < 0.f ? 0 : 1]);
|
||||||
|
if (x30_vWeight != 0.f)
|
||||||
|
animData.DelAdditiveAnimation(x8_anims[x30_vWeight > 0.f ? 2 : 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CABSFlinch::Start(CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
const CBCAdditiveFlinchCmd* cmd =
|
||||||
|
static_cast<const CBCAdditiveFlinchCmd*>(bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveFlinch));
|
||||||
|
x4_weight = cmd->GetWeight();
|
||||||
|
|
||||||
|
CPASAnimParmData parms(23);
|
||||||
|
std::pair<float, s32> best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1);
|
||||||
|
x8_anim = best.second;
|
||||||
|
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
animData.AddAdditiveAnimation(x8_anim, x4_weight, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSFlinch::GetBodyStateTransition(float dt, CBodyController& bc)
|
||||||
|
{
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveReaction))
|
||||||
|
return pas::EAnimationState::AdditiveReaction;
|
||||||
|
return pas::EAnimationState::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSFlinch::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||||
|
if (st == pas::EAnimationState::Invalid)
|
||||||
|
{
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
CCharAnimTime rem = animData.GetAdditiveAnimationTree(x8_anim)->VGetTimeRemaining();
|
||||||
|
if (std::fabs(rem.GetSeconds()) < 0.00001f)
|
||||||
|
return pas::EAnimationState::AdditiveIdle;
|
||||||
|
}
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSIdle::GetBodyStateTransition(float dt, CBodyController& bc)
|
||||||
|
{
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveReaction))
|
||||||
|
return pas::EAnimationState::AdditiveReaction;
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveFlinch))
|
||||||
|
return pas::EAnimationState::AdditiveFlinch;
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveAim))
|
||||||
|
return pas::EAnimationState::AdditiveAim;
|
||||||
|
return pas::EAnimationState::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSIdle::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
return GetBodyStateTransition(dt, bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CABSReaction::Start(CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
const CBCAdditiveReactionCmd* cmd =
|
||||||
|
static_cast<const CBCAdditiveReactionCmd*>(bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveReaction));
|
||||||
|
x4_weight = cmd->GetWeight();
|
||||||
|
xc_type = cmd->GetType();
|
||||||
|
x10_active = cmd->GetIsActive();
|
||||||
|
|
||||||
|
CPASAnimParmData parms(24, CPASAnimParm::FromEnum(s32(xc_type)));
|
||||||
|
std::pair<float, s32> best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1);
|
||||||
|
x8_anim = best.second;
|
||||||
|
|
||||||
|
if (x8_anim != -1)
|
||||||
|
{
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
animData.AddAdditiveAnimation(x8_anim, x4_weight, x10_active, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSReaction::GetBodyStateTransition(float dt, CBodyController& bc)
|
||||||
|
{
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveReaction) &&
|
||||||
|
xc_type == pas::EReactionType::Three)
|
||||||
|
return pas::EAnimationState::AdditiveReaction;
|
||||||
|
return pas::EAnimationState::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CABSReaction::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||||
|
if (st == pas::EAnimationState::Invalid)
|
||||||
|
{
|
||||||
|
if (x8_anim == -1)
|
||||||
|
return pas::EAnimationState::AdditiveIdle;
|
||||||
|
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
if (x10_active)
|
||||||
|
{
|
||||||
|
if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::TwentySeven))
|
||||||
|
{
|
||||||
|
StopAnimation(bc);
|
||||||
|
bc.GetOwner().RemoveEmitter();
|
||||||
|
return pas::EAnimationState::AdditiveIdle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (animData.IsAdditiveAnimationAdded(x8_anim))
|
||||||
|
{
|
||||||
|
CCharAnimTime rem = animData.GetAdditiveAnimationTree(x8_anim)->VGetTimeRemaining();
|
||||||
|
if (std::fabs(rem.GetSeconds()) < 0.00001f)
|
||||||
|
{
|
||||||
|
StopAnimation(bc);
|
||||||
|
return pas::EAnimationState::AdditiveIdle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pas::EAnimationState::AdditiveIdle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CABSReaction::StopAnimation(CBodyController& bc)
|
||||||
|
{
|
||||||
|
if (x8_anim != -1)
|
||||||
|
{
|
||||||
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
||||||
|
animData.DelAdditiveAnimation(x8_anim);
|
||||||
|
x8_anim = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,30 +7,68 @@
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
class CBodyController;
|
||||||
|
class CStateManager;
|
||||||
|
class CActor;
|
||||||
class CAdditiveBodyState
|
class CAdditiveBodyState
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual ~CAdditiveBodyState() = default;
|
||||||
|
virtual bool ApplyHeadTracking() const { return true; }
|
||||||
|
virtual bool CanShoot() const { return true; }
|
||||||
|
virtual void Start(CBodyController& bc, CStateManager& mgr) = 0;
|
||||||
|
virtual pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) = 0;
|
||||||
|
virtual void Shutdown(CBodyController& bc) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CABSAim : public CAdditiveBodyState
|
class CABSAim : public CAdditiveBodyState
|
||||||
{
|
{
|
||||||
|
bool x4_needsIdle = false;
|
||||||
|
s32 x8_anims[4];
|
||||||
|
float x18_angles[4];
|
||||||
|
float x28_hWeight = 0.f;
|
||||||
|
float x2c_hWeightVel = 0.f;
|
||||||
|
float x30_vWeight = 0.f;
|
||||||
|
float x34_vWeightVel = 0.f;
|
||||||
|
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||||
|
public:
|
||||||
|
void Start(CBodyController& bc, CStateManager& mgr);
|
||||||
|
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr);
|
||||||
|
void Shutdown(CBodyController& bc);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CABSFlinch : public CAdditiveBodyState
|
class CABSFlinch : public CAdditiveBodyState
|
||||||
{
|
{
|
||||||
|
float x4_weight = 1.f;
|
||||||
|
u32 x8_anim = 0;
|
||||||
|
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||||
|
public:
|
||||||
|
void Start(CBodyController& bc, CStateManager& mgr);
|
||||||
|
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr);
|
||||||
|
void Shutdown(CBodyController& bc) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CABSIdle : public CAdditiveBodyState
|
class CABSIdle : public CAdditiveBodyState
|
||||||
{
|
{
|
||||||
|
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||||
|
public:
|
||||||
|
void Start(CBodyController& bc, CStateManager& mgr) {}
|
||||||
|
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr);
|
||||||
|
void Shutdown(CBodyController& bc) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CABSReaction : public CAdditiveBodyState
|
class CABSReaction : public CAdditiveBodyState
|
||||||
{
|
{
|
||||||
|
float x4_weight = 1.f;
|
||||||
|
s32 x8_anim = -1;
|
||||||
|
pas::EReactionType xc_type = pas::EReactionType::Invalid;
|
||||||
|
bool x10_active = false;
|
||||||
|
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||||
|
void StopAnimation(CBodyController& bc);
|
||||||
|
public:
|
||||||
|
void Start(CBodyController& bc, CStateManager& mgr);
|
||||||
|
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr);
|
||||||
|
void Shutdown(CBodyController& bc) { StopAnimation(bc); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,6 +187,12 @@ SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAnimData::IsAdditiveAnimation(u32 idx) const
|
bool CAnimData::IsAdditiveAnimation(u32 idx) const
|
||||||
|
{
|
||||||
|
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||||
|
return x0_charFactory->HasAdditiveInfo(animIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAnimData::IsAdditiveAnimationAdded(u32 idx) const
|
||||||
{
|
{
|
||||||
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
|
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
|
||||||
|
@ -197,14 +203,12 @@ bool CAnimData::IsAdditiveAnimation(u32 idx) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CAnimTreeNode> CAnimData::GetAdditiveAnimationTree(u32 idx) const
|
const std::shared_ptr<CAnimTreeNode>& CAnimData::GetAdditiveAnimationTree(u32 idx) const
|
||||||
{
|
{
|
||||||
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
|
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
|
||||||
return pair.first == idx;
|
return pair.first == idx;
|
||||||
});
|
});
|
||||||
if (search == x434_additiveAnims.cend())
|
|
||||||
return {};
|
|
||||||
return search->second.GetAnim();
|
return search->second.GetAnim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +219,7 @@ bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
|
||||||
return pair.first == idx;
|
return pair.first == idx;
|
||||||
});
|
});
|
||||||
if (search == x434_additiveAnims.cend())
|
if (search == x434_additiveAnims.cend())
|
||||||
return {};
|
return false;
|
||||||
return search->second.IsActive();
|
return search->second.IsActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +261,17 @@ void CAnimData::AddAdditiveAnimation(u32 idx, float weight, bool active, bool b)
|
||||||
x434_additiveAnims.emplace_back(std::make_pair(idx, CAdditiveAnimPlayback(node, weight, active, info, b)));
|
x434_additiveAnims.emplace_back(std::make_pair(idx, CAdditiveAnimPlayback(node, weight, active, info, b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<CAnimationManager> CAnimData::GetAnimationManager()
|
std::shared_ptr<CAnimationManager> CAnimData::GetAnimationManager()
|
||||||
{
|
{
|
||||||
return x100_animMgr;
|
return x100_animMgr;
|
||||||
|
|
|
@ -162,10 +162,12 @@ public:
|
||||||
SAdvancementDeltas AdvanceAdditiveAnims(float);
|
SAdvancementDeltas AdvanceAdditiveAnims(float);
|
||||||
SAdvancementDeltas UpdateAdditiveAnims(float);
|
SAdvancementDeltas UpdateAdditiveAnims(float);
|
||||||
bool IsAdditiveAnimation(u32) const;
|
bool IsAdditiveAnimation(u32) const;
|
||||||
std::shared_ptr<CAnimTreeNode> GetAdditiveAnimationTree(u32) const;
|
bool IsAdditiveAnimationAdded(u32) const;
|
||||||
|
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
|
||||||
bool IsAdditiveAnimationActive(u32) const;
|
bool IsAdditiveAnimationActive(u32) const;
|
||||||
void DelAdditiveAnimation(u32);
|
void DelAdditiveAnimation(u32);
|
||||||
void AddAdditiveAnimation(u32, float, bool, bool);
|
void AddAdditiveAnimation(u32, float, bool, bool);
|
||||||
|
float GetAdditiveAnimationWeight(u32 idx) const;
|
||||||
std::shared_ptr<CAnimationManager> GetAnimationManager();
|
std::shared_ptr<CAnimationManager> GetAnimationManager();
|
||||||
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }
|
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }
|
||||||
const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); }
|
const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); }
|
||||||
|
|
|
@ -233,21 +233,25 @@ public:
|
||||||
|
|
||||||
class CBCAdditiveFlinchCmd : public CBodyStateCmd
|
class CBCAdditiveFlinchCmd : public CBodyStateCmd
|
||||||
{
|
{
|
||||||
float x8_ = 1.f;
|
float x8_weight = 1.f;
|
||||||
public:
|
public:
|
||||||
CBCAdditiveFlinchCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch) {}
|
CBCAdditiveFlinchCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch) {}
|
||||||
CBCAdditiveFlinchCmd(float f) : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch), x8_(f) {}
|
CBCAdditiveFlinchCmd(float f) : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch), x8_weight(f) {}
|
||||||
|
float GetWeight() const { return x8_weight; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBCAdditiveReactionCmd : public CBodyStateCmd
|
class CBCAdditiveReactionCmd : public CBodyStateCmd
|
||||||
{
|
{
|
||||||
float x8_ = 1.f;
|
float x8_weight = 1.f;
|
||||||
pas::EReactionType xc_type = pas::EReactionType::Invalid;
|
pas::EReactionType xc_type = pas::EReactionType::Invalid;
|
||||||
bool x10_ = false;
|
bool x10_active = false;
|
||||||
public:
|
public:
|
||||||
CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {}
|
CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {}
|
||||||
CBCAdditiveReactionCmd(pas::EReactionType type, float f)
|
CBCAdditiveReactionCmd(pas::EReactionType type, float f)
|
||||||
: CBodyStateCmd(EBodyStateCmd::AdditiveReaction), x8_(f), xc_type(type) {}
|
: CBodyStateCmd(EBodyStateCmd::AdditiveReaction), x8_weight(f), xc_type(type) {}
|
||||||
|
pas::EReactionType GetType() const { return xc_type; }
|
||||||
|
float GetWeight() const { return x8_weight; }
|
||||||
|
bool GetIsActive() const { return x10_active; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBCLoopAttackCmd : public CBodyStateCmd
|
class CBCLoopAttackCmd : public CBodyStateCmd
|
||||||
|
@ -327,7 +331,7 @@ class CBodyStateCmdMgr
|
||||||
CBCCoverCmd x230_cover;
|
CBCCoverCmd x230_cover;
|
||||||
CBCWallHangCmd x254_wallHang;
|
CBCWallHangCmd x254_wallHang;
|
||||||
CBodyStateCmd x260_ = {EBodyStateCmd::Locomotion};
|
CBodyStateCmd x260_ = {EBodyStateCmd::Locomotion};
|
||||||
CBodyStateCmd x268_ = {EBodyStateCmd::TwentyThree};
|
CBodyStateCmd x268_ = {EBodyStateCmd::AdditiveIdle};
|
||||||
CBCAdditiveAimCmd x270_additiveAim;
|
CBCAdditiveAimCmd x270_additiveAim;
|
||||||
CBCAdditiveFlinchCmd x278_additiveFlinch;
|
CBCAdditiveFlinchCmd x278_additiveFlinch;
|
||||||
CBCAdditiveReactionCmd x284_additiveReaction;
|
CBCAdditiveReactionCmd x284_additiveReaction;
|
||||||
|
|
|
@ -150,14 +150,24 @@ ResId CCharacterFactory::GetEventResourceIdForAnimResourceId(ResId id) const
|
||||||
|
|
||||||
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
|
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
|
||||||
{
|
{
|
||||||
auto search = std::lower_bound(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
||||||
[](const auto& anim, u32 test) -> bool { return anim.first < test; });
|
[](const auto& anim) { return anim.first; });
|
||||||
|
|
||||||
if (search == x40_additiveInfo.cend() || idx != search->first)
|
if (search == x40_additiveInfo.cend())
|
||||||
return x50_defaultAdditiveInfo;
|
return x50_defaultAdditiveInfo;
|
||||||
return search->second;
|
return search->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCharacterFactory::HasAdditiveInfo(u32 idx) const
|
||||||
|
{
|
||||||
|
auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
||||||
|
[](const auto& anim) { return anim.first; });
|
||||||
|
|
||||||
|
if (search == x40_additiveInfo.cend())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<CCharacterInfo>
|
std::vector<CCharacterInfo>
|
||||||
CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs)
|
CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
|
|
||||||
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; }
|
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; }
|
||||||
const CAdditiveAnimationInfo& FindAdditiveInfo(u32 idx) const;
|
const CAdditiveAnimationInfo& FindAdditiveInfo(u32 idx) const;
|
||||||
|
bool HasAdditiveInfo(u32 idx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,11 +62,9 @@ CPASAnimState::CPASAnimState(int stateId)
|
||||||
|
|
||||||
CPASAnimParm CPASAnimState::GetAnimParmData(s32 animId, u32 parmIdx) const
|
CPASAnimParm CPASAnimState::GetAnimParmData(s32 animId, u32 parmIdx) const
|
||||||
{
|
{
|
||||||
CPASAnimInfo key(animId);
|
auto search = rstl::binary_find(x14_anims.begin(), x14_anims.end(), animId,
|
||||||
auto search = std::lower_bound(x14_anims.begin(), x14_anims.end(), key,
|
[](const CPASAnimInfo& item) {return item.GetAnimId();});
|
||||||
[](const CPASAnimInfo& item, const CPASAnimInfo& testId) ->
|
if (search == x14_anims.end())
|
||||||
bool {return item.GetAnimId() < testId.GetAnimId();});
|
|
||||||
if (search == x14_anims.end() || search->GetAnimId() > animId)
|
|
||||||
return CPASAnimParm::NoParameter();
|
return CPASAnimParm::NoParameter();
|
||||||
|
|
||||||
CPASParmInfo parm = x4_parms.at(parmIdx);
|
CPASParmInfo parm = x4_parms.at(parmIdx);
|
||||||
|
|
|
@ -37,11 +37,10 @@ std::pair<float, s32> CPASDatabase::FindBestAnimation(const CPASAnimParmData& da
|
||||||
|
|
||||||
std::pair<float, s32> CPASDatabase::FindBestAnimation(const CPASAnimParmData& data, CRandom16& rand, s32 ignoreAnim) const
|
std::pair<float, s32> CPASDatabase::FindBestAnimation(const CPASAnimParmData& data, CRandom16& rand, s32 ignoreAnim) const
|
||||||
{
|
{
|
||||||
CPASAnimState key(data.GetStateId());
|
auto it = rstl::binary_find(x0_states.cbegin(), x0_states.cend(), data.GetStateId(),
|
||||||
auto it = std::lower_bound(x0_states.cbegin(), x0_states.cend(), key,
|
[](const CPASAnimState& item) {return item.GetStateId();});
|
||||||
[](const CPASAnimState& item, const CPASAnimState& test) -> bool {return item.GetStateId() < test.GetStateId();});
|
|
||||||
|
|
||||||
if (it == x0_states.cend() || it->GetStateId() > key.GetStateId())
|
if (it == x0_states.cend())
|
||||||
return {0.f, -1};
|
return {0.f, -1};
|
||||||
|
|
||||||
return (*it).FindBestAnimation(data.GetAnimParmData(), rand, ignoreAnim);
|
return (*it).FindBestAnimation(data.GetAnimParmData(), rand, ignoreAnim);
|
||||||
|
|
|
@ -61,7 +61,11 @@ enum class EAnimationState
|
||||||
Scripted,
|
Scripted,
|
||||||
ProjectileAttack,
|
ProjectileAttack,
|
||||||
Cover,
|
Cover,
|
||||||
WallHang
|
WallHang,
|
||||||
|
AdditiveIdle,
|
||||||
|
AdditiveAim,
|
||||||
|
AdditiveFlinch,
|
||||||
|
AdditiveReaction
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EHurledState
|
enum class EHurledState
|
||||||
|
@ -85,7 +89,11 @@ enum class EFallState
|
||||||
|
|
||||||
enum class EReactionType
|
enum class EReactionType
|
||||||
{
|
{
|
||||||
Invalid = -1
|
Invalid = -1,
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EAdditiveReactionType
|
enum class EAdditiveReactionType
|
||||||
|
@ -242,7 +250,7 @@ enum class EBodyStateCmd
|
||||||
Cover,
|
Cover,
|
||||||
WallHang,
|
WallHang,
|
||||||
Locomotion,
|
Locomotion,
|
||||||
TwentyThree,
|
AdditiveIdle,
|
||||||
AdditiveAim,
|
AdditiveAim,
|
||||||
AdditiveFlinch,
|
AdditiveFlinch,
|
||||||
AdditiveReaction,
|
AdditiveReaction,
|
||||||
|
|
|
@ -317,9 +317,9 @@ ResId CTextParser::GetAssetIdFromString(const char16_t* str, int len,
|
||||||
|
|
||||||
if (txtrMap)
|
if (txtrMap)
|
||||||
{
|
{
|
||||||
auto search = std::lower_bound(txtrMap->begin(), txtrMap->end(), id,
|
auto search = rstl::binary_find(txtrMap->begin(), txtrMap->end(), id,
|
||||||
[](const std::pair<ResId, ResId>& a, ResId test) { return a.first < test; });
|
[](const std::pair<ResId, ResId>& a) { return a.first; });
|
||||||
if (search != txtrMap->end() && search->first == id)
|
if (search != txtrMap->end())
|
||||||
id = search->second;
|
id = search->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,8 +169,8 @@ static const CCharacterIdentifier gCantEndChars[] =
|
||||||
|
|
||||||
int CWordBreakTables::GetBeginRank(wchar_t ch)
|
int CWordBreakTables::GetBeginRank(wchar_t ch)
|
||||||
{
|
{
|
||||||
auto search = std::lower_bound(std::cbegin(gCantBeginChars), std::cend(gCantBeginChars), ch,
|
auto search = rstl::binary_find(std::cbegin(gCantBeginChars), std::cend(gCantBeginChars), ch,
|
||||||
[](const CCharacterIdentifier& item, const wchar_t& test) -> bool {return item.chr < test;});
|
[](const CCharacterIdentifier& item) {return item.chr;});
|
||||||
if (search == std::cend(gCantBeginChars))
|
if (search == std::cend(gCantBeginChars))
|
||||||
return 5;
|
return 5;
|
||||||
return search->rank;
|
return search->rank;
|
||||||
|
@ -178,8 +178,8 @@ int CWordBreakTables::GetBeginRank(wchar_t ch)
|
||||||
|
|
||||||
int CWordBreakTables::GetEndRank(wchar_t ch)
|
int CWordBreakTables::GetEndRank(wchar_t ch)
|
||||||
{
|
{
|
||||||
auto search = std::lower_bound(std::cbegin(gCantEndChars), std::cend(gCantEndChars), ch,
|
auto search = rstl::binary_find(std::cbegin(gCantEndChars), std::cend(gCantEndChars), ch,
|
||||||
[](const CCharacterIdentifier& item, const wchar_t& test) -> bool {return item.chr < test;});
|
[](const CCharacterIdentifier& item) {return item.chr;});
|
||||||
if (search == std::cend(gCantEndChars))
|
if (search == std::cend(gCantEndChars))
|
||||||
return 5;
|
return 5;
|
||||||
return search->rank;
|
return search->rank;
|
||||||
|
|
|
@ -9,24 +9,4 @@ CEnergyDrainSource::CEnergyDrainSource(TUniqueId src, float intensity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TUniqueId CEnergyDrainSource::GetEnergyDrainSourceId() const
|
|
||||||
{
|
|
||||||
return x0_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CEnergyDrainSource::SetEnergyDrainIntensity(float in)
|
|
||||||
{
|
|
||||||
x4_intensity = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CEnergyDrainSource::GetEnergyDrainIntensity() const
|
|
||||||
{
|
|
||||||
return x4_intensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CEnergyDrainSource::operator<(const CEnergyDrainSource& other) const
|
|
||||||
{
|
|
||||||
return x0_source < other.x0_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,9 @@ class CEnergyDrainSource
|
||||||
float x4_intensity;
|
float x4_intensity;
|
||||||
public:
|
public:
|
||||||
CEnergyDrainSource(TUniqueId src, float intensity);
|
CEnergyDrainSource(TUniqueId src, float intensity);
|
||||||
TUniqueId GetEnergyDrainSourceId() const;
|
TUniqueId GetEnergyDrainSourceId() const { return x0_source; }
|
||||||
void SetEnergyDrainIntensity(float);
|
void SetEnergyDrainIntensity(float in) { x4_intensity = in; }
|
||||||
float GetEnergyDrainIntensity() const;
|
float GetEnergyDrainIntensity() const { return x4_intensity; }
|
||||||
|
|
||||||
bool operator<(const CEnergyDrainSource& other) const;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // __URDE_CENERGYDRAINSOURCE_HPP__
|
#endif // __URDE_CENERGYDRAINSOURCE_HPP__
|
||||||
|
|
|
@ -10,7 +10,8 @@ void CPlayerEnergyDrain::AddEnergyDrainSource(TUniqueId id, float intensity) { x
|
||||||
|
|
||||||
void CPlayerEnergyDrain::RemoveEnergyDrainSource(TUniqueId id)
|
void CPlayerEnergyDrain::RemoveEnergyDrainSource(TUniqueId id)
|
||||||
{
|
{
|
||||||
auto it = std::lower_bound(x0_sources.begin(), x0_sources.end(), CEnergyDrainSource(id, 0.f));
|
auto it = rstl::binary_find(x0_sources.begin(), x0_sources.end(), id,
|
||||||
|
[](const CEnergyDrainSource& item) {return item.GetEnergyDrainSourceId();});
|
||||||
if (it != x0_sources.end())
|
if (it != x0_sources.end())
|
||||||
x0_sources.erase(it);
|
x0_sources.erase(it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,21 @@ public:
|
||||||
T& operator[](size_t idx) { return x4_data[idx]; }
|
T& operator[](size_t idx) { return x4_data[idx]; }
|
||||||
const T& operator[](size_t idx) const { return x4_data[idx]; }
|
const T& operator[](size_t idx) const { return x4_data[idx]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class ForwardIt, class T>
|
||||||
|
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value)
|
||||||
|
{
|
||||||
|
first = std::lower_bound(first, last, value);
|
||||||
|
return (!(first == last) && !(value < *first)) ? first : last;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ForwardIt, class T, class GetKey>
|
||||||
|
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, GetKey getkey)
|
||||||
|
{
|
||||||
|
auto comp = [&](const auto& left, const T& right) { return getkey(left) < right; };
|
||||||
|
first = std::lower_bound(first, last, value, comp);
|
||||||
|
return (!(first == last) && !(value < getkey(*first))) ? first : last;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __RSTL_HPP__
|
#endif // __RSTL_HPP__
|
||||||
|
|
Loading…
Reference in New Issue