helloworld

This commit is contained in:
jeefo 2014-07-30 14:17:46 +04:00
commit 3a4164ec5d
30 changed files with 30901 additions and 0 deletions

6459
source/basecode.cpp Normal file

File diff suppressed because it is too large Load diff

1226
source/botmanager.cpp Normal file

File diff suppressed because it is too large Load diff

468
source/chatlib.cpp Normal file
View file

@ -0,0 +1,468 @@
//
// Copyright (c) 2014, by YaPB Development Team. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Version: $Id:$
//
#include <core.h>
ConVar yb_chat ("yb_chat", "1");
void StripTags (char *buffer)
{
// this function strips 'clan' tags specified below in given string buffer
// first three tags for Enhanced POD-Bot (e[POD], 3[POD], E[POD])
char *tagOpen[] = {"e[P", "3[P", "E[P", "-=", "-[", "-]", "-}", "-{", "<[", "<]", "[-", "]-", "{-", "}-", "[[", "[", "{", "]", "}", "<", ">", "-", "|", "=", "+"};
char *tagClose[] = {"]", "]", "]", "=-", "]-", "[-", "{-", "}-", "]>", "[>", "-]", "-[", "-}", "-{", "]]", "]", "}", "[", "{", ">", "<", "-", "|", "=", "+"};
int index, fieldStart, fieldStop, i;
int length = strlen (buffer); // get length of string
// foreach known tag...
for (index = 0; index < ARRAYSIZE_HLSDK (tagOpen); index++)
{
fieldStart = strstr (buffer, tagOpen[index]) - buffer; // look for a tag start
// have we found a tag start?
if (fieldStart >= 0 && fieldStart < 32)
{
fieldStop = strstr (buffer, tagClose[index]) - buffer; // look for a tag stop
// have we found a tag stop?
if ((fieldStop > fieldStart) && (fieldStop < 32))
{
int tagLength = strlen (tagClose[index]);
for (i = fieldStart; i < length - (fieldStop + tagLength - fieldStart); i++)
buffer[i] = buffer[i + (fieldStop + tagLength - fieldStart)]; // overwrite the buffer with the stripped string
buffer[i] = 0x0; // terminate the string
}
}
}
// have we stripped too much (all the stuff)?
if (buffer[0] != '\0')
{
strtrim (buffer); // if so, string is just a tag
// strip just the tag part...
for (index = 0; index < ARRAYSIZE_HLSDK(tagOpen); index++)
{
fieldStart = strstr (buffer, tagOpen[index]) - buffer; // look for a tag start
// have we found a tag start?
if (fieldStart >= 0 && fieldStart < 32)
{
fieldStop = fieldStart + strlen (tagOpen[index]); // set the tag stop
int tagLength = strlen (tagOpen[index]);
for (i = fieldStart; i < length - tagLength; i++)
buffer[i] = buffer[i + tagLength]; // overwrite the buffer with the stripped string
buffer[i] = 0x0; // terminate the string
fieldStart = strstr (buffer, tagClose[index]) - buffer; // look for a tag stop
// have we found a tag stop ?
if (fieldStart >= 0 && fieldStart < 32)
{
fieldStop = fieldStart + strlen (tagClose[index]); // set the tag
int tagLength = strlen (tagClose[index]);
for (i = fieldStart; i < length - tagLength; i++)
buffer[i] = buffer[i + tagLength]; // overwrite the buffer with the stripped string
buffer[i] = 0; // terminate the string
}
}
}
}
strtrim (buffer); // to finish, strip eventual blanks after and before the tag marks
}
char *HumanizeName (char *name)
{
// this function humanize player name (i.e. trim clan and switch to lower case (sometimes))
static char outputName[256]; // create return name buffer
strcpy (outputName, name); // copy name to new buffer
// drop tag marks, 80 percent of time
if (g_randGen.Long (1, 100) < 80)
StripTags (outputName);
else
strtrim (outputName);
// sometimes switch name to lower characters
// note: since we're using russian names written in english, we reduce this shit to 6 percent
if (g_randGen.Long (1, 100) <= 6)
{
for (int i = 0; i < static_cast <int> (strlen (outputName)); i++)
outputName[i] = tolower (outputName[i]); // to lower case
}
return &outputName[0]; // return terminated string
}
void HumanizeChat (char *buffer)
{
// this function humanize chat string to be more handwritten
int length = strlen (buffer); // get length of string
int i = 0;
// sometimes switch text to lowercase
// note: since we're using russian chat written in english, we reduce this shit to 4 percent
if (g_randGen.Long (1, 100) <= 4)
{
for (i = 0; i < length; i++)
buffer[i] = tolower (buffer[i]); // switch to lowercase
}
if (length > 15)
{
// "length / 2" percent of time drop a character
if (g_randGen.Long (1, 100) < (length / 2))
{
int pos = g_randGen.Long ((length / 8), length - (length / 8)); // chose random position in string
for (i = pos; i < length - 1; i++)
buffer[i] = buffer[i + 1]; // overwrite the buffer with stripped string
buffer[i] = 0x0; // terminate string;
length--; // update new string length
}
// "length" / 4 precent of time swap character
if (g_randGen.Long (1, 100) < (length / 4))
{
int pos = g_randGen.Long ((length / 8), ((3 * length) / 8)); // choose random position in string
char ch = buffer[pos]; // swap characters
buffer[pos] = buffer[pos + 1];
buffer[pos + 1] = ch;
}
}
buffer[length] = 0; // terminate string
}
void Bot::PrepareChatMessage (char *text)
{
// this function parses messages from the botchat, replaces keywords and converts names into a more human style
if (!yb_chat.GetBool () || IsNullString (text))
return;
memset (&m_tempStrings, 0, sizeof (m_tempStrings));
char *textStart = text;
char *pattern = text;
edict_t *talkEntity = NULL;
while (pattern != NULL)
{
// all replacement placeholders start with a %
pattern = strstr (textStart, "%");
if (pattern != NULL)
{
int length = pattern - textStart;
if (length > 0)
strncpy (m_tempStrings, textStart, length);
pattern++;
// player with most frags?
if (*pattern == 'f')
{
int highestFrags = -9000; // just pick some start value
int index = 0;
for (int i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || g_clients[i].ent == GetEntity ())
continue;
int frags = static_cast <int> (g_clients[i].ent->v.frags);
if (frags > highestFrags)
{
highestFrags = frags;
index = i;
}
}
talkEntity = g_clients[index].ent;
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
// mapname?
else if (*pattern == 'm')
strcat (m_tempStrings, GetMapName ());
// roundtime?
else if (*pattern == 'r')
{
int time = static_cast <int> (g_timeRoundEnd - GetWorldTime ());
strcat (m_tempStrings, FormatBuffer ("%02d:%02d", time / 60, time % 60));
}
// chat reply?
else if (*pattern == 's')
{
talkEntity = INDEXENT (m_sayTextBuffer.entityIndex);
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
// teammate alive?
else if (*pattern == 't')
{
int team = GetTeam (GetEntity ());
int i;
for (i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || (g_clients[i].team != team) || (g_clients[i].ent == GetEntity ()))
continue;
break;
}
if (i < GetMaxClients ())
{
if (!FNullEnt (pev->dmg_inflictor) && (GetTeam (GetEntity ()) == GetTeam (pev->dmg_inflictor)))
talkEntity = pev->dmg_inflictor;
else
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
else // no teammates alive...
{
for (i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || (g_clients[i].team != team) || (g_clients[i].ent == GetEntity ()))
continue;
break;
}
if (i < GetMaxClients ())
{
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
}
}
else if (*pattern == 'e')
{
int team = GetTeam (GetEntity ());
int i;
for (i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || (g_clients[i].team == team) || (g_clients[i].ent == GetEntity ()))
continue;
break;
}
if (i < GetMaxClients ())
{
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
else // no teammates alive...
{
for (i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || (g_clients[i].team == team) || (g_clients[i].ent == GetEntity ()))
continue;
break;
}
if (i < GetMaxClients ())
{
talkEntity = g_clients[i].ent;
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
}
}
else if (*pattern == 'd')
{
if (g_gameVersion == CSV_CZERO)
{
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))
{
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");
}
}
else if (*pattern == 'v')
{
talkEntity = m_lastVictim;
if (!FNullEnt (talkEntity))
strcat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))));
}
pattern++;
textStart = pattern;
}
}
// let the bots make some mistakes...
char tempString[160];
strncpy (tempString, textStart, 159);
HumanizeChat (tempString);
strcat (m_tempStrings, tempString);
}
bool CheckKeywords (char *tempMessage, char *reply)
{
// this function checks is string contain keyword, and generates relpy to it
if (!yb_chat.GetBool () || IsNullString (tempMessage))
return false;
IterateArray (g_replyFactory, i)
{
IterateArray (g_replyFactory[i].keywords, j)
{
// check is keyword has occurred in message
if (strstr (tempMessage, g_replyFactory[i].keywords[j].GetBuffer ()) != NULL)
{
Array <String> &replies = g_replyFactory[i].usedReplies;
if (replies.GetElementNumber () >= g_replyFactory[i].replies.GetElementNumber () / 2)
replies.RemoveAll ();
bool replyUsed = false;
const char *generatedReply = g_replyFactory[i].replies.GetRandomElement ();
// don't say this twice
IterateArray (replies, k)
{
if (strstr (replies[k].GetBuffer (), generatedReply) != NULL)
replyUsed = true;
}
// reply not used, so use it
if (!replyUsed)
{
strcpy (reply, generatedReply); // update final buffer
replies.Push (generatedReply); //add to ignore list
return true;
}
}
}
}
// didn't find a keyword? 70% of the time use some universal reply
if (g_randGen.Long (1, 100) < 70 && !g_chatFactory[CHAT_NOKW].IsEmpty ())
{
strcpy (reply, g_chatFactory[CHAT_NOKW].GetRandomElement ().GetBuffer ());
return true;
}
return false;
}
bool Bot::ParseChat (char *reply)
{
// this function parse chat buffer, and prepare buffer to keyword searching
char tempMessage[512];
strcpy (tempMessage, m_sayTextBuffer.sayText); // copy to safe place
// text to uppercase for keyword parsing
for (int i = 0; i < static_cast <int> (strlen (tempMessage)); i++)
tempMessage[i] = toupper (tempMessage[i]);
return CheckKeywords (tempMessage, reply);
}
bool Bot::RepliesToPlayer (void)
{
// this function sends reply to a player
if (m_sayTextBuffer.entityIndex != -1 && !IsNullString (m_sayTextBuffer.sayText))
{
char text[256];
// check is time to chat is good
if (m_sayTextBuffer.timeNextChat < GetWorldTime ())
{
if (g_randGen.Long (1, 100) < m_sayTextBuffer.chatProbability + g_randGen.Long (2, 10) && ParseChat (reinterpret_cast <char *> (&text)))
{
PrepareChatMessage (text);
PushMessageQueue (GSM_SAY);
m_sayTextBuffer.entityIndex = -1;
m_sayTextBuffer.sayText[0] = 0x0;
m_sayTextBuffer.timeNextChat = GetWorldTime () + m_sayTextBuffer.chatDelay;
return true;
}
m_sayTextBuffer.entityIndex = -1;
m_sayTextBuffer.sayText[0] = 0x0;
}
}
return false;
}
void Bot::SayText (const char *text)
{
// this function prints saytext message to all players
if (IsNullString (text))
return;
FakeClientCommand (GetEntity (), "say \"%s\"", text);
}
void Bot::TeamSayText (const char *text)
{
// this function prints saytext message only for teammates
if (IsNullString (text))
return;
FakeClientCommand (GetEntity (), "say_team \"%s\"", text);
}

1539
source/combat.cpp Normal file

File diff suppressed because it is too large Load diff

489
source/globals.cpp Normal file
View file

@ -0,0 +1,489 @@
//
// Copyright (c) 2014, by YaPB Development Team. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Version: $Id:$
//
#include <core.h>
bool g_canSayBombPlanted = true;
bool g_isMetamod = false;
bool g_radioInsteadVoice = false;
bool g_roundEnded = true;
bool g_botsCanPause = false;
bool g_sendAudioFinished = true;
bool g_bombPlanted = false;
bool g_bombSayString = false;
bool g_isCommencing = false;
bool g_editNoclip = false;
bool g_isFakeCommand = false;
bool g_waypointOn = false;
bool g_waypointsChanged = true;
bool g_autoWaypoint = false;
bool g_bLearnJumpWaypoint = false;
bool g_leaderChoosen[2] = {false, false};
float g_lastChatTime = 0.0;
float g_timeRoundStart = 0.0;
float g_timeRoundEnd = 0.0;
float g_timeRoundMid = 0.0;
float g_timeNextBombUpdate = 0.0;
float g_timeBombPlanted = 0.0;
float g_lastRadioTime[2] = {0.0, 0.0};
float g_autoPathDistance = 250.0;
int g_lastRadio[2];
int g_storeAddbotVars[4];
int g_radioSelect[32];
int g_fakeArgc = 0;
int g_gameVersion = CSV_STEAM;
int g_numWaypoints = 0;
int g_mapType = 0;
int g_killHistory = 0;
short g_modelIndexLaser = 0;
short g_modelIndexArrow = 0;
char g_fakeArgv[256];
Array <Array <String> > g_chatFactory;
Array <Array <ChatterItem> > g_chatterFactory;
Array <BotName> g_botNames;
Array <KeywordFactory> g_replyFactory;
RandGen g_randGen;
Library *g_gameLib = NULL;
meta_globals_t *gpMetaGlobals = NULL;
gamedll_funcs_t *gpGamedllFuncs = NULL;
mutil_funcs_t *gpMetaUtilFuncs = NULL;
gamefuncs_t g_functionTable;
EntityAPI_t g_entityAPI = NULL;
NewEntityAPI_t g_getNewEntityAPI = NULL;
BlendAPI_t g_serverBlendingAPI = NULL;
FuncPointers_t g_funcPointers = NULL;
enginefuncs_t g_engfuncs;
Client g_clients[32];
WeaponProperty g_weaponDefs[MAX_WEAPONS + 1];
edict_t *g_worldEdict = NULL;
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};
int g_rusherWeaponPrefs[NUM_WEAPONS] =
{0, 2, 1, 4, 5, 6, 3, 24, 19, 22, 23, 20, 21, 10, 12, 13, 7, 8, 11, 9, 18, 17, 19, 25, 15, 16};
int g_carefulWeaponPrefs[NUM_WEAPONS] =
{0, 2, 1, 4, 25, 6, 3, 7, 8, 12, 10, 13, 11, 9, 24, 18, 14, 17, 16, 15, 19, 20, 21, 22, 23, 5};
int g_grenadeBuyPrecent[NUM_WEAPONS - 23] =
{95, 85, 60};
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,
g_rusherWeaponPrefs,
g_carefulWeaponPrefs
};
// metamod engine & dllapi function tables
metamod_funcs_t gMetaFunctionTable =
{
NULL, // pfnEntityAPI_t ()
NULL, // pfnEntityAPI_t_Post ()
GetEntityAPI2, // pfnEntityAPI_t2 ()
GetEntityAPI2_Post, // pfnEntityAPI_t2_Post ()
NULL, // pfnGetNewDLLFunctions ()
NULL, // pfnGetNewDLLFunctions_Post ()
GetEngineFunctions, // pfnGetEngineFunctions ()
NULL, // pfnGetEngineFunctions_Post ()
};
// metamod plugin information
plugin_info_t Plugin_info =
{
META_INTERFACE_VERSION, // interface version
PRODUCT_NAME, // plugin name
PRODUCT_VERSION, // plugin version
PRODUCT_DATE, // date of creation
PRODUCT_AUTHOR, // plugin author
PRODUCT_URL, // plugin URL
PRODUCT_LOGTAG, // plugin logtag
PT_CHANGELEVEL, // when loadable
PT_ANYTIME, // when unloadable
};
// table with all available actions for the bots (filtered in & out in Bot::SetConditions) some of them have subactions included
TaskItem g_taskFilters[] =
{
{TASK_NORMAL, 0, -1, 0.0, true},
{TASK_PAUSE, 0, -1, 0.0, false},
{TASK_MOVETOPOSITION, 0, -1, 0.0, true},
{TASK_FOLLOWUSER, 0, -1,0.0, true},
{TASK_WAITFORGO, 0, -1, 0.0, true},
{TASK_PICKUPITEM, 0, -1, 0.0, true},
{TASK_CAMP, 0, -1, 0.0, true},
{TASK_PLANTBOMB, 0, -1, 0.0, false},
{TASK_DEFUSEBOMB, 0, -1, 0.0, false},
{TASK_ATTACK, 0, -1, 0.0, false},
{TASK_HUNTENEMY, 0, -1, 0.0, false},
{TASK_SEEKCOVER, 0, -1, 0.0, false},
{TASK_THROWHEGRENADE, 0, -1, 0.0, false},
{TASK_THROWFLASHBANG, 0, -1, 0.0, false},
{TASK_THROWSMOKE, 0, -1, 0.0, false},
{TASK_DOUBLEJUMP, 0, -1, 0.0, false},
{TASK_ESCAPEFROMBOMB, 0, -1, 0.0, false},
{TASK_SHOOTBREAKABLE, 0, -1, 0.0, false},
{TASK_HIDE, 0, -1, 0.0, false},
{TASK_BLINDED, 0, -1, 0.0, false},
{TASK_SPRAY, 0, -1, 0.0, false}
};
// 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 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}}
};
// bot menus
MenuText g_menus[21] =
{
// main menu
{
0x2ff,
"\\yYaPB Main Menu\\w\v\v"
"1. YaPB Control\v"
"2. Features\v\v"
"3. Fill Server\v"
"4. End Round\v\v"
"0. Exit"
},
// bot features menu
{
0x25f,
"\\yYaPB Features\\w\v\v"
"1. Weapon Mode Menu\v"
"2. Waypoint Menu\v"
"3. Select Personality\v\v"
"4. Toggle Debug Mode\v"
"5. Command Menu\v\v"
"0. Exit"
},
// bot control menu
{
0x2ff,
"\\yYaPB Control Menu\\w\v\v"
"1. Add a Bot, Quick\v"
"2. Add a Bot, Specified\v\v"
"3. Remove Random Bot\v"
"4. Remove All Bots\v\v"
"5. Remove Bot Menu\v\v"
"0. Exit"
},
// weapon mode select menu
{
0x27f,
"\\yYaPB Weapon Mode\\w\v\v"
"1. Knives only\v"
"2. Pistols only\v"
"3. Shotguns only\v"
"4. Machine Guns only\v"
"5. Rifles only\v"
"6. Sniper Weapons only\v"
"7. All Weapons\v\v"
"0. Exit"
},
// personality select menu
{
0x20f,
"\\yYaPB Personality\\w\v\v"
"1. Random\v"
"2. Normal\v"
"3. Aggressive\v"
"4. Careful\v\v"
"0. Exit"
},
// skill 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"
"0. Exit"
},
// team select menu
{
0x213,
"\\ySelect a team\\w\v\v"
"1. Terrorist Force\v"
"2. Counter-Terrorist Force\v\v"
"5. Auto-select\v\v"
"0. Exit"
},
// terrorist model select menu
{
0x21f,
"\\ySelect an appearance\\w\v\v"
"1. Phoenix Connexion\v"
"2. L337 Krew\v"
"3. Arctic Avengers\v"
"4. Guerilla Warfare\v\v"
"5. Auto-select\v\v"
"0. Exit"
},
// counter-terrirust model select menu
{
0x21f,
"\\ySelect an appearance\\w\v\v"
"1. Seal Team 6 (DEVGRU)\v"
"2. German GSG-9\v"
"3. UK SAS\v"
"4. French GIGN\v\v"
"5. Auto-select\v\v"
"0. Exit"
},
// main waypoint menu
{
0x3ff,
"\\yWaypoint Operations (Page 1)\\w\v\v"
"1. Show/Hide waypoints\v"
"2. Cache waypoint\v"
"3. Create path\v"
"4. Delete path\v"
"5. Add waypoint\v"
"6. Delete waypoint\v"
"7. Set Autopath Distance\v"
"8. Set Radius\v\v"
"9. Next...\v\v"
"0. Exit"
},
// main waypoint menu (page 2)
{
0x3ff,
"\\yWaypoint Operations (Page 2)\\w\v\v"
"1. Waypoint stats\v"
"2. Autowaypoint on/off\v"
"3. Set flags\v"
"4. Save waypoints\v"
"5. Save without checking\v"
"6. Load waypoints\v"
"7. Check waypoints\v"
"8. Noclip cheat on/off\v\v"
"9. Previous...\v\v"
"0. Exit"
},
// select waypoint radius menu
{
0x3ff,
"\\yWaypoint Radius\\w\v\v"
"1. SetRadius 0\v"
"2. SetRadius 8\v"
"3. SetRadius 16\v"
"4. SetRadius 32\v"
"5. SetRadius 48\v"
"6. SetRadius 64\v"
"7. SetRadius 80\v"
"8. SetRadius 96\v"
"9. SetRadius 128\v\v"
"0. Exit"
},
// waypoint add menu
{
0x3ff,
"\\yWaypoint Type\\w\v\v"
"1. Normal\v"
"\\r2. Terrorist Important\v"
"3. Counter-Terrorist Important\v"
"\\w4. Block with hostage / Ladder\v"
"\\y5. Rescue Zone\v"
"\\w6. Camping\v"
"7. Camp End\v"
"\\r8. Map Goal\v"
"\\w9. Jump\v\v"
"0. Exit"
},
// set waypoint flag menu
{
0x2ff,
"\\yToggle Waypoint Flags\\w\v\v"
"1. Block with Hostage\v"
"2. Terrorists Specific\v"
"3. CTs Specific\v"
"4. Use Elevator\v"
"5. Sniper Point (\\yFor Camp Points Only!\\w)\v\v"
"0. Exit"
},
// kickmenu #1
{
0x0,
NULL,
},
// kickmenu #2
{
0x0,
NULL,
},
// kickmenu #3
{
0x0,
NULL,
},
// kickmenu #4
{
0x0,
NULL,
},
// command menu
{
0x23f,
"\\yBot Command Menu\\w\v\v"
"1. Make Double Jump\v"
"2. Finish Double Jump\v\v"
"3. Drop the C4 Bomb\v"
"4. Drop the Weapon\v\v"
"0. Exit"
},
// auto-path max distance
{
0x27f,
"\\yAutoPath Distance\\w\v\v"
"1. Distance 0\v"
"2. Distance 100\v"
"3. Distance 130\v"
"4. Distance 160\v"
"5. Distance 190\v"
"6. Distance 220\v"
"7. Distance 250 (Default)\v\v"
"0. Exit"
},
// path connections
{
0x207,
"\\yCreate Path (Choose Direction)\\w\v\v"
"1. Outgoing Path\v"
"2. Incoming Path\v"
"3. Bidirectional (Both Ways)\v\v"
"0. Exit"
}
};

3540
source/interface.cpp Normal file

File diff suppressed because it is too large Load diff

2936
source/navigate.cpp Normal file

File diff suppressed because it is too large Load diff

481
source/netmsg.cpp Normal file
View file

@ -0,0 +1,481 @@
//
// Copyright (c) 2014, by YaPB Development Team. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Version: $Id:$
//
#include <core.h>
NetworkMsg::NetworkMsg (void)
{
m_message = NETMSG_UNDEFINED;
m_state = 0;
m_bot = NULL;
for (int i = 0; i < NETMSG_BOTVOICE; i++)
m_registerdMessages[i] = -1;
}
void NetworkMsg::HandleMessageIfRequired (int messageType, int requiredType)
{
if (messageType == m_registerdMessages[requiredType])
SetMessage (requiredType);
}
void NetworkMsg::Execute (void *p)
{
if (m_message == NETMSG_UNDEFINED)
return; // no message or not for bot, return
// some needed variables
static byte r, g, b;
static byte enabled;
static int damageArmor, damageTaken, damageBits;
static int killerIndex, victimIndex, playerIndex;
static int index, numPlayers;
static int state, id, clip;
static Vector damageOrigin;
static WeaponProperty weaponProp;
// now starts of netmessage execution
switch (m_message)
{
case NETMSG_VGUI:
// this message is sent when a VGUI menu is displayed.
if (m_state == 0)
{
switch (PTR_TO_INT (p))
{
case VMS_TEAM:
m_bot->m_startAction = GSM_TEAM_SELECT;
break;
case VMS_TF:
case VMS_CT:
m_bot->m_startAction = GSM_CLASS_SELECT;
break;
}
}
break;
case NETMSG_SHOWMENU:
// this message is sent when a text menu is displayed.
if (m_state < 3) // ignore first 3 fields of message
break;
if (strcmp (PTR_TO_STR (p), "#Team_Select") == 0) // team select menu?
m_bot->m_startAction = GSM_TEAM_SELECT;
else if (strcmp (PTR_TO_STR (p), "#Team_Select_Spect") == 0) // team select menu?
m_bot->m_startAction = GSM_TEAM_SELECT;
else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select_Spect") == 0) // team select menu?
m_bot->m_startAction = GSM_TEAM_SELECT;
else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select") == 0) // team select menu?
m_bot->m_startAction = GSM_TEAM_SELECT;
else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select") == 0) // team select menu?
m_bot->m_startAction = GSM_TEAM_SELECT;
else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select_Spect") == 0) // team select menu?
m_bot->m_startAction = GSM_TEAM_SELECT;
else if (strcmp (PTR_TO_STR (p), "#Terrorist_Select") == 0) // T model select?
m_bot->m_startAction = GSM_CLASS_SELECT;
else if (strcmp (PTR_TO_STR (p), "#CT_Select") == 0) // CT model select menu?
m_bot->m_startAction = GSM_CLASS_SELECT;
break;
case NETMSG_WEAPONLIST:
// this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used.
switch (m_state)
{
case 0:
strcpy (weaponProp.className, PTR_TO_STR (p));
break;
case 1:
weaponProp.ammo1 = PTR_TO_INT (p); // ammo index 1
break;
case 2:
weaponProp.ammo1Max = PTR_TO_INT (p); // max ammo 1
break;
case 5:
weaponProp.slotID = PTR_TO_INT (p); // slot for this weapon
break;
case 6:
weaponProp.position = PTR_TO_INT (p); // position in slot
break;
case 7:
weaponProp.id = PTR_TO_INT (p); // weapon ID
break;
case 8:
weaponProp.flags = PTR_TO_INT (p); // flags for weapon (WTF???)
g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information...
break;
}
break;
case NETMSG_CURWEAPON:
// this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased
switch (m_state)
{
case 0:
state = PTR_TO_INT (p); // state of the current weapon (WTF???)
break;
case 1:
id = PTR_TO_INT (p); // weapon ID of current weapon
break;
case 2:
clip = PTR_TO_INT (p); // ammo currently in the clip for this weapon
if (id <= 31)
{
if (state != 0)
m_bot->m_currentWeapon = id;
// ammo amount decreased ? must have fired a bullet...
if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip)
{
// time fired with in burst firing time ?
if (m_bot->m_timeLastFired + 1.0 > GetWorldTime ())
m_bot->m_burstShotsFired++;
m_bot->m_timeLastFired = GetWorldTime (); // remember the last bullet time
}
m_bot->m_ammoInClip[id] = clip;
}
break;
}
break;
case NETMSG_AMMOX:
// this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable!
switch (m_state)
{
case 0:
index = PTR_TO_INT (p); // ammo index (for type of ammo)
break;
case 1:
m_bot->m_ammo[index] = PTR_TO_INT (p); // store it away
break;
}
break;
case NETMSG_AMMOPICKUP:
// this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably
// not really necessary except it allows the HUD to draw pictures of ammo that have been picked up. The bots
// don't really need pictures since they don't have any eyes anyway.
switch (m_state)
{
case 0:
index = PTR_TO_INT (p);
break;
case 1:
m_bot->m_ammo[index] = PTR_TO_INT (p);
break;
}
break;
case NETMSG_DAMAGE:
// this message gets sent when the bots are getting damaged.
switch (m_state)
{
case 0:
damageArmor = PTR_TO_INT (p);
break;
case 1:
damageTaken = PTR_TO_INT (p);
break;
case 2:
damageBits = PTR_TO_INT (p);
if (m_bot && damageArmor > 0 || damageTaken > 0)
m_bot->TakeDamage (m_bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits);
break;
}
break;
case NETMSG_MONEY:
// this message gets sent when the bots money amount changes
if (m_state == 0)
m_bot->m_moneyAmount = PTR_TO_INT (p); // amount of money
break;
case NETMSG_STATUSICON:
switch (m_state)
{
case 0:
enabled = PTR_TO_BYTE (p);
break;
case 1:
if (strcmp (PTR_TO_STR (p), "defuser") == 0)
m_bot->m_hasDefuser = (enabled != 0);
else if (strcmp (PTR_TO_STR (p), "buyzone") == 0)
{
m_bot->m_inBuyZone = (enabled != 0);
// try to equip in buyzone
m_bot->EquipInBuyzone (0);
}
else if (strcmp (PTR_TO_STR (p), "vipsafety") == 0)
m_bot->m_inVIPZone = (enabled != 0);
else if (strcmp (PTR_TO_STR (p), "c4") == 0)
m_bot->m_inBombZone = (enabled == 2);
break;
}
break;
case NETMSG_DEATH: // this message sends on death
switch (m_state)
{
case 0:
killerIndex = PTR_TO_INT (p);
break;
case 1:
victimIndex = PTR_TO_INT (p);
break;
case 2:
if (killerIndex != 0 && killerIndex != victimIndex)
{
edict_t *killer = INDEXENT (killerIndex);
edict_t *victim = INDEXENT (victimIndex);
if (FNullEnt (killer) || FNullEnt (victim))
break;
// need to send congrats on well placed shot
for (int i = 0; i < GetMaxClients (); i++)
{
Bot *bot = g_botManager->GetBot (i);
if (bot != NULL && IsAlive (bot->GetEntity ()) && killer != bot->GetEntity () && bot->EntityIsVisible (victim->v.origin) && GetTeam (killer) == GetTeam (bot->GetEntity ()) && GetTeam (killer) != GetTeam (victim))
{
if (killer == g_hostEntity)
bot->HandleChatterMessage ("#Bot_NiceShotCommander");
else
bot->HandleChatterMessage ("#Bot_NiceShotPall");
break;
}
}
// notice nearby to victim teammates, that attacker is near
for (int i = 0; i < GetMaxClients (); i++)
{
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))
{
bot->m_actualReactionTime = 0.0;
bot->m_seeEnemyTime = GetWorldTime ();
bot->m_enemy = killer;
bot->m_lastEnemy = killer;
bot->m_lastEnemyOrigin = killer->v.origin;
}
}
Bot *bot = g_botManager->GetBot (killer);
// is this message about a bot who killed somebody?
if (bot != NULL)
bot->m_lastVictim = victim;
else // did a human kill a bot on his team?
{
Bot *bot = g_botManager->GetBot (victim);
if (bot != NULL)
{
if (GetTeam (killer) == GetTeam (victim))
bot->m_voteKickIndex = killerIndex;
bot->m_notKilled = false;
}
}
}
break;
}
break;
case NETMSG_SCREENFADE: // this message gets sent when the Screen fades (Flashbang)
switch (m_state)
{
case 3:
r = PTR_TO_BYTE (p);
break;
case 4:
g = PTR_TO_BYTE (p);
break;
case 5:
b = PTR_TO_BYTE (p);
break;
case 6:
m_bot->TakeBlinded (Vector (r, g, b), PTR_TO_BYTE (p));
break;
}
break;
case NETMSG_HLTV: // round restart in steam cs
switch (m_state)
{
case 0:
numPlayers = PTR_TO_INT (p);
break;
case 1:
if (numPlayers == 0 && PTR_TO_INT (p) == 0)
RoundInit ();
break;
}
break;
case NETMSG_RESETHUD:
#if 0
if (m_bot != NULL)
m_bot->NewRound ();
#endif
break;
case NETMSG_TEXTMSG:
if (m_state == 1)
{
if (FStrEq (PTR_TO_STR (p), "#CTs_Win") ||
FStrEq (PTR_TO_STR (p), "#Bomb_Defused") ||
FStrEq (PTR_TO_STR (p), "#Terrorists_Win") ||
FStrEq (PTR_TO_STR (p), "#Round_Draw") ||
FStrEq (PTR_TO_STR (p), "#All_Hostages_Rescued") ||
FStrEq (PTR_TO_STR (p), "#Target_Saved") ||
FStrEq (PTR_TO_STR (p), "#Hostages_Not_Rescued") ||
FStrEq (PTR_TO_STR (p), "#Terrorists_Not_Escaped") ||
FStrEq (PTR_TO_STR (p), "#VIP_Not_Escaped") ||
FStrEq (PTR_TO_STR (p), "#Escaping_Terrorists_Neutralized") ||
FStrEq (PTR_TO_STR (p), "#VIP_Assassinated") ||
FStrEq (PTR_TO_STR (p), "#VIP_Escaped") ||
FStrEq (PTR_TO_STR (p), "#Terrorists_Escaped") ||
FStrEq (PTR_TO_STR (p), "#CTs_PreventEscape") ||
FStrEq (PTR_TO_STR (p), "#Target_Bombed") ||
FStrEq (PTR_TO_STR (p), "#Game_Commencing") ||
FStrEq (PTR_TO_STR (p), "#Game_will_restart_in"))
{
g_roundEnded = true;
if (FStrEq (PTR_TO_STR (p), "#Game_Commencing"))
g_isCommencing = true;
if (FStrEq (PTR_TO_STR (p), "#CTs_Win"))
g_botManager->SetLastWinner (TEAM_CF); // update last winner for economics
if (FStrEq (PTR_TO_STR (p), "#Terrorists_Win"))
g_botManager->SetLastWinner (TEAM_TF); // update last winner for economics
g_waypoint->SetBombPosition (true);
}
else if (!g_bombPlanted && FStrEq (PTR_TO_STR (p), "#Bomb_Planted"))
{
g_bombPlanted = g_bombSayString = true;
g_timeBombPlanted = GetWorldTime ();
for (int i = 0; i < GetMaxClients (); i++)
{
Bot *bot = g_botManager->GetBot (i);
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);
}
}
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;
}
break;
case NETMSG_SCOREINFO:
switch (m_state)
{
case 0:
playerIndex = PTR_TO_INT (p);
break;
case 4:
if (playerIndex >= 0 && playerIndex <= GetMaxClients ())
{
if (PTR_TO_INT (p) == 1)
g_clients[playerIndex - 1].realTeam = TEAM_TF;
else if (PTR_TO_INT (p) == 2)
g_clients[playerIndex - 1].realTeam = TEAM_CF;
if (yb_csdm_mode.GetInt () == 2)
g_clients[playerIndex - 1].team = playerIndex;
else
g_clients[playerIndex - 1].team = g_clients[playerIndex - 1].realTeam;
}
break;
}
break;
case NETMSG_BARTIME:
if (m_state == 0)
{
if (PTR_TO_INT (p) > 0)
m_bot->m_hasProgressBar = true; // the progress bar on a hud
else if (PTR_TO_INT (p) == 0)
m_bot->m_hasProgressBar = false; // no progress bar or disappeared
}
break;
default:
AddLogEntry (true, LL_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_message);
}
m_state++; // and finally update network message state
}

1744
source/support.cpp Normal file

File diff suppressed because it is too large Load diff

2611
source/waypoint.cpp Normal file

File diff suppressed because it is too large Load diff