bot: refactor and clean up old code

fix: crash when saving old format pwf on hlds
bot: moved sdk headers to separate submodule
nav: improved unstuck and avoidance (thanks @commandcobra7) code
bot: use correct path slashes depending on platform for all data
cfg: removed simplified chines' translation, as it's too outdated
This commit is contained in:
jeefo 2023-05-12 20:00:06 +03:00
commit 7b58d51973
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
42 changed files with 365 additions and 3805 deletions

View file

@ -44,7 +44,7 @@ private:
Array <Array <ChatterItem>> m_chatter {};
Array <BotName> m_botNames {};
Array <Keywords> m_replies {};
Array <ChatKeywords> m_replies {};
SmallArray <WeaponInfo> m_weapons {};
SmallArray <WeaponProp> m_weaponProps {};
@ -170,7 +170,7 @@ public:
}
// get's the replies array
Array <Keywords> &getReplies () {
Array <ChatKeywords> &getReplies () {
return m_replies;
}

View file

@ -90,7 +90,7 @@ public:
private:
const char *allocStr (const char *str) const {
return STRING (engfuncs.pfnAllocString (str));
return string_t::from (engfuncs.pfnAllocString (str));
}
public:
@ -159,7 +159,7 @@ public:
void testModel (const Vector &start, const Vector &end, int hullNumber, edict_t *entToHit, TraceResult *ptr);
// trace line with channel, but allows us to store last traceline bot has fired, saving us some cpu cycles
bool testLineChannel (TraceChannel channel, const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult &result);
//bool testLineChannel (TraceChannel channel, const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult &result);
// test line
void testHull (const Vector &start, const Vector &end, int ignoreFlags, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr);
@ -389,7 +389,7 @@ public:
// prints center message to specified player
template <typename ...Args> void clientPrint (edict_t *ent, const char *fmt, Args &&...args) {
if (isNullEntity (ent)) {
if (isNullEntity (ent) || ent == getLocalEntity ()) {
print (fmt, cr::forward <Args> (args)...);
return;
}
@ -398,7 +398,7 @@ public:
// prints message to client console
template <typename ...Args> void centerPrint (edict_t *ent, const char *fmt, Args &&...args) {
if (isNullEntity (ent)) {
if (isNullEntity (ent) || ent == getLocalEntity ()) {
print (fmt, cr::forward <Args> (args)...);
return;
}
@ -407,7 +407,7 @@ public:
};
// simplify access for console variables
class ConVar final : public DenyCopying {
class ConVar final : public NonCopyable {
public:
cvar_t *ptr;

View file

@ -309,7 +309,7 @@ private:
ThreadPool m_botWorker;
public:
BotThreadWorker () = default;
explicit BotThreadWorker () = default;
~BotThreadWorker () = default;
public:
@ -322,7 +322,7 @@ public:
fn (); // no threads, no fun, just run task in current thread
return;
}
m_botWorker.enqueue (cr::forward <F> (fn));
m_botWorker.enqueue (cr::move (fn));
}
};

View file

@ -51,7 +51,7 @@ public:
// bot heuristic functions for astar planner
class Heuristic final {
public:
using Func = Lambda <float (int, int, int)>;
using Func = float (*) (int, int, int);
public:
// least kills and number of nodes to goal for a team
@ -84,7 +84,7 @@ public:
};
// A* algorithm for bots
class AStarAlgo final : public DenyCopying {
class AStarAlgo final : public NonCopyable {
public:
using HeuristicFn = Heuristic::Func;
@ -137,6 +137,9 @@ public:
m_constructedPath.reserve (getMaxLength ());
m_smoothedPath.reserve (getMaxLength ());
m_constructedPath.shrink ();
m_smoothedPath.shrink ();
}
// set the g heuristic

View file

@ -17,31 +17,54 @@
// simple class for bot internal information
class Product final : public Singleton <Product> {
public:
explicit constexpr Product () = default;
~Product () = default;
public:
struct Build {
StringRef hash { MODULE_COMMIT_COUNT };
StringRef count { MODULE_COMMIT_HASH };
StringRef author { MODULE_AUTHOR };
StringRef machine { MODULE_MACHINE };
StringRef compiler { MODULE_COMPILER };
StringRef id { MODULE_BUILD_ID };
static constexpr StringRef hash { MODULE_COMMIT_COUNT };
static constexpr StringRef count { MODULE_COMMIT_HASH };
static constexpr StringRef author { MODULE_AUTHOR };
static constexpr StringRef machine { MODULE_MACHINE };
static constexpr StringRef compiler { MODULE_COMPILER };
static constexpr StringRef id { MODULE_BUILD_ID };
} build {};
public:
StringRef name { "YaPB" };
StringRef year { &__DATE__[7] };
StringRef author { "YaPB Project" };
StringRef email { "yapb@jeefo.net" };
StringRef url { "https://yapb.jeefo.net/" };
StringRef download { "yapb.jeefo.net" };
StringRef folder { "yapb" };
StringRef logtag { "YB" };
StringRef dtime { __DATE__ " " __TIME__ };
StringRef date { __DATE__ };
StringRef version { MODULE_VERSION "." MODULE_COMMIT_COUNT };
StringRef cmdPri { "yb" };
StringRef cmdSec { "yapb" };
static constexpr StringRef name { "YaPB" };
static constexpr StringRef nameLower { "yapb" };
static constexpr StringRef year { &__DATE__[7] };
static constexpr StringRef author { "YaPB Project" };
static constexpr StringRef email { "yapb@jeefo.net" };
static constexpr StringRef url { "https://yapb.jeefo.net/" };
static constexpr StringRef download { "yapb.jeefo.net" };
static constexpr StringRef logtag { "YB" };
static constexpr StringRef dtime { __DATE__ " " __TIME__ };
static constexpr StringRef date { __DATE__ };
static constexpr StringRef version { MODULE_VERSION "." MODULE_COMMIT_COUNT };
static constexpr StringRef cmdPri { "yb" };
static constexpr StringRef cmdSec { "yapb" };
};
class Folders final : public Singleton <Folders> {
public:
explicit constexpr Folders () = default;
~Folders () = default;
public:
static constexpr StringRef bot { "yapb" };
static constexpr StringRef addons { "addons" };
static constexpr StringRef config { "conf" };
static constexpr StringRef data { "data" };
static constexpr StringRef lang { "lang" };
static constexpr StringRef logs { "logs" };
static constexpr StringRef train { "train" };
static constexpr StringRef graph { "graph" };
static constexpr StringRef podbot { "pwf" };
static constexpr StringRef ebot { "ewp" };
};
// expose product info
CR_EXPOSE_GLOBAL_SINGLETON (Product, product);
CR_EXPOSE_GLOBAL_SINGLETON (Folders, folders);

View file

@ -8,7 +8,7 @@
#pragma once
// storage file magic (podbot)
constexpr char kPodbotMagic[8] = "PODWAY!";
constexpr char kPodbotMagic[8] = { 'P', 'O', 'D', 'W', 'A', 'Y', '!', kNullChar };
constexpr int32_t kStorageMagic = 0x59415042; // storage magic for yapb-data files
constexpr int32_t kStorageMagicUB = 0x544f4255; //support also the fork format (merged back into yapb)

View file

@ -55,7 +55,7 @@ public:
bool isPlayerVIP (edict_t *ent);
// opens config helper
bool openConfig (const char *fileName, const char *errorIfNotExists, MemFile *outFile, bool languageDependant = false);
bool openConfig (StringRef fileName, StringRef errorIfNotExists, MemFile *outFile, bool languageDependant = false);
// nearest player search helper
bool findNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false, bool needBotWithC4 = false);

View file

@ -35,7 +35,7 @@ private:
float m_notifyMsgTimestamp {};
public:
GraphVistable () = default;
explicit GraphVistable () = default;
~GraphVistable () = default;
public:

View file

@ -7,12 +7,12 @@
#pragma once
#include <hlsdk/extdll.h>
#include <hlsdk/metamod.h>
#include <hlsdk/physint.h>
#include <crlib/crlib.h>
#include <linkage/goldsrc.h>
#include <linkage/metamod.h>
#include <linkage/physint.h>
// use all the cr-library
using namespace cr;
@ -405,13 +405,6 @@ CR_DECLARE_SCOPED_ENUM (Visibility,
None = 0
)
// channel for skip traceline
CR_DECLARE_SCOPED_ENUM (TraceChannel,
Enemy = 0,
Body,
Num
)
// frustum sides
CR_DECLARE_SCOPED_ENUM (FrustumSide,
Top = 0,
@ -424,53 +417,54 @@ CR_DECLARE_SCOPED_ENUM (FrustumSide,
)
// some hardcoded desire defines used to override calculated ones
namespace TaskPri {
static constexpr float Normal { 35.0f };
static constexpr float Pause { 36.0f };
static constexpr float Camp { 37.0f };
static constexpr float Spraypaint { 38.0f };
static constexpr float FollowUser { 39.0f };
static constexpr float MoveToPosition { 50.0f };
static constexpr float DefuseBomb { 89.0f };
static constexpr float PlantBomb { 89.0f };
static constexpr float Attack { 90.0f };
static constexpr float SeekCover { 91.0f };
static constexpr float Hide { 92.0f };
static constexpr float Throw { 99.0f };
static constexpr float DoubleJump { 99.0f };
static constexpr float Blind { 100.0f };
static constexpr float ShootBreakable { 100.0f };
static constexpr float EscapeFromBomb { 100.0f };
}
struct TaskPri {
static constexpr auto Normal { 35.0f };
static constexpr auto Pause { 36.0f };
static constexpr auto Camp { 37.0f };
static constexpr auto Spraypaint { 38.0f };
static constexpr auto FollowUser { 39.0f };
static constexpr auto MoveToPosition { 50.0f };
static constexpr auto DefuseBomb { 89.0f };
static constexpr auto PlantBomb { 89.0f };
static constexpr auto Attack { 90.0f };
static constexpr auto SeekCover { 91.0f };
static constexpr auto Hide { 92.0f };
static constexpr auto Throw { 99.0f };
static constexpr auto DoubleJump { 99.0f };
static constexpr auto Blind { 100.0f };
static constexpr auto ShootBreakable { 100.0f };
static constexpr auto EscapeFromBomb { 100.0f };
};
constexpr float kInfiniteDistance = 9999999.0f;
constexpr float kGrenadeCheckTime = 0.6f;
constexpr float kSprayDistance = 260.0f;
constexpr float kDoubleSprayDistance = kSprayDistance * 2;
constexpr float kMaxChatterRepeatInterval = 99.0f;
constexpr auto kInfiniteDistance = 9999999.0f;
constexpr auto kGrenadeCheckTime = 0.6f;
constexpr auto kSprayDistance = 260.0f;
constexpr auto kDoubleSprayDistance = kSprayDistance * 2;
constexpr auto kMaxChatterRepeatInterval = 99.0f;
constexpr int kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
constexpr int kMaxWeapons = 32;
constexpr int kNumWeapons = 26;
constexpr int kMaxCollideMoves = 3;
constexpr int kGameMaxPlayers = 32;
constexpr int kGameTeamNum = 2;
constexpr int kInvalidNodeIndex = -1;
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
constexpr auto kMaxWeapons = 32;
constexpr auto kNumWeapons = 26;
constexpr auto kMaxCollideMoves = 3;
constexpr auto kGameMaxPlayers = 32;
constexpr auto kGameTeamNum = 2;
constexpr auto kInvalidNodeIndex = -1;
constexpr auto kConfigExtension = "cfg";
// weapon masks
constexpr auto kPrimaryWeaponMask = (cr::bit (Weapon::XM1014) | cr::bit (Weapon::M3) | cr::bit (Weapon::MAC10) | cr::bit (Weapon::UMP45) | cr::bit (Weapon::MP5) | cr::bit (Weapon::TMP) | cr::bit (Weapon::P90) | cr::bit (Weapon::AUG) | cr::bit (Weapon::M4A1) | cr::bit (Weapon::SG552) | cr::bit (Weapon::AK47) | cr::bit (Weapon::Scout) | cr::bit (Weapon::SG550) | cr::bit (Weapon::AWP) | cr::bit (Weapon::G3SG1) | cr::bit (Weapon::M249) | cr::bit (Weapon::Famas) | cr::bit (Weapon::Galil));
constexpr auto kSecondaryWeaponMask = (cr::bit (Weapon::P228) | cr::bit (Weapon::Elite) | cr::bit (Weapon::USP) | cr::bit (Weapon::Glock18) | cr::bit (Weapon::Deagle) | cr::bit (Weapon::FiveSeven));
// links keywords and replies together
struct Keywords {
struct ChatKeywords {
StringArray keywords;
StringArray replies;
StringArray usedReplies;
public:
Keywords () = default;
ChatKeywords () = default;
Keywords (const StringArray &keywords, const StringArray &replies) {
ChatKeywords (const StringArray &keywords, const StringArray &replies) {
this->keywords.clear ();
this->replies.clear ();
this->usedReplies.clear ();
@ -589,7 +583,7 @@ struct ChatCollection {
#include <graph.h>
// this structure links nodes returned from pathfinder
class PathWalk final : public DenyCopying {
class PathWalk final : public NonCopyable {
private:
size_t m_cursor {};
size_t m_length {};
@ -675,9 +669,6 @@ private:
uint32_t m_aimFlags {}; // aiming conditions
uint32_t m_currentTravelFlags {}; // connection flags like jumping
int m_traceSkip[TraceChannel::Num] {}; // trace need to be skipped?
int m_messageQueue[32] {}; // stack for messages
int m_oldButtons {}; // our old buttons
int m_reloadState {}; // current reload state
int m_voicePitch {}; // bot voice pitch
@ -701,6 +692,7 @@ private:
float m_prevTime {}; // time previously checked movement speed
float m_heavyTimestamp {}; // is it time to execute heavy-weight functions
float m_prevSpeed {}; // speed some frames before
float m_prevVelocity {}; // velocity some frames before
float m_timeDoorOpen {}; // time to next door open check
float m_lastChatTime {}; // time bot last chatted
float m_timeLogoSpray {}; // time bot last spray logo
@ -749,6 +741,7 @@ private:
float m_playServerTime {}; // time bot spent in the game
float m_changeViewTime {}; // timestamp to change look at while at freezetime
float m_breakableTime {}; // breakeble acquired time
float m_stuckTimestamp {}; // last time was stuck
bool m_moveToGoal {}; // bot currently moving to goal??
bool m_isStuck {}; // bot is stuck
@ -770,6 +763,7 @@ private:
bool m_grenadeRequested {}; // bot requested change to grenade
bool m_needToSendWelcomeChat {}; // bot needs to greet people on server?
bool m_isCreature {}; // bot is not a player, but something else ? zombie ?
bool m_defuseNotified {}; // bot is notified about bomb defusion
Pickup m_pickupType {}; // type of entity which needs to be used/picked up
PathWalk m_pathWalk {}; // pointer to current node from path
@ -779,7 +773,6 @@ private:
FindPath m_pathType {}; // which pathfinder to use
uint8_t m_enemyParts {}; // visibility flags
uint16_t m_modelMask {}; // model mask bits
TraceResult m_lastTrace[TraceChannel::Num] {}; // last trace result
UniquePtr <class AStarAlgo> m_planner;
edict_t *m_pickupItem {}; // pointer to entity of item to use/pickup
@ -810,7 +803,6 @@ private:
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
Array <edict_t *> m_hostages {}; // pointer to used hostage entities
Array <int32_t> m_nodeHistory {}; // history of selected goals
Path *m_path {}; // pointer to the current path node
String m_chatBuffer {}; // space for strings (say text...)
@ -888,7 +880,6 @@ private:
bool checkChatKeywords (String &reply);
bool isReplyingToChat ();
bool isReachableNode (int index);
bool isBannedNode (int index);
bool updateLiftHandling ();
bool updateLiftStates ();
bool canRunHeavyWeight ();
@ -962,6 +953,7 @@ private:
void logicDuringFreezetime ();
void translateInput ();
void moveToGoal ();
void resetMovement ();
void normal_ ();
void spraypaint_ ();
@ -1193,7 +1185,7 @@ public:
bool isShieldDrawn ();
bool findNextBestNode ();
bool seesEntity (const Vector &dest, bool fromBody = false);
bool canSkipNextTrace (TraceChannel channel);
//bool canSkipNextTrace (TraceChannel channel);
int getAmmo ();
int getAmmo (int id);
@ -1242,16 +1234,6 @@ public:
return m_currentNodeIndex;
}
// set the last bot trace result
void setLastTraceResult (TraceChannel channel, TraceResult *traceResult) {
m_lastTrace[channel] = *traceResult;
}
// get the bot last trace result
TraceResult &getLastTraceResult (TraceChannel channel) {
return m_lastTrace[channel];
}
// is low on admmo on index?
bool isLowOnAmmo (const int index, const float factor) const;