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
|
||||
{
|
||||
auto search = std::lower_bound(m_origToNew.cbegin(), m_origToNew.cend(), id,
|
||||
[](const auto& id, ResId test) -> bool { return id.first < test; });
|
||||
if (search == m_origToNew.cend() || search->first != id)
|
||||
auto search = rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id,
|
||||
[](const auto& id) { return id.first; });
|
||||
if (search == m_origToNew.cend())
|
||||
return -1;
|
||||
return search->second;
|
||||
}
|
||||
|
||||
ResId TranslateNewToOriginal(ResId id) const
|
||||
{
|
||||
auto search = std::lower_bound(m_newToOrig.cbegin(), m_newToOrig.cend(), id,
|
||||
[](const auto& id, ResId test) -> bool { return id.first < test; });
|
||||
if (search == m_newToOrig.cend() || search->first != id)
|
||||
auto search = rstl::binary_find(m_newToOrig.cbegin(), m_newToOrig.cend(), id,
|
||||
[](const auto& id) { return id.first; });
|
||||
if (search == m_newToOrig.cend())
|
||||
return -1;
|
||||
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
|
||||
{
|
||||
|
||||
class CBodyController;
|
||||
class CStateManager;
|
||||
class CActor;
|
||||
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
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
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(),
|
||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
|
||||
|
@ -197,14 +203,12 @@ bool CAnimData::IsAdditiveAnimation(u32 idx) const
|
|||
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(),
|
||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
|
||||
return pair.first == idx;
|
||||
});
|
||||
if (search == x434_additiveAnims.cend())
|
||||
return {};
|
||||
return search->second.GetAnim();
|
||||
}
|
||||
|
||||
|
@ -215,7 +219,7 @@ bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
|
|||
return pair.first == idx;
|
||||
});
|
||||
if (search == x434_additiveAnims.cend())
|
||||
return {};
|
||||
return false;
|
||||
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)));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return x100_animMgr;
|
||||
|
|
|
@ -162,10 +162,12 @@ public:
|
|||
SAdvancementDeltas AdvanceAdditiveAnims(float);
|
||||
SAdvancementDeltas UpdateAdditiveAnims(float);
|
||||
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;
|
||||
void DelAdditiveAnimation(u32);
|
||||
void AddAdditiveAnimation(u32, float, bool, bool);
|
||||
float GetAdditiveAnimationWeight(u32 idx) const;
|
||||
std::shared_ptr<CAnimationManager> GetAnimationManager();
|
||||
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }
|
||||
const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); }
|
||||
|
|
|
@ -233,21 +233,25 @@ public:
|
|||
|
||||
class CBCAdditiveFlinchCmd : public CBodyStateCmd
|
||||
{
|
||||
float x8_ = 1.f;
|
||||
float x8_weight = 1.f;
|
||||
public:
|
||||
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
|
||||
{
|
||||
float x8_ = 1.f;
|
||||
float x8_weight = 1.f;
|
||||
pas::EReactionType xc_type = pas::EReactionType::Invalid;
|
||||
bool x10_ = false;
|
||||
bool x10_active = false;
|
||||
public:
|
||||
CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {}
|
||||
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
|
||||
|
@ -327,7 +331,7 @@ class CBodyStateCmdMgr
|
|||
CBCCoverCmd x230_cover;
|
||||
CBCWallHangCmd x254_wallHang;
|
||||
CBodyStateCmd x260_ = {EBodyStateCmd::Locomotion};
|
||||
CBodyStateCmd x268_ = {EBodyStateCmd::TwentyThree};
|
||||
CBodyStateCmd x268_ = {EBodyStateCmd::AdditiveIdle};
|
||||
CBCAdditiveAimCmd x270_additiveAim;
|
||||
CBCAdditiveFlinchCmd x278_additiveFlinch;
|
||||
CBCAdditiveReactionCmd x284_additiveReaction;
|
||||
|
|
|
@ -150,14 +150,24 @@ ResId CCharacterFactory::GetEventResourceIdForAnimResourceId(ResId id) const
|
|||
|
||||
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
|
||||
{
|
||||
auto search = std::lower_bound(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
||||
[](const auto& anim, u32 test) -> bool { return anim.first < test; });
|
||||
auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
||||
[](const auto& anim) { return anim.first; });
|
||||
|
||||
if (search == x40_additiveInfo.cend() || idx != search->first)
|
||||
if (search == x40_additiveInfo.cend())
|
||||
return x50_defaultAdditiveInfo;
|
||||
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>
|
||||
CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs)
|
||||
{
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
|
||||
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; }
|
||||
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
|
||||
{
|
||||
CPASAnimInfo key(animId);
|
||||
auto search = std::lower_bound(x14_anims.begin(), x14_anims.end(), key,
|
||||
[](const CPASAnimInfo& item, const CPASAnimInfo& testId) ->
|
||||
bool {return item.GetAnimId() < testId.GetAnimId();});
|
||||
if (search == x14_anims.end() || search->GetAnimId() > animId)
|
||||
auto search = rstl::binary_find(x14_anims.begin(), x14_anims.end(), animId,
|
||||
[](const CPASAnimInfo& item) {return item.GetAnimId();});
|
||||
if (search == x14_anims.end())
|
||||
return CPASAnimParm::NoParameter();
|
||||
|
||||
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
|
||||
{
|
||||
CPASAnimState key(data.GetStateId());
|
||||
auto it = std::lower_bound(x0_states.cbegin(), x0_states.cend(), key,
|
||||
[](const CPASAnimState& item, const CPASAnimState& test) -> bool {return item.GetStateId() < test.GetStateId();});
|
||||
auto it = rstl::binary_find(x0_states.cbegin(), x0_states.cend(), data.GetStateId(),
|
||||
[](const CPASAnimState& item) {return item.GetStateId();});
|
||||
|
||||
if (it == x0_states.cend() || it->GetStateId() > key.GetStateId())
|
||||
if (it == x0_states.cend())
|
||||
return {0.f, -1};
|
||||
|
||||
return (*it).FindBestAnimation(data.GetAnimParmData(), rand, ignoreAnim);
|
||||
|
|
|
@ -61,7 +61,11 @@ enum class EAnimationState
|
|||
Scripted,
|
||||
ProjectileAttack,
|
||||
Cover,
|
||||
WallHang
|
||||
WallHang,
|
||||
AdditiveIdle,
|
||||
AdditiveAim,
|
||||
AdditiveFlinch,
|
||||
AdditiveReaction
|
||||
};
|
||||
|
||||
enum class EHurledState
|
||||
|
@ -85,7 +89,11 @@ enum class EFallState
|
|||
|
||||
enum class EReactionType
|
||||
{
|
||||
Invalid = -1
|
||||
Invalid = -1,
|
||||
Zero,
|
||||
One,
|
||||
Two,
|
||||
Three
|
||||
};
|
||||
|
||||
enum class EAdditiveReactionType
|
||||
|
@ -242,7 +250,7 @@ enum class EBodyStateCmd
|
|||
Cover,
|
||||
WallHang,
|
||||
Locomotion,
|
||||
TwentyThree,
|
||||
AdditiveIdle,
|
||||
AdditiveAim,
|
||||
AdditiveFlinch,
|
||||
AdditiveReaction,
|
||||
|
|
|
@ -317,9 +317,9 @@ ResId CTextParser::GetAssetIdFromString(const char16_t* str, int len,
|
|||
|
||||
if (txtrMap)
|
||||
{
|
||||
auto search = std::lower_bound(txtrMap->begin(), txtrMap->end(), id,
|
||||
[](const std::pair<ResId, ResId>& a, ResId test) { return a.first < test; });
|
||||
if (search != txtrMap->end() && search->first == id)
|
||||
auto search = rstl::binary_find(txtrMap->begin(), txtrMap->end(), id,
|
||||
[](const std::pair<ResId, ResId>& a) { return a.first; });
|
||||
if (search != txtrMap->end())
|
||||
id = search->second;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,8 +169,8 @@ static const CCharacterIdentifier gCantEndChars[] =
|
|||
|
||||
int CWordBreakTables::GetBeginRank(wchar_t ch)
|
||||
{
|
||||
auto search = std::lower_bound(std::cbegin(gCantBeginChars), std::cend(gCantBeginChars), ch,
|
||||
[](const CCharacterIdentifier& item, const wchar_t& test) -> bool {return item.chr < test;});
|
||||
auto search = rstl::binary_find(std::cbegin(gCantBeginChars), std::cend(gCantBeginChars), ch,
|
||||
[](const CCharacterIdentifier& item) {return item.chr;});
|
||||
if (search == std::cend(gCantBeginChars))
|
||||
return 5;
|
||||
return search->rank;
|
||||
|
@ -178,8 +178,8 @@ int CWordBreakTables::GetBeginRank(wchar_t ch)
|
|||
|
||||
int CWordBreakTables::GetEndRank(wchar_t ch)
|
||||
{
|
||||
auto search = std::lower_bound(std::cbegin(gCantEndChars), std::cend(gCantEndChars), ch,
|
||||
[](const CCharacterIdentifier& item, const wchar_t& test) -> bool {return item.chr < test;});
|
||||
auto search = rstl::binary_find(std::cbegin(gCantEndChars), std::cend(gCantEndChars), ch,
|
||||
[](const CCharacterIdentifier& item) {return item.chr;});
|
||||
if (search == std::cend(gCantEndChars))
|
||||
return 5;
|
||||
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;
|
||||
public:
|
||||
CEnergyDrainSource(TUniqueId src, float intensity);
|
||||
TUniqueId GetEnergyDrainSourceId() const;
|
||||
void SetEnergyDrainIntensity(float);
|
||||
float GetEnergyDrainIntensity() const;
|
||||
|
||||
bool operator<(const CEnergyDrainSource& other) const;
|
||||
TUniqueId GetEnergyDrainSourceId() const { return x0_source; }
|
||||
void SetEnergyDrainIntensity(float in) { x4_intensity = in; }
|
||||
float GetEnergyDrainIntensity() const { return x4_intensity; }
|
||||
};
|
||||
}
|
||||
#endif // __URDE_CENERGYDRAINSOURCE_HPP__
|
||||
|
|
|
@ -10,7 +10,8 @@ void CPlayerEnergyDrain::AddEnergyDrainSource(TUniqueId id, float intensity) { x
|
|||
|
||||
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())
|
||||
x0_sources.erase(it);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,21 @@ public:
|
|||
T& operator[](size_t idx) { 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__
|
||||
|
|
Loading…
Reference in New Issue