mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2025-04-10 11:40:02 +03:00
Friendly fire fixes Bot Chatter: Bots will react to enemy snipers presence previously unused chatter on both 1.6 and czero but is used on cs source Probably fixed where teammate that use sniperrifles looking at bots that don't use sniperrifles got warned
369 lines
11 KiB
C++
369 lines
11 KiB
C++
/*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* In addition, as a special exception, the author gives permission to
|
|
* link the code of this program with the Half-Life Game Engine ("HL
|
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
* respects for all of the code used other than the HL Engine and MODs
|
|
* from Valve. If you modify this file, you may extend this exception
|
|
* to your version of the file, but you are not obligated to do so. If
|
|
* you do not wish to do so, delete this exception statement from your
|
|
* version.
|
|
*
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
|
|
cvar_t cv_bot_enable = { "bot_enable", "0", 0, 0.0f, nullptr };
|
|
cvar_t cv_bot_traceview = { "bot_traceview", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_stop = { "bot_stop", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_show_nav = { "bot_show_nav", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_show_danger = { "bot_show_danger", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_nav_edit = { "bot_nav_edit", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_nav_zdraw = { "bot_nav_zdraw", "4", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_walk = { "bot_walk", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_difficulty = { "bot_difficulty", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_debug = { "bot_debug", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_quicksave = { "bot_quicksave", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_quota = { "bot_quota", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_prefix = { "bot_prefix", "", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_rogues = { "bot_allow_rogues", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_pistols = { "bot_allow_pistols", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_shotguns = { "bot_allow_shotguns", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_sub_machine_guns = { "bot_allow_sub_machine_guns", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_rifles = { "bot_allow_rifles", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_machine_guns = { "bot_allow_machine_guns", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_grenades = { "bot_allow_grenades", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_snipers = { "bot_allow_snipers", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_allow_shield = { "bot_allow_shield", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_join_team = { "bot_join_team", "any", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_join_after_player = { "bot_join_after_player", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_auto_vacate = { "bot_auto_vacate", "1", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_zombie = { "bot_zombie", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_defer_to_human = { "bot_defer_to_human", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_chatter = { "bot_chatter", "normal", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_profile_db = { "bot_profile_db", "BotProfile.db", FCVAR_SERVER, 0.0f, nullptr };
|
|
|
|
#ifdef REGAMEDLL_ADD
|
|
cvar_t cv_bot_deathmatch = { "bot_deathmatch", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_quota_mode = { "bot_quota_mode", "normal", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_join_delay = { "bot_join_delay", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
cvar_t cv_bot_freeze = { "bot_freeze", "0", 0, 0.0f, nullptr };
|
|
cvar_t cv_bot_mimic = { "bot_mimic", "0", 0, 0.0f, nullptr };
|
|
cvar_t cv_bot_mimic_yaw_offset = { "bot_mimic_yaw_offset", "0", 0, 0.0f, nullptr };
|
|
#else
|
|
// Migrated to bot_quota_mode, use "match"
|
|
cvar_t cv_bot_quota_match = { "bot_quota_match", "0", FCVAR_SERVER, 0.0f, nullptr };
|
|
#endif
|
|
|
|
void InstallBotControl()
|
|
{
|
|
if (TheBots)
|
|
{
|
|
delete TheBots;
|
|
}
|
|
|
|
TheBots = new CCSBotManager;
|
|
}
|
|
|
|
// Engine callback for custom server commands
|
|
void Bot_ServerCommand()
|
|
{
|
|
if (TheBots)
|
|
{
|
|
const char *pcmd = CMD_ARGV(0);
|
|
TheBots->ServerCommand(pcmd);
|
|
}
|
|
}
|
|
|
|
void Bot_RegisterCVars()
|
|
{
|
|
if (!AreBotsAllowed())
|
|
return;
|
|
|
|
CVAR_REGISTER(&cv_bot_traceview);
|
|
CVAR_REGISTER(&cv_bot_stop);
|
|
CVAR_REGISTER(&cv_bot_show_nav);
|
|
CVAR_REGISTER(&cv_bot_show_danger);
|
|
CVAR_REGISTER(&cv_bot_nav_edit);
|
|
CVAR_REGISTER(&cv_bot_nav_zdraw);
|
|
CVAR_REGISTER(&cv_bot_walk);
|
|
CVAR_REGISTER(&cv_bot_difficulty);
|
|
CVAR_REGISTER(&cv_bot_debug);
|
|
CVAR_REGISTER(&cv_bot_quicksave);
|
|
CVAR_REGISTER(&cv_bot_quota);
|
|
|
|
#ifndef REGAMEDLL_ADD
|
|
CVAR_REGISTER(&cv_bot_quota_match);
|
|
#endif
|
|
|
|
CVAR_REGISTER(&cv_bot_prefix);
|
|
CVAR_REGISTER(&cv_bot_allow_rogues);
|
|
CVAR_REGISTER(&cv_bot_allow_pistols);
|
|
CVAR_REGISTER(&cv_bot_allow_shotguns);
|
|
CVAR_REGISTER(&cv_bot_allow_sub_machine_guns);
|
|
CVAR_REGISTER(&cv_bot_allow_rifles);
|
|
CVAR_REGISTER(&cv_bot_allow_machine_guns);
|
|
CVAR_REGISTER(&cv_bot_allow_grenades);
|
|
CVAR_REGISTER(&cv_bot_allow_snipers);
|
|
CVAR_REGISTER(&cv_bot_allow_shield);
|
|
CVAR_REGISTER(&cv_bot_join_team);
|
|
CVAR_REGISTER(&cv_bot_join_after_player);
|
|
CVAR_REGISTER(&cv_bot_auto_vacate);
|
|
CVAR_REGISTER(&cv_bot_zombie);
|
|
CVAR_REGISTER(&cv_bot_defer_to_human);
|
|
CVAR_REGISTER(&cv_bot_chatter);
|
|
CVAR_REGISTER(&cv_bot_profile_db);
|
|
|
|
#ifdef REGAMEDLL_ADD
|
|
CVAR_REGISTER(&cv_bot_deathmatch);
|
|
CVAR_REGISTER(&cv_bot_quota_mode);
|
|
CVAR_REGISTER(&cv_bot_join_delay);
|
|
CVAR_REGISTER(&cv_bot_freeze);
|
|
CVAR_REGISTER(&cv_bot_mimic);
|
|
CVAR_REGISTER(&cv_bot_mimic_yaw_offset);
|
|
#endif
|
|
|
|
}
|
|
|
|
// Constructor
|
|
CCSBot::CCSBot() : m_gameState(this), m_chatter(this)
|
|
{
|
|
;
|
|
}
|
|
|
|
// Prepare bot for action
|
|
bool CCSBot::Initialize(const BotProfile *profile)
|
|
{
|
|
// extend
|
|
CBot::Initialize(profile);
|
|
|
|
// CS bot initialization
|
|
m_diedLastRound = false;
|
|
m_morale = POSITIVE; // starting a new round makes everyone a little happy
|
|
|
|
m_combatRange = RANDOM_FLOAT(325, 425);
|
|
|
|
m_navNodeList = nullptr;
|
|
m_currentNode = nullptr;
|
|
|
|
// set initial safe time guess for this map
|
|
m_safeTime = 15.0f + 5.0f * GetProfile()->GetAggression();
|
|
|
|
m_name[0] = '\0';
|
|
|
|
ResetValues();
|
|
StartNormalProcess();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Reset internal data to initial state
|
|
void CCSBot::ResetValues()
|
|
{
|
|
m_chatter.Reset();
|
|
m_gameState.Reset();
|
|
|
|
m_avoid = nullptr;
|
|
m_avoidTimestamp = 0.0f;
|
|
|
|
m_hurryTimer.Invalidate();
|
|
|
|
m_isStuck = false;
|
|
m_stuckTimestamp = 0.0f;
|
|
m_wiggleTimestamp = 0.0f;
|
|
m_stuckJumpTimestamp = 0.0f;
|
|
|
|
m_pathLength = 0;
|
|
m_pathIndex = 0;
|
|
m_areaEnteredTimestamp = 0.0f;
|
|
m_currentArea = nullptr;
|
|
m_lastKnownArea = nullptr;
|
|
|
|
#ifdef REGAMEDLL_ADD
|
|
m_isEnemySniperVisible = false;
|
|
m_sawEnemySniperTimer.Invalidate();
|
|
#endif
|
|
|
|
m_avoidFriendTimer.Invalidate();
|
|
m_isFriendInTheWay = false;
|
|
m_isWaitingBehindFriend = false;
|
|
|
|
m_disposition = ENGAGE_AND_INVESTIGATE;
|
|
|
|
m_enemy = nullptr;
|
|
|
|
m_isWaitingToTossGrenade = false;
|
|
m_wasSafe = true;
|
|
|
|
m_nearbyEnemyCount = 0;
|
|
m_enemyPlace = 0;
|
|
m_nearbyFriendCount = 0;
|
|
m_closestVisibleFriend = nullptr;
|
|
m_closestVisibleHumanFriend = nullptr;
|
|
|
|
for (int w = 0; w < ARRAYSIZE(m_watchInfo); w++)
|
|
{
|
|
m_watchInfo[w].timestamp = 0.0f;
|
|
m_watchInfo[w].isEnemy = false;
|
|
}
|
|
|
|
m_isEnemyVisible = false;
|
|
m_visibleEnemyParts = NONE;
|
|
m_lastSawEnemyTimestamp = 0.0f;
|
|
m_firstSawEnemyTimestamp = 0.0f;
|
|
m_currentEnemyAcquireTimestamp = 0.0f;
|
|
m_isLastEnemyDead = true;
|
|
m_attacker = nullptr;
|
|
m_attackedTimestamp = 0.0f;
|
|
m_enemyDeathTimestamp = 0.0f;
|
|
m_lastVictimID = 0;
|
|
m_isAimingAtEnemy = false;
|
|
m_fireWeaponTimestamp = 0.0f;
|
|
m_equipTimer.Invalidate();
|
|
|
|
m_isFollowing = false;
|
|
m_leader = nullptr;
|
|
m_followTimestamp = 0.0f;
|
|
m_allowAutoFollowTime = 0.0f;
|
|
|
|
m_enemyQueueIndex = 0;
|
|
m_enemyQueueCount = 0;
|
|
m_enemyQueueAttendIndex = 0;
|
|
m_bomber = nullptr;
|
|
|
|
m_lookAroundStateTimestamp = 0.0f;
|
|
m_inhibitLookAroundTimestamp = 0.0f;
|
|
|
|
m_lookPitch = 0.0f;
|
|
m_lookPitchVel = 0.0f;
|
|
m_lookYaw = 0.0f;
|
|
m_lookYawVel = 0.0f;
|
|
|
|
m_aimOffsetTimestamp = 0.0f;
|
|
m_aimSpreadTimestamp = 0.0f;
|
|
m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
|
|
|
|
m_spotEncounter = nullptr;
|
|
m_spotCheckTimestamp = 0.0f;
|
|
m_peripheralTimestamp = 0.0f;
|
|
|
|
m_avgVelIndex = 0;
|
|
m_avgVelCount = 0;
|
|
|
|
m_lastOrigin = pev ? pev->origin : Vector(0, 0, 0);
|
|
|
|
m_lastRadioCommand = EVENT_INVALID;
|
|
m_lastRadioRecievedTimestamp = 0.0f;
|
|
m_lastRadioSentTimestamp = 0.0f;
|
|
m_radioSubject = nullptr;
|
|
m_voiceFeedbackEndTimestamp = 0.0f;
|
|
|
|
m_hostageEscortCount = 0;
|
|
m_hostageEscortCountTimestamp = 0.0f;
|
|
|
|
m_noisePosition = Vector(0, 0, 0);
|
|
m_noiseTimestamp = 0.0f;
|
|
m_noiseCheckTimestamp = 0.0f;
|
|
m_isNoiseTravelRangeChecked = false;
|
|
|
|
m_stateTimestamp = 0.0f;
|
|
m_task = SEEK_AND_DESTROY;
|
|
m_taskEntity = nullptr;
|
|
|
|
m_approachPointCount = 0;
|
|
m_approachPointViewPosition = Vector(0, 0, 0);
|
|
|
|
m_checkedHidingSpotCount = 0;
|
|
m_isJumpCrouching = false;
|
|
|
|
StandUp();
|
|
Run();
|
|
m_mustRunTimer.Invalidate();
|
|
m_repathTimer.Invalidate();
|
|
m_pathLadder = nullptr;
|
|
|
|
m_huntState.ClearHuntArea();
|
|
|
|
// adjust morale - if we died, our morale decreased,
|
|
// but if we live, no adjustement (round win/loss also adjusts morale
|
|
if (m_diedLastRound)
|
|
DecreaseMorale();
|
|
|
|
m_diedLastRound = false;
|
|
|
|
// IsRogue() randomly changes this
|
|
m_isRogue = false;
|
|
|
|
m_surpriseDelay = 0.0f;
|
|
m_surpriseTimestamp = 0.0f;
|
|
|
|
// even though these are EHANDLEs, they need to be NULL-ed
|
|
m_goalEntity = nullptr;
|
|
m_avoid = nullptr;
|
|
m_enemy = nullptr;
|
|
|
|
#ifdef REGAMEDLL_FIXES
|
|
for (int i = 0; i < MAX_ENEMY_QUEUE; i++)
|
|
{
|
|
m_enemyQueue[i].player = nullptr;
|
|
m_enemyQueue[i].isReloading = false;
|
|
m_enemyQueue[i].isProtectedByShield = false;
|
|
}
|
|
#endif
|
|
|
|
// start in idle state
|
|
StopAttacking();
|
|
Idle();
|
|
}
|
|
|
|
// Called when bot is placed in map, and when bots are reset after a round ends.
|
|
// NOTE: For some reason, this can be called twice when a bot is added.
|
|
void CCSBot::SpawnBot()
|
|
{
|
|
TheCSBots()->ValidateMapData();
|
|
ResetValues();
|
|
|
|
Q_strlcpy(m_name, STRING(pev->netname));
|
|
|
|
SetState(&m_buyState);
|
|
SetTouch(&CCSBot::BotTouch);
|
|
|
|
if (TheNavAreaList.empty() && !TheCSBots()->IsLearningMap())
|
|
{
|
|
TheCSBots()->SetLearningMapFlag();
|
|
StartLearnProcess();
|
|
}
|
|
}
|
|
|
|
void CCSBot::RoundRespawn()
|
|
{
|
|
// do the normal player spawn process
|
|
CBasePlayer::RoundRespawn();
|
|
EndVoiceFeedback();
|
|
}
|
|
|
|
void CCSBot::Disconnect()
|
|
{
|
|
EndVoiceFeedback();
|
|
|
|
if (m_processMode != PROCESS_NORMAL)
|
|
{
|
|
hideProgressMeter();
|
|
}
|
|
}
|