Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

805 lines
22 KiB

//++ BulliT
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "weapons.h"
#include "game.h"
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "aggamerules.h"
#include "agclient.h"
#ifndef NO_VOICEGAMEMGR
#include "voice_gamemgr.h"
extern CVoiceGameMgr g_VoiceGameMgr;
#endif
#ifdef AGMSGSTAT
#include "agmsgstat.h"
#endif
extern cvar_t timeleft, fragsleft;
extern int gmsgSayText;
extern int gmsgLocation;
extern int gmsgAuthID;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern int gmsgPlaySound;
extern int gmsgTeamInfo;
extern int g_teamplay;
AgClient::AgClient()
{
}
AgClient::~AgClient()
{
}
FILE_GLOBAL const char* s_szCommands[] =
{
"hud_spectatebar <1,0> - Spectator bar with information.",
"hud_timer <0-3> - Timer mode, 0 off, 1 = Time remaining, 2 = Effective time, 3 clock.",
"hud_playerid <1,0> - Player id.",
"hud_settings <1,0> - Show server settings.",
"cl_matchreport <1,0> - Save matchreport in /report directory.",
"cl_autowepswitch <2,1,0> - Switch to better weapon when you walk over it. 2 = Ag switch",
"cl_scores <0 - 32> - Amount of scores to draw on hud.",
"cl_only_team_talk <1,0> - Only print team talk.",
"auth <name> <pass> - Authenticate you as an admin.",
"newpass <oldpass> <newpass> - Change password.",
"settings - Shows server settings.",
"timeleft - Shows time left.",
"timeout - Call 1 minute timeout.",
"play_team <wavefile> - Players wave file to m8's.",
"play_close <wavefile> - Players wave file to m8's that are close.",
"say enhancements - %%h health, %%a armour, %%q ammo, %%w weapon, %%l location",
"more say - %%p longjump status %%s your score",
"say_close - Says a message to team m8's close to you.",
"spectate - Leave/enter spectator mode.",
"ready/notready - Set ready mode.",
"winamp play/pause/stop/forward/back/next/prev/close/shuffle/repeat/volume 0-255",
"dropitems - Drops flag in CTF mode",
};
bool AgClient::HandleCommand(CBasePlayer* pPlayer)
{
ASSERT(NULL != pPlayer);
if (!pPlayer)
return false;
ASSERT(NULL != pPlayer->pev);
if (!pPlayer->pev)
return false;
ASSERT(NULL != g_pGameRules);
if (!g_pGameRules || 0 == CMD_ARGC())
return false;
if (FStrEq(CMD_ARGV(0), "_special"))
{
return true;
}
else if (FStrEq(CMD_ARGV(0), "say"))
{
Say(pPlayer, All);
return true;
}
else if (FStrEq(CMD_ARGV(0), "say_team"))
{
Say(pPlayer, Team);
return true;
}
else if (FStrEq(CMD_ARGV(0), "say_close"))
{
Say(pPlayer, Close);
return true;
}
else if (FStrEq(CMD_ARGV(0), "spectate" ))
{
if (pPlayer->IsProxy())
return pPlayer->Spectate_HLTV();
//Dont spectate if player is in game in arena.
//Use sound and text flood checks, We dont want lamers to change to often.
if( ( pPlayer->IsIngame() && ARENA == AgGametype() ) || pPlayer->FloodCheck() || pPlayer->FloodSound())
return true;
if (2 == CMD_ARGC() && 1 == atoi(CMD_ARGV(1)))
pPlayer->Spectate_Start();
else if (2 == CMD_ARGC() && 0 == atoi(CMD_ARGV(1)))
pPlayer->Spectate_Stop();
else
pPlayer->Spectate_Spectate();
return true;
}
else if (FStrEq(CMD_ARGV(0), "follownext") && 2 == CMD_ARGC())
{
bool bReverse = 1 == atoi(CMD_ARGV(1));
pPlayer->Spectate_Nextplayer(bReverse);
return true;
}
else if (FStrEq(CMD_ARGV(0), "spec_mode") && 2 == CMD_ARGC())
{
int iSpecMode = atoi(CMD_ARGV(1));
pPlayer->Spectate_SetMode(iSpecMode);
return true;
}
else if (FStrEq(CMD_ARGV(0), "jointeam" ) && 2 == CMD_ARGC())
{
if (pPlayer->IsProxy())
return true;
if (g_teamplay)
{
const char* pszTeamName = "";
const char* pszTeamNumber = CMD_ARGV(1);
int iTeam = atoi(pszTeamNumber)-1;
if (5 == iTeam && g_teamplay)
{
if (!g_pGameRules->IsValidTeam(pPlayer->TeamID()))
{
((CHalfLifeTeamplay*)g_pGameRules)->RecountTeams();
pszTeamName = ((CHalfLifeTeamplay*)g_pGameRules)->TeamWithFewestPlayers();
}
}
else
pszTeamName = g_pGameRules->GetIndexedTeamName(iTeam);
if (strlen(pszTeamName))
g_pGameRules->ChangePlayerTeam(pPlayer,pszTeamName,TRUE,TRUE);
}
if (pPlayer->IsSpectator())
pPlayer->Spectate_Stop();
return true;
}
else if (FStrEq(CMD_ARGV(0), "timeleft" ))
{
if (timelimit.value && timeleft.value)
AgConsole(UTIL_VarArgs("timeleft = %.0f", (double)timeleft.value), pPlayer);
return true;
}
else if (FStrEq(CMD_ARGV(0), "timeout" ))
{
if (ARENA != AgGametype() || LMS != AgGametype())
g_pGameRules->m_Timeout.Timeout(pPlayer);
return true;
}
else if (FStrEq(CMD_ARGV(0), "ready" ))
{
if (ARENA == AgGametype())
{
g_pGameRules->m_Arena.Ready(pPlayer);
return true;
}
else if (LMS == AgGametype())
{
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "Changed mode to READY.\n");
if (!pPlayer->m_bReady)
{
pPlayer->m_bReady = true;
//Send new team name
if (g_pGameRules->IsTeamplay())
{
MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo );
WRITE_BYTE( pPlayer->entindex() );
WRITE_STRING( pPlayer->TeamID() );
MESSAGE_END();
}
}
return true;
}
}
else if (FStrEq(CMD_ARGV(0), "notready" ))
{
if (ARENA == AgGametype())
{
g_pGameRules->m_Arena.NotReady(pPlayer);
return true;
}
else if (LMS == AgGametype())
{
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "Changed mode to NOT READY.\n");
if (pPlayer->m_bReady)
{
pPlayer->m_bReady = false;
pPlayer->SetIngame(false); //Cant respawn
if(!pPlayer->IsSpectator())
{
pPlayer->Spectate_Start(true);
pPlayer->Spectate_SetMode(OBS_IN_EYE);
}
else
{
//Send new team name (blank for specs)
if (g_pGameRules->IsTeamplay())
{
MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo );
WRITE_BYTE( pPlayer->entindex() );
WRITE_STRING( pPlayer->TeamID() );
MESSAGE_END();
}
}
}
return true;
}
}
else if (FStrEq(CMD_ARGV(0), "play_team" ))
{
if (2 == CMD_ARGC())
{
Play(pPlayer, Team, CMD_ARGV(1));
}
return true;
}
else if (FStrEq(CMD_ARGV(0), "play_close" ))
{
if (2 == CMD_ARGC())
{
Play(pPlayer, Close, CMD_ARGV(1));
}
return true;
} else if (FStrEq(CMD_ARGV(0), "auth" ))
{
if (3 == CMD_ARGC())
{
AdminCache.Auth(CMD_ARGV(1), CMD_ARGV(2), pPlayer);
}
return true;
}
else if (FStrEq(CMD_ARGV(0), "newpass" ))
{
if (3 == CMD_ARGC())
{
AdminCache.Newpass(CMD_ARGV(1), CMD_ARGV(2), pPlayer);
}
return true;
}
else if (FStrEq(CMD_ARGV(0), "help"))
{
for (int i = 0; i < sizeof(s_szCommands)/sizeof(s_szCommands[0]); i++)
AgConsole(s_szCommands[i],pPlayer);
//Continue with more help commands.
return false;
}
else if (FStrEq(CMD_ARGV(0), "settings"))
{
pPlayer->SetDisplayGamemode(0);
return true;
}
#ifndef AG_NO_CLIENT_DLL
else if (FStrEq(CMD_ARGV(0), "dropitems") && CTF == AgGametype())
{
g_pGameRules->m_CTF.PlayerDropFlag(pPlayer,true);
return true;
}
#ifdef _DEBUG
else if (FStrEq(CMD_ARGV(0), "addctfitem"))
#else
else if (FStrEq(CMD_ARGV(0), "addctfitem") && g_bLangame)
#endif
{
if (2 == CMD_ARGC())
{
g_pGameRules->m_CTF.m_FileItemCache.Add(CMD_ARGV(1), pPlayer);
}
return true;
}
#ifdef _DEBUG
else if (FStrEq(CMD_ARGV(0), "dellastctfitem"))
#else
else if (FStrEq(CMD_ARGV(0), "dellastctfitem") && g_bLangame)
#endif
{
if (1 == CMD_ARGC())
{
g_pGameRules->m_CTF.m_FileItemCache.Del(pPlayer);
}
return true;
}
#ifdef _DEBUG
else if (FStrEq(CMD_ARGV(0), "listctfitem"))
#else
else if (FStrEq(CMD_ARGV(0), "listctfitem") && g_bLangame)
#endif
{
if (1 == CMD_ARGC())
{
g_pGameRules->m_CTF.m_FileItemCache.List(pPlayer);
}
return true;
}
//++ muphicks
#ifdef _DEBUG
else if (FStrEq(CMD_ARGV(0), "adddomitem"))
#else
else if (FStrEq(CMD_ARGV(0), "adddomitem") && g_bLangame)
#endif
{
if (2 == CMD_ARGC())
{
g_pGameRules->m_DOM.m_FileItemCache.Add(CMD_ARGV(1), pPlayer);
}
return true;
}
#ifdef _DEBUG
else if (FStrEq(CMD_ARGV(0), "dellastdomitem"))
#else
else if (FStrEq(CMD_ARGV(0), "dellastdomitem") && g_bLangame)
#endif
{
if (1 == CMD_ARGC())
{
g_pGameRules->m_DOM.m_FileItemCache.Del(pPlayer);
}
return true;
}
#ifdef _DEBUG
else if (FStrEq(CMD_ARGV(0), "listdomitem"))
#else
else if (FStrEq(CMD_ARGV(0), "listdomitem") && g_bLangame)
#endif
{
if (1 == CMD_ARGC())
{
g_pGameRules->m_DOM.m_FileItemCache.List(pPlayer);
}
return true;
}
//-- muphicks
#endif
else if (FStrEq(CMD_ARGV(0), "changeteam"))
{
#define MENU_TEAM 2
pPlayer->ShowVGUI(MENU_TEAM);
return true;
}
else if (FStrEq(CMD_ARGV(0), "fullupdate"))
{
pPlayer->ForceClientDllUpdate();
return true;
}
else if (FStrEq(CMD_ARGV(0), "agosinfo"))
{
AgConsole(AgOSVersion(),pPlayer);
return true;
}
#ifndef AG_NO_CLIENT_DLL
else if (FStrEq(CMD_ARGV(0), "maplist"))
{
g_pGameRules->SendMapListToClient(pPlayer,true);
return true;
}
#endif
#ifdef AGMSGSTAT
else if (FStrEq(CMD_ARGV(0), "agmsgstat"))
{
g_MsgStat.DumpStats();
return true;
}
#endif
/*
else if (FStrEq(CMD_ARGV(0), "botme"))
{
edict_t* pEntity = g_engfuncs.pfnCreateFakeClient( "botme" );
entvars_t *pev = &pEntity->v;
CBasePlayer* pBot = GetClassPtr((CBasePlayer*)pev); //Link bot object to the edict
pBot->Init();
pev->flags |= FL_FAKECLIENT; // bot is fakeclient
pBot->Spawn();
pev->flags |= FL_FAKECLIENT; // bot is fakeclient
pBot = (CBasePlayer *)CBasePlayer::Instance(pEntity);
g_pGameRules->PlayerThink( pBot);
g_engfuncs.pfnSetClientKeyValue( pPlayer->entindex(),
g_engfuncs.pfnGetInfoKeyBuffer(pEntity), "model", "xxx");
}
*/
return false;
}
CBaseEntity* FindEntityForward( CBasePlayer* pMe )
{
TraceResult tr;
UTIL_MakeVectors(pMe->pev->v_angle);
UTIL_TraceLine(pMe->pev->origin + pMe->pev->view_ofs,pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 2048,missile, pMe->edict(), &tr );
if( tr.flFraction != 1.0f && !FNullEnt( tr.pHit ) )
{
CBaseEntity* pHit = CBaseEntity::Instance( tr.pHit );
return pHit;
}
return NULL;
}
void AgClient::Say(CBasePlayer* pPlayer, say_type Type )
{
char* pSayText = (char*)CMD_ARGS();
if ( CMD_ARGC() < 2 || 128 < strlen(pSayText) || !pPlayer || !g_pGameRules || 1 > strlen(pSayText))
return;
//Check if the user is flooding us with nonsens.
if( ( ( All == Type || pPlayer->IsSpectator() ) && pPlayer->FloodCheck() ) || pPlayer->FloodText())
return;
bool bSendLocation = false;
bool bSendDeathLocation = false;
char szText[256];
char* pText = szText;
if (pPlayer->IsSpectator() && Team == Type)
pText = pText + sprintf(pText,"%c(ST) %s: ", 2, pPlayer->GetName());
else if (pPlayer->IsSpectator())
pText = pText + sprintf(pText,"%c(S) %s: ", 2, pPlayer->GetName());
else if (Team == Type)
pText = pText + sprintf(pText,"%c(T) %s: ", 2, pPlayer->GetName());
else if (Close == Type)
pText = pText + sprintf(pText,"%c(C) %s: ", 2, pPlayer->GetName());
else
pText = pText + sprintf(pText,"%c(A) %s: ", 2, pPlayer->GetName());
//Remove quotes
if (*pSayText == '"')
{
pSayText++;
pSayText[strlen(pSayText)-1] = 0;
}
if (1 > strlen(pSayText))
return;
//Check AG teambind
while (*pSayText && (pText - szText) < 200) //Dont overflow the string. Stop when its 200 chars.
{
if ('%' == *pSayText)
{
pSayText++;
if ('h' == *pSayText || 'H' == *pSayText)
{
//Health.
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator())
pText = pText + sprintf(pText,"%.0f", (double)pPlayer->pev->health);
pSayText++;
continue;
}
else if ('a' == *pSayText || 'A' == *pSayText)
{
//Armour.
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator())
pText = pText + sprintf(pText,"%.0f",pPlayer->pev->armorvalue);
pSayText++;
continue;
}
else if ('q' == *pSayText || 'Q' == *pSayText)
{
//Ammo.
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator() && pPlayer->m_pActiveItem && pPlayer->m_pActiveItem->m_iId < MAX_AMMO_SLOTS)
{
CBasePlayerWeapon* pWeapon = (CBasePlayerWeapon*)pPlayer->m_pActiveItem->GetWeaponPtr();
if (pWeapon)
{
int iAmmoIndex1 = -1;
int iAmmoIndex2 = -1;
if (pWeapon->pszAmmo1())
iAmmoIndex1 = pPlayer->GetAmmoIndex( pWeapon->pszAmmo1() );
if (pWeapon->pszAmmo2())
iAmmoIndex2 = pPlayer->GetAmmoIndex( pWeapon->pszAmmo2() );
if (iAmmoIndex1 != -1 && iAmmoIndex2 != -1)
pText = pText + sprintf(pText,"%d/%d",(int)(pPlayer->m_rgAmmo[iAmmoIndex1] + pWeapon->m_iClip),(int)(pPlayer->m_rgAmmo[iAmmoIndex2]));
else if (iAmmoIndex1 != -1)
pText = pText + sprintf(pText,"%d",(int)(pPlayer->m_rgAmmo[iAmmoIndex1] + pWeapon->m_iClip));
else if (iAmmoIndex2 != -1)
pText = pText + sprintf(pText,"%d",(int)(pPlayer->m_rgAmmo[iAmmoIndex2] + pWeapon->m_iClip));
else
pText = pText + sprintf(pText,"0");
}
}
pSayText++;
continue;
}
else if ('w' == *pSayText || 'W' == *pSayText)
{
//Weapon
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator() && pPlayer->m_pActiveItem && pPlayer->m_pActiveItem->m_iId < MAX_WEAPONS)
{
char* pWeapon = (char*)strstr(pPlayer->m_pActiveItem->pszName(),"weapon_");
if (pWeapon)
{
pText = pText + sprintf(pText,"%s",&pWeapon[7]);
}
}
pSayText++;
continue;
}
else if ('p' == *pSayText || 'P' == *pSayText)
{
//LJ Status
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator())
{
if (pPlayer->m_fLongJump)
pText = pText + sprintf(pText,"got LJ");
else
pText = pText + sprintf(pText,"no LJ");
}
pSayText++;
continue;
}
/*
else if ('o' == *pSayText || 'o' == *pSayText)
{
//Looking at.
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator())
{
CBaseEntity* pEntity = FindEntityForward(pPlayer);
if (pEntity && pEntity->pev)
pText = pText + sprintf(pText,STRING(pEntity->pev->classname));
}
pSayText++;
continue;
}
*/
else if ('s' == *pSayText || 'S' == *pSayText)
{
//Score
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator())
pText = pText + sprintf(pText,"%.0f/%d", (double)pPlayer->pev->frags, pPlayer->m_iDeaths);
pSayText++;
continue;
}
else if ('f' == *pSayText || 'F' == *pSayText)
{
//Flag info
if (pPlayer && pPlayer->IsAlive() && !pPlayer->IsSpectator())
{
if (pPlayer->m_bFlagTeam1)
pText = pText + sprintf(pText,CTF_TEAM1_NAME);
else if (pPlayer->m_bFlagTeam2)
pText = pText + sprintf(pText,CTF_TEAM2_NAME);
}
pSayText++;
continue;
}
else if ('l' == *pSayText || 'L' == *pSayText)
{
#ifdef AG_NO_CLIENT_DLL
pText = pText + sprintf(pText,g_pGameRules->m_LocationCache.Location(pPlayer->pev->origin).c_str());
pSayText++;
continue;
#else
bSendLocation = true;
pText[0] = '%';
pText++;
#endif
}
else if ('d' == *pSayText || 'D' == *pSayText)
{
#ifdef AG_NO_CLIENT_DLL
pText = pText + sprintf(pText,g_pGameRules->m_LocationCache.Location(pPlayer->GetKilledPosition()).c_str());
pSayText++;
continue;
#else
bSendDeathLocation = true;
pText[0] = '%';
pText++;
#endif
}
else
{
pText[0] = '%';
pText++;
continue;
}
}
*pText = *pSayText;
pText++;
pSayText++;
}
*pText = '\0';
#ifdef AG_NO_CLIENT_DLL
AgStripColors(szText);
#endif
// team match?
const char *temp;
if (All == Type)
temp = "say";
else
temp = "say_team";
if ( g_teamplay )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" %s \"%s\"\n",
STRING( pPlayer->edict()->v.netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ),
temp,
szText );
}
else
{
UTIL_LogPrintf( "\"%s<%i><%s><%i>\" %s \"%s\"\n",
STRING( pPlayer->edict()->v.netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GETPLAYERUSERID( pPlayer->edict() ),
temp,
szText );
}
if (pPlayer->IsSpectator())
{
//Spectators can talk to team m8
//Loop through all players
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer* pPlayerLoop = AgPlayerByIndex(i);
if (pPlayerLoop && pPlayerLoop->IsNetClient())
{
#ifndef NO_VOICEGAMEMGR
// can the receiver hear the sender? or has he muted him?
if ( g_VoiceGameMgr.PlayerHasBlockedPlayer( pPlayerLoop, pPlayer ) )
continue;
#endif
//Sort team messages. Only talk to team m8's that are spectators
if ( (Team == Type || Close == Type )
&& !pPlayerLoop->IsSpectator() && pPlayer != pPlayerLoop)
continue;
//Dont let specs talk to all if spectalk = 0 if it aint an admin on a match
if (0 == ag_spectalk.value && !pPlayer->IsAdmin() && All == Type && 0 < ag_match_running.value && pPlayer != pPlayerLoop)
continue;
#ifndef AG_NO_CLIENT_DLL
if (bSendLocation)
{
MESSAGE_BEGIN( MSG_ONE, gmsgLocation, NULL, pPlayerLoop->edict() );
WRITE_BYTE( ENTINDEX(pPlayer->edict()) );
WRITE_COORD( pPlayer->pev->origin[0]);
WRITE_COORD( pPlayer->pev->origin[1]);
WRITE_COORD( pPlayer->pev->origin[2]);
MESSAGE_END();
}
if (bSendDeathLocation)
{
MESSAGE_BEGIN( MSG_ONE, gmsgLocation, NULL, pPlayerLoop->edict() );
WRITE_BYTE( ENTINDEX(pPlayer->edict()) );
WRITE_COORD( pPlayer->GetKilledPosition()[0]);
WRITE_COORD( pPlayer->GetKilledPosition()[1]);
WRITE_COORD( pPlayer->GetKilledPosition()[2]);
MESSAGE_END();
}
#endif
//Ok to send text.
MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, pPlayerLoop->edict() );
WRITE_BYTE( pPlayer->entindex() );
WRITE_STRING( UTIL_VarArgs("%s\n", szText) );
MESSAGE_END();
}
}
}
else
{
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer* pPlayerLoop = AgPlayerByIndex(i);
if (pPlayerLoop && pPlayerLoop->IsNetClient())
{
#ifndef NO_VOICEGAMEMGR
// can the receiver hear the sender? or has he muted him?
if ( g_VoiceGameMgr.PlayerHasBlockedPlayer( pPlayerLoop, pPlayer ) )
continue;
#endif
if (Close == Type && pPlayer != pPlayerLoop)
{
//Check if team m8 is close enough.
vec3_t vDist = pPlayerLoop->pev->origin - pPlayer->pev->origin;
if (vDist .Length () > 700)
continue;
}
// for team or close we only say to our own team
if ( (Team == Type || Close == Type ) &&
g_pGameRules->PlayerRelationship(pPlayerLoop, pPlayer) != GR_TEAMMATE &&
pPlayer != pPlayerLoop)
continue;
//Dont let spectators read your team talk.
if ( (Team == Type || Close == Type ) && pPlayerLoop->IsSpectator())
continue;
#ifndef AG_NO_CLIENT_DLL
if (bSendLocation)
{
MESSAGE_BEGIN( MSG_ONE, gmsgLocation, NULL, pPlayerLoop->edict() );
WRITE_BYTE( ENTINDEX(pPlayer->edict()) );
WRITE_COORD( pPlayer->pev->origin[0]);
WRITE_COORD( pPlayer->pev->origin[1]);
WRITE_COORD( pPlayer->pev->origin[2]);
MESSAGE_END();
}
if (bSendDeathLocation)
{
MESSAGE_BEGIN( MSG_ONE, gmsgLocation, NULL, pPlayerLoop->edict() );
WRITE_BYTE( ENTINDEX(pPlayer->edict()) );
WRITE_COORD( pPlayer->GetKilledPosition()[0]);
WRITE_COORD( pPlayer->GetKilledPosition()[1]);
WRITE_COORD( pPlayer->GetKilledPosition()[2]);
MESSAGE_END();
}
#endif
//Ok to send text.
MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, pPlayerLoop->edict() );
WRITE_BYTE( pPlayer->entindex() );
WRITE_STRING( UTIL_VarArgs("%s\n", szText) );
MESSAGE_END();
}
}
}
// echo to server console
AgConsole(szText);
}
void AgClient::Play(CBasePlayer* pPlayer, say_type Type, const char* pszWave)
{
//Check for flooding if spectator
if( ( pPlayer->IsSpectator() && pPlayer->FloodCheck() ) || !g_pGameRules->IsTeamplay() || pPlayer->FloodSound())
return;
//Play sound to teammates.
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer* pPlayerLoop = AgPlayerByIndex(i);
// for team or close we only play to our own team
if ( (Team == Type || Close == Type) && !(pPlayerLoop == pPlayer || g_pGameRules->PlayerRelationship( pPlayer, pPlayerLoop ) == GR_TEAMMATE))
continue;
vec3_t vDist = pPlayerLoop->pev->origin - pPlayer->pev->origin;
if (Type == Close && vDist.Length () > 700)
continue;
//Dont let spectators hear your team talk.
if ( (Team == Type || Close == Type ) && pPlayerLoop->IsSpectator())
continue;
#ifdef AG_NO_CLIENT_DLL
AgSound(pPlayerLoop, pszWave);
#else
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, gmsgPlaySound, NULL, pPlayerLoop->pev );
WRITE_BYTE( pPlayer->entindex());
WRITE_COORD( pPlayer->pev->origin[0]);
WRITE_COORD( pPlayer->pev->origin[1]);
WRITE_COORD( pPlayer->pev->origin[2]);
WRITE_STRING(pszWave);
MESSAGE_END();
#endif
/*
MESSAGE_BEGIN( MSG_ONE, gmsgPlaySound, NULL, pPlayerLoop->pev );
WRITE_SHORT( pPlayer->entindex());
WRITE_STRING(CMD_ARGV(1));
MESSAGE_END();
*/
}
}
//-- Martin Webrant