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
|
|
@ -2146,6 +2146,7 @@ void Bot::filterTasks () {
|
|||
// zombie bots has more hunt desire
|
||||
if (m_isCreature && huntEnemyDesire > 16.0f) {
|
||||
huntEnemyDesire = TaskPri::Attack;
|
||||
seekCoverDesire = 0.0f;
|
||||
}
|
||||
|
||||
// blinded behavior
|
||||
|
|
@ -2250,37 +2251,9 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
|
|||
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 (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);
|
||||
}
|
||||
handleChatterTaskChange (tid);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 () {
|
||||
// this function handling radio and reacting to it
|
||||
|
||||
|
||||
// don't allow bot listen you if bot is busy
|
||||
if (m_radioOrder != Radio::ReportInTeam
|
||||
&& (getCurrentTaskId () == Task::DefuseBomb
|
||||
|
|
|
|||
|
|
@ -208,28 +208,29 @@ void BotConfig::loadWeaponsConfig () {
|
|||
trim.trim ();
|
||||
}
|
||||
auto splitted = pair[1].split (",");
|
||||
auto key = pair[0];
|
||||
|
||||
if (pair[0].startsWith ("MapStandard")) {
|
||||
addWeaponEntries (m_weapons, false, pair[0], splitted);
|
||||
if (key.startsWith ("MapStandard")) {
|
||||
addWeaponEntries (m_weapons, false, key, splitted);
|
||||
}
|
||||
else if (pair[0].startsWith ("MapAS")) {
|
||||
addWeaponEntries (m_weapons, true, pair[0], splitted);
|
||||
else if (key.startsWith ("MapAS")) {
|
||||
addWeaponEntries (m_weapons, true, key, splitted);
|
||||
}
|
||||
|
||||
else if (pair[0].startsWith ("GrenadePercent")) {
|
||||
addIntEntries (m_grenadeBuyPrecent, pair[0], splitted);
|
||||
else if (key.startsWith ("GrenadePercent")) {
|
||||
addIntEntries (m_grenadeBuyPrecent, key, splitted);
|
||||
}
|
||||
else if (pair[0].startsWith ("Economics")) {
|
||||
addIntEntries (m_botBuyEconomyTable, pair[0], splitted);
|
||||
else if (key.startsWith ("Economics")) {
|
||||
addIntEntries (m_botBuyEconomyTable, key, splitted);
|
||||
}
|
||||
else if (pair[0].startsWith ("PersonalityNormal")) {
|
||||
addIntEntries (m_normalWeaponPrefs, pair[0], splitted);
|
||||
else if (key.startsWith ("PersonalityNormal")) {
|
||||
addIntEntries (m_normalWeaponPrefs, key, splitted);
|
||||
}
|
||||
else if (pair[0].startsWith ("PersonalityRusher")) {
|
||||
addIntEntries (m_rusherWeaponPrefs, pair[0], splitted);
|
||||
else if (key.startsWith ("PersonalityRusher")) {
|
||||
addIntEntries (m_rusherWeaponPrefs, key, splitted);
|
||||
}
|
||||
else if (pair[0].startsWith ("PersonalityCareful")) {
|
||||
addIntEntries (m_carefulWeaponPrefs, pair[0], splitted);
|
||||
else if (key.startsWith ("PersonalityCareful")) {
|
||||
addIntEntries (m_carefulWeaponPrefs, key, splitted);
|
||||
}
|
||||
}
|
||||
file.close ();
|
||||
|
|
@ -244,7 +245,7 @@ void BotConfig::loadChatterConfig () {
|
|||
|
||||
// chatter initialization
|
||||
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 ();
|
||||
|
||||
|
|
@ -402,7 +403,7 @@ void BotConfig::loadChatConfig () {
|
|||
MemFile file {};
|
||||
|
||||
// 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 keywords {};
|
||||
|
|
@ -549,7 +550,7 @@ void BotConfig::loadLanguageConfig () {
|
|||
file.close ();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
bool BotGraph::isAnalyzed () const {
|
||||
return (m_info.header.options & StorageOption::Analyzed);
|
||||
}
|
||||
|
||||
void BotGraph::add (int type, const Vector &pos) {
|
||||
if (!hasEditor () && !analyzer.isAnalyzing ()) {
|
||||
return;
|
||||
|
|
@ -2836,22 +2840,6 @@ BotGraph::BotGraph () {
|
|||
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) {
|
||||
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
|
||||
// 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 (atoi (kvd->szValue) == 7) {
|
||||
game.markBreakableAsInvalid (ent);
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ void MessageDispatcher::start (edict_t *ent, int32_t type) {
|
|||
m_bot = bots[ent];
|
||||
|
||||
if (!m_bot) {
|
||||
m_current = NetMsg::None;
|
||||
stopCollection ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -561,7 +561,8 @@ void MessageDispatcher::stop () {
|
|||
return;
|
||||
}
|
||||
(this->*m_handlers[m_current]) ();
|
||||
m_current = NetMsg::None;
|
||||
|
||||
stopCollection ();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
int Bot::findBestGoal () {
|
||||
if (m_isCreature) {
|
||||
if (!graph.m_terrorPoints.empty ()) {
|
||||
if (game.is (GameFlags::ZombieMod) && m_isCreature) {
|
||||
const auto &players = bots.countTeamPlayers ();
|
||||
|
||||
if (players.first < graph.m_terrorPoints.length <int> ()) {
|
||||
return graph.m_terrorPoints.random ();
|
||||
}
|
||||
|
||||
if (!graph.m_goalPoints.empty ()) {
|
||||
else if (players.first < graph.m_goalPoints.length <int> ()) {
|
||||
return graph.m_goalPoints.random ();
|
||||
}
|
||||
return graph.random ();
|
||||
|
|
|
|||
|
|
@ -1473,9 +1473,9 @@ void Bot::shootBreakable_ () {
|
|||
}
|
||||
else {
|
||||
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_breakableEntity = nullptr;
|
||||
|
|
@ -1494,8 +1494,6 @@ void Bot::shootBreakable_ () {
|
|||
m_navTimeset = game.time ();
|
||||
m_lookAtSafe = m_breakableOrigin;
|
||||
|
||||
const float distToObstacle = pev->origin.distanceSq (m_lookAtSafe);
|
||||
|
||||
// is bot facing the breakable?
|
||||
if (util.getConeDeviation (ent (), m_lookAtSafe) >= 0.90f) {
|
||||
m_moveSpeed = 0.0f;
|
||||
|
|
@ -1510,6 +1508,7 @@ void Bot::shootBreakable_ () {
|
|||
pev->button |= IN_ATTACK;
|
||||
}
|
||||
}
|
||||
const float distToObstacle = pev->origin.distanceSq (m_lookAtSafe);
|
||||
|
||||
// if with knife with no ammo, recompute breakable distance
|
||||
if (!hasAnyAmmoInClip ()
|
||||
|
|
@ -1703,6 +1702,7 @@ void Bot::pickupItem_ () {
|
|||
for (const auto &client : util.getClients ()) {
|
||||
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)) {
|
||||
|
||||
return EntitySearchResult::Continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue