if you are using an open source plugin ,it is better to share the code . or use this for test :
"this is a simple structure of an un-released plugin without a huge details"
PHP Code:
#include <sdktools>
Handle Plugin_Handle[3];
float LastValidPos[3];
public OnPluginStart()
{
StartPrepSDKCall(SDKCall_Player);
if (!PrepSDKCall_SetSignature(SDKLibrary_Server,"\x56\x8B\xF1\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75",16)
&& !PrepSDKCall_SetSignature(SDKLibrary_Server,"\x56\x8B\xF1\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75",16)
&& !PrepSDKCall_SetSignature(SDKLibrary_Server, "@_ZN13CTerrorPlayer12RoundRespawnEv",0))
SetFailState("SetSignature [RoundRespawn] : Unable to find address.");
Plugin_Handle[0] = EndPrepSDKCall();
Plugin_Handle[1] = FindConVar("director_no_death_check");
HookConVarChange(Plugin_Handle[1] , On_Death_Check_Changed);
if (GetConVarInt(Plugin_Handle[1])) Check(true);
}
public On_Death_Check_Changed(ConVar convar, const char[] oldValue, const char[] newValue)
{
if (StringToInt(newValue) && !StringToInt(oldValue)) Check(true);
if (!StringToInt(newValue) && StringToInt(oldValue)) Check(false);
}
Check(bool Enable)
{
if (Enable)
{
Plugin_Handle[2] = CreateConVar("director_no_death_respawn_time", "5.0", "time in seconds before re-spawn", FCVAR_NONE , true, 0.1);
HookEvent("player_activate",event_activate);
HookEvent("round_start", event_round_start);
HookEvent("player_death", event_player_death);
RestartRound();
}
else
{
UnhookEvent("player_activate",event_activate);
UnhookEvent("round_start", event_round_start);
UnhookEvent("player_death", event_player_death);
LastValidPos = {0.0 , 0.0 , 0.0};
delete Plugin_Handle[2];
}
}
RestartRound(){
ServerCommand("sm_cvar endround");//ServerCommand("sm_cvar mp_restartgame 1");
}
public event_activate(Handle event, char[] event_name, bool dontBroadcast){
CreateTimer( GetConVarFloat(Plugin_Handle[2]) ,Timer_Respawn , GetClientOfUserId(GetEventInt(event, "userid")) ,TIMER_FLAG_NO_MAPCHANGE);
}
public event_round_start(Handle event, char[] event_name, bool dontBroadcast){
LastValidPos = {0.0 , 0.0 , 0.0};
}
public event_player_death(Handle event, char[] event_name, bool dontBroadcast)
{
int client = GetClientOfUserId(GetEventInt(event, "userid"));
if (client && GetClientTeam(client) == 2)
{
if ( GetEntityFlags(client) & FL_ONGROUND || !(GetEventInt(event, "type") & 1048608) ) // 1048608 : DMG_FALL|DMG_CHOKE (no much exp in l4d2 so you can add more filters)
GetClientAbsOrigin(client, LastValidPos);
CreateTimer( GetConVarFloat(Plugin_Handle[2]) ,Timer_Respawn ,client , TIMER_FLAG_NO_MAPCHANGE);
}
}
public Action Timer_Respawn(Handle timer, any client)
{
if (IsClientInGame(client) && GetClientTeam(client) == 2 && !IsPlayerAlive(client)){
{
SDKCall(Plugin_Handle[0], client);
if (LastValidPos[0])
TeleportEntity(client, LastValidPos , NULL_VECTOR, NULL_VECTOR);
}
return Plugin_Handled;
}
* time to re-spawn dead survivors is 5 seconds by default controlled by
director_no_death_respawn_time .
* no round failure , survivors are unstoppable .
* the plugin won't work unless director_no_death_check is "1"
* I think it is meaningless to keep re-spawning dead players without any limit , as I don't have much exp. in l4d2 , but let me know if : a round time limit is required ?! or if you want to add something .
btw ,
It is likely that the plugin you are using is manually terminating the round after death , in other words : it cheats on director to achieve only one benefit which is : skipping [incap fail status] .
then it takes the death check on its own and end the round manually when all players are dead .
I'm sure that it is not in the cvar
director_no_death_check .
because if it was enabled , then it would force the director to ignore the survivors fail status [whatever is the case] . so that when all survivors fall down on the ground or
die the director acts like (I didn't see anything) .
As a result , the round won't end automatically , and the scenario of mission failure will never be called .
https://developer.valvesoftware.com/...ing%20scenario