#pragma semicolon 1;
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <morecolors>
#define PREFIX "[ZPROPS]"
enum Props
{
String:Name[80],
String:type[80],
String:model[256],
price,
health
}
new Props:g_Props[200][Props];
new PropsCount;
new g_Credits[MAXPLAYERS+1];
stock bool:IsValidPlayer(client, bool:alive = false, team = -1)
{
if(client>0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
{
if(alive && !IsPlayerAlive(client))
return false;
if(team != -1 && GetClientTeam(client) != team)
return false;
return true;
}
return false;
}
public Plugin:myinfo =
{
name = "ZPROPS",
author = "-=AWP=-",
description = "[New edition] Create Props.",
version = "1.0.2",
};
public OnPluginStart()
{
RegAdminCmd("zprops_addcred", Command_AddCred, ADMFLAG_ROOT);
RegAdminCmd("zprops_setcred", Command_SetCred, ADMFLAG_ROOT);
RegConsoleCmd("sm_zprops", Command_ZProps);
HookEvent("player_death", PlayerDeath);
}
public OnConfigsExecuted()
{
GetProps();
}
GetProps()
{
PropsCount = 0;
new Handle:kv = CreateKeyValues("Props");
if(!FileToKeyValues(kv, "cfg/zprops/props.cfg")) SetFailState("%s \"cfg/zprops/props.cfg\" not found", PREFIX);
if(KvGotoFirstSubKey(kv))
{
do
{
KvGetSectionName(kv, g_Props[PropsCount][Name], 80);
KvGetString(kv, "type", g_Props[PropsCount][type], 80, "prop_physics");
KvGetString(kv, "model", g_Props[PropsCount][model], 256, "models/error.mdl");
g_Props[PropsCount][price] = KvGetNum(kv, "price", 1);
g_Props[PropsCount][health] = KvGetNum(kv, "health", 500);
PrecacheModel(g_Props[PropsCount][model]);
PropsCount++;
}
while(KvGotoNextKey(kv));
}
CloseHandle(kv);
if(PropsCount == 0) SetFailState("%s Sorry. But Props in \"cfg/zprops/props.cfg\" not found", PREFIX);
}
public Action:Command_AddCred(client, args)
{
new String:arg1[64], String:arg2[64];
if(args == 2)
{
GetCmdArg(1, arg1, 64);
GetCmdArg(2, arg2, 64);
}
else return Plugin_Handled;
new target = FindTarget(client, arg1);
if(!IsValidPlayer(target))
{
return Plugin_Handled;
}
new cred = StringToInt(arg2);
g_Credits[target] += cred;
CPrintToChat(target, "\x07FF0000%s \x07FFFFFFВы получили \x07FF0000%d \x07FFFFFFкредитов \x07FFFF00от администратора!", PREFIX, cred);
return Plugin_Handled;
}
public Action:Command_SetCred(client, args)
{
new String:arg1[64], String:arg2[64];
if(args == 2)
{
GetCmdArg(1, arg1, 64);
GetCmdArg(2, arg2, 64);
}
else return Plugin_Handled;
new target = FindTarget(client, arg1);
if(!IsValidPlayer(target))
{
return Plugin_Handled;
}
new cred = StringToInt(arg2);
g_Credits[target] = cred;
CPrintToChat(target, "\x07FF0000%s \x07FFFFFFВаши кредиты были изменены администратором на \x07FF0000%d\x07FFFFFF.", PREFIX, cred);
return Plugin_Handled;
}
public OnClientPutInServer(client)
{
g_Credits[client] = 6;
}
public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "attacker"));
new victim = GetClientOfUserId(GetEventInt(event, "userid"));
if(IsValidPlayer(client) && IsValidPlayer(victim))
{
g_Credits[client]++;
}
}
public Action:Command_ZProps(client, args)
{
if(IsValidPlayer(client))
{
OpenMainMenu(client);
}
return Plugin_Handled;
}
OpenMainMenu(client, item = 0)
{
new Handle:menu = CreateMenu(MainSelect);
SetMenuTitle(menu, "======= %s =======\n \nВаши кредиты: %d\n \n", PREFIX, g_Credits[client]);
decl String:id[11];
decl String:buffer[80];
for(new i = 0; i < PropsCount; i++)
{
IntToString(i, id, sizeof(id));
Format(buffer, sizeof(buffer), "[%d кред.] %s", g_Props[i][price], g_Props[i][Name]);
if(g_Credits[client] >= g_Props[i][price]) AddMenuItem(menu, id, buffer);
else AddMenuItem(menu, id, buffer, ITEMDRAW_DISABLED);
}
SetMenuExitButton(menu, true);
DisplayMenuAtItem(menu, client, item, 0);
}
public MainSelect(Handle:menu, MenuAction:action, client, param2)
{
if(action == MenuAction_Select)
{
new String:sel[32];
GetMenuItem(menu, param2, sel, 32);
new selected = StringToInt(sel);
if(g_Credits[client] >= g_Props[selected][price])
{
CreateProps(client, selected);
}
else CPrintToChat(client, "\x07FF0000%s \x07FFFFFFУ вас не достаточно средств для покупки \x07FFFF00%s\x07FFFFFF.", PREFIX, g_Props[selected][Name]);
OpenMainMenu(client, GetMenuSelectionPosition());
}
}
CreateProps(client, selected)
{
if(IsValidPlayer(client))
{
new prop = CreateEntityByName(g_Props[selected][type]);
if(prop > 0)
{
decl Float:Pos[3];
GetLookPos(client, Pos);
DispatchKeyValueVector(prop, "origin", Pos);
decl String:zName[30];
Format(zName, sizeof(zName), "%d/%d", g_Props[selected][health], g_Props[selected][health]);
DispatchKeyValue(prop, "targetname", zName);
DispatchKeyValue(prop, "model", g_Props[selected][model]);
DispatchSpawn(prop);
SDKHook(prop, SDKHook_OnTakeDamage, OnTakeDamage);
SetEntityRenderMode(prop, RENDER_TRANSCOLOR);
SetEntityRenderColor(prop, 0, 255, 0, 255);
g_Credits[client] -= g_Props[selected][price];
CPrintToChat(client, "\x07FF0000%s \x07FFFFFFВы купили предмет: \"%s\" за %d кредитов.", PREFIX, g_Props[selected][Name], g_Props[selected][price]);
}
else LogError("%s Error. Can't create prop (Name: %s, type: %s)", PREFIX, g_Props[selected][Name], g_Props[selected][type]);
}
}
public Action:OnTakeDamage(entity, &attacker, &inflictor, &Float:damage, &damagetype)
{
decl String:eName[30];
if(GetEntPropString(entity, Prop_Data, "m_iName", eName, sizeof(eName)))
{
decl String:part[2][30];
if((ExplodeString(eName, "/", part, 2, 30)) == 2)
{
new hp = StringToInt(part[0]);
new maxhp = StringToInt(part[1]);
hp -= RoundFloat(damage);
if(hp > 0)
{
Format(eName, sizeof(eName), "%d/%d", hp, maxhp);
DispatchKeyValue(entity, "targetname", eName);
new percent = RoundFloat((float(hp) / float(maxhp)) * 100.0);
if(percent > 66) SetEntityRenderColor(entity, 0, 255, 0, 255);
else if(66 > percent > 33) SetEntityRenderColor(entity, 255, 255, 0, 255);
else if(33 > percent) SetEntityRenderColor(entity, 255, 0, 0, 255);
PrintCenterText(attacker, "Здоровье: %d/%d", hp, maxhp);
}
else
{
SDKUnhook(entity, SDKHook_OnTakeDamage, OnTakeDamage);
AcceptEntityInput(entity, "Break", attacker);
}
}
}
}
GetLookPos(client, Float:Lock_Pos[3])
{
decl Float:vAngles[3];
decl Float:vOrigin[3];
decl Float:vBuffer[3];
decl Float:vStart[3];
decl Float:Distance;
GetClientEyePosition(client, vOrigin);
GetClientEyeAngles(client, vAngles);
new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SHOT, RayType_Infinite, TraceEntityFilterPlayer);
TR_GetEndPosition(vStart, trace);
GetVectorDistance(vOrigin, vStart, false);
Distance = -50.0;
GetAngleVectors(vAngles, vBuffer, NULL_VECTOR, NULL_VECTOR);
Lock_Pos[0] = vStart[0] + (vBuffer[0]*Distance);
Lock_Pos[1] = vStart[1] + (vBuffer[1]*Distance);
Lock_Pos[2] = vStart[2] + (vBuffer[2]*Distance);
CloseHandle(trace);
}
public bool:TraceEntityFilterPlayer(entity, contentsMask)
{
return entity > GetMaxClients() || !entity;
}