mirror of
https://github.com/ENSL/NS.git
synced 2025-02-23 20:31:04 +00:00
Added weldable obstacles back into navigation
Bots now understand how to get around weldable barriers
This commit is contained in:
parent
e72addc6d1
commit
d15e7bfdad
4 changed files with 123 additions and 37 deletions
|
@ -32,9 +32,7 @@
|
||||||
#include "DetourAlloc.h"
|
#include "DetourAlloc.h"
|
||||||
|
|
||||||
vector<nav_door> NavDoors;
|
vector<nav_door> NavDoors;
|
||||||
|
vector<nav_weldable> NavWeldableObstacles;
|
||||||
nav_weldable NavWeldableObstacles[32];
|
|
||||||
int NumWeldableObstacles;
|
|
||||||
|
|
||||||
nav_mesh NavMeshes[MAX_NAV_MESHES]; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
nav_mesh NavMeshes[MAX_NAV_MESHES]; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
||||||
nav_profile BaseNavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
nav_profile BaseNavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
||||||
|
@ -541,11 +539,9 @@ void UnloadNavigationData()
|
||||||
UnloadNavMeshes();
|
UnloadNavMeshes();
|
||||||
|
|
||||||
UTIL_ClearDoorData();
|
UTIL_ClearDoorData();
|
||||||
|
UTIL_ClearWeldablesData();
|
||||||
|
|
||||||
memset(BaseNavProfiles, 0, sizeof(nav_profile));
|
memset(BaseNavProfiles, 0, sizeof(nav_profile));
|
||||||
memset(NavWeldableObstacles, 0, sizeof(NavWeldableObstacles));
|
|
||||||
|
|
||||||
NumWeldableObstacles = 0;
|
|
||||||
|
|
||||||
AIMGR_ClearBotData();
|
AIMGR_ClearBotData();
|
||||||
|
|
||||||
|
@ -905,6 +901,7 @@ void UTIL_PopulateBaseNavProfiles()
|
||||||
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.setIncludeFlags(0xFFFF);
|
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.setIncludeFlags(0xFFFF);
|
||||||
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.setExcludeFlags(0);
|
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.setExcludeFlags(0);
|
||||||
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.addExcludeFlags(SAMPLE_POLYFLAGS_WALLCLIMB);
|
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.addExcludeFlags(SAMPLE_POLYFLAGS_WALLCLIMB);
|
||||||
|
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.addExcludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||||
|
|
||||||
BaseNavProfiles[SKULK_BASE_NAV_PROFILE].NavMeshIndex = REGULAR_NAV_MESH;
|
BaseNavProfiles[SKULK_BASE_NAV_PROFILE].NavMeshIndex = REGULAR_NAV_MESH;
|
||||||
BaseNavProfiles[SKULK_BASE_NAV_PROFILE].bFlyingProfile = false;
|
BaseNavProfiles[SKULK_BASE_NAV_PROFILE].bFlyingProfile = false;
|
||||||
|
@ -2068,9 +2065,21 @@ void CheckAndHandleDoorObstruction(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (FNullEnt(BlockingDoorEdict)) { return; }
|
if (FNullEnt(BlockingDoorEdict)) { return; }
|
||||||
|
|
||||||
CBaseToggle* BlockingDoor = GetClassPtr((CBaseToggle*)VARS(BlockingDoorEdict));
|
CBaseToggle* BlockingDoor = dynamic_cast<CBaseToggle*>(CBaseEntity::Instance(BlockingDoorEdict));
|
||||||
|
|
||||||
if (!BlockingDoor) { return; }
|
if (!BlockingDoor)
|
||||||
|
{
|
||||||
|
AvHWeldable* WeldableRef = dynamic_cast<AvHWeldable*>(CBaseEntity::Instance(BlockingDoorEdict));
|
||||||
|
|
||||||
|
if (!WeldableRef)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AITASK_SetWeldTask(pBot, &pBot->BotNavInfo.MovementTask, BlockingDoorEdict, true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Vector NearestPoint = UTIL_GetClosestPointOnEntityToLocation(pBot->Edict->v.origin, BlockingDoorEdict);
|
Vector NearestPoint = UTIL_GetClosestPointOnEntityToLocation(pBot->Edict->v.origin, BlockingDoorEdict);
|
||||||
|
|
||||||
|
@ -2185,7 +2194,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2207,7 +2217,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2231,7 +2242,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2250,7 +2262,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2272,7 +2285,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2526,7 +2540,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0 )
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2548,7 +2563,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2572,7 +2588,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2592,7 +2609,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -2612,7 +2630,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
||||||
{
|
{
|
||||||
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
if (strcmp(STRING(doorHit.pHit->v.classname), "func_door") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_seethroughdoor") == 0
|
||||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0)
|
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||||
|
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||||
{
|
{
|
||||||
return doorHit.pHit;
|
return doorHit.pHit;
|
||||||
}
|
}
|
||||||
|
@ -4766,13 +4785,15 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
bool bHasMovementTask = (BotNavInfo->MovementTask.TaskType != TASK_NONE);
|
bool bHasMovementTask = (BotNavInfo->MovementTask.TaskType != TASK_NONE);
|
||||||
|
|
||||||
Vector MoveTaskDestination = g_vecZero;
|
Vector MoveTaskDestination = g_vecZero;
|
||||||
|
Vector MoveTaskOrigin = g_vecZero;
|
||||||
|
|
||||||
if (bHasMovementTask)
|
if (bHasMovementTask)
|
||||||
{
|
{
|
||||||
MoveTaskDestination = (!vIsZero(BotNavInfo->MovementTask.TaskLocation)) ? BotNavInfo->MovementTask.TaskLocation : BotNavInfo->MovementTask.TaskTarget->v.origin;
|
MoveTaskDestination = BotNavInfo->MovementTask.TaskLocation;
|
||||||
|
MoveTaskOrigin = (!FNullEnt(BotNavInfo->MovementTask.TaskTarget)) ? BotNavInfo->MovementTask.TaskTarget->v.origin : g_vecZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bUltimateDestinationChanged = !vEquals(Destination, BotNavInfo->TargetDestination, GetPlayerRadius(pBot->Player)) && !vEquals(Destination, MoveTaskDestination);
|
bool bUltimateDestinationChanged = !vEquals(Destination, BotNavInfo->TargetDestination, GetPlayerRadius(pBot->Player)) && !vEquals(Destination, MoveTaskDestination) && !vEquals(Destination, MoveTaskOrigin);
|
||||||
|
|
||||||
bool bHasReachedDestination = BotIsAtLocation(pBot, BotNavInfo->TargetDestination);
|
bool bHasReachedDestination = BotIsAtLocation(pBot, BotNavInfo->TargetDestination);
|
||||||
|
|
||||||
|
@ -4781,13 +4802,17 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
// First abort our current move so we don't try to recalculate half-way up a wall or ladder
|
// First abort our current move so we don't try to recalculate half-way up a wall or ladder
|
||||||
if (bIsFlyingProfile || AbortCurrentMove(pBot, Destination))
|
if (bIsFlyingProfile || AbortCurrentMove(pBot, Destination))
|
||||||
{
|
{
|
||||||
ClearBotPath(pBot);
|
// Don't clear the path if we're in the middle of a movement task
|
||||||
|
if (!vEquals(Destination, MoveTaskDestination) && !vEquals(Destination, MoveTaskOrigin))
|
||||||
|
{
|
||||||
|
ClearBotPath(pBot);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bHasMovementTask && !vEquals(Destination, MoveTaskDestination))
|
if (bHasMovementTask && !vEquals(Destination, MoveTaskDestination) && !vEquals(Destination, MoveTaskOrigin))
|
||||||
{
|
{
|
||||||
if (AITASK_IsTaskStillValid(pBot, &BotNavInfo->MovementTask))
|
if (AITASK_IsTaskStillValid(pBot, &BotNavInfo->MovementTask))
|
||||||
{
|
{
|
||||||
|
@ -4817,6 +4842,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
|
|
||||||
pBot->BotNavInfo.LastPathCalcTime = gpGlobals->time;
|
pBot->BotNavInfo.LastPathCalcTime = gpGlobals->time;
|
||||||
BotNavInfo->bPendingRecalculation = false;
|
BotNavInfo->bPendingRecalculation = false;
|
||||||
|
BotNavInfo->bNavProfileChanged = false;
|
||||||
|
|
||||||
if (vIsZero(BotNavInfo->TargetDestination))
|
if (vIsZero(BotNavInfo->TargetDestination))
|
||||||
{
|
{
|
||||||
|
@ -6468,15 +6494,15 @@ void UTIL_LinkTriggerToDoor(const edict_t* DoorEdict, nav_door* DoorRef)
|
||||||
|
|
||||||
void UTIL_PopulateWeldableObstacles()
|
void UTIL_PopulateWeldableObstacles()
|
||||||
{
|
{
|
||||||
memset(NavWeldableObstacles, 0, sizeof(NavWeldableObstacles));
|
UTIL_ClearWeldablesData();
|
||||||
NumWeldableObstacles = 0;
|
|
||||||
|
|
||||||
CBaseEntity* currWeldable = NULL;
|
CBaseEntity* currWeldable = NULL;
|
||||||
while (((currWeldable = UTIL_FindEntityByClassname(currWeldable, "avhweldable")) != NULL))
|
while (((currWeldable = UTIL_FindEntityByClassname(currWeldable, "avhweldable")) != NULL))
|
||||||
{
|
{
|
||||||
if (currWeldable->pev->solid == SOLID_BSP)
|
if (currWeldable->pev->solid == SOLID_BSP)
|
||||||
{
|
{
|
||||||
NavWeldableObstacles[NumWeldableObstacles].WeldableEdict = currWeldable->edict();
|
nav_weldable NewWeldable;
|
||||||
|
NewWeldable.WeldableEdict = currWeldable->edict();
|
||||||
|
|
||||||
float SizeX = currWeldable->pev->size.x;
|
float SizeX = currWeldable->pev->size.x;
|
||||||
float SizeY = currWeldable->pev->size.y;
|
float SizeY = currWeldable->pev->size.y;
|
||||||
|
@ -6511,11 +6537,11 @@ void UTIL_PopulateWeldableObstacles()
|
||||||
|
|
||||||
Vector CurrentPoint = StartPoint;
|
Vector CurrentPoint = StartPoint;
|
||||||
|
|
||||||
NavWeldableObstacles[NumWeldableObstacles].NumObstacles = NumObstacles;
|
NewWeldable.NumObstacles = NumObstacles;
|
||||||
|
|
||||||
for (int ii = 0; ii < NumObstacles; ii++)
|
for (int ii = 0; ii < NumObstacles; ii++)
|
||||||
{
|
{
|
||||||
UTIL_AddTemporaryObstacles(CurrentPoint, CylinderRadius, SizeZ, DT_TILECACHE_NULL_AREA, NavWeldableObstacles[NumWeldableObstacles].ObstacleRefs[ii]);
|
UTIL_AddTemporaryObstacles(CurrentPoint, CylinderRadius, SizeZ, DT_TILECACHE_WELD_AREA, NewWeldable.ObstacleRefs[ii]);
|
||||||
|
|
||||||
if (bUseXAxis)
|
if (bUseXAxis)
|
||||||
{
|
{
|
||||||
|
@ -6527,7 +6553,7 @@ void UTIL_PopulateWeldableObstacles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NumWeldableObstacles++;
|
NavWeldableObstacles.push_back(NewWeldable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6593,20 +6619,24 @@ void UTIL_UpdateDoors(bool bInitial)
|
||||||
|
|
||||||
void UTIL_UpdateWeldableObstacles()
|
void UTIL_UpdateWeldableObstacles()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NumWeldableObstacles; i++)
|
for (auto it = NavWeldableObstacles.begin(); it != NavWeldableObstacles.end();)
|
||||||
{
|
{
|
||||||
if (NavWeldableObstacles[i].NumObstacles == 0) { continue; }
|
edict_t* WeldableEdict = it->WeldableEdict;
|
||||||
|
|
||||||
edict_t* WeldableEdict = NavWeldableObstacles[i].WeldableEdict;
|
|
||||||
|
|
||||||
if (FNullEnt(WeldableEdict) || WeldableEdict->v.deadflag != DEAD_NO || WeldableEdict->v.solid != SOLID_BSP)
|
if (FNullEnt(WeldableEdict) || WeldableEdict->v.deadflag != DEAD_NO || WeldableEdict->v.solid != SOLID_BSP)
|
||||||
{
|
{
|
||||||
for (int ii = 0; ii < NavWeldableObstacles[i].NumObstacles; ii++)
|
for (int ii = 0; ii < it->NumObstacles; ii++)
|
||||||
{
|
{
|
||||||
UTIL_RemoveTemporaryObstacles(NavWeldableObstacles[i].ObstacleRefs[ii]);
|
UTIL_RemoveTemporaryObstacles(it->ObstacleRefs[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
NavWeldableObstacles[i].NumObstacles = 0;
|
it->NumObstacles = 0;
|
||||||
|
|
||||||
|
it = NavWeldableObstacles.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6666,7 +6696,7 @@ void UTIL_ApplyTempObstaclesToDoor(nav_door* DoorRef, const int Area)
|
||||||
|
|
||||||
for (int ii = 0; ii < NumObstacles; ii++)
|
for (int ii = 0; ii < NumObstacles; ii++)
|
||||||
{
|
{
|
||||||
UTIL_AddTemporaryObstacles(CurrentPoint, CylinderRadius, SizeZ * 2.0f, Area, DoorRef->ObstacleRefs[ii]);
|
UTIL_AddTemporaryObstacles(CurrentPoint, CylinderRadius, SizeZ, Area, DoorRef->ObstacleRefs[ii]);
|
||||||
|
|
||||||
if (bUseXAxis)
|
if (bUseXAxis)
|
||||||
{
|
{
|
||||||
|
@ -6738,12 +6768,46 @@ void UTIL_UpdateDoorTriggers(nav_door* Door)
|
||||||
|
|
||||||
void UTIL_ClearDoorData()
|
void UTIL_ClearDoorData()
|
||||||
{
|
{
|
||||||
|
for (auto it = NavDoors.begin(); it != NavDoors.end(); it++)
|
||||||
|
{
|
||||||
|
if (it->NumObstacles > 0)
|
||||||
|
{
|
||||||
|
for (int ii = 0; ii < it->NumObstacles; ii++)
|
||||||
|
{
|
||||||
|
UTIL_RemoveTemporaryObstacles(it->ObstacleRefs[ii]);
|
||||||
|
}
|
||||||
|
|
||||||
|
it->NumObstacles = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NavDoors.clear();
|
NavDoors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UTIL_ClearWeldablesData()
|
||||||
|
{
|
||||||
|
for (auto it = NavWeldableObstacles.begin(); it != NavWeldableObstacles.end(); it++)
|
||||||
|
{
|
||||||
|
if (it->NumObstacles > 0)
|
||||||
|
{
|
||||||
|
for (int ii = 0; ii < it->NumObstacles; ii++)
|
||||||
|
{
|
||||||
|
UTIL_RemoveTemporaryObstacles(it->ObstacleRefs[ii]);
|
||||||
|
}
|
||||||
|
|
||||||
|
it->NumObstacles = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavWeldableObstacles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Need to add orientated box obstacle for door
|
// TODO: Need to add orientated box obstacle for door
|
||||||
void UTIL_PopulateDoors()
|
void UTIL_PopulateDoors()
|
||||||
{
|
{
|
||||||
|
|
||||||
UTIL_ClearDoorData();
|
UTIL_ClearDoorData();
|
||||||
|
|
||||||
CBaseEntity* currDoor = NULL;
|
CBaseEntity* currDoor = NULL;
|
||||||
|
|
|
@ -425,6 +425,7 @@ void ClearBotPath(AvHAIPlayer* pBot);
|
||||||
void ClearBotStuckMovement(AvHAIPlayer* pBot);
|
void ClearBotStuckMovement(AvHAIPlayer* pBot);
|
||||||
|
|
||||||
void UTIL_ClearDoorData();
|
void UTIL_ClearDoorData();
|
||||||
|
void UTIL_ClearWeldablesData();
|
||||||
|
|
||||||
// Based on the direction the bot wants to move and it's current facing angle, sets the forward and side move, and the directional buttons to make the bot actually move
|
// Based on the direction the bot wants to move and it's current facing angle, sets the forward and side move, and the directional buttons to make the bot actually move
|
||||||
void BotMovementInputs(AvHAIPlayer* pBot);
|
void BotMovementInputs(AvHAIPlayer* pBot);
|
||||||
|
|
|
@ -595,6 +595,7 @@ void AITAC_UpdateMapAIData()
|
||||||
}
|
}
|
||||||
|
|
||||||
UTIL_UpdateDoors(false);
|
UTIL_UpdateDoors(false);
|
||||||
|
UTIL_UpdateWeldableObstacles();
|
||||||
|
|
||||||
AITAC_RefreshHiveData();
|
AITAC_RefreshHiveData();
|
||||||
}
|
}
|
||||||
|
@ -968,15 +969,32 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
||||||
if (vIsZero(BuildingMap[EntIndex].Location) || !vEquals(BaseBuildable->pev->origin, BuildingMap[EntIndex].Location, 5.0f))
|
if (vIsZero(BuildingMap[EntIndex].Location) || !vEquals(BaseBuildable->pev->origin, BuildingMap[EntIndex].Location, 5.0f))
|
||||||
{
|
{
|
||||||
bool bIsOnNavMesh = UTIL_PointIsOnNavmesh(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], UTIL_GetEntityGroundLocation(BuildingEdict), Vector(max_player_use_reach, max_player_use_reach, max_player_use_reach));
|
bool bIsOnNavMesh = UTIL_PointIsOnNavmesh(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], UTIL_GetEntityGroundLocation(BuildingEdict), Vector(max_player_use_reach, max_player_use_reach, max_player_use_reach));
|
||||||
|
|
||||||
if (bIsOnNavMesh)
|
if (bIsOnNavMesh)
|
||||||
{
|
{
|
||||||
bool bIsReachableMarine = UTIL_PointIsReachable(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
bool bIsReachableMarine = UTIL_PointIsReachable(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||||
bool bIsReachableSkulk = UTIL_PointIsReachable(BaseNavProfiles[SKULK_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
bool bIsReachableSkulk = UTIL_PointIsReachable(BaseNavProfiles[SKULK_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||||
bool bIsReachableOnos = UTIL_PointIsReachable(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
bool bIsReachableOnos = UTIL_PointIsReachable(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||||
|
|
||||||
|
// Check if basic marines can reach. If they can then no need to separately check welder marines as they automatically can. If not, separately check for welders.
|
||||||
if (bIsReachableMarine)
|
if (bIsReachableMarine)
|
||||||
{
|
{
|
||||||
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_MARINE;
|
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_MARINE;
|
||||||
|
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_WELDER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nav_profile WelderProfile;
|
||||||
|
memcpy(&WelderProfile, &BaseNavProfiles[MARINE_BASE_NAV_PROFILE], sizeof(nav_profile));
|
||||||
|
|
||||||
|
WelderProfile.Filters.removeExcludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||||
|
|
||||||
|
bool bIsReachableWelder = UTIL_PointIsReachable(WelderProfile, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||||
|
|
||||||
|
if (bIsReachableWelder)
|
||||||
|
{
|
||||||
|
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_WELDER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bIsReachableSkulk)
|
if (bIsReachableSkulk)
|
||||||
|
@ -989,6 +1007,8 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
||||||
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_ONOS;
|
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_ONOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2202,7 +2202,7 @@ void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
if (IsPlayerInUseRange(pBot->Edict, Task->TaskTarget))
|
if (IsPlayerInUseRange(pBot->Edict, Task->TaskTarget))
|
||||||
{
|
{
|
||||||
BotLookAt(pBot, UTIL_GetCentreOfEntity(Task->TaskTarget));
|
BotLookAt(pBot, UTIL_GetClosestPointOnEntityToLocation(pBot->CurrentEyePosition, Task->TaskTarget));
|
||||||
pBot->DesiredCombatWeapon = WEAPON_MARINE_WELDER;
|
pBot->DesiredCombatWeapon = WEAPON_MARINE_WELDER;
|
||||||
|
|
||||||
if (GetBotCurrentWeapon(pBot) != WEAPON_MARINE_WELDER)
|
if (GetBotCurrentWeapon(pBot) != WEAPON_MARINE_WELDER)
|
||||||
|
@ -2714,6 +2714,7 @@ void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Targe
|
||||||
Task->TaskTarget = Target;
|
Task->TaskTarget = Target;
|
||||||
Task->TaskType = TASK_WELD;
|
Task->TaskType = TASK_WELD;
|
||||||
Task->bTaskIsUrgent = bIsUrgent;
|
Task->bTaskIsUrgent = bIsUrgent;
|
||||||
|
Task->TaskLocation = ZERO_VECTOR;
|
||||||
Task->TaskLength = 0.0f;
|
Task->TaskLength = 0.0f;
|
||||||
|
|
||||||
if (IsEdictPlayer(Target) || IsEdictStructure(Target)) { return; }
|
if (IsEdictPlayer(Target) || IsEdictStructure(Target)) { return; }
|
||||||
|
|
Loading…
Reference in a new issue