PHP Code:
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
bool IsPlayerGhost[MAXPLAYERS+1] = {false, ...};
public void OnPluginStart()
{
RegConsoleCmd("ghost", Command_GhostToggle);
}
public void OnMapStart()
{
int ent = -1;
while ((ent = FindEntityByClassname(ent, "func_door")) != -1)
SDKHook(ent, SDKHook_ShouldCollide, ShouldCollide);
while ((ent = FindEntityByClassname(ent, "func_door_rotating")) != -1)
SDKHook(ent, SDKHook_ShouldCollide, ShouldCollide);
while ((ent = FindEntityByClassname(ent, "func_lookdoor")) != -1)
SDKHook(ent, SDKHook_ShouldCollide, ShouldCollide);
while ((ent = FindEntityByClassname(ent, "prop_door_rotating")) != -1)
SDKHook(ent, SDKHook_ShouldCollide, ShouldCollide);
}
public void OnEntityCreated(int entity, const char[] classname)
{
if(StrEqual(classname, "prop_door_rotating", false) || StrEqual(classname, "func_lookdoor", false) || StrEqual(classname, "func_door_rotating", false) || StrEqual(classname, "func_door", false))
SDKHook(entity, SDKHook_ShouldCollide, ShouldCollide );
}
public Action Command_GhostToggle(int client, int args)
{
IsPlayerGhost[client] = !IsPlayerGhost[client];
if(IsPlayerGhost[client])
PrintToChat(client, "\x01\x02 \x10You have became a ghost");
else
PrintToChat(client, "\x01\x02 \x02You are no longer a ghost");
}
int GetClosestPlayerNear(int ent)
{
float entPos[3];
GetEntPropVector(ent, Prop_Data, "m_vecAbsOrigin", entPos);
float closestDistance = 9999999.0;
int closestPlayer = -1;
for(int client = 1;client<MaxClients+1;client++)
{
if(IsValidClient(client) && IsPlayerAlive(client))
{
float playerPos[3];
GetClientAbsOrigin(client, playerPos);
float dist = GetVectorDistance(entPos, playerPos);
if(dist < closestDistance)
{
closestDistance = dist;
closestPlayer = client;
}
}
}
return closestPlayer;
}
public bool ShouldCollide(entity, collisiongroup, contentsmask, bool result)
{
int player = GetClosestPlayerNear(entity);
if(player != -1)
if(IsPlayerGhost[player])
return false;
return true;
}
bool IsValidClient(int client)
{
if (!(1 <= client <= MaxClients) || !IsClientConnected(client) || !IsClientInGame(client) || IsClientSourceTV(client) || IsClientReplay(client))
return false;
return true;
}
It's not the best solution but it should be good enough for a ghost dm that works cross source engine games without specfic detour hooks.