I have coded a plugin and I want to know your guys' input as to if it is the most optimized way to perform what I want in the plugin. As you will probably be able to tell, it is a respawn timer plugin for TF2. I also want to know if passing the UserID to the timer/frame callback is also necessary (I believe it is but I could be wrong).
PHP Code:
#pragma semicolon 1
#define PLUGIN_VERSION "1.0.0"
#include <sourcemod>
#include <tf2_stocks>
Handle hTimer[MAXPLAYERS+1];
ConVar hConVars[5];
bool bEnable, bBots, bCenter, bHint;
int iTime, iTimeleft[MAXPLAYERS+1];
methodmap Player {
public Player(int client) {
return view_as<Player>(client);
}
property int Index {
public get() {
return view_as<int>(this);
}
}
property int UserID {
public get() {
return GetClientUserId(this.Index);
}
}
property int Time {
public get() {
return iTimeleft[this.Index];
}
public set(int value) {
iTimeleft[this.Index] = value;
}
}
property bool Alive {
public get() {
return IsPlayerAlive(this.Index);
}
}
property bool Valid {
public get() {
return IsValidClient(this.Index);
}
}
property bool Fake {
public get() {
return IsFakeClient(this.Index);
}
}
public void Respawn() {
return TF2_RespawnPlayer(this.Index);
}
public void PrintText(const char[] buffer, any ...) {
int len = strlen(buffer);
char[] format = new char[len];
VFormat(format, len, buffer, 2);
if (bCenter)
PrintCenterText(this.Index, format);
if (bHint)
PrintHintText(this.Index, format);
}
public void DelTimer() {
DeleteTimer(this.Index);
}
}
public Plugin myinfo = {
name = "[TF2] Respawn Timer",
author = "Sgt. Gremulock",
description = "Respawn timer for TF2.",
version = PLUGIN_VERSION,
url = "grem-co.com"
};
public void OnPluginStart()
{
CreateConVar("sm_respawntimer_version", PLUGIN_VERSION, "Plugin's version.", FCVAR_NOTIFY|FCVAR_DONTRECORD);
hConVars[0] = CreateConVar("sm_respawntimer_enable", "1", "Enable/disable the plugin.\n(1 = Enable, 0 = Disable)", _, true, 0.0, true, 1.0);
hConVars[1] = CreateConVar("sm_respawntimer_bots", "1", "Enable/disable the respawn timer for bots.\n(1 = Enable, 0 = Disable)", _, true, 0.0, true, 1.0);
hConVars[2] = CreateConVar("sm_respawntimer_time", "5", "Time (in seconds) until player should respawn.\n(<1 = Instant (If value is <1, center & hint text will not display regardless of ConVar value.))", _, true, 0.0);
hConVars[3] = CreateConVar("sm_respawntimer_center_text", "1", "Display center text for seconds remaining until respawn.\n(1 = Enable, 0 = Disable)", _, true, 0.0, true, 1.0);
hConVars[4] = CreateConVar("sm_respawntimer_hint_text", "1", "Display hint text for seconds remaining until respawn.\n(1 = Enable, 0 = Disable)", _, true, 0.0, true, 1.0);
for (int i = 0; i < sizeof(hConVars); i++)
hConVars[i].AddChangeHook(ConVarUpdate);
AutoExecConfig(true, "RespawnTimer");
HookEvent("player_death", Event_PlayerDeath);
}
public void OnConfigsExecuted()
{
bEnable = hConVars[0].BoolValue;
bBots = hConVars[1].BoolValue;
iTime = hConVars[2].IntValue;
bCenter = hConVars[3].BoolValue;
bHint = hConVars[4].BoolValue;
}
public void ConVarUpdate(ConVar cvar, const char[] oldValue, const char[] newValue)
{
if (cvar == hConVars[0])
bEnable = hConVars[0].BoolValue;
if (cvar == hConVars[1])
bBots = hConVars[1].BoolValue;
if (cvar == hConVars[2])
iTime = hConVars[2].IntValue;
if (cvar == hConVars[3])
bCenter = hConVars[3].BoolValue;
if (cvar == hConVars[4])
bHint = hConVars[4].BoolValue;
}
public void OnClientDisconnect(int client)
{
Player player = Player(client);
player.Time = 0;
player.DelTimer();
}
public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
if (!bEnable || event.GetInt("death_flags") & TF_DEATHFLAG_DEADRINGER)
return;
Player player = Player(GetClientOfUserId(event.GetInt("userid")));
if (player.Valid)
if (!iTime)
RequestFrame(Frame_Callback, player.UserID);
else {
player.Time = iTime;
player.PrintText("You will respawn in %i seconds", player.Time);
hTimer[player.Index] = CreateTimer(1.0, Timer_Callback, player.UserID, TIMER_REPEAT);
}
}
public Action Timer_Callback(Handle timer, int userid)
{
Player player = Player(GetClientOfUserId(userid));
if (player.Valid)
{
if (player.Alive)
{
hTimer[player.Index] = null;
return Plugin_Stop;
}
if (!player.Time)
{
player.Respawn();
hTimer[player.Index] = null;
return Plugin_Stop;
}
player.Time--;
player.PrintText("You will respawn in %i seconds", player.Time);
return Plugin_Continue;
} else
player.DelTimer();
return Plugin_Stop;
}
public void Frame_Callback(int userid)
{
Player player = Player(GetClientOfUserId(userid));
if (player.Valid && !player.Alive)
player.Respawn();
}
stock bool IsValidClient(int client)
{
return client > 0 && client <= MaxClients && IsClientInGame(client) && !(!bBots && IsFakeClient(client));
}
stock void DeleteTimer(int client)
{
if (hTimer[client])
{
KillTimer(hTimer[client]);
hTimer[client] = null;
}
}