代码拉取完成,页面将自动刷新
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "saverestore.h"
#include "player.h"
#include "spectator.h"
#include "client.h"
#include "soundent.h"
#include "gamerules.h"
#include "game.h"
#include "customentity.h"
#include "weapons.h"
#include "weaponinfo.h"
#include "usercmd.h"
#include "netadr.h"
#include "monsters.h"
#include "triggers.h"
#include "globals.h"
#include "entity_state.h"
#include "shake.h"
#include "unicode_strtools.h"
#include "debug.h"
#include "bot_include.h"
#include "gamemode/mods.h"
#include "player/player_model.h"
#include "player/player_mod_strategy.h"
#include "player/player_zombie.h"
#include "weapons_buy.h"
#include <tuple>
namespace sv {
/*
* Globals initialization
*/
time_point_t g_flTimeLimit;
time_point_t g_flResetTime;
bool g_bClientPrintEnable = true;
bool g_skipCareerInitialSpawn = false;
static entity_field_alias_t entity_field_alias[] =
{
{"origin[0]", 0},
{"origin[1]", 0},
{"origin[2]", 0},
{"angles[0]", 0},
{"angles[1]", 0},
{"angles[2]", 0},
};
static entity_field_alias_t player_field_alias[] =
{
{"origin[0]", 0},
{"origin[1]", 0},
{"origin[2]", 0},
};
static entity_field_alias_t custom_entity_field_alias[] =
{
{"origin[0]", 0},
{"origin[1]", 0},
{"origin[2]", 0},
{"angles[0]", 0},
{"angles[1]", 0},
{"angles[2]", 0},
{"skin", 0},
{"sequence", 0},
{"animtime", 0},
};
static int g_serveractive = 0;
PLAYERPVSSTATUS g_PVSStatus[MAX_CLIENTS];
unsigned short m_usResetDecals;
unsigned short g_iShadowSprite;
int CMD_ARGC_()
{
if (!UseBotArgs)
return CMD_ARGC();
int i = 0;
while (BotArgs[i])
++i;
return i;
}
const char *CMD_ARGV_(int i)
{
if (!UseBotArgs)
return CMD_ARGV(i);
if (i < 4)
return BotArgs[i];
return NULL;
}
NOXREF void set_suicide_frame(entvars_t *pev)
{
if (!FStrEq(STRING(pev->model), "models/player.mdl"))
return;
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_TOSS;
pev->deadflag = DEAD_DEAD;
pev->nextthink = {};
}
void TeamChangeUpdate(CBasePlayer *player, int team_id)
{
MESSAGE_BEGIN(MSG_ALL, gmsgTeamInfo);
WRITE_BYTE(player->entindex());
switch (team_id) {
case CT:
WRITE_STRING("CT");
break;
case TERRORIST:
WRITE_STRING("TERRORIST");
break;
case SPECTATOR:
WRITE_STRING("SPECTATOR");
break;
default:
WRITE_STRING("UNASSIGNED");
break;
}
MESSAGE_END();
if (team_id != UNASSIGNED) {
player->SetScoreboardAttributes();
}
}
void BlinkAccount(CBasePlayer *player, int numBlinks)
{
MESSAGE_BEGIN(MSG_ONE, gmsgBlinkAcct, NULL, player->pev);
WRITE_BYTE(numBlinks);
MESSAGE_END();
}
BOOL EXT_FUNC ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *szRejectReason)
{
return g_pGameRules->ClientConnected(pEntity, pszName, pszAddress, szRejectReason);
}
void EXT_FUNC ClientDisconnect(edict_t *pEntity)
{
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(CBaseEntity::Instance(pEntity));
if (!g_fGameOver) {
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, "#Game_disconnected", STRING(pEntity->v.netname));
#if 0
CSound *pSound = CSoundEnt::SoundPointerForIndex(CSoundEnt::ClientSoundIndex(pEntity));
if (pSound)
pSound->Reset();
#endif
pEntity->v.takedamage = DAMAGE_NO;
pEntity->v.solid = SOLID_NOT;
pEntity->v.flags = FL_DORMANT;
if (pPlayer != NULL)
pPlayer->SetThink(NULL);
UTIL_SetOrigin(&pEntity->v, pEntity->v.origin);
g_pGameRules->ClientDisconnected(pEntity);
}
if (TheBots != NULL) {
TheBots->ClientDisconnect(pPlayer);
}
}
void respawn(entvars_t *pev, BOOL fCopyCorpse)
{
if (gpGlobals->coop || gpGlobals->deathmatch) {
CHalfLifeMultiplay *mp = g_pGameRules;
if (mp->m_iTotalRoundsPlayed > 0)
mp->MarkSpawnSkipped();
CBasePlayer *pPlayer = GetClassPtr<CBasePlayer>(pev);
if (mp->IsCareer() && mp->ShouldSkipSpawn() && pPlayer->IsAlive())
g_skipCareerInitialSpawn = true;
pPlayer->Spawn();
g_skipCareerInitialSpawn = false;
} else if (pev->deadflag > DEAD_NO) {
SERVER_COMMAND("reload\n");
}
}
// Suicide...
void EXT_FUNC ClientKill(edict_t *pEntity)
{
entvars_t *pev = &pEntity->v;
CHalfLifeMultiplay *mp = g_pGameRules;
CBasePlayer *pl = (CBasePlayer *) CBasePlayer::Instance(pev);
if (pl->IsObserver())
return;
if (pl->m_iJoiningState != JOINED)
return;
// prevent suiciding too often
if (pl->m_fNextSuicideTime > gpGlobals->time)
return;
pl->m_LastHitGroup = 0;
// don't let them suicide for 5 seconds after suiciding
pl->m_fNextSuicideTime = gpGlobals->time + 1s;
// have the player kill themself
pEntity->v.health = 0;
pl->Killed(pev, GIB_NEVER);
if (mp->m_pVIP == pl) {
mp->m_iConsecutiveVIP = 10;
}
}
void ShowMenu(CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, const char *pszText)
{
MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pPlayer->pev);
WRITE_SHORT(bitsValidSlots);
WRITE_CHAR(nDisplayTime);
WRITE_BYTE(fNeedMore);
WRITE_STRING(pszText);
MESSAGE_END();
}
void ShowVGUIMenu(CBasePlayer *pPlayer, int MenuType, int BitMask, const char *szOldMenu)
{
if (pPlayer->m_bVGUIMenus || MenuType > VGUI_Menu_Buy_Item) {
MESSAGE_BEGIN(MSG_ONE, gmsgVGUIMenu, NULL, pPlayer->pev);
WRITE_BYTE(MenuType);
WRITE_SHORT(BitMask);
WRITE_CHAR(-1);
WRITE_BYTE(0);
WRITE_STRING(" ");
MESSAGE_END();
} else
ShowMenu(pPlayer, BitMask, -1, 0, szOldMenu);
}
NOXREF int CountTeams()
{
int iNumCT = 0, iNumTerrorist = 0;
CBaseEntity *pPlayer = NULL;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) {
if (FNullEnt(pPlayer->edict()))
break;
CBasePlayer *player = GetClassPtr<CBasePlayer>(pPlayer->pev);
if (player->m_iTeam == UNASSIGNED)
continue;
if (player->pev->flags & FL_DORMANT)
continue;
if (player->m_iTeam == SPECTATOR)
continue;
if (player->m_iTeam == CT)
iNumCT++;
else if (player->m_iTeam == TERRORIST)
iNumTerrorist++;
}
return iNumCT - iNumTerrorist;
}
void ListPlayers(CBasePlayer *current)
{
char message[120], cNumber[12];
Q_strcpy(message, "");
CBaseEntity *pPlayer = NULL;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) {
if (FNullEnt(pPlayer->edict()))
break;
if (pPlayer->pev->flags & FL_DORMANT)
continue;
CBasePlayer *player = GetClassPtr<CBasePlayer>(pPlayer->pev);
int iUserID = GETPLAYERUSERID(ENT(player->pev));
Q_sprintf(cNumber, "%d", iUserID);
Q_strcpy(message, "\n");
Q_strcat(message, cNumber);
Q_strcat(message, " : ");
Q_strcat(message, STRING(player->pev->netname));
ClientPrint(current->pev, HUD_PRINTCONSOLE, message);
}
ClientPrint(current->pev, HUD_PRINTCONSOLE, "\n");
}
int CountTeamPlayers(int iTeam)
{
CBaseEntity *pPlayer = NULL;
int i = 0;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) {
if (FNullEnt(pPlayer->edict()))
break;
if (pPlayer->pev->flags & FL_DORMANT)
continue;
if (GetClassPtr<CBasePlayer>(pPlayer->pev)->m_iTeam == iTeam)
++i;
}
return i;
}
void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
{
CBaseEntity *pTempEntity;
CBasePlayer *pTempPlayer;
int iValidVotes;
int iVoteID;
int iVotesNeeded;
float fKickPercent;
if (!pVotingPlayer || !pKickPlayer)
return;
int iTeamCount = CountTeamPlayers(pVotingPlayer->m_iTeam);
if (iTeamCount < 3)
return;
iValidVotes = 0;
pTempEntity = NULL;
iVoteID = pVotingPlayer->m_iCurrentKickVote;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")) != NULL) {
if (FNullEnt(pTempEntity->edict()))
break;
pTempPlayer = GetClassPtr<CBasePlayer>(pTempEntity->pev);
if (!pTempPlayer || pTempPlayer->m_iTeam == UNASSIGNED)
continue;
if (pTempPlayer->m_iTeam == pVotingPlayer->m_iTeam && pTempPlayer->m_iCurrentKickVote == iVoteID)
iValidVotes++;
}
if (kick_percent.value < 0)
CVAR_SET_STRING("mp_kickpercent", "0.0");
else if (kick_percent.value > 1)
CVAR_SET_STRING("mp_kickpercent", "1.0");
iVotesNeeded = iValidVotes;
fKickPercent = (iTeamCount * kick_percent.value + 0.5);
if (iVotesNeeded >= (int) fKickPercent) {
UTIL_ClientPrintAll(HUD_PRINTCENTER, "#Game_kicked", STRING(pKickPlayer->pev->netname));
SERVER_COMMAND(UTIL_VarArgs("kick # %d\n", iVoteID));
pTempEntity = NULL;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")) != NULL) {
if (FNullEnt(pTempEntity->edict()))
break;
pTempPlayer = GetClassPtr<CBasePlayer>(pTempEntity->pev);
if (!pTempPlayer || pTempPlayer->m_iTeam == UNASSIGNED)
continue;
if (pTempPlayer->m_iTeam == pVotingPlayer->m_iTeam && pTempPlayer->m_iCurrentKickVote == iVoteID)
pTempPlayer->m_iCurrentKickVote = 0;
}
}
}
TeamName SelectDefaultTeam()
{
TeamName team = UNASSIGNED;
CHalfLifeMultiplay *mp = g_pGameRules;
if (mp->m_iNumTerrorist < mp->m_iNumCT) {
team = TERRORIST;
} else if (mp->m_iNumTerrorist > mp->m_iNumCT) {
team = CT;
}
// Choose the team that's losing
else if (mp->m_iNumTerroristWins < mp->m_iNumCTWins) {
team = TERRORIST;
} else if (mp->m_iNumCTWins < mp->m_iNumTerroristWins) {
team = CT;
} else {
// Teams and scores are equal, pick a random team
if (RANDOM_LONG(0, 1) == 0) {
team = CT;
} else {
team = TERRORIST;
}
}
if (mp->TeamFull(team)) {
// Pick the opposite team
if (team == TERRORIST) {
team = CT;
} else {
team = TERRORIST;
}
// No choices left
if (mp->TeamFull(team)) {
return UNASSIGNED;
}
}
return team;
}
void CheckStartMoney()
{
int money = (int) startmoney.value;
if (money > 16000)
CVAR_SET_FLOAT("mp_startmoney", 16000);
else if (money < 800)
CVAR_SET_FLOAT("mp_startmoney", 800);
}
void EXT_FUNC ClientPutInServer(edict_t *pEntity)
{
entvars_t *pev = &pEntity->v;
CBasePlayer *pPlayer = GetClassPtr<CBasePlayer>(pev);
CHalfLifeMultiplay *mp = g_pGameRules;
pPlayer->SetCustomDecalFrames(-1);
pPlayer->SetPrefsFromUserinfo(GET_INFO_BUFFER(pEntity));
if (!mp->IsMultiplayer()) {
pPlayer->Spawn();
return;
}
pPlayer->m_bNotKilled = true;
pPlayer->m_iIgnoreGlobalChat = IGNOREMSG_NONE;
pPlayer->m_iTeamKills = 0;
pPlayer->m_bJustConnected = true;
pPlayer->Spawn();
pPlayer->m_bTeamChanged = false;
pPlayer->m_iNumSpawns = 0;
CheckStartMoney();
pPlayer->m_iAccount = (int) startmoney.value;
pPlayer->m_fGameHUDInitialized = FALSE;
pPlayer->m_flDisplayHistory &= ~DHF_ROUND_STARTED;
pPlayer->pev->flags |= FL_SPECTATOR;
pPlayer->pev->solid = SOLID_NOT;
pPlayer->pev->movetype = MOVETYPE_NOCLIP;
pPlayer->pev->effects = EF_NODRAW;
pPlayer->pev->effects |= EF_NOINTERP;
pPlayer->pev->takedamage = DAMAGE_NO;
pPlayer->pev->deadflag = DEAD_DEAD;
pPlayer->pev->velocity = g_vecZero;
pPlayer->pev->punchangle = g_vecZero;
pPlayer->m_iJoiningState = READINGLTEXT;
pPlayer->m_iTeam = UNASSIGNED;
pPlayer->pev->fixangle = 1;
pPlayer->m_iModelName = MODEL_URBAN;
pPlayer->m_bContextHelp = true;
pPlayer->m_bHasNightVision = false;
pPlayer->m_iHostagesKilled = 0;
pPlayer->m_iMapVote = 0;
pPlayer->m_iCurrentKickVote = 0;
pPlayer->m_fDeadTime = {};
pPlayer->has_disconnected = false;
pPlayer->m_iMenu = Menu_OFF;
pPlayer->ClearAutoBuyData();
pPlayer->m_rebuyString = NULL;
SET_CLIENT_MAXSPEED(ENT(pPlayer->pev), 1);
SET_MODEL(ENT(pPlayer->pev), "models/player.mdl");
pPlayer->SetThink(NULL);
CBaseEntity *Target = UTIL_FindEntityByClassname(NULL, "trigger_camera");
pPlayer->m_pIntroCamera = Target;
if (mp && mp->m_bMapHasCameras == MAP_HAS_CAMERAS_INIT) {
mp->m_bMapHasCameras = (Target != NULL);
}
if (pPlayer->m_pIntroCamera)
Target = UTIL_FindEntityByTargetname(NULL, STRING(pPlayer->m_pIntroCamera->pev->target));
if (pPlayer->m_pIntroCamera && Target) {
Vector CamAngles = UTIL_VecToAngles((Target->pev->origin - pPlayer->m_pIntroCamera->pev->origin).Normalize());
CamAngles.x = -CamAngles.x;
UTIL_SetOrigin(pPlayer->pev, pPlayer->m_pIntroCamera->pev->origin);
pPlayer->pev->angles = CamAngles;
pPlayer->pev->v_angle = pPlayer->pev->angles;
pPlayer->m_fIntroCamTime = gpGlobals->time + 6s;
pPlayer->pev->view_ofs = g_vecZero;
} else {
pPlayer->m_iTeam = CT;
if (mp) {
mp->GetPlayerSpawnSpot(pPlayer);
}
pPlayer->m_iTeam = UNASSIGNED;
pPlayer->pev->v_angle = g_vecZero;
pPlayer->pev->angles = gpGlobals->v_forward;
}
if (TheBots) {
TheBots->OnEvent(EVENT_PLAYER_CHANGED_TEAM, (CBaseEntity *) pPlayer);
}
pPlayer->m_iJoiningState = SHOWLTEXT;
static char sName[128];
Q_strcpy(sName, STRING(pPlayer->pev->netname));
for (char *pApersand = sName; pApersand && *pApersand != '\0'; pApersand++) {
if (*pApersand == '%')
*pApersand = ' ';
}
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, "#Game_connected", (sName[0] != '\0') ? sName : "<unconnected>");
}
int Q_strlen_(const char *str)
{
int count = 0;
if (str && *str) {
while (str[count++ + 1]);
}
return count;
}
void Host_Say(edict_t *pEntity, int teamonly)
{
CBasePlayer *client;
int j;
char *p;
char text[128];
char szTemp[256];
const char *cpSay = "say";
const char *cpSayTeam = "say_team";
const char *pcmd = CMD_ARGV_(0);
bool bSenderDead = false;
entvars_t *pev = &pEntity->v;
CBasePlayer *player = GetClassPtr<CBasePlayer>(pev);
if (player->m_flLastTalk != time_point_t{} && gpGlobals->time - player->m_flLastTalk < 0.66s)
return;
player->m_flLastTalk = gpGlobals->time;
if (player->pev->deadflag != DEAD_NO)
bSenderDead = true;
// We can get a raw string now, without the "say " prepended
if (CMD_ARGC_() == 0)
return;
if (!Q_stricmp(pcmd, cpSay) || !Q_stricmp(pcmd, cpSayTeam)) {
if (CMD_ARGC_() >= 2) {
p = (char *) CMD_ARGS();
} else {
// say with a blank message, nothing to do
return;
}
} else // Raw text, need to prepend argv[0]
{
if (CMD_ARGC_() >= 2) {
Q_sprintf(szTemp, "%s %s", (char *) pcmd, (char *) CMD_ARGS());
} else {
// Just a one word command, use the first word...sigh
Q_sprintf(szTemp, "%s", (char *) pcmd);
}
p = szTemp;
}
// remove quotes if present
if (*p == '"') {
p++;
p[Q_strlen(p) - 1] = '\0';
}
// make sure the text has content
if (!p || !p[0] || !Q_UnicodeValidate(p)) {
// no character found, so say nothing
return;
}
Q_StripUnprintableAndSpace(p);
if (Q_strlen(p) <= 0)
return;
const char *placeName = NULL;
const char *pszFormat = NULL;
const char *pszConsoleFormat = NULL;
bool consoleUsesPlaceName = false;
// team only
if (teamonly) {
if (g_bIsCzeroGame && (player->m_iTeam == CT || player->m_iTeam == TERRORIST)) {
// search the place name where is located the player
Place playerPlace = TheNavAreaGrid.GetPlace(&player->pev->origin);
const BotPhraseList *placeList = TheBotPhrases->GetPlaceList();
for (auto phrase : *placeList) {
if (phrase->GetID() == playerPlace) {
placeName = phrase->GetName();
break;
}
}
}
if (player->m_iTeam == CT) {
if (bSenderDead) {
pszFormat = "#Cstrike_Chat_CT_Dead";
pszConsoleFormat = "*DEAD*(Counter-Terrorist) %s : %s";
} else if (placeName != NULL) {
pszFormat = "#Cstrike_Chat_CT_Loc";
pszConsoleFormat = "*(Counter-Terrorist) %s @ %s : %s";
consoleUsesPlaceName = true;
} else {
pszFormat = "#Cstrike_Chat_CT";
pszConsoleFormat = "(Counter-Terrorist) %s : %s";
}
} else if (player->m_iTeam == TERRORIST) {
if (bSenderDead) {
pszFormat = "#Cstrike_Chat_T_Dead";
pszConsoleFormat = "*DEAD*(Terrorist) %s : %s";
} else if (placeName != NULL) {
pszFormat = "#Cstrike_Chat_T_Loc";
pszConsoleFormat = "(Terrorist) %s @ %s : %s";
consoleUsesPlaceName = true;
} else {
pszFormat = "#Cstrike_Chat_T";
pszConsoleFormat = "(Terrorist) %s : %s";
}
} else {
pszFormat = "#Cstrike_Chat_Spec";
pszConsoleFormat = "(Spectator) %s : %s";
}
}
// everyone
else {
if (bSenderDead) {
if (player->m_iTeam == SPECTATOR) {
pszFormat = "#Cstrike_Chat_AllSpec";
pszConsoleFormat = "*SPEC* %s : %s";
} else {
pszFormat = "#Cstrike_Chat_AllDead";
pszConsoleFormat = "*DEAD* %s : %s";
}
} else {
pszFormat = "#Cstrike_Chat_All";
pszConsoleFormat = "%s : %s";
}
}
text[0] = '\0';
// -3 for /n and null terminator
j = sizeof(text) - 3 - Q_strlen(text) - Q_strlen(pszFormat);
if (placeName != NULL) {
j -= Q_strlen(placeName) + 1;
}
if ((signed int) Q_strlen(p) > j)
p[j] = 0;
for (char *pAmpersand = p; pAmpersand != NULL && *pAmpersand != '\0'; pAmpersand++) {
if (pAmpersand[0] == '%') {
if (pAmpersand[1] != 'l' && pAmpersand[1] != ' ' && pAmpersand[1] != '\0') {
pAmpersand[0] = ' ';
}
}
}
Q_strcat(text, p);
Q_strcat(text, "\n");
// loop through all players
// Start with the first player.
// This may return the world in single player if the client types something between levels or during spawn
// so check it, or it will infinite loop
client = NULL;
while ((client = (CBasePlayer *) UTIL_FindEntityByClassname(client, "player")) != NULL) {
if (FNullEnt(client->edict()))
break;
if (!client->pev)
continue;
if (client->edict() == pEntity)
continue;
// Not a client ? (should never be true)
if (!client->IsNetClient())
continue;
// can the receiver hear the sender? or has he muted him?
if (gpGlobals->deathmatch != 0.0f && g_pGameRules->m_VoiceGameMgr.PlayerHasBlockedPlayer(client, player))
continue;
if (teamonly && client->m_iTeam != player->m_iTeam)
continue;
if ((client->pev->deadflag != DEAD_NO && !bSenderDead) || (client->pev->deadflag == DEAD_NO && bSenderDead)) {
if (!(player->pev->flags & FL_PROXY))
continue;
}
if ((client->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY && client->m_iTeam == player->m_iTeam)
|| client->m_iIgnoreGlobalChat == IGNOREMSG_NONE) {
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, client->pev);
WRITE_BYTE(ENTINDEX(pEntity));
WRITE_STRING(pszFormat);
WRITE_STRING("");
WRITE_STRING(text);
if (placeName != NULL) {
WRITE_STRING(placeName);
}
MESSAGE_END();
}
}
char *fullText = p;
// print to the sending client
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, &pEntity->v);
WRITE_BYTE(ENTINDEX(pEntity));
WRITE_STRING(pszFormat);
WRITE_STRING("");
WRITE_STRING(text);
if (placeName != NULL) {
WRITE_STRING(placeName);
}
MESSAGE_END();
// echo to server console
if (pszConsoleFormat) {
if (placeName && consoleUsesPlaceName)
SERVER_PRINT(UTIL_VarArgs(pszConsoleFormat, STRING(player->pev->netname), placeName, text));
else
SERVER_PRINT(UTIL_VarArgs(pszConsoleFormat, STRING(player->pev->netname), text));
} else
SERVER_PRINT(text);
if (CVAR_GET_FLOAT("mp_logmessages") != 0) {
const char *temp = teamonly ? "say_team" : "say";
const char *deadText = (player->m_iTeam != SPECTATOR && bSenderDead) ? " (dead)" : "";
const char *szTeam = GetTeam(player->m_iTeam);
UTIL_LogPrintf
(
"\"%s<%i><%s><%s>\" %s \"%s\"%s\n",
STRING(player->pev->netname),
GETPLAYERUSERID(player->edict()),
GETPLAYERAUTHID(player->edict()),
szTeam,
temp,
fullText,
deadText
);
}
}
void DropSecondary(CBasePlayer *pPlayer)
{
if (pPlayer->HasShield()) {
if (pPlayer->HasShield() && pPlayer->m_bShieldDrawn && pPlayer->m_pActiveItem != NULL) {
((CBasePlayerWeapon *) pPlayer->m_pActiveItem)->SecondaryAttack();
}
pPlayer->m_bShieldDrawn = false;
}
CBasePlayerWeapon *pWeapon = (CBasePlayerWeapon *) pPlayer->m_rgpPlayerItems[PISTOL_SLOT];
if (pWeapon != NULL) {
pPlayer->DropPlayerItem(STRING(pWeapon->pev->classname));
}
}
void DropPrimary(CBasePlayer *pPlayer)
{
if (pPlayer->HasShield()) {
pPlayer->DropShield();
return;
}
if (pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]) {
pPlayer->DropPlayerItem(STRING(pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]->pev->classname));
}
}
bool CanBuyThis(CBasePlayer *pPlayer, int iWeapon)
{
CHalfLifeMultiplay *mp = g_pGameRules;
#ifdef ENABLE_SHIELD
if (pPlayer->HasShield() && iWeapon == WEAPON_ELITE)
{
return false;
}
if (pPlayer->HasShield() && iWeapon == WEAPON_SHIELDGUN)
{
return false;
}
if (pPlayer->m_rgpPlayerItems[ PISTOL_SLOT ] != NULL && pPlayer->m_rgpPlayerItems[ PISTOL_SLOT ]->m_iId == WEAPON_ELITE && iWeapon == WEAPON_SHIELDGUN)
{
return false;
}
#else
if (iWeapon == WEAPON_SHIELDGUN) {
return false;
}
#endif
if (pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT] != NULL &&
pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]->m_iId == iWeapon) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cstrike_Already_Own_Weapon");
}
return false;
}
if (pPlayer->m_rgpPlayerItems[PISTOL_SLOT] != NULL && pPlayer->m_rgpPlayerItems[PISTOL_SLOT]->m_iId == iWeapon) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cstrike_Already_Own_Weapon");
}
return false;
}
if (!CanBuyWeaponByMaptype(pPlayer->m_iTeam, (WeaponIdType) iWeapon,
(mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES))) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cannot_Buy_This");
}
return false;
}
return true;
}
void BuyPistol(CBasePlayer *pPlayer, int iSlot)
{
int iWeapon = 0;
int iWeaponPrice = 0;
const char *pszWeapon = NULL;
if (!pPlayer->CanPlayerBuy(true)) {
return;
}
if (iSlot < 1 || iSlot > 5) {
return;
}
switch (iSlot) {
case 1: {
iWeapon = WEAPON_GLOCK18;
iWeaponPrice = GLOCK18_PRICE;
pszWeapon = "weapon_glock18";
break;
}
case 2: {
iWeapon = WEAPON_USP;
iWeaponPrice = USP_PRICE;
pszWeapon = "weapon_usp";
break;
}
case 3: {
iWeapon = WEAPON_P228;
iWeaponPrice = P228_PRICE;
pszWeapon = "weapon_p228";
break;
}
case 4: {
iWeapon = WEAPON_DEAGLE;
iWeaponPrice = DEAGLE_PRICE;
pszWeapon = "weapon_deagle";
break;
}
case 5: {
if (pPlayer->m_iTeam == CT) {
iWeapon = WEAPON_FIVESEVEN;
iWeaponPrice = FIVESEVEN_PRICE;
pszWeapon = "weapon_fiveseven";
} else {
iWeapon = WEAPON_ELITE;
iWeaponPrice = ELITE_PRICE;
pszWeapon = "weapon_elite";
}
break;
}
}
if (!CanBuyThis(pPlayer, iWeapon)) {
return;
}
if (pPlayer->m_iAccount < iWeaponPrice) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
DropSecondary(pPlayer);
pPlayer->GiveNamedItem(pszWeapon);
pPlayer->AddAccount(-iWeaponPrice);
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void BuyShotgun(CBasePlayer *pPlayer, int iSlot)
{
int iWeapon = 0;
int iWeaponPrice = 0;
const char *pszWeapon = NULL;
if (!pPlayer->CanPlayerBuy(true)) {
return;
}
if (iSlot < 1 || iSlot > 2) {
return;
}
switch (iSlot) {
case 1: {
iWeapon = WEAPON_M3;
iWeaponPrice = M3_PRICE;
pszWeapon = "weapon_m3";
break;
}
case 2: {
iWeapon = WEAPON_XM1014;
iWeaponPrice = XM1014_PRICE;
pszWeapon = "weapon_xm1014";
break;
}
}
if (!CanBuyThis(pPlayer, iWeapon)) {
return;
}
if (pPlayer->m_iAccount < iWeaponPrice) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
DropPrimary(pPlayer);
pPlayer->GiveNamedItem(pszWeapon);
pPlayer->AddAccount(-iWeaponPrice);
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void BuySubMachineGun(CBasePlayer *pPlayer, int iSlot)
{
int iWeapon = 0;
int iWeaponPrice = 0;
const char *pszWeapon = NULL;
if (!pPlayer->CanPlayerBuy(true)) {
return;
}
if (iSlot < 1 || iSlot > 4) {
return;
}
switch (iSlot) {
case 1: {
if (pPlayer->m_iTeam == CT) {
iWeapon = WEAPON_TMP;
iWeaponPrice = TMP_PRICE;
pszWeapon = "weapon_tmp";
} else {
iWeapon = WEAPON_MAC10;
iWeaponPrice = MAC10_PRICE;
pszWeapon = "weapon_mac10";
}
break;
}
case 2: {
iWeapon = WEAPON_MP5N;
iWeaponPrice = MP5NAVY_PRICE;
pszWeapon = "weapon_mp5navy";
break;
}
case 3: {
iWeapon = WEAPON_UMP45;
iWeaponPrice = UMP45_PRICE;
pszWeapon = "weapon_ump45";
break;
}
case 4: {
iWeapon = WEAPON_P90;
iWeaponPrice = P90_PRICE;
pszWeapon = "weapon_p90";
break;
}
}
if (!CanBuyThis(pPlayer, iWeapon)) {
return;
}
if (pPlayer->m_iAccount < iWeaponPrice) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
DropPrimary(pPlayer);
pPlayer->GiveNamedItem(pszWeapon);
pPlayer->AddAccount(-iWeaponPrice);
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void BuyWeaponByWeaponID(CBasePlayer *pPlayer, WeaponIdType weaponID)
{
if (!pPlayer->CanPlayerBuy(true)) {
return;
}
if (!CanBuyThis(pPlayer, weaponID)) {
return;
}
WeaponInfoStruct *info = GetWeaponInfo(weaponID);
if (!info || !info->entityName) {
return;
}
if (pPlayer->m_iAccount < info->cost) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
if (IsPrimaryWeapon(weaponID)) {
DropPrimary(pPlayer);
} else {
DropSecondary(pPlayer);
}
pPlayer->GiveNamedItem(info->entityName);
pPlayer->AddAccount(-info->cost);
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void BuyRifle(CBasePlayer *pPlayer, int iSlot)
{
int iWeapon = 0;
int iWeaponPrice = 0;
bool bIsCT = false;
const char *pszWeapon = NULL;
if (!pPlayer->CanPlayerBuy(true)) {
return;
}
if (iSlot < 1 || iSlot > 6) {
return;
}
if (pPlayer->m_iTeam == CT)
bIsCT = true;
switch (iSlot) {
case 2: {
if (bIsCT) {
iWeapon = WEAPON_SCOUT;
iWeaponPrice = SCOUT_PRICE;
pszWeapon = "weapon_scout";
} else {
iWeapon = WEAPON_AK47;
iWeaponPrice = AK47_PRICE;
pszWeapon = "weapon_ak47";
}
break;
}
case 3: {
if (bIsCT) {
iWeapon = WEAPON_M4A1;
iWeaponPrice = M4A1_PRICE;
pszWeapon = "weapon_m4a1";
} else {
iWeapon = WEAPON_SCOUT;
iWeaponPrice = SCOUT_PRICE;
pszWeapon = "weapon_scout";
}
break;
}
case 4: {
if (bIsCT) {
iWeapon = WEAPON_AUG;
iWeaponPrice = AUG_PRICE;
pszWeapon = "weapon_aug";
} else {
iWeapon = WEAPON_SG552;
iWeaponPrice = SG552_PRICE;
pszWeapon = "weapon_sg552";
}
break;
}
case 5: {
if (bIsCT) {
iWeapon = WEAPON_SG550;
iWeaponPrice = SG550_PRICE;
pszWeapon = "weapon_sg550";
} else {
iWeapon = WEAPON_AWP;
iWeaponPrice = AWP_PRICE;
pszWeapon = "weapon_awp";
}
break;
}
case 6: {
if (bIsCT) {
iWeapon = WEAPON_AWP;
iWeaponPrice = AWP_PRICE;
pszWeapon = "weapon_awp";
} else {
iWeapon = WEAPON_G3SG1;
iWeaponPrice = G3SG1_PRICE;
pszWeapon = "weapon_g3sg1";
}
break;
}
default: {
if (bIsCT) {
iWeapon = WEAPON_FAMAS;
iWeaponPrice = FAMAS_PRICE;
pszWeapon = "weapon_famas";
} else {
iWeapon = WEAPON_GALIL;
iWeaponPrice = GALIL_PRICE;
pszWeapon = "weapon_galil";
}
break;
}
}
if (!CanBuyThis(pPlayer, iWeapon)) {
return;
}
if (pPlayer->m_iAccount < iWeaponPrice) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
DropPrimary(pPlayer);
pPlayer->GiveNamedItem(pszWeapon);
pPlayer->AddAccount(-iWeaponPrice);
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void BuyMachineGun(CBasePlayer *pPlayer, int iSlot)
{
int iWeapon = WEAPON_M249;
int iWeaponPrice = M249_PRICE;
const char *pszWeapon = "weapon_m249";
if (!pPlayer->CanPlayerBuy(true)) {
return;
}
if (iSlot != 1) {
return;
}
if (!CanBuyThis(pPlayer, iWeapon)) {
return;
}
if (pPlayer->m_iAccount < iWeaponPrice) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
DropPrimary(pPlayer);
pPlayer->GiveNamedItem(pszWeapon);
pPlayer->AddAccount(-iWeaponPrice);
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void ZbsUpgrade(CBasePlayer *pPlayer, int iSlot)
{
if (!pPlayer->CanPlayerBuy(true))
return;
switch (iSlot) {
case MENU_SLOT_UPGRADE_HP: {
pPlayer->ClientCommand("zbs_hp_up");
break;
}
case MENU_SLOT_UPGRADE_ATK: {
pPlayer->ClientCommand("zbs_atk_up");
break;
}
}
}
void BuyItem(CBasePlayer *pPlayer, int iSlot)
{
//int iItem = 0;
int iItemPrice = 0;
const char *pszItem = NULL;
if (!pPlayer->CanPlayerBuy(true))
return;
if (pPlayer->m_iTeam == CT) {
if (iSlot < 1 || iSlot > 8)
return;
} else {
if (iSlot < 1 || iSlot > 6)
return;
}
int fullArmor = (pPlayer->pev->armorvalue >= 100);
int helmet = (pPlayer->m_iKevlar == ARMOR_TYPE_HELMET);
//int price;
int enoughMoney = 1;
switch (iSlot) {
case MENU_SLOT_ITEM_VEST: {
if (fullArmor) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_Kevlar");
}
return;
}
if (pPlayer->m_iAccount >= KEVLAR_PRICE) {
if (helmet) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_Helmet_Bought_Kevlar");
}
}
pszItem = "item_kevlar";
iItemPrice = KEVLAR_PRICE;
} else
enoughMoney = 0;
break;
}
case MENU_SLOT_ITEM_VESTHELM: {
if (fullArmor) {
if (helmet) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_Kevlar_Helmet");
}
return;
}
if (pPlayer->m_iAccount >= HELMET_PRICE) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_Kevlar_Bought_Helmet");
}
pszItem = "item_assaultsuit";
iItemPrice = HELMET_PRICE;
} else
enoughMoney = 0;
break;
} else {
if (helmet) {
if (pPlayer->m_iAccount >= KEVLAR_PRICE) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_Helmet_Bought_Kevlar");
}
pszItem = "item_assaultsuit";
iItemPrice = KEVLAR_PRICE;
} else
enoughMoney = 0;
} else {
if (pPlayer->m_iAccount >= ASSAULTSUIT_PRICE) {
pszItem = "item_assaultsuit";
iItemPrice = ASSAULTSUIT_PRICE;
} else
enoughMoney = 0;
}
}
break;
}
case MENU_SLOT_ITEM_FLASHGREN: {
if (pPlayer->AmmoInventory(pPlayer->GetAmmoIndex("Flashbang")) >= 2) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cannot_Carry_Anymore");
}
return;
}
if (pPlayer->m_iAccount >= FLASHBANG_PRICE) {
pszItem = "weapon_flashbang";
iItemPrice = FLASHBANG_PRICE;
} else
enoughMoney = 0;
break;
}
case MENU_SLOT_ITEM_HEGREN: {
if (pPlayer->AmmoInventory(pPlayer->GetAmmoIndex("HEGrenade")) >= 1) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cannot_Carry_Anymore");
}
return;
}
if (pPlayer->m_iAccount >= HEGRENADE_PRICE) {
pszItem = "weapon_hegrenade";
iItemPrice = HEGRENADE_PRICE;
} else
enoughMoney = 0;
break;
}
case MENU_SLOT_ITEM_SMOKEGREN: {
if (pPlayer->AmmoInventory(pPlayer->GetAmmoIndex("SmokeGrenade")) >= 1) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cannot_Carry_Anymore");
}
return;
}
if (pPlayer->m_iAccount >= SMOKEGRENADE_PRICE) {
pszItem = "weapon_smokegrenade";
iItemPrice = SMOKEGRENADE_PRICE;
} else
enoughMoney = 0;
break;
}
case MENU_SLOT_ITEM_NVG: {
if (pPlayer->m_bHasNightVision) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_One");
}
return;
}
if (pPlayer->m_iAccount >= NVG_PRICE) {
if (!(pPlayer->m_flDisplayHistory & DHF_NIGHTVISION)) {
pPlayer->HintMessage("#Hint_use_nightvision");
pPlayer->m_flDisplayHistory |= DHF_NIGHTVISION;
}
EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/equip_nvg.wav", VOL_NORM, ATTN_NORM);
pPlayer->m_bHasNightVision = true;
pPlayer->AddAccount(-NVG_PRICE);
SendItemStatus(pPlayer);
} else
enoughMoney = 0;
break;
}
case MENU_SLOT_ITEM_DEFUSEKIT: {
if (pPlayer->m_iTeam != CT || !g_pGameRules->m_bMapHasBombTarget) {
return;
}
if (pPlayer->m_bHasDefuser) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Already_Have_One");
}
return;
}
if (pPlayer->m_iAccount >= DEFUSEKIT_PRICE) {
pPlayer->m_bHasDefuser = true;
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pPlayer->pev);
WRITE_BYTE(STATUSICON_SHOW);
WRITE_STRING("defuser");
WRITE_BYTE(0);
WRITE_BYTE(160);
WRITE_BYTE(0);
MESSAGE_END();
pPlayer->pev->body = 1;
pPlayer->AddAccount(-DEFUSEKIT_PRICE);
EMIT_SOUND(ENT(pPlayer->pev), CHAN_VOICE, "items/kevlar.wav", VOL_NORM, ATTN_NORM);
SendItemStatus(pPlayer);
} else
enoughMoney = 0;
break;
}
case MENU_SLOT_ITEM_SHIELD: {
if (!CanBuyThis(pPlayer, WEAPON_SHIELDGUN)) {
return;
}
if (pPlayer->m_iAccount >= SHIELDGUN_PRICE) {
DropPrimary(pPlayer);
pPlayer->GiveShield(true);
pPlayer->AddAccount(-SHIELDGUN_PRICE);
EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM);
} else
enoughMoney = 0;
break;
}
}
if (!enoughMoney) {
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(pPlayer, 2);
}
return;
}
if (pszItem != NULL) {
pPlayer->GiveNamedItem(pszItem);
pPlayer->AddAccount(-iItemPrice);
}
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
void HandleMenu_ChooseAppearance(CBasePlayer *player, int slot)
{
CHalfLifeMultiplay *mp = g_pGameRules;
int numSkins = g_bIsCzeroGame ? CZ_NUM_SKIN : CS_NUM_SKIN;
struct
{
ModelName model_id;
const char *model_name;
int model_name_index;
} appearance;
Q_memset(&appearance, 0, sizeof(appearance));
if (player->m_iTeam == TERRORIST) {
if ((slot > numSkins || slot < 1) && (!TheBotProfiles->GetCustomSkin(slot) || !player->IsBot())) {
slot = RANDOM_LONG(1, numSkins);
}
switch (slot) {
case 1:
appearance.model_id = MODEL_TERROR;
appearance.model_name = "terror";
break;
case 2:
appearance.model_id = MODEL_LEET;
appearance.model_name = "leet";
break;
case 3:
appearance.model_id = MODEL_ARCTIC;
appearance.model_name = "arctic";
break;
case 4:
appearance.model_id = MODEL_GUERILLA;
appearance.model_name = "guerilla";
break;
case 5:
if (g_bIsCzeroGame) {
appearance.model_id = MODEL_MILITIA;
appearance.model_name = "militia";
break;
}
default:
if (TheBotProfiles->GetCustomSkinModelname(slot) && player->IsBot()) {
appearance.model_name = (char *) TheBotProfiles->GetCustomSkinModelname(slot);
} else {
appearance.model_id = MODEL_TERROR;
appearance.model_name = "terror";
}
break;
}
// default T model models/player/terror/terror.mdl
appearance.model_name_index = 8;
} else if (player->m_iTeam == CT) {
if ((slot > numSkins || slot < 1) && (!TheBotProfiles->GetCustomSkin(slot) || !player->IsBot())) {
slot = RANDOM_LONG(1, numSkins);
}
switch (slot) {
case 1:
appearance.model_id = MODEL_URBAN;
appearance.model_name = "urban";
break;
case 2:
appearance.model_id = MODEL_GSG9;
appearance.model_name = "gsg9";
break;
case 3:
appearance.model_id = MODEL_SAS;
appearance.model_name = "sas";
break;
case 4:
appearance.model_id = MODEL_GIGN;
appearance.model_name = "gign";
break;
case 5:
if (g_bIsCzeroGame) {
appearance.model_id = MODEL_SPETSNAZ;
appearance.model_name = "spetsnaz";
break;
}
default:
if (TheBotProfiles->GetCustomSkinModelname(slot) && player->IsBot()) {
appearance.model_name = (char *) TheBotProfiles->GetCustomSkinModelname(slot);
} else {
appearance.model_id = MODEL_URBAN;
appearance.model_name = "urban";
}
break;
}
// default CT model models/player/urban/urban.mdl
appearance.model_name_index = 9;
}
player->ResetMenu();
// Reset the player's state
if (player->m_iJoiningState == JOINED) {
mp->CheckWinConditions();
} else if (player->m_iJoiningState == PICKINGTEAM) {
player->m_iJoiningState = GETINTOGAME;
if (mp->IsCareer()) {
if (!player->IsBot()) {
mp->CheckWinConditions();
}
}
}
player->pev->body = 0;
player->m_iModelName = appearance.model_id;
SET_CLIENT_KEY_VALUE(player->entindex(), GET_INFO_BUFFER(player->edict()), "model", appearance.model_name);
player->SetNewPlayerModel(Client_ApperanceToModel(appearance.model_name_index));
if (mp->m_iMapHasVIPSafetyZone == MAP_VIP_SAFETYZONE_UNINITIALIZED) {
if ((UTIL_FindEntityByClassname(NULL, "func_vip_safetyzone")) != NULL)
mp->m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_YES;
else
mp->m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_NO;
}
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES) {
if (!mp->m_pVIP && player->m_iTeam == CT) {
player->MakeVIP();
}
}
}
// returns true if the selection has been handled and the player's menu
// can be closed...false if the menu should be displayed again
BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
{
CHalfLifeMultiplay *mp = g_pGameRules;
int oldTeam;
const char *szOldTeam;
const char *szNewTeam;
// If this player is a VIP, don't allow him to switch teams/appearances unless the following conditions are met :
// a) There is another CT player who is in the queue to be a VIP
// b) This player is dead
if (player->m_bIsVIP) {
if (player->pev->deadflag == DEAD_NO) {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Switch_From_VIP");
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return TRUE;
} else if (g_pGameRules->IsVIPQueueEmpty()) {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Switch_From_VIP");
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return TRUE;
}
}
TeamName team = UNASSIGNED;
switch (slot) {
case MENU_SLOT_TERRORIST:
team = TERRORIST;
break;
case MENU_SLOT_CT:
team = CT;
break;
case MENU_SLOT_TEAM_VIP: {
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES && player->m_iTeam == CT) {
mp->AddToVIPQueue(player);
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return TRUE;
} else {
return FALSE;
}
break;
}
case MENU_SLOT_TEAM_RANDOM: {
// Attempt to auto-select a team
team = SelectDefaultTeam();
if (team == UNASSIGNED) {
if (cv_bot_auto_vacate.value > 0.0f && !player->IsBot()) {
team = (RANDOM_LONG(0, 1) == 0) ? TERRORIST : CT;
if (!UTIL_KickBotFromTeam(team)) {
// no bots on that team, try the other
team = (team == CT) ? TERRORIST : CT;
if (!UTIL_KickBotFromTeam(team)) {
// couldn't kick any bots, fail
team = UNASSIGNED;
}
}
}
}
break;
}
case MENU_SLOT_TEAM_SPECT: {
// Prevent this is the cvar is set
// spectator proxy
if (!allow_spectators.value && !(player->pev->flags & FL_PROXY)) {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Be_Spectator");
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return FALSE;
}
// are we already a spectator?
if (player->m_iTeam == SPECTATOR) {
return TRUE;
}
// Only spectate if we are in the freeze period or dead.
// This is done here just in case.
if (mp->IsFreezePeriod() || player->pev->deadflag != DEAD_NO) {
if (player->m_iTeam != UNASSIGNED && player->pev->deadflag == DEAD_NO) {
ClientKill(player->edict());
// add 1 to frags to balance out the 1 subtracted for killing yourself
player->pev->frags++;
}
player->RemoveAllItems(TRUE);
player->m_bHasC4 = false;
if (player->m_iTeam != SPECTATOR) {
// notify other clients of player joined to team spectator
UTIL_LogPrintf
(
"\"%s<%i><%s><%s>\" joined team \"SPECTATOR\"\n",
STRING(player->pev->netname),
GETPLAYERUSERID(player->edict()),
GETPLAYERAUTHID(player->edict()),
GetTeam(player->m_iTeam)
);
}
player->m_iTeam = SPECTATOR;
player->m_iJoiningState = JOINED;
// Reset money
player->m_iAccount.Reset();
player->m_iAccount.UpdateHUD(player);
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
WRITE_BYTE(ENTINDEX(player->edict()));
WRITE_SHORT((int) player->pev->frags);
WRITE_SHORT(player->m_iDeaths);
WRITE_SHORT(0);
WRITE_SHORT(0);
MESSAGE_END();
player->m_pIntroCamera = NULL;
player->m_bTeamChanged = true;
if (TheBots != NULL) {
TheBots->OnEvent(EVENT_PLAYER_CHANGED_TEAM, player);
}
TeamChangeUpdate(player, player->m_iTeam);
edict_t *pentSpawnSpot = mp->GetPlayerSpawnSpot(player);
player->StartObserver(VARS(pentSpawnSpot)->origin, VARS(pentSpawnSpot)->angles);
#if 0
MESSAGE_BEGIN(MSG_ALL, gmsgSpectator);
WRITE_BYTE(ENTINDEX(player->edict()));
WRITE_BYTE(1);
MESSAGE_END();
#endif
// do we have fadetoblack on? (need to fade their screen back in)
if (fadetoblack.value) {
UTIL_ScreenFade(player, Vector(0, 0, 0), 0.001s, 0s, 0, FFADE_IN);
}
return TRUE;
} else {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Be_Spectator");
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return FALSE;
}
break;
}
default:
return FALSE;
}
// If the code gets this far, the team is not TEAM_UNASSIGNED
// Player is switching to a new team (It is possible to switch to the
// same team just to choose a new appearance)
if (mp->TeamFull(team)) {
// The specified team is full
// attempt to kick a bot to make room for this player
bool madeRoom = false;
if (cv_bot_auto_vacate.value > 0 && !player->IsBot()) {
if (UTIL_KickBotFromTeam(team))
madeRoom = true;
}
if (!madeRoom) {
ClientPrint(player->pev, HUD_PRINTCENTER, (team == TERRORIST) ? "#Terrorists_Full" : "#CTs_Full");
return FALSE;
}
}
// players are allowed to change to their own team so they can just change their model
if (mp->TeamStacked(team, player->m_iTeam)) {
// The specified team is full
ClientPrint(player->pev, HUD_PRINTCENTER, (team == TERRORIST) ? "#Too_Many_Terrorists" : "#Too_Many_CTs");
return FALSE;
}
if (team != SPECTATOR && !player->IsBot()) {
int humanTeam = UNASSIGNED;
if (!Q_stricmp(humans_join_team.string, "CT")) {
humanTeam = CT;
} else if (!Q_stricmp(humans_join_team.string, "T")) {
humanTeam = TERRORIST;
}
if (humanTeam != UNASSIGNED && team != humanTeam) {
ClientPrint(player->pev, HUD_PRINTCENTER,
(team == TERRORIST) ? "#Humans_Join_Team_CT" : "#Humans_Join_Team_T");
return FALSE;
}
}
// If we already died and changed teams once, deny
if (player->m_bTeamChanged) {
if (player->pev->deadflag != DEAD_NO) {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Only_1_Team_Change");
return FALSE;
}
}
if (player->m_iTeam == SPECTATOR && team != SPECTATOR) {
// If they're switching into spectator, setup spectator properties..
player->m_bNotKilled = true;
player->m_iIgnoreGlobalChat = IGNOREMSG_NONE;
player->m_iTeamKills = 0;
CheckStartMoney();
// all players start with "mp_startmoney" bucks
player->m_iAccount = (int) startmoney.value;
player->pev->solid = SOLID_NOT;
player->pev->movetype = MOVETYPE_NOCLIP;
player->pev->effects = EF_NODRAW;
player->pev->effects |= EF_NOINTERP;
player->pev->takedamage = DAMAGE_NO;
player->pev->deadflag = DEAD_DEAD;
player->pev->velocity = g_vecZero;
player->pev->punchangle = g_vecZero;
player->m_bHasNightVision = false;
player->m_iHostagesKilled = 0;
player->m_fDeadTime = {};
player->has_disconnected = false;
player->m_iJoiningState = GETINTOGAME;
SendItemStatus(player);
SET_CLIENT_MAXSPEED(ENT(player->pev), 1);
SET_MODEL(ENT(player->pev), "models/player.mdl");
}
if (!g_pGameRules->IsCareer()) {
switch (team) {
case CT:
if (g_bIsCzeroGame)
ShowVGUIMenu(player, VGUI_Menu_Class_CT,
(MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6),
"#CT_Select");
else
ShowVGUIMenu(player, VGUI_Menu_Class_CT,
(MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#CT_Select");
break;
case TERRORIST:
if (g_bIsCzeroGame)
ShowVGUIMenu(player, VGUI_Menu_Class_T,
(MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6),
"#Terrorist_Select");
else
ShowVGUIMenu(player, VGUI_Menu_Class_T,
(MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5), "#Terrorist_Select");
break;
default:
break;
}
}
player->m_iMenu = Menu_ChooseAppearance;
// Show the appropriate Choose Appearance menu
// This must come before ClientKill() for CheckWinConditions() to function properly
if (player->pev->deadflag == DEAD_NO) {
ClientKill(player->edict());
}
// Switch their actual team...
player->m_bTeamChanged = true;
oldTeam = player->m_iTeam;
player->m_iTeam = team;
if (TheBots != NULL) {
TheBots->OnEvent(EVENT_PLAYER_CHANGED_TEAM, player);
}
TeamChangeUpdate(player, player->m_iTeam);
szOldTeam = GetTeam(oldTeam);
szNewTeam = GetTeam(team);
// Notify others that this player has joined a new team
UTIL_ClientPrintAll
(
HUD_PRINTNOTIFY,
(team == TERRORIST) ? "#Game_join_terrorist" : "#Game_join_ct",
(STRING(player->pev->netname) && STRING(player->pev->netname)[0] != 0) ? STRING(
player->pev->netname) : "<unconnected>"
);
UTIL_LogPrintf
(
"\"%s<%i><%s><%s>\" joined team \"%s\"\n",
STRING(player->pev->netname),
GETPLAYERUSERID(player->edict()),
GETPLAYERAUTHID(player->edict()),
szOldTeam,
szNewTeam
);
return TRUE;
}
void Radio1(CBasePlayer *player, int slot)
{
if (player->m_flRadioTime >= gpGlobals->time) {
return;
}
if (player->m_iRadioMessages <= 0) {
return;
}
player->m_iRadioMessages--;
player->m_flRadioTime = gpGlobals->time + 1.5s;
if (player->m_bIsZombie)
{
switch (slot) {
case 1:
player->Radio("%!MRAD_COVERME_ZB", "#Cover_me");
break;
case 2:
player->Radio("%!MRAD_TAKEPOINT_ZB", "#You_take_the_point");
break;
case 3:
player->Radio("%!MRAD_POSITION_ZB", "#Hold_this_position");
break;
case 4:
player->Radio("%!MRAD_REGROUP_ZB", "#Regroup_team");
break;
case 5:
player->Radio("%!MRAD_FOLLOWME_ZB", "#Follow_me");
break;
case 6:
player->Radio("%!MRAD_HITASSIST_ZB", "#Taking_fire");
break;
}
}
else
{
switch (slot) {
case 1:
player->Radio("%!MRAD_COVERME", "#Cover_me");
break;
case 2:
player->Radio("%!MRAD_TAKEPOINT", "#You_take_the_point");
break;
case 3:
player->Radio("%!MRAD_POSITION", "#Hold_this_position");
break;
case 4:
player->Radio("%!MRAD_REGROUP", "#Regroup_team");
break;
case 5:
player->Radio("%!MRAD_FOLLOWME", "#Follow_me");
break;
case 6:
player->Radio("%!MRAD_HITASSIST", "#Taking_fire");
break;
}
}
if (TheBots != NULL) {
TheBots->OnEvent((GameEventType) (EVENT_START_RADIO_1 + slot), player);
}
}
void Radio2(CBasePlayer *player, int slot)
{
if (player->m_flRadioTime >= gpGlobals->time) {
return;
}
if (player->m_iRadioMessages <= 0) {
return;
}
player->m_iRadioMessages--;
player->m_flRadioTime = gpGlobals->time + 1.5s;
if (player->m_bIsZombie)
{
switch (slot) {
case 1:
player->Radio("%!MRAD_GO_ZB", "#Go_go_go");
break;
case 2:
player->Radio("%!MRAD_FALLBACK_ZB", "#Team_fall_back");
break;
case 3:
player->Radio("%!MRAD_STICKTOG_ZB", "#Stick_together_team");
break;
case 4:
player->Radio("%!MRAD_GETINPOS_ZB", "#Get_in_position_and_wait");
break;
case 5:
player->Radio("%!MRAD_STORMFRONT_ZB", "#Storm_the_front");
break;
case 6:
player->Radio("%!MRAD_REPORTIN_ZB", "#Report_in_team");
break;
}
}
else
{
switch (slot) {
case 1:
player->Radio("%!MRAD_GO", "#Go_go_go");
break;
case 2:
player->Radio("%!MRAD_FALLBACK", "#Team_fall_back");
break;
case 3:
player->Radio("%!MRAD_STICKTOG", "#Stick_together_team");
break;
case 4:
player->Radio("%!MRAD_GETINPOS", "#Get_in_position_and_wait");
break;
case 5:
player->Radio("%!MRAD_STORMFRONT", "#Storm_the_front");
break;
case 6:
player->Radio("%!MRAD_REPORTIN", "#Report_in_team");
break;
}
}
if (TheBots != NULL) {
TheBots->OnEvent((GameEventType) (EVENT_START_RADIO_2 + slot), player);
}
}
void Radio3(CBasePlayer *player, int slot)
{
if (player->m_flRadioTime >= gpGlobals->time) {
return;
}
if (player->m_iRadioMessages <= 0) {
return;
}
player->m_iRadioMessages--;
player->m_flRadioTime = gpGlobals->time + 1.5s;
if (player->m_bIsZombie)
{
switch (slot) {
case 1:
if (RANDOM_LONG(0, 1))
player->Radio("%!MRAD_AFFIRM_ZB", "#Affirmative");
else
player->Radio("%!MRAD_ROGER_ZB", "#Roger_that");
break;
case 2:
player->Radio("%!MRAD_ENEMYSPOT_ZB", "#Enemy_spotted");
break;
case 3:
player->Radio("%!MRAD_BACKUP_ZB", "#Need_backup");
break;
case 4:
player->Radio("%!MRAD_CLEAR_ZB", "#Sector_clear");
break;
case 5:
player->Radio("%!MRAD_INPOS_ZB", "#In_position");
break;
case 6:
player->Radio("%!MRAD_REPRTINGIN_ZB", "#Reporting_in");
break;
case 7:
player->Radio("%!MRAD_BLOW_ZB", "#Get_out_of_there");
break;
case 8:
player->Radio("%!MRAD_NEGATIVE_ZB", "#Negative");
break;
case 9:
player->Radio("%!MRAD_ENEMYDOWN_ZB", "#Enemy_down");
break;
}
}
else
{
switch (slot) {
case 1:
if (RANDOM_LONG(0, 1))
player->Radio("%!MRAD_AFFIRM", "#Affirmative");
else
player->Radio("%!MRAD_ROGER", "#Roger_that");
break;
case 2:
player->Radio("%!MRAD_ENEMYSPOT", "#Enemy_spotted");
break;
case 3:
player->Radio("%!MRAD_BACKUP", "#Need_backup");
break;
case 4:
player->Radio("%!MRAD_CLEAR", "#Sector_clear");
break;
case 5:
player->Radio("%!MRAD_INPOS", "#In_position");
break;
case 6:
player->Radio("%!MRAD_REPRTINGIN", "#Reporting_in");
break;
case 7:
player->Radio("%!MRAD_BLOW", "#Get_out_of_there");
break;
case 8:
player->Radio("%!MRAD_NEGATIVE", "#Negative");
break;
case 9:
player->Radio("%!MRAD_ENEMYDOWN", "#Enemy_down");
break;
}
}
if (TheBots != NULL) {
TheBots->OnEvent((GameEventType) (EVENT_START_RADIO_3 + slot), player);
}
}
bool BuyGunAmmo(CBasePlayer *player, CBasePlayerItem *weapon, bool bBlinkMoney)
{
if (!player->CanPlayerBuy(true)) {
return false;
}
// Ensure that the weapon uses ammo
int nAmmo = weapon->PrimaryAmmoIndex();
if (nAmmo == -1) {
return false;
}
WeaponBuyAmmoConfig config = weapon->GetBuyAmmoConfig();
int cost = config.cost;
const char *classname = config.classname;
if (!classname) {
ALERT(at_console, "Tried to buy ammo for an unrecognized gun\n");
return false;
}
// Can only buy if the player does not already have full ammo
int iMax = weapon->iMaxAmmo1();
if (player->m_rgAmmo[nAmmo] >= player->m_pModStrategy->ComputeMaxAmmo(classname, iMax)) {
return false;
}
// Purchase the ammo if the player has enough money
if (player->m_iAccount >= cost) {
player->GiveNamedItem(classname);
player->AddAccount(-cost);
return true;
}
if (bBlinkMoney) {
if (g_bClientPrintEnable) {
// Not enough money.. let the player know
ClientPrint(player->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(player, 2);
}
}
return false;
}
bool BuyAmmo(CBasePlayer *player, int nSlot, bool bBlinkMoney)
{
if (!player->CanPlayerBuy(true)) {
return false;
}
if (nSlot < PRIMARY_WEAPON_SLOT || nSlot > PISTOL_SLOT) {
return false;
}
// Buy one ammo clip for all weapons in the given slot
//
// nSlot == 1 : Primary weapons
// nSlot == 2 : Secondary weapons
CBasePlayerItem *pItem = player->m_rgpPlayerItems[nSlot];
if (player->HasShield()) {
if (player->m_rgpPlayerItems[PISTOL_SLOT])
pItem = player->m_rgpPlayerItems[PISTOL_SLOT];
}
if (pItem != NULL) {
while (BuyGunAmmo(player, pItem, bBlinkMoney)) {
pItem = pItem->m_pNext;
if (!pItem) {
return true;
}
}
}
return false;
}
CBaseEntity *EntityFromUserID(int userID)
{
CBaseEntity *pTempEntity = NULL;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")) != NULL) {
if (FNullEnt(pTempEntity->edict()))
break;
CBasePlayer *pTempPlayer = GetClassPtr<CBasePlayer>(pTempEntity->pev);
if (pTempPlayer->m_iTeam != UNASSIGNED && userID == GETPLAYERUSERID(pTempEntity->edict())) {
return pTempPlayer;
}
}
return NULL;
}
NOXREF int CountPlayersInServer()
{
int count = 0;
CBaseEntity *pTempEntity = NULL;
while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")) != NULL) {
if (FNullEnt(pTempEntity->edict()))
break;
CBasePlayer *pTempPlayer = GetClassPtr<CBasePlayer>(pTempEntity->pev);
if (pTempPlayer->m_iTeam != UNASSIGNED) {
count++;
}
}
return count;
}
// Handles the special "buy" alias commands we're creating to accommodate the buy
// scripts players use (now that we've rearranged the buy menus and broken the scripts)
// ** Returns TRUE if we've handled the command **
BOOL HandleBuyAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
{
// Let them buy it if it's got a weapon data string.
BOOL bRetVal = FALSE;
const char *pszFailItem = NULL;
WeaponIdType weaponID = WEAPON_NONE;
const char *weaponFailName = BuyAliasToWeaponID(pszCommand, weaponID);
if (weaponID != WEAPON_NONE) {
// Ok, we have weapon info ID.
// assasination maps have a specific set of weapons that can be used in them.
if (CanBuyWeaponByMaptype(pPlayer->m_iTeam, weaponID,
(g_pGameRules->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES))) {
bRetVal = TRUE;
BuyWeaponByWeaponID(pPlayer, weaponID);
} else if (weaponFailName != NULL) {
bRetVal = TRUE;
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Alias_Not_Avail", weaponFailName);
}
} else {
bRetVal = TRUE;
if (g_bClientPrintEnable) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Cannot_Buy_This");
}
}
} else {
// primary ammo
if (FStrEq(pszCommand, "primammo")) {
bRetVal = TRUE;
// Buy as much primary ammo as possible
// Blink money only if player doesn't have enough for the
// first clip
if (BuyAmmo(pPlayer, PRIMARY_WEAPON_SLOT, true)) {
while (BuyAmmo(pPlayer, PRIMARY_WEAPON_SLOT, false));
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
}
// secondary ammo
else if (FStrEq(pszCommand, "secammo")) {
bRetVal = TRUE;
// Buy as much secondary ammo as possible
// Blink money only if player doesn't have enough for the
// first clip
if (BuyAmmo(pPlayer, PISTOL_SLOT, true)) {
while (BuyAmmo(pPlayer, PISTOL_SLOT, false));
if (TheTutor != NULL) {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
}
}
// equipment
else if (FStrEq(pszCommand, "vest")) {
bRetVal = TRUE;
BuyItem(pPlayer, MENU_SLOT_ITEM_VEST);
} else if (FStrEq(pszCommand, "vesthelm")) {
bRetVal = TRUE;
BuyItem(pPlayer, MENU_SLOT_ITEM_VESTHELM);
} else if (FStrEq(pszCommand, "flash")) {
bRetVal = TRUE;
BuyItem(pPlayer, MENU_SLOT_ITEM_FLASHGREN);
} else if (FStrEq(pszCommand, "hegren")) {
bRetVal = TRUE;
BuyItem(pPlayer, MENU_SLOT_ITEM_HEGREN);
} else if (FStrEq(pszCommand, "sgren")) {
bRetVal = TRUE;
BuyItem(pPlayer, MENU_SLOT_ITEM_SMOKEGREN);
} else if (FStrEq(pszCommand, "nvgs")) {
bRetVal = TRUE;
BuyItem(pPlayer, MENU_SLOT_ITEM_NVG);
} else if (FStrEq(pszCommand, "defuser")) {
bRetVal = TRUE;
if (pPlayer->m_iTeam == CT) {
BuyItem(pPlayer, MENU_SLOT_ITEM_DEFUSEKIT);
} else {
// fail gracefully
pszFailItem = "#Bomb_Defusal_Kit";
}
} else if (FStrEq(pszCommand, "shield")) {
bRetVal = TRUE;
if (pPlayer->m_iTeam == CT) {
BuyItem(pPlayer, MENU_SLOT_ITEM_SHIELD);
} else {
// fail gracefully
pszFailItem = "#TactShield_Desc";
}
}
}
if (g_bClientPrintEnable && pszFailItem != NULL) {
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Alias_Not_Avail", pszFailItem);
}
pPlayer->BuildRebuyStruct();
return bRetVal;
}
BOOL HandleRadioAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
{
BOOL bRetVal = FALSE;
if (FStrEq(pszCommand, "coverme")) {
bRetVal = TRUE;
Radio1(pPlayer, 1);
} else if (FStrEq(pszCommand, "takepoint")) {
bRetVal = TRUE;
Radio1(pPlayer, 2);
} else if (FStrEq(pszCommand, "holdpos")) {
bRetVal = TRUE;
Radio1(pPlayer, 3);
} else if (FStrEq(pszCommand, "regroup")) {
bRetVal = TRUE;
Radio1(pPlayer, 4);
} else if (FStrEq(pszCommand, "followme")) {
bRetVal = TRUE;
Radio1(pPlayer, 5);
} else if (FStrEq(pszCommand, "takingfire")) {
bRetVal = TRUE;
Radio1(pPlayer, 6);
} else if (FStrEq(pszCommand, "go")) {
bRetVal = TRUE;
Radio2(pPlayer, 1);
} else if (FStrEq(pszCommand, "fallback")) {
bRetVal = TRUE;
Radio2(pPlayer, 2);
} else if (FStrEq(pszCommand, "sticktog")) {
bRetVal = TRUE;
Radio2(pPlayer, 3);
} else if (FStrEq(pszCommand, "getinpos")) {
bRetVal = TRUE;
Radio2(pPlayer, 4);
} else if (FStrEq(pszCommand, "stormfront")) {
bRetVal = TRUE;
Radio2(pPlayer, 5);
} else if (FStrEq(pszCommand, "report")) {
bRetVal = TRUE;
Radio2(pPlayer, 6);
} else if (FStrEq(pszCommand, "roger")) {
bRetVal = TRUE;
Radio3(pPlayer, 1);
} else if (FStrEq(pszCommand, "enemyspot")) {
bRetVal = TRUE;
Radio3(pPlayer, 2);
} else if (FStrEq(pszCommand, "needbackup")) {
bRetVal = TRUE;
Radio3(pPlayer, 3);
} else if (FStrEq(pszCommand, "sectorclear")) {
bRetVal = TRUE;
Radio3(pPlayer, 4);
} else if (FStrEq(pszCommand, "inposition")) {
bRetVal = TRUE;
Radio3(pPlayer, 5);
} else if (FStrEq(pszCommand, "reportingin")) {
bRetVal = TRUE;
Radio3(pPlayer, 6);
} else if (FStrEq(pszCommand, "getout")) {
bRetVal = TRUE;
Radio3(pPlayer, 7);
} else if (FStrEq(pszCommand, "negative")) {
bRetVal = TRUE;
Radio3(pPlayer, 8);
} else if (FStrEq(pszCommand, "enemydown")) {
bRetVal = TRUE;
Radio3(pPlayer, 9);
}
return bRetVal;
}
// Use CMD_ARGV, CMD_ARGV, and CMD_ARGC to get pointers the character string command.
void EXT_FUNC ClientCommand(edict_t *pEntity)
{
const char *pcmd = CMD_ARGV_(0);
const char *pstr = NULL;
CHalfLifeMultiplay *mp = g_pGameRules;
// Is the client spawned yet?
if (!pEntity->pvPrivateData)
return;
entvars_t *pev = &pEntity->v;
CBasePlayer *player = GetClassPtr<CBasePlayer>(pev);
if (FStrEq(pcmd, "say"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[0])
{
player->m_flLastCommandTime[0] = gpGlobals->time + 0.3s;
Host_Say(pEntity, 0);
}
}
else if (FStrEq(pcmd, "inspect"))
{
if ((int)CVAR_GET_FLOAT("mp_csgoinspect"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[7])
{
player->m_flLastCommandTime[7] = gpGlobals->time + 0.3s;
if (!player->m_bIsZombie)
{
if(player->m_pActiveItem != NULL)
player->m_pActiveItem->Inspect();
}
}
}
}
else if (FStrEq(pcmd, "changemodel"))
{
if ((int)CVAR_GET_FLOAT("mp_csgoinspect"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[7])
{
player->m_flLastCommandTime[7] = gpGlobals->time + 0.3s;
if (!player->m_bIsZombie)
{
player->m_pActiveItem->ChangeModel();
}
}
}
}
else if (FStrEq(pcmd, "say_team"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[1])
{
player->m_flLastCommandTime[1] = gpGlobals->time + 0.3s;
Host_Say(pEntity, 1);
}
}
else if (FStrEq(pcmd, "fullupdate"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[2])
{
player->m_flLastCommandTime[2] = gpGlobals->time + 0.6s;
player->ForceClientDllUpdate();
}
}
else if (FStrEq(pcmd, "vote"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[3])
{
player->m_flLastCommandTime[3] = gpGlobals->time + 0.3s;
if (gpGlobals->time < player->m_flNextVoteTime)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Wait_3_Seconds");
return;
}
player->m_flNextVoteTime = gpGlobals->time + 3s;
if (player->m_iTeam != UNASSIGNED)
{
int iVoteID;
int iVoteFail = 0;
int iNumArgs = CMD_ARGC_();
const char *pszArg1 = CMD_ARGV_(1);
int iVoteLength = Q_strlen(pszArg1);
if (iNumArgs != 2 || iVoteLength <= 0 || iVoteLength > 6)
{
iVoteFail = 1;
}
iVoteID = Q_atoi(pszArg1);
if (iVoteID <= 0)
{
iVoteFail = 1;
}
if (iVoteFail)
{
ListPlayers(player);
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_vote_usage");
return;
}
if (CountTeamPlayers(player->m_iTeam) < 3)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Cannot_Vote_With_Less_Than_Three");
return;
}
CBaseEntity *pKickEntity = EntityFromUserID(iVoteID);
if (pKickEntity != NULL)
{
CBasePlayer *pKickPlayer = GetClassPtr<CBasePlayer>(pKickEntity->pev);
if (pKickPlayer->m_iTeam != player->m_iTeam)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_vote_players_on_your_team");
return;
}
if (pKickPlayer == player)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_vote_not_yourself");
return;
}
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_vote_cast", UTIL_dtos1(iVoteID));
player->m_iCurrentKickVote = iVoteID;
ProcessKickVote(player, pKickPlayer);
}
else
{
ListPlayers(player);
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_vote_player_not_found", UTIL_dtos1(iVoteID));
}
}
}
}
else if (FStrEq(pcmd, "listmaps"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[5])
{
player->m_flLastCommandTime[5] = gpGlobals->time + 0.3s;
mp->DisplayMaps(player, 0);
}
}
else if (FStrEq(pcmd, "votemap"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[4])
{
player->m_flLastCommandTime[4] = gpGlobals->time + 0.3s;
if (gpGlobals->time < player->m_flNextVoteTime)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Wait_3_Seconds");
return;
}
player->m_flNextVoteTime = gpGlobals->time + 3s;
if (player->m_iTeam != UNASSIGNED)
{
if (gpGlobals->time.time_since_epoch() < 180s)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Cannot_Vote_Map");
return;
}
int iFailed = 0;
int iNumArgs = CMD_ARGC_();
const char *pszArg1 = CMD_ARGV_(1);
int iVoteLength = Q_strlen(pszArg1);
if (iNumArgs != 2 || iVoteLength > 5)
{
iFailed = 1;
}
int iVoteID = Q_atoi(pszArg1);
if (iVoteID < 1 || iVoteID > MAX_VOTE_MAPS)
{
iFailed = 1;
}
if (iVoteID > GetMapCount())
{
iFailed = 1;
}
if (iFailed)
{
mp->DisplayMaps(player, 0);
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_votemap_usage");
return;
}
if (CountTeamPlayers(player->m_iTeam) < 2)
{
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Cannot_Vote_Need_More_People");
return;
}
if (player->m_iMapVote)
{
mp->m_iMapVotes[ player->m_iMapVote ]--;
if (mp->m_iMapVotes[player->m_iMapVote] < 0)
{
mp->m_iMapVotes[player->m_iMapVote] = 0;
}
}
ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_voted_for_map", UTIL_dtos1(iVoteID));
player->m_iMapVote = iVoteID;
mp->ProcessMapVote(player, iVoteID);
}
}
}
else if (FStrEq(pcmd, "timeleft"))
{
if (gpGlobals->time > player->m_iTimeCheckAllowed)
{
player->m_iTimeCheckAllowed = gpGlobals->time + 1s;
if (!timelimit.value)
{
ClientPrint(player->pev, HUD_PRINTTALK, "#Game_no_timelimit");
return;
}
int iTimeRemaining = (int)(g_flTimeLimit - gpGlobals->time).count();
if (iTimeRemaining < 0)
iTimeRemaining = 0;
int iMinutes = (int)(iTimeRemaining % 60);
int iSeconds = (int)(iTimeRemaining / 60);
char secs[5];
char *temp = UTIL_dtos2(iMinutes);
if (iMinutes >= 10)
{
secs[0] = temp[0];
secs[1] = temp[1];
secs[2] = '\0';
}
else
{
secs[0] = '0';
secs[1] = temp[0];
secs[2] = '\0';
}
ClientPrint(player->pev, HUD_PRINTTALK, "#Game_timelimit", UTIL_dtos1(iSeconds), secs);
}
}
else if (FStrEq(pcmd, "listplayers"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[6])
{
player->m_flLastCommandTime[6] = gpGlobals->time + 0.3s;
ListPlayers(player);
}
}
else if (FStrEq(pcmd, "client_buy_open"))
{
if (player->m_iMenu == Menu_OFF)
{
player->m_iMenu = Menu_ClientBuy;
}
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (TheTutor != NULL)
{
TheTutor->OnEvent(EVENT_TUTOR_BUY_MENU_OPENNED);
}
}
else
{
MESSAGE_BEGIN(MSG_ONE, gmsgBuyClose, NULL, player->pev);
MESSAGE_END();
}
}
else if (FStrEq(pcmd, "client_buy_close"))
{
if (player->m_iMenu == Menu_ClientBuy)
{
player->m_iMenu = Menu_OFF;
}
}
else if (FStrEq(pcmd, "menuselect"))
{
int slot = Q_atoi(CMD_ARGV_(1));
if (player->m_iJoiningState == JOINED || (player->m_iMenu != Menu_ChooseAppearance && player->m_iMenu != Menu_ChooseTeam))
{
if (slot == 10)
{
player->m_iMenu = Menu_OFF;
}
}
switch (player->m_iMenu)
{
case Menu_OFF:
break;
case Menu_ChooseTeam:
{
if (!player->m_bVGUIMenus && !HandleMenu_ChooseTeam(player, slot))
{
if (player->m_iJoiningState == JOINED)
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_0), "#IG_Team_Select");
else
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5), "#Team_Select");
player->m_iMenu = Menu_ChooseTeam;
}
break;
}
case Menu_IGChooseTeam:
{
if (!player->m_bVGUIMenus)
{
HandleMenu_ChooseTeam(player, slot);
}
break;
}
case Menu_ChooseAppearance:
{
if (!player->m_bVGUIMenus)
{
HandleMenu_ChooseAppearance(player, slot);
}
break;
}
case Menu_Buy:
{
if (!player->m_bVGUIMenus)
{
switch (slot)
{
case VGUI_MenuSlot_Buy_Pistol:
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Pistol, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_0), "#CT_BuyPistol");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Pistol, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_0), "#T_BuyPistol");
player->m_iMenu = Menu_BuyPistol;
break;
}
case VGUI_MenuSlot_Buy_ShotGun:
{
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES && player->m_iTeam == TERRORIST)
ShowVGUIMenu(player, VGUI_Menu_Buy_ShotGun, MENU_KEY_0, "#AS_BuyShotgun");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_ShotGun, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_0), "#BuyShotgun");
player->m_iMenu = Menu_BuyShotgun;
break;
}
case VGUI_MenuSlot_Buy_SubMachineGun:
{
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES)
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_SubMachineGun, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_0), "#AS_CT_BuySubMachineGun");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_SubMachineGun, (MENU_KEY_1 | MENU_KEY_3 | MENU_KEY_0), "#AS_T_BuySubMachineGun");
}
else
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_SubMachineGun, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_0), "#CT_BuySubMachineGun");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_SubMachineGun, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_0), "#T_BuySubMachineGun");
}
player->m_iMenu = Menu_BuySubMachineGun;
break;
}
case VGUI_MenuSlot_Buy_Rifle:
{
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES)
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Rifle, (MENU_KEY_1 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_0), "#AS_CT_BuyRifle");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Rifle, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_0), "#AS_T_BuyRifle");
}
else
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Rifle, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#CT_BuyRifle");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Rifle, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#T_BuyRifle");
}
player->m_iMenu = Menu_BuyRifle;
break;
}
case VGUI_MenuSlot_Buy_MachineGun:
{
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES && player->m_iTeam == TERRORIST)
ShowVGUIMenu(player, VGUI_Menu_Buy_MachineGun, MENU_KEY_0, "#AS_T_BuyMachineGun");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_MachineGun, (MENU_KEY_1 | MENU_KEY_0), "#BuyMachineGun");
player->m_iMenu = Menu_BuyMachineGun;
break;
}
case VGUI_MenuSlot_Buy_PrimAmmo:
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (BuyAmmo(player, PRIMARY_WEAPON_SLOT, true))
{
while (BuyAmmo(player, PRIMARY_WEAPON_SLOT, false))
;
if (TheTutor != NULL)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, player);
}
}
player->BuildRebuyStruct();
}
break;
}
case VGUI_MenuSlot_Buy_SecAmmo:
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (BuyAmmo(player, PISTOL_SLOT, true))
{
while (BuyAmmo(player, PISTOL_SLOT, false))
;
if (TheTutor != NULL)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, player);
}
}
player->BuildRebuyStruct();
}
break;
}
case VGUI_MenuSlot_Buy_Item:
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (mp->m_bMapHasBombTarget)
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_7 | MENU_KEY_8 | MENU_KEY_0), "#DCT_BuyItem");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#DT_BuyItem");
}
else
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_8 | MENU_KEY_0), "#CT_BuyItem");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#T_BuyItem");
}
player->m_iMenu = Menu_BuyItem;
}
break;
}
case VGUI_MenuSlot_Zbs_Upgrade:
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (!player->m_bVGUIMenus)
ShowMenu(player, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_0), -1, 0, "#ZbsUpgrade");
player->m_iMenu = Menu_ZbsUpgrade;
}
break;
}
}
}
break;
}
case Menu_BuyPistol:
{
if (!player->m_bVGUIMenus)
{
BuyPistol(player, slot);
}
break;
}
case Menu_BuyShotgun:
{
if (!player->m_bVGUIMenus)
{
BuyShotgun(player, slot);
}
break;
}
case Menu_BuySubMachineGun:
{
if (!player->m_bVGUIMenus)
{
BuySubMachineGun(player, slot);
}
break;
}
case Menu_BuyRifle:
{
if (!player->m_bVGUIMenus)
{
BuyRifle(player, slot);
}
break;
}
case Menu_BuyMachineGun:
{
if (!player->m_bVGUIMenus)
{
BuyMachineGun(player, slot);
}
break;
}
case Menu_BuyItem:
{
if (!player->m_bVGUIMenus)
{
BuyItem(player, slot);
}
break;
}
case Menu_Radio1:
{
Radio1(player, slot);
break;
}
case Menu_Radio2:
{
Radio2(player, slot);
break;
}
case Menu_Radio3:
{
Radio3(player, slot);
break;
}
case Menu_ZbsUpgrade:
{
if (!player->m_bVGUIMenus)
{
ZbsUpgrade(player, slot);
}
break;
}
default:
ALERT(at_console, "ClientCommand(): Invalid menu selected\n");
break;
}
}
else if (FStrEq(pcmd, "chooseteam"))
{
if (player->m_iMenu == Menu_ChooseAppearance)
{
return;
}
if (player->m_bTeamChanged)
{
if (player->pev->deadflag != DEAD_NO)
{
ClientPrint(player->pev, HUD_PRINTCENTER, "#Only_1_Team_Change");
return;
}
}
if (!mp->IsCareer())
{
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES && player->m_iJoiningState == JOINED && player->m_iTeam == CT)
{
if (mp->IsFreezePeriod() || player->pev->deadflag != DEAD_NO)
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#IG_VIP_Team_Select_Spect");
else
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_5 | MENU_KEY_0), "#IG_VIP_Team_Select");
}
else
{
if (mp->IsFreezePeriod() || player->pev->deadflag != DEAD_NO)
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#IG_Team_Select_Spect");
else
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_0), "#IG_Team_Select");
}
player->m_iMenu = Menu_ChooseTeam;
}
}
else if (FStrEq(pcmd, "showbriefing"))
{
if (player->m_iMenu == Menu_OFF)
{
if (g_szMapBriefingText[0] != '\0')
{
if (player->m_iTeam != UNASSIGNED && !(player->m_afPhysicsFlags & PFLAG_OBSERVER))
{
player->MenuPrint(g_szMapBriefingText);
player->m_bMissionBriefing = true;
}
}
}
}
else if (FStrEq(pcmd, "ignoremsg"))
{
if (player->m_iIgnoreGlobalChat == IGNOREMSG_NONE)
{
player->m_iIgnoreGlobalChat = IGNOREMSG_ENEMY;
ClientPrint(player->pev, HUD_PRINTCENTER, "#Ignore_Broadcast_Messages");
}
else if (player->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY)
{
player->m_iIgnoreGlobalChat = IGNOREMSG_TEAM;
ClientPrint(player->pev, HUD_PRINTCENTER, "#Ignore_Broadcast_Team_Messages");
}
else if (player->m_iIgnoreGlobalChat == IGNOREMSG_TEAM)
{
player->m_iIgnoreGlobalChat = IGNOREMSG_NONE;
ClientPrint(player->pev, HUD_PRINTCENTER, "#Accept_All_Messages");
}
}
else if (FStrEq(pcmd, "ignorerad"))
{
player->m_bIgnoreRadio = !player->m_bIgnoreRadio;
ClientPrint(player->pev, HUD_PRINTCENTER, player->m_bIgnoreRadio ? "#Ignore_Radio" : "#Accept_Radio");
}
else if (FStrEq(pcmd, "become_vip"))
{
if (player->m_iJoiningState != JOINED || player->m_iTeam != CT)
{
ClientPrint(player->pev, HUD_PRINTCENTER, "#Command_Not_Available");
return;
}
mp->AddToVIPQueue(player);
}
else if (FStrEq(pcmd, "spectate") && (player->pev->flags & FL_PROXY)) // always allow proxies to become a spectator
{
// clients wants to become a spectator
HandleMenu_ChooseTeam(player, MENU_SLOT_TEAM_SPECT);
}
else if (FStrEq(pcmd, "specmode"))
{
// new spectator mode
int mode = Q_atoi(CMD_ARGV_(1));
if (player->IsObserver() && player->CanSwitchObserverModes())
player->Observer_SetMode(mode);
else
player->m_iObserverLastMode = mode;
if (mode == OBS_CHASE_FREE)
{
MESSAGE_BEGIN(MSG_ONE, gmsgADStop, NULL, player->pev);
MESSAGE_END();
}
}
else if (FStrEq(pcmd, "spec_set_ad"))
{
float val = Q_atof(CMD_ARGV_(1));
player->SetObserverAutoDirector(val > 0.0f);
}
else if (FStrEq(pcmd, "follownext"))
{
// follow next player
int arg = Q_atoi(CMD_ARGV_(1));
if (player->IsObserver() && player->CanSwitchObserverModes())
{
player->Observer_FindNextPlayer(arg != 0);
}
}
else if (FStrEq(pcmd, "follow"))
{
if (player->IsObserver() && player->CanSwitchObserverModes())
{
player->Observer_FindNextPlayer(false, CMD_ARGV_(1));
}
}
else
{
if (mp->ClientCommand_DeadOrAlive(GetClassPtr<CBasePlayer>(pev), pcmd))
return;
if (TheBots != NULL)
{
if (TheBots->ClientCommand(GetClassPtr<CBasePlayer>(pev), pcmd))
return;
}
if (FStrEq(pcmd, "mp_debug"))
{
UTIL_SetDprintfFlags(CMD_ARGV_(1));
}
else if (FStrEq(pcmd, "jointeam"))
{
if (player->m_iMenu == Menu_ChooseAppearance)
{
ClientPrint(player->pev, HUD_PRINTCENTER, "#Command_Not_Available");
return;
}
int slot = Q_atoi(CMD_ARGV_(1));
if (HandleMenu_ChooseTeam(player, slot))
{
if (slot == MENU_SLOT_TEAM_VIP || slot == MENU_SLOT_TEAM_SPECT || player->m_bIsVIP)
{
player->ResetMenu();
}
else
player->m_iMenu = Menu_ChooseAppearance;
}
else
{
if (player->m_iJoiningState == JOINED)
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_0), "#IG_Team_Select");
else
ShowVGUIMenu(player, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5), "#Team_Select");
player->m_iMenu = Menu_ChooseTeam;
}
}
else if (FStrEq(pcmd, "joinclass"))
{
int slot = Q_atoi(CMD_ARGV_(1));
if (player->m_iMenu != Menu_ChooseAppearance)
{
ClientPrint(player->pev, HUD_PRINTCENTER, "#Command_Not_Available");
return;
}
HandleMenu_ChooseAppearance(player, slot);
}
else if (player->pev->deadflag == DEAD_NO)
{
if (FStrEq(pcmd, "nightvision"))
{
if (gpGlobals->time >= player->m_flLastCommandTime[7])
{
player->m_flLastCommandTime[7] = gpGlobals->time + 0.3s;
if (!player->m_bHasNightVision)
return;
if (player->m_bNightVisionOn)
{
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "items/nvg_off.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, player->pev);
WRITE_BYTE(0); // disable nightvision
MESSAGE_END();
player->m_bNightVisionOn = false;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CBasePlayer *pObserver = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
if (pObserver && pObserver->IsObservingPlayer(player))
{
EMIT_SOUND(ENT(pObserver->pev), CHAN_ITEM, "items/nvg_off.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, pObserver->pev);
WRITE_BYTE(0); // disable nightvision
MESSAGE_END();
pObserver->m_bNightVisionOn = false;
}
}
}
else
{
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "items/nvg_on.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, player->pev);
WRITE_BYTE(1); // enable nightvision
MESSAGE_END();
player->m_bNightVisionOn = true;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CBasePlayer *pObserver = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
if (pObserver && pObserver->IsObservingPlayer(player))
{
EMIT_SOUND(ENT(pObserver->pev), CHAN_ITEM, "items/nvg_on.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, pObserver->pev);
WRITE_BYTE(1); // enable nightvision
MESSAGE_END();
pObserver->m_bNightVisionOn = true;
}
}
}
}
}
else if (FStrEq(pcmd, "radio1"))
{
ShowMenu(player, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), -1, FALSE, "#RadioA");
player->m_iMenu = Menu_Radio1;
}
else if (FStrEq(pcmd, "radio2"))
{
ShowMenu(player, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), -1, FALSE, "#RadioB");
player->m_iMenu = Menu_Radio2;
return;
}
else if (FStrEq(pcmd, "radio3"))
{
ShowMenu(player, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_7 | MENU_KEY_8 | MENU_KEY_9 | MENU_KEY_0), -1, FALSE, "#RadioC");
player->m_iMenu = Menu_Radio3;
}
else if (FStrEq(pcmd, "drop"))
{
// player is dropping an item.
if (g_pGameRules->ClientCommand(player, "BTE_ZombieSkill1") || player->m_pModStrategy->ClientCommand("BTE_ZombieSkill1"))
{
// ...
}
#ifdef ENABLE_SHIELD
else if (player->HasShield())
{
if (player->m_pActiveItem != NULL && player->m_pActiveItem->m_iId == WEAPON_C4)
{
player->DropPlayerItem("weapon_c4");
}
else
player->DropShield();
}
#endif
else
player->DropPlayerItem(CMD_ARGV_(1));
}
else if (FStrEq(pcmd, "fov"))
{
#if 0
if (g_flWeaponCheat && CMD_ARGC() > 1)
GetClassPtr<CBasePlayer>(pev)->m_iFOV = Q_atoi(CMD_ARGV(1));
else
CLIENT_PRINTF(pEntity, print_console, UTIL_VarArgs("\"fov\" is \"%d\"\n", (int)GetClassPtr<CBasePlayer>(pev)->m_iFOV));
#endif
}
else if (FStrEq(pcmd, "use"))
{
GetClassPtr<CBasePlayer>(pev)->SelectItem(CMD_ARGV_(1));
}
else if (((pstr = Q_strstr(pcmd, "weapon_")) != NULL) && (pstr == pcmd))
{
if (!player->m_pActiveItem->CanHolster())
return;
GetClassPtr<CBasePlayer>(pev)->SelectItem(pcmd);
}
else if (((pstr = Q_strstr(pcmd, "knife_")) != NULL) && (pstr == pcmd))
{
GetClassPtr<CBasePlayer>(pev)->SelectItem(pcmd);
}
else if (((pstr = Q_strstr(pcmd, "z4b_")) != NULL) && (pstr == pcmd))
{
GetClassPtr<CBasePlayer>(pev)->SelectItem(pcmd);
}
else if (((pstr = Q_strstr(pcmd, "csgo_")) != NULL) && (pstr == pcmd))
{
GetClassPtr<CBasePlayer>(pev)->SelectItem(pcmd);
}
else if (FStrEq(pcmd, "lastinv"))
{
GetClassPtr<CBasePlayer>(pev)->SelectLastItem();
}
else if (FStrEq(pcmd, "buyammo1"))
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
BuyAmmo(player, PRIMARY_WEAPON_SLOT, true);
player->BuildRebuyStruct();
if (TheTutor != NULL)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, player);
}
}
}
else if (FStrEq(pcmd, "buyammo2"))
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
BuyAmmo(player, PISTOL_SLOT, true);
player->BuildRebuyStruct();
if (TheTutor != NULL)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, player);
}
}
}
else if (FStrEq(pcmd, "buyequip"))
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (mp->m_bMapHasBombTarget)
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_7 | MENU_KEY_8 | MENU_KEY_0), "#DCT_BuyItem");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#DT_BuyItem");
}
else
{
if (player->m_iTeam == CT)
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_8 | MENU_KEY_0), "#CT_BuyItem");
else
ShowVGUIMenu(player, VGUI_Menu_Buy_Item, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_0), "#T_BuyItem");
}
player->m_iMenu = Menu_BuyItem;
}
}
else if (FStrEq(pcmd, "buy"))
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
if (g_pModRunning->DamageTrack() == DT_ZBS)
ShowVGUIMenu(player, VGUI_Menu_Buy, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_7 | MENU_KEY_8 | MENU_KEY_9 | MENU_KEY_0), "#BuyZbs");
else
ShowVGUIMenu(player, VGUI_Menu_Buy, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_3 | MENU_KEY_4 | MENU_KEY_5 | MENU_KEY_6 | MENU_KEY_7 | MENU_KEY_8 | MENU_KEY_0), "#Buy");
player->m_iMenu = Menu_Buy;
if (TheBots != NULL)
{
TheBots->OnEvent(EVENT_TUTOR_BUY_MENU_OPENNED);
}
}
}
else if (FStrEq(pcmd, "cl_setautobuy"))
{
player->ClearAutoBuyData();
for (int i = 1; i < CMD_ARGC_(); ++i)
{
player->AddAutoBuyData(CMD_ARGV_(i));
}
bool oldval = g_bClientPrintEnable;
g_bClientPrintEnable = false;
player->AutoBuy();
g_bClientPrintEnable = oldval;
}
else if (FStrEq(pcmd, "cl_setrebuy"))
{
if (CMD_ARGC_() == 2)
{
player->InitRebuyData(CMD_ARGV_(1));
bool oldval = g_bClientPrintEnable;
g_bClientPrintEnable = false;
player->Rebuy();
g_bClientPrintEnable = oldval;
}
}
else if (FStrEq(pcmd, "cl_autobuy"))
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
bool oldval = g_bClientPrintEnable;
g_bClientPrintEnable = false;
player->AutoBuy();
g_bClientPrintEnable = oldval;
}
}
else if (FStrEq(pcmd, "cl_rebuy"))
{
if (player->m_signals.GetState() & SIGNAL_BUY)
{
bool oldval = g_bClientPrintEnable;
g_bClientPrintEnable = false;
player->Rebuy();
g_bClientPrintEnable = oldval;
}
}
else if (FStrEq(pcmd, "smartradio"))
{
player->SmartRadio();
}
else if (FStrEq(pcmd, "moe_buy"))
{
MoE_HandleBuyCommands(player, CMD_ARGV_(1));
}
else
{
if (HandleBuyAliasCommands(player, pcmd))
return;
if (HandleRadioAliasCommands(player, pcmd))
return;
if (!g_pGameRules->ClientCommand(GetClassPtr<CBasePlayer>(pev), pcmd) && !player->m_pModStrategy->ClientCommand(pcmd))
{
// tell the user they entered an unknown command
char command[128];
// check the length of the command (prevents crash)
// max total length is 192 ...and we're adding a string below ("Unknown command: %s\n")
Q_strncpy(command, pcmd, sizeof(command) - 1);
command[sizeof(command) - 1] = '\0';
// Add extra '\n' to make command string safe
// This extra '\n' is removed by the client, so it is ok
command[sizeof(command) - 2] = '\0';
command[Q_strlen(command)] = '\n';
// tell the user they entered an unknown command
ClientPrint(&pEntity->v, HUD_PRINTCONSOLE, "#Game_unknown_command", command);
}
}
}
}
}
void EXT_FUNC ClientUserInfoChanged(edict_t *pEntity, char *infobuffer)
{
// Is the client spawned yet?
if (!pEntity->pvPrivateData)
{
return;
}
CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance(pEntity);
char *szBufferName = GET_KEY_VALUE(infobuffer, "name");
int iClientIndex = pPlayer->entindex();
// msg everyone if someone changes their name, and it isn't the first time (changing no name to current name)
if (pEntity->v.netname && STRING(pEntity->v.netname)[0] != '\0' && !FStrEq(STRING(pEntity->v.netname), szBufferName))
{
char szName[32];
Q_snprintf(szName, sizeof(szName), "%s", szBufferName);
// First parse the name and remove any %'s
for (char *pPct = szName; pPct != NULL && *pPct != '\0'; pPct++)
{
// Replace it with a space
if (*pPct == '%' || *pPct == '&')
*pPct = ' ';
}
if (szName[0] == '#')
szName[0] = '*';
if (pPlayer->pev->deadflag != DEAD_NO)
{
pPlayer->m_bHasChangedName = true;
Q_snprintf(pPlayer->m_szNewName, sizeof(pPlayer->m_szNewName), "%s", szName);
ClientPrint(pPlayer->pev, HUD_PRINTTALK, "#Name_change_at_respawn");
SET_CLIENT_KEY_VALUE(iClientIndex, infobuffer, "name", (char *)STRING(pEntity->v.netname));
}
else
{
// Set the name
SET_CLIENT_KEY_VALUE(iClientIndex, infobuffer, "name", szName);
MESSAGE_BEGIN(MSG_BROADCAST, gmsgSayText);
WRITE_BYTE(iClientIndex);
WRITE_STRING("#Cstrike_Name_Change");
WRITE_STRING(STRING(pEntity->v.netname));
WRITE_STRING(szName);
MESSAGE_END();
UTIL_LogPrintf
(
"\"%s<%i><%s><%s>\" changed name to \"%s\"\n",
STRING(pEntity->v.netname),
GETPLAYERUSERID(pEntity),
GETPLAYERAUTHID(pEntity),
GetTeam(pPlayer->m_iTeam),
szName
);
}
}
g_pGameRules->ClientUserInfoChanged(pPlayer, infobuffer);
}
void EXT_FUNC ServerDeactivate()
{
// It's possible that the engine will call this function more times than is necessary
// Therefore, only run it one time for each call to ServerActivate
if (g_serveractive != 1)
{
return;
}
g_serveractive = 0;
// Peform any shutdown operations here...
g_pGameRules->ServerDeactivate();
CLocalNav::Reset();
if (TheBots != NULL)
{
TheBots->ServerDeactivate();
}
if (g_pHostages != NULL)
{
g_pHostages->ServerDeactivate();
}
}
void EXT_FUNC ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
int i;
CBaseEntity *pClass;
// Every call to ServerActivate should be matched by a call to ServerDeactivate
g_serveractive = 1;
EmptyEntityHashTable();
// Clients have not been initialized yet
for (i = 0; i < edictCount; ++i)
{
edict_t *pEdict = &pEdictList[i];
if (pEdict->free)
continue;
// Clients aren't necessarily initialized until ClientPutInServer()
if (i < clientMax || !pEdict->pvPrivateData)
continue;
pClass = CBaseEntity::Instance(pEdict);
// Activate this entity if it's got a class & isn't dormant
if (pClass && !(pClass->pev->flags & FL_DORMANT))
{
AddEntityHashValue(&pEdict->v, STRING(pEdict->v.classname), CLASSNAME);
pClass->Activate();
}
else
ALERT(at_console, "Can't instance %s\n", STRING(pEdict->v.classname));
}
// Link user messages here to make sure first client can get them...
LinkUserMessages();
WriteSigonMessages();
if (g_pGameRules != NULL)
{
g_pGameRules->CheckMapConditions();
}
if (TheBots != NULL)
{
TheBots->ServerActivate();
}
if (g_pHostages != NULL)
{
g_pHostages->ServerActivate();
}
}
void EXT_FUNC PlayerPreThink(edict_t *pEntity)
{
entvars_t *pev = &pEntity->v;
CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity);
if (pPlayer)
{
pPlayer->PreThink();
}
}
void EXT_FUNC PlayerPostThink(edict_t *pEntity)
{
entvars_t *pev = &pEntity->v;
CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity);
if (pPlayer)
{
pPlayer->PostThink();
}
}
void EXT_FUNC ParmsNewLevel()
{
;
}
void EXT_FUNC ParmsChangeLevel()
{
// retrieve the pointer to the save data
SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData;
if (pSaveData)
{
pSaveData->connectionCount = BuildChangeList(pSaveData->levelList, MAX_LEVEL_CONNECTIONS);
}
}
void EXT_FUNC StartFrame()
{
if (g_pGameRules != NULL)
{
g_pGameRules->Think();
}
if (g_fGameOver)
return;
CLocalNav::Think();
static cvar_t *skill = NULL;
if (!skill)
{
skill = CVAR_GET_POINTER("skill");
}
gpGlobals->teamplay = 1.0f;
if (skill != NULL)
g_iSkillLevel = (int)skill->value;
else
g_iSkillLevel = 0;
if (TheBots != NULL)
{
TheBots->StartFrame();
}
if (TheTutor != NULL)
{
TheTutor->StartFrame(gpGlobals->time);
}
}
void ClientPrecache()
{
int i;
PRECACHE_SOUND("weapons/dryfire_pistol.wav");
PRECACHE_SOUND("weapons/dryfire_rifle.wav");
PRECACHE_SOUND("player/pl_shot1.wav");
PRECACHE_SOUND("player/pl_die1.wav");
PRECACHE_SOUND("player/headshot1.wav");
PRECACHE_SOUND("player/headshot2.wav");
PRECACHE_SOUND("player/headshot3.wav");
PRECACHE_SOUND("player/bhit_flesh-1.wav");
PRECACHE_SOUND("player/bhit_flesh-2.wav");
PRECACHE_SOUND("player/bhit_flesh-3.wav");
PRECACHE_SOUND("player/bhit_kevlar-1.wav");
PRECACHE_SOUND("player/bhit_helmet-1.wav");
PRECACHE_SOUND("player/csgo_headshot.wav");
PRECACHE_SOUND("player/die1.wav");
PRECACHE_SOUND("player/die2.wav");
PRECACHE_SOUND("player/die3.wav");
PRECACHE_SOUND("player/death6.wav");
PRECACHE_SOUND("radio/locknload.wav");
PRECACHE_SOUND("radio/letsgo.wav");
PRECACHE_SOUND("radio/moveout.wav");
PRECACHE_SOUND("radio/com_go.wav");
PRECACHE_SOUND("radio/rescued.wav");
PRECACHE_SOUND("radio/rounddraw.wav");
PRECACHE_SOUND("items/kevlar.wav");
PRECACHE_SOUND("items/ammopickup2.wav");
PRECACHE_SOUND("items/nvg_on.wav");
PRECACHE_SOUND("items/nvg_off.wav");
PRECACHE_SOUND("items/equip_nvg.wav");
PRECACHE_SOUND("weapons/c4_beep1.wav");
PRECACHE_SOUND("weapons/c4_beep2.wav");
PRECACHE_SOUND("weapons/c4_beep3.wav");
PRECACHE_SOUND("weapons/c4_beep4.wav");
PRECACHE_SOUND("weapons/c4_beep5.wav");
PRECACHE_SOUND("weapons/c4_explode1.wav");
PRECACHE_SOUND("weapons/c4_plant.wav");
PRECACHE_SOUND("weapons/c4_disarm.wav");
PRECACHE_SOUND("weapons/c4_disarmed.wav");
PRECACHE_SOUND("weapons/explode3.wav");
PRECACHE_SOUND("weapons/explode4.wav");
PRECACHE_SOUND("weapons/explode5.wav");
PRECACHE_SOUND("player/sprayer.wav");
PRECACHE_SOUND("player/pl_fallpain2.wav");
PRECACHE_SOUND("player/pl_fallpain3.wav");
PRECACHE_SOUND("player/pl_snow1.wav");
PRECACHE_SOUND("player/pl_snow2.wav");
PRECACHE_SOUND("player/pl_snow3.wav");
PRECACHE_SOUND("player/pl_snow4.wav");
PRECACHE_SOUND("player/pl_snow5.wav");
PRECACHE_SOUND("player/pl_snow6.wav");
PRECACHE_SOUND("player/pl_step1.wav");
PRECACHE_SOUND("player/pl_step2.wav");
PRECACHE_SOUND("player/pl_step3.wav");
PRECACHE_SOUND("player/pl_step4.wav");
PRECACHE_SOUND("common/npc_step1.wav");
PRECACHE_SOUND("common/npc_step2.wav");
PRECACHE_SOUND("common/npc_step3.wav");
PRECACHE_SOUND("common/npc_step4.wav");
PRECACHE_SOUND("player/pl_metal1.wav");
PRECACHE_SOUND("player/pl_metal2.wav");
PRECACHE_SOUND("player/pl_metal3.wav");
PRECACHE_SOUND("player/pl_metal4.wav");
PRECACHE_SOUND("player/pl_dirt1.wav");
PRECACHE_SOUND("player/pl_dirt2.wav");
PRECACHE_SOUND("player/pl_dirt3.wav");
PRECACHE_SOUND("player/pl_dirt4.wav");
PRECACHE_SOUND("player/pl_duct1.wav");
PRECACHE_SOUND("player/pl_duct2.wav");
PRECACHE_SOUND("player/pl_duct3.wav");
PRECACHE_SOUND("player/pl_duct4.wav");
PRECACHE_SOUND("player/pl_grate1.wav");
PRECACHE_SOUND("player/pl_grate2.wav");
PRECACHE_SOUND("player/pl_grate3.wav");
PRECACHE_SOUND("player/pl_grate4.wav");
PRECACHE_SOUND("player/pl_slosh1.wav");
PRECACHE_SOUND("player/pl_slosh2.wav");
PRECACHE_SOUND("player/pl_slosh3.wav");
PRECACHE_SOUND("player/pl_slosh4.wav");
PRECACHE_SOUND("player/pl_tile1.wav");
PRECACHE_SOUND("player/pl_tile2.wav");
PRECACHE_SOUND("player/pl_tile3.wav");
PRECACHE_SOUND("player/pl_tile4.wav");
PRECACHE_SOUND("player/pl_tile5.wav");
PRECACHE_SOUND("player/pl_swim1.wav");
PRECACHE_SOUND("player/pl_swim2.wav");
PRECACHE_SOUND("player/pl_swim3.wav");
PRECACHE_SOUND("player/pl_swim4.wav");
PRECACHE_SOUND("player/pl_ladder1.wav");
PRECACHE_SOUND("player/pl_ladder2.wav");
PRECACHE_SOUND("player/pl_ladder3.wav");
PRECACHE_SOUND("player/pl_ladder4.wav");
PRECACHE_SOUND("player/pl_wade1.wav");
PRECACHE_SOUND("player/pl_wade2.wav");
PRECACHE_SOUND("player/pl_wade3.wav");
PRECACHE_SOUND("player/pl_wade4.wav");
PRECACHE_SOUND("debris/wood1.wav");
PRECACHE_SOUND("debris/wood2.wav");
PRECACHE_SOUND("debris/wood3.wav");
PRECACHE_SOUND("plats/train_use1.wav");
PRECACHE_SOUND("plats/vehicle_ignition.wav");
PRECACHE_SOUND("buttons/spark5.wav");
PRECACHE_SOUND("buttons/spark6.wav");
PRECACHE_SOUND("debris/glass1.wav");
PRECACHE_SOUND("debris/glass2.wav");
PRECACHE_SOUND("debris/glass3.wav");
PRECACHE_SOUND("items/flashlight1.wav");
PRECACHE_SOUND("items/flashlight1.wav");
PRECACHE_SOUND("common/bodysplat.wav");
PRECACHE_SOUND("player/pl_pain2.wav");
PRECACHE_SOUND("player/pl_pain4.wav");
PRECACHE_SOUND("player/pl_pain5.wav");
PRECACHE_SOUND("player/pl_pain6.wav");
PRECACHE_SOUND("player/pl_pain7.wav");
PlayerZombie_Precache();
PlayerModel_Precache();
if (g_bIsCzeroGame)
{
for (i = FirstCustomSkin; i <= LastCustomSkin; ++i)
{
const char *fname = TheBotProfiles->GetCustomSkinFname(i);
if (!fname)
break;
PRECACHE_MODEL((char *)fname);
}
}
PRECACHE_MODEL("models/p_ak47.mdl");
PRECACHE_MODEL("models/p_aug.mdl");
PRECACHE_MODEL("models/p_awp.mdl");
PRECACHE_MODEL("models/p_c4.mdl");
PRECACHE_MODEL("models/w_c4.mdl");
PRECACHE_MODEL("models/p_deagle.mdl");
PRECACHE_MODEL("models/p_flashbang.mdl");
PRECACHE_MODEL("models/p_hegrenade.mdl");
PRECACHE_MODEL("models/p_glock18.mdl");
PRECACHE_MODEL("models/p_p228.mdl");
PRECACHE_MODEL("models/p_smokegrenade.mdl");
PRECACHE_MODEL("models/p_usp.mdl");
PRECACHE_MODEL("models/p_fiveseven.mdl");
PRECACHE_MODEL("models/p_knife.mdl");
PRECACHE_MODEL("models/w_flashbang.mdl");
PRECACHE_MODEL("models/w_hegrenade.mdl");
PRECACHE_MODEL("models/p_sg550.mdl");
PRECACHE_MODEL("models/p_g3sg1.mdl");
PRECACHE_MODEL("models/p_m249.mdl");
PRECACHE_MODEL("models/p_m3.mdl");
PRECACHE_MODEL("models/p_m4a1.mdl");
PRECACHE_MODEL("models/p_mac10.mdl");
PRECACHE_MODEL("models/p_mp5.mdl");
PRECACHE_MODEL("models/p_ump45.mdl");
PRECACHE_MODEL("models/p_p90.mdl");
PRECACHE_MODEL("models/p_scout.mdl");
PRECACHE_MODEL("models/p_sg552.mdl");
PRECACHE_MODEL("models/w_smokegrenade.mdl");
PRECACHE_MODEL("models/p_tmp.mdl");
PRECACHE_MODEL("models/p_elite.mdl");
PRECACHE_MODEL("models/p_xm1014.mdl");
PRECACHE_MODEL("models/p_galil.mdl");
PRECACHE_MODEL("models/p_famas.mdl");
#ifdef ENABLE_SHIELD
PRECACHE_MODEL("models/shield/p_shield_deagle.mdl");
PRECACHE_MODEL("models/shield/p_shield_flashbang.mdl");
PRECACHE_MODEL("models/shield/p_shield_hegrenade.mdl");
PRECACHE_MODEL("models/shield/p_shield_glock18.mdl");
PRECACHE_MODEL("models/shield/p_shield_p228.mdl");
PRECACHE_MODEL("models/shield/p_shield_smokegrenade.mdl");
PRECACHE_MODEL("models/shield/p_shield_usp.mdl");
PRECACHE_MODEL("models/shield/p_shield_fiveseven.mdl");
PRECACHE_MODEL("models/shield/p_shield_knife.mdl");
PRECACHE_MODEL("models/p_shield.mdl");
PRECACHE_MODEL("models/w_shield.mdl");
#endif
Vector temp = g_vecZero;
Vector vMin = Vector(-38, -24, -41);
Vector vMax = Vector(38, 24, 41);
PlayerModel_ForceUnmodified(vMin, vMax);
if (g_bIsCzeroGame)
{
for (i = FirstCustomSkin; i <= LastCustomSkin; ++i)
{
const char *fname = TheBotProfiles->GetCustomSkinFname(i);
if (!fname)
break;
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds_if_avail, (float *)&vMin, (float *)&vMax, fname);
}
}
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/black_smoke1.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/black_smoke2.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/black_smoke3.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/black_smoke4.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/fast_wallpuff1.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/smokepuff.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/gas_puff_01.spr");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_nw.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_ne.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_sw.tga");
if (g_bIsCzeroGame)
{
vMin = Vector(-13, -6, -22);
vMax = Vector(13, 6, 22);
}
else
{
vMin = Vector(-12, -6, -22);
vMax = Vector(12, 6, 22);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_deagle.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_p228.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_elite.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_usp.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_fiveseven.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_glock18.mdl");
if (g_bIsCzeroGame)
{
vMin = Vector(-26, -19, -21);
vMax = Vector(26, 23, 21);
}
else
{
vMin = Vector(-25, -19, -21);
vMax = Vector(25, 23, 21);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_xm1014.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_m3.mdl");
if (g_bIsCzeroGame)
{
vMin = Vector(-23, -9, -20);
vMax = Vector(23, 17, 20);
}
else
{
vMin = Vector(-23, -8, -20);
vMax = Vector(23, 8, 20);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_mac10.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_mp5.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_ump45.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_tmp.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_p90.mdl");
if (g_bIsCzeroGame)
{
vMin = Vector(-38, -33, -22);
vMax = Vector(38, 15, 35);
}
else
{
vMin = Vector(-31, -8, -21);
vMax = Vector(31, 12, 31);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_ak47.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_aug.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_awp.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_g3sg1.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_sg550.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_m4a1.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_scout.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_sg552.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_famas.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_galil.mdl");
if (g_bIsCzeroGame)
{
vMin = Vector(-30, -10, -20);
vMax = Vector(30, 11, 20);
}
else
{
vMin = Vector(-24, -10, -20);
vMax = Vector(25, 10, 20);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_m249.mdl");
vMin = Vector(-7, -7, -15);
vMax = Vector(7, 7, 15);
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_c4.mdl");
vMin = Vector(-4, -8, -3);
vMax = Vector(3, 7, 3);
if (g_bIsCzeroGame)
{
vMin = Vector(-17, -8, -3);
vMax = Vector(17, 7, 3);
}
else
{
vMin = Vector(-4, -8, -3);
vMax = Vector(3, 7, 3);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/w_c4.mdl");
if (g_bIsCzeroGame)
{
vMin = Vector(-7, -3, -18);
vMax = Vector(7, 2, 18);
}
else
{
vMin = Vector(-7, -2, -18);
vMax = Vector(7, 2, 18);
}
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_flashbang.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_hegrenade.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_smokegrenade.mdl");
if (g_bIsCzeroGame)
vMin = Vector(-5, -5, -7);
else
vMin = Vector(-5, -5, -5);
vMax = Vector(5, 5, 14);
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/w_flashbang.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/w_hegrenade.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/w_smokegrenade.mdl");
vMin = Vector(-7, -11, -18);
vMax = Vector(7, 6, 18);
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/p_knife.mdl");
if (g_bIsCzeroGame)
{
vMin = Vector(-21, -25, -54);
vMax = Vector(21, 23, 24);
}
else
{
vMin = Vector(-16, -8, -54);
vMax = Vector(16, 6, 24);
}
#ifdef ENABLE_SHIELD
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_deagle.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_fiveseven.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_flashbang.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_glock18.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_hegrenade.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_knife.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_p228.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_smokegrenade.mdl");
ENGINE_FORCE_UNMODIFIED(force_model_specifybounds, (float *)&vMin, (float *)&vMax, "models/shield/p_shield_usp.mdl");
#endif
PRECACHE_SOUND("common/wpn_hudoff.wav");
PRECACHE_SOUND("common/wpn_hudon.wav");
PRECACHE_SOUND("common/wpn_moveselect.wav");
PRECACHE_SOUND("common/wpn_select.wav");
PRECACHE_SOUND("common/wpn_denyselect.wav");
PRECACHE_SOUND("player/geiger6.wav");
PRECACHE_SOUND("player/geiger5.wav");
PRECACHE_SOUND("player/geiger4.wav");
PRECACHE_SOUND("player/geiger3.wav");
PRECACHE_SOUND("player/geiger2.wav");
PRECACHE_SOUND("player/geiger1.wav");
if (giPrecacheGrunt)
UTIL_PrecacheOther("enemy_terrorist");
g_iShadowSprite = PRECACHE_MODEL("sprites/shadow_circle.spr");
PRECACHE_MODEL("sprites/wall_puff1.spr");
PRECACHE_MODEL("sprites/wall_puff2.spr");
PRECACHE_MODEL("sprites/wall_puff3.spr");
PRECACHE_MODEL("sprites/wall_puff4.spr");
PRECACHE_MODEL("sprites/black_smoke1.spr");
PRECACHE_MODEL("sprites/black_smoke2.spr");
PRECACHE_MODEL("sprites/black_smoke3.spr");
PRECACHE_MODEL("sprites/black_smoke4.spr");
PRECACHE_MODEL("sprites/gas_puff_01.spr");
PRECACHE_MODEL("sprites/fast_wallpuff1.spr");
PRECACHE_MODEL("sprites/pistol_smoke1.spr");
PRECACHE_MODEL("sprites/pistol_smoke2.spr");
PRECACHE_MODEL("sprites/rifle_smoke1.spr");
PRECACHE_MODEL("sprites/rifle_smoke2.spr");
PRECACHE_MODEL("sprites/rifle_smoke3.spr");
PRECACHE_GENERIC("sprites/scope_arc.tga");
PRECACHE_GENERIC("sprites/scope_arc_nw.tga");
PRECACHE_GENERIC("sprites/scope_arc_ne.tga");
PRECACHE_GENERIC("sprites/scope_arc_sw.tga");
m_usResetDecals = g_engfuncs.pfnPrecacheEvent(1, "events/decal_reset.sc");
/*Vector temp = g_vecZero;
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_nw.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_ne.tga");
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_sw.tga");
PRECACHE_GENERIC("sprites/scope_arc.tga");
PRECACHE_GENERIC("sprites/scope_arc_nw.tga");
PRECACHE_GENERIC("sprites/scope_arc_ne.tga");
PRECACHE_GENERIC("sprites/scope_arc_sw.tga");
m_usResetDecals = g_engfuncs.pfnPrecacheEvent(1, "events/decal_reset.sc");*/
}
const char *EXT_FUNC GetGameDescription()
{
if (g_bIsCzeroGame)
return "Condition Zero";
return "Counter-Strike";
}
void EXT_FUNC Sys_Error(const char *error_string)
{
;
}
void EXT_FUNC PlayerCustomization(edict_t *pEntity, customization_t *pCust)
{
CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity);
if (!pPlayer)
{
ALERT(at_console, "PlayerCustomization: Couldn't get player!\n");
return;
}
if (!pCust)
{
ALERT(at_console, "PlayerCustomization: NULL customization!\n");
return;
}
switch (pCust->resource.type)
{
case t_decal:
pPlayer->SetCustomDecalFrames(pCust->nUserData2);
break;
case t_sound:
case t_skin:
case t_model:
break;
default:
ALERT(at_console, "PlayerCustomization: Unknown customization type!\n");
break;
}
}
void EXT_FUNC SpectatorConnect(edict_t *pEntity)
{
CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity);
if (pPlayer)
{
pPlayer->SpectatorConnect();
}
}
void EXT_FUNC SpectatorDisconnect(edict_t *pEntity)
{
CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity);
if (pPlayer)
{
pPlayer->SpectatorDisconnect();
}
}
void EXT_FUNC SpectatorThink(edict_t *pEntity)
{
CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity);
if (pPlayer)
{
pPlayer->SpectatorThink();
}
}
void EXT_FUNC SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas)
{
edict_t *pView = pClient;
// Find the client's PVS
if (pViewEntity)
{
pView = pViewEntity;
}
if (pClient->v.flags & FL_PROXY)
{
*pvs = NULL; // the spectator proxy sees
*pas = NULL; // and hears everything
return;
}
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(CBasePlayer::Instance(pClient));
if (pPlayer != NULL && pPlayer->pev->iuser2 && pPlayer->m_hObserverTarget)
{
if (pPlayer->m_afPhysicsFlags & PFLAG_OBSERVER)
{
pView = pPlayer->m_hObserverTarget->edict();
UTIL_SetOrigin(pPlayer->pev, pPlayer->m_hObserverTarget->pev->origin);
}
}
Vector org = pView->v.origin + pView->v.view_ofs;
if (pView->v.flags & FL_DUCKING)
{
org = org + (VEC_HULL_MIN - VEC_DUCK_HULL_MIN);
}
*pvs = ENGINE_SET_PVS((float *)&org);
*pas = ENGINE_SET_PAS((float *)&org);
}
void ResetPlayerPVS(edict_t *client, int clientnum)
{
PLAYERPVSSTATUS *pvs = &g_PVSStatus[clientnum];
Q_memset(pvs, 0, sizeof(*pvs));
pvs->headnode = client->headnode;
pvs->num_leafs = client->num_leafs;
Q_memcpy(pvs->leafnums, client->leafnums, sizeof(pvs->leafnums));
}
bool CheckPlayerPVSLeafChanged(edict_t *client, int clientnum)
{
PLAYERPVSSTATUS *pvs = &g_PVSStatus[clientnum];
if (pvs->headnode != client->headnode || pvs->num_leafs != client->num_leafs)
return true;
for (int i = 0; i < pvs->num_leafs; ++i)
{
if (client->leafnums[i] != pvs->leafnums[i])
return true;
}
return false;
}
void MarkEntityInPVS(int clientnum, int entitynum, time_point_t time, bool inpvs)
{
PLAYERPVSSTATUS *pvs;
ENTITYPVSSTATUS *es;
pvs = &g_PVSStatus[clientnum];
es = &pvs->m_Status[entitynum];
if (inpvs)
es->m_fTimeEnteredPVS = time;
else
es->m_fTimeEnteredPVS = {};
}
bool CheckEntityRecentlyInPVS(int clientnum, int entitynum, time_point_t currenttime)
{
PLAYERPVSSTATUS *pvs;
ENTITYPVSSTATUS *es;
pvs = &g_PVSStatus[clientnum];
es = &pvs->m_Status[entitynum];
if (es->m_fTimeEnteredPVS + 1.0s >= currenttime)
{
return true;
}
return false;
}
int EXT_FUNC AddToFullPack (struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
{
if ((ent->v.effects & EF_NODRAW) == EF_NODRAW && ent != host)
return 0;
if (!ent->v.modelindex || !STRING (ent->v.model))
return 0;
if ((ent->v.flags & FL_SPECTATOR) == FL_SPECTATOR && ent != host)
return 0;
int i;
int hostnum = ENTINDEX (host) - 1;
if (CheckPlayerPVSLeafChanged (host, hostnum))
ResetPlayerPVS (host, hostnum);
if (ent != host)
{
if (!CheckEntityRecentlyInPVS (hostnum, e, gpGlobals->time))
{
if (!ENGINE_CHECK_VISIBILITY (ent, pSet))
{
MarkEntityInPVS (hostnum, e, invalid_time_point, false);
return 0;
}
MarkEntityInPVS (hostnum, e, gpGlobals->time, true);
}
}
if ((ent->v.flags & FL_SKIPLOCALHOST) == FL_SKIPLOCALHOST && (hostflags & 1) && ent->v.owner == host)
return 0;
if (host->v.groupinfo)
{
UTIL_SetGroupTrace (host->v.groupinfo, GROUP_OP_AND);
if (ent->v.groupinfo)
{
if (g_groupop == GROUP_OP_AND)
{
if (!(ent->v.groupinfo & host->v.groupinfo))
return 0;
}
else if (g_groupop == GROUP_OP_NAND)
{
if (ent->v.groupinfo & host->v.groupinfo)
return 0;
}
}
UTIL_UnsetGroupTrace ();
}
Q_memset (state, 0, sizeof (entity_state_t));
state->number = e;
state->entityType = ENTITY_NORMAL;
if (ent->v.flags & FL_CUSTOMENTITY)
state->entityType = ENTITY_BEAM;
state->animtime = (int)(1000.0 * ent->v.animtime.time_since_epoch().count()) / 1000.0;
Q_memcpy (state->origin, ent->v.origin, sizeof (float) * 3);
Q_memcpy (state->angles, ent->v.angles, sizeof (float) * 3);
Q_memcpy (state->mins, ent->v.mins, sizeof (float) * 3);
Q_memcpy (state->maxs, ent->v.maxs, sizeof (float) * 3);
Q_memcpy (state->startpos, ent->v.startpos, sizeof (float) * 3);
Q_memcpy (state->endpos, ent->v.endpos, sizeof (float) * 3);
state->impacttime = ent->v.impacttime.time_since_epoch() / 1s;
state->starttime = ent->v.starttime.time_since_epoch() / 1s;
state->modelindex = ent->v.modelindex;
state->frame = ent->v.frame;
state->skin = ent->v.skin;
state->effects = ent->v.effects;
if (!player && ent->v.animtime > time_point_t{} && !ent->v.velocity.x && !ent->v.velocity.y && !ent->v.velocity.z)
state->eflags |= EFLAG_SLERP;
state->scale = ent->v.scale;
state->solid = ent->v.solid;
state->colormap = ent->v.colormap;
state->movetype = ent->v.movetype;
state->sequence = ent->v.sequence;
state->framerate = ent->v.framerate;
state->body = ent->v.body;
for (i = 0; i < 4; ++i)
state->controller[i] = ent->v.controller[i];
for (i = 0; i < 2; ++i)
state->blending[i] = ent->v.blending[i];
state->rendermode = ent->v.rendermode;
state->renderamt = (int)ent->v.renderamt;
state->renderfx = ent->v.renderfx;
state->rendercolor.r = (byte)ent->v.rendercolor.x;
state->rendercolor.g = (byte)ent->v.rendercolor.y;
state->rendercolor.b = (byte)ent->v.rendercolor.z;
state->aiment = 0;
if (ent->v.aiment)
state->aiment = ENTINDEX (ent->v.aiment);
state->owner = 0;
if (ent->v.owner)
{
int owner = ENTINDEX (ent->v.owner);
if (owner >= 1 && owner <= gpGlobals->maxClients)
state->owner = owner;
}
if (player)
{
Q_memcpy (state->basevelocity, ent->v.basevelocity, sizeof (float) * 3);
state->weaponmodel = MODEL_INDEX (STRING (ent->v.weaponmodel));
state->gaitsequence = ent->v.gaitsequence;
state->spectator = (ent->v.flags & FL_SPECTATOR);
state->friction = ent->v.friction;
state->gravity = ent->v.gravity;
state->usehull = (ent->v.flags & FL_DUCKING) ? 1 : 0;
state->health = (int)ent->v.health;
}
else
state->playerclass = ent->v.playerclass;
state->iuser4 = ent->v.iuser4;
g_pModRunning->AddToFullPack_Post(state, e, ent, host, hostflags, player, pSet);
return 1;
}
// Creates baselines used for network encoding, especially for player data since players are not spawned until connect time.
void EXT_FUNC CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, Vector player_mins, Vector player_maxs)
{
baseline->origin = entity->v.origin;
baseline->angles = entity->v.angles;
baseline->frame = entity->v.frame;
baseline->skin = (short)entity->v.skin;
// render information
baseline->rendermode = (byte)entity->v.rendermode;
baseline->renderamt = (byte)entity->v.renderamt;
baseline->rendercolor.r = (byte)entity->v.rendercolor.x;
baseline->rendercolor.g = (byte)entity->v.rendercolor.y;
baseline->rendercolor.b = (byte)entity->v.rendercolor.z;
baseline->renderfx = (byte)entity->v.renderfx;
if (player)
{
baseline->mins = player_mins;
baseline->maxs = player_maxs;
baseline->colormap = eindex;
baseline->modelindex = playermodelindex;
baseline->friction = 1.0;
baseline->movetype = MOVETYPE_WALK;
baseline->solid = SOLID_SLIDEBOX;
baseline->scale = entity->v.scale;
baseline->framerate = 1.0;
baseline->gravity = 1.0;
}
else
{
baseline->mins = entity->v.mins;
baseline->maxs = entity->v.maxs;
baseline->colormap = 0;
baseline->modelindex = entity->v.modelindex;
baseline->movetype = entity->v.movetype;
baseline->scale = entity->v.scale;
baseline->solid = entity->v.solid;
baseline->framerate = entity->v.framerate;
baseline->gravity = entity->v.gravity;
}
}
void Entity_FieldInit(struct delta_s *pFields)
{
entity_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD(pFields, entity_field_alias[ FIELD_ORIGIN0 ].name);
entity_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD(pFields, entity_field_alias[ FIELD_ORIGIN1 ].name);
entity_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD(pFields, entity_field_alias[ FIELD_ORIGIN2 ].name);
entity_field_alias[ FIELD_ANGLES0 ].field = DELTA_FINDFIELD(pFields, entity_field_alias[ FIELD_ANGLES0 ].name);
entity_field_alias[ FIELD_ANGLES1 ].field = DELTA_FINDFIELD(pFields, entity_field_alias[ FIELD_ANGLES1 ].name);
entity_field_alias[ FIELD_ANGLES2 ].field = DELTA_FINDFIELD(pFields, entity_field_alias[ FIELD_ANGLES2 ].name);
}
// Callback for sending entity_state_t info over network.
void Entity_Encode(struct delta_s *pFields, const unsigned char *from, const unsigned char *to)
{
entity_state_t *f, *t;
int localplayer = 0;
static int initialized = 0;
if (!initialized)
{
Entity_FieldInit(pFields);
initialized = 1;
}
f = (entity_state_t *)from;
t = (entity_state_t *)to;
// Never send origin to local player, it's sent with more resolution in clientdata_t structure
localplayer = (t->number - 1) == ENGINE_CURRENT_PLAYER();
if (localplayer)
{
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
}
if (t->impacttime != 0 && t->starttime != 0)
{
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ANGLES0 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ANGLES1 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ANGLES2 ].field);
}
if (t->movetype == MOVETYPE_FOLLOW && t->aiment != 0)
{
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
}
else if (t->aiment != f->aiment)
{
DELTA_SETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_SETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_SETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
}
}
void Player_FieldInit(struct delta_s *pFields)
{
player_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD(pFields, player_field_alias[ FIELD_ORIGIN0 ].name);
player_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD(pFields, player_field_alias[ FIELD_ORIGIN1 ].name);
player_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD(pFields, player_field_alias[ FIELD_ORIGIN2 ].name);
}
// Callback for sending entity_state_t for players info over network.
void Player_Encode(struct delta_s *pFields, const unsigned char *from, const unsigned char *to)
{
entity_state_t *f, *t;
int localplayer = 0;
static int initialized = 0;
if (!initialized)
{
Player_FieldInit(pFields);
initialized = 1;
}
f = (entity_state_t *)from;
t = (entity_state_t *)to;
// Never send origin to local player, it's sent with more resolution in clientdata_t structure
localplayer = (t->number - 1) == ENGINE_CURRENT_PLAYER();
if (localplayer)
{
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
}
if (t->movetype == MOVETYPE_FOLLOW && t->aiment != 0)
{
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_UNSETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
}
else if (t->aiment != f->aiment)
{
DELTA_SETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN0 ].field);
DELTA_SETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN1 ].field);
DELTA_SETBYINDEX(pFields, entity_field_alias[ FIELD_ORIGIN2 ].field);
}
}
void Custom_Entity_FieldInit(delta_s *pFields)
{
custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].name);
custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].name);
custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].name);
custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].name);
custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].name);
custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].name);
custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].name);
custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].name);
custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field = DELTA_FINDFIELD(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].name);
}
// Callback for sending entity_state_t info ( for custom entities ) over network.
void Custom_Encode(struct delta_s *pFields, const unsigned char *from, const unsigned char *to)
{
entity_state_t *f, *t;
int beamType;
static int initialized = 0;
if (!initialized)
{
Custom_Entity_FieldInit(pFields);
initialized = 1;
}
f = (entity_state_t *)from;
t = (entity_state_t *)to;
beamType = t->rendermode & 0x0F;
if (beamType != BEAM_POINTS)
{
if (beamType != BEAM_ENTPOINT)
{
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field);
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field);
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field);
}
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field);
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field);
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field);
}
if (beamType != BEAM_ENTS && beamType != BEAM_ENTPOINT)
{
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field);
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field);
}
// animtime is compared by rounding first
// see if we really shouldn't actually send it
if ((int)f->animtime == (int)t->animtime)
{
DELTA_UNSETBYINDEX(pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field);
}
}
void EXT_FUNC RegisterEncoders()
{
DELTA_ADDENCODER("Entity_Encode", Entity_Encode);
DELTA_ADDENCODER("Custom_Encode", Custom_Encode);
DELTA_ADDENCODER("Player_Encode", Player_Encode);
}
int EXT_FUNC GetWeaponData(edict_s *player, struct weapon_data_s *info)
{
entvars_t *pev = &player->v;
CBasePlayer *pl = dynamic_cast<CBasePlayer *>(CBasePlayer::Instance(pev));
Q_memset(info, 0, sizeof(weapon_data_t) * MAX_WEAPONS);
if (!pl)
{
return 1;
}
for (int i = 0; i < MAX_ITEM_TYPES; ++i)
{
CBasePlayerItem *pPlayerItem = pl->m_rgpPlayerItems[i];
while (pPlayerItem != NULL)
{
CBasePlayerWeapon *gun = dynamic_cast<CBasePlayerWeapon *>(pPlayerItem->GetWeaponPtr());
if (gun != NULL && gun->UseDecrement())
{
ItemInfo II;
Q_memset(&II, 0, sizeof(II));
gun->GetItemInfo(&II);
if (II.iId >= 0 && II.iId < MAX_WEAPONS)
{
weapon_data_t *item = &info[II.iId];
item->m_iId = II.iId;
item->m_iClip = gun->m_iClip;
item->m_flTimeWeaponIdle = max(gun->m_flTimeWeaponIdle, -0.001s) / 1s;
item->m_flNextPrimaryAttack = max(gun->m_flNextPrimaryAttack, -0.001s) / 1s;
item->m_flNextSecondaryAttack = max(gun->m_flNextSecondaryAttack, -0.001s) / 1s;
item->m_flNextReload = max(gun->m_flNextReload, -0.001s) / 1s;
item->m_fInReload = gun->m_fInReload;
item->m_fInSpecialReload = gun->m_fInSpecialReload;
item->m_fInZoom = gun->m_iShotsFired;
item->m_fAimedDamage = gun->m_flLastFire.time_since_epoch() / 1s;
item->m_iWeaponState = gun->m_iWeaponState;
item->fuser2 = gun->m_flStartThrow.time_since_epoch() / 1s;
item->fuser3 = gun->m_flReleaseThrow.time_since_epoch() / 1s;
item->iuser1 = gun->m_iSwing;
}
}
pPlayerItem = pPlayerItem->m_pNext;
}
}
return 1;
}
void EXT_FUNC UpdateClientData(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
{
if (!ent || !ent->pvPrivateData)
{
return;
}
entvars_t *pevOrg = NULL;
entvars_t *pev = const_cast<entvars_t *>(&ent->v);
CBasePlayer *pl = dynamic_cast<CBasePlayer *>(CBasePlayer::Instance(pev));
if (pl != NULL && pl->pev->iuser1 == OBS_IN_EYE && pl->m_hObserverTarget)
{
pevOrg = pev;
pev = pl->m_hObserverTarget->pev;
pl = dynamic_cast<CBasePlayer *>(CBasePlayer::Instance(pev));
}
pl->m_pModStrategy->UpdateClientData(sendweapons, cd, pevOrg);
}
void EXT_FUNC CmdStart(const edict_t *player, struct usercmd_s *cmd, unsigned int random_seed)
{
entvars_t *pev = const_cast<entvars_t *>(&player->v);
CBasePlayer *pl = dynamic_cast<CBasePlayer *>(CBasePlayer::Instance(pev));
if (pl != NULL)
{
/*
if (pl->pev->groupinfo)
{
UTIL_SetGroupTrace(pl->pev->groupinfo, GROUP_OP_AND);
}
pl->random_seed = random_seed;
*/
// moved to player_mod_strategy
pl->m_pModStrategy->CmdStart(cmd, random_seed);
}
}
void EXT_FUNC CmdEnd(const edict_t *player)
{
entvars_t *pev = const_cast<entvars_t *>(&player->v);
CBasePlayer *pl = dynamic_cast<CBasePlayer *>(CBasePlayer::Instance(pev));
if (pl != NULL)
{
if (pl->pev->groupinfo)
UTIL_UnsetGroupTrace();
if (pev->flags & FL_DUCKING)
UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX);
}
}
int EXT_FUNC ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size)
{
// Parse stuff from args
int max_buffer_size = *response_buffer_size;
// Zero it out since we aren't going to respond.
// If we wanted to response, we'd write data into response_buffer
*response_buffer_size = 0;
// Since we don't listen for anything here, just respond that it's a bogus message
// If we didn't reject the message, we'd return 1 for success instead.
return 0;
}
int EXT_FUNC GetHullBounds(int hullnumber, float *mins, float *maxs)
{
switch (hullnumber)
{
case 0: // Normal player
VEC_HULL_MIN.CopyToArray(mins);
VEC_HULL_MAX.CopyToArray(maxs);
return TRUE;
case 1: // Crouched player
VEC_DUCK_HULL_MIN.CopyToArray(mins);
VEC_DUCK_HULL_MAX.CopyToArray(maxs);
return TRUE;
case 2: // Point based hull
Vector(0, 0, 0).CopyToArray(mins);
Vector(0, 0, 0).CopyToArray(maxs);
return TRUE;
default:
return FALSE;
}
return hullnumber < 3;
}
// Create pseudo-baselines for items that aren't placed in the map at spawn time, but which are likely
// to be created during play ( e.g., grenades, ammo packs, projectiles, corpses, etc. )
void EXT_FUNC CreateInstancedBaselines()
{
#if 0
int iret = 0;
entity_state_t state;
Q_memset(&state, 0, sizeof(state));
// Create any additional baselines here for things like grendates, etc.
// iret = ENGINE_INSTANCE_BASELINE(pc->pev->classname, &state);
// Destroy objects.
// UTIL_Remove(pc);
#endif
}
int EXT_FUNC InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message)
{
// Server doesn't care?
if (CVAR_GET_FLOAT("mp_consistency") != 1)
return 0;
// Default behavior is to kick the player
Q_sprintf(disconnect_message, "Server is enforcing file consistency for %s\n", filename);
// Kick now with specified disconnect message.
return 1;
}
// The game .dll should return 1 if lag compensation should be allowed ( could also just set
// the sv_unlag cvar.
// Most games right now should return 0, until client-side weapon prediction code is written
// and tested for them ( note you can predict weapons, but not do lag compensation, too,
// if you want.
int EXT_FUNC AllowLagCompensation()
{
return 1;
}
} // namespace sv;
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。