#include <sourcemod>
#include <tf2>
#include <tf2_stocks>
#include <sdktools_engine>
#include <sdktools_functions>
#include <sdktools_gamerules>
#include <sdkhooks>
#include <sdktools>
#include <sdktools_tempents>
#include <sdktools_tempents_stocks>
#pragma semicolon 1
float pos1[3];
float pos2[3];
int finalbomber = 0;
int rv = 0;
int pbomber = 0;
int bomber = 0;
int votes = 0;
int voters = 0;
int votesneeded = 0;
int sizeofteam = 0;
int reds[32];
int g_ExplosionSprite = -1;
char g_BoomSound[PLATFORM_MAX_PATH];
bool bomberused = false;
bool bomblock = true;
bool bomberdead = false;
bool bomberexists = false;
bool voted[MAXPLAYERS + 1] = {false, ...};
public OnPluginStart()
{
g_ExplosionSprite = PrecacheModel("materials/sprites/sprite_fire01.vmt");
PrecacheSound("ambient/explosions/explode_8.wav", true);
CreateConVar("bomberratio", "0.6", "voteratio for bomber", 0, true, 0.1, true, 1.0);
RegAdminCmd("sm_wtb", whosthebomber, 0);
RegAdminCmd("sm_iamtb", iamthebomber, 0);
CreateConVar("bombradius", "600", "Explosion radius.", 0, true, 50.0, true, 3000.0);
CreateConVar("damagebomb", "220", "Damage when bomb explodes.");
HookEvent("arena_round_start", roundstart);
HookEvent("arena_win_panel", arenawin);
}
public OnMapStart()
{
Handle gameConfig = LoadGameConfigFile("funcommands.games");
if (gameConfig == null)
{
SetFailState("Unable to load game config funcommands.games");
return;
}
if (GameConfGetKeyValue(gameConfig, "SoundBoom", g_BoomSound, sizeof(g_BoomSound)) && g_BoomSound[0])
{
PrecacheSound(g_BoomSound, true);
}
char buffer[PLATFORM_MAX_PATH];
if (GameConfGetKeyValue(gameConfig, "SpriteExplosion", buffer, sizeof(buffer)) && buffer[0])
{
g_ExplosionSprite = PrecacheModel(buffer);
}
delete gameConfig;
}
public Action whosthebomber(int client, int args)
{
if (bomblock == true)
{
PrintToChat(client, "You cannot vote at this time.");
voted[client] = false;
return Plugin_Handled;
}
if (IsClientInGame(client) == false && IsClientConnected(client) == false)
{
return Plugin_Handled;
}
ConVar imthebomber = FindConVar("bomberratio");
float cv_votesneeded = GetConVarFloat(imthebomber);
votesneeded = RoundToFloor(float(votes) * cv_votesneeded);
if (voted[client] == true)
{
PrintToChat(client, "[SM] You have already voted!");
}
if (voted[client] == false)
{
if (votes == 0)
{
votes++;
PrintToChatAll("%N has voted for 'Who's the Bomber', vote %i.", client, votes);
voted[client] = true;
}
else
{
votes++;
PrintToChatAll("%N has voted for 'Who's the Bomber', vote %i.", client, votes);
voted[client] = true;
}
}
if (votes >= votesneeded && finalbomber == 0 && bomberexists == false)
{
for (bomber = 1; bomber <= MaxClients; bomber++)
{
if (IsClientInGame(bomber) == true && IsPlayerAlive(bomber) == true)
{
if (TF2_GetClientTeam(bomber) == TFTeam_Red)
{
reds[rv++] = bomber;
}
}
}
sizeofteam = GetTeamClientCount(2);
pbomber = GetRandomInt(0, sizeofteam);
finalbomber = reds[pbomber];
PrintToChatAll("A bomber has been selected!");
bomberexists = true;
bomberused = false;
}
return Plugin_Handled;
}
public void OnClientDisconnect(int client)
{
if (IsClientInGame(client) == false)
{
return Plugin_Handled;
}
ConVar imthebomber = FindConVar("bomberratio");
float cv_votesneeded = GetConVarFloat(imthebomber);
if (voted[client] == true)
{
votes--;
}
voters--;
votesneeded = RoundToFloor(float(voters) * cv_votesneeded);
voted[client] = false;
return Plugin_Handled;
}
public void OnClientConnected(int client)
{
if (IsClientInGame(client) == false)
{
return Plugin_Handled;
}
ConVar imthebomber = FindConVar("bomberratio");
float cv_votesneeded = GetConVarFloat(imthebomber);
voted[client] = false;
voters++;
votesneeded = RoundToFloor(float(voters) * cv_votesneeded);
return Plugin_Handled;
}
public Action iamthebomber(int client, int args)
{
if (bomberexists == false)
{
PrintToChat(client, "Bomber does not exist yet!");
return Plugin_Handled;
}
if (IsClientInGame(client) == false && IsClientConnected(client) == false)
{
PrintToChat(client, "You are not the bomber!");
return Plugin_Handled;
}
if (bomberexists == true && finalbomber != client)
{
PrintToChat(client, "You are not the bomber!");
return Plugin_Handled;
}
else
{
if (bomberused == true && finalbomber == client)
{
PrintToChat(client, "Your bomb has been used!");
}
if (bomberused == false && finalbomber == client)
{
ServerCommand("sm_beacon %N", client);
TF2_AddCondition(client, TFCond_HalloweenBombHead, TFCondDuration_Infinite, 0);
GetClientAbsOrigin(client, pos1);
CreateTimer(5.0, bombexplode, _);
return Plugin_Handled;
}
return Plugin_Handled;
}
}
public Action bombexplode(Handle timer)
{
if (bomberdead == true)
{
return Plugin_Handled;
}
else
{
float EyeVec[3];
GetClientEyePosition(finalbomber, EyeVec);
ConVar bombrad = FindConVar("bombradius");
ConVar dbomb = FindConVar("damagebomb");
if (g_ExplosionSprite > -1)
{
TE_SetupExplosion(pos1, g_ExplosionSprite, 5.0, 1, 0, bombrad.IntValue, 5000);
TE_SendToAll();
}
if (g_BoomSound[0])
{
EmitAmbientSound(g_BoomSound, EyeVec, finalbomber, SNDLEVEL_RAIDSIREN);
}
for (int i = 1; i <= MaxClients; i++)
{
if (i != finalbomber && IsClientInGame(i) && IsPlayerAlive(i) && TF2_GetClientTeam(i) != TFTeam_Red)
{
if(!TF2_IsPlayerInCondition(i, TFCond_Ubercharged))
{
GetClientAbsOrigin(i, pos2);
if(GetVectorDistance(pos1, pos2) <= GetConVarFloat(bombrad))
{
int damage = GetConVarInt(dbomb);
if(GetClientHealth(i) - damage <= 0)
{
PrintToChatAll("%N has died from the explosion!", i);
}
SDKHooks_TakeDamage(i, 0, finalbomber, GetConVarFloat(dbomb), DMG_PREVENT_PHYSICS_FORCE|DMG_CRUSH|DMG_ALWAYSGIB);
}
}
ForcePlayerSuicide(finalbomber);
if (IsPlayerAlive(finalbomber) == false)
{
PrintToChatAll("The bomber, %N, is dead!", finalbomber);
TF2_RemoveCondition(finalbomber, TFCond_HalloweenBombHead);
bomberdead = true;
}
}
}
}
return Plugin_Handled;
}
public Action roundstart(Event event, const char[] name, bool dontBroadcast)
{
bomberused = false;
bomblock = false;
finalbomber = 0;
rv = 0;
votes = 0;
bomberdead = false;
bomberexists = false;
for (int i = 1; i <= MaxClients; i++)
{
voted[i] = false;
return Plugin_Continue;
}
return Plugin_Handled;
}
public Action arenawin(Event event, const char[] name, bool dontBroadcast)
{
bomberused = false;
bomblock = true;
finalbomber = 0;
rv = 0;
votes = 0;
bomberdead = false;
bomberexists = false;
for (int i = 1; i <= MaxClients; i++)
{
voted[i] = false;
return Plugin_Continue;
}
return Plugin_Handled;
}