mirror of
https://github.com/JezuzLizard/T4SP-Server-Plugin.git
synced 2025-04-20 13:35:43 +00:00
Merge
This commit is contained in:
commit
719a00dc94
522
src/component/ai.cpp
Normal file
522
src/component/ai.cpp
Normal file
@ -0,0 +1,522 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "scheduler.hpp"
|
||||
#include "component/gsc.hpp"
|
||||
|
||||
#include <json.hpp>
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
|
||||
namespace ai
|
||||
{
|
||||
namespace
|
||||
{
|
||||
/*
|
||||
int __cdecl Path_AStarAlgorithm_CustomSearchInfo_FindPath_(path_t *pPath, team_t eTeam, const float *vStartPos, pathnode_t *pNodeFrom, const float *vGoalPos, int bAllowNegotiationLinks, CustomSearchInfo_FindPath *searchInfo, int bIgnoreBadplaces, pathnode_t *nodeTo)
|
||||
{
|
||||
float *returnVGoaPosl; // edx
|
||||
int nodeLinkIndex; // ebx
|
||||
pathnode_t *returnStartNode; // ecx
|
||||
pathnode_t *returnEndNode; // edi
|
||||
pathlink_s *endNodeLinks; // eax
|
||||
int nodeNum; // esi
|
||||
float *endNodeLinkDist; // eax
|
||||
pathnode_t *pSuccessor; // esi
|
||||
float v17; // xmm0_4
|
||||
pathnode_t *v18; // eax
|
||||
pathnode_t *v19; // eax
|
||||
float v20; // xmm1_4
|
||||
long double v21; // st7
|
||||
float v22; // xmm3_4
|
||||
float v23; // xmm0_4
|
||||
float v24; // xmm1_4
|
||||
float v25; // xmm2_4
|
||||
float v26; // xmm0_4
|
||||
float v27; // xmm1_4
|
||||
float v28; // xmm1_4
|
||||
pathnode_t *pInsert; // eax
|
||||
pathnode_t *v30; // ecx
|
||||
pathnode_t *v31; // eax
|
||||
int success; // eax
|
||||
float v33; // [esp+10h] [ebp-8Ch]
|
||||
int linkCount; // [esp+14h] [ebp-88h]
|
||||
float negotiationOverlapCost; // [esp+18h] [ebp-84h]
|
||||
pathnode_t topParent; // [esp+1Ch] [ebp-80h] BYREF
|
||||
|
||||
returnVGoaPosl = (float *)vGoalPos;
|
||||
nodeLinkIndex = 0;
|
||||
if ( vGoalPos )
|
||||
{
|
||||
g_pathAttemptGoalPos[0] = *vGoalPos;
|
||||
g_pathAttemptGoalPos[1] = vGoalPos[1];
|
||||
g_pathAttemptGoalPos[2] = vGoalPos[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pathAttemptGoalPos[0] = 0.0;
|
||||
g_pathAttemptGoalPos[1] = 0.0;
|
||||
g_pathAttemptGoalPos[2] = 0.0;
|
||||
}
|
||||
returnStartNode = pNodeFrom;
|
||||
pNodeFrom->transient.iSearchFrame = ++level.iSearchFrame;
|
||||
returnEndNode = pNodeFrom;
|
||||
pNodeFrom->transient.pParent = &topParent;
|
||||
pNodeFrom->transient.pNextOpen = 0;
|
||||
pNodeFrom->transient.pPrevOpen = &topParent;
|
||||
pNodeFrom->transient.fCost = 0.0;
|
||||
topParent.transient.pNextOpen = pNodeFrom;
|
||||
while ( returnEndNode != searchInfo->m_pNodeTo )
|
||||
{
|
||||
topParent.transient.pNextOpen = returnEndNode->transient.pNextOpen;
|
||||
if ( topParent.transient.pNextOpen )
|
||||
topParent.transient.pNextOpen->transient.pPrevOpen = &topParent;
|
||||
linkCount = 0;
|
||||
if ( returnEndNode->dynamic.wLinkCount > 0 )
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
if ( bIgnoreBadplaces || !returnEndNode->constant.Links[nodeLinkIndex].ubBadPlaceCount[eTeam] )
|
||||
{
|
||||
endNodeLinks = returnEndNode->constant.Links;
|
||||
nodeNum = endNodeLinks[nodeLinkIndex].nodeNum;
|
||||
endNodeLinkDist = &endNodeLinks[nodeLinkIndex].fDist;
|
||||
pSuccessor = &gameWorldCurrent->path.nodes[nodeNum];
|
||||
if ( returnEndNode->constant.type != NODE_NEGOTIATION_BEGIN || pSuccessor->constant.type != NODE_NEGOTIATION_END || !returnEndNode->dynamic.wOverlapCount && !pSuccessor->dynamic.wOverlapCount )
|
||||
{
|
||||
if ( pSuccessor->transient.iSearchFrame != level.iSearchFrame )
|
||||
{
|
||||
pSuccessor->transient.iSearchFrame = level.iSearchFrame;
|
||||
negotiationOverlapCost = searchInfo->negotiationOverlapCost;
|
||||
v20 = vGoalPos[1] - pSuccessor->constant.vOrigin[1];
|
||||
v21 = sqrtf((float)((float)(*vGoalPos - pSuccessor->constant.vOrigin[0]) * (float)(*vGoalPos - pSuccessor->constant.vOrigin[0])) + (float)(v20 * v20));
|
||||
v22 = pSuccessor->constant.minUseDistSq;
|
||||
if ( v22 <= 1.0 || (v23 = searchInfo->startPos[0] - pSuccessor->constant.vOrigin[0], v24 = searchInfo->startPos[1] - pSuccessor->constant.vOrigin[1], v25 = searchInfo->startPos[2] - pSuccessor->constant.vOrigin[2], v22 <= (float)((float)((float)(v23 * v23) + (float)(v24 * v24)) + (float)(v25 * v25))) )
|
||||
{
|
||||
v26 = v21 + (double)pSuccessor->dynamic.userCount * negotiationOverlapCost;
|
||||
}
|
||||
else
|
||||
{
|
||||
v33 = v21 + (double)pSuccessor->dynamic.userCount * negotiationOverlapCost;
|
||||
v26 = negotiationOverlapCost + v33;
|
||||
}
|
||||
pSuccessor->transient.fHeuristic = v26;
|
||||
v17 = returnEndNode->constant.Links[nodeLinkIndex].fDist + returnEndNode->transient.fCost;
|
||||
LABEL_25:
|
||||
v27 = pSuccessor->transient.fHeuristic;
|
||||
pSuccessor->transient.pParent = returnEndNode;
|
||||
pSuccessor->transient.fCost = v17;
|
||||
v28 = v27 + v17;
|
||||
pInsert = &topParent;
|
||||
if ( topParent.transient.pNextOpen )
|
||||
{
|
||||
do
|
||||
{
|
||||
v30 = pInsert->transient.pNextOpen;
|
||||
if ( (float)(v30->transient.fHeuristic + v30->transient.fCost) >= v28 )
|
||||
break;
|
||||
pInsert = pInsert->transient.pNextOpen;
|
||||
}
|
||||
while ( v30->transient.pNextOpen );
|
||||
}
|
||||
pSuccessor->transient.pPrevOpen = pInsert;
|
||||
pSuccessor->transient.pNextOpen = pInsert->transient.pNextOpen;
|
||||
pInsert->transient.pNextOpen = pSuccessor;
|
||||
v31 = pSuccessor->transient.pNextOpen;
|
||||
if ( v31 )
|
||||
v31->transient.pPrevOpen = pSuccessor;
|
||||
goto LABEL_30;
|
||||
}
|
||||
v17 = returnEndNode->transient.fCost + *endNodeLinkDist;
|
||||
if ( v17 < pSuccessor->transient.fCost )
|
||||
{
|
||||
v18 = pSuccessor->transient.pPrevOpen;
|
||||
if ( v18 )
|
||||
{
|
||||
v18->transient.pNextOpen = pSuccessor->transient.pNextOpen;
|
||||
v19 = pSuccessor->transient.pNextOpen;
|
||||
if ( v19 )
|
||||
v19->transient.pPrevOpen = pSuccessor->transient.pPrevOpen;
|
||||
}
|
||||
goto LABEL_25;
|
||||
}
|
||||
}
|
||||
}
|
||||
LABEL_30:
|
||||
++nodeLinkIndex;
|
||||
if ( ++linkCount >= returnEndNode->dynamic.wLinkCount )
|
||||
{
|
||||
returnVGoaPosl = (float *)vGoalPos;
|
||||
returnStartNode = pNodeFrom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeLinkIndex = 0;
|
||||
returnEndNode->transient.pPrevOpen = 0;
|
||||
returnEndNode = topParent.transient.pNextOpen;
|
||||
if ( !topParent.transient.pNextOpen )
|
||||
return 0;
|
||||
}
|
||||
if ( pPath )
|
||||
success = Path_GeneratePath(pPath, eTeam, vStartPos, returnVGoaPosl, returnStartNode, returnEndNode, 1, bAllowNegotiationLinks);
|
||||
else
|
||||
success = 1;
|
||||
return success;
|
||||
}
|
||||
*/
|
||||
|
||||
int Path_AStarAlgorithm_CustomSearchInfo_FindPath_custom(game::path_t* pPath, game::team_t eTeam, const float* vStartPos, game::pathnode_t* pNodeFrom, const float* vGoalPos, int bAllowNegotiationLinks, game::CustomSearchInfo_FindPath* searchInfo, int bIgnoreBadplaces, game::pathnode_t* nodeTo)
|
||||
{
|
||||
float* returnVGoaPosl; // edx
|
||||
int nodeLinkIndex; // ebx
|
||||
game::pathnode_t* returnStartNode; // ecx
|
||||
game::pathnode_t* returnEndNode; // edi
|
||||
game::pathlink_s* endNodeLinks; // eax
|
||||
int nodeNum; // esi
|
||||
float* endNodeLinkDist; // eax
|
||||
game::pathnode_t* pSuccessor; // esi
|
||||
float v17; // xmm0_4
|
||||
game::pathnode_t* v18; // eax
|
||||
game::pathnode_t* v19; // eax
|
||||
float v20; // xmm1_4
|
||||
long double v21; // st7
|
||||
float v22; // xmm3_4
|
||||
float v23; // xmm0_4
|
||||
float v24; // xmm1_4
|
||||
float v25; // xmm2_4
|
||||
float v26; // xmm0_4
|
||||
float v27; // xmm1_4
|
||||
float v28; // xmm1_4
|
||||
game::pathnode_t* pInsert; // eax
|
||||
game::pathnode_t* v30; // ecx
|
||||
game::pathnode_t* v31; // eax
|
||||
int success; // eax
|
||||
float v33; // [esp+10h] [ebp-8Ch]
|
||||
int linkCount; // [esp+14h] [ebp-88h]
|
||||
float negotiationOverlapCost; // [esp+18h] [ebp-84h]
|
||||
game::pathnode_t topParent; // [esp+1Ch] [ebp-80h] BYREF
|
||||
|
||||
returnVGoaPosl = (float*)vGoalPos;
|
||||
nodeLinkIndex = 0;
|
||||
if (vGoalPos)
|
||||
{
|
||||
*game::g_pathAttemptGoalPos[0] = vGoalPos[0];
|
||||
*game::g_pathAttemptGoalPos[1] = vGoalPos[1];
|
||||
*game::g_pathAttemptGoalPos[2] = vGoalPos[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
*game::g_pathAttemptGoalPos[0] = 0.0f;
|
||||
*game::g_pathAttemptGoalPos[1] = 0.0f;
|
||||
*game::g_pathAttemptGoalPos[2] = 0.0f;
|
||||
}
|
||||
returnStartNode = pNodeFrom;
|
||||
pNodeFrom->transient.iSearchFrame = ++game::level->iSearchFrame;
|
||||
returnEndNode = pNodeFrom;
|
||||
pNodeFrom->transient.pParent = &topParent;
|
||||
pNodeFrom->transient.pNextOpen = 0;
|
||||
pNodeFrom->transient.pPrevOpen = &topParent;
|
||||
pNodeFrom->transient.fCost = 0.0;
|
||||
topParent.transient.pNextOpen = pNodeFrom;
|
||||
while (returnEndNode != searchInfo->m_pNodeTo)
|
||||
{
|
||||
topParent.transient.pNextOpen = returnEndNode->transient.pNextOpen;
|
||||
if (topParent.transient.pNextOpen)
|
||||
topParent.transient.pNextOpen->transient.pPrevOpen = &topParent;
|
||||
linkCount = 0;
|
||||
if (returnEndNode->dynamic.wLinkCount > 0)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (bIgnoreBadplaces || !returnEndNode->constant.Links[nodeLinkIndex].ubBadPlaceCount[eTeam])
|
||||
{
|
||||
endNodeLinks = returnEndNode->constant.Links;
|
||||
nodeNum = endNodeLinks[nodeLinkIndex].nodeNum;
|
||||
endNodeLinkDist = &endNodeLinks[nodeLinkIndex].fDist;
|
||||
pSuccessor = &(*game::gameWorldCurrent)->path.nodes[nodeNum];
|
||||
if (returnEndNode->constant.type != game::NODE_NEGOTIATION_BEGIN || pSuccessor->constant.type != game::NODE_NEGOTIATION_END || !returnEndNode->dynamic.wOverlapCount && !pSuccessor->dynamic.wOverlapCount)
|
||||
{
|
||||
if (pSuccessor->transient.iSearchFrame != game::level->iSearchFrame)
|
||||
{
|
||||
pSuccessor->transient.iSearchFrame = game::level->iSearchFrame;
|
||||
negotiationOverlapCost = searchInfo->negotiationOverlapCost;
|
||||
v20 = vGoalPos[1] - pSuccessor->constant.vOrigin[1];
|
||||
v21 = sqrtf((float)((float)(*vGoalPos - pSuccessor->constant.vOrigin[0]) * (float)(*vGoalPos - pSuccessor->constant.vOrigin[0])) + (float)(v20 * v20));
|
||||
v22 = pSuccessor->constant.minUseDistSq;
|
||||
if (v22 <= 1.0 || (v23 = searchInfo->startPos[0] - pSuccessor->constant.vOrigin[0], v24 = searchInfo->startPos[1] - pSuccessor->constant.vOrigin[1], v25 = searchInfo->startPos[2] - pSuccessor->constant.vOrigin[2], v22 <= (float)((float)((float)(v23 * v23) + (float)(v24 * v24)) + (float)(v25 * v25))))
|
||||
{
|
||||
v26 = v21 + (double)pSuccessor->dynamic.userCount * negotiationOverlapCost;
|
||||
}
|
||||
else
|
||||
{
|
||||
v33 = v21 + (double)pSuccessor->dynamic.userCount * negotiationOverlapCost;
|
||||
v26 = negotiationOverlapCost + v33;
|
||||
}
|
||||
pSuccessor->transient.fHeuristic = v26;
|
||||
v17 = returnEndNode->constant.Links[nodeLinkIndex].fDist + returnEndNode->transient.fCost;
|
||||
LABEL_25:
|
||||
v27 = pSuccessor->transient.fHeuristic;
|
||||
pSuccessor->transient.pParent = returnEndNode;
|
||||
pSuccessor->transient.fCost = v17;
|
||||
v28 = v27 + v17;
|
||||
pInsert = &topParent;
|
||||
if (topParent.transient.pNextOpen)
|
||||
{
|
||||
do
|
||||
{
|
||||
v30 = pInsert->transient.pNextOpen;
|
||||
if ((float)(v30->transient.fHeuristic + v30->transient.fCost) >= v28)
|
||||
break;
|
||||
pInsert = pInsert->transient.pNextOpen;
|
||||
} while (v30->transient.pNextOpen);
|
||||
}
|
||||
pSuccessor->transient.pPrevOpen = pInsert;
|
||||
pSuccessor->transient.pNextOpen = pInsert->transient.pNextOpen;
|
||||
pInsert->transient.pNextOpen = pSuccessor;
|
||||
v31 = pSuccessor->transient.pNextOpen;
|
||||
if (v31)
|
||||
v31->transient.pPrevOpen = pSuccessor;
|
||||
goto LABEL_30;
|
||||
}
|
||||
v17 = returnEndNode->transient.fCost + *endNodeLinkDist;
|
||||
if (v17 < pSuccessor->transient.fCost)
|
||||
{
|
||||
v18 = pSuccessor->transient.pPrevOpen;
|
||||
if (v18)
|
||||
{
|
||||
v18->transient.pNextOpen = pSuccessor->transient.pNextOpen;
|
||||
v19 = pSuccessor->transient.pNextOpen;
|
||||
if (v19)
|
||||
v19->transient.pPrevOpen = pSuccessor->transient.pPrevOpen;
|
||||
}
|
||||
goto LABEL_25;
|
||||
}
|
||||
}
|
||||
}
|
||||
LABEL_30:
|
||||
++nodeLinkIndex;
|
||||
if (++linkCount >= returnEndNode->dynamic.wLinkCount)
|
||||
{
|
||||
returnVGoaPosl = (float*)vGoalPos;
|
||||
returnStartNode = pNodeFrom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeLinkIndex = 0;
|
||||
returnEndNode->transient.pPrevOpen = 0;
|
||||
returnEndNode = topParent.transient.pNextOpen;
|
||||
if (!topParent.transient.pNextOpen)
|
||||
return 0;
|
||||
}
|
||||
if (pPath)
|
||||
success = game::Path_GeneratePath(pPath, eTeam, vStartPos, returnVGoaPosl, returnStartNode, returnEndNode, 1, bAllowNegotiationLinks);
|
||||
else
|
||||
success = 1;
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
//Original
|
||||
int __userpurge Path_FindPathFromTo@<eax>(float *startPos@<eax>, pathnode_t *pNodeTo@<edx>, path_t *pPath, team_t eTeam, pathnode_t *pNodeFrom, float *vGoalPos, int bAllowNegotiationLinks, int bIgnoreBadplaces)
|
||||
{
|
||||
int v8; // xmm0_4
|
||||
CustomSearchInfo_FindPath info; // [esp+0h] [ebp-14h] BYREF
|
||||
|
||||
v8 = ai_pathNegotiationOverlapCost->current.integer;
|
||||
info.m_pNodeTo = pNodeTo;
|
||||
LODWORD(info.negotiationOverlapCost) = v8;
|
||||
info.startPos[0] = *startPos;
|
||||
info.startPos[1] = startPos[1];
|
||||
info.startPos[2] = startPos[2];
|
||||
return Path_AStarAlgorithm_CustomSearchInfo_FindPath_(pPath, eTeam, startPos, pNodeFrom, vGoalPos, bAllowNegotiationLinks, &info, bIgnoreBadplaces, pNodeTo);
|
||||
}
|
||||
*/
|
||||
|
||||
int Path_FindPathFromTo_custom(float* startPos, game::pathnode_t* pNodeTo, game::path_t* pPath, game::team_t eTeam, game::pathnode_t* pNodeFrom, float* vGoalPos, int bAllowNegotiationLinks, int bIgnoreBadplaces)
|
||||
{
|
||||
int overlapCost; // xmm0_4
|
||||
game::CustomSearchInfo_FindPath info = {}; // [esp+0h] [ebp-14h] BYREF
|
||||
int result;
|
||||
|
||||
overlapCost = (*game::ai_pathNegotiationOverlapCost)->current.integer;
|
||||
info.m_pNodeTo = pNodeTo;
|
||||
info.negotiationOverlapCost = overlapCost;
|
||||
info.startPos[0] = startPos[0];
|
||||
info.startPos[1] = startPos[1];
|
||||
info.startPos[2] = startPos[2];
|
||||
result = Path_AStarAlgorithm_CustomSearchInfo_FindPath_custom(pPath, eTeam, startPos, pNodeFrom, vGoalPos, bAllowNegotiationLinks, &info, bIgnoreBadplaces, pNodeTo);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
//Original
|
||||
int __userpurge Path_FindPath@<eax>(path_t* pPath@<ecx>, team_t eTeam@<edx>, float* vStartPos, float* vGoalPos, int bAllowNegotiationLinks)
|
||||
{
|
||||
pathnode_t* pNodeTo; // esi
|
||||
int result; // eax
|
||||
pathnode_t* pNodeFrom; // eax
|
||||
int a9; // [esp+2Ch] [ebp-304h] BYREF
|
||||
int a4[192]; // [esp+30h] [ebp-300h] BYREF
|
||||
|
||||
pNodeTo = Path_NearestNodeNotCrossPlanes(NAN, COERCE_FLOAT(64), (int)vGoalPos, (int)a4, 192.0, 0, 0, 0, (int)&a9, 0);
|
||||
if (pNodeTo && (pNodeFrom = Path_NearestNodeNotCrossPlanes(NAN, COERCE_FLOAT(64), (int)vStartPos, (int)a4, 192.0, 0, 0, 0, (int)&a9, 0)) != 0)
|
||||
result = Path_FindPathFromTo(vStartPos, pNodeTo, pPath, eTeam, pNodeFrom, vGoalPos, bAllowNegotiationLinks, 0);
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
int Path_FindPath_custom(game::path_t* pPath, game::team_t eTeam, float* vStartPos, float* vGoalPos, int bAllowNegotiationLinks)
|
||||
{
|
||||
int result; // eax
|
||||
int returnCount = 0; // [esp+2Ch] [ebp-304h] BYREF
|
||||
std::unique_ptr<game::pathsort_t[], void (*)(game::pathsort_t*)> nodes(new game::pathsort_t[64], [](game::pathsort_t* ptr) { delete[] ptr; });
|
||||
const int maxNodes = 64;
|
||||
|
||||
game::pathnode_t* pNodeTo = game::Path_NearestNodeNotCrossPlanes(-2, maxNodes, vGoalPos, nodes.get(), 192.0f, 0.0f, 0.0f, 0.0f, &returnCount, game::NEAREST_NODE_DO_HEIGHT_CHECK);
|
||||
if (!pNodeTo)
|
||||
{
|
||||
printf("Couldn't find the node to\n");
|
||||
}
|
||||
game::pathnode_t* pNodeFrom = game::Path_NearestNodeNotCrossPlanes(-2, maxNodes, vStartPos, nodes.get(), 192.0f, 0.0f, 0.0f, 0.0f, &returnCount, game::NEAREST_NODE_DO_HEIGHT_CHECK);
|
||||
if (pNodeTo && pNodeFrom)
|
||||
{
|
||||
result = Path_FindPathFromTo_custom(vStartPos, pNodeTo, pPath, eTeam, pNodeFrom, vGoalPos, bAllowNegotiationLinks, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
//utils::hook::jump(0x4CF280, Path_FindPath_stub);
|
||||
|
||||
gsc::method::add("getlinkednodes", [](game::scr_entref_s ent)
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_PATHNODE)
|
||||
{
|
||||
game::Scr_Error("Not a pathnode", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto primary_node = &(*game::gameWorldCurrent)->path.nodes[ent.entnum];
|
||||
|
||||
game::Scr_MakeArray(game::SCRIPTINSTANCE_SERVER);
|
||||
|
||||
for (auto i = 0; i < primary_node->constant.totalLinkCount; i++)
|
||||
{
|
||||
auto linked_node = &(*game::gameWorldCurrent)->path.nodes[primary_node->constant.Links[i].nodeNum];
|
||||
|
||||
game::Scr_AddPathnode(game::SCRIPTINSTANCE_SERVER, linked_node);
|
||||
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
|
||||
}
|
||||
});
|
||||
|
||||
gsc::method::add("getnodenumber", [](game::scr_entref_s ent)
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_PATHNODE)
|
||||
{
|
||||
game::Scr_Error("Not a pathnode", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto node = &(*game::gameWorldCurrent)->path.nodes[ent.entnum];
|
||||
|
||||
auto entnum = node - (*game::gameWorldCurrent)->path.nodes;
|
||||
|
||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, entnum);
|
||||
});
|
||||
|
||||
gsc::function::add("getnodebynumber", []()
|
||||
{
|
||||
auto node_num = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0);
|
||||
|
||||
if (node_num == game::g_path->actualNodeCount)
|
||||
{
|
||||
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node_num < 0 || node_num > game::g_path->actualNodeCount)
|
||||
{
|
||||
game::Scr_Error(utils::string::va("Number %d is not valid for a node", node_num), game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto node = &(*game::gameWorldCurrent)->path.nodes[node_num];
|
||||
|
||||
game::Scr_AddPathnode(game::SCRIPTINSTANCE_SERVER, node);
|
||||
});
|
||||
|
||||
gsc::function::add("generatepath", []()
|
||||
{
|
||||
auto path = std::make_unique<game::path_t>();
|
||||
|
||||
float start_pos[3] = {};
|
||||
|
||||
float goal_pos[3] = {};
|
||||
|
||||
auto team = "neutral"s;
|
||||
|
||||
auto allow_negotiation_links = false;
|
||||
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 0, start_pos);
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 1, goal_pos);
|
||||
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 3)
|
||||
{
|
||||
if (game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 2) != game::VAR_UNDEFINED)
|
||||
{
|
||||
team = game::Scr_GetString(game::SCRIPTINSTANCE_SERVER, 2);
|
||||
}
|
||||
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 4)
|
||||
{
|
||||
allow_negotiation_links = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (!game::team_map.contains(team))
|
||||
{
|
||||
game::Scr_Error(utils::string::va("Team %s is not valid", team.data()), game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto eTeam = game::team_map.at(team);
|
||||
|
||||
auto success = Path_FindPath_custom(path.get(), eTeam, start_pos, goal_pos, allow_negotiation_links);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
|
||||
return;
|
||||
}
|
||||
|
||||
game::Scr_MakeArray(game::SCRIPTINSTANCE_SERVER);
|
||||
|
||||
//Reverse the order of the array so index 0 is from the starting point instead of the end
|
||||
for (auto i = path->wPathLen; i >= 0; i--)
|
||||
{
|
||||
//Return the number of the node instead of the node itself because of spooky GSC VM corruption
|
||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, path->pts[i].iNodeNum);
|
||||
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(ai::component)
|
0
src/component/debug.cpp
Normal file
0
src/component/debug.cpp
Normal file
@ -260,117 +260,25 @@ namespace gsc
|
||||
game::Scr_AddEntity(game::SCRIPTINSTANCE_SERVER, ent2);
|
||||
});
|
||||
|
||||
method::add("getlinkednodes", [](game::scr_entref_s ent)
|
||||
function::add("writefile", []()
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_PATHNODE)
|
||||
const auto path = game::Scr_GetString(game::SCRIPTINSTANCE_SERVER, 0);
|
||||
const auto data = game::Scr_GetString(game::SCRIPTINSTANCE_SERVER, 1);
|
||||
|
||||
auto append = false;
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) > 2)
|
||||
{
|
||||
game::Scr_Error("Not a pathnode", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
append = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 2);
|
||||
}
|
||||
|
||||
auto primary_node = &(*game::gameWorldCurrent)->path.nodes[ent.entnum];
|
||||
|
||||
game::Scr_MakeArray(game::SCRIPTINSTANCE_SERVER);
|
||||
|
||||
for (auto i = 0; i < primary_node->constant.totalLinkCount; i++)
|
||||
{
|
||||
auto linked_node = &(*game::gameWorldCurrent)->path.nodes[primary_node->constant.Links[i].nodeNum];
|
||||
|
||||
game::Scr_AddPathnode(game::SCRIPTINSTANCE_SERVER, linked_node);
|
||||
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
|
||||
}
|
||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, utils::io::write_file(path, data, append));
|
||||
});
|
||||
|
||||
method::add("getnodenumber", [](game::scr_entref_s ent)
|
||||
gsc::function::add("readfile", []()
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_PATHNODE)
|
||||
{
|
||||
game::Scr_Error("Not a pathnode", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto node = &(*game::gameWorldCurrent)->path.nodes[ent.entnum];
|
||||
|
||||
auto entnum = node - (*game::gameWorldCurrent)->path.nodes;
|
||||
|
||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, entnum);
|
||||
const auto path = game::Scr_GetString(game::SCRIPTINSTANCE_SERVER, 0);
|
||||
game::Scr_AddString(game::SCRIPTINSTANCE_SERVER, utils::io::read_file(path).c_str());
|
||||
});
|
||||
|
||||
function::add("getnodebynumber", []()
|
||||
{
|
||||
auto node_num = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0);
|
||||
|
||||
if (node_num == game::g_path->actualNodeCount)
|
||||
{
|
||||
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node_num < 0 || node_num > game::g_path->actualNodeCount)
|
||||
{
|
||||
game::Scr_Error(utils::string::va("Number %d is not valid for a node", node_num), game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto node = &(*game::gameWorldCurrent)->path.nodes[node_num];
|
||||
|
||||
game::Scr_AddPathnode(game::SCRIPTINSTANCE_SERVER, node);
|
||||
});
|
||||
|
||||
function::add("generatepath", []()
|
||||
{
|
||||
auto path = std::make_unique<game::path_t>();
|
||||
|
||||
float start_pos[3] = {};
|
||||
|
||||
float goal_pos[3] = {};
|
||||
|
||||
auto team = "neutral"s;
|
||||
|
||||
auto allow_negotiation_links = false;
|
||||
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 0, start_pos);
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 1, goal_pos);
|
||||
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 3)
|
||||
{
|
||||
if (game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 2) != game::VAR_UNDEFINED)
|
||||
{
|
||||
team = game::Scr_GetString(game::SCRIPTINSTANCE_SERVER, 2);
|
||||
}
|
||||
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 4)
|
||||
{
|
||||
allow_negotiation_links = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (!game::team_map.contains(team))
|
||||
{
|
||||
game::Scr_Error(utils::string::va("Team %s is not valid", team.data()), game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto eTeam = game::team_map.at(team);
|
||||
|
||||
auto success = game::Path_FindPath(path.get(), eTeam, start_pos, goal_pos, allow_negotiation_links);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
|
||||
return;
|
||||
}
|
||||
|
||||
game::Scr_MakeArray(game::SCRIPTINSTANCE_SERVER);
|
||||
|
||||
for (auto i = 0; i < path->wPathLen; i++)
|
||||
{
|
||||
//Return the number of the node instead of the node itself because of spooky GSC VM corruption
|
||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, path->pts[i].iNodeNum);
|
||||
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
21
src/component/gsc.hpp
Normal file
21
src/component/gsc.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdinc.hpp>
|
||||
|
||||
namespace gsc
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace function
|
||||
{
|
||||
void add(const std::string& name, const game::BuiltinFunction function);
|
||||
}
|
||||
|
||||
namespace method
|
||||
{
|
||||
void add(const std::string& name, const game::BuiltinMethod method);
|
||||
}
|
||||
}
|
@ -5,14 +5,57 @@
|
||||
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
utils::hook::detour gscr_spawn_hook;
|
||||
|
||||
namespace
|
||||
{
|
||||
game::dvar_s* custom_dvar;
|
||||
game::dvar_s* custom_string_dvar;
|
||||
|
||||
void print_script_callstack(const char* msg, game::scriptInstance_t inst)
|
||||
{
|
||||
int i; // [esp+4h] [ebp-4h]
|
||||
printf("******* Callstack for %s *******\n", msg);
|
||||
game::Scr_PrintPrevCodePos(game::function_stack[inst].pos, inst, game::CON_CHANNEL_DONT_FILTER, 0);
|
||||
auto function_count = game::gScrVmPub[inst].function_count;
|
||||
if (function_count)
|
||||
{
|
||||
for (i = function_count - 1; i >= 1; --i)
|
||||
{
|
||||
printf("Info: called from:\n");
|
||||
game::Scr_PrintPrevCodePos(
|
||||
game::gScrVmPub[inst].function_frame_start[i].fs.pos,
|
||||
inst,
|
||||
game::CON_CHANNEL_DONT_FILTER,
|
||||
game::gScrVmPub[inst].function_frame_start[i].fs.localId == 0);
|
||||
}
|
||||
printf("started from:\n");
|
||||
game::Scr_PrintPrevCodePos(game::gScrVmPub[inst].function_frame_start[0].fs.pos, inst, game::CON_CHANNEL_DONT_FILTER, 1u);
|
||||
}
|
||||
printf("************************************\n");
|
||||
}
|
||||
|
||||
void gscr_spawn_stub()
|
||||
{
|
||||
auto classname = game::Scr_GetConstString(game::SCRIPTINSTANCE_SERVER, 0);
|
||||
|
||||
float origin[3] = {};
|
||||
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 1, origin);
|
||||
|
||||
if (classname == game::scr_const->script_origin)
|
||||
{
|
||||
print_script_callstack(utils::string::va("GScr_Spawn() classname: script_origin at: (%f, %f, %f)", origin[0], origin[1], origin[2]), game::SCRIPTINSTANCE_SERVER);
|
||||
}
|
||||
|
||||
gscr_spawn_hook.invoke<void>();
|
||||
}
|
||||
}
|
||||
|
||||
bool our_funny_call(game::pathnode_t* begin_node, game::pathnode_t* end_node, bool allowNeg)
|
||||
{
|
||||
if (!allowNeg && begin_node->constant.type == game::NODE_NEGOTIATION_BEGIN && end_node->constant.type == game::NODE_NEGOTIATION_END)
|
||||
@ -81,6 +124,17 @@ namespace test
|
||||
//printf("Biggie Spam McCheese\n");
|
||||
});
|
||||
|
||||
gscr_spawn_hook.create(0x517630, gscr_spawn_stub);
|
||||
|
||||
//Disable AI print spam
|
||||
utils::hook::nop(0x4BAB7D, 5);
|
||||
utils::hook::nop(0x4BAAFA, 5);
|
||||
|
||||
//Disable asset loading print spam
|
||||
utils::hook::nop(0x48D9D9, 5);
|
||||
|
||||
//Disable unknown dvar spam
|
||||
utils::hook::nop(0x5F04AF, 5);
|
||||
|
||||
// fix NEGOTIATION links
|
||||
utils::hook::jump(0x4D3296, our_funny_hook);
|
||||
|
@ -32,6 +32,20 @@ namespace game
|
||||
{ "dead", TEAM_DEAD }
|
||||
};
|
||||
|
||||
void Scr_PrintPrevCodePos(const char* codepos, int scriptInstance, con_channel_e channel, int index)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x68B340);
|
||||
|
||||
__asm
|
||||
{
|
||||
push index;
|
||||
push channel;
|
||||
push scriptInstance;
|
||||
mov eax, codepos;
|
||||
call call_addr;
|
||||
}
|
||||
}
|
||||
|
||||
int Scr_GetInt(game::scriptInstance_t inst, unsigned int arg_index)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x699C50);
|
||||
@ -321,7 +335,7 @@ namespace game
|
||||
|
||||
unsigned int Scr_GetNumParam(scriptInstance_t inst)
|
||||
{
|
||||
return scrVmPub[inst].outparamcount;
|
||||
return gScrVmPub[inst].outparamcount;
|
||||
}
|
||||
|
||||
VariableType Scr_GetType(scriptInstance_t inst, unsigned int index)
|
||||
@ -441,6 +455,80 @@ namespace game
|
||||
return answer;
|
||||
}
|
||||
|
||||
pathnode_t* Path_NearestNodeNotCrossPlanes(int typeFlags, int maxNodes, float* vOrigin, pathsort_t* nodes, float fMaxDist, float a6, float a7, int iPlaneCount, int* returnCount, nearestNodeHeightCheck heightCheck)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x55C210);
|
||||
|
||||
pathnode_t* answer;
|
||||
|
||||
__asm
|
||||
{
|
||||
push heightCheck;
|
||||
push returnCount;
|
||||
push iPlaneCount;
|
||||
push a7;
|
||||
push a6;
|
||||
push fMaxDist;
|
||||
push nodes;
|
||||
push vOrigin;
|
||||
mov ecx, maxNodes;
|
||||
mov edx, typeFlags;
|
||||
call call_addr;
|
||||
add esp, 0x20;
|
||||
mov answer, eax;
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
//This is a __userpurge, which automatically cleans up the stack by itself so do not do add esp
|
||||
int Path_FindPathFromTo(float* startPos, pathnode_t* pNodeTo, path_t* pPath, team_t eTeam, pathnode_t* pNodeFrom, float* vGoalPos, int bAllowNegotiationLinks, int bIgnoreBadplaces)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x4CF3F0);
|
||||
|
||||
int answer;
|
||||
|
||||
__asm
|
||||
{
|
||||
push bIgnoreBadplaces;
|
||||
push bAllowNegotiationLinks;
|
||||
push vGoalPos;
|
||||
push pNodeFrom;
|
||||
push eTeam;
|
||||
push pPath;
|
||||
mov edx, pNodeTo;
|
||||
mov eax, startPos;
|
||||
call call_addr;
|
||||
mov answer, eax;
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
//This is a __userpurge, which automatically cleans up the stack by itself so do not do add esp
|
||||
int Path_GeneratePath(path_t* pPath, team_t eTeam, const float* vStartPos, float* vGoalPos, pathnode_t* pNodeFrom, pathnode_t* pNodeTo, int bIncludeGoalPos, int bAllowNegotiationLinks)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x4CED90);
|
||||
|
||||
int answer;
|
||||
|
||||
__asm
|
||||
{
|
||||
push bAllowNegotiationLinks;
|
||||
push bIncludeGoalPos;
|
||||
push pNodeTo;
|
||||
push pNodeFrom;
|
||||
push vGoalPos;
|
||||
push vStartPos;
|
||||
push eTeam;
|
||||
mov eax, pPath;
|
||||
call call_addr;
|
||||
mov answer, eax;
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
namespace plutonium
|
||||
{
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ namespace game
|
||||
|
||||
extern std::map<std::string, team_t> team_map;
|
||||
|
||||
void Scr_PrintPrevCodePos(const char* codepos, int scriptInstance, con_channel_e channel, int index);
|
||||
|
||||
const char* Cmd_Argv(int index);
|
||||
unsigned int Cmd_Argc();
|
||||
void Cmd_AddCommand(const char* name, void(__cdecl* function)());
|
||||
@ -57,6 +59,9 @@ namespace game
|
||||
const char* SL_ConvertToString(scriptInstance_t inst, int id);
|
||||
|
||||
int Path_FindPath(path_t* pPath, team_t eTeam, float* vStartPos, float* vGoalPos, int bAllowNegotiationLinks);
|
||||
pathnode_t* Path_NearestNodeNotCrossPlanes(int typeFlags, int maxNodes, float* vOrigin, pathsort_t* nodes, float fMaxDist, float a6, float a7, int iPlaneCount, int* returnCount, nearestNodeHeightCheck heightCheck);
|
||||
int Path_FindPathFromTo(float* startPos, pathnode_t* pNodeTo, path_t* pPath, team_t eTeam, pathnode_t* pNodeFrom, float* vGoalPos, int bAllowNegotiationLinks, int bIgnoreBadplaces);
|
||||
int Path_GeneratePath(path_t* pPath, team_t eTeam, const float* vStartPos, float* vGoalPos, pathnode_t* pNodeFrom, pathnode_t* pNodeTo, int bIncludeGoalPos, int bAllowNegotiationLinks);
|
||||
|
||||
template <typename T>
|
||||
class symbol
|
||||
|
@ -1419,6 +1419,134 @@ namespace game
|
||||
float fOrientLerp;
|
||||
};
|
||||
|
||||
struct animCmdState_s
|
||||
{
|
||||
int field_0;
|
||||
int field_4;
|
||||
int field_8;
|
||||
int field_C;
|
||||
int field_10;
|
||||
int field_14;
|
||||
int field_18;
|
||||
int field_1C;
|
||||
int field_20;
|
||||
int field_24;
|
||||
int field_28;
|
||||
};
|
||||
|
||||
struct SpawnVar
|
||||
{
|
||||
bool spawnVarsValid;
|
||||
int numSpawnVars;
|
||||
char* spawnVars[64][2];
|
||||
int numSpawnVarChars;
|
||||
char spawnVarChars[2048];
|
||||
};
|
||||
|
||||
enum loading_t : __int32
|
||||
{
|
||||
LOADING_DONE = 0x0,
|
||||
LOADING_LEVEL = 0x1,
|
||||
LOADING_SAVEGAME = 0x2,
|
||||
};
|
||||
|
||||
struct cached_tag_mat_t
|
||||
{
|
||||
int time;
|
||||
int entnum;
|
||||
unsigned __int16 name;
|
||||
float tagMat[4][3];
|
||||
};
|
||||
|
||||
struct trigger_info_t
|
||||
{
|
||||
unsigned __int16 entnum;
|
||||
unsigned __int16 otherEntnum;
|
||||
int useCount;
|
||||
int otherUseCount;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) level_locals_s
|
||||
{
|
||||
gclient_s* clients;
|
||||
gentity_s* gentities;
|
||||
int unk1;
|
||||
int num_entities;
|
||||
gentity_s* firstFreeEnt;
|
||||
gentity_s* lastFreeEnt;
|
||||
sentient_s* sentients;
|
||||
actor_s* actors;
|
||||
scr_vehicle_s* vehicles;
|
||||
TurretInfo* turrets;
|
||||
animCmdState_s* animCmds;
|
||||
char gap_2C[4096];
|
||||
int logFile;
|
||||
int initializing;
|
||||
int clientIsSpawning;
|
||||
int maxclients;
|
||||
int framenum;
|
||||
int time;
|
||||
int previousTime;
|
||||
int startTime;
|
||||
int newSession;
|
||||
int actorCorpseCount;
|
||||
SpawnVar spawnVar;
|
||||
int reloadDelayTime;
|
||||
int absoluteReloadDelayTime;
|
||||
EntHandle droppedWeaponCue[32];
|
||||
int changelevel;
|
||||
int bMissionSuccess;
|
||||
int bMissionFailed;
|
||||
int exitTime;
|
||||
int savepersist;
|
||||
char cinematic[64];
|
||||
float fFogOpaqueDist;
|
||||
float fFogOpaqueDistSqrd;
|
||||
unsigned int grenadeHintCount;
|
||||
int remapCount;
|
||||
int iSearchFrame;
|
||||
loading_t loading;
|
||||
int actorPredictDepth;
|
||||
int bDrawCompassFriendlies;
|
||||
int bPlayerIgnoreRadiusDamage;
|
||||
int bPlayerIgnoreRadiusDamageLatched;
|
||||
int triggerIndex;
|
||||
int padd;
|
||||
int currentEntityThink;
|
||||
int currentIndex;
|
||||
bool checkAnimChange;
|
||||
int registerWeapons;
|
||||
int bRegisterItems;
|
||||
int framePos;
|
||||
cached_tag_mat_t cachedTagMat;
|
||||
cached_tag_mat_t cachedEntTargetTagMat;
|
||||
__int16 soundAliasFirst;
|
||||
__int16 soundAliasLast;
|
||||
trigger_info_t pendingTriggerList[256];
|
||||
trigger_info_t currentTriggerList[256];
|
||||
int pendingTriggerListSize;
|
||||
int currentTriggerListSize;
|
||||
int entTriggerIndex[1024];
|
||||
unsigned __int8 specialIndex[1024];
|
||||
char gap4808[2628];
|
||||
int scriptPrintChannel;
|
||||
float compassMapUpperLeft[2];
|
||||
float compassMapWorldSize[2];
|
||||
float compassNorth[2];
|
||||
float mapSunColor[3];
|
||||
float mapSunDirection[3];
|
||||
int script_ai_limit;
|
||||
int disable_grenade_suicide;
|
||||
int huh;
|
||||
int manualNameChange;
|
||||
objective_t objectives[16];
|
||||
int frameTime;
|
||||
int finished;
|
||||
int pad;
|
||||
};
|
||||
|
||||
static_assert(sizeof(level_locals_s) == 0x549C);
|
||||
|
||||
enum nodeType
|
||||
{
|
||||
NODE_BADNODE = 0x0,
|
||||
@ -1572,12 +1700,12 @@ namespace game
|
||||
float origin[3];
|
||||
float maxDist;
|
||||
float maxDistSq;
|
||||
float maxHeight;
|
||||
float maxHeightSq;
|
||||
int typeFlags;
|
||||
pathsort_t* nodes;
|
||||
int maxNodes;
|
||||
int nodeCount;
|
||||
float maxHeight;
|
||||
};
|
||||
|
||||
struct __declspec(align(128)) pathlocal_t
|
||||
@ -1585,9 +1713,22 @@ namespace game
|
||||
PathLinkInfo pathLinkInfoArray[2048];
|
||||
int pathLinkInfoArrayInited;
|
||||
unsigned int actualNodeCount;
|
||||
pathlocal_t_circle circle;
|
||||
unsigned int extraNodes;
|
||||
unsigned int originErrors;
|
||||
pathlocal_t_circle circle;
|
||||
};
|
||||
|
||||
struct CustomSearchInfo_FindPath
|
||||
{
|
||||
pathnode_t* m_pNodeTo;
|
||||
float startPos[3];
|
||||
float negotiationOverlapCost;
|
||||
};
|
||||
|
||||
enum nearestNodeHeightCheck
|
||||
{
|
||||
NEAREST_NODE_DO_HEIGHT_CHECK = 0x0,
|
||||
NEAREST_NODE_DONT_DO_HEIGHT_CHECK = 0x1,
|
||||
};
|
||||
|
||||
enum VariableType
|
||||
@ -1674,4 +1815,358 @@ namespace game
|
||||
function_frame_t function_frame_start[32];
|
||||
VariableValue stack[2048];
|
||||
};
|
||||
|
||||
struct __declspec(align(2)) scr_const_t
|
||||
{
|
||||
unsigned __int16 _;
|
||||
__int16 active2;
|
||||
__int16 j_spine4;
|
||||
__int16 j_helmet;
|
||||
__int16 j_head;
|
||||
__int16 all;
|
||||
__int16 allies;
|
||||
__int16 axis;
|
||||
__int16 bad_path;
|
||||
__int16 begin_firing;
|
||||
__int16 unknown_location;
|
||||
__int16 cancel_location;
|
||||
__int16 confirm_location;
|
||||
__int16 regroup_location;
|
||||
__int16 defend_location;
|
||||
__int16 clear_squadcommand;
|
||||
__int16 squadleader_changed;
|
||||
__int16 squad_disbanded;
|
||||
__int16 deployed_turret;
|
||||
__int16 crouch;
|
||||
__int16 current;
|
||||
__int16 damage;
|
||||
__int16 dead;
|
||||
__int16 death;
|
||||
__int16 disconnect;
|
||||
__int16 death_or_disconnect;
|
||||
__int16 detonate;
|
||||
__int16 direct;
|
||||
__int16 dlight;
|
||||
__int16 done;
|
||||
__int16 empty;
|
||||
__int16 end_firing;
|
||||
__int16 enter_vehicle;
|
||||
__int16 entity;
|
||||
__int16 exit_vehicle;
|
||||
__int16 change_seat;
|
||||
__int16 vehicle_death;
|
||||
__int16 explode;
|
||||
__int16 failed;
|
||||
__int16 free;
|
||||
__int16 fraction;
|
||||
__int16 goal;
|
||||
__int16 goal_changed;
|
||||
__int16 goal_yaw;
|
||||
__int16 grenade;
|
||||
__int16 grenade_danger;
|
||||
__int16 grenade_fire;
|
||||
__int16 grenade_launcher_fire;
|
||||
__int16 grenade_pullback;
|
||||
__int16 info_notnull;
|
||||
__int16 invisible;
|
||||
__int16 key1;
|
||||
__int16 key2;
|
||||
__int16 killanimscript;
|
||||
__int16 left;
|
||||
__int16 left_tread;
|
||||
__int16 light;
|
||||
__int16 movedone;
|
||||
__int16 noclass;
|
||||
__int16 none;
|
||||
__int16 normal;
|
||||
__int16 player;
|
||||
__int16 position;
|
||||
__int16 projectile_impact;
|
||||
__int16 prone;
|
||||
__int16 right;
|
||||
__int16 right_tread;
|
||||
__int16 tank_armor;
|
||||
__int16 reload;
|
||||
__int16 reload_start;
|
||||
__int16 rocket;
|
||||
__int16 rotatedone;
|
||||
__int16 script_brushmodel;
|
||||
__int16 script_model;
|
||||
__int16 script_origin;
|
||||
__int16 snd_enveffectsprio_level;
|
||||
__int16 snd_enveffectsprio_shellshock;
|
||||
__int16 snd_busvolprio_holdbreath;
|
||||
__int16 snd_busvolprio_pain;
|
||||
__int16 snd_busvolprio_shellshock;
|
||||
__int16 stand;
|
||||
__int16 suppression;
|
||||
__int16 suppression_end;
|
||||
__int16 surfacetype;
|
||||
__int16 tag_aim;
|
||||
__int16 tag_aim_animated;
|
||||
__int16 tag_brass;
|
||||
__int16 tag_butt;
|
||||
__int16 tag_clip;
|
||||
__int16 tag_flash;
|
||||
__int16 tag_flash_11;
|
||||
__int16 tag_flash_2;
|
||||
__int16 tag_flash_22;
|
||||
__int16 tag_flash_3;
|
||||
__int16 tag_fx;
|
||||
__int16 tag_inhand2;
|
||||
__int16 tag_knife_attach;
|
||||
__int16 tag_knife_fx;
|
||||
__int16 tag_bayonet;
|
||||
__int16 tag_laser;
|
||||
__int16 tag_origin;
|
||||
__int16 tag_weapon;
|
||||
__int16 tag_player2;
|
||||
__int16 tag_camera;
|
||||
__int16 tag_weapon_right;
|
||||
__int16 tag_gasmask;
|
||||
__int16 tag_gasmask2;
|
||||
__int16 tag_sync;
|
||||
__int16 tag_wake;
|
||||
__int16 target_script_trigger;
|
||||
__int16 tempEntity;
|
||||
__int16 top;
|
||||
__int16 touch;
|
||||
__int16 trigger;
|
||||
__int16 trigger_use;
|
||||
__int16 trigger_use_touch;
|
||||
__int16 trigger_damage;
|
||||
__int16 trigger_lookat;
|
||||
__int16 trigger_radius;
|
||||
__int16 truck_cam;
|
||||
__int16 weapon_change_on_turret;
|
||||
__int16 weapon_change;
|
||||
__int16 weapon_change_complete;
|
||||
__int16 weapon_fired;
|
||||
__int16 weapon_pvp_attack;
|
||||
__int16 worldspawn;
|
||||
__int16 flashbang;
|
||||
__int16 flash;
|
||||
__int16 smoke;
|
||||
__int16 night_vision_on;
|
||||
__int16 night_vision_off;
|
||||
__int16 back_low;
|
||||
__int16 back_mid;
|
||||
__int16 back_up;
|
||||
__int16 head;
|
||||
__int16 j_mainroot;
|
||||
__int16 neck;
|
||||
__int16 pelvis;
|
||||
__int16 j_head2;
|
||||
__int16 MOD_UNKNOWN;
|
||||
__int16 MOD_PISTOL_BULLET;
|
||||
__int16 MOD_RIFLE_BULLET;
|
||||
__int16 MOD_GRENADE;
|
||||
__int16 MOD_GRENADE_SPLASH;
|
||||
__int16 MOD_PROJECTILE;
|
||||
__int16 MOD_PROJECTILE_SPLASH;
|
||||
__int16 MOD_MELEE;
|
||||
__int16 MOD_BAYONET;
|
||||
__int16 MOD_HEAD_SHOT;
|
||||
__int16 MOD_CRUSH;
|
||||
__int16 MOD_TELEFRAG;
|
||||
__int16 MOD_FALLING;
|
||||
__int16 MOD_SUICIDE;
|
||||
__int16 MOD_TRIGGER_HURT;
|
||||
__int16 MOD_EXPLOSIVE;
|
||||
__int16 MOD_IMPACT;
|
||||
__int16 MOD_BURNED;
|
||||
__int16 MOD_HIT_BY_OBJECT;
|
||||
__int16 MOD_DROWN;
|
||||
__int16 script_vehicle;
|
||||
__int16 script_vehicle_collision;
|
||||
__int16 script_vehicle_collmap;
|
||||
__int16 script_vehicle_corpse;
|
||||
__int16 turret_fire;
|
||||
__int16 turret_on_target;
|
||||
__int16 turret_not_on_target;
|
||||
__int16 turret_on_vistarget;
|
||||
__int16 turret_no_vis;
|
||||
__int16 turret_rotate_stopped;
|
||||
__int16 turret_deactivate;
|
||||
__int16 turretstatechange;
|
||||
__int16 turretownerchange;
|
||||
__int16 reached_end_node;
|
||||
__int16 reached_wait_node;
|
||||
__int16 reached_wait_speed;
|
||||
__int16 near_goal;
|
||||
__int16 veh_collision;
|
||||
__int16 veh_predictedcollision;
|
||||
__int16 script_camera;
|
||||
__int16 begin;
|
||||
__int16 curve_nodehit;
|
||||
__int16 curve_start;
|
||||
__int16 curve_end;
|
||||
__int16 tag_enter_driver;
|
||||
__int16 tag_enter_gunner1;
|
||||
__int16 tag_enter_gunner2;
|
||||
__int16 tag_enter_gunner3;
|
||||
__int16 tag_enter_gunner4;
|
||||
__int16 tag_enter_passenger;
|
||||
__int16 tag_enter_passenger2;
|
||||
__int16 tag_enter_passenger3;
|
||||
__int16 tag_enter_passenger4;
|
||||
__int16 tag_player;
|
||||
__int16 tag_passenger1;
|
||||
__int16 tag_passenger2;
|
||||
__int16 tag_passenger3;
|
||||
__int16 tag_passenger4;
|
||||
__int16 tag_gunner1;
|
||||
__int16 tag_gunner2;
|
||||
__int16 tag_gunner3;
|
||||
__int16 tag_gunner4;
|
||||
__int16 tag_gunner_barrel1;
|
||||
__int16 tag_gunner_barrel2;
|
||||
__int16 tag_gunner_barrel3;
|
||||
__int16 tag_gunner_barrel4;
|
||||
__int16 tag_gunner_turret1;
|
||||
__int16 tag_gunner_turret2;
|
||||
__int16 tag_gunner_turret3;
|
||||
__int16 tag_gunner_turret4;
|
||||
__int16 tag_flash_gunner1;
|
||||
__int16 tag_flash_gunner2;
|
||||
__int16 tag_flash_gunner3;
|
||||
__int16 tag_flash_gunner4;
|
||||
__int16 tag_flash_gunner1a;
|
||||
__int16 tag_flash_gunner2a;
|
||||
__int16 tag_flash_gunner3a;
|
||||
__int16 tag_flash_gunner4a;
|
||||
__int16 tag_gunner_brass1;
|
||||
__int16 tag_gunner_hands1;
|
||||
__int16 tag_wheel_front_left;
|
||||
__int16 tag_wheel_front_right;
|
||||
__int16 tag_wheel_back_left;
|
||||
__int16 tag_wheel_back_right;
|
||||
__int16 tag_wheel_middle_left;
|
||||
__int16 tag_wheel_middle_right;
|
||||
__int16 vampire_health_regen;
|
||||
__int16 vampire_kill;
|
||||
__int16 morphine_shot;
|
||||
__int16 morphine_revive;
|
||||
__int16 freelook;
|
||||
__int16 intermission;
|
||||
__int16 playing;
|
||||
__int16 spectator;
|
||||
__int16 action_notify_attack;
|
||||
__int16 action_notify_melee;
|
||||
__int16 action_notify_use_reload;
|
||||
__int16 always;
|
||||
__int16 auto_ai;
|
||||
__int16 auto_nonai;
|
||||
__int16 back_left;
|
||||
__int16 back_right;
|
||||
__int16 begin_custom_anim;
|
||||
__int16 bullethit;
|
||||
__int16 count;
|
||||
__int16 corner_approach;
|
||||
__int16 damage_notdone;
|
||||
__int16 deathplant;
|
||||
__int16 front_left;
|
||||
__int16 front_right;
|
||||
__int16 tag_inhand;
|
||||
__int16 high_priority;
|
||||
__int16 info_player_deathmatch;
|
||||
__int16 infinite_energy;
|
||||
__int16 low_priority;
|
||||
__int16 manual;
|
||||
__int16 manual_ai;
|
||||
__int16 max_time;
|
||||
__int16 menuresponse;
|
||||
__int16 middle_left;
|
||||
__int16 middle_right;
|
||||
__int16 min_energy;
|
||||
__int16 min_time;
|
||||
__int16 neutral;
|
||||
__int16 never;
|
||||
__int16 pickup;
|
||||
__int16 receiver;
|
||||
__int16 sound_blend;
|
||||
__int16 tag_wingtipl;
|
||||
__int16 tag_wingtipr;
|
||||
__int16 tag_wingmidl;
|
||||
__int16 tag_wingmidr;
|
||||
__int16 tag_prop;
|
||||
__int16 tag_end;
|
||||
__int16 tag_tailtop;
|
||||
__int16 tag_tailbottom;
|
||||
__int16 tag_detach;
|
||||
__int16 tag_passenger;
|
||||
__int16 tag_enter_back;
|
||||
__int16 tag_detach2;
|
||||
__int16 tag_popout;
|
||||
__int16 tag_body;
|
||||
__int16 tag_turret;
|
||||
__int16 tag_turret_base;
|
||||
__int16 tag_barrel;
|
||||
__int16 tag_weapon_left;
|
||||
__int16 human;
|
||||
__int16 custom;
|
||||
__int16 angle_deltas;
|
||||
__int16 bulletwhizby;
|
||||
__int16 dog;
|
||||
__int16 enemy;
|
||||
__int16 enemy_visible;
|
||||
__int16 face_angle;
|
||||
__int16 face_current;
|
||||
__int16 face_default;
|
||||
__int16 face_direction;
|
||||
__int16 face_enemy;
|
||||
__int16 face_enemy_or_motion;
|
||||
__int16 face_goal;
|
||||
__int16 face_motion;
|
||||
__int16 face_point;
|
||||
__int16 gravity;
|
||||
__int16 groundEntChanged;
|
||||
__int16 gunshot;
|
||||
__int16 obstacle;
|
||||
__int16 movemode;
|
||||
__int16 node_out_of_range;
|
||||
__int16 node_relinquished;
|
||||
__int16 node_taken;
|
||||
__int16 node_not_safe;
|
||||
__int16 noclip;
|
||||
__int16 nogravity;
|
||||
__int16 nophysics;
|
||||
__int16 pain;
|
||||
__int16 run;
|
||||
__int16 runto_arrived;
|
||||
__int16 silenced_shot;
|
||||
__int16 spawned;
|
||||
__int16 start_move;
|
||||
__int16 stop;
|
||||
__int16 stop_soon;
|
||||
__int16 tag_eye;
|
||||
__int16 walk;
|
||||
__int16 world;
|
||||
__int16 zonly_physics;
|
||||
__int16 j_ankle_le;
|
||||
__int16 j_ankle_ri;
|
||||
__int16 j_ball_le;
|
||||
__int16 j_ball_ri;
|
||||
__int16 j_palm_le;
|
||||
__int16 j_palm_ri;
|
||||
__int16 broken;
|
||||
__int16 destructible;
|
||||
__int16 snapacknowledged;
|
||||
__int16 disconnected;
|
||||
__int16 cinematic;
|
||||
__int16 uicinematic;
|
||||
__int16 logo;
|
||||
__int16 connecting;
|
||||
__int16 challenging;
|
||||
__int16 connected;
|
||||
__int16 sendingstats;
|
||||
__int16 loading;
|
||||
__int16 primed;
|
||||
__int16 active;
|
||||
__int16 map_restart;
|
||||
__int16 orientdone;
|
||||
__int16 field_2B6;
|
||||
};
|
||||
|
||||
|
||||
}
|
@ -12,18 +12,37 @@ namespace game
|
||||
WEAK symbol<void(scriptInstance_t inst)> Scr_AddArray { 0x0, 0x69AA50 };
|
||||
WEAK symbol<unsigned int(scriptInstance_t inst, char* string, int user, unsigned int len)> SL_GetStringOfSize { 0x0, 0x68DE50 };
|
||||
|
||||
WEAK symbol<int(path_t* pPath, team_t eTeam, const float* vStartPos, pathnode_t* pNodeFrom, const float* vGoalPos, int bAllowNegotiationLinks, CustomSearchInfo_FindPath* custom, int bIncludeGoalInPath, pathnode_t* bIgnoreBadPlaces)> Path_AStarAlgorithm_CustomSearchInfo_FindPath_{ 0x0, 0x4D3190 };
|
||||
|
||||
// Variables
|
||||
|
||||
WEAK symbol<cmd_function_s*> cmd_functions{ 0x0, 0x1F416F4 };
|
||||
WEAK symbol<CmdArgs> cmd_args{ 0x0, 0x1F41670 };
|
||||
|
||||
WEAK symbol<GameWorldSp*> gameWorldCurrent{ 0x0, 0x8E1D80 };
|
||||
|
||||
WEAK symbol<pathlocal_t> g_path{ 0x0, 0x1F2F700 };
|
||||
|
||||
WEAK symbol<gentity_s> g_entities{ 0x0, 0x176C6F0 };
|
||||
//WEAK symbol<scrVarPub_t> scrVarPub{ 0x0, 0x3882B70 };
|
||||
WEAK symbol<scrVmPub_t> gScrVmPub{ 0x0, 0x3BD4700 };
|
||||
WEAK symbol<level_locals_s> level{ 0x0, 0x18F5D88 };
|
||||
WEAK symbol<float*> g_pathAttemptGoalPos{ 0x0, 0x16CFD6C };
|
||||
//WEAK symbol<scrParserPub_t> scrParserPub{ 0x0, 0x3882B00 };
|
||||
//WEAK symbol<scrVarGlob_t> gScrVarGlob{ 0x0, 0x3914700 };
|
||||
|
||||
WEAK symbol<scrVmPub_t> scrVmPub{ 0x0, 0x3BD4700 };
|
||||
WEAK symbol<function_stack_t> function_stack{ 0x0, 0x3BDDDD0 };
|
||||
WEAK symbol<scr_const_t> scr_const{0x0, 0x1F33B90};
|
||||
|
||||
// Dvars
|
||||
|
||||
WEAK symbol<dvar_s*> com_developer{ 0x0, 0x1F55288 };
|
||||
WEAK symbol<dvar_s*> com_logfile{ 0x0, 0x1F552BC };
|
||||
WEAK symbol<dvar_s*> com_developer_script{ 0x0, 0x1F9646C };
|
||||
WEAK symbol<dvar_s*> ai_pathNegotiationOverlapCost{ 0x0, 0x18FB224 };
|
||||
WEAK symbol<dvar_s*> fs_homepath{ 0x0, 0x2123C1C };
|
||||
WEAK symbol<dvar_s*> fs_game{ 0x0, 0x2122B00 };
|
||||
WEAK symbol<dvar_s*> useFastFile{ 0x0, 0x1F552FC };
|
||||
WEAK symbol<dvar_s*> sv_running{ 0x0, 0x1F552DC };
|
||||
WEAK symbol<dvar_s*> g_connectpaths{ 0x0, 0x18ECF8C };
|
||||
WEAK symbol<dvar_s*> r_reflectionProbeGenerate{ 0x0, 0x3BFD478 };
|
||||
|
||||
namespace plutonium
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user