#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#define wS_BEAM "sprites/laser.vmt"
#define wS_SOUND_CREATE "ambient/office/button1.wav"
#define wS_SOUND_SELECT "physics/metal/chain_impact_hard2.wav"
#define wS_SOUND_EXPLOD "weapons/hegrenade/explode5.wav"
public Plugin:myinfo =
{
name = "Dangerous Beams",
author = "wS (World-Source.Ru)",
version = "1.2"
};
new g_Laser, g_Dissolver, g_LaserPrice, g_LaserLimit;
new wS_MyLasersCount[MAXPLAYERS + 1];
new wS_MyBeamRef[MAXPLAYERS + 1];
new Handle:h_beam_clear;
new Handle:g_ClearBeamPanel;
new Float:wS_UserPos1[MAXPLAYERS + 1][3];
new Float:wS_UserPos2[MAXPLAYERS + 1][3];
public OnPluginStart()
{
/////
new Handle:cvar = CreateConVar("beam_price", "2500", "Стоимость создания лазера", _, true, 0.0, true, 16000.0);
g_LaserPrice = GetConVarInt(cvar); HookConVarChange(cvar, cvar_changed);
cvar = CreateConVar("beam_limit", "3", "Сколько игрок может создать лазеров за раунд", _, true, 1.0);
g_LaserLimit = GetConVarInt(cvar); HookConVarChange(cvar, cvar_changed);
h_beam_clear = CreateConVar("beam_clear", "1", "1 = Удалять лазер после того, как он убил игрока; 0 = Нет", _, true, 0.0, true, 1.0);
AutoExecConfig(true, "dangerous_beams", "sourcemod");
/////
RegConsoleCmd("beam", beam_cmd);
HookEvent("player_spawn", player_spawn);
HookEvent("round_start", round_start, EventHookMode_PostNoCopy);
g_ClearBeamPanel = CreatePanel();
DrawPanelText(g_ClearBeamPanel, "Удалить этот лазер?\n \n");
DrawPanelItem(g_ClearBeamPanel, "Да!");
DrawPanelItem(g_ClearBeamPanel, "Нет, не надо");
}
public cvar_changed(Handle:cvar, const String:OldValue[], const String:NewValue[])
{
decl String:CvarName[32]; GetConVarName(cvar, CvarName, 32);
if (strcmp(CvarName, "beam_price") == 0) g_LaserPrice = GetConVarInt(cvar);
else if (strcmp(CvarName, "beam_limit") == 0) g_LaserLimit = GetConVarInt(cvar);
}
public round_start(Handle:event, const String:name[], bool:silent)
{
g_Dissolver = CreateEntityByName("env_entity_dissolver");
if (GetRandomInt(1, 7) == 3)
PrintToChatAll("\x01Создавай лазеры: \x04beam \x01(консоль), \x04!beam \x01и \x04/beam \x01(чат)");
}
public OnMapStart()
{
g_Laser = PrecacheModel("materials/sprites/laser.vmt", true);
PrecacheModel(wS_BEAM, true);
PrecacheSound(wS_SOUND_CREATE, true);
PrecacheSound(wS_SOUND_SELECT, true);
PrecacheSound(wS_SOUND_EXPLOD, true);
}
public player_spawn(Handle:event, const String:name[], bool:silent)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
wS_MyLasersCount[client] = 0;
wS_UserPos1[client][0] = 387335538.0;
wS_UserPos2[client][0] = 387335538.0;
}
public Action:beam_cmd(client, args)
{
if (0 < client <= MaxClients && wS_HaveAccessToMenu(client))
{
wS_SchowMenu(client);
ClientCommand(client, "playgamesound \"%s\"", wS_SOUND_SELECT);
}
return Plugin_Handled;
}
wS_SchowMenu(client)
{
new Handle:p = CreatePanel();
decl String:text[65];
Format(text, 65, "Dangerous Beams (%d)\n \n", g_LaserLimit - wS_MyLasersCount[client]);
SetPanelTitle(p, text);
DrawPanelItem(p, wS_UserPos1[client][0] == 387335538.0 ? "Позиция 1: НЕТ (УСТАНОВИТЬ)" : "Позиция 1: ЕСТЬ (ИЗМЕНИТЬ)");
DrawPanelItem(p, wS_UserPos2[client][0] == 387335538.0 ? "Позиция 2: НЕТ (УСТАНОВИТЬ)\n \n" : "Позиция 2: ЕСТЬ (ИЗМЕНИТЬ)\n \n");
if (wS_UserPos1[client][0] != 387335538.0 && wS_UserPos2[client][0] != 387335538.0)
{
if (g_LaserPrice > 0)
{
Format(text, 65, "СОЗДАТЬ лазер ($%d)\n \n", g_LaserPrice);
DrawPanelItem(p, text);
}
else
DrawPanelItem(p, "СОЗДАТЬ лазер\n \n");
}
else
DrawPanelItem(p, "СОЗДАТЬ лазер\n \n", ITEMDRAW_DISABLED);
SetPanelCurrentKey(p, 10); DrawPanelItem(p, "Выход");
SendPanelToClient(p, client, wS_MenuSelect, 0);
CloseHandle(p);
}
public wS_MenuSelect(Handle:menu, MenuAction:action, client, item)
{
if (action != MenuAction_Select || item > 3 || !wS_HaveAccessToMenu(client))
return;
if (item < 3)
{
wS_GetPos(client, item);
wS_SchowMenu(client);
}
else if (wS_UserPos1[client][0] != 387335538.0 && wS_UserPos2[client][0] != 387335538.0)
{
new e = CreateEntityByName("env_beam");
TeleportEntity(e, wS_UserPos1[client], NULL_VECTOR, NULL_VECTOR);
SetEntityModel(e, wS_BEAM);
DispatchKeyValue(e, "texture", wS_BEAM);
DispatchKeyValue(e, "renderamt", "255");
if (GetClientTeam(client) == 2)
{
DispatchKeyValue(e, "rendercolor", "255 0 0");
DispatchKeyValue(e, "targetname", "2");
}
else
{
DispatchKeyValue(e, "rendercolor", "0 0 255");
DispatchKeyValue(e, "targetname", "3");
}
SetEntPropEnt(e, Prop_Send, "m_PredictableID", client);
DispatchKeyValue(e, "life", "0");
DispatchKeyValue(e, "BoltWidth", "5.0");
DispatchKeyValue(e, "StrikeTime", "0");
DispatchKeyValue(e, "TouchType", "4");
SetEntPropVector(e, Prop_Data, "m_vecEndPos", wS_UserPos2[client]);
DispatchKeyValue(e, "spawnflags", "1");
DispatchSpawn(e);
HookSingleEntityOutput(e, "OnTouchedByEntity", wS_BeamTouched);
wS_MyLasersCount[client] += 1;
if (g_LaserPrice > 0)
SetEntProp(client, Prop_Send, "m_iAccount", GetEntProp(client, Prop_Send, "m_iAccount") - g_LaserPrice);
wS_UserPos1[client][0] = 387335538.0;
wS_UserPos2[client][0] = 387335538.0;
EmitAmbientSound(wS_SOUND_CREATE, NULL_VECTOR, e);
wS_SchowMenu(client);
}
else
PrintToChat(client, "\x04Нужно выбрать две позиции (начало и конец)");
ClientCommand(client, "playgamesound \"%s\"", wS_SOUND_SELECT);
}
public KillLaser_Panel(Handle:menu, MenuAction:action, client, item)
{
if (action != MenuAction_Select || item != 1)
return;
new index = EntRefToEntIndex(wS_MyBeamRef[client]);
if (index > MaxClients)
{
AcceptEntityInput(index, "Kill");
wS_MyBeamRef[client] = 0;
if (g_LaserPrice > 0)
{
new cash = GetEntProp(client, Prop_Send, "m_iAccount") + g_LaserPrice;
if (cash > 16000) cash = 16000;
SetEntProp(client, Prop_Send, "m_iAccount", cash);
}
wS_MyLasersCount[client] -= 1;
ClientCommand(client, "playgamesound \"%s\"", wS_SOUND_SELECT);
wS_SchowMenu(client);
}
}
bool:wS_HaveAccessToMenu(client)
{
if (!IsPlayerAlive(client))
{
PrintToChat(client, "\x04Вы мертвы");
return false;
}
if (wS_MyLasersCount[client] >= g_LaserLimit)
{
PrintToChat(client, "\x04Вы уже использовали все лазеры");
return false;
}
if (g_LaserPrice > 0 && GetEntProp(client, Prop_Send, "m_iAccount") < g_LaserPrice)
{
PrintToChat(client, "\x04Стоимость лазера: $%d", g_LaserPrice);
return false;
}
return true;
}
public wS_BeamTouched(const String:output[], ent, activator, Float:delay)
{
decl String:t[5]; t[0] = '\0'; GetEntPropString(ent, Prop_Data, "m_iName", t, 15);
if (GetClientTeam(activator) != StringToInt(t))
{
decl Float:origin[3]; GetClientAbsOrigin(activator, origin);
ForcePlayerSuicide(activator);
TE_SetupExplosion(origin, g_Laser, 50.0, 0, TE_EXPLFLAG_NONE, 150, 1); TE_SendToAll();
EmitAmbientSound(wS_SOUND_EXPLOD, NULL_VECTOR, activator);
new ragdoll = GetEntPropEnt(activator, Prop_Send, "m_hRagdoll");
if (ragdoll > MaxClients && IsValidEntity(ragdoll))
{
IgniteEntity(ragdoll, 3.0);
CreateTimer(3.0, KillRagdoll, EntIndexToEntRef(ragdoll), TIMER_FLAG_NO_MAPCHANGE);
}
if (GetConVarBool(h_beam_clear))
{
AcceptEntityInput(ent, "Kill");
return;
}
}
else if (GetEntPropEnt(ent, Prop_Send, "m_PredictableID") == activator)
{
wS_MyBeamRef[activator] = EntIndexToEntRef(ent);
SendPanelToClient(g_ClearBeamPanel, activator, KillLaser_Panel, 0);
}
AcceptEntityInput(ent, "TurnOff");
CreateTimer(0.1, ActivateBeam, ent, TIMER_FLAG_NO_MAPCHANGE);
}
public Action:ActivateBeam(Handle:timer, any:ent)
{
if (IsValidEntity(ent)) AcceptEntityInput(ent, "TurnOn");
return Plugin_Stop;
}
wS_GetPos(client, posNum)
{
decl Float:angles[3];
if (!GetClientEyeAngles(client, angles))
return;
decl Float:EyePosition[3];
GetClientEyePosition(client, EyePosition);
TR_TraceRayFilter(EyePosition, angles, MASK_SOLID, RayType_Infinite, TraceFilter, client);
TR_GetEndPosition(posNum == 1 ? wS_UserPos1[client] : wS_UserPos2[client]);
}
public bool:TraceFilter(entity, mask, any:client) return entity != client;
public Action:KillRagdoll(Handle:timer, any:ref)
{
if (g_Dissolver < 1)
return;
new index = EntRefToEntIndex(ref);
if (index <= MaxClients)
return;
decl String:name[15]; Format(name, 15, "wS_%d", index);
DispatchKeyValue(index, "targetname", name);
DispatchKeyValue(g_Dissolver, "target", name);
DispatchKeyValue(g_Dissolver, "magnitude", "1");
DispatchKeyValue(g_Dissolver, "dissolvetype", "0");
AcceptEntityInput(g_Dissolver, "Dissolve");
}