Pathfinding and generator fixes

This commit is contained in:
Jack Andersen 2019-01-29 22:38:16 -10:00
parent c9a38c567f
commit c3d8afa852
7 changed files with 69 additions and 71 deletions

View File

@ -486,7 +486,7 @@ bool CSpacePirate::ShouldFrenzy(CStateManager& mgr) {
}
void CSpacePirate::SquadReset(CStateManager& mgr) {
CTeamAiMgr::ResetTeamAiRole(!x634_27_melee ? CTeamAiMgr::EAttackType::Projectile : CTeamAiMgr::EAttackType::Melee,
CTeamAiMgr::ResetTeamAiRole(!x634_27_melee ? CTeamAiMgr::EAttackType::Ranged : CTeamAiMgr::EAttackType::Melee,
mgr, x8c8_teamAiMgrId, GetUniqueId(), true);
}
@ -496,7 +496,7 @@ void CSpacePirate::SquadAdd(CStateManager& mgr) {
if (x8c8_teamAiMgrId != kInvalidUniqueId) {
if (TCastToPtr<CTeamAiMgr> aimgr = mgr.ObjectById(x8c8_teamAiMgrId)) {
aimgr->AssignTeamAiRole(*this,
x634_27_melee ? CTeamAiRole::ETeamAiRole::Melee : CTeamAiRole::ETeamAiRole::Projectile,
x634_27_melee ? CTeamAiRole::ETeamAiRole::Melee : CTeamAiRole::ETeamAiRole::Ranged,
CTeamAiRole::ETeamAiRole::Unknown, CTeamAiRole::ETeamAiRole::Invalid);
}
}
@ -565,9 +565,9 @@ void CSpacePirate::UpdateAttacks(float dt, CStateManager& mgr) {
x7bc_attackRemTime -= dt;
if (x7bc_attackRemTime < 0.f) {
const CTeamAiRole* role = CTeamAiMgr::GetTeamAiRole(mgr, x8c8_teamAiMgrId, GetUniqueId());
if (!role || role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Projectile) {
if (!role || role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Ranged) {
if (x8c8_teamAiMgrId == kInvalidUniqueId ||
CTeamAiMgr::AddAttacker(CTeamAiMgr::EAttackType::Projectile, mgr, x8c8_teamAiMgrId, GetUniqueId())) {
CTeamAiMgr::AddAttacker(CTeamAiMgr::EAttackType::Ranged, mgr, x8c8_teamAiMgrId, GetUniqueId())) {
if (ShouldFrenzy(mgr))
x7c4_burstFire.SetBurstType(2);
if (x635_26_seated)

View File

@ -41,7 +41,7 @@ void CWarWasp::SwarmAdd(CStateManager& mgr) {
if (x674_aiMgr != kInvalidUniqueId) {
if (TCastToPtr<CTeamAiMgr> aimgr = mgr.ObjectById(x674_aiMgr)) {
CTeamAiRole::ETeamAiRole role = x3fc_flavor == EFlavorType::Two ?
CTeamAiRole::ETeamAiRole::Projectile : CTeamAiRole::ETeamAiRole::Melee;
CTeamAiRole::ETeamAiRole::Ranged : CTeamAiRole::ETeamAiRole::Melee;
if (!aimgr->IsPartOfTeam(GetUniqueId())) {
aimgr->AssignTeamAiRole(*this, role, CTeamAiRole::ETeamAiRole::Invalid, CTeamAiRole::ETeamAiRole::Invalid);
}
@ -343,7 +343,7 @@ void CWarWasp::ApplySeparationBehavior(CStateManager& mgr, float sep) {
float useSep = sep;
if (CTeamAiRole* role = CTeamAiMgr::GetTeamAiRole(mgr, x674_aiMgr, ai->GetUniqueId())) {
if (role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Melee ||
role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Projectile)
role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Ranged)
useSep *= 2.f;
}
zeus::CVector3f separation = x45c_steeringBehaviors.Separation(*this, ai->GetTranslation(), useSep);
@ -724,7 +724,7 @@ void CWarWasp::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) {
case EStateMsg::Activate:
x72e_28_inProjectileAttack = true;
if (x674_aiMgr != kInvalidUniqueId) {
x568_stateProg = CTeamAiMgr::AddAttacker(CTeamAiMgr::EAttackType::Projectile,
x568_stateProg = CTeamAiMgr::AddAttacker(CTeamAiMgr::EAttackType::Ranged,
mgr, x674_aiMgr, GetUniqueId()) ? 0 : 3;
} else {
x568_stateProg = 0;
@ -752,7 +752,7 @@ void CWarWasp::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) {
}
break;
case EStateMsg::Deactivate:
CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Projectile, mgr, x674_aiMgr, GetUniqueId(), false);
CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Ranged, mgr, x674_aiMgr, GetUniqueId(), false);
x700_attackRemTime = CalcTimeToNextAttack(mgr);
x72e_28_inProjectileAttack = false;
break;
@ -778,9 +778,9 @@ float CWarWasp::CalcTimeToNextAttack(CStateManager& mgr) {
float mul = 1.f;
if (TCastToConstPtr<CTeamAiMgr> aimgr = mgr.GetObjectById(x674_aiMgr)) {
s32 maxCount = (x3fc_flavor == EFlavorType::Two) ?
aimgr->GetMaxProjectileAttackerCount() : aimgr->GetMaxMeleeAttackerCount();
aimgr->GetMaxRangedAttackerCount() : aimgr->GetMaxMeleeAttackerCount();
s32 count = (x3fc_flavor == EFlavorType::Two) ?
aimgr->GetNumAssignedOfRole(CTeamAiRole::ETeamAiRole::Projectile) :
aimgr->GetNumAssignedOfRole(CTeamAiRole::ETeamAiRole::Ranged) :
aimgr->GetNumAssignedOfRole(CTeamAiRole::ETeamAiRole::Melee);
if (count <= maxCount)
mul *= 0.5f;
@ -1122,11 +1122,11 @@ bool CWarWasp::HearShot(CStateManager& mgr, float arg) {
bool CWarWasp::ShouldFire(CStateManager& mgr, float arg) {
if (x700_attackRemTime <= 0.f) {
if (CTeamAiRole* role = CTeamAiMgr::GetTeamAiRole(mgr, x674_aiMgr, GetUniqueId())) {
if (role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Projectile) {
if (role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Ranged) {
zeus::CVector3f delta = GetProjectileAimPos(mgr, -1.25f) - GetTranslation();
if (delta.canBeNormalized() && GetTransform().basis[1].dot(delta.normalized()) >= 0.906f) {
if (TCastToPtr<CTeamAiMgr> aimgr = mgr.ObjectById(x674_aiMgr)) {
return !aimgr->HasProjectileAttackers();
return !aimgr->HasRangedAttackers();
}
}
}

View File

@ -188,14 +188,14 @@ zeus::CVector3f CPFRegion::FitThroughLink2d(const zeus::CVector3f& p1, const CPF
zeus::CVector3f nodeDelta = nextNode.GetPos() - node.GetPos();
float t = 0.5f;
if (chRadius < 0.5f * link.Get2dWidth()) {
zeus::CVector2f delta2d(nodeDelta.x(), nodeDelta.y());
zeus::CVector2f delta2d = nodeDelta.toVec2f();
delta2d *= link.GetOO2dWidth();
zeus::CVector3f nodeToP1 = p1 - node.GetPos();
float f27 = nodeToP1.dot(node.GetNormal());
float f31 = delta2d.dot(zeus::CVector2f(nodeToP1.y(), nodeToP1.y()));
float f31 = delta2d.dot(nodeToP1.toVec2f());
zeus::CVector3f nodeToP2 = p2 - node.GetPos();
float f26 = -nodeToP2.dot(node.GetNormal());
float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y(), nodeToP2.y()));
float f1b = delta2d.dot(nodeToP2.toVec2f());
float f3 = f27 + f26;
if (f3 > FLT_EPSILON)
t = zeus::clamp(chRadius, 1.f / f3 * (f26 * f31 + f27 * f1b), link.Get2dWidth() - chRadius) * link.GetOO2dWidth();

View File

@ -688,17 +688,15 @@ bool CPatterned::OffLine(CStateManager&, float arg) {
void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
if (CPathFindSearch* search = GetSearchPath()) {
u32 curWp = search->GetCurrentWaypoint();
const auto& waypoints = search->GetWaypoints();
switch (msg) {
case EStateMsg::Activate: {
if (search->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) {
x2ec_reflectedDestPos = GetTranslation();
zeus::CVector3f destPos;
if (curWp + 1 < waypoints.size())
destPos = waypoints[curWp + 1];
if (search->GetCurrentWaypoint() + 1 < search->GetWaypoints().size())
destPos = search->GetWaypoints()[search->GetCurrentWaypoint() + 1];
else
destPos = waypoints[curWp];
destPos = search->GetWaypoints()[search->GetCurrentWaypoint()];
SetDestPos(destPos);
x328_24_inPosition = false;
ApproachDest(mgr);
@ -706,7 +704,7 @@ void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
break;
}
case EStateMsg::Update: {
if (curWp < waypoints.size() - 1) {
if (search->GetCurrentWaypoint() < search->GetWaypoints().size() - 1) {
if (x328_24_inPosition || x328_27_onGround)
x401_24_pathOverCount += 1;
zeus::CVector3f biasedPos = GetTranslation() + 0.3f * zeus::CVector3f::skUp;

View File

@ -53,9 +53,9 @@ void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sende
if (!stateMgr.GetObjectById(uid))
continue;
activates.emplace_back(uid, conn.x8_objId);
} else {
stateMgr.SendScriptMsgAlways(uid, GetUniqueId(), conn.x4_msg);
}
stateMgr.SendScriptMsgAlways(uid, GetUniqueId(), conn.x4_msg);
}
if (activates.empty())

View File

@ -29,13 +29,13 @@ struct TeamAiRoleSorter {
CTeamAiData::CTeamAiData(CInputStream& in, s32 propCount)
: x0_aiCount(in.readUint32Big())
, x4_meleeCount(in.readUint32Big())
, x8_projectileCount(in.readUint32Big())
, x8_rangedCount(in.readUint32Big())
, xc_unknownCount(in.readUint32Big())
, x10_maxMeleeAttackerCount(in.readUint32Big())
, x14_maxProjectileAttackerCount(in.readUint32Big())
, x14_maxRangedAttackerCount(in.readUint32Big())
, x18_positionMode(in.readUint32Big())
, x1c_meleeTimeInterval(propCount > 8 ? in.readFloatBig() : 0.f)
, x20_projectileTimeInterval(propCount > 8 ? in.readFloatBig() : 0.f) {}
, x20_rangedTimeInterval(propCount > 8 ? in.readFloatBig() : 0.f) {}
CTeamAiMgr::CTeamAiMgr(TUniqueId uid, std::string_view name, const CEntityInfo& info, const CTeamAiData& data)
: CEntity(uid, info, true, name), x34_data(data) {
@ -43,8 +43,8 @@ CTeamAiMgr::CTeamAiMgr(TUniqueId uid, std::string_view name, const CEntityInfo&
x58_roles.reserve(x34_data.x0_aiCount);
if (x34_data.x4_meleeCount)
x68_meleeAttackers.reserve(x34_data.x4_meleeCount);
if (x34_data.x8_projectileCount)
x78_projectileAttackers.reserve(x34_data.x8_projectileCount);
if (x34_data.x8_rangedCount)
x78_rangedAttackers.reserve(x34_data.x8_rangedCount);
}
void CTeamAiMgr::Accept(IVisitor& visitor) { visitor.Visit(this); }
@ -158,7 +158,7 @@ void CTeamAiMgr::UpdateRoles(CStateManager& mgr) {
TeamAiRoleSorter sorter(aimPos, 1);
std::sort(x58_roles.begin(), x58_roles.end(), sorter);
AssignRoles(CTeamAiRole::ETeamAiRole::Melee, x34_data.x4_meleeCount);
AssignRoles(CTeamAiRole::ETeamAiRole::Projectile, x34_data.x8_projectileCount);
AssignRoles(CTeamAiRole::ETeamAiRole::Ranged, x34_data.x8_rangedCount);
AssignRoles(CTeamAiRole::ETeamAiRole::Unknown, x34_data.xc_unknownCount);
for (auto& role : x58_roles) {
if (role.GetTeamAiRole() <= CTeamAiRole::ETeamAiRole::Initial ||
@ -176,7 +176,7 @@ void CTeamAiMgr::Think(float dt, CStateManager& mgr) {
UpdateRoles(mgr);
PositionTeam(mgr);
x90_timeSinceMelee += dt;
x94_timeSinceProjectile += dt;
x94_timeSinceRanged += dt;
}
void CTeamAiMgr::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& mgr) {
@ -233,36 +233,36 @@ void CTeamAiMgr::RemoveMeleeAttacker(TUniqueId aiId) {
x68_meleeAttackers.erase(search);
}
bool CTeamAiMgr::IsProjectileAttacker(TUniqueId aiId) const {
auto search = rstl::binary_find(x78_projectileAttackers.begin(), x78_projectileAttackers.end(), aiId);
return search != x78_projectileAttackers.end();
bool CTeamAiMgr::IsRangedAttacker(TUniqueId aiId) const {
auto search = rstl::binary_find(x78_rangedAttackers.begin(), x78_rangedAttackers.end(), aiId);
return search != x78_rangedAttackers.end();
}
bool CTeamAiMgr::CanAcceptProjectileAttacker(TUniqueId aiId) const {
if (x94_timeSinceProjectile >= x34_data.x20_projectileTimeInterval &&
x78_projectileAttackers.size() < x34_data.x14_maxProjectileAttackerCount)
bool CTeamAiMgr::CanAcceptRangedAttacker(TUniqueId aiId) const {
if (x94_timeSinceRanged >= x34_data.x20_rangedTimeInterval &&
x78_rangedAttackers.size() < x34_data.x14_maxRangedAttackerCount)
return true;
return IsProjectileAttacker(aiId);
return IsRangedAttacker(aiId);
}
bool CTeamAiMgr::AddProjectileAttacker(TUniqueId aiId) {
if (x94_timeSinceProjectile >= x34_data.x20_projectileTimeInterval &&
x78_projectileAttackers.size() < x34_data.x14_maxProjectileAttackerCount && HasTeamAiRole(aiId)) {
auto search = rstl::binary_find(x78_projectileAttackers.begin(), x78_projectileAttackers.end(), aiId);
if (search == x78_projectileAttackers.end()) {
x78_projectileAttackers.insert(
std::lower_bound(x78_projectileAttackers.begin(), x78_projectileAttackers.end(), aiId), aiId);
x94_timeSinceProjectile = 0.f;
bool CTeamAiMgr::AddRangedAttacker(TUniqueId aiId) {
if (x94_timeSinceRanged >= x34_data.x20_rangedTimeInterval &&
x78_rangedAttackers.size() < x34_data.x14_maxRangedAttackerCount && HasTeamAiRole(aiId)) {
auto search = rstl::binary_find(x78_rangedAttackers.begin(), x78_rangedAttackers.end(), aiId);
if (search == x78_rangedAttackers.end()) {
x78_rangedAttackers.insert(
std::lower_bound(x78_rangedAttackers.begin(), x78_rangedAttackers.end(), aiId), aiId);
x94_timeSinceRanged = 0.f;
}
return true;
}
return false;
}
void CTeamAiMgr::RemoveProjectileAttacker(TUniqueId aiId) {
auto search = rstl::binary_find(x78_projectileAttackers.begin(), x78_projectileAttackers.end(), aiId);
if (search != x78_projectileAttackers.end())
x78_projectileAttackers.erase(search);
void CTeamAiMgr::RemoveRangedAttacker(TUniqueId aiId) {
auto search = rstl::binary_find(x78_rangedAttackers.begin(), x78_rangedAttackers.end(), aiId);
if (search != x78_rangedAttackers.end())
x78_rangedAttackers.erase(search);
}
bool CTeamAiMgr::AssignTeamAiRole(const CAi& ai, CTeamAiRole::ETeamAiRole roleA, CTeamAiRole::ETeamAiRole roleB,
@ -283,8 +283,8 @@ bool CTeamAiMgr::AssignTeamAiRole(const CAi& ai, CTeamAiRole::ETeamAiRole roleA,
void CTeamAiMgr::RemoveTeamAiRole(TUniqueId aiId) {
if (IsMeleeAttacker(aiId))
RemoveMeleeAttacker(aiId);
if (IsProjectileAttacker(aiId))
RemoveProjectileAttacker(aiId);
if (IsRangedAttacker(aiId))
RemoveRangedAttacker(aiId);
auto search =
rstl::binary_find(x58_roles.begin(), x58_roles.end(), aiId, [](const auto& obj) { return obj.GetOwnerId(); });
x58_roles.erase(search);
@ -328,9 +328,9 @@ void CTeamAiMgr::ResetTeamAiRole(EAttackType type, CStateManager& mgr, TUniqueId
if (type == EAttackType::Melee) {
if (tmgr->IsMeleeAttacker(aiId))
tmgr->RemoveMeleeAttacker(aiId);
} else if (type == EAttackType::Projectile) {
if (tmgr->IsProjectileAttacker(aiId))
tmgr->RemoveProjectileAttacker(aiId);
} else if (type == EAttackType::Ranged) {
if (tmgr->IsRangedAttacker(aiId))
tmgr->RemoveRangedAttacker(aiId);
}
if (clearRole)
tmgr->ClearTeamAiRole(aiId);
@ -343,8 +343,8 @@ bool CTeamAiMgr::CanAcceptAttacker(EAttackType type, CStateManager& mgr, TUnique
if (tmgr->HasTeamAiRole(aiId)) {
if (type == EAttackType::Melee)
return tmgr->CanAcceptMeleeAttacker(aiId);
else if (type == EAttackType::Projectile)
return tmgr->CanAcceptProjectileAttacker(aiId);
else if (type == EAttackType::Ranged)
return tmgr->CanAcceptRangedAttacker(aiId);
}
}
return false;
@ -355,8 +355,8 @@ bool CTeamAiMgr::AddAttacker(EAttackType type, CStateManager& mgr, TUniqueId mgr
if (tmgr->HasTeamAiRole(aiId)) {
if (type == EAttackType::Melee)
return tmgr->AddMeleeAttacker(aiId);
else if (type == EAttackType::Projectile)
return tmgr->AddProjectileAttacker(aiId);
else if (type == EAttackType::Ranged)
return tmgr->AddRangedAttacker(aiId);
}
}
return false;

View File

@ -11,7 +11,7 @@ class CTeamAiRole {
friend class CTeamAiMgr;
public:
enum class ETeamAiRole { Invalid = -1, Initial, Melee, Projectile, Unknown, Unassigned };
enum class ETeamAiRole { Invalid = -1, Initial, Melee, Ranged, Unknown, Unassigned };
private:
TUniqueId x0_ownerId;
@ -41,13 +41,13 @@ class CTeamAiData {
friend class CTeamAiMgr;
u32 x0_aiCount;
u32 x4_meleeCount;
u32 x8_projectileCount;
u32 x8_rangedCount;
u32 xc_unknownCount;
u32 x10_maxMeleeAttackerCount;
u32 x14_maxProjectileAttackerCount;
u32 x14_maxRangedAttackerCount;
u32 x18_positionMode;
float x1c_meleeTimeInterval;
float x20_projectileTimeInterval;
float x20_rangedTimeInterval;
public:
CTeamAiData(CInputStream& in, s32 propCount);
@ -55,17 +55,17 @@ public:
class CTeamAiMgr : public CEntity {
public:
enum class EAttackType { Melee, Projectile };
enum class EAttackType { Melee, Ranged };
private:
CTeamAiData x34_data;
std::vector<CTeamAiRole> x58_roles;
std::vector<TUniqueId> x68_meleeAttackers;
std::vector<TUniqueId> x78_projectileAttackers;
std::vector<TUniqueId> x78_rangedAttackers;
float x88_timeDirty = 0.f;
TUniqueId x8c_teamCaptainId = kInvalidUniqueId;
float x90_timeSinceMelee;
float x94_timeSinceProjectile;
float x94_timeSinceRanged;
void UpdateTeamCaptain();
bool ShouldUpdateRoles(float dt);
@ -95,17 +95,17 @@ public:
bool CanAcceptMeleeAttacker(TUniqueId aiId) const;
bool AddMeleeAttacker(TUniqueId aiId);
void RemoveMeleeAttacker(TUniqueId aiId);
bool IsProjectileAttacker(TUniqueId aiId) const;
bool CanAcceptProjectileAttacker(TUniqueId aiId) const;
bool AddProjectileAttacker(TUniqueId aiId);
void RemoveProjectileAttacker(TUniqueId aiId);
bool IsRangedAttacker(TUniqueId aiId) const;
bool CanAcceptRangedAttacker(TUniqueId aiId) const;
bool AddRangedAttacker(TUniqueId aiId);
void RemoveRangedAttacker(TUniqueId aiId);
bool HasMeleeAttackers() const { return !x68_meleeAttackers.empty(); }
bool HasProjectileAttackers() const { return !x78_projectileAttackers.empty(); }
bool HasRangedAttackers() const { return !x78_rangedAttackers.empty(); }
s32 GetNumRoles() const { return x58_roles.size(); }
const std::vector<CTeamAiRole>& GetRoles() const { return x58_roles; }
s32 GetMaxMeleeAttackerCount() const { return x34_data.x10_maxMeleeAttackerCount; }
s32 GetMaxProjectileAttackerCount() const { return x34_data.x14_maxProjectileAttackerCount; }
s32 GetMaxRangedAttackerCount() const { return x34_data.x14_maxRangedAttackerCount; }
static CTeamAiRole* GetTeamAiRole(CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId);
static void ResetTeamAiRole(EAttackType type, CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId, bool clearRole);