Skip to content

Commit

Permalink
Add more ways to collect Nav Areas (#42)
Browse files Browse the repository at this point in the history
* Added CNavArea.GetAdjacent/IncomingConnectionLength natives
* Deprecate SurroundingAreasCollector in favor of AreasCollector
  • Loading branch information
KitRifty authored Aug 3, 2023
1 parent aa60c6b commit b5dd18a
Show file tree
Hide file tree
Showing 7 changed files with 457 additions and 13 deletions.
4 changes: 2 additions & 2 deletions extension/extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ConVar* sourcemod_version = nullptr;
IBaseNPC_Tools* g_pBaseNPCTools = new BaseNPC_Tools_API;
std::vector<sp_nativeinfo_t> gNatives;

DEFINEHANDLEOBJ(SurroundingAreasCollector, CUtlVector< CNavArea* >);
DEFINEHANDLEOBJ(AreasCollector, CUtlVector< CNavArea* >);

ConVar* g_cvDeveloper = nullptr;
extern ConVar* NextBotSpeedLookAheadRange;
Expand Down Expand Up @@ -102,7 +102,7 @@ bool CBaseNPCExt::SDK_OnLoad(char* error, size_t maxlength, bool late) {
GETGAMEDATAOFFSET("CBaseEntity::Event_Killed", iOffset);
SH_MANUALHOOK_RECONFIGURE(MEvent_Killed, iOffset, 0, 0);

CREATEHANDLETYPE(SurroundingAreasCollector);
CREATEHANDLETYPE(AreasCollector);

sharesys->AddDependency(myself, "bintools.ext", true, true);
sharesys->AddDependency(myself, "sdktools.ext", true, true);
Expand Down
4 changes: 2 additions & 2 deletions extension/extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ extern HandleType_t HANDLENAME(PluginPathFollower);
extern HandleType_t HANDLENAME(PluginBotReply);
extern HandleType_t HANDLENAME(PluginBotEntityFilter);

extern HandleType_t HANDLENAME(SurroundingAreasCollector);
extern HandleType_t HANDLENAME(TSurroundingAreasCollector);
extern HandleType_t HANDLENAME(AreasCollector);
extern HandleType_t HANDLENAME(TAreasCollector);

extern HandleType_t g_CellArrayHandle;
extern HandleType_t g_KeyValueType;
Expand Down
68 changes: 64 additions & 4 deletions extension/natives/nav.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

namespace natives::nav {

namespace surroundingareas {
namespace collector {

inline CUtlVector<CNavArea*>* Get(IPluginContext* context, const cell_t param) {
HandleSecurity security;
security.pOwner = nullptr;
security.pIdentity = myself->GetIdentity();
Handle_t hndlObject = static_cast<Handle_t>(param);
CUtlVector<CNavArea*>* collector = nullptr;
READHANDLE(hndlObject, SurroundingAreasCollector, collector)
READHANDLE(hndlObject, AreasCollector, collector)
return collector;
}

Expand All @@ -36,6 +36,8 @@ cell_t GetElement(IPluginContext* context, const cell_t* params) {

void setup(std::vector<sp_nativeinfo_t>& natives) {
sp_nativeinfo_t list[] = {
{"AreasCollector.Count", GetCount},
{"AreasCollector.Get", GetElement},
{"SurroundingAreasCollector.Count", GetCount},
{"SurroundingAreasCollector.Get", GetElement},
};
Expand Down Expand Up @@ -94,10 +96,65 @@ cell_t GetNavAreaByID(IPluginContext* context, const cell_t* params) {
return PtrToPawnAddress(ToolsNavMesh->GetNavAreaByID(id));
}

class CCollectorAddToTail {
public:
CCollectorAddToTail( CUtlVector<CNavArea*>* vec ) : m_vec( vec ) {}
bool operator() ( CNavArea *area ) { m_vec->AddToTail(area); return true; }

private:
CUtlVector<CNavArea*>* m_vec;
};

cell_t CollectSurroundingAreas(IPluginContext* context, const cell_t* params) {
CUtlVector<CNavArea*> *pCollector = new CUtlVector<CNavArea*>;
CollectSurroundingAreas( pCollector, (CNavArea*)PawnAddressToPtr(params[2]), sp_ctof(params[3]), sp_ctof(params[4]), sp_ctof(params[5]));
return CREATEHANDLE(SurroundingAreasCollector, pCollector);
return CREATEHANDLE(AreasCollector, pCollector);
}

cell_t CollectAreasOverlappingExtent(IPluginContext* context, const cell_t* params) {
Vector lo; Vector hi; cell_t* addr;
context->LocalToPhysAddr(params[2], &addr);
PawnVectorToVector(addr, lo);
context->LocalToPhysAddr(params[3], &addr);
PawnVectorToVector(addr, hi);

Extent extent;
extent.Init();
extent.lo = lo;
extent.hi = hi;

CUtlVector<CNavArea*> *pCollector = new CUtlVector<CNavArea*>;
CCollectorAddToTail addToTail(pCollector);

ToolsNavMesh->ForAllAreasOverlappingExtent(addToTail, extent);
return CREATEHANDLE(AreasCollector, pCollector);
}

cell_t CollectAreasInRadius(IPluginContext* context, const cell_t* params) {
cell_t* posAddr; Vector pos;
context->LocalToPhysAddr(params[2], &posAddr);
PawnVectorToVector(posAddr, pos);

float radius = sp_ctof(params[3]);

CUtlVector<CNavArea*> *pCollector = new CUtlVector<CNavArea*>;
CCollectorAddToTail addToTail(pCollector);

ToolsNavMesh->ForAllAreasInRadius(addToTail, pos, radius);
return CREATEHANDLE(AreasCollector, pCollector);
}

cell_t CollectAreasAlongLine(IPluginContext* context, const cell_t* params) {
CNavArea* startArea = (CNavArea*)PawnAddressToPtr(params[2]);
CNavArea* endArea = (CNavArea*)PawnAddressToPtr(params[3]);
cell_t* reachedEndAddr;
context->LocalToPhysAddr(params[4], &reachedEndAddr);

CUtlVector<CNavArea*> *pCollector = new CUtlVector<CNavArea*>;
CCollectorAddToTail addToTail(pCollector);

*reachedEndAddr = ToolsNavMesh->ForAllAreasAlongLine(addToTail, startArea, endArea) ? 1 : 0;
return CREATEHANDLE(AreasCollector, pCollector);
}

class SMPathCost : public IPathCost
Expand Down Expand Up @@ -199,7 +256,7 @@ cell_t BuildPath(IPluginContext* context, const cell_t* params) {

void setup(std::vector<sp_nativeinfo_t>& natives) {
area::setup(natives);
surroundingareas::setup(natives);
collector::setup(natives);

tf::nav::setup(natives);

Expand All @@ -210,6 +267,9 @@ void setup(std::vector<sp_nativeinfo_t>& natives) {
{"CNavMesh.IsOutOfDate", IsOutOfDate},
{"CNavMesh.GetNavAreaCount", GetNavAreaCount},
{"CNavMesh.CollectSurroundingAreas", CollectSurroundingAreas},
{"CNavMesh.CollectAreasOverlappingExtent", CollectAreasOverlappingExtent},
{"CNavMesh.CollectAreasInRadius", CollectAreasInRadius},
{"CNavMesh.CollectAreasAlongLine", CollectAreasAlongLine},
{"CNavMesh.GetNavAreaByID", GetNavAreaByID},
{"CNavMesh.GetNearestNavArea", GetNearestNavArea},
{"CNavMesh.BuildPath", BuildPath},
Expand Down
46 changes: 44 additions & 2 deletions extension/natives/nav/area.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,26 @@ cell_t GetAdjacentArea(IPluginContext* context, const cell_t* params) {
return PtrToPawnAddress(area->GetAdjacentArea(dir, params[3]));
}

cell_t GetAdjacentLength(IPluginContext* context, const cell_t* params) {
auto area = Get(context, params[1]);
if (!area) {
return 0;
}

NavDirType dir = (NavDirType)params[2];
if (dir < 0 || dir >= NUM_DIRECTIONS) {
return context->ThrowNativeError("Invalid direction %d", dir);
}

int i = params[3];
const NavConnectVector *adjacent = area->GetAdjacentAreas(dir);
if (i < 0 || i >= adjacent->Count()) {
return context->ThrowNativeError("Array index %d is out of bounds (array size: %d)", i, adjacent->Count());
}

return sp_ftoc(adjacent->Element(i).length);
}

cell_t GetIncomingConnectionsCount(IPluginContext* context, const cell_t* params) {
auto area = Get(context, params[1]);
if (!area) {
Expand All @@ -583,7 +603,7 @@ cell_t GetIncomingConnectionsCount(IPluginContext* context, const cell_t* params
return area->GetIncomingConnections(dir)->Count();
}

cell_t GetIncomingConnections(IPluginContext* context, const cell_t* params) {
cell_t GetIncomingConnection(IPluginContext* context, const cell_t* params) {
auto area = Get(context, params[1]);
if (!area) {
return 0;
Expand All @@ -602,6 +622,26 @@ cell_t GetIncomingConnections(IPluginContext* context, const cell_t* params) {
return PtrToPawnAddress(incoming->Element(i).area);
}

cell_t GetIncomingConnectionLength(IPluginContext* context, const cell_t* params) {
auto area = Get(context, params[1]);
if (!area) {
return 0;
}

NavDirType dir = (NavDirType)params[2];
if (dir < 0 || dir >= NUM_DIRECTIONS) {
return context->ThrowNativeError("Invalid direction %d", dir);
}

int i = params[3];
const NavConnectVector *incoming = area->GetIncomingConnections(dir);
if (i < 0 || i >= incoming->Count()) {
return context->ThrowNativeError("Array index %d is out of bounds (array size: %d)", i, incoming->Count());
}

return sp_ftoc(incoming->Element(i).length);
}

cell_t IsEdge(IPluginContext* context, const cell_t* params) {
auto area = Get(context, params[1]);
if (!area) {
Expand Down Expand Up @@ -881,6 +921,7 @@ void setup(std::vector<sp_nativeinfo_t>& natives) {
{"CNavArea.GetCenter", GetCenter},
{"CNavArea.GetAdjacentCount", GetAdjacentCount},
{"CNavArea.GetAdjacentArea", GetAdjacentArea},
{"CNavArea.GetAdjacentLength", GetAdjacentLength},
{"CNavArea.IsConnected", IsConnected},
{"CNavArea.IsOverlappingX", IsOverlappingX},
{"CNavArea.IsOverlappingY", IsOverlappingY},
Expand All @@ -889,7 +930,8 @@ void setup(std::vector<sp_nativeinfo_t>& natives) {
{"CNavArea.IsOverlappingExtent", IsOverlappingExtent},
{"CNavArea.GetExtent", GetExtent},
{"CNavArea.GetIncomingConnectionCount", GetIncomingConnectionsCount},
{"CNavArea.GetIncomingConnection", GetIncomingConnections},
{"CNavArea.GetIncomingConnection", GetIncomingConnection},
{"CNavArea.GetIncomingConnectionLength", GetIncomingConnectionLength},
{"CNavArea.IsEdge", IsEdge},
{"CNavArea.Contains", Contains},
{"CNavArea.ContainsPoint", ContainsPoint},
Expand Down
Loading

0 comments on commit b5dd18a

Please sign in to comment.