fix: logos config not initialized (resolves #691)
bot: make sure rescue zone icon blinking to consider bot reached rescue zone when escorting hostages (ref #688) bot: remove hardcoded radio communication randoms, so they're now depends on bots personality refactor: some refactoring of code
This commit is contained in:
parent
d6d76e136d
commit
6dfb09f110
26 changed files with 180 additions and 141 deletions
|
|
@ -43,7 +43,7 @@ set(YAPB_SRC
|
||||||
"src/vistable.cpp"
|
"src/vistable.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} MODULE ${YAPB_SRC})
|
add_library(${PROJECT_NAME} SHARED ${YAPB_SRC})
|
||||||
find_package(Git QUIET)
|
find_package(Git QUIET)
|
||||||
|
|
||||||
if(GIT_FOUND)
|
if(GIT_FOUND)
|
||||||
|
|
@ -110,9 +110,13 @@ if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU"
|
||||||
set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8 OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc")
|
if(VITA)
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -fPIC)
|
target_compile_options(${PROJECT_NAME} PRIVATE -fno-use-cxa-atexit)
|
||||||
target_link_options(${PROJECT_NAME} PRIVATE -fPIC)
|
else()
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8 OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc")
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -fPIC)
|
||||||
|
target_link_options(${PROJECT_NAME} PRIVATE -fPIC)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
elseif(WIN32 AND MSVC)
|
elseif(WIN32 AND MSVC)
|
||||||
set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
|
|
@ -132,7 +136,7 @@ if(WIN32 OR MINGW)
|
||||||
target_sources(${PROJECT_NAME} PRIVATE "vc/yapb.rc")
|
target_sources(${PROJECT_NAME} PRIVATE "vc/yapb.rc")
|
||||||
elseif(ANDROID)
|
elseif(ANDROID)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE m dl log)
|
target_link_libraries(${PROJECT_NAME} PRIVATE m dl log)
|
||||||
else()
|
elseif(NOT VITA)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE m dl pthread)
|
target_link_libraries(${PROJECT_NAME} PRIVATE m dl pthread)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 01a2628642b5d28c42d115bbe99167756376839c
|
Subproject commit 43f0acc90e9042efb8e9f7287bfa6935a0f4bc90
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit bd5617f41c84fa1f4e5800c75ea286f4d3cba62e
|
Subproject commit a21540a52d7559333ad9d8326411daf78af62891
|
||||||
|
|
@ -53,7 +53,7 @@ private:
|
||||||
void cleanup ();
|
void cleanup ();
|
||||||
|
|
||||||
// show overlay message about analyzing
|
// show overlay message about analyzing
|
||||||
void displayOverlayMessage ();
|
void displayOverlayMessage () const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ public:
|
||||||
void levelShutdown ();
|
void levelShutdown ();
|
||||||
|
|
||||||
// display world line
|
// display world line
|
||||||
void drawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, const Color &color, int brightness, int speed, int life, DrawLine type = DrawLine::Simple);
|
void drawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, const Color &color, int brightness, int speed, int life, DrawLine type = DrawLine::Simple) const;
|
||||||
|
|
||||||
// test line
|
// test line
|
||||||
void testLine (const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult *ptr);
|
void testLine (const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult *ptr);
|
||||||
|
|
@ -260,13 +260,13 @@ public:
|
||||||
void searchEntities (StringRef field, StringRef value, EntitySearch functor);
|
void searchEntities (StringRef field, StringRef value, EntitySearch functor);
|
||||||
|
|
||||||
// search entities in sphere
|
// search entities in sphere
|
||||||
void searchEntities (const Vector &position, float radius, EntitySearch functor);
|
void searchEntities (const Vector &position, float radius, EntitySearch functor) const;
|
||||||
|
|
||||||
// check if map has entity
|
// check if map has entity
|
||||||
bool hasEntityInGame (StringRef classname);
|
bool hasEntityInGame (StringRef classname);
|
||||||
|
|
||||||
// print the version to server console on startup
|
// print the version to server console on startup
|
||||||
void printBotVersion ();
|
void printBotVersion () const;
|
||||||
|
|
||||||
// ensure prosperous gaming environment as per: https://github.com/yapb/yapb/issues/575
|
// ensure prosperous gaming environment as per: https://github.com/yapb/yapb/issues/575
|
||||||
void ensureHealthyGameEnvironment ();
|
void ensureHealthyGameEnvironment ();
|
||||||
|
|
@ -388,7 +388,7 @@ public:
|
||||||
bool checkVisibility (edict_t *ent, uint8_t *set);
|
bool checkVisibility (edict_t *ent, uint8_t *set);
|
||||||
|
|
||||||
// get pvs/pas visibility set
|
// get pvs/pas visibility set
|
||||||
uint8_t *getVisibilitySet (Bot *bot, bool pvs);
|
uint8_t *getVisibilitySet (Bot *bot, bool pvs) const;
|
||||||
|
|
||||||
// what kind of game engine / game dll / mod / tool we're running ?
|
// what kind of game engine / game dll / mod / tool we're running ?
|
||||||
bool is (const int type) const {
|
bool is (const int type) const {
|
||||||
|
|
|
||||||
12
inc/graph.h
12
inc/graph.h
|
|
@ -218,9 +218,9 @@ public:
|
||||||
bool convertOldFormat ();
|
bool convertOldFormat ();
|
||||||
bool isConnected (int a, int b);
|
bool isConnected (int a, int b);
|
||||||
bool isConnected (int index);
|
bool isConnected (int index);
|
||||||
bool isNodeReacheableEx (const Vector &src, const Vector &destination, const float maxHeight);
|
bool isNodeReacheableEx (const Vector &src, const Vector &destination, const float maxHeight) const;
|
||||||
bool isNodeReacheable (const Vector &src, const Vector &destination);
|
bool isNodeReacheable (const Vector &src, const Vector &destination) const;
|
||||||
bool isNodeReacheableWithJump (const Vector &src, const Vector &destination);
|
bool isNodeReacheableWithJump (const Vector &src, const Vector &destination) const;
|
||||||
bool checkNodes (bool teleportPlayer, bool onlyPaths = false);
|
bool checkNodes (bool teleportPlayer, bool onlyPaths = false);
|
||||||
bool isVisited (int index);
|
bool isVisited (int index);
|
||||||
|
|
||||||
|
|
@ -255,13 +255,13 @@ public:
|
||||||
void eraseFromBucket (const Vector &pos, int index);
|
void eraseFromBucket (const Vector &pos, int index);
|
||||||
void setBombOrigin (bool reset = false, const Vector &pos = nullptr);
|
void setBombOrigin (bool reset = false, const Vector &pos = nullptr);
|
||||||
void unassignPath (int from, int to);
|
void unassignPath (int from, int to);
|
||||||
void convertFromPOD (Path &path, const PODPath &pod);
|
void convertFromPOD (Path &path, const PODPath &pod) const;
|
||||||
void convertToPOD (const Path &path, PODPath &pod);
|
void convertToPOD (const Path &path, PODPath &pod);
|
||||||
void convertCampDirection (Path &path);
|
void convertCampDirection (Path &path) const;
|
||||||
void setAutoPathDistance (const float distance);
|
void setAutoPathDistance (const float distance);
|
||||||
void showStats ();
|
void showStats ();
|
||||||
void showFileInfo ();
|
void showFileInfo ();
|
||||||
void emitNotify (int32_t sound);
|
void emitNotify (int32_t sound) const;
|
||||||
void syncCollectOnline ();
|
void syncCollectOnline ();
|
||||||
void collectOnline ();
|
void collectOnline ();
|
||||||
|
|
||||||
|
|
|
||||||
27
inc/hooks.h
27
inc/hooks.h
|
|
@ -109,19 +109,22 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// used for transit calls between game dll and engine without all needed functions on bot side
|
// used for transit calls between game dll and engine without all needed functions on bot side
|
||||||
class DynamicLinkerHook : public Singleton <DynamicLinkerHook> {
|
class EntityLinkHook : public Singleton <EntityLinkHook> {
|
||||||
private:
|
private:
|
||||||
#if defined(CR_WINDOWS)
|
#if defined(CR_WINDOWS)
|
||||||
# define DLSYM_FUNCTION GetProcAddress
|
# define DLSYM_FUNCTION GetProcAddress
|
||||||
# define DLCLOSE_FUNCTION FreeLibrary
|
# define DLCLOSE_FUNCTION FreeLibrary
|
||||||
|
#elif defined(CR_PSVITA) // just a shim
|
||||||
|
# define DLSYM_FUNCTION vrtld_dlsym
|
||||||
|
# define DLCLOSE_FUNCTION vrtld_dlclose
|
||||||
#else
|
#else
|
||||||
# define DLSYM_FUNCTION dlsym
|
# define DLSYM_FUNCTION dlsym
|
||||||
# define DLCLOSE_FUNCTION dlclose
|
# define DLCLOSE_FUNCTION dlclose
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using DlsymProto = SharedLibrary::Func CR_STDCALL (SharedLibrary::Handle, const char *);
|
using DlsymProto = decltype (DLSYM_FUNCTION);
|
||||||
using DlcloseProto = int CR_STDCALL (SharedLibrary::Handle);
|
using DlcloseProto = decltype (DLCLOSE_FUNCTION);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_paused { false };
|
bool m_paused { false };
|
||||||
|
|
@ -133,16 +136,16 @@ private:
|
||||||
SharedLibrary m_self {};
|
SharedLibrary m_self {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DynamicLinkerHook () = default;
|
EntityLinkHook () = default;
|
||||||
~DynamicLinkerHook () = default;
|
~EntityLinkHook () = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void initialize ();
|
void initialize ();
|
||||||
bool needsBypass () const;
|
bool needsBypass () const;
|
||||||
|
|
||||||
SharedLibrary::Func lookup (SharedLibrary::Handle module, const char *function);
|
SharedLibrary::Func lookupSymbol (SharedLibrary::Handle module, const char *function);
|
||||||
|
|
||||||
decltype (auto) close (SharedLibrary::Handle module) {
|
decltype (auto) freeLibrary (SharedLibrary::Handle module) {
|
||||||
if (m_self.handle () == module) {
|
if (m_self.handle () == module) {
|
||||||
disable ();
|
disable ();
|
||||||
return m_dlclose (module);
|
return m_dlclose (module);
|
||||||
|
|
@ -177,15 +180,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CR_FORCE_STACK_ALIGN static SharedLibrary::Func CR_STDCALL lookupHandler (SharedLibrary::Handle module, const char *function) {
|
CR_FORCE_STACK_ALIGN static SharedLibrary::Func CR_STDCALL lookupHandler (SharedLibrary::Handle handle, const char *function) {
|
||||||
return instance ().lookup (module, function);
|
return instance ().lookupSymbol (handle, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
CR_FORCE_STACK_ALIGN static int CR_STDCALL closeHandler (SharedLibrary::Handle module) {
|
CR_FORCE_STACK_ALIGN static int CR_STDCALL closeHandler (SharedLibrary::Handle handle) {
|
||||||
return instance ().close (module);
|
return instance ().freeLibrary (handle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// expose global
|
// expose global
|
||||||
CR_EXPOSE_GLOBAL_SINGLETON (DynamicLinkerHook, entlink);
|
CR_EXPOSE_GLOBAL_SINGLETON (EntityLinkHook, entlink);
|
||||||
CR_EXPOSE_GLOBAL_SINGLETON (ServerQueryHook, fakequeries);
|
CR_EXPOSE_GLOBAL_SINGLETON (ServerQueryHook, fakequeries);
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ public:
|
||||||
void kickEveryone (bool instant = false, bool zeroQuota = true);
|
void kickEveryone (bool instant = false, bool zeroQuota = true);
|
||||||
void kickBot (int index);
|
void kickBot (int index);
|
||||||
void kickFromTeam (Team team, bool removeAll = false);
|
void kickFromTeam (Team team, bool removeAll = false);
|
||||||
void killAllBots (int team = -1, bool silent = false);
|
void killAllBots (int team = Team::Invalid, bool silent = false);
|
||||||
void maintainQuota ();
|
void maintainQuota ();
|
||||||
void maintainAutoKill ();
|
void maintainAutoKill ();
|
||||||
void maintainLeaders ();
|
void maintainLeaders ();
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ public:
|
||||||
bool load ();
|
bool load ();
|
||||||
|
|
||||||
// flush matrices to disk, so we will not rebuild them on load same map
|
// flush matrices to disk, so we will not rebuild them on load same map
|
||||||
void save ();
|
void save () const;
|
||||||
|
|
||||||
// do the pathfinding
|
// do the pathfinding
|
||||||
bool find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, int *pathDistance = nullptr);
|
bool find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, int *pathDistance = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// updates bot view frustum
|
// updates bot view frustum
|
||||||
void calculate (Planes &planes, const Vector &viewAngle, const Vector &viewOffset);
|
void calculate (Planes &planes, const Vector &viewAngle, const Vector &viewOffset) const;
|
||||||
|
|
||||||
// check if object inside frustum plane
|
// check if object inside frustum plane
|
||||||
bool isObjectInsidePlane (const Plane &plane, const Vector ¢er, float height, float radius) const;
|
bool isObjectInsidePlane (const Plane &plane, const Vector ¢er, float height, float radius) const;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public:
|
||||||
bool visible (int srcIndex, int destIndex, VisIndex vis = VisIndex::Any);
|
bool visible (int srcIndex, int destIndex, VisIndex vis = VisIndex::Any);
|
||||||
|
|
||||||
void load ();
|
void load ();
|
||||||
void save ();
|
void save () const;
|
||||||
void rebuild ();
|
void rebuild ();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
55
inc/yapb.h
55
inc/yapb.h
|
|
@ -225,6 +225,7 @@ private:
|
||||||
int m_tryOpenDoor {}; // attempt's to open the door
|
int m_tryOpenDoor {}; // attempt's to open the door
|
||||||
int m_liftState {}; // state of lift handling
|
int m_liftState {}; // state of lift handling
|
||||||
int m_radioSelect {}; // radio entry
|
int m_radioSelect {}; // radio entry
|
||||||
|
int m_radioPercent {}; // radio usage percent (in response)
|
||||||
int m_killsCount {}; // the kills count of a bot
|
int m_killsCount {}; // the kills count of a bot
|
||||||
|
|
||||||
int m_lastPredictIndex {}; // last predicted path index
|
int m_lastPredictIndex {}; // last predicted path index
|
||||||
|
|
@ -370,7 +371,7 @@ private:
|
||||||
CountdownTimer m_repathTimer {}; // bots is going to repath his route
|
CountdownTimer m_repathTimer {}; // bots is going to repath his route
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int pickBestWeapon (Array <int> &vec, int moneySave);
|
int pickBestWeapon (Array <int> &vec, int moneySave) const;
|
||||||
int getRandomCampDir ();
|
int getRandomCampDir ();
|
||||||
int findAimingNode (const Vector &to, int &pathLength);
|
int findAimingNode (const Vector &to, int &pathLength);
|
||||||
int findNearestNode ();
|
int findNearestNode ();
|
||||||
|
|
@ -382,18 +383,18 @@ private:
|
||||||
int findGoalPost (int tactic, IntArray *defensive, IntArray *offensive);
|
int findGoalPost (int tactic, IntArray *defensive, IntArray *offensive);
|
||||||
int bestPrimaryCarried ();
|
int bestPrimaryCarried ();
|
||||||
int bestSecondaryCarried ();
|
int bestSecondaryCarried ();
|
||||||
int bestGrenadeCarried ();
|
int bestGrenadeCarried () const;
|
||||||
int getBestOwnedWeapon ();
|
int getBestOwnedWeapon () const;
|
||||||
int getBestOwnedPistol ();
|
int getBestOwnedPistol () const;
|
||||||
int changeNodeIndex (int index);
|
int changeNodeIndex (int index);
|
||||||
int numEnemiesNear (const Vector &origin, const float radius);
|
int numEnemiesNear (const Vector &origin, const float radius) const;
|
||||||
int numFriendsNear (const Vector &origin, const float radius);
|
int numFriendsNear (const Vector &origin, const float radius) const;
|
||||||
|
|
||||||
float getBombTimeleft () const;
|
float getBombTimeleft () const;
|
||||||
float getEstimatedNodeReachTime ();
|
float getEstimatedNodeReachTime ();
|
||||||
float isInFOV (const Vector &dest);
|
float isInFOV (const Vector &dest) const;
|
||||||
float getShiftSpeed ();
|
float getShiftSpeed ();
|
||||||
float calculateScaleFactor (edict_t *ent);
|
float calculateScaleFactor (edict_t *ent) const;
|
||||||
|
|
||||||
bool canReplaceWeapon ();
|
bool canReplaceWeapon ();
|
||||||
bool canDuckUnder (const Vector &normal);
|
bool canDuckUnder (const Vector &normal);
|
||||||
|
|
@ -418,14 +419,14 @@ private:
|
||||||
bool seesEnemy (edict_t *player);
|
bool seesEnemy (edict_t *player);
|
||||||
bool hasActiveGoal ();
|
bool hasActiveGoal ();
|
||||||
bool advanceMovement ();
|
bool advanceMovement ();
|
||||||
bool isBombDefusing (const Vector &bombOrigin);
|
bool isBombDefusing (const Vector &bombOrigin) const;
|
||||||
bool isOccupiedNode (int index, bool needZeroVelocity = false);
|
bool isOccupiedNode (int index, bool needZeroVelocity = false);
|
||||||
bool seesItem (const Vector &dest, StringRef classname);
|
bool seesItem (const Vector &dest, StringRef classname);
|
||||||
bool lastEnemyShootable ();
|
bool lastEnemyShootable ();
|
||||||
bool rateGroundWeapon (edict_t *ent);
|
bool rateGroundWeapon (edict_t *ent);
|
||||||
bool reactOnEnemy ();
|
bool reactOnEnemy ();
|
||||||
bool selectBestNextNode ();
|
bool selectBestNextNode ();
|
||||||
bool hasAnyWeapons ();
|
bool hasAnyWeapons () const;
|
||||||
bool hasAnyAmmoInClip ();
|
bool hasAnyAmmoInClip ();
|
||||||
bool isKnifeMode ();
|
bool isKnifeMode ();
|
||||||
bool isGrenadeWar ();
|
bool isGrenadeWar ();
|
||||||
|
|
@ -439,13 +440,13 @@ private:
|
||||||
bool isEnemyHidden (edict_t *enemy);
|
bool isEnemyHidden (edict_t *enemy);
|
||||||
bool isEnemyInvincible (edict_t *enemy);
|
bool isEnemyInvincible (edict_t *enemy);
|
||||||
bool isEnemyNoTarget (edict_t *enemy);
|
bool isEnemyNoTarget (edict_t *enemy);
|
||||||
bool isEnemyInDarkArea (edict_t *enemy);
|
bool isEnemyInDarkArea (edict_t *enemy) const;
|
||||||
bool isFriendInLineOfFire (float distance);
|
bool isFriendInLineOfFire (float distance) const;
|
||||||
bool isGroupOfEnemies (const Vector &location);
|
bool isGroupOfEnemies (const Vector &location);
|
||||||
bool isPenetrableObstacle (const Vector &dest);
|
bool isPenetrableObstacle (const Vector &dest);
|
||||||
bool isPenetrableObstacle1 (const Vector &dest, int penetratePower);
|
bool isPenetrableObstacle1 (const Vector &dest, int penetratePower) const;
|
||||||
bool isPenetrableObstacle2 (const Vector &dest, int penetratePower);
|
bool isPenetrableObstacle2 (const Vector &dest, int penetratePower) const;
|
||||||
bool isPenetrableObstacle3 (const Vector &dest, int penetratePower);
|
bool isPenetrableObstacle3 (const Vector &dest, int penetratePower) const;
|
||||||
bool isEnemyBehindShield (edict_t *enemy);
|
bool isEnemyBehindShield (edict_t *enemy);
|
||||||
bool checkChatKeywords (String &reply);
|
bool checkChatKeywords (String &reply);
|
||||||
bool isReplyingToChat ();
|
bool isReplyingToChat ();
|
||||||
|
|
@ -455,13 +456,13 @@ private:
|
||||||
bool canRunHeavyWeight ();
|
bool canRunHeavyWeight ();
|
||||||
bool isEnemyInSight (Vector &endPos);
|
bool isEnemyInSight (Vector &endPos);
|
||||||
bool isEnemyNoticeable (float range);
|
bool isEnemyNoticeable (float range);
|
||||||
bool isCreature ();
|
bool isCreature () const;
|
||||||
bool isPreviousLadder ();
|
bool isPreviousLadder () const;
|
||||||
bool isIgnoredItem (edict_t *ent);
|
bool isIgnoredItem (edict_t *ent);
|
||||||
|
|
||||||
void doPlayerAvoidance (const Vector &normal);
|
void doPlayerAvoidance (const Vector &normal);
|
||||||
void selectCampButtons (int index);
|
void selectCampButtons (int index);
|
||||||
void instantChatter (int type);
|
void instantChatter (int type) const;
|
||||||
void update ();
|
void update ();
|
||||||
void runMovement ();
|
void runMovement ();
|
||||||
void checkSpawnConditions ();
|
void checkSpawnConditions ();
|
||||||
|
|
@ -488,7 +489,7 @@ private:
|
||||||
void checkFall ();
|
void checkFall ();
|
||||||
void checkDarkness ();
|
void checkDarkness ();
|
||||||
void checkParachute ();
|
void checkParachute ();
|
||||||
void updatePracticeValue (int damage);
|
void updatePracticeValue (int damage) const;
|
||||||
void updatePracticeDamage (edict_t *attacker, int damage);
|
void updatePracticeDamage (edict_t *attacker, int damage);
|
||||||
void findShortestPath (int srcIndex, int destIndex);
|
void findShortestPath (int srcIndex, int destIndex);
|
||||||
void findPath (int srcIndex, int destIndex, FindPath pathType = FindPath::Fast);
|
void findPath (int srcIndex, int destIndex, FindPath pathType = FindPath::Fast);
|
||||||
|
|
@ -563,9 +564,9 @@ private:
|
||||||
Vector isBombAudible ();
|
Vector isBombAudible ();
|
||||||
Vector getBodyOffsetError (float distance);
|
Vector getBodyOffsetError (float distance);
|
||||||
Vector getCampDirection (const Vector &dest);
|
Vector getCampDirection (const Vector &dest);
|
||||||
Vector getCustomHeight (float distance);
|
Vector getCustomHeight (float distance) const;
|
||||||
|
|
||||||
uint8_t computeMsec ();
|
uint8_t computeMsec () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isOnLadder () const {
|
bool isOnLadder () const {
|
||||||
|
|
@ -735,7 +736,7 @@ public:
|
||||||
void pushMsgQueue (int message);
|
void pushMsgQueue (int message);
|
||||||
void prepareChatMessage (StringRef message);
|
void prepareChatMessage (StringRef message);
|
||||||
void checkForChat ();
|
void checkForChat ();
|
||||||
void showChatterIcon (bool show, bool disconnect = false);
|
void showChatterIcon (bool show, bool disconnect = false) const;
|
||||||
void clearSearchNodes ();
|
void clearSearchNodes ();
|
||||||
void checkBreakable (edict_t *touch);
|
void checkBreakable (edict_t *touch);
|
||||||
void checkBreakablesAround ();
|
void checkBreakablesAround ();
|
||||||
|
|
@ -757,16 +758,16 @@ public:
|
||||||
void sendBotToOrigin (const Vector &origin);
|
void sendBotToOrigin (const Vector &origin);
|
||||||
void markStale ();
|
void markStale ();
|
||||||
bool hasHostage ();
|
bool hasHostage ();
|
||||||
bool hasPrimaryWeapon ();
|
bool hasPrimaryWeapon () const;
|
||||||
bool hasSecondaryWeapon ();
|
bool hasSecondaryWeapon () const;
|
||||||
bool hasShield ();
|
bool hasShield ();
|
||||||
bool isShieldDrawn ();
|
bool isShieldDrawn ();
|
||||||
bool findNextBestNode ();
|
bool findNextBestNode ();
|
||||||
bool findNextBestNodeEx (const IntArray &data, bool handleFails);
|
bool findNextBestNodeEx (const IntArray &data, bool handleFails);
|
||||||
bool seesEntity (const Vector &dest, bool fromBody = false);
|
bool seesEntity (const Vector &dest, bool fromBody = false);
|
||||||
|
|
||||||
int getAmmo ();
|
int getAmmo () const;
|
||||||
int getAmmo (int id);
|
int getAmmo (int id) const;
|
||||||
int getNearestToPlantedBomb ();
|
int getNearestToPlantedBomb ();
|
||||||
|
|
||||||
float getConnectionTime ();
|
float getConnectionTime ();
|
||||||
|
|
@ -793,7 +794,7 @@ public:
|
||||||
return getTask ()->id;
|
return getTask ()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
edict_t *ent () {
|
edict_t *ent () const {
|
||||||
return pev->pContainingEntity;
|
return pev->pContainingEntity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ void GraphAnalyze::cleanup () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAnalyze::displayOverlayMessage () {
|
void GraphAnalyze::displayOverlayMessage () const {
|
||||||
auto listenserverEdict = game.getLocalEntity ();
|
auto listenserverEdict = game.getLocalEntity ();
|
||||||
|
|
||||||
if (game.isNullEntity (listenserverEdict) || !m_isAnalyzing) {
|
if (game.isNullEntity (listenserverEdict) || !m_isAnalyzing) {
|
||||||
|
|
|
||||||
|
|
@ -856,7 +856,7 @@ Vector Bot::getCampDirection (const Vector &dest) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::showChatterIcon (bool show, bool disconnect) {
|
void Bot::showChatterIcon (bool show, bool disconnect) const {
|
||||||
// this function depending on show boolean, shows/remove chatter, icon, on the head of bot.
|
// this function depending on show boolean, shows/remove chatter, icon, on the head of bot.
|
||||||
|
|
||||||
if (!game.is (GameFlags::HasBotVoice) || cv_radio_mode.as <int> () != 2) {
|
if (!game.is (GameFlags::HasBotVoice) || cv_radio_mode.as <int> () != 2) {
|
||||||
|
|
@ -894,7 +894,7 @@ void Bot::showChatterIcon (bool show, bool disconnect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::instantChatter (int type) {
|
void Bot::instantChatter (int type) const {
|
||||||
// this function sends instant chatter messages.
|
// this function sends instant chatter messages.
|
||||||
if (!game.is (GameFlags::HasBotVoice)
|
if (!game.is (GameFlags::HasBotVoice)
|
||||||
|| cv_radio_mode.as <int> () != 2
|
|| cv_radio_mode.as <int> () != 2
|
||||||
|
|
@ -1222,7 +1222,7 @@ bool Bot::canReplaceWeapon () {
|
||||||
return isWeaponRestricted (m_currentWeapon);
|
return isWeaponRestricted (m_currentWeapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::pickBestWeapon (Array <int> &vec, int moneySave) {
|
int Bot::pickBestWeapon (Array <int> &vec, int moneySave) const {
|
||||||
// this function picks best available weapon from random choice with money save
|
// this function picks best available weapon from random choice with money save
|
||||||
|
|
||||||
if (vec.length () < 2) {
|
if (vec.length () < 2) {
|
||||||
|
|
@ -1890,6 +1890,7 @@ void Bot::setConditions () {
|
||||||
if (m_agressionLevel > 1.0f) {
|
if (m_agressionLevel > 1.0f) {
|
||||||
m_agressionLevel = 1.0f;
|
m_agressionLevel = 1.0f;
|
||||||
}
|
}
|
||||||
|
m_radioPercent = cr::min (m_radioPercent - rg (1, 5), 15);
|
||||||
|
|
||||||
if (rg.chance (10)) {
|
if (rg.chance (10)) {
|
||||||
pushChatMessage (Chat::Kill);
|
pushChatMessage (Chat::Kill);
|
||||||
|
|
@ -2450,7 +2451,7 @@ void Bot::checkRadioQueue () {
|
||||||
if (seesEntity (m_radioEntity->v.origin) || m_radioOrder == Radio::StickTogetherTeam) {
|
if (seesEntity (m_radioEntity->v.origin) || m_radioOrder == Radio::StickTogetherTeam) {
|
||||||
if (game.isNullEntity (m_targetEntity)
|
if (game.isNullEntity (m_targetEntity)
|
||||||
&& game.isNullEntity (m_enemy)
|
&& game.isNullEntity (m_enemy)
|
||||||
&& rg.chance (m_personality == Personality::Careful ? 80 : 20)) {
|
&& rg.chance (m_radioPercent)) {
|
||||||
|
|
||||||
int numFollowers = 0;
|
int numFollowers = 0;
|
||||||
|
|
||||||
|
|
@ -2494,11 +2495,11 @@ void Bot::checkRadioQueue () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_radioOrder != Chatter::GoingToPlantBomb && rg.chance (25)) {
|
else if (m_radioOrder != Chatter::GoingToPlantBomb && rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::Negative);
|
pushRadioMessage (Radio::Negative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_radioOrder != Chatter::GoingToPlantBomb && rg.chance (35)) {
|
else if (m_radioOrder != Chatter::GoingToPlantBomb && rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::Negative);
|
pushRadioMessage (Radio::Negative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2530,7 +2531,7 @@ void Bot::checkRadioQueue () {
|
||||||
m_fearLevel = 0.0f;
|
m_fearLevel = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rg.chance (45) && cv_radio_mode.as <int> () == 2) {
|
if (rg.chance (m_radioPercent) && cv_radio_mode.as <int> () == 2) {
|
||||||
pushChatterMessage (Chatter::OnMyWay);
|
pushChatterMessage (Chatter::OnMyWay);
|
||||||
}
|
}
|
||||||
else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as <int> () != 2) {
|
else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as <int> () != 2) {
|
||||||
|
|
@ -2538,7 +2539,7 @@ void Bot::checkRadioQueue () {
|
||||||
}
|
}
|
||||||
tryHeadTowardRadioMessage ();
|
tryHeadTowardRadioMessage ();
|
||||||
}
|
}
|
||||||
else if (rg.chance (25)) {
|
else if (rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::Negative);
|
pushRadioMessage (Radio::Negative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2559,7 +2560,7 @@ void Bot::checkRadioQueue () {
|
||||||
case Chatter::ScaredEmotion:
|
case Chatter::ScaredEmotion:
|
||||||
case Chatter::PinnedDown:
|
case Chatter::PinnedDown:
|
||||||
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (2048.0f) || !m_moveToC4)
|
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (2048.0f) || !m_moveToC4)
|
||||||
&& rg.chance (50)
|
&& rg.chance (m_radioPercent)
|
||||||
&& m_seeEnemyTime + 4.0f < game.time ()) {
|
&& m_seeEnemyTime + 4.0f < game.time ()) {
|
||||||
|
|
||||||
m_fearLevel -= 0.1f;
|
m_fearLevel -= 0.1f;
|
||||||
|
|
@ -2568,22 +2569,22 @@ void Bot::checkRadioQueue () {
|
||||||
m_fearLevel = 0.0f;
|
m_fearLevel = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rg.chance (45) && cv_radio_mode.as <int> () == 2) {
|
if (rg.chance (m_radioPercent) && cv_radio_mode.as <int> () == 2) {
|
||||||
pushChatterMessage (Chatter::OnMyWay);
|
pushChatterMessage (Chatter::OnMyWay);
|
||||||
}
|
}
|
||||||
else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as <int> () != 2 && rg.chance (50)) {
|
else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as <int> () != 2 && rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::RogerThat);
|
pushRadioMessage (Radio::RogerThat);
|
||||||
}
|
}
|
||||||
tryHeadTowardRadioMessage ();
|
tryHeadTowardRadioMessage ();
|
||||||
}
|
}
|
||||||
else if (rg.chance (30) && m_radioOrder == Radio::NeedBackup) {
|
else if (rg.chance (m_radioPercent) && m_radioOrder == Radio::NeedBackup) {
|
||||||
pushRadioMessage (Radio::Negative);
|
pushRadioMessage (Radio::Negative);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Radio::GoGoGo:
|
case Radio::GoGoGo:
|
||||||
if (m_radioEntity == m_targetEntity) {
|
if (m_radioEntity == m_targetEntity) {
|
||||||
if (rg.chance (45) && cv_radio_mode.as <int> () == 2) {
|
if (rg.chance (m_radioPercent) && cv_radio_mode.as <int> () == 2) {
|
||||||
pushRadioMessage (Radio::RogerThat);
|
pushRadioMessage (Radio::RogerThat);
|
||||||
}
|
}
|
||||||
else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as <int> () != 2) {
|
else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as <int> () != 2) {
|
||||||
|
|
@ -2622,7 +2623,7 @@ void Bot::checkRadioQueue () {
|
||||||
pushRadioMessage (Radio::RogerThat);
|
pushRadioMessage (Radio::RogerThat);
|
||||||
resetDoubleJump ();
|
resetDoubleJump ();
|
||||||
}
|
}
|
||||||
else if (rg.chance (35)) {
|
else if (rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::Negative);
|
pushRadioMessage (Radio::Negative);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2637,7 +2638,7 @@ void Bot::checkRadioQueue () {
|
||||||
m_targetEntity = nullptr;
|
m_targetEntity = nullptr;
|
||||||
startTask (Task::EscapeFromBomb, TaskPri::EscapeFromBomb, kInvalidNodeIndex, 0.0f, true);
|
startTask (Task::EscapeFromBomb, TaskPri::EscapeFromBomb, kInvalidNodeIndex, 0.0f, true);
|
||||||
}
|
}
|
||||||
else if (rg.chance (35)) {
|
else if (rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::Negative);
|
pushRadioMessage (Radio::Negative);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2656,7 +2657,7 @@ void Bot::checkRadioQueue () {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Radio::StormTheFront:
|
case Radio::StormTheFront:
|
||||||
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (1024.0f)) && rg.chance (50)) {
|
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (1024.0f)) && rg.chance (m_radioPercent)) {
|
||||||
pushRadioMessage (Radio::RogerThat);
|
pushRadioMessage (Radio::RogerThat);
|
||||||
|
|
||||||
// don't pause/camp anymore
|
// don't pause/camp anymore
|
||||||
|
|
@ -2738,7 +2739,7 @@ void Bot::checkRadioQueue () {
|
||||||
case Radio::ReportInTeam:
|
case Radio::ReportInTeam:
|
||||||
switch (getCurrentTaskId ()) {
|
switch (getCurrentTaskId ()) {
|
||||||
case Task::Normal:
|
case Task::Normal:
|
||||||
if (getTask ()->data != kInvalidNodeIndex && rg.chance (70)) {
|
if (getTask ()->data != kInvalidNodeIndex && rg.chance (m_radioPercent)) {
|
||||||
const auto &path = graph[getTask ()->data];
|
const auto &path = graph[getTask ()->data];
|
||||||
|
|
||||||
if (path.flags & NodeFlag::Goal) {
|
if (path.flags & NodeFlag::Goal) {
|
||||||
|
|
@ -2752,14 +2753,14 @@ void Bot::checkRadioQueue () {
|
||||||
else if (m_hasHostage) {
|
else if (m_hasHostage) {
|
||||||
pushChatterMessage (Chatter::RescuingHostages);
|
pushChatterMessage (Chatter::RescuingHostages);
|
||||||
}
|
}
|
||||||
else if ((path.flags & NodeFlag::Camp) && rg.chance (75)) {
|
else if ((path.flags & NodeFlag::Camp) && rg.chance (m_radioPercent)) {
|
||||||
pushChatterMessage (Chatter::GoingToCamp);
|
pushChatterMessage (Chatter::GoingToCamp);
|
||||||
}
|
}
|
||||||
else if (m_states & Sense::HearingEnemy) {
|
else if (m_states & Sense::HearingEnemy) {
|
||||||
pushChatterMessage (Chatter::HeardTheEnemy);
|
pushChatterMessage (Chatter::HeardTheEnemy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rg.chance (30)) {
|
else if (rg.chance (m_radioPercent)) {
|
||||||
pushChatterMessage (Chatter::ReportingIn);
|
pushChatterMessage (Chatter::ReportingIn);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2771,7 +2772,7 @@ void Bot::checkRadioQueue () {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Task::Camp:
|
case Task::Camp:
|
||||||
if (rg.chance (40)) {
|
if (rg.chance (m_radioPercent)) {
|
||||||
if (bots.isBombPlanted () && m_team == Team::Terrorist) {
|
if (bots.isBombPlanted () && m_team == Team::Terrorist) {
|
||||||
pushChatterMessage (Chatter::GuardingPlantedC4);
|
pushChatterMessage (Chatter::GuardingPlantedC4);
|
||||||
}
|
}
|
||||||
|
|
@ -2828,7 +2829,7 @@ void Bot::checkRadioQueue () {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (rg.chance (50)) {
|
if (rg.chance (m_radioPercent)) {
|
||||||
pushChatterMessage (Chatter::Nothing);
|
pushChatterMessage (Chatter::Nothing);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2942,7 +2943,7 @@ void Bot::tryHeadTowardRadioMessage () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((util.isFakeClient (m_radioEntity)
|
if ((util.isFakeClient (m_radioEntity)
|
||||||
&& rg.chance (25)
|
&& rg.chance (m_radioPercent)
|
||||||
&& m_personality == Personality::Normal) || !(m_radioEntity->v.flags & FL_FAKECLIENT)) {
|
&& m_personality == Personality::Normal) || !(m_radioEntity->v.flags & FL_FAKECLIENT)) {
|
||||||
|
|
||||||
if (tid == Task::Pause || tid == Task::Camp) {
|
if (tid == Task::Pause || tid == Task::Camp) {
|
||||||
|
|
@ -3657,6 +3658,9 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) {
|
||||||
pushChatterMessage (Chatter::FriendlyFire);
|
pushChatterMessage (Chatter::FriendlyFire);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// increase radio percent
|
||||||
|
m_radioPercent = cr::max (m_radioPercent + 1, 90);
|
||||||
|
|
||||||
// attacked by an enemy
|
// attacked by an enemy
|
||||||
if (m_healthValue > 60.0f) {
|
if (m_healthValue > 60.0f) {
|
||||||
m_agressionLevel += 0.1f;
|
m_agressionLevel += 0.1f;
|
||||||
|
|
@ -3744,7 +3748,7 @@ void Bot::takeBlind (int alpha) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::updatePracticeValue (int damage) {
|
void Bot::updatePracticeValue (int damage) const {
|
||||||
// gets called each time a bot gets damaged by some enemy. tries to achieve a statistic about most/less dangerous
|
// gets called each time a bot gets damaged by some enemy. tries to achieve a statistic about most/less dangerous
|
||||||
// nodes for a destination goal used for pathfinding
|
// nodes for a destination goal used for pathfinding
|
||||||
|
|
||||||
|
|
@ -3960,7 +3964,7 @@ bool Bot::canRunHeavyWeight () {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Bot::computeMsec () {
|
uint8_t Bot::computeMsec () const {
|
||||||
// estimate msec to use for this command based on time passed from the previous command
|
// estimate msec to use for this command based on time passed from the previous command
|
||||||
|
|
||||||
return static_cast <uint8_t> (cr::min (static_cast <int32_t> (cr::roundf ((game.time () - m_previousThinkTime) * 1000.0f)), 255));
|
return static_cast <uint8_t> (cr::min (static_cast <int32_t> (cr::roundf ((game.time () - m_previousThinkTime) * 1000.0f)), 255));
|
||||||
|
|
@ -4248,7 +4252,7 @@ void Bot::selectCampButtons (int index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isBombDefusing (const Vector &bombOrigin) {
|
bool Bot::isBombDefusing (const Vector &bombOrigin) const {
|
||||||
// this function finds if somebody currently defusing the bomb.
|
// this function finds if somebody currently defusing the bomb.
|
||||||
|
|
||||||
if (!bots.isBombPlanted ()) {
|
if (!bots.isBombPlanted ()) {
|
||||||
|
|
@ -4354,7 +4358,7 @@ void Bot::refreshCreatureStatus (char *infobuffer) {
|
||||||
m_modelMask = modelTest.mask;
|
m_modelMask = modelTest.mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isCreature () {
|
bool Bot::isCreature () const {
|
||||||
// current creature models are: zombie, chicken
|
// current creature models are: zombie, chicken
|
||||||
constexpr auto kModelMaskZombie = (('o' << 8) + 'z');
|
constexpr auto kModelMaskZombie = (('o' << 8) + 'z');
|
||||||
constexpr auto kModelMaskChicken = (('h' << 8) + 'c');
|
constexpr auto kModelMaskChicken = (('h' << 8) + 'c');
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ ConVar cv_aim_trace_consider_glass ("aim_trace_consider_glass", "0", "Bots will
|
||||||
ConVar mp_friendlyfire ("mp_friendlyfire", nullptr, Var::GameRef);
|
ConVar mp_friendlyfire ("mp_friendlyfire", nullptr, Var::GameRef);
|
||||||
ConVar sv_gravity ("sv_gravity", nullptr, Var::GameRef);
|
ConVar sv_gravity ("sv_gravity", nullptr, Var::GameRef);
|
||||||
|
|
||||||
int Bot::numFriendsNear (const Vector &origin, const float radius) {
|
int Bot::numFriendsNear (const Vector &origin, const float radius) const {
|
||||||
if (game.is (GameFlags::FreeForAll)) {
|
if (game.is (GameFlags::FreeForAll)) {
|
||||||
return 0; // no friends on free for all mode
|
return 0; // no friends on free for all mode
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ int Bot::numFriendsNear (const Vector &origin, const float radius) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::numEnemiesNear (const Vector &origin, const float radius) {
|
int Bot::numEnemiesNear (const Vector &origin, const float radius) const {
|
||||||
if (game.is (GameFlags::FreeForAll)) {
|
if (game.is (GameFlags::FreeForAll)) {
|
||||||
return 0; // no enemies on free for all mode
|
return 0; // no enemies on free for all mode
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +129,7 @@ bool Bot::isEnemyNoTarget (edict_t *enemy) {
|
||||||
return !!(enemy->v.flags & FL_NOTARGET);
|
return !!(enemy->v.flags & FL_NOTARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isEnemyInDarkArea (edict_t *enemy) {
|
bool Bot::isEnemyInDarkArea (edict_t *enemy) const {
|
||||||
if (!cv_check_darkness && game.isNullEntity (enemy)) {
|
if (!cv_check_darkness && game.isNullEntity (enemy)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -773,7 +773,7 @@ Vector Bot::getEnemyBodyOffset () {
|
||||||
return spot;
|
return spot;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Bot::getCustomHeight (float distance) {
|
Vector Bot::getCustomHeight (float distance) const {
|
||||||
enum DistanceIndex {
|
enum DistanceIndex {
|
||||||
Long, Middle, Short
|
Long, Middle, Short
|
||||||
};
|
};
|
||||||
|
|
@ -808,7 +808,7 @@ Vector Bot::getCustomHeight (float distance) {
|
||||||
return { 0.0f, 0.0f, kOffsetRanges[m_weaponType][distanceIndex] };
|
return { 0.0f, 0.0f, kOffsetRanges[m_weaponType][distanceIndex] };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isFriendInLineOfFire (float distance) {
|
bool Bot::isFriendInLineOfFire (float distance) const {
|
||||||
// bot can't hurt teammates, if friendly fire is not enabled...
|
// bot can't hurt teammates, if friendly fire is not enabled...
|
||||||
if (!mp_friendlyfire || game.is (GameFlags::CSDM)) {
|
if (!mp_friendlyfire || game.is (GameFlags::CSDM)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -868,7 +868,7 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
|
||||||
return isPenetrableObstacle2 (dest, penetratePower);
|
return isPenetrableObstacle2 (dest, penetratePower);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isPenetrableObstacle1 (const Vector &dest, int penetratePower) {
|
bool Bot::isPenetrableObstacle1 (const Vector &dest, int penetratePower) const {
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
|
|
||||||
float obstacleDistanceSq = 0.0f;
|
float obstacleDistanceSq = 0.0f;
|
||||||
|
|
@ -906,7 +906,7 @@ bool Bot::isPenetrableObstacle1 (const Vector &dest, int penetratePower) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isPenetrableObstacle2 (const Vector &dest, int) {
|
bool Bot::isPenetrableObstacle2 (const Vector &dest, int) const {
|
||||||
// this function returns if enemy can be shoot through some obstacle
|
// this function returns if enemy can be shoot through some obstacle
|
||||||
|
|
||||||
const Vector &source = getEyesPos ();
|
const Vector &source = getEyesPos ();
|
||||||
|
|
@ -941,7 +941,7 @@ bool Bot::isPenetrableObstacle2 (const Vector &dest, int) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isPenetrableObstacle3 (const Vector &dest, int penetratePower) {
|
bool Bot::isPenetrableObstacle3 (const Vector &dest, int penetratePower) const {
|
||||||
// this function returns if enemy can be shoot through some obstacle
|
// this function returns if enemy can be shoot through some obstacle
|
||||||
|
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
|
|
@ -1659,13 +1659,13 @@ void Bot::attackMovement () {
|
||||||
ignoreCollision ();
|
ignoreCollision ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::hasPrimaryWeapon () {
|
bool Bot::hasPrimaryWeapon () const {
|
||||||
// this function returns returns true, if bot has a primary weapon
|
// this function returns returns true, if bot has a primary weapon
|
||||||
|
|
||||||
return (pev->weapons & kPrimaryWeaponMask) != 0;
|
return (pev->weapons & kPrimaryWeaponMask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::hasSecondaryWeapon () {
|
bool Bot::hasSecondaryWeapon () const {
|
||||||
// this function returns returns true, if bot has a secondary weapon
|
// this function returns returns true, if bot has a secondary weapon
|
||||||
|
|
||||||
return (pev->weapons & kSecondaryWeaponMask) != 0;
|
return (pev->weapons & kSecondaryWeaponMask) != 0;
|
||||||
|
|
@ -1752,7 +1752,7 @@ int Bot::bestSecondaryCarried () {
|
||||||
return weaponIndex;
|
return weaponIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::bestGrenadeCarried () {
|
int Bot::bestGrenadeCarried () const {
|
||||||
if (pev->weapons & cr::bit (Weapon::Explosive)) {
|
if (pev->weapons & cr::bit (Weapon::Explosive)) {
|
||||||
return Weapon::Explosive;
|
return Weapon::Explosive;
|
||||||
}
|
}
|
||||||
|
|
@ -1792,7 +1792,7 @@ bool Bot::rateGroundWeapon (edict_t *ent) {
|
||||||
return groundIndex > hasWeapon;
|
return groundIndex > hasWeapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::hasAnyWeapons () {
|
bool Bot::hasAnyWeapons () const {
|
||||||
return !!(pev->weapons & (kPrimaryWeaponMask | kSecondaryWeaponMask));
|
return !!(pev->weapons & (kPrimaryWeaponMask | kSecondaryWeaponMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1902,7 +1902,7 @@ void Bot::selectSecondary () {
|
||||||
pev->weapons = oldWeapons;
|
pev->weapons = oldWeapons;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::getBestOwnedWeapon () {
|
int Bot::getBestOwnedWeapon () const {
|
||||||
auto tab = conf.getRawWeapons ();
|
auto tab = conf.getRawWeapons ();
|
||||||
|
|
||||||
int weapons = pev->weapons;
|
int weapons = pev->weapons;
|
||||||
|
|
@ -1921,7 +1921,7 @@ int Bot::getBestOwnedWeapon () {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::getBestOwnedPistol () {
|
int Bot::getBestOwnedPistol () const {
|
||||||
auto tab = conf.getRawWeapons ();
|
auto tab = conf.getRawWeapons ();
|
||||||
|
|
||||||
int weapons = pev->weapons;
|
int weapons = pev->weapons;
|
||||||
|
|
@ -2111,7 +2111,7 @@ void Bot::checkReload () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Bot::calculateScaleFactor (edict_t *ent) {
|
float Bot::calculateScaleFactor (edict_t *ent) const {
|
||||||
Vector entSize = ent->v.maxs - ent->v.mins;
|
Vector entSize = ent->v.maxs - ent->v.mins;
|
||||||
const float entArea = 2.0f * (entSize.x * entSize.y + entSize.y * entSize.z + entSize.x * entSize.z);
|
const float entArea = 2.0f * (entSize.x * entSize.y + entSize.y * entSize.z + entSize.x * entSize.z);
|
||||||
|
|
||||||
|
|
@ -2571,11 +2571,11 @@ bool Bot::isEnemyNoticeable (float range) {
|
||||||
return rg (0.0f, 100.0f) < noticeChance;
|
return rg (0.0f, 100.0f) < noticeChance;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::getAmmo () {
|
int Bot::getAmmo () const {
|
||||||
return getAmmo (m_currentWeapon);
|
return getAmmo (m_currentWeapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::getAmmo (int id) {
|
int Bot::getAmmo (int id) const {
|
||||||
const auto &prop = conf.getWeaponProp (id);
|
const auto &prop = conf.getWeaponProp (id);
|
||||||
|
|
||||||
if (prop.ammo1 == -1 || prop.ammo1 > kMaxWeapons - 1) {
|
if (prop.ammo1 == -1 || prop.ammo1 > kMaxWeapons - 1) {
|
||||||
|
|
|
||||||
|
|
@ -761,12 +761,13 @@ void BotConfig::loadLogosConfig () {
|
||||||
if (isCommentLine (line)) {
|
if (isCommentLine (line)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addLogoIndex (line);
|
addLogoIndex (line.trim ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// use defaults
|
// use defaults
|
||||||
if (m_logosIndices.empty ()) {
|
if (m_logosIndices.empty ()) {
|
||||||
|
game.print ("EMPTY!!!!!");
|
||||||
auto defaults = String { "{biohaz;{graf003;{graf004;{graf005;{lambda06;{target;{hand1;{spit2;{bloodhand6;{foot_l;{foot_r" }.split (";");
|
auto defaults = String { "{biohaz;{graf003;{graf004;{graf005;{lambda06;{target;{hand1;{spit2;{bloodhand6;{foot_l;{foot_r" }.split (";");
|
||||||
|
|
||||||
for (const auto &logo : defaults) {
|
for (const auto &logo : defaults) {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ int BotControl::cmdAddBot () {
|
||||||
|
|
||||||
// this is duplicate error as in main bot creation code, but not to be silent
|
// this is duplicate error as in main bot creation code, but not to be silent
|
||||||
if (!graph.length () || graph.hasChanged ()) {
|
if (!graph.length () || graph.hasChanged ()) {
|
||||||
ctrl.msg ("There is no graph found or graph is changed. Cannot create bot.");
|
msg ("There is no graph found or graph is changed. Cannot create bot.");
|
||||||
return BotCommandResult::Handled;
|
return BotCommandResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +91,7 @@ int BotControl::cmdKillBots () {
|
||||||
bots.killAllBots (Team::Terrorist, silentKill);
|
bots.killAllBots (Team::Terrorist, silentKill);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bots.killAllBots (-1, silentKill);
|
bots.killAllBots (Team::Invalid, silentKill);
|
||||||
}
|
}
|
||||||
return BotCommandResult::Handled;
|
return BotCommandResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
@ -204,6 +204,9 @@ int BotControl::cmdCvars () {
|
||||||
|
|
||||||
auto match = arg <StringRef> (pattern);
|
auto match = arg <StringRef> (pattern);
|
||||||
|
|
||||||
|
// stop printing if executed once more
|
||||||
|
flushPrintQueue ();
|
||||||
|
|
||||||
// revert all the cvars to their default values
|
// revert all the cvars to their default values
|
||||||
if (match == "defaults") {
|
if (match == "defaults") {
|
||||||
msg ("Bots cvars has been reverted to their default values.");
|
msg ("Bots cvars has been reverted to their default values.");
|
||||||
|
|
@ -244,7 +247,7 @@ int BotControl::cmdCvars () {
|
||||||
cfg.puts ("// Configuration file for %s\n\n", product.name);
|
cfg.puts ("// Configuration file for %s\n\n", product.name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ctrl.setRapidOutput (true);
|
setRapidOutput (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &cvar : game.getCvars ()) {
|
for (const auto &cvar : game.getCvars ()) {
|
||||||
|
|
@ -303,7 +306,7 @@ int BotControl::cmdCvars () {
|
||||||
msg (" ");
|
msg (" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctrl.setRapidOutput (false);
|
setRapidOutput (false);
|
||||||
|
|
||||||
if (isSave) {
|
if (isSave) {
|
||||||
if (!cfg) {
|
if (!cfg) {
|
||||||
|
|
@ -2172,13 +2175,13 @@ void BotControl::maintainAdminRights () {
|
||||||
}
|
}
|
||||||
else if (password != engfuncs.pfnInfoKeyValue (engfuncs.pfnGetInfoKeyBuffer (ent), key.chars ())) {
|
else if (password != engfuncs.pfnInfoKeyValue (engfuncs.pfnGetInfoKeyBuffer (ent), key.chars ())) {
|
||||||
client.flags &= ~ClientFlags::Admin;
|
client.flags &= ~ClientFlags::Admin;
|
||||||
ctrl.msg ("Player %s had lost remote access to %s.", ent->v.netname.chars (), product.name);
|
msg ("Player %s had lost remote access to %s.", ent->v.netname.chars (), product.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(client.flags & ClientFlags::Admin) && !key.empty () && !password.empty ()) {
|
else if (!(client.flags & ClientFlags::Admin) && !key.empty () && !password.empty ()) {
|
||||||
if (password == engfuncs.pfnInfoKeyValue (engfuncs.pfnGetInfoKeyBuffer (ent), key.chars ())) {
|
if (password == engfuncs.pfnInfoKeyValue (engfuncs.pfnGetInfoKeyBuffer (ent), key.chars ())) {
|
||||||
client.flags |= ClientFlags::Admin;
|
client.flags |= ClientFlags::Admin;
|
||||||
ctrl.msg ("Player %s had gained full remote access to %s.", ent->v.netname.chars (), product.name);
|
msg ("Player %s had gained full remote access to %s.", ent->v.netname.chars (), product.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ void Game::levelShutdown () {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::drawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, const Color &color, int brightness, int speed, int life, DrawLine type) {
|
void Game::drawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, const Color &color, int brightness, int speed, int life, DrawLine type) const {
|
||||||
// this function draws a arrow visible from the client side of the player whose player entity
|
// this function draws a arrow visible from the client side of the player whose player entity
|
||||||
// is pointed to by ent, from the vector location start to the vector location end,
|
// is pointed to by ent, from the vector location start to the vector location end,
|
||||||
// which is supposed to last life tenths seconds, and having the color defined by RGB.
|
// which is supposed to last life tenths seconds, and having the color defined by RGB.
|
||||||
|
|
@ -410,7 +410,7 @@ bool Game::checkVisibility (edict_t *ent, uint8_t *set) {
|
||||||
return engfuncs.pfnCheckVisibility (ent, set) > 0;
|
return engfuncs.pfnCheckVisibility (ent, set) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *Game::getVisibilitySet (Bot *bot, bool pvs) {
|
uint8_t *Game::getVisibilitySet (Bot *bot, bool pvs) const {
|
||||||
if (is (GameFlags::Xash3DLegacy)) {
|
if (is (GameFlags::Xash3DLegacy)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -545,7 +545,7 @@ void Game::prepareBotArgs (edict_t *ent, String str) {
|
||||||
m_botArgs.emplace (args.substr (quote, args.length () - 1).trim ("\"")); // add string with trimmed quotes
|
m_botArgs.emplace (args.substr (quote, args.length () - 1).trim ("\"")); // add string with trimmed quotes
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (auto arg : args.split (" ")) {
|
for (auto &&arg : args.split (" ")) {
|
||||||
m_botArgs.emplace (arg);
|
m_botArgs.emplace (arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -560,7 +560,7 @@ void Game::prepareBotArgs (edict_t *ent, String str) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (str.find (';', 0) != String::InvalidIndex) {
|
if (str.find (';', 0) != String::InvalidIndex) {
|
||||||
for (auto part : str.split (";")) {
|
for (auto &&part : str.split (";")) {
|
||||||
parsePartArgs (part.trim ());
|
parsePartArgs (part.trim ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1126,7 +1126,7 @@ void Game::searchEntities (StringRef field, StringRef value, EntitySearch functo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::searchEntities (const Vector &position, float radius, EntitySearch functor) {
|
void Game::searchEntities (const Vector &position, float radius, EntitySearch functor) const {
|
||||||
edict_t *ent = nullptr;
|
edict_t *ent = nullptr;
|
||||||
const Vector &pos = position.empty () ? m_startEntity->v.origin : position;
|
const Vector &pos = position.empty () ? m_startEntity->v.origin : position;
|
||||||
|
|
||||||
|
|
@ -1145,7 +1145,7 @@ bool Game::hasEntityInGame (StringRef classname) {
|
||||||
return !isNullEntity (engfuncs.pfnFindEntityByString (nullptr, "classname", classname.chars ()));
|
return !isNullEntity (engfuncs.pfnFindEntityByString (nullptr, "classname", classname.chars ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::printBotVersion () {
|
void Game::printBotVersion () const {
|
||||||
String gameVersionStr {};
|
String gameVersionStr {};
|
||||||
StringArray botRuntimeFlags {};
|
StringArray botRuntimeFlags {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1301,7 +1301,7 @@ void BotGraph::showFileInfo () {
|
||||||
msg (" bsp_size: %d", exten.mapSize);
|
msg (" bsp_size: %d", exten.mapSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotGraph::emitNotify (int32_t sound) {
|
void BotGraph::emitNotify (int32_t sound) const {
|
||||||
static HashMap <int32_t, String> notifySounds = {
|
static HashMap <int32_t, String> notifySounds = {
|
||||||
{ NotifySound::Added, "weapons/xbow_hit1.wav" },
|
{ NotifySound::Added, "weapons/xbow_hit1.wav" },
|
||||||
{ NotifySound::Change, "weapons/mine_activate.wav" },
|
{ NotifySound::Change, "weapons/mine_activate.wav" },
|
||||||
|
|
@ -1559,7 +1559,7 @@ void BotGraph::initLightLevels () {
|
||||||
if (m_paths.empty () || m_lightChecked) {
|
if (m_paths.empty () || m_lightChecked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto players = bots.countTeamPlayers ();
|
const auto &players = bots.countTeamPlayers ();
|
||||||
|
|
||||||
// do calculation if some-one is already playing on the server
|
// do calculation if some-one is already playing on the server
|
||||||
if (!players.first && !players.second) {
|
if (!players.first && !players.second) {
|
||||||
|
|
@ -1953,7 +1953,7 @@ float BotGraph::calculateTravelTime (float maxSpeed, const Vector &src, const Ve
|
||||||
return origin.distance2d (src) / maxSpeed;
|
return origin.distance2d (src) / maxSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination, const float maxHeight) {
|
bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination, const float maxHeight) const {
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
|
|
||||||
float distanceSq = destination.distanceSq (src);
|
float distanceSq = destination.distanceSq (src);
|
||||||
|
|
@ -2044,11 +2044,11 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) const {
|
||||||
return isNodeReacheableEx (src, destination, 45.0f);
|
return isNodeReacheableEx (src, destination, 45.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotGraph::isNodeReacheableWithJump (const Vector &src, const Vector &destination) {
|
bool BotGraph::isNodeReacheableWithJump (const Vector &src, const Vector &destination) const {
|
||||||
return isNodeReacheableEx (src, destination, cv_graph_analyze_max_jump_height.as <float> ());
|
return isNodeReacheableEx (src, destination, cv_graph_analyze_max_jump_height.as <float> ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2872,7 +2872,7 @@ void BotGraph::unassignPath (int from, int to) {
|
||||||
m_hasChanged = true;
|
m_hasChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotGraph::convertFromPOD (Path &path, const PODPath &pod) {
|
void BotGraph::convertFromPOD (Path &path, const PODPath &pod) const {
|
||||||
path.number = pod.number;
|
path.number = pod.number;
|
||||||
path.flags = pod.flags;
|
path.flags = pod.flags;
|
||||||
path.origin = pod.origin;
|
path.origin = pod.origin;
|
||||||
|
|
@ -2916,7 +2916,7 @@ void BotGraph::convertToPOD (const Path &path, PODPath &pod) {
|
||||||
pod.vis.crouch = path.vis.crouch;
|
pod.vis.crouch = path.vis.crouch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotGraph::convertCampDirection (Path &path) {
|
void BotGraph::convertCampDirection (Path &path) const {
|
||||||
// this function converts old vector based camp directions to angles, note that podbotmm graph
|
// this function converts old vector based camp directions to angles, note that podbotmm graph
|
||||||
// are already saved with angles, and converting this stuff may result strange look directions.
|
// are already saved with angles, and converting this stuff may result strange look directions.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ void ServerQueryHook::init () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedLibrary::Func DynamicLinkerHook::lookup (SharedLibrary::Handle module, const char *function) {
|
SharedLibrary::Func EntityLinkHook::lookupSymbol (SharedLibrary::Handle module, const char *function) {
|
||||||
static const auto &gamedll = game.lib ().handle ();
|
static const auto &gamedll = game.lib ().handle ();
|
||||||
static const auto &self = m_self.handle ();
|
static const auto &self = m_self.handle ();
|
||||||
|
|
||||||
|
|
@ -148,7 +148,7 @@ SharedLibrary::Func DynamicLinkerHook::lookup (SharedLibrary::Handle module, con
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicLinkerHook::callPlayerFunction (edict_t *ent) {
|
bool EntityLinkHook::callPlayerFunction (edict_t *ent) {
|
||||||
auto callPlayer = [&] () {
|
auto callPlayer = [&] () {
|
||||||
reinterpret_cast <EntityProto> (reinterpret_cast <void *> (m_exports["player"])) (&ent->v);
|
reinterpret_cast <EntityProto> (reinterpret_cast <void *> (m_exports["player"])) (&ent->v);
|
||||||
};
|
};
|
||||||
|
|
@ -169,11 +169,11 @@ bool DynamicLinkerHook::callPlayerFunction (edict_t *ent) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicLinkerHook::needsBypass () const {
|
bool EntityLinkHook::needsBypass () const {
|
||||||
return !plat.win && !game.isDedicated ();
|
return !plat.win && !game.isDedicated ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicLinkerHook::initialize () {
|
void EntityLinkHook::initialize () {
|
||||||
#if defined(LINKENT_STATIC)
|
#if defined(LINKENT_STATIC)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -669,7 +669,7 @@ void BotManager::killAllBots (int team, bool silent) {
|
||||||
// this function kills all bots on server (only this dll controlled bots)
|
// this function kills all bots on server (only this dll controlled bots)
|
||||||
|
|
||||||
for (const auto &bot : m_bots) {
|
for (const auto &bot : m_bots) {
|
||||||
if (team != -1 && game.getRealTeam (bot->ent ()) != team) {
|
if (team != Team::Invalid && game.getRealTeam (bot->ent ()) != team) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bot->kill ();
|
bot->kill ();
|
||||||
|
|
@ -922,11 +922,14 @@ void BotManager::listBots () {
|
||||||
bot->index (),
|
bot->index (),
|
||||||
bot->pev->netname.chars (),
|
bot->pev->netname.chars (),
|
||||||
bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful",
|
bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful",
|
||||||
|
|
||||||
botTeam (bot->ent ()),
|
botTeam (bot->ent ()),
|
||||||
bot->m_difficulty,
|
bot->m_difficulty,
|
||||||
static_cast <int> (bot->pev->frags),
|
static_cast <int> (bot->pev->frags),
|
||||||
|
|
||||||
bot->m_deathCount,
|
bot->m_deathCount,
|
||||||
bot->m_isAlive ? "yes" : "no",
|
bot->m_isAlive ? "yes" : "no",
|
||||||
|
|
||||||
timelimitStr);
|
timelimitStr);
|
||||||
}
|
}
|
||||||
ctrl.msg ("%d bots", m_bots.length ());
|
ctrl.msg ("%d bots", m_bots.length ());
|
||||||
|
|
@ -1123,7 +1126,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char reject[StringBuffer::StaticBufferSize] = { 0, };
|
char reject[128] = { 0, };
|
||||||
MDLL_ClientConnect (bot, bot->v.netname.chars (), strings.format ("127.0.0.%d", clientIndex + 100), reject);
|
MDLL_ClientConnect (bot, bot->v.netname.chars (), strings.format ("127.0.0.%d", clientIndex + 100), reject);
|
||||||
|
|
||||||
if (!strings.isEmpty (reject)) {
|
if (!strings.isEmpty (reject)) {
|
||||||
|
|
@ -1569,6 +1572,7 @@ void Bot::newRound () {
|
||||||
m_hitboxEnumerator = cr::makeUnique <PlayerHitboxEnumerator> ();
|
m_hitboxEnumerator = cr::makeUnique <PlayerHitboxEnumerator> ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
showChatterIcon (false);
|
||||||
|
|
||||||
m_approachingLadderTimer.invalidate ();
|
m_approachingLadderTimer.invalidate ();
|
||||||
m_forgetLastVictimTimer.invalidate ();
|
m_forgetLastVictimTimer.invalidate ();
|
||||||
|
|
@ -1609,6 +1613,24 @@ void Bot::newRound () {
|
||||||
m_buyState = BuyState::PrimaryWeapon;
|
m_buyState = BuyState::PrimaryWeapon;
|
||||||
m_lastEquipTime = 0.0f;
|
m_lastEquipTime = 0.0f;
|
||||||
|
|
||||||
|
// setup radio percent each round
|
||||||
|
const auto badMorale = m_fearLevel > m_agressionLevel ? rg.chance (75) : rg.chance (35);
|
||||||
|
|
||||||
|
switch (m_personality) {
|
||||||
|
case Personality::Normal:
|
||||||
|
default:
|
||||||
|
m_radioPercent = badMorale ? rg (50, 75) : rg (25, 50);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Personality::Rusher:
|
||||||
|
m_radioPercent = badMorale ? rg (35, 50) : rg (15, 35);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Personality::Careful:
|
||||||
|
m_radioPercent = badMorale ? rg (70, 90) : rg (50, 70);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// if bot died, clear all weapon stuff and force buying again
|
// if bot died, clear all weapon stuff and force buying again
|
||||||
if (!m_isAlive) {
|
if (!m_isAlive) {
|
||||||
clearAmmoInfo ();
|
clearAmmoInfo ();
|
||||||
|
|
|
||||||
|
|
@ -282,8 +282,8 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
|
||||||
else if (tactic == GoalTactic::Offensive && !(*offensive).empty ()) { // offensive goal
|
else if (tactic == GoalTactic::Offensive && !(*offensive).empty ()) { // offensive goal
|
||||||
postProcessGoals (*offensive, goalChoices);
|
postProcessGoals (*offensive, goalChoices);
|
||||||
}
|
}
|
||||||
else if (tactic == GoalTactic::Goal && !graph.m_goalPoints.empty ()) // map goal node
|
else if (tactic == GoalTactic::Goal && !graph.m_goalPoints.empty ()) { // map goal node
|
||||||
{
|
|
||||||
// force bomber to select closest goal, if round-start goal was reset by something
|
// force bomber to select closest goal, if round-start goal was reset by something
|
||||||
if (m_hasC4 && bots.getRoundStartTime () + 20.0f < game.time ()) {
|
if (m_hasC4 && bots.getRoundStartTime () + 20.0f < game.time ()) {
|
||||||
float nearestDistanceSq = kInfiniteDistance;
|
float nearestDistanceSq = kInfiniteDistance;
|
||||||
|
|
@ -3421,7 +3421,7 @@ bool Bot::isReachableNode (int index) {
|
||||||
return tr.flFraction >= 1.0f;
|
return tr.flFraction >= 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::isPreviousLadder () {
|
bool Bot::isPreviousLadder () const {
|
||||||
const auto prevNodeIndex = m_previousNodes[0];
|
const auto prevNodeIndex = m_previousNodes[0];
|
||||||
|
|
||||||
// bot entered ladder path
|
// bot entered ladder path
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@ bool FloydWarshallAlgo::load () {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloydWarshallAlgo::save () {
|
void FloydWarshallAlgo::save () const {
|
||||||
if (!m_length) {
|
if (!m_length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -448,7 +448,7 @@ bool DijkstraAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, i
|
||||||
m_distance[srcIndex] = 0;
|
m_distance[srcIndex] = 0;
|
||||||
|
|
||||||
while (!m_queue.empty ()) {
|
while (!m_queue.empty ()) {
|
||||||
auto route = m_queue.pop ();
|
const auto &route = m_queue.pop ();
|
||||||
auto current = route.second;
|
auto current = route.second;
|
||||||
|
|
||||||
// finished search
|
// finished search
|
||||||
|
|
|
||||||
|
|
@ -192,8 +192,9 @@ void Bot::normal_ () {
|
||||||
if (game.mapIs (MapFlags::HostageRescue)) {
|
if (game.mapIs (MapFlags::HostageRescue)) {
|
||||||
// CT Bot has some hostages following?
|
// CT Bot has some hostages following?
|
||||||
if (m_team == Team::CT && m_hasHostage) {
|
if (m_team == Team::CT && m_hasHostage) {
|
||||||
|
|
||||||
// and reached a rescue point?
|
// and reached a rescue point?
|
||||||
if (m_pathFlags & NodeFlag::Rescue) {
|
if (m_inRescueZone && (m_pathFlags & NodeFlag::Rescue)) {
|
||||||
m_hostages.clear ();
|
m_hostages.clear ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ ConVar cv_whose_your_daddy ("whose_your_daddy", "0", "Enables or disables extra
|
||||||
// game console variables
|
// game console variables
|
||||||
ConVar mp_flashlight ("mp_flashlight", nullptr, Var::GameRef);
|
ConVar mp_flashlight ("mp_flashlight", nullptr, Var::GameRef);
|
||||||
|
|
||||||
float Bot::isInFOV (const Vector &destination) {
|
float Bot::isInFOV (const Vector &destination) const {
|
||||||
const float entityAngle = cr::wrapAngle360 (destination.yaw ()); // find yaw angle from source to destination...
|
const float entityAngle = cr::wrapAngle360 (destination.yaw ()); // find yaw angle from source to destination...
|
||||||
const float viewAngle = cr::wrapAngle360 (pev->v_angle.y); // get bot's current view angle...
|
const float viewAngle = cr::wrapAngle360 (pev->v_angle.y); // get bot's current view angle...
|
||||||
|
|
||||||
|
|
@ -368,7 +368,7 @@ bool Frustum::isObjectInsidePlane (const Plane &plane, const Vector ¢er, flo
|
||||||
return isPointInsidePlane (top) || isPointInsidePlane (bottom);
|
return isPointInsidePlane (top) || isPointInsidePlane (bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frustum::calculate (Planes &planes, const Vector &viewAngle, const Vector &viewOffset) {
|
void Frustum::calculate (Planes &planes, const Vector &viewAngle, const Vector &viewOffset) const {
|
||||||
Vector forward {}, right {}, up {};
|
Vector forward {}, right {}, up {};
|
||||||
viewAngle.angleVectors (&forward, &right, &up);
|
viewAngle.angleVectors (&forward, &right, &up);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ void GraphVistable::load () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphVistable::save () {
|
void GraphVistable::save () const {
|
||||||
if (!graph.length () || graph.hasChanged () || m_rebuild) {
|
if (!graph.length () || graph.hasChanged () || m_rebuild) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue