NS/main/source/mod/AvHAIMath.h
pierow 58358d0927
Bot integration for v3.3b8 (#156)
* Initial bot commit

* Added server commands and cvars for adding AI players to the game.
* Added auto modes for automating the adding and removal of bots
* Bots connect to the server and join teams correctly

* Added round restart and new map detection for AI system

Push before new project added for detour

* Initial bot integration

* Integrated all basic bot code for navigation and task performing
* Added support for multi_managers to better understand how buttons and triggers affect doors

* Improved bot understanding of door triggers and weldables

* Reworked nav profiles

Nav profiles for bots are now dynamically updated to take into account changing capabilities, such as picking up a welder

* Improved bot door usage

* Added weldable obstacles back into navigation

Bots now understand how to get around weldable barriers

* Replaced fixed arrays with vectors

* Resource node and hive lists are now vectors.
* Further improved bot weld behaviour

* Added dynamic reachability calculations

When barriers and doors are open/closed, new reachability calculations are done for structures and items so bots understand when items/structures become reachable or unreachable as the match progresses.

* Added team-based reachability calculations

Reachabilities for structures and items are now based on the team, so bots understand when they can't reach a structure from their spawn point.

* Implemented long-range off-mesh connections and dynamic off-mesh connections

* Implemented fully dynamic off-mesh connections

Phase gates now use connections rather than custom path finding. Much more performant.

* Replaced arrays with vectors for simpler code

* Started Bot Swimming

* Bots understand trigger_changetarget

Bots can now navigate doors operated with a trigger_changetarget so they understand the sequence in which triggers must be activated to make it work

* Push before trying to fix long-range connections

* Implement new off-mesh connection system

* Redid population of door triggers

* Fixed trigger types and links to doors

* Added lift and moving platform support

* Lift improvements

* Bots avoid getting crushed under a lift when summoning it
* Bots are better at judging which stop a platform needs to be at

* Tweak lift and welder usage

* Fixed bug with multiple off-mesh connections close together

* Finish lift movement

* Fixed dodgy path finding

* Improved skulk ladder usage and lerk lift usage

* Fix crash with path finding

* Re-implement commander AI

* Commander improvements

* Improve commander sieging

* Commander scanning tweak

* Reimplemented regular marine AI

* Start reimplementing alien AI

* Implement gorge building behaviours

* Start alien tactical decisioning

* Continuing alien building and other non-combat logic

* More alien role work

* Adjusted base node definitions

* Iterate Capper Logic

* Alien assault AI

* Alien Combat

* Fix grenade throwing, better combat

* Marine combat AI improvements

* Commander improvements

* Commander + nav improvements

* Drop mines

* Improved bot stuck detection

* Commander supply improvements

* Bot fill timing config

* Added nsbots.cfg to configure internal bots

* Changed bot config file to "nsbots.cfg"

* Bug fixing with navigation

* Fix skulk movement on ladders

* Improved commander placement and tactical refresh

* Fixed bug with ladder climbing

* Doors block off-mesh connections

* Finished doors blocking connections

* Marine and alien tactical bug fixes

* Add commander beacon back in

* Start combat mode stuff

* First pass at combat mode

* Bots attack turrets

* Fix ladder and wall climbing

* Commander chat request

* Improved skulk ladders

* Added nav meshes for new bot code

* Added bot configuration to listen server menu

* Added bot config file

* Added default bot config to listenserver.cfg

* Added default bot settings to server.cfg

* Include VS filter for bot files

* Crash fixes

* Bot improvements

* Bot stability and mine placement improvements

* Fixed crash on new map start with bots

* Reverted Svencoop fix

* Fixed crash, added more cvars

* Performance improvement

* Commander building improvements

* Stop bot spasming when waiting to take command

* Fixed doors not blocking connections

* Added bot disabled guard to round start

* Commander improvements, movement improvements

* Tweaked level load sequence

* Performance improvements

* Bot load spread

* Fixed commander update

* Refactor bot frame handling

* Bug fixes + Pierow's dynamic load spread

* Minor bug fixes

* Fix door detection, prep for test

* Fixed commander siege spam

* linux compile test

* fix hardcoded inlcudes

* O1 compile flag for detour
- fix linux server crash

* Revert detour compile flags to original for windows

* linux build update

* remove x64 build configs

* update bot nav meshes and configs

* fix bot physics at high server fps, update navmeshes. from @RGreenlees

---------

Co-authored-by: RGreenlees <RGreenlees@users.noreply.github.com>
Co-authored-by: RichardGreenlees <richard.greenlees@forecast.global>
2024-03-21 14:17:18 -04:00

208 lines
No EOL
9.9 KiB
C

//
// EvoBot - Neoptolemus' Natural Selection bot, based on Botman's HPB bot template
//
// bot_math.h
//
// Contains all useful math functions for bot stuff
//
#pragma once
#ifndef AVH_AI_MATH_H
#define AVH_AI_MATH_H
#include "../dlls/extdll.h"
static const Vector ZERO_VECTOR = Vector(0.0f, 0.0f, 0.0f);
static const Vector UP_VECTOR = Vector(0.0f, 0.0f, 1.0f); // Normalized "up" direction
static const Vector RIGHT_VECTOR = Vector(1.0f, 0.0f, 0.0f); // Normalized "right" direction
static const Vector FWD_VECTOR = Vector(0.0f, 1.0f, 0.0f); // Normalized "forward" direction
static const float MATH_PI = 3.141592654f;
static const float DEGREES_RADIANS_CONV = (MATH_PI / 180.0f);
static const float GOLDSRC_GRAVITY = 400.0f; // Default speed of gravity in GoldSrc units per second squared
// Defines a frustum plane
typedef struct _FRUSTUM_PLANE_T
{
Vector normal;
Vector point;
float d;
} frustum_plane_t;
// GENERAL MATH
// Is the input string a valid integer?
bool isNumber(const char* line);
// Is the input string a valid floating point number?
bool isFloat(const char* line);
// Square the input
float sqrf(float input);
// Return the sign (-1 if number is negative, 1 if positive, 0 if 0)
float signf(float input);
// Clamp float value between min and max
float clampf(float input, float inMin, float inMax);
// Clamp int value between min and max
float clampi(int input, int inMin, int inMax);
// For any given view angle, ensure that the angle is expressed as a value between -180 and 180
float UTIL_WrapAngle(float angle);
// For view angles, ensures that the angles do not exceed -180 or 180
Vector UTIL_WrapAngles(Vector angles);
// Spherical linear interpolation of float from start to end at interp speed
float fInterpTo(float start, float end, float DeltaTime, float InterpSpeed);
// Linear interpolation of float from start to end at interp speed
float fInterpConstantTo(float start, float end, float DeltaTime, float InterpSpeed);
// Random float between min value and max value
float frandrange(float MinValue, float MaxValue);
// Random integer between min and max values
int irandrange(int MinValue, int MaxValue);
// Convert degrees to radians
float fDegreesToRadians(const float Degrees);
// Return random boolean
bool randbool();
// Returns the max of two integers
int imaxi(const int a, const int b);
// Returns the min of two integers
int imini(const int a, const int b);
// VECTOR MATH
// 2D (ignore Z axis) distance between v1 and v2
float vDist2D(const Vector v1, const Vector v2);
// 3D distance between v1 and v2
float vDist3D(const Vector v1, const Vector v2);
// Squared (no sqrt) 2D distance (ignore Z axis) between v1 and v2
float vDist2DSq(const Vector v1, const Vector v2);
// Squared (no sqrt) 3D distance between v1 and v2
float vDist3DSq(const Vector v1, const Vector v2);
// 3D length of vector
float vSize3D(const Vector V);
// 2D length (no Z axis) of vector
float vSize2D(const Vector V);
// Squared 3D length of vector
float vSize3DSq(const Vector V);
// Squared 2D length (no Z axis) of vector
float vSize2DSq(const Vector V);
// Are two vectors equal, using default epsilon of 0.1f
bool vEquals(const Vector v1, const Vector v2);
bool vEquals2D(const Vector v1, const Vector v2);
// Are two vectors equal, using custom epsilon
bool vEquals(const Vector v1, const Vector v2, const float epsilon);
bool vEquals2D(const Vector v1, const Vector v2, const float epsilon);
bool vIsZero(const Vector v1);
bool fNearlyEqual(const float f1, const float f2);
// Returns the dot product of two unit vectors
inline float UTIL_GetDotProduct(const Vector v1, const Vector v2) { return ((v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z)); }
// Returns the dot product of two unit vectors excluding Z axis
float UTIL_GetDotProduct2D(const Vector v1, const Vector v2);
// Normalize the unit vector (modifies input)
void UTIL_NormalizeVector(Vector* vec);
// Normalize the unit vector without the Z axis (modifies input)
void UTIL_NormalizeVector2D(Vector* vec);
// Returns a normalized copy of the input unit vector
Vector UTIL_GetVectorNormal(const Vector vec);
// Returns a normalized 2D copy of the input vector without Z axis
Vector UTIL_GetVectorNormal2D(const Vector vec);
//Returns the cross product of v1 and v2
Vector UTIL_GetCrossProduct(const Vector v1, const Vector v2);
// Returns the surface normal of a poly defined at points v1, v2 and v3 (clockwise)
Vector UTIL_GetSurfaceNormal(const Vector v1, const Vector v2, const Vector v3);
bool vPointOverlaps3D(const Vector Point, const Vector MinBB, const Vector MaxBB);
bool vPointOverlaps2D(const Vector Point, const Vector MinBB, const Vector MaxBB);
bool vBBOverlaps2D(const Vector MinBBA, const Vector MaxBBA, const Vector MinBBB, const Vector MaxBBB);
// For the two lines provided, returns true if they cross each other on the X and Y axis
bool vIntersects2D(const Vector LineAStart, const Vector LineAEnd, const Vector LineBStart, const Vector LineBEnd);
Vector vClosestPointOnBB(const Vector Point, const Vector MinBB, const Vector MaxBB);
void vScaleBB(Vector& MinBB, Vector& MaxBB, const float Scale);
// WIP: Trying to get a working random unit vector in cone. Not currently used
Vector UTIL_GetRandomUnitVectorInCone(const Vector ConeDirection, const float HalfAngleRadians);
Vector random_unit_vector_within_cone(const Vector Direction, double HalfAngleRadians);
// Takes in a bot's current view angle and a target direction to look in, and returns the appropriate view angles. Eases into the target
Vector ViewInterpTo(const Vector CurrentViewAngles, const Vector& TargetDirection, const float DeltaTime, const float InterpSpeed);
// LINE MATH
// For given line defined by lineFrom -> lineTo, how far away from that line is CheckPoint?
float vDistanceFromLine3D(const Vector lineFrom, const Vector lineTo, const Vector CheckPoint);
// For given line defined by lineFrom -> lineTo, how far away from that line is CheckPoint? Ignores Z axis
float vDistanceFromLine2D(const Vector lineFrom, const Vector lineTo, const Vector CheckPoint);
// For given line defined by lineFrom -> lineTo, get squared distance from that line of CheckPoint. Ignores Z axis
float vDistanceFromLine2DSq(const Vector lineFrom, const Vector lineTo, const Vector CheckPoint);
// Returns 0 if point sits right on the line defined by lineFrom -> lineTo, -1 if it sits to the left, 1 if it sits to the right. Ignores Z axis
int vPointOnLine(const Vector lineFrom, const Vector lineTo, const Vector point);
// Finds the closest point along a line to the input point
Vector vClosestPointOnLine(const Vector lineFrom, const Vector lineTo, const Vector point);
// Finds the closest point along a line to the input point, ignores Z axis
Vector vClosestPointOnLine2D(const Vector lineFrom, const Vector lineTo, const Vector point);
// Finds the closest point along a line to the input point, assumes infinite line
Vector vClosestPointOnInfiniteLine3D(const Vector PointOnLine, const Vector NormalisedLineDir, const Vector TestPoint);
// Finds the closest point along a line to the input point, assumes infinite line. Ignores Z axis
Vector vClosestPointOnInfiniteLine2D(const Vector PointOnLine, const Vector NormalisedLineDir, const Vector TestPoint);
// CONVERSIONS
// Converts input metres to GoldSrc units (approx 1 metres = 52.5 units)
float UTIL_MetresToGoldSrcUnits(const float Metres);
// Converts input GoldSrc units to metres (approx 52.5 units = 1 metre)
float UTIL_GoldSrcUnitsToMetres(const float GoldSrcUnits);
// Converts angles to unit vector
void UTIL_AnglesToVector(const Vector angles, Vector* fwd, Vector* right, Vector* up);
// Returns unit vector pointing in direction of input angles
Vector UTIL_GetForwardVector(const Vector angles);
// Returns 2D unit vector pointing in direction of input view angles, ignoring Z axis
Vector UTIL_GetForwardVector2D(const Vector angles);
// GEOMETRY STUFF
// Returns random point on a circle, assuming circle normal is (0, 0, 1)
Vector UTIL_RandomPointOnCircle(const Vector origin, const float radius);
// Returns the required pitch needed to hit the target point from launch point, taking projectile speed and gravity into account
Vector GetPitchForProjectile(Vector LaunchPoint, Vector TargetPoint, const float ProjectileSpeed, const float Gravity);
// Confirms if the given point is on the inside of a frustum plane or not
bool UTIL_PointInsidePlane(const frustum_plane_t* plane, const Vector point);
/* Tests to see if the defined cylinder is intersecting with the supplied frustum plane.
Since players are always upright, it is reasonable to assume that it is impossible for both the
top and bottom of the cylinder to be outside the plane if it is intersecting, therefore
we only need to test the top and bottom cylinder at the closest point to the plane.*/
bool UTIL_CylinderInsidePlane(const frustum_plane_t* plane, const Vector centre, float height, float radius);
// Set the normal and position for the plane based on the 3 points defining it
void UTIL_SetFrustumPlane(frustum_plane_t* plane, Vector v1, Vector v2, Vector v3);
// Finds the closest point to the polygon, defined by segments (edges)
float UTIL_GetDistanceToPolygon2DSq(const Vector TestPoint, const Vector* Segments, const int NumSegments);
// Based on the target's motion and the weapon's projectile speed, where should the bot aim to lead the target and hit them?
Vector UTIL_GetAimLocationToLeadTarget(const Vector ShooterLocation, const Vector TargetLocation, const Vector TargetVelocity, const float ProjectileVelocity);
// If flying through the air (e.g. blink), what velocity does the bot need to land on the target spot?
float UTIL_GetVelocityRequiredToReachTarget(const Vector StartLocation, const Vector TargetLocation, float Gravity);
Vector UTIL_GetRandomPointInBoundingBox(const Vector BoxMin, const Vector BoxMax);
// OTHER STUFF
// Function to get number of set bits in a positive integer n
unsigned int UTIL_CountSetBitsInInteger(unsigned int n);
float UTIL_CalculateSlopeAngleBetweenPoints(const Vector StartPoint, const Vector EndPoint);
#endif