#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#define PLUGIN_VERSION "1.0.0"
new bool:Enabled;
new bool:GameStart;
#define VOTE_NO "###no###"
#define VOTE_YES "###yes###"
new VIPColor[4]= {255,255,0, 255};
new Handle:l4d_vip_count = INVALID_HANDLE;
new Handle:l4d_vip_enable = INVALID_HANDLE;
new Handle:killtimer = INVALID_HANDLE;
new PlayerVIP[MAXPLAYERS+1];
new GameMode;
new bool:L4D2Version;
new g_sprite;
new g_BeamSprite;
new g_HaloSprite;
public Plugin:myinfo =
{
name = "vip",
author = "Pan Xiaohai",
description = "vip",
version = PLUGIN_VERSION,
}
public OnPluginStart()
{
GameCheck();
l4d_vip_enable = CreateConVar("l4d_vip_enable", "1", "vid mode 0:disable, 1:enable ", FCVAR_PLUGIN);
l4d_vip_count = CreateConVar("l4d_vip_count", "2", "", FCVAR_PLUGIN);
HookEvent("player_bot_replace", player_bot_replace); //A bot takes over an existing player
HookEvent("bot_player_replace", bot_player_replace); //A player takes over an existing bot
HookEvent("round_start", RoundStart);
HookEvent("player_death", evtPlayerDeath);
RegAdminCmd("sm_setvip",sm_setvip,ADMFLAG_RCON);
RegConsoleCmd("sm_vip",sm_vip);
//AutoExecConfig(true, "l4d_vip");
}
GameCheck()
{
decl String:GameName[16];
GetConVarString(FindConVar("mp_gamemode"), GameName, sizeof(GameName));
if (StrEqual(GameName, "survival", false))
GameMode = 3;
else if (StrEqual(GameName, "versus", false) || StrEqual(GameName, "teamversus", false) || StrEqual(GameName, "scavenge", false) || StrEqual(GameName, "teamscavenge", false))
GameMode = 2;
else if (StrEqual(GameName, "coop", false) || StrEqual(GameName, "realism", false))
GameMode = 1;
else
{
GameMode = 0;
}
GetGameFolderName(GameName, sizeof(GameName));
if (StrEqual(GameName, "left4dead2", false))
{
L4D2Version=true;
}
else
{
L4D2Version=false;
}
}
public OnMapStart()
{
if(L4D2Version)
{
g_sprite = PrecacheModel("materials/sprites/laserbeam.vmt");
g_BeamSprite = PrecacheModel("materials/sprites/laserbeam.vmt");
g_HaloSprite = PrecacheModel("materials/dev/halo_add_to_screen.vmt");
}
else
{
g_sprite = PrecacheModel("materials/sprites/laser.vmt");
g_BeamSprite = PrecacheModel("materials/sprites/laser.vmt");
g_HaloSprite = PrecacheModel("materials/sprites/halo01.vmt");
}
}
public Action:RoundStart (Handle:event, const String:name[], bool:dontBroadcast)
{
if(killtimer!=INVALID_HANDLE)
{
KillTimer(killtimer);
killtimer=INVALID_HANDLE;
}
for (new i=1;i<=MaxClients;i++)
{
PlayerVIP[i]=0;
}
return Plugin_Continue;
}
public Action:Event_Player_Spawn(Handle:event, String:event_name[], bool:dontBroadcast)
{
if(GameMode==2 || GetConVarInt(l4d_vip_enable)==0 || GetConVarInt(l4d_vip_count)<=0) return Plugin_Continue;
new client = GetClientOfUserId(GetEventInt(event, "userid"));
SetColor(client, PlayerVIP[client]==0);
//PrintToChatAll(" %N spaawn ", client);
return Plugin_Continue;
}
public Action:evtPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
if(GameMode==2 || GetConVarInt(l4d_vip_enable)==0 || GetConVarInt(l4d_vip_count)<=0) return Plugin_Continue;
new client = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
if(client > 0 && IsClientInGame(client) && GetClientTeam(client)==2)
{
if(PlayerVIP[client]>0)
{
new vipc=VIPCount();
new vipa=AliveVipCount();
//PrintToChatAll(" %d %d ", vipc, vipa);
if(vipc>0 && vipa==0)
{
PrintToChatAll("所有 VIP 死亡, 游戏结束");
killtimer=CreateTimer(2.0, KillOne, 0, TIMER_REPEAT);
}
else if(vipc>0)
{
PrintToChatAll("VIP %N 死亡", client);
}
}
PlayerVIP[client]=0;
}
return Plugin_Continue;
}
public Action:KillOne(Handle:timer, any:client)
{
new c=0;
for (new i=1;i<=MaxClients;i++)
{
if(IsClientInGame(i) && GetClientTeam(i)==2 && IsPlayerAlive(i))
{
if(c==0)ForcePlayerSuicide(i);
c++;
}
}
if(c>=1)return Plugin_Continue;
else
{
killtimer=INVALID_HANDLE;
return Plugin_Stop;
}
}
public player_bot_replace(Handle:Spawn_Event, const String:Spawn_Name[], bool:Spawn_Broadcast)
{
if(GameMode==2 || GetConVarInt(l4d_vip_enable)==0 || GetConVarInt(l4d_vip_count)<=0) return Plugin_Continue;
new client = GetClientOfUserId(GetEventInt(Spawn_Event, "player"));
new bot = GetClientOfUserId(GetEventInt(Spawn_Event, "bot"));
new c=PlayerVIP[bot];
PlayerVIP[bot]=PlayerVIP[client];
PlayerVIP[client]=c;
PlayerVIP[bot]=0;
PlayerVIP[client]=0;
SetColor(client, PlayerVIP[client]==0);
SetColor(bot, PlayerVIP[bot]==0);
//PrintToChatAll("%N place %N", bot, client);
}
public bot_player_replace(Handle:Spawn_Event, const String:Spawn_Name[], bool:Spawn_Broadcast)
{
if(GameMode==2 || GetConVarInt(l4d_vip_enable)==0 || GetConVarInt(l4d_vip_count)<=0) return Plugin_Continue;
new client = GetClientOfUserId(GetEventInt(Spawn_Event, "player"));
new bot = GetClientOfUserId(GetEventInt(Spawn_Event, "bot"));
new c=PlayerVIP[client];
PlayerVIP[client]=PlayerVIP[bot];
PlayerVIP[bot]=c;
PlayerVIP[bot]=0;
PlayerVIP[client]=0;
SetColor(client, PlayerVIP[client]==0);
SetColor(bot, PlayerVIP[bot]==0);
//PrintToChatAll("%N place %N", client, bot);
}
VIPCount()
{
new c=0;
for (new i=1;i<=MaxClients;i++)
{
if(PlayerVIP[i]>0)
{
if(IsClientInGame(i) && GetClientTeam(i)==2 )
{
c++;
}
else
{
PlayerVIP[i]=0;
}
}
}
return c;
}
AliveVipCount()
{
new c=0;
for (new i=1;i<=MaxClients;i++)
{
if(PlayerVIP[i]>0)
{
if(IsClientInGame(i) && GetClientTeam(i)==2 && IsPlayerAlive(i))
{
c++;
}
}
}
return c;
}
DelRandomVip()
{
new c=0;
new r=GetRandomInt(0, VIPCount()-1);
for (new i=1;i<=MaxClients;i++)
{
if(PlayerVIP[i]>0)
{
if(IsClientInGame(i) && GetClientTeam(i)==2 )
{
if(IsPlayerAlive(i))
{
if(c==r)
{
PlayerVIP[i]=0;
SetColor(i, true);
PrintToChatAll("%N 成为普通人", i);
}
c++;
}
}
}
}
return c;
}
SetColor(i, bool:b)
{
if(i>0 && IsClientInGame(i) && GetClientTeam(i)==2 && IsPlayerAlive(i) )
{
if(b)
{
SetEntityRenderMode(i, RenderMode:3);
SetEntityRenderColor(i, 255,255,255,255);
}
else
{
SetEntityRenderMode(i, RenderMode:3);
SetEntityRenderColor(i, 255,0,0,255);
}
}
}
public Action:sm_setvip(client, args)
{
if(GameMode==2 || GetConVarInt(l4d_vip_enable)==0 || GetConVarInt(l4d_vip_count)<=0) return Plugin_Continue;
new String:arg[8];
GetCmdArg(1,arg,8);
new Input=StringToInt(arg[0]);
new c=GetClientOfUserId(Input);
if(c>0 && IsClientInGame(c) && GetClientTeam(c)==2 && IsPlayerAlive(c))
{
if(PlayerVIP[c]>0)
{
PlayerVIP[c]=0;
SetColor(c, true);
PrintToChatAll("%N 成为 普通人", c);
}
else
{
if(VIPCount()+1>GetConVarInt(l4d_vip_count))
{
DelRandomVip();
}
PlayerVIP[c]=1;
SetColor(c, false);
PrintToChatAll("%N 成为 VIP, 大家要保护他", c);
}
}
return Plugin_Continue;
}
new requestingclient=0;
new Handle:g_hVoteMenu = INVALID_HANDLE;
public Action:sm_vip(client, args)
{
if(GameMode==2 || GetConVarInt(l4d_vip_enable)==0 || GetConVarInt(l4d_vip_count)<=0) return Plugin_Continue;
if (client>0)
{
new String:title[111];
if (IsClientInGame(client) && GetClientTeam(client)==2)
{
if (IsVoteInProgress())
{
PrintToChat(client,"等待");
return Plugin_Handled;
}
if (!TestVoteDelay(client))
{
PrintToChat(client,"等待");
return Plugin_Handled;
}
if(requestingclient>0)
{
PrintToChat(client,"等待");
return Plugin_Handled;
}
Format(title, 111, "是否同意 %N 成为 VIP", client);
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
SetMenuTitle(g_hVoteMenu, "%s?", title);
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
SetMenuExitButton(g_hVoteMenu, false);
VoteMenuToAll(g_hVoteMenu, 20);
requestingclient=client;
}
}
}
VoteMenuClose()
{
CloseHandle(g_hVoteMenu);
g_hVoteMenu = INVALID_HANDLE;
}
public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_End)
{
VoteMenuClose();
requestingclient=0;
}
else if (action == MenuAction_Display)
{
}
else if (action == MenuAction_DisplayItem)
{
}
/* else if (action == MenuAction_Select)
{
VoteSelect(menu, param1, param2);
}*/
else if (action == MenuAction_VoteCancel && param1 == VoteCancel_NoVotes)
{
}
else if (action == MenuAction_VoteEnd)
{
decl String:item[64], String:display[64];
new Float:percent, Float:limit, votes, totalVotes;
limit=0.5;
GetMenuVoteInfo(param2, votes, totalVotes);
GetMenuItem(menu, param1, item, sizeof(item), _, display, sizeof(display));
if (strcmp(item, VOTE_NO) == 0 && param1 == 1)
{
votes = totalVotes - votes; // Reverse the votes to be in relation to the Yes option.
}
percent = GetVotePercent(votes, totalVotes);
/* :TODO: g_voteClient[userid] needs to be checked */
// A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
{
if(requestingclient>0 && IsClientInGame(requestingclient))
{
PrintToChatAll("投票不通过, %d 同意, %d 反对", requestingclient,votes, totalVotes-votes);
}
}
else
{
PrintToChatAll("投票通过, %d 同意, %d 反对", requestingclient, votes, totalVotes-votes);
if(VIPCount()+1>GetConVarInt(l4d_vip_count))
{
DelRandomVip();
}
PlayerVIP[requestingclient]=1;
SetColor(requestingclient, false);
PrintToChatAll("%N 成为 VIP, 大家要保护他", requestingclient);
}
requestingclient=0;
}
return 0;
}
Float:GetVotePercent(votes, totalVotes)
{
return FloatDiv(float(votes),float(totalVotes));
}
bool:TestVoteDelay(client)
{
new delay = CheckVoteDelay();
if (delay > 0)
{
return false;
}
return true;
}
求生之路 投票成为Vip-源码。
评论
(0)