fix: problems with breakable on cs_mari (ref #686)
fix: goal selection on some zombie maps (ref #684)
This commit is contained in:
parent
aeff9f8d46
commit
d6d76e136d
12 changed files with 95 additions and 86 deletions
|
|
@ -2651,7 +2651,7 @@ Weapon configuration file not found. Loading defaults.
|
||||||
未找到武器配置文件。加载默认值。
|
未找到武器配置文件。加载默认值。
|
||||||
|
|
||||||
[ORIGINAL]
|
[ORIGINAL]
|
||||||
Couldn't open chatter system configuration
|
Couldn't open chatter configuration.
|
||||||
|
|
||||||
[TRANSLATED]
|
[TRANSLATED]
|
||||||
无法打开聊天系统配置
|
无法打开聊天系统配置
|
||||||
|
|
@ -2669,7 +2669,7 @@ Bots chatter communication disabled.
|
||||||
已禁用人机聊天通信。
|
已禁用人机聊天通信。
|
||||||
|
|
||||||
[ORIGINAL]
|
[ORIGINAL]
|
||||||
Chat file not found.
|
Couldn't open chat configuration.
|
||||||
|
|
||||||
[TRANSLATED]
|
[TRANSLATED]
|
||||||
未找到聊天文件。
|
未找到聊天文件。
|
||||||
|
|
@ -2687,7 +2687,7 @@ Specified language not found.
|
||||||
未找到指定语言。
|
未找到指定语言。
|
||||||
|
|
||||||
[ORIGINAL]
|
[ORIGINAL]
|
||||||
Couldn't load language configuration
|
Couldn't load language configuration.
|
||||||
|
|
||||||
[TRANSLATED]
|
[TRANSLATED]
|
||||||
无法加载语言配置
|
无法加载语言配置
|
||||||
|
|
|
||||||
|
|
@ -2650,10 +2650,10 @@ Weapon configuration file not found. Loading defaults.
|
||||||
Оружейный конфигурационный файл не найден. Загружаем стандартные значения.
|
Оружейный конфигурационный файл не найден. Загружаем стандартные значения.
|
||||||
|
|
||||||
[ORIGINAL]
|
[ORIGINAL]
|
||||||
Couldn't open chatter system configuration
|
Couldn't open chat configuration.
|
||||||
|
|
||||||
[TRANSLATED]
|
[TRANSLATED]
|
||||||
Не удалось открыть конфигурацию системы переговоров
|
Не удалось открыть конфигурацию переговоров.
|
||||||
|
|
||||||
[ORIGINAL]
|
[ORIGINAL]
|
||||||
Error in chatter config file syntax... Please correct all errors.
|
Error in chatter config file syntax... Please correct all errors.
|
||||||
|
|
@ -2686,7 +2686,7 @@ Specified language not found.
|
||||||
Указанный язык не найден.
|
Указанный язык не найден.
|
||||||
|
|
||||||
[ORIGINAL]
|
[ORIGINAL]
|
||||||
Couldn't load language configuration
|
Couldn't load language configuration.
|
||||||
|
|
||||||
[TRANSLATED]
|
[TRANSLATED]
|
||||||
Не удалось загрузить языковую конфигурацию
|
Не удалось загрузить языковую конфигурацию
|
||||||
|
|
|
||||||
21
inc/graph.h
21
inc/graph.h
|
|
@ -223,11 +223,11 @@ public:
|
||||||
bool isNodeReacheableWithJump (const Vector &src, const Vector &destination);
|
bool isNodeReacheableWithJump (const Vector &src, const Vector &destination);
|
||||||
bool checkNodes (bool teleportPlayer, bool onlyPaths = false);
|
bool checkNodes (bool teleportPlayer, bool onlyPaths = false);
|
||||||
bool isVisited (int index);
|
bool isVisited (int index);
|
||||||
bool isAnalyzed () const;
|
|
||||||
|
|
||||||
bool saveGraphData ();
|
bool saveGraphData ();
|
||||||
bool loadGraphData ();
|
bool loadGraphData ();
|
||||||
bool canDownload ();
|
bool canDownload ();
|
||||||
|
bool isAnalyzed () const;
|
||||||
|
|
||||||
void saveOldFormat ();
|
void saveOldFormat ();
|
||||||
void reset ();
|
void reset ();
|
||||||
|
|
@ -251,8 +251,7 @@ public:
|
||||||
void startLearnJump ();
|
void startLearnJump ();
|
||||||
void setVisited (int index);
|
void setVisited (int index);
|
||||||
void clearVisited ();
|
void clearVisited ();
|
||||||
void initBuckets ();
|
|
||||||
void addToBucket (const Vector &pos, int index);
|
|
||||||
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);
|
||||||
|
|
@ -267,7 +266,6 @@ public:
|
||||||
void collectOnline ();
|
void collectOnline ();
|
||||||
|
|
||||||
IntArray getNearestInRadius (float radius, const Vector &origin, int maxCount = -1);
|
IntArray getNearestInRadius (float radius, const Vector &origin, int maxCount = -1);
|
||||||
const IntArray &getNodesInBucket (const Vector &pos);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StringRef getAuthor () const {
|
StringRef getAuthor () const {
|
||||||
|
|
@ -353,6 +351,21 @@ public:
|
||||||
return m_nodeNumbers;
|
return m_nodeNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reinitialize buckets
|
||||||
|
void initBuckets () {
|
||||||
|
m_hashTable.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the bucket of nodes near position
|
||||||
|
const IntArray &getNodesInBucket (const Vector &pos) {
|
||||||
|
return m_hashTable[locateBucket (pos)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a node to position bucket
|
||||||
|
void addToBucket (const Vector &pos, int index) {
|
||||||
|
m_hashTable[locateBucket (pos)].emplace (index);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// graph helper for sending message to correct channel
|
// graph helper for sending message to correct channel
|
||||||
template <typename ...Args> void msg (const char *fmt, Args &&...args);
|
template <typename ...Args> void msg (const char *fmt, Args &&...args);
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset () {
|
void reset () {
|
||||||
m_current = NetMsg::None;
|
stopCollection ();
|
||||||
m_bot = nullptr;
|
m_bot = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -520,6 +520,7 @@ private:
|
||||||
void updateRightRef ();
|
void updateRightRef ();
|
||||||
void donateC4ToHuman ();
|
void donateC4ToHuman ();
|
||||||
void clearAmmoInfo ();
|
void clearAmmoInfo ();
|
||||||
|
void handleChatterTaskChange (Task tid);
|
||||||
|
|
||||||
void completeTask ();
|
void completeTask ();
|
||||||
void executeTasks ();
|
void executeTasks ();
|
||||||
|
|
|
||||||
|
|
@ -2146,6 +2146,7 @@ void Bot::filterTasks () {
|
||||||
// zombie bots has more hunt desire
|
// zombie bots has more hunt desire
|
||||||
if (m_isCreature && huntEnemyDesire > 16.0f) {
|
if (m_isCreature && huntEnemyDesire > 16.0f) {
|
||||||
huntEnemyDesire = TaskPri::Attack;
|
huntEnemyDesire = TaskPri::Attack;
|
||||||
|
seekCoverDesire = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// blinded behavior
|
// blinded behavior
|
||||||
|
|
@ -2250,37 +2251,9 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
|
||||||
selectBestWeapon ();
|
selectBestWeapon ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is best place to handle some voice commands report team some info
|
// this is best place to handle some chatter commands report team some info
|
||||||
if (cv_radio_mode.as <int> () > 1) {
|
if (cv_radio_mode.as <int> () > 1) {
|
||||||
if (rg.chance (90)) {
|
handleChatterTaskChange (tid);
|
||||||
if (tid == Task::Blind) {
|
|
||||||
pushChatterMessage (Chatter::Blind);
|
|
||||||
}
|
|
||||||
else if (tid == Task::PlantBomb) {
|
|
||||||
pushChatterMessage (Chatter::PlantingBomb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rg.chance (25) && tid == Task::Camp) {
|
|
||||||
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted ()) {
|
|
||||||
pushChatterMessage (Chatter::GuardingPlantedC4);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pushChatterMessage (Chatter::GoingToCamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rg.chance (75) && tid == Task::Camp && m_team == Team::CT && m_inEscapeZone) {
|
|
||||||
pushChatterMessage (Chatter::GoingToGuardEscapeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inRescueZone) {
|
|
||||||
pushChatterMessage (Chatter::GoingToGuardRescueZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inVIPZone) {
|
|
||||||
pushChatterMessage (Chatter::GoingToGuardVIPSafety);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_debug_goal.as <int> () != kInvalidNodeIndex) {
|
if (cv_debug_goal.as <int> () != kInvalidNodeIndex) {
|
||||||
|
|
@ -2419,10 +2392,41 @@ bool Bot::lastEnemyShootable () {
|
||||||
return util.getConeDeviation (ent (), m_lastEnemyOrigin) >= 0.90f && isPenetrableObstacle (m_lastEnemyOrigin);
|
return util.getConeDeviation (ent (), m_lastEnemyOrigin) >= 0.90f && isPenetrableObstacle (m_lastEnemyOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bot::handleChatterTaskChange (Task tid) {
|
||||||
|
if (rg.chance (90)) {
|
||||||
|
if (tid == Task::Blind) {
|
||||||
|
pushChatterMessage (Chatter::Blind);
|
||||||
|
}
|
||||||
|
else if (tid == Task::PlantBomb) {
|
||||||
|
pushChatterMessage (Chatter::PlantingBomb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rg.chance (25) && tid == Task::Camp) {
|
||||||
|
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted ()) {
|
||||||
|
pushChatterMessage (Chatter::GuardingPlantedC4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pushChatterMessage (Chatter::GoingToCamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rg.chance (75) && tid == Task::Camp && m_team == Team::CT && m_inEscapeZone) {
|
||||||
|
pushChatterMessage (Chatter::GoingToGuardEscapeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inRescueZone) {
|
||||||
|
pushChatterMessage (Chatter::GoingToGuardRescueZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inVIPZone) {
|
||||||
|
pushChatterMessage (Chatter::GoingToGuardVIPSafety);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Bot::checkRadioQueue () {
|
void Bot::checkRadioQueue () {
|
||||||
// this function handling radio and reacting to it
|
// this function handling radio and reacting to it
|
||||||
|
|
||||||
|
|
||||||
// don't allow bot listen you if bot is busy
|
// don't allow bot listen you if bot is busy
|
||||||
if (m_radioOrder != Radio::ReportInTeam
|
if (m_radioOrder != Radio::ReportInTeam
|
||||||
&& (getCurrentTaskId () == Task::DefuseBomb
|
&& (getCurrentTaskId () == Task::DefuseBomb
|
||||||
|
|
|
||||||
|
|
@ -208,28 +208,29 @@ void BotConfig::loadWeaponsConfig () {
|
||||||
trim.trim ();
|
trim.trim ();
|
||||||
}
|
}
|
||||||
auto splitted = pair[1].split (",");
|
auto splitted = pair[1].split (",");
|
||||||
|
auto key = pair[0];
|
||||||
|
|
||||||
if (pair[0].startsWith ("MapStandard")) {
|
if (key.startsWith ("MapStandard")) {
|
||||||
addWeaponEntries (m_weapons, false, pair[0], splitted);
|
addWeaponEntries (m_weapons, false, key, splitted);
|
||||||
}
|
}
|
||||||
else if (pair[0].startsWith ("MapAS")) {
|
else if (key.startsWith ("MapAS")) {
|
||||||
addWeaponEntries (m_weapons, true, pair[0], splitted);
|
addWeaponEntries (m_weapons, true, key, splitted);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (pair[0].startsWith ("GrenadePercent")) {
|
else if (key.startsWith ("GrenadePercent")) {
|
||||||
addIntEntries (m_grenadeBuyPrecent, pair[0], splitted);
|
addIntEntries (m_grenadeBuyPrecent, key, splitted);
|
||||||
}
|
}
|
||||||
else if (pair[0].startsWith ("Economics")) {
|
else if (key.startsWith ("Economics")) {
|
||||||
addIntEntries (m_botBuyEconomyTable, pair[0], splitted);
|
addIntEntries (m_botBuyEconomyTable, key, splitted);
|
||||||
}
|
}
|
||||||
else if (pair[0].startsWith ("PersonalityNormal")) {
|
else if (key.startsWith ("PersonalityNormal")) {
|
||||||
addIntEntries (m_normalWeaponPrefs, pair[0], splitted);
|
addIntEntries (m_normalWeaponPrefs, key, splitted);
|
||||||
}
|
}
|
||||||
else if (pair[0].startsWith ("PersonalityRusher")) {
|
else if (key.startsWith ("PersonalityRusher")) {
|
||||||
addIntEntries (m_rusherWeaponPrefs, pair[0], splitted);
|
addIntEntries (m_rusherWeaponPrefs, key, splitted);
|
||||||
}
|
}
|
||||||
else if (pair[0].startsWith ("PersonalityCareful")) {
|
else if (key.startsWith ("PersonalityCareful")) {
|
||||||
addIntEntries (m_carefulWeaponPrefs, pair[0], splitted);
|
addIntEntries (m_carefulWeaponPrefs, key, splitted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.close ();
|
file.close ();
|
||||||
|
|
@ -244,7 +245,7 @@ void BotConfig::loadChatterConfig () {
|
||||||
|
|
||||||
// chatter initialization
|
// chatter initialization
|
||||||
if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.as <int> () == 2
|
if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.as <int> () == 2
|
||||||
&& openConfig ("chatter", "Couldn't open chatter system configuration", &file)) {
|
&& openConfig ("chatter", "Couldn't open chatter configuration.", &file)) {
|
||||||
|
|
||||||
m_chatter.clear ();
|
m_chatter.clear ();
|
||||||
|
|
||||||
|
|
@ -402,7 +403,7 @@ void BotConfig::loadChatConfig () {
|
||||||
MemFile file {};
|
MemFile file {};
|
||||||
|
|
||||||
// chat config initialization
|
// chat config initialization
|
||||||
if (openConfig ("chat", "Chat file not found.", &file, true)) {
|
if (openConfig ("chat", "Couldn't open chat configuration.", &file, true)) {
|
||||||
StringArray *chat = nullptr;
|
StringArray *chat = nullptr;
|
||||||
|
|
||||||
StringArray keywords {};
|
StringArray keywords {};
|
||||||
|
|
@ -549,7 +550,7 @@ void BotConfig::loadLanguageConfig () {
|
||||||
file.close ();
|
file.close ();
|
||||||
}
|
}
|
||||||
else if (cv_language.as <StringRef> () != "en") {
|
else if (cv_language.as <StringRef> () != "en") {
|
||||||
logger.error ("Couldn't load language configuration");
|
logger.error ("Couldn't load language configuration.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -599,6 +599,10 @@ IntArray BotGraph::getNearestInRadius (float radius, const Vector &origin, int m
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BotGraph::isAnalyzed () const {
|
||||||
|
return (m_info.header.options & StorageOption::Analyzed);
|
||||||
|
}
|
||||||
|
|
||||||
void BotGraph::add (int type, const Vector &pos) {
|
void BotGraph::add (int type, const Vector &pos) {
|
||||||
if (!hasEditor () && !analyzer.isAnalyzing ()) {
|
if (!hasEditor () && !analyzer.isAnalyzing ()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -2836,22 +2840,6 @@ BotGraph::BotGraph () {
|
||||||
m_editor = nullptr;
|
m_editor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotGraph::initBuckets () {
|
|
||||||
m_hashTable.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BotGraph::addToBucket (const Vector &pos, int index) {
|
|
||||||
m_hashTable[locateBucket (pos)].emplace (index);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Array <int32_t> &BotGraph::getNodesInBucket (const Vector &pos) {
|
|
||||||
return m_hashTable[locateBucket (pos)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BotGraph::isAnalyzed () const {
|
|
||||||
return (m_info.header.options & StorageOption::Analyzed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BotGraph::eraseFromBucket (const Vector &pos, int index) {
|
void BotGraph::eraseFromBucket (const Vector &pos, int index) {
|
||||||
auto &data = m_hashTable[locateBucket (pos)];
|
auto &data = m_hashTable[locateBucket (pos)];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -459,7 +459,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int interfaceVersion) {
|
||||||
// would all have the dull "models/player.mdl" one). The entity for which the keyvalue data
|
// would all have the dull "models/player.mdl" one). The entity for which the keyvalue data
|
||||||
// pointer is requested is pentKeyvalue, the pointer to the keyvalue data structure pkvd.
|
// pointer is requested is pentKeyvalue, the pointer to the keyvalue data structure pkvd.
|
||||||
|
|
||||||
if (game.isNullEntity (ent) && strcmp (ent->v.classname.chars (), "func_breakable") == 0) {
|
if (!game.isNullEntity (ent) && strcmp (ent->v.classname.chars (), "func_breakable") == 0) {
|
||||||
if (kvd && kvd->szKeyName && strcmp (kvd->szKeyName, "material") == 0) {
|
if (kvd && kvd->szKeyName && strcmp (kvd->szKeyName, "material") == 0) {
|
||||||
if (atoi (kvd->szValue) == 7) {
|
if (atoi (kvd->szValue) == 7) {
|
||||||
game.markBreakableAsInvalid (ent);
|
game.markBreakableAsInvalid (ent);
|
||||||
|
|
|
||||||
|
|
@ -549,7 +549,7 @@ void MessageDispatcher::start (edict_t *ent, int32_t type) {
|
||||||
m_bot = bots[ent];
|
m_bot = bots[ent];
|
||||||
|
|
||||||
if (!m_bot) {
|
if (!m_bot) {
|
||||||
m_current = NetMsg::None;
|
stopCollection ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -561,7 +561,8 @@ void MessageDispatcher::stop () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(this->*m_handlers[m_current]) ();
|
(this->*m_handlers[m_current]) ();
|
||||||
m_current = NetMsg::None;
|
|
||||||
|
stopCollection ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageDispatcher::ensureMessages () {
|
void MessageDispatcher::ensureMessages () {
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,13 @@ ConVar cv_has_team_semiclip ("has_team_semiclip", "0", "When enabled, bots will
|
||||||
ConVar cv_graph_slope_height ("graph_slope_height", "24.0", "Determines the maximum slope height change between the current and next node to consider the current link as a jump link. Only for generated graphs.", true, 12.0f, 48.0f);
|
ConVar cv_graph_slope_height ("graph_slope_height", "24.0", "Determines the maximum slope height change between the current and next node to consider the current link as a jump link. Only for generated graphs.", true, 12.0f, 48.0f);
|
||||||
|
|
||||||
int Bot::findBestGoal () {
|
int Bot::findBestGoal () {
|
||||||
if (m_isCreature) {
|
if (game.is (GameFlags::ZombieMod) && m_isCreature) {
|
||||||
if (!graph.m_terrorPoints.empty ()) {
|
const auto &players = bots.countTeamPlayers ();
|
||||||
|
|
||||||
|
if (players.first < graph.m_terrorPoints.length <int> ()) {
|
||||||
return graph.m_terrorPoints.random ();
|
return graph.m_terrorPoints.random ();
|
||||||
}
|
}
|
||||||
|
else if (players.first < graph.m_goalPoints.length <int> ()) {
|
||||||
if (!graph.m_goalPoints.empty ()) {
|
|
||||||
return graph.m_goalPoints.random ();
|
return graph.m_goalPoints.random ();
|
||||||
}
|
}
|
||||||
return graph.random ();
|
return graph.random ();
|
||||||
|
|
|
||||||
|
|
@ -1473,9 +1473,9 @@ void Bot::shootBreakable_ () {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
game.testLine (pev->origin, m_breakableOrigin, TraceIgnore::None, ent (), &tr);
|
game.testLine (pev->origin, m_breakableOrigin, TraceIgnore::Monsters , ent (), &tr);
|
||||||
|
|
||||||
if (tr.pHit != m_breakableEntity || !util.isVisible (tr.vecEndPos, ent ())) {
|
if (tr.pHit != m_breakableEntity && !cr::fequal (tr.flFraction, 1.0f)) {
|
||||||
m_ignoredBreakable.push (tr.pHit);
|
m_ignoredBreakable.push (tr.pHit);
|
||||||
|
|
||||||
m_breakableEntity = nullptr;
|
m_breakableEntity = nullptr;
|
||||||
|
|
@ -1494,8 +1494,6 @@ void Bot::shootBreakable_ () {
|
||||||
m_navTimeset = game.time ();
|
m_navTimeset = game.time ();
|
||||||
m_lookAtSafe = m_breakableOrigin;
|
m_lookAtSafe = m_breakableOrigin;
|
||||||
|
|
||||||
const float distToObstacle = pev->origin.distanceSq (m_lookAtSafe);
|
|
||||||
|
|
||||||
// is bot facing the breakable?
|
// is bot facing the breakable?
|
||||||
if (util.getConeDeviation (ent (), m_lookAtSafe) >= 0.90f) {
|
if (util.getConeDeviation (ent (), m_lookAtSafe) >= 0.90f) {
|
||||||
m_moveSpeed = 0.0f;
|
m_moveSpeed = 0.0f;
|
||||||
|
|
@ -1510,6 +1508,7 @@ void Bot::shootBreakable_ () {
|
||||||
pev->button |= IN_ATTACK;
|
pev->button |= IN_ATTACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const float distToObstacle = pev->origin.distanceSq (m_lookAtSafe);
|
||||||
|
|
||||||
// if with knife with no ammo, recompute breakable distance
|
// if with knife with no ammo, recompute breakable distance
|
||||||
if (!hasAnyAmmoInClip ()
|
if (!hasAnyAmmoInClip ()
|
||||||
|
|
@ -1703,6 +1702,7 @@ void Bot::pickupItem_ () {
|
||||||
for (const auto &client : util.getClients ()) {
|
for (const auto &client : util.getClients ()) {
|
||||||
if ((client.flags & ClientFlags::Used) && !(client.ent->v.flags & FL_FAKECLIENT) && (client.flags & ClientFlags::Alive) &&
|
if ((client.flags & ClientFlags::Used) && !(client.ent->v.flags & FL_FAKECLIENT) && (client.flags & ClientFlags::Alive) &&
|
||||||
client.team == m_team && client.ent->v.origin.distanceSq (ent->v.origin) <= cr::sqrf (240.0f)) {
|
client.team == m_team && client.ent->v.origin.distanceSq (ent->v.origin) <= cr::sqrf (240.0f)) {
|
||||||
|
|
||||||
return EntitySearchResult::Continue;
|
return EntitySearchResult::Continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue