control: add g path_clean to remove all links from node (#475)
refactor: small cosmetic changes
This commit is contained in:
parent
fe5c8ef053
commit
fb301b7b19
23 changed files with 205 additions and 132 deletions
|
|
@ -447,3 +447,8 @@ constexpr auto kSecondaryWeaponMask = (cr::bit (Weapon::P228) | cr::bit (Weapon:
|
|||
|
||||
// weapons < 7 are secondary
|
||||
constexpr auto kPrimaryWeaponMinIndex = 7;
|
||||
|
||||
// grenade model names
|
||||
static constexpr StringRef kExplosiveModelName = "hegrenade.mdl";
|
||||
static constexpr StringRef kFlashbangModelName = "flashbang.mdl";
|
||||
static constexpr StringRef kSmokeModelName = "smokegrenade.mdl";
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ private:
|
|||
int cmdNodePathCreate ();
|
||||
int cmdNodePathDelete ();
|
||||
int cmdNodePathSetAutoDistance ();
|
||||
int cmdNodePathCleanAll ();
|
||||
int cmdNodeAcquireEditor ();
|
||||
int cmdNodeReleaseEditor ();
|
||||
int cmdNodeUpload ();
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public:
|
|||
// provides utility functions to not call original engine (less call-cost)
|
||||
class Game final : public Singleton <Game> {
|
||||
public:
|
||||
using EntitySearch = Lambda <EntitySearchResult (edict_t *)>;
|
||||
using EntitySearch = const Lambda <EntitySearchResult (edict_t *)> &;
|
||||
|
||||
private:
|
||||
int m_drawModels[DrawLine::Count] {};
|
||||
|
|
@ -227,12 +227,12 @@ public:
|
|||
}
|
||||
|
||||
// get "maxplayers" limit on server
|
||||
int maxClients () const {
|
||||
int maxClients () const {
|
||||
return globals->maxClients;
|
||||
}
|
||||
|
||||
// get the fakeclient command interface
|
||||
bool isBotCmd () const {
|
||||
bool isBotCmd () const {
|
||||
return !m_botArgs.empty ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ public:
|
|||
void setRadius (int index, float radius);
|
||||
void pathCreate (char dir);
|
||||
void erasePath ();
|
||||
void resetPath (int index);
|
||||
void cachePoint (int index);
|
||||
void calculatePathRadius (int index);
|
||||
void addBasic ();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ struct BotRequest {
|
|||
// manager class
|
||||
class BotManager final : public Singleton <BotManager> {
|
||||
public:
|
||||
using ForEachBot = Lambda <bool (Bot *)>;
|
||||
using ForEachBot = const Lambda <bool (Bot *)> &;
|
||||
using UniqueBot = UniquePtr <Bot>;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ CR_DECLARE_SCOPED_ENUM (AStarResult,
|
|||
)
|
||||
|
||||
// node added
|
||||
using NodeAdderFn = Lambda <bool (int)>;
|
||||
using NodeAdderFn = const Lambda <bool (int)> &;
|
||||
|
||||
// route twin node
|
||||
template <typename HT> struct RouteTwin final {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
// check if entity is a hostage entity
|
||||
bool isHostageEntity (edict_t *ent);
|
||||
|
||||
// check if entity is a door enitty
|
||||
// check if entity is a door entity
|
||||
bool isDoorEntity (edict_t *ent);
|
||||
|
||||
// this function is checking that pointed by ent pointer obstacle, can be destroyed
|
||||
|
|
@ -133,13 +133,13 @@ public:
|
|||
}
|
||||
|
||||
// gets the shooting cone deviation
|
||||
float getShootingCone (edict_t *ent, const Vector &position) {
|
||||
return ent->v.v_angle.forward () | (position - (ent->v.origin + ent->v.view_ofs)).normalize (); // he's facing it, he meant it
|
||||
float getShootingCone (edict_t *ent, const Vector &pos) {
|
||||
return ent->v.v_angle.forward () | (pos - (ent->v.origin + ent->v.view_ofs)).normalize (); // he's facing it, he meant it
|
||||
}
|
||||
|
||||
// check if origin is inside view cone of entity
|
||||
bool isInViewCone (const Vector &origin, edict_t *ent) {
|
||||
return getShootingCone (ent, origin) >= cr::cosf (cr::deg2rad ((ent->v.fov > 0 ? ent->v.fov : 90.0f) * 0.5f));
|
||||
// check if position is inside view cone of entity
|
||||
bool isInViewCone (const Vector &pos, edict_t *ent) {
|
||||
return getShootingCone (ent, pos) >= cr::cosf (cr::deg2rad ((ent->v.fov > 0 ? ent->v.fov : 90.0f) * 0.5f));
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ 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
|
||||
|
||||
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
|
||||
Array <edict_t *> m_hostages {}; // pointer to used hostage entities
|
||||
|
|
@ -485,7 +486,7 @@ private:
|
|||
void findShortestPath (int srcIndex, int destIndex);
|
||||
void findPath (int srcIndex, int destIndex, FindPath pathType = FindPath::Fast);
|
||||
void syncFindPath (int srcIndex, int destIndex, FindPath pathType);
|
||||
void debugMsgInternal (const char *str);
|
||||
void debugMsgInternal (StringRef str);
|
||||
void frame ();
|
||||
void resetCollision ();
|
||||
void ignoreCollision ();
|
||||
|
|
@ -509,6 +510,7 @@ private:
|
|||
void syncUpdatePredictedIndex ();
|
||||
void updatePredictedIndex ();
|
||||
void refreshModelName (char *infobuffer);
|
||||
void updateRightRef ();
|
||||
|
||||
void completeTask ();
|
||||
void executeTasks ();
|
||||
|
|
@ -540,9 +542,9 @@ private:
|
|||
void pickupItem_ ();
|
||||
void shootBreakable_ ();
|
||||
|
||||
edict_t *lookupButton (const char *target);
|
||||
edict_t *lookupButton (StringRef target);
|
||||
edict_t *lookupBreakable ();
|
||||
edict_t *setCorrectGrenadeVelocity (const char *model);
|
||||
edict_t *setCorrectGrenadeVelocity (StringRef model);
|
||||
|
||||
Vector getEnemyBodyOffset ();
|
||||
Vector calcThrow (const Vector &start, const Vector &stop);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ void Bot::pushMsgQueue (int message) {
|
|||
|
||||
if (message == BotMsg::Say) {
|
||||
// notify other bots of the spoken text otherwise, bots won't respond to other bots (network messages aren't sent from bots)
|
||||
int entityIndex = index ();
|
||||
const int entityIndex = index ();
|
||||
|
||||
for (const auto &other : bots) {
|
||||
if (other->pev != pev) {
|
||||
|
|
@ -96,7 +96,7 @@ void Bot::avoidGrenades () {
|
|||
}
|
||||
auto model = pent->v.model.str (9);
|
||||
|
||||
if (m_preventFlashing < game.time () && m_personality == Personality::Rusher && m_difficulty == Difficulty::Expert && model == "flashbang.mdl") {
|
||||
if (m_preventFlashing < game.time () && m_personality == Personality::Rusher && m_difficulty == Difficulty::Expert && model == kFlashbangModelName) {
|
||||
// don't look at flash bang
|
||||
if (!(m_states & Sense::SeeingEnemy)) {
|
||||
m_lookAt.y = cr::wrapAngle ((game.getEntityOrigin (pent) - getEyesPos ()).angles ().y + 180.0f);
|
||||
|
|
@ -105,7 +105,7 @@ void Bot::avoidGrenades () {
|
|||
m_preventFlashing = game.time () + rg.get (1.0f, 2.0f);
|
||||
}
|
||||
}
|
||||
else if (game.isNullEntity (m_avoidGrenade) && model == "hegrenade.mdl") {
|
||||
else if (game.isNullEntity (m_avoidGrenade) && model == kExplosiveModelName) {
|
||||
if (game.getTeam (pent->v.owner) == m_team || pent->v.owner == ent ()) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ void Bot::avoidGrenades () {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if ((pent->v.flags & FL_ONGROUND) && model == "smokegrenade.mdl") {
|
||||
else if ((pent->v.flags & FL_ONGROUND) && model == kSmokeModelName) {
|
||||
if (isInFOV (pent->v.origin - getEyesPos ()) < pev->fov / 3.0f) {
|
||||
const auto &entOrigin = game.getEntityOrigin (pent);
|
||||
const auto &betweenUs = (entOrigin - pev->origin).normalize_apx ();
|
||||
|
|
@ -403,8 +403,8 @@ void Bot::updatePickups () {
|
|||
pickupType = Pickup::Weapon;
|
||||
|
||||
if (cv_pickup_ammo_and_kits.bool_ ()) {
|
||||
int primaryWeaponCarried = bestPrimaryCarried ();
|
||||
int secondaryWeaponCarried = bestSecondaryCarried ();
|
||||
const int primaryWeaponCarried = bestPrimaryCarried ();
|
||||
const int secondaryWeaponCarried = bestSecondaryCarried ();
|
||||
|
||||
const auto &config = conf.getWeapons ();
|
||||
const auto &primary = config[primaryWeaponCarried];
|
||||
|
|
@ -493,13 +493,13 @@ void Bot::updatePickups () {
|
|||
else if (!rateGroundWeapon (ent)) {
|
||||
allowPickup = false;
|
||||
}
|
||||
else if ((pev->weapons & cr::bit (Weapon::Flashbang)) && model == "flashbang.mdl") {
|
||||
else if ((pev->weapons & cr::bit (Weapon::Flashbang)) && model == kFlashbangModelName) {
|
||||
allowPickup = false;
|
||||
}
|
||||
else if ((pev->weapons & cr::bit (Weapon::Explosive)) && model == "hegrenade.mdl") {
|
||||
else if ((pev->weapons & cr::bit (Weapon::Explosive)) && model == kExplosiveModelName) {
|
||||
allowPickup = false;
|
||||
}
|
||||
else if ((pev->weapons & cr::bit (Weapon::Smoke)) && model == "smokegrenade.mdl") {
|
||||
else if ((pev->weapons & cr::bit (Weapon::Smoke)) && model == kSmokeModelName) {
|
||||
allowPickup = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -637,7 +637,6 @@ void Bot::updatePickups () {
|
|||
}
|
||||
|
||||
if (pev->origin.distanceSq (origin) > cr::sqrf (60.0f)) {
|
||||
|
||||
if (!graph.isNodeReacheable (pev->origin, origin)) {
|
||||
allowPickup = false;
|
||||
}
|
||||
|
|
@ -840,7 +839,7 @@ void Bot::instantChatter (int type) {
|
|||
const int ownIndex = index ();
|
||||
|
||||
auto writeChatterSound = [&msg] (ChatterItem item) {
|
||||
msg.writeString (strings.format ("%s%s%s.wav", cv_chatter_path.str (), PATH_SEP, item.name));
|
||||
msg.writeString (strings.format ("%s%s%s.wav", cv_chatter_path.str (), kPathSeparator, item.name));
|
||||
};
|
||||
|
||||
for (auto &client : util.getClients ()) {
|
||||
|
|
@ -3483,7 +3482,7 @@ void Bot::resetDoubleJump () {
|
|||
m_jumpReady = false;
|
||||
}
|
||||
|
||||
void Bot::debugMsgInternal (const char *str) {
|
||||
void Bot::debugMsgInternal (StringRef str) {
|
||||
if (game.isDedicated ()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void BotSupport::addChatErrors (String &line) {
|
|||
if (rg.chance (8) && cv_language.str () == "en") {
|
||||
line.lowercase ();
|
||||
}
|
||||
auto length = static_cast <int32_t> (line.length ());
|
||||
const auto length = static_cast <int32_t> (line.length ());
|
||||
|
||||
if (length > 15) {
|
||||
const auto percentile = length / 2;
|
||||
|
|
@ -106,6 +106,7 @@ bool BotSupport::checkKeywords (StringRef line, String &reply) {
|
|||
if (!replyUsed) {
|
||||
reply.assign (choosenReply); // update final buffer
|
||||
usedReplies.push (choosenReply); // add to ignore list
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -168,7 +169,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
|||
if (!(client.flags & ClientFlags::Used) || client.ent == ent ()) {
|
||||
continue;
|
||||
}
|
||||
int frags = static_cast <int> (client.ent->v.frags);
|
||||
const auto frags = static_cast <int> (client.ent->v.frags);
|
||||
|
||||
if (frags > highestFrags) {
|
||||
highestFrags = frags;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ bool Bot::isEnemyHidden (edict_t *enemy) {
|
|||
if (!cv_check_enemy_rendering.bool_ () || game.isNullEntity (enemy)) {
|
||||
return false;
|
||||
}
|
||||
entvars_t &v = enemy->v;
|
||||
const auto &v = enemy->v;
|
||||
|
||||
const bool enemyHasGun = (v.weapons & kPrimaryWeaponMask) || (v.weapons & kSecondaryWeaponMask);
|
||||
const bool enemyGunfire = (v.button & IN_ATTACK) || (v.oldbuttons & IN_ATTACK);
|
||||
|
|
@ -94,7 +94,7 @@ bool Bot::isEnemyInvincible (edict_t *enemy) {
|
|||
if (!cv_check_enemy_invincibility.bool_ () || game.isNullEntity (enemy)) {
|
||||
return false;
|
||||
}
|
||||
const entvars_t &v = enemy->v;
|
||||
const auto &v = enemy->v;
|
||||
|
||||
if (v.solid < SOLID_BBOX) {
|
||||
return true;
|
||||
|
|
@ -162,14 +162,15 @@ bool Bot::checkBodyParts (edict_t *target) {
|
|||
return true;
|
||||
}
|
||||
|
||||
constexpr auto standFeet = 34.0f;
|
||||
constexpr auto crouchFeet = 14.0f;
|
||||
constexpr auto kStandFeet = 34.0f;
|
||||
constexpr auto kCrouchFeet = 14.0f;
|
||||
constexpr auto kEdgeOffset = 13.0f;
|
||||
|
||||
if (target->v.flags & FL_DUCKING) {
|
||||
spot.z = target->v.origin.z - crouchFeet;
|
||||
spot.z = target->v.origin.z - kCrouchFeet;
|
||||
}
|
||||
else {
|
||||
spot.z = target->v.origin.z - standFeet;
|
||||
spot.z = target->v.origin.z - kStandFeet;
|
||||
}
|
||||
game.testLine (eyes, spot, ignoreFlags, self, &result);
|
||||
|
||||
|
|
@ -179,12 +180,10 @@ bool Bot::checkBodyParts (edict_t *target) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
const float edgeOffset = 13.0f;
|
||||
Vector dir = (target->v.origin - pev->origin).normalize2d ();
|
||||
|
||||
Vector perp (-dir.y, dir.x, 0.0f);
|
||||
spot = target->v.origin + Vector (perp.x * edgeOffset, perp.y * edgeOffset, 0);
|
||||
spot = target->v.origin + Vector (perp.x * kEdgeOffset, perp.y * kEdgeOffset, 0);
|
||||
|
||||
game.testLine (eyes, spot, ignoreFlags, self, &result);
|
||||
|
||||
|
|
@ -194,7 +193,7 @@ bool Bot::checkBodyParts (edict_t *target) {
|
|||
|
||||
return true;
|
||||
}
|
||||
spot = target->v.origin - Vector (perp.x * edgeOffset, perp.y * edgeOffset, 0);
|
||||
spot = target->v.origin - Vector (perp.x * kEdgeOffset, perp.y * kEdgeOffset, 0);
|
||||
|
||||
game.testLine (eyes, spot, ignoreFlags, self, &result);
|
||||
|
||||
|
|
@ -554,7 +553,7 @@ Vector Bot::getCustomHeight (float distance) {
|
|||
constexpr float offsetRanges[9][3] = {
|
||||
{ 0.0f, 0.0f, 0.0f }, // none
|
||||
{ 0.0f, 0.0f, 0.0f }, // melee
|
||||
{ 0.5f, -3.0f, -4.5f }, // pistol
|
||||
{ 0.5f, -0.1f, -1.5f }, // pistol
|
||||
{ 6.5f, 6.0f, -2.0f }, // shotgun
|
||||
{ 0.5f -7.5f, -9.5f }, // zoomrifle
|
||||
{ 0.5f, -7.5f, -9.5f }, // rifle
|
||||
|
|
@ -771,6 +770,9 @@ bool Bot::needToPauseFiring (float distance) {
|
|||
else if (distance < kDoubleSprayDistance) {
|
||||
offset = 2.75f;
|
||||
}
|
||||
else if ((m_states & Sense::SuspectEnemy) && distance < kDoubleSprayDistance) {
|
||||
return false;
|
||||
}
|
||||
const float xPunch = cr::sqrf (cr::deg2rad (pev->punchangle.x));
|
||||
const float yPunch = cr::sqrf (cr::deg2rad (pev->punchangle.y));
|
||||
|
||||
|
|
@ -931,12 +933,12 @@ void Bot::selectWeapons (float distance, int index, int id, int choosen) {
|
|||
pev->button |= IN_ATTACK;
|
||||
}
|
||||
|
||||
constexpr float minDelay[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f };
|
||||
constexpr float maxDelay[] = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f };
|
||||
constexpr float kMinFireDelay[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f };
|
||||
constexpr float kMaxFireDelay[] = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f };
|
||||
|
||||
const int offset = cr::abs <int> (m_difficulty * 25 / 20 - 5);
|
||||
|
||||
m_shootTime = game.time () + 0.1f + rg.get (minDelay[offset], maxDelay[offset]);
|
||||
m_shootTime = game.time () + 0.1f + rg.get (kMinFireDelay[offset], kMaxFireDelay[offset]);
|
||||
m_zoomCheckTime = game.time ();
|
||||
}
|
||||
}
|
||||
|
|
@ -944,8 +946,8 @@ void Bot::selectWeapons (float distance, int index, int id, int choosen) {
|
|||
|
||||
void Bot::fireWeapons () {
|
||||
// this function will return true if weapon was fired, false otherwise
|
||||
//
|
||||
// do not handle this if with grenade, as it's done it throw grendate task
|
||||
|
||||
// do not handle this if with grenade, as it's done it throw grenade task
|
||||
if (m_isUsingGrenade) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -963,7 +965,7 @@ void Bot::fireWeapons () {
|
|||
const auto tab = conf.getRawWeapons ();
|
||||
const auto weapons = pev->weapons;
|
||||
|
||||
// if jason mode use knife only
|
||||
// if knife mode use knife only
|
||||
if (isKnifeMode ()) {
|
||||
selectWeapons (distance, selectIndex, selectId, choosenWeapon);
|
||||
return;
|
||||
|
|
@ -1707,10 +1709,10 @@ void Bot::checkReload () {
|
|||
|
||||
float Bot::calculateScaleFactor (edict_t *ent) {
|
||||
Vector entSize = ent->v.maxs - ent->v.mins;
|
||||
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);
|
||||
|
||||
Vector botSize = pev->maxs - pev->mins;
|
||||
float botArea = 2.0f * (botSize.x * botSize.y + botSize.y * botSize.z + botSize.x * botSize.z);
|
||||
const float botArea = 2.0f * (botSize.x * botSize.y + botSize.y * botSize.z + botSize.x * botSize.z);
|
||||
|
||||
return entArea / botArea;
|
||||
}
|
||||
|
|
@ -1809,7 +1811,7 @@ Vector Bot::calcThrow (const Vector &start, const Vector &stop) {
|
|||
return velocity * 0.7793f;
|
||||
}
|
||||
|
||||
edict_t *Bot::setCorrectGrenadeVelocity (const char *model) {
|
||||
edict_t *Bot::setCorrectGrenadeVelocity (StringRef model) {
|
||||
edict_t *result = nullptr;
|
||||
|
||||
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
||||
|
|
@ -1856,11 +1858,11 @@ void Bot::checkGrenadesThrow () {
|
|||
}
|
||||
|
||||
// check if we have grenades to throw
|
||||
int grenadeToThrow = bestGrenadeCarried ();
|
||||
const auto grenadeToThrow = bestGrenadeCarried ();
|
||||
|
||||
// if we don't have grenades no need to check it this round again
|
||||
if (grenadeToThrow == -1) {
|
||||
m_grenadeCheckTime = game.time () + 15.0f; // changed since, conzero can drop grens from dead players
|
||||
m_grenadeCheckTime = game.time () + 15.0f; // changed since, czero can drop grenades from dead players
|
||||
|
||||
clearThrowStates (m_states);
|
||||
return;
|
||||
|
|
@ -2051,18 +2053,18 @@ bool Bot::isEnemyNoticeable (float range) {
|
|||
if (m_enemyParts & Visibility::Other) {
|
||||
coverRatio += rg.get (10.0f, 25.0f);
|
||||
}
|
||||
constexpr float closeRange = 300.0f;
|
||||
constexpr float farRange = 1000.0f;
|
||||
constexpr float kCloseRange = 300.0f;
|
||||
constexpr float kFarRange = 1000.0f;
|
||||
|
||||
float rangeModifier;
|
||||
if (range < closeRange) {
|
||||
if (range < kCloseRange) {
|
||||
rangeModifier = 0.0f;
|
||||
}
|
||||
else if (range > farRange) {
|
||||
else if (range > kFarRange) {
|
||||
rangeModifier = 1.0f;
|
||||
}
|
||||
else {
|
||||
rangeModifier = (range - closeRange) / (farRange - closeRange);
|
||||
rangeModifier = (range - kCloseRange) / (kFarRange - kCloseRange);
|
||||
}
|
||||
|
||||
// harder to notice when crouched
|
||||
|
|
@ -2072,13 +2074,13 @@ bool Bot::isEnemyNoticeable (float range) {
|
|||
float playerSpeedSq = m_enemy->v.velocity.lengthSq ();
|
||||
float farChance, closeChance;
|
||||
|
||||
constexpr float runSpeed = cr::sqrf (200.0f);
|
||||
constexpr float walkSpeed = cr::sqrf (30.0f);
|
||||
constexpr float kRunSpeed = cr::sqrf (200.0f);
|
||||
constexpr float kWalkSpeed = cr::sqrf (30.0f);
|
||||
|
||||
if (playerSpeedSq > runSpeed) {
|
||||
if (playerSpeedSq > kRunSpeed) {
|
||||
return true; // running players are always easy to spot (must be standing to run)
|
||||
}
|
||||
else if (playerSpeedSq > walkSpeed) {
|
||||
else if (playerSpeedSq > kWalkSpeed) {
|
||||
// walking players are less noticeable far away
|
||||
if (isCrouching) {
|
||||
closeChance = 90.0f;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ void BotConfig::loadNamesConfig () {
|
|||
String line;
|
||||
MemFile file;
|
||||
|
||||
constexpr auto kMaxNameLen = 32;
|
||||
|
||||
// naming initialization
|
||||
if (openConfig ("names", "Name configuration file not found.", &file, true)) {
|
||||
m_botNames.clear ();
|
||||
|
|
@ -135,8 +137,8 @@ void BotConfig::loadNamesConfig () {
|
|||
continue;
|
||||
}
|
||||
// max botname is 32 characters
|
||||
if (line.length () > 32) {
|
||||
line[32] = kNullChar;
|
||||
if (line.length () > kMaxNameLen - 1) {
|
||||
line[kMaxNameLen - 1] = kNullChar;
|
||||
}
|
||||
m_botNames.emplace (line, -1);
|
||||
}
|
||||
|
|
@ -583,7 +585,7 @@ void BotConfig::loadDifficultyConfig () {
|
|||
diff->aimError.z = values[8].float_ ();
|
||||
};
|
||||
|
||||
// avatars initialization
|
||||
// difficulty initialization
|
||||
if (openConfig ("difficulty", "Difficulty config file not found. Loading defaults.", &file)) {
|
||||
|
||||
while (file.getLine (line)) {
|
||||
|
|
@ -706,20 +708,20 @@ BotName *BotConfig::pickBotName () {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < m_botNames.length () * 2; ++i) {
|
||||
auto botName = &m_botNames.random ();
|
||||
auto bn = &m_botNames.random ();
|
||||
|
||||
if (botName->name.length () < 3 || botName->usedBy != -1) {
|
||||
if (bn->name.length () < 3 || bn->usedBy != -1) {
|
||||
continue;
|
||||
}
|
||||
return botName;
|
||||
return bn;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BotConfig::clearUsedName (Bot *bot) {
|
||||
for (auto &name : m_botNames) {
|
||||
if (name.usedBy == bot->index ()) {
|
||||
name.usedBy = -1;
|
||||
for (auto &bn : m_botNames) {
|
||||
if (bn.usedBy == bot->index ()) {
|
||||
bn.usedBy = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ int BotControl::cmdCvars () {
|
|||
|
||||
if (isSave) {
|
||||
if (!cfg) {
|
||||
msg ("Unable to write cvars to config file. File not accesssible");
|
||||
msg ("Unable to write cvars to config file. File not accessible");
|
||||
return BotCommandResult::Handled;
|
||||
}
|
||||
msg ("Bots cvars has been written to file.");
|
||||
|
|
@ -368,6 +368,7 @@ int BotControl::cmdNode () {
|
|||
addGraphCmd ("path_create_jump", "path_create_jump [noarguments]", "Creates jumping path connection from nearest to faced node.", &BotControl::cmdNodePathCreate);
|
||||
addGraphCmd ("path_delete", "path_delete [noarguments]", "Deletes path from nearest to faced node.", &BotControl::cmdNodePathDelete);
|
||||
addGraphCmd ("path_set_autopath", "path_set_autopath [max_distance]", "Opens menu for setting autopath maximum distance.", &BotControl::cmdNodePathSetAutoDistance);
|
||||
addGraphCmd ("path_clean", "path_clean [index]", "Clean's up all types of connections from the node.", &BotControl::cmdNodePathCleanAll);
|
||||
|
||||
// camp points iterator
|
||||
addGraphCmd ("iterate_camp", "iterate_camp [begin|end|next]", "Allows to go through all camp points on map.", &BotControl::cmdNodeIterateCamp);
|
||||
|
|
@ -756,6 +757,19 @@ int BotControl::cmdNodePathSetAutoDistance () {
|
|||
return BotCommandResult::Handled;
|
||||
}
|
||||
|
||||
int BotControl::cmdNodePathCleanAll () {
|
||||
enum args { graph_cmd = 1, cmd, index };
|
||||
|
||||
auto requestedNode = kInvalidNodeIndex;
|
||||
|
||||
if (hasArg (index)) {
|
||||
requestedNode = intValue (index);
|
||||
}
|
||||
graph.resetPath (requestedNode);
|
||||
|
||||
return BotCommandResult::Handled;
|
||||
}
|
||||
|
||||
int BotControl::cmdNodeAcquireEditor () {
|
||||
enum args { graph_cmd = 1 };
|
||||
|
||||
|
|
|
|||
|
|
@ -803,7 +803,7 @@ bool Game::loadCSBinary () {
|
|||
|
||||
// search the libraries inside game dlls directory
|
||||
for (const auto &lib : libs) {
|
||||
auto path = strings.joinPath (modname, "dlls", lib) + DLL_SUFFIX;
|
||||
auto path = strings.joinPath (modname, "dlls", lib) + kLibrarySuffix;
|
||||
|
||||
// if we can't read file, skip it
|
||||
if (!plat.fileExists (path.chars ())) {
|
||||
|
|
@ -1136,7 +1136,7 @@ void LightMeasure::initializeLightstyles () {
|
|||
// reset all light styles
|
||||
for (auto &ls : m_lightstyle) {
|
||||
ls.length = 0;
|
||||
ls.map[0] = 0;
|
||||
ls.map[0] = kNullChar;
|
||||
}
|
||||
|
||||
for (auto &lsv : m_lightstyleValue) {
|
||||
|
|
@ -1226,7 +1226,7 @@ template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const
|
|||
if (surf->flags & SURF_DRAWTILED) {
|
||||
continue; // no lightmaps
|
||||
}
|
||||
auto tex = surf->texinfo;
|
||||
const auto tex = surf->texinfo;
|
||||
|
||||
// see where in lightmap space our intersection point is
|
||||
const int s = static_cast <int> ((mid | Vector (tex->vecs[0])) + tex->vecs[0][3]);
|
||||
|
|
|
|||
|
|
@ -1135,6 +1135,45 @@ void BotGraph::erasePath () {
|
|||
msg ("There is already no path on this node.");
|
||||
}
|
||||
|
||||
void BotGraph::resetPath (int index) {
|
||||
int node = index;
|
||||
|
||||
if (!exists (node)) {
|
||||
node = getEditorNearest ();
|
||||
|
||||
if (!exists (node)) {
|
||||
msg ("Unable to find nearest node in 50 units.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// helper
|
||||
auto destroy = [] (PathLink &link) -> void {
|
||||
link.index = kInvalidNodeIndex;
|
||||
link.distance = 0;
|
||||
link.flags = 0;
|
||||
link.velocity = nullptr;
|
||||
};
|
||||
|
||||
// clean all incoming
|
||||
for (auto &connected : m_paths) {
|
||||
for (auto &link : connected.links) {
|
||||
if (link.index == node) {
|
||||
destroy (link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean all outgoing connections
|
||||
for (auto &link : m_paths[node].links) {
|
||||
destroy (link);
|
||||
}
|
||||
emitNotify (NotifySound::Change);
|
||||
|
||||
// notify use something evil happened
|
||||
msg ("All paths for node #%d has been reset.", node);
|
||||
}
|
||||
|
||||
void BotGraph::cachePoint (int index) {
|
||||
const int node = exists (index) ? index : getEditorNearest ();
|
||||
|
||||
|
|
@ -1579,7 +1618,7 @@ bool BotGraph::loadGraphData () {
|
|||
reset ();
|
||||
|
||||
// check if loaded
|
||||
bool dataLoaded = bstor.load <Path> (m_paths, &exten, &outOptions);
|
||||
const bool dataLoaded = bstor.load <Path> (m_paths, &exten, &outOptions);
|
||||
|
||||
if (dataLoaded) {
|
||||
initBuckets ();
|
||||
|
|
@ -1898,7 +1937,7 @@ void BotGraph::frame () {
|
|||
for (auto &path : m_paths) {
|
||||
const float distanceSq = path.origin.distanceSq (m_editor->v.origin);
|
||||
|
||||
// check if node is whitin a distance, and is visible
|
||||
// check if node is within a distance, and is visible
|
||||
if (distanceSq < cr::sqrf (cv_graph_draw_distance.float_ ()) && ((util.isVisible (path.origin, m_editor) && util.isInViewCone (path.origin, m_editor)) || !util.isAlive (m_editor) || distanceSq < cr::sqrf (64.0f))) {
|
||||
// check the distance
|
||||
if (distanceSq < nearestDistanceSq) {
|
||||
|
|
@ -2128,7 +2167,7 @@ void BotGraph::frame () {
|
|||
};
|
||||
|
||||
// very helpful stuff..
|
||||
auto getNodeData = [&] (StringRef type, int node) -> String {
|
||||
auto getNodeData = [this] (StringRef type, int node) -> String {
|
||||
String message, flags;
|
||||
|
||||
const auto &p = m_paths[node];
|
||||
|
|
|
|||
|
|
@ -992,7 +992,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) {
|
|||
// this function does core operation of creating bot, it's called by addbot (),
|
||||
// when bot setup completed, (this is a bot class constructor)
|
||||
|
||||
int clientIndex = game.indexOfEntity (bot);
|
||||
const int clientIndex = game.indexOfEntity (bot);
|
||||
pev = &bot->v;
|
||||
|
||||
if (bot->pvPrivateData != nullptr) {
|
||||
|
|
@ -1176,25 +1176,25 @@ int BotManager::getAliveHumansCount () {
|
|||
}
|
||||
|
||||
int BotManager::getPlayerPriority (edict_t *ent) {
|
||||
constexpr auto highPrio = 512;
|
||||
constexpr auto kHighPriority = 512;
|
||||
|
||||
// always check for only our own bots
|
||||
auto bot = bots[ent];
|
||||
|
||||
// if player just return high prio
|
||||
if (!bot) {
|
||||
return game.indexOfEntity (ent) + highPrio;
|
||||
return game.indexOfEntity (ent) + kHighPriority;
|
||||
}
|
||||
|
||||
// give bots some priority
|
||||
if (bot->m_hasC4 || bot->m_isVIP || bot->m_hasHostage || bot->m_healthValue < ent->v.health) {
|
||||
return bot->entindex () + highPrio;
|
||||
return bot->entindex () + kHighPriority;
|
||||
}
|
||||
auto task = bot->getCurrentTaskId ();
|
||||
|
||||
// higher priority if camping or hiding
|
||||
if (task == Task::Camp || task == Task::Hide) {
|
||||
return bot->entindex () + highPrio;
|
||||
return bot->entindex () + kHighPriority;
|
||||
}
|
||||
return bot->entindex ();
|
||||
}
|
||||
|
|
@ -1229,7 +1229,7 @@ void BotManager::erase (Bot *bot) {
|
|||
}
|
||||
bot->markStale ();
|
||||
|
||||
auto index = m_bots.index (e);
|
||||
const auto index = m_bots.index (e);
|
||||
e.reset ();
|
||||
|
||||
m_bots.erase (index, 1); // remove from bots array
|
||||
|
|
@ -1291,6 +1291,7 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
|
|||
if (victimBot != nullptr) {
|
||||
if (killerTeam == victimBot->m_team) {
|
||||
victimBot->m_voteKickIndex = game.indexOfEntity (killer);
|
||||
|
||||
for (const auto ¬ify : bots) {
|
||||
if (notify->seesEntity (victim->v.origin)) {
|
||||
notify->pushChatterMessage (Chatter::TeamKill);
|
||||
|
|
@ -1502,6 +1503,9 @@ void Bot::newRound () {
|
|||
m_goalHist.clear ();
|
||||
m_ignoredBreakable.clear ();
|
||||
|
||||
// update refvec for blocked movement
|
||||
updateRightRef ();
|
||||
|
||||
// and put buying into its message queue
|
||||
pushMsgQueue (BotMsg::Buy);
|
||||
startTask (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
|
||||
|
|
@ -1618,7 +1622,7 @@ void Bot::updateTeamJoin () {
|
|||
m_startAction = BotMsg::TeamSelect;
|
||||
}
|
||||
|
||||
// if bot was unable to join team, and no menus popups, check for stacked team
|
||||
// if bot was unable to join team, and no menus pop-ups, check for stacked team
|
||||
if (m_startAction == BotMsg::None) {
|
||||
if (++m_retryJoin > 3 && bots.isTeamStacked (m_wantedTeam - 1)) {
|
||||
m_retryJoin = 0;
|
||||
|
|
@ -1710,7 +1714,7 @@ void BotManager::captureChatRadio (StringRef cmd, StringRef arg, edict_t *ent) {
|
|||
}
|
||||
|
||||
if (cmd.startsWith ("say")) {
|
||||
const bool alive = util.isAlive (ent);
|
||||
const bool alive = util.isAlive (ent);
|
||||
int team = -1;
|
||||
|
||||
if (cmd == "say_team") {
|
||||
|
|
@ -1768,7 +1772,7 @@ void BotManager::notifyBombDefuse () {
|
|||
const auto &bombPos = graph.getBombOrigin ();
|
||||
|
||||
for (const auto &bot : bots) {
|
||||
auto task = bot->getCurrentTaskId ();
|
||||
const auto task = bot->getCurrentTaskId ();
|
||||
|
||||
if (!bot->m_defuseNotified && bot->m_notKilled && task != Task::MoveToPosition && task != Task::DefuseBomb && task != Task::EscapeFromBomb) {
|
||||
if (bot->m_team == Team::Terrorist && bot->pev->origin.distanceSq (bombPos) < cr::sqrf (384.0f)) {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ void MessageDispatcher::netMsgVGUIMenu () {
|
|||
|
||||
enum args { menu = 0, min = 1 };
|
||||
|
||||
// check the minimum states or existance of bot
|
||||
// check the minimum states or existence of bot
|
||||
if (m_args.length () < min || !m_bot) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ void MessageDispatcher::netMsgShowMenu () {
|
|||
|
||||
enum args { menu = 3, min = 4 };
|
||||
|
||||
// check the minimum states or existance of bot
|
||||
// check the minimum states or existence of bot
|
||||
if (m_args.length () < min || !m_bot) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -144,7 +144,7 @@ void MessageDispatcher::netMsgWeaponList () {
|
|||
}
|
||||
|
||||
void MessageDispatcher::netMsgCurWeapon () {
|
||||
// this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased
|
||||
// this message is sent when a weapon is selected (either by the bot choosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased
|
||||
|
||||
enum args { state = 0, id = 1, clip = 2, min = 3 };
|
||||
|
||||
|
|
@ -524,7 +524,7 @@ void MessageDispatcher::start (edict_t *ent, int32_t type) {
|
|||
m_current = m_handlers[msg] ? msg : NetMsg::None;
|
||||
}
|
||||
|
||||
// no messagem no processing
|
||||
// no message no processing
|
||||
if (m_current == NetMsg::None) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -571,6 +571,6 @@ int32_t MessageDispatcher::id (NetMsg msg) {
|
|||
Bot *MessageDispatcher::pickBot (int32_t index) {
|
||||
const auto &client = util.getClient (m_args[index].long_ - 1);
|
||||
|
||||
// get the bot in this msg
|
||||
// get the bot in this message
|
||||
return bots[client.ent];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -661,7 +661,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
|||
}
|
||||
|
||||
if (seesEntity (m_destOrigin)) {
|
||||
auto right = m_moveAngles.right ();
|
||||
const auto &right = m_moveAngles.right ();
|
||||
|
||||
src = getEyesPos ();
|
||||
src = src + right * 15.0f;
|
||||
|
|
@ -910,7 +910,7 @@ bool Bot::updateNavigation () {
|
|||
if (feet.z > pev->origin.z) {
|
||||
feet = pev->origin + pev->maxs;
|
||||
}
|
||||
feet = { pev->origin.x, pev->origin.y, feet.z };
|
||||
feet = { pev->origin.x, pev->origin.y, feet.z };
|
||||
|
||||
// calculate like we do with grenades
|
||||
auto velocity = calcThrow (feet, node);
|
||||
|
|
@ -947,11 +947,10 @@ bool Bot::updateNavigation () {
|
|||
selectBestWeapon ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((m_pathFlags & NodeFlag::Ladder) || isOnLadder ()) {
|
||||
constexpr auto kLadderOffset = Vector (0.0f, 0.0f, 16.0f);
|
||||
|
||||
if (m_pathOrigin.z >= (pev->origin.z + 16.0f)) {
|
||||
constexpr auto kLadderOffset = Vector (0.0f, 0.0f, 16.0f);
|
||||
m_pathOrigin = m_path->origin + kLadderOffset;
|
||||
}
|
||||
else if (m_pathOrigin.z < pev->origin.z + 16.0f && !isOnLadder () && isOnFloor () && !(pev->flags & FL_DUCKING)) {
|
||||
|
|
@ -1059,7 +1058,7 @@ bool Bot::updateNavigation () {
|
|||
ignoreCollision (); // don't consider being stuck
|
||||
|
||||
if (rg.chance (50)) {
|
||||
// do not use door directrly under xash, or we will get failed assert in gamedll code
|
||||
// do not use door directly under xash, or we will get failed assert in gamedll code
|
||||
if (game.is (GameFlags::Xash3D)) {
|
||||
pev->button |= IN_USE;
|
||||
}
|
||||
|
|
@ -1357,7 +1356,7 @@ bool Bot::updateLiftHandling () {
|
|||
|
||||
// bot is trying to find button inside a lift
|
||||
if (m_liftState == LiftState::LookingButtonInside) {
|
||||
auto button = lookupButton (m_liftEntity->v.targetname.chars ());
|
||||
auto button = lookupButton (m_liftEntity->v.targetname.str ());
|
||||
|
||||
// got a valid button entity ?
|
||||
if (!game.isNullEntity (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0f < game.time () && cr::fzero (m_liftEntity->v.velocity.z) && isOnFloor ()) {
|
||||
|
|
@ -1406,7 +1405,7 @@ bool Bot::updateLiftHandling () {
|
|||
}
|
||||
}
|
||||
else if (!game.isNullEntity (m_liftEntity)) {
|
||||
auto button = lookupButton (m_liftEntity->v.targetname.chars ());
|
||||
auto button = lookupButton (m_liftEntity->v.targetname.str ());
|
||||
|
||||
// if we got a valid button entity
|
||||
if (!game.isNullEntity (button)) {
|
||||
|
|
@ -1702,18 +1701,18 @@ void Bot::findValidNode () {
|
|||
findNextBestNode ();
|
||||
}
|
||||
else if (m_navTimeset + getEstimatedNodeReachTime () < game.time ()) {
|
||||
constexpr int maxDamageValue = PracticeLimit::Damage;
|
||||
constexpr int kMaxDamageValue = PracticeLimit::Damage;
|
||||
|
||||
// increase danger for both teams
|
||||
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
||||
int damageValue = practice.getDamage (team, m_currentNodeIndex, m_currentNodeIndex);
|
||||
damageValue = cr::clamp (damageValue + 100, 0, maxDamageValue);
|
||||
damageValue = cr::clamp (damageValue + 100, 0, kMaxDamageValue);
|
||||
|
||||
// affect nearby connected with victim nodes
|
||||
for (auto &neighbour : m_path->links) {
|
||||
if (graph.exists (neighbour.index)) {
|
||||
int neighbourValue = practice.getDamage (team, neighbour.index, neighbour.index);
|
||||
neighbourValue = cr::clamp (neighbourValue + 100, 0, maxDamageValue);
|
||||
neighbourValue = cr::clamp (neighbourValue + 100, 0, kMaxDamageValue);
|
||||
|
||||
practice.setDamage (m_team, neighbour.index, neighbour.index, neighbourValue);
|
||||
}
|
||||
|
|
@ -2062,8 +2061,8 @@ int Bot::findCoverNode (float maxDistance) {
|
|||
}
|
||||
|
||||
// use the 'real' pathfinding distances
|
||||
float distance = planner.dist (srcIndex, path.number);
|
||||
float enemyDistance = planner.dist (enemyIndex, path.number);
|
||||
const float distance = planner.dist (srcIndex, path.number);
|
||||
const float enemyDistance = planner.dist (enemyIndex, path.number);
|
||||
|
||||
if (distance >= enemyDistance) {
|
||||
continue;
|
||||
|
|
@ -2408,6 +2407,10 @@ void Bot::setPathOrigin () {
|
|||
}
|
||||
}
|
||||
|
||||
void Bot::updateRightRef () {
|
||||
m_rightRef = Vector { 0.0f, pev->angles.y, 0.0f }.right (); // convert current view angle to vectors for traceline math...
|
||||
}
|
||||
|
||||
bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
|
||||
// checks if bot is blocked in his movement direction (excluding doors)
|
||||
|
||||
|
|
@ -2416,7 +2419,6 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
|
|||
// first do a trace from the bot's eyes forward...
|
||||
auto src = getEyesPos ();
|
||||
auto forward = src + normal * 24.0f;
|
||||
auto right = Vector (0.0f, pev->angles.y, 0.0f).right ();
|
||||
|
||||
auto checkDoor = [] (TraceResult *result) {
|
||||
if (!game.mapIs (MapFlags::HasDoors)) {
|
||||
|
|
@ -2437,10 +2439,13 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
|
|||
}
|
||||
constexpr auto kVec00N16 = Vector (0.0f, 0.0f, -16.0f);
|
||||
|
||||
// right referential vector
|
||||
updateRightRef ();
|
||||
|
||||
// bot's head is clear, check at shoulder level...
|
||||
// trace from the bot's shoulder left diagonal forward to the right shoulder...
|
||||
src = getEyesPos () + kVec00N16 - right * -16.0f;
|
||||
forward = getEyesPos () + kVec00N16 + right * 16.0f + normal * 24.0f;
|
||||
src = getEyesPos () + kVec00N16 - m_rightRef * -16.0f;
|
||||
forward = getEyesPos () + kVec00N16 + m_rightRef * 16.0f + normal * 24.0f;
|
||||
|
||||
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
|
||||
|
||||
|
|
@ -2451,8 +2456,8 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
|
|||
|
||||
// bot's head is clear, check at shoulder level...
|
||||
// trace from the bot's shoulder right diagonal forward to the left shoulder...
|
||||
src = getEyesPos () + kVec00N16 + right * 16.0f;
|
||||
forward = getEyesPos () + kVec00N16 - right * -16.0f + normal * 24.0f;
|
||||
src = getEyesPos () + kVec00N16 + m_rightRef * 16.0f;
|
||||
forward = getEyesPos () + kVec00N16 - m_rightRef * -16.0f + normal * 24.0f;
|
||||
|
||||
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
|
||||
|
||||
|
|
@ -2487,8 +2492,8 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
|
|||
constexpr auto kVec00N24 = Vector (0.0f, 0.0f, -24.0f);
|
||||
|
||||
// trace from the left waist to the right forward waist pos
|
||||
src = pev->origin + kVec00N17 - right * -16.0f;
|
||||
forward = pev->origin + kVec00N17 + right * 16.0f + normal * 24.0f;
|
||||
src = pev->origin + kVec00N17 - m_rightRef * -16.0f;
|
||||
forward = pev->origin + kVec00N17 + m_rightRef * 16.0f + normal * 24.0f;
|
||||
|
||||
// trace from the bot's waist straight forward...
|
||||
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
|
||||
|
|
@ -2499,8 +2504,8 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
|
|||
}
|
||||
|
||||
// trace from the left waist to the right forward waist pos
|
||||
src = pev->origin + kVec00N24 + right * 16.0f;
|
||||
forward = pev->origin + kVec00N24 - right * -16.0f + normal * 24.0f;
|
||||
src = pev->origin + kVec00N24 + m_rightRef * 16.0f;
|
||||
forward = pev->origin + kVec00N24 - m_rightRef * -16.0f + normal * 24.0f;
|
||||
|
||||
game.testLine (src, forward, TraceIgnore::Monsters, ent (), tr);
|
||||
|
||||
|
|
@ -2580,7 +2585,7 @@ bool Bot::canJumpUp (const Vector &normal) {
|
|||
if (!isOnFloor () && (isOnLadder () || !isInWater ())) {
|
||||
return false;
|
||||
}
|
||||
auto right = Vector (0.0f, pev->angles.y, 0.0f).right (); // convert current view angle to vectors for traceline math...
|
||||
updateRightRef ();
|
||||
|
||||
// check for normal jump height first...
|
||||
auto src = pev->origin + Vector (0.0f, 0.0f, -36.0f + 45.0f);
|
||||
|
|
@ -2590,7 +2595,7 @@ bool Bot::canJumpUp (const Vector &normal) {
|
|||
game.testLine (src, dest, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
if (tr.flFraction < 1.0f) {
|
||||
return doneCanJumpUp (normal, right);
|
||||
return doneCanJumpUp (normal, m_rightRef);
|
||||
}
|
||||
else {
|
||||
// now trace from jump height upward to check for obstructions...
|
||||
|
|
@ -2605,7 +2610,7 @@ bool Bot::canJumpUp (const Vector &normal) {
|
|||
}
|
||||
|
||||
// now check same height to one side of the bot...
|
||||
src = pev->origin + right * 16.0f + Vector (0.0f, 0.0f, -36.0f + 45.0f);
|
||||
src = pev->origin + m_rightRef * 16.0f + Vector (0.0f, 0.0f, -36.0f + 45.0f);
|
||||
dest = src + normal * 32.0f;
|
||||
|
||||
// trace a line forward at maximum jump height...
|
||||
|
|
@ -2613,7 +2618,7 @@ bool Bot::canJumpUp (const Vector &normal) {
|
|||
|
||||
// if trace hit something, return false
|
||||
if (tr.flFraction < 1.0f) {
|
||||
return doneCanJumpUp (normal, right);
|
||||
return doneCanJumpUp (normal, m_rightRef);
|
||||
}
|
||||
|
||||
// now trace from jump height upward to check for obstructions...
|
||||
|
|
@ -2628,7 +2633,7 @@ bool Bot::canJumpUp (const Vector &normal) {
|
|||
}
|
||||
|
||||
// now check same height on the other side of the bot...
|
||||
src = pev->origin + (-right * 16.0f) + Vector (0.0f, 0.0f, -36.0f + 45.0f);
|
||||
src = pev->origin + (-m_rightRef * 16.0f) + Vector (0.0f, 0.0f, -36.0f + 45.0f);
|
||||
dest = src + normal * 32.0f;
|
||||
|
||||
// trace a line forward at maximum jump height...
|
||||
|
|
@ -2636,7 +2641,7 @@ bool Bot::canJumpUp (const Vector &normal) {
|
|||
|
||||
// if trace hit something, return false
|
||||
if (tr.flFraction < 1.0f) {
|
||||
return doneCanJumpUp (normal, right);
|
||||
return doneCanJumpUp (normal, m_rightRef);
|
||||
}
|
||||
|
||||
// now trace from jump height upward to check for obstructions...
|
||||
|
|
@ -2744,12 +2749,10 @@ bool Bot::canDuckUnder (const Vector &normal) {
|
|||
if (tr.flFraction < 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert current view angle to vectors for TraceLine math...
|
||||
auto right = Vector (0.0f, pev->angles.y, 0.0f).right ();
|
||||
updateRightRef ();
|
||||
|
||||
// now check same height to one side of the bot...
|
||||
src = baseHeight + right * 16.0f;
|
||||
src = baseHeight + m_rightRef * 16.0f;
|
||||
dest = src + normal * 32.0f;
|
||||
|
||||
// trace a line forward at duck height...
|
||||
|
|
@ -2761,7 +2764,7 @@ bool Bot::canDuckUnder (const Vector &normal) {
|
|||
}
|
||||
|
||||
// now check same height on the other side of the bot...
|
||||
src = baseHeight + (-right * 16.0f);
|
||||
src = baseHeight + (-m_rightRef * 16.0f);
|
||||
dest = src + normal * 32.0f;
|
||||
|
||||
// trace a line forward at duck height...
|
||||
|
|
@ -3057,11 +3060,11 @@ bool Bot::isOccupiedNode (int index, bool needZeroVelocity) {
|
|||
return false;
|
||||
}
|
||||
|
||||
edict_t *Bot::lookupButton (const char *target) {
|
||||
edict_t *Bot::lookupButton (StringRef target) {
|
||||
// this function tries to find nearest to current bot button, and returns pointer to
|
||||
// it's entity, also here must be specified the target, that button must open.
|
||||
|
||||
if (strings.isEmpty (target)) {
|
||||
if (target.empty ()) {
|
||||
return nullptr;
|
||||
}
|
||||
float nearestDistanceSq = kInfiniteDistance;
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ bool FloydWarshallAlgo::load () {
|
|||
if (!m_length) {
|
||||
return false;
|
||||
}
|
||||
bool dataLoaded = bstor.load <Matrix> (m_matrix);
|
||||
const bool dataLoaded = bstor.load <Matrix> (m_matrix);
|
||||
|
||||
// do not rebuild if loaded
|
||||
if (dataLoaded) {
|
||||
|
|
@ -451,7 +451,7 @@ bool DijkstraAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, i
|
|||
|
||||
for (const auto &link : graph[current].links) {
|
||||
if (link.index != kInvalidNodeIndex) {
|
||||
auto dlink = m_distance[current] + link.distance;
|
||||
const auto dlink = m_distance[current] + link.distance;
|
||||
|
||||
if (dlink < m_distance[link.index]) {
|
||||
m_distance[link.index] = dlink;
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ void BotPractice::load () {
|
|||
SmallArray <DangerSaveRestore> data;
|
||||
m_data.clear ();
|
||||
|
||||
bool dataLoaded = bstor.load <DangerSaveRestore> (data);
|
||||
const bool dataLoaded = bstor.load <DangerSaveRestore> (data);
|
||||
|
||||
// copy back to hash table
|
||||
if (dataLoaded) {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ template <typename U> bool BotStorage::save (const SmallArray <U> &data, ExtenHe
|
|||
SmallArray <uint8_t> compressed (rawLength + sizeof (uint8_t) * ULZ::Excess);
|
||||
|
||||
// try to compress
|
||||
auto compressedLength = static_cast <size_t> (ulz.compress (reinterpret_cast <uint8_t *> (data.data ()), static_cast <int32_t> (rawLength), reinterpret_cast <uint8_t *> (compressed.data ())));
|
||||
const auto compressedLength = static_cast <size_t> (ulz.compress (reinterpret_cast <uint8_t *> (data.data ()), static_cast <int32_t> (rawLength), reinterpret_cast <uint8_t *> (compressed.data ())));
|
||||
|
||||
if (compressedLength > 0) {
|
||||
StorageHeader hdr {};
|
||||
|
|
@ -349,7 +349,7 @@ String BotStorage::buildPath (int32_t file, bool isMemoryLoad) {
|
|||
}
|
||||
|
||||
// finally use correct path separators for us
|
||||
return String::join (path, PATH_SEP);
|
||||
return String::join (path, kPathSeparator);
|
||||
}
|
||||
|
||||
int32_t BotStorage::storageToBotFile (int32_t options) {
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ bool BotSupport::isDoorEntity (edict_t *ent) {
|
|||
if (game.isNullEntity (ent)) {
|
||||
return false;
|
||||
}
|
||||
return ent->v.classname.str ().startsWith ("func_door");;
|
||||
return ent->v.classname.str ().startsWith ("func_door");
|
||||
}
|
||||
|
||||
bool BotSupport::isHostageEntity (edict_t *ent) {
|
||||
|
|
|
|||
|
|
@ -1097,7 +1097,7 @@ void Bot::throwExplosive_ () {
|
|||
else {
|
||||
m_aimFlags |= AimFlags::Grenade;
|
||||
|
||||
auto grenade = setCorrectGrenadeVelocity ("hegrenade.mdl");
|
||||
auto grenade = setCorrectGrenadeVelocity (kExplosiveModelName);
|
||||
|
||||
if (game.isNullEntity (grenade)) {
|
||||
if (m_currentWeapon != Weapon::Explosive && !m_grenadeRequested) {
|
||||
|
|
@ -1163,7 +1163,7 @@ void Bot::throwFlashbang_ () {
|
|||
else {
|
||||
m_aimFlags |= AimFlags::Grenade;
|
||||
|
||||
auto grenade = setCorrectGrenadeVelocity ("flashbang.mdl");
|
||||
auto grenade = setCorrectGrenadeVelocity (kFlashbangModelName);
|
||||
|
||||
if (game.isNullEntity (grenade)) {
|
||||
if (m_currentWeapon != Weapon::Flashbang && !m_grenadeRequested) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue