#include <sourcemod>
#include <sdktools>
#include <tf2>
#include <tf2_stocks>
#include <dukehacks>
#define SND_EXPLODE "weapons/explode2.wav"
#define SND_LASER "weapons/teleporter_receive.wav"
#define LASER "sprites/laser.vmt"
#define TEAM_RED 2
#define TEAM_BLUE 3
#define COLOR_RED "255 0 0"
#define COLOR_BLUE "0 0 255"
new smoke, explosion;
new HammerTime[MAXPLAYERS + 1][5];
new Hammers[MAXPLAYERS + 1][2];
new bool:UsingControlBanHammer[MAXPLAYERS + 1];
new bool:UsingLockOnBanHammer[MAXPLAYERS + 1];
new bool:Hammered[MAXPLAYERS + 1];
new bool:centered[MAXPLAYERS + 1];
new bool:targetCount;
new m_vecEndPos;
new maxplayers, maxentities;
public Plugin:myinfo =
{
name = "Ban Hammer",
author = "Goss",
description = "Calls down the Orbitial Ban hammer on a player",
version = "1.0",
url = "http://www.bhslaughter.com/"
}
public OnPluginStart ( )
{
m_vecEndPos = FindSendPropInfo("CBeam", "m_vecEndPos");
LoadTranslations("common.phrases");
HookEvent("player_death", Events);
HookEvent("player_spawn", Events);
HookEvent("player_disconnect", Events);
RegAdminCmd("sm_hammer", Command_LockBanHammer, ADMFLAG_CUSTOM4, "");
RegAdminCmd("sm_aimhammer", Command_ControlHammer, ADMFLAG_CUSTOM4, "");
RegAdminCmd("sm_clear", Command_Clear, ADMFLAG_CUSTOM4, "");
//RegAdminCmd("sm_bhammer", Command_BanHammer, ADMFLAG_CUSTOM4, "");
}
public OnMapStart ( )
{
maxplayers = GetMaxClients();
maxentities = GetMaxEntities();
explosion = PrecacheModel("sprites/floorfire4_.vmt", true);
smoke = PrecacheModel ("sprites/steam1.vmt");
PrecacheSound(SND_EXPLODE, true);
PrecacheSound(SND_LASER, true);
PrecacheModel(LASER, true);
}
public OnEventShutdown()
{
UnhookEvent("player_death", Events);
UnhookEvent("player_spawn", Events);
UnhookEvent("player_disconnect", Events);
}
public OnGameFrame()
{
for(new i = 1; i <= maxplayers; i++)
{
if(IsClientInGame(i) && !IsClientObserver(i) && IsPlayerAlive(i))
{
if(centered[i] || targetCount)
{
if(UsingControlBanHammer[i])
{
new hammer = HammerTime[i][3];
if(IsValidEntity(hammer))
{
new Float:position[3];
GetEyePosition(i, position);
TeleportEntity(hammer, position, NULL_VECTOR,NULL_VECTOR);
position[2] += 2000;
SetEntDataVector(hammer, m_vecEndPos, position, true);
}
}
if(Hammered[i])
{
new hammer = Hammers[i][1];
if(IsValidEntity(hammer))
{
new Float:position[3];
GetClientAbsOrigin(i, position);
TeleportEntity(hammer, position, NULL_VECTOR,NULL_VECTOR);
position[2] += 2000;
SetEntDataVector(hammer, m_vecEndPos, position, true);
}
}
}
}
}
}
public Action:Events(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
UsingControlBanHammer[client] = false;
UsingLockOnBanHammer[client] = false;
Hammered[client] = false;
}
public Action:Command_Clear(client, args)
{
for(new i = 0; i <= maxentities; i++)
{
if(IsValidEntity(i))
{
decl String:classname[32];
GetEdictClassname(i, classname, sizeof(classname));
if(StrEqual(classname, "env_beam"))
{
AcceptEntityInput(i,"kill");
PrintToChatAll("Deleted %s - %i", classname, i);
}
}
}
return Plugin_Handled;
}
public Action:Command_BanHammer(client, args)
{
decl String:s_Arg[32];
decl String:reason[32];
decl String:time[32];
GetCmdArg (1, s_Arg, sizeof(s_Arg));
GetCmdArg (2, time, sizeof(time));
GetCmdArg (3, reason, sizeof(reason));
new target = FindTarget ( client, s_Arg );
if (target == -1 || !IsPlayerAlive(target))
{
return Plugin_Handled;
}
decl String:admin[32];
decl String:player[32];
GetClientName(client, admin, sizeof(admin));
GetClientName(target, player, sizeof(player));
ServerCommand("sm_freeze #%d", GetClientUserId(target));
UsingLockOnBanHammer[client] = true;
new Float:position[3];
GetClientAbsOrigin(target, position);
CreateBeams(client, position, target);
CreateTimer(1.5, Explode, target);
PrintToChatAll ("%s struck down %s with the Orbital Banned Hammer", admin, player );
new Handle:data = CreateDataPack();
CreateTimer(5.0, Ban, data);
WritePackCell(data, target);
WritePackString(data, reason);
return Plugin_Handled;
}
public Action:Ban(Handle:timer, Handle:data)
{
ResetPack(data);
new target = ReadPackCell(data);
decl String:reason[32];
ReadPackString(data, reason, sizeof(reason));
BanClient(target, 0, BANFLAG_AUTO, reason, reason, "Ban Hammer");
CloseHandle(data);
}
public Action:Command_LockBanHammer(client, args)
{
if(!UsingControlBanHammer[client] && !UsingLockOnBanHammer[client])
{
UsingLockOnBanHammer[client] = true;
if (args < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_hammer <#userid|name>");
return Plugin_Handled;
}
decl String:arg[65];
GetCmdArg(1, arg, sizeof(arg));
decl String:target_name[MAX_TARGET_LENGTH];
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
if ((target_count = ProcessTargetString(arg, client, target_list, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name, sizeof(target_name), tn_is_ml)) <= 0)
{
ReplyToTargetError(client, target_count);
return Plugin_Handled;
}
if(target_count > 1)
{
targetCount = true;
EmitSoundToAll(SND_LASER);
}
else
{
targetCount = false;
}
new targetIndex;
for (new i = 0; i < target_count; i++)
{
new Float:position[3];
targetIndex = target_list[i];
GetClientAbsOrigin(targetIndex, position);
if(!Hammered[targetIndex])
{
if(IsClientInGame(targetIndex) && !IsClientObserver(targetIndex) && IsPlayerAlive(targetIndex))
{
Hammered[targetIndex] = true;
CreateBeams(client, position, targetIndex);
CreateTimer(1.5, Explode, targetIndex);
decl String:target[32];
decl String:admin[32];
GetClientName(targetIndex, target, sizeof(target));
GetClientName(client, admin, sizeof(admin));
PrintToChatAll ("%s struck down %s with the Orbital Hammer", admin, target );
}
}
}
}
return Plugin_Handled;
}
public Action:Command_ControlHammer (client, args)
{
if(IsClientInGame(client) && !IsClientObserver(client) && IsPlayerAlive(client))
{
if(!UsingControlBanHammer[client] && !UsingLockOnBanHammer[client])
{
UsingControlBanHammer[client] = true;
new Float:position[3];
GetEyePosition(client, position);
CreateBeams(client, position, client);
}
}
return Plugin_Handled;
}
public CreateBeams(any:client, Float:position[3], any:target)
{
if(!targetCount)
{
position[0] -= 100;
Beam(client, position, 0, target);
position[0] += 200;
Beam(client, position, 1, target);
position[0] -= 100;
position[1] -= 100;
Beam(client, position, 2, target);
position[1] += 200;
Beam(client, position, 3, target);
}
else
{
Beam(client, position, 3, target);
centered[client] = true;
}
new Handle:data = CreateDataPack();
CreateTimer(3.5, TurnOffControl, data);
WritePackCell(data, client);
WritePackCell(data, target);
}
public Beam(any:client, Float:position[3], array, any:target)
{
decl String:beam[3];
Format(beam, sizeof(beam), "%d", array);
decl String:name[8];
Format(name, sizeof(name), "%d", client);
new ent = CreateEntityByName("env_beam");
TeleportEntity(ent, position, NULL_VECTOR, NULL_VECTOR);
HammerTime[client][array] = ent;
SetEntityModel(ent, LASER);
if(UsingControlBanHammer[client])
{
TeleportEntity(ent, position, NULL_VECTOR, NULL_VECTOR);
position[2] += 1000;
SetEntPropVector(ent, Prop_Data, "m_vecEndPos", position);
}
DispatchKeyValue(ent, "targetname", beam);
//DispatchKeyValue(client, "parentname", name);
//DispatchKeyValue(ent, "parentname", name);
//SetVariantString(name);
//AcceptEntityInput(ent, "SetParent");
//SetVariantString(name);
//AcceptEntityInput(ent, "SetParentAttachment");
//SetVariantString(name);
//AcceptEntityInput(ent, "SetParentAttachmentMaintainOffset");
DispatchKeyValue(ent, "TouchType", "3");
DispatchKeyValue(ent, "damage", "50");
DispatchSpawn(ent);
SetEntPropEnt(ent, Prop_Data, "m_hOwnerEntity", target);
if(UsingControlBanHammer[client] && array == 3)
{
SetEntPropEnt(ent, Prop_Data, "m_hOwnerEntity", client);
HookSingleEntityOutput(ent, "OnTouchedByEntity", BeamTouched, false);
CreateTimer(0.4, TE_Explode, client);
}
if(!UsingControlBanHammer[client] && array == 3)
{
Hammers[target][1] = ent;
}
if(targetCount)
{
SetEntPropFloat(ent, Prop_Data, "m_fWidth", 20.0);
SetEntPropFloat(ent, Prop_Data, "m_fEndWidth", 20.0);
CreateTimer(3.0, UnhookBeam, ent);
}
else
{
SetEntPropFloat(ent, Prop_Data, "m_fWidth", 4.0);
SetEntPropFloat(ent, Prop_Data, "m_fEndWidth", 4.0);
}
decl String:teamColor[32];
if(GetClientTeam(client) == TEAM_RED)
{
teamColor = COLOR_RED;
AttachParticle(ent, "player_recent_teleport_red", 3.0);
}
else
{
teamColor = COLOR_BLUE;
AttachParticle(ent, "player_recent_teleport_blue", 3.0);
}
DispatchKeyValue(ent, "rendercolor", teamColor);
ActivateEntity(ent);
AcceptEntityInput(ent, "TurnOn");
if(!targetCount)
{
EmitSoundToAll(SND_LASER, ent, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, SNDVOL_NORMAL, 100, ent, position, NULL_VECTOR, true, 0.0);
}
}
public Action:UnhookBeam(Handle:timer, any:entity)
{
if(IsValidEntity(entity))
{
UnhookSingleEntityOutput(entity, "OnBreak", BeamTouched);
AcceptEntityInput(entity,"kill");
}
}
public BeamTouched(const String:output[], caller, activator, Float:delay)
{
AcceptEntityInput(caller, "TurnOff");
AcceptEntityInput(caller, "TurnOn");
//decl String:name[2];
//GetEntPropString(caller, Prop_Data, "m_iName", name, sizeof(name));
ForcePlayerSuicide(activator);
new owner = GetEntPropEnt(caller, Prop_Data, "m_hOwnerEntity");
decl String:admin[32];
decl String:player[32];
GetClientName(owner, admin, sizeof(admin));
GetClientName(activator, player, sizeof(player));
PrintToChatAll ("%s struck down %s with the Orbital Hammer", admin, player );
}
//Timer for lockon explode
public Action:Explode(Handle:timer, any:entity)
{
FakeClientCommand(entity, "explode");
}
public ResultType:dhOnEntitySpawned(edict)
{
if(IsValidEntity(edict))
{
if(!targetCount)
{
decl String:classname[32];
GetEdictClassname(edict, classname, sizeof(classname));
if(StrEqual(classname, "env_beam"))
{
decl String:targetname[8];
GetEntPropString(edict, Prop_Data, "m_iName", targetname, sizeof(targetname));
new Float:k = 0.0;
if(StrEqual(targetname, "0"))
{
for(new j = 0; j < 100; j++)
{
CreateTimer(0.0 + k, CenterBeam0, edict);
k += 0.005;
}
}
else if(StrEqual(targetname, "1"))
{
for(new j = 0; j < 100; j++)
{
CreateTimer(0.0 + k, CenterBeam1, edict);
k += 0.005;
}
}
else if(StrEqual(targetname, "2"))
{
for(new j = 0; j < 100; j++)
{
CreateTimer(0.0 + k, CenterBeam2, edict);
k += 0.005;
}
}
else if(StrEqual(targetname, "3"))
{
for(new j = 0; j < 100; j++)
{
CreateTimer(0.0 + k, CenterBeam3, edict);
k += 0.005;
}
}
}
}
}
}
public Action:TE_Explode(Handle:timer, any:client)
{
new Float:position[3];
if(UsingControlBanHammer[client])
{
GetEyePosition(client, position);
}
else
{
GetClientAbsOrigin(client, position);
}
TE_SetupExplosion(position, explosion, 0.1, 1, 4, 0, 0);
TE_SendToAll ( );
EmitSoundToAll(SND_EXPLODE, SOUND_FROM_WORLD, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, SNDVOL_NORMAL, 100, -1, position, NULL_VECTOR, true, 0.0);
TE_SetupSmoke (position, smoke, 10.0, 10 );
TE_SendToAll ( );
}
public Action:TurnOffControl(Handle:timer, Handle:data)
{
ResetPack(data);
new client = ReadPackCell(data);
new target = ReadPackCell(data);
UsingControlBanHammer[client] = false;
UsingLockOnBanHammer[client] = false;
Hammered[target] = false;
centered[client] = false;
targetCount = false;
}
public Action:CenterBeam0(Handle:timer, any:edict)
{
static rates[MAXPLAYERS + 1] = 0;
if(IsValidEntity(edict))
{
new client = GetEntPropEnt(edict, Prop_Data, "m_hOwnerEntity");
if(IsValidEntity(client))
{
new Float:position[3];
if(UsingControlBanHammer[client])
{
GetEyePosition(client, position);
}
else
{
GetClientAbsOrigin(client, position);
}
position[0] -= 100;
position[0] += rates[client];
TeleportEntity(edict, position, NULL_VECTOR,NULL_VECTOR);
position[2] += 2000;
SetEntDataVector(edict, m_vecEndPos, position, true);
rates[client]++;
if(rates[client] >= 100)
{
AcceptEntityInput(edict,"kill");
rates[client] = 0;
}
}
}
}
public Action:CenterBeam1(Handle:timer, any:edict)
{
static rates[MAXPLAYERS + 1] = 0;
if(IsValidEntity(edict))
{
new client = GetEntPropEnt(edict, Prop_Data, "m_hOwnerEntity");
if(IsValidEntity(client))
{
new Float:position[3];
if(UsingControlBanHammer[client])
{
GetEyePosition(client, position);
}
else
{
GetClientAbsOrigin(client, position);
}
position[0] += 100;
position[0] -= rates[client];
TeleportEntity(edict, position, NULL_VECTOR,NULL_VECTOR);
position[2] += 2000;
SetEntDataVector(edict, m_vecEndPos, position, true);
rates[client]++;
if(rates[client] >= 100)
{
AcceptEntityInput(edict,"kill");
rates[client] = 0;
}
}
}
}
public Action:CenterBeam2(Handle:timer, any:edict)
{
static rates[MAXPLAYERS + 1] = 0;
if(IsValidEntity(edict))
{
new client = GetEntPropEnt(edict, Prop_Data, "m_hOwnerEntity");
if(IsValidEntity(client))
{
new Float:position[3];
if(UsingControlBanHammer[client])
{
GetEyePosition(client, position);
}
else
{
GetClientAbsOrigin(client, position);
}
position[1] -= 100;
position[1] += rates[client];
TeleportEntity(edict, position, NULL_VECTOR,NULL_VECTOR);
position[2] += 2000;
SetEntDataVector(edict, m_vecEndPos, position, true);
rates[client]++;
if(rates[client] >= 100)
{
AcceptEntityInput(edict,"kill");
rates[client] = 0;
}
}
}
}
public Action:CenterBeam3(Handle:timer, any:edict)
{
static rates[MAXPLAYERS + 1] = 0;
if(IsValidEntity(edict))
{
new client = GetEntPropEnt(edict, Prop_Data, "m_hOwnerEntity");
if(IsValidEntity(client))
{
new Float:position[3];
if(UsingControlBanHammer[client])
{
GetEyePosition(client, position);
}
else
{
GetClientAbsOrigin(client, position);
}
position[1] += 100;
position[1] -= rates[client];
TeleportEntity(edict, position, NULL_VECTOR,NULL_VECTOR);
position[2] += 2000;
SetEntDataVector(edict, m_vecEndPos, position, true);
rates[client]++;
if(rates[client] >= 100)
{
centered[client] = true;
SetEntPropFloat(edict, Prop_Data, "m_fWidth", 20.0);
SetEntPropFloat(edict, Prop_Data, "m_fEndWidth", 20.0);
rates[client] = 0;
CreateTimer(3.0, UnhookBeam, edict);
}
}
}
}
public GetEyePosition(client, Float:array[3])
{
new Float:start[3], Float:end[3], Float:angle[3];
GetClientEyePosition(client, start);
GetClientEyeAngles(client, angle);
GetAngleVectors(angle, end, NULL_VECTOR, NULL_VECTOR);
NormalizeVector(end, end);
TR_TraceRayFilter(start, angle, MASK_PLAYERSOLID, RayType_Infinite, TraceRayDontHitSelf, client);
if (TR_DidHit(INVALID_HANDLE))
{
TR_GetEndPosition(end, INVALID_HANDLE);
array = end;
}
}
public bool:TraceRayDontHitSelf(entity, mask, any:data)
{
decl String:classname[64];
GetEdictClassname(entity, classname, sizeof(classname));
if(entity == data) // Check if the TraceRay hit the itself.
{
return false // Don't let the entity be hit
}
else if(StrEqual(classname, "player"))
{
return false;
}
return true // It didn't hit itself
}
public AttachParticle(entity, String:particleType[], Float:time)
{
new particle = CreateEntityByName("info_particle_system");
decl String:name[64];
if (IsValidEntity(particle))
{
new Float:position[3];
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", position);
position[2] += 5;
TeleportEntity(particle, position, NULL_VECTOR, NULL_VECTOR);
Format(name, sizeof(name), "target%i", entity);
DispatchKeyValue(entity, "targetname", name);
DispatchKeyValue(particle, "targetname", "tf2particle");
DispatchKeyValue(particle, "parentname", name);
DispatchKeyValue(particle, "effect_name", particleType);
DispatchSpawn(particle);
SetVariantString(name);
AcceptEntityInput(particle, "SetParent");
SetVariantString("flag");
AcceptEntityInput(particle, "SetParentAttachment");
ActivateEntity(particle);
AcceptEntityInput(particle, "start");
CreateTimer(time, DeleteParticle, particle);
}
}
public Action:DeleteParticle(Handle:timer, any:particle)
{
if (IsValidEntity(particle))
{
decl String:classname[64];
GetEdictClassname(particle, classname, sizeof(classname));
if (StrEqual(classname, "info_particle_system", false))
{
RemoveEdict(particle);
}
}
}