Code:
#include <sourcemod>
#include <sdktools>
#pragma semicolon 1
#pragma newdecls required
#define SURVIVOR_TEAM 2
ConVar g_PluginEnable;
ConVar g_MaxDistanceApart;
ConVar g_PosUpdateInterval;
ConVar g_hTeleTime;
float cPos[MAXPLAYERS+1][3];
public Plugin myinfo = {
name = "Teleport 'Fallen behind' survivors",
author = "Gravity",
version = "0.0.0",
description = "Teleports players who are 'fallen behind' to another survivor randomly adjustable by cvar.",
url = "https://forums.alliedmods.net/showthread.php?t=318682"
};
public void OnPluginStart()
{
g_PluginEnable = CreateConVar("l4d_survivorteleporter_enabled", "1", "Enable or disable plugin.", 0, true, 0.0, true, 1.0);
g_hTeleTime = CreateConVar("l4d_survivorteleporter_delay", "3.0", "delay before teleporting a player.");
g_MaxDistanceApart = CreateConVar("l4d_survivorteleporter_distance", "800.0", "The initial radius for how far away survivors must be before teleported.");
g_PosUpdateInterval = CreateConVar("l4d_survivorteleporter_interval", "5.0", "How often the plugin should run check on survivor positions.", 0, true, 1.0, true, 10.0);
HookEvent("player_spawn", Event_OnPlayerSpawn);
}
public void Event_OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast)
{
if (!GetConVarBool(g_PluginEnable))return;
int userid = event.GetInt("userid");
int client = GetClientOfUserId(userid);
if( IsValidClient(client) && GetClientTeam(client) == SURVIVOR_TEAM )
{
CreateTimer(GetConVarFloat(g_PosUpdateInterval), TimerCheckForClientPos, GetClientUserId(client), TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
}
}
public Action TimerCheckForClientPos(Handle timer, int data)
{
int client = GetClientOfUserId(data);
if( client && IsPlayerAlive(client) )
{
// If behind specified radius of any survivor, teleport.
int rndSurvivors = GetRandomSurvivor();
float rndFPos[3];
// Update position every 5 seconds
GetClientAbsOrigin(client, cPos[client]);
GetClientAbsOrigin(rndSurvivors, rndFPos);
if( IsFallenBehind(cPos[client], rndFPos) )
{
PrintToChat(client, "You are behind the team, except you will be teleported soon!");
CreateTimer(GetConVarFloat(g_hTeleTime), Timer_TeleportPlayer, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);
}
}
return Plugin_Continue;
}
public Action Timer_TeleportPlayer(Handle timer, int data)
{
int client = GetClientOfUserId(data);
int rndSurvivors = GetRandomSurvivor();
float fRandomPosition[3];
GetClientAbsOrigin(rndSurvivors, fRandomPosition);
if( client && IsClientInGame(client) && rndSurvivors > 0 )
{
TeleportEntity(client, fRandomPosition, NULL_VECTOR, NULL_VECTOR);
}
}
//credits hardcoop
/** @return: the index to a random survivor */
int GetRandomSurvivor() {
int survivors[MAXPLAYERS];
int numSurvivors = 0;
for( int i = 1; i < MAXPLAYERS; i++ ) {
if( IsValidClient(i) && GetClientTeam(i) == SURVIVOR_TEAM ) {
survivors[numSurvivors] = i;
numSurvivors++;
}
}
return survivors[GetRandomInt(0, numSurvivors - 1)];
}
bool IsFallenBehind( float vec1[3], float vec2[3] )
{
if( GetVectorDistance(vec1, vec2) >= GetConVarFloat(g_MaxDistanceApart) )
{
return true;
}
return false;
}
bool IsValidClient( int client )
{
if( client > 0 && client <= MaxClients && IsClientInGame(client) ) return true;
else return false;
}