2018-10-07 03:42:33 +00:00
|
|
|
#pragma once
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-05-10 02:56:54 +00:00
|
|
|
#include "CEntity.hpp"
|
2018-11-26 02:15:44 +00:00
|
|
|
#include "zeus/CVector3f.hpp"
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
namespace urde {
|
2018-11-26 02:15:44 +00:00
|
|
|
class CStateManager;
|
|
|
|
class CAi;
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CTeamAiRole {
|
|
|
|
friend class CTeamAiMgr;
|
|
|
|
|
2018-11-26 02:15:44 +00:00
|
|
|
public:
|
2019-01-30 08:38:16 +00:00
|
|
|
enum class ETeamAiRole { Invalid = -1, Initial, Melee, Ranged, Unknown, Unassigned };
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2018-11-26 02:15:44 +00:00
|
|
|
private:
|
2018-12-08 05:30:43 +00:00
|
|
|
TUniqueId x0_ownerId;
|
|
|
|
ETeamAiRole x4_roleA = ETeamAiRole::Invalid;
|
|
|
|
ETeamAiRole x8_roleB = ETeamAiRole::Invalid;
|
|
|
|
ETeamAiRole xc_roleC = ETeamAiRole::Invalid;
|
|
|
|
ETeamAiRole x10_curRole = ETeamAiRole::Invalid;
|
|
|
|
s32 x14_roleIndex = -1;
|
|
|
|
s32 x18_captainPriority = 0;
|
|
|
|
zeus::CVector3f x1c_position;
|
|
|
|
|
2018-11-26 02:15:44 +00:00
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
CTeamAiRole(TUniqueId ownerId, ETeamAiRole a, ETeamAiRole b, ETeamAiRole c)
|
|
|
|
: x0_ownerId(ownerId), x4_roleA(a), x8_roleB(b), xc_roleC(c) {}
|
|
|
|
TUniqueId GetOwnerId() const { return x0_ownerId; }
|
|
|
|
bool HasTeamAiRole() const { return false; }
|
|
|
|
ETeamAiRole GetTeamAiRole() const { return x10_curRole; }
|
|
|
|
void SetTeamAiRole(ETeamAiRole role) { x10_curRole = role; }
|
|
|
|
s32 GetRoleIndex() const { return x14_roleIndex; }
|
|
|
|
void SetRoleIndex(s32 idx) { x14_roleIndex = idx; }
|
|
|
|
const zeus::CVector3f& GetTeamPosition() const { return x1c_position; }
|
|
|
|
void SetTeamPosition(const zeus::CVector3f& pos) { x1c_position = pos; }
|
|
|
|
bool operator<(const CTeamAiRole& other) const { return x0_ownerId < other.x0_ownerId; }
|
2018-11-26 02:15:44 +00:00
|
|
|
};
|
2018-05-10 02:56:54 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CTeamAiData {
|
|
|
|
friend class CTeamAiMgr;
|
|
|
|
u32 x0_aiCount;
|
|
|
|
u32 x4_meleeCount;
|
2019-01-30 08:38:16 +00:00
|
|
|
u32 x8_rangedCount;
|
2018-12-08 05:30:43 +00:00
|
|
|
u32 xc_unknownCount;
|
|
|
|
u32 x10_maxMeleeAttackerCount;
|
2019-01-30 08:38:16 +00:00
|
|
|
u32 x14_maxRangedAttackerCount;
|
2018-12-08 05:30:43 +00:00
|
|
|
u32 x18_positionMode;
|
|
|
|
float x1c_meleeTimeInterval;
|
2019-01-30 08:38:16 +00:00
|
|
|
float x20_rangedTimeInterval;
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2018-05-10 02:56:54 +00:00
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
CTeamAiData(CInputStream& in, s32 propCount);
|
2018-05-10 02:56:54 +00:00
|
|
|
};
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CTeamAiMgr : public CEntity {
|
2018-05-10 02:56:54 +00:00
|
|
|
public:
|
2019-01-30 08:38:16 +00:00
|
|
|
enum class EAttackType { Melee, Ranged };
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2018-11-26 02:15:44 +00:00
|
|
|
private:
|
2018-12-08 05:30:43 +00:00
|
|
|
CTeamAiData x34_data;
|
|
|
|
std::vector<CTeamAiRole> x58_roles;
|
|
|
|
std::vector<TUniqueId> x68_meleeAttackers;
|
2019-01-30 08:38:16 +00:00
|
|
|
std::vector<TUniqueId> x78_rangedAttackers;
|
2018-12-08 05:30:43 +00:00
|
|
|
float x88_timeDirty = 0.f;
|
|
|
|
TUniqueId x8c_teamCaptainId = kInvalidUniqueId;
|
|
|
|
float x90_timeSinceMelee;
|
2019-01-30 08:38:16 +00:00
|
|
|
float x94_timeSinceRanged;
|
2018-11-26 02:15:44 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void UpdateTeamCaptain();
|
|
|
|
bool ShouldUpdateRoles(float dt);
|
|
|
|
void ResetRoles(CStateManager& mgr);
|
|
|
|
void AssignRoles(CTeamAiRole::ETeamAiRole role, s32 count);
|
|
|
|
void UpdateRoles(CStateManager& mgr);
|
|
|
|
void SpacingSort(CStateManager& mgr, const zeus::CVector3f& pos);
|
|
|
|
void PositionTeam(CStateManager& mgr);
|
2018-11-26 02:15:44 +00:00
|
|
|
|
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
CTeamAiMgr(TUniqueId uid, std::string_view name, const CEntityInfo& info, const CTeamAiData& data);
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void Accept(IVisitor&);
|
|
|
|
void Think(float dt, CStateManager& mgr);
|
|
|
|
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& mgr);
|
|
|
|
CTeamAiRole* GetTeamAiRole(TUniqueId aiId);
|
|
|
|
bool IsPartOfTeam(TUniqueId aiId) const;
|
|
|
|
bool HasTeamAiRole(TUniqueId aiId) const;
|
|
|
|
bool AssignTeamAiRole(const CAi& ai, CTeamAiRole::ETeamAiRole roleA, CTeamAiRole::ETeamAiRole roleB,
|
|
|
|
CTeamAiRole::ETeamAiRole roleC);
|
|
|
|
void RemoveTeamAiRole(TUniqueId aiId);
|
|
|
|
void ClearTeamAiRole(TUniqueId aiId);
|
|
|
|
s32 GetNumAssignedOfRole(CTeamAiRole::ETeamAiRole role) const;
|
|
|
|
s32 GetNumAssignedAiRoles() const;
|
2018-11-26 02:15:44 +00:00
|
|
|
|
2018-12-31 05:01:42 +00:00
|
|
|
bool IsMeleeAttacker(TUniqueId aiId) const;
|
|
|
|
bool CanAcceptMeleeAttacker(TUniqueId aiId) const;
|
|
|
|
bool AddMeleeAttacker(TUniqueId aiId);
|
|
|
|
void RemoveMeleeAttacker(TUniqueId aiId);
|
2019-01-30 08:38:16 +00:00
|
|
|
bool IsRangedAttacker(TUniqueId aiId) const;
|
|
|
|
bool CanAcceptRangedAttacker(TUniqueId aiId) const;
|
|
|
|
bool AddRangedAttacker(TUniqueId aiId);
|
|
|
|
void RemoveRangedAttacker(TUniqueId aiId);
|
2018-12-31 05:01:42 +00:00
|
|
|
|
2019-01-16 04:22:44 +00:00
|
|
|
bool HasMeleeAttackers() const { return !x68_meleeAttackers.empty(); }
|
2019-01-30 08:38:16 +00:00
|
|
|
bool HasRangedAttackers() const { return !x78_rangedAttackers.empty(); }
|
2019-01-16 04:22:44 +00:00
|
|
|
s32 GetNumRoles() const { return x58_roles.size(); }
|
|
|
|
const std::vector<CTeamAiRole>& GetRoles() const { return x58_roles; }
|
|
|
|
s32 GetMaxMeleeAttackerCount() const { return x34_data.x10_maxMeleeAttackerCount; }
|
2019-01-30 08:38:16 +00:00
|
|
|
s32 GetMaxRangedAttackerCount() const { return x34_data.x14_maxRangedAttackerCount; }
|
2019-01-16 04:22:44 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
static CTeamAiRole* GetTeamAiRole(CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId);
|
|
|
|
static void ResetTeamAiRole(EAttackType type, CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId, bool clearRole);
|
|
|
|
static bool CanAcceptAttacker(EAttackType type, CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId);
|
|
|
|
static bool AddAttacker(EAttackType type, CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId);
|
2018-12-08 01:49:15 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
static TUniqueId GetTeamAiMgr(CAi& ai, CStateManager& mgr);
|
2017-09-12 15:27:48 +00:00
|
|
|
};
|
2018-12-08 05:30:43 +00:00
|
|
|
} // namespace urde
|