some work done in 9 months

This commit is contained in:
Dmitriy 2015-06-04 11:52:48 +03:00
commit b3b157fab0
17 changed files with 1214 additions and 1272 deletions

View file

@ -189,7 +189,8 @@ enum TaskId_t
TASK_SHOOTBREAKABLE,
TASK_HIDE,
TASK_BLINDED,
TASK_SPRAY
TASK_SPRAY,
TASK_MAX
};
// supported cs's
@ -541,7 +542,6 @@ enum WaypointFlag
enum PathFlag
{
PATHFLAG_JUMP = (1 << 0), // must jump for this connection
PATHFLAG_DOUBLEJUMP = (1 << 1) // must use friend for this connection
};
// defines waypoint connection types
@ -672,28 +672,10 @@ struct WeaponSelect
int buySelect; // select item in buy menu (standard map)
int newBuySelectT; // for counter-strike v1.6
int newBuySelectCT; // for counter-strike v1.6
bool shootsThru; // can shoot thru walls
int penetratePower; // penetrate power
bool primaryFireHold; // hold down primary fire button to use?
};
// skill definitions
struct SkillDefinition
{
float minSurpriseTime; // surprise delay (minimum)
float maxSurpriseTime; // surprise delay (maximum)
float campStartDelay; // delay befor start camping
float campEndDelay; // delay before end camping
float minTurnSpeed; // initial minimum turnspeed
float maxTurnSpeed; // initial maximum turnspeed
float aimOffs_X; // X/Y/Z maximum offsets
float aimOffs_Y; // X/Y/Z maximum offsets
float aimOffs_Z; // X/Y/Z maximum offsets
int headshotFrequency; // precent to aiming to player head
int heardShootThruProb; // precent to shooting throug wall when seen something
int seenShootThruProb; // precent to shooting throug wall when heard something
int recoilAmount; // amount of recoil when the bot should pause shooting
};
// fire delay definiton
struct FireDelay
{
@ -753,7 +735,7 @@ struct ExperienceSave
// bot creation tab
struct CreateQueue
{
int skill;
int difficulty;
int team;
int member;
int personality;
@ -846,6 +828,7 @@ private:
int m_messageQueue[32]; // stack for messages
char m_tempStrings[160]; // space for strings (say text...)
int m_radioSelect; // radio entry
float m_headedTime;
float m_blindRecognizeTime; // time to recognize enemy
float m_itemCheckTime; // time next search for items needs to be done
@ -862,6 +845,7 @@ private:
float m_timeLogoSpray; // time bot last spray logo
float m_knifeAttackTime; // time to rush with knife (at the beginning of the round)
bool m_defendedBomb; // defend action issued
bool m_defendHostage;
float m_askCheckTime; // time to ask team
float m_collideTime; // time last collision
@ -886,7 +870,6 @@ private:
int m_waypointFlags; // current waypoint flags
int m_loosedBombWptIndex; // nearest to loosed bomb waypoint
int m_plantedBombWptIndex;// nearest to planted bomb waypoint
float m_skillOffset; // offset to bots skill
unsigned short m_currentTravelFlags; // connection flags like jumping
bool m_jumpFinished; // has bot finished jumping
@ -931,6 +914,7 @@ private:
float m_zoomCheckTime; // time to check zoom again
float m_shieldCheckTime; // time to check shiled drawing again
float m_grenadeCheckTime; // time to check grenade usage
float m_lastEquipTime; // last time we equipped in buyzone
bool m_checkKnifeSwitch; // is time to check switch to knife action
bool m_checkWeaponSwitch; // is time to check weapon switch
@ -1001,6 +985,7 @@ private:
bool DoWaypointNav (void);
bool EnemyIsThreat (void);
void FacePosition (void);
void SetIdealReactionTimes (bool actual = false);
bool IsRestricted (int weaponIndex);
bool IsRestrictedAMX (int weaponIndex);
@ -1015,6 +1000,7 @@ private:
int FindDefendWaypoint (Vector origin);
int FindGoal (void);
void FindItem (void);
void CheckTerrain (float movedDistance);
void GetCampDirection (Vector *dest);
void CollectGoalExperience (int damage, int team);
@ -1027,7 +1013,7 @@ private:
bool IsBombDefusing (Vector bombOrigin);
bool IsBlockedLeft (void);
bool IsBlockedRight (void);
bool IsWaypointUsed (int index);
bool IsPointOccupied (int index);
inline bool IsOnLadder (void) { return pev->movetype == MOVETYPE_FLY; }
inline bool IsOnFloor (void) { return (pev->flags & (FL_ONGROUND | FL_PARTIALGROUND)) != 0; }
inline bool IsInWater (void) { return pev->waterlevel >= 2; }
@ -1106,12 +1092,13 @@ public:
int m_wantedTeam; // player team bot wants select
int m_wantedClass; // player model bot wants to select
int m_skill; ;// bots play skill
int m_difficulty;
int m_moneyAmount; // amount of money in bot's bank
Personality m_personality;
float m_spawnTime; // time this bot spawned
float m_timeTeamOrder; // time of last radio command
float m_timePeriodicUpdate; // time to per-second think
bool m_isVIP; // bot is vip?
bool m_bIsDefendingTeam; // bot in defending team on this map
@ -1139,7 +1126,8 @@ public:
bool m_hasProgressBar; // has progress bar on a HUD
bool m_jumpReady; // is double jump ready
bool m_canChooseAimDirection; // can choose aiming direction
float m_breakableCheckTime;
float m_blindTime; // time when bot is blinded
float m_blindMoveSpeed; // mad speeds when bot is blind
float m_blindSidemoveSpeed; // mad side move speeds when bot is blind
@ -1204,14 +1192,13 @@ public:
Array <TaskItem> m_tasks;
Bot (edict_t *bot, int skill, int personality, int team, int member);
Bot (edict_t *bot, int difficulty, int personality, int team, int member);
~Bot (void);
int GetAmmo (void);
inline int GetAmmoInClip (void) { return m_ammoInClip[m_currentWeapon]; }
inline edict_t *GetEntity (void) { return ENT (pev); };
inline EOFFSET GetOffset (void) { return OFFSET (pev); };
inline edict_t *GetEntity (void) { return pev->pContainingEntity; };
int GetIndex (void);
inline Vector Center (void) { return (pev->absmax + pev->absmin) * 0.5; };
@ -1229,7 +1216,9 @@ public:
void DeleteSearchNodes (void);
void RemoveCertainTask (TaskId_t id);
void StartTask (TaskId_t id, float desire, int data, float time, bool canContinue);
void StartTask_ (int, const char *f, TaskId_t id, float desire, int data, float time, bool canContinue);
#define StartTask(i,d,a,t,c) StartTask_(__LINE__, __FUNCTION__,i,d,a,t,c)
void ResetTasks (void);
TaskItem *GetTask (void);
inline TaskId_t GetTaskId (void) { return GetTask ()->id; };
@ -1246,13 +1235,13 @@ public:
void RadioMessage (int message);
void ChatterMessage (int message);
void HandleChatterMessage (const char *sz);
void TryHeadTowardRadioEntity (void);
void Kill (void);
void Kick (void);
void ResetDoubleJumpState (void);
void MoveToVector (Vector to);
int FindPlantedBomb(void);
int FindLoosedBomb (void);
bool HasHostage (void);
bool UsesRifle (void);
@ -1286,7 +1275,7 @@ private:
bool m_deathMsgSent; // for fakeping
protected:
int CreateBot (String name, int skill, int personality, int team, int member);
int CreateBot (String name, int difficulty, int personality, int team, int member);
public:
BotManager (void);
@ -1314,9 +1303,9 @@ public:
void CheckAutoVacate (edict_t *ent);
void AddRandom (void) { AddBot ("", -1, -1, -1, -1); }
void AddBot (const String &name, int skill, int personality, int team, int member);
void AddBot (String name, String skill, String personality, String team, String member);
void FillServer (int selection, int personality = PERSONALITY_NORMAL, int skill = -1, int numToAdd = -1);
void AddBot (const String &name, int difficulty, int personality, int team, int member);
void AddBot (String name, String difficulty, String personality, String team, String member);
void FillServer (int selection, int personality = PERSONALITY_NORMAL, int difficulty = -1, int numToAdd = -1);
void RemoveAll (bool zeroQuota = true);
void RemoveRandom (void);
@ -1516,10 +1505,10 @@ enum VarType
VT_NORMAL = 0,
VT_READONLY,
VT_PASSWORD,
VT_NOSERVER,
VT_NOREGISTER
};
class ConVarWrapper : public Singleton <ConVarWrapper>
{
private:
@ -1613,7 +1602,7 @@ extern bool IsDedicatedServer (void);
extern bool IsVisible (const Vector &origin, edict_t *ent);
extern bool IsAlive (edict_t *ent);
extern bool IsInViewCone (Vector origin, edict_t *ent);
extern bool IsWeaponShootingThroughWall (int id);
extern int GetWeaponPenetrationPower (int id);
extern bool IsValidBot (edict_t *ent);
extern bool IsValidPlayer (edict_t *ent);
extern bool OpenConfig (const char *fileName, char *errorIfNotExists, File *outFile, bool languageDependant = false);
@ -1659,7 +1648,6 @@ extern void SoundSimulateUpdate (int playerIndex);
// very global convars
extern ConVar yb_jasonmode;
extern ConVar yb_communication_type;
extern ConVar yb_hardcore_mode;
extern ConVar yb_csdm_mode;
extern ConVar yb_ignore_enemies;

View file

@ -1,4 +1,4 @@
//
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
@ -2404,8 +2404,7 @@ public:
~String (void)
{
if (m_bufferPtr != NULL)
delete [] m_bufferPtr;
delete [] m_bufferPtr;
}
String (const char *bufferPtr)
@ -2469,22 +2468,7 @@ public:
return &m_bufferPtr[0];
}
//
// Function: ToString
// Gets the string buffer (constant).
//
// Returns:
// Pointer to constant buffer.
//
const char *ToString (void) const
{
if (m_bufferPtr == NULL || *m_bufferPtr == 0x0)
return "";
return &m_bufferPtr[0];
}
//
// Function: ToFloat
// Gets the string as float, if possible.
@ -4034,7 +4018,7 @@ public:
static String result;
if (m_fileName != "(no)" && m_line != -1)
result.AssignFormat ("Exception: %s at %s:%i", m_exceptionText.ToString (), m_fileName.ToString (), m_line);
result.AssignFormat ("Exception: %s at %s:%i", m_exceptionText.GetBuffer (), m_fileName.GetBuffer (), m_line);
else
result = m_exceptionText;

View file

@ -33,6 +33,7 @@ extern float g_timeRoundEnd;
extern float g_timeRoundMid;
extern float g_timeNextBombUpdate;
extern float g_timeRoundStart;
extern float g_timePerSecondUpdate;
extern float g_lastRadioTime[2];
extern int g_mapType;
@ -70,7 +71,6 @@ extern WeaponProperty g_weaponDefs[MAX_WEAPONS + 1];
extern Client g_clients[32];
extern MenuText g_menus[21];
extern SkillDefinition g_skillTab[6];
extern TaskItem g_taskFilters[];
extern Experience *g_experienceData;
@ -108,7 +108,17 @@ static inline edict_t *EntityOfIndex (const int index)
return static_cast <edict_t *> (g_worldEdict + index);
};
inline int IndexOfEntity (const edict_t *ent)
static inline int IndexOfEntity(const edict_t *ent)
{
return static_cast <int> (ent - g_worldEdict);
};
static inline int EntOffsetOfEntity(const edict_t *ent)
{
return (char *) ent - (char *) g_worldEdict;
}
static inline bool IsEntityNull (const edict_t *ent)
{
return !ent || !EntOffsetOfEntity (ent);
}

View file

@ -11,17 +11,17 @@
// general product information
#define PRODUCT_NAME "YaPB"
#define PRODUCT_VERSION "2.6"
#define PRODUCT_VERSION "2.7"
#define PRODUCT_AUTHOR "YaPB Dev Team"
#define PRODUCT_URL "http://yapb.jeefo.net/"
#define PRODUCT_EMAIL "dmitry@jeefo.net"
#define PRODUCT_LOGTAG "YAPB"
#define PRODUCT_DESCRIPTION PRODUCT_NAME " v" PRODUCT_VERSION " - The Counter-Strike 1.6 Bot"
#define PRODUCT_COPYRIGHT "Copyright © 2014, by " PRODUCT_AUTHOR
#define PRODUCT_DESCRIPTION PRODUCT_NAME " v" PRODUCT_VERSION " - The Counter-Strike Bot"
#define PRODUCT_COPYRIGHT "Copyright © 2015, by " PRODUCT_AUTHOR
#define PRODUCT_LEGAL "Half-Life, Counter-Strike, Counter-Strike: Condition Zero, Steam, Valve is a trademark of Valve Corporation"
#define PRODUCT_ORIGINAL_NAME "yapb.dll"
#define PRODUCT_INTERNAL_NAME "podbot"
#define PRODUCT_VERSION_DWORD 2,6,0 // major version, minor version, WIP (or Update) version, BUILD number (generated with RES file)
#define PRODUCT_SUPPORT_VERSION "1.4 - CZ"
#define PRODUCT_VERSION_DWORD 2,7,0 // major version, minor version, WIP (or Update) version, BUILD number (generated with RES file)
#define PRODUCT_SUPPORT_VERSION "1.0 - CZ"
#define PRODUCT_DATE __DATE__

View file

@ -26,7 +26,7 @@
#include <../include/resource.h>
// generated by update tool -- do not edit --
#define PRODUCT_BUILD_TOOL 3892
#define PRODUCT_BUILD_TOOL 4153
VS_VERSION_INFO VERSIONINFO
FILEVERSION PRODUCT_VERSION_DWORD, PRODUCT_BUILD_TOOL

View file

@ -1,10 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yapb", "yapb.vcxproj", "{C232645A-3B99-48F4-A1F3-F20CF0A9568B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A92F154C-37FE-4A86-8BD4-B9910F0FDC10}"
ProjectSection(SolutionItems) = preProject
Performance1.psess = Performance1.psess
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_Mmgr|Any CPU = Debug_Mmgr|Any CPU

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug_Mmgr|Win32">
<Configuration>Debug_Mmgr</Configuration>
@ -51,6 +51,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{C232645A-3B99-48F4-A1F3-F20CF0A9568B}</ProjectGuid>
<RootNamespace>yapb</RootNamespace>
<TargetPlatformVersion>8.1</TargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Mmgr|Win32'" Label="Configuration">
@ -60,7 +61,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120_xp</PlatformToolset>
<PlatformToolset>v140_xp</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -171,7 +172,7 @@
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetPath)" "d:\steam\SteamApps\common\Half-Life\cstrike\addons\yapb\dlls" /y</Command>
<Command>copy "$(TargetPath)" "d:\temp\SteamApps\common\Half-Life\cstrike\addons\yapb\dlls" /y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -190,7 +191,7 @@
<HeaderFileName />
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
@ -203,7 +204,7 @@
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet>AdvancedVectorExtensions</EnableEnhancedInstructionSet>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
@ -220,6 +221,7 @@
<InterproceduralOptimization>SingleFile</InterproceduralOptimization>
<FlushDenormalResultsToZero>true</FlushDenormalResultsToZero>
<Parallelization>false</Parallelization>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -249,9 +251,11 @@
<TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion />
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ImageHasSafeExceptionHandlers>true</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetPath)" "d:\steam\SteamApps\common\Half-Life\cstrike\addons\yapb\dlls" /y</Command>
<Command>copy "$(TargetPath)" "d:\temp\SteamApps\common\Half-Life\cstrike\addons\yapb\dlls" /y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Mmgr|Win32'">

File diff suppressed because it is too large Load diff

View file

@ -49,6 +49,8 @@ void StripTags (char *buffer)
{
strtrim (buffer); // if so, string is just a tag
int tagLength = 0;
// strip just the tag part...
for (index = 0; index < ARRAYSIZE_HLSDK(tagOpen); index++)
{
@ -58,7 +60,7 @@ void StripTags (char *buffer)
if (fieldStart >= 0 && fieldStart < 32)
{
fieldStop = fieldStart + strlen (tagOpen[index]); // set the tag stop
int tagLength = strlen (tagOpen[index]);
tagLength = strlen (tagOpen[index]);
for (i = fieldStart; i < length - tagLength; i++)
buffer[i] = buffer[i + tagLength]; // overwrite the buffer with the stripped string
@ -71,7 +73,7 @@ void StripTags (char *buffer)
if (fieldStart >= 0 && fieldStart < 32)
{
fieldStop = fieldStart + strlen (tagClose[index]); // set the tag
int tagLength = strlen (tagClose[index]);
tagLength = strlen (tagClose[index]);
for (i = fieldStart; i < length - tagLength; i++)
buffer[i] = buffer[i + tagLength]; // overwrite the buffer with the stripped string
@ -198,7 +200,7 @@ void Bot::PrepareChatMessage (char *text)
}
talkEntity = g_clients[index].ent;
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
// mapname?
@ -215,7 +217,7 @@ void Bot::PrepareChatMessage (char *text)
{
talkEntity = EntityOfIndex (m_sayTextBuffer.entityIndex);
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
// teammate alive?
@ -233,12 +235,12 @@ void Bot::PrepareChatMessage (char *text)
if (i < GetMaxClients ())
{
if (!FNullEnt (pev->dmg_inflictor) && (m_team == GetTeam (pev->dmg_inflictor)))
if (!IsEntityNull (pev->dmg_inflictor) && (m_team == GetTeam (pev->dmg_inflictor)))
talkEntity = pev->dmg_inflictor;
else
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
else // no teammates alive...
@ -255,7 +257,7 @@ void Bot::PrepareChatMessage (char *text)
{
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
}
@ -275,7 +277,7 @@ void Bot::PrepareChatMessage (char *text)
{
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
else // no teammates alive...
@ -290,7 +292,7 @@ void Bot::PrepareChatMessage (char *text)
{
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
}
@ -301,17 +303,13 @@ void Bot::PrepareChatMessage (char *text)
{
if (g_randGen.Long (1, 100) < 30)
strcat (m_tempStrings, "CZ");
else if (g_randGen.Long (1, 100) < 80)
strcat (m_tempStrings, "KoHTpa K3");
else
strcat (m_tempStrings, "Condition Zero");
}
else if ((g_gameVersion == CSV_STEAM) || (g_gameVersion == CSV_OLD))
else if (g_gameVersion == CSV_STEAM || g_gameVersion == CSV_OLD)
{
if (g_randGen.Long (1, 100) < 30)
strcat (m_tempStrings, "CS");
else if (g_randGen.Long (1, 100) < 80)
strcat (m_tempStrings, "KoHTpa");
else
strcat (m_tempStrings, "Counter-Strike");
}
@ -320,7 +318,7 @@ void Bot::PrepareChatMessage (char *text)
{
talkEntity = m_lastVictim;
if (!FNullEnt (talkEntity))
if (!IsEntityNull (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
pattern++;

View file

@ -1,4 +1,4 @@
//
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
@ -11,7 +11,7 @@
ConVar yb_shoots_thru_walls ("yb_shoots_thru_walls", "1");
ConVar yb_ignore_enemies ("yb_ignore_enemies", "0");
ConVar yb_csdm_mode ("yb_csdm_mode", "0");
ConVar yb_csdm_mode ("yb_csdm_mode", "0", VT_NOSERVER);
ConVar mp_friendlyfire ("mp_friendlyfire", NULL, VT_NOREGISTER);
@ -56,16 +56,17 @@ bool Bot::LookupEnemy (void)
return false;
// do not check for new enemy too fast
if (!FNullEnt (m_enemy) && m_enemyUpdateTime > GetWorldTime () && !(m_states & STATE_SUSPECT_ENEMY))
if (!IsEntityNull (m_enemy) && m_enemyUpdateTime + 2.5f > GetWorldTime () && !(m_states & STATE_SUSPECT_ENEMY))
{
m_aimFlags |= AIM_ENEMY;
m_states |= STATE_SUSPECT_ENEMY;
return true;
}
edict_t *player, *newEnemy = NULL;
float nearestDistance = m_viewDistance;
int i;
// setup potentially visible set for this bot
Vector potentialVisibility = EyePosition ();
@ -78,7 +79,7 @@ bool Bot::LookupEnemy (void)
if (m_seeEnemyTime + 4.0 < GetWorldTime ())
m_states &= ~STATE_SUSPECT_ENEMY;
if (!FNullEnt (m_enemy))
if (!IsEntityNull (m_enemy))
{
player = m_enemy;
@ -88,12 +89,12 @@ bool Bot::LookupEnemy (void)
}
// the old enemy is no longer visible or
if (FNullEnt (newEnemy))
if (IsEntityNull (newEnemy))
{
m_enemyUpdateTime = GetWorldTime () + 0.25;
// search the world for players...
for (i = 0; i < GetMaxClients (); i++)
for (int i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || (g_clients[i].team == m_team) || (g_clients[i].ent == GetEntity ()))
continue;
@ -109,9 +110,9 @@ bool Bot::LookupEnemy (void)
continue;
// do some blind by smoke grenade
if (IsBehindSmokeClouds (player) && m_blindRecognizeTime < GetWorldTime ())
if (m_blindRecognizeTime < GetWorldTime () && IsBehindSmokeClouds (player))
{
m_blindRecognizeTime = GetWorldTime () + g_randGen.Float (2.0, 3.0);
m_blindRecognizeTime = GetWorldTime () + g_randGen.Float (1.0, 2.0);
if (g_randGen.Long (0, 100) < 50)
ChatterMessage (Chatter_BehindSmoke);
@ -160,13 +161,13 @@ bool Bot::LookupEnemy (void)
}
else
{
if (m_seeEnemyTime + 3.0 < GetWorldTime () && (m_hasC4 || HasHostage () || !FNullEnt (m_targetEntity)))
if (m_seeEnemyTime + 3.0 < GetWorldTime () && (m_hasC4 || HasHostage () || !IsEntityNull (m_targetEntity)))
RadioMessage (Radio_EnemySpotted);
m_targetEntity = NULL; // stop following when we see an enemy...
if (g_randGen.Long (0, 100) < m_skill)
m_enemySurpriseTime = GetWorldTime () + (m_actualReactionTime / 3);
if (g_randGen.Long (0, 100) < m_difficulty * 25)
m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime / 3;
else
m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime;
@ -190,7 +191,7 @@ bool Bot::LookupEnemy (void)
if (friendBot != NULL)
{
if (friendBot->m_seeEnemyTime + 2.0 < GetWorldTime () || FNullEnt (friendBot->m_lastEnemy))
if (friendBot->m_seeEnemyTime + 2.0 < GetWorldTime () || IsEntityNull (friendBot->m_lastEnemy))
{
if (IsVisible (pev->origin, ENT (friendBot->pev)))
{
@ -204,7 +205,7 @@ bool Bot::LookupEnemy (void)
return true;
}
}
else if (!FNullEnt (m_enemy))
else if (!IsEntityNull (m_enemy))
{
newEnemy = m_enemy;
m_lastEnemy = newEnemy;
@ -237,26 +238,23 @@ bool Bot::LookupEnemy (void)
}
// if no enemy visible check if last one shoot able through wall
if (yb_shoots_thru_walls.GetBool () && g_randGen.Long (1, 100) < g_skillTab[m_skill / 20].seenShootThruProb)
if (yb_shoots_thru_walls.GetBool () && m_difficulty >= 2 && IsShootableThruObstacle (newEnemy->v.origin))
{
if (IsShootableThruObstacle (newEnemy->v.origin))
{
m_seeEnemyTime = GetWorldTime () - 0.35f;
m_seeEnemyTime = GetWorldTime () - 0.35f;
m_states |= STATE_SUSPECT_ENEMY;
m_aimFlags |= AIM_LAST_ENEMY;
m_states |= STATE_SUSPECT_ENEMY;
m_aimFlags |= AIM_LAST_ENEMY;
m_enemy = newEnemy;
m_lastEnemy = newEnemy;
m_lastEnemyOrigin = newEnemy->v.origin;
m_enemy = newEnemy;
m_lastEnemy = newEnemy;
m_lastEnemyOrigin = newEnemy->v.origin;
return true;
}
return true;
}
}
// check if bots should reload...
if ((m_aimFlags <= AIM_PREDICT_ENEMY && m_seeEnemyTime + 3.0 < GetWorldTime () && !(m_states & (STATE_SEEING_ENEMY | STATE_HEARING_ENEMY)) && FNullEnt (m_lastEnemy) && FNullEnt (m_enemy) && GetTaskId () != TASK_SHOOTBREAKABLE && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) || g_roundEnded)
if ((m_aimFlags <= AIM_PREDICT_ENEMY && m_seeEnemyTime + 3.0 < GetWorldTime () && !(m_states & (STATE_SEEING_ENEMY | STATE_HEARING_ENEMY)) && IsEntityNull (m_lastEnemy) && IsEntityNull (m_enemy) && GetTaskId () != TASK_SHOOTBREAKABLE && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) || g_roundEnded)
{
if (!m_reloadState)
m_reloadState = RELOAD_PRIMARY;
@ -282,54 +280,60 @@ Vector Bot::GetAimPosition (void)
// get enemy position initially
Vector targetOrigin = m_enemy->v.origin;
Vector randomize = nullvec;
const Vector &adjust = Vector (g_randGen.Float (m_enemy->v.mins.x * 0.5f, m_enemy->v.maxs.x * 0.5f), g_randGen.Float (m_enemy->v.mins.y * 0.5f, m_enemy->v.maxs.y * 0.5f), g_randGen.Float (m_enemy->v.mins.z * 0.5f, m_enemy->v.maxs.z * 0.5f));
// do not aim at head, at long distance (only if not using sniper weapon)
if ((m_visibility & VISIBLE_BODY) && !UsesSniper () && !UsesPistol () && (distance > (yb_hardcore_mode.GetBool () ? 3400.0 : 2600.0)))
if ((m_visibility & VISIBLE_BODY) && !UsesSniper () && !UsesPistol () && (distance > (m_difficulty == 4 ? 2400.0 : 1200.0)))
m_visibility &= ~VISIBLE_HEAD;
// if we only suspect an enemy behind a wall take the worst skill
if ((m_states & STATE_SUSPECT_ENEMY) && !(m_states & STATE_SEEING_ENEMY))
targetOrigin = targetOrigin + Vector (g_randGen.Float (m_enemy->v.mins.x * 0.5f, m_enemy->v.maxs.x * 0.5f), g_randGen.Float (m_enemy->v.mins.y * 0.5f, m_enemy->v.maxs.y * 0.5f), g_randGen.Float (m_enemy->v.mins.z * 0.5f, m_enemy->v.maxs.z * 0.5f));
targetOrigin = targetOrigin + adjust;
else
{
// now take in account different parts of enemy body
if (m_visibility & (VISIBLE_HEAD | VISIBLE_BODY)) // visible head & body
{
int headshotFreq[5] = { 20, 40, 60, 90, 100 };
// now check is our skill match to aim at head, else aim at enemy body
if ((g_randGen.Long (1, 100) < g_skillTab[m_skill / 20].headshotFrequency) || UsesPistol ())
if ((g_randGen.Long (1, 100) < headshotFreq[m_difficulty]) || UsesPistol ())
targetOrigin = targetOrigin + m_enemy->v.view_ofs + Vector (0.0f, 0.0f, GetZOffset (distance));
else
targetOrigin = targetOrigin + Vector (0.0f, 0.0f, 3.52f);
targetOrigin = targetOrigin + Vector (0.0f, 0.0f, GetZOffset (distance));
}
else if (m_visibility & VISIBLE_HEAD) // visible only head
targetOrigin = targetOrigin + m_enemy->v.view_ofs + Vector (0.0f, 0.0f, GetZOffset (distance));
else if (m_visibility & VISIBLE_BODY) // visible only body
targetOrigin = targetOrigin + Vector (0.0f, 0.0f, 3.52f);
targetOrigin = targetOrigin + Vector (0.0f, 0.0f, GetZOffset (distance));
else if (m_visibility & VISIBLE_OTHER) // random part of body is visible
targetOrigin = m_enemyOrigin;
else if (m_visibility & VISIBLE_HEAD) // visible only head
targetOrigin = targetOrigin + m_enemy->v.view_ofs + Vector (0.0f, 0.0f, GetZOffset (distance));
else // something goes wrong, use last enemy origin
{
targetOrigin = m_lastEnemyOrigin;
if (m_difficulty < 3)
randomize = adjust;
}
m_lastEnemyOrigin = targetOrigin;
}
const Vector &velocity = UsesSniper () ? nullvec : (1.0f * m_frameInterval * m_enemy->v.velocity - 1.0 * m_frameInterval * pev->velocity).SkipZ ();
if (!yb_hardcore_mode.GetBool ())
if (m_difficulty < 3 && randomize != nullvec)
{
float divOffs, distance = (m_enemyOrigin - pev->origin).GetLength ();
float divOffs = (m_enemyOrigin - pev->origin).GetLength ();
if (pev->fov < 40)
divOffs = distance / 2000;
divOffs = divOffs / 2000;
else if (pev->fov < 90)
divOffs = distance / 1000;
divOffs = divOffs / 1000;
else
divOffs = distance / 500;
targetOrigin.x += divOffs * g_randGen.Float (-g_skillTab[m_skill / 20].aimOffs_X, g_skillTab[m_skill / 20].aimOffs_X);
targetOrigin.y += divOffs * g_randGen.Float (-g_skillTab[m_skill / 20].aimOffs_Y, g_skillTab[m_skill / 20].aimOffs_Y);
targetOrigin.z += divOffs * g_randGen.Float (-g_skillTab[m_skill / 20].aimOffs_Z, g_skillTab[m_skill / 20].aimOffs_Z);
divOffs = divOffs / 500;
// randomize the target position
m_enemyOrigin = targetOrigin + ((pev->velocity - m_enemy->v.velocity).SkipZ () * m_frameInterval * 1.2);
m_enemyOrigin = divOffs * randomize + velocity;
}
else
m_enemyOrigin = targetOrigin;
@ -353,7 +357,7 @@ float Bot::GetZOffset (float distance)
const float BurstDistance = 300.0f;
const float DoubleBurstDistance = BurstDistance * 2;
float result = 3.0f;
float result = 3.5f;
if (distance < 2800.0f && distance > DoubleBurstDistance)
{
@ -371,7 +375,7 @@ float Bot::GetZOffset (float distance)
else if (zoomableRifle) result = 3.5f;
else if (pistol) result = 6.5f;
else if (submachine) result = 3.5f;
else if (rifle) result = 1.0f;
else if (rifle) result = 1.6f;
else if (m249) result = -1.0f;
else if (shotgun) result = 10.0f;
}
@ -400,7 +404,7 @@ bool Bot::IsFriendInLineOfFire (float distance)
TraceLine (EyePosition (), EyePosition () + pev->v_angle.Normalize () * distance, false, false, GetEntity (), &tr);
// check if we hit something
if (!FNullEnt (tr.pHit))
if (!IsEntityNull (tr.pHit))
{
int playerIndex = IndexOfEntity (tr.pHit) - 1;
@ -428,41 +432,49 @@ bool Bot::IsFriendInLineOfFire (float distance)
bool Bot::IsShootableThruObstacle (Vector dest)
{
// this function returns if enemy can be shoot through some obstacle
// this function returns true if enemy can be shoot through some obstacle, false otherwise.
// credits goes to Immortal_BLG
if (m_skill <= 60 || !IsWeaponShootingThroughWall (m_currentWeapon))
if (m_difficulty < 2)
return false;
Vector source = EyePosition ();
Vector direction = (dest - source).Normalize (); // 1 unit long
Vector point = nullvec;
int penetratePower = GetWeaponPenetrationPower (m_currentWeapon);
int thikness = 0;
int numHits = 0;
if (penetratePower == 0)
return false;
// set conditions....
Vector source = EyePosition ();
const Vector &direction = (dest - source).Normalize () * 8.0f; // 8 units long
TraceResult tr;
TraceLine (source, dest, true, true, GetEntity (), &tr);
while (tr.flFraction != 1.0 && numHits < 3)
do
{
numHits++;
thikness++;
// trace from the bot's eyes to destination...
TraceLine (source, dest, true, GetEntity (), &tr);
point = tr.vecEndPos + direction;
while (POINT_CONTENTS (point) == CONTENTS_SOLID && thikness < 98)
if (tr.fStartSolid)
{
point = point + direction;
thikness++;
}
TraceLine (point, dest, true, true, GetEntity (), &tr);
}
if (tr.fAllSolid)
return false;
// move 8 units closer to the destination....
source += direction;
}
else
{
// check if line hit anything
if (tr.flFraction == 1.0f)
return true;
--penetratePower;
// move 8 units closer to the destination....
source = tr.vecEndPos + direction;
}
} while (penetratePower > 0);
if (numHits < 3 && thikness < 98)
{
if ((dest - point).GetLengthSquared () < 13143)
return true;
}
return false;
}
@ -479,21 +491,35 @@ bool Bot::DoFirePause (float distance, FireDelay *fireDelay)
if (m_firePause > GetWorldTime ())
return true;
float offset = 0.0f;
const float BurstDistance = 300.0f;
const float DoubleBurstDistance = BurstDistance * 2;
if (distance < BurstDistance) // KWo - 09.04.2010
return false;
else if (distance < 2 * BurstDistance)
offset = 10.0;
else
offset = 5.0;
float angle = sqrtf ((fabsf (pev->punchangle.y) * Math::MATH_PI / 180.0) * (fabsf (pev->punchangle.y) * Math::MATH_PI / 180.0) + (fabsf (pev->punchangle.x) * Math::MATH_PI / 180.0) * (fabsf (pev->punchangle.x) * Math::MATH_PI / 180.0));
// check if we need to compensate recoil
if (tanf ((fabsf (pev->punchangle.y) + fabsf (pev->punchangle.x)) * Math::MATH_PI / 360.0) * distance > 20 + m_skillOffset)
if (tanf (angle) * distance > offset + 30.0f + ((100 - (m_difficulty * 25)) / 100.f))
{
if (m_firePause < GetWorldTime () - 0.4)
m_firePause = GetWorldTime () + g_randGen.Float (0.4, 0.4 + 1.2 * m_skillOffset);
if (m_firePause < GetWorldTime () - 0.4f)
m_firePause = GetWorldTime () + g_randGen.Float (0.4f, 0.4f + 0.3f * ((100 - (m_difficulty * 25)) / 100.f));
return true;
}
if (!yb_hardcore_mode.GetBool () && fireDelay->maxFireBullets + g_randGen.Long (0, 1) <= m_burstShotsFired)
if (m_difficulty < 3 && fireDelay->maxFireBullets + g_randGen.Long (0, 1) <= m_burstShotsFired)
{
float delayTime = 0.1 * distance / fireDelay->minBurstPauseFactor;
if (delayTime > (125.0 / (m_skill + 1)))
delayTime = 125.0 / (m_skill + 1);
if (delayTime > (125.0 / (m_difficulty * 25 + 1)))
delayTime = 125.0 / (m_difficulty * 25 + 1);
m_firePause = GetWorldTime () + delayTime;
m_burstShotsFired = 0;
@ -516,7 +542,7 @@ void Bot::FireWeapon (void)
}
// or if friend in line of fire, stop this too but do not update shoot time
if (!FNullEnt (m_enemy) && IsFriendInLineOfFire (distance))
if (!IsEntityNull (m_enemy) && IsFriendInLineOfFire (distance))
return;
FireDelay *delay = &g_fireDelay[0];
@ -531,8 +557,8 @@ void Bot::FireWeapon (void)
if (yb_jasonmode.GetBool ())
goto WeaponSelectEnd;
// use knife if near and good skill (l33t dude!)
if (m_skill > 80 && pev->health > 80 && !FNullEnt (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsGroupOfEnemies (pev->origin))
// use knife if near and good difficulty (l33t dude!)
if (m_difficulty >= 3 && pev->health > 80 && !IsEntityNull (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsGroupOfEnemies (pev->origin))
goto WeaponSelectEnd;
// loop through all the weapons until terminator is found...
@ -585,7 +611,7 @@ void Bot::FireWeapon (void)
if (IsEnemyProtectedByShield (m_enemy) && !(m_currentWeapon == WEAPON_KNIFE) && IsEnemyViewable (m_enemy))
{
if (!g_bombPlanted && g_randGen.Float (0, 100) < 50)
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + g_randGen.Float (10, 20), true);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + g_randGen.Float (5, 10), true);
}
@ -597,7 +623,7 @@ void Bot::FireWeapon (void)
if (distance >= 750 || ((m_enemy->v.button & IN_ATTACK) && !IsShieldDrawn()))
{
pev->button |= (IN_ATTACK2 | IN_DUCK); // draw the shield
pev->button |= IN_ATTACK2; // draw the shield
pev->button &= ~IN_DUCK;
if (IsGroupOfEnemies (pev->origin, 3, 550) || (GetNearbyEnemiesNearPosition (pev->origin, 550) >= 3 && IsShieldDrawn ()))
@ -614,9 +640,10 @@ void Bot::FireWeapon (void)
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + g_randGen.Float (10, 20), true);
}
}
else if (IsShieldDrawn () || (!FNullEnt (m_enemy) && (m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable (m_enemy)))
else if (IsShieldDrawn () || (!IsEntityNull (m_enemy) && (m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable (m_enemy)))
{
pev->button |= (IN_ATTACK2 | IN_DUCK); // draw out the shield
if (!g_bombPlanted)
StartTask (TASK_SEEKCOVER, TASKPRI_SEEKCOVER, -1, GetWorldTime () + g_randGen.Float (10, 25), true);
}
@ -668,7 +695,7 @@ WeaponSelectEnd:
{
if ((distance >= 750) && !IsShieldDrawn ())
pev->button |= IN_ATTACK2; // draw the shield
else if (IsShieldDrawn () || (!FNullEnt (m_enemy) && (m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable(m_enemy)))
else if (IsShieldDrawn () || (!IsEntityNull (m_enemy) && (m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable(m_enemy)))
pev->button |= IN_ATTACK2; // draw out the shield
m_shieldCheckTime = GetWorldTime () + 1.0;
@ -687,14 +714,14 @@ WeaponSelectEnd:
m_zoomCheckTime = GetWorldTime ();
if (!FNullEnt (m_enemy) && (pev->velocity.x != 0 || pev->velocity.y != 0 || pev->velocity.z != 0) && (pev->basevelocity.x != 0 || pev->basevelocity.y != 0 || pev->basevelocity.z != 0))
if (!IsEntityNull (m_enemy) && (pev->velocity.x != 0 || pev->velocity.y != 0 || pev->velocity.z != 0) && (pev->basevelocity.x != 0 || pev->basevelocity.y != 0 || pev->basevelocity.z != 0))
{
m_moveSpeed = 0.0;
m_strafeSpeed = 0.0;
m_navTimeset = GetWorldTime ();
}
}
else if (UsesZoomableRifle () && m_zoomCheckTime < GetWorldTime () && m_skill < 90) // else is the bot holding a zoomable rifle?
else if (UsesZoomableRifle () && m_zoomCheckTime < GetWorldTime () && m_difficulty < 3) // else is the bot holding a zoomable rifle?
{
if (distance > 800 && pev->fov >= 90) // should the bot switch to zoomed mode?
pev->button |= IN_ATTACK2;
@ -717,15 +744,16 @@ WeaponSelectEnd:
}
const float baseDelay = delay[chosenWeaponIndex].primaryBaseDelay;
const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs ((m_skill / 20) - 5)];
const float maxDelay = delay[chosenWeaponIndex].primaryMaxDelay[abs ((m_skill / 20) - 5)];
const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs (m_difficulty - 4)];
const float maxDelay = delay[chosenWeaponIndex].primaryMaxDelay[abs (m_difficulty - 4)];
// need to care for burst fire?
if (distance < 256.0 || m_blindTime > GetWorldTime ())
{
if (selectId == WEAPON_KNIFE)
{
if (distance < 64.0)
if (distance < 102.0f)
{
if (g_randGen.Long (1, 100) < 30)
pev->button |= IN_ATTACK; // use primary attack
@ -790,7 +818,7 @@ WeaponSelectEnd:
if (!IsEnemyProtectedByShield(m_lastEnemy))
{
pev->button &= ~IN_ATTACK;
LookupEnemy();;
LookupEnemy();
}
pev->button |= IN_ATTACK;
@ -808,6 +836,9 @@ bool Bot::IsWeaponBadInDistance (int weaponIndex, float distance)
int weaponID = g_weaponSelect[weaponIndex].id;
if (weaponID == WEAPON_KNIFE)
return false;
// check is ammo available for secondary weapon
if (m_ammoInClip[g_weaponSelect[GetBestSecondaryWeaponCarried ()].id] >= 1)
return false;
@ -878,7 +909,7 @@ void Bot::FocusEnemy (void)
void Bot::CombatFight (void)
{
// no enemy? no need to do strafing
if (FNullEnt (m_enemy))
if (IsEntityNull (m_enemy))
return;
Vector enemyOrigin = m_lookAt;
@ -890,7 +921,7 @@ void Bot::CombatFight (void)
float distance = enemyOrigin.GetLength (); // how far away is the enemy scum?
if (m_timeWaypointMove + m_frameInterval < GetWorldTime ())
if (m_timeWaypointMove + m_frameInterval + 0.5f < GetWorldTime ())
{
if (m_currentWeapon == WEAPON_KNIFE)
return;
@ -916,17 +947,17 @@ void Bot::CombatFight (void)
m_fearLevel += 0.5;
CheckGrenades();
CheckThrow(EyePosition(),m_throw);
CheckThrow (EyePosition(), m_throw);
if (m_states & (STATE_SEEING_ENEMY) && !m_hasC4)
StartTask(TASK_SEEKCOVER, TASKPRI_SEEKCOVER,-1, g_randGen.Long (10, 20), true);
if ((m_states & STATE_SEEING_ENEMY) && !m_hasC4)
StartTask (TASK_SEEKCOVER, TASKPRI_SEEKCOVER, -1, g_randGen.Long (10, 20), true);
}
// If using sniper do not jump around !
if (UsesSniper () && m_states & STATE_SEEING_ENEMY || IsEnemyViewable (m_enemy) && !m_isStuck)
pev->button &= ~IN_JUMP;
// only take cover when bomb is not planted and enemy can see the bot or the bot is VIP
if (approach < 30 && !g_bombPlanted && (::IsInViewCone (pev->origin, m_enemy) || m_isVIP))
if (approach < 30 && !g_bombPlanted && (IsInViewCone (m_enemy->v.origin) || m_isVIP))
{
m_moveSpeed = -pev->maxspeed;
@ -978,7 +1009,7 @@ void Bot::CombatFight (void)
{
if (m_lastFightStyleCheck + 3.0 < GetWorldTime ())
{
if (g_randGen.Long (0, 100) < 65)
if (g_randGen.Long (0, 100) < 50)
m_fightStyle = 1;
else
m_fightStyle = 0;
@ -987,7 +1018,7 @@ void Bot::CombatFight (void)
}
}
if ((m_skill > 50 && m_fightStyle == 0) || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 500.0))
if ((m_difficulty >= 1 && m_fightStyle == 0) || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 500.0))
{
if (m_strafeSetTime < GetWorldTime ())
{
@ -1005,23 +1036,23 @@ void Bot::CombatFight (void)
if (g_randGen.Long (1, 100) < 30)
m_combatStrafeDir ^= 1;
m_strafeSetTime = GetWorldTime () + g_randGen.Float (0.5, 2.5);
m_strafeSetTime = GetWorldTime () + g_randGen.Float (0.5, 3.0);
}
if (m_combatStrafeDir == 0)
{
if (!CheckWallOnLeft ())
m_strafeSpeed = -160.0;
m_strafeSpeed = -pev->maxspeed;
else
{
m_combatStrafeDir ^= 1;
m_strafeSetTime = GetWorldTime () + 0.7;
m_strafeSetTime = GetWorldTime () + 1.0;
}
}
else
{
if (!CheckWallOnRight ())
m_strafeSpeed = 160.0;
m_strafeSpeed = -pev->maxspeed;
else
{
m_combatStrafeDir ^= 1;
@ -1029,10 +1060,10 @@ void Bot::CombatFight (void)
}
}
if (m_skill > 80 && (m_jumpTime + 5.0 < GetWorldTime () && IsOnFloor () && g_randGen.Long (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.GetLength2D () > 150.0))
if (m_difficulty >= 3 && (m_jumpTime + 5.0 < GetWorldTime () && IsOnFloor () && g_randGen.Long (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.GetLength2D () > 150.0))
pev->button |= IN_JUMP;
if (m_moveSpeed != 0.0 && distance > 150.0)
if (m_moveSpeed > 0.0 && distance > 150.0)
m_moveSpeed = 0.0;
}
else if (m_fightStyle == 1)
@ -1049,7 +1080,7 @@ void Bot::CombatFight (void)
int nearestToEnemyPoint = g_waypoint->FindNearest (m_enemy->v.origin);
if (shouldDuck && GetTaskId () != TASK_SEEKCOVER && GetTaskId () != TASK_HUNTENEMY && (m_visibility & VISIBLE_BODY) && !(m_visibility & VISIBLE_OTHER) && g_waypoint->IsDuckVisible (m_currentWaypointIndex, nearestToEnemyPoint))
m_duckTime = GetWorldTime () + (m_frameInterval * 3.5);
m_duckTime = GetWorldTime () + 1.0f;
m_moveSpeed = 0.0;
m_strafeSpeed = 0.0;
@ -1063,16 +1094,16 @@ void Bot::CombatFight (void)
m_strafeSpeed = 0.0;
}
if (m_moveSpeed != 0.0)
if (m_moveSpeed > 0.0f)
m_moveSpeed = GetWalkSpeed ();
if (m_isReloading)
{
m_moveSpeed = -pev->maxspeed;
m_duckTime = GetWorldTime () - (m_frameInterval * 4.0);
m_duckTime = GetWorldTime () - 1.0f;
}
if (!IsInWater () && !IsOnLadder () && (m_moveSpeed != 0 || m_strafeSpeed != 0.0f))
if (!IsInWater () && !IsOnLadder () && (m_moveSpeed > 0.0f || m_strafeSpeed >= 0.0f))
{
MakeVectors (pev->v_angle);
@ -1121,7 +1152,7 @@ bool Bot::IsEnemyProtectedByShield (edict_t *enemy)
{
// this function returns true, if enemy protected by the shield
if (FNullEnt (enemy) || (HasShield () && IsShieldDrawn ()))
if (IsEntityNull (enemy) || (HasShield () && IsShieldDrawn ()))
return false;
// check if enemy has shield and this shield is drawn

View file

@ -32,6 +32,7 @@ float g_timeRoundEnd = 0.0;
float g_timeRoundMid = 0.0;
float g_timeNextBombUpdate = 0.0;
float g_timeBombPlanted = 0.0;
float g_timePerSecondUpdate = 0.0;
float g_lastRadioTime[2] = {0.0, 0.0};
float g_autoPathDistance = 250.0;
@ -77,8 +78,6 @@ edict_t *g_hostEntity = NULL;
globalvars_t *g_pGlobals = NULL;
Experience *g_experienceData = NULL;
// default tables for personality weapon preferences, overridden by weapons.cfg
int g_normalWeaponPrefs[NUM_WEAPONS] =
{0, 2, 1, 4, 5, 6, 3, 12, 10, 24, 25, 13, 11, 8, 7, 22, 23, 18, 21, 17, 19, 15, 17, 9, 14, 16};
@ -95,16 +94,6 @@ int g_grenadeBuyPrecent[NUM_WEAPONS - 23] =
int g_botBuyEconomyTable[NUM_WEAPONS - 15] =
{1900, 2100, 2100, 4000, 6000, 7000, 16000, 1200, 800, 1000, 3000};
SkillDefinition g_skillTab[6] =
{
{0.8, 1.0, 45.0, 65.0, 2.0, 3.0, 40.0, 40.0, 50.0, 0, 0, 0, 50},
{0.6, 0.8, 40.0, 60.0, 3.0, 4.0, 30.0, 30.0, 42.0, 10, 0, 0, 40},
{0.4, 0.6, 35.0, 55.0, 4.0, 6.0, 20.0, 20.0, 32.0, 30, 0, 50, 35},
{0.2, 0.3, 30.0, 50.0, 6.0, 8.0, 10.0, 10.0, 18.0, 0, 30, 80, 30},
{0.1, 0.2, 25.0, 40.0, 8.0, 10.0, 5.0, 5.0, 10.0, 80, 50, 100, 23},
{0.0, 0.1, 20.0, 30.0, 9.0, 12.0, 0.0, 5.0, 0.0, 100, 100, 100, 20}
};
int *g_weaponPrefs[] =
{
g_normalWeaponPrefs,
@ -168,65 +157,65 @@ TaskItem g_taskFilters[] =
// weapons and their specifications
WeaponSelect g_weaponSelect[NUM_WEAPONS + 1] =
{
{WEAPON_KNIFE, "weapon_knife", "knife.mdl", 0, 0, -1, -1, 0, 0, 0, 0, false, true },
{WEAPON_USP, "weapon_usp", "usp.mdl", 500, 1, -1, -1, 1, 1, 2, 2, false, false},
{WEAPON_GLOCK, "weapon_glock18", "glock18.mdl", 400, 1, -1, -1, 1, 2, 1, 1, false, false},
{WEAPON_DEAGLE, "weapon_deagle", "deagle.mdl", 650, 1, 2, 2, 1, 3, 4, 4, true, false},
{WEAPON_P228, "weapon_p228", "p228.mdl", 600, 1, 2, 2, 1, 4, 3, 3, false, false},
{WEAPON_ELITE, "weapon_elite", "elite.mdl", 1000, 1, 0, 0, 1, 5, 5, 5, false, false},
{WEAPON_FIVESEVEN, "weapon_fiveseven", "fiveseven.mdl", 750, 1, 1, 1, 1, 6, 5, 5, false, false},
{WEAPON_M3, "weapon_m3", "m3.mdl", 1700, 1, 2, -1, 2, 1, 1, 1, false, false},
{WEAPON_XM1014, "weapon_xm1014", "xm1014.mdl", 3000, 1, 2, -1, 2, 2, 2, 2, false, false},
{WEAPON_MP5, "weapon_mp5navy", "mp5.mdl", 1500, 1, 2, 1, 3, 1, 2, 2, false, true },
{WEAPON_TMP, "weapon_tmp", "tmp.mdl", 1250, 1, 1, 1, 3, 2, 1, 1, false, true },
{WEAPON_P90, "weapon_p90", "p90.mdl", 2350, 1, 2, 1, 3, 3, 4, 4, false, true },
{WEAPON_MAC10, "weapon_mac10", "mac10.mdl", 1400, 1, 0, 0, 3, 4, 1, 1, false, true },
{WEAPON_UMP45, "weapon_ump45", "ump45.mdl", 1700, 1, 2, 2, 3, 5, 3, 3, false, true },
{WEAPON_AK47, "weapon_ak47", "ak47.mdl", 2500, 1, 0, 0, 4, 1, 2, 2, true, true },
{WEAPON_SG552, "weapon_sg552", "sg552.mdl", 3500, 1, 0, -1, 4, 2, 4, 4, true, true },
{WEAPON_M4A1, "weapon_m4a1", "m4a1.mdl", 3100, 1, 1, 1, 4, 3, 3, 3, true, true },
{WEAPON_GALIL, "weapon_galil", "galil.mdl", 2000, 1, 0, 0, 4, -1, 1, 1, true, true },
{WEAPON_FAMAS, "weapon_famas", "famas.mdl", 2250, 1, 1, 1, 4, -1, 1, 1, true, true },
{WEAPON_AUG, "weapon_aug", "aug.mdl", 3500, 1, 1, 1, 4, 4, 4, 4, true, true },
{WEAPON_SCOUT, "weapon_scout", "scout.mdl", 2750, 1, 2, 0, 4, 5, 3, 2, true, false},
{WEAPON_AWP, "weapon_awp", "awp.mdl", 4750, 1, 2, 0, 4, 6, 5, 6, true, false},
{WEAPON_G3SG1, "weapon_g3sg1", "g3sg1.mdl", 5000, 1, 0, 2, 4, 7, 6, 6, true, false},
{WEAPON_SG550, "weapon_sg550", "sg550.mdl", 4200, 1, 1, 1, 4, 8, 5, 5, true, false},
{WEAPON_M249, "weapon_m249", "m249.mdl", 5750, 1, 2, 1, 5, 1, 1, 1, true, true },
{WEAPON_SHIELD, "weapon_shield", "shield.mdl", 2200, 0, 1, 1, 8, -1, 8, 8, false, false},
{0, "", "", 0, 0, 0, 0, 0, 0, 0, 0, false, false}
{WEAPON_KNIFE, "weapon_knife", "knife.mdl", 0, 0, -1, -1, 0, 0, 0, 0, 0, true },
{WEAPON_USP, "weapon_usp", "usp.mdl", 500, 1, -1, -1, 1, 1, 2, 2, 0, false},
{WEAPON_GLOCK, "weapon_glock18", "glock18.mdl", 400, 1, -1, -1, 1, 2, 1, 1, 0, false},
{WEAPON_DEAGLE, "weapon_deagle", "deagle.mdl", 650, 1, 2, 2, 1, 3, 4, 4, 2, false},
{WEAPON_P228, "weapon_p228", "p228.mdl", 600, 1, 2, 2, 1, 4, 3, 3, 0, false},
{WEAPON_ELITE, "weapon_elite", "elite.mdl", 1000, 1, 0, 0, 1, 5, 5, 5, 0, false},
{WEAPON_FIVESEVEN, "weapon_fiveseven", "fiveseven.mdl", 750, 1, 1, 1, 1, 6, 5, 5, 0, false},
{WEAPON_M3, "weapon_m3", "m3.mdl", 1700, 1, 2, -1, 2, 1, 1, 1, 0, false},
{WEAPON_XM1014, "weapon_xm1014", "xm1014.mdl", 3000, 1, 2, -1, 2, 2, 2, 2, 0, false},
{WEAPON_MP5, "weapon_mp5navy", "mp5.mdl", 1500, 1, 2, 1, 3, 1, 2, 2, 0, true },
{WEAPON_TMP, "weapon_tmp", "tmp.mdl", 1250, 1, 1, 1, 3, 2, 1, 1, 0, true },
{WEAPON_P90, "weapon_p90", "p90.mdl", 2350, 1, 2, 1, 3, 3, 4, 4, 0, true },
{WEAPON_MAC10, "weapon_mac10", "mac10.mdl", 1400, 1, 0, 0, 3, 4, 1, 1, 0, true },
{WEAPON_UMP45, "weapon_ump45", "ump45.mdl", 1700, 1, 2, 2, 3, 5, 3, 3, 0, true },
{WEAPON_AK47, "weapon_ak47", "ak47.mdl", 2500, 1, 0, 0, 4, 1, 2, 2, 2, true },
{WEAPON_SG552, "weapon_sg552", "sg552.mdl", 3500, 1, 0, -1, 4, 2, 4, 4, 2, true },
{WEAPON_M4A1, "weapon_m4a1", "m4a1.mdl", 3100, 1, 1, 1, 4, 3, 3, 3, 2, true },
{WEAPON_GALIL, "weapon_galil", "galil.mdl", 2000, 1, 0, 0, 4, -1, 1, 1, 2, true },
{WEAPON_FAMAS, "weapon_famas", "famas.mdl", 2250, 1, 1, 1, 4, -1, 1, 1, 2, true },
{WEAPON_AUG, "weapon_aug", "aug.mdl", 3500, 1, 1, 1, 4, 4, 4, 4, 2, true },
{WEAPON_SCOUT, "weapon_scout", "scout.mdl", 2750, 1, 2, 0, 4, 5, 3, 2, 3, false},
{WEAPON_AWP, "weapon_awp", "awp.mdl", 4750, 1, 2, 0, 4, 6, 5, 6, 3, false},
{WEAPON_G3SG1, "weapon_g3sg1", "g3sg1.mdl", 5000, 1, 0, 2, 4, 7, 6, 6, 3, false},
{WEAPON_SG550, "weapon_sg550", "sg550.mdl", 4200, 1, 1, 1, 4, 8, 5, 5, 3, false},
{WEAPON_M249, "weapon_m249", "m249.mdl", 5750, 1, 2, 1, 5, 1, 1, 1, 2, true },
{WEAPON_SHIELD, "weapon_shield", "shield.mdl", 2200, 0, 1, 1, 8, -1, 8, 8, 0, false},
{0, "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
};
// weapon firing delay based on skill (min and max delay for each weapon)
FireDelay g_fireDelay[NUM_WEAPONS + 1] =
{
{WEAPON_KNIFE, 255, 256, 0.10, {0.0, 0.2, 0.3, 0.4, 0.6, 0.8}, {0.1, 0.3, 0.5, 0.7, 1.0, 1.2}, 0.0, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}},
{WEAPON_USP, 3, 853, 0.15, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_GLOCK, 5, 853, 0.15, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_DEAGLE, 2, 640, 0.20, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_P228, 4, 853, 0.14, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_ELITE, 3, 640, 0.20, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_FIVESEVEN, 4, 731, 0.14, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_M3, 8, 365, 0.86, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_XM1014, 7, 512, 0.15, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_MP5, 4, 731, 0.10, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_TMP, 3, 731, 0.05, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_P90, 4, 731, 0.10, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_MAC10, 3, 731, 0.06, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_UMP45, 4, 731, 0.15, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_AK47, 2, 512, 0.09, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_SG552, 3, 512, 0.11, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_M4A1, 3, 512, 0.08, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_GALIL, 4, 512, 0.09, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_FAMAS, 4, 512, 0.10, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_AUG, 3, 512, 0.11, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_SCOUT, 10, 256, 0.18, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_AWP, 10, 170, 0.22, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_G3SG1, 4, 256, 0.25, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_SG550, 4, 256, 0.25, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_M249, 3, 640, 0.10, {0.0, 0.1, 0.2, 0.3, 0.4, 0.6}, {0.1, 0.2, 0.3, 0.4, 0.5, 0.7}, 0.2, {0.0, 0.0, 0.1, 0.1, 0.2}, {0.1, 0.1, 0.2, 0.2, 0.4}},
{WEAPON_SHIELD, 0, 256, 0.00, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 0.0, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}},
{0, 0, 256, 0.00, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 0.0, {0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0}}
{ WEAPON_KNIFE, 255, 256, 0.10f,{ 0.0f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f },{ 0.1f, 0.3f, 0.5f, 0.7f, 1.0f, 1.2f }, 0.0f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
{ WEAPON_USP, 3, 853, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_GLOCK, 5, 853, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_DEAGLE, 2, 640, 0.20f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_P228, 4, 853, 0.14f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_ELITE, 3, 640, 0.20f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_FIVESEVEN, 4, 731, 0.14f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_M3, 8, 365, 0.86f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_XM1014, 7, 512, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_MP5, 4, 731, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_TMP, 3, 731, 0.05f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_P90, 4, 731, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_MAC10, 3, 731, 0.06f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_UMP45, 4, 731, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_AK47, 2, 512, 0.09f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SG552, 3, 512, 0.11f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_M4A1, 3, 512, 0.08f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_GALIL, 4, 512, 0.09f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_FAMAS, 4, 512, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_AUG, 3, 512, 0.11f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SCOUT, 10, 256, 0.18f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_AWP, 10, 170, 0.22f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_G3SG1, 4, 256, 0.25f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SG550, 4, 256, 0.25f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_M249, 3, 640, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SHIELD, 0, 256, 0.00f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, 0.0f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
{ 0, 0, 256, 0.00f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, 0.0f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }
};
@ -236,8 +225,8 @@ MenuText g_menus[21] =
// main menu
{
0x2ff,
"\\yYaPB Main Menu\\w\v\v"
"1. YaPB Control\v"
"\\yMain Menu\\w\v\v"
"1. Control Bots\v"
"2. Features\v\v"
"3. Fill Server\v"
"4. End Round\v\v"
@ -247,7 +236,7 @@ MenuText g_menus[21] =
// bot features menu
{
0x25f,
"\\yYaPB Features\\w\v\v"
"\\yBots Features\\w\v\v"
"1. Weapon Mode Menu\v"
"2. Waypoint Menu\v"
"3. Select Personality\v\v"
@ -259,7 +248,7 @@ MenuText g_menus[21] =
// bot control menu
{
0x2ff,
"\\yYaPB Control Menu\\w\v\v"
"\\yBots Control Menu\\w\v\v"
"1. Add a Bot, Quick\v"
"2. Add a Bot, Specified\v\v"
"3. Remove Random Bot\v"
@ -271,7 +260,7 @@ MenuText g_menus[21] =
// weapon mode select menu
{
0x27f,
"\\yYaPB Weapon Mode\\w\v\v"
"\\yBots Weapon Mode\\w\v\v"
"1. Knives only\v"
"2. Pistols only\v"
"3. Shotguns only\v"
@ -285,7 +274,7 @@ MenuText g_menus[21] =
// personality select menu
{
0x20f,
"\\yYaPB Personality\\w\v\v"
"\\yBots Personality\\w\v\v"
"1. Random\v"
"2. Normal\v"
"3. Aggressive\v"
@ -293,16 +282,15 @@ MenuText g_menus[21] =
"0. Exit"
},
// skill select menu
// difficulty select menu
{
0x23f,
"\\yYaPB Skill Level\\w\v\v"
"1. Stupid (0-20)\v"
"2. Newbie (20-40)\v"
"3. Average (40-60)\v"
"4. Advanced (60-80)\v"
"5. Professional (80-99)\v"
"6. Godlike (100)\v\v"
"\\yBots Difficulty Level\\w\v\v"
"1. Newbie\v"
"2. Average\v"
"3. Normal\v"
"4. Professional\v"
"4. Godlike\v"
"0. Exit"
},

View file

@ -11,7 +11,7 @@
// console vars
ConVar yb_password ("yb_password", "", VT_PASSWORD);
ConVar yb_password_key ("yb_password_key", "_ybwp");
ConVar yb_password_key ("yb_password_key", "_ybwp", VT_NOSERVER);
ConVar yb_language ("yb_language", "en");
ConVar yb_version ("yb_version", PRODUCT_VERSION, VT_READONLY);
@ -24,9 +24,9 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
if (stricmp (arg0, "addbot") == 0 || stricmp (arg0, "add") == 0)
g_botManager->AddBot (arg4, arg1, arg2, arg3, arg5);
// adding one bot with high skill parameters to random team
// adding one bot with high difficuluty parameters to random team
if (stricmp (arg0, "addbot_hs") == 0 || stricmp (arg0, "addhs") == 0)
g_botManager->AddBot (arg4, "100", "1", arg3, arg5);
g_botManager->AddBot (arg4, "4", "1", arg3, arg5);
// adding one bot with random parameters to terrorist team
else if (stricmp (arg0, "addbot_t") == 0 || stricmp (arg0, "add_t") == 0)
@ -122,12 +122,12 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
if (IsNullString (arg1))
return 1;
edict_t *ent = EntityOfIndex (atoi (arg1) - 1);
edict_t *target = EntityOfIndex (atoi (arg1) - 1);
if (IsValidBot (ent))
if (IsValidBot (target))
{
FakeClientCommand (ent, arg2);
ClientPrint (ent, print_withtag, "Bot %s executing command %s", STRING (ent->v.netname), arg2);
FakeClientCommand (target, arg2);
ClientPrint (ent, print_withtag, "Bot %s executing command %s", STRING (target->v.netname), arg2);
}
else
ClientPrint (ent, print_withtag, "Player is not BOT!");
@ -280,7 +280,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// waypoint manimupulation (really obsolete, can be edited through menu) (supported only on listen server)
else if (stricmp (arg0, "waypoint") == 0 || stricmp (arg0, "wp") == 0 || stricmp (arg0, "wpt") == 0)
{
if (IsDedicatedServer () || FNullEnt (g_hostEntity))
if (IsDedicatedServer () || IsEntityNull (g_hostEntity))
return 2;
// enables or disable waypoint displaying
@ -325,11 +325,11 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
if (stricmp (arg2, "on") == 0)
{
while (!FNullEnt (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start")))
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start")))
spawnEntity->v.effects &= ~EF_NODRAW;
while (!FNullEnt (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch")))
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch")))
spawnEntity->v.effects &= ~EF_NODRAW;
while (!FNullEnt (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start")))
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start")))
spawnEntity->v.effects &= ~EF_NODRAW;
ServerCommand ("mp_roundtime 9"); // reset round time to maximum
@ -338,11 +338,11 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
}
else if (stricmp (arg2, "off") == 0)
{
while (!FNullEnt (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start")))
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start")))
spawnEntity->v.effects |= EF_NODRAW;
while (!FNullEnt (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch")))
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch")))
spawnEntity->v.effects |= EF_NODRAW;
while (!FNullEnt (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start")))
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start")))
spawnEntity->v.effects |= EF_NODRAW;
}
}
@ -448,7 +448,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// path waypoint editing system (supported only on listen server)
else if (stricmp (arg0, "pathwaypoint") == 0 || stricmp (arg0, "path") == 0 || stricmp (arg0, "pwp") == 0)
{
if (IsDedicatedServer () || FNullEnt (g_hostEntity))
if (IsDedicatedServer () || IsEntityNull (g_hostEntity))
return 2;
// opens path creation menu
@ -479,7 +479,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// automatic waypoint handling (supported only on listen server)
else if (stricmp (arg0, "autowaypoint") == 0 || stricmp (arg0, "autowp") == 0)
{
if (IsDedicatedServer () || FNullEnt (g_hostEntity))
if (IsDedicatedServer () || IsEntityNull (g_hostEntity))
return 2;
// enable autowaypointing
@ -500,7 +500,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// experience system handling (supported only on listen server)
else if (stricmp (arg0, "experience") == 0 || stricmp (arg0, "exp") == 0)
{
if (IsDedicatedServer () || FNullEnt (g_hostEntity))
if (IsDedicatedServer () || IsEntityNull (g_hostEntity))
return 2;
// write experience table (and visibility table) to hard disk
@ -557,10 +557,9 @@ void ParseVoiceEvent (const String &base, int type, float timeToRepeat)
void InitConfig (void)
{
File fp;
char command[80], line[256];
char line[256];
KeywordFactory replyKey;
int chatType = -1;
// fixes for crashing if configs couldn't be accessed
g_chatFactory.SetSize (CHAT_TOTAL);
@ -593,47 +592,50 @@ void InitConfig (void)
// CHAT SYSTEM CONFIG INITIALIZATION
if (OpenConfig ("chat.cfg", "Chat file not found.", &fp, true))
{
char section[80];
int chatType = -1;
while (fp.GetBuffer (line, 255))
{
SKIP_COMMENTS ();
strcpy (command, GetField (line, 0, 1));
strcpy (section, GetField (line, 0, 1));
if (strcmp (command, "[KILLED]") == 0)
if (strcmp (section, "[KILLED]") == 0)
{
chatType = 0;
continue;
}
else if (strcmp (command, "[BOMBPLANT]") == 0)
else if (strcmp (section, "[BOMBPLANT]") == 0)
{
chatType = 1;
continue;
}
else if (strcmp (command, "[DEADCHAT]") == 0)
else if (strcmp (section, "[DEADCHAT]") == 0)
{
chatType = 2;
continue;
}
else if (strcmp (command, "[REPLIES]") == 0)
else if (strcmp (section, "[REPLIES]") == 0)
{
chatType = 3;
continue;
}
else if (strcmp (command, "[UNKNOWN]") == 0)
else if (strcmp (section, "[UNKNOWN]") == 0)
{
chatType = 4;
continue;
}
else if (strcmp (command, "[TEAMATTACK]") == 0)
else if (strcmp (section, "[TEAMATTACK]") == 0)
{
chatType = 5;
continue;
}
else if (strcmp (command, "[WELCOME]") == 0)
else if (strcmp (section, "[WELCOME]") == 0)
{
chatType = 6;
continue;
}
else if (strcmp (command, "[TEAMKILL]") == 0)
else if (strcmp (section, "[TEAMKILL]") == 0)
{
chatType = 7;
continue;
@ -777,64 +779,6 @@ void InitConfig (void)
for (int i = 0; i < NUM_WEAPONS; i++)
g_carefulWeaponPrefs[i] = splitted[i].ToInt ();
}
else if (pair[0].Contains ("Skill"))
{
if (splitted.GetElementNumber () != 8)
AddLogEntry (true, LL_FATAL, "%s entry in general config is not valid.", pair[0].GetBuffer ());
int parserState = 0;
if (pair[0].Contains ("Stupid"))
parserState = 0;
else if (pair[0].Contains ("Newbie"))
parserState = 1;
else if (pair[0].Contains ("Average"))
parserState = 2;
else if (pair[0].Contains ("Advanced"))
parserState = 3;
else if (pair[0].Contains ("Professional"))
parserState = 4;
else if (pair[0].Contains ("Godlike"))
parserState = 5;
for (int i = 0; i < 8; i++)
{
switch (i)
{
case 0:
g_skillTab[parserState].minSurpriseTime = splitted[i].ToFloat ();
break;
case 1:
g_skillTab[parserState].maxSurpriseTime = splitted[i].ToFloat ();
break;
case 2:
g_skillTab[parserState].minTurnSpeed = splitted[i].ToFloat ();
break;
case 3:
g_skillTab[parserState].maxTurnSpeed = splitted[i].ToFloat ();
break;
case 4:
g_skillTab[parserState].headshotFrequency = splitted[i].ToInt ();
break;
case 5:
g_skillTab[parserState].heardShootThruProb = splitted[i].ToInt ();
break;
case 6:
g_skillTab[parserState].seenShootThruProb = splitted[i].ToInt ();
break;
case 7:
g_skillTab[parserState].recoilAmount = splitted[i].ToInt ();
break;
}
}
}
}
fp.Close ();
}
@ -1013,6 +957,8 @@ void InitConfig (void)
g_weaponPrefs[PERSONALITY_NORMAL] = reinterpret_cast <int *> (&g_normalWeaponPrefs);
g_weaponPrefs[PERSONALITY_RUSHER] = reinterpret_cast <int *> (&g_rusherWeaponPrefs);
g_weaponPrefs[PERSONALITY_CAREFUL] = reinterpret_cast <int *> (&g_carefulWeaponPrefs);
g_timePerSecondUpdate = 0.0f;
}
void CommandHandler_NotMM (void)
@ -1772,27 +1718,23 @@ void ClientCommand (edict_t *ent)
switch (selection)
{
case 1:
g_storeAddbotVars[0] = g_randGen.Long (0, 20);
g_storeAddbotVars[0] = 0;
break;
case 2:
g_storeAddbotVars[0] = g_randGen.Long (20, 40);
g_storeAddbotVars[0] = 1;
break;
case 3:
g_storeAddbotVars[0] = g_randGen.Long (40, 60);
g_storeAddbotVars[0] = 2;
break;
case 4:
g_storeAddbotVars[0] = g_randGen.Long (60, 80);
g_storeAddbotVars[0] = 3;
break;
case 5:
g_storeAddbotVars[0] = g_randGen.Long (80, 99);
break;
case 6:
g_storeAddbotVars[0] = 100;
g_storeAddbotVars[0] = 4;
break;
case 10:
@ -2102,17 +2044,17 @@ void ClientCommand (edict_t *ent)
if (!(g_clients[i].flags & CF_USED) || (team != -1 && team != g_clients[i].team) || isAlive != IsAlive (g_clients[i].ent))
continue;
Bot *bot = g_botManager->GetBot (i);
Bot *target = g_botManager->GetBot (i);
if (bot != NULL)
if (target != NULL)
{
bot->m_sayTextBuffer.entityIndex = IndexOfEntity (ent);
target->m_sayTextBuffer.entityIndex = IndexOfEntity (ent);
if (IsNullString (CMD_ARGS ()))
continue;
strcpy (bot->m_sayTextBuffer.sayText, CMD_ARGS ());
bot->m_sayTextBuffer.timeNextChat = GetWorldTime () + bot->m_sayTextBuffer.chatDelay;
strcpy (target->m_sayTextBuffer.sayText, CMD_ARGS ());
target->m_sayTextBuffer.timeNextChat = GetWorldTime () + target->m_sayTextBuffer.chatDelay;
}
}
}
@ -2227,7 +2169,7 @@ void StartFrame (void)
{
edict_t *player = EntityOfIndex (i + 1);
if (!FNullEnt (player) && (player->v.flags & FL_CLIENT))
if (!IsEntityNull (player) && (player->v.flags & FL_CLIENT))
{
g_clients[i].ent = player;
g_clients[i].flags |= CF_USED;
@ -2253,13 +2195,12 @@ void StartFrame (void)
g_clients[i].ent = NULL;
}
}
static float secondTimer = 0.0;
// **** AI EXECUTION STARTS ****
g_botManager->Think ();
// **** AI EXECUTION FINISH ****
if (!IsDedicatedServer () && !FNullEnt (g_hostEntity))
if (!IsDedicatedServer () && !IsEntityNull (g_hostEntity))
{
if (g_waypointOn)
g_waypoint->Think ();
@ -2268,14 +2209,16 @@ void StartFrame (void)
}
g_botManager->SetDeathMsgState (false);
if (secondTimer < GetWorldTime ())
if (g_timePerSecondUpdate <= GetWorldTime ())
{
g_botManager->CalculatePingOffsets ();
for (int i = 0; i < GetMaxClients (); i++)
{
edict_t *player = EntityOfIndex (i + 1);
// code below is executed only on dedicated server
if (IsDedicatedServer () && !FNullEnt (player) && (player->v.flags & FL_CLIENT) && !(player->v.flags & FL_FAKECLIENT))
if (IsDedicatedServer () && !IsEntityNull (player) && (player->v.flags & FL_CLIENT) && !(player->v.flags & FL_FAKECLIENT))
{
if (g_clients[i].flags & CF_ADMIN)
{
@ -2305,7 +2248,7 @@ void StartFrame (void)
if (csdm_active != NULL && csdm_active->value > 0)
yb_csdm_mode.SetInt (mp_freeforall != NULL && mp_freeforall->value > 0 ? 2 : 1);
}
g_botManager->CalculatePingOffsets ();
g_timePerSecondUpdate = GetWorldTime () + 1.0f;
}
extern ConVar yb_danger_factor;
@ -2313,8 +2256,6 @@ void StartFrame (void)
if (yb_danger_factor.GetFloat () >= 4096)
yb_danger_factor.SetFloat (4096.0);
secondTimer = GetWorldTime () + 1.5;
if (g_bombPlanted)
g_waypoint->SetBombPosition ();
}
@ -2486,7 +2427,7 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed
g_netMsg->HandleMessageIfRequired (msgType, NETMSG_WEAPONLIST);
if (!FNullEnt (ed))
if (!IsEntityNull (ed))
{
int index = g_botManager->GetIndex (ed);
@ -2626,11 +2567,6 @@ void pfnWriteCoord (float value)
void pfnWriteString (const char *sz)
{
Bot *bot = g_botManager->FindOneValidAliveBot ();
if (bot != NULL && IsAlive (bot->GetEntity ()))
bot->HandleChatterMessage (sz);
// if this message is for a bot, call the client message function...
g_netMsg->Execute ((void *) sz);
@ -2691,16 +2627,16 @@ const char *pfnCmd_Args (void)
if (strncmp ("say ", g_fakeArgv, 4) == 0)
{
if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, g_fakeArgv + 4);
RETURN_META_VALUE (MRES_SUPERCEDE, &g_fakeArgv[4]);
return g_fakeArgv + 4; // skip the "say" bot client command
return &g_fakeArgv[4]; // skip the "say" bot client command
}
else if (strncmp ("say_team ", g_fakeArgv, 9) == 0)
{
if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, g_fakeArgv + 9);
RETURN_META_VALUE (MRES_SUPERCEDE, &g_fakeArgv[9]);
return g_fakeArgv + 9; // skip the "say_team" bot client command
return &g_fakeArgv[9]; // skip the "say_team" bot client command
}
if (g_isMetamod)
@ -3172,7 +3108,6 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
g_convarWrapper->PushRegisteredConVarsToEngine ();
ModSupport_t *knownMod = NULL;
char gameDLLName[256];
for (int i = 0; s_supportedMods[i].name; i++)
{
@ -3200,6 +3135,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
if (g_isMetamod)
return; // we should stop the attempt for loading the real gamedll, since metamod handle this for us
char gameDLLName[256];
sprintf (gameDLLName, "%s/dlls/%s", knownMod->name,
#if defined (PLATFORM_WIN32)

View file

@ -1,4 +1,4 @@
//
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
@ -14,15 +14,13 @@ ConVar yb_autovacate ("yb_autovacate", "-1");
ConVar yb_quota ("yb_quota", "0");
ConVar yb_quota_match ("yb_quota_match", "0");
ConVar yb_quota_match_max ("yb_quota_match_max", "0");
ConVar yb_join_after_player ("yb_join_after_player", "0");
ConVar yb_join_after_player ("yb_join_after_player", "0", VT_NOSERVER);
ConVar yb_join_team ("yb_join_team", "any");
ConVar yb_name_prefix ("yb_name_prefix", "");
ConVar yb_minskill ("yb_minskill", "60");
ConVar yb_maxskill ("yb_maxskill", "100");
ConVar yb_name_prefix ("yb_name_prefix", "", VT_NOSERVER);
ConVar yb_difficulty ("yb_difficulty", "4");
ConVar yb_skill_tags ("yb_skill_tags", "0");
ConVar yb_latency_display ("yb_latency_display", "2");
BotManager::BotManager (void)
@ -66,9 +64,9 @@ void BotManager::CallGameEntity (entvars_t *vars)
(*playerFunction) (vars);
}
int BotManager::CreateBot (String name, int skill, int personality, int team, int member)
int BotManager::CreateBot (String name, int difficulty, int personality, int team, int member)
{
// this function completely prepares bot entity (edict) for creation, creates team, skill, sets name etc, and
// this function completely prepares bot entity (edict) for creation, creates team, difficulty, sets name etc, and
// then sends result to bot constructor
@ -86,11 +84,14 @@ int BotManager::CreateBot (String name, int skill, int personality, int team, in
return 0;
}
if (skill < 0 || skill > 100)
skill = g_randGen.Long (yb_minskill.GetInt (), yb_maxskill.GetInt ());
if (difficulty < 0 || difficulty > 4)
difficulty = yb_difficulty.GetInt ();
if (skill > 100 || skill < 0)
skill = g_randGen.Long (0, 100);
if (difficulty < 0 || difficulty > 4)
{
difficulty = g_randGen.Long (3, 4);
yb_difficulty.SetInt (difficulty);
}
if (personality < 0 || personality > 2)
{
@ -117,13 +118,16 @@ int BotManager::CreateBot (String name, int skill, int personality, int team, in
if (nameFound)
break;
BotName *name = &g_botNames.GetRandomElement ();
BotName *pickedName = &g_botNames.GetRandomElement ();
if (name == NULL || (name != NULL && name->used))
if (pickedName == NULL)
continue;
name->used = nameFound = true;
strcpy (outputName, name->name);
if (pickedName->used)
continue;
pickedName->used = nameFound = true;
strcpy (outputName, pickedName->name);
}
}
else
@ -132,25 +136,19 @@ int BotManager::CreateBot (String name, int skill, int personality, int team, in
else
strncpy (outputName, name, 21);
if (!IsNullString (yb_name_prefix.GetString ()) || yb_skill_tags.GetBool ())
if (!IsNullString (yb_name_prefix.GetString ()))
{
char prefixedName[33]; // temp buffer for storing modified name
if (!IsNullString (yb_name_prefix.GetString ()))
sprintf (prefixedName, "%s %s", yb_name_prefix.GetString (), outputName);
else if (yb_skill_tags.GetBool ())
sprintf (prefixedName, "%s (%d)", outputName, skill);
else if (!IsNullString (yb_name_prefix.GetString ()) && yb_skill_tags.GetBool ())
sprintf (prefixedName, "%s %s (%d)", yb_name_prefix.GetString (), outputName, skill);
// buffer has been modified, copy to real name
if (!IsNullString (prefixedName))
strcpy (outputName, prefixedName);
}
if (FNullEnt ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName))))
if (IsEntityNull ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName))))
{
CenterPrint ("Maximum players reached (%d/%d). Unable to create Bot.", GetMaxClients (), GetMaxClients ());
return 2;
@ -161,12 +159,12 @@ int BotManager::CreateBot (String name, int skill, int personality, int team, in
InternalAssert (index >= 0 && index <= 32); // check index
InternalAssert (m_bots[index] == NULL); // check bot slot
m_bots[index] = new Bot (bot, skill, personality, team, member);
m_bots[index] = new Bot (bot, difficulty, personality, team, member);
if (m_bots == NULL)
TerminateOnMalloc ();
ServerPrint ("Connecting Bot... (Skill %d)", skill);
ServerPrint ("Connecting Bot...");
return 1;
}
@ -174,7 +172,7 @@ int BotManager::CreateBot (String name, int skill, int personality, int team, in
int BotManager::GetIndex (edict_t *ent)
{
// this function returns index of bot (using own bot array)
if (FNullEnt (ent))
if (IsEntityNull (ent))
return -1;
int index = IndexOfEntity (ent) - 1;
@ -257,7 +255,7 @@ void BotManager::Think (void)
}
}
void BotManager::AddBot (const String &name, int skill, int personality, int team, int member)
void BotManager::AddBot (const String &name, int difficulty, int personality, int team, int member)
{
// this function putting bot creation process to queue to prevent engine crashes
@ -265,7 +263,7 @@ void BotManager::AddBot (const String &name, int skill, int personality, int tea
// fill the holder
bot.name = name;
bot.skill = skill;
bot.difficulty = difficulty;
bot.personality = personality;
bot.team = team;
bot.member = member;
@ -278,18 +276,18 @@ void BotManager::AddBot (const String &name, int skill, int personality, int tea
yb_quota.SetInt (GetBotsNum () + 1);
}
void BotManager::AddBot (String name, String skill, String personality, String team, String member)
void BotManager::AddBot (String name, String difficulty, String personality, String team, String member)
{
// this function is same as the function above, but accept as parameters string instead of integers
CreateQueue bot;
const String &any = "*";
bot.name = (name.IsEmpty () || (name == any)) ? String ("\0") : name;
bot.skill = (skill.IsEmpty () || (skill == any)) ? -1 : skill.ToInt ();
bot.team = (team.IsEmpty () || (team == any)) ? -1 : team.ToInt ();
bot.member = (member.IsEmpty () || (member == any)) ? -1 : member.ToInt ();
bot.personality = (personality.IsEmpty () || (personality == any)) ? -1 : personality.ToInt ();
bot.name = (name.IsEmpty () || name == any) ? String ("\0") : name;
bot.difficulty = (difficulty.IsEmpty () || difficulty == any) ? -1 : difficulty.ToInt ();
bot.team = (team.IsEmpty () || team == any) ? -1 : team.ToInt ();
bot.member = (member.IsEmpty () || member == any) ? -1 : member.ToInt ();
bot.personality = (personality.IsEmpty () || personality == any) ? -1 : personality.ToInt ();
m_creationTab.Push (bot);
@ -320,12 +318,12 @@ void BotManager::MaintainBotQuota (void)
if (!m_creationTab.IsEmpty () && m_maintainTime < GetWorldTime ())
{
CreateQueue last = m_creationTab.Pop ();
int resultOfCall = CreateBot (last.name, last.skill, last.personality, last.team, last.member);
int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member);
// check the result of creation
if (resultOfCall == 0)
{
m_creationTab.RemoveAll (); // something worng with waypoints, reset tab of creation
m_creationTab.RemoveAll (); // something wrong with waypoints, reset tab of creation
yb_quota.SetInt (0); // reset quota
}
else if (resultOfCall == 2)
@ -392,7 +390,7 @@ void BotManager::InitQuota (void)
m_creationTab.RemoveAll ();
}
void BotManager::FillServer (int selection, int personality, int skill, int numToAdd)
void BotManager::FillServer (int selection, int personality, int difficulty, int numToAdd)
{
// this function fill server with bots, with specified team & personality
@ -420,26 +418,7 @@ void BotManager::FillServer (int selection, int personality, int skill, int numT
int toAdd = numToAdd == -1 ? GetMaxClients () - (GetHumansNum () + GetBotsNum ()) : numToAdd;
for (int i = 0; i <= toAdd; i++)
{
// since we got constant skill from menu (since creation process call automatic), we need to manually
// randomize skill here, on given skill there.
int randomizedSkill = 0;
if (skill >= 0 && skill <= 20)
randomizedSkill = g_randGen.Long (0, 20);
else if (skill > 20 && skill <= 40)
randomizedSkill = g_randGen.Long (20, 40);
else if (skill > 40 && skill <= 60)
randomizedSkill = g_randGen.Long (40, 60);
else if (skill > 60 && skill <= 80)
randomizedSkill = g_randGen.Long (60, 80);
else if (skill > 80 && skill <= 99)
randomizedSkill = g_randGen.Long (80, 99);
else if (skill == 100)
randomizedSkill = skill;
AddBot ("", randomizedSkill, personality, selection, -1);
}
AddBot ("", difficulty, personality, selection, -1);
yb_quota.SetInt (toAdd);
yb_quota_match.SetInt (0);
@ -503,16 +482,16 @@ void BotManager::RemoveMenu (edict_t *ent, int selection)
for (int i = ((selection - 1) * 8); i < selection * 8; i++)
{
if ((m_bots[i] != NULL) && !FNullEnt (m_bots[i]->GetEntity ()))
if ((m_bots[i] != NULL) && !IsEntityNull (m_bots[i]->GetEntity ()))
{
validSlots |= 1 << (i - ((selection - 1) * 8));
sprintf (buffer, "%s %1.1d. %s%s\n", buffer, i - ((selection - 1) * 8) + 1, STRING (m_bots[i]->pev->netname), GetTeam (m_bots[i]->GetEntity ()) == TEAM_CF ? " \\y(CT)\\w" : " \\r(T)\\w");
}
else
sprintf (buffer, "%s\\d %1.1d. Not a YaPB\\w\n", buffer, i - ((selection - 1) * 8) + 1);
sprintf (buffer, "%s\\d %1.1d. Not a Bot\\w\n", buffer, i - ((selection - 1) * 8) + 1);
}
sprintf (tempBuffer, "\\yYaPB Remove Menu (%d/4):\\w\n\n%s\n%s 0. Back", selection, buffer, (selection == 4) ? "" : " 9. More...\n");
sprintf (tempBuffer, "\\yBots Remove Menu (%d/4):\\w\n\n%s\n%s 0. Back", selection, buffer, (selection == 4) ? "" : " 9. More...\n");
switch (selection)
{
@ -633,7 +612,7 @@ void BotManager::ListBots (void)
{
// this function list's bots currently playing on the server
ServerPrintNoTag ("%-3.5s %-9.13s %-17.18s %-3.4s %-3.4s %-3.4s", "index", "name", "personality", "team", "skill", "frags");
ServerPrintNoTag ("%-3.5s %-9.13s %-17.18s %-3.4s %-3.4s %-3.4s", "index", "name", "personality", "team", "difficulty", "frags");
for (int i = 0; i < GetMaxClients (); i++)
{
@ -645,7 +624,7 @@ void BotManager::ListBots (void)
Bot *bot = GetBot (player);
if (bot != NULL)
ServerPrintNoTag ("[%-3.1d] %-9.13s %-17.18s %-3.4s %-3.1d %-3.1d", i, STRING (player->v.netname), bot->m_personality == PERSONALITY_RUSHER ? "rusher" : bot->m_personality == PERSONALITY_NORMAL ? "normal" : "careful", GetTeam (player) != 0 ? "CT" : "T", bot->m_skill, static_cast <int> (player->v.frags));
ServerPrintNoTag ("[%-3.1d] %-9.13s %-17.18s %-3.4s %-3.1d %-3.1d", i, STRING (player->v.netname), bot->m_personality == PERSONALITY_RUSHER ? "rusher" : bot->m_personality == PERSONALITY_NORMAL ? "normal" : "careful", GetTeam (player) != 0 ? "CT" : "T", bot->m_difficulty, static_cast <int> (player->v.frags));
}
}
}
@ -735,10 +714,7 @@ void BotManager::Free (void)
// this function free all bots slots (used on server shutdown)
for (int i = 0; i < 32; i++)
{
if (m_bots[i] != NULL)
Free (i);
}
Free (i);
}
void BotManager::Free (int index)
@ -749,7 +725,7 @@ void BotManager::Free (int index)
m_bots[index] = NULL;
}
Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member)
{
// this function does core operation of creating bot, it's called by CreateBot (),
// when bot setup completed, (this is a bot class constructor)
@ -759,7 +735,7 @@ Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
memset (this, 0, sizeof (Bot));
pev = VARS (bot);
pev = &bot->v;
if (bot->pvPrivateData != NULL)
FREE_PRIVATE (bot);
@ -771,18 +747,7 @@ Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
BotManager::CallGameEntity (&bot->v);
// set all info buffer keys for this bot
char *buffer = GET_INFOKEYBUFFER (bot);
SET_CLIENT_KEYVALUE (clientIndex, buffer, "model", "");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "rate", "3500.000000");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_updaterate", "20");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lw", "0");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lc", "0");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "tracker", "0");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_dlmax", "128");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "friends", "0");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "dm", "0");
SET_CLIENT_KEYVALUE (clientIndex, buffer, "_ah", "0");
char *buffer = GET_INFOKEYBUFFER (bot);;
SET_CLIENT_KEYVALUE (clientIndex, buffer, "_vgui_menus", "0");
if (g_gameVersion != CSV_OLD && yb_latency_display.GetInt () == 1)
@ -791,6 +756,9 @@ Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
rejectReason[0] = 0; // reset the reject reason template string
MDLL_ClientConnect (bot, "BOT", FormatBuffer ("127.0.0.%d", IndexOfEntity (bot) + 100), rejectReason);
memset (&m_pingOffset, 0, sizeof (m_pingOffset));
memset (&m_ping, 0, sizeof (m_ping));
if (!IsNullString (rejectReason))
{
AddLogEntry (true, LL_WARNING, "Server refused '%s' connection (%s)", STRING (bot->v.netname), rejectReason);
@ -816,17 +784,24 @@ Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
m_sayTextBuffer.chatProbability = g_randGen.Long (1, 100);
m_notKilled = false;
m_skill = skill;
m_weaponBurstMode = BM_OFF;
m_difficulty = difficulty;
if (difficulty < 0 || difficulty > 4)
{
difficulty = g_randGen.Long (3, 4);
yb_difficulty.SetInt (difficulty);
}
m_lastThinkTime = GetWorldTime () - 0.1f;
m_frameInterval = GetWorldTime ();
m_timePeriodicUpdate = 0.0f;
bot->v.idealpitch = bot->v.v_angle.x;
bot->v.ideal_yaw = bot->v.v_angle.y;
bot->v.yaw_speed = g_randGen.Float (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed);
bot->v.pitch_speed = g_randGen.Float (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed);
bot->v.yaw_speed = g_randGen.Float (m_difficulty * 40, m_difficulty * 45);
bot->v.pitch_speed = g_randGen.Float (m_difficulty * 40, m_difficulty * 45);
switch (personality)
{
@ -1050,8 +1025,7 @@ void Bot::NewRound (void)
m_position = nullvec;
m_liftTravelPos = nullvec;
m_idealReactionTime = g_skillTab[m_skill / 20].minSurpriseTime;
m_actualReactionTime = g_skillTab[m_skill / 20].minSurpriseTime;
SetIdealReactionTimes (true);
m_targetEntity = NULL;
m_tasks = NULL;
@ -1075,7 +1049,7 @@ void Bot::NewRound (void)
m_grenadeCheckTime = 0.0;
m_isUsingGrenade = false;
m_skillOffset = static_cast <float> ((100 - m_skill) / 100.0);
m_breakableCheckTime = 0.0f;
m_blindButton = 0;
m_blindTime = 0.0;
m_jumpTime = 0.0;
@ -1087,6 +1061,7 @@ void Bot::NewRound (void)
m_sayTextBuffer.sayText[0] = 0x0;
m_buyState = 0;
m_lastEquipTime = 0.0f;
if (!m_notKilled) // if bot died, clear all weapon stuff and force buying again
{
@ -1117,6 +1092,8 @@ void Bot::NewRound (void)
m_radioEntity = NULL;
m_radioOrder = 0;
m_defendedBomb = false;
m_defendHostage = false;
m_headedTime = 0.0f;
m_timeLogoSpray = GetWorldTime () + g_randGen.Float (0.5, 2.0);
m_spawnTime = GetWorldTime ();
@ -1153,7 +1130,7 @@ void Bot::Kill (void)
edict_t *hurtEntity = (*g_engfuncs.pfnCreateNamedEntity) (MAKE_STRING ("trigger_hurt"));
if (FNullEnt (hurtEntity))
if (IsEntityNull (hurtEntity))
return;
hurtEntity->v.classname = MAKE_STRING (g_weaponDefs[m_currentWeapon].className);
@ -1199,10 +1176,12 @@ void Bot::StartGame (void)
if (m_startAction == GSM_TEAM_SELECT)
{
m_startAction = GSM_IDLE; // switch back to idle
char teamJoin = yb_join_team.GetString ()[0];
if (yb_join_team.GetString ()[0] == 'C' || yb_join_team.GetString ()[0] == 'c')
if (teamJoin == 'C' || teamJoin == 'c')
m_wantedTeam = 2;
else if (yb_join_team.GetString ()[0] == 'T' || yb_join_team.GetString ()[0] == 't')
else if (teamJoin == 'T' || teamJoin == 't')
m_wantedTeam = 1;
if (m_wantedTeam != 1 && m_wantedTeam != 2)
@ -1276,7 +1255,7 @@ void BotManager::CalculatePingOffsets (void)
if (bot == NULL)
continue;
int botPing = g_randGen.Long (averagePing - averagePing * 0.2f, averagePing + averagePing * 0.2f) + g_randGen.Long (bot->m_skill / 100 * 0.5, bot->m_skill / 100);
int botPing = g_randGen.Long (averagePing - averagePing * 0.2f, averagePing + averagePing * 0.2f) + g_randGen.Long (bot->m_difficulty + 3, bot->m_difficulty + 6) + 10;
if (botPing <= 5)
botPing = g_randGen.Long (10, 23);
@ -1303,14 +1282,13 @@ void BotManager::SendPingDataOffsets (edict_t *to)
if (yb_latency_display.GetInt () != 2)
return;
if (!IsValidPlayer (to) || IsValidBot (to))
if (IsEntityNull (to))
return;
if (!((to->v.button & IN_SCORE) || (to->v.oldbuttons & IN_SCORE)))
if (!(to->v.flags & FL_CLIENT) && !(((to->v.button & IN_SCORE) || !(to->v.oldbuttons & IN_SCORE))))
return;
static int sending;
sending = 0;
// missing from sdk
static const int SVC_PINGS = 17;

View file

@ -1,4 +1,4 @@
//
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
@ -9,50 +9,51 @@
#include <core.h>
ConVar yb_danger_factor ("yb_danger_factor", "800");
ConVar yb_danger_factor ("yb_danger_factor", "900", VT_NOSERVER);
ConVar yb_aim_method ("yb_aim_method", "3");
ConVar yb_aim_method ("yb_aim_method", "3", VT_NOSERVER);
ConVar yb_aim_damper_coefficient_x ("yb_aim_damper_coefficient_x", "0.22");
ConVar yb_aim_damper_coefficient_y ("yb_aim_damper_coefficient_y", "0.22");
ConVar yb_aim_damper_coefficient_x ("yb_aim_damper_coefficient_x", "0.22", VT_NOSERVER);
ConVar yb_aim_damper_coefficient_y ("yb_aim_damper_coefficient_y", "0.22", VT_NOSERVER);
ConVar yb_aim_deviation_x ("yb_aim_deviation_x", "2.0");
ConVar yb_aim_deviation_y ("yb_aim_deviation_y", "1.0");
ConVar yb_aim_deviation_x ("yb_aim_deviation_x", "2.0", VT_NOSERVER);
ConVar yb_aim_deviation_y ("yb_aim_deviation_y", "1.0", VT_NOSERVER);
ConVar yb_aim_influence_x_on_y ("yb_aim_influence_x_on_y", "0.25");
ConVar yb_aim_influence_y_on_x ("yb_aim_influence_y_on_x", "0.17");
ConVar yb_aim_influence_x_on_y ("yb_aim_influence_x_on_y", "0.26", VT_NOSERVER);
ConVar yb_aim_influence_y_on_x ("yb_aim_influence_y_on_x", "0.18", VT_NOSERVER);
ConVar yb_aim_notarget_slowdown_ratio ("yb_aim_notarget_slowdown_ratio", "0.5");
ConVar yb_aim_offset_delay ("yb_aim_offset_delay", "1.2");
ConVar yb_aim_notarget_slowdown_ratio ("yb_aim_notarget_slowdown_ratio", "0.6", VT_NOSERVER);
ConVar yb_aim_offset_delay ("yb_aim_offset_delay", "0.5", VT_NOSERVER);
ConVar yb_aim_spring_stiffness_x ("yb_aim_spring_stiffness_x", "13.0");
ConVar yb_aim_spring_stiffness_y ("yb_aim_spring_stiffness_y", "13.0");
ConVar yb_aim_spring_stiffness_x ("yb_aim_spring_stiffness_x", "15.0", VT_NOSERVER);
ConVar yb_aim_spring_stiffness_y ("yb_aim_spring_stiffness_y", "14.0", VT_NOSERVER);
ConVar yb_aim_target_anticipation_ratio ("yb_aim_target_anticipation_ratio", "3.0");
ConVar yb_aim_target_anticipation_ratio ("yb_aim_target_anticipation_ratio", "5.0", VT_NOSERVER);
int Bot::FindGoal (void)
{
// chooses a destination (goal) waypoint for a bot
if (m_team == TEAM_TF && (g_mapType & MAP_DE))
if (!g_bombPlanted && m_team == TEAM_TF && (g_mapType & MAP_DE))
{
edict_t *pent = NULL;
while (!FNullEnt (pent = FIND_ENTITY_BY_STRING (pent, "classname", "weaponbox")))
while (!IsEntityNull (pent = FIND_ENTITY_BY_STRING (pent, "classname", "weaponbox")))
{
if (strcmp (STRING (pent->v.model), "models/w_backpack.mdl") == 0)
{
int index = g_waypoint->FindNearest (GetEntityOrigin (pent));
if (index >= 0 && index < g_numWaypoints)
return index;
return m_loosedBombWptIndex = index;
break;
}
}
}
int tactic;
// path finding behaviour depending on map type
int tactic;
int offensive;
int defensive;
int goalDesire;
@ -84,7 +85,7 @@ int Bot::FindGoal (void)
tactic = 3;
goto TacticChoosen;
}
else if (HasHostage () && m_team == TEAM_CF)
else if (m_team == TEAM_CF && HasHostage ())
{
tactic = 2;
offensiveWpts = g_waypoint->m_rescuePoints;
@ -119,7 +120,7 @@ int Bot::FindGoal (void)
}
return m_chosenGoalIndex = ChooseBombWaypoint ();
}
defensive += 40.0f;
defensive += 25.0f;
offensive -= 25.0f;
}
else if ((g_mapType & MAP_DE) && m_team == TEAM_TF && g_timeRoundStart + 10.0f < GetWorldTime ())
@ -129,7 +130,7 @@ int Bot::FindGoal (void)
return m_chosenGoalIndex = FindDefendWaypoint (g_waypoint->GetBombPosition ());
}
goalDesire = g_randGen.Long (0, 100) + offensive;
goalDesire = g_randGen.Long (0, 100 + (offensive * 0.5)) + offensive;
forwardDesire = g_randGen.Long (0, 100) + offensive;
campDesire = g_randGen.Long (0, 100) + defensive;
backoffDesire = g_randGen.Long (0, 100) + defensive;
@ -145,11 +146,13 @@ int Bot::FindGoal (void)
tacticChoice = campDesire;
tactic = 1;
}
if (forwardDesire > tacticChoice)
{
tacticChoice = forwardDesire;
tactic = 2;
}
if (goalDesire > tacticChoice)
tactic = 3;
@ -172,7 +175,7 @@ TacticChoosen:
for (int i = 0; i < 4; i++)
{
goalChoices[i] = g_waypoint->m_sniperPoints.GetRandomElement ();
InternalAssert ((goalChoices[i] >= 0) && (goalChoices[i] < g_numWaypoints));
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
}
}
else
@ -180,7 +183,7 @@ TacticChoosen:
for (int i = 0; i < 4; i++)
{
goalChoices[i] = g_waypoint->m_campPoints.GetRandomElement ();
InternalAssert ((goalChoices[i] >= 0) && (goalChoices[i] < g_numWaypoints));
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
}
}
}
@ -189,15 +192,21 @@ TacticChoosen:
for (int i = 0; i < 4; i++)
{
goalChoices[i] = offensiveWpts.GetRandomElement ();
InternalAssert ((goalChoices[i] >= 0) && (goalChoices[i] < g_numWaypoints));
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
}
}
else if (tactic == 3 && !g_waypoint->m_goalPoints.IsEmpty ()) // map goal waypoint
{
for (int i = 0; i < 4; i++)
if (m_hasC4 && g_timeRoundStart + 20.0f < GetWorldTime ())
{
goalChoices[i] = g_waypoint->m_goalPoints.GetRandomElement ();
InternalAssert ((goalChoices[i] >= 0) && (goalChoices[i] < g_numWaypoints));
}
else
{
for (int i = 0; i < 4; i++)
{
goalChoices[i] = g_waypoint->m_goalPoints.GetRandomElement ();
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
}
}
}
@ -205,7 +214,7 @@ TacticChoosen:
ChangeWptIndex (g_waypoint->FindNearest (pev->origin));
if (goalChoices[0] == -1)
return m_chosenGoalIndex = g_randGen.Long (0, g_numWaypoints - 1);
return m_chosenGoalIndex = g_randGen.Long (0, g_numWaypoints - 1);
bool isSorting = false;
@ -270,6 +279,352 @@ bool Bot::GoalIsValid (void)
return false;
}
void Bot::CheckTerrain (float movedDistance)
{
edict_t *ent = NULL;
// Test if there's a shootable breakable in our way
if (m_breakableCheckTime < GetWorldTime () && !IsEntityNull (ent = FindBreakable ()))
{
m_breakableEntity = ent;
m_campButtons = pev->button & IN_DUCK;
StartTask (TASK_SHOOTBREAKABLE, TASKPRI_SHOOTBREAKABLE, -1, 0.0, false);
m_breakableCheckTime = GetWorldTime () + 0.7f;
return;
}
// calculate 2 direction vectors, 1 without the up/down component
Vector directionOld = m_destOrigin - (pev->origin + pev->velocity * m_frameInterval);
Vector directionNormal = directionOld.Normalize ();
Vector direction = directionNormal;
directionNormal.z = 0.0;
m_moveAngles = directionOld.ToAngles ();
m_moveAngles.ClampAngles ();
m_moveAngles.x *= -1.0; // invert for engine
m_isStuck = false;
Vector src = nullvec;
Vector destination = nullvec;
TraceResult tr;
// very cpu intensive
#if 0
ent = NULL;
edict_t *pentNearest = NULL;
if (FindNearestPlayer (reinterpret_cast <void **> (&pentNearest), GetEntity (), pev->maxspeed, true, false, true, true)) // found somebody?
{
MakeVectors (m_moveAngles); // use our movement angles
// try to predict where we should be next frame
Vector moved = pev->origin + g_pGlobals->v_forward * m_moveSpeed * m_frameInterval;
moved = moved + g_pGlobals->v_right * m_strafeSpeed * m_frameInterval;
moved = moved + pev->velocity * m_frameInterval;
float nearestDistance = (pentNearest->v.origin - pev->origin).GetLength2D ();
float nextFrameDistance = ((pentNearest->v.origin + pentNearest->v.velocity * m_frameInterval) - pev->origin).GetLength2D ();
// is player that near now or in future that we need to steer away?
if ((pentNearest->v.origin - moved).GetLength2D () <= 48.0 || (nearestDistance <= 56.0 && nextFrameDistance < nearestDistance))
{
// to start strafing, we have to first figure out if the target is on the left side or right side
Vector dirToPoint = (pev->origin - pentNearest->v.origin).SkipZ ();
if ((dirToPoint | g_pGlobals->v_right.SkipZ ()) > 0.0)
SetStrafeSpeed (directionNormal, pev->maxspeed);
else
SetStrafeSpeed (directionNormal, -pev->maxspeed);
ResetCollideState ();
if (nearestDistance < 56.0 && (dirToPoint | g_pGlobals->v_forward.SkipZ ()) < 0.0)
m_moveSpeed = -pev->maxspeed;
}
}
#endif
// Standing still, no need to check?
// FIXME: doesn't care for ladder movement (handled separately) should be included in some way
if ((m_moveSpeed >= 10 || m_strafeSpeed >= 10) && m_lastCollTime < GetWorldTime ())
{
if (movedDistance < 2.0 && m_prevSpeed >= 1.0) // didn't we move enough previously?
{
// Then consider being stuck
m_prevTime = GetWorldTime ();
m_isStuck = true;
if (m_firstCollideTime == 0.0)
m_firstCollideTime = GetWorldTime () + 0.2;
}
else // not stuck yet
{
// test if there's something ahead blocking the way
if (CantMoveForward (directionNormal, &tr) && !IsOnLadder ())
{
if (m_firstCollideTime == 0.0)
m_firstCollideTime = GetWorldTime () + 0.2;
else if (m_firstCollideTime <= GetWorldTime ())
m_isStuck = true;
}
else
m_firstCollideTime = 0.0;
}
if (!m_isStuck) // not stuck?
{
if (m_probeTime + 0.5 < GetWorldTime ())
ResetCollideState (); // reset collision memory if not being stuck for 0.5 secs
else
{
// remember to keep pressing duck if it was necessary ago
if (m_collideMoves[m_collStateIndex] == COLLISION_DUCK && IsOnFloor () || IsInWater ())
pev->button |= IN_DUCK;
}
}
else // bot is stuck!
{
// not yet decided what to do?
if (m_collisionState == COLLISION_NOTDECICED)
{
char bits = 0;
if (IsOnLadder ())
bits = PROBE_STRAFE;
else if (IsInWater ())
bits = (PROBE_JUMP | PROBE_STRAFE);
else
bits = ((g_randGen.Long (0, 10) > 7 ? PROBE_JUMP : 0) | PROBE_STRAFE | PROBE_DUCK);
// collision check allowed if not flying through the air
if (IsOnFloor () || IsOnLadder () || IsInWater ())
{
char state[8];
int i = 0;
// first 4 entries hold the possible collision states
state[i++] = COLLISION_JUMP;
state[i++] = COLLISION_DUCK;
state[i++] = COLLISION_STRAFELEFT;
state[i++] = COLLISION_STRAFERIGHT;
// now weight all possible states
if (bits & PROBE_JUMP)
{
state[i] = 0;
if (CanJumpUp (directionNormal))
state[i] += 10;
if (m_destOrigin.z >= pev->origin.z + 18.0)
state[i] += 5;
if (EntityIsVisible (m_destOrigin))
{
MakeVectors (m_moveAngles);
src = EyePosition ();
src = src + (g_pGlobals->v_right * 15);
TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0)
{
src = EyePosition ();
src = src - (g_pGlobals->v_right * 15);
TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0)
state[i] += 5;
}
}
if (pev->flags & FL_DUCKING)
src = pev->origin;
else
src = pev->origin + Vector (0, 0, -17);
destination = src + directionNormal * 30;
TraceLine (src, destination, true, true, GetEntity (), &tr);
if (tr.flFraction != 1.0)
state[i] += 10;
}
else
state[i] = 0;
i++;
if (bits & PROBE_DUCK)
{
state[i] = 0;
if (CanDuckUnder (directionNormal))
state[i] += 10;
if ((m_destOrigin.z + 36.0 <= pev->origin.z) && EntityIsVisible (m_destOrigin))
state[i] += 5;
}
else
state[i] = 0;
i++;
if (bits & PROBE_STRAFE)
{
state[i] = 0;
state[i + 1] = 0;
// to start strafing, we have to first figure out if the target is on the left side or right side
MakeVectors (m_moveAngles);
Vector dirToPoint = (pev->origin - m_destOrigin).Normalize2D ();
Vector rightSide = g_pGlobals->v_right.Normalize2D ();
bool dirRight = false;
bool dirLeft = false;
bool blockedLeft = false;
bool blockedRight = false;
if ((dirToPoint | rightSide) > 0)
dirRight = true;
else
dirLeft = true;
if (m_moveSpeed > 0)
direction = g_pGlobals->v_forward;
else
direction = -g_pGlobals->v_forward;
// now check which side is blocked
src = pev->origin + (g_pGlobals->v_right * 32);
destination = src + (direction * 32);
TraceHull (src, destination, true, head_hull, GetEntity (), &tr);
if (tr.flFraction != 1.0)
blockedRight = true;
src = pev->origin - (g_pGlobals->v_right * 32);
destination = src + (direction * 32);
TraceHull (src, destination, true, head_hull, GetEntity (), &tr);
if (tr.flFraction != 1.0)
blockedLeft = true;
if (dirLeft)
state[i] += 5;
else
state[i] -= 5;
if (blockedLeft)
state[i] -= 5;
i++;
if (dirRight)
state[i] += 5;
else
state[i] -= 5;
if (blockedRight)
state[i] -= 5;
}
else
{
state[i] = 0;
i++;
state[i] = 0;
}
// weighted all possible moves, now sort them to start with most probable
int temp = 0;
bool isSorting = false;
do
{
isSorting = false;
for (i = 0; i < 3; i++)
{
if (state[i + 4] < state[i + 5])
{
temp = state[i];
state[i] = state[i + 1];
state[i + 1] = temp;
temp = state[i + 4];
state[i + 4] = state[i + 5];
state[i + 5] = temp;
isSorting = true;
}
}
} while (isSorting);
for (i = 0; i < 4; i++)
m_collideMoves[i] = state[i];
m_collideTime = GetWorldTime ();
m_probeTime = GetWorldTime () + 0.5;
m_collisionProbeBits = bits;
m_collisionState = COLLISION_PROBING;
m_collStateIndex = 0;
}
}
if (m_collisionState == COLLISION_PROBING)
{
if (m_probeTime < GetWorldTime ())
{
m_collStateIndex++;
m_probeTime = GetWorldTime () + 0.5;
if (m_collStateIndex > 4)
{
m_navTimeset = GetWorldTime () - 5.0;
ResetCollideState ();
}
}
if (m_collStateIndex <= 4)
{
switch (m_collideMoves[m_collStateIndex])
{
case COLLISION_JUMP:
if (IsOnFloor () || IsInWater ())
pev->button |= IN_JUMP;
break;
case COLLISION_DUCK:
if (IsOnFloor () || IsInWater ())
pev->button |= IN_DUCK;
break;
case COLLISION_STRAFELEFT:
pev->button |= IN_MOVELEFT;
SetStrafeSpeed (directionNormal, -pev->maxspeed);
break;
case COLLISION_STRAFERIGHT:
pev->button |= IN_MOVERIGHT;
SetStrafeSpeed (directionNormal, pev->maxspeed);
break;
}
}
}
}
}
}
bool Bot::DoWaypointNav (void)
{
// this function is a main path navigation
@ -360,7 +715,7 @@ bool Bot::DoWaypointNav (void)
TraceLine (m_currentPath->origin, m_currentPath->origin + Vector (0, 0, -50), true, true, GetEntity (), &tr);
// if trace result shows us that it is a lift
if (!FNullEnt (tr.pHit) && m_navNode != NULL && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0) && !liftClosedDoorExists)
if (!IsEntityNull (tr.pHit) && m_navNode != NULL && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0) && !liftClosedDoorExists)
{
if ((m_liftState == LIFT_NO_NEARBY || m_liftState == LIFT_WAITING_FOR || m_liftState == LIFT_LOOKING_BUTTON_OUTSIDE) && tr.pHit->v.velocity.z == 0)
{
@ -386,7 +741,7 @@ bool Bot::DoWaypointNav (void)
{
TraceLine (m_currentPath->origin, g_waypoint->GetPath (m_navNode->next->index)->origin, true, true, GetEntity (), &tr);
if (!FNullEnt (tr.pHit) && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0))
if (!IsEntityNull (tr.pHit) && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0))
m_liftEntity = tr.pHit;
}
m_liftState = LIFT_LOOKING_BUTTON_OUTSIDE;
@ -491,7 +846,7 @@ bool Bot::DoWaypointNav (void)
edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname));
// got a valid button entity ?
if (!FNullEnt (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0 < GetWorldTime () && m_liftEntity->v.velocity.z == 0.0 && IsOnFloor ())
if (!IsEntityNull (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0 < GetWorldTime () && m_liftEntity->v.velocity.z == 0.0 && IsOnFloor ())
{
m_pickupItem = button;
m_pickupType = PICKUP_BUTTON;
@ -503,7 +858,7 @@ bool Bot::DoWaypointNav (void)
// is lift activated and bot is standing on it and lift is moving ?
if (m_liftState == LIFT_LOOKING_BUTTON_INSIDE || m_liftState == LIFT_ENTERING_IN || m_liftState == LIFT_WAIT_FOR_TEAMMATES || m_liftState == LIFT_WAITING_FOR)
{
if (pev->groundentity == m_liftEntity && m_liftEntity->v.velocity.z != 0 && IsOnFloor () && ((g_waypoint->GetPath (m_prevWptIndex[0])->flags & FLAG_LIFT) || !FNullEnt (m_targetEntity)))
if (pev->groundentity == m_liftEntity && m_liftEntity->v.velocity.z != 0 && IsOnFloor () && ((g_waypoint->GetPath (m_prevWptIndex[0])->flags & FLAG_LIFT) || !IsEntityNull (m_targetEntity)))
{
m_liftState = LIFT_TRAVELING_BY;
m_liftUsageTime = GetWorldTime () + 14.0;
@ -553,12 +908,12 @@ bool Bot::DoWaypointNav (void)
edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname));
// if we got a valid button entity
if (!FNullEnt (button))
if (!IsEntityNull (button))
{
// iterate though clients, and find if lift already used
for (int i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team != m_team || g_clients[i].ent == GetEntity () || FNullEnt (g_clients[i].ent->v.groundentity))
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team != m_team || g_clients[i].ent == GetEntity () || IsEntityNull (g_clients[i].ent->v.groundentity))
continue;
if (g_clients[i].ent->v.groundentity == m_liftEntity)
@ -642,7 +997,7 @@ bool Bot::DoWaypointNav (void)
}
}
if (!FNullEnt (m_liftEntity) && !(m_currentPath->flags & FLAG_LIFT))
if (!IsEntityNull (m_liftEntity) && !(m_currentPath->flags & FLAG_LIFT))
{
if (m_liftState == LIFT_TRAVELING_BY)
{
@ -682,7 +1037,7 @@ bool Bot::DoWaypointNav (void)
// check if we are going through a door...
TraceLine (pev->origin, m_waypointOrigin, true, GetEntity (), &tr);
if (!FNullEnt (tr.pHit) && FNullEnt (m_liftEntity) && strncmp (STRING (tr.pHit->v.classname), "func_door", 9) == 0)
if (!IsEntityNull (tr.pHit) && IsEntityNull (m_liftEntity) && strncmp (STRING (tr.pHit->v.classname), "func_door", 9) == 0)
{
// if the door is near enough...
if ((GetEntityOrigin (tr.pHit) - pev->origin).GetLengthSquared () < 2500)
@ -699,7 +1054,7 @@ bool Bot::DoWaypointNav (void)
edict_t *button = FindNearestButton (STRING (tr.pHit->v.targetname));
// check if we got valid button
if (!FNullEnt (button))
if (!IsEntityNull (button))
{
m_pickupItem = button;
m_pickupType = PICKUP_BUTTON;
@ -717,9 +1072,9 @@ bool Bot::DoWaypointNav (void)
edict_t *ent = NULL;
if (m_doorOpenAttempt > 2 && !FNullEnt (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 100)))
if (m_doorOpenAttempt > 2 && !IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 100)))
{
if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && IsWeaponShootingThroughWall (m_currentWeapon))
if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0)
{
m_seeEnemyTime = GetWorldTime ();
@ -1063,7 +1418,7 @@ int gfunctionKillsDistCTWithHostage (int currentIndex, int parentIndex)
return 65355;
else if (current->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionKillsDistCT (currentIndex, parentIndex) * 500;
return gfunctionKillsDistCT (currentIndex, parentIndex) * 5000;
return gfunctionKillsDistCT (currentIndex, parentIndex);
}
@ -1122,7 +1477,7 @@ int gfunctionKillsCTWithHostage (int currentIndex, int parentIndex)
return 65355;
else if (current->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionKillsDistCT (currentIndex, parentIndex) * 500;
return gfunctionKillsDistCT (currentIndex, parentIndex) * 5000;
return gfunctionKillsCT (currentIndex, parentIndex);
}
@ -1156,7 +1511,7 @@ int gfunctionPathDistWithHostage (int currentIndex, int parentIndex)
if (current->flags & FLAG_NOHOSTAGE)
return 65355;
else if (current->flags & (FLAG_CROUCH | FLAG_LADDER))
return gfunctionPathDist (currentIndex, parentIndex) * 500;
return gfunctionPathDist (currentIndex, parentIndex) * 5000;
return gfunctionPathDist (currentIndex, parentIndex);
}
@ -1439,14 +1794,14 @@ bool Bot::FindWaypoint (void)
float reachDistances[3];
// nullify all waypoint search stuff
for (int i = 0; i < 3; i++)
for (i = 0; i < 3; i++)
{
waypointIndeces[i] = -1;
reachDistances[i] = 9999.0;
}
// do main search loop
for (int i = 0; i < g_numWaypoints; i++)
for (i = 0; i < g_numWaypoints; i++)
{
// ignore current waypoint and previous recent waypoints...
if (i == m_currentWaypointIndex || i == m_prevWptIndex[0] || i == m_prevWptIndex[1] || i == m_prevWptIndex[2] || i == m_prevWptIndex[3] || i == m_prevWptIndex[4])
@ -1457,7 +1812,7 @@ bool Bot::FindWaypoint (void)
continue;
// check if waypoint is already used by another bot...
if (IsWaypointUsed (i))
if (IsPointOccupied (i))
{
coveredWaypoint = i;
continue;
@ -1521,7 +1876,7 @@ void Bot::GetValidWaypoint (void)
// FIXME: Do some error checks if we got a waypoint
}
else if ((m_navTimeset + GetEstimatedReachTime () < GetWorldTime ()) && FNullEnt (m_enemy))
else if (m_navTimeset + GetEstimatedReachTime () < GetWorldTime () && IsEntityNull (m_enemy))
{
if (m_team == TEAM_TF)
{
@ -1585,7 +1940,7 @@ void Bot::ChangeWptIndex (int waypointIndex)
m_prevWptIndex[4] = m_prevWptIndex[3];
m_prevWptIndex[3] = m_prevWptIndex[2];
m_prevWptIndex[2] = m_prevWptIndex[1];
m_prevWptIndex[0] = waypointIndex;
m_prevWptIndex[0] = m_currentWaypointIndex;
m_currentWaypointIndex = waypointIndex;
m_navTimeset = GetWorldTime ();
@ -1626,7 +1981,7 @@ int Bot::ChooseBombWaypoint (void)
if (distance < lastDistance)
{
goal = goals[i];
lastDistance = distance;;
lastDistance = distance;
}
}
@ -1666,7 +2021,7 @@ int Bot::FindDefendWaypoint (Vector origin)
for (int i = 0; i < g_numWaypoints; i++) // find the best waypoint now
{
// exclude ladder & current waypoints
if ((g_waypoint->GetPath (i)->flags & FLAG_LADDER) || i == srcIndex || !g_waypoint->IsVisible (i, posIndex) || IsWaypointUsed (i))
if ((g_waypoint->GetPath (i)->flags & FLAG_LADDER) || i == srcIndex || !g_waypoint->IsVisible (i, posIndex) || IsPointOccupied (i))
continue;
// use the 'real' pathfinding distances
@ -1904,7 +2259,7 @@ bool Bot::GetBestNextWaypoint (void)
InternalAssert (m_navNode != NULL);
InternalAssert (m_navNode->next != NULL);
if (!IsWaypointUsed (m_navNode->index))
if (!IsPointOccupied (m_navNode->index))
return false;
for (int i = 0; i < MAX_PATH_INDEX; i++)
@ -1916,7 +2271,7 @@ bool Bot::GetBestNextWaypoint (void)
if (g_waypoint->GetPath (id)->flags & FLAG_LADDER) // don't use ladder waypoints as alternative
continue;
if (!IsWaypointUsed (id))
if (!IsPointOccupied (id))
{
m_navNode->index = id;
return true;
@ -1948,8 +2303,8 @@ bool Bot::HeadTowardWaypoint (void)
if (m_navNode != m_navNodeStart && m_navNode->next != NULL)
{
GetBestNextWaypoint ();
int taskID= GetTaskId ();
int taskID = GetTaskId ();
m_minSpeed = pev->maxspeed;
// only if we in normal task and bomb is not planted
@ -1965,38 +2320,35 @@ bool Bot::HeadTowardWaypoint (void)
else
kills = (g_experienceData + (waypoint * g_numWaypoints) + waypoint)->team1Damage / g_highestDamageCT;
switch (m_personality)
{
case PERSONALITY_NORMAL:
kills *= 0.33f;
break;
default:
kills *= 0.5f;
break;
}
// if damage done higher than one
if (kills > 0.15f && g_timeRoundMid + 30.0f > GetWorldTime ())
if (kills > 0.15f && g_timeRoundMid + 30.0f > GetWorldTime () && m_timeCamping + 10.0 < GetWorldTime())
{
switch (m_personality)
{
case PERSONALITY_NORMAL:
kills *= 0.33f;
break;
default:
kills *= 0.5f;
break;
}
if (m_baseAgressionLevel < kills && GetTaskId () != TASK_MOVETOPOSITION && HasPrimaryWeapon ())
{
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + (m_fearLevel * (g_timeRoundMid - GetWorldTime ()) * 0.5), true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (g_waypoint->GetPath (waypoint)->origin), 0.0, true);
if (m_skill > 95)
if (m_difficulty >= 2)
pev->button |= IN_DUCK;
}
}
else
if (g_botsCanPause && !IsOnLadder () && !IsInWater () && !m_currentTravelFlags && IsOnFloor ())
{
if (static_cast <float> (kills) == m_baseAgressionLevel)
m_campButtons |= IN_DUCK;
else if (g_randGen.Long (1, 100) > (m_skill + g_randGen.Long (1, 20)))
else if (g_randGen.Long (1, 100) < m_difficulty * 25)
m_minSpeed = GetWalkSpeed ();
}
}
@ -2050,9 +2402,10 @@ bool Bot::HeadTowardWaypoint (void)
}
// is there a jump waypoint right ahead and do we need to draw out the light weapon ?
if (willJump && (jumpDistance > 210 || (destination.z + 32.0 > src.z && jumpDistance > 150) || ((destination - src).GetLength2D () < 50 && jumpDistance > 60)) && !(m_states & STATE_SEEING_ENEMY) && m_currentWeapon != WEAPON_KNIFE && !m_isReloading)
if (willJump && m_currentWeapon != WEAPON_KNIFE && m_currentWeapon != WEAPON_SCOUT && !m_isReloading && !UsesPistol () && (jumpDistance > 210 || (destination.z + 32.0f > src.z && jumpDistance > 150.0f) || ((destination - src).GetLength2D () < 60 && jumpDistance > 60)) && IsEntityNull (m_enemy))
SelectWeaponByName ("weapon_knife"); // draw out the knife if we needed
// bot not already on ladder but will be soon?
if ((g_waypoint->GetPath (destIndex)->flags & FLAG_LADDER) && !IsOnLadder ())
{
@ -2697,9 +3050,10 @@ int Bot::GetAimingWaypoint (void)
void Bot::FacePosition (void)
{
// adjust all body and view angles to face an absolute vector
Vector direction = (m_lookAt - EyePosition ()).ToAngles ();
direction = direction + pev->punchangle * m_skill / 100.0;
direction = direction + pev->punchangle * (m_difficulty * 25) / 100.0;
direction.x *= -1.0; // invert for engine
Vector deviation = (direction - pev->v_angle);
@ -2707,16 +3061,16 @@ void Bot::FacePosition (void)
direction.ClampAngles ();
deviation.ClampAngles ();
int forcedTurnMethod = yb_aim_method.GetInt ();
int aimMethod = yb_aim_method.GetInt ();
if ((forcedTurnMethod < 1) || (forcedTurnMethod > 3))
forcedTurnMethod = 3;
if (aimMethod < 1 || aimMethod > 3)
aimMethod = 3;
if (forcedTurnMethod == 1)
if (aimMethod == 1)
pev->v_angle = direction;
else if (forcedTurnMethod == 2)
else if (aimMethod == 2)
{
float turnSkill = static_cast <float> (0.05 * m_skill) + 0.5;
float turnSkill = static_cast <float> (0.05 * (m_difficulty * 25)) + 0.5;
float aimSpeed = 0.17 + turnSkill * 0.06;
float frameCompensation = g_pGlobals->frametime * 1000 * 0.01;
@ -2728,7 +3082,7 @@ void Bot::FacePosition (void)
pev->pitch_speed = ((pev->pitch_speed * momentum) + aimSpeed * deviation.x * (1.0 - momentum)) * frameCompensation;
pev->yaw_speed = ((pev->yaw_speed * momentum) + aimSpeed * deviation.y * (1.0 - momentum)) * frameCompensation;
if (m_skill < 100)
if (m_difficulty <= 2)
{
// influence of y movement on x axis, based on skill (less influence than x on y since it's
// easier and more natural for the bot to "move its mouse" horizontally than vertically)
@ -2739,7 +3093,7 @@ void Bot::FacePosition (void)
pev->v_angle.x += pev->pitch_speed; // change pitch angles
pev->v_angle.y += pev->yaw_speed; // change yaw angles
}
else if (forcedTurnMethod == 3)
else if (aimMethod == 3)
{
Vector springStiffness (yb_aim_spring_stiffness_x.GetFloat (), yb_aim_spring_stiffness_y.GetFloat (), 0);
Vector damperCoefficient (yb_aim_damper_coefficient_x.GetFloat (), yb_aim_damper_coefficient_y.GetFloat (), 0);
@ -2753,10 +3107,10 @@ void Bot::FacePosition (void)
m_targetOriginAngularSpeed.ClampAngles ();
m_idealAngles.ClampAngles ();
if (yb_hardcore_mode.GetBool ())
if (m_difficulty == 4)
{
influence = influence * m_skillOffset;
randomization = randomization * m_skillOffset;
influence = influence * ((100 - (m_difficulty * 25)) / 100.f);
randomization = randomization * ((100 - (m_difficulty * 25)) / 100.f);
}
if (m_aimFlags & (AIM_ENEMY | AIM_ENTITY | AIM_GRENADE | AIM_LAST_ENEMY) || GetTaskId () == TASK_SHOOTBREAKABLE)
@ -2766,10 +3120,10 @@ void Bot::FacePosition (void)
if (IsValidPlayer (m_enemy))
{
m_targetOriginAngularSpeed = ((m_enemyOrigin - pev->origin + 1.5 * m_frameInterval * (1.0 * m_enemy->v.velocity) - 0.0 * g_pGlobals->frametime * pev->velocity).ToAngles () - (m_enemyOrigin - pev->origin).ToAngles ()) * 0.45 * yb_aim_target_anticipation_ratio.GetFloat () * static_cast <float> (m_skill / 100);
m_targetOriginAngularSpeed = ((m_enemyOrigin - pev->origin + 1.5 * m_frameInterval * (1.0 * m_enemy->v.velocity) - 0.0 * g_pGlobals->frametime * pev->velocity).ToAngles () - (m_enemyOrigin - pev->origin).ToAngles ()) * 0.45 * yb_aim_target_anticipation_ratio.GetFloat () * static_cast <float> ((m_difficulty * 25) / 100);
if (m_angularDeviation.GetLength () < 5.0)
springStiffness = (5.0 - m_angularDeviation.GetLength ()) * 0.25 * static_cast <float> (m_skill / 100) * springStiffness + springStiffness;
springStiffness = (5.0 - m_angularDeviation.GetLength ()) * 0.25 * static_cast <float> ((m_difficulty * 25) / 100) * springStiffness + springStiffness;
m_targetOriginAngularSpeed.x = -m_targetOriginAngularSpeed.x;
@ -2782,10 +3136,10 @@ void Bot::FacePosition (void)
m_targetOriginAngularSpeed = nullvec;
if (m_skill >= 80)
if (m_difficulty >= 3)
stiffness = springStiffness;
else
stiffness = springStiffness * (0.2 + m_skill / 125.0);
stiffness = springStiffness * (0.2 + (m_difficulty * 25) / 125.0);
}
else
{
@ -2816,12 +3170,12 @@ void Bot::FacePosition (void)
stiffnessMultiplier = 0.5;
}
// also take in account the remaining deviation (slow down the aiming in the last 10°)
if (!yb_hardcore_mode.GetBool () && (m_angularDeviation.GetLength () < 10.0))
// also take in account the remaining deviation (slow down the aiming in the last 10°)
if (m_difficulty < 3 && (m_angularDeviation.GetLength () < 10.0))
stiffnessMultiplier *= m_angularDeviation.GetLength () * 0.1;
// slow down even more if we are not moving
if (!yb_hardcore_mode.GetBool () && pev->velocity.GetLength () < 1.0 && GetTaskId () != TASK_CAMP && GetTaskId () != TASK_ATTACK)
if (m_difficulty < 3 && pev->velocity.GetLength () < 1.0 && GetTaskId () != TASK_CAMP && GetTaskId () != TASK_ATTACK)
stiffnessMultiplier *= 0.5;
// but don't allow getting below a certain value
@ -2874,31 +3228,6 @@ void Bot::SetStrafeSpeed (Vector moveDir, float strafeSpeed)
m_strafeSpeed = -strafeSpeed;
}
int Bot::FindLoosedBomb (void)
{
// this function tries to find droped c4 on the defuse scenario map and returns nearest to it waypoint
if ((m_team != TEAM_TF) || !(g_mapType & MAP_DE))
return -1; // don't search for bomb if the player is CT, or it's not defusing bomb
edict_t *bombEntity = NULL; // temporaly pointer to bomb
// search the bomb on the map
while (!FNullEnt (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "weaponbox")))
{
if (strcmp (STRING (bombEntity->v.model) + 9, "backpack.mdl") == 0)
{
int nearestIndex = g_waypoint->FindNearest (GetEntityOrigin (bombEntity));
if ((nearestIndex >= 0) && (nearestIndex < g_numWaypoints))
return nearestIndex;
break;
}
}
return -1;
}
int Bot::FindPlantedBomb (void)
{
// this function tries to find planted c4 on the defuse scenario map and returns nearest to it waypoint
@ -2909,7 +3238,7 @@ int Bot::FindPlantedBomb (void)
edict_t *bombEntity = NULL; // temporaly pointer to bomb
// search the bomb on the map
while (!FNullEnt (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "grenade")))
while (!IsEntityNull (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "grenade")))
{
if (strcmp (STRING (bombEntity->v.model) + 9, "c4.mdl") == 0)
{
@ -2924,7 +3253,7 @@ int Bot::FindPlantedBomb (void)
return -1;
}
bool Bot::IsWaypointUsed (int index)
bool Bot::IsPointOccupied (int index)
{
if (index < 0 || index >= g_numWaypoints)
return true;
@ -2938,17 +3267,7 @@ bool Bot::IsWaypointUsed (int index)
continue;
// check if this waypoint is already used
if (IsAlive (bot->GetEntity ()) && (bot->m_currentWaypointIndex == index || bot->GetTask ()->data == index || (g_waypoint->GetPath (index)->origin - bot->pev->origin).GetLength2D () < 80.0))
return true;
}
// secondary check waypoint radius for any player
edict_t *ent = NULL;
// search player entities in waypoint radius
while (!FNullEnt (ent = FIND_ENTITY_IN_SPHERE (ent, g_waypoint->GetPath (index)->origin, 80.0)))
{
if (ent != GetEntity () && IsValidBot (ent) && IsAlive (ent))
if (IsAlive (bot->GetEntity ()) && (bot->m_currentWaypointIndex == index || bot->GetTask ()->data == index || (g_waypoint->GetPath (index)->origin - bot->pev->origin).GetLength2D () < 180.0))
return true;
}
return false;
@ -2966,7 +3285,7 @@ edict_t *Bot::FindNearestButton (const char *targetName)
edict_t *searchEntity = NULL, *foundEntity = NULL;
// find the nearest button which can open our target
while (!FNullEnt(searchEntity = FIND_ENTITY_BY_TARGET(searchEntity, targetName)))
while (!IsEntityNull(searchEntity = FIND_ENTITY_BY_TARGET(searchEntity, targetName)))
{
Vector entityOrign = GetEntityOrigin (searchEntity);

View file

@ -267,7 +267,7 @@ void NetworkMsg::Execute (void *p)
edict_t *killer = EntityOfIndex (killerIndex);
edict_t *victim = EntityOfIndex (victimIndex);
if (FNullEnt (killer) || FNullEnt (victim))
if (IsEntityNull (killer) || IsEntityNull (victim))
break;
// need to send congrats on well placed shot
@ -291,7 +291,7 @@ void NetworkMsg::Execute (void *p)
{
Bot *bot = g_botManager->GetBot (i);
if (bot != NULL && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && FNullEnt (bot->m_enemy) && GetTeam (killer) != GetTeam (victim))
if (bot != NULL && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && IsEntityNull (bot->m_enemy) && GetTeam (killer) != GetTeam (victim))
{
bot->m_actualReactionTime = 0.0;
bot->m_seeEnemyTime = GetWorldTime ();
@ -309,14 +309,14 @@ void NetworkMsg::Execute (void *p)
else // did a human kill a bot on his team?
{
Bot *bot = g_botManager->GetBot (victim);
Bot *target = g_botManager->GetBot (victim);
if (bot != NULL)
if (target != NULL)
{
if (GetTeam (killer) == GetTeam (victim))
bot->m_voteKickIndex = killerIndex;
target->m_voteKickIndex = killerIndex;
bot->m_notKilled = false;
target->m_notKilled = false;
}
}
}
@ -406,25 +406,36 @@ void NetworkMsg::Execute (void *p)
g_bombPlanted = g_bombSayString = true;
g_timeBombPlanted = GetWorldTime ();
for (int i = 0; i < GetMaxClients (); i++)
{
Bot *bot = g_botManager->GetBot (i);
if (yb_communication_type.GetInt() == 2)
{
for (int i = 0; i < GetMaxClients(); i++)
{
Bot *bot = g_botManager->GetBot(i);
if (bot != NULL && IsAlive (bot->GetEntity ()))
{
bot->DeleteSearchNodes ();
bot->ResetTasks ();
if (bot != NULL && IsAlive(bot->GetEntity()))
{
bot->DeleteSearchNodes();
bot->ResetTasks();
if (g_randGen.Long (0, 100) < 85 && GetTeam (bot->GetEntity ()) == TEAM_CF)
bot->ChatterMessage (Chatter_WhereIsTheBomb);
}
}
if (g_randGen.Long(0, 100) < 75 && GetTeam(bot->GetEntity()) == TEAM_CF)
bot->ChatterMessage(Chatter_WhereIsTheBomb);
}
}
}
g_waypoint->SetBombPosition ();
}
else if (m_bot != NULL && FStrEq (PTR_TO_STR (p), "#Switch_To_BurstFire"))
m_bot->m_weaponBurstMode = BM_ON;
else if (m_bot != NULL && FStrEq (PTR_TO_STR (p), "#Switch_To_SemiAuto"))
m_bot->m_weaponBurstMode = BM_OFF;
if (yb_communication_type.GetInt() == 2)
{
Bot *bot = g_botManager->FindOneValidAliveBot();
if (bot != NULL && IsAlive(bot->GetEntity()))
bot->HandleChatterMessage(PTR_TO_STR(p));
}
}
break;

View file

@ -1,4 +1,4 @@
//
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
@ -9,7 +9,7 @@
#include <core.h>
ConVar yb_listenserver_welcome ("yb_listenserver_welcome", "1");
ConVar yb_listenserver_welcome ("yb_listenserver_welcome", "1", VT_NOSERVER);
ConVar mp_roundtime ("mp_roundtime", NULL, VT_NOREGISTER);
ConVar mp_freezetime ("mp_freezetime", NULL, VT_NOREGISTER);
@ -97,10 +97,10 @@ char *FormatBuffer (char *format, ...)
bool IsAlive (edict_t *ent)
{
if (FNullEnt (ent))
return false; // reliability check
if (IsEntityNull (ent))
return false;
return (ent->v.deadflag == DEAD_NO) && (ent->v.health > 0) && (ent->v.movetype != MOVETYPE_NOCLIP);
return ent->v.deadflag == DEAD_NO && ent->v.health > 0 && ent->v.movetype != MOVETYPE_NOCLIP;
}
float GetShootingConeDeviation (edict_t *ent, Vector *position)
@ -124,7 +124,7 @@ bool IsInViewCone (Vector origin, edict_t *ent)
bool IsVisible (const Vector &origin, edict_t *ent)
{
if (FNullEnt (ent))
if (IsEntityNull (ent))
return false;
TraceResult tr;
@ -141,7 +141,7 @@ Vector GetEntityOrigin (edict_t *ent)
// this expanded function returns the vector origin of a bounded entity, assuming that any
// entity that has a bounding box has its center at the center of the bounding box itself.
if (FNullEnt (ent))
if (IsEntityNull (ent))
return nullvec;
if (ent->v.origin == nullvec)
@ -162,14 +162,14 @@ void DisplayMenuToClient (edict_t *ent, MenuText *menu)
String tempText = String (menu->menuText);
tempText.Replace ("\v", "\n");
char *text = g_localizer->TranslateInput (tempText.ToString ());
char *text = g_localizer->TranslateInput (tempText.GetBuffer ());
tempText = String (text);
// make menu looks best
for (int i = 0; i <= 9; i++)
tempText.Replace (FormatBuffer ("%d.", i), FormatBuffer ("\\r%d.\\w", i));
text = (char *) tempText.ToString ();
text = (char *) tempText.GetBuffer ();
while (strlen (text) >= 64)
{
@ -219,7 +219,7 @@ void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex)
logotypes = String ("{biohaz;{graf004;{graf005;{lambda06;{target;{hand1").Split (";");
int entityIndex = -1, message = TE_DECAL;
int decalIndex = (*g_engfuncs.pfnDecalIndex) (logotypes[logotypeIndex].ToString ());
int decalIndex = (*g_engfuncs.pfnDecalIndex) (logotypes[logotypeIndex].GetBuffer ());
if (decalIndex < 0)
decalIndex = (*g_engfuncs.pfnDecalIndex) ("{lambda06");
@ -227,7 +227,7 @@ void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex)
if (trace->flFraction == 1.0)
return;
if (!FNullEnt (trace->pHit))
if (!IsEntityNull (trace->pHit))
{
if (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP)
entityIndex = IndexOfEntity (trace->pHit);
@ -289,9 +289,7 @@ void FreeLibraryMemory (void)
// this function free's all allocated memory
g_waypoint->Init (); // frees waypoint data
if (g_experienceData != NULL)
delete [] g_experienceData;
delete [] g_experienceData;
g_experienceData = NULL;
}
@ -305,9 +303,9 @@ void FakeClientCommand (edict_t *fakeClient, const char *format, ...)
va_list ap;
static char command[256];
int start, stop, i, index, stringIndex = 0;
int stop, i, stringIndex = 0;
if (FNullEnt (fakeClient))
if (IsEntityNull (fakeClient))
return; // reliability check
// concatenate all the arguments in one string
@ -324,7 +322,7 @@ void FakeClientCommand (edict_t *fakeClient, const char *format, ...)
// process all individual commands (separated by a semicolon) one each a time
while (stringIndex < length)
{
start = stringIndex; // save field start position (first character)
int start = stringIndex; // save field start position (first character)
while (stringIndex < length && command[stringIndex] != ';')
stringIndex++; // reach end of field
@ -340,7 +338,7 @@ void FakeClientCommand (edict_t *fakeClient, const char *format, ...)
g_fakeArgv[i - start] = 0; // terminate the string
stringIndex++; // move the overall string index one step further to bypass the semicolon
index = 0;
int index = 0;
g_fakeArgc = 0; // let's now parse that command and count the different arguments
// count the number of arguments
@ -764,6 +762,9 @@ void RoundInit (void)
g_lastRadioTime[1] = 0.0;
g_botsCanPause = false;
for (int i = 0; i < TASK_MAX; i++)
g_taskFilters[i].time = 0.0f;
UpdateGlobalExperienceData (); // update experience data on round start
// calculate the round mid/end in world time
@ -772,7 +773,7 @@ void RoundInit (void)
g_timeRoundEnd = g_timeRoundStart + mp_roundtime.GetFloat () * 60;
}
bool IsWeaponShootingThroughWall (int id)
int GetWeaponPenetrationPower (int id)
{
// returns if weapon can pierce through a wall
@ -781,15 +782,11 @@ bool IsWeaponShootingThroughWall (int id)
while (g_weaponSelect[i].id)
{
if (g_weaponSelect[i].id == id)
{
if (g_weaponSelect[i].shootsThru)
return true;
return g_weaponSelect[i].penetratePower;
return false;
}
i++;
}
return false;
return 0;
}
int GetTeam (edict_t *ent)
@ -799,7 +796,7 @@ int GetTeam (edict_t *ent)
bool IsValidPlayer (edict_t *ent)
{
if (FNullEnt (ent))
if (IsEntityNull (ent))
return false;
if (ent->v.flags & FL_PROXY)
@ -813,7 +810,7 @@ bool IsValidPlayer (edict_t *ent)
bool IsValidBot (edict_t *ent)
{
if (g_botManager->GetBot (ent) != NULL || (!FNullEnt (ent) && (ent->v.flags & FL_FAKECLIENT)))
if (g_botManager->GetBot (ent) != NULL || (!IsEntityNull (ent) && (ent->v.flags & FL_FAKECLIENT)))
return true;
return false;
@ -884,7 +881,7 @@ void ServerPrint (const char *format, ...)
vsprintf (string, g_localizer->TranslateInput (format), ap);
va_end (ap);
SERVER_PRINT (FormatBuffer ("[%s] %s\n", PRODUCT_LOGTAG, string));
SERVER_PRINT (FormatBuffer ("%s\n", string));
}
void ServerPrintNoTag (const char *format, ...)
@ -952,7 +949,7 @@ void ClientPrint (edict_t *ent, int dest, const char *format, ...)
vsprintf (string, g_localizer->TranslateInput (format), ap);
va_end (ap);
if (FNullEnt (ent) || ent == g_hostEntity)
if (IsEntityNull (ent) || ent == g_hostEntity)
{
if (dest & 0x3ff)
ServerPrint (string);
@ -1079,9 +1076,9 @@ void CheckWelcomeMessage (void)
if (receiveTime > 0.0 && receiveTime < GetWorldTime () && !isReceived && (g_numWaypoints > 0 ? g_isCommencing : true))
{
ServerCommand ("speak \"%s\"", const_cast <char *> (sentences.GetRandomElement ().ToString ()));
ServerCommand ("speak \"%s\"", const_cast <char *> (sentences.GetRandomElement ().GetBuffer ()));
ChartPrint ("----- YaPB v%s (Build: %u), {%s}, (c) 2014, by %s -----", PRODUCT_VERSION, GenerateBuildNumber (), PRODUCT_DATE, PRODUCT_AUTHOR);
ChartPrint ("----- YaPB v%s (Build: %u), {%s}, (c) 2015, by %s -----", PRODUCT_VERSION, GenerateBuildNumber (), PRODUCT_DATE, PRODUCT_AUTHOR);
HudMessage (g_hostEntity, true, Vector (g_randGen.Long (33, 255), g_randGen.Long (33, 255), g_randGen.Long (33, 255)), "\nServer is running YaPB v%s (Build: %u)\nDeveloped by %s\n\n%s", PRODUCT_VERSION, GenerateBuildNumber (), PRODUCT_AUTHOR, g_waypoint->GetInfo ());
receiveTime = 0.0;
@ -1402,15 +1399,15 @@ bool FindNearestPlayer (void **pvHolder, edict_t *to, float searchDistance, bool
edict_t *ent = NULL, *survive = NULL; // pointer to temporaly & survive entity
float nearestPlayer = 4096.0; // nearest player
while (!FNullEnt (ent = FIND_ENTITY_IN_SPHERE (ent, to->v.origin, searchDistance)))
while (!IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, to->v.origin, searchDistance)))
{
if (FNullEnt (ent) || !IsValidPlayer (ent) || to == ent)
if (IsEntityNull (ent) || !IsValidPlayer (ent) || to == ent)
continue; // skip invalid players
if ((sameTeam && GetTeam (ent) != GetTeam (to)) || (isAlive && !IsAlive (ent)) || (needBot && !IsValidBot (ent)) || (needDrawn && (ent->v.effects & EF_NODRAW)))
continue; // filter players with parameters
float distance = (ent->v.origin - to->v.origin).GetLength ();
float distance = (ent->v.origin - to->v.origin).GetLengthSquared ();
if (distance < nearestPlayer)
{
@ -1419,7 +1416,7 @@ bool FindNearestPlayer (void **pvHolder, edict_t *to, float searchDistance, bool
}
}
if (FNullEnt (survive))
if (IsEntityNull (survive))
return false; // nothing found
// fill the holder
@ -1436,7 +1433,7 @@ void SoundAttachToThreat (edict_t *ent, const char *sample, float volume)
// this function called by the sound hooking code (in emit_sound) enters the played sound into
// the array associated with the entity
if (FNullEnt (ent) || IsNullString (sample))
if (IsEntityNull (ent) || IsNullString (sample))
return; // reliability check
Vector origin = GetEntityOrigin (ent);

View file

@ -1,4 +1,4 @@
//
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
@ -9,10 +9,10 @@
#include <core.h>
ConVar yb_wptsubfolder ("yb_wptsubfolder", "");
ConVar yb_wptsubfolder ("yb_wptsubfolder", "", VT_NOSERVER);
ConVar yb_waypoint_autodl_host ("yb_waypoint_autodl_host", "yapb.jeefo.net");
ConVar yb_waypoint_autodl_enable ("yb_waypoint_autodl_enable", "1");
ConVar yb_waypoint_autodl_host ("yb_waypoint_autodl_host", "yapb.jeefo.net", VT_NOSERVER);
ConVar yb_waypoint_autodl_enable ("yb_waypoint_autodl_enable", "1", VT_NOSERVER);
void Waypoint::Init (void)
{
@ -104,7 +104,7 @@ int Waypoint::FindFarest (Vector origin, float maxDistance)
int Waypoint::FindNearest (Vector origin, float minDistance, int flags)
{
// find the nearest waypoint to that Origin and return the index
// find the nearest waypoint to that origin and return the index
int index = -1;
@ -156,7 +156,7 @@ void Waypoint::FindInRadius (Array <int> &queueID, float radius, Vector origin)
void Waypoint::Add (int flags, const Vector &waypointOrigin)
{
if (FNullEnt (g_hostEntity))
if (IsEntityNull (g_hostEntity))
return;
int index = -1, i;
@ -234,7 +234,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin)
placeNew = false;
path = m_paths[index];
int flags = 0;
flags = 0;
for (i = 0; i < MAX_PATH_INDEX; i++)
flags += path->connectionFlags[i];
@ -581,11 +581,11 @@ int Waypoint::GetFacingIndex (void)
// get the current view cone
viewCone[0] = GetShootingConeDeviation (g_hostEntity, &m_paths[i]->origin);
Vector bound = m_paths[i]->origin - Vector (0, 0, m_paths[i]->flags & FLAG_CROUCH ? 8 : 15);
Vector bound = m_paths[i]->origin - Vector (0, 0, (m_paths[i]->flags & FLAG_CROUCH) ? 8 : 15);
// get the current view cone
viewCone[1] = GetShootingConeDeviation (g_hostEntity, &bound);
bound = m_paths[i]->origin + Vector (0, 0, m_paths[i]->flags & FLAG_CROUCH ? 8 : 15);
bound = m_paths[i]->origin + Vector (0, 0, (m_paths[i]->flags & FLAG_CROUCH) ? 8 : 15);
// get the current view cone
viewCone[2] = GetShootingConeDeviation (g_hostEntity, &bound);
@ -1252,7 +1252,6 @@ bool Waypoint::Reachable (Bot *bot, int index)
Vector dest = GetPath (index)->origin;
float distance = (dest - src).GetLength ();
float distance2D = (dest - src).GetLength2D ();
// check is destination is close to us enoguh
if (distance >= 201) // Default: 201
@ -1260,6 +1259,8 @@ bool Waypoint::Reachable (Bot *bot, int index)
if (bot->pev->waterlevel == 2 || bot->pev->waterlevel == 3)
{
float distance2D = (dest - src).GetLength2D ();
// is destination waypoint higher that source (45 is max jump height), or destination waypoint higher that source
if ((dest.z > src.z + 40.0 || dest.z < src.z - 75.0) && (!(GetPath (index)->flags & FLAG_LADDER) || distance2D >= 16.0))
return false; // unable to reach this one
@ -1289,7 +1290,7 @@ bool Waypoint::IsNodeReachable (Vector src, Vector destination)
// check if we go through a func_illusionary, in which case return false
TraceHull (src, destination, ignore_monsters, head_hull, g_hostEntity, &tr);
if (!FNullEnt (tr.pHit) && strcmp ("func_illusionary", STRING (tr.pHit->v.classname)) == 0)
if (!IsEntityNull (tr.pHit) && strcmp ("func_illusionary", STRING (tr.pHit->v.classname)) == 0)
return false; // don't add pathwaypoints through func_illusionaries
// check if this waypoint is "visible"...
@ -1467,7 +1468,7 @@ char *Waypoint::GetWaypointInfo (int id)
}
static char messageBuffer[1024];
sprintf (messageBuffer, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (path->flags == 0 && !jumpPoint) ? " (none)" : "", path->flags & FLAG_LIFT ? " LIFT" : "", path->flags & FLAG_CROUCH ? " CROUCH" : "", path->flags & FLAG_CROSSING ? " CROSSING" : "", path->flags & FLAG_CAMP ? " CAMP" : "", path->flags & FLAG_TF_ONLY ? " TERRORIST" : "", path->flags & FLAG_CF_ONLY ? " CT" : "", path->flags & FLAG_SNIPER ? " SNIPER" : "", path->flags & FLAG_GOAL ? " GOAL" : "", path->flags & FLAG_LADDER ? " LADDER" : "", path->flags & FLAG_RESCUE ? " RESCUE" : "", path->flags & FLAG_DOUBLEJUMP ? " JUMPHELP" : "", path->flags & FLAG_NOHOSTAGE ? " NOHOSTAGE" : "", jumpPoint ? " JUMP" : "");
sprintf (messageBuffer, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (path->flags == 0 && !jumpPoint) ? " (none)" : "", (path->flags & FLAG_LIFT) ? " LIFT" : "", (path->flags & FLAG_CROUCH) ? " CROUCH" : "", (path->flags & FLAG_CROSSING) ? " CROSSING" : "", (path->flags & FLAG_CAMP) ? " CAMP" : "", (path->flags & FLAG_TF_ONLY) ? " TERRORIST" : "", (path->flags & FLAG_CF_ONLY) ? " CT" : "", (path->flags & FLAG_SNIPER) ? " SNIPER" : "", (path->flags & FLAG_GOAL) ? " GOAL" : "", (path->flags & FLAG_LADDER) ? " LADDER" : "", (path->flags & FLAG_RESCUE) ? " RESCUE" : "", (path->flags & FLAG_DOUBLEJUMP) ? " JUMPHELP" : "", (path->flags & FLAG_NOHOSTAGE) ? " NOHOSTAGE" : "", jumpPoint ? " JUMP" : "");
// return the message buffer
return messageBuffer;
@ -1477,7 +1478,7 @@ void Waypoint::Think (void)
{
// this function executes frame of waypoint operation code.
if (FNullEnt (g_hostEntity))
if (IsEntityNull (g_hostEntity))
return; // this function is only valid on listenserver, and in waypoint enabled mode.
float nearestDistance = FLT_MAX;
@ -1644,7 +1645,7 @@ void Waypoint::Think (void)
// draw the camplines
if (path->flags & FLAG_CAMP)
{
Vector campSourceOrigin = campSourceOrigin = path->origin + Vector (0, 0, 36);
Vector campSourceOrigin = path->origin + Vector (0, 0, 36);
// check if it's a source
if (path->flags & FLAG_CROUCH)
@ -1807,7 +1808,7 @@ bool Waypoint::NodesValid (void)
{
connections = 0;
for (int j = 0; j < MAX_PATH_INDEX; j++)
for (j = 0; j < MAX_PATH_INDEX; j++)
{
if (m_paths[i]->index[j] != -1)
{
@ -1987,15 +1988,15 @@ bool Waypoint::NodesValid (void)
visited[current->index] = true;
IterateArray (outgoingPaths[current->index], j)
IterateArray (outgoingPaths[current->index], p)
{
if (visited[outgoingPaths[current->index][j]])
if (visited[outgoingPaths[current->index][p]])
continue; // skip this waypoint as it's already visited
PathNode *pNewNode = new PathNode;
pNewNode->next = stack;
pNewNode->index = outgoingPaths[current->index][j];
pNewNode->index = outgoingPaths[current->index][p];
stack = pNewNode;
}
delete current;
@ -2006,7 +2007,7 @@ bool Waypoint::NodesValid (void)
if (!visited[i])
{
AddLogEntry (true, LL_WARNING, "Path broken from Waypoint #%d to Waypoint #0!", i);
(*g_engfuncs.pfnSetOrigin) (g_hostEntity, m_paths[i]->origin);
SET_ORIGIN (g_hostEntity, m_paths[i]->origin);
g_waypointOn = true;
g_editNoclip = true;
@ -2180,7 +2181,7 @@ void Waypoint::CreateBasic (void)
edict_t *ent = NULL;
// first of all, if map contains ladder points, create it
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_ladder")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_ladder")))
{
Vector ladderLeft = ent->v.absmin;
Vector ladderRight = ent->v.absmax;
@ -2229,7 +2230,7 @@ void Waypoint::CreateBasic (void)
}
// then terrortist spawnpoints
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_deathmatch")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_deathmatch")))
{
Vector origin = GetEntityOrigin (ent);
@ -2238,7 +2239,7 @@ void Waypoint::CreateBasic (void)
}
// then add ct spawnpoints
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_start")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_start")))
{
Vector origin = GetEntityOrigin (ent);
@ -2247,7 +2248,7 @@ void Waypoint::CreateBasic (void)
}
// then vip spawnpoint
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_vip_start")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_vip_start")))
{
Vector origin = GetEntityOrigin (ent);
@ -2256,7 +2257,7 @@ void Waypoint::CreateBasic (void)
}
// hostage rescue zone
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_hostage_rescue")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_hostage_rescue")))
{
Vector origin = GetEntityOrigin (ent);
@ -2265,7 +2266,7 @@ void Waypoint::CreateBasic (void)
}
// hostage rescue zone (same as above)
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_hostage_rescue")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_hostage_rescue")))
{
Vector origin = GetEntityOrigin (ent);
@ -2274,7 +2275,7 @@ void Waypoint::CreateBasic (void)
}
// bombspot zone
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_bomb_target")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_bomb_target")))
{
Vector origin = GetEntityOrigin (ent);
@ -2283,7 +2284,7 @@ void Waypoint::CreateBasic (void)
}
// bombspot zone (same as above)
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_bomb_target")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_bomb_target")))
{
Vector origin = GetEntityOrigin (ent);
@ -2292,7 +2293,7 @@ void Waypoint::CreateBasic (void)
}
// hostage entities
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "hostage_entity")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "hostage_entity")))
{
// if already saved || moving skip it
if ((ent->v.effects & EF_NODRAW) && (ent->v.speed > 0))
@ -2305,7 +2306,7 @@ void Waypoint::CreateBasic (void)
}
// vip rescue (safety) zone
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_vip_safetyzone")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_vip_safetyzone")))
{
Vector origin = GetEntityOrigin (ent);
@ -2314,7 +2315,7 @@ void Waypoint::CreateBasic (void)
}
// terrorist escape zone
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_escapezone")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_escapezone")))
{
Vector origin = GetEntityOrigin (ent);
@ -2323,7 +2324,7 @@ void Waypoint::CreateBasic (void)
}
// weapons on the map ?
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "armoury_entity")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "armoury_entity")))
{
Vector origin = GetEntityOrigin (ent);
@ -2382,7 +2383,7 @@ void Waypoint::SetBombPosition (bool shouldReset)
edict_t *ent = NULL;
while (!FNullEnt (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade")))
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade")))
{
if (strcmp (STRING (ent->v.model) + 9, "c4.mdl") == 0)
{