mirror of
https://github.com/ENSL/NS.git
synced 2025-02-22 20:01:09 +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"
|
||||
|
||||
vector<nav_door> NavDoors;
|
||||
|
||||
nav_weldable NavWeldableObstacles[32];
|
||||
int NumWeldableObstacles;
|
||||
vector<nav_weldable> NavWeldableObstacles;
|
||||
|
||||
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
|
||||
|
@ -541,11 +539,9 @@ void UnloadNavigationData()
|
|||
UnloadNavMeshes();
|
||||
|
||||
UTIL_ClearDoorData();
|
||||
UTIL_ClearWeldablesData();
|
||||
|
||||
memset(BaseNavProfiles, 0, sizeof(nav_profile));
|
||||
memset(NavWeldableObstacles, 0, sizeof(NavWeldableObstacles));
|
||||
|
||||
NumWeldableObstacles = 0;
|
||||
|
||||
AIMGR_ClearBotData();
|
||||
|
||||
|
@ -905,6 +901,7 @@ void UTIL_PopulateBaseNavProfiles()
|
|||
BaseNavProfiles[MARINE_BASE_NAV_PROFILE].Filters.setIncludeFlags(0xFFFF);
|
||||
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_WELD);
|
||||
|
||||
BaseNavProfiles[SKULK_BASE_NAV_PROFILE].NavMeshIndex = REGULAR_NAV_MESH;
|
||||
BaseNavProfiles[SKULK_BASE_NAV_PROFILE].bFlyingProfile = false;
|
||||
|
@ -2068,9 +2065,21 @@ void CheckAndHandleDoorObstruction(AvHAIPlayer* pBot)
|
|||
|
||||
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);
|
||||
|
||||
|
@ -2185,7 +2194,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
|||
{
|
||||
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_door_rotating") == 0)
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||
{
|
||||
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
|
||||
|| 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;
|
||||
}
|
||||
|
@ -2231,7 +2242,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
|||
{
|
||||
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_door_rotating") == 0)
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||
{
|
||||
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
|
||||
|| 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;
|
||||
}
|
||||
|
@ -2272,7 +2285,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNod
|
|||
{
|
||||
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_door_rotating") == 0)
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||
{
|
||||
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
|
||||
|| 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;
|
||||
}
|
||||
|
@ -2548,7 +2563,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
|||
{
|
||||
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_door_rotating") == 0)
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||
{
|
||||
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
|
||||
|| 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;
|
||||
}
|
||||
|
@ -2592,7 +2609,8 @@ edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector T
|
|||
{
|
||||
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_door_rotating") == 0)
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "func_door_rotating") == 0
|
||||
|| strcmp(STRING(doorHit.pHit->v.classname), "avhweldable") == 0)
|
||||
{
|
||||
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
|
||||
|| 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;
|
||||
}
|
||||
|
@ -4766,13 +4785,15 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
bool bHasMovementTask = (BotNavInfo->MovementTask.TaskType != TASK_NONE);
|
||||
|
||||
Vector MoveTaskDestination = g_vecZero;
|
||||
Vector MoveTaskOrigin = g_vecZero;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bHasMovementTask && !vEquals(Destination, MoveTaskDestination))
|
||||
if (bHasMovementTask && !vEquals(Destination, MoveTaskDestination) && !vEquals(Destination, MoveTaskOrigin))
|
||||
{
|
||||
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;
|
||||
BotNavInfo->bPendingRecalculation = false;
|
||||
BotNavInfo->bNavProfileChanged = false;
|
||||
|
||||
if (vIsZero(BotNavInfo->TargetDestination))
|
||||
{
|
||||
|
@ -6468,15 +6494,15 @@ void UTIL_LinkTriggerToDoor(const edict_t* DoorEdict, nav_door* DoorRef)
|
|||
|
||||
void UTIL_PopulateWeldableObstacles()
|
||||
{
|
||||
memset(NavWeldableObstacles, 0, sizeof(NavWeldableObstacles));
|
||||
NumWeldableObstacles = 0;
|
||||
UTIL_ClearWeldablesData();
|
||||
|
||||
CBaseEntity* currWeldable = NULL;
|
||||
while (((currWeldable = UTIL_FindEntityByClassname(currWeldable, "avhweldable")) != NULL))
|
||||
{
|
||||
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 SizeY = currWeldable->pev->size.y;
|
||||
|
@ -6511,11 +6537,11 @@ void UTIL_PopulateWeldableObstacles()
|
|||
|
||||
Vector CurrentPoint = StartPoint;
|
||||
|
||||
NavWeldableObstacles[NumWeldableObstacles].NumObstacles = NumObstacles;
|
||||
NewWeldable.NumObstacles = NumObstacles;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -6527,7 +6553,7 @@ void UTIL_PopulateWeldableObstacles()
|
|||
}
|
||||
}
|
||||
|
||||
NumWeldableObstacles++;
|
||||
NavWeldableObstacles.push_back(NewWeldable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6593,20 +6619,24 @@ void UTIL_UpdateDoors(bool bInitial)
|
|||
|
||||
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 = NavWeldableObstacles[i].WeldableEdict;
|
||||
edict_t* WeldableEdict = it->WeldableEdict;
|
||||
|
||||
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++)
|
||||
{
|
||||
UTIL_AddTemporaryObstacles(CurrentPoint, CylinderRadius, SizeZ * 2.0f, Area, DoorRef->ObstacleRefs[ii]);
|
||||
UTIL_AddTemporaryObstacles(CurrentPoint, CylinderRadius, SizeZ, Area, DoorRef->ObstacleRefs[ii]);
|
||||
|
||||
if (bUseXAxis)
|
||||
{
|
||||
|
@ -6738,12 +6768,46 @@ void UTIL_UpdateDoorTriggers(nav_door* Door)
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
void UTIL_PopulateDoors()
|
||||
{
|
||||
|
||||
UTIL_ClearDoorData();
|
||||
|
||||
CBaseEntity* currDoor = NULL;
|
||||
|
|
|
@ -425,6 +425,7 @@ void ClearBotPath(AvHAIPlayer* pBot);
|
|||
void ClearBotStuckMovement(AvHAIPlayer* pBot);
|
||||
|
||||
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
|
||||
void BotMovementInputs(AvHAIPlayer* pBot);
|
||||
|
|
|
@ -595,6 +595,7 @@ void AITAC_UpdateMapAIData()
|
|||
}
|
||||
|
||||
UTIL_UpdateDoors(false);
|
||||
UTIL_UpdateWeldableObstacles();
|
||||
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
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)
|
||||
|
@ -989,6 +1007,8 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
BuildingMap[EntIndex].ReachabilityFlags |= AI_REACHABILITY_ONOS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2202,7 +2202,7 @@ void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
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;
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) != WEAPON_MARINE_WELDER)
|
||||
|
@ -2714,6 +2714,7 @@ void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Targe
|
|||
Task->TaskTarget = Target;
|
||||
Task->TaskType = TASK_WELD;
|
||||
Task->bTaskIsUrgent = bIsUrgent;
|
||||
Task->TaskLocation = ZERO_VECTOR;
|
||||
Task->TaskLength = 0.0f;
|
||||
|
||||
if (IsEdictPlayer(Target) || IsEdictStructure(Target)) { return; }
|
||||
|
|
Loading…
Reference in a new issue