#pragma semicolon 1
#pragma newdecls required
#include <cstrike>
#include <sdktools_functions>
public Plugin myinfo =
{
name = "Bot Replacer",
author = "SenatoR, babka68",
description = "Игрок может сыграть вместо бота",
version = "1.3.0_22.01.2024 (rewritten by Grey83)",
url = "https://vk.com/zakazserver68, hlmod.ru"
}
Handle
hTimer;
bool
bShow,
bNotify,
iRemove;
int
iUses[MAXPLAYERS + 1],
iAmount,
iCost,
iTarget;
public void OnPluginStart()
{
ConVar cvar;
cvar = CreateConVar("sm_bot_replacer_amount", "20", "Сколько раз за раунд игрок может сыграть вместо бота?", _, true, _, true, 2.0);
cvar.AddChangeHook(CVarChanged_Amount_Bot);
iAmount = cvar.IntValue;
cvar = CreateConVar("sm_bot_replacer_price", "1", "Сколько стоит сыграть за бота?", _, true, _, true, 16000.0);
cvar.AddChangeHook(CVarChanged_Price_Bot);
iCost = cvar.IntValue;
cvar = CreateConVar("sm_bot_replacer_showhud", "1", "Показывать сообщение, что можно играть за бота?", _, true, _, true, 1.0);
cvar.AddChangeHook(CVarChanged_Show_Message_Hud);
CVarChanged_Show_Message_Hud(cvar, NULL_STRING, NULL_STRING);
cvar = CreateConVar("sm_bot_replacer_typekick", "0", "0 - Кикнуть бота, 1 - Удалить бота", _, true, _, true, 1.0);
cvar.AddChangeHook(CVarChanged_Type_Kick);
iRemove = cvar.BoolValue;
AutoExecConfig(true, "sm_bot_replacer");
HookEvent("round_freeze_end", Event_Round, EventHookMode_PostNoCopy);
HookEvent("round_end", Event_Round, EventHookMode_PostNoCopy);
}
public void CVarChanged_Amount_Bot(ConVar cvar, const char[] oldValue, const char[] newValue)
{
iAmount = cvar.IntValue;
}
public void CVarChanged_Price_Bot(ConVar cvar, const char[] oldValue, const char[] newValue)
{
iCost = cvar.IntValue;
}
public void CVarChanged_Show_Message_Hud(ConVar cvar, const char[] oldValue, const char[] newValue)
{
if((bNotify = cvar.BoolValue) == !hTimer) OnMapStart();
}
public void CVarChanged_Type_Kick(ConVar cvar, const char[] oldValue, const char[] newValue)
{
iRemove = cvar.BoolValue;
}
public void OnMapStart()
{
if(bNotify) hTimer = CreateTimer(1.0, Timer_Notify, _, TIMER_REPEAT);
else OnMapEnd();
}
public Action Timer_Notify(Handle timer)
{
if(!bShow)
return Plugin_Continue;
static int i, t;
for(i = 1; i <= MaxClients; i++)
if(iUses[i] < iAmount // может заменять?
&& IsClientInGame(i) && !IsFakeClient(i) && (t = GetClientTeam(i)) > 1 && !IsPlayerAlive(i)
&& (iTarget = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget")) > 0 && IsFakeClient(iTarget)// наблюдает за ботом?
&& (!iCost || iCost <= GetEntProp(i, Prop_Send, "m_iAccount")) // достаточно средств?
&& t == GetClientTeam(iTarget) && IsPlayerAlive(iTarget)) // подходящий бот?
{
PrintHintText(i, "=====================================\nНАЖМИТЕ E ЧТОБЫ ИГРАТЬ ЗА БОТА %N \n=====================================", iTarget);
}
return Plugin_Continue;
}
public void Event_Round(Event event, const char[] name, bool dontBroadcast)
{
bShow = name[6] == 'f';
for(int i = 1; i <= MaxClients; i++) OnClientDisconnect(i);
}
public Action OnPlayerRunCmd(int client, int &buttons)
{
static bool use[MAXPLAYERS+1];
static int ap, h, armor, helmet, money;
static float pos[3];
if(buttons & IN_USE && !use[client] && iUses[client] < iAmount && !IsPlayerAlive(client)
&& (iTarget = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget")) > 0 && IsFakeClient(iTarget)
&& GetClientTeam(client) == GetClientTeam(iTarget)
&& iCost <= (money = GetEntProp(client, Prop_Send, "m_iAccount")))
{
int health = GetClientHealth(iTarget);
if(ap > 0 || (ap = FindSendPropInfo("CCSPlayer", "m_ArmorValue")) > 0) armor = GetEntData(client, ap, 1);
if(h > 0 || (h = FindSendPropInfo("CCSPlayer", "m_bHasHelmet")) > 0) helmet = GetEntData(client, h, 1);
GetClientAbsOrigin(iTarget, pos);
if(iRemove)
ServerCommand("bot_kick %N", iTarget);
else KickClient(iTarget);
CS_RespawnPlayer(client);
iUses[client]++;
SetEntProp(client, Prop_Send, "m_iAccount", money - iCost);
TeleportEntity(client, pos, NULL_VECTOR, NULL_VECTOR);
SetEntityHealth(client, health);
if(ap > 0) SetEntData(client, ap, armor, 1, true);
if(h > 0) SetEntData(client, h, helmet, 1, true);
}
use[client] = !!(buttons & IN_USE);
return Plugin_Continue;
}
public void OnClientDisconnect(int client)
{
iUses[client] = 0;
}
public void OnMapEnd()
{
if(hTimer) delete hTimer;
}