mirror of https://github.com/AxioDL/metaforce.git
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
23870c53aa
|
@ -119,7 +119,7 @@ public:
|
||||||
|
|
||||||
CHealthInfo& GetHealthInfo();
|
CHealthInfo& GetHealthInfo();
|
||||||
const CHealthInfo& GetHealthInfo() const;
|
const CHealthInfo& GetHealthInfo() const;
|
||||||
u32 GetPickupTotal() { return 99; }
|
u32 GetPickupTotal() const { return 99; }
|
||||||
void SetIsFusionEnabled(bool val) { x0_26_fusion = val; }
|
void SetIsFusionEnabled(bool val) { x0_26_fusion = val; }
|
||||||
bool IsFusionEnabled() const { return x0_26_fusion; }
|
bool IsFusionEnabled() const { return x0_26_fusion; }
|
||||||
EPlayerSuit GetCurrentSuit() const;
|
EPlayerSuit GetCurrentSuit() const;
|
||||||
|
|
|
@ -66,7 +66,7 @@ CScannableObjectInfo::SBucket::SBucket(CInputStream& in, u32 version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CFactoryFnReturn FScannableObjectInfoFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer&,
|
CFactoryFnReturn FScannableObjectInfoFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer&,
|
||||||
CObjectReference* selfRef) {
|
CObjectReference*) {
|
||||||
return TToken<CScannableObjectInfo>::GetIObjObjectFor(std::make_unique<CScannableObjectInfo>(in, tag.id));
|
return TToken<CScannableObjectInfo>::GetIObjObjectFor(std::make_unique<CScannableObjectInfo>(in, tag.id));
|
||||||
}
|
}
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -4,13 +4,16 @@
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
CStaticInterference::CStaticInterference(int sourceCount) { m_sources.reserve(sourceCount); }
|
CStaticInterference::CStaticInterference(size_t sourceCount) { m_sources.reserve(sourceCount); }
|
||||||
|
|
||||||
void CStaticInterference::RemoveSource(TUniqueId id) {
|
void CStaticInterference::RemoveSource(TUniqueId id) {
|
||||||
auto iter = std::find_if(m_sources.begin(), m_sources.end(),
|
const auto iter = std::find_if(m_sources.cbegin(), m_sources.cend(), [id](const auto& src) { return src.id == id; });
|
||||||
[id](const CStaticInterferenceSource& src) -> bool { return src.id == id; });
|
|
||||||
if (iter != m_sources.end())
|
if (iter == m_sources.cend()) {
|
||||||
m_sources.erase(iter);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sources.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStaticInterference::Update(CStateManager&, float dt) {
|
void CStaticInterference::Update(CStateManager&, float dt) {
|
||||||
|
@ -44,15 +47,17 @@ float CStaticInterference::GetTotalInterference() const {
|
||||||
|
|
||||||
void CStaticInterference::AddSource(TUniqueId id, float magnitude, float duration) {
|
void CStaticInterference::AddSource(TUniqueId id, float magnitude, float duration) {
|
||||||
magnitude = zeus::clamp(0.f, magnitude, 1.f);
|
magnitude = zeus::clamp(0.f, magnitude, 1.f);
|
||||||
auto search = std::find_if(m_sources.begin(), m_sources.end(),
|
const auto search = std::find_if(m_sources.begin(), m_sources.end(),
|
||||||
[id](CStaticInterferenceSource& source) { return source.id == id; });
|
[id](const CStaticInterferenceSource& source) { return source.id == id; });
|
||||||
if (search != m_sources.end()) {
|
if (search != m_sources.cend()) {
|
||||||
search->magnitude = magnitude;
|
search->magnitude = magnitude;
|
||||||
search->timeLeft = duration;
|
search->timeLeft = duration;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_sources.size() < m_sources.capacity())
|
|
||||||
|
if (m_sources.size() < m_sources.capacity()) {
|
||||||
m_sources.push_back({id, magnitude, duration});
|
m_sources.push_back({id, magnitude, duration});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -16,7 +16,7 @@ class CStaticInterference {
|
||||||
std::vector<CStaticInterferenceSource> m_sources;
|
std::vector<CStaticInterferenceSource> m_sources;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CStaticInterference(int sourceCount);
|
explicit CStaticInterference(size_t sourceCount);
|
||||||
void RemoveSource(TUniqueId id);
|
void RemoveSource(TUniqueId id);
|
||||||
void Update(CStateManager&, float dt);
|
void Update(CStateManager&, float dt);
|
||||||
float GetTotalInterference() const;
|
float GetTotalInterference() const;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "Runtime/GuiSys/CFontImageDef.hpp"
|
#include "Runtime/GuiSys/CFontImageDef.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Runtime/Graphics/CTexture.hpp"
|
#include "Runtime/Graphics/CTexture.hpp"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
@ -19,10 +21,7 @@ CFontImageDef::CFontImageDef(const TToken<CTexture>& tex, const zeus::CVector2f&
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFontImageDef::IsLoaded() const {
|
bool CFontImageDef::IsLoaded() const {
|
||||||
for (const TToken<CTexture>& tok : x4_texs)
|
return std::all_of(x4_texs.cbegin(), x4_texs.cend(), [](const auto& token) { return token.IsLoaded(); });
|
||||||
if (!tok.IsLoaded())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CFontImageDef::CalculateBaseline() const {
|
s32 CFontImageDef::CalculateBaseline() const {
|
||||||
|
|
|
@ -26,7 +26,7 @@ void CFontRenderState::SetColor(EColorType tp, const CTextColor& col) {
|
||||||
case EColorType::Main:
|
case EColorType::Main:
|
||||||
case EColorType::Outline:
|
case EColorType::Outline:
|
||||||
case EColorType::Geometry:
|
case EColorType::Geometry:
|
||||||
x54_colors[int(tp)] = col;
|
x54_colors[size_t(tp)] = col;
|
||||||
break;
|
break;
|
||||||
case EColorType::Foreground:
|
case EColorType::Foreground:
|
||||||
x54_colors[0] = col;
|
x54_colors[0] = col;
|
||||||
|
|
|
@ -692,8 +692,8 @@ void CMain::UpdateDiscordPresence(CAssetId worldSTRG) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_GameState != nullptr) {
|
if (g_GameState != nullptr) {
|
||||||
if (CPlayerState* pState = g_GameState->GetPlayerState().get()) {
|
if (const CPlayerState* pState = g_GameState->GetPlayerState().get()) {
|
||||||
u32 itemPercent = pState->CalculateItemCollectionRate() * 100 / pState->GetPickupTotal();
|
const u32 itemPercent = pState->CalculateItemCollectionRate() * 100 / pState->GetPickupTotal();
|
||||||
if (DiscordItemPercent != itemPercent) {
|
if (DiscordItemPercent != itemPercent) {
|
||||||
DiscordItemPercent = itemPercent;
|
DiscordItemPercent = itemPercent;
|
||||||
DiscordState = fmt::format(FMT_STRING("{}%"), itemPercent);
|
DiscordState = fmt::format(FMT_STRING("{}%"), itemPercent);
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include "Runtime/MP1/World/CElitePirate.hpp"
|
#include "Runtime/MP1/World/CElitePirate.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "Runtime/Camera/CFirstPersonCamera.hpp"
|
#include "Runtime/Camera/CFirstPersonCamera.hpp"
|
||||||
#include "Runtime/Collision/CCollisionActor.hpp"
|
#include "Runtime/Collision/CCollisionActor.hpp"
|
||||||
#include "Runtime/Collision/CCollisionActorManager.hpp"
|
#include "Runtime/Collision/CCollisionActorManager.hpp"
|
||||||
|
@ -39,7 +42,22 @@ constexpr std::array<SSphereJointInfo, 7> skSphereJointList{{
|
||||||
{"L_Ball", 0.8f},
|
{"L_Ball", 0.8f},
|
||||||
{"R_Ball", 0.8f},
|
{"R_Ball", 0.8f},
|
||||||
}};
|
}};
|
||||||
} // namespace
|
|
||||||
|
// The following used to be member functions, but are made internal as
|
||||||
|
// they alter no internal state.
|
||||||
|
|
||||||
|
// Used to be a member function with a pointer and size in GM8Ev0
|
||||||
|
bool IsArmClawCollider(std::string_view name, std::string_view locator, const std::array<SJointInfo, 3>& info) {
|
||||||
|
if (name == locator) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return std::any_of(info.cbegin(), info.cend(), [&name](const auto& entry) { return entry.from == name; });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector<TUniqueId, 7>& vec) {
|
||||||
|
return std::find(vec.cbegin(), vec.cend(), uid) != vec.cend();
|
||||||
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount)
|
CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount)
|
||||||
: x0_tauntInterval(in.readFloatBig())
|
: x0_tauntInterval(in.readFloatBig())
|
||||||
|
@ -784,10 +802,6 @@ void CElitePirate::SetShotAt(bool val, CStateManager& mgr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CElitePirate::IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector<TUniqueId, 7>& vec) const {
|
|
||||||
return std::find(vec.begin(), vec.end(), uid) != vec.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CElitePirate::AddCollisionList(const SJointInfo* joints, size_t count,
|
void CElitePirate::AddCollisionList(const SJointInfo* joints, size_t count,
|
||||||
std::vector<CJointCollisionDescription>& outJoints) const {
|
std::vector<CJointCollisionDescription>& outJoints) const {
|
||||||
const CAnimData* animData = GetModelData()->GetAnimationData();
|
const CAnimData* animData = GetModelData()->GetAnimationData();
|
||||||
|
@ -855,11 +869,9 @@ void CElitePirate::SetupCollisionActorInfo(CStateManager& mgr) {
|
||||||
if (TCastToPtr<CCollisionActor> act = mgr.ObjectById(uid)) {
|
if (TCastToPtr<CCollisionActor> act = mgr.ObjectById(uid)) {
|
||||||
if (colDesc.GetName() == "Head_1"sv) {
|
if (colDesc.GetName() == "Head_1"sv) {
|
||||||
x770_collisionHeadId = uid;
|
x770_collisionHeadId = uid;
|
||||||
} else if (IsArmClawCollider(colDesc.GetName(), "R_Palm_LCTR"sv, skRightArmJointList.data(),
|
} else if (IsArmClawCollider(colDesc.GetName(), "R_Palm_LCTR"sv, skRightArmJointList)) {
|
||||||
skRightArmJointList.size())) {
|
|
||||||
x774_collisionRJointIds.push_back(uid);
|
x774_collisionRJointIds.push_back(uid);
|
||||||
} else if (IsArmClawCollider(colDesc.GetName(), "L_Palm_LCTR"sv, skLeftArmJointList.data(),
|
} else if (IsArmClawCollider(colDesc.GetName(), "L_Palm_LCTR"sv, skLeftArmJointList)) {
|
||||||
skLeftArmJointList.size())) {
|
|
||||||
x788_collisionLJointIds.push_back(uid);
|
x788_collisionLJointIds.push_back(uid);
|
||||||
}
|
}
|
||||||
if (uid != x770_collisionHeadId) {
|
if (uid != x770_collisionHeadId) {
|
||||||
|
@ -879,19 +891,6 @@ void CElitePirate::SetupCollisionActorInfo(CStateManager& mgr) {
|
||||||
x5d4_collisionActorMgr->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough});
|
x5d4_collisionActorMgr->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CElitePirate::IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info,
|
|
||||||
size_t infoCount) const {
|
|
||||||
if (name == locator) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < infoCount; ++i) {
|
|
||||||
if (name == info[i].from) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) {
|
void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) {
|
||||||
const CAnimationParameters& params = x5d8_data.GetLauncherAnimParams();
|
const CAnimationParameters& params = x5d8_data.GetLauncherAnimParams();
|
||||||
if (!params.GetACSFile().IsValid()) {
|
if (!params.GetACSFile().IsValid()) {
|
||||||
|
|
|
@ -220,15 +220,12 @@ protected:
|
||||||
const CCollisionActorManager& GetCollisionActorManager() const { return *x5d4_collisionActorMgr; }
|
const CCollisionActorManager& GetCollisionActorManager() const { return *x5d4_collisionActorMgr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector<TUniqueId, 7>& vec) const;
|
|
||||||
void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count,
|
void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count,
|
||||||
std::vector<CJointCollisionDescription>& outJoints) const;
|
std::vector<CJointCollisionDescription>& outJoints) const;
|
||||||
void AddCollisionList(const SJointInfo* joints, size_t count,
|
void AddCollisionList(const SJointInfo* joints, size_t count,
|
||||||
std::vector<CJointCollisionDescription>& outJoints) const;
|
std::vector<CJointCollisionDescription>& outJoints) const;
|
||||||
void SetupCollisionManager(CStateManager& mgr);
|
void SetupCollisionManager(CStateManager& mgr);
|
||||||
void SetupCollisionActorInfo(CStateManager& mgr);
|
void SetupCollisionActorInfo(CStateManager& mgr);
|
||||||
bool IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info,
|
|
||||||
size_t infoCount) const;
|
|
||||||
void ApplyDamageToHead(CStateManager& mgr, TUniqueId uid);
|
void ApplyDamageToHead(CStateManager& mgr, TUniqueId uid);
|
||||||
void CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf);
|
void CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf);
|
||||||
bool CanKnockBack(const CDamageInfo& info) const;
|
bool CanKnockBack(const CDamageInfo& info) const;
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
constexpr zeus::CColor CPatterned::skDamageColor(0.5f, 0.f, 0.f);
|
|
||||||
constexpr CMaterialList skPatternedGroundMaterialList(EMaterialTypes::Character, EMaterialTypes::Solid,
|
constexpr CMaterialList skPatternedGroundMaterialList(EMaterialTypes::Character, EMaterialTypes::Solid,
|
||||||
EMaterialTypes::Orbit, EMaterialTypes::GroundCollider,
|
EMaterialTypes::Orbit, EMaterialTypes::GroundCollider,
|
||||||
EMaterialTypes::Target);
|
EMaterialTypes::Target);
|
||||||
|
|
|
@ -31,7 +31,7 @@ using CPatternedTryFunc = void (CPatterned::*)(CStateManager&, int);
|
||||||
|
|
||||||
class CPatterned : public CAi {
|
class CPatterned : public CAi {
|
||||||
public:
|
public:
|
||||||
static const zeus::CColor skDamageColor;
|
static constexpr zeus::CColor skDamageColor{0.5f, 0.f, 0.f};
|
||||||
enum class ECharacter {
|
enum class ECharacter {
|
||||||
AtomicAlpha = 0,
|
AtomicAlpha = 0,
|
||||||
AtomicBeta = 1,
|
AtomicBeta = 1,
|
||||||
|
|
|
@ -110,9 +110,6 @@ void CScriptActor::Think(float dt, CStateManager& mgr) {
|
||||||
MoveToOR(deltas.x0_posDelta, dt);
|
MoveToOR(deltas.x0_posDelta, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (TCastToPtr<MP1::CActorContraption>(this))
|
|
||||||
//printf("DEL %f\n", zeus::radToDeg(zeus::CEulerAngles(deltas.xc_rotDelta).z()));
|
|
||||||
//printf("DEL %f %f %f %f\n", float(deltas.xc_rotDelta[0]), float(deltas.xc_rotDelta[1]), float(deltas.xc_rotDelta[2]), float(deltas.xc_rotDelta[3]));
|
|
||||||
RotateToOR(deltas.xc_rotDelta, dt);
|
RotateToOR(deltas.xc_rotDelta, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ void CScriptActorRotate::UpdateActors(bool next, CStateManager& mgr) {
|
||||||
auto search = mgr.GetIdListForScript(conn.x8_objId);
|
auto search = mgr.GetIdListForScript(conn.x8_objId);
|
||||||
for (auto it = search.first; it != search.second; ++it) {
|
for (auto it = search.first; it != search.second; ++it) {
|
||||||
if (const TCastToConstPtr<CActor> act = mgr.ObjectById(it->second)) {
|
if (const TCastToConstPtr<CActor> act = mgr.ObjectById(it->second)) {
|
||||||
x48_actors[it->second] = act->GetTransform().getRotation();
|
x48_actors.insert_or_assign(it->second, act->GetTransform().getRotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ void CScriptAiJumpPoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId oth
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SConnection& conn : x20_conns) {
|
for (const SConnection& conn : x20_conns) {
|
||||||
if (conn.x0_state != EScriptObjectState::Arrived || conn.x4_msg != EScriptObjectMessage::Next) {
|
if (conn.x0_state != EScriptObjectState::Arrived || conn.x4_msg != EScriptObjectMessage::Next) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,18 +15,18 @@ CScriptSpawnPoint::CScriptSpawnPoint(TUniqueId uid, std::string_view name, const
|
||||||
bool defaultSpawn, bool active, bool morphed)
|
bool defaultSpawn, bool active, bool morphed)
|
||||||
: CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts) {
|
: CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::MorphBall)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::MorphBall)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::MorphBallBombs)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::MorphBallBombs)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::PhazonSuit)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::PhazonSuit)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::ThermalVisor)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::ThermalVisor)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::XRayVisor)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::XRayVisor)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::GrappleBeam)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::GrappleBeam)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::BoostBall)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::BoostBall)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::ChargeBeam)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::ChargeBeam)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::PowerBombs)] = 8;
|
x64_itemCounts[size_t(CPlayerState::EItemType::PowerBombs)] = 8;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::SpaceJumpBoots)] = 1;
|
x64_itemCounts[size_t(CPlayerState::EItemType::SpaceJumpBoots)] = 1;
|
||||||
x64_itemCounts[int(CPlayerState::EItemType::Missiles)] =
|
x64_itemCounts[size_t(CPlayerState::EItemType::Missiles)] =
|
||||||
std::max(x64_itemCounts[int(CPlayerState::EItemType::Missiles)], u32(5));
|
std::max(x64_itemCounts[size_t(CPlayerState::EItemType::Missiles)], u32(5));
|
||||||
#endif
|
#endif
|
||||||
x10c_24_firstSpawn = defaultSpawn;
|
x10c_24_firstSpawn = defaultSpawn;
|
||||||
x10c_25_morphed = morphed;
|
x10c_25_morphed = morphed;
|
||||||
|
@ -77,8 +77,8 @@ void CScriptSpawnPoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objI
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CScriptSpawnPoint::GetPowerup(CPlayerState::EItemType item) const {
|
u32 CScriptSpawnPoint::GetPowerup(CPlayerState::EItemType item) const {
|
||||||
const auto idx = static_cast<int>(item);
|
const auto idx = static_cast<size_t>(item);
|
||||||
if (item >= CPlayerState::EItemType::Max || idx < 0) {
|
if (item >= CPlayerState::EItemType::Max) {
|
||||||
return x64_itemCounts.front();
|
return x64_itemCounts.front();
|
||||||
}
|
}
|
||||||
return x64_itemCounts[idx];
|
return x64_itemCounts[idx];
|
||||||
|
|
|
@ -10,15 +10,22 @@
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
struct TeamAiRoleSorter {
|
struct TeamAiRoleSorter {
|
||||||
|
enum class Type {
|
||||||
|
OwnerID,
|
||||||
|
Distance,
|
||||||
|
TeamAIRole,
|
||||||
|
};
|
||||||
|
|
||||||
zeus::CVector3f x0_pos;
|
zeus::CVector3f x0_pos;
|
||||||
s32 xc_type;
|
Type xc_type;
|
||||||
|
|
||||||
bool operator()(const CTeamAiRole& a, const CTeamAiRole& b) const {
|
bool operator()(const CTeamAiRole& a, const CTeamAiRole& b) const {
|
||||||
float aDist = (x0_pos - a.GetTeamPosition()).magSquared();
|
const float aDist = (x0_pos - a.GetTeamPosition()).magSquared();
|
||||||
float bDist = (x0_pos - b.GetTeamPosition()).magSquared();
|
const float bDist = (x0_pos - b.GetTeamPosition()).magSquared();
|
||||||
switch (xc_type) {
|
switch (xc_type) {
|
||||||
case 0:
|
case Type::OwnerID:
|
||||||
return a.GetOwnerId() < b.GetOwnerId();
|
return a.GetOwnerId() < b.GetOwnerId();
|
||||||
case 1:
|
case Type::Distance:
|
||||||
return aDist < bDist;
|
return aDist < bDist;
|
||||||
default:
|
default:
|
||||||
if (a.GetTeamAiRole() == b.GetTeamAiRole())
|
if (a.GetTeamAiRole() == b.GetTeamAiRole())
|
||||||
|
@ -27,7 +34,7 @@ struct TeamAiRoleSorter {
|
||||||
return a.GetTeamAiRole() < b.GetTeamAiRole();
|
return a.GetTeamAiRole() < b.GetTeamAiRole();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TeamAiRoleSorter(const zeus::CVector3f& pos, s32 type) : x0_pos(pos), xc_type(type) {}
|
TeamAiRoleSorter(const zeus::CVector3f& pos, Type type) : x0_pos(pos), xc_type(type) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
CTeamAiData::CTeamAiData(CInputStream& in, s32 propCount)
|
CTeamAiData::CTeamAiData(CInputStream& in, s32 propCount)
|
||||||
|
@ -65,20 +72,19 @@ void CTeamAiMgr::UpdateTeamCaptain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTeamAiMgr::ShouldUpdateRoles(float dt) {
|
bool CTeamAiMgr::ShouldUpdateRoles(float dt) {
|
||||||
if (x58_roles.empty())
|
if (x58_roles.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
x88_timeDirty += dt;
|
|
||||||
if (x88_timeDirty >= 1.5f)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (const auto& role : x58_roles) {
|
|
||||||
if (role.GetTeamAiRole() <= CTeamAiRole::ETeamAiRole::Initial ||
|
|
||||||
role.GetTeamAiRole() > CTeamAiRole::ETeamAiRole::Unassigned)
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
x88_timeDirty += dt;
|
||||||
|
if (x88_timeDirty >= 1.5f) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::any_of(x58_roles.cbegin(), x58_roles.cend(), [](const auto& role) {
|
||||||
|
return role.GetTeamAiRole() <= CTeamAiRole::ETeamAiRole::Initial ||
|
||||||
|
role.GetTeamAiRole() > CTeamAiRole::ETeamAiRole::Unassigned;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTeamAiMgr::ResetRoles(CStateManager& mgr) {
|
void CTeamAiMgr::ResetRoles(CStateManager& mgr) {
|
||||||
|
@ -91,27 +97,29 @@ void CTeamAiMgr::ResetRoles(CStateManager& mgr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTeamAiMgr::SpacingSort(CStateManager& mgr, const zeus::CVector3f& pos) {
|
void CTeamAiMgr::SpacingSort(CStateManager& mgr, const zeus::CVector3f& pos) {
|
||||||
TeamAiRoleSorter sorter(pos, 2);
|
const TeamAiRoleSorter sorter(pos, TeamAiRoleSorter::Type::TeamAIRole);
|
||||||
std::sort(x58_roles.begin(), x58_roles.end(), sorter);
|
std::sort(x58_roles.begin(), x58_roles.end(), sorter);
|
||||||
float tierStagger = 4.5f;
|
float tierStagger = 4.5f;
|
||||||
for (const auto& role : x58_roles) {
|
for (const auto& role : x58_roles) {
|
||||||
if (TCastToPtr<CAi> ai = mgr.ObjectById(role.GetOwnerId())) {
|
if (const TCastToConstPtr<CAi> ai = mgr.ObjectById(role.GetOwnerId())) {
|
||||||
float length = (ai->GetBaseBoundingBox().max.y() - ai->GetBaseBoundingBox().min.y()) * 1.5f;
|
const float length = (ai->GetBaseBoundingBox().max.y() - ai->GetBaseBoundingBox().min.y()) * 1.5f;
|
||||||
if (length > tierStagger)
|
if (length > tierStagger) {
|
||||||
tierStagger = length;
|
tierStagger = length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float curTierDist = tierStagger;
|
float curTierDist = tierStagger;
|
||||||
int tierTeamSize = 0;
|
int tierTeamSize = 0;
|
||||||
int maxTierTeamSize = 3;
|
int maxTierTeamSize = 3;
|
||||||
for (auto& role : x58_roles) {
|
for (auto& role : x58_roles) {
|
||||||
if (TCastToPtr<CAi> ai = mgr.ObjectById(role.GetOwnerId())) {
|
if (const TCastToConstPtr<CAi> ai = mgr.ObjectById(role.GetOwnerId())) {
|
||||||
zeus::CVector3f delta = ai->GetTranslation() - pos;
|
zeus::CVector3f delta = ai->GetTranslation() - pos;
|
||||||
zeus::CVector3f newPos;
|
zeus::CVector3f newPos;
|
||||||
if (delta.canBeNormalized())
|
if (delta.canBeNormalized()) {
|
||||||
newPos = pos + delta.normalized() * curTierDist;
|
newPos = pos + delta.normalized() * curTierDist;
|
||||||
else
|
} else {
|
||||||
newPos = pos + ai->GetTransform().basis[1] * curTierDist;
|
newPos = pos + ai->GetTransform().basis[1] * curTierDist;
|
||||||
|
}
|
||||||
role.x1c_position = newPos;
|
role.x1c_position = newPos;
|
||||||
role.x1c_position.z() = ai->GetTranslation().z();
|
role.x1c_position.z() = ai->GetTranslation().z();
|
||||||
tierTeamSize += 1;
|
tierTeamSize += 1;
|
||||||
|
@ -122,7 +130,7 @@ void CTeamAiMgr::SpacingSort(CStateManager& mgr, const zeus::CVector3f& pos) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TeamAiRoleSorter sorter2(pos, 0);
|
const TeamAiRoleSorter sorter2(pos, TeamAiRoleSorter::Type::OwnerID);
|
||||||
std::sort(x58_roles.begin(), x58_roles.end(), sorter2);
|
std::sort(x58_roles.begin(), x58_roles.end(), sorter2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,24 +141,29 @@ void CTeamAiMgr::PositionTeam(CStateManager& mgr) {
|
||||||
SpacingSort(mgr, aimPos);
|
SpacingSort(mgr, aimPos);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (auto& role : x58_roles)
|
for (auto& role : x58_roles) {
|
||||||
if (TCastToPtr<CAi> ai = mgr.ObjectById(role.GetOwnerId()))
|
if (const TCastToConstPtr<CAi> ai = mgr.ObjectById(role.GetOwnerId())) {
|
||||||
role.x1c_position = ai->GetOrigin(mgr, role, aimPos);
|
role.x1c_position = ai->GetOrigin(mgr, role, aimPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTeamAiMgr::AssignRoles(CTeamAiRole::ETeamAiRole assRole, s32 count) {
|
void CTeamAiMgr::AssignRoles(CTeamAiRole::ETeamAiRole assRole, s32 count) {
|
||||||
if (count == 0)
|
if (count == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
s32 lastIdx = 0;
|
s32 lastIdx = 0;
|
||||||
for (auto& role : x58_roles) {
|
for (auto& role : x58_roles) {
|
||||||
if (role.GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Initial) {
|
if (role.GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Initial) {
|
||||||
if (role.x4_roleA == assRole || role.x8_roleB == assRole || role.xc_roleC == assRole) {
|
if (role.x4_roleA == assRole || role.x8_roleB == assRole || role.xc_roleC == assRole) {
|
||||||
role.x10_curRole = assRole;
|
role.x10_curRole = assRole;
|
||||||
role.x14_roleIndex = lastIdx++;
|
role.x14_roleIndex = lastIdx++;
|
||||||
if (lastIdx == count)
|
if (lastIdx == count) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,26 +171,34 @@ void CTeamAiMgr::AssignRoles(CTeamAiRole::ETeamAiRole assRole, s32 count) {
|
||||||
|
|
||||||
void CTeamAiMgr::UpdateRoles(CStateManager& mgr) {
|
void CTeamAiMgr::UpdateRoles(CStateManager& mgr) {
|
||||||
ResetRoles(mgr);
|
ResetRoles(mgr);
|
||||||
zeus::CVector3f aimPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
|
|
||||||
TeamAiRoleSorter sorter(aimPos, 1);
|
const zeus::CVector3f aimPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
|
||||||
|
const TeamAiRoleSorter sorter(aimPos, TeamAiRoleSorter::Type::Distance);
|
||||||
std::sort(x58_roles.begin(), x58_roles.end(), sorter);
|
std::sort(x58_roles.begin(), x58_roles.end(), sorter);
|
||||||
|
|
||||||
AssignRoles(CTeamAiRole::ETeamAiRole::Melee, x34_data.x4_meleeCount);
|
AssignRoles(CTeamAiRole::ETeamAiRole::Melee, x34_data.x4_meleeCount);
|
||||||
AssignRoles(CTeamAiRole::ETeamAiRole::Ranged, x34_data.x8_rangedCount);
|
AssignRoles(CTeamAiRole::ETeamAiRole::Ranged, x34_data.x8_rangedCount);
|
||||||
AssignRoles(CTeamAiRole::ETeamAiRole::Unknown, x34_data.xc_unknownCount);
|
AssignRoles(CTeamAiRole::ETeamAiRole::Unknown, x34_data.xc_unknownCount);
|
||||||
|
|
||||||
for (auto& role : x58_roles) {
|
for (auto& role : x58_roles) {
|
||||||
if (role.GetTeamAiRole() <= CTeamAiRole::ETeamAiRole::Initial ||
|
if (role.GetTeamAiRole() <= CTeamAiRole::ETeamAiRole::Initial ||
|
||||||
role.GetTeamAiRole() > CTeamAiRole::ETeamAiRole::Unassigned)
|
role.GetTeamAiRole() > CTeamAiRole::ETeamAiRole::Unassigned) {
|
||||||
role.SetTeamAiRole(CTeamAiRole::ETeamAiRole::Unassigned);
|
role.SetTeamAiRole(CTeamAiRole::ETeamAiRole::Unassigned);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TeamAiRoleSorter sorter2(aimPos, 0);
|
|
||||||
|
const TeamAiRoleSorter sorter2(aimPos, TeamAiRoleSorter::Type::OwnerID);
|
||||||
std::sort(x58_roles.begin(), x58_roles.end(), sorter2);
|
std::sort(x58_roles.begin(), x58_roles.end(), sorter2);
|
||||||
x88_timeDirty = 0.f;
|
x88_timeDirty = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTeamAiMgr::Think(float dt, CStateManager& mgr) {
|
void CTeamAiMgr::Think(float dt, CStateManager& mgr) {
|
||||||
CEntity::Think(dt, mgr);
|
CEntity::Think(dt, mgr);
|
||||||
if (ShouldUpdateRoles(dt))
|
|
||||||
|
if (ShouldUpdateRoles(dt)) {
|
||||||
UpdateRoles(mgr);
|
UpdateRoles(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
PositionTeam(mgr);
|
PositionTeam(mgr);
|
||||||
x90_timeSinceMelee += dt;
|
x90_timeSinceMelee += dt;
|
||||||
x94_timeSinceRanged += dt;
|
x94_timeSinceRanged += dt;
|
||||||
|
|
Loading…
Reference in New Issue