initial commit
This commit is contained in:
commit
72f7665358
123
AdminCheats/scripting/AdminCheats.sp
Normal file
123
AdminCheats/scripting/AdminCheats.sp
Normal file
@ -0,0 +1,123 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
#pragma newdecls required
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "AdminCheats",
|
||||
author = "BotoX",
|
||||
description = "Allows usage of (most) cheat commands for admins.",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
};
|
||||
|
||||
ConVar g_CVar_sv_cheats;
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
g_CVar_sv_cheats = FindConVar("sv_cheats");
|
||||
g_CVar_sv_cheats.Flags &= ~FCVAR_NOTIFY;
|
||||
g_CVar_sv_cheats.Flags &= ~FCVAR_REPLICATED;
|
||||
g_CVar_sv_cheats.AddChangeHook(OnConVarChanged);
|
||||
g_CVar_sv_cheats.SetInt(1);
|
||||
|
||||
MakeCheatCommand("give");
|
||||
|
||||
int NumHooks = 0;
|
||||
char sConCommand[128];
|
||||
bool IsCommand;
|
||||
int Flags;
|
||||
Handle hSearch = FindFirstConCommand(sConCommand, sizeof(sConCommand), IsCommand, Flags);
|
||||
do
|
||||
{
|
||||
if(IsCommand && Flags & FCVAR_CHEAT)
|
||||
{
|
||||
RegConsoleCmd(sConCommand, OnCheatCommand);
|
||||
NumHooks++;
|
||||
}
|
||||
}
|
||||
while(FindNextConCommand(hSearch, sConCommand, sizeof(sConCommand), IsCommand, Flags));
|
||||
|
||||
PrintToServer("Hooked %d cheat commands.", NumHooks);
|
||||
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
public void OnPluginEnd()
|
||||
{
|
||||
g_CVar_sv_cheats.SetInt(0);
|
||||
g_CVar_sv_cheats.Flags |= FCVAR_NOTIFY;
|
||||
g_CVar_sv_cheats.Flags |= FCVAR_REPLICATED;
|
||||
}
|
||||
|
||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||
{
|
||||
g_CVar_sv_cheats.SetInt(1);
|
||||
CreateTimer(0.1, Timer_UpdateClients);
|
||||
}
|
||||
|
||||
public Action Timer_UpdateClients(Handle timer, Handle hndl)
|
||||
{
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
public void UpdateClients()
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
||||
OnClientPostAdminCheck(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
SendConVarValue(client, g_CVar_sv_cheats, "0");
|
||||
}
|
||||
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
if(IsFakeClient(client))
|
||||
return;
|
||||
|
||||
if(g_CVar_sv_cheats.BoolValue && GetAdminFlag(GetUserAdmin(client), Admin_Cheats))
|
||||
SendConVarValue(client, g_CVar_sv_cheats, "1");
|
||||
else
|
||||
SendConVarValue(client, g_CVar_sv_cheats, "0");
|
||||
}
|
||||
|
||||
public Action OnCheatCommand(int client, int args)
|
||||
{
|
||||
if(client == 0)
|
||||
return Plugin_Continue;
|
||||
|
||||
if(IsClientAuthorized(client) && GetAdminFlag(GetUserAdmin(client), Admin_Cheats))
|
||||
return Plugin_Continue;
|
||||
|
||||
PrintToConsole(client, "denied :^)");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
|
||||
{
|
||||
if(!impulse)
|
||||
return Plugin_Continue;
|
||||
|
||||
if(impulse == 100 || impulse == 201)
|
||||
return Plugin_Continue;
|
||||
|
||||
if(IsClientAuthorized(client) && GetAdminFlag(GetUserAdmin(client), Admin_Cheats))
|
||||
return Plugin_Continue;
|
||||
|
||||
PrintToConsole(client, "denied :^)");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
stock void MakeCheatCommand(const char[] name)
|
||||
{
|
||||
int Flags = GetCommandFlags(name);
|
||||
if(Flags != INVALID_FCVAR_FLAGS)
|
||||
SetCommandFlags(name, FCVAR_CHEAT | Flags);
|
||||
}
|
1
AdvancedTargeting/scripting/.gitignore
vendored
Normal file
1
AdvancedTargeting/scripting/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SteamAPI.secret
|
451
AdvancedTargeting/scripting/AdvancedTargeting.sp
Normal file
451
AdvancedTargeting/scripting/AdvancedTargeting.sp
Normal file
@ -0,0 +1,451 @@
|
||||
#pragma semicolon 1
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
#pragma dynamic 128*1024
|
||||
|
||||
#include <sourcemod>
|
||||
#include <SteamWorks>
|
||||
//#include <EasyJSON>
|
||||
#include <AdvancedTargeting>
|
||||
|
||||
Handle g_FriendsArray[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
|
||||
bool g_bLateLoad = false;
|
||||
|
||||
//#define STEAM_API_KEY "secret"
|
||||
#include "SteamAPI.secret"
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Advanced Targeting",
|
||||
author = "BotoX",
|
||||
description = "Adds @admins and @friends targeting method",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
AddMultiTargetFilter("@admins", Filter_Admin, "Admins", false);
|
||||
AddMultiTargetFilter("@!admins", Filter_NotAdmin, "Not Admins", false);
|
||||
AddMultiTargetFilter("@friends", Filter_Friends, "Steam Friends", false);
|
||||
AddMultiTargetFilter("@!friends", Filter_NotFriends, "Not Steam Friends", false);
|
||||
|
||||
RegConsoleCmd("sm_admins", Command_Admins, "Currently online admins.");
|
||||
RegConsoleCmd("sm_friends", Command_Friends, "Currently online friends.");
|
||||
|
||||
if(g_bLateLoad)
|
||||
{
|
||||
char sSteam32ID[32];
|
||||
for(new i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i) &&
|
||||
GetClientAuthId(i, AuthId_Steam2, sSteam32ID, sizeof(sSteam32ID)))
|
||||
{
|
||||
OnClientAuthorized(i, sSteam32ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OnPluginEnd()
|
||||
{
|
||||
RemoveMultiTargetFilter("@admins", Filter_Admin);
|
||||
RemoveMultiTargetFilter("@!admins", Filter_NotAdmin);
|
||||
RemoveMultiTargetFilter("@friends", Filter_Friends);
|
||||
RemoveMultiTargetFilter("@!friends", Filter_NotFriends);
|
||||
}
|
||||
|
||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
||||
{
|
||||
CreateNative("IsClientFriend", Native_IsClientFriend);
|
||||
CreateNative("ReadClientFriends", Native_ReadClientFriends);
|
||||
RegPluginLibrary("AdvancedTargeting");
|
||||
|
||||
g_bLateLoad = late;
|
||||
return APLRes_Success;
|
||||
}
|
||||
|
||||
public Action Command_Admins(int client, int args)
|
||||
{
|
||||
char aBuf[1024];
|
||||
char aBuf2[MAX_NAME_LENGTH];
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && GetAdminFlag(GetUserAdmin(i), Admin_Generic))
|
||||
{
|
||||
GetClientName(i, aBuf2, sizeof(aBuf2));
|
||||
StrCat(aBuf, sizeof(aBuf), aBuf2);
|
||||
StrCat(aBuf, sizeof(aBuf), ", ");
|
||||
}
|
||||
}
|
||||
|
||||
if(strlen(aBuf))
|
||||
{
|
||||
aBuf[strlen(aBuf) - 2] = 0;
|
||||
PrintToChat(client, "[SM] Admins currently online: %s", aBuf);
|
||||
}
|
||||
else
|
||||
PrintToChat(client, "[SM] Admins currently online: none");
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_Friends(int client, int args)
|
||||
{
|
||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
||||
{
|
||||
PrintToChat(client, "[SM] Could not read your friendslist, your profile must be set to public!");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char aBuf[1024];
|
||||
char aBuf2[MAX_NAME_LENGTH];
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
||||
{
|
||||
int Steam3ID = GetSteamAccountID(i);
|
||||
|
||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) != -1)
|
||||
{
|
||||
GetClientName(i, aBuf2, sizeof(aBuf2));
|
||||
StrCat(aBuf, sizeof(aBuf), aBuf2);
|
||||
StrCat(aBuf, sizeof(aBuf), ", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(strlen(aBuf))
|
||||
{
|
||||
aBuf[strlen(aBuf) - 2] = 0;
|
||||
PrintToChat(client, "[SM] Friends currently online: %s", aBuf);
|
||||
}
|
||||
else
|
||||
PrintToChat(client, "[SM] Friends currently online: none");
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public bool Filter_Admin(const char[] sPattern, Handle hClients, int client)
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && GetAdminFlag(GetUserAdmin(i), Admin_Generic))
|
||||
{
|
||||
PushArrayCell(hClients, i);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Filter_NotAdmin(const char[] sPattern, Handle hClients, int client)
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && !GetAdminFlag(GetUserAdmin(i), Admin_Generic))
|
||||
{
|
||||
PushArrayCell(hClients, i);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Filter_Friends(const char[] sPattern, Handle hClients, int client)
|
||||
{
|
||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
||||
{
|
||||
PrintToChat(client, "[SM] Could not read your friendslist, your profile must be set to public!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(i != client && IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
||||
{
|
||||
int Steam3ID = GetSteamAccountID(i);
|
||||
|
||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) != -1)
|
||||
PushArrayCell(hClients, i);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Filter_NotFriends(const char[] sPattern, Handle hClients, int client)
|
||||
{
|
||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
||||
{
|
||||
PrintToChat(client, "[SM] Could not read your friendslist, your profile must be set to public!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(i != client && IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
||||
{
|
||||
int Steam3ID = GetSteamAccountID(i);
|
||||
|
||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) == -1)
|
||||
PushArrayCell(hClients, i);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnClientAuthorized(int client, const char[] auth)
|
||||
{
|
||||
if(IsFakeClient(client))
|
||||
return;
|
||||
|
||||
char sSteam64ID[32];
|
||||
Steam32IDtoSteam64ID(auth, sSteam64ID, sizeof(sSteam64ID));
|
||||
|
||||
static char sRequest[256];
|
||||
FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=%s&steamid=%s&relationship=friend&format=vdf", STEAM_API_KEY, sSteam64ID);
|
||||
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
|
||||
if (!hRequest ||
|
||||
!SteamWorks_SetHTTPRequestContextValue(hRequest, client) ||
|
||||
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
CloseHandle(hRequest);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
if(g_FriendsArray[client] != INVALID_HANDLE)
|
||||
CloseHandle(g_FriendsArray[client]);
|
||||
|
||||
g_FriendsArray[client] = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
public OnTransferComplete(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, int client)
|
||||
{
|
||||
if(bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
// Private profile or maybe steam down?
|
||||
//LogError("SteamAPI HTTP Response failed: %d", eStatusCode);
|
||||
CloseHandle(hRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
int Length;
|
||||
SteamWorks_GetHTTPResponseBodySize(hRequest, Length);
|
||||
|
||||
char[] sData = new char[Length];
|
||||
SteamWorks_GetHTTPResponseBodyData(hRequest, sData, Length);
|
||||
//SteamWorks_GetHTTPResponseBodyCallback(hRequest, APIWebResponse, client);
|
||||
|
||||
CloseHandle(hRequest);
|
||||
|
||||
APIWebResponse(sData, client);
|
||||
}
|
||||
|
||||
public APIWebResponse(const char[] sData, int client)
|
||||
{
|
||||
KeyValues Response = new KeyValues("SteamAPIResponse");
|
||||
if(!Response.ImportFromString(sData, "SteamAPIResponse"))
|
||||
{
|
||||
LogError("ImportFromString(sData, \"SteamAPIResponse\") failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Response.JumpToKey("friends"))
|
||||
{
|
||||
LogError("JumpToKey(\"friends\") failed.");
|
||||
delete Response;
|
||||
return;
|
||||
}
|
||||
|
||||
// No friends?
|
||||
if(!Response.GotoFirstSubKey())
|
||||
{
|
||||
//LogError("GotoFirstSubKey() failed.");
|
||||
delete Response;
|
||||
return;
|
||||
}
|
||||
|
||||
g_FriendsArray[client] = CreateArray();
|
||||
|
||||
char sCommunityID[32];
|
||||
do
|
||||
{
|
||||
Response.GetString("steamid", sCommunityID, sizeof(sCommunityID));
|
||||
|
||||
PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID));
|
||||
}
|
||||
while(Response.GotoNextKey());
|
||||
|
||||
delete Response;
|
||||
|
||||
/* DEPRECATED JSON CODE
|
||||
Handle hJSON = DecodeJSON(sData);
|
||||
if(!hJSON)
|
||||
{
|
||||
LogError("DecodeJSON failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
Handle hFriendslist = INVALID_HANDLE;
|
||||
if(!JSONGetObject(hJSON, "friendslist", hFriendslist))
|
||||
{
|
||||
LogError("JSONGetObject(hJSON, \"friendslist\", hFriendslist) failed.");
|
||||
DestroyJSON(hJSON);
|
||||
return;
|
||||
}
|
||||
|
||||
Handle hFriends = INVALID_HANDLE;
|
||||
if(!JSONGetArray(hFriendslist, "friends", hFriends))
|
||||
{
|
||||
LogError("JSONGetObject(hFriendslist, \"friends\", hFriends) failed.");
|
||||
DestroyJSON(hJSON);
|
||||
return;
|
||||
}
|
||||
|
||||
int ArraySize = GetArraySize(hFriends);
|
||||
PrintToServer("ArraySize: %d", ArraySize);
|
||||
|
||||
for(int i = 0; i < ArraySize; i++)
|
||||
{
|
||||
Handle hEntry = INVALID_HANDLE;
|
||||
JSONGetArrayObject(hFriends, i, hEntry);
|
||||
|
||||
static char sCommunityID[32];
|
||||
if(!JSONGetString(hEntry, "steamid", sCommunityID, sizeof(sCommunityID)))
|
||||
{
|
||||
LogError("JSONGetString(hArray, \"steamid\", sCommunityID, %d) failed.", sizeof(sCommunityID));
|
||||
DestroyJSON(hJSON);
|
||||
return;
|
||||
}
|
||||
|
||||
PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID));
|
||||
}
|
||||
|
||||
DestroyJSON(hJSON);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
stock bool Steam32IDtoSteam64ID(const char[] sSteam32ID, char[] sSteam64ID, int Size)
|
||||
{
|
||||
if(strlen(sSteam32ID) < 11 || strncmp(sSteam32ID[0], "STEAM_0:", 8))
|
||||
{
|
||||
sSteam64ID[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int iUpper = 765611979;
|
||||
int isSteam64ID = StringToInt(sSteam32ID[10]) * 2 + 60265728 + sSteam32ID[8] - 48;
|
||||
|
||||
int iDiv = isSteam64ID / 100000000;
|
||||
int iIdx = 9 - (iDiv ? (iDiv / 10 + 1) : 0);
|
||||
iUpper += iDiv;
|
||||
|
||||
IntToString(isSteam64ID, sSteam64ID[iIdx], Size - iIdx);
|
||||
iIdx = sSteam64ID[9];
|
||||
IntToString(iUpper, sSteam64ID, Size);
|
||||
sSteam64ID[9] = iIdx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
stock int Steam64toSteam3(const char[] sSteam64ID)
|
||||
{
|
||||
if(strlen(sSteam64ID) != 17)
|
||||
return 0;
|
||||
|
||||
// convert SteamID64 to array of integers
|
||||
int aSteam64ID[17];
|
||||
for(int i = 0; i < 17; i++)
|
||||
aSteam64ID[i] = sSteam64ID[i] - 48;
|
||||
|
||||
// subtract individual SteamID64 identifier (0x0110000100000000)
|
||||
int aSteam64IDIdent[] = {7, 6, 5, 6, 1, 1, 9, 7, 9, 6, 0, 2, 6, 5, 7, 2, 8};
|
||||
int Carry = 0;
|
||||
for(int i = 16; i >= 0; i--)
|
||||
{
|
||||
if(aSteam64ID[i] < aSteam64IDIdent[i] + Carry)
|
||||
{
|
||||
aSteam64ID[i] = aSteam64ID[i] - aSteam64IDIdent[i] - Carry + 10;
|
||||
Carry = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
aSteam64ID[i] = aSteam64ID[i] - aSteam64IDIdent[i] - Carry;
|
||||
Carry = 0;
|
||||
}
|
||||
}
|
||||
|
||||
char aBuf[17];
|
||||
int j = 0;
|
||||
bool ZereosDone = false;
|
||||
for(int i = 0; i < 17; i++)
|
||||
{
|
||||
if(!ZereosDone && !aSteam64ID[i])
|
||||
continue;
|
||||
ZereosDone = true;
|
||||
|
||||
aBuf[j++] = aSteam64ID[i] + 48;
|
||||
}
|
||||
|
||||
return StringToInt(aBuf);
|
||||
}
|
||||
|
||||
public int Native_IsClientFriend(Handle plugin, int numParams)
|
||||
{
|
||||
new client = GetNativeCell(1);
|
||||
new friend = GetNativeCell(2);
|
||||
|
||||
if(client > MaxClients || client <= 0 || friend > MaxClients || friend <= 0)
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!IsClientInGame(client) || !IsClientInGame(friend))
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(IsFakeClient(client) || IsFakeClient(friend))
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is fake-client.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
||||
return -1;
|
||||
|
||||
if(IsClientAuthorized(friend))
|
||||
{
|
||||
int Steam3ID = GetSteamAccountID(friend);
|
||||
|
||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) != -1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Native_ReadClientFriends(Handle plugin, int numParams)
|
||||
{
|
||||
new client = GetNativeCell(1);
|
||||
|
||||
if(client > MaxClients || client <= 0)
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(g_FriendsArray[client] != INVALID_HANDLE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
25
AdvancedTargeting/scripting/include/AdvancedTargeting.inc
Normal file
25
AdvancedTargeting/scripting/include/AdvancedTargeting.inc
Normal file
@ -0,0 +1,25 @@
|
||||
#if defined _AdvancedTargeting_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _AdvancedTargeting_Included
|
||||
|
||||
native int IsClientFriend(int client, int friend);
|
||||
native int ReadClientFriends(int client);
|
||||
|
||||
public SharedPlugin:__pl_AdvancedTargeting =
|
||||
{
|
||||
name = "AdvancedTargeting",
|
||||
file = "AdvancedTargeting.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public __pl_myfile_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("IsClientFriend");
|
||||
}
|
||||
#endif
|
1
AdvancedTargeting/scripting/include/SteamWorks.inc
Symbolic link
1
AdvancedTargeting/scripting/include/SteamWorks.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/SteamWorks.inc
|
314
AfkManager/scripting/AfkManager.sp
Normal file
314
AfkManager/scripting/AfkManager.sp
Normal file
@ -0,0 +1,314 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <cstrike>
|
||||
|
||||
#define AFK_CHECK_INTERVAL 5.0
|
||||
|
||||
bool g_Players_bEnabled[MAXPLAYERS + 1];
|
||||
bool g_Players_bFlagged[MAXPLAYERS + 1];
|
||||
int g_Players_iLastAction[MAXPLAYERS + 1];
|
||||
float g_Players_fEyePosition[MAXPLAYERS + 1][3];
|
||||
int g_Players_iButtons[MAXPLAYERS + 1];
|
||||
int g_Players_iSpecMode[MAXPLAYERS + 1];
|
||||
int g_Players_iSpecTarget[MAXPLAYERS + 1];
|
||||
|
||||
float g_fKickTime;
|
||||
float g_fMoveTime;
|
||||
float g_fWarnTime;
|
||||
int g_iKickMinPlayers;
|
||||
int g_iMoveMinPlayers;
|
||||
int g_iImmunity;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Good AFK Manager",
|
||||
author = "BotoX",
|
||||
description = "A good AFK manager?",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public Cvar_KickTime(Handle:cvar, const String:oldvalue[], const String:newvalue[])
|
||||
{
|
||||
g_fKickTime = GetConVarFloat(cvar);
|
||||
}
|
||||
public Cvar_MoveTime(Handle:cvar, const String:oldvalue[], const String:newvalue[])
|
||||
{
|
||||
g_fMoveTime = GetConVarFloat(cvar);
|
||||
}
|
||||
public Cvar_WarnTime(Handle:cvar, const String:oldvalue[], const String:newvalue[])
|
||||
{
|
||||
g_fWarnTime = GetConVarFloat(cvar);
|
||||
}
|
||||
public Cvar_KickMinPlayers(Handle:cvar, const String:oldvalue[], const String:newvalue[])
|
||||
{
|
||||
g_iKickMinPlayers = GetConVarInt(cvar);
|
||||
}
|
||||
public Cvar_MoveMinPlayers(Handle:cvar, const String:oldvalue[], const String:newvalue[])
|
||||
{
|
||||
g_iMoveMinPlayers = GetConVarInt(cvar);
|
||||
}
|
||||
public Cvar_Immunity(Handle:cvar, const String:oldvalue[], const String:newvalue[])
|
||||
{
|
||||
g_iImmunity = GetConVarInt(cvar);
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
Handle cvar;
|
||||
HookConVarChange((cvar = CreateConVar("sm_afk_move_min", "4", "Min players for AFK move")), Cvar_MoveMinPlayers);
|
||||
g_iMoveMinPlayers = GetConVarInt(cvar);
|
||||
|
||||
HookConVarChange((cvar = CreateConVar("sm_afk_kick_min", "6", "Min players for AFK kick")), Cvar_KickMinPlayers);
|
||||
g_iKickMinPlayers = GetConVarInt(cvar);
|
||||
|
||||
HookConVarChange((cvar = CreateConVar("sm_afk_move_time", "60.0", "Time in seconds for AFK Move. 0 = DISABLED")), Cvar_MoveTime);
|
||||
g_fMoveTime = GetConVarFloat(cvar);
|
||||
|
||||
HookConVarChange((cvar = CreateConVar("sm_afk_kick_time", "120.0", "Time in seconds to AFK Kick. 0 = DISABLED")), Cvar_KickTime);
|
||||
g_fKickTime = GetConVarFloat(cvar);
|
||||
|
||||
HookConVarChange((cvar = CreateConVar("sm_afk_warn_time", "30.0", "Time in seconds remaining before warning")), Cvar_WarnTime);
|
||||
g_fWarnTime = GetConVarFloat(cvar);
|
||||
|
||||
HookConVarChange((cvar = CreateConVar("sm_afk_immunity", "1", "AFK admins immunity: 0 = DISABLED, 1 = COMPLETE, 2 = KICK, 3 = MOVE")), Cvar_Immunity);
|
||||
g_iImmunity = GetConVarInt(cvar);
|
||||
|
||||
CloseHandle(cvar);
|
||||
|
||||
AddCommandListener(Command_Say, "say");
|
||||
AddCommandListener(Command_Say, "say_team");
|
||||
HookEvent("player_team", Event_PlayerTeamPost, EventHookMode_Post);
|
||||
|
||||
AutoExecConfig(true, "plugin.AfkManager");
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
CreateTimer(AFK_CHECK_INTERVAL, Timer_CheckPlayer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
||||
for (int Index = 1; Index <= MaxClients; Index++)
|
||||
{
|
||||
g_Players_bEnabled[Index] = false;
|
||||
if (IsClientConnected(Index) && IsClientInGame(Index) && !IsFakeClient(Index))
|
||||
InitializePlayer(Index);
|
||||
}
|
||||
}
|
||||
|
||||
CheckAdminImmunity(Index)
|
||||
{
|
||||
AdminId Id = GetUserAdmin(Index);
|
||||
return GetAdminFlag(Id, Admin_Generic);
|
||||
}
|
||||
|
||||
ResetPlayer(Index)
|
||||
{
|
||||
g_Players_bEnabled[Index] = false;
|
||||
g_Players_bFlagged[Index] = false;
|
||||
g_Players_iLastAction[Index] = 0;
|
||||
g_Players_fEyePosition[Index] = Float:{0.0, 0.0, 0.0};
|
||||
g_Players_iButtons[Index] = 0;
|
||||
g_Players_iSpecMode[Index] = 0;
|
||||
g_Players_iSpecTarget[Index] = 0;
|
||||
}
|
||||
|
||||
InitializePlayer(Index)
|
||||
{
|
||||
if (!(g_iImmunity == 1 && CheckAdminImmunity(Index)))
|
||||
{
|
||||
ResetPlayer(Index);
|
||||
g_Players_iLastAction[Index] = GetTime();
|
||||
g_Players_bEnabled[Index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public OnClientPostAdminCheck(Index)
|
||||
{
|
||||
if (!IsFakeClient(Index))
|
||||
InitializePlayer(Index);
|
||||
}
|
||||
|
||||
public OnClientDisconnect(Index)
|
||||
{
|
||||
ResetPlayer(Index);
|
||||
}
|
||||
|
||||
public Action:Event_PlayerTeamPost(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
int Index = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||
if (Index > 0 && !IsFakeClient(Index))
|
||||
{
|
||||
if (!g_Players_bEnabled[Index])
|
||||
InitializePlayer(Index);
|
||||
g_Players_iLastAction[Index] = GetTime();
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Say(Index, const String:Command[], Args)
|
||||
{
|
||||
g_Players_iLastAction[Index] = GetTime();
|
||||
}
|
||||
|
||||
public Action:OnPlayerRunCmd(Index, &iButtons, &iImpulse, Float:fVel[3], Float:fAngles[3], &iWeapon)
|
||||
{
|
||||
if (((g_Players_fEyePosition[Index][0] != fAngles[0]) ||
|
||||
(g_Players_fEyePosition[Index][1] != fAngles[1]) ||
|
||||
(g_Players_fEyePosition[Index][2] != fAngles[2]))
|
||||
&& g_Players_iSpecMode[Index] != 4) // OBS_MODE_IN_EYE
|
||||
{
|
||||
if(!((iButtons & IN_LEFT) || (iButtons & IN_RIGHT)))
|
||||
g_Players_iLastAction[Index] = GetTime();
|
||||
|
||||
g_Players_fEyePosition[Index] = fAngles;
|
||||
}
|
||||
|
||||
if(g_Players_iButtons[Index] != iButtons)
|
||||
{
|
||||
g_Players_iLastAction[Index] = GetTime();
|
||||
g_Players_iButtons[Index] = iButtons;
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action:Timer_CheckPlayer(Handle:Timer, any:Data)
|
||||
{
|
||||
int Index;
|
||||
int Clients = 0;
|
||||
|
||||
for (Index = 1; Index <= MaxClients; Index++)
|
||||
{
|
||||
if (IsClientInGame(Index) && !IsFakeClient(Index))
|
||||
Clients++;
|
||||
}
|
||||
|
||||
bool bMovePlayers = (Clients >= g_iMoveMinPlayers && g_fMoveTime > 0.0);
|
||||
bool bKickPlayers = (Clients >= g_iKickMinPlayers && g_fKickTime > 0.0);
|
||||
|
||||
if (!bMovePlayers && !bKickPlayers)
|
||||
return Plugin_Continue;
|
||||
|
||||
for (Index = 1; Index <= MaxClients; Index++)
|
||||
{
|
||||
if (!g_Players_bEnabled[Index] || !IsClientInGame(Index)) // Is this player actually in the game?
|
||||
continue;
|
||||
|
||||
int iTeamNum = GetClientTeam(Index);
|
||||
|
||||
if (IsClientObserver(Index))
|
||||
{
|
||||
if (iTeamNum > CS_TEAM_SPECTATOR && !IsPlayerAlive(Index))
|
||||
continue;
|
||||
|
||||
int iSpecMode = g_Players_iSpecMode[Index];
|
||||
int iSpecTarget = g_Players_iSpecTarget[Index];
|
||||
|
||||
g_Players_iSpecMode[Index] = GetEntProp(Index, Prop_Send, "m_iObserverMode");
|
||||
g_Players_iSpecTarget[Index] = GetEntPropEnt(Index, Prop_Send, "m_hObserverTarget");
|
||||
|
||||
if ((iSpecMode && g_Players_iSpecMode[Index] != iSpecMode) || (iSpecTarget && g_Players_iSpecTarget[Index] != iSpecTarget))
|
||||
g_Players_iLastAction[Index] = GetTime();
|
||||
}
|
||||
|
||||
int IdleTime = GetTime() - g_Players_iLastAction[Index];
|
||||
|
||||
if (g_Players_bFlagged[Index] && (g_fKickTime - IdleTime) > 0.0)
|
||||
{
|
||||
PrintCenterText(Index, "Welcome back!");
|
||||
PrintToChat(Index, "\x04[AFK] \x01You have been un-flagged for being inactive.");
|
||||
g_Players_bFlagged[Index] = false;
|
||||
}
|
||||
|
||||
if (bMovePlayers && iTeamNum > CS_TEAM_SPECTATOR && ( !g_iImmunity || g_iImmunity == 2 || !CheckAdminImmunity(Index)))
|
||||
{
|
||||
float iTimeleft = g_fMoveTime - IdleTime;
|
||||
if (iTimeleft > 0.0)
|
||||
{
|
||||
if(iTimeleft <= g_fWarnTime)
|
||||
{
|
||||
PrintCenterText(Index, "Warning: If you do not move in %d seconds, you will be moved to spectate.", RoundToFloor(iTimeleft));
|
||||
PrintToChat(Index, "\x04[AFK] \x01Warning: If you do not move in %d seconds, you will be moved to spectate.", RoundToFloor(iTimeleft));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decl String:f_Name[MAX_NAME_LENGTH+4];
|
||||
Format(f_Name, sizeof(f_Name), "\x03%N\x01", Index);
|
||||
PrintToChatAll("\x04[AFK] \x01%s was moved to spectate for being AFK too long.", f_Name);
|
||||
ForcePlayerSuicide(Index);
|
||||
ChangeClientTeam(Index, CS_TEAM_SPECTATOR);
|
||||
}
|
||||
}
|
||||
else if (g_fKickTime > 0.0 && (!g_iImmunity || g_iImmunity == 3 || !CheckAdminImmunity(Index)))
|
||||
{
|
||||
float iTimeleft = g_fKickTime - IdleTime;
|
||||
if (iTimeleft > 0.0)
|
||||
{
|
||||
if (iTimeleft <= g_fWarnTime)
|
||||
{
|
||||
PrintCenterText(Index, "Warning: If you do not move in %d seconds, you will be kick-flagged for being inactive.", RoundToFloor(iTimeleft));
|
||||
PrintToChat(Index, "\x04[AFK] \x01Warning: If you do not move in %d seconds, you will be kick-flagged for being inactive.", RoundToFloor(iTimeleft));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_Players_bFlagged[Index])
|
||||
{
|
||||
PrintToChat(Index, "\x04[AFK] \x01You have been kick-flagged for being inactive.");
|
||||
g_Players_bFlagged[Index] = true;
|
||||
}
|
||||
int FlaggedPlayers = 0;
|
||||
int Position = 1;
|
||||
for (int Index_ = 1; Index_ <= MaxClients; Index_++)
|
||||
{
|
||||
if (!g_Players_bFlagged[Index_])
|
||||
continue;
|
||||
|
||||
FlaggedPlayers++;
|
||||
int IdleTime_ = GetTime() - g_Players_iLastAction[Index_];
|
||||
|
||||
if (IdleTime_ > IdleTime)
|
||||
Position++;
|
||||
}
|
||||
PrintCenterText(Index, "You have been kick-flagged for being inactive. [%d/%d]", Position, FlaggedPlayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(bKickPlayers)
|
||||
{
|
||||
int InactivePlayer = -1;
|
||||
int InactivePlayerTime = 0;
|
||||
|
||||
for (Index = 1; Index <= MaxClients; Index++)
|
||||
{
|
||||
if (!g_Players_bFlagged[Index])
|
||||
continue;
|
||||
|
||||
int IdleTime = GetTime() - g_Players_iLastAction[Index];
|
||||
|
||||
if (IdleTime > InactivePlayerTime)
|
||||
{
|
||||
InactivePlayer = Index;
|
||||
InactivePlayerTime = IdleTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (InactivePlayer == -1)
|
||||
break;
|
||||
else
|
||||
{
|
||||
decl String:f_Name[MAX_NAME_LENGTH+4];
|
||||
Format(f_Name, sizeof(f_Name), "\x03%N\x01", InactivePlayer);
|
||||
PrintToChatAll("\x04[AFK] %s was kicked for being AFK too long. (%d seconds)", f_Name, InactivePlayerTime);
|
||||
KickClient(InactivePlayer, "[AFK] You were kicked for being AFK too long. (%d seconds)", InactivePlayerTime);
|
||||
Clients--;
|
||||
g_Players_bFlagged[InactivePlayer] = false;
|
||||
}
|
||||
|
||||
bKickPlayers = (Clients >= g_iKickMinPlayers && g_fKickTime > 0.0);
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
31
ConnectAnnounce/scripting/ConnectAnnounce.sp
Normal file
31
ConnectAnnounce/scripting/ConnectAnnounce.sp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <geoip>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
public Plugin myinfo = {
|
||||
name = "Connect Announce",
|
||||
author = "BotoX",
|
||||
description = "Simple connect announcer",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
}
|
||||
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
if(IsFakeClient(client))
|
||||
return;
|
||||
|
||||
static char sAuth[32];
|
||||
static char sIP[16];
|
||||
static char sCountry[32];
|
||||
|
||||
GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth));
|
||||
|
||||
if(GetClientIP(client, sIP, sizeof(sIP)) && GeoipCountry(sIP, sCountry, sizeof(sCountry)))
|
||||
PrintToChatAll("\x04%L [\x03%s\x04] connected from %s", client, sAuth, sCountry);
|
||||
else
|
||||
PrintToChatAll("\x04%L [\x03%s\x04] connected", client, sAuth);
|
||||
}
|
648
ExtraCommands/scripting/ExtraCommands.sp
Normal file
648
ExtraCommands/scripting/ExtraCommands.sp
Normal file
@ -0,0 +1,648 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <sdkhooks>
|
||||
|
||||
bool g_bInBuyZoneAll = false;
|
||||
bool g_bInBuyZone[MAXPLAYERS + 1] = {false, ...};
|
||||
|
||||
bool g_bInfAmmoHooked = false;
|
||||
bool g_bInfAmmoAll = false;
|
||||
bool g_bInfAmmo[MAXPLAYERS + 1] = {false, ...};
|
||||
|
||||
ConVar g_CVar_sv_pausable;
|
||||
bool g_bPaused;
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Advanced Commands",
|
||||
author = "BotoX",
|
||||
description = "Adds: hp, kevlar, weapon, strip, buyzone, iammo, speed",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
RegAdminCmd("sm_hp", Command_Health, ADMFLAG_GENERIC, "sm_hp <#userid|name> <value>");
|
||||
RegAdminCmd("sm_kevlar", Command_Kevlar, ADMFLAG_GENERIC, "sm_kevlar <#userid|name> <value>");
|
||||
RegAdminCmd("sm_weapon", Command_Weapon, ADMFLAG_GENERIC, "sm_weapon <#userid|name> <name> [clip] [ammo]");
|
||||
RegAdminCmd("sm_give", Command_Weapon, ADMFLAG_GENERIC, "sm_give <#userid|name> <name> [clip] [ammo]");
|
||||
RegAdminCmd("sm_strip", Command_Strip, ADMFLAG_GENERIC, "sm_strip <#userid|name>");
|
||||
RegAdminCmd("sm_buyzone", Command_BuyZone, ADMFLAG_CUSTOM3, "sm_buyzone <#userid|name> <0|1>");
|
||||
RegAdminCmd("sm_iammo", Command_InfAmmo, ADMFLAG_CUSTOM3, "sm_iammo <#userid|name> <0|1>");
|
||||
RegAdminCmd("sm_speed", Command_Speed, ADMFLAG_CUSTOM3, "sm_speed <#userid|name> <0|1>");
|
||||
|
||||
HookEvent("bomb_planted", Event_BombPlanted, EventHookMode_Pre);
|
||||
HookEvent("bomb_defused", Event_BombDefused, EventHookMode_Pre);
|
||||
|
||||
g_CVar_sv_pausable = FindConVar("sv_pausable");
|
||||
if(g_CVar_sv_pausable)
|
||||
AddCommandListener(Listener_Pause, "pause");
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
g_bInBuyZoneAll = false;
|
||||
g_bInfAmmoAll = false;
|
||||
if(g_bInfAmmoHooked)
|
||||
{
|
||||
UnhookEvent("weapon_fire", Event_WeaponFire);
|
||||
g_bInfAmmoHooked = false;
|
||||
}
|
||||
|
||||
/* Handle late load */
|
||||
for(new i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientConnected(i) && IsClientInGame(i))
|
||||
{
|
||||
g_bInfAmmo[i] = false;
|
||||
g_bInBuyZone[i] = false;
|
||||
SDKHook(i, SDKHook_PreThink, OnPreThink);
|
||||
SDKHook(i, SDKHook_PostThinkPost, OnPostThinkPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action Listener_Pause(int client, const char[] command, int argc)
|
||||
{
|
||||
if(!g_CVar_sv_pausable.BoolValue)
|
||||
{
|
||||
ReplyToCommand(client, "sv_pausable is set to 0!");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
if(client == 0)
|
||||
{
|
||||
PrintToServer("[SM] Cannot use command from server console.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
if(!IsClientAuthorized(client) || !GetAdminFlag(GetUserAdmin(client), Admin_Generic))
|
||||
{
|
||||
ReplyToCommand(client, "You do not have permission to pause the game.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "%s the game.", g_bPaused ? "Unpaused" : "Paused");
|
||||
LogAction(client, -1, "%s the game.", g_bPaused ? "Unpaused" : "Paused");
|
||||
g_bPaused = !g_bPaused;
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
|
||||
public Action:Event_BombPlanted(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
for(new i = 1; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if(IsClientInGame(i))
|
||||
ClientCommand(i, "playgamesound \"radio/bombpl.wav\"");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Event_BombDefused(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
for(new i = 1; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if(IsClientInGame(i))
|
||||
ClientCommand(i, "playgamesound \"radio/bombdef.wav\"");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public OnClientPutInServer(client)
|
||||
{
|
||||
g_bInBuyZone[client] = false;
|
||||
g_bInfAmmo[client] = false;
|
||||
SDKHook(client, SDKHook_PreThink, OnPreThink);
|
||||
SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
||||
}
|
||||
|
||||
public OnPreThink(client)
|
||||
{
|
||||
if(IsClientInGame(client) && IsPlayerAlive(client))
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_bInBombZone", 1);
|
||||
}
|
||||
}
|
||||
|
||||
public OnPostThinkPost(client)
|
||||
{
|
||||
if(IsClientInGame(client) && IsPlayerAlive(client))
|
||||
{
|
||||
if(g_bInBuyZoneAll || g_bInBuyZone[client])
|
||||
SetEntProp(client, Prop_Send, "m_bInBuyZone", 1);
|
||||
}
|
||||
}
|
||||
|
||||
public Event_WeaponFire(Handle:hEvent, String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
|
||||
if(!g_bInfAmmoAll && !g_bInfAmmo[client])
|
||||
return;
|
||||
|
||||
new weapon = GetEntPropEnt(client, Prop_Data, "m_hActiveWeapon", 0);
|
||||
if(IsValidEntity(weapon))
|
||||
{
|
||||
if(weapon == GetPlayerWeaponSlot(client, 0) || weapon == GetPlayerWeaponSlot(client, 1))
|
||||
{
|
||||
if(GetEntProp(weapon, Prop_Send, "m_iState", 4, 0) == 2 && GetEntProp(weapon, Prop_Send, "m_iClip1", 4, 0))
|
||||
{
|
||||
new toAdd = 1;
|
||||
new String:weaponClassname[128];
|
||||
GetEntityClassname(weapon, weaponClassname, 128);
|
||||
|
||||
if(StrEqual(weaponClassname, "weapon_glock", true) || StrEqual(weaponClassname, "weapon_famas", true))
|
||||
{
|
||||
if(GetEntProp(weapon, Prop_Data, "m_bBurstMode", 4, 0))
|
||||
{
|
||||
switch (GetEntProp(weapon, Prop_Send, "m_iClip1", 4, 0))
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
toAdd = 1;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
toAdd = 2;
|
||||
}
|
||||
default:
|
||||
{
|
||||
toAdd = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SetEntProp(weapon, Prop_Send, "m_iClip1", GetEntProp(weapon, Prop_Send, "m_iClip1", 4, 0) + toAdd, 4, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public Action:Command_Health(client, args)
|
||||
{
|
||||
if(args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_hp <#userid|name> <value>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new amount = 0;
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if(StringToIntEx(arg2, amount) == 0 || amount <= 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
SetEntProp(target_list[i], Prop_Send, "m_iHealth", amount, 1);
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "Set health to %d on target %s", amount, target_name);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Kevlar(client, args)
|
||||
{
|
||||
if(args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_kevlar <#userid|name> <value>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new amount = 0;
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if(StringToIntEx(arg2, amount) == 0 || amount <= 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
SetEntProp(target_list[i], Prop_Send, "m_ArmorValue", amount, 1);
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "Set kevlar to %d on target %s", amount, target_name);
|
||||
LogAction(client, -1, "Set kevlar to %d on target %s", amount, target_name);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Weapon(client, args)
|
||||
{
|
||||
if(args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_weapon <#userid|name> <weapon> [clip] [ammo]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new ammo = 2500;
|
||||
new clip = -1;
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:arg2[65];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
|
||||
decl String:weapon[65];
|
||||
if(strncmp(arg2, "weapon_", 7) != 0 && strncmp(arg2, "item_", 5) != 0 && !StrEqual(arg2, "nvg", false))
|
||||
Format(weapon, sizeof(weapon), "weapon_%s", arg2);
|
||||
else
|
||||
strcopy(weapon, sizeof(weapon), arg2);
|
||||
|
||||
if(StrContains(weapon, "grenade", false) != -1 || StrContains(weapon, "flashbang", false) != -1 || strncmp(arg2, "item_", 5) == 0)
|
||||
ammo = -1;
|
||||
|
||||
new AdminId:id = GetUserAdmin(client);
|
||||
new superadmin = GetAdminFlag(id, Admin_Custom3);
|
||||
|
||||
if(!superadmin)
|
||||
{
|
||||
if(StrEqual(weapon, "weapon_c4", false) || StrEqual(weapon, "weapon_smokegrenade", false) || StrEqual(weapon, "item_defuser", false))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] This weapon is restricted!");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
if(args >= 3)
|
||||
{
|
||||
decl String:arg3[20];
|
||||
GetCmdArg(3, arg3, sizeof(arg3));
|
||||
if(StringToIntEx(arg3, clip) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Clip Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
if(args >= 4)
|
||||
{
|
||||
decl String:arg4[20];
|
||||
GetCmdArg(4, arg4, sizeof(arg4));
|
||||
if(StringToIntEx(arg4, ammo) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Ammo Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
if(StrContains(weapon, "grenade", false) != -1 || StrContains(weapon, "flashbang", false) != -1)
|
||||
{
|
||||
new tmp = ammo;
|
||||
ammo = clip;
|
||||
clip = tmp;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(StrEqual(weapon, "nvg", false))
|
||||
{
|
||||
for(new i = 0; i < target_count; i++)
|
||||
SetEntProp(target_list[i], Prop_Send, "m_bHasNightVision", 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
new ent = GivePlayerItem(target_list[i], weapon);
|
||||
|
||||
if(ent == -1) {
|
||||
ReplyToCommand(client, "[SM] Invalid Weapon");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(clip != -1)
|
||||
SetEntProp(ent, Prop_Send, "m_iClip1", clip);
|
||||
|
||||
if(ammo != -1)
|
||||
{
|
||||
new PrimaryAmmoType = GetEntProp(ent, Prop_Data, "m_iPrimaryAmmoType");
|
||||
if(PrimaryAmmoType != -1)
|
||||
SetEntProp(target_list[i], Prop_Send, "m_iAmmo", ammo, _, PrimaryAmmoType);
|
||||
}
|
||||
|
||||
if(strncmp(arg2, "item_", 5) != 0 && !StrEqual(weapon, "weapon_hegrenade", false))
|
||||
EquipPlayerWeapon(target_list[i], ent);
|
||||
|
||||
if(ammo != -1)
|
||||
{
|
||||
new PrimaryAmmoType = GetEntProp(ent, Prop_Data, "m_iPrimaryAmmoType");
|
||||
if(PrimaryAmmoType != -1)
|
||||
SetEntProp(target_list[i], Prop_Send, "m_iAmmo", ammo, _, PrimaryAmmoType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "Gave %s to target %s", weapon, target_name);
|
||||
LogAction(client, -1, "Gave %s to target %s", weapon, target_name);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Strip(client, args)
|
||||
{
|
||||
if(args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_strip <#userid|name>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
for(new j = 0; j < 5; j++)
|
||||
{
|
||||
new w = -1;
|
||||
while ((w = GetPlayerWeaponSlot(target_list[i], j)) != -1)
|
||||
{
|
||||
if(IsValidEntity(w))
|
||||
RemovePlayerItem(target_list[i], w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "Stripped all weapons on target %s", target_name);
|
||||
LogAction(client, -1, "Stripped all weapons on target %s", target_name);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_BuyZone(client, args)
|
||||
{
|
||||
if(args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_buyzone <#userid|name> <0|1>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new value = -1;
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if(StringToIntEx(arg2, value) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
|
||||
if(StrEqual(arg, "@all", false))
|
||||
{
|
||||
target_name = "all players";
|
||||
g_bInBuyZoneAll = value ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
g_bInBuyZone[target_list[i]] = value ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "%s permanent buyzone on target %s", (value ? "Enabled" : "Disabled"), target_name);
|
||||
LogAction(client, -1, "%s permanent buyzone on target %s", (value ? "Enabled" : "Disabled"), target_name);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_InfAmmo(client, args)
|
||||
{
|
||||
if(args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_iammo <#userid|name> <0|1>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new value = -1;
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if(StringToIntEx(arg2, value) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
|
||||
if(StrEqual(arg, "@all", false))
|
||||
{
|
||||
target_name = "all players";
|
||||
g_bInfAmmoAll = value ? true : false;
|
||||
|
||||
if(!g_bInfAmmoAll)
|
||||
{
|
||||
for(new i = 0; i < MAXPLAYERS; i++)
|
||||
g_bInfAmmo[i] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
g_bInfAmmo[target_list[i]] = value ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "%s infinite ammo on target %s", (value ? "Enabled" : "Disabled"), target_name);
|
||||
LogAction(client, -1, "%s infinite ammo on target %s", (value ? "Enabled" : "Disabled"), target_name);
|
||||
|
||||
if(g_bInfAmmoAll)
|
||||
{
|
||||
if(!g_bInfAmmoHooked)
|
||||
{
|
||||
HookEvent("weapon_fire", Event_WeaponFire);
|
||||
g_bInfAmmoHooked = true;
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if(g_bInfAmmo[i])
|
||||
{
|
||||
if(!g_bInfAmmoHooked)
|
||||
{
|
||||
HookEvent("weapon_fire", Event_WeaponFire);
|
||||
g_bInfAmmoHooked = true;
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
if(g_bInfAmmoHooked)
|
||||
{
|
||||
UnhookEvent("weapon_fire", Event_WeaponFire);
|
||||
g_bInfAmmoHooked = false;
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Speed(client, args)
|
||||
{
|
||||
if(args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_speed <#userid|name> <value>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new Float:speed = 0.0;
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if(StringToFloatEx(arg2, speed) == 0 || speed <= 0.0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Invalid Value");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(new i = 0; i < target_count; i++)
|
||||
{
|
||||
SetEntPropFloat(target_list[i], Prop_Data, "m_flLaggedMovementValue", speed);
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "Set speed to %.2f on target %s", speed, target_name);
|
||||
LogAction(client, -1, "Set speed to %.2f on target %s", speed, target_name);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
50
FixGameUI/gamedata/FixGameUI.games.txt
Normal file
50
FixGameUI/gamedata/FixGameUI.games.txt
Normal file
@ -0,0 +1,50 @@
|
||||
"Games"
|
||||
{
|
||||
"#default"
|
||||
{
|
||||
"#supported"
|
||||
{
|
||||
"game" "cstrike"
|
||||
"game" "tf"
|
||||
"game" "dod"
|
||||
"game" "hl2mp"
|
||||
"engine" "sdk2013"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "36"
|
||||
"linux" "37"
|
||||
"mac" "37"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"csgo"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "40"
|
||||
"linux" "41"
|
||||
"mac" "41"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"left4dead2"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"AcceptInput"
|
||||
{
|
||||
"windows" "43"
|
||||
"linux" "44"
|
||||
"mac" "44"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
128
FixGameUI/scripting/FixGameUI.sp
Normal file
128
FixGameUI/scripting/FixGameUI.sp
Normal file
@ -0,0 +1,128 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools_entoutput>
|
||||
#include <sdktools_entinput>
|
||||
#include <sdktools_engine>
|
||||
#include <sdkhooks>
|
||||
#include <dhooks>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "FixGameUI",
|
||||
author = "hlstriker + GoD-Tony",
|
||||
description = "Fixes game_ui entity bug.",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
}
|
||||
|
||||
new g_iAttachedGameUI[MAXPLAYERS+1];
|
||||
new Handle:g_hAcceptInput = INVALID_HANDLE;
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post);
|
||||
|
||||
HookEntityOutput("game_ui", "PlayerOn", GameUI_PlayerOn);
|
||||
HookEntityOutput("game_ui", "PlayerOff", GameUI_PlayerOff);
|
||||
|
||||
// Gamedata.
|
||||
new Handle:hConfig = LoadGameConfigFile("FixGameUI.games");
|
||||
if (hConfig == INVALID_HANDLE)
|
||||
{
|
||||
SetFailState("Could not find gamedata file: FixGameUI.games.txt");
|
||||
}
|
||||
|
||||
new offset = GameConfGetOffset(hConfig, "AcceptInput");
|
||||
if (offset == -1)
|
||||
{
|
||||
SetFailState("Failed to find AcceptInput offset");
|
||||
}
|
||||
CloseHandle(hConfig);
|
||||
|
||||
// DHooks.
|
||||
g_hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, Hook_AcceptInput);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_Object, 20); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_Int);
|
||||
|
||||
}
|
||||
|
||||
public Action:Event_PlayerDeath(Handle:hEvent, const String:szName[], bool:bDontBroadcast)
|
||||
{
|
||||
new iClient = GetClientOfUserId(GetEventInt(hEvent, "userid"));
|
||||
RemoveFromGameUI(iClient);
|
||||
SetClientViewEntity(iClient, iClient);
|
||||
|
||||
new iFlags = GetEntityFlags(iClient);
|
||||
iFlags &= ~FL_ONTRAIN;
|
||||
iFlags &= ~FL_FROZEN;
|
||||
iFlags &= ~FL_ATCONTROLS;
|
||||
SetEntityFlags(iClient, iFlags);
|
||||
}
|
||||
|
||||
public OnClientDisconnect(iClient)
|
||||
{
|
||||
RemoveFromGameUI(iClient);
|
||||
}
|
||||
|
||||
public GameUI_PlayerOn(const String:szOutput[], iCaller, iActivator, Float:fDelay)
|
||||
{
|
||||
if(!(1 <= iActivator <= MaxClients))
|
||||
return;
|
||||
|
||||
g_iAttachedGameUI[iActivator] = EntIndexToEntRef(iCaller);
|
||||
}
|
||||
|
||||
public GameUI_PlayerOff(const String:szOutput[], iCaller, iActivator, Float:fDelay)
|
||||
{
|
||||
if(!(1 <= iActivator <= MaxClients))
|
||||
return;
|
||||
|
||||
g_iAttachedGameUI[iActivator] = 0;
|
||||
}
|
||||
|
||||
RemoveFromGameUI(iClient)
|
||||
{
|
||||
if(!g_iAttachedGameUI[iClient])
|
||||
return;
|
||||
|
||||
new iEnt = EntRefToEntIndex(g_iAttachedGameUI[iClient]);
|
||||
if(iEnt == INVALID_ENT_REFERENCE)
|
||||
return;
|
||||
|
||||
AcceptEntityInput(iEnt, "Deactivate", iClient, iEnt);
|
||||
}
|
||||
|
||||
public OnEntityCreated(entity, const String:classname[])
|
||||
{
|
||||
if (StrEqual(classname, "game_ui"))
|
||||
{
|
||||
DHookEntity(g_hAcceptInput, false, entity);
|
||||
}
|
||||
}
|
||||
|
||||
public MRESReturn:Hook_AcceptInput(thisptr, Handle:hReturn, Handle:hParams)
|
||||
{
|
||||
new String:sCommand[128];
|
||||
DHookGetParamString(hParams, 1, sCommand, sizeof(sCommand));
|
||||
|
||||
if (StrEqual(sCommand, "Deactivate"))
|
||||
{
|
||||
new pPlayer = GetEntPropEnt(thisptr, Prop_Data, "m_player");
|
||||
|
||||
if (pPlayer == -1)
|
||||
{
|
||||
// Manually disable think.
|
||||
SetEntProp(thisptr, Prop_Data, "m_nNextThinkTick", -1);
|
||||
|
||||
DHookSetReturn(hReturn, false);
|
||||
return MRES_Supercede;
|
||||
}
|
||||
}
|
||||
|
||||
DHookSetReturn(hReturn, true);
|
||||
return MRES_Ignored;
|
||||
}
|
1
FixGameUI/scripting/includes/dhooks.inc
Symbolic link
1
FixGameUI/scripting/includes/dhooks.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/dhooks.inc
|
44
Flashlight/scripting/Flashlight.sp
Normal file
44
Flashlight/scripting/Flashlight.sp
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
#pragma newdecls required
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Flashlight",
|
||||
author = "BotoX",
|
||||
description = "Dead flashlight, block sound from other clients.",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
AddNormalSoundHook(OnSound);
|
||||
}
|
||||
|
||||
public Action OnSound(int clients[64], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags)
|
||||
{
|
||||
if(entity >= 1 && entity <= MAXPLAYERS && StrEqual(sample, "items/flashlight1.wav", false))
|
||||
{
|
||||
numClients = 1;
|
||||
clients[0] = entity;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
|
||||
{
|
||||
// Dead flashlight
|
||||
if(impulse == 100 && !IsPlayerAlive(client))
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_fEffects", GetEntProp(client, Prop_Send, "m_fEffects") ^ 4);
|
||||
ClientCommand(client, "playgamesound \"items/flashlight1.wav\"");
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
112
ForceInputs/scripting/ForceInputs.sp
Normal file
112
ForceInputs/scripting/ForceInputs.sp
Normal file
@ -0,0 +1,112 @@
|
||||
//====================================================================================================
|
||||
//
|
||||
// Name: ForceInput
|
||||
// Author: zaCade
|
||||
// Description: Allows admins to force inputs on entities. (ent_fire)
|
||||
//
|
||||
//====================================================================================================
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "ForceInput",
|
||||
author = "zaCade",
|
||||
description = "Allows admins to force inputs on entities. (ent_fire)",
|
||||
version = "1.2",
|
||||
url = ""
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public OnPluginStart()
|
||||
{
|
||||
RegAdminCmd("sm_forceinput", Command_ForceInput, ADMFLAG_ROOT);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public Action:Command_ForceInput(client, args)
|
||||
{
|
||||
if (GetCmdArgs() < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_forceinput <classname/targetname> <input> [parameter]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new String:sArguments[3][256];
|
||||
GetCmdArg(1, sArguments[0], sizeof(sArguments[]));
|
||||
GetCmdArg(2, sArguments[1], sizeof(sArguments[]));
|
||||
GetCmdArg(3, sArguments[2], sizeof(sArguments[]));
|
||||
|
||||
if (StrEqual(sArguments[0], "!self"))
|
||||
{
|
||||
if (strlen(sArguments[2]))
|
||||
SetVariantString(sArguments[2]);
|
||||
|
||||
AcceptEntityInput(client, sArguments[1], client, client);
|
||||
ReplyToCommand(client, "[SM] Input succesfull.");
|
||||
}
|
||||
else if (StrEqual(sArguments[0], "!target"))
|
||||
{
|
||||
new entity = INVALID_ENT_REFERENCE;
|
||||
|
||||
new Float:fPosition[3], Float:fAngles[3];
|
||||
GetClientEyePosition(client, fPosition);
|
||||
GetClientEyeAngles(client, fAngles);
|
||||
|
||||
new Handle:hTrace = TR_TraceRayFilterEx(fPosition, fAngles, MASK_SOLID, RayType_Infinite, TraceRayFilter, client);
|
||||
|
||||
if (TR_DidHit(hTrace) && ((entity = TR_GetEntityIndex(hTrace)) >= 1))
|
||||
{
|
||||
if (IsValidEntity(entity) || IsValidEdict(entity))
|
||||
{
|
||||
if (strlen(sArguments[2]))
|
||||
SetVariantString(sArguments[2]);
|
||||
|
||||
AcceptEntityInput(entity, sArguments[1], client, client);
|
||||
ReplyToCommand(client, "[SM] Input succesfull.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new entity = INVALID_ENT_REFERENCE;
|
||||
|
||||
while ((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
|
||||
{
|
||||
if (IsValidEntity(entity) || IsValidEdict(entity))
|
||||
{
|
||||
new String:sClassname[64], String:sTargetname[64];
|
||||
GetEntPropString(entity, Prop_Data, "m_iClassname", sClassname, sizeof(sClassname));
|
||||
GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname));
|
||||
|
||||
if (StrEqual(sClassname, sArguments[0], false) || StrEqual(sTargetname, sArguments[0], false))
|
||||
{
|
||||
if (strlen(sArguments[2]))
|
||||
SetVariantString(sArguments[2]);
|
||||
|
||||
AcceptEntityInput(entity, sArguments[1], client, client);
|
||||
ReplyToCommand(client, "[SM] Input succesfull.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public bool:TraceRayFilter(entity, mask, any:client)
|
||||
{
|
||||
if (entity == client)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
44
KevlarEquip/scripting/KevlarEquip.sp
Normal file
44
KevlarEquip/scripting/KevlarEquip.sp
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdkhooks>
|
||||
#include <zombiereloaded>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "KevlarEquip",
|
||||
author = "BotoX",
|
||||
description = "Equip players with kevlar when they spawn, unglitch kevlar and strip it when you get infected",
|
||||
version = "2.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public OnClientPutInServer(client)
|
||||
{
|
||||
SDKHook(client, SDKHook_SpawnPost, Hook_OnPlayerSpawn);
|
||||
}
|
||||
|
||||
public Hook_OnPlayerSpawn(client)
|
||||
{
|
||||
if(IsPlayerAlive(client) && ZR_IsClientHuman(client))
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_ArmorValue", 100, 1);
|
||||
SetEntProp(client, Prop_Send, "m_bHasHelmet", 1);
|
||||
// Reset last hitgroup to generic - fixes kevlar bug
|
||||
// Example: You get hit in the head by a bullet as a zombie
|
||||
// the round ends, you spawn as a human.
|
||||
// You get damaged by a trigger, the game still thinks you
|
||||
// are getting damaged in the head hitgroup, >mfw source engine.
|
||||
// Thanks to leaked 2007 Source Engine Code.
|
||||
SetEntData(client, 4444, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
public ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn)
|
||||
{
|
||||
if(IsPlayerAlive(client))
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_ArmorValue", 0, 1);
|
||||
SetEntProp(client, Prop_Send, "m_bHasHelmet", 0);
|
||||
}
|
||||
}
|
28
NapalmLagFix/gamedata/napalmlagfix.games.txt
Normal file
28
NapalmLagFix/gamedata/napalmlagfix.games.txt
Normal file
@ -0,0 +1,28 @@
|
||||
"Games"
|
||||
{
|
||||
"cstrike"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"RadiusDamage"
|
||||
{
|
||||
"windows" "68"
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"csgo"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"RadiusDamage"
|
||||
{
|
||||
"windows" "68"
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
118
NapalmLagFix/scripting/NapalmLagFix.sp
Normal file
118
NapalmLagFix/scripting/NapalmLagFix.sp
Normal file
@ -0,0 +1,118 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <dhooks>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <updater>
|
||||
|
||||
#define PLUGIN_NAME "Napalm Lag Fix"
|
||||
#define PLUGIN_VERSION "1.0.3"
|
||||
|
||||
#define UPDATE_URL "http://godtony.mooo.com/napalmlagfix/napalmlagfix.txt"
|
||||
|
||||
#define DMG_BURN (1 << 3)
|
||||
|
||||
new Handle:g_hRadiusDamage = INVALID_HANDLE;
|
||||
new bool:g_bCheckNullPtr = false;
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = PLUGIN_NAME,
|
||||
author = "GoD-Tony + BotoX",
|
||||
description = "Prevents lag when napalm is used on players",
|
||||
version = PLUGIN_VERSION,
|
||||
url = "https://forums.alliedmods.net/showthread.php?t=188093" // Demo: http://youtu.be/YdhAu5IEVVM
|
||||
};
|
||||
|
||||
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
|
||||
{
|
||||
MarkNativeAsOptional("DHookIsNullParam");
|
||||
|
||||
return APLRes_Success;
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
// Convars.
|
||||
new Handle:hCvar = CreateConVar("sm_napalmlagfix_version", PLUGIN_VERSION, PLUGIN_NAME, FCVAR_PLUGIN|FCVAR_NOTIFY|FCVAR_DONTRECORD);
|
||||
SetConVarString(hCvar, PLUGIN_VERSION);
|
||||
|
||||
// Gamedata.
|
||||
new Handle:hConfig = LoadGameConfigFile("napalmlagfix.games");
|
||||
|
||||
if (hConfig == INVALID_HANDLE)
|
||||
{
|
||||
SetFailState("Could not find gamedata file: napalmlagfix.games.txt");
|
||||
}
|
||||
|
||||
new offset = GameConfGetOffset(hConfig, "RadiusDamage");
|
||||
|
||||
if (offset == -1)
|
||||
{
|
||||
SetFailState("Failed to find RadiusDamage offset");
|
||||
}
|
||||
|
||||
CloseHandle(hConfig);
|
||||
|
||||
// DHooks.
|
||||
g_bCheckNullPtr = (GetFeatureStatus(FeatureType_Native, "DHookIsNullParam") == FeatureStatus_Available);
|
||||
|
||||
g_hRadiusDamage = DHookCreate(offset, HookType_GameRules, ReturnType_Void, ThisPointer_Ignore, Hook_RadiusDamage);
|
||||
DHookAddParam(g_hRadiusDamage, HookParamType_ObjectPtr); // 1 - CTakeDamageInfo &info
|
||||
DHookAddParam(g_hRadiusDamage, HookParamType_VectorPtr); // 2 - Vector &vecSrc
|
||||
DHookAddParam(g_hRadiusDamage, HookParamType_Float); // 3 - float flRadius
|
||||
DHookAddParam(g_hRadiusDamage, HookParamType_Int); // 4 - int iClassIgnore
|
||||
DHookAddParam(g_hRadiusDamage, HookParamType_CBaseEntity); // 5 - CBaseEntity *pEntityIgnore
|
||||
|
||||
// Updater.
|
||||
if (LibraryExists("updater"))
|
||||
{
|
||||
Updater_AddPlugin(UPDATE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
public OnLibraryAdded(const String:name[])
|
||||
{
|
||||
if (StrEqual(name, "updater"))
|
||||
{
|
||||
Updater_AddPlugin(UPDATE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
public Updater_OnPluginUpdated()
|
||||
{
|
||||
// There could be new gamedata in this update.
|
||||
ReloadPlugin();
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
DHookGamerules(g_hRadiusDamage, false);
|
||||
}
|
||||
|
||||
public MRESReturn:Hook_RadiusDamage(Handle:hParams)
|
||||
{
|
||||
// As of DHooks 1.0.12 we must check for a null param.
|
||||
if (g_bCheckNullPtr && DHookIsNullParam(hParams, 5))
|
||||
return MRES_Ignored;
|
||||
|
||||
new iDmgBits = DHookGetParamObjectPtrVar(hParams, 1, 60, ObjectValueType_Int);
|
||||
new iEntIgnore = DHookGetParam(hParams, 5);
|
||||
|
||||
if(!(iDmgBits & DMG_BURN))
|
||||
return MRES_Ignored;
|
||||
|
||||
// Block napalm damage if it's coming from another client.
|
||||
if (1 <= iEntIgnore <= MaxClients)
|
||||
return MRES_Supercede;
|
||||
|
||||
// Block napalm that comes from grenades
|
||||
new String:sEntClassName[64];
|
||||
if(GetEntityClassname(iEntIgnore, sEntClassName, sizeof(sEntClassName)))
|
||||
{
|
||||
if(!strcmp(sEntClassName, "hegrenade_projectile"))
|
||||
return MRES_Supercede;
|
||||
}
|
||||
|
||||
return MRES_Ignored;
|
||||
}
|
1
NapalmLagFix/scripting/include/dhooks.inc
Symbolic link
1
NapalmLagFix/scripting/include/dhooks.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/dhooks.inc
|
15
NoGrenadeRinging/gamedata/NoGrenadeRinging.games.txt
Normal file
15
NoGrenadeRinging/gamedata/NoGrenadeRinging.games.txt
Normal file
@ -0,0 +1,15 @@
|
||||
"Games"
|
||||
{
|
||||
"cstrike"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"OnDamagedByExplosion"
|
||||
{
|
||||
"windows" "335"
|
||||
"linux" "336"
|
||||
"mac" "336"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
NoGrenadeRinging/scripting/NoGrenadeRinging.sp
Normal file
42
NoGrenadeRinging/scripting/NoGrenadeRinging.sp
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma semicolon 1
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <dhooks>
|
||||
|
||||
//int CCSPlayer::OnDamagedByExplosion(CTakeDamageInfo const&)
|
||||
Handle g_hDamagedByExplosion;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "NoGrenadeRinging",
|
||||
author = "BotoX",
|
||||
description = "Block the annoying ringing noise when a grenade explodes next to you",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
Handle hTemp = LoadGameConfigFile("NoGrenadeRinging.games");
|
||||
if(hTemp == INVALID_HANDLE)
|
||||
SetFailState("Why you no has gamedata?");
|
||||
|
||||
int Offset = GameConfGetOffset(hTemp, "OnDamagedByExplosion");
|
||||
g_hDamagedByExplosion = DHookCreate(Offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnDamagedByExplosion);
|
||||
DHookAddParam(g_hDamagedByExplosion, HookParamType_ObjectPtr);
|
||||
|
||||
CloseHandle(hTemp);
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
//Dont add removal callback for this one
|
||||
DHookEntity(g_hDamagedByExplosion, false, client);
|
||||
}
|
||||
|
||||
//int CCSPlayer::OnDamagedByExplosion(CTakeDamageInfo const&)
|
||||
public MRESReturn:OnDamagedByExplosion(int pThis, Handle hReturn, Handle hParams)
|
||||
{
|
||||
// Block call
|
||||
return MRES_Supercede;
|
||||
}
|
1
NoGrenadeRinging/scripting/include/dhooks.inc
Symbolic link
1
NoGrenadeRinging/scripting/include/dhooks.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/dhooks.inc
|
91
NoShake/scripting/NoShake.sp
Normal file
91
NoShake/scripting/NoShake.sp
Normal file
@ -0,0 +1,91 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdkhooks>
|
||||
#include <clientprefs>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
Handle g_hNoShakeCookie;
|
||||
ConVar g_Cvar_NoShakeGlobal;
|
||||
|
||||
bool g_bNoShake[MAXPLAYERS] = {false, ...};
|
||||
bool g_bNoShakeGlobal = false;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "NoShake",
|
||||
author = "BotoX",
|
||||
description = "Disable env_shake",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
RegConsoleCmd("sm_shake", Command_Shake, "[NoShake] Disables or enables screen shakes.");
|
||||
RegConsoleCmd("sm_noshake", Command_Shake, "[NoShake] Disables or enables screen shakes.");
|
||||
|
||||
g_hNoShakeCookie = RegClientCookie("noshake_cookie", "NoShake", CookieAccess_Protected);
|
||||
|
||||
g_Cvar_NoShakeGlobal = CreateConVar("sm_noshake_global", "0", "Disable screenshake globally.", 0, true, 0.0, true, 1.0);
|
||||
g_bNoShakeGlobal = g_Cvar_NoShakeGlobal.BoolValue;
|
||||
g_Cvar_NoShakeGlobal.AddChangeHook(OnConVarChanged);
|
||||
|
||||
HookUserMessage(GetUserMessageId("Shake"), MsgHook, true);
|
||||
}
|
||||
|
||||
public void OnClientCookiesCached(int client)
|
||||
{
|
||||
static char sCookieValue[2];
|
||||
GetClientCookie(client, g_hNoShakeCookie, sCookieValue, sizeof(sCookieValue));
|
||||
g_bNoShake[client] = StringToInt(sCookieValue) != 0;
|
||||
}
|
||||
|
||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||
{
|
||||
if(StringToInt(newValue) > StringToInt(oldValue))
|
||||
PrintToChatAll("\x03[NoShake]\x01 Enabled NoShake globally!");
|
||||
else if(StringToInt(newValue) < StringToInt(oldValue))
|
||||
PrintToChatAll("\x03[NoShake]\x01 Disabled NoShake globally!");
|
||||
|
||||
g_bNoShakeGlobal = StringToInt(newValue) != 0;
|
||||
}
|
||||
|
||||
public Action MsgHook(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
|
||||
{
|
||||
if(playersNum == 1 && (g_bNoShakeGlobal || g_bNoShake[players[0]]))
|
||||
return Plugin_Handled;
|
||||
else
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Command_Shake(int client, int args)
|
||||
{
|
||||
if(g_bNoShakeGlobal)
|
||||
return Plugin_Handled;
|
||||
|
||||
if(!AreClientCookiesCached(client))
|
||||
{
|
||||
ReplyToCommand(client, "\x03[NoShake]\x01 Please wait. Your settings are still loading.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(g_bNoShake[client])
|
||||
{
|
||||
g_bNoShake[client] = false;
|
||||
ReplyToCommand(client, "\x03[NoShake]\x01 has been disabled!");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_bNoShake[client] = true;
|
||||
ReplyToCommand(client, "\x03[NoShake]\x01 has been enabled!");
|
||||
}
|
||||
|
||||
static char sCookieValue[2];
|
||||
IntToString(g_bNoShake[client], sCookieValue, sizeof(sCookieValue));
|
||||
SetClientCookie(client, g_hNoShakeCookie, sCookieValue);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v1_4_1.cfg
Normal file
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v1_4_1.cfg
Normal file
@ -0,0 +1,49 @@
|
||||
"levels"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "Level 0"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "a"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "a"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "b"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "b"
|
||||
}
|
||||
}
|
||||
}
|
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v3_1.cfg
Normal file
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v3_1.cfg
Normal file
@ -0,0 +1,49 @@
|
||||
"levels"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "Level 0"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "a"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "a"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "b"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "b"
|
||||
}
|
||||
}
|
||||
}
|
77
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v6.cfg
Normal file
77
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v6.cfg
Normal file
@ -0,0 +1,77 @@
|
||||
"levels"
|
||||
{
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser1" "leveling_counter,Add,1"
|
||||
"ExactMatches" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser1" "leveling_counter,Add,1"
|
||||
"ExactMatches" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser1" "leveling_counter,Add,1"
|
||||
"ExactMatches" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser1" "leveling_counter,Add,1"
|
||||
"MinMatches" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
}
|
57
SaveLevel/configs/savelevel/ze_FFXII_Feywood_b3_1.cfg
Normal file
57
SaveLevel/configs/savelevel/ze_FFXII_Feywood_b3_1.cfg
Normal file
@ -0,0 +1,57 @@
|
||||
"levels"
|
||||
{
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser4" "Map_Level_Check,Add,1"
|
||||
"ExactMatches" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser4" "Map_Level_Check,Add,1"
|
||||
"ExactMatches" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser4" "Map_Level_Check,Add,1"
|
||||
"MinMatches" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
}
|
98
SaveLevel/configs/savelevel/ze_FFXII_Paramina_Rift_v1_3.cfg
Normal file
98
SaveLevel/configs/savelevel/ze_FFXII_Paramina_Rift_v1_3.cfg
Normal file
@ -0,0 +1,98 @@
|
||||
"levels"
|
||||
{
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser2" "leveling_counter,add,1"
|
||||
"ExactMatches" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser2" "leveling_counter,add,1"
|
||||
"ExactMatches" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser2" "leveling_counter,add,1"
|
||||
"ExactMatches" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser2" "leveling_counter,add,1"
|
||||
"ExactMatches" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
"5"
|
||||
{
|
||||
"name" "Level 5"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser2" "leveling_counter,add,1"
|
||||
"MinMatches" "5"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
||||
"m_iFrags" "500"
|
||||
}
|
||||
}
|
||||
}
|
76
SaveLevel/configs/savelevel/ze_TESV_Skyrim_v3.cfg
Normal file
76
SaveLevel/configs/savelevel/ze_TESV_Skyrim_v3.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
"levels"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "Level 0"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
"m_iFrags" "0"
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "2"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "3"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "4"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
}
|
77
SaveLevel/configs/savelevel/ze_harry_potter_v1_3.cfg
Normal file
77
SaveLevel/configs/savelevel/ze_harry_potter_v1_3.cfg
Normal file
@ -0,0 +1,77 @@
|
||||
"levels"
|
||||
{
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser3" "map_wandlevels,Add,1"
|
||||
"ExactMatches" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser3" "map_wandlevels,Add,1"
|
||||
"ExactMatches" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser3" "map_wandlevels,Add,1"
|
||||
"ExactMatches" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"outputs"
|
||||
{
|
||||
"m_OnUser3" "map_wandlevels,Add,1"
|
||||
"MinMatches" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v2_2fix.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v2_2fix.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"levels"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "Level 0"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
"m_iFrags" "0"
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "2"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "3"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "4"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
"5"
|
||||
{
|
||||
"name" "Level 5"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "5"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "5"
|
||||
"m_iFrags" "500"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v3_5.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v3_5.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"levels"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "Level 0"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
"m_iFrags" "0"
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "2"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "3"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "4"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
"5"
|
||||
{
|
||||
"name" "Level 5"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "5"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "5"
|
||||
"m_iFrags" "500"
|
||||
}
|
||||
}
|
||||
}
|
76
SaveLevel/configs/savelevel/ze_tesv_skyrim_v4fix.cfg
Normal file
76
SaveLevel/configs/savelevel/ze_tesv_skyrim_v4fix.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
"levels"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "Level 0"
|
||||
"restore"
|
||||
{
|
||||
"m_iName" ""
|
||||
"m_iFrags" "0"
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"name" "Level 1"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "1"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "1"
|
||||
"m_iFrags" "100"
|
||||
}
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"name" "Level 2"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "2"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "2"
|
||||
"m_iFrags" "200"
|
||||
}
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"name" "Level 3"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "3"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "3"
|
||||
"m_iFrags" "300"
|
||||
}
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"name" "Level 4"
|
||||
"match"
|
||||
{
|
||||
"props"
|
||||
{
|
||||
"m_iName" "4"
|
||||
}
|
||||
}
|
||||
"restore"
|
||||
{
|
||||
"m_iName" "4"
|
||||
"m_iFrags" "400"
|
||||
}
|
||||
}
|
||||
}
|
299
SaveLevel/scripting/SaveLevel.sp
Normal file
299
SaveLevel/scripting/SaveLevel.sp
Normal file
@ -0,0 +1,299 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <outputinfo>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
StringMap g_PlayerLevels;
|
||||
KeyValues g_Config;
|
||||
KeyValues g_PropAltNames;
|
||||
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "SaveLevel",
|
||||
author = "BotoX",
|
||||
description = "Saves players level on maps when they disconnect and restore them on connect.",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
g_PropAltNames = new KeyValues("PropAltNames");
|
||||
g_PropAltNames.SetString("m_iName", "targetname");
|
||||
}
|
||||
|
||||
public void OnPluginEnd()
|
||||
{
|
||||
if(g_Config)
|
||||
delete g_Config;
|
||||
if(g_PlayerLevels)
|
||||
delete g_PlayerLevels;
|
||||
delete g_PropAltNames;
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
if(g_Config)
|
||||
delete g_Config;
|
||||
if(g_PlayerLevels)
|
||||
delete g_PlayerLevels;
|
||||
|
||||
char sMapName[PLATFORM_MAX_PATH];
|
||||
GetCurrentMap(sMapName, sizeof(sMapName));
|
||||
|
||||
char sConfigFile[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/savelevel/%s.cfg", sMapName);
|
||||
if(!FileExists(sConfigFile))
|
||||
{
|
||||
LogMessage("Could not find mapconfig: \"%s\"", sConfigFile);
|
||||
return;
|
||||
}
|
||||
LogMessage("Found mapconfig: \"%s\"", sConfigFile);
|
||||
|
||||
g_Config = new KeyValues("levels");
|
||||
if(!g_Config.ImportFromFile(sConfigFile))
|
||||
{
|
||||
delete g_Config;
|
||||
LogMessage("ImportFromFile() failed!");
|
||||
return;
|
||||
}
|
||||
g_Config.Rewind();
|
||||
|
||||
if(!g_Config.GotoFirstSubKey())
|
||||
{
|
||||
delete g_Config;
|
||||
LogMessage("GotoFirstSubKey() failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
g_PlayerLevels = new StringMap();
|
||||
}
|
||||
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
if(!g_PlayerLevels)
|
||||
return;
|
||||
|
||||
char sSteamID[32];
|
||||
GetClientAuthId(client, AuthId_Steam3, sSteamID, sizeof(sSteamID));
|
||||
|
||||
static char sTargets[128];
|
||||
if(g_PlayerLevels.GetString(sSteamID, sTargets, sizeof(sTargets)))
|
||||
{
|
||||
g_PlayerLevels.Remove(sSteamID);
|
||||
char sNames[128];
|
||||
static char asTargets[4][32];
|
||||
int Split = ExplodeString(sTargets, ";", asTargets, sizeof(asTargets), sizeof(asTargets[]));
|
||||
|
||||
g_Config.Rewind();
|
||||
for(int i = 0; i < Split; i++)
|
||||
{
|
||||
if(!g_Config.JumpToKey(asTargets[i]))
|
||||
continue;
|
||||
|
||||
static char sKey[32];
|
||||
static char sValue[1024];
|
||||
if(g_Config.JumpToKey("restore"))
|
||||
{
|
||||
if(g_Config.GotoFirstSubKey(false))
|
||||
{
|
||||
do
|
||||
{
|
||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
||||
if(StrEqual(sKey, "AddOutput", false))
|
||||
{
|
||||
SetVariantString(sValue);
|
||||
AcceptEntityInput(client, sKey, client, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropFieldType Type;
|
||||
int NumBits;
|
||||
int Offset = FindDataMapInfo(client, sKey, Type, NumBits);
|
||||
if(Offset != -1)
|
||||
{
|
||||
if(Type == PropField_Integer)
|
||||
{
|
||||
int Value = StringToInt(sValue);
|
||||
SetEntData(client, Offset, Value, NumBits / 8, false);
|
||||
}
|
||||
else if(Type == PropField_Float)
|
||||
{
|
||||
float Value = StringToFloat(sValue);
|
||||
SetEntDataFloat(client, Offset, Value, false);
|
||||
}
|
||||
else if(Type == PropField_String)
|
||||
{
|
||||
SetEntDataString(client, Offset, sValue, strlen(sValue) + 1, false);
|
||||
}
|
||||
else if(Type == PropField_String_T)
|
||||
{
|
||||
static char sAltKey[32];
|
||||
g_PropAltNames.GetString(sKey, sAltKey, sizeof(sAltKey), NULL_STRING);
|
||||
if(sAltKey[0])
|
||||
DispatchKeyValue(client, sAltKey, sValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while(g_Config.GotoNextKey(false));
|
||||
|
||||
g_Config.GoBack();
|
||||
g_Config.GoBack();
|
||||
g_Config.GetString("name", sValue, sizeof(sValue));
|
||||
g_Config.GoBack();
|
||||
StrCat(sNames, sizeof(sNames), sValue);
|
||||
StrCat(sNames, sizeof(sNames), ", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int NamesLen = strlen(sNames);
|
||||
if(NamesLen)
|
||||
{
|
||||
sNames[NamesLen - 2] = 0; // Cut off ', '
|
||||
PrintToChatAll("\x03[SaveLevel]\x01 %N has been restored to: \x04%s", client, sNames);
|
||||
}
|
||||
g_Config.Rewind();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
if(!g_Config || !g_PlayerLevels)
|
||||
return;
|
||||
|
||||
g_Config.Rewind();
|
||||
g_Config.GotoFirstSubKey();
|
||||
|
||||
char sTargets[128];
|
||||
static char sTarget[32];
|
||||
static char sKey[32];
|
||||
static char sValue[1024];
|
||||
static char sOutput[1024];
|
||||
bool Found = false;
|
||||
do
|
||||
{
|
||||
g_Config.GetSectionName(sTarget, sizeof(sTarget));
|
||||
if(!g_Config.JumpToKey("match"))
|
||||
continue;
|
||||
|
||||
int Matches = 0;
|
||||
int ExactMatches = g_Config.GetNum("ExactMatches", -1);
|
||||
int MinMatches = g_Config.GetNum("MinMatches", -1);
|
||||
int MaxMatches = g_Config.GetNum("MaxMatches", -1);
|
||||
|
||||
if(!g_Config.GotoFirstSubKey(false))
|
||||
continue;
|
||||
|
||||
do
|
||||
{
|
||||
static char sSection[32];
|
||||
g_Config.GetSectionName(sSection, sizeof(sSection));
|
||||
|
||||
if(StrEqual(sSection, "outputs"))
|
||||
{
|
||||
int _Matches = 0;
|
||||
int _ExactMatches = g_Config.GetNum("ExactMatches", -1);
|
||||
int _MinMatches = g_Config.GetNum("MinMatches", -1);
|
||||
int _MaxMatches = g_Config.GetNum("MaxMatches", -1);
|
||||
|
||||
if(g_Config.GotoFirstSubKey(false))
|
||||
{
|
||||
do
|
||||
{
|
||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
||||
|
||||
int Count = GetOutputCount(client, sKey);
|
||||
for(int i = 0; i < Count; i++)
|
||||
{
|
||||
int Len = GetOutputTarget(client, sKey, i, sOutput);
|
||||
sOutput[Len] = ','; Len++;
|
||||
Len += GetOutputTargetInput(client, sKey, i, sOutput[Len]);
|
||||
sOutput[Len] = ','; Len++;
|
||||
Len += GetOutputParameter(client, sKey, i, sOutput[Len]);
|
||||
|
||||
if(StrEqual(sValue, sOutput))
|
||||
_Matches++;
|
||||
}
|
||||
}
|
||||
while(g_Config.GotoNextKey(false));
|
||||
|
||||
g_Config.GoBack();
|
||||
}
|
||||
g_Config.GoBack();
|
||||
|
||||
Matches += CalcMatches(_Matches, _ExactMatches, _MinMatches, _MaxMatches);
|
||||
}
|
||||
else if(StrEqual(sSection, "props"))
|
||||
{
|
||||
int _Matches = 0;
|
||||
int _ExactMatches = g_Config.GetNum("ExactMatches", -1);
|
||||
int _MinMatches = g_Config.GetNum("MinMatches", -1);
|
||||
int _MaxMatches = g_Config.GetNum("MaxMatches", -1);
|
||||
|
||||
if(g_Config.GotoFirstSubKey(false))
|
||||
{
|
||||
do
|
||||
{
|
||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
||||
|
||||
GetEntPropString(client, Prop_Data, sKey, sOutput, sizeof(sOutput));
|
||||
|
||||
if(StrEqual(sValue, sOutput))
|
||||
_Matches++;
|
||||
}
|
||||
while(g_Config.GotoNextKey(false));
|
||||
|
||||
g_Config.GoBack();
|
||||
}
|
||||
g_Config.GoBack();
|
||||
|
||||
Matches += CalcMatches(_Matches, _ExactMatches, _MinMatches, _MaxMatches);
|
||||
}
|
||||
}
|
||||
while(g_Config.GotoNextKey(false));
|
||||
|
||||
g_Config.GoBack();
|
||||
|
||||
if(CalcMatches(Matches, ExactMatches, MinMatches, MaxMatches))
|
||||
{
|
||||
if(Found)
|
||||
StrCat(sTargets, sizeof(sTargets), ";");
|
||||
|
||||
Found = true;
|
||||
StrCat(sTargets, sizeof(sTargets), sTarget);
|
||||
}
|
||||
}
|
||||
while(g_Config.GotoNextKey());
|
||||
|
||||
g_Config.Rewind();
|
||||
if(!Found)
|
||||
return;
|
||||
|
||||
char sSteamID[32];
|
||||
GetClientAuthId(client, AuthId_Steam3, sSteamID, sizeof(sSteamID));
|
||||
g_PlayerLevels.SetString(sSteamID, sTargets, true);
|
||||
}
|
||||
|
||||
stock int CalcMatches(int Matches, int ExactMatches, int MinMatches, int MaxMatches)
|
||||
{
|
||||
int Value = 0;
|
||||
if((ExactMatches == -1 && MinMatches == -1 && MaxMatches == -1 && Matches) ||
|
||||
Matches == ExactMatches ||
|
||||
(MinMatches != -1 && MaxMatches == -1 && Matches >= MinMatches) ||
|
||||
(MaxMatches != -1 && MinMatches == -1 && Matches <= MaxMatches) ||
|
||||
(MinMatches != -1 && MaxMatches != -1 && Matches >= MinMatches && Matches <= MaxMatches))
|
||||
{
|
||||
Value++;
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
1
SaveLevel/scripting/include/outputinfo.inc
Symbolic link
1
SaveLevel/scripting/include/outputinfo.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/outputinfo.inc
|
908
SelfMute/scripting/SelfMute.sp
Normal file
908
SelfMute/scripting/SelfMute.sp
Normal file
@ -0,0 +1,908 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <adminmenu>
|
||||
#include <cstrike>
|
||||
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <ccc>
|
||||
#include <zombiereloaded>
|
||||
#include <voiceannounce_ex>
|
||||
#include <AdvancedTargeting>
|
||||
#define REQUIRE_PLUGIN
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
bool g_Plugin_ccc = false;
|
||||
bool g_Plugin_zombiereloaded = false;
|
||||
bool g_Plugin_voiceannounce_ex = false;
|
||||
bool g_Plugin_AdvancedTargeting = false;
|
||||
|
||||
#define PLUGIN_VERSION "2.0"
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "SelfMute",
|
||||
author = "BotoX",
|
||||
description = "Ignore other players in text and voicechat.",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MUTE_NONE = 0,
|
||||
MUTE_SPEC = 1,
|
||||
MUTE_CT = 2,
|
||||
MUTE_T = 4,
|
||||
MUTE_DEAD = 8,
|
||||
MUTE_ALIVE = 16,
|
||||
MUTE_NOTFRIENDS = 32,
|
||||
MUTE_ALL = 64,
|
||||
MUTE_LAST = 64
|
||||
};
|
||||
|
||||
bool g_Ignored[(MAXPLAYERS + 1) * (MAXPLAYERS + 1)];
|
||||
int g_SpecialMutes[MAXPLAYERS + 1];
|
||||
|
||||
char g_PlayerNames[MAXPLAYERS+1][MAX_NAME_LENGTH];
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
CreateConVar("sm_selfmute_version", PLUGIN_VERSION, "Version of Self-Mute", FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
|
||||
|
||||
RegConsoleCmd("sm_sm", Command_SelfMute, "Mute player by typing !sm [playername]");
|
||||
RegConsoleCmd("sm_su", Command_SelfUnMute, "Unmute player by typing !su [playername]");
|
||||
RegConsoleCmd("sm_cm", Command_CheckMutes, "Check who you have self-muted");
|
||||
|
||||
HookEvent("round_start", Event_Round);
|
||||
HookEvent("round_end", Event_Round);
|
||||
HookEvent("player_team", Event_TeamChange);
|
||||
|
||||
UserMsg RadioText = GetUserMessageId("RadioText");
|
||||
if(RadioText == INVALID_MESSAGE_ID)
|
||||
SetFailState("This game doesn't support RadioText user messages.");
|
||||
|
||||
HookUserMessage(RadioText, Hook_UserMessageRadioText, true);
|
||||
|
||||
UserMsg SendAudio = GetUserMessageId("SendAudio");
|
||||
if(SendAudio == INVALID_MESSAGE_ID)
|
||||
SetFailState("This game doesn't support SendAudio user messages.");
|
||||
|
||||
HookUserMessage(SendAudio, Hook_UserMessageSendAudio, true);
|
||||
}
|
||||
|
||||
public void OnAllPluginsLoaded()
|
||||
{
|
||||
g_Plugin_ccc = LibraryExists("ccc");
|
||||
g_Plugin_zombiereloaded = true;//LibraryExists("zombiereloaded");
|
||||
g_Plugin_voiceannounce_ex = LibraryExists("voiceannounce_ex");
|
||||
g_Plugin_AdvancedTargeting = LibraryExists("AdvancedTargeting");
|
||||
PrintToServer("CCC: %s\nZombieReloaded: %s\nVoiceAnnounce: %s\nAdvancedTargeting: %s",
|
||||
(g_Plugin_ccc ? "loaded" : "not loaded"),
|
||||
(g_Plugin_zombiereloaded ? "loaded" : "not loaded"),
|
||||
(g_Plugin_voiceannounce_ex ? "loaded" : "not loaded"),
|
||||
(g_Plugin_AdvancedTargeting ? "loaded" : "not loaded"));
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
g_SpecialMutes[client] = MUTE_NONE;
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
SetIgnored(client, i, false);
|
||||
|
||||
UpdateSpecialMutesOtherClients(client);
|
||||
UpdateIgnored();
|
||||
}
|
||||
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
UpdateSpecialMutesOtherClients(client);
|
||||
UpdateSpecialMutesThisClient(client);
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
g_SpecialMutes[client] = MUTE_NONE;
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
SetIgnored(client, i, false);
|
||||
|
||||
if(IsClientInGame(i) && !IsFakeClient(i) && i != client)
|
||||
SetListenOverride(i, client, Listen_Yes);
|
||||
}
|
||||
|
||||
UpdateIgnored();
|
||||
}
|
||||
|
||||
public void Event_Round(Handle event, const char[] name, bool dontBroadcast)
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i))
|
||||
UpdateSpecialMutesThisClient(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void Event_TeamChange(Handle event, const char[] name, bool dontBroadcast)
|
||||
{
|
||||
int client = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||
|
||||
UpdateSpecialMutesOtherClients(client);
|
||||
}
|
||||
|
||||
public int ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
||||
{
|
||||
UpdateSpecialMutesOtherClients(client);
|
||||
}
|
||||
|
||||
public int ZR_OnClientHumanPost(int client, bool respawn, bool protect)
|
||||
{
|
||||
UpdateSpecialMutesOtherClients(client);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mutes this client on other players
|
||||
*/
|
||||
void UpdateSpecialMutesOtherClients(int client)
|
||||
{
|
||||
bool Alive = IsPlayerAlive(client);
|
||||
int Team = GetClientTeam(client);
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(i == client || !IsClientInGame(i) || IsFakeClient(i))
|
||||
continue;
|
||||
|
||||
int Flags = MUTE_NONE;
|
||||
|
||||
if(g_SpecialMutes[i] & MUTE_SPEC && Team == CS_TEAM_SPECTATOR)
|
||||
Flags |= MUTE_SPEC;
|
||||
|
||||
else if(g_SpecialMutes[i] & MUTE_CT && Alive &&
|
||||
((g_Plugin_zombiereloaded && ZR_IsClientHuman(client)) || (!g_Plugin_zombiereloaded && Team == CS_TEAM_CT)))
|
||||
Flags |= MUTE_CT;
|
||||
|
||||
else if(g_SpecialMutes[i] & MUTE_T && Alive &&
|
||||
((g_Plugin_zombiereloaded && ZR_IsClientZombie(client)) || (!g_Plugin_zombiereloaded && Team == CS_TEAM_T)))
|
||||
Flags |= MUTE_T;
|
||||
|
||||
else if(g_SpecialMutes[i] & MUTE_DEAD && !Alive)
|
||||
Flags |= MUTE_DEAD;
|
||||
|
||||
else if(g_SpecialMutes[i] & MUTE_ALIVE && Alive)
|
||||
Flags |= MUTE_ALIVE;
|
||||
|
||||
else if(g_SpecialMutes[i] & MUTE_NOTFRIENDS &&
|
||||
g_Plugin_AdvancedTargeting && IsClientFriend(i, client) == 0)
|
||||
Flags |= MUTE_NOTFRIENDS;
|
||||
|
||||
else if(g_SpecialMutes[i] & MUTE_ALL)
|
||||
Flags |= MUTE_ALL;
|
||||
|
||||
if(Flags)
|
||||
SetListenOverride(i, client, Listen_No);
|
||||
else if(!GetIgnored(i, client))
|
||||
SetListenOverride(i, client, Listen_Yes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mutes other players on this client
|
||||
*/
|
||||
void UpdateSpecialMutesThisClient(int client)
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(i == client || !IsClientInGame(i) || IsFakeClient(i))
|
||||
continue;
|
||||
|
||||
bool Alive = IsPlayerAlive(i);
|
||||
int Team = GetClientTeam(i);
|
||||
|
||||
int Flags = MUTE_NONE;
|
||||
|
||||
if(g_SpecialMutes[client] & MUTE_SPEC && Team == CS_TEAM_SPECTATOR)
|
||||
Flags |= MUTE_SPEC;
|
||||
|
||||
else if(g_SpecialMutes[client] & MUTE_CT && Alive &&
|
||||
((g_Plugin_zombiereloaded && ZR_IsClientHuman(i) || (!g_Plugin_zombiereloaded) && Team == CS_TEAM_CT)))
|
||||
Flags |= MUTE_CT;
|
||||
|
||||
else if(g_SpecialMutes[client] & MUTE_T && Alive &&
|
||||
((g_Plugin_zombiereloaded && ZR_IsClientZombie(i) || (!g_Plugin_zombiereloaded) && Team == CS_TEAM_T)))
|
||||
Flags |= MUTE_T;
|
||||
|
||||
else if(g_SpecialMutes[client] & MUTE_DEAD && !Alive)
|
||||
Flags |= MUTE_DEAD;
|
||||
|
||||
else if(g_SpecialMutes[client] & MUTE_ALIVE && Alive)
|
||||
Flags |= MUTE_ALIVE;
|
||||
|
||||
else if(g_SpecialMutes[client] & MUTE_NOTFRIENDS &&
|
||||
g_Plugin_AdvancedTargeting && IsClientFriend(client, i) == 0)
|
||||
Flags |= MUTE_NOTFRIENDS;
|
||||
|
||||
else if(g_SpecialMutes[client] & MUTE_ALL)
|
||||
Flags |= MUTE_ALL;
|
||||
|
||||
if(Flags)
|
||||
SetListenOverride(client, i, Listen_No);
|
||||
else if(!GetIgnored(client, i))
|
||||
SetListenOverride(client, i, Listen_Yes);
|
||||
}
|
||||
}
|
||||
|
||||
int GetSpecialMutesFlags(char[] Argument)
|
||||
{
|
||||
int SpecialMute = MUTE_NONE;
|
||||
if(StrEqual(Argument, "@spec", false) || StrEqual(Argument, "@!ct", false) || StrEqual(Argument, "@!t", false))
|
||||
SpecialMute |= MUTE_SPEC;
|
||||
if(StrEqual(Argument, "@ct", false) || StrEqual(Argument, "@!t", false) || StrEqual(Argument, "@!spec", false))
|
||||
SpecialMute |= MUTE_CT;
|
||||
if(StrEqual(Argument, "@t", false) || StrEqual(Argument, "@!ct", false) || StrEqual(Argument, "@!spec", false))
|
||||
SpecialMute |= MUTE_T;
|
||||
if(StrEqual(Argument, "@dead", false) || StrEqual(Argument, "@!alive", false))
|
||||
SpecialMute |= MUTE_DEAD;
|
||||
if(StrEqual(Argument, "@alive", false) || StrEqual(Argument, "@!dead", false))
|
||||
SpecialMute |= MUTE_ALIVE;
|
||||
if(g_Plugin_AdvancedTargeting && StrEqual(Argument, "@!friends", false))
|
||||
SpecialMute |= MUTE_NOTFRIENDS;
|
||||
if(StrEqual(Argument, "@all", false))
|
||||
SpecialMute |= MUTE_ALL;
|
||||
|
||||
return SpecialMute;
|
||||
}
|
||||
|
||||
void FormatSpecialMutes(int SpecialMute, char[] aBuf, int BufLen)
|
||||
{
|
||||
if(!SpecialMute)
|
||||
{
|
||||
StrCat(aBuf, BufLen, "none");
|
||||
return;
|
||||
}
|
||||
|
||||
bool Status = false;
|
||||
int MuteCount = RoundFloat(Logarithm(float(MUTE_LAST), 2.0));
|
||||
for(int i = 0; i <= MuteCount; i++)
|
||||
{
|
||||
switch(SpecialMute & RoundFloat(Pow(2.0, float(i))))
|
||||
{
|
||||
case MUTE_SPEC:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "Spectators, ");
|
||||
Status = true;
|
||||
}
|
||||
case MUTE_CT:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "CTs, ");
|
||||
Status = true;
|
||||
}
|
||||
case MUTE_T:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "Ts, ");
|
||||
Status = true;
|
||||
}
|
||||
case MUTE_DEAD:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "Dead players, ");
|
||||
Status = true;
|
||||
}
|
||||
case MUTE_ALIVE:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "Alive players, ");
|
||||
Status = true;
|
||||
}
|
||||
case MUTE_NOTFRIENDS:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "Not Steam friends, ");
|
||||
Status = true;
|
||||
}
|
||||
case MUTE_ALL:
|
||||
{
|
||||
StrCat(aBuf, BufLen, "Everyone, ");
|
||||
Status = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cut off last ', '
|
||||
if(Status)
|
||||
aBuf[strlen(aBuf) - 2] = 0;
|
||||
}
|
||||
|
||||
bool MuteSpecial(int client, char[] Argument)
|
||||
{
|
||||
bool RetValue = false;
|
||||
int SpecialMute = GetSpecialMutesFlags(Argument);
|
||||
|
||||
if(SpecialMute & MUTE_NOTFRIENDS && g_Plugin_AdvancedTargeting && ReadClientFriends(client) != 1)
|
||||
{
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 Could not read your friendslist, your profile must be set to public!");
|
||||
SpecialMute &= ~MUTE_NOTFRIENDS;
|
||||
RetValue = true;
|
||||
}
|
||||
|
||||
if(SpecialMute)
|
||||
{
|
||||
if(SpecialMute & MUTE_ALL || g_SpecialMutes[client] & MUTE_ALL)
|
||||
{
|
||||
g_SpecialMutes[client] = MUTE_ALL;
|
||||
SpecialMute = MUTE_ALL;
|
||||
}
|
||||
else
|
||||
g_SpecialMutes[client] |= SpecialMute;
|
||||
|
||||
UpdateSpecialMutesThisClient(client);
|
||||
|
||||
char aBuf[128];
|
||||
FormatSpecialMutes(SpecialMute, aBuf, sizeof(aBuf));
|
||||
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted group:\x04 %s", aBuf);
|
||||
RetValue = true;
|
||||
}
|
||||
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
bool UnMuteSpecial(int client, char[] Argument)
|
||||
{
|
||||
int SpecialMute = GetSpecialMutesFlags(Argument);
|
||||
|
||||
if(SpecialMute)
|
||||
{
|
||||
if(SpecialMute & MUTE_ALL)
|
||||
{
|
||||
if(g_SpecialMutes[client])
|
||||
{
|
||||
SpecialMute = g_SpecialMutes[client];
|
||||
g_SpecialMutes[client] = MUTE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i))
|
||||
UnIgnore(client, i);
|
||||
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 all players");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
g_SpecialMutes[client] &= ~SpecialMute;
|
||||
|
||||
UpdateSpecialMutesThisClient(client);
|
||||
|
||||
char aBuf[256];
|
||||
FormatSpecialMutes(SpecialMute, aBuf, sizeof(aBuf));
|
||||
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-unmuted group:\x04 %s", aBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ignore(int client, int target)
|
||||
{
|
||||
SetIgnored(client, target, true);
|
||||
SetListenOverride(client, target, Listen_No);
|
||||
}
|
||||
|
||||
void UnIgnore(int client, int target)
|
||||
{
|
||||
SetIgnored(client, target, false);
|
||||
SetListenOverride(client, target, Listen_Yes);
|
||||
}
|
||||
|
||||
/*
|
||||
* CHAT COMMANDS
|
||||
*/
|
||||
public Action Command_SelfMute(int client, int args)
|
||||
{
|
||||
if(client == 0)
|
||||
{
|
||||
PrintToServer("[SM] Cannot use command from server console.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(args < 1)
|
||||
{
|
||||
DisplayMuteMenu(client);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char Argument[65];
|
||||
GetCmdArgString(Argument, sizeof(Argument));
|
||||
|
||||
char Filtered[65];
|
||||
strcopy(Filtered, sizeof(Filtered), Argument);
|
||||
StripQuotes(Filtered);
|
||||
TrimString(Filtered);
|
||||
|
||||
if(StrEqual(Filtered, "@me", false))
|
||||
{
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You can't mute yourself, don't be silly.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(MuteSpecial(client, Filtered))
|
||||
return Plugin_Handled;
|
||||
|
||||
char sTargetName[MAX_TARGET_LENGTH];
|
||||
int aTargetList[MAXPLAYERS];
|
||||
int TargetCount;
|
||||
bool TnIsMl;
|
||||
|
||||
if((TargetCount = ProcessTargetString(
|
||||
Argument,
|
||||
client,
|
||||
aTargetList,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_CONNECTED|COMMAND_FILTER_NO_IMMUNITY,
|
||||
sTargetName,
|
||||
sizeof(sTargetName),
|
||||
TnIsMl)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, TargetCount);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(int i = 0; i < TargetCount; i++)
|
||||
{
|
||||
if(aTargetList[i] != client)
|
||||
Ignore(client, aTargetList[i]);
|
||||
}
|
||||
UpdateIgnored();
|
||||
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted:\x04 %s", sTargetName);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_SelfUnMute(int client, int args)
|
||||
{
|
||||
if(client == 0)
|
||||
{
|
||||
PrintToServer("[SM] Cannot use command from server console.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(args < 1)
|
||||
{
|
||||
DisplayUnMuteMenu(client);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char Argument[65];
|
||||
GetCmdArgString(Argument, sizeof(Argument));
|
||||
|
||||
char Filtered[65];
|
||||
strcopy(Filtered, sizeof(Filtered), Argument);
|
||||
StripQuotes(Filtered);
|
||||
TrimString(Filtered);
|
||||
|
||||
if(StrEqual(Filtered, "@me", false))
|
||||
{
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 Unmuting won't work either.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if(UnMuteSpecial(client, Filtered))
|
||||
return Plugin_Handled;
|
||||
|
||||
char sTargetName[MAX_TARGET_LENGTH];
|
||||
int aTargetList[MAXPLAYERS];
|
||||
int TargetCount;
|
||||
bool TnIsMl;
|
||||
|
||||
if((TargetCount = ProcessTargetString(
|
||||
Argument,
|
||||
client,
|
||||
aTargetList,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_CONNECTED|COMMAND_FILTER_NO_IMMUNITY,
|
||||
sTargetName,
|
||||
sizeof(sTargetName),
|
||||
TnIsMl)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, TargetCount);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for(int i = 0; i < TargetCount; i++)
|
||||
{
|
||||
if(aTargetList[i] != client)
|
||||
UnIgnore(client, aTargetList[i]);
|
||||
}
|
||||
UpdateIgnored();
|
||||
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %s", sTargetName);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_CheckMutes(int client, int args)
|
||||
{
|
||||
if(client == 0)
|
||||
{
|
||||
PrintToServer("[SM] Cannot use command from server console.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char aBuf[1024];
|
||||
char aBuf2[MAX_NAME_LENGTH];
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(GetIgnored(client, i))
|
||||
{
|
||||
GetClientName(i, aBuf2, sizeof(aBuf2));
|
||||
StrCat(aBuf, sizeof(aBuf), aBuf2);
|
||||
StrCat(aBuf, sizeof(aBuf), ", ");
|
||||
}
|
||||
}
|
||||
|
||||
// Cut off last ', '
|
||||
if(strlen(aBuf))
|
||||
{
|
||||
aBuf[strlen(aBuf) - 2] = 0;
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted:\x04 %s", aBuf);
|
||||
}
|
||||
else if(!g_SpecialMutes[client])
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have not self-muted anyone!\x04", aBuf);
|
||||
|
||||
if(g_SpecialMutes[client])
|
||||
{
|
||||
aBuf[0] = 0;
|
||||
FormatSpecialMutes(g_SpecialMutes[client], aBuf, sizeof(aBuf));
|
||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted group:\x04 %s", aBuf);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
/*
|
||||
* MENU
|
||||
*/
|
||||
void DisplayMuteMenu(int client)
|
||||
{
|
||||
Menu menu = new Menu(MenuHandler_MuteMenu, MenuAction_Select|MenuAction_Cancel|MenuAction_End|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
menu.ExitButton = true;
|
||||
|
||||
int[] aClients = new int[MaxClients + 1];
|
||||
|
||||
if(g_Plugin_voiceannounce_ex)
|
||||
{
|
||||
// Count talking players and insert id's into aClients array
|
||||
int CurrentlyTalking = 0;
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(i != client && IsClientInGame(i) && !IsFakeClient(i) && IsClientSpeaking(i))
|
||||
aClients[CurrentlyTalking++] = i;
|
||||
}
|
||||
|
||||
if(CurrentlyTalking > 0)
|
||||
{
|
||||
// insert player names into g_PlayerNames array
|
||||
for(int i = 0; i < CurrentlyTalking; i++)
|
||||
GetClientName(aClients[i], g_PlayerNames[aClients[i]], sizeof(g_PlayerNames[]));
|
||||
|
||||
// sort aClients array by player name
|
||||
SortCustom1D(aClients, CurrentlyTalking, SortByPlayerName);
|
||||
|
||||
// insert players sorted
|
||||
char aBuf[11];
|
||||
for(int i = 0; i < CurrentlyTalking; i++)
|
||||
{
|
||||
IntToString(GetClientUserId(aClients[i]), aBuf, sizeof(aBuf));
|
||||
menu.AddItem(aBuf, g_PlayerNames[aClients[i]]);
|
||||
}
|
||||
|
||||
// insert spacers
|
||||
int Entries = 7 - CurrentlyTalking % 7;
|
||||
while(Entries--)
|
||||
menu.AddItem("", "", ITEMDRAW_RAWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
menu.AddItem("@all", "Everyone");
|
||||
menu.AddItem("@spec", "Spectators");
|
||||
menu.AddItem("@ct", "Counter-Terrorists");
|
||||
menu.AddItem("@t", "Terrorists");
|
||||
menu.AddItem("@dead", "Dead players");
|
||||
menu.AddItem("@alive", "Alive players");
|
||||
if(g_Plugin_AdvancedTargeting)
|
||||
menu.AddItem("@!friends", "Not Steam friend");
|
||||
else
|
||||
menu.AddItem("", "", ITEMDRAW_RAWLINE);
|
||||
|
||||
// Count valid players and insert id's into aClients array
|
||||
int Players = 0;
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if(i != client && IsClientInGame(i) && !IsFakeClient(i))
|
||||
aClients[Players++] = i;
|
||||
}
|
||||
|
||||
// insert player names into g_PlayerNames array
|
||||
for(int i = 0; i < Players; i++)
|
||||
GetClientName(aClients[i], g_PlayerNames[aClients[i]], sizeof(g_PlayerNames[]));
|
||||
|
||||
// sort aClients array by player name
|
||||
SortCustom1D(aClients, Players, SortByPlayerName);
|
||||
|
||||
// insert players sorted
|
||||
char aBuf[12];
|
||||
for(int i = 0; i < Players; i++)
|
||||
{
|
||||
IntToString(GetClientUserId(aClients[i]), aBuf, sizeof(aBuf));
|
||||
menu.AddItem(aBuf, g_PlayerNames[aClients[i]]);
|
||||
}
|
||||
|
||||
menu.Display(client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public int MenuHandler_MuteMenu(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case MenuAction_End:
|
||||
{
|
||||
if(param1 != MenuEnd_Selected)
|
||||
CloseHandle(menu);
|
||||
}
|
||||
case MenuAction_Select:
|
||||
{
|
||||
int Style;
|
||||
char aItem[32];
|
||||
char aDisp[MAX_NAME_LENGTH + 4];
|
||||
menu.GetItem(param2, aItem, sizeof(aItem), Style, aDisp, sizeof(aDisp));
|
||||
|
||||
if(Style != ITEMDRAW_DEFAULT || !aItem[0])
|
||||
{
|
||||
PrintToChat(param1, "Internal error: aItem[0] -> %d | Style -> %d", aItem[0], Style);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(aItem[0] == '@')
|
||||
{
|
||||
int Flag = GetSpecialMutesFlags(aItem);
|
||||
if(Flag && g_SpecialMutes[param1] & Flag)
|
||||
UnMuteSpecial(param1, aItem);
|
||||
else
|
||||
MuteSpecial(param1, aItem);
|
||||
|
||||
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UserId = StringToInt(aItem);
|
||||
int client = GetClientOfUserId(UserId);
|
||||
if(!client)
|
||||
{
|
||||
PrintToChat(param1, "\x04[Self-Mute]\x01 Player no longer available.");
|
||||
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(GetIgnored(param1, client))
|
||||
{
|
||||
UnIgnore(param1, client);
|
||||
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %N", client);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ignore(param1, client);
|
||||
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-muted:\x04 %N", client);
|
||||
}
|
||||
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
||||
return 0;
|
||||
}
|
||||
case MenuAction_DrawItem:
|
||||
{
|
||||
int Style;
|
||||
char aItem[32];
|
||||
menu.GetItem(param2, aItem, sizeof(aItem), Style);
|
||||
|
||||
if(!aItem[0])
|
||||
return ITEMDRAW_DISABLED;
|
||||
|
||||
if(aItem[0] == '@')
|
||||
{
|
||||
int Flag = GetSpecialMutesFlags(aItem);
|
||||
if(Flag & MUTE_ALL)
|
||||
return Style;
|
||||
else if(g_SpecialMutes[param1] & MUTE_ALL)
|
||||
return ITEMDRAW_DISABLED;
|
||||
|
||||
return Style;
|
||||
}
|
||||
|
||||
int UserId = StringToInt(aItem);
|
||||
int client = GetClientOfUserId(UserId);
|
||||
if(!client) // Player disconnected
|
||||
return ITEMDRAW_DISABLED;
|
||||
|
||||
return Style;
|
||||
}
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
int Style;
|
||||
char aItem[32];
|
||||
char aDisp[MAX_NAME_LENGTH + 4];
|
||||
menu.GetItem(param2, aItem, sizeof(aItem), Style, aDisp, sizeof(aDisp));
|
||||
|
||||
// Start of current page
|
||||
if((param2 + 1) % 7 == 1)
|
||||
{
|
||||
if(aItem[0] == '@')
|
||||
menu.SetTitle("[Self-Mute] Groups");
|
||||
else if(param2 == 0)
|
||||
menu.SetTitle("[Self-Mute] Talking players");
|
||||
else
|
||||
menu.SetTitle("[Self-Mute] All players");
|
||||
}
|
||||
|
||||
if(!aItem[0])
|
||||
return 0;
|
||||
|
||||
if(aItem[0] == '@')
|
||||
{
|
||||
int Flag = GetSpecialMutesFlags(aItem);
|
||||
if(Flag && g_SpecialMutes[param1] & Flag)
|
||||
{
|
||||
char aBuf[32] = "[M] ";
|
||||
FormatSpecialMutes(Flag, aBuf, sizeof(aBuf));
|
||||
if(!StrEqual(aDisp, aBuf))
|
||||
return RedrawMenuItem(aBuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UserId = StringToInt(aItem);
|
||||
int client = GetClientOfUserId(UserId);
|
||||
if(!client) // Player disconnected
|
||||
{
|
||||
char aBuf[MAX_NAME_LENGTH + 4] = "[D] ";
|
||||
StrCat(aBuf, sizeof(aBuf), aDisp);
|
||||
if(!StrEqual(aDisp, aBuf))
|
||||
return RedrawMenuItem(aBuf);
|
||||
}
|
||||
|
||||
if(GetIgnored(param1, client))
|
||||
{
|
||||
char aBuf[MAX_NAME_LENGTH + 4] = "[M] ";
|
||||
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
||||
StrCat(aBuf, sizeof(aBuf), g_PlayerNames[client]);
|
||||
if(!StrEqual(aDisp, aBuf))
|
||||
return RedrawMenuItem(aBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
||||
if(!StrEqual(aDisp, g_PlayerNames[client]))
|
||||
return RedrawMenuItem(g_PlayerNames[client]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DisplayUnMuteMenu(int client)
|
||||
{
|
||||
// TODO: Implement me
|
||||
}
|
||||
|
||||
/*
|
||||
* HOOKS
|
||||
*/
|
||||
int g_MsgDest;
|
||||
int g_MsgClient;
|
||||
char g_MsgName[256];
|
||||
char g_MsgParam1[256];
|
||||
char g_MsgParam2[256];
|
||||
char g_MsgParam3[256];
|
||||
char g_MsgParam4[256];
|
||||
int g_MsgPlayersNum;
|
||||
int g_MsgPlayers[MAXPLAYERS + 1];
|
||||
|
||||
int g_TimerDerp = 0;
|
||||
|
||||
public Action Hook_UserMessageRadioText(UserMsg msg_id, Handle bf, const int[] players, int playersNum, bool reliable, bool init)
|
||||
{
|
||||
g_MsgDest = BfReadByte(bf);
|
||||
g_MsgClient = BfReadByte(bf);
|
||||
BfReadString(bf, g_MsgName, sizeof(g_MsgName), false);
|
||||
BfReadString(bf, g_MsgParam1, sizeof(g_MsgParam1), false);
|
||||
BfReadString(bf, g_MsgParam2, sizeof(g_MsgParam2), false);
|
||||
BfReadString(bf, g_MsgParam3, sizeof(g_MsgParam3), false);
|
||||
BfReadString(bf, g_MsgParam4, sizeof(g_MsgParam4), false);
|
||||
|
||||
g_MsgPlayersNum = playersNum;
|
||||
for(int i = 0; i < playersNum; i++)
|
||||
g_MsgPlayers[i] = players[i];
|
||||
|
||||
if(!g_TimerDerp)
|
||||
CreateTimer(0.1, Timer_PlayerRadio);
|
||||
|
||||
g_TimerDerp++;
|
||||
if(g_TimerDerp > 1)
|
||||
PrintToServer("DEBUG: Timer_PlayerRadio derped! (%d)", g_TimerDerp);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char g_MsgRadioSound[256];
|
||||
|
||||
public Action Hook_UserMessageSendAudio(UserMsg msg_id, Handle bf, const int[] players, int playersNum, bool reliable, bool init)
|
||||
{
|
||||
BfReadString(bf, g_MsgRadioSound, sizeof(g_MsgRadioSound), false);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Timer_PlayerRadio(Handle timer)
|
||||
{
|
||||
g_TimerDerp = 0;
|
||||
if(g_MsgClient == -1)
|
||||
return Plugin_Continue;
|
||||
|
||||
int[] players = new int[g_MsgPlayersNum + 1];
|
||||
int playersNum = 0;
|
||||
|
||||
for(int i = 0; i < g_MsgPlayersNum; i++)
|
||||
{
|
||||
int client = g_MsgPlayers[i];
|
||||
if(IsClientInGame(client) && !GetIgnored(client, g_MsgClient))
|
||||
players[playersNum++] = client;
|
||||
}
|
||||
|
||||
Handle RadioText = StartMessage("RadioText", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS);
|
||||
BfWriteByte(RadioText, g_MsgDest);
|
||||
BfWriteByte(RadioText, g_MsgClient);
|
||||
BfWriteString(RadioText, g_MsgName);
|
||||
BfWriteString(RadioText, g_MsgParam1);
|
||||
BfWriteString(RadioText, g_MsgParam2);
|
||||
BfWriteString(RadioText, g_MsgParam3);
|
||||
BfWriteString(RadioText, g_MsgParam4);
|
||||
EndMessage();
|
||||
|
||||
Handle SendAudio = StartMessage("SendAudio", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS);
|
||||
BfWriteString(SendAudio, g_MsgRadioSound);
|
||||
EndMessage();
|
||||
|
||||
g_MsgClient = -1;
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* HELPERS
|
||||
*/
|
||||
void UpdateIgnored()
|
||||
{
|
||||
if(g_Plugin_ccc)
|
||||
CCC_UpdateIgnoredArray(g_Ignored);
|
||||
}
|
||||
|
||||
public int SortByPlayerName(int elem1, int elem2, const int[] array, Handle hndl)
|
||||
{
|
||||
return strcmp(g_PlayerNames[elem1], g_PlayerNames[elem2], false);
|
||||
}
|
||||
|
||||
bool GetIgnored(int client, int target)
|
||||
{
|
||||
return g_Ignored[(client * (MAXPLAYERS + 1) + target)];
|
||||
}
|
||||
|
||||
void SetIgnored(int client, int target, bool ignored)
|
||||
{
|
||||
g_Ignored[(client * (MAXPLAYERS + 1) + target)] = ignored;
|
||||
}
|
1
SelfMute/scripting/include/AdvancedTargeting.inc
Symbolic link
1
SelfMute/scripting/include/AdvancedTargeting.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../AdvancedTargeting/scripting/include/AdvancedTargeting.inc
|
1
SelfMute/scripting/include/ccc.inc
Symbolic link
1
SelfMute/scripting/include/ccc.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../custom-chatcolors/scripting/include/ccc.inc
|
1
SelfMute/scripting/include/voiceannounce_ex.inc
Symbolic link
1
SelfMute/scripting/include/voiceannounce_ex.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../voiceannounce_ex/scripting/include/voiceannounce_ex.inc
|
1
SelfMute/scripting/include/zombiereloaded.inc
Symbolic link
1
SelfMute/scripting/include/zombiereloaded.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/zombiereloaded.inc
|
208
Status/scripting/Status.sp
Normal file
208
Status/scripting/Status.sp
Normal file
@ -0,0 +1,208 @@
|
||||
#pragma semicolon 1
|
||||
//====================================================================================================
|
||||
//
|
||||
// Name: Status Fixer.
|
||||
// Author: zaCade + BotoX
|
||||
// Description: Fixes the 'status' command.
|
||||
//
|
||||
//====================================================================================================
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
ConVar g_Cvar_HostIP;
|
||||
ConVar g_Cvar_HostPort;
|
||||
ConVar g_Cvar_HostName;
|
||||
ConVar g_Cvar_HostTags;
|
||||
|
||||
Handle g_hPlayerList[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
|
||||
bool g_bDataAvailable = false;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Status Fixer",
|
||||
author = "zaCade + BotoX",
|
||||
description = "Fixes the 'status' command",
|
||||
version = "1.1",
|
||||
url = ""
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public void OnPluginStart()
|
||||
{
|
||||
g_Cvar_HostIP = FindConVar("hostip");
|
||||
g_Cvar_HostPort = FindConVar("hostport");
|
||||
g_Cvar_HostName = FindConVar("hostname");
|
||||
g_Cvar_HostTags = FindConVar("sv_tags");
|
||||
|
||||
AddCommandListener(Command_Status, "status");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public Action Command_Status(int client, const char[] command, int args)
|
||||
{
|
||||
if(client)
|
||||
{
|
||||
if(g_hPlayerList[client] != INVALID_HANDLE)
|
||||
return Plugin_Handled;
|
||||
|
||||
static char sServerName[128];
|
||||
static char sServerTags[128];
|
||||
static char sServerAdress[128];
|
||||
|
||||
int iServerIP = g_Cvar_HostIP.IntValue;
|
||||
int iServerPort = g_Cvar_HostPort.IntValue;
|
||||
|
||||
g_Cvar_HostName.GetString(sServerName, sizeof(sServerName));
|
||||
g_Cvar_HostTags.GetString(sServerTags, sizeof(sServerTags));
|
||||
|
||||
Format(sServerAdress, sizeof(sServerAdress), "%d.%d.%d.%d:%d", iServerIP >>> 24 & 255, iServerIP >>> 16 & 255, iServerIP >>> 8 & 255, iServerIP & 255, iServerPort);
|
||||
|
||||
static char sMapName[128];
|
||||
GetCurrentMap(sMapName, sizeof(sMapName));
|
||||
|
||||
float fPosition[3];
|
||||
GetClientAbsOrigin(client, fPosition);
|
||||
|
||||
int iRealClients;
|
||||
int iFakeClients;
|
||||
int iTotalClients;
|
||||
|
||||
for(int player = 1; player <= MaxClients; player++)
|
||||
{
|
||||
if(IsClientConnected(player))
|
||||
{
|
||||
iTotalClients++;
|
||||
|
||||
if(IsFakeClient(player))
|
||||
iFakeClients++;
|
||||
else
|
||||
iRealClients++;
|
||||
}
|
||||
}
|
||||
|
||||
static char sSendBuffer[1000];
|
||||
int iBufLength = 0;
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "hostname: %s\n", sServerName);
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%stickrate: %d\n", sSendBuffer, RoundToZero(1.0 / GetTickInterval()));
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%sudp/ip : %s\n", sSendBuffer, sServerAdress);
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%smap : %s at: %.0f x, %.0f y, %.0f z\n", sSendBuffer, sMapName, fPosition[0], fPosition[1], fPosition[2]);
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%stags : %s\n", sSendBuffer, sServerTags);
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%s%edicts : %d/%d/%d (used/max/free)\n", sSendBuffer, GetEntityCount(), GetMaxEntities(), GetMaxEntities() - GetEntityCount());
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%splayers : %d humans | %d bots (%d/%d)\n", sSendBuffer, iRealClients, iFakeClients, iTotalClients, MaxClients);
|
||||
Format(sSendBuffer, sizeof(sSendBuffer), "%s# %8s %40s %24s %12s %4s %4s %s", sSendBuffer, "userid", "name", "uniqueid", "connected", "ping", "loss", "state");
|
||||
|
||||
g_hPlayerList[client] = CreateArray(ByteCountToCells(1000));
|
||||
|
||||
PushArrayString(g_hPlayerList[client], sSendBuffer);
|
||||
g_bDataAvailable = true;
|
||||
sSendBuffer[0] = 0;
|
||||
|
||||
for(int player = 1; player <= MaxClients; player++)
|
||||
{
|
||||
if(IsClientConnected(player))
|
||||
{
|
||||
static char sPlayerID[8];
|
||||
static char sPlayerName[40];
|
||||
char sPlayerAuth[24];
|
||||
char sPlayerTime[12];
|
||||
char sPlayerPing[4];
|
||||
char sPlayerLoss[4];
|
||||
static char sPlayerState[16];
|
||||
|
||||
Format(sPlayerID, sizeof(sPlayerID), "%d", GetClientUserId(player));
|
||||
Format(sPlayerName, sizeof(sPlayerName), "\"%N\"", player);
|
||||
|
||||
if(!GetClientAuthId(player, AuthId_Steam2, sPlayerAuth, sizeof(sPlayerAuth)))
|
||||
Format(sPlayerAuth, sizeof(sPlayerAuth), "STEAM_ID_PENDING");
|
||||
|
||||
if(!IsFakeClient(player))
|
||||
{
|
||||
int iHours = RoundToFloor((GetClientTime(player) / 3600));
|
||||
int iMinutes = RoundToFloor((GetClientTime(player) - (iHours * 3600)) / 60);
|
||||
int iSeconds = RoundToFloor((GetClientTime(player) - (iHours * 3600)) - (iMinutes * 60));
|
||||
|
||||
if (iHours)
|
||||
Format(sPlayerTime, sizeof(sPlayerTime), "%d:%02d:%02d", iHours, iMinutes, iSeconds);
|
||||
else
|
||||
Format(sPlayerTime, sizeof(sPlayerTime), "%d:%02d", iMinutes, iSeconds);
|
||||
|
||||
Format(sPlayerPing, sizeof(sPlayerPing), "%d", RoundFloat(GetClientLatency(player, NetFlow_Outgoing) * 800));
|
||||
Format(sPlayerLoss, sizeof(sPlayerLoss), "%d", RoundFloat(GetClientAvgLoss(player, NetFlow_Outgoing) * 100));
|
||||
}
|
||||
|
||||
if(IsClientInGame(player))
|
||||
Format(sPlayerState, sizeof(sPlayerState), "active");
|
||||
else
|
||||
Format(sPlayerState, sizeof(sPlayerState), "spawning");
|
||||
|
||||
static char sFormatted[128];
|
||||
Format(sFormatted, sizeof(sFormatted), "# %8s %40s %24s %12s %4s %4s %s\n", sPlayerID, sPlayerName, sPlayerAuth, sPlayerTime, sPlayerPing, sPlayerLoss, sPlayerState);
|
||||
|
||||
int iFormattedLength = strlen(sFormatted);
|
||||
if(iBufLength + iFormattedLength >= 1000)
|
||||
{
|
||||
sSendBuffer[iBufLength - 1] = 0;
|
||||
PushArrayString(g_hPlayerList[client], sSendBuffer);
|
||||
sSendBuffer[0] = 0;
|
||||
iBufLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
StrCat(sSendBuffer, sizeof(sSendBuffer), sFormatted);
|
||||
iBufLength += iFormattedLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(iBufLength)
|
||||
{
|
||||
sSendBuffer[iBufLength - 1] = 0;
|
||||
PushArrayString(g_hPlayerList[client], sSendBuffer);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public void OnGameFrame()
|
||||
{
|
||||
if(!g_bDataAvailable)
|
||||
return;
|
||||
|
||||
bool bGotData = false;
|
||||
for(int client = 0; client < MAXPLAYERS + 1; client++)
|
||||
{
|
||||
if(g_hPlayerList[client] == INVALID_HANDLE)
|
||||
continue;
|
||||
|
||||
if(!IsClientInGame(client) || !GetArraySize(g_hPlayerList[client]))
|
||||
{
|
||||
CloseHandle(g_hPlayerList[client]);
|
||||
g_hPlayerList[client] = INVALID_HANDLE;
|
||||
continue;
|
||||
}
|
||||
|
||||
static char sBuffer[1000];
|
||||
GetArrayString(g_hPlayerList[client], 0, sBuffer, sizeof(sBuffer));
|
||||
RemoveFromArray(g_hPlayerList[client], 0);
|
||||
|
||||
PrintToConsole(client, sBuffer);
|
||||
bGotData = true;
|
||||
}
|
||||
|
||||
if(!bGotData)
|
||||
g_bDataAvailable = false;
|
||||
}
|
333
StopSound/scripting/StopSound.sp
Normal file
333
StopSound/scripting/StopSound.sp
Normal file
@ -0,0 +1,333 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <morecolors>
|
||||
|
||||
#define PLUGIN_NAME "Toggle Weapon Sounds"
|
||||
#define PLUGIN_VERSION "1.2.0"
|
||||
|
||||
#define UPDATE_URL "http://godtony.mooo.com/stopsound/stopsound.txt"
|
||||
|
||||
new bool:g_bStopSound[MAXPLAYERS+1], bool:g_bHooked;
|
||||
static String:g_sKVPATH[PLATFORM_MAX_PATH];
|
||||
new Handle:g_hWepSounds;
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = PLUGIN_NAME,
|
||||
author = "GoD-Tony, edit by id/Obus",
|
||||
description = "Allows clients to stop hearing weapon sounds",
|
||||
version = PLUGIN_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
// Detect game and hook appropriate tempent.
|
||||
decl String:sGame[32];
|
||||
GetGameFolderName(sGame, sizeof(sGame));
|
||||
|
||||
if (StrEqual(sGame, "cstrike"))
|
||||
{
|
||||
AddTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot);
|
||||
}
|
||||
else if (StrEqual(sGame, "dod"))
|
||||
{
|
||||
AddTempEntHook("FireBullets", DODS_Hook_FireBullets);
|
||||
}
|
||||
|
||||
// TF2/HL2:DM and misc weapon sounds will be caught here.
|
||||
AddNormalSoundHook(Hook_NormalSound);
|
||||
|
||||
CreateConVar("sm_stopsound_version", PLUGIN_VERSION, "Toggle Weapon Sounds", FCVAR_NOTIFY|FCVAR_DONTRECORD|FCVAR_REPLICATED);
|
||||
RegConsoleCmd("sm_stopsound", Command_StopSound, "Toggle hearing weapon sounds");
|
||||
|
||||
if (g_hWepSounds != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_hWepSounds);
|
||||
}
|
||||
|
||||
g_hWepSounds = CreateKeyValues("WeaponSounds");
|
||||
BuildPath(Path_SM, g_sKVPATH, sizeof(g_sKVPATH), "data/playerprefs.WepSounds.txt");
|
||||
|
||||
FileToKeyValues(g_hWepSounds, g_sKVPATH);
|
||||
|
||||
// Updater.
|
||||
//if (LibraryExists("updater"))
|
||||
//{
|
||||
// Updater_AddPlugin(UPDATE_URL);
|
||||
//}
|
||||
}
|
||||
|
||||
/*public OnLibraryAdded(const String:name[])
|
||||
{
|
||||
if (StrEqual(name, "updater"))
|
||||
{
|
||||
Updater_AddPlugin(UPDATE_URL);
|
||||
}
|
||||
}*/
|
||||
|
||||
public Action:Command_StopSound(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
PrintToServer("[SM] Cannot use command from server console.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (args > 0)
|
||||
{
|
||||
decl String:Arguments[32];
|
||||
GetCmdArg(1, Arguments, sizeof(Arguments));
|
||||
|
||||
if (StrEqual(Arguments, "save"))
|
||||
{
|
||||
KvRewind(g_hWepSounds);
|
||||
|
||||
decl String:SID[32];
|
||||
GetClientAuthId(client, AuthId_Steam2, SID, sizeof(SID));
|
||||
|
||||
if (KvJumpToKey(g_hWepSounds, SID, true))
|
||||
{
|
||||
new disabled;
|
||||
disabled = KvGetNum(g_hWepSounds, "disabled", 0);
|
||||
|
||||
if (!disabled)
|
||||
{
|
||||
//CPrintToChat(client, "[StopSound] Saved entry for STEAMID({green}%s{default}) {green}successfully{default}.", SID);
|
||||
KvSetNum(g_hWepSounds, "disabled", 1);
|
||||
KvRewind(g_hWepSounds);
|
||||
KeyValuesToFile(g_hWepSounds, g_sKVPATH);
|
||||
|
||||
g_bStopSound[client] = true;
|
||||
CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds {red}disabled{default} - {green}entry saved{default}.");
|
||||
CheckHooks();
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
else
|
||||
{
|
||||
//CPrintToChat(client, "[StopSound] Entry for STEAMID({green}%s{default}) {green}successfully deleted{default}.", SID);
|
||||
KvDeleteThis(g_hWepSounds);
|
||||
KvRewind(g_hWepSounds);
|
||||
KeyValuesToFile(g_hWepSounds, g_sKVPATH);
|
||||
|
||||
g_bStopSound[client] = false;
|
||||
CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds {green}enabled{default} - {red}entry deleted{default}.");
|
||||
CheckHooks();
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
KvRewind(g_hWepSounds);
|
||||
}
|
||||
else if (StrEqual(Arguments, "delete"))
|
||||
{
|
||||
KvRewind(g_hWepSounds);
|
||||
|
||||
decl String:SID[32];
|
||||
GetClientAuthId(client, AuthId_Steam2, SID, sizeof(SID));
|
||||
|
||||
if (KvJumpToKey(g_hWepSounds, SID, false))
|
||||
{
|
||||
g_bStopSound[client] = false;
|
||||
CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds {green}enabled{default} - {red}entry deleted{default}.");
|
||||
CheckHooks();
|
||||
|
||||
KvDeleteThis(g_hWepSounds);
|
||||
KvRewind(g_hWepSounds);
|
||||
KeyValuesToFile(g_hWepSounds, g_sKVPATH);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPrintToChat(client, "{green}[StopSound]{default} Entry {red}not found{default}.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(client, "[SM] Usage sm_stopsound <save|delete>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
g_bStopSound[client] = !g_bStopSound[client];
|
||||
CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds %s.", g_bStopSound[client] ? "{red}disabled{default}" : "{green}enabled{default}");
|
||||
CheckHooks();
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public OnClientPutInServer(client)
|
||||
{
|
||||
KvRewind(g_hWepSounds);
|
||||
|
||||
decl String:SID[32];
|
||||
GetClientAuthId(client, AuthId_Steam2, SID, sizeof(SID));
|
||||
|
||||
if (KvJumpToKey(g_hWepSounds, SID, false))
|
||||
{
|
||||
new disabled;
|
||||
disabled = KvGetNum(g_hWepSounds, "disabled", 0);
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
g_bStopSound[client] = true;
|
||||
}
|
||||
}
|
||||
|
||||
CheckHooks();
|
||||
KvRewind(g_hWepSounds);
|
||||
}
|
||||
|
||||
public OnClientDisconnect_Post(client)
|
||||
{
|
||||
g_bStopSound[client] = false;
|
||||
CheckHooks();
|
||||
}
|
||||
|
||||
CheckHooks()
|
||||
{
|
||||
new bool:bShouldHook = false;
|
||||
|
||||
for (new i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (g_bStopSound[i])
|
||||
{
|
||||
bShouldHook = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fake (un)hook because toggling actual hooks will cause server instability.
|
||||
g_bHooked = bShouldHook;
|
||||
}
|
||||
|
||||
public Action:Hook_NormalSound(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags)
|
||||
{
|
||||
// Ignore non-weapon sounds.
|
||||
if (!g_bHooked || !(strncmp(sample, "weapons", 7) == 0 || strncmp(sample[1], "weapons", 7) == 0))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
decl i, j;
|
||||
|
||||
for (i = 0; i < numClients; i++)
|
||||
{
|
||||
if (g_bStopSound[clients[i]])
|
||||
{
|
||||
// Remove the client from the array.
|
||||
for (j = i; j < numClients - 1; j++)
|
||||
{
|
||||
clients[j] = clients[j + 1];
|
||||
}
|
||||
|
||||
numClients--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
return (numClients > 0) ? Plugin_Changed : Plugin_Stop;
|
||||
}
|
||||
|
||||
public Action:CSS_Hook_ShotgunShot(const String:te_name[], const Players[], numClients, Float:delay)
|
||||
{
|
||||
if (!g_bHooked)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
// Check which clients need to be excluded.
|
||||
decl newClients[MaxClients], client, i;
|
||||
new newTotal = 0;
|
||||
|
||||
for (i = 0; i < numClients; i++)
|
||||
{
|
||||
client = Players[i];
|
||||
|
||||
if (!g_bStopSound[client])
|
||||
{
|
||||
newClients[newTotal++] = client;
|
||||
}
|
||||
}
|
||||
|
||||
// No clients were excluded.
|
||||
if (newTotal == numClients)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
else if (newTotal == 0) // All clients were excluded and there is no need to broadcast.
|
||||
{
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
// Re-broadcast to clients that still need it.
|
||||
decl Float:vTemp[3];
|
||||
TE_Start("Shotgun Shot");
|
||||
TE_ReadVector("m_vecOrigin", vTemp);
|
||||
TE_WriteVector("m_vecOrigin", vTemp);
|
||||
TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
|
||||
TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
|
||||
TE_WriteNum("m_iWeaponID", TE_ReadNum("m_iWeaponID"));
|
||||
TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
|
||||
TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
|
||||
TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
|
||||
TE_WriteFloat("m_fInaccuracy", TE_ReadFloat("m_fInaccuracy"));
|
||||
TE_WriteFloat("m_fSpread", TE_ReadFloat("m_fSpread"));
|
||||
TE_Send(newClients, newTotal, delay);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
public Action:DODS_Hook_FireBullets(const String:te_name[], const Players[], numClients, Float:delay)
|
||||
{
|
||||
if (!g_bHooked)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
// Check which clients need to be excluded.
|
||||
decl newClients[MaxClients], client, i;
|
||||
new newTotal = 0;
|
||||
|
||||
for (i = 0; i < numClients; i++)
|
||||
{
|
||||
client = Players[i];
|
||||
|
||||
if (!g_bStopSound[client])
|
||||
{
|
||||
newClients[newTotal++] = client;
|
||||
}
|
||||
}
|
||||
|
||||
// No clients were excluded.
|
||||
if (newTotal == numClients)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
else if (newTotal == 0)// All clients were excluded and there is no need to broadcast.
|
||||
{
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
// Re-broadcast to clients that still need it.
|
||||
decl Float:vTemp[3];
|
||||
TE_Start("FireBullets");
|
||||
TE_ReadVector("m_vecOrigin", vTemp);
|
||||
TE_WriteVector("m_vecOrigin", vTemp);
|
||||
TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
|
||||
TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
|
||||
TE_WriteNum("m_iWeaponID", TE_ReadNum("m_iWeaponID"));
|
||||
TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
|
||||
TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
|
||||
TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
|
||||
TE_WriteFloat("m_flSpread", TE_ReadFloat("m_flSpread"));
|
||||
TE_Send(newClients, newTotal, delay);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
1
StopSound/scripting/include/morecolors.inc
Symbolic link
1
StopSound/scripting/include/morecolors.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/morecolors.inc
|
21
SvGravityFix/scripting/SvGravityFix.sp
Normal file
21
SvGravityFix/scripting/SvGravityFix.sp
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "sv_gravity fix",
|
||||
author = "BotoX",
|
||||
description = "Resets sv_gravity at game_end",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnMapEnd()
|
||||
{
|
||||
ConVar SvGravity = FindConVar("sv_gravity");
|
||||
SvGravity.IntValue = 800;
|
||||
}
|
274
WeaponCleaner/scripting/WeaponCleaner.sp
Normal file
274
WeaponCleaner/scripting/WeaponCleaner.sp
Normal file
@ -0,0 +1,274 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdkhooks>
|
||||
#include <sdktools>
|
||||
|
||||
#define TIMER_INTERVAL 1.0
|
||||
Handle g_hTimer = INVALID_HANDLE;
|
||||
|
||||
ConVar g_CVar_MaxWeapons;
|
||||
ConVar g_CVar_WeaponLifetime;
|
||||
|
||||
new g_RealRoundStartedTime;
|
||||
new g_MaxWeapons;
|
||||
new g_MaxWeaponLifetime;
|
||||
|
||||
#define MAX_WEAPONS MAXPLAYERS
|
||||
new G_WeaponArray[MAX_WEAPONS][2];
|
||||
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "WeaponCleaner",
|
||||
author = "BotoX",
|
||||
description = "Clean unneeded weapons",
|
||||
version = "2.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
RegAdminCmd("sm_sweep", Command_CleanupWeapons, ADMFLAG_GENERIC, "Cleans up all the weapons on the map unless they have a HammerID attached to them.");
|
||||
|
||||
g_CVar_MaxWeapons = CreateConVar("sm_weaponcleaner_max", "5", "The maximum amount of weapons allowed in the game.", 0, true, 0.0, true, MAX_WEAPONS - 1.0);
|
||||
g_MaxWeapons = g_CVar_MaxWeapons.IntValue;
|
||||
g_CVar_MaxWeapons.AddChangeHook(OnConVarChanged);
|
||||
|
||||
g_CVar_WeaponLifetime = CreateConVar("sm_weaponcleaner_lifetime", "15", "The maximum amount of time in seconds a weapon is allowed in the game.", 0, true, 0.0);
|
||||
g_MaxWeaponLifetime = g_CVar_WeaponLifetime.IntValue;
|
||||
g_CVar_WeaponLifetime.AddChangeHook(OnConVarChanged);
|
||||
|
||||
HookEvent("round_start", Event_RoundStart);
|
||||
|
||||
AutoExecConfig(true, "plugin.WeaponCleaner");
|
||||
}
|
||||
|
||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||
{
|
||||
if(convar == g_CVar_MaxWeapons)
|
||||
{
|
||||
if(StringToInt(newValue) < StringToInt(oldValue))
|
||||
{
|
||||
// Need to shrink list and kill items
|
||||
new d = StringToInt(oldValue) - StringToInt(newValue);
|
||||
|
||||
// Kill items that don't have space anymore
|
||||
for(new i = 0; d && i < g_MaxWeapons; i++)
|
||||
{
|
||||
if(!G_WeaponArray[i][0])
|
||||
continue;
|
||||
|
||||
// Kill it
|
||||
AcceptEntityInput(G_WeaponArray[0][0], "Kill");
|
||||
// This implicitly calls OnEntityDestroyed() which calls RemoveWeapon()
|
||||
|
||||
// Move index backwards (since the list was modified by removing it)
|
||||
i--;
|
||||
d--;
|
||||
}
|
||||
}
|
||||
g_MaxWeapons = StringToInt(newValue);
|
||||
}
|
||||
else if(convar == g_CVar_WeaponLifetime)
|
||||
{
|
||||
g_MaxWeaponLifetime = StringToInt(newValue);
|
||||
CheckWeapons();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer))
|
||||
g_hTimer = INVALID_HANDLE;
|
||||
|
||||
g_hTimer = CreateTimer(TIMER_INTERVAL, Timer_CleanupWeapons, INVALID_HANDLE, TIMER_REPEAT);
|
||||
}
|
||||
|
||||
public void OnMapEnd()
|
||||
{
|
||||
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer))
|
||||
g_hTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
SDKHook(client, SDKHook_WeaponDropPost, OnWeaponDrop);
|
||||
SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponEquip);
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
SDKUnhook(client, SDKHook_WeaponDropPost, OnWeaponDrop);
|
||||
SDKUnhook(client, SDKHook_WeaponEquipPost, OnWeaponEquip);
|
||||
}
|
||||
|
||||
public void OnEntityCreated(int entity, const char[] classname)
|
||||
{
|
||||
if(IsValidEntity(entity) && strncmp(classname, "weapon_", 7) == 0)
|
||||
{
|
||||
SDKHook(entity, SDKHook_Spawn, OnWeaponSpawned);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEntityDestroyed(int entity)
|
||||
{
|
||||
RemoveWeapon(entity);
|
||||
}
|
||||
|
||||
public void OnWeaponSpawned(int entity)
|
||||
{
|
||||
new HammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
||||
// Should not be cleaned since it's a map spawned weapon
|
||||
if(HammerID)
|
||||
return;
|
||||
|
||||
// Weapon doesn't belong to any player
|
||||
if(GetEntPropEnt(entity, Prop_Data, "m_hOwnerEntity") == -1)
|
||||
InsertWeapon(entity);
|
||||
}
|
||||
|
||||
public Action OnWeaponEquip(int client, int entity)
|
||||
{
|
||||
if(!IsValidEntity(entity))
|
||||
return;
|
||||
|
||||
new HammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
||||
// Should not be cleaned since it's a map spawned weapon
|
||||
if(HammerID)
|
||||
return;
|
||||
|
||||
// Weapon should not be cleaned anymore
|
||||
RemoveWeapon(entity);
|
||||
}
|
||||
|
||||
public Action OnWeaponDrop(int client, int entity)
|
||||
{
|
||||
if(!IsValidEntity(entity))
|
||||
return;
|
||||
|
||||
new HammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
||||
// Should not be cleaned since it's a map spawned weapon
|
||||
if(HammerID)
|
||||
return;
|
||||
|
||||
// Kill all dropped weapons during mp_freezetime
|
||||
if(GetTime() < g_RealRoundStartedTime)
|
||||
{
|
||||
// Kill it
|
||||
AcceptEntityInput(entity, "Kill");
|
||||
return;
|
||||
}
|
||||
|
||||
// Weapon should be cleaned again
|
||||
InsertWeapon(entity);
|
||||
}
|
||||
|
||||
bool InsertWeapon(int entity)
|
||||
{
|
||||
// Try to find a free slot
|
||||
for(new i = 0; i < g_MaxWeapons; i++)
|
||||
{
|
||||
if(G_WeaponArray[i][0])
|
||||
continue;
|
||||
|
||||
// Found a free slot, add it here
|
||||
G_WeaponArray[i][0] = entity;
|
||||
G_WeaponArray[i][1] = GetTime();
|
||||
return true;
|
||||
}
|
||||
|
||||
// No free slot found
|
||||
// Kill the first (oldest) item in the list
|
||||
AcceptEntityInput(G_WeaponArray[0][0], "Kill");
|
||||
// This implicitly calls OnEntityDestroyed() which calls RemoveWeapon()
|
||||
|
||||
// Add new weapon to the end of the list
|
||||
G_WeaponArray[g_MaxWeapons - 1][0] = entity;
|
||||
G_WeaponArray[g_MaxWeapons - 1][1] = GetTime();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveWeapon(int entity)
|
||||
{
|
||||
// Find the Weapon
|
||||
for(new i = 0; i < g_MaxWeapons; i++)
|
||||
{
|
||||
if(G_WeaponArray[i][0] == entity)
|
||||
{
|
||||
G_WeaponArray[i][0] = 0; G_WeaponArray[i][1] = 0;
|
||||
|
||||
// Move list items in front of this index back by one
|
||||
for(new j = i + 1; j < g_MaxWeapons; j++)
|
||||
{
|
||||
G_WeaponArray[j - 1][0] = G_WeaponArray[j][0];
|
||||
G_WeaponArray[j - 1][1] = G_WeaponArray[j][1];
|
||||
}
|
||||
|
||||
// Reset last list item
|
||||
G_WeaponArray[g_MaxWeapons - 1][0] = 0;
|
||||
G_WeaponArray[g_MaxWeapons - 1][1] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckWeapons()
|
||||
{
|
||||
for(new i = 0; i < g_MaxWeapons; i++)
|
||||
{
|
||||
if(!G_WeaponArray[i][0])
|
||||
continue;
|
||||
|
||||
if(GetTime() - G_WeaponArray[i][1] >= g_MaxWeaponLifetime)
|
||||
{
|
||||
// Kill it
|
||||
AcceptEntityInput(G_WeaponArray[i][0], "Kill");
|
||||
// This implicitly calls OnEntityDestroyed() which calls RemoveWeapon()
|
||||
|
||||
// Move index backwards (since the list was modified by removing it)
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CleanupWeapons()
|
||||
{
|
||||
for(new i = 0; i < g_MaxWeapons; i++)
|
||||
{
|
||||
if(!G_WeaponArray[i][0])
|
||||
continue;
|
||||
|
||||
// Kill it
|
||||
AcceptEntityInput(G_WeaponArray[i][0], "Kill");
|
||||
// This implicitly calls OnEntityDestroyed() which calls RemoveWeapon()
|
||||
|
||||
// Move index backwards (since the list was modified by removing it)
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
public Action Event_RoundStart(Handle:event, const char[] name, bool:dontBroadcast)
|
||||
{
|
||||
for(new i = 0; i < MAX_WEAPONS; i++)
|
||||
{
|
||||
G_WeaponArray[i][0] = 0; G_WeaponArray[i][1] = 0;
|
||||
}
|
||||
g_RealRoundStartedTime = GetTime() + GetConVarInt(FindConVar("mp_freezetime"));
|
||||
}
|
||||
|
||||
public Action Timer_CleanupWeapons(Handle:timer)
|
||||
{
|
||||
CheckWeapons();
|
||||
}
|
||||
|
||||
public Action Command_CleanupWeapons(client, args)
|
||||
{
|
||||
CleanupWeapons();
|
||||
|
||||
LogAction(client, -1, "%L performed a weapons cleanup", client);
|
||||
PrintToChat(client, "[SM] Weapons cleaned successfully!");
|
||||
}
|
3307
custom-chatcolors/scripting/custom-chatcolors.sp
Normal file
3307
custom-chatcolors/scripting/custom-chatcolors.sp
Normal file
File diff suppressed because it is too large
Load Diff
190
custom-chatcolors/scripting/include/ccc.inc
Normal file
190
custom-chatcolors/scripting/include/ccc.inc
Normal file
@ -0,0 +1,190 @@
|
||||
/**
|
||||
* This is the include file for Custom Chat Colors
|
||||
* https://forums.alliedmods.net/showthread.php?t=186695
|
||||
* To check that Custom Chat Colors is installed and running, verify that the "ccc" library exists
|
||||
*/
|
||||
|
||||
#if defined _ccc_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _ccc_included
|
||||
|
||||
enum CCC_ColorType {
|
||||
CCC_TagColor,
|
||||
CCC_NameColor,
|
||||
CCC_ChatColor
|
||||
};
|
||||
|
||||
#define COLOR_NULL -1
|
||||
#define COLOR_NONE -2
|
||||
#define COLOR_CGREEN -3 //0x40FF40
|
||||
#define COLOR_OLIVE -4 //0x99FF99
|
||||
#define COLOR_TEAM -5
|
||||
|
||||
/**
|
||||
* Gets a client's color as a hexadecimal integer.
|
||||
*
|
||||
* @param client Client index
|
||||
* @param type Color type to retreive
|
||||
* @param alpha Pass a boolean variable by reference here and it will be true if the color has alpha specified or false if it doesn't (or is a stock color)
|
||||
* @return Color as a hexadecimal integer (use %X in formatting to get a hexadecimal string)
|
||||
*
|
||||
* On error/errors: Invalid client index or client is not in game
|
||||
*/
|
||||
native CCC_GetColor(client, CCC_ColorType:type, &bool:alpha = false);
|
||||
|
||||
/**
|
||||
* Sets a client's color as a hexadecimal integer.
|
||||
*
|
||||
* @param client Client index
|
||||
* @param type Color type to set
|
||||
* @param color Integer representation of the color (use StringToInt(input, 16) to convert a hexadecimal string) or one of the color defines
|
||||
* @param alpha Are you specifying a color with alpha?
|
||||
* @return True if the color is updated successfully, false otherwise
|
||||
*
|
||||
* On error/errors: Invalid client index or client is not in game
|
||||
*/
|
||||
native bool:CCC_SetColor(client, CCC_ColorType:type, color, bool:alpha);
|
||||
|
||||
/**
|
||||
* Gets a client's tag
|
||||
*
|
||||
* @param client Client index
|
||||
* @param buffer Buffer to store the tag in
|
||||
* @param maxlen Maximum buffer length
|
||||
* @noreturn
|
||||
*
|
||||
* On error/errors: Invalid client index or client is not in game
|
||||
*/
|
||||
native CCC_GetTag(client, String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Sets a client's tag
|
||||
*
|
||||
* @param client Client index
|
||||
* @param tag String containing the new tag
|
||||
* @noreturn
|
||||
*
|
||||
* On error/errors: Invalid client index or client is not in game
|
||||
*/
|
||||
native CCC_SetTag(client, const String:tag[]);
|
||||
|
||||
/**
|
||||
* Resets a client's color to the value in the config file.
|
||||
*
|
||||
* @param client Client index
|
||||
* @param type Color type to restore
|
||||
* @noreturn
|
||||
*
|
||||
* On error/errors: Invalid client index or client is not in game
|
||||
*/
|
||||
native CCC_ResetColor(client, CCC_ColorType:type);
|
||||
|
||||
/**
|
||||
* Resets a client's tag to the value in the config file.
|
||||
*
|
||||
* @param client Client index
|
||||
* @noreturn
|
||||
*
|
||||
* On error/errors: Invalid client index or client is not in game
|
||||
*/
|
||||
native CCC_ResetTag(client);
|
||||
|
||||
/**
|
||||
* Called when a cilent's name is about to be colored
|
||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
||||
*
|
||||
* @param client Client index
|
||||
* @return Plugin_Handled to prevent coloring, Plugin_Continue to allow coloring
|
||||
*/
|
||||
#pragma deprecated Use CCC_OnColor instead
|
||||
forward Action:CCC_OnNameColor(client);
|
||||
|
||||
/**
|
||||
* Called when a client's chat is about to be colored
|
||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
||||
*
|
||||
* @param client Client index
|
||||
* @return Plugin_Handled to prevent coloring, Plugin_Continue to allow coloring
|
||||
*/
|
||||
#pragma deprecated Use CCC_OnColor instead
|
||||
forward Action:CCC_OnChatColor(client);
|
||||
|
||||
/**
|
||||
* Called when a client's name is about to be tagged
|
||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
||||
*
|
||||
* @param client Client index
|
||||
* @return Plugin_Handled to prevent tagging, Plugin_Continue to allow tagging
|
||||
*/
|
||||
#pragma deprecated Use CCC_OnColor instead
|
||||
forward Action:CCC_OnTagApplied(client);
|
||||
|
||||
/**
|
||||
* Called when a client's name is about to be tagged
|
||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
||||
*
|
||||
* @param client Client index
|
||||
* @param message Chat message that will be printed
|
||||
* @param type What type of color will be applied. If this is CCC_TagColor, it controls whether the tag will be applied at all, not whether the tag will be colored.
|
||||
* @return Plugin_Handled to prevent coloring, Plugin_Continue to allow coloring
|
||||
*/
|
||||
forward Action:CCC_OnColor(client, const String:message[], CCC_ColorType:type);
|
||||
|
||||
/**
|
||||
* Called when a message has been fully colored and will be sent, unless further plugins modify it through Simple Chat Processor
|
||||
*
|
||||
* @param author Author client index
|
||||
* @param message Message
|
||||
* @param maxlen Maximum length of message buffer
|
||||
* @noreturn
|
||||
*/
|
||||
forward CCC_OnChatMessage(author, String:message[], maxlen);
|
||||
|
||||
/**
|
||||
* Called when a client's colors and tag are about to be loaded from the config file
|
||||
* At this point, the client has NO COLORS
|
||||
*
|
||||
* @param client Client index
|
||||
* @return Plugin_Handled or Plugin_Stop to prevent loading, Plugin_Continue or Plugin_Changed to allow
|
||||
*/
|
||||
forward Action:CCC_OnUserConfigPreLoaded(client);
|
||||
|
||||
/**
|
||||
* Called when a client's colors and tag have been loaded from the config file
|
||||
*
|
||||
* @param client Client index
|
||||
* @noreturn
|
||||
*/
|
||||
forward CCC_OnUserConfigLoaded(client);
|
||||
|
||||
/**
|
||||
* Called when the configuration file is reloaded with the sm_reloadccc command
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward CCC_OnConfigReloaded();
|
||||
|
||||
native void CCC_UpdateIgnoredArray(bool IgnoredArray[(MAXPLAYERS + 1) * (MAXPLAYERS + 1)]);
|
||||
|
||||
public SharedPlugin:__pl_ccc = {
|
||||
name = "ccc",
|
||||
file = "custom-chatcolors.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1
|
||||
#else
|
||||
required = 0
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public __pl_ccc_SetNTVOptional() {
|
||||
MarkNativeAsOptional("CCC_GetColor");
|
||||
MarkNativeAsOptional("CCC_SetColor");
|
||||
MarkNativeAsOptional("CCC_GetTag");
|
||||
MarkNativeAsOptional("CCC_ResetTag");
|
||||
MarkNativeAsOptional("CCC_ResetColor");
|
||||
MarkNativeAsOptional("CCC_ResetTag");
|
||||
MarkNativeAsOptional("CCC_UpdateIgnoredArray");
|
||||
}
|
||||
#endif
|
1
custom-chatcolors/scripting/include/morecolors.inc
Symbolic link
1
custom-chatcolors/scripting/include/morecolors.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/morecolors.inc
|
53
custom-chatcolors/translations/allchat.phrases.txt
Normal file
53
custom-chatcolors/translations/allchat.phrases.txt
Normal file
@ -0,0 +1,53 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Cstrike_Chat_CT_Loc"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "(Counter-Terrorist) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_CT"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "(Counter-Terrorist) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_T_Loc"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "(Terrorist) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_T"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "(Terrorist) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_CT_Dead"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "*DEAD*(Counter-Terrorist) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_T_Dead"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "*DEAD*(Terrorist) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_Spec"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "(Spectator) {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_All"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "{1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_AllDead"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "*DEAD* {1} : {2}"
|
||||
}
|
||||
"Cstrike_Chat_AllSpec"
|
||||
{
|
||||
"#format" "{1:s},{2:s}"
|
||||
"en" "*SPEC* {1} : {2}"
|
||||
}
|
||||
}
|
324
includes/SteamWorks.inc
Normal file
324
includes/SteamWorks.inc
Normal file
@ -0,0 +1,324 @@
|
||||
#if defined _SteamWorks_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _SteamWorks_Included
|
||||
|
||||
/* results from UserHasLicenseForApp */
|
||||
enum EUserHasLicenseForAppResult
|
||||
{
|
||||
k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app
|
||||
k_EUserHasLicenseResultDoesNotHaveLicense = 1, // User does not have a license for the specified app
|
||||
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated
|
||||
};
|
||||
|
||||
/* General result codes */
|
||||
enum EResult
|
||||
{
|
||||
k_EResultOK = 1, // success
|
||||
k_EResultFail = 2, // generic failure
|
||||
k_EResultNoConnection = 3, // no/failed network connection
|
||||
// k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
|
||||
k_EResultInvalidPassword = 5, // password/ticket is invalid
|
||||
k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
|
||||
k_EResultInvalidProtocolVer = 7, // protocol version is incorrect
|
||||
k_EResultInvalidParam = 8, // a parameter is incorrect
|
||||
k_EResultFileNotFound = 9, // file was not found
|
||||
k_EResultBusy = 10, // called method busy - action not taken
|
||||
k_EResultInvalidState = 11, // called object was in an invalid state
|
||||
k_EResultInvalidName = 12, // name is invalid
|
||||
k_EResultInvalidEmail = 13, // email is invalid
|
||||
k_EResultDuplicateName = 14, // name is not unique
|
||||
k_EResultAccessDenied = 15, // access is denied
|
||||
k_EResultTimeout = 16, // operation timed out
|
||||
k_EResultBanned = 17, // VAC2 banned
|
||||
k_EResultAccountNotFound = 18, // account not found
|
||||
k_EResultInvalidSteamID = 19, // steamID is invalid
|
||||
k_EResultServiceUnavailable = 20, // The requested service is currently unavailable
|
||||
k_EResultNotLoggedOn = 21, // The user is not logged on
|
||||
k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party)
|
||||
k_EResultEncryptionFailure = 23, // Encryption or Decryption failed
|
||||
k_EResultInsufficientPrivilege = 24, // Insufficient privilege
|
||||
k_EResultLimitExceeded = 25, // Too much of a good thing
|
||||
k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes)
|
||||
k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired
|
||||
k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again
|
||||
k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time
|
||||
k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user
|
||||
k_EResultIPNotFound = 31, // IP address not found
|
||||
k_EResultPersistFailed = 32, // failed to write change to the data store
|
||||
k_EResultLockingFailed = 33, // failed to acquire access lock for this operation
|
||||
k_EResultLogonSessionReplaced = 34,
|
||||
k_EResultConnectFailed = 35,
|
||||
k_EResultHandshakeFailed = 36,
|
||||
k_EResultIOFailure = 37,
|
||||
k_EResultRemoteDisconnect = 38,
|
||||
k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested
|
||||
k_EResultBlocked = 40, // a user didn't allow it
|
||||
k_EResultIgnored = 41, // target is ignoring sender
|
||||
k_EResultNoMatch = 42, // nothing matching the request found
|
||||
k_EResultAccountDisabled = 43,
|
||||
k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now
|
||||
k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available
|
||||
k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin
|
||||
k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol.
|
||||
k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another.
|
||||
k_EResultPasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed.
|
||||
k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait
|
||||
k_EResultSuspended = 51, // Long running operation (content download) suspended/paused
|
||||
k_EResultCancelled = 52, // Operation canceled (typically by user: content download)
|
||||
k_EResultDataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable
|
||||
k_EResultDiskFull = 54, // Operation canceled - not enough disk space.
|
||||
k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed
|
||||
k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side
|
||||
k_EResultExternalAccountUnlinked = 57, // External account (PSN, Facebook...) is not linked to a Steam account
|
||||
k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid
|
||||
k_EResultExternalAccountAlreadyLinked = 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
|
||||
k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files
|
||||
k_EResultIllegalPassword = 61, // The requested new password is not legal
|
||||
k_EResultSameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer )
|
||||
k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure
|
||||
k_EResultCannotUseOldPassword = 64, // The requested new password is not legal
|
||||
k_EResultInvalidLoginAuthCode = 65, // account login denied due to auth code invalid
|
||||
k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent
|
||||
k_EResultHardwareNotCapableOfIPT = 67, //
|
||||
k_EResultIPTInitError = 68, //
|
||||
k_EResultParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user
|
||||
k_EResultFacebookQueryError = 70, // Facebook query returned an error
|
||||
k_EResultExpiredLoginAuthCode = 71, // account login denied due to auth code expired
|
||||
k_EResultIPLoginRestrictionFailed = 72,
|
||||
k_EResultAccountLockedDown = 73,
|
||||
k_EResultAccountLogonDeniedVerifiedEmailRequired = 74,
|
||||
k_EResultNoMatchingURL = 75,
|
||||
k_EResultBadResponse = 76, // parse failure, missing field, etc.
|
||||
k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password
|
||||
k_EResultValueOutOfRange = 78 // the value entered is outside the acceptable range
|
||||
};
|
||||
|
||||
/* This enum is used in client API methods, do not re-number existing values. */
|
||||
enum EHTTPMethod
|
||||
{
|
||||
k_EHTTPMethodInvalid = 0,
|
||||
k_EHTTPMethodGET,
|
||||
k_EHTTPMethodHEAD,
|
||||
k_EHTTPMethodPOST,
|
||||
k_EHTTPMethodPUT,
|
||||
k_EHTTPMethodDELETE,
|
||||
k_EHTTPMethodOPTIONS,
|
||||
|
||||
// The remaining HTTP methods are not yet supported, per rfc2616 section 5.1.1 only GET and HEAD are required for
|
||||
// a compliant general purpose server. We'll likely add more as we find uses for them.
|
||||
|
||||
// k_EHTTPMethodTRACE,
|
||||
// k_EHTTPMethodCONNECT
|
||||
};
|
||||
|
||||
|
||||
/* HTTP Status codes that the server can send in response to a request, see rfc2616 section 10.3 for descriptions
|
||||
of each of these. */
|
||||
enum EHTTPStatusCode
|
||||
{
|
||||
// Invalid status code (this isn't defined in HTTP, used to indicate unset in our code)
|
||||
k_EHTTPStatusCodeInvalid = 0,
|
||||
|
||||
// Informational codes
|
||||
k_EHTTPStatusCode100Continue = 100,
|
||||
k_EHTTPStatusCode101SwitchingProtocols = 101,
|
||||
|
||||
// Success codes
|
||||
k_EHTTPStatusCode200OK = 200,
|
||||
k_EHTTPStatusCode201Created = 201,
|
||||
k_EHTTPStatusCode202Accepted = 202,
|
||||
k_EHTTPStatusCode203NonAuthoritative = 203,
|
||||
k_EHTTPStatusCode204NoContent = 204,
|
||||
k_EHTTPStatusCode205ResetContent = 205,
|
||||
k_EHTTPStatusCode206PartialContent = 206,
|
||||
|
||||
// Redirection codes
|
||||
k_EHTTPStatusCode300MultipleChoices = 300,
|
||||
k_EHTTPStatusCode301MovedPermanently = 301,
|
||||
k_EHTTPStatusCode302Found = 302,
|
||||
k_EHTTPStatusCode303SeeOther = 303,
|
||||
k_EHTTPStatusCode304NotModified = 304,
|
||||
k_EHTTPStatusCode305UseProxy = 305,
|
||||
//k_EHTTPStatusCode306Unused = 306, (used in old HTTP spec, now unused in 1.1)
|
||||
k_EHTTPStatusCode307TemporaryRedirect = 307,
|
||||
|
||||
// Error codes
|
||||
k_EHTTPStatusCode400BadRequest = 400,
|
||||
k_EHTTPStatusCode401Unauthorized = 401, // You probably want 403 or something else. 401 implies you're sending a WWW-Authenticate header and the client can sent an Authorization header in response.
|
||||
k_EHTTPStatusCode402PaymentRequired = 402, // This is reserved for future HTTP specs, not really supported by clients
|
||||
k_EHTTPStatusCode403Forbidden = 403,
|
||||
k_EHTTPStatusCode404NotFound = 404,
|
||||
k_EHTTPStatusCode405MethodNotAllowed = 405,
|
||||
k_EHTTPStatusCode406NotAcceptable = 406,
|
||||
k_EHTTPStatusCode407ProxyAuthRequired = 407,
|
||||
k_EHTTPStatusCode408RequestTimeout = 408,
|
||||
k_EHTTPStatusCode409Conflict = 409,
|
||||
k_EHTTPStatusCode410Gone = 410,
|
||||
k_EHTTPStatusCode411LengthRequired = 411,
|
||||
k_EHTTPStatusCode412PreconditionFailed = 412,
|
||||
k_EHTTPStatusCode413RequestEntityTooLarge = 413,
|
||||
k_EHTTPStatusCode414RequestURITooLong = 414,
|
||||
k_EHTTPStatusCode415UnsupportedMediaType = 415,
|
||||
k_EHTTPStatusCode416RequestedRangeNotSatisfiable = 416,
|
||||
k_EHTTPStatusCode417ExpectationFailed = 417,
|
||||
k_EHTTPStatusCode4xxUnknown = 418, // 418 is reserved, so we'll use it to mean unknown
|
||||
k_EHTTPStatusCode429TooManyRequests = 429,
|
||||
|
||||
// Server error codes
|
||||
k_EHTTPStatusCode500InternalServerError = 500,
|
||||
k_EHTTPStatusCode501NotImplemented = 501,
|
||||
k_EHTTPStatusCode502BadGateway = 502,
|
||||
k_EHTTPStatusCode503ServiceUnavailable = 503,
|
||||
k_EHTTPStatusCode504GatewayTimeout = 504,
|
||||
k_EHTTPStatusCode505HTTPVersionNotSupported = 505,
|
||||
k_EHTTPStatusCode5xxUnknown = 599,
|
||||
};
|
||||
|
||||
native bool:SteamWorks_IsVACEnabled();
|
||||
native bool:SteamWorks_GetPublicIP(ipaddr[4]);
|
||||
native SteamWorks_GetPublicIPCell();
|
||||
native bool:SteamWorks_IsLoaded();
|
||||
native bool:SteamWorks_SetGameDescription(String:sDesc[]);
|
||||
native bool:SteamWorks_IsConnected();
|
||||
native bool:SteamWorks_SetRule(const String:sKey[], const String:sValue[]);
|
||||
native bool:SteamWorks_ClearRules();
|
||||
native bool:SteamWorks_ForceHeartbeat();
|
||||
native bool:SteamWorks_GetUserGroupStatus(client, groupid);
|
||||
native bool:SteamWorks_GetUserGroupStatusAuthID(authid, groupid);
|
||||
|
||||
native EUserHasLicenseForAppResult:SteamWorks_HasLicenseForApp(client, app);
|
||||
native SteamWorks_GetClientSteamID(client, String:sSteamID[], length);
|
||||
|
||||
native bool:SteamWorks_RequestStatsAuthID(authid, appid);
|
||||
native bool:SteamWorks_RequestStats(client, appid);
|
||||
native bool:SteamWorks_GetStatCell(client, const String:sKey[], &value);
|
||||
native bool:SteamWorks_GetStatAuthIDCell(authid, const String:sKey[], &value);
|
||||
native bool:SteamWorks_GetStatFloat(client, const String:sKey[], &Float:value);
|
||||
native bool:SteamWorks_GetStatAuthIDFloat(authid, const String:sKey[], &Float:value);
|
||||
|
||||
native Handle:SteamWorks_CreateHTTPRequest(EHTTPMethod:method, const String:sURL[]);
|
||||
native bool:SteamWorks_SetHTTPRequestContextValue(Handle:hHandle, any:data1, any:data2=0);
|
||||
native bool:SteamWorks_SetHTTPRequestNetworkActivityTimeout(Handle:hHandle, timeout);
|
||||
native bool:SteamWorks_SetHTTPRequestHeaderValue(Handle:hHandle, const String:sName[], const String:sValue[]);
|
||||
native bool:SteamWorks_SetHTTPRequestGetOrPostParameter(Handle:hHandle, const String:sName[], const String:sValue[]);
|
||||
|
||||
funcenum SteamWorksHTTPRequestCompleted
|
||||
{
|
||||
public(Handle:hRequest, bool:bFailure, bool:bRequestSuccessful, EHTTPStatusCode:eStatusCode),
|
||||
public(Handle:hRequest, bool:bFailure, bool:bRequestSuccessful, EHTTPStatusCode:eStatusCode, any:data1),
|
||||
public(Handle:hRequest, bool:bFailure, bool:bRequestSuccessful, EHTTPStatusCode:eStatusCode, any:data1, any:data2)
|
||||
};
|
||||
|
||||
funcenum SteamWorksHTTPHeadersReceived
|
||||
{
|
||||
public(Handle:hRequest, bool:bFailure),
|
||||
public(Handle:hRequest, bool:bFailure, any:data1),
|
||||
public(Handle:hRequest, bool:bFailure, any:data1, any:data2)
|
||||
};
|
||||
|
||||
funcenum SteamWorksHTTPDataReceived
|
||||
{
|
||||
public(Handle:hRequest, bool:bFailure, offset, bytesreceived),
|
||||
public(Handle:hRequest, bool:bFailure, offset, bytesreceived, any:data1),
|
||||
public(Handle:hRequest, bool:bFailure, offset, bytesreceived, any:data1, any:data2)
|
||||
};
|
||||
|
||||
native bool:SteamWorks_SetHTTPCallbacks(Handle:hHandle, SteamWorksHTTPRequestCompleted:fCompleted = INVALID_FUNCTION, SteamWorksHTTPHeadersReceived:fHeaders = INVALID_FUNCTION, SteamWorksHTTPDataReceived:fData = INVALID_FUNCTION, Handle:hCalling = INVALID_HANDLE);
|
||||
native bool:SteamWorks_SendHTTPRequest(Handle:hRequest);
|
||||
native bool:SteamWorks_SendHTTPRequestAndStreamResponse(Handle:hRequest);
|
||||
native bool:SteamWorks_DeferHTTPRequest(Handle:hRequest);
|
||||
native bool:SteamWorks_PrioritizeHTTPRequest(Handle:hRequest);
|
||||
native bool:SteamWorks_GetHTTPResponseHeaderSize(Handle:hRequest, const String:sHeader[], &size);
|
||||
native bool:SteamWorks_GetHTTPResponseHeaderValue(Handle:hRequest, const String:sHeader[], String:sValue[], size);
|
||||
native bool:SteamWorks_GetHTTPResponseBodySize(Handle:hRequest, &size);
|
||||
native bool:SteamWorks_GetHTTPResponseBodyData(Handle:hRequest, String:sBody[], length);
|
||||
native bool:SteamWorks_GetHTTPStreamingResponseBodyData(Handle:hRequest, cOffset, String:sBody[], length);
|
||||
native bool:SteamWorks_GetHTTPDownloadProgressPct(Handle:hRequest, &Float:percent);
|
||||
native bool:SteamWorks_SetHTTPRequestRawPostBody(Handle:hRequest, const String:sContentType[], const String:sBody[], bodylen);
|
||||
|
||||
funcenum SteamWorksHTTPBodyCallback
|
||||
{
|
||||
public(const String:sData[]),
|
||||
public(const String:sData[], any:value),
|
||||
public(const data[], any:value, datalen)
|
||||
};
|
||||
|
||||
native bool:SteamWorks_GetHTTPResponseBodyCallback(Handle:hRequest, SteamWorksHTTPBodyCallback:fCallback, any:data = 0, Handle:hPlugin = INVALID_HANDLE);
|
||||
native bool:SteamWorks_WriteHTTPResponseBodyToFile(Handle:hRequest, const String:sFileName[]);
|
||||
|
||||
forward SW_OnValidateClient(ownerauthid, authid);
|
||||
forward SteamWorks_OnValidateClient(ownerauthid, authid);
|
||||
forward SteamWorks_SteamServersConnected();
|
||||
forward SteamWorks_SteamServersConnectFailure(EResult:result);
|
||||
forward SteamWorks_SteamServersDisconnected(EResult:result);
|
||||
|
||||
forward Action:SteamWorks_RestartRequested();
|
||||
forward SteamWorks_TokenRequested(String:sToken[], maxlen);
|
||||
|
||||
forward SteamWorks_OnClientGroupStatus(authid, groupid, bool:isMember, bool:isOfficer);
|
||||
|
||||
public Extension:__ext_SteamWorks =
|
||||
{
|
||||
name = "SteamWorks",
|
||||
file = "SteamWorks.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_SteamWorks_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("SteamWorks_IsVACEnabled");
|
||||
MarkNativeAsOptional("SteamWorks_GetPublicIP");
|
||||
MarkNativeAsOptional("SteamWorks_GetPublicIPCell");
|
||||
MarkNativeAsOptional("SteamWorks_IsLoaded");
|
||||
MarkNativeAsOptional("SteamWorks_SetGameDescription");
|
||||
MarkNativeAsOptional("SteamWorks_IsConnected");
|
||||
MarkNativeAsOptional("SteamWorks_SetRule");
|
||||
MarkNativeAsOptional("SteamWorks_ClearRules");
|
||||
MarkNativeAsOptional("SteamWorks_ForceHeartbeat");
|
||||
MarkNativeAsOptional("SteamWorks_GetUserGroupStatus");
|
||||
MarkNativeAsOptional("SteamWorks_GetUserGroupStatusAuthID");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_HasLicenseForApp");
|
||||
MarkNativeAsOptional("SteamWorks_GetClientSteamID");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_RequestStatsAuthID");
|
||||
MarkNativeAsOptional("SteamWorks_RequestStats");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatCell");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatAuthIDCell");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatFloat");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatAuthIDFloat");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_CreateHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestContextValue");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestNetworkActivityTimeout");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestHeaderValue");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestGetOrPostParameter");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPCallbacks");
|
||||
MarkNativeAsOptional("SteamWorks_SendHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_SendHTTPRequestAndStreamResponse");
|
||||
MarkNativeAsOptional("SteamWorks_DeferHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_PrioritizeHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseHeaderSize");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseHeaderValue");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodySize");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodyData");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPStreamingResponseBodyData");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPDownloadProgressPct");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestRawPostBody");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodyCallback");
|
||||
MarkNativeAsOptional("SteamWorks_WriteHTTPResponseBodyToFile");
|
||||
}
|
||||
#endif
|
539
includes/colors.inc
Normal file
539
includes/colors.inc
Normal file
@ -0,0 +1,539 @@
|
||||
/**************************************************************************
|
||||
* *
|
||||
* Colored Chat Functions *
|
||||
* Author: exvel, Editor: Popoklopsi, Powerlord, Bara *
|
||||
* Version: 1.1.3 *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#if defined _colors_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _colors_included
|
||||
|
||||
#define MAX_MESSAGE_LENGTH 250
|
||||
#define MAX_COLORS 12
|
||||
|
||||
#define SERVER_INDEX 0
|
||||
#define NO_INDEX -1
|
||||
#define NO_PLAYER -2
|
||||
|
||||
enum Colors
|
||||
{
|
||||
Color_Default = 0,
|
||||
Color_Darkred,
|
||||
Color_Green,
|
||||
Color_Lightgreen,
|
||||
Color_Red,
|
||||
Color_Blue,
|
||||
Color_Olive,
|
||||
Color_Lime,
|
||||
Color_Lightred,
|
||||
Color_Purple,
|
||||
Color_Grey,
|
||||
Color_Orange
|
||||
}
|
||||
|
||||
/* Colors' properties */
|
||||
new String:CTag[][] = {"{default}", "{darkred}", "{green}", "{lightgreen}", "{red}", "{blue}", "{olive}", "{lime}", "{lightred}", "{purple}", "{grey}", "{orange}"};
|
||||
new String:CTagCode[][] = {"\x01", "\x02", "\x04", "\x03", "\x03", "\x03", "\x05", "\x06", "\x07", "\x03", "\x08", "\x09"};
|
||||
new bool:CTagReqSayText2[] = {false, false, false, true, true, true, false, false, false, false, false, false};
|
||||
new bool:CEventIsHooked = false;
|
||||
new bool:CSkipList[MAXPLAYERS+1] = {false,...};
|
||||
|
||||
/* Game default profile */
|
||||
new bool:CProfile_Colors[] = {true, false, true, false, false, false, false, false, false, false, false, false};
|
||||
new CProfile_TeamIndex[] = {NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX};
|
||||
new bool:CProfile_SayText2 = false;
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client in the chat area.
|
||||
* Supports color tags.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param szMessage Message (formatting rules).
|
||||
* @return No return
|
||||
*
|
||||
* On error/Errors: If the client is not connected an error will be thrown.
|
||||
*/
|
||||
stock CPrintToChat(client, const String:szMessage[], any:...)
|
||||
{
|
||||
if (client <= 0 || client > MaxClients)
|
||||
ThrowError("Invalid client index %d", client);
|
||||
|
||||
if (!IsClientInGame(client))
|
||||
ThrowError("Client %d is not in game", client);
|
||||
|
||||
decl String:szBuffer[MAX_MESSAGE_LENGTH];
|
||||
decl String:szCMessage[MAX_MESSAGE_LENGTH];
|
||||
|
||||
SetGlobalTransTarget(client);
|
||||
|
||||
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
|
||||
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 3);
|
||||
|
||||
new index = CFormat(szCMessage, sizeof(szCMessage));
|
||||
|
||||
if (index == NO_INDEX)
|
||||
PrintToChat(client, "%s", szCMessage);
|
||||
else
|
||||
CSayText2(client, index, szCMessage);
|
||||
}
|
||||
|
||||
stock CReplyToCommand(client, const String:szMessage[], any:...)
|
||||
{
|
||||
|
||||
decl String:szCMessage[MAX_MESSAGE_LENGTH];
|
||||
VFormat(szCMessage, sizeof(szCMessage), szMessage, 3);
|
||||
|
||||
if (client == 0)
|
||||
{
|
||||
CRemoveTags(szCMessage, sizeof(szCMessage));
|
||||
PrintToServer("%s", szCMessage);
|
||||
}
|
||||
else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE)
|
||||
{
|
||||
CRemoveTags(szCMessage, sizeof(szCMessage));
|
||||
PrintToConsole(client, "%s", szCMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
CPrintToChat(client, "%s", szCMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prints a message to all clients in the chat area.
|
||||
* Supports color tags.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param szMessage Message (formatting rules)
|
||||
* @return No return
|
||||
*/
|
||||
stock CPrintToChatAll(const String:szMessage[], any:...)
|
||||
{
|
||||
decl String:szBuffer[MAX_MESSAGE_LENGTH];
|
||||
|
||||
for (new i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i])
|
||||
{
|
||||
SetGlobalTransTarget(i);
|
||||
VFormat(szBuffer, sizeof(szBuffer), szMessage, 2);
|
||||
|
||||
CPrintToChat(i, "%s", szBuffer);
|
||||
}
|
||||
|
||||
CSkipList[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client in the chat area.
|
||||
* Supports color tags and teamcolor tag.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param author Author index whose color will be used for teamcolor tag.
|
||||
* @param szMessage Message (formatting rules).
|
||||
* @return No return
|
||||
*
|
||||
* On error/Errors: If the client or author are not connected an error will be thrown.
|
||||
*/
|
||||
stock CPrintToChatEx(client, author, const String:szMessage[], any:...)
|
||||
{
|
||||
if (client <= 0 || client > MaxClients)
|
||||
ThrowError("Invalid client index %d", client);
|
||||
|
||||
if (!IsClientInGame(client))
|
||||
ThrowError("Client %d is not in game", client);
|
||||
|
||||
if (author < 0 || author > MaxClients)
|
||||
ThrowError("Invalid client index %d", author);
|
||||
|
||||
decl String:szBuffer[MAX_MESSAGE_LENGTH];
|
||||
decl String:szCMessage[MAX_MESSAGE_LENGTH];
|
||||
|
||||
SetGlobalTransTarget(client);
|
||||
|
||||
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
|
||||
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 4);
|
||||
|
||||
new index = CFormat(szCMessage, sizeof(szCMessage), author);
|
||||
|
||||
if (index == NO_INDEX)
|
||||
PrintToChat(client, "%s", szCMessage);
|
||||
else
|
||||
CSayText2(client, author, szCMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to all clients in the chat area.
|
||||
* Supports color tags and teamcolor tag.
|
||||
*
|
||||
* @param author Author index whos color will be used for teamcolor tag.
|
||||
* @param szMessage Message (formatting rules).
|
||||
* @return No return
|
||||
*
|
||||
* On error/Errors: If the author is not connected an error will be thrown.
|
||||
*/
|
||||
stock CPrintToChatAllEx(author, const String:szMessage[], any:...)
|
||||
{
|
||||
if (author < 0 || author > MaxClients)
|
||||
ThrowError("Invalid client index %d", author);
|
||||
|
||||
if (!IsClientInGame(author))
|
||||
ThrowError("Client %d is not in game", author);
|
||||
|
||||
decl String:szBuffer[MAX_MESSAGE_LENGTH];
|
||||
|
||||
for (new i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i])
|
||||
{
|
||||
SetGlobalTransTarget(i);
|
||||
VFormat(szBuffer, sizeof(szBuffer), szMessage, 3);
|
||||
|
||||
CPrintToChatEx(i, author, "%s", szBuffer);
|
||||
}
|
||||
|
||||
CSkipList[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes color tags from the string.
|
||||
*
|
||||
* @param szMessage String.
|
||||
* @return No return
|
||||
*/
|
||||
stock CRemoveTags(String:szMessage[], maxlength)
|
||||
{
|
||||
for (new i = 0; i < MAX_COLORS; i++)
|
||||
ReplaceString(szMessage, maxlength, CTag[i], "", false);
|
||||
|
||||
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a color is allowed or not
|
||||
*
|
||||
* @param tag Color Tag.
|
||||
* @return True when color is supported, otherwise false
|
||||
*/
|
||||
stock CColorAllowed(Colors:color)
|
||||
{
|
||||
if (!CEventIsHooked)
|
||||
{
|
||||
CSetupProfile();
|
||||
|
||||
CEventIsHooked = true;
|
||||
}
|
||||
|
||||
return CProfile_Colors[color];
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the color with another color
|
||||
* Handle with care!
|
||||
*
|
||||
* @param color color to replace.
|
||||
* @param newColor color to replace with.
|
||||
* @noreturn
|
||||
*/
|
||||
stock CReplaceColor(Colors:color, Colors:newColor)
|
||||
{
|
||||
if (!CEventIsHooked)
|
||||
{
|
||||
CSetupProfile();
|
||||
|
||||
CEventIsHooked = true;
|
||||
}
|
||||
|
||||
CProfile_Colors[color] = CProfile_Colors[newColor];
|
||||
CProfile_TeamIndex[color] = CProfile_TeamIndex[newColor];
|
||||
|
||||
CTagReqSayText2[color] = CTagReqSayText2[newColor];
|
||||
Format(CTagCode[color], sizeof(CTagCode[]), CTagCode[newColor])
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should only be used right in front of
|
||||
* CPrintToChatAll or CPrintToChatAllEx and it tells
|
||||
* to those funcions to skip specified client when printing
|
||||
* message to all clients. After message is printed client will
|
||||
* no more be skipped.
|
||||
*
|
||||
* @param client Client index
|
||||
* @return No return
|
||||
*/
|
||||
stock CSkipNextClient(client)
|
||||
{
|
||||
if (client <= 0 || client > MaxClients)
|
||||
ThrowError("Invalid client index %d", client);
|
||||
|
||||
CSkipList[client] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces color tags in a string with color codes
|
||||
*
|
||||
* @param szMessage String.
|
||||
* @param maxlength Maximum length of the string buffer.
|
||||
* @return Client index that can be used for SayText2 author index
|
||||
*
|
||||
* On error/Errors: If there is more then one team color is used an error will be thrown.
|
||||
*/
|
||||
stock CFormat(String:szMessage[], maxlength, author=NO_INDEX)
|
||||
{
|
||||
decl String:szGameName[30];
|
||||
|
||||
GetGameFolderName(szGameName, sizeof(szGameName));
|
||||
|
||||
/* Hook event for auto profile setup on map start */
|
||||
if (!CEventIsHooked)
|
||||
{
|
||||
CSetupProfile();
|
||||
HookEvent("server_spawn", CEvent_MapStart, EventHookMode_PostNoCopy);
|
||||
|
||||
CEventIsHooked = true;
|
||||
}
|
||||
|
||||
new iRandomPlayer = NO_INDEX;
|
||||
|
||||
// On CS:GO set invisible precolor
|
||||
if (StrEqual(szGameName, "csgo", false))
|
||||
Format(szMessage, maxlength, " \x01\x0B\x01%s", szMessage);
|
||||
|
||||
/* If author was specified replace {teamcolor} tag */
|
||||
if (author != NO_INDEX)
|
||||
{
|
||||
if (CProfile_SayText2)
|
||||
{
|
||||
ReplaceString(szMessage, maxlength, "{teamcolor}", "\x03", false);
|
||||
|
||||
iRandomPlayer = author;
|
||||
}
|
||||
/* If saytext2 is not supported by game replace {teamcolor} with green tag */
|
||||
else
|
||||
ReplaceString(szMessage, maxlength, "{teamcolor}", CTagCode[Color_Green], false);
|
||||
}
|
||||
else
|
||||
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
|
||||
|
||||
/* For other color tags we need a loop */
|
||||
for (new i = 0; i < MAX_COLORS; i++)
|
||||
{
|
||||
/* If tag not found - skip */
|
||||
if (StrContains(szMessage, CTag[i], false) == -1)
|
||||
continue;
|
||||
|
||||
/* If tag is not supported by game replace it with green tag */
|
||||
else if (!CProfile_Colors[i])
|
||||
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false);
|
||||
|
||||
/* If tag doesn't need saytext2 simply replace */
|
||||
else if (!CTagReqSayText2[i])
|
||||
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[i], false);
|
||||
|
||||
/* Tag needs saytext2 */
|
||||
else
|
||||
{
|
||||
/* If saytext2 is not supported by game replace tag with green tag */
|
||||
if (!CProfile_SayText2)
|
||||
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false);
|
||||
|
||||
/* Game supports saytext2 */
|
||||
else
|
||||
{
|
||||
/* If random player for tag wasn't specified replace tag and find player */
|
||||
if (iRandomPlayer == NO_INDEX)
|
||||
{
|
||||
/* Searching for valid client for tag */
|
||||
iRandomPlayer = CFindRandomPlayerByTeam(CProfile_TeamIndex[i]);
|
||||
|
||||
/* If player not found replace tag with green color tag */
|
||||
if (iRandomPlayer == NO_PLAYER)
|
||||
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false);
|
||||
|
||||
/* If player was found simply replace */
|
||||
else
|
||||
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[i], false);
|
||||
|
||||
}
|
||||
/* If found another team color tag throw error */
|
||||
else
|
||||
{
|
||||
//ReplaceString(szMessage, maxlength, CTag[i], "");
|
||||
ThrowError("Using two team colors in one message is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return iRandomPlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Founds a random player with specified team
|
||||
*
|
||||
* @param color_team Client team.
|
||||
* @return Client index or NO_PLAYER if no player found
|
||||
*/
|
||||
stock CFindRandomPlayerByTeam(color_team)
|
||||
{
|
||||
if (color_team == SERVER_INDEX)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
for (new i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i) && GetClientTeam(i) == color_team)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return NO_PLAYER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a SayText2 usermessage to a client
|
||||
*
|
||||
* @param szMessage Client index
|
||||
* @param maxlength Author index
|
||||
* @param szMessage Message
|
||||
* @return No return.
|
||||
*/
|
||||
stock CSayText2(client, author, const String:szMessage[])
|
||||
{
|
||||
new Handle:hBuffer = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
|
||||
|
||||
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
|
||||
{
|
||||
PbSetInt(hBuffer, "ent_idx", author);
|
||||
PbSetBool(hBuffer, "chat", true);
|
||||
PbSetString(hBuffer, "msg_name", szMessage);
|
||||
PbAddString(hBuffer, "params", "");
|
||||
PbAddString(hBuffer, "params", "");
|
||||
PbAddString(hBuffer, "params", "");
|
||||
PbAddString(hBuffer, "params", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
BfWriteByte(hBuffer, author);
|
||||
BfWriteByte(hBuffer, true);
|
||||
BfWriteString(hBuffer, szMessage);
|
||||
}
|
||||
|
||||
EndMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates game color profile
|
||||
* This function must be edited if you want to add more games support
|
||||
*
|
||||
* @return No return.
|
||||
*/
|
||||
stock CSetupProfile()
|
||||
{
|
||||
decl String:szGameName[30];
|
||||
GetGameFolderName(szGameName, sizeof(szGameName));
|
||||
|
||||
if (StrEqual(szGameName, "cstrike", false))
|
||||
{
|
||||
CProfile_Colors[Color_Lightgreen] = true;
|
||||
CProfile_Colors[Color_Red] = true;
|
||||
CProfile_Colors[Color_Blue] = true;
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
|
||||
CProfile_TeamIndex[Color_Red] = 2;
|
||||
CProfile_TeamIndex[Color_Blue] = 3;
|
||||
CProfile_SayText2 = true;
|
||||
}
|
||||
else if (StrEqual(szGameName, "csgo", false))
|
||||
{
|
||||
CProfile_Colors[Color_Red] = true;
|
||||
CProfile_Colors[Color_Blue] = true;
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
CProfile_Colors[Color_Darkred] = true;
|
||||
CProfile_Colors[Color_Lime] = true;
|
||||
CProfile_Colors[Color_Lightred] = true;
|
||||
CProfile_Colors[Color_Purple] = true;
|
||||
CProfile_Colors[Color_Grey] = true;
|
||||
CProfile_Colors[Color_Orange] = true;
|
||||
CProfile_TeamIndex[Color_Red] = 2;
|
||||
CProfile_TeamIndex[Color_Blue] = 3;
|
||||
CProfile_SayText2 = true;
|
||||
}
|
||||
else if (StrEqual(szGameName, "tf", false))
|
||||
{
|
||||
CProfile_Colors[Color_Lightgreen] = true;
|
||||
CProfile_Colors[Color_Red] = true;
|
||||
CProfile_Colors[Color_Blue] = true;
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
|
||||
CProfile_TeamIndex[Color_Red] = 2;
|
||||
CProfile_TeamIndex[Color_Blue] = 3;
|
||||
CProfile_SayText2 = true;
|
||||
}
|
||||
else if (StrEqual(szGameName, "left4dead", false) || StrEqual(szGameName, "left4dead2", false))
|
||||
{
|
||||
CProfile_Colors[Color_Lightgreen] = true;
|
||||
CProfile_Colors[Color_Red] = true;
|
||||
CProfile_Colors[Color_Blue] = true;
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
|
||||
CProfile_TeamIndex[Color_Red] = 3;
|
||||
CProfile_TeamIndex[Color_Blue] = 2;
|
||||
CProfile_SayText2 = true;
|
||||
}
|
||||
else if (StrEqual(szGameName, "hl2mp", false))
|
||||
{
|
||||
/* hl2mp profile is based on mp_teamplay convar */
|
||||
if (GetConVarBool(FindConVar("mp_teamplay")))
|
||||
{
|
||||
CProfile_Colors[Color_Red] = true;
|
||||
CProfile_Colors[Color_Blue] = true;
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
CProfile_TeamIndex[Color_Red] = 3;
|
||||
CProfile_TeamIndex[Color_Blue] = 2;
|
||||
CProfile_SayText2 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CProfile_SayText2 = false;
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
}
|
||||
}
|
||||
else if (StrEqual(szGameName, "dod", false))
|
||||
{
|
||||
CProfile_Colors[Color_Olive] = true;
|
||||
CProfile_SayText2 = false;
|
||||
}
|
||||
/* Profile for other games */
|
||||
else
|
||||
{
|
||||
if (GetUserMessageId("SayText2") == INVALID_MESSAGE_ID)
|
||||
{
|
||||
CProfile_SayText2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CProfile_Colors[Color_Red] = true;
|
||||
CProfile_Colors[Color_Blue] = true;
|
||||
CProfile_TeamIndex[Color_Red] = 2;
|
||||
CProfile_TeamIndex[Color_Blue] = 3;
|
||||
CProfile_SayText2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:CEvent_MapStart(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
CSetupProfile();
|
||||
|
||||
for (new i = 1; i <= MaxClients; i++)
|
||||
CSkipList[i] = false;
|
||||
}
|
482
includes/dhooks.inc
Normal file
482
includes/dhooks.inc
Normal file
@ -0,0 +1,482 @@
|
||||
#if defined _dhooks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _dhooks_included
|
||||
|
||||
enum ObjectValueType
|
||||
{
|
||||
ObjectValueType_Int = 0,
|
||||
ObjectValueType_Bool,
|
||||
ObjectValueType_Ehandle,
|
||||
ObjectValueType_Float,
|
||||
ObjectValueType_CBaseEntityPtr,
|
||||
ObjectValueType_IntPtr,
|
||||
ObjectValueType_BoolPtr,
|
||||
ObjectValueType_EhandlePtr,
|
||||
ObjectValueType_FloatPtr,
|
||||
ObjectValueType_Vector,
|
||||
ObjectValueType_VectorPtr,
|
||||
ObjectValueType_CharPtr,
|
||||
ObjectValueType_String
|
||||
};
|
||||
|
||||
enum ListenType
|
||||
{
|
||||
ListenType_Created,
|
||||
ListenType_Deleted
|
||||
};
|
||||
|
||||
enum ReturnType
|
||||
{
|
||||
ReturnType_Unknown,
|
||||
ReturnType_Void,
|
||||
ReturnType_Int,
|
||||
ReturnType_Bool,
|
||||
ReturnType_Float,
|
||||
ReturnType_String, //Note this is a string_t
|
||||
ReturnType_StringPtr, //Note this is a string_t *
|
||||
ReturnType_CharPtr,
|
||||
ReturnType_Vector,
|
||||
ReturnType_VectorPtr,
|
||||
ReturnType_CBaseEntity,
|
||||
ReturnType_Edict
|
||||
};
|
||||
|
||||
enum HookParamType
|
||||
{
|
||||
HookParamType_Unknown,
|
||||
HookParamType_Int,
|
||||
HookParamType_Bool,
|
||||
HookParamType_Float,
|
||||
HookParamType_String, //Note this is a string_t
|
||||
HookParamType_StringPtr, //Note this is a string_t *
|
||||
HookParamType_CharPtr,
|
||||
HookParamType_VectorPtr,
|
||||
HookParamType_CBaseEntity,
|
||||
HookParamType_ObjectPtr,
|
||||
HookParamType_Edict,
|
||||
HookParamType_Object
|
||||
};
|
||||
|
||||
enum ThisPointerType
|
||||
{
|
||||
ThisPointer_Ignore,
|
||||
ThisPointer_CBaseEntity,
|
||||
ThisPointer_Address
|
||||
};
|
||||
|
||||
enum HookType
|
||||
{
|
||||
HookType_Entity,
|
||||
HookType_GameRules,
|
||||
HookType_Raw
|
||||
};
|
||||
|
||||
enum MRESReturn
|
||||
{
|
||||
MRES_ChangedHandled = -2, // Use changed values and return MRES_Handled
|
||||
MRES_ChangedOverride, // Use changed values and return MRES_Override
|
||||
MRES_Ignored, // plugin didn't take any action
|
||||
MRES_Handled, // plugin did something, but real function should still be called
|
||||
MRES_Override, // call real function, but use my return value
|
||||
MRES_Supercede // skip real function; use my return value
|
||||
};
|
||||
|
||||
enum DHookPassFlag
|
||||
{
|
||||
DHookPass_ByVal = (1<<0),
|
||||
DHookPass_ByRef = (1<<1)
|
||||
};
|
||||
|
||||
typeset ListenCB
|
||||
{
|
||||
//Deleted
|
||||
function void (int entity);
|
||||
|
||||
//Created
|
||||
function void (int entity, const char[] classname);
|
||||
};
|
||||
|
||||
typeset DHookRemovalCB
|
||||
{
|
||||
function void (int hookid);
|
||||
};
|
||||
typeset DHookCallback
|
||||
{
|
||||
//Function Example: void Ham::Test() with this pointer ignore
|
||||
function MRESReturn ();
|
||||
|
||||
//Function Example: void Ham::Test() with this pointer passed
|
||||
function MRESReturn (int pThis);
|
||||
|
||||
//Function Example: void Ham::Test(int cake) with this pointer ignore
|
||||
function MRESReturn (Handle hParams);
|
||||
|
||||
//Function Example: void Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (int pThis, Handle hParams);
|
||||
|
||||
//Function Example: int Ham::Test() with this pointer ignore
|
||||
function MRESReturn (Handle hReturn);
|
||||
|
||||
//Function Example: int Ham::Test() with this pointer passed
|
||||
function MRESReturn (int pThis, Handle hReturn);
|
||||
|
||||
//Function Example: int Ham::Test(int cake) with this pointer ignore
|
||||
function MRESReturn (Handle hReturn, Handle hParams);
|
||||
|
||||
//Function Example: int Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (int pThis, Handle hReturn, Handle hParams);
|
||||
|
||||
//Address NOW
|
||||
|
||||
//Function Example: void Ham::Test() with this pointer passed
|
||||
function MRESReturn (Address pThis);
|
||||
|
||||
//Function Example: void Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (Address pThis, Handle hParams);
|
||||
|
||||
//Function Example: int Ham::Test() with this pointer passed
|
||||
function MRESReturn (Address pThis, Handle hReturn);
|
||||
|
||||
//Function Example: int Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (Address pThis, Handle hReturn, Handle hParams);
|
||||
|
||||
};
|
||||
|
||||
/* Adds an entity listener hook
|
||||
*
|
||||
* @param type Type of listener to add
|
||||
* @param callback Callback to use
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookAddEntityListener(ListenType type, ListenCB callback);
|
||||
|
||||
/* Removes an entity listener hook
|
||||
*
|
||||
* @param type Type of listener to remove
|
||||
* @param callback Callback this listener was using
|
||||
*
|
||||
* @return True if one was removed false otherwise.
|
||||
*/
|
||||
native bool DHookRemoveEntityListener(ListenType type, ListenCB callback);
|
||||
|
||||
/* Creates a hook
|
||||
*
|
||||
* @param offset vtable offset for function to hook
|
||||
* @param hooktype Type of hook
|
||||
* @param returntype Type type of return
|
||||
* @param thistype Type of this pointer or ignore (ignore can be used if not needed)
|
||||
* @param callback Callback function
|
||||
*
|
||||
* @return Returns setup handle for the hook or INVALID_HANDLE.
|
||||
*/
|
||||
native Handle DHookCreate(int offset, HookType hooktype, ReturnType returntype, ThisPointerType thistype, DHookCallback callback);
|
||||
|
||||
/* Adds param to a hook setup
|
||||
*
|
||||
* @param setup Setup handle to add the param to.
|
||||
* @param type Param type
|
||||
* @param size Used for Objects (not Object ptr) to define the size of the object.
|
||||
* @param flag Used to change the pass type.
|
||||
*
|
||||
* @error Invalid setup handle or too many params added (request upping the max in thread)
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookAddParam(Handle setup, HookParamType type, int size=-1, DHookPassFlag flag=DHookPass_ByVal);
|
||||
//native DHookAddParam(Handle:setup, HookParamType:type);
|
||||
|
||||
/* Hook entity
|
||||
*
|
||||
* @param setup Setup handle to use to add the hook.
|
||||
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||
* @param entity Entity index to hook on.
|
||||
* @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
|
||||
*
|
||||
* @error Invalid setup handle, invalid entity or invalid hook type.
|
||||
* @return -1 on fail a hookid on success
|
||||
*/
|
||||
native int DHookEntity(Handle setup, bool post, int entity, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||
|
||||
/* Hook gamerules
|
||||
*
|
||||
* @param setup Setup handle to use to add the hook.
|
||||
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||
* @param removalcb Callback for when the hook is removed (Game rules hooks are auto-removed on map end and will call this callback)
|
||||
*
|
||||
* @error Invalid setup handle, failing to get gamerules pointer or invalid hook type.
|
||||
* @return -1 on fail a hookid on success
|
||||
*/
|
||||
native int DHookGamerules(Handle setup, bool post, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||
|
||||
/* Hook a raw pointer
|
||||
*
|
||||
* @param setup Setup handle to use to add the hook.
|
||||
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||
* @param addr This pointer address.
|
||||
* @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
|
||||
*
|
||||
* @error Invalid setup handle, invalid address or invalid hook type.
|
||||
* @return -1 on fail a hookid on success
|
||||
*/
|
||||
native int DHookRaw(Handle setup, bool post, Address addr, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||
|
||||
/* Remove hook by hook id
|
||||
*
|
||||
* @param hookid Hook id to remove
|
||||
*
|
||||
* @return true on success false otherwise
|
||||
* @note This will not fire the removal callback!
|
||||
*/
|
||||
native bool DHookRemoveHookID(int hookid);
|
||||
|
||||
/* Get param value (Only use for: int, entity, bool or float param types)
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1. 0 Will return the number of params stored)
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @return value if num greater than 0. If 0 returns paramcount.
|
||||
*/
|
||||
native any DHookGetParam(Handle hParams, int num);
|
||||
|
||||
/* Get vector param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
|
||||
* @param vec Vector buffer to store result.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamVector(Handle hParams, int num, float vec[3]);
|
||||
|
||||
/* Get string param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
|
||||
* @param buffer String buffer to store result
|
||||
* @param size Buffer size
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamString(Handle hParams, int num, char[] buffer, int size);
|
||||
|
||||
/* Set param value (Only use for: int, entity, bool or float param types)
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||
* @param value Value to set it as (only pass int, bool, float or entity index)
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParam(Handle hParams, int num, any value);
|
||||
|
||||
/* Set vector param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||
* @param vec Value to set vector as.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamVector(Handle hParams, int num, float vec[3]);
|
||||
|
||||
/* Set string param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||
* @param value Value to set string as.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamString(Handle hParams, int num, char[] value);
|
||||
|
||||
/* Get return value (Only use for: int, entity, bool or float return types)
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @return Returns default value if prehook returns actual value if post hook.
|
||||
*/
|
||||
native any DHookGetReturn(Handle hReturn);
|
||||
|
||||
/* Get return vector value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param vec Vector buffer to store result in. (In pre hooks will be default value (0.0,0.0,0.0))
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetReturnVector(Handle hReturn, float vec[3]);
|
||||
|
||||
/* Get return string value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param buffer String buffer to store result in. (In pre hooks will be default value "")
|
||||
* @param size String buffer size
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetReturnString(Handle hReturn, char[] buffer, int size);
|
||||
|
||||
/* Set return value (Only use for: int, entity, bool or float return types)
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param value Value to set return as
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetReturn(Handle hReturn, any value);
|
||||
|
||||
/* Set return vector value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param vec Value to set return vector as
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetReturnVector(Handle hReturn, float vec[3]);
|
||||
|
||||
/* Set return string value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param value Value to set return string as
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetReturnString(Handle hReturn, char[] value);
|
||||
|
||||
//WE SHOULD WRAP THESE AROUND STOCKS FOR NON PTR AS WE SUPPORT BOTH WITH THESE NATIVE'S
|
||||
|
||||
/* Gets an objects variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get.
|
||||
* @param offset Offset within the object to the var to get.
|
||||
* @param type Type of var it is
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @return Value of the objects var. If EHANDLE type or entity returns entity index.
|
||||
*/
|
||||
native any DHookGetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type);
|
||||
|
||||
/* Sets an objects variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to set.
|
||||
* @param offset Offset within the object to the var to set.
|
||||
* @param type Type of var it is
|
||||
* @param value The value to set the var to.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type, any value);
|
||||
|
||||
/* Gets an objects vector variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get.
|
||||
* @param offset Offset within the object to the var to get.
|
||||
* @param type Type of var it is
|
||||
* @param buffer Buffer to store the result vector
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float buffer[3]);
|
||||
|
||||
/* Sets an objects vector variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to set.
|
||||
* @param offset Offset within the object to the var to set.
|
||||
* @param type Type of var it is
|
||||
* @param value The value to set the vector var to.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float value[3]);
|
||||
|
||||
/* Gets an objects string variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get.
|
||||
* @param offset Offset within the object to the var to get.
|
||||
* @param type Type of var it is
|
||||
* @param buffer Buffer to store the result vector
|
||||
* @param size Size of the buffer
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamObjectPtrString(Handle hParams, int num, int offset, ObjectValueType type, char[] buffer, int size);
|
||||
|
||||
/* Checks if a pointer param is null
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to check.
|
||||
*
|
||||
* @error Non pointer param
|
||||
* @return True if null false otherwise.
|
||||
*/
|
||||
native bool DHookIsNullParam(Handle hParams, int num);
|
||||
|
||||
public Extension __ext_dhooks =
|
||||
{
|
||||
name = "dhooks",
|
||||
file = "dhooks.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_dhooks_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("DHookAddEntityListener");
|
||||
MarkNativeAsOptional("DHookRemoveEntityListener");
|
||||
MarkNativeAsOptional("DHookCreate");
|
||||
MarkNativeAsOptional("DHookAddParam");
|
||||
MarkNativeAsOptional("DHookEntity");
|
||||
MarkNativeAsOptional("DHookGamerules");
|
||||
MarkNativeAsOptional("DHookRaw");
|
||||
MarkNativeAsOptional("DHookRemoveHookID");
|
||||
MarkNativeAsOptional("DHookGetParam");
|
||||
MarkNativeAsOptional("DHookGetParamVector");
|
||||
MarkNativeAsOptional("DHookGetParamString");
|
||||
MarkNativeAsOptional("DHookSetParam");
|
||||
MarkNativeAsOptional("DHookSetParamVector");
|
||||
MarkNativeAsOptional("DHookSetParamString");
|
||||
MarkNativeAsOptional("DHookGetReturn");
|
||||
MarkNativeAsOptional("DHookGetReturnVector");
|
||||
MarkNativeAsOptional("DHookGetReturnString");
|
||||
MarkNativeAsOptional("DHookSetReturn");
|
||||
MarkNativeAsOptional("DHookSetReturnVector");
|
||||
MarkNativeAsOptional("DHookSetReturnString");
|
||||
MarkNativeAsOptional("DHookGetParamObjectPtrVar");
|
||||
MarkNativeAsOptional("DHookSetParamObjectPtrVar");
|
||||
MarkNativeAsOptional("DHookGetParamObjectPtrVarVector");
|
||||
MarkNativeAsOptional("DHookSetParamObjectPtrVarVector");
|
||||
MarkNativeAsOptional("DHookIsNullParam");
|
||||
MarkNativeAsOptional("DHookGetParamObjectPtrString");
|
||||
}
|
||||
#endif
|
674
includes/morecolors.inc
Normal file
674
includes/morecolors.inc
Normal file
@ -0,0 +1,674 @@
|
||||
// MOAR COLORS
|
||||
// By Dr. McKay
|
||||
// Inspired by: https://forums.alliedmods.net/showthread.php?t=96831
|
||||
|
||||
#if defined _colors_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _colors_included
|
||||
|
||||
#include <regex>
|
||||
|
||||
#define MORE_COLORS_VERSION "1.9.1"
|
||||
#define MAX_MESSAGE_LENGTH 256
|
||||
#define MAX_BUFFER_LENGTH (MAX_MESSAGE_LENGTH * 4)
|
||||
|
||||
#define COLOR_RED 0xFF4040
|
||||
#define COLOR_BLUE 0x99CCFF
|
||||
#define COLOR_GRAY 0xCCCCCC
|
||||
#define COLOR_GREEN 0x3EFF3E
|
||||
|
||||
#define GAME_DODS 0
|
||||
|
||||
new bool:CSkipList[MAXPLAYERS + 1];
|
||||
new Handle:CTrie;
|
||||
new CTeamColors[][] = {{0xCCCCCC, 0x4D7942, 0xFF4040}}; // Multi-dimensional array for games that don't support SayText2. First index is the game index (as defined by the GAME_ defines), second index is team. 0 = spectator, 1 = team1, 2 = team2
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client in the chat area.
|
||||
* Supports color tags.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param message Message (formatting rules).
|
||||
* @noreturn
|
||||
*
|
||||
* On error/Errors: If the client is not connected an error will be thrown.
|
||||
*/
|
||||
stock CPrintToChat(client, const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
if(client <= 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %i", client);
|
||||
}
|
||||
if(!IsClientInGame(client)) {
|
||||
ThrowError("Client %i is not in game", client);
|
||||
}
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
SetGlobalTransTarget(client);
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 3);
|
||||
CReplaceColorCodes(buffer2);
|
||||
CSendMessage(client, buffer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to all clients in the chat area.
|
||||
* Supports color tags.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param message Message (formatting rules).
|
||||
* @noreturn
|
||||
*/
|
||||
stock CPrintToChatAll(const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
for(new i = 1; i <= MaxClients; i++) {
|
||||
if(!IsClientInGame(i) || CSkipList[i]) {
|
||||
CSkipList[i] = false;
|
||||
continue;
|
||||
}
|
||||
SetGlobalTransTarget(i);
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 2);
|
||||
CReplaceColorCodes(buffer2);
|
||||
CSendMessage(i, buffer2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client in the chat area.
|
||||
* Supports color tags and teamcolor tag.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param author Author index whose color will be used for teamcolor tag.
|
||||
* @param message Message (formatting rules).
|
||||
* @noreturn
|
||||
*
|
||||
* On error/Errors: If the client or author are not connected an error will be thrown
|
||||
*/
|
||||
stock CPrintToChatEx(client, author, const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
if(client <= 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %i", client);
|
||||
}
|
||||
if(!IsClientInGame(client)) {
|
||||
ThrowError("Client %i is not in game", client);
|
||||
}
|
||||
if(author <= 0 || author > MaxClients) {
|
||||
ThrowError("Invalid client index %i", author);
|
||||
}
|
||||
if(!IsClientInGame(author)) {
|
||||
ThrowError("Client %i is not in game", author);
|
||||
}
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
SetGlobalTransTarget(client);
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 4);
|
||||
CReplaceColorCodes(buffer2, author);
|
||||
CSendMessage(client, buffer2, author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to all clients in the chat area.
|
||||
* Supports color tags and teamcolor tag.
|
||||
*
|
||||
* @param author Author index whose color will be used for teamcolor tag.
|
||||
* @param message Message (formatting rules).
|
||||
* @noreturn
|
||||
*
|
||||
* On error/Errors: If the author is not connected an error will be thrown.
|
||||
*/
|
||||
stock CPrintToChatAllEx(author, const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
if(author <= 0 || author > MaxClients) {
|
||||
ThrowError("Invalid client index %i", author);
|
||||
}
|
||||
if(!IsClientInGame(author)) {
|
||||
ThrowError("Client %i is not in game", author);
|
||||
}
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
for(new i = 1; i <= MaxClients; i++) {
|
||||
if(!IsClientInGame(i) || CSkipList[i]) {
|
||||
CSkipList[i] = false;
|
||||
continue;
|
||||
}
|
||||
SetGlobalTransTarget(i);
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 3);
|
||||
CReplaceColorCodes(buffer2, author);
|
||||
CSendMessage(i, buffer2, author);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a SayText2 usermessage
|
||||
*
|
||||
* @param client Client to send usermessage to
|
||||
* @param message Message to send
|
||||
* @noreturn
|
||||
*/
|
||||
stock CSendMessage(client, const String:message[], author=0) {
|
||||
if(author == 0) {
|
||||
author = client;
|
||||
}
|
||||
decl String:buffer[MAX_MESSAGE_LENGTH], String:game[16];
|
||||
GetGameFolderName(game, sizeof(game));
|
||||
strcopy(buffer, sizeof(buffer), message);
|
||||
new UserMsg:index = GetUserMessageId("SayText2");
|
||||
if(index == INVALID_MESSAGE_ID) {
|
||||
if(StrEqual(game, "dod")) {
|
||||
new team = GetClientTeam(author);
|
||||
if(team == 0) {
|
||||
ReplaceString(buffer, sizeof(buffer), "\x03", "\x04", false); // Unassigned gets green
|
||||
} else {
|
||||
decl String:temp[16];
|
||||
Format(temp, sizeof(temp), "\x07%06X", CTeamColors[GAME_DODS][team - 1]);
|
||||
ReplaceString(buffer, sizeof(buffer), "\x03", temp, false);
|
||||
}
|
||||
}
|
||||
PrintToChat(client, "%s", buffer);
|
||||
return;
|
||||
}
|
||||
new Handle:buf = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
|
||||
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf) {
|
||||
PbSetInt(buf, "ent_idx", author);
|
||||
PbSetBool(buf, "chat", true);
|
||||
PbSetString(buf, "msg_name", buffer);
|
||||
PbAddString(buf, "params", "");
|
||||
PbAddString(buf, "params", "");
|
||||
PbAddString(buf, "params", "");
|
||||
PbAddString(buf, "params", "");
|
||||
} else {
|
||||
BfWriteByte(buf, author); // Message author
|
||||
BfWriteByte(buf, true); // Chat message
|
||||
BfWriteString(buf, buffer); // Message text
|
||||
}
|
||||
EndMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should only be used right in front of
|
||||
* CPrintToChatAll or CPrintToChatAllEx. It causes those functions
|
||||
* to skip the specified client when printing the message.
|
||||
* After printing the message, the client will no longer be skipped.
|
||||
*
|
||||
* @param client Client index
|
||||
* @noreturn
|
||||
*/
|
||||
stock CSkipNextClient(client) {
|
||||
if(client <= 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %i", client);
|
||||
}
|
||||
CSkipList[client] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the colors trie is initialized and initializes it if it's not (used internally)
|
||||
*
|
||||
* @return No return
|
||||
*/
|
||||
stock CCheckTrie() {
|
||||
if(CTrie == INVALID_HANDLE) {
|
||||
CTrie = InitColorTrie();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces color tags in a string with color codes (used internally by CPrintToChat, CPrintToChatAll, CPrintToChatEx, and CPrintToChatAllEx
|
||||
*
|
||||
* @param buffer String.
|
||||
* @param author Optional client index to use for {teamcolor} tags, or 0 for none
|
||||
* @param removeTags Optional boolean value to determine whether we're replacing tags with colors, or just removing tags, used by CRemoveTags
|
||||
* @param maxlen Optional value for max buffer length, used by CRemoveTags
|
||||
* @noreturn
|
||||
*
|
||||
* On error/Errors: If the client index passed for author is invalid or not in game.
|
||||
*/
|
||||
stock CReplaceColorCodes(String:buffer[], author=0, bool:removeTags=false, maxlen=MAX_BUFFER_LENGTH) {
|
||||
CCheckTrie();
|
||||
if(!removeTags) {
|
||||
ReplaceString(buffer, maxlen, "{default}", "\x01", false);
|
||||
} else {
|
||||
ReplaceString(buffer, maxlen, "{default}", "", false);
|
||||
ReplaceString(buffer, maxlen, "{teamcolor}", "", false);
|
||||
}
|
||||
if(author != 0 && !removeTags) {
|
||||
if(author < 0 || author > MaxClients) {
|
||||
ThrowError("Invalid client index %i", author);
|
||||
}
|
||||
if(!IsClientInGame(author)) {
|
||||
ThrowError("Client %i is not in game", author);
|
||||
}
|
||||
ReplaceString(buffer, maxlen, "{teamcolor}", "\x03", false);
|
||||
}
|
||||
new cursor = 0;
|
||||
new value;
|
||||
decl String:tag[32], String:buff[32], String:output[maxlen];
|
||||
strcopy(output, maxlen, buffer);
|
||||
// Since the string's size is going to be changing, output will hold the replaced string and we'll search buffer
|
||||
|
||||
new Handle:regex = CompileRegex("{[a-zA-Z0-9]+}");
|
||||
for(new i = 0; i < 1000; i++) { // The RegEx extension is quite flaky, so we have to loop here :/. This loop is supposed to be infinite and broken by return, but conditions have been added to be safe.
|
||||
if(MatchRegex(regex, buffer[cursor]) < 1) {
|
||||
CloseHandle(regex);
|
||||
strcopy(buffer, maxlen, output);
|
||||
return;
|
||||
}
|
||||
GetRegexSubString(regex, 0, tag, sizeof(tag));
|
||||
CStrToLower(tag);
|
||||
cursor = StrContains(buffer[cursor], tag, false) + cursor + 1;
|
||||
strcopy(buff, sizeof(buff), tag);
|
||||
ReplaceString(buff, sizeof(buff), "{", "");
|
||||
ReplaceString(buff, sizeof(buff), "}", "");
|
||||
|
||||
if(!GetTrieValue(CTrie, buff, value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(removeTags) {
|
||||
ReplaceString(output, maxlen, tag, "", false);
|
||||
} else {
|
||||
Format(buff, sizeof(buff), "\x07%06X", value);
|
||||
ReplaceString(output, maxlen, tag, buff, false);
|
||||
}
|
||||
}
|
||||
LogError("[MORE COLORS] Infinite loop broken.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a part of a string
|
||||
*
|
||||
* @param input String to get the part from
|
||||
* @param output Buffer to write to
|
||||
* @param maxlen Max length of output buffer
|
||||
* @param start Position to start at
|
||||
* @param numChars Number of characters to return, or 0 for the end of the string
|
||||
* @noreturn
|
||||
*/
|
||||
stock CSubString(const String:input[], String:output[], maxlen, start, numChars=0) {
|
||||
new i = 0;
|
||||
for(;;) {
|
||||
if(i == maxlen - 1 || i >= numChars || input[start + i] == '\0') {
|
||||
output[i] = '\0';
|
||||
return;
|
||||
}
|
||||
output[i] = input[start + i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to lowercase
|
||||
*
|
||||
* @param buffer String to convert
|
||||
* @noreturn
|
||||
*/
|
||||
stock CStrToLower(String:buffer[]) {
|
||||
new len = strlen(buffer);
|
||||
for(new i = 0; i < len; i++) {
|
||||
buffer[i] = CharToLower(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a color to the colors trie
|
||||
*
|
||||
* @param name Color name, without braces
|
||||
* @param color Hexadecimal representation of the color (0xRRGGBB)
|
||||
* @return True if color was added successfully, false if a color already exists with that name
|
||||
*/
|
||||
stock bool:CAddColor(const String:name[], color) {
|
||||
CCheckTrie();
|
||||
new value;
|
||||
if(GetTrieValue(CTrie, name, value)) {
|
||||
return false;
|
||||
}
|
||||
decl String:newName[64];
|
||||
strcopy(newName, sizeof(newName), name);
|
||||
CStrToLower(newName);
|
||||
SetTrieValue(CTrie, newName, color);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes color tags from a message
|
||||
*
|
||||
* @param message Message to remove tags from
|
||||
* @param maxlen Maximum buffer length
|
||||
* @noreturn
|
||||
*/
|
||||
stock CRemoveTags(String:message[], maxlen) {
|
||||
CReplaceColorCodes(message, 0, true, maxlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replies to a command with colors
|
||||
*
|
||||
* @param client Client to reply to
|
||||
* @param message Message (formatting rules)
|
||||
* @noreturn
|
||||
*/
|
||||
stock CReplyToCommand(client, const String:message[], any:...) {
|
||||
decl String:buffer[MAX_BUFFER_LENGTH];
|
||||
SetGlobalTransTarget(client);
|
||||
VFormat(buffer, sizeof(buffer), message, 3);
|
||||
if(GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
|
||||
CRemoveTags(buffer, sizeof(buffer));
|
||||
PrintToConsole(client, "%s", buffer);
|
||||
} else {
|
||||
CPrintToChat(client, "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replies to a command with colors
|
||||
*
|
||||
* @param client Client to reply to
|
||||
* @param author Client to use for {teamcolor}
|
||||
* @param message Message (formatting rules)
|
||||
* @noreturn
|
||||
*/
|
||||
stock CReplyToCommandEx(client, author, const String:message[], any:...) {
|
||||
decl String:buffer[MAX_BUFFER_LENGTH];
|
||||
SetGlobalTransTarget(client);
|
||||
VFormat(buffer, sizeof(buffer), message, 4);
|
||||
if(GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
|
||||
CRemoveTags(buffer, sizeof(buffer));
|
||||
PrintToConsole(client, "%s", buffer);
|
||||
} else {
|
||||
CPrintToChatEx(client, author, "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows admin activity with colors
|
||||
*
|
||||
* @param client Client performing an action
|
||||
* @param message Message (formatting rules)
|
||||
* @noreturn
|
||||
*/
|
||||
stock CShowActivity(client, const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
if(client < 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %d", client);
|
||||
}
|
||||
if(client != 0 && !IsClientInGame(client)) {
|
||||
ThrowError("Client %d is not in game", client);
|
||||
}
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 3);
|
||||
CReplaceColorCodes(buffer2);
|
||||
ShowActivity(client, "%s", buffer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows admin activity with colors
|
||||
*
|
||||
* @param client Client performing an action
|
||||
* @param tag Tag to prepend to the message (color tags supported)
|
||||
* @param message Message (formatting rules)
|
||||
* @noreturn
|
||||
*/
|
||||
stock CShowActivityEx(client, const String:tag[], const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
if(client < 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %d", client);
|
||||
}
|
||||
if(client != 0 && !IsClientInGame(client)) {
|
||||
ThrowError("Client %d is not in game", client);
|
||||
}
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 4);
|
||||
CReplaceColorCodes(buffer2);
|
||||
strcopy(buffer, sizeof(buffer), tag);
|
||||
CReplaceColorCodes(buffer);
|
||||
ShowActivityEx(client, tag, "%s", buffer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows admin activity with colors
|
||||
*
|
||||
* @param client Client performing an action
|
||||
* @param tag Tag to prepend to the message (color tags supported)
|
||||
* @param message Message (formatting rules)
|
||||
* @noreturn
|
||||
*/
|
||||
stock CShowActivity2(client, const String:tag[], const String:message[], any:...) {
|
||||
CCheckTrie();
|
||||
if(client < 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %d", client);
|
||||
}
|
||||
if(client != 0 && !IsClientInGame(client)) {
|
||||
ThrowError("Client %d is not in game", client);
|
||||
}
|
||||
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
|
||||
Format(buffer, sizeof(buffer), "\x01%s", message);
|
||||
VFormat(buffer2, sizeof(buffer2), buffer, 4);
|
||||
CReplaceColorCodes(buffer2);
|
||||
strcopy(buffer, sizeof(buffer), tag);
|
||||
CReplaceColorCodes(buffer);
|
||||
ShowActivity2(client, buffer, "%s", buffer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a color name exists
|
||||
*
|
||||
* @param color The color name to check
|
||||
* @return True if the color exists, false otherwise
|
||||
*/
|
||||
stock bool:CColorExists(const String:color[]) {
|
||||
CCheckTrie();
|
||||
new temp;
|
||||
return GetTrieValue(CTrie, color, temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hexadecimal representation of a client's team color (will NOT initialize the trie)
|
||||
*
|
||||
* @param client Client to get the team color for
|
||||
* @return Client's team color in hexadecimal, or green if unknown
|
||||
* On error/Errors: If the client index passed is invalid or not in game.
|
||||
*/
|
||||
stock CGetTeamColor(client) {
|
||||
if(client <= 0 || client > MaxClients) {
|
||||
ThrowError("Invalid client index %i", client);
|
||||
}
|
||||
if(!IsClientInGame(client)) {
|
||||
ThrowError("Client %i is not in game", client);
|
||||
}
|
||||
new value;
|
||||
switch(GetClientTeam(client)) {
|
||||
case 1: {
|
||||
value = COLOR_GRAY;
|
||||
}
|
||||
case 2: {
|
||||
value = COLOR_RED;
|
||||
}
|
||||
case 3: {
|
||||
value = COLOR_BLUE;
|
||||
}
|
||||
default: {
|
||||
value = COLOR_GREEN;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
stock Handle:InitColorTrie() {
|
||||
new Handle:hTrie = CreateTrie();
|
||||
SetTrieValue(hTrie, "aliceblue", 0xF0F8FF);
|
||||
SetTrieValue(hTrie, "allies", 0x4D7942); // same as Allies team in DoD:S
|
||||
SetTrieValue(hTrie, "ancient", 0xEB4B4B); // same as Ancient item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "antiquewhite", 0xFAEBD7);
|
||||
SetTrieValue(hTrie, "aqua", 0x00FFFF);
|
||||
SetTrieValue(hTrie, "aquamarine", 0x7FFFD4);
|
||||
SetTrieValue(hTrie, "arcana", 0xADE55C); // same as Arcana item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "axis", 0xFF4040); // same as Axis team in DoD:S
|
||||
SetTrieValue(hTrie, "azure", 0x007FFF);
|
||||
SetTrieValue(hTrie, "beige", 0xF5F5DC);
|
||||
SetTrieValue(hTrie, "bisque", 0xFFE4C4);
|
||||
SetTrieValue(hTrie, "black", 0x000000);
|
||||
SetTrieValue(hTrie, "blanchedalmond", 0xFFEBCD);
|
||||
SetTrieValue(hTrie, "blue", 0x99CCFF); // same as BLU/Counter-Terrorist team color
|
||||
SetTrieValue(hTrie, "blueviolet", 0x8A2BE2);
|
||||
SetTrieValue(hTrie, "brown", 0xA52A2A);
|
||||
SetTrieValue(hTrie, "burlywood", 0xDEB887);
|
||||
SetTrieValue(hTrie, "cadetblue", 0x5F9EA0);
|
||||
SetTrieValue(hTrie, "chartreuse", 0x7FFF00);
|
||||
SetTrieValue(hTrie, "chocolate", 0xD2691E);
|
||||
SetTrieValue(hTrie, "collectors", 0xAA0000); // same as Collector's item quality in TF2
|
||||
SetTrieValue(hTrie, "common", 0xB0C3D9); // same as Common item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "community", 0x70B04A); // same as Community item quality in TF2
|
||||
SetTrieValue(hTrie, "coral", 0xFF7F50);
|
||||
SetTrieValue(hTrie, "cornflowerblue", 0x6495ED);
|
||||
SetTrieValue(hTrie, "cornsilk", 0xFFF8DC);
|
||||
SetTrieValue(hTrie, "corrupted", 0xA32C2E); // same as Corrupted item quality in Dota 2
|
||||
SetTrieValue(hTrie, "crimson", 0xDC143C);
|
||||
SetTrieValue(hTrie, "cyan", 0x00FFFF);
|
||||
SetTrieValue(hTrie, "darkblue", 0x00008B);
|
||||
SetTrieValue(hTrie, "darkcyan", 0x008B8B);
|
||||
SetTrieValue(hTrie, "darkgoldenrod", 0xB8860B);
|
||||
SetTrieValue(hTrie, "darkgray", 0xA9A9A9);
|
||||
SetTrieValue(hTrie, "darkgrey", 0xA9A9A9);
|
||||
SetTrieValue(hTrie, "darkgreen", 0x006400);
|
||||
SetTrieValue(hTrie, "darkkhaki", 0xBDB76B);
|
||||
SetTrieValue(hTrie, "darkmagenta", 0x8B008B);
|
||||
SetTrieValue(hTrie, "darkolivegreen", 0x556B2F);
|
||||
SetTrieValue(hTrie, "darkorange", 0xFF8C00);
|
||||
SetTrieValue(hTrie, "darkorchid", 0x9932CC);
|
||||
SetTrieValue(hTrie, "darkred", 0x8B0000);
|
||||
SetTrieValue(hTrie, "darksalmon", 0xE9967A);
|
||||
SetTrieValue(hTrie, "darkseagreen", 0x8FBC8F);
|
||||
SetTrieValue(hTrie, "darkslateblue", 0x483D8B);
|
||||
SetTrieValue(hTrie, "darkslategray", 0x2F4F4F);
|
||||
SetTrieValue(hTrie, "darkslategrey", 0x2F4F4F);
|
||||
SetTrieValue(hTrie, "darkturquoise", 0x00CED1);
|
||||
SetTrieValue(hTrie, "darkviolet", 0x9400D3);
|
||||
SetTrieValue(hTrie, "deeppink", 0xFF1493);
|
||||
SetTrieValue(hTrie, "deepskyblue", 0x00BFFF);
|
||||
SetTrieValue(hTrie, "dimgray", 0x696969);
|
||||
SetTrieValue(hTrie, "dimgrey", 0x696969);
|
||||
SetTrieValue(hTrie, "dodgerblue", 0x1E90FF);
|
||||
SetTrieValue(hTrie, "exalted", 0xCCCCCD); // same as Exalted item quality in Dota 2
|
||||
SetTrieValue(hTrie, "firebrick", 0xB22222);
|
||||
SetTrieValue(hTrie, "floralwhite", 0xFFFAF0);
|
||||
SetTrieValue(hTrie, "forestgreen", 0x228B22);
|
||||
SetTrieValue(hTrie, "frozen", 0x4983B3); // same as Frozen item quality in Dota 2
|
||||
SetTrieValue(hTrie, "fuchsia", 0xFF00FF);
|
||||
SetTrieValue(hTrie, "fullblue", 0x0000FF);
|
||||
SetTrieValue(hTrie, "fullred", 0xFF0000);
|
||||
SetTrieValue(hTrie, "gainsboro", 0xDCDCDC);
|
||||
SetTrieValue(hTrie, "genuine", 0x4D7455); // same as Genuine item quality in TF2
|
||||
SetTrieValue(hTrie, "ghostwhite", 0xF8F8FF);
|
||||
SetTrieValue(hTrie, "gold", 0xFFD700);
|
||||
SetTrieValue(hTrie, "goldenrod", 0xDAA520);
|
||||
SetTrieValue(hTrie, "gray", 0xCCCCCC); // same as spectator team color
|
||||
SetTrieValue(hTrie, "grey", 0xCCCCCC);
|
||||
SetTrieValue(hTrie, "green", 0x3EFF3E);
|
||||
SetTrieValue(hTrie, "greenyellow", 0xADFF2F);
|
||||
SetTrieValue(hTrie, "haunted", 0x38F3AB); // same as Haunted item quality in TF2
|
||||
SetTrieValue(hTrie, "honeydew", 0xF0FFF0);
|
||||
SetTrieValue(hTrie, "hotpink", 0xFF69B4);
|
||||
SetTrieValue(hTrie, "immortal", 0xE4AE33); // same as Immortal item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "indianred", 0xCD5C5C);
|
||||
SetTrieValue(hTrie, "indigo", 0x4B0082);
|
||||
SetTrieValue(hTrie, "ivory", 0xFFFFF0);
|
||||
SetTrieValue(hTrie, "khaki", 0xF0E68C);
|
||||
SetTrieValue(hTrie, "lavender", 0xE6E6FA);
|
||||
SetTrieValue(hTrie, "lavenderblush", 0xFFF0F5);
|
||||
SetTrieValue(hTrie, "lawngreen", 0x7CFC00);
|
||||
SetTrieValue(hTrie, "legendary", 0xD32CE6); // same as Legendary item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "lemonchiffon", 0xFFFACD);
|
||||
SetTrieValue(hTrie, "lightblue", 0xADD8E6);
|
||||
SetTrieValue(hTrie, "lightcoral", 0xF08080);
|
||||
SetTrieValue(hTrie, "lightcyan", 0xE0FFFF);
|
||||
SetTrieValue(hTrie, "lightgoldenrodyellow", 0xFAFAD2);
|
||||
SetTrieValue(hTrie, "lightgray", 0xD3D3D3);
|
||||
SetTrieValue(hTrie, "lightgrey", 0xD3D3D3);
|
||||
SetTrieValue(hTrie, "lightgreen", 0x99FF99);
|
||||
SetTrieValue(hTrie, "lightpink", 0xFFB6C1);
|
||||
SetTrieValue(hTrie, "lightsalmon", 0xFFA07A);
|
||||
SetTrieValue(hTrie, "lightseagreen", 0x20B2AA);
|
||||
SetTrieValue(hTrie, "lightskyblue", 0x87CEFA);
|
||||
SetTrieValue(hTrie, "lightslategray", 0x778899);
|
||||
SetTrieValue(hTrie, "lightslategrey", 0x778899);
|
||||
SetTrieValue(hTrie, "lightsteelblue", 0xB0C4DE);
|
||||
SetTrieValue(hTrie, "lightyellow", 0xFFFFE0);
|
||||
SetTrieValue(hTrie, "lime", 0x00FF00);
|
||||
SetTrieValue(hTrie, "limegreen", 0x32CD32);
|
||||
SetTrieValue(hTrie, "linen", 0xFAF0E6);
|
||||
SetTrieValue(hTrie, "magenta", 0xFF00FF);
|
||||
SetTrieValue(hTrie, "maroon", 0x800000);
|
||||
SetTrieValue(hTrie, "mediumaquamarine", 0x66CDAA);
|
||||
SetTrieValue(hTrie, "mediumblue", 0x0000CD);
|
||||
SetTrieValue(hTrie, "mediumorchid", 0xBA55D3);
|
||||
SetTrieValue(hTrie, "mediumpurple", 0x9370D8);
|
||||
SetTrieValue(hTrie, "mediumseagreen", 0x3CB371);
|
||||
SetTrieValue(hTrie, "mediumslateblue", 0x7B68EE);
|
||||
SetTrieValue(hTrie, "mediumspringgreen", 0x00FA9A);
|
||||
SetTrieValue(hTrie, "mediumturquoise", 0x48D1CC);
|
||||
SetTrieValue(hTrie, "mediumvioletred", 0xC71585);
|
||||
SetTrieValue(hTrie, "midnightblue", 0x191970);
|
||||
SetTrieValue(hTrie, "mintcream", 0xF5FFFA);
|
||||
SetTrieValue(hTrie, "mistyrose", 0xFFE4E1);
|
||||
SetTrieValue(hTrie, "moccasin", 0xFFE4B5);
|
||||
SetTrieValue(hTrie, "mythical", 0x8847FF); // same as Mythical item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "navajowhite", 0xFFDEAD);
|
||||
SetTrieValue(hTrie, "navy", 0x000080);
|
||||
SetTrieValue(hTrie, "normal", 0xB2B2B2); // same as Normal item quality in TF2
|
||||
SetTrieValue(hTrie, "oldlace", 0xFDF5E6);
|
||||
SetTrieValue(hTrie, "olive", 0x9EC34F);
|
||||
SetTrieValue(hTrie, "olivedrab", 0x6B8E23);
|
||||
SetTrieValue(hTrie, "orange", 0xFFA500);
|
||||
SetTrieValue(hTrie, "orangered", 0xFF4500);
|
||||
SetTrieValue(hTrie, "orchid", 0xDA70D6);
|
||||
SetTrieValue(hTrie, "palegoldenrod", 0xEEE8AA);
|
||||
SetTrieValue(hTrie, "palegreen", 0x98FB98);
|
||||
SetTrieValue(hTrie, "paleturquoise", 0xAFEEEE);
|
||||
SetTrieValue(hTrie, "palevioletred", 0xD87093);
|
||||
SetTrieValue(hTrie, "papayawhip", 0xFFEFD5);
|
||||
SetTrieValue(hTrie, "peachpuff", 0xFFDAB9);
|
||||
SetTrieValue(hTrie, "peru", 0xCD853F);
|
||||
SetTrieValue(hTrie, "pink", 0xFFC0CB);
|
||||
SetTrieValue(hTrie, "plum", 0xDDA0DD);
|
||||
SetTrieValue(hTrie, "powderblue", 0xB0E0E6);
|
||||
SetTrieValue(hTrie, "purple", 0x800080);
|
||||
SetTrieValue(hTrie, "rare", 0x4B69FF); // same as Rare item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "red", 0xFF4040); // same as RED/Terrorist team color
|
||||
SetTrieValue(hTrie, "rosybrown", 0xBC8F8F);
|
||||
SetTrieValue(hTrie, "royalblue", 0x4169E1);
|
||||
SetTrieValue(hTrie, "saddlebrown", 0x8B4513);
|
||||
SetTrieValue(hTrie, "salmon", 0xFA8072);
|
||||
SetTrieValue(hTrie, "sandybrown", 0xF4A460);
|
||||
SetTrieValue(hTrie, "seagreen", 0x2E8B57);
|
||||
SetTrieValue(hTrie, "seashell", 0xFFF5EE);
|
||||
SetTrieValue(hTrie, "selfmade", 0x70B04A); // same as Self-Made item quality in TF2
|
||||
SetTrieValue(hTrie, "sienna", 0xA0522D);
|
||||
SetTrieValue(hTrie, "silver", 0xC0C0C0);
|
||||
SetTrieValue(hTrie, "skyblue", 0x87CEEB);
|
||||
SetTrieValue(hTrie, "slateblue", 0x6A5ACD);
|
||||
SetTrieValue(hTrie, "slategray", 0x708090);
|
||||
SetTrieValue(hTrie, "slategrey", 0x708090);
|
||||
SetTrieValue(hTrie, "snow", 0xFFFAFA);
|
||||
SetTrieValue(hTrie, "springgreen", 0x00FF7F);
|
||||
SetTrieValue(hTrie, "steelblue", 0x4682B4);
|
||||
SetTrieValue(hTrie, "strange", 0xCF6A32); // same as Strange item quality in TF2
|
||||
SetTrieValue(hTrie, "tan", 0xD2B48C);
|
||||
SetTrieValue(hTrie, "teal", 0x008080);
|
||||
SetTrieValue(hTrie, "thistle", 0xD8BFD8);
|
||||
SetTrieValue(hTrie, "tomato", 0xFF6347);
|
||||
SetTrieValue(hTrie, "turquoise", 0x40E0D0);
|
||||
SetTrieValue(hTrie, "uncommon", 0xB0C3D9); // same as Uncommon item rarity in Dota 2
|
||||
SetTrieValue(hTrie, "unique", 0xFFD700); // same as Unique item quality in TF2
|
||||
SetTrieValue(hTrie, "unusual", 0x8650AC); // same as Unusual item quality in TF2
|
||||
SetTrieValue(hTrie, "valve", 0xA50F79); // same as Valve item quality in TF2
|
||||
SetTrieValue(hTrie, "vintage", 0x476291); // same as Vintage item quality in TF2
|
||||
SetTrieValue(hTrie, "violet", 0xEE82EE);
|
||||
SetTrieValue(hTrie, "wheat", 0xF5DEB3);
|
||||
SetTrieValue(hTrie, "white", 0xFFFFFF);
|
||||
SetTrieValue(hTrie, "whitesmoke", 0xF5F5F5);
|
||||
SetTrieValue(hTrie, "yellow", 0xFFFF00);
|
||||
SetTrieValue(hTrie, "yellowgreen", 0x9ACD32);
|
||||
return hTrie;
|
||||
}
|
915
includes/nativevotes.inc
Normal file
915
includes/nativevotes.inc
Normal file
@ -0,0 +1,915 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* NativeVotes
|
||||
* Copyright (C) 2011-2013 Ross Bemrose (Powerlord). All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <menus>
|
||||
#include <sourcemod>
|
||||
|
||||
// NativeVotes 0.8 series
|
||||
|
||||
#if defined _nativevotes_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _nativevotes_included
|
||||
|
||||
#define CLIENT_DISCONNECTED -1
|
||||
|
||||
#define NATIVEVOTES_EXTEND "Extend current Map" /** Defined in TF2, but doesn't appear to be localized */
|
||||
|
||||
#define NATIVEVOTES_ALL_TEAMS -1 // Defined by TF2, may be the same in L4D/L4D2
|
||||
#define NATIVEVOTES_TF2_ALL_TEAMS 0 // Defined by TF2, may be the same in L4D/L4D2
|
||||
#define NATIVEVOTES_TEAM_UNASSIGNED 0 // For completeness, do not otherwise use
|
||||
#define NATIVEVOTES_TEAM_SPECTATOR 1 // Spectators
|
||||
#define NATIVEVOTES_TEAM_1 2 // RED/Survivors/Terrorists
|
||||
#define NATIVEVOTES_TEAM_2 3 // BLU/Infected/Counter-Terrorists
|
||||
|
||||
#define NATIVEVOTES_SERVER_INDEX 99 // Defined by TF2, may be the same in L4D/L4D2
|
||||
|
||||
// These may seem backwards, but this is the order that the votes appear in the vote screen
|
||||
#define NATIVEVOTES_VOTE_INVALID -1 /**< Vote was invalid, currently only valid internally */
|
||||
#define NATIVEVOTES_VOTE_YES 0 /**< Vote was yes */
|
||||
#define NATIVEVOTES_VOTE_NO 1 /**< Vote was no */
|
||||
|
||||
/*
|
||||
The following MenuActions are supported. Arguments are also listed, as they differ slightly from the default
|
||||
MenuAction_Start A menu has been started (nothing passed). Only exists for compat reasons.
|
||||
MenuAction_Display A menu is about to be displayed (param1=client). If you choose to change the vote text,
|
||||
To change the text, use RedrawVoteTitle()
|
||||
If you do so, return 1 or _:Plugin_Changed Otherwise, return _:Plugin_Continue or 0.
|
||||
MenuAction_Select An item was selected (param1=client, param2=item). For subplugin support.
|
||||
MenuAction_End A vote has fully ended and the vote object is ready to be cleaned up
|
||||
param1 is MenuEnd reason, either MenuEnd_VotingCancelled or MenuEnd_VotingDone
|
||||
MenuAction_VoteEnd A vote sequence has succeeded (param1=chosen item)
|
||||
This is not called if NativeVotes_SetResultCallback has been used on the vote.
|
||||
You should call NativeVotes_DisplayPass or NativeVotes_DisplayPassEx after this
|
||||
MenuAction_VoteStart A vote sequence has started (nothing passed). Use this instead of MenuAction_Start
|
||||
MenuAction_VoteCancel A vote sequence has been cancelled (param1=reason)
|
||||
MenuAction_DisplayItem Item text is being drawn to the display (param1=client, param2=item)
|
||||
To change the text, use RedrawVoteItem().
|
||||
If you do so, return 1 or _:Plugin_Changed. Otherwise, return _:Plugin_Continue or 0.
|
||||
*/
|
||||
|
||||
#define NATIVEVOTES_ACTIONS_DEFAULT MenuAction_VoteStart|MenuAction_VoteCancel|MenuAction_VoteEnd|MenuAction_End
|
||||
|
||||
/**
|
||||
* Vote types. These are mapped to translation strings and pass strings by VoteStart and VotePass handlers
|
||||
*/
|
||||
enum NativeVotesType
|
||||
{
|
||||
NativeVotesType_None = 0, /** Special placeholder for callvote with no arguments for NativeVotes_OnCallVote */
|
||||
NativeVotesType_Custom_YesNo, /**< Yes/No, details are vote text. */
|
||||
NativeVotesType_Custom_Mult, /**< TF2/CS:GO: Multiple-choice, details are vote text. */
|
||||
NativeVotesType_ChgCampaign, /**< L4D/L4D2: Yes/No, details are campaign name */
|
||||
NativeVotesType_ChgDifficulty, /**< L4D/L4D2: Yes/No, details are difficulty number in L4D/L4D2 */
|
||||
NativeVotesType_ReturnToLobby, /**< L4D/L4D2: Yes/No, details are ignored */
|
||||
NativeVotesType_AlltalkOn, /**< L4D2: Yes/No, details are ignored (handled internally by extension) */
|
||||
NativeVotesType_AlltalkOff, /**< L4D2: Yes/No, details are ignored (handled internally by extension) */
|
||||
NativeVotesType_Restart, /**< Yes/No, details are ignored */
|
||||
NativeVotesType_Kick, /**< Yes/No, target is player userid, details are auto-set by target */
|
||||
NativeVotesType_KickIdle, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
|
||||
NativeVotesType_KickScamming, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
|
||||
NativeVotesType_KickCheating, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
|
||||
NativeVotesType_ChgLevel, /**< Yes/No, details are level number in L4D/L4D2 or map name in TF2 */
|
||||
NativeVotesType_NextLevel, /**< TF2/CS:GO: Yes/No, details are map name */
|
||||
NativeVotesType_NextLevelMult, /**< TF2/CS:GO: Multiple-choice, details are ignored */
|
||||
NativeVotesType_ScrambleNow, /**< TF2/CS:GO: Yes/No, details are ignored */
|
||||
NativeVotesType_ScrambleEnd, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesType_ChgMission, /**< TF2: Yes/No, details are popfile */
|
||||
NativeVotesType_SwapTeams, /**< CS:GO: Yes/No, details are ignored */
|
||||
NativeVotesType_Surrender, /**< CS:GO: Yes/No, details are ignored */
|
||||
NativeVotesType_Rematch, /**< CS:GO: Yes/No, details are ignored */
|
||||
NativeVotesType_Continue, /**< CS:GO: Yes/No, details are ignored */
|
||||
NativeVotesType_StartRound, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesType_Eternaween, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesType_AutoBalanceOn, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesType_AutoBalanceOff, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesType_ClassLimitsOn, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesType_ClassLimitsOff, /**< TF2: Yes/No, details are ignored */
|
||||
};
|
||||
|
||||
enum NativeVotesPassType
|
||||
{
|
||||
NativeVotesPass_None = 0, /**< Special placeholder for error value */
|
||||
NativeVotesPass_Custom, /**< Details are custom pass message */
|
||||
NativeVotesPass_ChgCampaign, /**< L4D/L4D2: Details are campaign name */
|
||||
NativeVotesPass_ChgDifficulty, /**< L4D/L4D2/TF2: Details are difficulty number in L4D/L4D2 and mission name in TF2 */
|
||||
NativeVotesPass_ReturnToLobby, /**< L4D/L4D2: Details are ignored */
|
||||
NativeVotesPass_AlltalkOn, /**< L4D2: Details are ignored */
|
||||
NativeVotesPass_AlltalkOff, /**< L4D2: Details are ignored */
|
||||
NativeVotesPass_Restart, /**< Details are ignored */
|
||||
NativeVotesPass_Kick, /**< Details are player name */
|
||||
NativeVotesPass_ChgLevel, /**< Details are level number in L4D/L4D2 or map name in TF2/CS:GO */
|
||||
NativeVotesPass_NextLevel, /**< TF2/CS:GO: Details are map name */
|
||||
NativeVotesPass_Extend, /**< TF2/CS:GO: Details are ignored */
|
||||
NativeVotesPass_Scramble, /**< TF2/CS:GO: Details are ignored */
|
||||
NativeVotesPass_ChgMission, /**< TF2: Details are popfile */
|
||||
NativeVotesPass_SwapTeams, /**< CS:GO: Details are ignored */
|
||||
NativeVotesPass_Surrender, /**< CS:GO: Details are ignored */
|
||||
NativeVotesPass_Rematch, /**< CS:GO: Details are ignored */
|
||||
NativeVotesPass_Continue, /**< CS:GO: Details are ignored */
|
||||
NativeVotesPass_StartRound, /**< TF2: Details are ignored */
|
||||
NativeVotesPass_Eternaween, /**< TF2: Details are ignored */
|
||||
NativeVotesPass_AutoBalanceOn, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesPass_AutoBalanceOff, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesPass_ClassLimitsOn, /**< TF2: Yes/No, details are ignored */
|
||||
NativeVotesPass_ClassLimitsOff, /**< TF2: Yes/No, details are ignored */
|
||||
};
|
||||
|
||||
/**
|
||||
* Reasons a vote was canceled. Not used for L4D/L4D2, as they don't care
|
||||
*/
|
||||
enum NativeVotesFailType
|
||||
{
|
||||
NativeVotesFail_Generic = 0, /**< Vote was generically cancelled. */
|
||||
NativeVotesFail_Loses = 3, /**< No votes outnumbered Yes votes */
|
||||
NativeVotesFail_NotEnoughVotes = 4, /**< Vote did not receive enough votes. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Reasons a callvote command failed.
|
||||
* This is provided as a convenience to plugin authors as it's not strictly part of the vote system
|
||||
*/
|
||||
enum NativeVotesCallFailType
|
||||
{
|
||||
NativeVotesCallFail_Generic = 0, /**< Generic fail. */
|
||||
NativeVotesCallFail_Loading = 1, /**< L4D/L4D2: Players are still loading. */
|
||||
NativeVotesCallFail_Recent = 2, /**< TF2/CS:GO: You can't call another vote yet: Argument is seconds until you can call another vote. */
|
||||
NativeVotesCallFail_Disabled = 5, /**< TF2/CS:GO: Server has disabled that issue. */
|
||||
NativeVotesCallFail_MapNotFound = 6, /**< TF2/CS:GO: Server does not have that map. */
|
||||
NativeVotesCallFail_SpecifyMap = 7, /**< TF2/CS:GO: You must specify a map. */
|
||||
NativeVotesCallFail_Failed = 8, /**< TF2/CS:GO: This vote failed recently. */
|
||||
NativeVotesCallFail_WrongTeam = 9, /**< TF2/CS:GO: Team can't call this vote. */
|
||||
NativeVotesCallFail_Waiting = 10, /**< TF2/CS:GO: Vote can't be called during Waiting For Players. */
|
||||
NativeVotesCallFail_PlayerNotFound = 11, /**< TF2/CS:GO: Player to kick can't be found. Buggy in TF2. */
|
||||
NativeVotesCallFail_Unknown = 11,
|
||||
NativeVotesCallFail_CantKickAdmin = 12, /**< TF2/CS:GO: Can't kick server admin. */
|
||||
NativeVotesCallFail_ScramblePending = 13, /**< TF2/CS:GO: Team Scramble is pending.. */
|
||||
NativeVotesCallFail_Spectators = 14, /**< TF2/CS:GO: Spectators aren't allowed to call votes. */
|
||||
NativeVotesCallFail_LevelSet = 15, /**< TF2/CS:GO: Next level already set. */
|
||||
NativeVotesCallFail_MapNotValid = 16, /**< ???: Map is invalid. */
|
||||
NativeVotesCallFail_KickTime = 17, /**< ???: Cannot kick for time. */
|
||||
NativeVotesCallFail_KickDuringRound = 18, /**< ???: Cannot kick during a round. */
|
||||
NativeVotesCallFail_AlreadyActive = 19 /**< TF2: Cannot call vote because modification (Eternaween) is already active (may not work) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Is a specific vote type supported by this game?
|
||||
*
|
||||
* @param voteType Vote type
|
||||
*/
|
||||
native bool:NativeVotes_IsVoteTypeSupported(NativeVotesType:voteType);
|
||||
|
||||
/**
|
||||
* Creates a new, empty vote.
|
||||
*
|
||||
* @param handler Function which will receive vote actions.
|
||||
* @param voteType Vote type, cannot be changed after set
|
||||
* @param actions Optionally set which actions to receive. Start,
|
||||
* Cancel, and End will always be received regardless
|
||||
* of whether they are set or not. They are also
|
||||
* the only default actions.
|
||||
* @return A new vote Handle on INVALID_HANDLE if a vote type is unsupported by this game.
|
||||
*/
|
||||
native Handle:NativeVotes_Create(MenuHandler:handler, NativeVotesType:voteType,
|
||||
MenuAction:actions=NATIVEVOTES_ACTIONS_DEFAULT);
|
||||
|
||||
/**
|
||||
* Frees all handles related to a vote.
|
||||
*
|
||||
* THIS MUST BE CALLED TO AVOID HANDLE LEAKS
|
||||
*
|
||||
* @param vote Vote handle
|
||||
* @noreturn
|
||||
*/
|
||||
native Handle:NativeVotes_Close(Handle:vote);
|
||||
|
||||
/**
|
||||
* Appends a new item to the end of a vote. Only valid for Multiple Choice votes
|
||||
*
|
||||
* @param vote NativeVotes Handle.
|
||||
* @param info Item information string.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle, item limit reached, or if the vote is not multiple choice.
|
||||
*/
|
||||
native bool:NativeVotes_AddItem(Handle:vote, const String:info[], const String:display[]);
|
||||
|
||||
/**
|
||||
* Inserts an item into the menu before a certain position; the new item will
|
||||
* be at the given position and all next items pushed forward.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param position Position, starting from 0.
|
||||
* @param info Item information string.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
|
||||
*/
|
||||
native bool:NativeVotes_InsertItem(Handle:vote, position, const String:info[], const String:display[]);
|
||||
|
||||
/**
|
||||
* Removes an item from the menu.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param position Position, starting from 0.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
|
||||
*/
|
||||
native bool:NativeVotes_RemoveItem(Handle:vote, position);
|
||||
|
||||
/**
|
||||
* Removes all items from a vote.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
|
||||
*/
|
||||
native NativeVotes_RemoveAllItems(Handle:vote);
|
||||
|
||||
/**
|
||||
* Retrieves information about a vote item.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param position Position, starting from 0.
|
||||
* @param infoBuf Info buffer.
|
||||
* @param infoBufLen Maximum length of the info buffer.
|
||||
* @return True on success, false if position is invalid.
|
||||
* @error Invalid Handlem
|
||||
*/
|
||||
native bool:NativeVotes_GetItem(Handle:vote,
|
||||
position,
|
||||
String:infoBuf[],
|
||||
infoBufLen,
|
||||
String:dispBuf[]="",
|
||||
dispBufLen=0);
|
||||
|
||||
/**
|
||||
* Returns the number of items in a vote.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @return Number of items in the vote.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_GetItemCount(Handle:vote);
|
||||
|
||||
/**
|
||||
* Sets the vote's details for votes that support details
|
||||
* If this is a custom vote, use NativeVotes_SetTitle to set the vote's title.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param argument Details string. See vote types for what details stands for.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_SetDetails(Handle:vote, const String:argument[]);
|
||||
|
||||
/**
|
||||
* Returns the text of a vote's details if set.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param buffer Buffer to store details.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_GetDetails(Handle:vote, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets a custom vote's title
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param title Vote title string.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_SetTitle(Handle:vote, const String:argument[]);
|
||||
|
||||
/**
|
||||
* Return the vote's Title.
|
||||
* If not set, returns Details instead.
|
||||
* This behavior is for compatibility with NativeVotes 0.8.0 and below.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param buffer Buffer to store title.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_GetTitle(Handle:vote, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets the target userid for vote
|
||||
* This should be used instead of SetArgument for votes that target players
|
||||
*
|
||||
* Also sets target SteamID
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param userid Client index of target player
|
||||
* @param setDetails If true, also sets vote details to client's name
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_SetTarget(Handle:vote, client, bool:setDetails=true);
|
||||
|
||||
/**
|
||||
* Returns the userid of a vote's target
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @return Client index of target player or 0 for no target or target disconnected since vote started
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_GetTarget(Handle:vote);
|
||||
|
||||
/**
|
||||
* Get the Steam ID of a vote's target
|
||||
* Useful if the target has disconnect from the server during a vote.
|
||||
* This was added in specifically for Kick/Ban votes
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param buffer Buffer to store steamId. Should be 19 characters or more..
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_GetTargetSteam(Handle:vote, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Returns whether a vote is in progress.
|
||||
*
|
||||
* @return True if a NativeVotes vote is in progress, false otherwise.
|
||||
*/
|
||||
native bool:NativeVotes_IsVoteInProgress();
|
||||
|
||||
/**
|
||||
* Returns a style's maximum items
|
||||
*
|
||||
* @return Maximum items
|
||||
*/
|
||||
native NativeVotes_GetMaxItems();
|
||||
|
||||
/**
|
||||
* Sets a vote's option flags.
|
||||
*
|
||||
* If a certain bit is not supported, it will be stripped before being set.
|
||||
*
|
||||
* NOTE: This is currently unused, but reserved for future use.
|
||||
*
|
||||
* @param menu Builtin Vote Handle.
|
||||
* @param flags A new bitstring of VOTEFLAG bits.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_SetOptionFlags(Handle:vote, flags);
|
||||
|
||||
/**
|
||||
* Retrieves a menu's option flags.
|
||||
*
|
||||
* NOTE: This is currently unused, but reserved for future use.
|
||||
*
|
||||
* @param vote Builtin Vote Handle.
|
||||
* @return A bitstring of VOTEFLAG bits.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native NativeVotes_GetOptionFlags(Handle:vote);
|
||||
|
||||
/**
|
||||
* Cancels the vote in progress.
|
||||
*
|
||||
* @noreturn
|
||||
* @error If no vote is in progress.
|
||||
*/
|
||||
native NativeVotes_Cancel();
|
||||
|
||||
/**
|
||||
* Callback for when a vote has ended and results are available.
|
||||
*
|
||||
* Due to SourceMod Forward limitations in plugins, multi-dimension arrays can't be passed
|
||||
* to forwards. This means we have to split the client_info and item_info arrays into
|
||||
* their components.
|
||||
*
|
||||
* @param vote The vote being voted on.
|
||||
* @param num_votes Number of votes tallied in total.
|
||||
* @param num_clients Number of clients who could vote.
|
||||
* @param client_indexes Array of client indexes. Parallel with client_votes.
|
||||
* @param client_votes Array of client votes. Parallel with client_indexes.
|
||||
* @param num_items Number of unique items that were selected.
|
||||
* @param item_indexes Array of vote item indexes. Parallel with item_votes..
|
||||
* @param item_votes Array of vote vote counts. Parallel with item_indexes.
|
||||
* @noreturn
|
||||
*/
|
||||
functag public NativeVotes_VoteHandler(Handle:vote,
|
||||
num_votes,
|
||||
num_clients,
|
||||
const client_indexes[],
|
||||
const client_votes[],
|
||||
num_items,
|
||||
const item_indexes[],
|
||||
const item_votes[]);
|
||||
/**
|
||||
* Function to convert client/vote arrays into their two-dimensional versions,
|
||||
* which can then be passed to a standard vote handler.
|
||||
*
|
||||
* client_info and item_info are the resulting arrays.
|
||||
*
|
||||
* Note: When declaring client_info and item_info, you'll probably want to declare them like this:
|
||||
* new client_info[num_clients][2];
|
||||
* new item_info[num_items][2];
|
||||
*
|
||||
* @param num_clients Number of clients who could vote.
|
||||
* @param client_indexes Array of client indexes. Parallel with client_votes.
|
||||
* @param client_votes Array of client votes. Parallel with client_indexes.
|
||||
* @param num_items Number of unique items that were selected.
|
||||
* @param item_indexes Array of vote item indexes. Parallel with item_votes..
|
||||
* @param item_votes Array of vote vote counts. Parallel with item_indexes.
|
||||
* @param client_info Array of clients. Use VOTEINFO_CLIENT_ defines.
|
||||
* @param item_info Array of items, sorted by count. Use VOTEINFO_ITEM
|
||||
* defines.
|
||||
* @noreturn
|
||||
*/
|
||||
stock NativeVotes_FixResults(num_clients,
|
||||
const client_indexes[],
|
||||
const client_votes[],
|
||||
num_items,
|
||||
const item_indexes[],
|
||||
const item_votes[],
|
||||
client_info[][2],
|
||||
item_info[][2])
|
||||
{
|
||||
for (new i = 0; i < num_clients; ++i)
|
||||
{
|
||||
client_info[i][VOTEINFO_CLIENT_INDEX] = client_indexes[i];
|
||||
client_info[i][VOTEINFO_CLIENT_ITEM] = client_votes[i];
|
||||
}
|
||||
|
||||
for (new i = 0; i < num_items; ++i)
|
||||
{
|
||||
item_info[i][VOTEINFO_ITEM_INDEX] = item_indexes[i];
|
||||
item_info[i][VOTEINFO_ITEM_VOTES] = item_votes[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an advanced vote handling callback. If this callback is set,
|
||||
* MenuAction_VoteEnd will not be called.
|
||||
*
|
||||
* @param vote NativeVotes Handle.
|
||||
* @param callback Callback function.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or callback.
|
||||
*/
|
||||
native NativeVotes_SetResultCallback(Handle:vote, NativeVotes_VoteHandler:callback);
|
||||
|
||||
/**
|
||||
* Returns the number of seconds you should "wait" before displaying
|
||||
* a public vote. This number is the time remaining until
|
||||
* (last_vote + sm_vote_delay).
|
||||
*
|
||||
* @return Number of seconds to wait, or 0 for none.
|
||||
*/
|
||||
native NativeVotes_CheckVoteDelay();
|
||||
|
||||
/**
|
||||
* Returns whether a client is in the pool of clients allowed
|
||||
* to participate in the current vote. This is determined by
|
||||
* the client list passed to NativeVotes_Display().
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return True if client is allowed to vote, false otherwise.
|
||||
* @error If no vote is in progress or client index is invalid.
|
||||
*/
|
||||
native bool:NativeVotes_IsClientInVotePool(client);
|
||||
|
||||
/**
|
||||
* Redraws the current vote to a client in the voting pool.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param revotes True to allow revotes, false otherwise.
|
||||
* @return True on success, false if the client is in the vote pool
|
||||
* but cannot vote again.
|
||||
* @error No vote in progress, client is not in the voting pool,
|
||||
* or client index is invalid.
|
||||
*/
|
||||
native bool:NativeVotes_RedrawClientVote(client, bool:revotes=true);
|
||||
|
||||
/**
|
||||
* Retrieve the vote type
|
||||
*
|
||||
* @param vote NativeVotes Handle.
|
||||
* @return The built in vote type
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native NativeVotesType:NativeVotes_GetType(Handle:vote);
|
||||
|
||||
/**
|
||||
* Set the team this vote is for, or NATIVEVOTES_ALL_TEAMS for all teams.
|
||||
*
|
||||
* Defaults to NATIVEVOTES_ALL_TEAMS if not explicitly set.
|
||||
*
|
||||
* @param vote NativeVotes Handle.
|
||||
* @param team Team number this vote is for
|
||||
* @noreturn
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native NativeVotes_SetTeam(Handle:vote, team);
|
||||
|
||||
/**
|
||||
* Retrieve the team this vote is for
|
||||
*
|
||||
* @param vote NativeVotes Handle.
|
||||
* @return Team index or NATIVEVOTES_ALL_TEAMS for all teams.
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native NativeVotes_GetTeam(Handle:vote);
|
||||
|
||||
/**
|
||||
* Set the client index of the player who initiated the vote.
|
||||
* Use NATIVEVOTES_SERVER_INDEX if initiated by the server itself.
|
||||
*
|
||||
* Defaults to NATIVEVOTES_SERVER_INDEX if not explicitly set.
|
||||
*
|
||||
* @param vote NativeVotes Handle.
|
||||
* @param client Client who initiated the vote or NATIVEVOTES_SERVER_INDEX
|
||||
* @noreturn
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native NativeVotes_SetInitiator(Handle:vote, client);
|
||||
|
||||
/**
|
||||
* Retrieve the client index of the player who initiated the vote or NATIVEVOTES_SERVER_INDEX if
|
||||
* initiated by the server itself.
|
||||
*
|
||||
* @param Vote handle
|
||||
* @return Client index or NATIVEVOTES_SERVER_INDEX
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native NativeVotes_GetInitiator(Handle:vote);
|
||||
|
||||
/**
|
||||
* Broadcasts a vote to a list of clients. The most selected item will be
|
||||
* returned through MenuAction_VoteEnd. On a tie, a random item will be returned
|
||||
* from a list of the tied items.
|
||||
*
|
||||
* Note that MenuAction_VoteStart, MenuAction_VoteCancel, MenuAction_VoteEnd, and MenuAction_End are all
|
||||
* default callbacks and do not need to be enabled.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param clients Array of clients to broadcast to.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false if a vote is already in progress.
|
||||
* @error Invalid Handle, or a vote is already in progress.
|
||||
*/
|
||||
native bool:NativeVotes_Display(Handle:vote, clients[], numClients, time);
|
||||
|
||||
/**
|
||||
* Sends a vote menu to all clients. See NativeVotes_Display() for more information.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false if this menu already has a vote session
|
||||
* in progress.
|
||||
* @error Invalid Handle, or a vote is already in progress.
|
||||
*/
|
||||
stock bool:NativeVotes_DisplayToAll(Handle:vote, time)
|
||||
{
|
||||
new total = 0;
|
||||
decl players[MaxClients];
|
||||
|
||||
for (new i=1; i<=MaxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || IsFakeClient(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
players[total++] = i;
|
||||
}
|
||||
|
||||
return NativeVotes_Display(vote, players, total, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a vote menu to a single team. See NativeVotes_Display() for more information.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param team Team to send vote to. 1 = spectators, 2 = RED/Survivors/Terrorists, 3 = BLU/Infected/Counter-Terrorists
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false if this menu already has a vote session
|
||||
* in progress.
|
||||
* @error Invalid Handle, or a vote is already in progress.
|
||||
*/
|
||||
stock bool:NativeVotes_DisplayToTeam(Handle:vote, team, time)
|
||||
{
|
||||
NativeVotes_SetTeam(vote, team);
|
||||
|
||||
new total;
|
||||
decl players[MaxClients];
|
||||
|
||||
for (new i=1; i<=MaxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) != team))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
players[total++] = i;
|
||||
}
|
||||
|
||||
return NativeVotes_Display(vote, players, total, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a vote menu to all clients who are not spectators or waiting to choose a team. See NativeVotes_Display() for more information.
|
||||
*
|
||||
* @param vote Vote Handle.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false if this menu already has a vote session
|
||||
* in progress.
|
||||
* @error Invalid Handle, or a vote is already in progress.
|
||||
*/
|
||||
stock bool:NativeVotes_DisplayToAllNonSpectators(Handle:vote, time)
|
||||
{
|
||||
new total;
|
||||
decl players[MaxClients];
|
||||
|
||||
for (new i=1; i<=MaxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) < 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
players[total++] = i;
|
||||
}
|
||||
|
||||
return NativeVotes_Display(vote, players, total, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display vote passed screen
|
||||
*
|
||||
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
|
||||
* to hide the vote screen for users who didn't vote, and to clear out their selection
|
||||
* for the next vote.
|
||||
*
|
||||
* @param vote Vote handle
|
||||
* @param details Normally the item that won the vote or format string. Also used for custom vote winners
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
native NativeVotes_DisplayPass(Handle:vote, const String:details[]="");
|
||||
|
||||
/**
|
||||
* Display vote passed screen with custom text to a single user
|
||||
*
|
||||
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
|
||||
* to hide the vote screen for users who didn't vote, and to clear out their selection
|
||||
* for the next vote.
|
||||
*
|
||||
* @param vote Vote handle
|
||||
* @param client client to display to
|
||||
* @param format A format string.
|
||||
* @param any Variable number of format parameters
|
||||
* @noreturn
|
||||
*/
|
||||
native NativeVotes_DisplayPassCustomToOne(Handle:vote, client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Display vote passed screen with custom text
|
||||
*
|
||||
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
|
||||
* to hide the vote screen for users who didn't vote, and to clear out their selection
|
||||
* for the next vote.
|
||||
*
|
||||
* @param vote Vote handle
|
||||
* @param format A format string.
|
||||
* @param any Variable number of format parameters
|
||||
* @noreturn
|
||||
*/
|
||||
stock NativeVotes_DisplayPassCustom(Handle:vote, const String:format[], any:...)
|
||||
{
|
||||
decl String:buffer[192];
|
||||
|
||||
for (new i = 1; i <= MaxClients; ++i)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
SetGlobalTransTarget(i);
|
||||
VFormat(buffer, sizeof(buffer), format, 3);
|
||||
NativeVotes_DisplayPassCustomToOne(vote, i, "%s", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display vote passed screen with a custom type.
|
||||
*
|
||||
* A sample usage of this would be if Extend won an RTV vote: NativeVotes_DisplayPassEx(vote, NativeVotesPass_Extend, map);
|
||||
*
|
||||
* You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx,
|
||||
* or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote
|
||||
* and to clear out their selection for the next vote.
|
||||
*
|
||||
* #param vote Vote handle
|
||||
* @param passType The pass screen to display
|
||||
* @param details Normally the item that won the vote. Also used for custom vote winners
|
||||
* @noreturn
|
||||
*/
|
||||
native NativeVotes_DisplayPassEx(Handle:vote, NativeVotesPassType:passType, const String:details[]="");
|
||||
|
||||
/**
|
||||
* Display failure screen.
|
||||
*
|
||||
* You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx,
|
||||
* or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote,
|
||||
* and to clear out their selection for the next vote.
|
||||
*
|
||||
* @param reason Vote failure reason from NativeVotesFailType enum
|
||||
* @noreturn
|
||||
*/
|
||||
native NativeVotes_DisplayFail(Handle:vote, NativeVotesFailType:reason=NativeVotesFail_Generic);
|
||||
|
||||
/**
|
||||
* Quick stock to determine whether voting is allowed. This doesn't let you
|
||||
* fine-tune a reason for not voting, so it's not recommended for lazily
|
||||
* telling clients that voting isn't allowed.
|
||||
*
|
||||
* @return True if voting is allowed, false if voting is in progress
|
||||
* or the cooldown is active.
|
||||
*/
|
||||
stock bool:NativeVotes_IsNewVoteAllowed()
|
||||
{
|
||||
if (NativeVotes_IsVoteInProgress() || NativeVotes_CheckVoteDelay() != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when callvote is called with no arguments.
|
||||
*
|
||||
* This is used to configure the VoteSetup usermessage on TF2 and CS:GO
|
||||
*
|
||||
* @param client Client, in case the votes are restricted by client
|
||||
* @param voteTypes Populate this array with the vote types this server supports
|
||||
* Custom and multiple choice votes are not supported from
|
||||
* the GUI and are thus ignored.
|
||||
* @return Plugin_Continue to allow the server itself (or another plugin) to process the callvote
|
||||
* Plugin_Changed if you're changing the voteTypes,
|
||||
* Plugin_Handled to return a blank VoteSetup usermessage
|
||||
* Plugin_Stop to prevent VoteSetup usermessage (not recommended)
|
||||
*/
|
||||
//functag public Action:NativeVotes_CallVoteSetupHandler(client, NativeVotesType:voteTypes[]);
|
||||
|
||||
/**
|
||||
* Forward for "callvote" handling
|
||||
*
|
||||
* You should respond to this by starting a vote or by calling NativeVotes_DisplayCallVoteFail
|
||||
*
|
||||
* @param client Client
|
||||
* @param voteType Type of vote being called. This will NEVER be a multiple-choice or custom vote.
|
||||
* @param voteArgument Vote argument or blank if the vote type has no argument.
|
||||
* @param target target userid for kick votes or 0 for all other votes
|
||||
* @return Plugin_Continue to allow the server itself (or another plugin) to process the callvote
|
||||
* Plugin_Handled if you processed this vote type
|
||||
* Plugin_Stop to block the vote type (not recommended)
|
||||
*/
|
||||
//functag public Action:NativeVotes_CallVoteHandler(client, NativeVotesType:voteType, const String:voteArgument[], target);
|
||||
|
||||
/**
|
||||
* Register a plugin as a vote manager.
|
||||
* This is used to abstract away the details of the callvote command.
|
||||
*
|
||||
* @param callHandler Handler for callvote commands.
|
||||
* @param setupHandler Handler to override the which vote types your server supports. Only useful on TF2 and CS:GO.
|
||||
* @noreturn
|
||||
*/
|
||||
//native NativeVotes_RegisterVoteManager(NativeVotes_CallVoteHandler:callHandler, NativeVotes_CallVoteSetupHandler:setupHandler=INVALID_FUNCTION);
|
||||
|
||||
/**
|
||||
* Send a call vote fail screen to a user
|
||||
* Used to respond to a callvote with invalid arguments or for other reasons
|
||||
* (such as trying to target an admin for a kick/ban vote)
|
||||
*
|
||||
* @param client The client to display the fail screen to
|
||||
* @param reason A vote call fail reason
|
||||
* @param time For NativeVotesCallFail_Recent, the number of seconds until the vote
|
||||
* can be called again
|
||||
*/
|
||||
native NativeVotes_DisplayCallVoteFail(client, NativeVotesCallFailType:reason, time);
|
||||
|
||||
/**
|
||||
* Redraws the vote title from inside a MenuAction_Display callback
|
||||
* Not supported on L4D
|
||||
*
|
||||
* @param text Vote title to draw
|
||||
* @error If called from outside MenuAction_Display
|
||||
* @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't.
|
||||
*/
|
||||
native Action:NativeVotes_RedrawVoteTitle(const String:text[]);
|
||||
|
||||
/**
|
||||
* Redraws the vote text from inside a MenuAction_DisplayItem callback.
|
||||
* Only supported on multiple-choice votes
|
||||
*
|
||||
* @param text Vote text to draw.
|
||||
* @error If called from outside MenuAction_DisplayItem
|
||||
* @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't.
|
||||
*/
|
||||
native Action:NativeVotes_RedrawVoteItem(const String:text[]);
|
||||
|
||||
/**
|
||||
* Retrieves voting information from MenuAction_VoteEnd.
|
||||
*
|
||||
* @param param2 Second parameter of MenuAction_VoteEnd.
|
||||
* @param winningVotes Number of votes received by the winning option.
|
||||
* @param totalVotes Number of total votes received.
|
||||
* @noreturn
|
||||
*/
|
||||
stock NativeVotes_GetInfo(param2, &winningVotes, &totalVotes)
|
||||
{
|
||||
winningVotes = param2 & 0xFFFF;
|
||||
totalVotes = param2 >> 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public SharedPlugin:__pl_nativevotes =
|
||||
{
|
||||
name = "nativevotes",
|
||||
file = "nativevotes.smx",
|
||||
#if defined REQUIRE_PLUGINS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
public __pl_nativevotes_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("NativeVotes_IsVoteTypeSupported");
|
||||
MarkNativeAsOptional("NativeVotes_Create");
|
||||
MarkNativeAsOptional("NativeVotes_Close");
|
||||
MarkNativeAsOptional("NativeVotes_AddItem");
|
||||
MarkNativeAsOptional("NativeVotes_InsertItem");
|
||||
MarkNativeAsOptional("NativeVotes_RemoveItem");
|
||||
MarkNativeAsOptional("NativeVotes_RemoveAllItems");
|
||||
MarkNativeAsOptional("NativeVotes_GetItem");
|
||||
MarkNativeAsOptional("NativeVotes_GetItemCount");
|
||||
MarkNativeAsOptional("NativeVotes_SetDetails");
|
||||
MarkNativeAsOptional("NativeVotes_GetDetails");
|
||||
MarkNativeAsOptional("NativeVotes_SetTitle");
|
||||
MarkNativeAsOptional("NativeVotes_GetTitle");
|
||||
MarkNativeAsOptional("NativeVotes_SetTarget");
|
||||
MarkNativeAsOptional("NativeVotes_GetTarget");
|
||||
MarkNativeAsOptional("NativeVotes_GetTargetSteam");
|
||||
MarkNativeAsOptional("NativeVotes_IsVoteInProgress");
|
||||
MarkNativeAsOptional("NativeVotes_GetMaxItems");
|
||||
MarkNativeAsOptional("NativeVotes_SetOptionFlags");
|
||||
MarkNativeAsOptional("NativeVotes_GetOptionFlags");
|
||||
MarkNativeAsOptional("NativeVotes_Cancel");
|
||||
MarkNativeAsOptional("NativeVotes_SetResultCallback");
|
||||
MarkNativeAsOptional("NativeVotes_CheckVoteDelay");
|
||||
MarkNativeAsOptional("NativeVotes_IsClientInVotePool");
|
||||
MarkNativeAsOptional("NativeVotes_RedrawClientVote");
|
||||
MarkNativeAsOptional("NativeVotes_RedrawClientVote");
|
||||
MarkNativeAsOptional("NativeVotes_GetType");
|
||||
MarkNativeAsOptional("NativeVotes_SetTeam");
|
||||
MarkNativeAsOptional("NativeVotes_GetTeam");
|
||||
MarkNativeAsOptional("NativeVotes_SetInitiator");
|
||||
MarkNativeAsOptional("NativeVotes_GetInitiator");
|
||||
MarkNativeAsOptional("NativeVotes_Display");
|
||||
MarkNativeAsOptional("NativeVotes_DisplayPass");
|
||||
MarkNativeAsOptional("NativeVotes_DisplayPassCustomToOne");
|
||||
MarkNativeAsOptional("NativeVotes_DisplayPassEx");
|
||||
MarkNativeAsOptional("NativeVotes_DisplayFail");
|
||||
MarkNativeAsOptional("NativeVotes_RegisterVoteManager");
|
||||
MarkNativeAsOptional("NativeVotes_DisplayCallVoteFail");
|
||||
MarkNativeAsOptional("NativeVotes_RedrawVoteTitle");
|
||||
MarkNativeAsOptional("NativeVotes_RedrawVoteItem");
|
||||
}
|
40
includes/outputinfo.inc
Normal file
40
includes/outputinfo.inc
Normal file
@ -0,0 +1,40 @@
|
||||
#if defined _OutputInfo_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _OutputInfo_Included
|
||||
|
||||
native GetOutputCount(int Entity, const char[] sOutput);
|
||||
native GetOutputTarget(int Entity, const char[] sOutput, int Index, char[] sTarget);
|
||||
native GetOutputTargetInput(int Entity, const char[] sOutput, int Index, char[] sTargetInput);
|
||||
native GetOutputParameter(int Entity, const char[] sOutput, int Index, char[] sParameter);
|
||||
native Float:GetOutputDelay(int Entity, const char[] sOutput, int Index);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension __ext_outputinfo =
|
||||
{
|
||||
name = "OutputInfo",
|
||||
file = "outputinfo.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_outputinfo_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("GetOutputCount");
|
||||
MarkNativeAsOptional("GetOutputTarget");
|
||||
MarkNativeAsOptional("GetOutputTargetInput");
|
||||
MarkNativeAsOptional("GetOutputParameter");
|
||||
MarkNativeAsOptional("GetOutputDelay");
|
||||
}
|
||||
#endif
|
36
includes/zombiereloaded.inc
Normal file
36
includes/zombiereloaded.inc
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: zombiereloaded.inc
|
||||
* Type: Include
|
||||
* Description: Main API include file.
|
||||
* Notes: Include this file to include the whole ZR API.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
#if defined _zr_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _zr_included
|
||||
|
||||
#include <zr/infect.zr>
|
||||
#include <zr/respawn.zr>
|
||||
#include <zr/class.zr>
|
127
includes/zr/class.zr.inc
Normal file
127
includes/zr/class.zr.inc
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: class.zr.inc
|
||||
* Type: Include
|
||||
* Description: Player class API.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section Internal class cache types. Specifies which class data to access.
|
||||
*/
|
||||
#define ZR_CLASS_CACHE_ORIGINAL 0 /** Original class data loaded from file. */
|
||||
#define ZR_CLASS_CACHE_MODIFIED 1 /** Default cache. Class data modified by eventual multipliers, map configs, commands, etc. */
|
||||
#define ZR_CLASS_CACHE_PLAYER 2 /** Current player class attributes. The class index parameter is used as client index when reading from this cache. */
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Results when selecting a class for a player.
|
||||
*/
|
||||
enum ClassSelectResult
|
||||
{
|
||||
ClassSelected_NoChange, /** No class change was necessary (class already selected). */
|
||||
ClassSelected_Instant, /** Class was instantly changed. */
|
||||
ClassSelected_NextSpawn /** Class will be used next spawn. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a class index is valid or not.
|
||||
*
|
||||
* @param classIndex Class index to validate.
|
||||
*
|
||||
* @return True if valid, false otherwise.
|
||||
*/
|
||||
native bool:ZR_IsValidClassIndex(classIndex);
|
||||
|
||||
/**
|
||||
* Gets the currently active class index that the player is using.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return The active class index.
|
||||
*/
|
||||
native bool:ZR_GetActiveClass(client);
|
||||
|
||||
/**
|
||||
* Gets the current human class index that the player is using.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return The human class index.
|
||||
*/
|
||||
native bool:ZR_GetHumanClass(client);
|
||||
|
||||
/**
|
||||
* Gets the current zombie class index that the player is using.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return The zombie class index.
|
||||
*/
|
||||
native bool:ZR_GetZombieClass(client);
|
||||
|
||||
/**
|
||||
* Selects a class for a player.
|
||||
*
|
||||
* Human class attribute may be instantly applied if player is alive, human and
|
||||
* instant class change is enabled. Otherwise only the selected index will be
|
||||
* updated for next spawn.
|
||||
*
|
||||
* Class selection will be saved in client cookies if enabled.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param classIndex Class index.
|
||||
* @param applyIfPossible Optional. Apply class attributes if conditions allow
|
||||
* it. Default is true.
|
||||
* @param saveIfEnabled Optional. Save class selection in client cookies if
|
||||
* enabled. Default is true.
|
||||
*
|
||||
* @return Class selection result. See enum ClassSelectResult.
|
||||
*/
|
||||
native ClassSelectResult:ZR_SelectClientClass(client, classIndex, bool:applyIfPossible = true, bool:saveIfEnabled = true);
|
||||
|
||||
/**
|
||||
* Gets the class index of the class with the specified name.
|
||||
*
|
||||
* Note: This search is linear and probably won't perform well in large loops.
|
||||
*
|
||||
* @param className Class name to search for.
|
||||
* @param cacheType Optional. Specifies which class cache to read from,
|
||||
* except player cache.
|
||||
*
|
||||
* @return Class index, or -1 if none found.
|
||||
*/
|
||||
native ZR_GetClassByName(const String:className[], cacheType = ZR_CLASS_CACHE_MODIFIED);
|
||||
|
||||
/**
|
||||
* Gets the class name displayed in the class menu.
|
||||
*
|
||||
* @param index Index of the class in a class cache or a client index,
|
||||
* depending on the cache type specified.
|
||||
* @param buffer The destination string buffer.
|
||||
* @param maxlen The length of the destination string buffer.
|
||||
* @param cacheType Optional. Specifies which class cache to read from.
|
||||
* @return Number of cells written. -1 on error.
|
||||
*/
|
||||
native ZR_GetClassDisplayName(index, String:buffer[], maxlen, cacheType = ZR_CLASS_CACHE_MODIFIED);
|
123
includes/zr/infect.zr.inc
Normal file
123
includes/zr/infect.zr.inc
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: infect.zr.inc
|
||||
* Type: Include
|
||||
* Description: Infect-related natives/forwards.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns true if the player is a zombie, false if not.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return True if zombie, false if not.
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native bool:ZR_IsClientZombie(client);
|
||||
|
||||
/**
|
||||
* Returns true if the player is a human, false if not.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return True if human, false if not.
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native bool:ZR_IsClientHuman(client);
|
||||
|
||||
/**
|
||||
* Infects a player.
|
||||
*
|
||||
* Note: If the player already is a zombie, the player will be re-infected.
|
||||
*
|
||||
* @param client The client to infect.
|
||||
* @param attacker (Optional) The attacker who did the infect.
|
||||
* @param motherInfect (Optional) Infect as a mother zombie.
|
||||
* @param respawnOverride (Optional) Set to true to override respawn cvar.
|
||||
* @param respawn (Optional) Value to override with.
|
||||
*
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
|
||||
|
||||
/**
|
||||
* Turns a zombie back into a human.
|
||||
*
|
||||
* Note: If the player already is a human, this code will still run as the
|
||||
* player was a zombie.
|
||||
*
|
||||
* @param client The client to make human.
|
||||
* @param respawn Teleport client back to spawn.
|
||||
* @param protect Start spawn protection on client.
|
||||
*
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
|
||||
|
||||
/**
|
||||
* Called when a player is about to become a zombie.
|
||||
* Here you can modify any variable or block the infection entirely.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param attacker The the infecter. (-1 if there is no infecter)
|
||||
* @param motherInfect If the client is becoming a mother zombie.
|
||||
* @param respawnOverride True if the respawn cvar is being overridden.
|
||||
* @param respawn The value that respawn is being overridden with.
|
||||
*
|
||||
* @return Plugin_Handled to block infection. Anything else
|
||||
* (like Plugin_Continue) to allow infection.
|
||||
*/
|
||||
forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn);
|
||||
|
||||
/**
|
||||
* Called after a player has become a zombie.
|
||||
*
|
||||
* @param client The client that was infected.
|
||||
* @param attacker The the infecter. (-1 if there is no infecter)
|
||||
* @param motherInfect If the client is a mother zombie.
|
||||
* @param respawnOverride True if the respawn cvar was overridden.
|
||||
* @param respawn The value that respawn was overridden with.
|
||||
*/
|
||||
forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn);
|
||||
|
||||
/**
|
||||
* Called when a player is about to become a human. (Through an admin command).
|
||||
* Here you can modify any variable or block the action entirely.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param respawn True if the client was respawned, false if not.
|
||||
* @param protect True if the client spawn protected, false if not.
|
||||
*
|
||||
* @return Plugin_Handled to block infection. Anything else
|
||||
* (like Plugin_Continue) to allow acion.
|
||||
*/
|
||||
forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
|
||||
|
||||
/**
|
||||
* Called after a player has become a human. (Through an admin command.)
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param respawn Whether the client was respawned.
|
||||
* @param protect Whether the client has spawn protection.
|
||||
*/
|
||||
forward ZR_OnClientHumanPost(client, bool:respawn, bool:protect);
|
95
includes/zr/respawn.zr.inc
Normal file
95
includes/zr/respawn.zr.inc
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: respawn.zr.inc
|
||||
* Type: Include
|
||||
* Description: Infect-related natives/forwards.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Conditions for respawning players.
|
||||
*/
|
||||
enum ZR_RespawnCondition
|
||||
{
|
||||
ZR_Repsawn_Default = -1, /** Let ZR decide according to its settings. */
|
||||
ZR_Respawn_Human = 0, /** Respawn as a human. */
|
||||
ZR_Respawn_Zombie, /** Respawn as a zombie. */
|
||||
ZR_Respawn_ZombieIfSuicide /** Respawn as a zombie if killed by world damage. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns a player into the round.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param condition Optional. Set respawn condition, defaults to current
|
||||
* ZR settings. See ZR_RespawnCondition for details.
|
||||
* @error Invalid client index, not connected or already alive.
|
||||
*/
|
||||
native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Default);
|
||||
|
||||
/**
|
||||
* Called right before ZR is about to respawn a player.
|
||||
* Here you can modify any variable or stop the action entirely.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param condition Respawn condition. See ZR_RespawnCondition for
|
||||
* details.
|
||||
*
|
||||
* @return Plugin_Handled to block respawn.
|
||||
*/
|
||||
forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
|
||||
|
||||
/**
|
||||
* Called after ZR respawned a player.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param condition Current condition of the respawned player. See
|
||||
* ZR_RespawnCondition for details.
|
||||
*/
|
||||
forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
|
||||
|
||||
/**
|
||||
* Set if a player died by a suicide or world damage.
|
||||
|
||||
* Note: This will change the respawn condition.
|
||||
* Note: This value is reset to default by ZR when a zombie player dies.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param suicide True to say the player suicided, false if killed by another
|
||||
* player.
|
||||
*
|
||||
* @error Invalid client index or not connected.
|
||||
*/
|
||||
native ZR_SetKilledByWorld(client, bool:suicide);
|
||||
|
||||
/**
|
||||
* Get whether the player died by a suicide or world damage.
|
||||
*
|
||||
* Note: This value is only valid after death event, and before respawn.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return True if the player died by suicide, false if killed by
|
||||
* another player.
|
||||
* @error Invalid client index or not connected.
|
||||
*/
|
||||
native bool:ZR_GetKilledByWorld(client);
|
@ -0,0 +1,21 @@
|
||||
ar_baggage
|
||||
ar_monastery
|
||||
ar_shoots
|
||||
cs_assault
|
||||
cs_italy
|
||||
cs_militia
|
||||
cs_office
|
||||
de_aztec
|
||||
de_bank
|
||||
de_dust
|
||||
de_dust2
|
||||
de_inferno
|
||||
de_lake
|
||||
de_mirage
|
||||
de_nuke
|
||||
de_safehouse
|
||||
de_shorttrain
|
||||
de_stmarc
|
||||
de_sugarcane
|
||||
de_train
|
||||
de_vertigo
|
@ -0,0 +1,28 @@
|
||||
as_oilrig
|
||||
cs_747
|
||||
cs_assault
|
||||
cs_backalley
|
||||
cs_compound
|
||||
cs_estate
|
||||
cs_havana
|
||||
cs_italy
|
||||
cs_militia
|
||||
cs_office
|
||||
cs_siege
|
||||
de_airstrip
|
||||
de_aztec
|
||||
de_cbble
|
||||
de_chateau
|
||||
de_dust2
|
||||
de_dust
|
||||
de_inferno
|
||||
de_nuke
|
||||
de_piranesi
|
||||
de_port
|
||||
de_prodigy
|
||||
de_storm
|
||||
de_survivor
|
||||
de_tides
|
||||
de_torn
|
||||
de_train
|
||||
de_vertigo
|
@ -0,0 +1,9 @@
|
||||
dod_anzio
|
||||
dod_argentan
|
||||
dod_avalanche
|
||||
dod_colmar
|
||||
dod_donner
|
||||
dod_flash
|
||||
dod_jagd
|
||||
dod_kalt
|
||||
dod_palermo
|
@ -0,0 +1,7 @@
|
||||
dm_lockdown
|
||||
dm_overwatch
|
||||
dm_runoff
|
||||
dm_steamlab
|
||||
dm_underpass
|
||||
dm_resistance
|
||||
dm_powerhouse
|
65
mapchooser_extended/configs/mapchooser_extended/maps/tf.txt
Normal file
65
mapchooser_extended/configs/mapchooser_extended/maps/tf.txt
Normal file
@ -0,0 +1,65 @@
|
||||
tc_hydro
|
||||
cp_well
|
||||
cp_granary
|
||||
cp_dustbowl
|
||||
cp_gravelpit
|
||||
ctf_2fort
|
||||
ctf_well
|
||||
cp_badlands
|
||||
pl_goldrush
|
||||
cp_fastlane
|
||||
ctf_turbine
|
||||
pl_badwater
|
||||
cp_steel
|
||||
arena_badlands
|
||||
arena_granary
|
||||
arena_lumberyard
|
||||
arena_ravine
|
||||
arena_well
|
||||
cp_egypt_final
|
||||
cp_junction_final
|
||||
arena_watchtower
|
||||
plr_pipeline
|
||||
arena_sawmill
|
||||
arena_nucleus
|
||||
pl_hoodoo_final
|
||||
koth_sawmill
|
||||
koth_nucleus
|
||||
koth_viaduct
|
||||
ctf_sawmill
|
||||
arena_offblast_final
|
||||
cp_yukon_final
|
||||
koth_harvest_final
|
||||
koth_harvest_event
|
||||
ctf_doublecross
|
||||
cp_gorge
|
||||
cp_freight_final1
|
||||
pl_upward
|
||||
plr_hightower
|
||||
pl_thundermountain
|
||||
cp_coldfront
|
||||
cp_mountainlab
|
||||
cp_manor_event
|
||||
cp_degrootkeep
|
||||
cp_5gorge
|
||||
pl_frontier_final
|
||||
plr_nightfall_final
|
||||
koth_lakeside_final
|
||||
koth_badlands
|
||||
pl_barnblitz
|
||||
cp_gullywash_final1
|
||||
koth_viaduct_event
|
||||
cp_foundry
|
||||
sd_doomsday
|
||||
koth_king
|
||||
mvm_mannworks
|
||||
mvm_coaltown
|
||||
mvm_decoy
|
||||
koth_lakeside_event
|
||||
mvm_bigrock
|
||||
cp_process_final
|
||||
cp_standin_final
|
||||
plr_hightower_event
|
||||
cp_snakewater_final1
|
||||
mvm_mannhattan
|
||||
mvm_rottenburg
|
@ -0,0 +1,77 @@
|
||||
"MapchooserSoundsList"
|
||||
{
|
||||
"tf"
|
||||
{
|
||||
"counter"
|
||||
{
|
||||
"1"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_begins_1sec.mp3"
|
||||
"builtin" "vo/announcer_begins_1sec.wav"
|
||||
"event" "Announcer.RoundBegins1Seconds"
|
||||
}
|
||||
"2"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_begins_2sec.mp3"
|
||||
"builtin" "vo/announcer_begins_2sec.wav"
|
||||
"event" "Announcer.RoundBegins2Seconds"
|
||||
}
|
||||
"3"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_begins_3sec.mp3"
|
||||
"builtin" "vo/announcer_begins_3sec.wav"
|
||||
"event" "Announcer.RoundBegins3Seconds"
|
||||
}
|
||||
"4"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_begins_4sec.mp3"
|
||||
"builtin" "vo/announcer_begins_4sec.wav"
|
||||
"event" "Announcer.RoundBegins4Seconds"
|
||||
}
|
||||
"5"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_begins_5sec.mp3"
|
||||
"builtin" "vo/announcer_begins_5sec.wav"
|
||||
"event" "Announcer.RoundBegins5Seconds"
|
||||
}
|
||||
"10"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_dec_missionbegins10s01.mp3"
|
||||
"builtin" "vo/announcer_dec_missionbegins10s01.wav"
|
||||
}
|
||||
"30"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_dec_missionbegins30s01.mp3"
|
||||
"builtin" "vo/announcer_dec_missionbegins30s01.wav"
|
||||
}
|
||||
"60"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_dec_missionbegins60s06.mp3"
|
||||
"builtin" "vo/announcer_dec_missionbegins60s06.wav"
|
||||
}
|
||||
}
|
||||
"vote start"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/vote_started.mp3"
|
||||
"event" "Vote.Created"
|
||||
"builtin" "ui/vote_started.wav"
|
||||
}
|
||||
"vote end"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/vote_success.mp3"
|
||||
"event" "Vote.Passed"
|
||||
"builtin" "ui/vote_success.wav"
|
||||
}
|
||||
"vote warning"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/announcer_dec_missionbegins60s03.mp3"
|
||||
"builtin" "vo/announcer_dec_missionbegins60s03.wav"
|
||||
}
|
||||
"runoff warning"
|
||||
{
|
||||
"sound" "sourcemod/mapchooser/tf2/vote_failure.mp3"
|
||||
"event" "Vote.Failed"
|
||||
"builtin" "ui/vote_failure.wav"
|
||||
}
|
||||
}
|
||||
}
|
1
mapchooser_extended/scripting/include/colors.inc
Symbolic link
1
mapchooser_extended/scripting/include/colors.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/colors.inc
|
108
mapchooser_extended/scripting/include/mapchooser_extended.inc
Normal file
108
mapchooser_extended/scripting/include/mapchooser_extended.inc
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* MapChooser Extended
|
||||
* Creates a map vote at appropriate times, setting sm_nextmap to the winning
|
||||
* vote
|
||||
*
|
||||
* MapChooser Extended (C)2011-2013 Powerlord (Ross Bemrose)
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _mapchooser_extended_included_
|
||||
#endinput
|
||||
#endif
|
||||
#define _mapchooser_extended_included_
|
||||
#include <mapchooser>
|
||||
|
||||
// MCE 1.9 series
|
||||
|
||||
enum CanNominateResult
|
||||
{
|
||||
CanNominate_No_VoteFull, /** No, nominations list is full */
|
||||
CanNominate_No_VoteInProgress, /** No, map vote is in progress */
|
||||
CanNominate_No_VoteComplete, /** No, map vote is completed */
|
||||
CanNominate_Yes, /** Yes, you can nominate */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called whenever warning timer starts
|
||||
*
|
||||
*/
|
||||
forward OnMapVoteWarningStart();
|
||||
|
||||
/**
|
||||
* Called whenever runoff warning timer starts
|
||||
*/
|
||||
forward OnMapVoteRunnoffWarningStart();
|
||||
|
||||
/**
|
||||
* Called whenever the timer ticks
|
||||
*/
|
||||
forward OnMapVoteWarningTick(time);
|
||||
|
||||
/**
|
||||
* Called whenever vote starts
|
||||
*
|
||||
* @deprecated Will be removed in MapChooser 1.8. Use OnMapVoteStarted instead.
|
||||
*/
|
||||
forward OnMapVoteStart();
|
||||
|
||||
/**
|
||||
* Called whenever vote ends
|
||||
*/
|
||||
forward OnMapVoteEnd(const String:map[]);
|
||||
|
||||
/**
|
||||
* Is a map on the current game's official list?
|
||||
* This should be treated as informative only.
|
||||
*
|
||||
* @param map Name of map to check
|
||||
* @return true if it's on the list of official maps for this game
|
||||
*/
|
||||
native bool:IsMapOfficial(const String:map[]);
|
||||
|
||||
/**
|
||||
* Is nominate allowed?
|
||||
*
|
||||
* @return A CanNominateResult corresponding to whether a vote is allowed or not
|
||||
*/
|
||||
native CanNominateResult:CanNominate();
|
||||
|
||||
native bool:ExcludeMap(const String:map[]);
|
||||
|
||||
public SharedPlugin:__pl_mapchooser_extended =
|
||||
{
|
||||
name = "mapchooser",
|
||||
file = "mapchooser_extended.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
1
mapchooser_extended/scripting/include/nativevotes.inc
Symbolic link
1
mapchooser_extended/scripting/include/nativevotes.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../includes/nativevotes.inc
|
2343
mapchooser_extended/scripting/mapchooser_extended.sp
Normal file
2343
mapchooser_extended/scripting/mapchooser_extended.sp
Normal file
File diff suppressed because it is too large
Load Diff
703
mapchooser_extended/scripting/nominations_extended.sp
Normal file
703
mapchooser_extended/scripting/nominations_extended.sp
Normal file
@ -0,0 +1,703 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* Nominations Extended
|
||||
* Allows players to nominate maps for Mapchooser
|
||||
*
|
||||
* Nominations Extended (C)2012-2013 Powerlord (Ross Bemrose)
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <sourcemod>
|
||||
#include <mapchooser>
|
||||
#include "include/mapchooser_extended"
|
||||
#include <colors>
|
||||
#pragma semicolon 1
|
||||
|
||||
#define MCE_VERSION "1.10.0"
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Map Nominations Extended",
|
||||
author = "Powerlord and AlliedModders LLC",
|
||||
description = "Provides Map Nominations",
|
||||
version = MCE_VERSION,
|
||||
url = "https://forums.alliedmods.net/showthread.php?t=156974"
|
||||
};
|
||||
|
||||
new Handle:g_Cvar_ExcludeOld = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ExcludeCurrent = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_MapList = INVALID_HANDLE;
|
||||
new Handle:g_AdminMapList = INVALID_HANDLE;
|
||||
new Handle:g_MapMenu = INVALID_HANDLE;
|
||||
new Handle:g_AdminMapMenu = INVALID_HANDLE;
|
||||
new g_mapFileSerial = -1;
|
||||
new g_AdminMapFileSerial = -1;
|
||||
|
||||
#define MAPSTATUS_ENABLED (1<<0)
|
||||
#define MAPSTATUS_DISABLED (1<<1)
|
||||
#define MAPSTATUS_EXCLUDE_CURRENT (1<<2)
|
||||
#define MAPSTATUS_EXCLUDE_PREVIOUS (1<<3)
|
||||
#define MAPSTATUS_EXCLUDE_NOMINATED (1<<4)
|
||||
|
||||
new Handle:g_mapTrie;
|
||||
|
||||
// Nominations Extended Convars
|
||||
new Handle:g_Cvar_MarkCustomMaps = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Cvar_NominateDelay = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_InitialDelay = INVALID_HANDLE;
|
||||
new g_Player_NominationDelay[MAXPLAYERS+1];
|
||||
new g_NominationDelay;
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("nominations.phrases");
|
||||
LoadTranslations("basetriggers.phrases"); // for Next Map phrase
|
||||
LoadTranslations("mapchooser_extended.phrases");
|
||||
|
||||
new arraySize = ByteCountToCells(PLATFORM_MAX_PATH);
|
||||
g_MapList = CreateArray(arraySize);
|
||||
g_AdminMapList = CreateArray(arraySize);
|
||||
|
||||
g_Cvar_ExcludeOld = CreateConVar("sm_nominate_excludeold", "1", "Specifies if the current map should be excluded from the Nominations list", 0, true, 0.00, true, 1.0);
|
||||
g_Cvar_ExcludeCurrent = CreateConVar("sm_nominate_excludecurrent", "1", "Specifies if the MapChooser excluded maps should also be excluded from Nominations", 0, true, 0.00, true, 1.0);
|
||||
g_Cvar_InitialDelay = CreateConVar("sm_nominate_initialdelay", "60.0", "Time in seconds before first Nomination can be made", 0, true, 0.00);
|
||||
g_Cvar_NominateDelay = CreateConVar("sm_nominate_delay", "3.0", "Delay between nominations", 0, true, 0.00, true, 60.00);
|
||||
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
RegConsoleCmd("sm_nominate", Command_Nominate);
|
||||
RegConsoleCmd("sm_nomlist", Command_NominateList);
|
||||
|
||||
RegAdminCmd("sm_nominate_addmap", Command_Addmap, ADMFLAG_CHANGEMAP, "sm_nominate_addmap <mapname> - Forces a map to be on the next mapvote.");
|
||||
|
||||
// BotoX
|
||||
RegAdminCmd("sm_nominate_exclude", Command_AddExclude, ADMFLAG_CHANGEMAP, "sm_nominate_exclude <mapname> - Forces a map to be inserted into the recently played maps. Effectively blocking the map from being nominated.");
|
||||
|
||||
// Nominations Extended cvars
|
||||
CreateConVar("ne_version", MCE_VERSION, "Nominations Extended Version", FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD);
|
||||
|
||||
g_mapTrie = CreateTrie();
|
||||
}
|
||||
|
||||
public OnAllPluginsLoaded()
|
||||
{
|
||||
// This is an MCE cvar... this plugin requires MCE to be loaded. Granted, this plugin SHOULD have an MCE dependency.
|
||||
g_Cvar_MarkCustomMaps = FindConVar("mce_markcustommaps");
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
if (ReadMapList(g_MapList,
|
||||
g_mapFileSerial,
|
||||
"nominations",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_MAPSFOLDER)
|
||||
== INVALID_HANDLE)
|
||||
{
|
||||
if (g_mapFileSerial == -1)
|
||||
{
|
||||
SetFailState("Unable to create a valid map list.");
|
||||
}
|
||||
}
|
||||
if (ReadMapList(g_AdminMapList,
|
||||
g_AdminMapFileSerial,
|
||||
"sm_nominate_addmap menu",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT|MAPLIST_FLAG_MAPSFOLDER)
|
||||
== INVALID_HANDLE)
|
||||
{
|
||||
if (g_AdminMapFileSerial == -1)
|
||||
{
|
||||
SetFailState("Unable to create a valid admin map list.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (new i = 0; i < GetArraySize(g_MapList); i++)
|
||||
{
|
||||
decl String:map[PLATFORM_MAX_PATH];
|
||||
GetArrayString(g_MapList, i, map, sizeof(map));
|
||||
|
||||
new Index = FindStringInArray(g_AdminMapList, map);
|
||||
if (Index != -1)
|
||||
RemoveFromArray(g_AdminMapList, Index);
|
||||
}
|
||||
}
|
||||
|
||||
g_NominationDelay = GetTime() + GetConVarInt(g_Cvar_InitialDelay);
|
||||
|
||||
BuildMapMenu();
|
||||
BuildAdminMapMenu();
|
||||
}
|
||||
|
||||
public OnNominationRemoved(const String:map[], owner)
|
||||
{
|
||||
new status;
|
||||
|
||||
/* Is the map in our list? */
|
||||
if (!GetTrieValue(g_mapTrie, map, status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Was the map disabled due to being nominated */
|
||||
if ((status & MAPSTATUS_EXCLUDE_NOMINATED) != MAPSTATUS_EXCLUDE_NOMINATED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetTrieValue(g_mapTrie, map, MAPSTATUS_ENABLED);
|
||||
}
|
||||
|
||||
public Action:Command_Addmap(client, args)
|
||||
{
|
||||
if (args == 0)
|
||||
{
|
||||
AttemptAdminNominate(client);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (args != 1)
|
||||
{
|
||||
CReplyToCommand(client, "[NE] Usage: sm_nominate_addmap <mapname>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:mapname[PLATFORM_MAX_PATH];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
// new status;
|
||||
if (/*!GetTrieValue(g_mapTrie, mapname, status)*/!IsMapValid(mapname))
|
||||
{
|
||||
CReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new NominateResult:result = NominateMap(mapname, true, 0);
|
||||
|
||||
if (result > Nominate_Replaced)
|
||||
{
|
||||
/* We assume already in vote is the casue because the maplist does a Map Validity check and we forced, so it can't be full */
|
||||
CReplyToCommand(client, "%t", "Map Already In Vote", mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
SetTrieValue(g_mapTrie, mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
|
||||
|
||||
CReplyToCommand(client, "%t", "Map Inserted", mapname);
|
||||
LogAction(client, -1, "\"%L\" inserted map \"%s\".", client, mapname);
|
||||
|
||||
PrintToChatAll("[NE] %N has inserted %s into nominations", client, mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_AddExclude(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
CReplyToCommand(client, "[NE] Usage: sm_nominate_exclude <mapname>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:mapname[PLATFORM_MAX_PATH];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
new status;
|
||||
if(!GetTrieValue(g_mapTrie, mapname, status))
|
||||
{
|
||||
ReplyToCommand(client, "[NE] %t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShowActivity(client, "Excluded map \"%s\" from nomination", mapname);
|
||||
LogAction(client, -1, "\"%L\" excluded map \"%s\" from nomination", client, mapname);
|
||||
|
||||
SetTrieValue(g_mapTrie, mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_PREVIOUS);
|
||||
|
||||
// native call to mapchooser_extended
|
||||
ExcludeMap(mapname);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
{
|
||||
if (!client)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
if (!GetCmdArgString(text, sizeof(text)))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new startidx = 0;
|
||||
if(text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT);
|
||||
|
||||
if (strcmp(text[startidx], "nominate", false) == 0)
|
||||
{
|
||||
if (IsNominateAllowed(client))
|
||||
{
|
||||
if (g_NominationDelay > GetTime())
|
||||
ReplyToCommand(client, "[NE] Nominations will be unlocked in %d seconds", g_NominationDelay - GetTime());
|
||||
else
|
||||
AttemptNominate(client);
|
||||
}
|
||||
}
|
||||
|
||||
SetCmdReplySource(old);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action:Command_Nominate(client, args)
|
||||
{
|
||||
if (!client || !IsNominateAllowed(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (g_NominationDelay > GetTime())
|
||||
{
|
||||
ReplyToCommand(client, "[NE] Nominations will be unlocked in %d seconds", g_NominationDelay - GetTime());
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (args == 0)
|
||||
{
|
||||
AttemptNominate(client);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (g_Player_NominationDelay[client] > GetTime())
|
||||
{
|
||||
ReplyToCommand(client, "[NE] Please wait %d seconds before you can nominate again", g_Player_NominationDelay[client] - GetTime());
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:mapname[PLATFORM_MAX_PATH];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
new status;
|
||||
if (!GetTrieValue(g_mapTrie, mapname, status))
|
||||
{
|
||||
CReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED)
|
||||
{
|
||||
if ((status & MAPSTATUS_EXCLUDE_CURRENT) == MAPSTATUS_EXCLUDE_CURRENT)
|
||||
{
|
||||
CReplyToCommand(client, "[NE] %t", "Can't Nominate Current Map");
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_EXCLUDE_PREVIOUS) == MAPSTATUS_EXCLUDE_PREVIOUS)
|
||||
{
|
||||
CReplyToCommand(client, "[NE] %t", "Map in Exclude List");
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_EXCLUDE_NOMINATED) == MAPSTATUS_EXCLUDE_NOMINATED)
|
||||
{
|
||||
CReplyToCommand(client, "[NE] %t", "Map Already Nominated");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new NominateResult:result = NominateMap(mapname, false, client);
|
||||
|
||||
if (result > Nominate_Replaced)
|
||||
{
|
||||
if (result == Nominate_AlreadyInVote)
|
||||
{
|
||||
CReplyToCommand(client, "[NE] %t", "Map Already In Vote", mapname);
|
||||
}
|
||||
else if (result == Nominate_VoteFull)
|
||||
{
|
||||
CReplyToCommand(client, "[ME] %t", "Max Nominations");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
/* Map was nominated! - Disable the menu item and update the trie */
|
||||
|
||||
SetTrieValue(g_mapTrie, mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
|
||||
|
||||
decl String:name[MAX_NAME_LENGTH];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
if(result == Nominate_Added)
|
||||
PrintToChatAll("[NE] %t", "Map Nominated", name, mapname);
|
||||
else if(result == Nominate_Replaced)
|
||||
PrintToChatAll("[NE] %t", "Map Nomination Changed", name, mapname);
|
||||
|
||||
LogMessage("%s nominated %s", name, mapname);
|
||||
|
||||
g_Player_NominationDelay[client] = GetTime() + GetConVarInt(g_Cvar_NominateDelay);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action:Command_NominateList(client, args)
|
||||
{
|
||||
new arraySize = ByteCountToCells(PLATFORM_MAX_PATH);
|
||||
new Handle:MapList = CreateArray(arraySize);
|
||||
GetNominatedMapList(MapList);
|
||||
if (!GetArraySize(MapList))
|
||||
{
|
||||
CReplyToCommand(client, "[NE] No maps have been nominated.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new Handle:NominateListMenu = CreateMenu(Handler_NominateListMenu, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem);
|
||||
|
||||
decl String:map[PLATFORM_MAX_PATH];
|
||||
for (new i = 0; i < GetArraySize(MapList); i++)
|
||||
{
|
||||
GetArrayString(MapList, i, map, sizeof(map));
|
||||
AddMenuItem(NominateListMenu, map, map);
|
||||
}
|
||||
|
||||
SetMenuTitle(NominateListMenu, "Nominated Maps", client);
|
||||
DisplayMenu(NominateListMenu, client, MENU_TIME_FOREVER);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Handler_NominateListMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
AttemptNominate(client)
|
||||
{
|
||||
SetMenuTitle(g_MapMenu, "%T", "Nominate Title", client);
|
||||
DisplayMenu(g_MapMenu, client, MENU_TIME_FOREVER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AttemptAdminNominate(client)
|
||||
{
|
||||
SetMenuTitle(g_AdminMapMenu, "%T", "Nominate Title", client);
|
||||
DisplayMenu(g_AdminMapMenu, client, MENU_TIME_FOREVER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BuildMapMenu()
|
||||
{
|
||||
if (g_MapMenu != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_MapMenu);
|
||||
g_MapMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
ClearTrie(g_mapTrie);
|
||||
|
||||
g_MapMenu = CreateMenu(Handler_MapSelectMenu, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
|
||||
decl String:map[PLATFORM_MAX_PATH];
|
||||
|
||||
new Handle:excludeMaps = INVALID_HANDLE;
|
||||
decl String:currentMap[32];
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeOld))
|
||||
{
|
||||
excludeMaps = CreateArray(ByteCountToCells(PLATFORM_MAX_PATH));
|
||||
GetExcludeMapList(excludeMaps);
|
||||
}
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeCurrent))
|
||||
{
|
||||
GetCurrentMap(currentMap, sizeof(currentMap));
|
||||
}
|
||||
|
||||
|
||||
for (new i = 0; i < GetArraySize(g_MapList); i++)
|
||||
{
|
||||
new status = MAPSTATUS_ENABLED;
|
||||
|
||||
GetArrayString(g_MapList, i, map, sizeof(map));
|
||||
|
||||
if (GetConVarBool(g_Cvar_ExcludeCurrent))
|
||||
{
|
||||
if (StrEqual(map, currentMap))
|
||||
{
|
||||
status = MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_CURRENT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dont bother with this check if the current map check passed */
|
||||
if (GetConVarBool(g_Cvar_ExcludeOld) && status == MAPSTATUS_ENABLED)
|
||||
{
|
||||
if (FindStringInArray(excludeMaps, map) != -1)
|
||||
{
|
||||
status = MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_PREVIOUS;
|
||||
}
|
||||
}
|
||||
|
||||
AddMenuItem(g_MapMenu, map, map);
|
||||
SetTrieValue(g_mapTrie, map, status);
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_MapMenu, true);
|
||||
|
||||
if (excludeMaps != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(excludeMaps);
|
||||
}
|
||||
}
|
||||
|
||||
BuildAdminMapMenu()
|
||||
{
|
||||
if (g_AdminMapMenu != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_AdminMapMenu);
|
||||
g_AdminMapMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
g_AdminMapMenu = CreateMenu(Handler_AdminMapSelectMenu, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
|
||||
decl String:map[PLATFORM_MAX_PATH];
|
||||
|
||||
for (new i = 0; i < GetArraySize(g_AdminMapList); i++)
|
||||
{
|
||||
GetArrayString(g_AdminMapList, i, map, sizeof(map));
|
||||
|
||||
AddMenuItem(g_AdminMapMenu, map, map);
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_AdminMapMenu, true);
|
||||
}
|
||||
|
||||
public Handler_MapSelectMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_Select:
|
||||
{
|
||||
decl String:map[PLATFORM_MAX_PATH], String:name[MAX_NAME_LENGTH];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
GetClientName(param1, name, MAX_NAME_LENGTH);
|
||||
|
||||
new NominateResult:result = NominateMap(map, false, param1);
|
||||
|
||||
/* Don't need to check for InvalidMap because the menu did that already */
|
||||
if (result == Nominate_AlreadyInVote)
|
||||
{
|
||||
PrintToChat(param1, "[NE] %t", "Map Already Nominated");
|
||||
return 0;
|
||||
}
|
||||
else if (result == Nominate_VoteFull)
|
||||
{
|
||||
PrintToChat(param1, "[NE] %t", "Max Nominations");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetTrieValue(g_mapTrie, map, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
|
||||
|
||||
if(result == Nominate_Added)
|
||||
PrintToChatAll("[NE] %t", "Map Nominated", name, map);
|
||||
else if(result == Nominate_Replaced)
|
||||
PrintToChatAll("[NE] %t", "Map Nomination Changed", name, map);
|
||||
|
||||
LogMessage("%s nominated %s", name, map);
|
||||
}
|
||||
|
||||
case MenuAction_DrawItem:
|
||||
{
|
||||
decl String:map[PLATFORM_MAX_PATH];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
new status;
|
||||
|
||||
if (!GetTrieValue(g_mapTrie, map, status))
|
||||
{
|
||||
LogError("Menu selection of item not in trie. Major logic problem somewhere.");
|
||||
return ITEMDRAW_DEFAULT;
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED)
|
||||
{
|
||||
return ITEMDRAW_DISABLED;
|
||||
}
|
||||
|
||||
return ITEMDRAW_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
decl String:map[PLATFORM_MAX_PATH];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
new mark = GetConVarInt(g_Cvar_MarkCustomMaps);
|
||||
new bool:official;
|
||||
|
||||
new status;
|
||||
|
||||
if (!GetTrieValue(g_mapTrie, map, status))
|
||||
{
|
||||
LogError("Menu selection of item not in trie. Major logic problem somewhere.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
decl String:buffer[100];
|
||||
decl String:display[150];
|
||||
|
||||
if (mark)
|
||||
{
|
||||
official = IsMapOfficial(map);
|
||||
}
|
||||
|
||||
if (mark && !official)
|
||||
{
|
||||
switch (mark)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Format(buffer, sizeof(buffer), "%T", "Custom Marked", param1, map);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
Format(buffer, sizeof(buffer), "%T", "Custom", param1, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcopy(buffer, sizeof(buffer), map);
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED)
|
||||
{
|
||||
if ((status & MAPSTATUS_EXCLUDE_CURRENT) == MAPSTATUS_EXCLUDE_CURRENT)
|
||||
{
|
||||
Format(display, sizeof(display), "%s (%T)", buffer, "Current Map", param1);
|
||||
return RedrawMenuItem(display);
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_EXCLUDE_PREVIOUS) == MAPSTATUS_EXCLUDE_PREVIOUS)
|
||||
{
|
||||
Format(display, sizeof(display), "%s (%T)", buffer, "Recently Played", param1);
|
||||
return RedrawMenuItem(display);
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_EXCLUDE_NOMINATED) == MAPSTATUS_EXCLUDE_NOMINATED)
|
||||
{
|
||||
Format(display, sizeof(display), "%s (%T)", buffer, "Nominated", param1);
|
||||
return RedrawMenuItem(display);
|
||||
}
|
||||
}
|
||||
|
||||
if (mark && !official)
|
||||
return RedrawMenuItem(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
stock bool:IsNominateAllowed(client)
|
||||
{
|
||||
new CanNominateResult:result = CanNominate();
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case CanNominate_No_VoteInProgress:
|
||||
{
|
||||
CReplyToCommand(client, "[ME] %t", "Nextmap Voting Started");
|
||||
return false;
|
||||
}
|
||||
|
||||
case CanNominate_No_VoteComplete:
|
||||
{
|
||||
new String:map[PLATFORM_MAX_PATH];
|
||||
GetNextMap(map, sizeof(map));
|
||||
CReplyToCommand(client, "[NE] %t", "Next Map", map);
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
case CanNominate_No_VoteFull:
|
||||
{
|
||||
CReplyToCommand(client, "[ME] %t", "Max Nominations");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Handler_AdminMapSelectMenu(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_Select:
|
||||
{
|
||||
decl String:map[PLATFORM_MAX_PATH], String:name[MAX_NAME_LENGTH];
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
new NominateResult:result = NominateMap(map, false, 0);
|
||||
|
||||
if (result == Nominate_AlreadyInVote)
|
||||
{
|
||||
PrintToChat(param1, "[NE] %t", "Map Already In Vote", map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetTrieValue(g_mapTrie, map, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
|
||||
|
||||
PrintToChat(param1, "[NE] %t", "Map Inserted", map);
|
||||
LogAction(param1, -1, "\"%L\" inserted map \"%s\".", param1, map);
|
||||
|
||||
PrintToChatAll("[NE] %N has inserted %s into nominations", name, map);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
378
mapchooser_extended/scripting/rockthevote_extended.sp
Normal file
378
mapchooser_extended/scripting/rockthevote_extended.sp
Normal file
@ -0,0 +1,378 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* Rock The Vote Extended
|
||||
* Creates a map vote when the required number of players have requested one.
|
||||
*
|
||||
* Rock The Vote Extended (C)2012-2013 Powerlord (Ross Bemrose)
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <sdkhooks>
|
||||
#include <mapchooser>
|
||||
#include "include/mapchooser_extended"
|
||||
#include <nextmap>
|
||||
#include <colors>
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#define MCE_VERSION "1.10.0"
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Rock The Vote Extended",
|
||||
author = "Powerlord and AlliedModders LLC",
|
||||
description = "Provides RTV Map Voting",
|
||||
version = MCE_VERSION,
|
||||
url = "https://forums.alliedmods.net/showthread.php?t=156974"
|
||||
};
|
||||
|
||||
new Handle:g_Cvar_Needed = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_MinPlayers = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_InitialDelay = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Interval = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_ChangeTime = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_RTVPostVoteAction = INVALID_HANDLE;
|
||||
|
||||
new bool:g_CanRTV = false; // True if RTV loaded maps and is active.
|
||||
new bool:g_RTVAllowed = false; // True if RTV is available to players. Used to delay rtv votes.
|
||||
new g_Voters = 0; // Total voters connected. Doesn't include fake clients.
|
||||
new g_Votes = 0; // Total number of "say rtv" votes
|
||||
new g_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed)
|
||||
new bool:g_Voted[MAXPLAYERS+1] = {false, ...};
|
||||
|
||||
new bool:g_InChange = false;
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("rockthevote.phrases");
|
||||
LoadTranslations("basevotes.phrases");
|
||||
|
||||
g_Cvar_Needed = CreateConVar("sm_rtv_needed", "0.60", "Percentage of players needed to rockthevote (Def 60%)", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_MinPlayers = CreateConVar("sm_rtv_minplayers", "0", "Number of players required before RTV will be enabled.", 0, true, 0.0, true, float(MAXPLAYERS));
|
||||
g_Cvar_InitialDelay = CreateConVar("sm_rtv_initialdelay", "30.0", "Time (in seconds) before first RTV can be held", 0, true, 0.00);
|
||||
g_Cvar_Interval = CreateConVar("sm_rtv_interval", "240.0", "Time (in seconds) after a failed RTV before another can be held", 0, true, 0.00);
|
||||
g_Cvar_ChangeTime = CreateConVar("sm_rtv_changetime", "0", "When to change the map after a succesful RTV: 0 - Instant, 1 - RoundEnd, 2 - MapEnd", _, true, 0.0, true, 2.0);
|
||||
g_Cvar_RTVPostVoteAction = CreateConVar("sm_rtv_postvoteaction", "0", "What to do with RTV's after a mapvote has completed. 0 - Allow, success = instant change, 1 - Deny", _, true, 0.0, true, 1.0);
|
||||
|
||||
HookEvent("player_team", OnPlayerChangedTeam);
|
||||
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
RegConsoleCmd("sm_rtv", Command_RTV);
|
||||
|
||||
RegAdminCmd("sm_forcertv", Command_ForceRTV, ADMFLAG_CHANGEMAP, "Force an RTV vote");
|
||||
RegAdminCmd("mce_forcertv", Command_ForceRTV, ADMFLAG_CHANGEMAP, "Force an RTV vote");
|
||||
|
||||
// Rock The Vote Extended cvars
|
||||
CreateConVar("rtve_version", MCE_VERSION, "Rock The Vote Extended Version", FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD);
|
||||
|
||||
AutoExecConfig(true, "rtv");
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
g_Voters = 0;
|
||||
g_Votes = 0;
|
||||
g_VotesNeeded = 0;
|
||||
g_InChange = false;
|
||||
|
||||
/* Handle late load */
|
||||
for (new i=1; i<=MaxClients; i++)
|
||||
{
|
||||
if (IsClientConnected(i))
|
||||
{
|
||||
OnClientConnected(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapEnd()
|
||||
{
|
||||
g_CanRTV = false;
|
||||
g_RTVAllowed = false;
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
g_CanRTV = true;
|
||||
g_RTVAllowed = false;
|
||||
CreateTimer(GetConVarFloat(g_Cvar_InitialDelay), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
|
||||
public OnClientConnected(client)
|
||||
{
|
||||
if(IsFakeClient(client))
|
||||
return;
|
||||
|
||||
g_Voted[client] = false;
|
||||
|
||||
g_Voters = GetTeamClientCount(2) + GetTeamClientCount(3);
|
||||
g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public OnClientDisconnect(client)
|
||||
{
|
||||
if(IsFakeClient(client))
|
||||
return;
|
||||
|
||||
if(g_Voted[client])
|
||||
{
|
||||
g_Votes--;
|
||||
}
|
||||
|
||||
g_Voters = GetTeamClientCount(2) + GetTeamClientCount(3);
|
||||
|
||||
g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
|
||||
|
||||
if (!g_CanRTV)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Votes &&
|
||||
g_Voters &&
|
||||
g_Votes >= g_VotesNeeded &&
|
||||
g_RTVAllowed )
|
||||
{
|
||||
if (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartRTV();
|
||||
}
|
||||
}
|
||||
|
||||
public OnPlayerChangedTeam(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new Client = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||
|
||||
if(IsFakeClient(Client))
|
||||
return;
|
||||
|
||||
if(Client == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsClientInGame(Client) && IsClientConnected(Client))
|
||||
{
|
||||
if (GetClientTeam(Client) == 1)
|
||||
{
|
||||
g_Voters = GetTeamClientCount(2) + GetTeamClientCount(3);
|
||||
g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
|
||||
|
||||
if (g_Votes &&
|
||||
g_Voters &&
|
||||
g_Votes >= g_VotesNeeded &&
|
||||
g_RTVAllowed )
|
||||
{
|
||||
if (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartRTV();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_RTV(client, args)
|
||||
{
|
||||
if (!g_CanRTV || !client)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
AttemptRTV(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
{
|
||||
if (!g_CanRTV || !client)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
if (!GetCmdArgString(text, sizeof(text)))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new startidx = 0;
|
||||
if(text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT);
|
||||
|
||||
if (strcmp(text[startidx], "rtv", false) == 0 || strcmp(text[startidx], "rockthevote", false) == 0)
|
||||
{
|
||||
AttemptRTV(client);
|
||||
}
|
||||
|
||||
SetCmdReplySource(old);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
AttemptRTV(client)
|
||||
{
|
||||
if (!g_RTVAllowed || (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished()))
|
||||
{
|
||||
CReplyToCommand(client, "[SM] %t", "RTV Not Allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanMapChooserStartVote())
|
||||
{
|
||||
CReplyToCommand(client, "[SM] %t", "RTV Started");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetClientCount(true) < GetConVarInt(g_Cvar_MinPlayers))
|
||||
{
|
||||
CReplyToCommand(client, "[SM] %t", "Minimal Players Not Met");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Voted[client])
|
||||
{
|
||||
CReplyToCommand(client, "[SM] %t", "Already Voted", g_Votes, g_VotesNeeded);
|
||||
return;
|
||||
}
|
||||
|
||||
new String:name[MAX_NAME_LENGTH];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
g_Votes++;
|
||||
g_Voted[client] = true;
|
||||
|
||||
CPrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded);
|
||||
|
||||
if (g_Votes >= g_VotesNeeded)
|
||||
{
|
||||
StartRTV();
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_DelayRTV(Handle:timer)
|
||||
{
|
||||
g_RTVAllowed = true;
|
||||
}
|
||||
|
||||
StartRTV()
|
||||
{
|
||||
if (g_InChange)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EndOfMapVoteEnabled() && HasEndOfMapVoteFinished())
|
||||
{
|
||||
/* Change right now then */
|
||||
new String:map[PLATFORM_MAX_PATH];
|
||||
if (GetNextMap(map, sizeof(map)))
|
||||
{
|
||||
CPrintToChatAll("[SM] %t", "Changing Maps", map);
|
||||
CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE);
|
||||
g_InChange = true;
|
||||
|
||||
ResetRTV();
|
||||
|
||||
g_RTVAllowed = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (CanMapChooserStartVote())
|
||||
{
|
||||
new MapChange:when = MapChange:GetConVarInt(g_Cvar_ChangeTime);
|
||||
InitiateMapChooserVote(when);
|
||||
|
||||
ResetRTV();
|
||||
|
||||
g_RTVAllowed = false;
|
||||
CreateTimer(GetConVarFloat(g_Cvar_Interval), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
ResetRTV()
|
||||
{
|
||||
g_Votes = 0;
|
||||
|
||||
for (new i=1; i<=MAXPLAYERS; i++)
|
||||
{
|
||||
g_Voted[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_ChangeMap(Handle:hTimer)
|
||||
{
|
||||
g_InChange = false;
|
||||
|
||||
LogMessage("RTV changing map manually");
|
||||
|
||||
new String:map[PLATFORM_MAX_PATH];
|
||||
if (GetNextMap(map, sizeof(map)))
|
||||
{
|
||||
ForceChangeLevel(map, "RTV after mapvote");
|
||||
}
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
// Rock The Vote Extended functions
|
||||
|
||||
public Action:Command_ForceRTV(client, args)
|
||||
{
|
||||
if (!g_CanRTV || !client)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[RTVE] ", "%t", "Initiated Vote Map");
|
||||
|
||||
StartRTV();
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
2
mapchooser_extended/translations/chi/incomplete.txt
Normal file
2
mapchooser_extended/translations/chi/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"chi" "下一幅地图投票了!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"chi" "下一幅地图投选已开始."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"chi" " 地图投票已结束. 下一幅地图将为 {1}. ( 得票{2}%% , {3}票)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"chi" "当前地图已被延长."
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"chi" "延长当前地图"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"chi" "请勿更换"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"chi" "当前地图已被延长! 投票显示! (得票 {1}%% 共 {2} 票)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"chi" "更换下一幅地图为 \"{1}\"."
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/cze/incomplete.txt
Normal file
2
mapchooser_extended/translations/cze/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"cze" "Hlasujte o příští mapě!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"cze" "Hlasování o příští mapě začalo."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"cze" "Hlasování o mapě skončilo. Příští mapou bude {1}. (Obdržela {2}%% z {3} hlasů)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"cze" "Současná mapa byla prodloužena. (Obdržela {1}%% z {2} hlasů)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"cze" "Prodloužit současnou mapu"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"cze" "Neměnit"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"cze" "Současná mapa pokračuje! Hlasování rozhodlo! (Obdržela {1}%% z {2} hlasů)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"cze" "Změnil příští mapu na \"{1}\"."
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/da/incomplete.txt
Normal file
2
mapchooser_extended/translations/da/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"da" "Stem om næste bane!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"da" "Afstemning for næste bane er begyndt."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"da" "Bane afstemning er fuldført. Den næste bane vil være {1}. (Modtog {2}%% af {3} stemmer) "
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"da" "Den nuværende bane er blevet forlænget. (Modtog {1}%% af {2} stemmer) "
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"da" "Forlæng bane"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"da" "Skift ikke!"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"da" "Den aktuelle bane fortsætter! Afstemningen har talt! (Modtog {1}%% af {2} stemmer)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"da" "Skiftede næste bane til \"{1}'."
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"de" "Stimme für die nächste Karte!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"de" "Abstimmung für die nächste Karte wurde gestartet."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"de" "Karten-Abstimmung wurde abgeschlossen. Nächste Karte wird {1} sein. ({2}%% von {3} Stimmen erhalten) "
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"de" "Die aktuelle Karte wurde verlängert. ({1}%% von {2} Stimmen erhalten) "
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"de" "Verlängere aktuelle Karte"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"de" "Nicht wechseln"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"de" "Aktuelle Karte geht weiter! Die Abstimmung hat entschieden! ({1}%% von {2} Stimmen erhalten) "
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"de" "Nächste Karte wurde auf \"{1}\" geändert. "
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"de" "Stichwahl für die nächste Karte!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"de" "Anzahl der Stimmen"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"de" "{1} (nicht vorhanden)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"de" "Keine Karte hat mehr als {1}%% der Stimmen.\nEine neue Abstimmung ist erforderlich!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"de" "Stichwahl startet in: {1} Sekunden"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"de" "Achtung! Die Abstimmung für die nächste Karte startet in: {1} Sekunden"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"de" "Überlegen Sie, welche Karte Sie spielen möchten ..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"de" "... und nicht unüberlegt wählen!"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"de" "Abstimmung ist bereits im Gange. Versuch Sie es erneut in {1} Sekunden"
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"de" "Die Top-{1} Karten haben gleich viele Stimmen!.\nEine neue Abstimmung ist erforderlich!"
|
||||
}
|
||||
|
||||
"Custom Marked"
|
||||
{
|
||||
"de" "*{1}"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"es" "Vota para el siguiente mapa!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"es" "La votacion para el siguiente mapa ha comenzado."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"es" "Votacion de Mapa finalizado. El siguiente mapa sera {1}. (Recibidos {2}%% de {3} votos)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"es" "El mapa actual ha sido extendido. (Recibidos {1}%% de {2} votos)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"es" "Extender mapa actual"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"es" "No cambiar"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"es" "El mapa actual continua! La votacion ha hablado! (Recibidos {1}%% de {2} votos)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"es" "El siguiente mapa ha cambiado a \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"es" "Hacer votacion para el siguiente mapa!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"es" "Numero de Votaciones"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"es" "{1} (Custom)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"es" "No hay ningun mapa que haya recibido el {1}%% de votaciones.\nEntonces, que mapa ganara? Es necesario otra votacion!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"es" "La votacion empezara en: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"es" "Atencion! La votacion para el siguiente mapa se iniciara en: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"es" "Considera que mapa quieres jugar..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"es" "...y no pulse los botones sin pensar ;-)"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"es" "Votacion ya iniciada. Intentando de nuevo en {1}s."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"es" "El top {1} de mapas tienen el mismo numero de votaciones.\nSe necesita una nueva votacion!"
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"fr" "Voter pour la prochaine map!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"fr" "Voter pour la prochaine map est lancer."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"fr" "Le VoteMap est terminer. La prochaine map sera {1}. (Reçu {2}%% sur {3} votes)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"fr" "La map actuelle a été prolonger. (Reçu {1}%% sur {2} votes)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"fr" "Prolonger la map"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"fr" "Ne pas changer"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"fr" "La map continue! Le vote a tranché! (Reçu {1}%% sur {2} votes)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"fr" "La map suivante sera \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"fr" "Votez a nouveau pour la prochaine Map!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"fr" "Nombres de votes"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"fr" "{1} (Custom)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"fr" "Aucune map n'a reçu plus de {1}%% du vote.\nAlors, quels maps va gagner? Un nouveau vote va être lancé!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"fr" "Un nouveau vote commence dans: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"fr" "Attention! Le vote pour la prochaine map commence dans: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"fr" "Voter pour la map que vous voulez jouer..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"fr" "...et ne pas cliquez sur une touche comme un con ;-)"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"fr" "Vote déjà en cours. Reassayer dans {1}s."
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"fr" "Votez pour la prochaine map!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"fr" "Le vote pour la prochaine map est lancé."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"fr" "Le VoteMap est terminé. La prochaine map sera {1}. (Reçu {2}%% sur {3} votes)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"fr" "La map actuelle a été prolongée. (Reçu {1}%% sur {2} votes)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"fr" "Prolonger la map"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"fr" "Ne pas changer"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"fr" "La map continue! Le vote a tranché! (Reçu {1}%% sur {2} votes)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"fr" "La map suivante sera \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"fr" "Votez à nouveau pour la prochaine Map!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"fr" "Nombres de votes"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"fr" "{1} (Custom)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"fr" "Aucune map n'a reçu plus de {1}%% du vote.\nAlors, quelle map va gagner? Un nouveau vote va être lancé!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"fr" "Un nouveau vote commence dans: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"fr" "Attention! Le vote pour la prochaine map commence dans: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"fr" "Votez pour la map que vous voulez jouer..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"fr" "...et n'appuyez pas sur une touche comme un con ;-)"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"fr" "Vote déjà en cours. Reassayez dans {1}s."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"fr" "{1} maps ont eu un même nombre de voix.\nUn nouveau vote est nécessaire!"
|
||||
}
|
||||
}
|
2
mapchooser_extended/translations/hu/incomplete.txt
Normal file
2
mapchooser_extended/translations/hu/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"hu" "Mi legyen a következő pálya?"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"hu" "Palyavalaszto szavazas elindult!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"hu" "A szavazás lezárult. A következő pálya a {1} lesz"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"hu" "Az aktualis palya meghosszabitva."
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"hu" "Palya meghosszabitasa"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"hu" "Ne valtsunk!"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"hu" "Jelenlegi palya folytatodik."
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"hu" "\"{1}\" lesz a kovetkezo palya"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"it" "Vota per la prossima mappa!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"it" "Le votazione per scegliere la prossima mappa sono iniziate."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"it" "Le votazioni sono terminate. La prossima mappa sarà {1}. (Con {2}%% su {3} votes)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"it" "La mappa attuale è stata estesa. (Con {1}%% su {2} votes)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"it" "Estendi la mappa corrente"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"it" "Non cambiare"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"it" "La mappa continua! Il voto ha parlato! (Con {1}%% su {2} votes)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"it" "La mappa successiva sarà \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"it" "Vota nuovamente per scegliere la prossima mappa!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"it" "Numero di voti"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"it" "{1} (Custom)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"it" "Nessuna mappa ha ricevuto più del {1}%% di voti.\nAllora, quale mappa vincerà? Si inizia un' altra votazione!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"it" "Una nuova votazione inizierà tra: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"it" "Attenzione! Le votazione per la prossima mappa cominceranno tra: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"it" "Vota la mappa chevorresti giocare..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"it" "...e non cliccare i tasti sconsideratamente :D"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"it" "Il voto è in corso. Riprova tra {1}s."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"it" "Le mappe hanno raggiunto il pareggio dei voti.\nBisogna nuovamente votare!"
|
||||
}
|
||||
}
|
2
mapchooser_extended/translations/jp/incomplete.txt
Normal file
2
mapchooser_extended/translations/jp/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"jp" "次のマップを投票してください!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"jp" "次のマップ投票をスタートしました。"
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"jp" "マップ投票が完了しました。次はマップは{1}です。({3}中{2}%%)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"jp" "現在のマップを延長します。({3}中{2}%%)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"jp" "現在のマップを延長"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"jp" "変更しない"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"jp" "現在のマップを延長します。({3}中{2}%%)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"jp" "次のマップを\"{1}\"に変更しました。"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"ko" "다음 맵을 결정하기 위한 투표!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"ko" "다음 맵을 결정하기 위한 투표가 시작되었습니다."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"ko" "맵 투표가 끝났습니다. 다음 맵은 {1} 이 될 것입니다. (전체 인원 {2}명 중 {1}%%의 표를 받았습니다.)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"ko" "현재 맵을 더하기로 결정했습니다. (전체 인원 {2}명 중 {1}%%의 표를 받았습니다.)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"ko" "지금 맵을 더 하자"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"ko" "바꾸지 말자"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"ko" "현재 맵을 계속 합니다!(전체 인원 {2} 명의 {1}%% 의 표를 받았습니다)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"ko" "다음 맵을 \"{1}\" 로 바꾸었습니다."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"ko" "다음 맵을 결정하기 위한 재투표!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"ko" "투표수"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"ko" "{1} (커스텀 맵)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"ko" "{1}%% 이상 투표를 받은 맵이 없습니다.\n다음 맵을 결정하기 위해 재투표를 합니다!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"ko" "재투표까지: {1}초"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"ko" "알립니다! 다음 맵을 결정하는 투표까지: {1}초"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"ko" "원하는 맵을 선택하세요..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"ko" "...그리고 아무거나 막 찍지 말고요 -_-"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"ko" "투표가 진행 중에 있습니다. {1}초 후 다시 시도합니다."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"ko" "{1}개 맵이 같은 투표수를 얻었습니다.\n재투표를 합니다!"
|
||||
}
|
||||
|
||||
"Custom Marked"
|
||||
{
|
||||
"ko" "*{1}"
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/lv/incomplete.txt
Normal file
2
mapchooser_extended/translations/lv/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"lv" "Balso par nākamo karti!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"lv" "Balsošana par nākamo karti ir sākusies."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"lv" "Balsošana par karti ir beigusies. Nākamā karte būs {1}. (Saņēma {2}%% no {3} balsīm) "
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"lv" "Patreizējās kartes laiks ir pagarināts. (Saņēma {1}%% no {2} balsīm) "
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"lv" "Pagarināt laiku patreizējā kartē"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"lv" "Nemainīt"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"lv" "Patreizējā karte turpinās! Aptauja ir beigusies! (Saņēma {1}%% no {2} balsīm)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"lv" "Nomainīja nākamo karti uz \"{1}\"."
|
||||
}
|
||||
|
||||
}
|
109
mapchooser_extended/translations/mapchooser_extended.phrases.txt
Normal file
109
mapchooser_extended/translations/mapchooser_extended.phrases.txt
Normal file
@ -0,0 +1,109 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"en" "Vote for the next map!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"en" "Voting for next map has started."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"#format" "{1:s},{2:i},{3:i}"
|
||||
"en" "Map voting has finished. The next map will be {1}. (Received {2}%% of {3} votes)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"#format" "{1:i},{2:i}"
|
||||
"en" "The current map has been extended. (Received {1}%% of {2} votes)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"en" "Extend Current Map"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"en" "Don't Change"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"#format" "{1:i},{2:i}"
|
||||
"en" "Current map continues! The Vote has spoken! (Received {1}%% of {2} votes)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Changed nextmap to \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"en" "Runoff Vote for the next map!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"en" "Number of votes"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "{1} (Custom)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"#format" "{1:i}"
|
||||
"en" "No map has received more than {1}%% of the vote.\nSo, which map will win? A revote is needed!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"#format" "{1:i}"
|
||||
"en" "Runoff vote will start in: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"#format" "{1:i}"
|
||||
"en" "Warning! Voting for the next map will begin in: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"en" "Consider which map you want to play..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"en" "...and don't hit buttons thoughtlessly ;-)"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"#format" "{1:i}"
|
||||
"en" "Vote already in progress. Retrying in {1}s."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"#format" "{1:i}"
|
||||
"en" "The top {1} maps had the same number of votes.\nA revote is needed!"
|
||||
}
|
||||
|
||||
"Custom Marked"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "*{1}"
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/nl/incomplete.txt
Normal file
2
mapchooser_extended/translations/nl/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"nl" "Stem voor de volgende map!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"nl" "Stemmen voor de volgende map is gestart."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"nl" "Map stemmen gestopt. De volgende map wordt {1}."
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"nl" "De huidige map is verlengd."
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"nl" "Verleng huidige map"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"nl" "Niet veranderen"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"nl" "Huidige map gaat verder! De Stem heeft gesproken! (Ontvangen {1}%% van de {2} stemmen)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"nl" "Volgende map verandert naar \"{1}\"."
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/no/incomplete.txt
Normal file
2
mapchooser_extended/translations/no/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"no" "Stem for det neste kartet!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"no" "Avstemning for det neste kartet har startet."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"no" "Kart-avstemningen er avsluttet. Det neste kartet vil være {1}. (Mottok {2}%% av {3} stemmer)."
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"no" "Gjeldende kart videreføres! (Mottok {1}%% av {2} stemmer)."
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"no" "Forleng gjeldende kart."
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"no" "Ikke bytt!"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"no" "Gjeldende kart videreføres! Avstemningen har talt! (Mottok {1}%% av {2} stemmer)."
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"no" "Byttet neste kart til \"{1}\""
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"pl" "Głosuj na następną mapę!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"pl" "Rozpoczęto głosowanie na następną mapę."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"pl" "Głosowanie na mapę zostało zakończone. Następną mapą będzie {1}. (Otrzymała {2} procent z {3} głosów) "
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"pl" "Aktualna mapa została przedłużona. (Otrzymała {1} procent z {2} głosów)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"pl" "Przedłuż bieżącą mapę"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"pl" "Nie Zmieniaj"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"pl" "Aktualna mapa będzie kontynuowana! (Otrzymano {1} procent z {2} głosów)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"pl" "Zmieniono następną mapę na: \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"pl" "Wybierz ponownie!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"pl" "Otrzymane głosy"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"pl" "{1} (Niestandardowa)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"pl" "Żadna mapa nie otrzymała przynajmniej {1}%% głosów.\nWięc która mapa jest zwycięzcą? Trzeba zagłosować ponownie!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"pl" "Ponowne głosowanie rozpocznie się za: {1}s\nTym razem się już zdecydujcie ;-)"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"pl" "UWAGA!!! Głosowanie na następną mapę rozpocznie się za: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"pl" "Zastanów się na której mapie chcesz grać..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"pl" "...wpisując !revote możesz zmienić swój głos."
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"pl" "Głosowanie w toku. Ponawiam za {1}s."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"pl" "{1} najlepsze mapy otrzymały tę samą ilość głosów.\nPotrzeba ponownego głosowania!"
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"pt" "Vote para o próximo mapa!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"pt" "Votação para o próximo mapa começou."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"pt" "A votação para o próximo mapa terminou. O próximo mapa será {1}. (Recebidos {2}%% de {3} votos)"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"pt" "A mapa atual foi estendido. (Recebidos {1}%% de {2} votos)"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"pt" "Estender tempo do mapa atual"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"pt" "Não Mudar"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"pt" "O mapa atual continua! O Voto foi dado! (Recebidos {1}%% de {2} votos)"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"pt" "Mudado o próximo mapa para \"{1}\"."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"pt" "Segundo turno de votos para o próximo mapa!"
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"pt" "Número de votos"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"pt" "{1} (Custom)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"pt" "Nenhum mapa recebeu mais que {1}%% de votos.\nEntão, qual mapa ganhará? Precisa de uma nova votação!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"pt" "Segundo turno começa em: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"pt" "Atenção! Votação para o próximo mapa começará em: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"pt" "Considere que mapa você quer jogar..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"pt" "...e não aperte os botões sem pensar ;-)"
|
||||
}
|
||||
|
||||
"Cannot Start Vote"
|
||||
{
|
||||
"pt" "Votação em progresso. Tentando novamente em {1}s."
|
||||
}
|
||||
|
||||
"Tie Vote"
|
||||
{
|
||||
"pt" "Os {1} mapas tiveram o mesmo número de votos.\nUma nova votação é necessária!"
|
||||
}
|
||||
|
||||
"Custom Marked"
|
||||
{
|
||||
"pt" "*{1}"
|
||||
}
|
||||
|
||||
}
|
1
mapchooser_extended/translations/ru/incomplete.txt
Normal file
1
mapchooser_extended/translations/ru/incomplete.txt
Normal file
@ -0,0 +1 @@
|
||||
Missing "Cannot Start Vote" and "Tie Vote"
|
@ -0,0 +1,83 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"ru" "Голосование за следующую карту."
|
||||
}
|
||||
|
||||
"Runoff Vote Nextmap"
|
||||
{
|
||||
"ru" "Повторное голосование за карту."
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"ru" "Голосование за следующую карту запущено."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"ru" "Голосование за карту завершено. Следующей картой будет: {1}. (Получено {2}%% из {3} голосов(а))"
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"ru" "Текущая карта была продлена. (Получено {1}%% из {2} голосов(а))"
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"ru" "Продлить текущую карту."
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"ru" "Не менять карту."
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"ru" "Текущая карта не сменится! (Получено {1}%% из {2} голосов(а))"
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"ru" "Следующая карта изменена на \"{1}\"."
|
||||
}
|
||||
|
||||
"Number Of Votes"
|
||||
{
|
||||
"ru" "Количество голосов"
|
||||
}
|
||||
|
||||
"Custom"
|
||||
{
|
||||
"ru" "{1} (Случайная)"
|
||||
}
|
||||
|
||||
"Revote Is Needed"
|
||||
{
|
||||
"ru" "Ни одна карта не получила более, чем {1}%% голосов(а).\nИтак, какая карта будет следующей? Приготовьтесь к повторному голосованию!"
|
||||
}
|
||||
|
||||
"Revote Warning"
|
||||
{
|
||||
"ru" "Повторное голосование начнётся через: {1}s"
|
||||
}
|
||||
|
||||
"Vote Warning"
|
||||
{
|
||||
"ru" "Внимание! Голосование за следующую карту начнётся через: {1}s"
|
||||
}
|
||||
|
||||
"Line One"
|
||||
{
|
||||
"ru" "Выбери, какая карта будет следующей..."
|
||||
}
|
||||
|
||||
"Line Two"
|
||||
{
|
||||
"ru" "...и не клацай кнопки,не подумав ;-)"
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/sv/incomplete.txt
Normal file
2
mapchooser_extended/translations/sv/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"sv" "Rösta för nästa bana!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"sv" "Röstning om nästa bana har börjat."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"sv" "Röstningen om banan har avslutats. Nästa bana kommer att bli {1}. (Fick {2}%% av {3} röster) "
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"sv" "Den nuvarande banan har förlängts. (Fick {1}%% av {2} röster) "
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"sv" "Förläng nuvarande bana"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"sv" "Byt inte"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"sv" "Nuvarande banan fortsätter! Röstningen har talat! (Fick {1}%% av {2} röster) "
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"sv" "Bytta nästa bana till \"{1}\". "
|
||||
}
|
||||
|
||||
}
|
2
mapchooser_extended/translations/tr/incomplete.txt
Normal file
2
mapchooser_extended/translations/tr/incomplete.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Missing "Runoff Vote Nextmap", "Number Of Votes", "Custom", "Revote Is Needed", "Revote Warning", "Vote Warning",
|
||||
"Line One", "Line Two", "Cannot Start Vote", and "Tie Vote"
|
@ -0,0 +1,43 @@
|
||||
"Phrases"
|
||||
{
|
||||
"Vote Nextmap"
|
||||
{
|
||||
"tr" "Sonraki harita için oy ver!"
|
||||
}
|
||||
|
||||
"Nextmap Voting Started"
|
||||
{
|
||||
"tr" "Sonraki harita için oylama başladı."
|
||||
}
|
||||
|
||||
"Nextmap Voting Finished"
|
||||
{
|
||||
"tr" "Harita oylaması sona erdi. Sıradaki harita {1} olacak. ({3} oyun %%{2}'i alındı) "
|
||||
}
|
||||
|
||||
"Current Map Extended"
|
||||
{
|
||||
"tr" "Geçerli harita uzatıldı. ({2} oyun %%{1}'i alındı) "
|
||||
}
|
||||
|
||||
"Extend Map"
|
||||
{
|
||||
"tr" "Geçerli Haritayı Uzat"
|
||||
}
|
||||
|
||||
"Dont Change"
|
||||
{
|
||||
"tr" "Değiştirme"
|
||||
}
|
||||
|
||||
"Current Map Stays"
|
||||
{
|
||||
"tr" "Geçerli harita devam ediyor! Oylama konuştu! ({2} oyun %%{1}'i alındı) "
|
||||
}
|
||||
|
||||
"Changed Next Map"
|
||||
{
|
||||
"tr" "Sıradaki harita \"{1}\" olarak değiştirildi."
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user