yapb-noob-edition/source/netmsg.cpp

483 lines
15 KiB
C++
Raw Normal View History

2014-07-30 14:17:46 +04:00
//
// 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;
2014-07-30 17:49:31 +04:00
else
g_clients[playerIndex - 1].realTeam = TEAM_SPEC;
2014-07-30 14:17:46 +04:00
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
}