nav: more fixes to ladder navigation
refactor: bot difficulty data and add graph refresh command combat: fixes for smoke grenades (ref #743) engine: fixes to spawn management (ref #744)
This commit is contained in:
parent
7b378ba3fa
commit
17ed252b60
26 changed files with 506 additions and 408 deletions
17
inc/config.h
17
inc/config.h
|
|
@ -29,16 +29,6 @@ public:
|
|||
|
||||
// mostly config stuff, and some stuff dealing with menus
|
||||
class BotConfig final : public Singleton <BotConfig> {
|
||||
public:
|
||||
struct DifficultyData {
|
||||
float reaction[2] {};
|
||||
int32_t headshotPct {};
|
||||
int32_t seenThruPct {};
|
||||
int32_t hearThruPct {};
|
||||
int32_t maxRecoil {};
|
||||
Vector aimError {};
|
||||
};
|
||||
|
||||
private:
|
||||
Array <StringArray> m_chat {};
|
||||
Array <Array <ChatterItem>> m_chatter {};
|
||||
|
|
@ -52,7 +42,7 @@ private:
|
|||
StringArray m_avatars {};
|
||||
|
||||
HashMap <uint32_t, String, Hash <int32_t>> m_language {};
|
||||
HashMap <int32_t, DifficultyData> m_difficulty {};
|
||||
HashMap <int32_t, BotDifficultyData> m_difficulty {};
|
||||
HashMap <String, String> m_custom {};
|
||||
|
||||
// default tables for personality weapon preferences, overridden by weapon.cfg
|
||||
|
|
@ -218,10 +208,7 @@ public:
|
|||
}
|
||||
|
||||
// get's the difficulty level tweaks
|
||||
DifficultyData *getDifficultyTweaks (int32_t level) {
|
||||
if (level < Difficulty::Noob || level > Difficulty::Expert) {
|
||||
return &m_difficulty[Difficulty::Expert];
|
||||
}
|
||||
BotDifficultyData *getDifficultyTweaks (int32_t level) {
|
||||
return &m_difficulty[level];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ CR_DECLARE_SCOPED_ENUM (Menu,
|
|||
|
||||
// bomb say string
|
||||
CR_DECLARE_SCOPED_ENUM (BombPlantedSay,
|
||||
ChatSay = cr::bit (1),
|
||||
Chatter = cr::bit (2)
|
||||
ChatSay = cr::bit (1),
|
||||
Chatter = cr::bit (2)
|
||||
)
|
||||
|
||||
// chat types id's
|
||||
|
|
@ -419,7 +419,13 @@ CR_DECLARE_SCOPED_ENUM (GoalTactic,
|
|||
RescueHostage
|
||||
)
|
||||
|
||||
// some hard-coded desire defines used to override calculated ones
|
||||
// ladder move direction
|
||||
CR_DECLARE_SCOPED_ENUM (LadderDir,
|
||||
Up = 0,
|
||||
Down,
|
||||
)
|
||||
|
||||
// some hard-coded desire defines used to override calculated ones
|
||||
namespace TaskPri {
|
||||
constexpr auto Normal { 35.0f };
|
||||
constexpr auto Pause { 36.0f };
|
||||
|
|
@ -447,7 +453,7 @@ constexpr auto kSprayDistanceX2 = kSprayDistance * 2;
|
|||
constexpr auto kMaxChatterRepeatInterval = 99.0f;
|
||||
constexpr auto kViewFrameUpdate = 1.0f / 25.0f;
|
||||
constexpr auto kGrenadeDamageRadius = 385.0f;
|
||||
constexpr auto kMinMovedDistance = 2.5f;
|
||||
constexpr auto kMinMovedDistance = cr::sqrf (2.0f);
|
||||
|
||||
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
|
||||
constexpr auto kMaxWeapons = 32;
|
||||
|
|
@ -462,35 +468,35 @@ 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));
|
||||
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));
|
||||
| cr::bit (Weapon::Elite)
|
||||
| cr::bit (Weapon::USP)
|
||||
| cr::bit (Weapon::Glock18)
|
||||
| cr::bit (Weapon::Deagle)
|
||||
| cr::bit (Weapon::FiveSeven));
|
||||
|
||||
constexpr auto kSniperWeaponMask = (cr::bit (Weapon::Scout)
|
||||
| cr::bit (Weapon::SG550)
|
||||
| cr::bit (Weapon::AWP)
|
||||
| cr::bit (Weapon::G3SG1));
|
||||
| cr::bit (Weapon::SG550)
|
||||
| cr::bit (Weapon::AWP)
|
||||
| cr::bit (Weapon::G3SG1));
|
||||
|
||||
// weapons < 7 are secondary
|
||||
constexpr auto kPrimaryWeaponMinIndex = 7;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ CR_DECLARE_SCOPED_ENUM (PrintQueueDestination,
|
|||
// bot command manager
|
||||
class BotControl final : public Singleton <BotControl> {
|
||||
public:
|
||||
using Handler = int (BotControl::*) ();
|
||||
using MenuHandler = int (BotControl::*) (int);
|
||||
using Handler = int (BotControl:: *) ();
|
||||
using MenuHandler = int (BotControl:: *) (int);
|
||||
|
||||
public:
|
||||
// generic bot command
|
||||
|
|
@ -36,8 +36,7 @@ public:
|
|||
public:
|
||||
explicit BotCmd () = default;
|
||||
|
||||
BotCmd (StringRef name, StringRef format, StringRef help, Handler handler, bool visible = true) : name (name), format (format), help (help), handler (cr::move (handler)), visible (visible)
|
||||
{ }
|
||||
BotCmd (StringRef name, StringRef format, StringRef help, Handler handler, bool visible = true) : name (name), format (format), help (help), handler (cr::move (handler)), visible (visible) {}
|
||||
};
|
||||
|
||||
// single bot menu
|
||||
|
|
@ -47,8 +46,7 @@ public:
|
|||
MenuHandler handler {};
|
||||
|
||||
public:
|
||||
explicit BotMenu (int ident, int slots, StringRef text, MenuHandler handler) : ident (ident), slots (slots), text (text), handler (cr::move (handler))
|
||||
{ }
|
||||
explicit BotMenu (int ident, int slots, StringRef text, MenuHandler handler) : ident (ident), slots (slots), text (text), handler (cr::move (handler)) {}
|
||||
};
|
||||
|
||||
// queued text message to prevent overflow with rapid output
|
||||
|
|
@ -57,10 +55,9 @@ public:
|
|||
String text {};
|
||||
|
||||
public:
|
||||
explicit PrintQueue () = default;
|
||||
explicit PrintQueue () = default;
|
||||
|
||||
PrintQueue (int32_t destination, StringRef text) : destination (destination), text (text)
|
||||
{ }
|
||||
PrintQueue (int32_t destination, StringRef text) : destination (destination), text (text) {}
|
||||
};
|
||||
|
||||
// save old values of changed cvars to revert them back when editing turned off
|
||||
|
|
@ -118,6 +115,7 @@ private:
|
|||
int cmdNodeSave ();
|
||||
int cmdNodeLoad ();
|
||||
int cmdNodeErase ();
|
||||
int cmdNodeRefresh ();
|
||||
int cmdNodeEraseTraining ();
|
||||
int cmdNodeDelete ();
|
||||
int cmdNodeCheck ();
|
||||
|
|
@ -255,7 +253,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
edict_t *getIssuer() {
|
||||
edict_t *getIssuer () {
|
||||
return m_ent;
|
||||
}
|
||||
|
||||
|
|
|
|||
14
inc/engine.h
14
inc/engine.h
|
|
@ -60,7 +60,7 @@ CR_DECLARE_SCOPED_ENUM (MapFlags,
|
|||
Escape = cr::bit (3),
|
||||
KnifeArena = cr::bit (4),
|
||||
FightYard = cr::bit (5),
|
||||
GrenadeWar = cr::bit(6),
|
||||
GrenadeWar = cr::bit (6),
|
||||
HasDoors = cr::bit (10), // additional flags
|
||||
HasButtons = cr::bit (11) // map has buttons
|
||||
)
|
||||
|
|
@ -190,6 +190,9 @@ public:
|
|||
// initialize levels
|
||||
void levelInitialize (edict_t *entities, int max);
|
||||
|
||||
// when entity spawns
|
||||
void onSpawnEntity (edict_t *ent);
|
||||
|
||||
// shutdown levels
|
||||
void levelShutdown ();
|
||||
|
||||
|
|
@ -291,7 +294,7 @@ public:
|
|||
bool isFakeClientEntity (edict_t *ent) const;
|
||||
|
||||
// check if entity is a player
|
||||
bool isPlayerEntity (edict_t *ent) const ;
|
||||
bool isPlayerEntity (edict_t *ent) const;
|
||||
|
||||
// check if entity is a monster
|
||||
bool isMonsterEntity (edict_t *ent) const;
|
||||
|
|
@ -333,7 +336,10 @@ public:
|
|||
|
||||
// gets custom engine args for client command
|
||||
const char *botArgs () const {
|
||||
return strings.format (String::join (m_botArgs, " ", m_botArgs[0].startsWith ("say") ? 1 : 0).chars ());
|
||||
auto result = strings.chars ();
|
||||
strings.copy (result, String::join (m_botArgs, " ", m_botArgs[0].startsWith ("say") ? 1 : 0).chars (), cr::StringBuffer::StaticBufferSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// gets custom engine argv for client command
|
||||
|
|
@ -486,7 +492,7 @@ public:
|
|||
|
||||
// helper to sending the client message
|
||||
void sendClientMessage (bool console, edict_t *ent, StringRef message);
|
||||
|
||||
|
||||
// helper to sending the server message
|
||||
void sendServerMessage (StringRef message);
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ public:
|
|||
bool loadGraphData ();
|
||||
bool canDownload ();
|
||||
bool isAnalyzed () const;
|
||||
bool isConverted () const;
|
||||
|
||||
void saveOldFormat ();
|
||||
void reset ();
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ CR_DECLARE_SCOPED_ENUM (StatusIconCache,
|
|||
|
||||
class MessageDispatcher final : public Singleton <MessageDispatcher> {
|
||||
private:
|
||||
using MsgFunc = void (MessageDispatcher::*) ();
|
||||
using MsgFunc = void (MessageDispatcher:: *) ();
|
||||
using MsgHash = Hash <int32_t>;
|
||||
|
||||
private:
|
||||
|
|
@ -81,9 +81,9 @@ private:
|
|||
};
|
||||
|
||||
public:
|
||||
Args (float value) : float_ (value) { }
|
||||
Args (int32_t value) : long_ (value) { }
|
||||
Args (const char *value) : chars_ (value) { }
|
||||
Args (float value) : float_ (value) {}
|
||||
Args (int32_t value) : long_ (value) {}
|
||||
Args (const char *value) : chars_ (value) {}
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ CR_DECLARE_SCOPED_ENUM (AStarResult,
|
|||
Success = 0,
|
||||
Failed,
|
||||
InternalError,
|
||||
)
|
||||
)
|
||||
|
||||
// node added
|
||||
using NodeAdderFn = const Lambda <bool (int)> &;
|
||||
// node added
|
||||
using NodeAdderFn = const Lambda <bool (int)> &;
|
||||
|
||||
// route twin node
|
||||
template <typename HT> struct RouteTwin final {
|
||||
|
|
@ -58,7 +58,7 @@ public:
|
|||
static float gfunctionKillsDist (int team, int currentIndex, int parentIndex);
|
||||
|
||||
// least kills and number of nodes to goal for a team (when with hostage)
|
||||
static float gfunctionKillsDistCTWithHostage (int team, int currentIndex, int parentIndex);
|
||||
static float gfunctionKillsDistCTWithHostage (int team, int currentIndex, int parentIndex);
|
||||
|
||||
// least kills to goal for a team
|
||||
static float gfunctionKills (int team, int currentIndex, int);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ CR_DECLARE_SCOPED_ENUM (StorageOption,
|
|||
Official = cr::bit (4), // this is additional flag for graph indicates graph are official
|
||||
Recovered = cr::bit (5), // this is additional flag indicates graph converted from podbot and was bad
|
||||
Exten = cr::bit (6), // this is additional flag indicates that there's extension info
|
||||
Analyzed = cr::bit (7) // this graph has been analyzed
|
||||
Analyzed = cr::bit (7), // this graph has been analyzed
|
||||
Converted = cr::bit (8) // converted from a pwf format
|
||||
)
|
||||
|
||||
// storage header versions
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ public:
|
|||
bool isReady () const {
|
||||
return !m_rebuild;
|
||||
}
|
||||
|
||||
// is visible fromr both points ?
|
||||
bool visibleBothSides (int srcIndex, int destIndex, VisIndex vis = VisIndex::Any) const {
|
||||
return visible (srcIndex, destIndex, vis) && visible (destIndex, srcIndex, vis);
|
||||
}
|
||||
};
|
||||
|
||||
// expose global
|
||||
|
|
|
|||
40
inc/yapb.h
40
inc/yapb.h
|
|
@ -23,7 +23,7 @@ using namespace cr;
|
|||
|
||||
// tasks definition
|
||||
struct BotTask {
|
||||
using Function = void (Bot::*) ();
|
||||
using Function = void (Bot:: *) ();
|
||||
|
||||
public:
|
||||
Function func {}; // corresponding exec function in bot class
|
||||
|
|
@ -34,7 +34,7 @@ public:
|
|||
bool resume {}; // if task can be continued if interrupted
|
||||
|
||||
public:
|
||||
BotTask (Function func, Task id, float desire, int data, float time, bool resume) : func (func), id (id), desire (desire), data (data), time (time), resume (resume) { }
|
||||
BotTask (Function func, Task id, float desire, int data, float time, bool resume) : func (func), id (id), desire (desire), data (data), time (time), resume (resume) {}
|
||||
};
|
||||
|
||||
// weapon properties structure
|
||||
|
|
@ -68,7 +68,7 @@ struct WeaponInfo {
|
|||
bool primaryFireHold {}; // hold down primary fire button to use?
|
||||
|
||||
public:
|
||||
WeaponInfo (int id,
|
||||
WeaponInfo (int id,
|
||||
StringRef name,
|
||||
StringRef model,
|
||||
int price,
|
||||
|
|
@ -78,14 +78,13 @@ public:
|
|||
int buyGroup,
|
||||
int buySelect,
|
||||
int buySelectT,
|
||||
int buySelectCT,
|
||||
int buySelectCT,
|
||||
int penetratePower,
|
||||
int maxClip,
|
||||
int type,
|
||||
bool fireHold) : id (id), name (name), model (model), price (price), minPrimaryAmmo (minPriAmmo), teamStandard (teamStd),
|
||||
bool fireHold) : id (id), name (name), model (model), price (price), minPrimaryAmmo (minPriAmmo), teamStandard (teamStd),
|
||||
teamAS (teamAs), buyGroup (buyGroup), buySelect (buySelect), buySelectT (buySelectT), buySelectCT (buySelectCT),
|
||||
penetratePower (penetratePower), maxClip (maxClip), type (type), primaryFireHold (fireHold)
|
||||
{ }
|
||||
penetratePower (penetratePower), maxClip (maxClip), type (type), primaryFireHold (fireHold) {}
|
||||
};
|
||||
|
||||
// clients noise
|
||||
|
|
@ -123,6 +122,16 @@ struct BotTeamData {
|
|||
int32_t lastRadioSlot = { kInvalidRadioSlot }; // last radio message for team
|
||||
};
|
||||
|
||||
// bot difficulty data
|
||||
struct BotDifficultyData {
|
||||
float reaction[2] {};
|
||||
int32_t headshotPct {};
|
||||
int32_t seenThruPct {};
|
||||
int32_t hearThruPct {};
|
||||
int32_t maxRecoil {};
|
||||
Vector aimError {};
|
||||
};
|
||||
|
||||
// include bot graph stuff
|
||||
#include <graph.h>
|
||||
#include <vision.h>
|
||||
|
|
@ -210,6 +219,8 @@ private:
|
|||
mutable Mutex m_pathFindLock {};
|
||||
mutable Mutex m_predictLock {};
|
||||
|
||||
float f_wpt_tim_str_chg;
|
||||
|
||||
private:
|
||||
uint32_t m_states {}; // sensing bitstates
|
||||
uint32_t m_collideMoves[kMaxCollideMoves] {}; // sorted array of movements
|
||||
|
|
@ -240,11 +251,10 @@ private:
|
|||
int m_lastPredictLength {}; // last predicted path length
|
||||
int m_pickupType {}; // type of entity which needs to be used/picked up
|
||||
|
||||
float m_headedTime {};
|
||||
float m_headedTime {}; // last time followed by radio entity
|
||||
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_timeHitDoor {}; // specific time after hitting the door
|
||||
float m_lastChatTime {}; // time bot last chatted
|
||||
|
|
@ -361,7 +371,6 @@ private:
|
|||
Vector m_lookAtPredict {}; // aiming vector when predicting
|
||||
Vector m_desiredVelocity {}; // desired velocity for jump nodes
|
||||
Vector m_breakableOrigin {}; // origin of breakable
|
||||
Vector m_rightRef {}; // right referential vector
|
||||
Vector m_checkFallPoint[2] {}; // check fall point
|
||||
|
||||
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
|
||||
|
|
@ -370,6 +379,7 @@ private:
|
|||
|
||||
UniquePtr <class PlayerHitboxEnumerator> m_hitboxEnumerator {};
|
||||
|
||||
BotDifficultyData *m_difficultyData {};
|
||||
Path *m_path {}; // pointer to the current path node
|
||||
String m_chatBuffer {}; // space for strings (say text...)
|
||||
Frustum::Planes m_viewFrustum {};
|
||||
|
|
@ -400,7 +410,7 @@ private:
|
|||
int numEnemiesNear (const Vector &origin, const float radius) const;
|
||||
int numFriendsNear (const Vector &origin, const float radius) const;
|
||||
|
||||
|
||||
|
||||
float getEstimatedNodeReachTime ();
|
||||
float isInFOV (const Vector &dest) const;
|
||||
float getShiftSpeed ();
|
||||
|
|
@ -529,7 +539,6 @@ private:
|
|||
void syncUpdatePredictedIndex ();
|
||||
void updatePredictedIndex ();
|
||||
void refreshCreatureStatus (char *infobuffer);
|
||||
void updateRightRef ();
|
||||
void donateC4ToHuman ();
|
||||
void clearAmmoInfo ();
|
||||
void handleChatterTaskChange (Task tid);
|
||||
|
|
@ -681,6 +690,7 @@ public:
|
|||
int m_ammoInClip[kMaxWeapons] {}; // ammo in clip for each weapons
|
||||
int m_ammo[MAX_AMMO_SLOTS] {}; // total ammo amounts
|
||||
int m_deathCount {}; // number of bot deaths
|
||||
int m_ladderDir {}; // ladder move direction
|
||||
|
||||
bool m_isVIP {}; // bot is vip?
|
||||
bool m_isAlive {}; // has the player been killed or has he just respawned
|
||||
|
|
@ -700,7 +710,7 @@ public:
|
|||
bool m_hasHostage {}; // does bot owns some hostages
|
||||
bool m_hasProgressBar {}; // has progress bar on a HUD
|
||||
bool m_jumpReady {}; // is double jump ready
|
||||
bool m_canChooseAimDirection {}; // can choose aiming direction
|
||||
bool m_canSetAimDirection {}; // can choose aiming direction
|
||||
bool m_isEnemyReachable {}; // direct line to enemy
|
||||
bool m_kickedByRotation {}; // is bot kicked due to rotation ?
|
||||
bool m_kickMeFromServer {}; // kick the bot off the server?
|
||||
|
|
@ -768,6 +778,7 @@ public:
|
|||
void startDoubleJump (edict_t *ent);
|
||||
void sendBotToOrigin (const Vector &origin);
|
||||
void markStale ();
|
||||
void setNewDifficulty (int32_t newDifficulty);
|
||||
bool hasHostage ();
|
||||
bool hasPrimaryWeapon () const;
|
||||
bool hasSecondaryWeapon () const;
|
||||
|
|
@ -792,7 +803,7 @@ public:
|
|||
bool isDucking () const {
|
||||
return !!(pev->flags & FL_DUCKING);
|
||||
}
|
||||
|
||||
|
||||
Vector getCenter () const {
|
||||
return (pev->absmax + pev->absmin) * 0.5;
|
||||
};
|
||||
|
|
@ -942,6 +953,7 @@ extern ConVar cv_ignore_enemies_after_spawn_time;
|
|||
extern ConVar cv_camping_time_min;
|
||||
extern ConVar cv_camping_time_max;
|
||||
extern ConVar cv_smoke_grenade_checks;
|
||||
extern ConVar cv_smoke_greande_checks_radius;
|
||||
extern ConVar cv_check_darkness;
|
||||
extern ConVar cv_use_hitbox_enemy_targeting;
|
||||
extern ConVar cv_restricted_weapons;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue