Senior Member
Join Date: May 2019
Location: Argentina
|
02-23-2021
, 22:35
[L4D2] Ready-Up: bugs !ready and sounds
|
#1
|
All players are ready! but the round does not start.
Sounds don't work either
Code:
/ui/survival_medal.wav
/ui/beep07.wav
/buttons/blip1.wav
/buttons/blip2.wav
Here a video demostration
weapons/hegrenade/beep.wav works on c5m1_waterfront, but only the infected can listen. WATCH VIDEO
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <left4dhooks>
#include <builtinvotes>
#include <colors>
#define NULL_VELOCITY Float:{0.0, 0.0, 0.0}
#define MAX_FOOTERS 10
#define MAX_FOOTER_LEN 65
#define MAX_SOUNDS 5
#define SOUND "/ui/survival_medal.wav"
#define DEBUG 0
public Plugin:myinfo =
{
name = "L4D2 Ready-Up",
author = "CanadaRox, (Lazy unoptimized additions by Sir)",
description = "New and improved ready-up plugin.",
version = "9.2.3",
url = ""
};
enum L4D2Team
{
L4D2Team_None = 0,
L4D2Team_Spectator,
L4D2Team_Survivor,
L4D2Team_Infected
}
// Plugin Cvars
new Handle:l4d_ready_disable_spawns;
new Handle:l4d_ready_cfg_name;
new Handle:l4d_ready_survivor_freeze;
new Handle:l4d_ready_max_players;
new Handle:l4d_ready_enable_sound;
new Handle:l4d_ready_delay;
new Handle:l4d_ready_chuckle;
new Handle:l4d_ready_live_sound;
new Handle:g_hVote;
//AFK?!
new Float:g_fButtonTime[MAXPLAYERS+1];
// Game Cvars
new Handle:director_no_specials;
new Handle:god;
new Handle:sb_stop;
new Handle:survivor_limit;
new Handle:z_max_player_zombies;
new Handle:sv_infinite_primary_ammo;
new Handle:casterTrie;
new Handle:liveForward;
new Handle:menuPanel;
new Handle:readyCountdownTimer;
new String:readyFooter[MAX_FOOTERS][MAX_FOOTER_LEN];
new bool:hiddenPanel[MAXPLAYERS + 1];
new bool:hiddenManually[MAXPLAYERS + 1];
new bool:inLiveCountdown = false;
new bool:inReadyUp;
new bool:isPlayerReady[MAXPLAYERS + 1];
new footerCounter = 0;
new readyDelay;
new Handle:allowedCastersTrie;
new String:liveSound[256];
new bool:blockSecretSpam[MAXPLAYERS + 1];
new bool:bHostName;
new String:countdownSound[MAX_SOUNDS][]=
{
"/ui/beep07.wav",
"/ui/beep07.wav",
"/ui/beep07.wav",
"/ui/beep07.wav",
"/ui/beep07.wav"
};
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("AddStringToReadyFooter", Native_AddStringToReadyFooter);
CreateNative("IsInReady", Native_IsInReady);
CreateNative("IsClientCaster", Native_IsClientCaster);
CreateNative("IsIDCaster", Native_IsIDCaster);
liveForward = CreateGlobalForward("OnRoundIsLive", ET_Event);
RegPluginLibrary("readyup");
return APLRes_Success;
}
public OnPluginStart()
{
CreateConVar("l4d_ready_enabled", "1", "This cvar doesn't do anything, but if it is 0 the logger wont log this game.", 0, true, 0.0, true, 1.0);
l4d_ready_cfg_name = CreateConVar("l4d_ready_cfg_name", "", "Configname to display on the ready-up panel", FCVAR_PRINTABLEONLY);
l4d_ready_disable_spawns = CreateConVar("l4d_ready_disable_spawns", "0", "Prevent SI from having spawns during ready-up", 0, true, 0.0, true, 1.0);
l4d_ready_survivor_freeze = CreateConVar("l4d_ready_survivor_freeze", "1", "Freeze the survivors during ready-up. When unfrozen they are unable to leave the saferoom but can move freely inside", 0, true, 0.0, true, 1.0);
l4d_ready_max_players = CreateConVar("l4d_ready_max_players", "12", "Maximum number of players to show on the ready-up panel.", 0, true, 0.0, true, MAXPLAYERS+1.0);
l4d_ready_delay = CreateConVar("l4d_ready_delay", "3", "Number of seconds to count down before the round goes live.", 0, true, 0.0);
l4d_ready_enable_sound = CreateConVar("l4d_ready_enable_sound", "1", "Enable sound during countdown & on live");
l4d_ready_chuckle = CreateConVar("l4d_ready_chuckle", "1", "Enable chuckle during countdown");
l4d_ready_live_sound = CreateConVar("l4d_ready_live_sound", "/ui/survival_medal.wav", "The sound that plays when a round goes live");
HookConVarChange(l4d_ready_survivor_freeze, SurvFreezeChange);
HookEvent("round_start", RoundStart_Event);
HookEvent("player_team", PlayerTeam_Event);
casterTrie = CreateTrie();
allowedCastersTrie = CreateTrie();
director_no_specials = FindConVar("director_no_specials");
god = FindConVar("god");
sb_stop = FindConVar("sb_stop");
survivor_limit = FindConVar("survivor_limit");
z_max_player_zombies = FindConVar("z_max_player_zombies");
sv_infinite_primary_ammo = FindConVar("sv_infinite_primary_ammo");
RegAdminCmd("sm_caster", Caster_Cmd, ADMFLAG_BAN, "Registers a player as a caster so the round will not go live unless they are ready");
RegAdminCmd("sm_forcestart", ForceStart_Cmd, ADMFLAG_BAN, "Forces the round to start regardless of player ready status. Players can unready to stop a force");
RegAdminCmd("sm_fs", ForceStart_Cmd, ADMFLAG_BAN, "Forces the round to start regardless of player ready status. Players can unready to stop a force");
RegConsoleCmd("\x73\x6d\x5f\x62\x6f\x6e\x65\x73\x61\x77", Secret_Cmd, "Every player has a different secret number between 0-1023");
RegConsoleCmd("sm_hide", Hide_Cmd, "Hides the ready-up panel so other menus can be seen");
RegConsoleCmd("sm_show", Show_Cmd, "Shows a hidden ready-up panel");
AddCommandListener(Say_Callback, "say");
AddCommandListener(Say_Callback, "say_team");
RegConsoleCmd("sm_notcasting", NotCasting_Cmd, "Deregister yourself as a caster or allow admins to deregister other players");
RegConsoleCmd("sm_uncast", NotCasting_Cmd, "Deregister yourself as a caster or allow admins to deregister other players");
RegConsoleCmd("sm_ready", Ready_Cmd, "Mark yourself as ready for the round to go live");
RegConsoleCmd("sm_toggleready", ToggleReady_Cmd, "Toggle your ready status");
RegConsoleCmd("sm_unready", Unready_Cmd, "Mark yourself as not ready if you have set yourself as ready");
RegConsoleCmd("sm_return", Return_Cmd, "Return to a valid saferoom spawn if you get stuck during an unfrozen ready-up period");
RegConsoleCmd("sm_cast", Cast_Cmd, "Registers the calling player as a caster so the round will not go live unless they are ready");
RegConsoleCmd("sm_kickspecs", KickSpecs_Cmd, "Let's vote to kick those Spectators!");
RegServerCmd("sm_resetcasters", ResetCaster_Cmd, "Used to reset casters between matches. This should be in confogl_off.cfg or equivalent for your system");
RegServerCmd("sm_add_caster_id", AddCasterSteamID_Cmd, "Used for adding casters to the whitelist -- i.e. who's allowed to self-register as a caster");
#if DEBUG
RegAdminCmd("sm_initready", InitReady_Cmd, ADMFLAG_ROOT);
RegAdminCmd("sm_initlive", InitLive_Cmd, ADMFLAG_ROOT);
#endif
LoadTranslations("common.phrases");
CreateTimer(0.2, CheckStuff);
}
public Action:CheckStuff(Handle:timer)
{
bHostName = (FindPluginByFile("server_namer.smx") != INVALID_HANDLE);
}
public Action:Say_Callback(client, const String:command[], argc)
{
SetEngineTime(client);
}
public OnPluginEnd()
{
InitiateLive(false);
}
public OnMapStart()
{
/* OnMapEnd needs this to work */
GetConVarString(l4d_ready_live_sound, liveSound, sizeof(liveSound));
PrecacheSound(SOUND);
PrecacheSound("/buttons/blip1.wav");
PrecacheSound("/buttons/blip2.wav");
PrecacheSound("quake/prepare.mp3");
PrecacheSound(liveSound);
for (new i = 0; i < MAX_SOUNDS; i++)
{
PrecacheSound(countdownSound[i]);
}
for (new client = 1; client <= MAXPLAYERS; client++)
{
blockSecretSpam[client] = false;
}
readyCountdownTimer = INVALID_HANDLE;
new String:sMap[64];
GetCurrentMap(sMap, 64);
}
public Action:KickSpecs_Cmd(client, args)
{
if (IsClientInGame(client) && GetClientTeam(client) != 1)
{
if (IsNewBuiltinVoteAllowed())
{
new iNumPlayers;
decl iPlayers[MaxClients];
//list of non-spectators players
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) == 1))
{
continue;
}
iPlayers[iNumPlayers++] = i;
}
new String:sBuffer[64];
g_hVote = CreateBuiltinVote(VoteActionHandler, BuiltinVoteType_Custom_YesNo, BuiltinVoteAction_Cancel | BuiltinVoteAction_VoteEnd | BuiltinVoteAction_End);
Format(sBuffer, sizeof(sBuffer), "Kick Non-Admin & Non-Casting Spectators?");
SetBuiltinVoteArgument(g_hVote, sBuffer);
SetBuiltinVoteInitiator(g_hVote, client);
SetBuiltinVoteResultCallback(g_hVote, SpecVoteResultHandler);
DisplayBuiltinVote(g_hVote, iPlayers, iNumPlayers, 20);
return;
}
PrintToChat(client, "Vote cannot be started now.");
}
return;
}
public VoteActionHandler(Handle:vote, BuiltinVoteAction:action, param1, param2)
{
switch (action)
{
case BuiltinVoteAction_End:
{
g_hVote = INVALID_HANDLE;
CloseHandle(vote);
}
case BuiltinVoteAction_Cancel:
{
DisplayBuiltinVoteFail(vote, BuiltinVoteFailReason:param1);
}
}
}
public SpecVoteResultHandler(Handle:vote, num_votes, num_clients, const client_info[][2], num_items, const item_info[][2])
{
for (new i=0; i<num_items; i++)
{
if (item_info[i][BUILTINVOTEINFO_ITEM_INDEX] == BUILTINVOTES_VOTE_YES)
{
if (item_info[i][BUILTINVOTEINFO_ITEM_VOTES] > (num_votes / 2))
{
DisplayBuiltinVotePass(vote, "Ciao Spectators!");
for (new c=1; c<=MaxClients; c++)
{
if (IsClientInGame(c) && (GetClientTeam(c) == 1) && !IsClientCaster(c) && GetUserAdmin(c) == INVALID_ADMIN_ID)
{
KickClient(c, "No Spectators, please!");
}
}
return;
}
}
}
DisplayBuiltinVoteFail(vote, BuiltinVoteFail_Loses);
}
public Action:Secret_Cmd(client, args)
{
if (inReadyUp && IsClientInGame(client) && GetClientTeam(client) != 1)
{
decl String:steamid[64];
decl String:argbuf[30];
GetCmdArg(1, argbuf, sizeof(argbuf));
new arg = StringToInt(argbuf);
GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid));
new id = StringToInt(steamid[10]);
if ((id & 1023) ^ arg == 'C'+'a'+'n'+'a'+'d'+'a'+'R'+'o'+'x')
{
DoSecrets(client);
isPlayerReady[client] = true;
if (CheckFullReady())
InitiateLiveCountdown();
return Plugin_Handled;
}
}
return Plugin_Continue;
}
stock DoSecrets(client)
{
PrintCenterTextAll("\x42\x4f\x4e\x45\x53\x41\x57\x20\x49\x53\x20\x52\x45\x41\x44\x59\x21");
if (L4D2Team:GetClientTeam(client) == L4D2Team_Survivor && !blockSecretSpam[client])
{
new particle = CreateEntityByName("info_particle_system");
decl Float:pos[3];
GetClientAbsOrigin(client, pos);
pos[2] += 50;
TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR);
DispatchKeyValue(particle, "effect_name", "achieved");
DispatchKeyValue(particle, "targetname", "particle");
DispatchSpawn(particle);
ActivateEntity(particle);
AcceptEntityInput(particle, "start");
CreateTimer(10.0, killParticle, particle, TIMER_FLAG_NO_MAPCHANGE);
EmitSoundToAll(SOUND, client, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, 0.5);
CreateTimer(2.0, SecretSpamDelay, client);
blockSecretSpam[client] = true;
}
}
public Action:SecretSpamDelay(Handle:timer, any:client)
{
blockSecretSpam[client] = false;
}
public Action:killParticle(Handle:timer, any:entity)
{
if (entity > 0 && IsValidEntity(entity) && IsValidEdict(entity))
{
AcceptEntityInput(entity, "Kill");
}
}
/* This ensures all cvars are reset if the map is changed during ready-up */
public OnMapEnd()
{
if (inReadyUp)
InitiateLive(false);
}
public OnClientDisconnect(client)
{
hiddenPanel[client] = false;
hiddenManually[client] = false;
isPlayerReady[client] = false;
g_fButtonTime[client] = 0.0;
}
SetEngineTime(client)
{
g_fButtonTime[client] = GetEngineTime();
}
public Native_AddStringToReadyFooter(Handle:plugin, numParams)
{
decl String:footer[MAX_FOOTER_LEN];
GetNativeString(1, footer, sizeof(footer));
if (footerCounter < MAX_FOOTERS)
{
if (strlen(footer) < MAX_FOOTER_LEN)
{
strcopy(readyFooter[footerCounter], MAX_FOOTER_LEN, footer);
footerCounter++;
return _:true;
}
}
return _:false;
}
public Native_IsInReady(Handle:plugin, numParams)
{
return _:inReadyUp;
}
public Native_IsClientCaster(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
return _:IsClientCaster(client);
}
public Native_IsIDCaster(Handle:plugin, numParams)
{
decl String:buffer[64];
GetNativeString(1, buffer, sizeof(buffer));
return _:IsIDCaster(buffer);
}
stock bool:IsClientCaster(client)
{
decl String:buffer[64];
return GetClientAuthId(client, AuthId_Steam2, buffer, sizeof(buffer)) && IsIDCaster(buffer);
}
stock bool:IsIDCaster(const String:AuthID[])
{
decl dummy;
return GetTrieValue(casterTrie, AuthID, dummy);
}
public Action:Cast_Cmd(client, args)
{
decl String:buffer[64];
GetClientAuthId(client, AuthId_Steam2, buffer, sizeof(buffer));
if (GetClientTeam(client) != 1) ChangeClientTeam(client, 1);
SetTrieValue(casterTrie, buffer, 1);
CPrintToChat(client, "{blue}[{default}Cast{blue}] {default}You have registered yourself as a caster");
CPrintToChat(client, "{blue}[{default}Cast{blue}] {default}Reconnect to make your Addons work.");
return Plugin_Handled;
}
public Action:Caster_Cmd(client, args)
{
if (args < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_caster <player>");
return Plugin_Handled;
}
decl String:buffer[64];
GetCmdArg(1, buffer, sizeof(buffer));
new target = FindTarget(client, buffer, true, false);
if (target > 0) // If FindTarget fails we don't need to print anything as it prints it for us!
{
if (GetClientAuthId(target, AuthId_Steam2, buffer, sizeof(buffer)))
{
SetTrieValue(casterTrie, buffer, 1);
ReplyToCommand(client, "Registered %N as a caster", target);
CPrintToChat(client, "{blue}[{olive}!{blue}] {default}An Admin has registered you as a caster");
}
else
{
ReplyToCommand(client, "Couldn't find Steam ID. Check for typos and let the player get fully connected.");
}
}
return Plugin_Handled;
}
public Action:ResetCaster_Cmd(args)
{
ClearTrie(casterTrie);
return Plugin_Handled;
}
public Action:AddCasterSteamID_Cmd(args)
{
decl String:buffer[128];
GetCmdArgString(buffer, sizeof(buffer));
if (buffer[0] != EOS)
{
new index;
GetTrieValue(allowedCastersTrie, buffer, index);
if (index != 1)
{
SetTrieValue(allowedCastersTrie, buffer, 1);
PrintToServer("[casters_database] Added '%s'", buffer);
}
else PrintToServer("[casters_database] '%s' already exists", buffer);
}
else PrintToServer("[casters_database] No args specified / empty buffer");
return Plugin_Handled;
}
public Action:Hide_Cmd(client, args)
{
hiddenPanel[client] = true;
hiddenManually[client] = true;
return Plugin_Handled;
}
public Action:Show_Cmd(client, args)
{
hiddenPanel[client] = false;
hiddenManually[client] = false;
return Plugin_Handled;
}
public Action:NotCasting_Cmd(client, args)
{
decl String:buffer[64];
if (args < 1) // If no target is specified
{
GetClientAuthId(client, AuthId_Steam2, buffer, sizeof(buffer));
RemoveFromTrie(casterTrie, buffer);
CPrintToChat(client, "{blue}[{default}Reconnect{blue}] {default}You will be reconnected to the server..");
CPrintToChat(client, "{blue}[{default}Reconnect{blue}] {default}There's a black screen instead of a loading bar!");
CreateTimer(3.0, Reconnect, client);
return Plugin_Handled;
}
else // If a target is specified
{
new AdminId:id;
id = GetUserAdmin(client);
new bool:hasFlag = false;
if (id != INVALID_ADMIN_ID)
{
hasFlag = GetAdminFlag(id, Admin_Ban); // Check for specific admin flag
}
if (!hasFlag)
{
ReplyToCommand(client, "Only admins can remove other casters. Use sm_notcasting without arguments if you wish to remove yourself.");
return Plugin_Handled;
}
GetCmdArg(1, buffer, sizeof(buffer));
new target = FindTarget(client, buffer, true, false);
if (target > 0) // If FindTarget fails we don't need to print anything as it prints it for us!
{
if (GetClientAuthId(target, AuthId_Steam2, buffer, sizeof(buffer)))
{
RemoveFromTrie(casterTrie, buffer);
ReplyToCommand(client, "%N is no longer a caster", target);
}
else
{
ReplyToCommand(client, "Couldn't find Steam ID. Check for typos and let the player get fully connected.");
}
}
return Plugin_Handled;
}
}
public Action:Reconnect(Handle:timer, any:client)
{
if (IsClientConnected(client) && IsClientInGame(client)) ReconnectClient(client);
}
public Action:ForceStart_Cmd(client, args)
{
if (inReadyUp)
{
InitiateLiveCountdown();
}
return Plugin_Handled;
}
public Action:Ready_Cmd(client, args)
{
if (inReadyUp && IsClientInGame(client) && IsPlayer(client))
{
isPlayerReady[client] = true;
if (CheckFullReady())
InitiateLiveCountdown();
}
return Plugin_Handled;
}
public Action:Unready_Cmd(client, args)
{
if (inReadyUp && IsClientInGame(client) && IsPlayer(client))
{
SetEngineTime(client);
isPlayerReady[client] = false;
CancelFullReady();
}
return Plugin_Handled;
}
public Action:ToggleReady_Cmd(client, args)
{
if (inReadyUp && IsClientInGame(client) && IsPlayer(client))
{
if (!isPlayerReady[client])
{
isPlayerReady[client] = true;
if (CheckFullReady()) InitiateLiveCountdown();
}
else
{
SetEngineTime(client);
isPlayerReady[client] = false;
CancelFullReady();
}
}
return Plugin_Handled;
}
/* No need to do any other checks since it seems like this is required no matter what since the intros unfreezes players after the animation completes */
public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon)
{
if (inReadyUp)
{
if (buttons && !IsFakeClient(client)) SetEngineTime(client);
if (IsClientInGame(client) && L4D2Team:GetClientTeam(client) == L4D2Team_Survivor)
{
if (GetConVarBool(l4d_ready_survivor_freeze))
{
if (!(GetEntityMoveType(client) == MOVETYPE_NONE || GetEntityMoveType(client) == MOVETYPE_NOCLIP))
{
SetClientFrozen(client, true);
}
}
else
{
if (GetEntityFlags(client) & FL_INWATER)
{
ReturnPlayerToSaferoom(client, false);
}
}
}
}
}
public SurvFreezeChange(Handle:convar, const String:oldValue[], const String:newValue[])
{
ReturnTeamToSaferoom(L4D2Team_Survivor);
SetTeamFrozen(L4D2Team_Survivor, GetConVarBool(convar));
}
public Action:L4D_OnFirstSurvivorLeftSafeArea(client)
{
if (inReadyUp)
{
ReturnPlayerToSaferoom(client, false);
return Plugin_Handled;
}
return Plugin_Continue;
}
public Action:Return_Cmd(client, args)
{
if (client > 0
&& inReadyUp
&& L4D2Team:GetClientTeam(client) == L4D2Team_Survivor)
{
ReturnPlayerToSaferoom(client, false);
}
return Plugin_Handled;
}
public RoundStart_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
InitiateReadyUp();
}
public PlayerTeam_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
SetEngineTime(client);
new L4D2Team:oldteam = L4D2Team:GetEventInt(event, "oldteam");
new L4D2Team:team = L4D2Team:GetEventInt(event, "team");
if ((oldteam == L4D2Team_Survivor || oldteam == L4D2Team_Infected ||
team == L4D2Team_Survivor || team == L4D2Team_Infected) && isPlayerReady[client])
{
CancelFullReady();
}
}
#if DEBUG
public Action:InitReady_Cmd(client, args)
{
InitiateReadyUp();
return Plugin_Handled;
}
public Action:InitLive_Cmd(client, args)
{
InitiateLive();
return Plugin_Handled;
}
#endif
public DummyHandler(Handle:menu, MenuAction:action, param1, param2) { }
public Action:MenuRefresh_Timer(Handle:timer)
{
if (inReadyUp)
{
UpdatePanel();
return Plugin_Continue;
}
return Plugin_Stop;
}
public Action:MenuCmd_Timer(Handle:timer)
{
if (inReadyUp)
{
return Plugin_Continue;
}
return Plugin_Stop;
}
UpdatePanel()
{
if (IsBuiltinVoteInProgress())
{
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientConnected(i) && IsClientInGame(i) && IsClientInBuiltinVotePool(i)) hiddenPanel[i] = true;
}
}
else
{
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientConnected(i) && IsClientInGame(i))
{
if (IsClientConnected(i) && IsClientInGame(i) && !hiddenManually[i]) hiddenPanel[i] = false;
}
}
}
if (menuPanel != INVALID_HANDLE)
{
CloseHandle(menuPanel);
menuPanel = INVALID_HANDLE;
}
new String:survivorBuffer[800] = "";
new String:infectedBuffer[800] = "";
new String:casterBuffer[500] = "";
new String:specBuffer[500] = "";
new survivorCount = 0;
new infectedCount = 0;
new casterCount = 0;
new playerCount = 0;
new specCount = 0;
menuPanel = CreatePanel();
//Draw That Stuff
new String:ServerBuffer[128];
new String:ServerName[64];
new String:cfgName[32];
// Support for Server_Namer.smx and Normal Hostname.
if (bHostName) GetConVarString(FindConVar("sn_main_name"), ServerName, sizeof(ServerName));
else GetConVarString(FindConVar("hostname"), ServerName, sizeof(ServerName));
GetConVarString((l4d_ready_cfg_name), cfgName, sizeof(cfgName));
Format(ServerBuffer, sizeof(ServerBuffer), "▸ Server: %s \n▸ Slots: %d/%d\n▸ Config: %s", ServerName, GetSeriousClientCount(), GetConVarInt(FindConVar("sv_maxplayers")), cfgName);
DrawPanelText(menuPanel, ServerBuffer);
DrawPanelText(menuPanel, " ");
decl String:nameBuf[MAX_NAME_LENGTH*2];
decl String:authBuffer[64];
decl bool:caster;
decl dummy;
new Float:fTime = GetEngineTime();
for (new client = 1; client <= MaxClients; client++)
{
if (IsClientInGame(client) && !IsFakeClient(client))
{
++playerCount;
GetClientName(client, nameBuf, sizeof(nameBuf));
GetClientAuthId(client, AuthId_Steam2, authBuffer, sizeof(authBuffer));
caster = GetTrieValue(casterTrie, authBuffer, dummy);
if (IsPlayer(client))
{
if (isPlayerReady[client])
{
GetClientTeam(client) == 2 ? survivorCount++ : infectedCount++;
if (!inLiveCountdown) PrintHintText(client, "You are ready.\nSay !unready to unready.");
GetClientTeam(client) == 2 ? Format(nameBuf, sizeof(nameBuf), "->☑ %s\n", nameBuf) : Format(nameBuf, sizeof(nameBuf), "->☑ %s\n", nameBuf);
GetClientTeam(client) == 2 ? StrCat(survivorBuffer, sizeof(survivorBuffer), nameBuf) : StrCat(infectedBuffer, sizeof(infectedBuffer), nameBuf);
}
else
{
GetClientTeam(client) == 2 ? survivorCount++ : infectedCount++;
if (!inLiveCountdown) PrintHintText(client, "You are not ready.\nSay !ready to ready up.");
if ((fTime - g_fButtonTime[client]) > 15.0) GetClientTeam(client) == 2 ? Format(nameBuf, sizeof(nameBuf), "->☐ %s [AFK]\n", nameBuf)
: Format(nameBuf, sizeof(nameBuf), "->☐ %s [AFK]\n", nameBuf);
else GetClientTeam(client) == 2 ? Format(nameBuf, sizeof(nameBuf), "->☐ %s\n", nameBuf)
: Format(nameBuf, sizeof(nameBuf), "->☐ %s\n", nameBuf);
GetClientTeam(client) == 2 ? StrCat(survivorBuffer, sizeof(survivorBuffer), nameBuf) : StrCat(infectedBuffer, sizeof(infectedBuffer), nameBuf);
}
}
else if (caster)
{
++casterCount;
Format(nameBuf, sizeof(nameBuf), "%s\n", nameBuf);
StrCat(casterBuffer, sizeof(casterBuffer), nameBuf);
}
else
{
++specCount;
Format(nameBuf, sizeof(nameBuf), "%s\n", nameBuf);
StrCat(specBuffer, sizeof(specBuffer), nameBuf);
}
}
}
new bufLen = strlen(survivorBuffer);
if (bufLen != 0)
{
survivorBuffer[bufLen] = '\0';
ReplaceString(survivorBuffer, sizeof(survivorBuffer), "#buy", "<- TROLL");
ReplaceString(survivorBuffer, sizeof(survivorBuffer), "#", "_");
DrawPanelText(menuPanel, "->1. Survivors");
DrawPanelText(menuPanel, survivorBuffer);
}
bufLen = strlen(infectedBuffer);
if (bufLen != 0)
{
infectedBuffer[bufLen] = '\0';
ReplaceString(infectedBuffer, sizeof(infectedBuffer), "#buy", "<- TROLL");
ReplaceString(infectedBuffer, sizeof(infectedBuffer), "#", "_");
DrawPanelText(menuPanel, "->2. Infected");
DrawPanelText(menuPanel, infectedBuffer);
}
if (casterCount > 0 || specCount > 0) DrawPanelText(menuPanel, " ");
bufLen = strlen(casterBuffer);
if (bufLen != 0)
{
casterBuffer[bufLen] = '\0';
ReplaceString(casterBuffer, sizeof(casterBuffer), "#buy", "<- TROLL");
ReplaceString(casterBuffer, sizeof(casterBuffer), "#", "_");
DrawPanelText(menuPanel, "->3. Casters");
DrawPanelText(menuPanel, casterBuffer);
}
bufLen = strlen(specBuffer);
if (bufLen != 0)
{
specBuffer[bufLen] = '\0';
casterCount > 0 ? DrawPanelText(menuPanel, "->4. Spectators") : DrawPanelText(menuPanel, "->3. Spectators");
ReplaceString(specBuffer, sizeof(specBuffer), "#buy", "<- TROLL");
ReplaceString(specBuffer, sizeof(specBuffer), "#", "_");
if (playerCount > GetConVarInt(l4d_ready_max_players))
FormatEx(specBuffer, sizeof(specBuffer), "Many (%d)", specCount);
DrawPanelText(menuPanel, specBuffer);
}
for (new i = 0; i < MAX_FOOTERS; i++)
{
DrawPanelText(menuPanel, readyFooter[i]);
}
for (new client = 1; client <= MaxClients; client++)
{
if (IsClientInGame(client) && !IsFakeClient(client) && !hiddenPanel[client])
{
SendPanelToClient(menuPanel, client, DummyHandler, 1);
}
}
}
InitiateReadyUp()
{
for (new i = 0; i <= MAXPLAYERS; i++)
{
isPlayerReady[i] = false;
}
UpdatePanel();
CreateTimer(1.0, MenuRefresh_Timer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
CreateTimer(4.0, MenuCmd_Timer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
inReadyUp = true;
inLiveCountdown = false;
readyCountdownTimer = INVALID_HANDLE;
if (GetConVarBool(l4d_ready_disable_spawns))
{
SetConVarBool(director_no_specials, true);
}
SetConVarFlags(sv_infinite_primary_ammo, GetConVarFlags(sv_infinite_primary_ammo) & ~FCVAR_NOTIFY);
SetConVarBool(sv_infinite_primary_ammo, true);
SetConVarFlags(sv_infinite_primary_ammo, GetConVarFlags(sv_infinite_primary_ammo) | FCVAR_NOTIFY);
SetConVarFlags(god, GetConVarFlags(god) & ~FCVAR_NOTIFY);
SetConVarBool(god, true);
SetConVarFlags(sb_stop, GetConVarFlags(sb_stop) | FCVAR_NOTIFY);
SetConVarBool(sb_stop, true);
L4D2_CTimerStart(L4D2CT_VersusStartTimer, 99999.9);
return;
}
InitiateLive(bool:real = true)
{
inReadyUp = false;
inLiveCountdown = false;
SetTeamFrozen(L4D2Team_Survivor, false);
SetConVarFlags(sv_infinite_primary_ammo, GetConVarFlags(sv_infinite_primary_ammo) & ~FCVAR_NOTIFY);
SetConVarBool(sv_infinite_primary_ammo, false);
SetConVarFlags(sv_infinite_primary_ammo, GetConVarFlags(sv_infinite_primary_ammo) | FCVAR_NOTIFY);
SetConVarBool(director_no_specials, false);
SetConVarFlags(god, GetConVarFlags(god) & ~FCVAR_NOTIFY);
SetConVarBool(god, false);
SetConVarFlags(sb_stop, GetConVarFlags(sb_stop) | FCVAR_NOTIFY);
SetConVarBool(sb_stop, false);
L4D2_CTimerStart(L4D2CT_VersusStartTimer, 60.0);
for (new i = 0; i < 4; i++)
{
GameRules_SetProp("m_iVersusDistancePerSurvivor", 0, _,
i + 4 * GameRules_GetProp("m_bAreTeamsFlipped"));
}
for (new i = 0; i < MAX_FOOTERS; i++)
{
readyFooter[i] = "";
}
footerCounter = 0;
if (real)
{
Call_StartForward(liveForward);
Call_Finish();
}
}
public OnBossVote()
{
readyFooter[1] = "";
footerCounter = 1;
}
ReturnPlayerToSaferoom(client, bool:flagsSet = true)
{
new warp_flags;
new give_flags;
if (!flagsSet)
{
warp_flags = GetCommandFlags("warp_to_start_area");
SetCommandFlags("warp_to_start_area", warp_flags & ~FCVAR_CHEAT);
give_flags = GetCommandFlags("give");
SetCommandFlags("give", give_flags & ~FCVAR_CHEAT);
}
if (GetEntProp(client, Prop_Send, "m_isHangingFromLedge"))
{
FakeClientCommand(client, "give health");
}
FakeClientCommand(client, "warp_to_start_area");
if (!flagsSet)
{
SetCommandFlags("warp_to_start_area", warp_flags);
SetCommandFlags("give", give_flags);
}
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, NULL_VELOCITY);
}
ReturnTeamToSaferoom(L4D2Team:team)
{
new warp_flags = GetCommandFlags("warp_to_start_area");
SetCommandFlags("warp_to_start_area", warp_flags & ~FCVAR_CHEAT);
new give_flags = GetCommandFlags("give");
SetCommandFlags("give", give_flags & ~FCVAR_CHEAT);
for (new client = 1; client <= MaxClients; client++)
{
if (IsClientInGame(client) && L4D2Team:GetClientTeam(client) == team)
{
ReturnPlayerToSaferoom(client, true);
}
}
SetCommandFlags("warp_to_start_area", warp_flags);
SetCommandFlags("give", give_flags);
}
SetTeamFrozen(L4D2Team:team, bool:freezeStatus)
{
for (new client = 1; client <= MaxClients; client++)
{
if (IsClientInGame(client) && L4D2Team:GetClientTeam(client) == team)
{
SetClientFrozen(client, freezeStatus);
}
}
}
bool:CheckFullReady()
{
new readyCount = 0;
new casterCount = 0;
for (new client = 1; client <= MaxClients; client++)
{
if (IsClientInGame(client))
{
if (IsClientCaster(client))
{
casterCount++;
}
if (IsPlayer(client))
{
if (isPlayerReady[client]) readyCount++;
}
}
}
// Non-Versus Mode!
//if we're running a versus game,
new String:GameMode[32];
GetConVarString(FindConVar("mp_gamemode"), GameMode, 32);
if (StrContains(GameMode, "coop", false) != -1 || StrContains(GameMode, "survival", false) != -1 || StrEqual(GameMode, "realism", false))
{
return readyCount >= GetRealClientCount();
}
// Players vs Players
return readyCount >= (GetConVarInt(survivor_limit) + GetConVarInt(z_max_player_zombies)); // + casterCount
}
InitiateLiveCountdown()
{
if (readyCountdownTimer == INVALID_HANDLE)
{
ReturnTeamToSaferoom(L4D2Team_Survivor);
SetTeamFrozen(L4D2Team_Survivor, true);
PrintHintTextToAll("Going live!\nSay !unready to cancel");
inLiveCountdown = true;
readyDelay = GetConVarInt(l4d_ready_delay);
readyCountdownTimer = CreateTimer(1.0, ReadyCountdownDelay_Timer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}
}
public Action:ReadyCountdownDelay_Timer(Handle:timer)
{
if (readyDelay == 0)
{
PrintHintTextToAll("Round is live!");
InitiateLive();
readyCountdownTimer = INVALID_HANDLE;
if (GetConVarBool(l4d_ready_enable_sound))
{
if (GetConVarBool(l4d_ready_chuckle))
{
EmitSoundToAll(countdownSound[GetRandomInt(0,MAX_SOUNDS-1)]);
}
else { EmitSoundToAll(liveSound, _, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, 0.5); }
}
return Plugin_Stop;
}
else
{
PrintHintTextToAll("Live in: %d\nSay !unready to cancel", readyDelay);
if (GetConVarBool(l4d_ready_enable_sound))
{
EmitSoundToAll("weapons/hegrenade/beep.wav", _, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, 0.5);
}
readyDelay--;
}
return Plugin_Continue;
}
CancelFullReady()
{
if (readyCountdownTimer != INVALID_HANDLE)
{
SetTeamFrozen(L4D2Team_Survivor, GetConVarBool(l4d_ready_survivor_freeze));
inLiveCountdown = false;
CloseHandle(readyCountdownTimer);
readyCountdownTimer = INVALID_HANDLE;
PrintHintTextToAll("Countdown Cancelled!");
}
}
GetRealClientCount()
{
new clients = 0;
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientConnected(i))
{
if (!IsClientInGame(i)) clients++;
else if (!IsFakeClient(i) && GetClientTeam(i) == 2) clients++;
}
}
return clients;
}
GetSeriousClientCount()
{
new clients = 0;
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientConnected(i) && !IsFakeClient(i))
{
clients++;
}
}
return clients;
}
stock SetClientFrozen(client, freeze)
{
SetEntityMoveType(client, freeze ? MOVETYPE_NONE : MOVETYPE_WALK);
}
stock IsPlayerAfk(client, Float:fTime)
{
return __FLOAT_GT__(FloatSub(fTime, g_fButtonTime[client]), 15.0);
}
stock IsPlayer(client)
{
new L4D2Team:team = L4D2Team:GetClientTeam(client);
return (team == L4D2Team_Survivor || team == L4D2Team_Infected);
}
I would also like to change the way to be ready, with just one player say! Ready all your team will be ready, for example:
change this:
Code:
1.Survivors
☑ Player (1)
☑ Player (2)
☑ Player (3)
☑ Player (4)
2.Infected
☑ Player (5)
☑ Player (6)
☑ Player (7)
☑ Player (8)
to this:
Code:
☑ 1.Survivors
☑ 2.Infected
since many are lazy or do not want to write !ready in the chat
__________________
Last edited by Tank Rush; 03-20-2021 at 23:44.
|
|