mirror of
https://github.com/ENSL/NS.git
synced 2025-04-20 16:30:56 +00:00
Reworked nav profiles
Nav profiles for bots are now dynamically updated to take into account changing capabilities, such as picking up a welder
This commit is contained in:
parent
f8951d672b
commit
b7db5adcaa
15 changed files with 1232 additions and 1066 deletions
|
@ -3,6 +3,9 @@
|
|||
#ifndef AVH_AI_CONSTANTS_H
|
||||
#define AVH_AI_CONSTANTS_H
|
||||
|
||||
#include "DetourStatus.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
#include "../AvHHive.h"
|
||||
#include "../AvHEntities.h"
|
||||
|
||||
|
@ -98,7 +101,8 @@ typedef enum _AI_REACHABILITY_STATUS
|
|||
AI_REACHABILITY_NONE = 0,
|
||||
AI_REACHABILITY_MARINE = 1u << 0,
|
||||
AI_REACHABILITY_SKULK = 1u << 1,
|
||||
AI_REACHABILITY_ONOS = 1u << 2
|
||||
AI_REACHABILITY_ONOS = 1u << 2,
|
||||
AI_REACHABILITY_WELDER = 1u << 3,
|
||||
} AvHAIReachabilityStatus;
|
||||
|
||||
// Data structure used to track resource nodes in the map
|
||||
|
@ -189,6 +193,15 @@ typedef enum _STRUCTUREPURPOSE
|
|||
|
||||
} StructurePurpose;
|
||||
|
||||
// A nav profile combines a nav mesh reference (indexed into NavMeshes) and filters to determine how a bot should find paths
|
||||
typedef struct _NAV_PROFILE
|
||||
{
|
||||
int NavMeshIndex = -1;
|
||||
dtQueryFilter Filters;
|
||||
bool bFlyingProfile = false;
|
||||
AvHAIReachabilityStatus ReachabilityFlag = AI_REACHABILITY_NONE;
|
||||
} nav_profile;
|
||||
|
||||
typedef struct _DEPLOYABLE_SEARCH_FILTER
|
||||
{
|
||||
unsigned int DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
|
@ -434,7 +447,6 @@ typedef struct _NAV_STATUS
|
|||
|
||||
BotMoveStyle MoveStyle = MOVESTYLE_NORMAL; // Current desired move style (e.g. normal, ambush, hide). Will trigger new path calculations if this changes
|
||||
float LastPathCalcTime = 0.0f; // When the bot last calculated a path, to limit how frequently it can recalculate
|
||||
int LastMoveProfile = -1; // The last navigation profile used by the bot. Will trigger new path calculations if this changes (e.g. changed class, changed move style)
|
||||
|
||||
bool bPendingRecalculation = false; // This bot should recalculate its path as soon as it can
|
||||
|
||||
|
@ -443,6 +455,9 @@ typedef struct _NAV_STATUS
|
|||
|
||||
AvHAIPlayerTask MovementTask;
|
||||
|
||||
nav_profile NavProfile;
|
||||
bool bNavProfileChanged = false;
|
||||
|
||||
} nav_status;
|
||||
|
||||
// Type of goal the commander wants to achieve
|
||||
|
@ -506,6 +521,7 @@ typedef struct AVH_AI_PLAYER
|
|||
byte AdjustedMsec = 0;
|
||||
|
||||
bool bIsPendingKill = false;
|
||||
bool bIsInactive = false;
|
||||
|
||||
float LastUseTime = 0.0f;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "../AvHGamerules.h"
|
||||
|
||||
int m_spriteTexture;
|
||||
|
||||
bool UTIL_CommanderTrace(const edict_t* pEdict, const Vector& start, const Vector& end)
|
||||
{
|
||||
TraceResult hit;
|
||||
|
@ -239,4 +241,121 @@ bool GetNearestMapLocationAtPoint(vec3_t SearchLocation, string& outLocation)
|
|||
}
|
||||
|
||||
return theSuccess;
|
||||
}
|
||||
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end)
|
||||
{
|
||||
if (FNullEnt(pEntity) || pEntity->free) { return; }
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity);
|
||||
WRITE_BYTE(TE_BEAMPOINTS);
|
||||
WRITE_COORD(start.x);
|
||||
WRITE_COORD(start.y);
|
||||
WRITE_COORD(start.z);
|
||||
WRITE_COORD(end.x);
|
||||
WRITE_COORD(end.y);
|
||||
WRITE_COORD(end.z);
|
||||
WRITE_SHORT(m_spriteTexture);
|
||||
WRITE_BYTE(1); // framestart
|
||||
WRITE_BYTE(10); // framerate
|
||||
WRITE_BYTE(1); // life in 0.1's
|
||||
WRITE_BYTE(5); // width
|
||||
WRITE_BYTE(0); // noise
|
||||
|
||||
WRITE_BYTE(255); // r, g, b
|
||||
WRITE_BYTE(255); // r, g, b
|
||||
WRITE_BYTE(255); // r, g, b
|
||||
|
||||
WRITE_BYTE(250); // brightness
|
||||
WRITE_BYTE(5); // speed
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, float drawTimeSeconds)
|
||||
{
|
||||
if (FNullEnt(pEntity) || pEntity->free) { return; }
|
||||
|
||||
int timeTenthSeconds = (int)floorf(drawTimeSeconds * 10.0f);
|
||||
timeTenthSeconds = fmaxf(timeTenthSeconds, 1);
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity);
|
||||
WRITE_BYTE(TE_BEAMPOINTS);
|
||||
WRITE_COORD(start.x);
|
||||
WRITE_COORD(start.y);
|
||||
WRITE_COORD(start.z);
|
||||
WRITE_COORD(end.x);
|
||||
WRITE_COORD(end.y);
|
||||
WRITE_COORD(end.z);
|
||||
WRITE_SHORT(m_spriteTexture);
|
||||
WRITE_BYTE(1); // framestart
|
||||
WRITE_BYTE(10); // framerate
|
||||
WRITE_BYTE(timeTenthSeconds); // life in 0.1's
|
||||
WRITE_BYTE(5); // width
|
||||
WRITE_BYTE(0); // noise
|
||||
|
||||
WRITE_BYTE(255); // r, g, b
|
||||
WRITE_BYTE(255); // r, g, b
|
||||
WRITE_BYTE(255); // r, g, b
|
||||
|
||||
WRITE_BYTE(250); // brightness
|
||||
WRITE_BYTE(5); // speed
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, float drawTimeSeconds, int r, int g, int b)
|
||||
{
|
||||
if (FNullEnt(pEntity) || pEntity->free) { return; }
|
||||
|
||||
int timeTenthSeconds = (int)floorf(drawTimeSeconds * 10.0f);
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity);
|
||||
WRITE_BYTE(TE_BEAMPOINTS);
|
||||
WRITE_COORD(start.x);
|
||||
WRITE_COORD(start.y);
|
||||
WRITE_COORD(start.z);
|
||||
WRITE_COORD(end.x);
|
||||
WRITE_COORD(end.y);
|
||||
WRITE_COORD(end.z);
|
||||
WRITE_SHORT(m_spriteTexture);
|
||||
WRITE_BYTE(1); // framestart
|
||||
WRITE_BYTE(10); // framerate
|
||||
WRITE_BYTE(timeTenthSeconds); // life in 0.1's
|
||||
WRITE_BYTE(5); // width
|
||||
WRITE_BYTE(0); // noise
|
||||
|
||||
WRITE_BYTE(r); // r, g, b
|
||||
WRITE_BYTE(g); // r, g, b
|
||||
WRITE_BYTE(b); // r, g, b
|
||||
|
||||
WRITE_BYTE(250); // brightness
|
||||
WRITE_BYTE(5); // speed
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, int r, int g, int b)
|
||||
{
|
||||
if (FNullEnt(pEntity) || pEntity->free) { return; }
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity);
|
||||
WRITE_BYTE(TE_BEAMPOINTS);
|
||||
WRITE_COORD(start.x);
|
||||
WRITE_COORD(start.y);
|
||||
WRITE_COORD(start.z);
|
||||
WRITE_COORD(end.x);
|
||||
WRITE_COORD(end.y);
|
||||
WRITE_COORD(end.z);
|
||||
WRITE_SHORT(m_spriteTexture);
|
||||
WRITE_BYTE(1); // framestart
|
||||
WRITE_BYTE(10); // framerate
|
||||
WRITE_BYTE(1); // life in 0.1's
|
||||
WRITE_BYTE(5); // width
|
||||
WRITE_BYTE(0); // noise
|
||||
|
||||
WRITE_BYTE(r); // r, g, b
|
||||
WRITE_BYTE(g); // r, g, b
|
||||
WRITE_BYTE(b); // r, g, b
|
||||
|
||||
WRITE_BYTE(250); // brightness
|
||||
WRITE_BYTE(5); // speed
|
||||
MESSAGE_END();
|
||||
}
|
|
@ -30,4 +30,13 @@ bool GetNearestMapLocationAtPoint(vec3_t SearchLocation, string& outLocation);
|
|||
|
||||
AvHAIDeployableStructureType GetDeployableObjectTypeFromEdict(const edict_t* StructureEdict);
|
||||
|
||||
// Draws a white line between start and end for the given player (pEntity) for 0.1s
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end);
|
||||
// Draws a white line between start and end for the given player (pEntity) for given number of seconds
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, float drawTimeSeconds);
|
||||
// Draws a coloured line using RGB input, between start and end for the given player (pEntity) for 0.1s
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, int r, int g, int b);
|
||||
// Draws a coloured line using RGB input, between start and end for the given player (pEntity) for given number of seconds
|
||||
void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, float drawTimeSeconds, int r, int g, int b);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -19,74 +19,48 @@
|
|||
cannot wall climb, and has a higher cost for crouch movement since it's slower.
|
||||
*/
|
||||
|
||||
constexpr auto MARINE_REGULAR_NAV_PROFILE = 0;
|
||||
|
||||
constexpr auto SKULK_REGULAR_NAV_PROFILE = 1;
|
||||
constexpr auto SKULK_AMBUSH_NAV_PROFILE = 2;
|
||||
|
||||
constexpr auto GORGE_REGULAR_NAV_PROFILE = 3;
|
||||
constexpr auto GORGE_HIDE_NAV_PROFILE = 4;
|
||||
|
||||
constexpr auto FADE_REGULAR_NAV_PROFILE = 5;
|
||||
|
||||
constexpr auto ONOS_REGULAR_NAV_PROFILE = 6;
|
||||
|
||||
constexpr auto BUILDING_REGULAR_NAV_PROFILE = 7;
|
||||
|
||||
constexpr auto ALL_NAV_PROFILE = 8;
|
||||
|
||||
constexpr auto LERK_FLYING_NAV_PROFILE = 9;
|
||||
|
||||
constexpr auto GORGE_BUILD_NAV_PROFILE = 10;
|
||||
|
||||
constexpr auto MARINE_WELD_NAV_PROFILE = 11;
|
||||
|
||||
constexpr auto MIN_PATH_RECALC_TIME = 0.33f; // How frequently can a bot recalculate its path? Default to max 3 times per second
|
||||
|
||||
constexpr auto MAX_BOT_STUCK_TIME = 30.0f; // How long a bot can be stuck, unable to move, before giving up and suiciding
|
||||
|
||||
constexpr auto MARINE_BASE_NAV_PROFILE = 0;
|
||||
constexpr auto SKULK_BASE_NAV_PROFILE = 1;
|
||||
constexpr auto GORGE_BASE_NAV_PROFILE = 2;
|
||||
constexpr auto LERK_BASE_NAV_PROFILE = 3;
|
||||
constexpr auto FADE_BASE_NAV_PROFILE = 4;
|
||||
constexpr auto ONOS_BASE_NAV_PROFILE = 5;
|
||||
constexpr auto STRUCTURE_BASE_NAV_PROFILE = 6;
|
||||
constexpr auto ALL_NAV_PROFILE = 7;
|
||||
|
||||
#define MAX_PATH_POLY 512 // Max nav mesh polys that can be traversed in a path. This should be sufficient for any sized map.
|
||||
|
||||
// Possible area types. Water, Road, Door and Grass are not used (left-over from Detour library)
|
||||
enum SamplePolyAreas
|
||||
{
|
||||
SAMPLE_POLYAREA_GROUND = 0, // Regular ground movement
|
||||
SAMPLE_POLYAREA_CROUCH = 1, // Requires crouched movement
|
||||
SAMPLE_POLYAREA_WATER = 2, // Swimming (NOT USED)
|
||||
SAMPLE_POLYAREA_BLOCKED = 3, // Requires a jump to get over
|
||||
SAMPLE_POLYAREA_WALLCLIMB = 4, // Requires the ability to wall climb (i.e. skulks/fades/lerks only)
|
||||
SAMPLE_POLYAREA_LADDER = 5, // Requires climbing a ladder (ignored by skulks)
|
||||
SAMPLE_POLYAREA_DOOR = 6, // Requires moving through a door (NOT USED)
|
||||
SAMPLE_POLYAREA_JUMP = 7, // Requires a jump to get through
|
||||
SAMPLE_POLYAREA_HIGHJUMP = 8, // Requires jumping from a great height
|
||||
SAMPLE_POLYAREA_FALL = 9, // Requires dropping down from a higher elevation
|
||||
SAMPLE_POLYAREA_HIGHFALL = 10, // Requires a large drop from a high height
|
||||
SAMPLE_POLYAREA_PHASEGATE = 11, // Requires accessing a phase gate (i.e. marines only)
|
||||
SAMPLE_POLYAREA_MSTRUCTURE = 12, // Requires bypassing a marine structure
|
||||
SAMPLE_POLYAREA_ASTRUCTURE = 13, // Requires bypassing an alien structure
|
||||
SAMPLE_POLYAREA_FLY = 14, // Requires the ability to fly (currently lerks only)
|
||||
SAMPLE_POLYAREA_GROUND = 0, // Regular ground movement
|
||||
SAMPLE_POLYAREA_CROUCH = 1, // Requires crouched movement
|
||||
SAMPLE_POLYAREA_BLOCKED = 2, // Requires a jump to get over
|
||||
SAMPLE_POLYAREA_FALLDAMAGE = 3, // Requires taking fall damage (if not immune to it)
|
||||
SAMPLE_POLYAREA_WALLCLIMB = 4 // Requires the ability to wall-stick, fly or blink
|
||||
};
|
||||
|
||||
// Possible movement types. Swim and door are not used
|
||||
enum SamplePolyFlags
|
||||
{
|
||||
SAMPLE_POLYFLAGS_WALK = 1 << 0, // Simple walk to traverse
|
||||
SAMPLE_POLYFLAGS_BLOCKED = 1 << 1, // Blocked by an obstruction, but can be jumped over
|
||||
SAMPLE_POLYFLAGS_WALLCLIMB = 1 << 2, // Requires climbing a wall to traverse
|
||||
SAMPLE_POLYFLAGS_LADDER = 1 << 3, // Requires climbing a ladder to traverse
|
||||
SAMPLE_POLYFLAGS_DOOR = 1 << 4, // Requires opening a door to traverse (not used)
|
||||
SAMPLE_POLYFLAGS_JUMP = 1 << 5, // Requires a jump to traverse
|
||||
SAMPLE_POLYFLAGS_HIGHJUMP = 1 << 6, // Requires a jump from a high height to traverse
|
||||
SAMPLE_POLYFLAGS_FALL = 1 << 7, // Requires dropping down from a safe height to traverse
|
||||
SAMPLE_POLYFLAGS_HIGHFALL = 1 << 8, // Requires dropping from a high height to traverse
|
||||
SAMPLE_POLYFLAGS_DISABLED = 1 << 9, // Disabled, not usable by anyone
|
||||
SAMPLE_POLYFLAGS_NOONOS = 1 << 10, // This movement is not allowed by onos
|
||||
SAMPLE_POLYFLAGS_PHASEGATE = 1 << 11, // Requires using a phase gate to traverse
|
||||
SAMPLE_POLYFLAGS_MSTRUCTURE = 1 << 12, // Marine Structure in the way, must be destroyed if alien, or impassable if marine
|
||||
SAMPLE_POLYFLAGS_ASTRUCTURE = 1 << 13, // Structure in the way, must be destroyed if marine, or impassable if alien
|
||||
SAMPLE_POLYFLAGS_WELD = 1 << 14, // Requires a welder to get through here
|
||||
SAMPLE_POLYFLAGS_ALL = 0xffff // All abilities.
|
||||
SAMPLE_POLYFLAGS_WALK = 1 << 0, // Simple walk to traverse
|
||||
SAMPLE_POLYFLAGS_FALL = 1 << 1, // Required dropping down
|
||||
SAMPLE_POLYFLAGS_BLOCKED = 1 << 2, // Blocked by an obstruction, but can be jumped over
|
||||
SAMPLE_POLYFLAGS_WALLCLIMB = 1 << 3, // Requires climbing a wall to traverse
|
||||
SAMPLE_POLYFLAGS_LADDER = 1 << 4, // Requires climbing a ladder to traverse
|
||||
SAMPLE_POLYFLAGS_JUMP = 1 << 5, // Requires a regular jump to traverse
|
||||
SAMPLE_POLYFLAGS_DUCKJUMP = 1 << 6, // Requires a duck-jump to traverse
|
||||
SAMPLE_POLYFLAGS_NOONOS = 1 << 7, // This movement is not allowed by onos
|
||||
SAMPLE_POLYFLAGS_PHASEGATE = 1 << 8, // Requires using a phase gate to traverse
|
||||
SAMPLE_POLYFLAGS_TEAM1STRUCTURE = 1 << 9, // A team 1 structure is in the way that cannot be jumped over. Impassable to team 1 players
|
||||
SAMPLE_POLYFLAGS_TEAM2STRUCTURE = 1 << 10, // A team 2 structure is in the way that cannot be jumped over. Impassable to team 2 players
|
||||
SAMPLE_POLYFLAGS_WELD = 1 << 11, // Requires a welder to get through here
|
||||
|
||||
SAMPLE_POLYFLAGS_DISABLED = 1 << 15, // Disabled, not usable by anyone
|
||||
SAMPLE_POLYFLAGS_ALL = 0xffff // All abilities.
|
||||
};
|
||||
|
||||
// Door type. Not currently used, future feature so bots know how to open a door
|
||||
|
@ -145,14 +119,6 @@ typedef struct _NAV_MESH
|
|||
class dtNavMesh* navMesh;
|
||||
} nav_mesh;
|
||||
|
||||
// A nav profile combines a nav mesh reference (indexed into NavMeshes) and filters to determine how a bot should find paths
|
||||
typedef struct _NAV_PROFILE
|
||||
{
|
||||
int NavMeshIndex = -1;
|
||||
dtQueryFilter Filters;
|
||||
bool bFlyingProfile = false;
|
||||
AvHAIReachabilityStatus ReachabilityFlag = AI_REACHABILITY_NONE;
|
||||
} nav_profile;
|
||||
|
||||
static const int NAVMESHSET_MAGIC = 'M' << 24 | 'S' << 16 | 'E' << 8 | 'T'; //'MSET', used to confirm the nav mesh we're loading is compatible;
|
||||
static const int NAVMESHSET_VERSION = 1;
|
||||
|
@ -181,7 +147,7 @@ static const int DOOR_START_OPEN = 1;
|
|||
static const float CHECK_STUCK_INTERVAL = 0.1f; // How frequently should the bot check if it's stuck?
|
||||
|
||||
static nav_mesh NavMeshes[MAX_NAV_MESHES]; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
||||
static nav_profile NavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
||||
static nav_profile BaseNavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
||||
|
||||
// Returns true if a valid nav mesh has been loaded into memory
|
||||
bool NavmeshLoaded();
|
||||
|
@ -196,6 +162,15 @@ bool LoadNavMesh(const char* mapname);
|
|||
// Unloads the nav meshes (UnloadNavMeshes()) and then reloads them (LoadNavMesh). Map data such as doors, hives, locations are not touched.
|
||||
void ReloadNavMeshes();
|
||||
|
||||
void SetBaseNavProfile(AvHAIPlayer* pBot);
|
||||
void UpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void MarineUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void SkulkUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void GorgeUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void LerkUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void FadeUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void OnosUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
|
||||
// FUTURE FEATURE: Will eventually link a door to the trigger than opens it
|
||||
void UTIL_LinkTriggerToDoor(const edict_t* DoorEdict, nav_door* DoorRef);
|
||||
|
||||
|
@ -207,14 +182,14 @@ Vector UTIL_GetRandomPointOnNavmesh(const AvHAIPlayer* pBot);
|
|||
|
||||
Returns ZERO_VECTOR if none found
|
||||
*/
|
||||
Vector UTIL_GetRandomPointOnNavmeshInRadius(const int NavProfileIndex, const Vector origin, const float MaxRadius);
|
||||
Vector UTIL_GetRandomPointOnNavmeshInRadius(const nav_profile& NavProfile, const Vector origin, const float MaxRadius);
|
||||
|
||||
/* Finds any random point on the navmesh that is relevant for the bot within a given radius of the origin point,
|
||||
ignores reachability (could return a location that isn't actually reachable for the bot).
|
||||
|
||||
Returns ZERO_VECTOR if none found
|
||||
*/
|
||||
Vector UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(const int NavProfileIndex, const Vector origin, const float MaxRadius);
|
||||
Vector UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(const nav_profile& NavProfile, const Vector origin, const float MaxRadius);
|
||||
|
||||
/* Finds any random point on the navmesh of the area type (e.g. crouch area) that is relevant for the bot within a given radius of the origin point,
|
||||
taking reachability into account(will not return impossible to reach location).
|
||||
|
@ -228,17 +203,17 @@ Vector UTIL_GetRandomPointOnNavmeshInRadiusOfAreaType(SamplePolyFlags Flag, cons
|
|||
|
||||
Returns ZERO_VECTOR if none found
|
||||
*/
|
||||
Vector UTIL_GetRandomPointOnNavmeshInDonut(const int NavProfile, const Vector origin, const float MinRadius, const float MaxRadius);
|
||||
Vector UTIL_GetRandomPointOnNavmeshInDonut(const nav_profile& NavProfile, const Vector origin, const float MinRadius, const float MaxRadius);
|
||||
|
||||
/* Finds any random point on the navmesh of the area type (e.g. crouch area) that is relevant for the bot within the min and max radius of the origin point,
|
||||
ignores reachability (could return a location that isn't actually reachable for the bot).
|
||||
|
||||
Returns ZERO_VECTOR if none found
|
||||
*/
|
||||
Vector UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(const int NavProfile, const Vector origin, const float MinRadius, const float MaxRadius);
|
||||
Vector UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(const nav_profile& NavProfile, const Vector origin, const float MinRadius, const float MaxRadius);
|
||||
|
||||
// Roughly estimates the movement cost to move between FromLocation and ToLocation. Uses simple formula of distance between points x cost modifier for that movement
|
||||
float UTIL_GetPathCostBetweenLocations(const int NavProfileIndex, const Vector FromLocation, const Vector ToLocation);
|
||||
float UTIL_GetPathCostBetweenLocations(const nav_profile &NavProfile, const Vector FromLocation, const Vector ToLocation);
|
||||
|
||||
// Returns true is the bot is grounded, on the nav mesh, and close enough to the Destination to be considered at that point
|
||||
bool BotIsAtLocation(const AvHAIPlayer* pBot, const Vector Destination);
|
||||
|
@ -275,7 +250,9 @@ DoorTrigger* UTIL_GetNearestDoorTrigger(const Vector Location, nav_door* Door, C
|
|||
bool UTIL_IsPathBlockedByDoor(const Vector StartLoc, const Vector EndLoc, edict_t* SearchDoor);
|
||||
|
||||
edict_t* UTIL_GetDoorBlockingPathPoint(bot_path_node* PathNode, edict_t* SearchDoor);
|
||||
edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector ToLocation, const unsigned char Area, edict_t* SearchDoor);
|
||||
edict_t* UTIL_GetDoorBlockingPathPoint(const Vector FromLocation, const Vector ToLocation, const unsigned short MovementFlag, edict_t* SearchDoor);
|
||||
edict_t* UTIL_GetBreakableBlockingPathPoint(AvHAIPlayer* pBot, bot_path_node* PathNode, edict_t* SearchBreakable);
|
||||
edict_t* UTIL_GetBreakableBlockingPathPoint(AvHAIPlayer* pBot, const Vector FromLocation, const Vector ToLocation, const unsigned short MovementFlag, edict_t* SearchBreakable);
|
||||
|
||||
|
||||
Vector UTIL_GetButtonFloorLocation(const Vector UserLocation, edict_t* ButtonEdict);
|
||||
|
@ -292,7 +269,7 @@ bool IsBotStuck(AvHAIPlayer* pBot, const Vector MoveDestination);
|
|||
void UTIL_UpdateTileCache();
|
||||
|
||||
Vector UTIL_GetNearestPointOnNavWall(AvHAIPlayer* pBot, const float MaxRadius);
|
||||
Vector UTIL_GetNearestPointOnNavWall(const int NavProfileIndex, const Vector Location, const float MaxRadius);
|
||||
Vector UTIL_GetNearestPointOnNavWall(const nav_profile& NavProfile, const Vector Location, const float MaxRadius);
|
||||
|
||||
/* Places a temporary obstacle of the given height and radius on the mesh.Will modify that part of the nav mesh to be the given area.
|
||||
An example use case is to place an obstacle of area type SAMPLE_POLYAREA_OBSTRUCTION to mark where buildings are.
|
||||
|
@ -346,22 +323,21 @@ void MoveDirectlyTo(AvHAIPlayer* pBot, const Vector Destination);
|
|||
void HandlePlayerAvoidance(AvHAIPlayer* pBot, const Vector MoveDestination);
|
||||
|
||||
// Special path finding that takes the presence of phase gates into account
|
||||
dtStatus FindPhaseGatePathToPoint(const int NavProfileIndex, Vector FromLocation, Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
dtStatus FindPhaseGatePathToPoint(const nav_profile& NavProfile, Vector FromLocation, Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
|
||||
// Special path finding that takes the presence of phase gates into account
|
||||
dtStatus FindFlightPathToPoint(const int NavProfileIndex, Vector FromLocation, Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
dtStatus FindFlightPathToPoint(const nav_profile& NavProfile, Vector FromLocation, Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
|
||||
Vector UTIL_FindHighestSuccessfulTracePoint(const Vector TraceFrom, const Vector TargetPoint, const Vector NextPoint, const float IterationStep, const float MinIdealHeight, const float MaxHeight);
|
||||
|
||||
// Similar to FindPathToPoint, but you can specify a max acceptable distance for partial results. Will return a failure if it can't reach at least MaxAcceptableDistance away from the ToLocation
|
||||
dtStatus FindPathClosestToPoint(AvHAIPlayer* pBot, const BotMoveStyle MoveStyle, const Vector FromLocation, const Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
dtStatus FindPathClosestToPoint(const int NavProfileIndex, const Vector FromLocation, const Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
dtStatus FindDetailedPathClosestToPoint(const int NavProfileIndex, const Vector FromLocation, const Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
dtStatus FindPathClosestToPoint(const nav_profile& NavProfile, const Vector FromLocation, const Vector ToLocation, bot_path_node* path, int* pathSize, float MaxAcceptableDistance);
|
||||
|
||||
// If the bot is stuck and off the path or nav mesh, this will try to find a point it can directly move towards to get it back on track
|
||||
Vector FindClosestPointBackOnPath(AvHAIPlayer* pBot);
|
||||
|
||||
Vector FindClosestNavigablePointToDestination(const int NavProfileIndex, const Vector FromLocation, const Vector ToLocation, float MaxAcceptableDistance);
|
||||
Vector FindClosestNavigablePointToDestination(const nav_profile& NavProfile, const Vector FromLocation, const Vector ToLocation, float MaxAcceptableDistance);
|
||||
|
||||
// Will attempt to move directly towards MoveDestination while jumping/ducking as needed, and avoiding obstacles in the way
|
||||
void PerformUnstuckMove(AvHAIPlayer* pBot, const Vector MoveDestination);
|
||||
|
@ -370,14 +346,11 @@ void PerformUnstuckMove(AvHAIPlayer* pBot, const Vector MoveDestination);
|
|||
static float frand();
|
||||
|
||||
// Finds the appropriate nav mesh for the requested profile
|
||||
const dtNavMesh* UTIL_GetNavMeshForProfile(const int NavProfileIndex);
|
||||
const dtNavMesh* UTIL_GetNavMeshForProfile(const nav_profile & NavProfile);
|
||||
// Finds the appropriate nav mesh query for the requested profile
|
||||
const dtNavMeshQuery* UTIL_GetNavMeshQueryForProfile(const int NavProfileIndex);
|
||||
// Finds the appropriate query filter for the requested profile
|
||||
const dtQueryFilter* UTIL_GetNavMeshFilterForProfile(const int NavProfileIndex);
|
||||
const dtNavMeshQuery* UTIL_GetNavMeshQueryForProfile(const nav_profile& NavProfile);
|
||||
// Finds the appropriatetile cache for the requested profile
|
||||
const dtTileCache* UTIL_GetTileCacheForProfile(const int NavProfileIndex);
|
||||
AvHAIReachabilityStatus UTIL_GetReachabilityFlagForProfile(const int NavProfileIndex);
|
||||
const dtTileCache* UTIL_GetTileCacheForProfile(const nav_profile& NavProfile);
|
||||
|
||||
float UTIL_PointIsDirectlyReachable_DEBUG(const Vector start, const Vector target);
|
||||
|
||||
|
@ -389,12 +362,12 @@ float UTIL_PointIsDirectlyReachable_DEBUG(const Vector start, const Vector targe
|
|||
bool UTIL_PointIsDirectlyReachable(const AvHAIPlayer* pBot, const Vector targetPoint);
|
||||
bool UTIL_PointIsDirectlyReachable(const AvHAIPlayer* pBot, const Vector start, const Vector target);
|
||||
bool UTIL_PointIsDirectlyReachable(const Vector start, const Vector target);
|
||||
bool UTIL_PointIsDirectlyReachable(const int NavProfileIndex, const Vector start, const Vector target);
|
||||
bool UTIL_PointIsDirectlyReachable(const nav_profile& NavProfile, const Vector start, const Vector target);
|
||||
|
||||
// Will trace along the nav mesh from start to target and return true if the trace reaches within MaxAcceptableDistance
|
||||
bool UTIL_TraceNav(const int NavProfileIndex, const Vector start, const Vector target, const float MaxAcceptableDistance);
|
||||
bool UTIL_TraceNav(const nav_profile& NavProfile, const Vector start, const Vector target, const float MaxAcceptableDistance);
|
||||
|
||||
void UTIL_TraceNavLine(const int NavProfileIndex, const Vector Start, const Vector End, nav_hitresult* HitResult);
|
||||
void UTIL_TraceNavLine(const nav_profile& NavProfile, const Vector Start, const Vector End, nav_hitresult* HitResult);
|
||||
|
||||
/*
|
||||
Project point to navmesh:
|
||||
|
@ -404,31 +377,21 @@ void UTIL_TraceNavLine(const int NavProfileIndex, const Vector Start, const Vect
|
|||
*/
|
||||
Vector UTIL_ProjectPointToNavmesh(const Vector Location);
|
||||
Vector UTIL_ProjectPointToNavmesh(const Vector Location, const Vector Extents);
|
||||
Vector UTIL_ProjectPointToNavmesh(const Vector Location, const int NavProfileIndex);
|
||||
Vector UTIL_ProjectPointToNavmesh(const Vector Location, const Vector Extents, const int NavProfileIndex);
|
||||
Vector UTIL_ProjectPointToNavmesh(const Vector Location, const nav_profile& NavProfile);
|
||||
Vector UTIL_ProjectPointToNavmesh(const Vector Location, const Vector Extents, const nav_profile& NavProfile);
|
||||
|
||||
/*
|
||||
Point is on navmesh:
|
||||
Returns true if it was able to project the point to the navmesh (see UTIL_ProjectPointToNavmesh())
|
||||
*/
|
||||
bool UTIL_PointIsOnNavmesh(const Vector Location, const int NavProfileIndex);
|
||||
bool UTIL_PointIsOnNavmesh(const int NavProfileIndex, const Vector Location, const Vector SearchExtents);
|
||||
|
||||
int UTIL_GetMoveProfileForBot(const AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
|
||||
|
||||
int UTIL_GetMoveProfileForMarine(const BotMoveStyle MoveStyle);
|
||||
int UTIL_GetMoveProfileForSkulk(const BotMoveStyle MoveStyle);
|
||||
int UTIL_GetMoveProfileForGorge(const BotMoveStyle MoveStyle);
|
||||
int UTIL_GetMoveProfileForLerk(const BotMoveStyle MoveStyle);
|
||||
int UTIL_GetMoveProfileForFade(const BotMoveStyle MoveStyle);
|
||||
int UTIL_GetMoveProfileForOnos(const BotMoveStyle MoveStyle);
|
||||
bool UTIL_PointIsOnNavmesh(const Vector Location, const nav_profile& NavProfile);
|
||||
bool UTIL_PointIsOnNavmesh(const nav_profile& NavProfile, const Vector Location, const Vector SearchExtents);
|
||||
|
||||
// Sets the BotNavInfo so the bot can track if it's on the ground, in the air, climbing a wall, on a ladder etc.
|
||||
void UTIL_UpdateBotMovementStatus(AvHAIPlayer* pBot);
|
||||
|
||||
// Returns true if a path could be found between From and To location. Cheaper than full path finding, only a rough check to confirm it can be done.
|
||||
bool UTIL_PointIsReachable(const int NavProfileIndex, const Vector FromLocation, const Vector ToLocation, const float MaxAcceptableDistance);
|
||||
bool UTIL_PointIsReachable(const nav_profile& NavProfile, const Vector FromLocation, const Vector ToLocation, const float MaxAcceptableDistance);
|
||||
|
||||
// If the bot has a path, it will work out how far along the path it can see and return the furthest point. Used so that the bot looks ahead along the path rather than just at its next path point
|
||||
Vector UTIL_GetFurthestVisiblePointOnPath(const AvHAIPlayer* pBot);
|
||||
|
@ -439,11 +402,11 @@ Vector UTIL_GetFurthestVisiblePointOnPath(const Vector ViewerLocation, const bot
|
|||
// Returns the nearest nav mesh poly reference for the edict's current world position
|
||||
dtPolyRef UTIL_GetNearestPolyRefForEntity(const edict_t* Edict);
|
||||
dtPolyRef UTIL_GetNearestPolyRefForLocation(const Vector Location);
|
||||
dtPolyRef UTIL_GetNearestPolyRefForLocation(const int NavProfileIndex, const Vector Location);
|
||||
dtPolyRef UTIL_GetNearestPolyRefForLocation(const nav_profile& NavProfile, const Vector Location);
|
||||
|
||||
// Returns the area for the nearest nav mesh poly to the given location. Returns BLOCKED if none found
|
||||
unsigned char UTIL_GetNavAreaAtLocation(const Vector Location);
|
||||
unsigned char UTIL_GetNavAreaAtLocation(const int NavProfile, const Vector Location);
|
||||
unsigned char UTIL_GetNavAreaAtLocation(const nav_profile& NavProfile, const Vector Location);
|
||||
|
||||
// For printing out human-readable nav mesh areas
|
||||
const char* UTIL_NavmeshAreaToChar(const unsigned char Area);
|
||||
|
@ -491,5 +454,7 @@ Vector UTIL_AdjustPointAwayFromNavWall(const Vector Location, const float MaxDis
|
|||
unsigned char UTIL_GetBotCurrentPathArea(AvHAIPlayer* pBot);
|
||||
unsigned char UTIL_GetNextBotCurrentPathArea(AvHAIPlayer* pBot);
|
||||
|
||||
void UTIL_PopulateBaseNavProfiles();
|
||||
|
||||
#endif // BOT_NAVIGATION_H
|
||||
|
||||
|
|
|
@ -257,9 +257,7 @@ void BotLeap(AvHAIPlayer* pBot, const Vector TargetLocation)
|
|||
|
||||
Vector LookLocation = TargetLocation;
|
||||
|
||||
int NavProfileIndex = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
unsigned char NavArea = UTIL_GetNavAreaAtLocation(NavProfileIndex, pBot->Edict->v.origin);
|
||||
unsigned char NavArea = UTIL_GetNavAreaAtLocation(pBot->BotNavInfo.NavProfile, pBot->Edict->v.origin);
|
||||
|
||||
if (NavArea == SAMPLE_POLYAREA_CROUCH)
|
||||
{
|
||||
|
@ -377,7 +375,7 @@ void LinkDeployedObjectToCommanderAction(AvHAIPlayer* Commander, AvHAIBuildableS
|
|||
|
||||
if (Action->NumDesiredInstances > 1)
|
||||
{
|
||||
Action->BuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(MARINE_REGULAR_NAV_PROFILE, Action->BuildLocation, UTIL_MetresToGoldSrcUnits(1.0f));
|
||||
Action->BuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], Action->BuildLocation, UTIL_MetresToGoldSrcUnits(1.0f));
|
||||
}
|
||||
|
||||
Action->bIsAwaitingBuildLink = false;
|
||||
|
@ -543,15 +541,13 @@ void BotAttackTarget(AvHAIPlayer* pBot, edict_t* Target)
|
|||
{
|
||||
Vector NewAttackLocation = ZERO_VECTOR;
|
||||
|
||||
int BotMoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
if (vIsZero(pBot->BotNavInfo.ActualMoveDestination))
|
||||
{
|
||||
NewAttackLocation = FindClosestNavigablePointToDestination(BotMoveProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(Target), WeaponRange);
|
||||
NewAttackLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(Target), WeaponRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewAttackLocation = UTIL_GetRandomPointOnNavmeshInRadius(BotMoveProfile, pBot->CurrentFloorPosition, 2.0f);
|
||||
NewAttackLocation = UTIL_GetRandomPointOnNavmeshInRadius(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, 2.0f);
|
||||
|
||||
// Did we find a clear spot we could attack from? If so, make that our new move destination
|
||||
if (NewAttackLocation != ZERO_VECTOR && UTIL_TraceEntity(pBot->Edict, NewAttackLocation + Vector(0.0f, 0.0f, 32.0f), UTIL_GetCentreOfEntity(Target)) == Target)
|
||||
|
@ -1405,16 +1401,21 @@ void UpdateBotChat(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
|
||||
void StartNewBotFrame(AvHAIPlayer* pBot)
|
||||
void ClearBotInputs(AvHAIPlayer* pBot)
|
||||
{
|
||||
edict_t* pEdict = pBot->Edict;
|
||||
|
||||
pBot->Button = 0;
|
||||
pBot->ForwardMove = 0.0f;
|
||||
pBot->SideMove = 0.0f;
|
||||
pBot->UpMove = 0.0f;
|
||||
pBot->Impulse = 0;
|
||||
pBot->Button = 0;
|
||||
}
|
||||
|
||||
void StartNewBotFrame(AvHAIPlayer* pBot)
|
||||
{
|
||||
edict_t* pEdict = pBot->Edict;
|
||||
|
||||
ClearBotInputs(pBot);
|
||||
pBot->CurrentEyePosition = GetPlayerEyePosition(pEdict);
|
||||
pBot->CurrentFloorPosition = UTIL_GetEntityGroundLocation(pEdict);
|
||||
pBot->LookTargetLocation = ZERO_VECTOR;
|
||||
|
@ -1482,15 +1483,13 @@ void TestNavThink(AvHAIPlayer* pBot)
|
|||
}
|
||||
else
|
||||
{
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
AvHAIResourceNode* RandomNode = AITAC_GetRandomResourceNode();
|
||||
|
||||
if (!RandomNode) { return; }
|
||||
|
||||
Vector RandomPoint = RandomNode->Location;
|
||||
|
||||
if (RandomPoint != ZERO_VECTOR && UTIL_PointIsReachable(MoveProfile, pBot->Edict->v.origin, RandomPoint, max_player_use_reach))
|
||||
if (RandomPoint != ZERO_VECTOR && UTIL_PointIsReachable(pBot->BotNavInfo.NavProfile, pBot->Edict->v.origin, RandomPoint, max_player_use_reach))
|
||||
{
|
||||
AITASK_SetMoveTask(pBot, &pBot->PrimaryBotTask, RandomPoint, true);
|
||||
}
|
||||
|
@ -1505,4 +1504,17 @@ void BotSwitchToWeapon(AvHAIPlayer* pBot, AvHAIWeapon NewWeaponSlot)
|
|||
{
|
||||
char* WeaponName = UTIL_WeaponTypeToClassname(NewWeaponSlot);
|
||||
pBot->Player->SwitchWeapon(WeaponName);
|
||||
}
|
||||
|
||||
bool ShouldBotThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
return IsPlayerActiveInGame(pBot->Edict) && !IsPlayerGestating(pBot->Edict);
|
||||
}
|
||||
|
||||
void BotResumePlay(AvHAIPlayer* pBot)
|
||||
{
|
||||
ClearBotMovement(pBot);
|
||||
SetBaseNavProfile(pBot);
|
||||
|
||||
pBot->bIsInactive = false;
|
||||
}
|
|
@ -50,6 +50,7 @@ Vector GetVisiblePointOnPlayerFromObserver(edict_t* Observer, edict_t* TargetPla
|
|||
|
||||
void UpdateBotChat(AvHAIPlayer* pBot);
|
||||
|
||||
void ClearBotInputs(AvHAIPlayer* pBot);
|
||||
void StartNewBotFrame(AvHAIPlayer* pBot);
|
||||
|
||||
void TestNavThink(AvHAIPlayer* pBot);
|
||||
|
@ -57,4 +58,8 @@ void DroneThink(AvHAIPlayer* pBot);
|
|||
|
||||
void BotSwitchToWeapon(AvHAIPlayer* pBot, AvHAIWeapon NewWeaponSlot);
|
||||
|
||||
bool ShouldBotThink(AvHAIPlayer* pBot);
|
||||
|
||||
void BotResumePlay(AvHAIPlayer* pBot);
|
||||
|
||||
#endif
|
|
@ -5,6 +5,7 @@
|
|||
#include "AvHAINavigation.h"
|
||||
#include "AvHAIConfig.h"
|
||||
#include "AvHAIWeaponHelper.h"
|
||||
#include "AvHAIHelper.h"
|
||||
#include "../AvHGamerules.h"
|
||||
#include "../dlls/client.h"
|
||||
#include <time.h>
|
||||
|
@ -26,6 +27,8 @@ int BotNameIndex = 0;
|
|||
|
||||
float AIStartedTime = 0.0f; // Used to give 5-second grace period before adding bots
|
||||
|
||||
extern int m_spriteTexture;
|
||||
|
||||
string BotNames[MAX_PLAYERS] = { "MrRobot",
|
||||
"Wall-E",
|
||||
"BeepBoop",
|
||||
|
@ -503,20 +506,33 @@ void AIMGR_UpdateAIPlayers()
|
|||
{
|
||||
BotDeltaTime = ThinkDelta;
|
||||
|
||||
StartNewBotFrame(bot);
|
||||
|
||||
UpdateBotChat(bot);
|
||||
|
||||
DroneThink(bot);
|
||||
|
||||
AvHAIWeapon DesiredWeapon = (bot->DesiredMoveWeapon != WEAPON_NONE) ? bot->DesiredMoveWeapon : bot->DesiredCombatWeapon;
|
||||
|
||||
if (DesiredWeapon != WEAPON_NONE && GetBotCurrentWeapon(bot) != DesiredWeapon)
|
||||
if (ShouldBotThink(bot))
|
||||
{
|
||||
BotSwitchToWeapon(bot, DesiredWeapon);
|
||||
}
|
||||
if (bot->bIsInactive)
|
||||
{
|
||||
BotResumePlay(bot);
|
||||
}
|
||||
|
||||
BotUpdateDesiredViewRotation(bot);
|
||||
StartNewBotFrame(bot);
|
||||
|
||||
UpdateBotChat(bot);
|
||||
|
||||
DroneThink(bot);
|
||||
|
||||
AvHAIWeapon DesiredWeapon = (bot->DesiredMoveWeapon != WEAPON_NONE) ? bot->DesiredMoveWeapon : bot->DesiredCombatWeapon;
|
||||
|
||||
if (DesiredWeapon != WEAPON_NONE && GetBotCurrentWeapon(bot) != DesiredWeapon)
|
||||
{
|
||||
BotSwitchToWeapon(bot, DesiredWeapon);
|
||||
}
|
||||
|
||||
BotUpdateDesiredViewRotation(bot);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearBotInputs(bot);
|
||||
bot->bIsInactive = true;
|
||||
}
|
||||
|
||||
// Needed to correctly handle client prediction and physics calculations
|
||||
byte adjustedmsec = BotThrottledMsec(bot);
|
||||
|
@ -642,6 +658,8 @@ void AIMGR_NewMap()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AIMGR_BotPrecache();
|
||||
}
|
||||
|
||||
AvHAIPlayer* AIMGR_GetAICommander(AvHTeamNumber Team)
|
||||
|
@ -716,4 +734,9 @@ void AIMGR_UpdateAIMapData()
|
|||
{
|
||||
UTIL_UpdateTileCache();
|
||||
AITAC_UpdateMapAIData();
|
||||
}
|
||||
|
||||
void AIMGR_BotPrecache()
|
||||
{
|
||||
m_spriteTexture = PRECACHE_MODEL("sprites/zbeam6.spr");
|
||||
}
|
|
@ -9,6 +9,7 @@ static const double BOT_MIN_FRAME_TIME = (1.0 / 60.0);
|
|||
// At map load / map restart, how long to wait before starting to add bots
|
||||
static const float AI_GRACE_PERIOD = 5.0f;
|
||||
|
||||
void AIMGR_BotPrecache();
|
||||
|
||||
// Called when the round restarts. Clears all tactical information but keeps navigation data.
|
||||
void AIMGR_ResetRound();
|
||||
|
|
|
@ -206,6 +206,23 @@ float GetPlayerRadius(const AvHPlayer* Player)
|
|||
}
|
||||
}
|
||||
|
||||
bool CanPlayerCrouch(const edict_t* Player)
|
||||
{
|
||||
if (FNullEnt(Player) || Player->free || !IsEdictPlayer(Player)) { return false; }
|
||||
|
||||
switch (Player->v.iuser3)
|
||||
{
|
||||
case AVH_USER3_ALIEN_PLAYER1:
|
||||
case AVH_USER3_ALIEN_PLAYER2:
|
||||
case AVH_USER3_ALIEN_PLAYER3:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetPlayerHullIndex(const edict_t* Player, const bool bIsCrouching)
|
||||
{
|
||||
if (!Player) { return 0; }
|
||||
|
@ -642,34 +659,36 @@ bool PlayerHasWeapon(const AvHPlayer* Player, const AvHAIWeapon DesiredCombatWea
|
|||
case WEAPON_LERK_BITE:
|
||||
case WEAPON_FADE_SWIPE:
|
||||
case WEAPON_ONOS_GORE:
|
||||
DesiredWeaponIndex = 0;
|
||||
DesiredWeaponIndex = 1;
|
||||
break;
|
||||
case WEAPON_SKULK_PARASITE:
|
||||
case WEAPON_GORGE_HEALINGSPRAY:
|
||||
case WEAPON_LERK_SPORES:
|
||||
case WEAPON_FADE_BLINK:
|
||||
case WEAPON_ONOS_DEVOUR:
|
||||
DesiredWeaponIndex = 1;
|
||||
DesiredWeaponIndex = 2;
|
||||
break;
|
||||
case WEAPON_SKULK_LEAP:
|
||||
case WEAPON_GORGE_BILEBOMB:
|
||||
case WEAPON_LERK_UMBRA:
|
||||
case WEAPON_FADE_METABOLIZE:
|
||||
case WEAPON_ONOS_STOMP:
|
||||
DesiredWeaponIndex = 2;
|
||||
DesiredWeaponIndex = 3;
|
||||
break;
|
||||
case WEAPON_SKULK_XENOCIDE:
|
||||
case WEAPON_GORGE_WEB:
|
||||
case WEAPON_LERK_PRIMALSCREAM:
|
||||
case WEAPON_FADE_ACIDROCKET:
|
||||
case WEAPON_ONOS_CHARGE:
|
||||
DesiredWeaponIndex = 3;
|
||||
DesiredWeaponIndex = 4;
|
||||
break;
|
||||
default:
|
||||
DesiredWeaponIndex = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (DesiredWeaponIndex < 0) { return false; }
|
||||
|
||||
AvHBasePlayerWeapon* Weapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[DesiredWeaponIndex]);
|
||||
|
||||
return (Weapon && Weapon->m_iEnabled);
|
||||
|
|
|
@ -77,6 +77,8 @@ int GetPlayerMaxArmour(const edict_t* Player);
|
|||
// Returns the player's current energy (between 0.0 and 1.0)
|
||||
float GetPlayerEnergy(const edict_t* Player);
|
||||
|
||||
// Can the player duck? Skulks, gorges and lerks cannot
|
||||
bool CanPlayerCrouch(const edict_t* Player);
|
||||
|
||||
// Returns player resources (for marines will be team resources)
|
||||
int GetPlayerResources(const edict_t* Player);
|
||||
|
|
|
@ -232,7 +232,7 @@ AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer
|
|||
|
||||
if (it.second.StructureType & Filter->DeployableTypes)
|
||||
{
|
||||
if (!UTIL_PointIsDirectlyReachable(UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL), pBot->Edict->v.origin, it.second.Location)) { continue; }
|
||||
if (!UTIL_PointIsDirectlyReachable(pBot->BotNavInfo.NavProfile, pBot->Edict->v.origin, it.second.Location)) { continue; }
|
||||
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
|
@ -255,7 +255,7 @@ AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer
|
|||
|
||||
if (it.second.StructureType & Filter->DeployableTypes)
|
||||
{
|
||||
if (!UTIL_PointIsDirectlyReachable(UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL), pBot->Edict->v.origin, it.second.Location)) { continue; }
|
||||
if (!UTIL_PointIsDirectlyReachable(pBot->BotNavInfo.NavProfile, pBot->Edict->v.origin, it.second.Location)) { continue; }
|
||||
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
|
@ -338,7 +338,7 @@ Vector AITAC_GetFloorLocationForHive(const AvHAIHiveDefinition* Hive)
|
|||
FOR_ALL_ENTITIES(kesTeamStart, AvHTeamStartEntity*)
|
||||
if (NearestNavigableLoc == ZERO_VECTOR)
|
||||
{
|
||||
NearestNavigableLoc = FindClosestNavigablePointToDestination(MARINE_REGULAR_NAV_PROFILE, theEntity->pev->origin, HiveFloorLoc, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
NearestNavigableLoc = FindClosestNavigablePointToDestination(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], theEntity->pev->origin, HiveFloorLoc, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
}
|
||||
END_FOR_ALL_ENTITIES(kesTeamStart);
|
||||
|
||||
|
@ -493,9 +493,9 @@ void AITAC_RefreshResourceNodes()
|
|||
ResourceNodes[NumTotalResNodes].Location = theEntity->pev->origin;
|
||||
ResourceNodes[NumTotalResNodes].ReachabilityFlags = AI_REACHABILITY_NONE;
|
||||
|
||||
bool bIsReachableMarine = UTIL_PointIsReachable(MARINE_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ResourceNodes[NumTotalResNodes].Location, max_player_use_reach);
|
||||
bool bIsReachableSkulk = UTIL_PointIsReachable(SKULK_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ResourceNodes[NumTotalResNodes].Location, max_player_use_reach);
|
||||
bool bIsReachableOnos = UTIL_PointIsReachable(ONOS_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ResourceNodes[NumTotalResNodes].Location, max_player_use_reach);
|
||||
bool bIsReachableMarine = UTIL_PointIsReachable(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ResourceNodes[NumTotalResNodes].Location, max_player_use_reach);
|
||||
bool bIsReachableSkulk = UTIL_PointIsReachable(BaseNavProfiles[SKULK_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ResourceNodes[NumTotalResNodes].Location, max_player_use_reach);
|
||||
bool bIsReachableOnos = UTIL_PointIsReachable(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ResourceNodes[NumTotalResNodes].Location, max_player_use_reach);
|
||||
|
||||
if (bIsReachableMarine)
|
||||
{
|
||||
|
@ -861,11 +861,11 @@ void AITAC_UpdateMarineItem(CBaseEntity* Item, AvHAIDeployableItemType ItemType)
|
|||
}
|
||||
else
|
||||
{
|
||||
MarineDroppedItemMap[EntIndex].bOnNavMesh = UTIL_PointIsOnNavmesh(MARINE_REGULAR_NAV_PROFILE, ItemEdict->v.origin, Vector(max_player_use_reach, max_player_use_reach, max_player_use_reach));
|
||||
MarineDroppedItemMap[EntIndex].bOnNavMesh = UTIL_PointIsOnNavmesh(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], ItemEdict->v.origin, Vector(max_player_use_reach, max_player_use_reach, max_player_use_reach));
|
||||
|
||||
if (MarineDroppedItemMap[EntIndex].bOnNavMesh)
|
||||
{
|
||||
MarineDroppedItemMap[EntIndex].bIsReachableMarine = UTIL_PointIsReachable(MARINE_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ItemEdict->v.origin, max_player_use_reach);
|
||||
MarineDroppedItemMap[EntIndex].bIsReachableMarine = UTIL_PointIsReachable(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), ItemEdict->v.origin, max_player_use_reach);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -937,7 +937,7 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
|
||||
if (bShouldCollide)
|
||||
{
|
||||
unsigned int area = UTIL_GetAreaForObstruction(StructureType);
|
||||
unsigned int area = UTIL_GetAreaForObstruction(StructureType, BuildingEdict);
|
||||
float Radius = UTIL_GetStructureRadiusForObstruction(StructureType);
|
||||
UTIL_AddTemporaryObstacles(UTIL_GetCentreOfEntity(BuildingMap[EntIndex].edict), Radius, 100.0f, area, BuildingMap[EntIndex].ObstacleRefs);
|
||||
}
|
||||
|
@ -953,12 +953,12 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
|
||||
if (vIsZero(BuildingMap[EntIndex].Location) || !vEquals(BaseBuildable->pev->origin, BuildingMap[EntIndex].Location, 5.0f))
|
||||
{
|
||||
bool bIsOnNavMesh = UTIL_PointIsOnNavmesh(MARINE_REGULAR_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)
|
||||
{
|
||||
bool bIsReachableMarine = UTIL_PointIsReachable(MARINE_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||
bool bIsReachableSkulk = UTIL_PointIsReachable(SKULK_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||
bool bIsReachableOnos = UTIL_PointIsReachable(ONOS_REGULAR_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 bIsReachableOnos = UTIL_PointIsReachable(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), UTIL_GetEntityGroundLocation(BuildingEdict), max_player_use_reach);
|
||||
|
||||
if (bIsReachableMarine)
|
||||
{
|
||||
|
@ -1237,10 +1237,15 @@ AvHAIDeployableStructureType UTIL_IUSER3ToStructureType(const int inIUSER3)
|
|||
|
||||
}
|
||||
|
||||
unsigned char UTIL_GetAreaForObstruction(AvHAIDeployableStructureType StructureType)
|
||||
unsigned char UTIL_GetAreaForObstruction(AvHAIDeployableStructureType StructureType, const edict_t* BuildingEdict)
|
||||
{
|
||||
if (StructureType == STRUCTURE_NONE) { return DT_TILECACHE_NULL_AREA; }
|
||||
|
||||
AvHTeamNumber TeamA = GetGameRules()->GetTeamANumber();
|
||||
AvHTeamNumber TeamB = GetGameRules()->GetTeamBNumber();
|
||||
|
||||
unsigned char StructureArea = (BuildingEdict->v.team == TeamA) ? DT_TILECACHE_TEAM1STRUCTURE_AREA : DT_TILECACHE_TEAM2STRUCTURE_AREA;
|
||||
|
||||
switch (StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_RESTOWER:
|
||||
|
@ -1248,10 +1253,9 @@ unsigned char UTIL_GetAreaForObstruction(AvHAIDeployableStructureType StructureT
|
|||
case STRUCTURE_MARINE_ARMOURY:
|
||||
case STRUCTURE_MARINE_ADVARMOURY:
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
return DT_TILECACHE_MSTRUCTURE_AREA;
|
||||
case STRUCTURE_ALIEN_RESTOWER:
|
||||
case STRUCTURE_ALIEN_HIVE:
|
||||
return DT_TILECACHE_ASTRUCTURE_AREA;
|
||||
return StructureArea;
|
||||
default:
|
||||
return DT_TILECACHE_BLOCKED_AREA;
|
||||
}
|
||||
|
@ -1342,9 +1346,7 @@ bool UTIL_IsBuildableStructureStillReachable(AvHAIPlayer* pBot, const edict_t* S
|
|||
|
||||
if (!StructureRef) { return false; }
|
||||
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
return (StructureRef->ReachabilityFlags & UTIL_GetReachabilityFlagForProfile(MoveProfile)) != 0;
|
||||
return (StructureRef->ReachabilityFlags & pBot->BotNavInfo.NavProfile.ReachabilityFlag) != 0;
|
||||
}
|
||||
|
||||
bool UTIL_IsDroppedItemStillReachable(AvHAIPlayer* pBot, const edict_t* Item)
|
||||
|
@ -1759,7 +1761,7 @@ Vector UTIL_GetNextMinePosition(edict_t* StructureToMine)
|
|||
}
|
||||
}
|
||||
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInDonut(MARINE_REGULAR_NAV_PROFILE, StructureToMine->v.origin, Size, Size + 16.0f);
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInDonut(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], StructureToMine->v.origin, Size, Size + 16.0f);
|
||||
|
||||
return BuildLocation;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ AvHAIDeployableStructureType UTIL_IUSER3ToStructureType(const int inIUSER3);
|
|||
|
||||
bool UTIL_ShouldStructureCollide(AvHAIDeployableStructureType StructureType);
|
||||
float UTIL_GetStructureRadiusForObstruction(AvHAIDeployableStructureType StructureType);
|
||||
unsigned char UTIL_GetAreaForObstruction(AvHAIDeployableStructureType StructureType);
|
||||
unsigned char UTIL_GetAreaForObstruction(AvHAIDeployableStructureType StructureType, const edict_t* BuildingEdict);
|
||||
|
||||
bool UTIL_IsStructureElectrified(edict_t* Structure);
|
||||
bool UTIL_StructureIsFullyBuilt(edict_t* Structure);
|
||||
|
|
|
@ -385,14 +385,14 @@ bool AITASK_IsWeldTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (IsEdictPlayer(Task->TaskTarget))
|
||||
{
|
||||
if (!IsPlayerMarine(Task->TaskTarget) || !IsPlayerActiveInGame(Task->TaskTarget)) { return false; }
|
||||
if (Task->TaskTarget->v.team != pBot->Edict->v.team || !IsPlayerMarine(Task->TaskTarget) || !IsPlayerActiveInGame(Task->TaskTarget)) { return false; }
|
||||
return (Task->TaskTarget->v.armorvalue < GetPlayerMaxArmour(Task->TaskTarget));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsEdictStructure(Task->TaskTarget))
|
||||
{
|
||||
if (!UTIL_IsBuildableStructureStillReachable(pBot, Task->TaskTarget)) { return false; }
|
||||
if (Task->TaskTarget->v.team != pBot->Edict->v.team || !UTIL_IsBuildableStructureStillReachable(pBot, Task->TaskTarget)) { return false; }
|
||||
|
||||
return (Task->TaskTarget->v.health < Task->TaskTarget->v.max_health);
|
||||
}
|
||||
|
@ -1064,7 +1064,7 @@ void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
if (Task->BuildAttempts > 3)
|
||||
{
|
||||
float Size = fmaxf(Task->TaskTarget->v.size.x, Task->TaskTarget->v.size.y);
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BUILDING_REGULAR_NAV_PROFILE, Task->TaskTarget->v.origin, Size + 8.0f);
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskTarget->v.origin, Size + 8.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1318,7 +1318,7 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (Task->TaskLocation != g_vecZero)
|
||||
{
|
||||
dtPolyRef Poly = UTIL_GetNavAreaAtLocation(BUILDING_REGULAR_NAV_PROFILE, Task->TaskLocation);
|
||||
dtPolyRef Poly = UTIL_GetNavAreaAtLocation(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation);
|
||||
|
||||
if (Poly != SAMPLE_POLYAREA_GROUND)
|
||||
{
|
||||
|
@ -1332,7 +1332,7 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
Vector TargetLocation = (ReinforcedStructure == STRUCTURE_ALIEN_HIVE) ? UTIL_GetFloorUnderEntity(Task->TaskTarget) : Task->TaskTarget->v.origin;
|
||||
|
||||
Vector BuildLocation = FindClosestNavigablePointToDestination(MARINE_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), TargetLocation, UTIL_MetresToGoldSrcUnits(50.0f));
|
||||
Vector BuildLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(GetGameRules()->GetTeamANumber()), TargetLocation, UTIL_MetresToGoldSrcUnits(50.0f));
|
||||
|
||||
if (BuildLocation != g_vecZero)
|
||||
{
|
||||
|
@ -1340,7 +1340,7 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
float MaxDist = fmaxf(UTIL_MetresToGoldSrcUnits(1.0f), (UTIL_MetresToGoldSrcUnits(5.0f) - currDist));
|
||||
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(GORGE_BUILD_NAV_PROFILE, BuildLocation, MaxDist);
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], BuildLocation, MaxDist);
|
||||
}
|
||||
|
||||
if (vIsZero(Task->TaskLocation)) { return; }
|
||||
|
@ -1640,11 +1640,11 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
if ((gpGlobals->time - Task->TaskStartedTime) > 1.0f)
|
||||
{
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BUILDING_REGULAR_NAV_PROFILE, pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (vIsZero(Task->TaskLocation))
|
||||
{
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(GORGE_REGULAR_NAV_PROFILE, pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
}
|
||||
|
||||
Task->TaskStartedTime = 0.0f;
|
||||
|
@ -1675,14 +1675,14 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (vDist2DSq(pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget)) > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)) || UTIL_GetNavAreaAtLocation(GORGE_BUILD_NAV_PROFILE, pBot->Edict->v.origin) != SAMPLE_POLYAREA_GROUND)
|
||||
if (vDist2DSq(pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget)) > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)) || UTIL_GetNavAreaAtLocation(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin) != SAMPLE_POLYAREA_GROUND)
|
||||
{
|
||||
MoveTo(pBot, UTIL_GetEntityGroundLocation(Task->TaskTarget), MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(GORGE_BUILD_NAV_PROFILE, pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (vIsZero(Task->TaskLocation))
|
||||
{
|
||||
|
@ -1691,7 +1691,7 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (Task->TaskLocation != g_vecZero)
|
||||
{
|
||||
Vector FinalEvolveLoc = UTIL_GetRandomPointOnNavmeshInRadius(GORGE_BUILD_NAV_PROFILE, Task->TaskLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
Vector FinalEvolveLoc = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (FinalEvolveLoc != g_vecZero)
|
||||
{
|
||||
|
@ -1777,7 +1777,7 @@ void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (Task->bIsWaitingForBuildLink)
|
||||
{
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(GORGE_REGULAR_NAV_PROFILE, pBot->Edict->v.origin, Hive->FloorLocation, UTIL_MetresToGoldSrcUnits(7.5f));
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin, Hive->FloorLocation, UTIL_MetresToGoldSrcUnits(7.5f));
|
||||
|
||||
if (vIsZero(Task->TaskLocation))
|
||||
{
|
||||
|
@ -1789,7 +1789,7 @@ void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
float MaxDist = (UTIL_MetresToGoldSrcUnits(7.5f) - Dist);
|
||||
|
||||
Vector AltLocation = UTIL_GetRandomPointOnNavmeshInRadius(GORGE_REGULAR_NAV_PROFILE, Task->TaskLocation, MaxDist);
|
||||
Vector AltLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, MaxDist);
|
||||
|
||||
if (AltLocation != g_vecZero)
|
||||
{
|
||||
|
@ -1899,18 +1899,18 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (Task->bIsWaitingForBuildLink)
|
||||
{
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(GORGE_BUILD_NAV_PROFILE, Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
Task->bIsWaitingForBuildLink = false;
|
||||
}
|
||||
|
||||
// If we are building a chamber
|
||||
if (Task->StructureType != STRUCTURE_ALIEN_RESTOWER)
|
||||
{
|
||||
dtPolyRef Poly = UTIL_GetNavAreaAtLocation(BUILDING_REGULAR_NAV_PROFILE, Task->TaskLocation);
|
||||
dtPolyRef Poly = UTIL_GetNavAreaAtLocation(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation);
|
||||
|
||||
if (Poly != SAMPLE_POLYAREA_GROUND)
|
||||
{
|
||||
Vector NewLocation = UTIL_GetRandomPointOnNavmeshInRadius(BUILDING_REGULAR_NAV_PROFILE, Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
Vector NewLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
|
||||
if (NewLocation != g_vecZero)
|
||||
{
|
||||
|
@ -2416,7 +2416,7 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
}
|
||||
else
|
||||
{
|
||||
pBot->GuardInfo.GuardLookLocation = UTIL_GetRandomPointOnNavmeshInRadius(SKULK_REGULAR_NAV_PROFILE, pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
pBot->GuardInfo.GuardLookLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[SKULK_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
pBot->GuardInfo.GuardLookLocation.z = pBot->CurrentEyePosition.z;
|
||||
}
|
||||
|
@ -2425,7 +2425,7 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
|
||||
Vector NewMoveCentre = GuardLocation - (LookDir * UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
|
||||
Vector NewMoveLoc = UTIL_GetRandomPointOnNavmeshInRadius(MARINE_REGULAR_NAV_PROFILE, NewMoveCentre, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
Vector NewMoveLoc = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], NewMoveCentre, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
|
||||
if (NewMoveLoc != g_vecZero)
|
||||
{
|
||||
|
@ -2471,7 +2471,7 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
|
||||
bool bEnemyIsAlien = GetGameRules()->GetTeam(EnemyTeam)->GetTeamType() == AVH_CLASS_TYPE_ALIEN;
|
||||
|
||||
int MoveProfileIndex = (bEnemyIsAlien) ? SKULK_REGULAR_NAV_PROFILE : MARINE_REGULAR_NAV_PROFILE;
|
||||
const nav_profile NavProfile = (bEnemyIsAlien) ? BaseNavProfiles[SKULK_BASE_NAV_PROFILE] : BaseNavProfiles[MARINE_BASE_NAV_PROFILE];
|
||||
|
||||
bot_path_node path[MAX_AI_PATH_SIZE];
|
||||
int pathSize = 0;
|
||||
|
@ -2485,7 +2485,7 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
|
||||
if (UTIL_QuickTrace(pEdict, GuardLocation + Vector(0.0f, 0.0f, 10.0f), Hive->Location) || vDist2DSq(GuardLocation, Hive->Location) < sqrf(UTIL_MetresToGoldSrcUnits(10.0f))) { continue; }
|
||||
|
||||
dtStatus SearchResult = FindPathClosestToPoint(MoveProfileIndex, Hive->FloorLocation, GuardLocation, path, &pathSize, 500.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, Hive->FloorLocation, GuardLocation, path, &pathSize, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
{
|
||||
|
@ -2498,7 +2498,7 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
}
|
||||
}
|
||||
|
||||
dtStatus SearchResult = FindPathClosestToPoint(MoveProfileIndex, AITAC_GetTeamStartingLocation(EnemyTeam), GuardLocation, path, &pathSize, 500.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(EnemyTeam), GuardLocation, path, &pathSize, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
{
|
||||
|
@ -2512,7 +2512,7 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
|
||||
if (vDist2DSq(GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam())) > sqrf(UTIL_MetresToGoldSrcUnits(15.0f)))
|
||||
{
|
||||
dtStatus SearchResult = FindPathClosestToPoint(MoveProfileIndex, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), GuardLocation, path, &pathSize, 500.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), GuardLocation, path, &pathSize, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
{
|
||||
|
@ -2658,6 +2658,7 @@ void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Targe
|
|||
Task->TaskTarget = Target;
|
||||
Task->TaskType = TASK_WELD;
|
||||
Task->bTaskIsUrgent = bIsUrgent;
|
||||
Task->TaskLength = 0.0f;
|
||||
|
||||
if (IsEdictPlayer(Target) || IsEdictStructure(Target)) { return; }
|
||||
|
||||
|
@ -2668,9 +2669,7 @@ void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Targe
|
|||
TargetLocation = Task->TaskTarget->v.origin;
|
||||
}
|
||||
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
Vector TaskLocation = FindClosestNavigablePointToDestination(MoveProfile, pBot->Edict->v.origin, TargetLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
Vector TaskLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->Edict->v.origin, TargetLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (vIsZero(TaskLocation))
|
||||
{
|
||||
|
@ -2709,10 +2708,8 @@ void AITASK_SetAttackTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Tar
|
|||
return;
|
||||
}
|
||||
|
||||
int BotProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
// Get as close as possible to the target
|
||||
Vector AttackLocation = FindClosestNavigablePointToDestination(BotProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(Target), UTIL_MetresToGoldSrcUnits(20.0f));
|
||||
Vector AttackLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(Target), UTIL_MetresToGoldSrcUnits(20.0f));
|
||||
|
||||
if (AttackLocation != g_vecZero)
|
||||
{
|
||||
|
@ -2736,10 +2733,8 @@ void AITASK_SetMoveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const Vector L
|
|||
|
||||
if (vIsZero(Location)) { return; }
|
||||
|
||||
int BotProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
// Get as close as possible to desired location
|
||||
Vector MoveLocation = FindClosestNavigablePointToDestination(BotProfile, pBot->CurrentFloorPosition, Location, UTIL_MetresToGoldSrcUnits(20.0f));
|
||||
Vector MoveLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, Location, UTIL_MetresToGoldSrcUnits(20.0f));
|
||||
|
||||
if (!vIsZero(MoveLocation))
|
||||
{
|
||||
|
@ -2760,12 +2755,12 @@ void AITASK_SetBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIDe
|
|||
if (vIsZero(Location)) { return; }
|
||||
|
||||
// Get as close as possible to desired location
|
||||
Vector BuildLocation = FindClosestNavigablePointToDestination(GORGE_REGULAR_NAV_PROFILE, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), Location, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
BuildLocation = UTIL_ProjectPointToNavmesh(BuildLocation, BUILDING_REGULAR_NAV_PROFILE);
|
||||
Vector BuildLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), Location, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
BuildLocation = UTIL_ProjectPointToNavmesh(BuildLocation, BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE]);
|
||||
|
||||
if (vIsZero(BuildLocation))
|
||||
{
|
||||
BuildLocation = FindClosestNavigablePointToDestination(UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL), pBot->CurrentFloorPosition, Location, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
BuildLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, Location, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
}
|
||||
|
||||
if (BuildLocation != g_vecZero)
|
||||
|
@ -2804,10 +2799,8 @@ void AITASK_SetBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Stru
|
|||
|
||||
if (Task->TaskType == TASK_BUILD && Task->TaskTarget == StructureToBuild) { return; }
|
||||
|
||||
int BotProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
// Get as close as possible to desired location
|
||||
Vector BuildLocation = FindClosestNavigablePointToDestination(BotProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(StructureToBuild), 80.0f);
|
||||
Vector BuildLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(StructureToBuild), 80.0f);
|
||||
|
||||
if (BuildLocation != g_vecZero)
|
||||
{
|
||||
|
@ -2863,9 +2856,7 @@ void AITASK_SetDefendTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Tar
|
|||
Task->TaskTarget = Target;
|
||||
Task->bTaskIsUrgent = bIsUrgent;
|
||||
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
Vector DefendPoint = FindClosestNavigablePointToDestination(MoveProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(Target), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Vector DefendPoint = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_GetEntityGroundLocation(Target), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (DefendPoint != g_vecZero)
|
||||
{
|
||||
|
@ -2931,11 +2922,9 @@ void AITASK_SetUseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target
|
|||
return;
|
||||
}
|
||||
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
Task->TaskType = TASK_USE;
|
||||
Task->TaskTarget = Target;
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(MoveProfile, pBot->CurrentFloorPosition, UTIL_ProjectPointToNavmesh(UTIL_GetCentreOfEntity(Target)), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_ProjectPointToNavmesh(UTIL_GetCentreOfEntity(Target)), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->bTaskIsUrgent = bIsUrgent;
|
||||
Task->TaskLength = 10.0f;
|
||||
Task->TaskStartedTime = gpGlobals->time;
|
||||
|
@ -2949,11 +2938,9 @@ void AITASK_SetUseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target
|
|||
return;
|
||||
}
|
||||
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
Task->TaskType = TASK_USE;
|
||||
Task->TaskTarget = Target;
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(MoveProfile, pBot->CurrentFloorPosition, UseLocation, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UseLocation, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->bTaskIsUrgent = bIsUrgent;
|
||||
Task->TaskLength = 10.0f;
|
||||
Task->TaskStartedTime = gpGlobals->time;
|
||||
|
@ -2967,11 +2954,9 @@ void AITASK_SetTouchTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Targ
|
|||
return;
|
||||
}
|
||||
|
||||
int MoveProfile = UTIL_GetMoveProfileForBot(pBot, MOVESTYLE_NORMAL);
|
||||
|
||||
Task->TaskType = TASK_TOUCH;
|
||||
Task->TaskTarget = Target;
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(MoveProfile, pBot->CurrentFloorPosition, UTIL_ProjectPointToNavmesh(UTIL_GetCentreOfEntity(Target)), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_ProjectPointToNavmesh(UTIL_GetCentreOfEntity(Target)), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
Task->bTaskIsUrgent = bIsUrgent;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ void InterruptReload(AvHAIPlayer* pBot)
|
|||
|
||||
AvHAIWeapon UTIL_GetBotPrimaryWeapon(const AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* Weapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[0]);
|
||||
AvHBasePlayerWeapon* Weapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (Weapon)
|
||||
{
|
||||
|
@ -205,7 +205,7 @@ AvHAIWeapon GetBotMarineSecondaryWeapon(const AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetPrimaryWeaponMaxAmmoReserve(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[0]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -217,7 +217,7 @@ int BotGetPrimaryWeaponMaxAmmoReserve(AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetPrimaryWeaponAmmoReserve(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[0]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ int BotGetPrimaryWeaponAmmoReserve(AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetSecondaryWeaponAmmoReserve(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -241,7 +241,7 @@ int BotGetSecondaryWeaponAmmoReserve(AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetPrimaryWeaponClipAmmo(const AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[0]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -253,7 +253,7 @@ int BotGetPrimaryWeaponClipAmmo(const AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetSecondaryWeaponClipAmmo(const AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -265,7 +265,7 @@ int BotGetSecondaryWeaponClipAmmo(const AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetPrimaryWeaponMaxClipSize(const AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[0]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -277,7 +277,7 @@ int BotGetPrimaryWeaponMaxClipSize(const AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetSecondaryWeaponMaxClipSize(const AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -289,7 +289,7 @@ int BotGetSecondaryWeaponMaxClipSize(const AvHAIPlayer* pBot)
|
|||
|
||||
int BotGetSecondaryWeaponMaxAmmoReserve(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -326,19 +326,19 @@ float GetMaxIdealWeaponRange(const AvHAIWeapon Weapon)
|
|||
case WEAPON_SKULK_XENOCIDE:
|
||||
return UTIL_MetresToGoldSrcUnits(5.0f);
|
||||
case WEAPON_ONOS_GORE:
|
||||
return kClawsRange;
|
||||
return BALANCE_VAR(kClawsRange);
|
||||
case WEAPON_ONOS_DEVOUR:
|
||||
return kDevourRange;
|
||||
return BALANCE_VAR(kDevourRange);
|
||||
case WEAPON_FADE_SWIPE:
|
||||
return kSwipeRange;
|
||||
return BALANCE_VAR(kSwipeRange);
|
||||
case WEAPON_SKULK_BITE:
|
||||
return kBiteRange;
|
||||
return BALANCE_VAR(kBiteRange);
|
||||
case WEAPON_LERK_BITE:
|
||||
return kBite2Range;
|
||||
return BALANCE_VAR(kBite2Range);
|
||||
case WEAPON_GORGE_HEALINGSPRAY:
|
||||
return kHealingSprayRange;
|
||||
return BALANCE_VAR(kHealingSprayRange);
|
||||
case WEAPON_MARINE_WELDER:
|
||||
return kWelderRange;
|
||||
return BALANCE_VAR(kWelderRange);
|
||||
default:
|
||||
return max_player_use_reach;
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ Vector UTIL_GetGrenadeThrowTarget(edict_t* Player, const Vector TargetLocation,
|
|||
bot_path_node CheckPath[MAX_AI_PATH_SIZE];
|
||||
int PathSize = 0;
|
||||
|
||||
dtStatus Status = FindPathClosestToPoint(ALL_NAV_PROFILE, Player->v.origin, TargetLocation, CheckPath, &PathSize, ExplosionRadius);
|
||||
dtStatus Status = FindPathClosestToPoint(BaseNavProfiles[ALL_NAV_PROFILE], Player->v.origin, TargetLocation, CheckPath, &PathSize, ExplosionRadius);
|
||||
|
||||
if (dtStatusSucceed(Status))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue