Css Buy - SP
Css Buy - SP
Revisions 2.0.3
- Fixed an issue where players could buy weapons/equipment belonging to the
other team outside of the buyzone / after the buytime.
- Changing css_buy_buytime now correctly updates the in-game buytime counter.
- The in-game buytime counter now sets itself correctly if there is a late
load.
- Cleaned up logic for the buy hook so that the plugin always reverts to the
internal buy command whenever possible.
- Added optional flag support for restricting purchases of weapons belonging
to opposing team to only those individuals with the specified flag.
*/
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <cstrike>
#include <colors>
new g_iEquipSlot[MAX_EQUIP_SIZE];
new g_iEquipTeam[MAX_EQUIP_SIZE];
new g_iEquipCost[MAX_EQUIP_SIZE];
new CSWeaponID:g_iEquipIndex[MAX_EQUIP_SIZE];
new g_iEquipOriginal[MAX_EQUIP_SIZE];
new g_iEquipFlag[MAX_EQUIP_SIZE];
new String:g_sEquipName[MAX_EQUIP_SIZE][32];
new String:g_sEquipMenu[MAX_EQUIP_SIZE][32];
new String:g_sMenuOptions[MAX_MENU_OPTIONS][32];
new bool:g_bRestrictedWeapon[2][MAX_EQUIP_SIZE];
new Handle:g_hRestrictedWeapon[2][MAX_EQUIP_SIZE] = { { INVALID_HANDLE, ... },
{ INVALID_HANDLE, ... } };
public Plugin:myinfo =
{
name = "CSS Buy Command",
author = "Twisted|Panda",
description = "Provides an advance purchasing method capable of overriding
game defaults.",
version = PLUGIN_VERSION,
url = "http://ominousgaming.com"
};
public OnPluginStart()
{
LoadTranslations("common.phrases");
LoadTranslations("css_buy.phrases");
g_hCvarBuyTime = FindConVar("mp_buytime");
HookConVarChange(g_hCvarBuyTime, OnSettingsChange);
g_hCvarAmmoFlashes = FindConVar("ammo_flashbang_max");
HookConVarChange(g_hCvarAmmoFlashes, OnSettingsChange);
g_hCvarAmmoSmokes = FindConVar("ammo_smokegrenade_max");
HookConVarChange(g_hCvarAmmoSmokes, OnSettingsChange);
g_hCvarAmmoGrenades = FindConVar("ammo_hegrenade_max");
HookConVarChange(g_hCvarAmmoGrenades, OnSettingsChange);
AddCommandListener(Command_Say, "say");
AddCommandListener(Command_Say, "say_team");
HookEvent("player_team", Event_OnPlayerTeam);
HookEvent("player_spawn", Event_OnPlayerSpawn);
HookEvent("player_death", Event_OnPlayerDeath);
HookEvent("round_start", Event_OnRoundStart);
HookEvent("round_freeze_end", Event_OnFreezeEnd);
Void_SetDefaults();
Void_DefineEquips();
}
public OnAllPluginsLoaded()
{
g_hRestrictConvar = FindConVar("sm_weaponrestrict_version");
g_bRestrictEnabled = (g_hRestrictConvar != INVALID_HANDLE) ? true : false;
if(g_bRestrictEnabled && !g_bRestrictLoaded)
{
decl String:_sBuffer[40];
new String:_sRed[] = "sm_restrict_*_t";
new String:_sBlue[] = "sm_restrict_*_ct";
g_bRestrictLoaded = true;
for(new i = 0; i < g_iNumEquips; i++)
{
strcopy(_sBuffer, 40, _sRed);
ReplaceString(_sBuffer, 40, "*", g_sEquipName[i]);
g_hRestrictedWeapon[0][i] = FindConVar(_sBuffer);
if(g_hRestrictedWeapon[0][i] != INVALID_HANDLE)
{
HookConVarChange(g_hRestrictedWeapon[0][i],
OnRestrictChange);
g_bRestrictedWeapon[0][i] =
GetConVarInt(g_hRestrictedWeapon[0][i]) == -1 ? false : true;
}
public OnConfigsExecuted()
{
if(g_bEnabled)
{
Format(g_sPrefixChat, sizeof(g_sPrefixChat), "%T", "Prefix_Chat",
LANG_SERVER);
Format(g_sPrefixHint, sizeof(g_sPrefixHint), "%T", "Prefix_Hint",
LANG_SERVER);
Format(g_sPrefixCenter, sizeof(g_sPrefixCenter), "%T", "Prefix_Center",
LANG_SERVER);
Format(g_sPrefixKey, sizeof(g_sPrefixKey), "%T", "Prefix_Key",
LANG_SERVER);
Format(g_sPrefixConsole, sizeof(g_sPrefixConsole), "%T",
"Prefix_Console", LANG_SERVER);
if(g_bLateLoad)
{
for(new i = 1; i <= MaxClients; i++)
{
if(IsClientInGame(i))
{
g_iTeam[i] = GetClientTeam(i);
g_bAlive[i] = IsPlayerAlive(i) ? true : false;
SDKHook(i, SDKHook_PostThinkPost,
Hook_PostThinkPost);
}
}
public OnClientPutInServer(client)
{
if(g_bEnabled)
{
if(IsClientInGame(client))
{
SDKHook(client, SDKHook_PostThinkPost, Hook_PostThinkPost);
}
}
}
public Hook_PostThinkPost(entity)
{
if(g_bEnabled)
{
if(!g_bBuyZone)
SetEntProp(entity, Prop_Send, "m_bInBuyZone", 1);
}
}
decl String:_sDisplay[32];
Format(_sDisplay, sizeof(_sDisplay), "%T", _sBuffer,
client);
if(!g_iEquipTeam[_iIndex] || g_iTeam[client] ==
g_iEquipTeam[_iIndex])
{
new _iCost = (g_iEquipCost[_iIndex] == -1) ?
CS_GetWeaponPrice(client, g_iEquipIndex[_iIndex]) : g_iEquipCost[_iIndex];
new _iCash = GetEntProp(client, Prop_Send,
"m_iAccount");
if(_iCash < _iCost)
{
PrintToClient(client, "%T",
"Insufficient_Funds", client, _sDisplay);
return Plugin_Handled;
}
new bool:_bPurchase;
decl String:_sLong[32];
Format(_sLong, sizeof(_sLong), "%s%s", ((_iIndex < 0)
? "item_" : "weapon_"), _sBuffer);
switch(g_iEquipSlot[_iIndex])
{
case -1:
{
if(GetEntProp(client, Prop_Send,
"m_ArmorValue") < 100)
{
_bPurchase = true;
SetEntProp(client, Prop_Send,
"m_ArmorValue", 100, 1);
}
}
case -2:
{
if(!GetEntProp(client, Prop_Send,
"m_bHasHelmet") || GetEntProp(client, Prop_Send, "m_ArmorValue") < 100)
{
_bPurchase = true;
SetEntProp(client, Prop_Send,
"m_ArmorValue", 100, 1);
SetEntProp(client, Prop_Send,
"m_bHasHelmet", 1, 1);
}
}
case -3:
{
if((!g_iEquipOriginal[_iIndex] ||
g_iTeam[client] == g_iEquipOriginal[_iIndex]) && !GetEntProp(client, Prop_Send,
"m_bHasDefuser"))
{
_bPurchase = true;
SetEntProp(client, Prop_Send,
"m_bHasDefuser", 1, 1);
}
}
case -4:
{
if(!GetEntProp(client, Prop_Send,
"m_bHasNightVision"))
{
_bPurchase = true;
SetEntProp(client, Prop_Send,
"m_bHasNightVision", 1, 1);
}
}
case 0, 1:
{
new _iEnt =
GetPlayerWeaponSlot(client, g_iEquipSlot[_iIndex]);
if(_iEnt == -1)
{
_bPurchase = true;
GivePlayerItem(client,
_sLong);
}
else
{
decl String:_sClassname[32];
GetEdictClassname(_iEnt,
_sClassname, sizeof(_sClassname));
if(StrEqual(_sClassname,
_sLong, false))
return Plugin_Continue;
else
{
_bPurchase = true;
CS_DropWeapon(client,
_iEnt, true, true);
new Handle:_hPack =
INVALID_HANDLE;
CreateDataTimer(0.1,
Timer_PurchaseWeapon, _hPack);
WritePackCell(_hPack,
GetClientUserId(client));
WritePackString(_hPack,
_sLong);
}
}
}
case 2:
{
new _iEnt =
GetPlayerWeaponSlot(client, g_iEquipSlot[_iIndex]);
if(_iEnt == -1)
{
_bPurchase = true;
GivePlayerItem(client,
_sLong);
}
}
case 3:
{
if(StrEqual(_sBuffer, "hegrenade"))
{
if(GetGrenadeCount(client,
CS_HE_GRENADE) < g_iCvarAmmoGrenades)
{
_bPurchase = true;
GivePlayerItem(client,
_sLong);
}
}
else if(StrEqual(_sBuffer,
"flashbang"))
{
if(GetGrenadeCount(client,
CS_FB_GRENADE) < g_iCvarAmmoFlashes)
{
_bPurchase = true;
GivePlayerItem(client,
_sLong);
}
}
else if(StrEqual(_sBuffer,
"smokegrenade"))
{
if(GetGrenadeCount(client,
CS_SM_GRENADE) < g_iCvarAmmoSmokes)
{
_bPurchase = true;
GivePlayerItem(client,
_sLong);
}
}
}
case 4:
{
if((!g_iEquipOriginal[_iIndex] ||
g_iTeam[client] == g_iEquipOriginal[_iIndex]) && !GetEntProp(client, Prop_Send,
"m_bHasDefuser"))
{
new _iEnt =
GetPlayerWeaponSlot(client, g_iEquipSlot[_iIndex]);
if(_iEnt == -1)
{
_bPurchase = true;
GivePlayerItem(client,
_sLong);
}
}
}
}
if(_bPurchase)
{
_iCash -= _iCost;
SetEntProp(client, Prop_Send,
"m_iAccount", _iCash);
}
return Plugin_Handled;
}
else
return Plugin_Continue;
}
else
{
decl String:_sTemp[32];
if(g_iEquipTeam[_iIndex] == CS_TEAM_T)
Format(_sTemp, sizeof(_sTemp), "%T",
"Buy_Team_Red", client);
else
Format(_sTemp, sizeof(_sTemp), "%T",
"Buy_Team_Blue", client);
return Plugin_Continue;
}
decl String:_sString[192];
if(!GetCmdArgString(_sString, sizeof(_sString)))
return Plugin_Continue;
StripQuotes(_sString);
new String:_sBuffer[2][32];
ExplodeString(_sString, " ", _sBuffer, 2, 32);
for(new i = 0; i < g_iNumCommands; i++)
{
if(StrEqual(_sBuffer[0], g_sBuyCommands[i], false))
{
if(!strlen(_sBuffer[1]))
{
if(g_bBuyMenu && g_iNumMenuOptions &&
(g_bAlive[client] && g_iTeam[client] >= CS_TEAM_T))
{
if(!g_bBuyZone || GetEntProp(client, Prop_Send,
"m_bInBuyZone"))
if(!g_bBuyTime || GetTime() < g_iBuyLeft)
Menu_Main(client);
else
PrintCenterText(client, "%t",
"Purchase_After_Buytime", g_iCvarBuyTime);
else
PrintCenterText(client, "%t",
"Purchase_Outside_Buyzone");
}
else
{
decl String:_sCommand[24];
strcopy(_sCommand, 24,
g_sBuyCommands[(GetRandomInt(0, (g_iNumCommands - 1)))]);
PrintToClient(client, "%T",
"Command_Display_Gear", client, _sCommand);
new String:_sTemp[1024];
Format(_sTemp, sizeof(_sTemp), "%s\n=-=-=-=-=-\
n", g_sPrefixConsole);
for(new j = 0; j < g_iNumEquips; j++)
Format(_sTemp, sizeof(_sTemp), "%s%s\n",
_sTemp, g_sEquipName[j]);
PrintToConsole(client, _sTemp);
}
}
else if(g_bAlive[client] && g_iTeam[client] >= CS_TEAM_T)
{
ReplaceString(_sBuffer[1], 32, "weapon_", "", false);
ReplaceString(_sBuffer[1], 32, "item_", "", false);
if(!g_bBuyZone || GetEntProp(client, Prop_Send,
"m_bInBuyZone"))
if(!g_bBuyTime || GetTime() < g_iBuyLeft)
FakeClientCommandEx(client, "buy %s",
_sBuffer[1]);
else
PrintCenterText(client, "%t",
"Purchase_After_Buytime", g_iCvarBuyTime);
else
PrintCenterText(client, "%t",
"Purchase_Outside_Buyzone");
}
return Plugin_Handled;
}
}
}
return Plugin_Continue;
}
public OnClientDisconnect(client)
{
if(g_bEnabled)
{
if(IsClientInGame(client))
{
g_iTeam[client] = 0;
g_bAlive[client] = false;
}
}
}
return Plugin_Continue;
}
g_bAlive[client] = true;
}
return Plugin_Continue;
}
g_bAlive[client] = false;
}
return Plugin_Continue;
}
return Plugin_Continue;
}
return Plugin_Continue;
}
Menu_Main(client, index = 0)
{
decl String:_sBuffer[128];
Format(_sBuffer, sizeof(_sBuffer), "%T", "Menu_Main_Title", client);
g_iOriginal[param1] = GetMenuSelectionPosition();
Menu_Buy(param1, StringToInt(_sOption));
}
}
}
Menu_Buy(client, type)
{
decl String:_sBuffer[128], String:_sTemp[32], String:_sSlot[8];
Format(_sBuffer, sizeof(_sBuffer), "%T", "Menu_Buy_Title", client,
g_sMenuOptions[type]);
GetGrenadeCount(client, type)
{
new offsAmmo = FindDataMapOffs(client, "m_iAmmo") + (type * 4);
return GetEntData(client, offsAmmo);
}
GetTeamIndex(team)
{
return (team == CS_TEAM_T) ? 0 : 1;
}
switch(g_iMessageMode)
{
case 0:
CPrintToChat(client, "%s%s", g_sPrefixChat, _sBuffer);
case 1:
PrintHintText(client, "%s%s", g_sPrefixHint, _sBuffer);
case 2:
PrintCenterText(client, "%s%s", g_sPrefixCenter, _sBuffer);
case 3:
{
Format(_sBuffer, sizeof(_sBuffer), "%s%s", g_sPrefixKey,
_sBuffer);
Void_DefineEquips()
{
g_hTrie_Equipment = CreateTrie();
g_iNumEquips = g_iNumMenuOptions = 0;
decl String:_sPath[256];
new Handle:_hKV = CreateKeyValues("CSSBuy_Weapons");
BuildPath(Path_SM, _sPath, 256, "configs/css_buy.weapons.txt");
if(FileToKeyValues(_hKV, _sPath))
{
KvGotoFirstSubKey(_hKV);
do
{
KvGetSectionName(_hKV, g_sEquipName[g_iNumEquips], 32);
SetTrieValue(g_hTrie_Equipment, g_sEquipName[g_iNumEquips],
g_iNumEquips);
g_iEquipCost[g_iNumEquips] = KvGetNum(_hKV, "cost");
g_iEquipSlot[g_iNumEquips] = KvGetNum(_hKV, "slot");
g_iEquipTeam[g_iNumEquips] = KvGetNum(_hKV, "team");
g_iEquipIndex[g_iNumEquips] = CSWeaponID:KvGetNum(_hKV, "index");
g_iEquipOriginal[g_iNumEquips] = KvGetNum(_hKV, "orig");
KvGetString(_hKV, "flag", _sPath, sizeof(_sPath));
g_iEquipFlag[g_iNumEquips] = strlen(_sPath) == 0 ? 0 :
ReadFlagString(_sPath);
if(!_bFound)
{
strcopy(g_sMenuOptions[g_iNumMenuOptions], 32,
g_sEquipMenu[g_iNumEquips]);
g_iNumMenuOptions++;
}
}
g_iNumEquips++;
}
while (KvGotoNextKey(_hKV));
CloseHandle(_hKV);
}
else
{
CloseHandle(_hKV);
SetFailState("CSSBuy: Could not locate
\"configs/css_buy.weapons.txt\"");
}
}
Void_SetDefaults()
{
g_bEnabled = GetConVarInt(g_hEnabled) ? true : false;
g_bBuyZone = GetConVarInt(g_hBuyZone) ? true : false;
g_bBuyTime = GetConVarInt(g_hBuyTime) ? true : false;
g_bBuyMenu = GetConVarInt(g_hBuyMenu) ? true : false;
g_fWelcome = GetConVarFloat(g_hWelcome);
g_iMessageMode = GetConVarInt(g_hMessageMode);
decl String:_sTemp[192];
GetConVarString(g_hBuyCommand, _sTemp, sizeof(_sTemp));
g_iNumCommands = ExplodeString(_sTemp, ", ", g_sBuyCommands,
MAX_CHAT_COMMANDS, MAX_COMMAND_LENGTH);
if(g_bBuyTime)
g_iBuyLeft = GetTime() + (g_iCvarBuyTime * 60);
}