mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Fix AIN building bugs
Fixed writing of: - Path nodes - Node links - Path clusters - Cluster links The previous globals 'g_pppAiNodeClusters' and 'g_pppAiNodeClusterLinks' were of type CUtlVector. These have been retyped and renamed accordingly. Also mapped the CAI_Cluster class out slightly more. Rebuild of path clusters and cluster links are still not correct; parsing a file in from r2, results in a different file on the disk, at the very offset the clusters are being written in (one field is off, this will be investigated soon).
This commit is contained in:
parent
c21747c4c6
commit
52bc73abb0
@ -123,6 +123,28 @@ CAI_Node** CAI_Network::GetPathNodes(void) const
|
||||
return m_pAInode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds a path node
|
||||
// Input : *origin -
|
||||
// jaw -
|
||||
// Output : CAI_Node*
|
||||
//-----------------------------------------------------------------------------
|
||||
CAI_Node* CAI_Network::AddPathNode(const Vector3D* origin, const float jaw)
|
||||
{
|
||||
return v_CAI_Network__AddPathNode(this, origin, jaw);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: creates a node link
|
||||
// Input : srcID -
|
||||
// destID -
|
||||
// Output : CAI_NodeLink*
|
||||
//-----------------------------------------------------------------------------
|
||||
CAI_NodeLink* CAI_Network::CreateNodeLink(int srcID, int destID)
|
||||
{
|
||||
return v_CAI_Network__CreateNodeLink(this, srcID, destID);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void VAI_Network::Attach() const
|
||||
{
|
||||
|
@ -19,8 +19,12 @@ public:
|
||||
|
||||
short GetHint(int nIndex) const;
|
||||
CAI_ScriptNode* GetScriptNodes(void) const;
|
||||
|
||||
CAI_Node* AddPathNode(const Vector3D* origin, const float jaw);
|
||||
CAI_Node** GetPathNodes(void) const;
|
||||
|
||||
CAI_NodeLink* CreateNodeLink(int srcID, int destID);
|
||||
|
||||
public:
|
||||
void* m_pVTable; // <-- 'this'.
|
||||
|
||||
@ -45,6 +49,12 @@ public:
|
||||
};
|
||||
inline CAI_Network** g_pAINetwork = nullptr;
|
||||
|
||||
inline CMemory p_CAI_Network__AddPathNode;
|
||||
inline CAI_Node*(*v_CAI_Network__AddPathNode)(CAI_Network* pNetwork, const Vector3D* origin, float yaw);
|
||||
|
||||
inline CMemory p_CAI_Network__CreateNodeLink;
|
||||
inline CAI_NodeLink* (*v_CAI_Network__CreateNodeLink)(CAI_Network* pNetwork, int srcID, int destID);
|
||||
|
||||
inline CMemory p_CAI_Network__DebugConnectMsg;
|
||||
inline void(*v_CAI_Network__DebugConnectMsg)(int node1, int node2, const char* pszformat, ...);
|
||||
|
||||
@ -53,13 +63,21 @@ class VAI_Network : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const
|
||||
{
|
||||
LogFunAdr("CAI_Network::AddPathNode", p_CAI_Network__AddPathNode.GetPtr());
|
||||
LogFunAdr("CAI_Network::CreateNodeLink", p_CAI_Network__CreateNodeLink.GetPtr());
|
||||
LogFunAdr("CAI_Network::DebugConnectMsg", p_CAI_Network__DebugConnectMsg.GetPtr());
|
||||
LogVarAdr("g_pAINetwork", reinterpret_cast<uintptr_t>(g_pAINetwork));
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
p_CAI_Network__AddPathNode = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 48 8B B9 ?? ?? ?? ?? 48 8B F2 0F 29 74 24 ??");
|
||||
v_CAI_Network__AddPathNode = p_CAI_Network__AddPathNode.RCast<CAI_Node*(*)(CAI_Network*, const Vector3D*, float)>();
|
||||
|
||||
p_CAI_Network__CreateNodeLink = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 57 41 56 48 83 EC 20 49 63 E8");
|
||||
v_CAI_Network__CreateNodeLink = p_CAI_Network__CreateNodeLink.RCast<CAI_NodeLink* (*)(CAI_Network*, int, int)>();
|
||||
|
||||
p_CAI_Network__DebugConnectMsg = g_GameDll.FindPatternSIMD("4C 89 4C 24 ?? 48 83 EC 18");
|
||||
v_CAI_Network__DebugConnectMsg = p_CAI_Network__DebugConnectMsg.RCast<void (*)(int, int, const char*, ...)>(); /*4C 89 4C 24 ?? 48 83 EC 18*/
|
||||
v_CAI_Network__DebugConnectMsg = p_CAI_Network__DebugConnectMsg.RCast<void (*)(int, int, const char*, ...)>();
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "game/server/ai_node.h"
|
||||
#include "game/server/ai_network.h"
|
||||
#include "game/server/ai_networkmanager.h"
|
||||
#include <public/worldsize.h>
|
||||
|
||||
constexpr int AINET_SCRIPT_VERSION_NUMBER = 21;
|
||||
constexpr int AINET_VERSION_NUMBER = 57;
|
||||
@ -32,6 +33,47 @@ CAI_NetworkBuilder::BuildFile
|
||||
*/
|
||||
void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
{
|
||||
//int test = 0;
|
||||
|
||||
//while (pNetwork->m_iNumNodes < 8000)
|
||||
//{
|
||||
// Vector3D origin;
|
||||
|
||||
// origin.Init(
|
||||
// RandomFloat(0.0f, MAX_COORD_FLOAT),
|
||||
// RandomFloat(0.0f, MAX_COORD_FLOAT),
|
||||
// RandomFloat(0.0f, MAX_COORD_FLOAT));
|
||||
|
||||
// /*CAI_Node* pNode = */pNetwork->AddPathNode(&origin, RandomFloat(-180, 180));
|
||||
|
||||
// if (test > 0)
|
||||
// pNetwork->CreateNodeLink(test-1, test);
|
||||
|
||||
// CAI_NodeCluster* cluster = new CAI_NodeCluster();
|
||||
// memset(cluster, '\0', sizeof(CAI_NodeCluster));
|
||||
|
||||
// origin.Init(
|
||||
// RandomFloat(0.0f, MAX_COORD_FLOAT),
|
||||
// RandomFloat(0.0f, MAX_COORD_FLOAT),
|
||||
// RandomFloat(0.0f, MAX_COORD_FLOAT));
|
||||
|
||||
// cluster->m_nIndex = test;
|
||||
// cluster->m_vOrigin = origin;
|
||||
|
||||
// g_pAINodeClusters->AddToTail(cluster);
|
||||
|
||||
// CAI_NodeClusterLink* clusterLink = new CAI_NodeClusterLink();
|
||||
// memset(clusterLink, '\0', sizeof(CAI_NodeClusterLink));
|
||||
|
||||
// clusterLink->prevIndex_MAYBE = (short)test;
|
||||
// clusterLink->nextIndex_MAYBE = (short)test + 1;
|
||||
|
||||
// clusterLink->flags = 4;
|
||||
|
||||
// g_pAINodeClusterLinks->AddToTail(clusterLink);
|
||||
// ++test;
|
||||
//}
|
||||
|
||||
char szMeshPath[MAX_PATH];
|
||||
char szGraphPath[MAX_PATH];
|
||||
|
||||
@ -65,7 +107,7 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
FileSystem()->Write(&g_ServerGlobalVariables->m_nMapVersion, sizeof(int), pAIGraph);
|
||||
|
||||
FileHandle_t pNavMesh = FileSystem()->Open(szMeshPath, "rb", "GAME");
|
||||
uint32_t nNavMeshHash = NULL;
|
||||
uint32_t nNavMeshCRC = NULL;
|
||||
|
||||
if (!pNavMesh)
|
||||
{
|
||||
@ -80,12 +122,12 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
FileSystem()->Read(pBuf.get(), nLen, pNavMesh);
|
||||
FileSystem()->Close(pNavMesh);
|
||||
|
||||
nNavMeshHash = crc32::update(NULL, pBuf.get(), nLen);
|
||||
nNavMeshCRC = crc32::update(NULL, pBuf.get(), nLen);
|
||||
}
|
||||
|
||||
// Large NavMesh CRC.
|
||||
DevMsg(eDLL_T::SERVER, " |-- NavMesh CRC: '0x%lX'\n", nNavMeshHash);
|
||||
FileSystem()->Write(&nNavMeshHash, sizeof(uint32_t), pAIGraph);
|
||||
DevMsg(eDLL_T::SERVER, " |-- NavMesh CRC: '0x%lX'\n", nNavMeshCRC);
|
||||
FileSystem()->Write(&nNavMeshCRC, sizeof(uint32_t), pAIGraph);
|
||||
|
||||
// Path nodes.
|
||||
DevMsg(eDLL_T::SERVER, " |-- Node count: '%d'\n", pNetwork->m_iNumNodes);
|
||||
@ -177,7 +219,7 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
diskLink.m_bHulls[k] = nodeLink->m_bHulls[k];
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::SERVER, " |-- Writing link '%h' => '%h' to '0x%zX'\n", diskLink.m_iSrcID, diskLink.m_iDestID, FileSystem()->Tell(pAIGraph));
|
||||
DevMsg(eDLL_T::SERVER, " |-- Writing link '%hd' => '%hd' to '0x%zX'\n", diskLink.m_iSrcID, diskLink.m_iDestID, FileSystem()->Tell(pAIGraph));
|
||||
FileSystem()->Write(&diskLink, sizeof(CAI_NodeLinkDisk), pAIGraph);
|
||||
}
|
||||
}
|
||||
@ -194,7 +236,7 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
if (pNetwork->m_iNumNodes > 0)
|
||||
{
|
||||
std::unique_ptr<uint32[]> unkNodeBlock(new uint32_t[pNetwork->m_iNumNodes * sizeof(uint32_t)]);
|
||||
memset(&unkNodeBlock, '\0', pNetwork->m_iNumNodes * sizeof(uint32_t));
|
||||
memset(unkNodeBlock.get(), '\0', pNetwork->m_iNumNodes * sizeof(uint32_t));
|
||||
|
||||
FileSystem()->Write(unkNodeBlock.get(), pNetwork->m_iNumNodes * sizeof(uint32_t), pAIGraph);
|
||||
}
|
||||
@ -202,6 +244,7 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
// TODO: This is traverse nodes i think? these aren't used in r2 ains so we can get away with just writing count=0 and skipping
|
||||
// but ideally should actually dump these.
|
||||
DevMsg(eDLL_T::SERVER, " |-- Writing '%d' traversal nodes at '0x%zX'\n", 0, FileSystem()->Tell(pAIGraph));
|
||||
|
||||
short traverseNodeCount = 0; // Only write count since count=0 means we don't have to actually do anything here.
|
||||
FileSystem()->Write(&traverseNodeCount, sizeof(short), pAIGraph);
|
||||
|
||||
@ -218,52 +261,63 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
|
||||
timer.Start();
|
||||
DevMsg(eDLL_T::SERVER, "+- Writing clusters...\n");
|
||||
|
||||
FileSystem()->Write(&*g_nAiNodeClusters, sizeof(*g_nAiNodeClusters), pAIGraph);
|
||||
for (int i = 0; i < *g_nAiNodeClusters; i++)
|
||||
const int numClusters = g_pAIPathClusters->Count();
|
||||
FileSystem()->Write(&numClusters, sizeof(int), pAIGraph);
|
||||
|
||||
FOR_EACH_VEC(*g_pAIPathClusters, i)
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, " |-- Writing cluster '#%d' at '0x%zX'\n", i, FileSystem()->Tell(pAIGraph));
|
||||
AINodeClusters* nodeClusters = (*g_pppAiNodeClusters)[i];
|
||||
|
||||
FileSystem()->Write(&nodeClusters->m_nIndex, sizeof(nodeClusters->m_nIndex), pAIGraph);
|
||||
FileSystem()->Write(&nodeClusters->unk1, sizeof(nodeClusters->unk1), pAIGraph);
|
||||
const CAI_Cluster* pathClusters = (*g_pAIPathClusters)[i];
|
||||
|
||||
FileSystem()->Write(&nodeClusters->m_vOrigin.x, sizeof(nodeClusters->m_vOrigin.x), pAIGraph);
|
||||
FileSystem()->Write(&nodeClusters->m_vOrigin.y, sizeof(nodeClusters->m_vOrigin.y), pAIGraph);
|
||||
FileSystem()->Write(&nodeClusters->m_vOrigin.z, sizeof(nodeClusters->m_vOrigin.z), pAIGraph);
|
||||
FileSystem()->Write(&pathClusters->m_nIndex, sizeof(int), pAIGraph);
|
||||
FileSystem()->Write(&pathClusters->unk1, sizeof(char), pAIGraph);
|
||||
|
||||
FileSystem()->Write(&nodeClusters->unkcount0, sizeof(nodeClusters->unkcount0), pAIGraph);
|
||||
for (int j = 0; j < nodeClusters->unkcount0; j++)
|
||||
FileSystem()->Write(&pathClusters->m_vOrigin.x, sizeof(vec_t), pAIGraph);
|
||||
FileSystem()->Write(&pathClusters->m_vOrigin.y, sizeof(vec_t), pAIGraph);
|
||||
FileSystem()->Write(&pathClusters->m_vOrigin.z, sizeof(vec_t), pAIGraph);
|
||||
|
||||
const int unkVec0Size = pathClusters->unkVec0.Count();
|
||||
FileSystem()->Write(&unkVec0Size, sizeof(int), pAIGraph);
|
||||
|
||||
FOR_EACH_VEC(pathClusters->unkVec0, j)
|
||||
{
|
||||
short unk2Short = static_cast<short>(nodeClusters->unk2[j]);
|
||||
FileSystem()->Write(&unk2Short, sizeof(unk2Short), pAIGraph);
|
||||
short unkShort = static_cast<short>(pathClusters->unkVec0[j]);
|
||||
FileSystem()->Write(&unkShort, sizeof(short), pAIGraph);
|
||||
}
|
||||
|
||||
FileSystem()->Write(&nodeClusters->unkcount1, sizeof(nodeClusters->unkcount1), pAIGraph);
|
||||
for (int j = 0; j < nodeClusters->unkcount1; j++)
|
||||
const int unkVec1Size = pathClusters->unkVec1.Count();
|
||||
FileSystem()->Write(&unkVec1Size, sizeof(int), pAIGraph);
|
||||
|
||||
FOR_EACH_VEC(pathClusters->unkVec1, j)
|
||||
{
|
||||
short unk3Short = static_cast<short>(nodeClusters->unk3[j]);
|
||||
FileSystem()->Write(&unk3Short, sizeof(unk3Short), pAIGraph);
|
||||
short unkShort = static_cast<short>(pathClusters->unkVec0[j]);
|
||||
FileSystem()->Write(&unkShort, sizeof(short), pAIGraph);
|
||||
}
|
||||
|
||||
FileSystem()->Write(&nodeClusters->unk5, sizeof(nodeClusters->unk5), pAIGraph);
|
||||
FileSystem()->Write(&pathClusters->unk5, sizeof(char), pAIGraph);
|
||||
}
|
||||
|
||||
timer.End();
|
||||
Msg(eDLL_T::SERVER, "...done writing clusters. %lf seconds (%d clusters)\n", timer.GetDuration().GetSeconds(), *g_nAiNodeClusters);
|
||||
Msg(eDLL_T::SERVER, "...done writing clusters. %lf seconds (%d clusters)\n", timer.GetDuration().GetSeconds(), numClusters);
|
||||
|
||||
timer.Start();
|
||||
DevMsg(eDLL_T::SERVER, "+- Writing cluster links...\n");
|
||||
|
||||
FileSystem()->Write(&*g_nAiNodeClusterLinks, sizeof(*g_nAiNodeClusterLinks), pAIGraph);
|
||||
for (int i = 0; i < *g_nAiNodeClusterLinks; i++)
|
||||
const int numClusterLinks = g_pAIClusterLinks->Count();
|
||||
FileSystem()->Write(&numClusterLinks, sizeof(int), pAIGraph);
|
||||
|
||||
FOR_EACH_VEC(*g_pAIClusterLinks, i)
|
||||
{
|
||||
// Disk and memory structs are literally identical here so just directly write.
|
||||
DevMsg(eDLL_T::SERVER, " |-- Writing cluster link '#%d' at '0x%zX'\n", i, FileSystem()->Tell(pAIGraph));
|
||||
FileSystem()->Write(&*g_pppAiNodeClusterLinks[i], sizeof(*(*g_pppAiNodeClusterLinks)[i]), pAIGraph);
|
||||
|
||||
// Disk and memory structs are literally identical here so just directly write.
|
||||
const CAI_ClusterLink* clusterLink = (*g_pAIClusterLinks)[i];
|
||||
FileSystem()->Write(clusterLink, sizeof(CAI_ClusterLink), pAIGraph);
|
||||
}
|
||||
|
||||
timer.End();
|
||||
Msg(eDLL_T::SERVER, "...done writing cluster links. %lf seconds (%d cluster links)\n", timer.GetDuration().GetSeconds(), *g_nAiNodeClusterLinks);
|
||||
Msg(eDLL_T::SERVER, "...done writing cluster links. %lf seconds (%d cluster links)\n", timer.GetDuration().GetSeconds(), numClusterLinks);
|
||||
|
||||
// This is always set to '-1'. Likely a field for maintaining compatibility.
|
||||
FileSystem()->Write(&pNetwork->unk5, sizeof(pNetwork->unk5), pAIGraph);
|
||||
|
@ -27,10 +27,8 @@ inline void*(*CAI_NetworkManager__LoadNetworkGraph)(void* thisptr, void* pBuffer
|
||||
inline CMemory p_CAI_NetworkBuilder__Build;
|
||||
inline void*(*CAI_NetworkBuilder__Build)(void* thisptr, CAI_Network* pNetwork, void* a3, int a4);
|
||||
|
||||
inline int * g_nAiNodeClusters = nullptr;
|
||||
inline AINodeClusters *** g_pppAiNodeClusters = nullptr;
|
||||
inline int * g_nAiNodeClusterLinks = nullptr;
|
||||
inline AINodeClusterLinks*** g_pppAiNodeClusterLinks = nullptr;
|
||||
inline CUtlVector<CAI_Cluster*>* g_pAIPathClusters = nullptr;
|
||||
inline CUtlVector<CAI_ClusterLink*>* g_pAIClusterLinks = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAI_NetworkBuilder
|
||||
@ -68,10 +66,8 @@ class VAI_NetworkManager : public IDetour
|
||||
LogFunAdr("CAI_NetworkManager::LoadNetworkGraph", p_CAI_NetworkManager__LoadNetworkGraph.GetPtr());
|
||||
LogFunAdr("CAI_NetworkManager::ShouldRebuild", p_CAI_NetworkManager__ShouldRebuild.GetPtr());
|
||||
LogFunAdr("CAI_NetworkBuilder::Build", p_CAI_NetworkBuilder__Build.GetPtr());
|
||||
LogVarAdr("g_nAiNodeClusters", reinterpret_cast<uintptr_t>(g_nAiNodeClusters));
|
||||
LogVarAdr("g_pAiNodeClusters", reinterpret_cast<uintptr_t>(g_pppAiNodeClusters));
|
||||
LogVarAdr("g_nAiNodeClusterLinks", reinterpret_cast<uintptr_t>(g_nAiNodeClusterLinks));
|
||||
LogVarAdr("g_pAiNodeClusterLinks", reinterpret_cast<uintptr_t>(g_pppAiNodeClusterLinks));
|
||||
LogVarAdr("g_AIPathClusters< CAI_Cluster* >", reinterpret_cast<uintptr_t>(g_pAIPathClusters));
|
||||
LogVarAdr("g_AIClusterLinks< CAI_ClusterLink* >", reinterpret_cast<uintptr_t>(g_pAIClusterLinks));
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
@ -93,14 +89,10 @@ class VAI_NetworkManager : public IDetour
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
g_nAiNodeClusters = g_GameDll.FindPatternSIMD("4C 0F BF 12")
|
||||
.FindPatternSelf("83 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x2, 0x7).RCast<int*>();
|
||||
g_pppAiNodeClusters = g_GameDll.FindPatternSIMD("F3 0F 10 52 ?? 4C 8B CA")
|
||||
.FindPatternSelf("48 8B 35", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<AINodeClusters***>();
|
||||
g_nAiNodeClusterLinks = g_GameDll.FindPatternSIMD("49 FF C0 48 83 C2 04 4D 3B C2 7C D4")
|
||||
.FindPatternSelf("8B 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
g_pppAiNodeClusterLinks = g_GameDll.FindPatternSIMD("F3 0F 10 52 ?? 4C 8B CA")
|
||||
.FindPatternSelf("4C 8B 1D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<AINodeClusterLinks***>();
|
||||
g_pAIPathClusters = g_GameDll.FindPatternSIMD("F3 0F 10 52 ?? 4C 8B CA")
|
||||
.FindPatternSelf("48 8B 35", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CUtlVector<CAI_Cluster*>*>();
|
||||
g_pAIClusterLinks = g_GameDll.FindPatternSIMD("F3 0F 10 52 ?? 4C 8B CA")
|
||||
.FindPatternSelf("4C 8B 1D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CUtlVector<CAI_ClusterLink*>*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
|
@ -94,37 +94,48 @@ struct CAI_ScriptNode
|
||||
Vector3D m_vOrigin;
|
||||
uint64_t scriptdata;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct AINodeClusters
|
||||
//=============================================================================
|
||||
// >> CAI_Cluster
|
||||
//=============================================================================
|
||||
struct CAI_Cluster
|
||||
{
|
||||
int m_nIndex;
|
||||
char unk0;
|
||||
char unk1; // Maps to unk1 on disk
|
||||
char pad0[2]; // Padding to +8
|
||||
char unk1; // Maps to unk1 on disk
|
||||
|
||||
Vector3D m_vOrigin;
|
||||
char unkC; // idk, might be a 4 bytes type or just padding.
|
||||
|
||||
char pad5[4];
|
||||
int* unk2; // Maps to unk5 on disk;
|
||||
char pad1[16]; // Pad to +48
|
||||
int unkcount0; // Maps to unkcount0 on disk
|
||||
// These are utlvectors in engine, but its
|
||||
// unknown what they do yet.
|
||||
CUtlVector<int> unkVec0;
|
||||
CUtlVector<int> unkVec1;
|
||||
|
||||
char pad2[4]; // Pad to +56
|
||||
int* unk3;
|
||||
char pad3[16]; // Pad to +80
|
||||
int unkcount1;
|
||||
// This is an array of floats that is indexed
|
||||
// into by teamNum at [r5apex_ds.exe + EC84DC];
|
||||
// Seems to be used along with the cvar:
|
||||
// 'ai_path_dangerous_cluster_min_time'.
|
||||
float clusterTime[MAX_TEAMS];
|
||||
|
||||
char pad4[132];
|
||||
float field_0250;
|
||||
float field_0254;
|
||||
float field_0258;
|
||||
char unk5;
|
||||
};
|
||||
static_assert(sizeof(CAI_Cluster) == 608);
|
||||
|
||||
struct AINodeClusterLinks
|
||||
//=============================================================================
|
||||
// >> CAI_ClusterLink
|
||||
//=============================================================================
|
||||
struct CAI_ClusterLink
|
||||
{
|
||||
short unk0;
|
||||
short unk1;
|
||||
short prevIndex_MAYBE;
|
||||
short nextIndex_MAYBE;
|
||||
int unk2;
|
||||
char unk3;
|
||||
char flags;
|
||||
char unk4;
|
||||
char unk5;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(CAI_ClusterLink) == 12);
|
Loading…
x
Reference in New Issue
Block a user