Refactoring

This commit is contained in:
s1lentq 2015-09-30 06:49:22 +06:00
parent 0aa8ac73a6
commit ed1dd85d6e
4 changed files with 15797 additions and 15290 deletions

View File

@ -214,6 +214,8 @@ void respawn(entvars_t *pev, BOOL fCopyCorpse)
} }
} }
// Suicide...
/* <48013> ../cstrike/dlls/client.cpp:347 */ /* <48013> ../cstrike/dlls/client.cpp:347 */
void ClientKill(edict_t *pEntity) void ClientKill(edict_t *pEntity)
{ {
@ -227,10 +229,16 @@ void ClientKill(edict_t *pEntity)
if (pl->m_iJoiningState != JOINED) if (pl->m_iJoiningState != JOINED)
return; return;
if (gpGlobals->time >= pl->m_fNextSuicideTime) // prevent suiciding too often
{ if (pl->m_fNextSuicideTime > gpGlobals->time)
return;
pl->m_LastHitGroup = 0; pl->m_LastHitGroup = 0;
// don't let them suicide for 5 seconds after suiciding
pl->m_fNextSuicideTime = gpGlobals->time + 1; pl->m_fNextSuicideTime = gpGlobals->time + 1;
// have the player kill themself
pEntity->v.health = 0; pEntity->v.health = 0;
pl->Killed(pev, GIB_NEVER); pl->Killed(pev, GIB_NEVER);
@ -239,7 +247,6 @@ void ClientKill(edict_t *pEntity)
mp->m_iConsecutiveVIP = 10; mp->m_iConsecutiveVIP = 10;
} }
} }
}
/* <47a8a> ../cstrike/dlls/client.cpp:379 */ /* <47a8a> ../cstrike/dlls/client.cpp:379 */
void ShowMenu(CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText) void ShowMenu(CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText)
@ -426,28 +433,53 @@ TeamName SelectDefaultTeam(void)
CHalfLifeMultiplay *mp = g_pGameRules; CHalfLifeMultiplay *mp = g_pGameRules;
if (mp->m_iNumTerrorist < mp->m_iNumCT) if (mp->m_iNumTerrorist < mp->m_iNumCT)
{
team = TERRORIST; team = TERRORIST;
}
else if (mp->m_iNumTerrorist > mp->m_iNumCT) else if (mp->m_iNumTerrorist > mp->m_iNumCT)
{
team = CT; team = CT;
}
else if (mp->m_iNumCTWins > mp->m_iNumTerroristWins) // Choose the team that's losing
else if (mp->m_iNumTerroristWins < mp->m_iNumCTWins)
{
team = TERRORIST; team = TERRORIST;
}
else if (mp->m_iNumCTWins < mp->m_iNumTerroristWins) else if (mp->m_iNumCTWins < mp->m_iNumTerroristWins)
{
team = CT; team = CT;
}
else else
team = RANDOM_LONG(0, 1) ? TERRORIST : CT; {
// Teams and scores are equal, pick a random team
if (RANDOM_LONG(0, 1) == 0)
{
team = CT;
}
else
{
team = TERRORIST;
}
}
if (mp->TeamFull(team)) if (mp->TeamFull(team))
{ {
// Pick the opposite team
if (team == TERRORIST) if (team == TERRORIST)
{
team = CT; team = CT;
}
else else
{
team = TERRORIST; team = TERRORIST;
}
// No choices left
if (mp->TeamFull(team)) if (mp->TeamFull(team))
{
return UNASSIGNED; return UNASSIGNED;
} }
}
return team; return team;
@ -1873,9 +1905,12 @@ void HandleMenu_ChooseAppearance(CBasePlayer *player, int slot)
player->m_iMenu = Menu_OFF; player->m_iMenu = Menu_OFF;
if (player->m_iJoiningState != JOINED) // Reset the player's state
if (player->m_iJoiningState == JOINED)
{ {
if (player->m_iJoiningState == PICKINGTEAM) mp->CheckWinConditions();
}
else if (player->m_iJoiningState == PICKINGTEAM)
{ {
player->m_iJoiningState = GETINTOGAME; player->m_iJoiningState = GETINTOGAME;
@ -1887,9 +1922,6 @@ void HandleMenu_ChooseAppearance(CBasePlayer *player, int slot)
} }
} }
} }
}
else
mp->CheckWinConditions();
player->pev->body = 0; player->pev->body = 0;
player->m_iModelName = appearance.model_id; player->m_iModelName = appearance.model_id;
@ -1897,7 +1929,7 @@ void HandleMenu_ChooseAppearance(CBasePlayer *player, int slot)
SET_CLIENT_KEY_VALUE(player->entindex(), GET_INFO_BUFFER(player->edict()), "model", appearance.model_name); SET_CLIENT_KEY_VALUE(player->entindex(), GET_INFO_BUFFER(player->edict()), "model", appearance.model_name);
player->SetNewPlayerModel(sPlayerModelFiles[ appearance.model_name_index ]); player->SetNewPlayerModel(sPlayerModelFiles[ appearance.model_name_index ]);
if (mp->m_iMapHasVIPSafetyZone == MAP_VIP_SAFETYZONE_INIT) if (mp->m_iMapHasVIPSafetyZone == MAP_VIP_SAFETYZONE_UNINITIALIZED)
{ {
if ((UTIL_FindEntityByClassname(NULL, "func_vip_safetyzone")) != NULL) if ((UTIL_FindEntityByClassname(NULL, "func_vip_safetyzone")) != NULL)
mp->m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_YES; mp->m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_YES;
@ -1914,15 +1946,21 @@ void HandleMenu_ChooseAppearance(CBasePlayer *player, int slot)
} }
} }
// returns true if the selection has been handled and the player's menu
// can be closed...false if the menu should be displayed again
/* <48e4b> ../cstrike/dlls/client.cpp:2214 */ /* <48e4b> ../cstrike/dlls/client.cpp:2214 */
BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot) BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
{ {
CHalfLifeMultiplay *mp = g_pGameRules; CHalfLifeMultiplay *mp = g_pGameRules;
TeamName team = UNASSIGNED;
int oldTeam; int oldTeam;
char *szOldTeam; char *szOldTeam;
char *szNewTeam; char *szNewTeam;
const char *szName;
// If this player is a VIP, don't allow him to switch teams/appearances unless the following conditions are met :
// a) There is another TEAM_CT player who is in the queue to be a VIP
// b) This player is dead
if (player->m_bIsVIP) if (player->m_bIsVIP)
{ {
@ -1933,8 +1971,7 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
return TRUE; return TRUE;
} }
else if (g_pGameRules->IsVIPQueueEmpty())
if (g_pGameRules->IsVIPQueueEmpty())
{ {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Switch_From_VIP"); ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Switch_From_VIP");
CLIENT_COMMAND(ENT(player->pev), "slot10\n"); CLIENT_COMMAND(ENT(player->pev), "slot10\n");
@ -1943,6 +1980,8 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
} }
} }
TeamName team = UNASSIGNED;
switch (slot) switch (slot)
{ {
case MENU_SLOT_TEAM_TERRORIST: case MENU_SLOT_TEAM_TERRORIST:
@ -1964,76 +2003,60 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
} }
case MENU_SLOT_TEAM_RANDOM: case MENU_SLOT_TEAM_RANDOM:
{ {
// Attempt to auto-select a team
team = SelectDefaultTeam(); team = SelectDefaultTeam();
if (team == UNASSIGNED) if (team == UNASSIGNED)
{ {
bool madeRoom = false;
if (cv_bot_auto_vacate.value > 0.0f && !player->IsBot()) if (cv_bot_auto_vacate.value > 0.0f && !player->IsBot())
{ {
team = (RANDOM_LONG(0, 1) == 0) ? TERRORIST : CT; team = (RANDOM_LONG(0, 1) == 0) ? TERRORIST : CT;
if (UTIL_KickBotFromTeam(team)) if (!UTIL_KickBotFromTeam(team))
madeRoom = true;
else
{ {
if (team == CT) // no bots on that team, try the other
team = TERRORIST; team = (team == CT) ? TERRORIST : CT;
else
team = CT;
if (UTIL_KickBotFromTeam(team)) if (!UTIL_KickBotFromTeam(team))
{ {
madeRoom = true; // couldn't kick any bots, fail
team = UNASSIGNED;
}
} }
} }
} }
if (!madeRoom)
{
ClientPrint(player->pev, HUD_PRINTCENTER, "#All_Teams_Full");
return FALSE;
}
}
break; break;
} }
case MENU_SLOT_TEAM_SPECT: case MENU_SLOT_TEAM_SPECT:
{ {
if (!allow_spectators.value) // Prevent this is the cvar is set
{ // spectator proxy
if (!(player->pev->flags & FL_PROXY)) if (!allow_spectators.value && !(player->pev->flags & FL_PROXY))
{ {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Be_Spectator"); ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Be_Spectator");
CLIENT_COMMAND(ENT(player->pev), "slot10\n"); CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return FALSE; return FALSE;
} }
}
// are we already a spectator?
if (player->m_iTeam == SPECTATOR) if (player->m_iTeam == SPECTATOR)
{ {
return TRUE; return TRUE;
} }
if (!mp->IsFreezePeriod()) // 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->pev->deadflag == DEAD_NO) if (player->m_iTeam != UNASSIGNED && player->pev->deadflag == DEAD_NO)
{
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Be_Spectator");
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return FALSE;
}
}
if (player->m_iTeam != UNASSIGNED)
{
if (player->pev->deadflag == DEAD_NO)
{ {
ClientKill(player->edict()); ClientKill(player->edict());
// add 1 to frags to balance out the 1 subtracted for killing yourself
player->pev->frags++; player->pev->frags++;
} }
}
player->RemoveAllItems(TRUE); player->RemoveAllItems(TRUE);
player->m_bHasC4 = false; player->m_bHasC4 = false;
@ -2053,6 +2076,8 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
player->m_iTeam = SPECTATOR; player->m_iTeam = SPECTATOR;
player->m_iJoiningState = JOINED; player->m_iJoiningState = JOINED;
// Reset money
player->m_iAccount = 0; player->m_iAccount = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, player->pev); MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, player->pev);
@ -2083,36 +2108,60 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
WRITE_BYTE(1); WRITE_BYTE(1);
MESSAGE_END(); MESSAGE_END();
// do we have fadetoblack on? (need to fade their screen back in)
if (fadetoblack.value) if (fadetoblack.value)
{ {
UTIL_ScreenFade(player, Vector(0, 0, 0), 0.001, 0, 0, 0); UTIL_ScreenFade(player, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
} }
return TRUE; return TRUE;
} }
}
if (mp->TeamFull(team) && (cv_bot_auto_vacate.value <= 0.0f || player->IsBot() || !UTIL_KickBotFromTeam(team)))
{
if (team == TERRORIST)
ClientPrint(player->pev, HUD_PRINTCENTER, "#Terrorists_Full");
else else
ClientPrint(player->pev, HUD_PRINTCENTER, "#CTs_Full"); {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Cannot_Be_Spectator");
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
return FALSE; 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)) if (mp->TeamStacked(team, player->m_iTeam))
{ {
if (team == TERRORIST) // The specified team is full
ClientPrint(player->pev, HUD_PRINTCENTER, "#Too_Many_Terrorists"); ClientPrint(player->pev, HUD_PRINTCENTER, (team == TERRORIST) ? "#Too_Many_Terrorists" : "#Too_Many_CTs");
else
ClientPrint(player->pev, HUD_PRINTCENTER, "#Too_Many_CTs");
return FALSE; return FALSE;
} }
if (!player->IsBot() && team != SPECTATOR) if (team != SPECTATOR && !player->IsBot())
{ {
int humanTeam = UNASSIGNED; int humanTeam = UNASSIGNED;
@ -2127,11 +2176,7 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
if (humanTeam != UNASSIGNED && team != humanTeam) if (humanTeam != UNASSIGNED && team != humanTeam)
{ {
if (team == TERRORIST) ClientPrint(player->pev, HUD_PRINTCENTER, (team == TERRORIST) ? "#Humans_Join_Team_CT" : "#Humans_Join_Team_T");
ClientPrint(player->pev, HUD_PRINTCENTER, "#Humans_Join_Team_CT");
else
ClientPrint(player->pev, HUD_PRINTCENTER, "#Humans_Join_Team_T");
return FALSE; return FALSE;
} }
} }
@ -2141,20 +2186,22 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
if (player->pev->deadflag != DEAD_NO) if (player->pev->deadflag != DEAD_NO)
{ {
ClientPrint(player->pev, HUD_PRINTCENTER, "#Only_1_Team_Change"); ClientPrint(player->pev, HUD_PRINTCENTER, "#Only_1_Team_Change");
return FALSE; return FALSE;
} }
} }
if (player->m_iTeam == SPECTATOR && team != SPECTATOR) if (player->m_iTeam == SPECTATOR && team != SPECTATOR)
{ {
// If they're switching into spectator, setup spectator properties..
player->m_bNotKilled = true; player->m_bNotKilled = true;
player->m_iIgnoreGlobalChat = IGNOREMSG_NONE; player->m_iIgnoreGlobalChat = IGNOREMSG_NONE;
player->m_iTeamKills = 0; player->m_iTeamKills = 0;
CheckStartMoney(); CheckStartMoney();
// all players start with "mp_startmoney" bucks
player->m_iAccount = (int)startmoney.value; player->m_iAccount = (int)startmoney.value;
player->pev->solid = SOLID_NOT; player->pev->solid = SOLID_NOT;
player->pev->movetype = MOVETYPE_NOCLIP; player->pev->movetype = MOVETYPE_NOCLIP;
player->pev->effects = EF_NODRAW; player->pev->effects = EF_NODRAW;
@ -2163,10 +2210,12 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
player->pev->deadflag = DEAD_DEAD; player->pev->deadflag = DEAD_DEAD;
player->pev->velocity = g_vecZero; player->pev->velocity = g_vecZero;
player->pev->punchangle = g_vecZero; player->pev->punchangle = g_vecZero;
player->m_bHasNightVision = false; player->m_bHasNightVision = false;
player->m_iHostagesKilled = 0; player->m_iHostagesKilled = 0;
player->m_fDeadTime = 0; player->m_fDeadTime = 0;
player->has_disconnected = false; player->has_disconnected = false;
player->m_iJoiningState = GETINTOGAME; player->m_iJoiningState = GETINTOGAME;
SendItemStatus(player); SendItemStatus(player);
@ -2198,11 +2247,15 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
player->m_iMenu = Menu_ChooseAppearance; 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) if (player->pev->deadflag == DEAD_NO)
{ {
ClientKill(player->edict()); ClientKill(player->edict());
} }
// Switch their actual team...
player->m_bTeamChanged = true; player->m_bTeamChanged = true;
oldTeam = player->m_iTeam; oldTeam = player->m_iTeam;
player->m_iTeam = team; player->m_iTeam = team;
@ -2211,20 +2264,17 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
TeamChangeUpdate(player, team); TeamChangeUpdate(player, team);
if (player->pev->netname)
{
szName = STRING(player->pev->netname);
if (!szName[0])
szName = "<unconnected>";
}
else
szName = "<unconnected>";
szOldTeam = GetTeam(oldTeam); szOldTeam = GetTeam(oldTeam);
szNewTeam = GetTeam(team); szNewTeam = GetTeam(team);
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, (team == TERRORIST) ? "#Game_join_terrorist" : "#Game_join_ct", szName); // 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 UTIL_LogPrintf
( (
"\"%s<%i><%s><%s>\" joined team \"%s\"\n", "\"%s<%i><%s><%s>\" joined team \"%s\"\n",
@ -2385,12 +2435,14 @@ bool BuyGunAmmo(CBasePlayer *player, CBasePlayerItem *weapon, bool bBlinkMoney)
return false; return false;
} }
// Ensure that the weapon uses ammo
int nAmmo = weapon->PrimaryAmmoIndex(); int nAmmo = weapon->PrimaryAmmoIndex();
if (nAmmo == -1) if (nAmmo == -1)
{ {
return false; return false;
} }
// Can only buy if the player does not already have full ammo
if (player->m_rgAmmo[ nAmmo ] >= weapon->iMaxAmmo1()) if (player->m_rgAmmo[ nAmmo ] >= weapon->iMaxAmmo1())
{ {
return false; return false;
@ -2457,6 +2509,7 @@ bool BuyGunAmmo(CBasePlayer *player, CBasePlayerItem *weapon, bool bBlinkMoney)
return false; return false;
} }
// Purchase the ammo if the player has enough money
if (player->m_iAccount >= cost) if (player->m_iAccount >= cost)
{ {
player->GiveNamedItem(classname); player->GiveNamedItem(classname);
@ -2468,6 +2521,7 @@ bool BuyGunAmmo(CBasePlayer *player, CBasePlayerItem *weapon, bool bBlinkMoney)
{ {
if (g_bClientPrintEnable) if (g_bClientPrintEnable)
{ {
// Not enough money.. let the player know
ClientPrint(player->pev, HUD_PRINTCENTER, "#Not_Enough_Money"); ClientPrint(player->pev, HUD_PRINTCENTER, "#Not_Enough_Money");
BlinkAccount(player, 2); BlinkAccount(player, 2);
} }
@ -2489,6 +2543,11 @@ bool BuyAmmo(CBasePlayer *player, int nSlot, bool bBlinkMoney)
return false; 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 ]; CBasePlayerItem *pItem = player->m_rgpPlayerItems[ nSlot ];
if (player->HasShield()) if (player->HasShield())
@ -2556,17 +2615,24 @@ NOXREF int CountPlayersInServer(void)
return 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 **
/* <4958c> ../cstrike/dlls/client.cpp:2983 */ /* <4958c> ../cstrike/dlls/client.cpp:2983 */
BOOL HandleBuyAliasCommands(CBasePlayer *pPlayer, const char *pszCommand) BOOL HandleBuyAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
{ {
// Let them buy it if it's got a weapon data string.
BOOL bRetVal = FALSE; BOOL bRetVal = FALSE;
//char *pszFailItem; const char *pszFailItem = NULL;
WeaponIdType weaponID = WEAPON_NONE; WeaponIdType weaponID = WEAPON_NONE;
const char *weaponFailName = BuyAliasToWeaponID(pszCommand, weaponID); const char *weaponFailName = BuyAliasToWeaponID(pszCommand, weaponID);
if (weaponID != WEAPON_NONE) 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))) if (CanBuyWeaponByMaptype(pPlayer->m_iTeam, weaponID, (g_pGameRules->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES)))
{ {
bRetVal = TRUE; bRetVal = TRUE;
@ -2591,34 +2657,45 @@ BOOL HandleBuyAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
} }
else else
{ {
// primary ammo
if (FStrEq(pszCommand, "primammo")) if (FStrEq(pszCommand, "primammo"))
{ {
bRetVal = TRUE; 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)) if (BuyAmmo(pPlayer, PRIMARY_WEAPON_SLOT, true))
{ {
while (BuyAmmo(pPlayer, PRIMARY_WEAPON_SLOT, false)) while (BuyAmmo(pPlayer, PRIMARY_WEAPON_SLOT, false))
; ;
if (TheTutor) if (TheTutor != NULL)
{ {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer); TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
} }
} }
} }
// secondary ammo
else if (FStrEq(pszCommand, "secammo")) else if (FStrEq(pszCommand, "secammo"))
{ {
bRetVal = TRUE; 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)) if (BuyAmmo(pPlayer, PISTOL_SLOT, true))
{ {
while (BuyAmmo(pPlayer, PISTOL_SLOT, false)) while (BuyAmmo(pPlayer, PISTOL_SLOT, false))
; ;
if (TheTutor) if (TheTutor != NULL)
{ {
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer); TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
} }
} }
} }
// equipment
else if (FStrEq(pszCommand, "vest")) else if (FStrEq(pszCommand, "vest"))
{ {
bRetVal = TRUE; bRetVal = TRUE;
@ -2652,29 +2729,34 @@ BOOL HandleBuyAliasCommands(CBasePlayer *pPlayer, const char *pszCommand)
else if (FStrEq(pszCommand, "defuser")) else if (FStrEq(pszCommand, "defuser"))
{ {
bRetVal = TRUE; bRetVal = TRUE;
if (pPlayer->m_iTeam != CT) if (pPlayer->m_iTeam == CT)
{ {
if (g_bClientPrintEnable) BuyItem(pPlayer, MENU_SLOT_ITEM_DEFUSEKIT);
{
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Alias_Not_Avail", "#Bomb_Defusal_Kit");
}
} }
else else
BuyItem(pPlayer, MENU_SLOT_ITEM_DEFUSEKIT); {
// fail gracefully
pszFailItem = "#Bomb_Defusal_Kit";
}
} }
else if (FStrEq(pszCommand, "shield")) else if (FStrEq(pszCommand, "shield"))
{ {
bRetVal = TRUE; bRetVal = TRUE;
if (pPlayer->m_iTeam != CT) if (pPlayer->m_iTeam == CT)
{ {
if (g_bClientPrintEnable)
{
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Alias_Not_Avail", "#TactShield_Desc");
}
}
else
BuyItem(pPlayer, MENU_SLOT_ITEM_SHIELD); 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(); pPlayer->BuildRebuyStruct();

View File

@ -42,9 +42,9 @@
#define MAX_BOMB_RADIUS 2048 #define MAX_BOMB_RADIUS 2048
#define MAP_VIP_SAFETYZONE_INIT 0 // initial #define MAP_VIP_SAFETYZONE_UNINITIALIZED 0 // uninitialized
#define MAP_HAVE_VIP_SAFETYZONE_YES 1 // on map have of vip safety zone #define MAP_HAVE_VIP_SAFETYZONE_YES 1 // has VIP safety zone
#define MAP_HAVE_VIP_SAFETYZONE_NO 2 // there is no safety zone #define MAP_HAVE_VIP_SAFETYZONE_NO 2 // does not have VIP safetyzone
#define MAP_HAS_CAMERAS_INIT 2 // initial #define MAP_HAS_CAMERAS_INIT 2 // initial
#define MAP_HAS_CAMERAS_YES 1 // on map have of camera's #define MAP_HAS_CAMERAS_YES 1 // on map have of camera's
@ -72,6 +72,7 @@ enum
}; };
// custom enum // custom enum
// used for EndRoundMessage() logged messages
enum ScenarionEventEndRound enum ScenarionEventEndRound
{ {
ROUND_TARGET_BOMB = 1, ROUND_TARGET_BOMB = 1,
@ -272,6 +273,8 @@ public:
} }
virtual BOOL FAllowMonsters(void) = 0; virtual BOOL FAllowMonsters(void) = 0;
virtual void EndMultiplayerGame(void) {}; virtual void EndMultiplayerGame(void) {};
// Stuff that is shared between client and server.
virtual BOOL IsFreezePeriod(void) virtual BOOL IsFreezePeriod(void)
{ {
return IsFreezePeriod_(); return IsFreezePeriod_();
@ -489,6 +492,8 @@ public:
virtual void ClientUserInfoChanged(CBasePlayer *pPlayer, char *infobuffer); virtual void ClientUserInfoChanged(CBasePlayer *pPlayer, char *infobuffer);
virtual int IPointsForKill(CBasePlayer *pAttacker, CBasePlayer *pKilled); virtual int IPointsForKill(CBasePlayer *pAttacker, CBasePlayer *pKilled);
virtual void PlayerKilled(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor); virtual void PlayerKilled(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor);
// Death notices
virtual void DeathNotice(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor); virtual void DeathNotice(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor);
virtual BOOL CanHavePlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon); virtual BOOL CanHavePlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon);
virtual void PlayerGotWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon); virtual void PlayerGotWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon);
@ -525,7 +530,12 @@ public:
} }
virtual void ServerDeactivate(void); virtual void ServerDeactivate(void);
virtual void CheckMapConditions(void); virtual void CheckMapConditions(void);
// Recreate all the map entities from the map data (preserving their indices),
// then remove everything else except the players.
// Also get rid of all world decals.
virtual void CleanUpMap(void); virtual void CleanUpMap(void);
virtual void RestartRound(void); virtual void RestartRound(void);
virtual void CheckWinConditions(void); virtual void CheckWinConditions(void);
virtual void RemoveGuns(void); virtual void RemoveGuns(void);
@ -608,6 +618,36 @@ public:
#endif // HOOK_GAMEDLL #endif // HOOK_GAMEDLL
public: public:
// Checks if it still needs players to start a round, or if it has enough players to start rounds.
// Starts a round and returns true if there are enough players.
bool NeededPlayersCheck(bool &bNeededPlayers);
// Setup counts for m_iNumTerrorist, m_iNumCT, m_iNumSpawnableTerrorist, m_iNumSpawnableCT, etc.
void InitializePlayerCounts(int &NumAliveTerrorist, int &NumAliveCT, int &NumDeadTerrorist, int &NumDeadCT);
// Check to see if the round is over for the various game types. Terminates the round
// and returns true if the round should end.
bool PrisonRoundEndCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers);
bool BombRoundEndCheck(bool bNeededPlayers);
bool HostageRescueRoundEndCheck(bool bNeededPlayers);
bool VIPRoundEndCheck(bool bNeededPlayers);
// Check to see if the teams exterminated each other. Ends the round and returns true if so.
bool TeamExterminationCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers);
void TerminateRound(float tmDelay, int iWinStatus);
// Check various conditions to end the map.
bool CheckGameOver(void);
bool CheckTimeLimit(void);
bool CheckMaxRounds(void);
bool CheckWinLimit(void);
void CheckFreezePeriodExpired(void);
void CheckRoundTimeExpired(void);
void CheckLevelInitialized(void);
void CheckRestartRound(void);
BOOL IsCareer(void); BOOL IsCareer(void);
void QueueCareerRoundEndMenu(float tmDelay, int iWinStatus); void QueueCareerRoundEndMenu(float tmDelay, int iWinStatus);
void SetCareerMatchLimit(int minWins, int winDifference); void SetCareerMatchLimit(int minWins, int winDifference);
@ -633,17 +673,23 @@ public:
BOOL TeamStacked(int newTeam_id, int curTeam_id); BOOL TeamStacked(int newTeam_id, int curTeam_id);
bool IsVIPQueueEmpty(void); bool IsVIPQueueEmpty(void);
bool AddToVIPQueue(CBasePlayer *toAdd); bool AddToVIPQueue(CBasePlayer *toAdd);
// VIP FUNCTIONS
void PickNextVIP(void); void PickNextVIP(void);
void StackVIPQueue(void); void StackVIPQueue(void);
void ResetCurrentVIP(void); void ResetCurrentVIP(void);
void BalanceTeams(void); void BalanceTeams(void);
void SwapAllPlayers(void); void SwapAllPlayers(void);
void UpdateTeamScores(void); void UpdateTeamScores(void);
void DisplayMaps(CBasePlayer *player, int iVote); void DisplayMaps(CBasePlayer *player, int iVote);
void ResetAllMapVotes(void); void ResetAllMapVotes(void);
void ProcessMapVote(CBasePlayer *player, int iVote); void ProcessMapVote(CBasePlayer *player, int iVote);
// BOMB MAP FUNCTIONS
BOOL IsThereABomber(void); BOOL IsThereABomber(void);
BOOL IsThereABomb(void); BOOL IsThereABomb(void);
bool IsMatchStarted(void) bool IsMatchStarted(void)
{ {
return (m_fTeamCount != 0.0f || m_fCareerRoundMenuTime != 0.0f || m_fCareerMatchMenuTime != 0.0f); return (m_fTeamCount != 0.0f || m_fCareerRoundMenuTime != 0.0f || m_fCareerMatchMenuTime != 0.0f);
@ -657,57 +703,64 @@ private:
public: public:
CVoiceGameMgr m_VoiceGameMgr; CVoiceGameMgr m_VoiceGameMgr;
float m_fTeamCount; float m_fTeamCount; // m_flRestartRoundTime, the global time when the round is supposed to end, if this is not 0
float m_flCheckWinConditions; float m_flCheckWinConditions;
float m_fRoundCount; float m_fRoundCount;
int m_iRoundTime; int m_iRoundTime; // (From mp_roundtime) - How many seconds long this round is.
int m_iRoundTimeSecs; int m_iRoundTimeSecs;
int m_iIntroRoundTime; int m_iIntroRoundTime; // (From mp_freezetime) - How many seconds long the intro round (when players are frozen) is.
float m_fIntroRoundCount; float m_fIntroRoundCount; // The global time when the intro round ends and the real one starts
// wrote the original "m_flRoundTime" comment for this variable).
int m_iAccountTerrorist; int m_iAccountTerrorist;
int m_iAccountCT; int m_iAccountCT;
int m_iNumTerrorist; int m_iNumTerrorist; // The number of terrorists on the team (this is generated at the end of a round)
int m_iNumCT; int m_iNumCT; // The number of CTs on the team (this is generated at the end of a round)
int m_iNumSpawnableTerrorist; int m_iNumSpawnableTerrorist;
int m_iNumSpawnableCT; int m_iNumSpawnableCT;
int m_iSpawnPointCount_Terrorist; int m_iSpawnPointCount_Terrorist; // Number of Terrorist spawn points
int m_iSpawnPointCount_CT; int m_iSpawnPointCount_CT; // Number of CT spawn points
int m_iHostagesRescued; int m_iHostagesRescued;
int m_iHostagesTouched; int m_iHostagesTouched;
int m_iRoundWinStatus; int m_iRoundWinStatus; // 1 == CT's won last round, 2 == Terrorists did, 3 == Draw, no winner
short m_iNumCTWins; short m_iNumCTWins;
short m_iNumTerroristWins; short m_iNumTerroristWins;
bool m_bTargetBombed;
bool m_bBombDefused; bool m_bTargetBombed; // whether or not the bomb has been bombed
bool m_bBombDefused; // whether or not the bomb has been defused
bool m_bMapHasBombTarget; bool m_bMapHasBombTarget;
bool m_bMapHasBombZone; bool m_bMapHasBombZone;
bool m_bMapHasBuyZone; bool m_bMapHasBuyZone;
bool m_bMapHasRescueZone; bool m_bMapHasRescueZone;
bool m_bMapHasEscapeZone; bool m_bMapHasEscapeZone;
int m_iMapHasVIPSafetyZone;
int m_iMapHasVIPSafetyZone; // 0 = uninitialized; 1 = has VIP safety zone; 2 = DOES not have VIP safetyzone
int m_bMapHasCameras; int m_bMapHasCameras;
int m_iC4Timer; int m_iC4Timer;
int m_iC4Guy; int m_iC4Guy; // The current Terrorist who has the C4.
int m_iLoserBonus; int m_iLoserBonus; // the amount of money the losing team gets. This scales up as they lose more rounds in a row
int m_iNumConsecutiveCTLoses; int m_iNumConsecutiveCTLoses; // the number of rounds the CTs have lost in a row.
int m_iNumConsecutiveTerroristLoses; int m_iNumConsecutiveTerroristLoses; // the number of rounds the Terrorists have lost in a row.
float m_fMaxIdlePeriod;
float m_fMaxIdlePeriod; // For the idle kick functionality. This is tha max amount of time that the player has to be idle before being kicked
int m_iLimitTeams; int m_iLimitTeams;
bool m_bLevelInitialized; bool m_bLevelInitialized;
bool m_bRoundTerminating; bool m_bRoundTerminating;
bool m_bCompleteReset; bool m_bCompleteReset; // Set to TRUE to have the scores reset next time round restarts
float m_flRequiredEscapeRatio; float m_flRequiredEscapeRatio;
int m_iNumEscapers; int m_iNumEscapers;
int m_iHaveEscaped; int m_iHaveEscaped;
bool m_bCTCantBuy; bool m_bCTCantBuy;
bool m_bTCantBuy; bool m_bTCantBuy; // Who can and can't buy.
float m_flBombRadius; float m_flBombRadius;
int m_iConsecutiveVIP; int m_iConsecutiveVIP;
int m_iTotalGunCount; int m_iTotalGunCount;
int m_iTotalGrenadeCount; int m_iTotalGrenadeCount;
int m_iTotalArmourCount; int m_iTotalArmourCount;
int m_iUnBalancedRounds; int m_iUnBalancedRounds; // keeps track of the # of consecutive rounds that have gone by where one team outnumbers the other team by more than 2
int m_iNumEscapeRounds; int m_iNumEscapeRounds; // keeps track of the # of consecutive rounds of escape played.. Teams will be swapped after 8 rounds
int m_iMapVotes[ MAX_VOTE_MAPS ]; int m_iMapVotes[ MAX_VOTE_MAPS ];
int m_iLastPick; int m_iLastPick;
int m_iMaxMapTime; int m_iMaxMapTime;

File diff suppressed because it is too large Load Diff

View File

@ -621,9 +621,11 @@ NOXREF CBasePlayer *CBasePlayer::GetNextRadioRecipient(CBasePlayer *pStartPlayer
/* <15edd2> ../cstrike/dlls/player.cpp:705 */ /* <15edd2> ../cstrike/dlls/player.cpp:705 */
void CBasePlayer::Radio(const char *msg_id, const char *msg_verbose, short pitch, bool showIcon) void CBasePlayer::Radio(const char *msg_id, const char *msg_verbose, short pitch, bool showIcon)
{ {
// Spectators don't say radio messages.
if (!IsPlayer()) if (!IsPlayer())
return; return;
// Neither do dead guys.
if (pev->deadflag != DEAD_NO && !IsBot()) if (pev->deadflag != DEAD_NO && !IsBot())
return; return;
@ -636,40 +638,52 @@ void CBasePlayer::Radio(const char *msg_id, const char *msg_verbose, short pitch
BOOL bSend = FALSE; BOOL bSend = FALSE;
CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pEntity->pev); CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pEntity->pev);
if (pEntity->IsPlayer()) if (pPlayer == NULL)
{
if (pEntity->IsDormant())
continue; continue;
if (pEntity && pPlayer->m_iTeam == m_iTeam) // are we a regular player? (not spectator)
if (pPlayer->IsPlayer())
{
if (pPlayer->IsDormant())
continue;
// is this player on our team? (even dead players hear our radio calls)
if (pPlayer->m_iTeam == m_iTeam)
bSend = TRUE; bSend = TRUE;
} }
else if (pEntity) // this means we're a spectator
else
{ {
int iSpecMode = IsObserver(); // do this when spectator mode is in
int iSpecMode = pPlayer->IsObserver();
if (iSpecMode != OBS_CHASE_LOCKED && iSpecMode != OBS_CHASE_FREE && iSpecMode != OBS_IN_EYE) if (iSpecMode != OBS_CHASE_LOCKED && iSpecMode != OBS_CHASE_FREE && iSpecMode != OBS_IN_EYE)
continue; continue;
if (!FNullEnt(m_hObserverTarget)) if (!FNullEnt(pPlayer->m_hObserverTarget))
continue; continue;
CBasePlayer *pTarget = (CBasePlayer *)CBaseEntity::Instance(pPlayer->m_hObserverTarget->pev); CBasePlayer *pTarget = (CBasePlayer *)CBaseEntity::Instance(pPlayer->m_hObserverTarget->pev);
if (pTarget && pTarget->m_iTeam == m_iTeam) if (pTarget && pTarget->m_iTeam == m_iTeam)
{
bSend = TRUE; bSend = TRUE;
} }
}
if (!bSend || pPlayer->m_bIgnoreRadio) if (bSend)
continue; {
// ignorerad command
if (!pPlayer->m_bIgnoreRadio)
{
MESSAGE_BEGIN(MSG_ONE, gmsgSendAudio, NULL, pEntity->pev); MESSAGE_BEGIN(MSG_ONE, gmsgSendAudio, NULL, pEntity->pev);
WRITE_BYTE(ENTINDEX(edict())); WRITE_BYTE(ENTINDEX(edict()));
WRITE_STRING(msg_id); WRITE_STRING(msg_id);
WRITE_SHORT(pitch); WRITE_SHORT(pitch);
MESSAGE_END(); MESSAGE_END();
if (msg_verbose) // radio message icon
if (msg_verbose != NULL)
{ {
// search the place name where is located the player // search the place name where is located the player
const char *placeName = NULL; const char *placeName = NULL;
@ -693,16 +707,19 @@ void CBasePlayer::Radio(const char *msg_id, const char *msg_verbose, short pitch
if (showIcon) if (showIcon)
{ {
// put an icon over this guys head to show that he used the radio
MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity->pev); MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity->pev);
WRITE_BYTE(TE_PLAYERATTACHMENT); WRITE_BYTE(TE_PLAYERATTACHMENT);
WRITE_BYTE(ENTINDEX(edict())); WRITE_BYTE(ENTINDEX(edict())); // byte (entity index of player)
WRITE_COORD(35); // vertical offset WRITE_COORD(35); // coord (vertical offset) ( attachment origin.z = player origin.z + vertical offset)
WRITE_SHORT(g_sModelIndexRadio); // model index WRITE_SHORT(g_sModelIndexRadio); // short (model index) of tempent
WRITE_SHORT(15); // life WRITE_SHORT(15); // short (life * 10 ) e.g. 40 = 4 seconds
MESSAGE_END(); MESSAGE_END();
} }
} }
} }
}
}
/* <1537f3> ../cstrike/dlls/player.cpp:812 */ /* <1537f3> ../cstrike/dlls/player.cpp:812 */
void CBasePlayer::SmartRadio(void) void CBasePlayer::SmartRadio(void)
@ -838,18 +855,21 @@ void CBasePlayer::__MAKE_VHOOK(TraceAttack)(entvars_t *pevAttacker, float flDama
bool bShouldBleed = true; bool bShouldBleed = true;
bool bShouldSpark = false; bool bShouldSpark = false;
bool bHitShield = IsHittingShield(vecDir, ptr); bool bHitShield = IsHittingShield(vecDir, ptr);
CBasePlayer *pAttacker = (CBasePlayer *)CBasePlayer::Instance(pevAttacker); CBasePlayer *pAttacker = (CBasePlayer *)CBasePlayer::Instance(pevAttacker);
if (CVAR_GET_FLOAT("mp_friendlyfire") == 0 && m_iTeam == pAttacker->m_iTeam) if (m_iTeam == pAttacker->m_iTeam && CVAR_GET_FLOAT("mp_friendlyfire") == 0)
bShouldBleed = false; bShouldBleed = false;
if (pev->takedamage == DAMAGE_NO) if (pev->takedamage == DAMAGE_NO)
return; return;
m_LastHitGroup = ptr->iHitgroup; m_LastHitGroup = ptr->iHitgroup;
if (bHitShield) if (bHitShield)
{ {
flDamage = 0; flDamage = 0;
bShouldBleed = false;
if (RANDOM_LONG(0, 1)) if (RANDOM_LONG(0, 1))
EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/ric_metal-1.wav", VOL_NORM, ATTN_NORM); EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/ric_metal-1.wav", VOL_NORM, ATTN_NORM);
@ -921,7 +941,7 @@ void CBasePlayer::__MAKE_VHOOK(TraceAttack)(entvars_t *pevAttacker, float flDama
} }
case HITGROUP_STOMACH: case HITGROUP_STOMACH:
{ {
flDamage = flDamage * 1.25; flDamage *= 1.25;
if (m_iKevlar != ARMOR_TYPE_EMPTY) if (m_iKevlar != ARMOR_TYPE_EMPTY)
bShouldBleed = false; bShouldBleed = false;
@ -958,7 +978,8 @@ void CBasePlayer::__MAKE_VHOOK(TraceAttack)(entvars_t *pevAttacker, float flDama
SpawnBlood(ptr->vecEndPos, BloodColor(), flDamage); // a little surface blood. SpawnBlood(ptr->vecEndPos, BloodColor(), flDamage); // a little surface blood.
TraceBleed(flDamage, vecDir, ptr, bitsDamageType); TraceBleed(flDamage, vecDir, ptr, bitsDamageType);
} }
else if (ptr->iHitgroup == HITGROUP_HEAD && bShouldSpark == true) // they hit a helmet
else if (ptr->iHitgroup == HITGROUP_HEAD && bShouldSpark)
{ {
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, ptr->vecEndPos); MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, ptr->vecEndPos);
WRITE_BYTE(TE_STREAK_SPLASH); WRITE_BYTE(TE_STREAK_SPLASH);
@ -3140,6 +3161,7 @@ void CBasePlayer::AddAccount(int amount, bool bTrackChange)
else if (m_iAccount > 16000) else if (m_iAccount > 16000)
m_iAccount = 16000; m_iAccount = 16000;
// Send money update to HUD
MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, pev); MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, pev);
WRITE_LONG(m_iAccount); WRITE_LONG(m_iAccount);
WRITE_BYTE(bTrackChange); WRITE_BYTE(bTrackChange);
@ -3627,6 +3649,7 @@ void CBasePlayer::__MAKE_VHOOK(RoundRespawn)(void)
{ {
m_canSwitchObserverModes = true; m_canSwitchObserverModes = true;
// teamkill punishment..
if (m_bJustKilledTeammate && CVAR_GET_FLOAT("mp_tkpunish")) if (m_bJustKilledTeammate && CVAR_GET_FLOAT("mp_tkpunish"))
{ {
m_bJustKilledTeammate = false; m_bJustKilledTeammate = false;
@ -4098,19 +4121,26 @@ void CBasePlayer::__MAKE_VHOOK(AddPointsToTeam)(int score, BOOL bAllowNegativeSc
bool CBasePlayer::CanPlayerBuy(bool display) bool CBasePlayer::CanPlayerBuy(bool display)
{ {
CHalfLifeMultiplay *mp = g_pGameRules; CHalfLifeMultiplay *mp = g_pGameRules;
int buyTime;
if (!mp->IsMultiplayer()) if (!mp->IsMultiplayer())
{ {
return CHalfLifeTraining::PlayerCanBuy(this); return CHalfLifeTraining::PlayerCanBuy(this);
} }
if (pev->deadflag != DEAD_NO || !(m_signals.GetState() & SIGNAL_BUY)) // is the player alive?
if (pev->deadflag != DEAD_NO)
{ {
return false; return false;
} }
buyTime = (int)(CVAR_GET_FLOAT("mp_buytime") * 60); // is the player in a buy zone?
if (!(m_signals.GetState() & SIGNAL_BUY))
{
return false;
}
int buyTime = (int)(CVAR_GET_FLOAT("mp_buytime") * 60);
if (buyTime < 15) if (buyTime < 15)
{ {
buyTime = 15; buyTime = 15;
@ -4123,30 +4153,37 @@ bool CBasePlayer::CanPlayerBuy(bool display)
{ {
ClientPrint(pev, HUD_PRINTCENTER, "#Cant_buy", UTIL_dtos1(buyTime)); ClientPrint(pev, HUD_PRINTCENTER, "#Cant_buy", UTIL_dtos1(buyTime));
} }
return false; return false;
} }
if (m_bIsVIP) if (m_bIsVIP)
{ {
if (display) if (display)
{ {
ClientPrint(pev, HUD_PRINTCENTER, "#VIP_cant_buy"); ClientPrint(pev, HUD_PRINTCENTER, "#VIP_cant_buy");
} }
return false; return false;
} }
if (mp->m_bCTCantBuy && m_iTeam == CT) if (mp->m_bCTCantBuy && m_iTeam == CT)
{ {
if (display) if (display)
{ {
ClientPrint(pev, HUD_PRINTCENTER, "#CT_cant_buy"); ClientPrint(pev, HUD_PRINTCENTER, "#CT_cant_buy");
} }
return false; return false;
} }
if (mp->m_bTCantBuy && m_iTeam == TERRORIST) if (mp->m_bTCantBuy && m_iTeam == TERRORIST)
{ {
if (display) if (display)
{ {
ClientPrint(pev, HUD_PRINTCENTER, "#Terrorist_cant_buy"); ClientPrint(pev, HUD_PRINTCENTER, "#Terrorist_cant_buy");
} }
return false; return false;
} }
@ -4156,27 +4193,32 @@ bool CBasePlayer::CanPlayerBuy(bool display)
/* <15f9ac> ../cstrike/dlls/player.cpp:4717 */ /* <15f9ac> ../cstrike/dlls/player.cpp:4717 */
void CBasePlayer::__MAKE_VHOOK(PreThink)(void) void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
{ {
int buttonsChanged = (pev->button ^ m_afButtonLast); // These buttons have changed this frame
int buttonsChanged = (m_afButtonLast ^ pev->button);
if (pev->button != m_afButtonLast) //this means the player has pressed or released a key
if (buttonsChanged)
m_fLastMovement = gpGlobals->time; m_fLastMovement = gpGlobals->time;
// Debounced button codes for pressed/released
// UNDONE: Do we need auto-repeat?
m_afButtonPressed = (buttonsChanged & pev->button); // The changed ones still down are "pressed" m_afButtonPressed = (buttonsChanged & pev->button); // The changed ones still down are "pressed"
m_afButtonReleased = (buttonsChanged & (~pev->button)); // The ones not down are "released" m_afButtonReleased = (buttonsChanged & (~pev->button)); // The ones not down are "released"
// Hint messages should be updated even if the game is over
m_hintMessageQueue.Update(this); m_hintMessageQueue.Update(this);
g_pGameRules->PlayerThink(this); g_pGameRules->PlayerThink(this);
if (g_fGameOver) if (g_fGameOver)
{ {
// intermission or finale
return; return;
} }
if (m_iJoiningState != JOINED) if (m_iJoiningState != JOINED)
{
JoiningThink(); JoiningThink();
}
// Mission Briefing text, remove it when the player hits an important button
if (m_bMissionBriefing) if (m_bMissionBriefing)
{ {
if (m_afButtonPressed & (IN_ATTACK | IN_ATTACK2)) if (m_afButtonPressed & (IN_ATTACK | IN_ATTACK2))
@ -4187,12 +4229,15 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
} }
} }
// is this still used?
UTIL_MakeVectors(pev->v_angle); UTIL_MakeVectors(pev->v_angle);
ItemPreFrame(); ItemPreFrame();
WaterMove(); WaterMove();
if (pev->flags & FL_ONGROUND) if (pev->flags & FL_ONGROUND)
{ {
// Slow down the player based on the velocity modifier
if (m_flVelocityModifier < 1.0f) if (m_flVelocityModifier < 1.0f)
{ {
float_precision modvel = m_flVelocityModifier + 0.01; float_precision modvel = m_flVelocityModifier + 0.01;
@ -4207,19 +4252,25 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
if (m_flIdleCheckTime <= (double)gpGlobals->time || m_flIdleCheckTime == 0.0f) if (m_flIdleCheckTime <= (double)gpGlobals->time || m_flIdleCheckTime == 0.0f)
{ {
// check every 5 seconds
m_flIdleCheckTime = gpGlobals->time + 5.0; m_flIdleCheckTime = gpGlobals->time + 5.0;
double v25 = gpGlobals->time - m_fLastMovement; float_precision flLastMove = gpGlobals->time - m_fLastMovement;
if (v25 > g_pGameRules->m_fMaxIdlePeriod) //check if this player has been inactive for 2 rounds straight
if (flLastMove > g_pGameRules->m_fMaxIdlePeriod)
{ {
if (!IsBot() && CVAR_GET_FLOAT("mp_autokick") != 0.0f) if (!IsBot() && CVAR_GET_FLOAT("mp_autokick") != 0.0f)
{ {
UTIL_LogPrintf("\"%s<%i><%s><%s>\" triggered \"Game_idle_kick\" (auto)\n", // Log the kick
UTIL_LogPrintf
(
"\"%s<%i><%s><%s>\" triggered \"Game_idle_kick\" (auto)\n",
STRING(pev->netname), STRING(pev->netname),
GETPLAYERUSERID(edict()), GETPLAYERUSERID(edict()),
GETPLAYERAUTHID(edict()), GETPLAYERAUTHID(edict()),
GetTeam(m_iTeam)); GetTeam(m_iTeam)
);
UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_idle_kick", STRING(pev->netname)); UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_idle_kick", STRING(pev->netname));
SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pev->netname))); SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pev->netname)));
@ -4235,6 +4286,7 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
// JOHN: checks if new client data (for HUD and view control) needs to be sent to the client // JOHN: checks if new client data (for HUD and view control) needs to be sent to the client
UpdateClientData(); UpdateClientData();
CheckTimeBasedDamage(); CheckTimeBasedDamage();
CheckSuitUpdate(); CheckSuitUpdate();
@ -4259,12 +4311,16 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
return; return;
} }
// new code to determine if a player is on a train or not
CBaseEntity *pGroundEntity = Instance(pev->groundentity); CBaseEntity *pGroundEntity = Instance(pev->groundentity);
if (pGroundEntity && pGroundEntity->Classify() == CLASS_VEHICLE) if (pGroundEntity && pGroundEntity->Classify() == CLASS_VEHICLE)
{
pev->iuser4 = 1; pev->iuser4 = 1;
}
else else
{
pev->iuser4 = 0; pev->iuser4 = 0;
}
// Train speed control // Train speed control
if (m_afPhysicsFlags & PFLAG_ONTRAIN) if (m_afPhysicsFlags & PFLAG_ONTRAIN)
@ -4284,9 +4340,8 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
if (!pTrain || !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) || !pTrain->OnControls(pev)) if (!pTrain || !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) || !pTrain->OnControls(pev))
{ {
m_iTrain = (TRAIN_NEW | TRAIN_OFF);
m_afPhysicsFlags &= ~PFLAG_ONTRAIN; m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = (TRAIN_NEW | TRAIN_OFF);
((CFuncVehicle *)pTrain)->m_pDriver = NULL; ((CFuncVehicle *)pTrain)->m_pDriver = NULL;
return; return;
} }
@ -4294,9 +4349,8 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
else if (!(pev->flags & FL_ONGROUND) || (pTrain->pev->spawnflags & SF_TRACKTRAIN_NOCONTROL)) else if (!(pev->flags & FL_ONGROUND) || (pTrain->pev->spawnflags & SF_TRACKTRAIN_NOCONTROL))
{ {
// Turn off the train if you jump, strafe, or the train controls go dead // Turn off the train if you jump, strafe, or the train controls go dead
m_iTrain = (TRAIN_NEW | TRAIN_OFF);
m_afPhysicsFlags &= ~PFLAG_ONTRAIN; m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = (TRAIN_NEW | TRAIN_OFF);
((CFuncVehicle *)pTrain)->m_pDriver = NULL; ((CFuncVehicle *)pTrain)->m_pDriver = NULL;
return; return;
} }
@ -4373,6 +4427,9 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
m_flFallVelocity = -pev->velocity.z; m_flFallVelocity = -pev->velocity.z;
} }
//!!!HACKHACK!!! Can't be hit by traceline when not animating?
//StudioFrameAdvance();
// Clear out ladder pointer // Clear out ladder pointer
m_hEnemy = NULL; m_hEnemy = NULL;
@ -4381,9 +4438,9 @@ void CBasePlayer::__MAKE_VHOOK(PreThink)(void)
pev->velocity = g_vecZero; pev->velocity = g_vecZero;
} }
if (!(m_flDisplayHistory & DHF_ROUND_STARTED) && CanPlayerBuy()) if (!(m_flDisplayHistory & DHF_ROUND_STARTED) && CanPlayerBuy(false))
{ {
HintMessage("#Hint_press_buy_to_purchase"); HintMessage("#Hint_press_buy_to_purchase", FALSE);
m_flDisplayHistory |= DHF_ROUND_STARTED; m_flDisplayHistory |= DHF_ROUND_STARTED;
} }
@ -4898,14 +4955,18 @@ edict_t *EntSelectSpawnPoint(CBaseEntity *pPlayer)
{ {
pSpot = UTIL_FindEntityByClassname(NULL, "info_vip_start"); pSpot = UTIL_FindEntityByClassname(NULL, "info_vip_start");
// skip over the null point
if (!FNullEnt(pSpot)) if (!FNullEnt(pSpot))
{
goto ReturnSpot; goto ReturnSpot;
}
goto CTSpawn; goto CTSpawn;
} }
else if (g_pGameRules->IsDeathmatch() && ((CBasePlayer *)pPlayer)->m_iTeam == CT) else if (g_pGameRules->IsDeathmatch() && ((CBasePlayer *)pPlayer)->m_iTeam == CT)
{ {
CTSpawn: CTSpawn:
// Find the next spawn spot.
pSpot = UTIL_FindEntityByClassname(g_pLastCTSpawn, "info_player_start"); pSpot = UTIL_FindEntityByClassname(g_pLastCTSpawn, "info_player_start");
// skip over the null point // skip over the null point
@ -4950,9 +5011,11 @@ edict_t *EntSelectSpawnPoint(CBaseEntity *pPlayer)
if (ent->IsPlayer() && ent->edict() != player) if (ent->IsPlayer() && ent->edict() != player)
ent->TakeDamage(VARS(INDEXENT(0)), VARS(INDEXENT(0)), 200, DMG_GENERIC); ent->TakeDamage(VARS(INDEXENT(0)), VARS(INDEXENT(0)), 200, DMG_GENERIC);
} }
goto ReturnSpot; goto ReturnSpot;
} }
} }
// The terrorist spawn points
else if (g_pGameRules->IsDeathmatch() && ((CBasePlayer *)pPlayer)->m_iTeam == TERRORIST) else if (g_pGameRules->IsDeathmatch() && ((CBasePlayer *)pPlayer)->m_iTeam == TERRORIST)
{ {
pSpot = UTIL_FindEntityByClassname(g_pLastTerroristSpawn, "info_player_deathmatch"); pSpot = UTIL_FindEntityByClassname(g_pLastTerroristSpawn, "info_player_deathmatch");
@ -5068,7 +5131,7 @@ void CBasePlayer::__MAKE_VHOOK(Spawn)(void)
m_progressStart = 0; m_progressStart = 0;
m_progressEnd = 0; m_progressEnd = 0;
if (pev->classname) if (!FStringNull(pev->classname))
{ {
RemoveEntityHashValue(pev, STRING(pev->classname), CLASSNAME); RemoveEntityHashValue(pev, STRING(pev->classname), CLASSNAME);
} }
@ -5320,14 +5383,14 @@ void CBasePlayer::__MAKE_VHOOK(Spawn)(void)
} }
} }
m_lastx = 0; m_lastx = m_lasty = 0;
m_lasty = 0;
g_pGameRules->PlayerSpawn(this); g_pGameRules->PlayerSpawn(this);
m_bNotKilled = true; m_bNotKilled = true;
m_bIsDefusing = false; m_bIsDefusing = false;
// Get rid of the progress bar...
SetProgressBarTime(0); SetProgressBarTime(0);
ResetMaxSpeed(); ResetMaxSpeed();
@ -6979,19 +7042,33 @@ void CBasePlayer::EnableControl(BOOL fControl)
/* <151142> ../cstrike/dlls/player.cpp:8387 */ /* <151142> ../cstrike/dlls/player.cpp:8387 */
void CBasePlayer::__MAKE_VHOOK(ResetMaxSpeed)(void) void CBasePlayer::__MAKE_VHOOK(ResetMaxSpeed)(void)
{ {
float speed = 240.0f; float speed;
if (IsObserver()) if (IsObserver())
speed = 900.0f; {
// Player gets speed bonus in observer mode
speed = 900;
}
else if (g_pGameRules->IsMultiplayer() && g_pGameRules->IsFreezePeriod()) else if (g_pGameRules->IsMultiplayer() && g_pGameRules->IsFreezePeriod())
speed = 1.0f; {
// Player should not move during the freeze period
else if (m_bIsVIP) speed = 1;
speed = 227.0f; }
// VIP is slow due to the armour he's wearing
else if (m_pActiveItem) else if (m_bIsVIP != NULL)
{
speed = 227;
}
else if (m_pActiveItem != NULL)
{
// Get player speed from selected weapon
speed = m_pActiveItem->GetMaxSpeed(); speed = m_pActiveItem->GetMaxSpeed();
}
else
{
// No active item, set the player's speed to default
speed = 240;
}
pev->maxspeed = speed; pev->maxspeed = speed;
} }