mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-08 10:58:27 +00:00
commit
f9b67450db
@ -24,6 +24,7 @@ The chat plugin manipulates chat messages sent by players.
|
|||||||
It includes custom chat names, tags, colors and all can be defined by the players/admins.
|
It includes custom chat names, tags, colors and all can be defined by the players/admins.
|
||||||
Admins need the chat flag, or the "shavit_chat" override (good for a donator perk).
|
Admins need the chat flag, or the "shavit_chat" override (good for a donator perk).
|
||||||
There's a user-friendly command named !cchelp so the users can easily understand what's going on.
|
There's a user-friendly command named !cchelp so the users can easily understand what's going on.
|
||||||
|
In addition, it integrates with rankings and allows you to have titles for players according to their ranking, relative ranking or points in the server using !chatranks.
|
||||||
|
|
||||||
#### shavit-hud
|
#### shavit-hud
|
||||||
The HUD plugin is `bhoptimer`'s OSD frontend.
|
The HUD plugin is `bhoptimer`'s OSD frontend.
|
||||||
|
|||||||
82
addons/sourcemod/configs/shavit-chat.cfg
Normal file
82
addons/sourcemod/configs/shavit-chat.cfg
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Available settings:
|
||||||
|
// "ranks" - inclusive rank range. (i.e. 1, 2, 10-19 or 0.0%-0.5%). Use a percent sign to use a percentile of total players. Add "p" as a prefix to use points instead of ranks, don't specify a range for points if you only want a minimum to unlock the title.
|
||||||
|
// "name" - custom name appearance. Default: "{name}"
|
||||||
|
// "message" - a prefix to the message itself. Default: ""
|
||||||
|
// "display" - display text in the !chatranks menu. "<n>" for a new line. Filling this is required.
|
||||||
|
// "free" - is this title available for everyone to use? Default: "0"
|
||||||
|
//
|
||||||
|
// Global variables:
|
||||||
|
// {default} - default color
|
||||||
|
// {team} - team color
|
||||||
|
// {green} - green color
|
||||||
|
// {name} - player name
|
||||||
|
// {clan} - clan tag
|
||||||
|
// {rand} - random color.
|
||||||
|
// {message} - message text
|
||||||
|
// {rank} - player rank (whole number)
|
||||||
|
// {rank1} - player rank in percentage (1 decimal point)
|
||||||
|
// {rank2} - player rank in percentage (2 decimal points)
|
||||||
|
// {rank3} - player rank in percentage (3 decimal points)
|
||||||
|
//
|
||||||
|
// Refer to shavit-messages.cfg for color settings.
|
||||||
|
//
|
||||||
|
"Chat"
|
||||||
|
{
|
||||||
|
"0" // unranked
|
||||||
|
{
|
||||||
|
"ranks" "0"
|
||||||
|
"name" "{team}[Unranked] {name}"
|
||||||
|
"display" "[Unranked]<n>Title used by unranked players."
|
||||||
|
}
|
||||||
|
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"ranks" "p10000"
|
||||||
|
"free" "0"
|
||||||
|
"name" "{rand}10k! {team}{name}"
|
||||||
|
"display" "10k Challenger<n>You are insane. You are a hero. You are a challenger.<n>A title awarded to the magnificent players who achieve 10,000 points."
|
||||||
|
}
|
||||||
|
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"ranks" "1"
|
||||||
|
"name" "{rand}ONE TRUE GOD {team}{name}"
|
||||||
|
"message" "{rand}"
|
||||||
|
"display" "[ONE TRUE GOD]<n>A title awarded only to the very best players."
|
||||||
|
}
|
||||||
|
|
||||||
|
"3"
|
||||||
|
{
|
||||||
|
"ranks" "2"
|
||||||
|
"name" "{green}LEGENDARY {name}"
|
||||||
|
"display" "[LEGENDARY]<n>A title obtained by legendary players."
|
||||||
|
}
|
||||||
|
|
||||||
|
"4"
|
||||||
|
{
|
||||||
|
"ranks" "3"
|
||||||
|
"name" "{green}HERO {team}{name}"
|
||||||
|
"display" "[HERO]<n>You're a hero, and you deserve this title."
|
||||||
|
}
|
||||||
|
|
||||||
|
"5"
|
||||||
|
{
|
||||||
|
"ranks" "4-10"
|
||||||
|
"name" "{rand}scrub{rand}! {name}"
|
||||||
|
"display" "scrub!<n>You're a noob."
|
||||||
|
}
|
||||||
|
|
||||||
|
"6"
|
||||||
|
{
|
||||||
|
"ranks" "11-100%"
|
||||||
|
"name" ":( {name}"
|
||||||
|
"display" "sad face<n>You're terrible. Get good!"
|
||||||
|
}
|
||||||
|
|
||||||
|
"7"
|
||||||
|
{
|
||||||
|
"free" "1"
|
||||||
|
"name" "{rand}:) {name}"
|
||||||
|
"display" ":)<n>Free chat title."
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -61,7 +61,7 @@ forward Action CP_OnChatMessage(int& author, ArrayList recipients, char[] flagst
|
|||||||
forward void CP_OnChatMessagePost(int author, ArrayList recipients, const char[] flagstring, const char[] formatstring, const char[] name, const char[] message, bool processcolors, bool removecolors);
|
forward void CP_OnChatMessagePost(int author, ArrayList recipients, const char[] flagstring, const char[] formatstring, const char[] name, const char[] message, bool processcolors, bool removecolors);
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
#if !defined REQUIRE_PLUGIN
|
||||||
public __pl_chat_processor_SetNTVOptional()
|
public void __pl_chat_processor_SetNTVOptional()
|
||||||
{
|
{
|
||||||
MarkNativeAsOptional("ChatProcessor_GetFlagFormatString");
|
MarkNativeAsOptional("ChatProcessor_GetFlagFormatString");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#define _shavit_included
|
#define _shavit_included
|
||||||
|
|
||||||
#define SHAVIT_VERSION "1.5b"
|
#define SHAVIT_VERSION "2.0.0"
|
||||||
#define STYLE_LIMIT 256
|
#define STYLE_LIMIT 256
|
||||||
#define MAX_ZONES 64
|
#define MAX_ZONES 64
|
||||||
|
|
||||||
@ -1102,12 +1102,22 @@ native StringMap Shavit_GetMapTiers();
|
|||||||
* This native will auto-assign colors and a chat prefix.
|
* This native will auto-assign colors and a chat prefix.
|
||||||
*
|
*
|
||||||
* @param client Client index.
|
* @param client Client index.
|
||||||
* @param format Formattiing rules.
|
* @param format Formatting rules.
|
||||||
* @param any Variable number of format parameters.
|
* @param any Variable number of format parameters.
|
||||||
* @return PrintToChat()
|
* @return PrintToChat()
|
||||||
*/
|
*/
|
||||||
native int Shavit_PrintToChat(int client, const char[] format, any ...);
|
native int Shavit_PrintToChat(int client, const char[] format, any ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an entry to bhoptimer's log file.
|
||||||
|
* (addons/sourcemod/logs/shavit.log)
|
||||||
|
*
|
||||||
|
* @param format Formatting rules.
|
||||||
|
* @param any Variable number of format parameters.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void Shavit_LogMessage(const char[] format, any ...);
|
||||||
|
|
||||||
// same as Shavit_PrintToChat() but loops through the whole server
|
// same as Shavit_PrintToChat() but loops through the whole server
|
||||||
// code stolen from the base halflife.inc file
|
// code stolen from the base halflife.inc file
|
||||||
stock void Shavit_PrintToChatAll(const char[] format, any ...)
|
stock void Shavit_PrintToChatAll(const char[] format, any ...)
|
||||||
|
|||||||
@ -22,25 +22,65 @@
|
|||||||
|
|
||||||
#include <sourcemod>
|
#include <sourcemod>
|
||||||
#include <chat-processor>
|
#include <chat-processor>
|
||||||
|
#include <clientprefs>
|
||||||
|
|
||||||
#undef REQUIRE_PLUGIN
|
#undef REQUIRE_PLUGIN
|
||||||
#define USES_CHAT_COLORS
|
#define USES_CHAT_COLORS
|
||||||
#include <shavit>
|
#include <shavit>
|
||||||
#include <rtler>
|
#include <rtler>
|
||||||
|
|
||||||
|
#undef REQUIRE_EXTENSIONS
|
||||||
|
#include <cstrike>
|
||||||
|
|
||||||
|
enum ChatRanksCache
|
||||||
|
{
|
||||||
|
iCRRangeType, // 0 - flat, 1 - percent, 2 - point range
|
||||||
|
Float:fCRFrom,
|
||||||
|
Float:fCRTo,
|
||||||
|
bool:bCRFree,
|
||||||
|
String:sCRName[MAXLENGTH_NAME],
|
||||||
|
String:sCRMessage[MAXLENGTH_MESSAGE],
|
||||||
|
String:sCRDisplay[192],
|
||||||
|
CRCACHE_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Rank_Flat,
|
||||||
|
Rank_Percentage,
|
||||||
|
Rank_Points
|
||||||
|
}
|
||||||
|
|
||||||
#pragma newdecls required
|
#pragma newdecls required
|
||||||
#pragma semicolon 1
|
#pragma semicolon 1
|
||||||
|
#pragma dynamic 131072
|
||||||
|
|
||||||
// database
|
// database
|
||||||
Database gH_SQL = null;
|
Database gH_SQL = null;
|
||||||
char gS_MySQLPrefix[32];
|
char gS_MySQLPrefix[32];
|
||||||
|
|
||||||
// modules
|
// modules
|
||||||
|
bool gB_Rankings = false;
|
||||||
bool gB_RTLer = false;
|
bool gB_RTLer = false;
|
||||||
|
|
||||||
|
// cvars
|
||||||
|
ConVar gCV_RankingsIntegration = null;
|
||||||
|
ConVar gCV_CustomChat = null;
|
||||||
|
|
||||||
|
// cached cvars
|
||||||
|
bool gB_RankingsIntegration = true;
|
||||||
|
int gI_CustomChat = 1;
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
EngineVersion gEV_Type = Engine_Unknown;
|
EngineVersion gEV_Type = Engine_Unknown;
|
||||||
|
|
||||||
|
Handle gH_ChatCookie = null;
|
||||||
|
|
||||||
|
// -2: auto-assign - user will fallback to this if they're on an index that they don't have access to.
|
||||||
|
// -1: custom ccname/ccmsg
|
||||||
|
int gI_ChatSelection[MAXPLAYERS+1];
|
||||||
|
ArrayList gA_ChatRanks = null;
|
||||||
|
|
||||||
bool gB_AllowCustom[MAXPLAYERS+1];
|
bool gB_AllowCustom[MAXPLAYERS+1];
|
||||||
|
|
||||||
bool gB_NameEnabled[MAXPLAYERS+1];
|
bool gB_NameEnabled[MAXPLAYERS+1];
|
||||||
@ -53,7 +93,7 @@ public Plugin myinfo =
|
|||||||
{
|
{
|
||||||
name = "[shavit] Chat",
|
name = "[shavit] Chat",
|
||||||
author = "shavit",
|
author = "shavit",
|
||||||
description = "Custom chat privileges (custom name and message colors).",
|
description = "Custom chat privileges (custom name/message colors), and rankings integration.",
|
||||||
version = SHAVIT_VERSION,
|
version = SHAVIT_VERSION,
|
||||||
url = "https://github.com/shavitush/bhoptimer"
|
url = "https://github.com/shavitush/bhoptimer"
|
||||||
}
|
}
|
||||||
@ -79,20 +119,123 @@ public void OnPluginStart()
|
|||||||
RegConsoleCmd("sm_ccname", Command_CCName, "Toggles/sets a custom chat name. Usage: sm_ccname <text> or sm_ccname \"off\" to disable.");
|
RegConsoleCmd("sm_ccname", Command_CCName, "Toggles/sets a custom chat name. Usage: sm_ccname <text> or sm_ccname \"off\" to disable.");
|
||||||
RegConsoleCmd("sm_ccmsg", Command_CCMessage, "Toggles/sets a custom chat message color. Usage: sm_ccmsg <color> or sm_ccmsg \"off\" to disable.");
|
RegConsoleCmd("sm_ccmsg", Command_CCMessage, "Toggles/sets a custom chat message color. Usage: sm_ccmsg <color> or sm_ccmsg \"off\" to disable.");
|
||||||
RegConsoleCmd("sm_ccmessage", Command_CCMessage, "Toggles/sets a custom chat message color. Usage: sm_ccmessage <color> or sm_ccmessage \"off\" to disable.");
|
RegConsoleCmd("sm_ccmessage", Command_CCMessage, "Toggles/sets a custom chat message color. Usage: sm_ccmessage <color> or sm_ccmessage \"off\" to disable.");
|
||||||
|
RegConsoleCmd("sm_chatrank", Command_ChatRanks, "View a menu with the chat ranks available to you.");
|
||||||
|
RegConsoleCmd("sm_chatranks", Command_ChatRanks, "View a menu with the chat ranks available to you.");
|
||||||
|
|
||||||
RegAdminCmd("sm_cclist", Command_CCList, ADMFLAG_CHAT, "Print the custom chat setting of all online players.");
|
RegAdminCmd("sm_cclist", Command_CCList, ADMFLAG_CHAT, "Print the custom chat setting of all online players.");
|
||||||
|
RegAdminCmd("sm_reloadchatranks", Command_ReloadChatRanks, ADMFLAG_ROOT, "Reloads the chatranks config file.");
|
||||||
|
|
||||||
|
gCV_RankingsIntegration = CreateConVar("shavit_chat_rankings", "1", "Integrate with rankings?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
||||||
|
gCV_CustomChat = CreateConVar("shavit_chat_customchat", "1", "Allow custom chat names or message colors?\n0 - Disabled\n1 - Enabled (requires chat flag/'shavit_chat' override)\n2 - Allow use by everyone", 0, true, 0.0, true, 2.0);
|
||||||
|
|
||||||
|
gCV_RankingsIntegration.AddChangeHook(OnConVarChanged);
|
||||||
|
gCV_CustomChat.AddChangeHook(OnConVarChanged);
|
||||||
|
|
||||||
|
AutoExecConfig();
|
||||||
|
|
||||||
|
gH_ChatCookie = RegClientCookie("shavit_chat_selection", "Chat settings", CookieAccess_Protected);
|
||||||
|
gA_ChatRanks = new ArrayList(view_as<int>(CRCACHE_SIZE));
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
{
|
{
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i))
|
if(IsClientInGame(i) && !IsFakeClient(i))
|
||||||
{
|
{
|
||||||
OnClientPostAdminCheck(i);
|
OnClientPostAdminCheck(i);
|
||||||
|
|
||||||
|
if(AreClientCookiesCached(i))
|
||||||
|
{
|
||||||
|
OnClientCookiesCached(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SQL_SetPrefix();
|
SQL_SetPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnMapStart()
|
||||||
|
{
|
||||||
|
if(!LoadChatConfig())
|
||||||
|
{
|
||||||
|
SetFailState("Could not load the chat configuration file. Make sure it exists (addons/sourcemod/configs/shavit-chat.cfg) and follows the proper syntax!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadChatConfig()
|
||||||
|
{
|
||||||
|
char[] sPath = new char[PLATFORM_MAX_PATH];
|
||||||
|
BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "configs/shavit-chat.cfg");
|
||||||
|
|
||||||
|
KeyValues kv = new KeyValues("shavit-chat");
|
||||||
|
|
||||||
|
if(!kv.ImportFromFile(sPath) || !kv.GotoFirstSubKey())
|
||||||
|
{
|
||||||
|
delete kv;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gA_ChatRanks.Clear();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
any[] aChatTitle = new any[CRCACHE_SIZE];
|
||||||
|
char[] sRanks = new char[32];
|
||||||
|
kv.GetString("ranks", sRanks, MAXLENGTH_NAME, "0");
|
||||||
|
|
||||||
|
if(sRanks[0] == 'p')
|
||||||
|
{
|
||||||
|
aChatTitle[iCRRangeType] = Rank_Points;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aChatTitle[iCRRangeType] = (StrContains(sRanks, "%%") == -1)? Rank_Flat:Rank_Percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplaceString(sRanks, 32, "p", "");
|
||||||
|
ReplaceString(sRanks, 32, "%%", "");
|
||||||
|
|
||||||
|
if(StrContains(sRanks, "-") != -1)
|
||||||
|
{
|
||||||
|
char[][] sExplodedString = new char[2][16];
|
||||||
|
ExplodeString(sRanks, "-", sExplodedString, 2, 64);
|
||||||
|
aChatTitle[fCRFrom] = StringToFloat(sExplodedString[0]);
|
||||||
|
aChatTitle[fCRTo] = StringToFloat(sExplodedString[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float fRank = StringToFloat(sRanks);
|
||||||
|
|
||||||
|
aChatTitle[fCRFrom] = fRank;
|
||||||
|
aChatTitle[fCRTo] = (aChatTitle[iCRRangeType] != Rank_Points)? fRank:2147483648.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aChatTitle[bCRFree] = view_as<bool>(kv.GetNum("free", false));
|
||||||
|
|
||||||
|
kv.GetString("name", aChatTitle[sCRName], MAXLENGTH_NAME, "{name}");
|
||||||
|
kv.GetString("message", aChatTitle[sCRMessage], MAXLENGTH_MESSAGE, "");
|
||||||
|
kv.GetString("display", aChatTitle[sCRDisplay], 192, "");
|
||||||
|
|
||||||
|
if(strlen(aChatTitle[sCRDisplay]) > 0)
|
||||||
|
{
|
||||||
|
gA_ChatRanks.PushArray(aChatTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(kv.GotoNextKey());
|
||||||
|
|
||||||
|
delete kv;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||||
|
{
|
||||||
|
gB_RankingsIntegration = gCV_RankingsIntegration.BoolValue;
|
||||||
|
gI_CustomChat = gCV_CustomChat.IntValue;
|
||||||
|
}
|
||||||
|
|
||||||
public void Shavit_OnDatabaseLoaded()
|
public void Shavit_OnDatabaseLoaded()
|
||||||
{
|
{
|
||||||
gH_SQL = Shavit_GetDatabase();
|
gH_SQL = Shavit_GetDatabase();
|
||||||
@ -154,6 +297,11 @@ public void OnLibraryAdded(const char[] name)
|
|||||||
{
|
{
|
||||||
gB_RTLer = true;
|
gB_RTLer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(StrEqual(name, "shavit-rankings"))
|
||||||
|
{
|
||||||
|
gB_Rankings = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLibraryRemoved(const char[] name)
|
public void OnLibraryRemoved(const char[] name)
|
||||||
@ -162,6 +310,28 @@ public void OnLibraryRemoved(const char[] name)
|
|||||||
{
|
{
|
||||||
gB_RTLer = false;
|
gB_RTLer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(StrEqual(name, "shavit-rankings"))
|
||||||
|
{
|
||||||
|
gB_Rankings = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientCookiesCached(int client)
|
||||||
|
{
|
||||||
|
char[] sChatSettings = new char[8];
|
||||||
|
GetClientCookie(client, gH_ChatCookie, sChatSettings, 8);
|
||||||
|
|
||||||
|
if(strlen(sChatSettings) == 0)
|
||||||
|
{
|
||||||
|
SetClientCookie(client, gH_ChatCookie, "-2");
|
||||||
|
gI_ChatSelection[client] = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gI_ChatSelection[client] = StringToInt(sChatSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
public void OnClientDisconnect(int client)
|
||||||
@ -182,7 +352,7 @@ public void OnClientPutInServer(int client)
|
|||||||
|
|
||||||
public void OnClientPostAdminCheck(int client)
|
public void OnClientPostAdminCheck(int client)
|
||||||
{
|
{
|
||||||
gB_AllowCustom[client] = CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT);
|
gB_AllowCustom[client] = gI_CustomChat > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gI_CustomChat == 2);
|
||||||
|
|
||||||
if(gH_SQL != null)
|
if(gH_SQL != null)
|
||||||
{
|
{
|
||||||
@ -201,14 +371,16 @@ public Action Command_CCHelp(int client, int args)
|
|||||||
|
|
||||||
Shavit_PrintToChat(client, "%T", "CheckConsole", client);
|
Shavit_PrintToChat(client, "%T", "CheckConsole", client);
|
||||||
|
|
||||||
PrintToConsole(client, "%T\n", "CCHelp_Intro", client);
|
PrintToConsole(client, "%T\n\n%T\n\n%T\n",
|
||||||
PrintToConsole(client, "%T", "CCHelp_Generic", client);
|
"CCHelp_Intro", client,
|
||||||
PrintToConsole(client, "%T", "CCHelp_GenericVariables", client);
|
"CCHelp_Generic", client,
|
||||||
|
"CCHelp_GenericVariables", client);
|
||||||
|
|
||||||
if(IsSource2013(gEV_Type))
|
if(IsSource2013(gEV_Type))
|
||||||
{
|
{
|
||||||
PrintToConsole(client, "%T", "CCHelp_CSS_1", client);
|
PrintToConsole(client, "%T\n\n%T",
|
||||||
PrintToConsole(client, "%T", "CCHelp_CSS_2", client);
|
"CCHelp_CSS_1", client,
|
||||||
|
"CCHelp_CSS_2", client);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -237,8 +409,6 @@ public Action Command_CCName(int client, int args)
|
|||||||
|
|
||||||
char[] sArgs = new char[128];
|
char[] sArgs = new char[128];
|
||||||
GetCmdArgString(sArgs, 128);
|
GetCmdArgString(sArgs, 128);
|
||||||
TrimString(sArgs);
|
|
||||||
FormatColors(sArgs, 128, true, true);
|
|
||||||
|
|
||||||
if(args == 0 || strlen(sArgs) == 0)
|
if(args == 0 || strlen(sArgs) == 0)
|
||||||
{
|
{
|
||||||
@ -287,8 +457,6 @@ public Action Command_CCMessage(int client, int args)
|
|||||||
|
|
||||||
char[] sArgs = new char[32];
|
char[] sArgs = new char[32];
|
||||||
GetCmdArgString(sArgs, 32);
|
GetCmdArgString(sArgs, 32);
|
||||||
TrimString(sArgs);
|
|
||||||
FormatColors(sArgs, 32, true, true);
|
|
||||||
|
|
||||||
if(args == 0 || strlen(sArgs) == 0)
|
if(args == 0 || strlen(sArgs) == 0)
|
||||||
{
|
{
|
||||||
@ -319,6 +487,175 @@ public Action Command_CCMessage(int client, int args)
|
|||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Action Command_ChatRanks(int client, int args)
|
||||||
|
{
|
||||||
|
if(client == 0)
|
||||||
|
{
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ShowChatRanksMenu(client, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Action ShowChatRanksMenu(int client, int item)
|
||||||
|
{
|
||||||
|
Menu menu = new Menu(MenuHandler_ChatRanks);
|
||||||
|
menu.SetTitle("%T\n ", "SelectChatRank", client);
|
||||||
|
|
||||||
|
char[] sDisplay = new char[128];
|
||||||
|
FormatEx(sDisplay, 128, "%T\n ", "AutoAssign", client);
|
||||||
|
menu.AddItem("-2", sDisplay, (gI_ChatSelection[client] == -2)? ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT);
|
||||||
|
|
||||||
|
if(gB_AllowCustom[client])
|
||||||
|
{
|
||||||
|
FormatEx(sDisplay, 128, "%T\n ", "CustomChat", client);
|
||||||
|
menu.AddItem("-1", sDisplay, (gI_ChatSelection[client] == -1)? ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int iLength = gA_ChatRanks.Length;
|
||||||
|
|
||||||
|
for(int i = 0; i < iLength; i++)
|
||||||
|
{
|
||||||
|
if(!HasRankAccess(client, i))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sInfo = new char[8];
|
||||||
|
IntToString(i, sInfo, 8);
|
||||||
|
|
||||||
|
any[] aCache = new any[CRCACHE_SIZE];
|
||||||
|
gA_ChatRanks.GetArray(i, aCache, view_as<int>(CRCACHE_SIZE));
|
||||||
|
|
||||||
|
strcopy(sDisplay, 192, aCache[sCRDisplay]);
|
||||||
|
ReplaceString(sDisplay, 192, "<n>", "\n");
|
||||||
|
StrCat(sDisplay, 192, "\n "); // to add spacing between each entry
|
||||||
|
|
||||||
|
menu.AddItem(sInfo, sDisplay, (gI_ChatSelection[client] == i)? ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.ExitButton = true;
|
||||||
|
menu.DisplayAt(client, item, MENU_TIME_FOREVER);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MenuHandler_ChatRanks(Menu menu, MenuAction action, int param1, int param2)
|
||||||
|
{
|
||||||
|
if(action == MenuAction_Select)
|
||||||
|
{
|
||||||
|
char[] sInfo = new char[8];
|
||||||
|
menu.GetItem(param2, sInfo, 8);
|
||||||
|
|
||||||
|
int iChoice = StringToInt(sInfo);
|
||||||
|
|
||||||
|
gI_ChatSelection[param1] = iChoice;
|
||||||
|
SetClientCookie(param1, gH_ChatCookie, sInfo);
|
||||||
|
|
||||||
|
Shavit_PrintToChat(param1, "%T", "ChatUpdated", param1);
|
||||||
|
ShowChatRanksMenu(param1, GetMenuSelectionPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(action == MenuAction_End)
|
||||||
|
{
|
||||||
|
delete menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasRankAccess(int client, int rank)
|
||||||
|
{
|
||||||
|
if(rank == -2 ||
|
||||||
|
(rank == -1 && gB_AllowCustom[client]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(!(0 <= rank <= (gA_ChatRanks.Length - 1)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static any aCache[view_as<int>(bCRFree)+1];
|
||||||
|
gA_ChatRanks.GetArray(rank, aCache[0], sizeof(aCache)); // a hack to only retrieve up to what we want
|
||||||
|
|
||||||
|
if(aCache[bCRFree])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!gB_Rankings || !gB_RankingsIntegration)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fRank = (aCache[iCRRangeType] != Rank_Points)? float(Shavit_GetRank(client)):Shavit_GetPoints(client);
|
||||||
|
|
||||||
|
if(aCache[iCRRangeType] == Rank_Flat || aCache[iCRRangeType] == Rank_Points)
|
||||||
|
{
|
||||||
|
if(aCache[fCRFrom] <= fRank <= aCache[fCRTo])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int iRanked = Shavit_GetRankedPlayers();
|
||||||
|
|
||||||
|
// just in case..
|
||||||
|
if(iRanked == 0)
|
||||||
|
{
|
||||||
|
iRanked = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fPercentile = (fRank / iRanked) * 100.0;
|
||||||
|
|
||||||
|
if(aCache[fCRFrom] <= fPercentile <= aCache[fCRTo])
|
||||||
|
{
|
||||||
|
PrintToServer("%.1f <= %.2f <= %.2f", aCache[fCRFrom], fPercentile, aCache[fCRTo]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetPlayerChatSettings(int client, char[] name, char[] message)
|
||||||
|
{
|
||||||
|
int iRank = gI_ChatSelection[client];
|
||||||
|
|
||||||
|
if(!HasRankAccess(client, iRank))
|
||||||
|
{
|
||||||
|
iRank = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iLength = gA_ChatRanks.Length;
|
||||||
|
|
||||||
|
// if we auto-assign, start looking for an available rank starting from index 0
|
||||||
|
if(iRank == -2)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < iLength; i++)
|
||||||
|
{
|
||||||
|
if(HasRankAccess(client, i))
|
||||||
|
{
|
||||||
|
iRank = i;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 <= iRank <= (iLength - 1))
|
||||||
|
{
|
||||||
|
any[] aCache = new any[CRCACHE_SIZE];
|
||||||
|
gA_ChatRanks.GetArray(iRank, aCache, view_as<int>(CRCACHE_SIZE));
|
||||||
|
|
||||||
|
strcopy(name, MAXLENGTH_NAME, aCache[sCRName]);
|
||||||
|
strcopy(message, MAXLENGTH_NAME, aCache[sCRMessage]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Action Command_CCList(int client, int args)
|
public Action Command_CCList(int client, int args)
|
||||||
{
|
{
|
||||||
ReplyToCommand(client, "%T", "CheckConsole", client);
|
ReplyToCommand(client, "%T", "CheckConsole", client);
|
||||||
@ -327,36 +664,67 @@ public Action Command_CCList(int client, int args)
|
|||||||
{
|
{
|
||||||
if(gB_AllowCustom[i])
|
if(gB_AllowCustom[i])
|
||||||
{
|
{
|
||||||
PrintToConsole(client, "%N (%d/%d) (name: \"%s\"; message: \"%s\")", i, i, GetClientUserId(i), gS_CustomName[i], gS_CustomMessage[i]);
|
PrintToConsole(client, "%N (%d/#%d) (name: \"%s\"; message: \"%s\")", i, i, GetClientUserId(i), gS_CustomName[i], gS_CustomMessage[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Action Command_ReloadChatRanks(int client, int args)
|
||||||
|
{
|
||||||
|
if(LoadChatConfig())
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "Reloaded chatranks config.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool &processcolors, bool &removecolors)
|
public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool &processcolors, bool &removecolors)
|
||||||
{
|
{
|
||||||
if(author == 0 || !gB_AllowCustom[author])
|
if(author == 0)
|
||||||
{
|
{
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gB_NameEnabled[author] && strlen(gS_CustomName[author]) > 0)
|
char[] sName = new char[MAXLENGTH_NAME];
|
||||||
|
char[] sMessage = new char[MAXLENGTH_MESSAGE];
|
||||||
|
|
||||||
|
if(gB_AllowCustom[author] && gI_ChatSelection[author] == -1)
|
||||||
{
|
{
|
||||||
char[] sName = new char[MAX_NAME_LENGTH];
|
if(gB_NameEnabled[author])
|
||||||
GetClientName(author, sName, MAX_NAME_LENGTH);
|
{
|
||||||
ReplaceString(gS_CustomName[author], MAXLENGTH_NAME, "{name}", sName);
|
strcopy(sName, MAXLENGTH_NAME, gS_CustomName[author]);
|
||||||
|
}
|
||||||
|
|
||||||
strcopy(name, MAXLENGTH_NAME, gS_CustomName[author]);
|
if(gB_MessageEnabled[author])
|
||||||
FormatRandom(name, MAXLENGTH_NAME);
|
{
|
||||||
|
strcopy(sMessage, MAXLENGTH_MESSAGE, gS_CustomMessage[author]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetPlayerChatSettings(author, sName, sMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strlen(sName) > 0)
|
||||||
|
{
|
||||||
if(gEV_Type == Engine_CSGO)
|
if(gEV_Type == Engine_CSGO)
|
||||||
{
|
{
|
||||||
Format(name, MAXLENGTH_NAME, " %s", name);
|
FormatEx(name, MAXLENGTH_NAME, " %s", sName);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gB_MessageEnabled[author] && strlen(gS_CustomMessage[author]) > 0)
|
else
|
||||||
|
{
|
||||||
|
strcopy(name, MAXLENGTH_NAME, sName);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormatChat(author, name, MAXLENGTH_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strlen(sMessage) > 0)
|
||||||
{
|
{
|
||||||
char[] sTemp = new char[MAXLENGTH_MESSAGE];
|
char[] sTemp = new char[MAXLENGTH_MESSAGE];
|
||||||
|
|
||||||
@ -364,34 +732,21 @@ public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstr
|
|||||||
if(gB_RTLer && RTLify(sTemp, MAXLENGTH_MESSAGE, message) > 0)
|
if(gB_RTLer && RTLify(sTemp, MAXLENGTH_MESSAGE, message) > 0)
|
||||||
{
|
{
|
||||||
TrimString(message);
|
TrimString(message);
|
||||||
Format(message, MAXLENGTH_MESSAGE, "%s%s", message, gS_CustomMessage[author]);
|
Format(message, MAXLENGTH_MESSAGE, "%s%s", message, sMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Format(message, MAXLENGTH_MESSAGE, "%s%s", gS_CustomMessage[author], message);
|
Format(message, MAXLENGTH_MESSAGE, "%s%s", sMessage, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatRandom(message, MAXLENGTH_MESSAGE);
|
FormatChat(author, message, MAXLENGTH_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined DEBUG
|
#if defined DEBUG
|
||||||
PrintToServer("%N %s", author, flagstring);
|
PrintToServer("%N %s", author, flagstring);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool allchat = (StrContains(flagstring, "_All") != -1);
|
|
||||||
int team = GetClientTeam(author);
|
|
||||||
|
|
||||||
recipients.Clear();
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(i == author || (IsClientInGame(i) && (allchat || GetClientTeam(i) == team)))
|
|
||||||
{
|
|
||||||
recipients.Push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removecolors = true;
|
removecolors = true;
|
||||||
processcolors = false;
|
processcolors = false;
|
||||||
|
|
||||||
@ -407,10 +762,13 @@ void FormatColors(char[] buffer, int size, bool colors, bool escape)
|
|||||||
ReplaceString(buffer, size, gS_GlobalColorNames[i], gS_GlobalColors[i]);
|
ReplaceString(buffer, size, gS_GlobalColorNames[i], gS_GlobalColors[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(gEV_Type == Engine_CSGO)
|
||||||
|
{
|
||||||
for(int i = 0; i < sizeof(gS_CSGOColorNames); i++)
|
for(int i = 0; i < sizeof(gS_CSGOColorNames); i++)
|
||||||
{
|
{
|
||||||
ReplaceString(buffer, size, gS_CSGOColorNames[i], gS_CSGOColors[i]);
|
ReplaceString(buffer, size, gS_CSGOColorNames[i], gS_CSGOColors[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReplaceString(buffer, size, "^", "\x07");
|
ReplaceString(buffer, size, "^", "\x07");
|
||||||
ReplaceString(buffer, size, "{RGB}", "\x07");
|
ReplaceString(buffer, size, "{RGB}", "\x07");
|
||||||
@ -424,8 +782,10 @@ void FormatColors(char[] buffer, int size, bool colors, bool escape)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormatRandom(char[] buffer, int size)
|
void FormatChat(int client, char[] buffer, int size)
|
||||||
{
|
{
|
||||||
|
FormatColors(buffer, size, true, true);
|
||||||
|
|
||||||
char[] temp = new char[8];
|
char[] temp = new char[8];
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -446,6 +806,42 @@ void FormatRandom(char[] buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while(ReplaceStringEx(buffer, size, "{rand}", temp) > 0);
|
while(ReplaceStringEx(buffer, size, "{rand}", temp) > 0);
|
||||||
|
|
||||||
|
if(gEV_Type != Engine_TF2)
|
||||||
|
{
|
||||||
|
char[] sTag = new char[32];
|
||||||
|
CS_GetClientClanTag(client, sTag, 32);
|
||||||
|
ReplaceString(buffer, size, "{clan}", sTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gB_Rankings)
|
||||||
|
{
|
||||||
|
int iRank = Shavit_GetRank(client);
|
||||||
|
char[] sRank = new char[16];
|
||||||
|
IntToString(iRank, sRank, 16);
|
||||||
|
ReplaceString(buffer, size, "{rank}", sRank);
|
||||||
|
|
||||||
|
int iRanked = Shavit_GetRankedPlayers();
|
||||||
|
|
||||||
|
if(iRanked == 0)
|
||||||
|
{
|
||||||
|
iRanked = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fPercentile = (float(iRank) / iRanked) * 100.0;
|
||||||
|
FormatEx(sRank, 16, "%.01f", fPercentile);
|
||||||
|
ReplaceString(buffer, size, "{rank1}", sRank);
|
||||||
|
|
||||||
|
FormatEx(sRank, 16, "%.02f", fPercentile);
|
||||||
|
ReplaceString(buffer, size, "{rank2}", sRank);
|
||||||
|
|
||||||
|
FormatEx(sRank, 16, "%.03f", fPercentile);
|
||||||
|
ReplaceString(buffer, size, "{rank3}", sRank);
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sName = new char[MAX_NAME_LENGTH];
|
||||||
|
GetClientName(client, sName, MAX_NAME_LENGTH);
|
||||||
|
ReplaceString(buffer, size, "{name}", sName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RealRandomInt(int min, int max)
|
int RealRandomInt(int min, int max)
|
||||||
|
|||||||
@ -94,22 +94,16 @@ bool gB_Zones = false;
|
|||||||
bool gB_WR = false;
|
bool gB_WR = false;
|
||||||
|
|
||||||
// cvars
|
// cvars
|
||||||
ConVar gCV_Autobhop = null;
|
|
||||||
ConVar gCV_LeftRight = null;
|
|
||||||
ConVar gCV_Restart = null;
|
ConVar gCV_Restart = null;
|
||||||
ConVar gCV_Pause = null;
|
ConVar gCV_Pause = null;
|
||||||
ConVar gCV_NoStaminaReset = null;
|
|
||||||
ConVar gCV_AllowTimerWithoutZone = null;
|
ConVar gCV_AllowTimerWithoutZone = null;
|
||||||
ConVar gCV_BlockPreJump = null;
|
ConVar gCV_BlockPreJump = null;
|
||||||
ConVar gCV_NoZAxisSpeed = null;
|
ConVar gCV_NoZAxisSpeed = null;
|
||||||
ConVar gCV_VelocityTeleport = null;
|
ConVar gCV_VelocityTeleport = null;
|
||||||
|
|
||||||
// cached cvars
|
// cached cvars
|
||||||
bool gB_Autobhop = true;
|
|
||||||
bool gB_LeftRight = true;
|
|
||||||
bool gB_Restart = true;
|
bool gB_Restart = true;
|
||||||
bool gB_Pause = true;
|
bool gB_Pause = true;
|
||||||
bool gB_NoStaminaReset = true;
|
|
||||||
bool gB_AllowTimerWithoutZone = false;
|
bool gB_AllowTimerWithoutZone = false;
|
||||||
bool gB_BlockPreJump = false;
|
bool gB_BlockPreJump = false;
|
||||||
bool gB_NoZAxisSpeed = true;
|
bool gB_NoZAxisSpeed = true;
|
||||||
@ -135,6 +129,7 @@ char gS_ChatStrings[CHATSETTINGS_SIZE][128];
|
|||||||
// misc cache
|
// misc cache
|
||||||
bool gB_StopChatSound = false;
|
bool gB_StopChatSound = false;
|
||||||
bool gB_HookedJump = false;
|
bool gB_HookedJump = false;
|
||||||
|
char gS_LogPath[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
// kz support
|
// kz support
|
||||||
bool gB_KZMap = false;
|
bool gB_KZMap = false;
|
||||||
@ -169,6 +164,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
|||||||
CreateNative("Shavit_IsKZMap", Native_IsKZMap);
|
CreateNative("Shavit_IsKZMap", Native_IsKZMap);
|
||||||
CreateNative("Shavit_IsPracticeMode", Native_IsPracticeMode);
|
CreateNative("Shavit_IsPracticeMode", Native_IsPracticeMode);
|
||||||
CreateNative("Shavit_LoadSnapshot", Native_LoadSnapshot);
|
CreateNative("Shavit_LoadSnapshot", Native_LoadSnapshot);
|
||||||
|
CreateNative("Shavit_LogMessage", Native_LogMessage);
|
||||||
CreateNative("Shavit_MarkKZMap", Native_MarkKZMap);
|
CreateNative("Shavit_MarkKZMap", Native_MarkKZMap);
|
||||||
CreateNative("Shavit_PauseTimer", Native_PauseTimer);
|
CreateNative("Shavit_PauseTimer", Native_PauseTimer);
|
||||||
CreateNative("Shavit_PrintToChat", Native_PrintToChat);
|
CreateNative("Shavit_PrintToChat", Native_PrintToChat);
|
||||||
@ -282,29 +278,26 @@ public void OnPluginStart()
|
|||||||
|
|
||||||
// style commands
|
// style commands
|
||||||
gSM_StyleCommands = new StringMap();
|
gSM_StyleCommands = new StringMap();
|
||||||
// commands END
|
|
||||||
|
|
||||||
#if defined DEBUG
|
#if defined DEBUG
|
||||||
RegConsoleCmd("sm_finishtest", Command_FinishTest);
|
RegConsoleCmd("sm_finishtest", Command_FinishTest);
|
||||||
#endif
|
#endif
|
||||||
|
// commands END
|
||||||
|
|
||||||
|
// logs
|
||||||
|
BuildPath(Path_SM, gS_LogPath, PLATFORM_MAX_PATH, "logs/shavit.log");
|
||||||
|
|
||||||
CreateConVar("shavit_version", SHAVIT_VERSION, "Plugin version.", (FCVAR_NOTIFY | FCVAR_DONTRECORD));
|
CreateConVar("shavit_version", SHAVIT_VERSION, "Plugin version.", (FCVAR_NOTIFY | FCVAR_DONTRECORD));
|
||||||
|
|
||||||
gCV_Autobhop = CreateConVar("shavit_core_autobhop", "1", "Enable autobhop?\nWill be forced to not work if STYLE_AUTOBHOP is not defined for a style!", FCVAR_NOTIFY, true, 0.0, true, 1.0);
|
|
||||||
gCV_LeftRight = CreateConVar("shavit_core_blockleftright", "1", "Block +left/right?", 0, true, 0.0, true, 1.0);
|
|
||||||
gCV_Restart = CreateConVar("shavit_core_restart", "1", "Allow commands that restart the timer?", 0, true, 0.0, true, 1.0);
|
gCV_Restart = CreateConVar("shavit_core_restart", "1", "Allow commands that restart the timer?", 0, true, 0.0, true, 1.0);
|
||||||
gCV_Pause = CreateConVar("shavit_core_pause", "1", "Allow pausing?", 0, true, 0.0, true, 1.0);
|
gCV_Pause = CreateConVar("shavit_core_pause", "1", "Allow pausing?", 0, true, 0.0, true, 1.0);
|
||||||
gCV_NoStaminaReset = CreateConVar("shavit_core_nostaminareset", "1", "Disables the built-in stamina reset.\nAlso known as 'easybhop'.\nWill be forced to not work if STYLE_EASYBHOP is not defined for a style!", 0, true, 0.0, true, 1.0);
|
|
||||||
gCV_AllowTimerWithoutZone = CreateConVar("shavit_core_timernozone", "0", "Allow the timer to start if there's no start zone?", 0, true, 0.0, true, 1.0);
|
gCV_AllowTimerWithoutZone = CreateConVar("shavit_core_timernozone", "0", "Allow the timer to start if there's no start zone?", 0, true, 0.0, true, 1.0);
|
||||||
gCV_BlockPreJump = CreateConVar("shavit_core_blockprejump", "0", "Prevents jumping in the start zone.", 0, true, 0.0, true, 1.0);
|
gCV_BlockPreJump = CreateConVar("shavit_core_blockprejump", "0", "Prevents jumping in the start zone.", 0, true, 0.0, true, 1.0);
|
||||||
gCV_NoZAxisSpeed = CreateConVar("shavit_core_nozaxisspeed", "1", "Don't start timer if vertical speed exists (btimes style).", 0, true, 0.0, true, 1.0);
|
gCV_NoZAxisSpeed = CreateConVar("shavit_core_nozaxisspeed", "1", "Don't start timer if vertical speed exists (btimes style).", 0, true, 0.0, true, 1.0);
|
||||||
gCV_VelocityTeleport = CreateConVar("shavit_core_velocityteleport", "0", "Teleport the client when changing its velocity? (for special styles)", 0, true, 0.0, true, 1.0);
|
gCV_VelocityTeleport = CreateConVar("shavit_core_velocityteleport", "0", "Teleport the client when changing its velocity? (for special styles)", 0, true, 0.0, true, 1.0);
|
||||||
|
|
||||||
gCV_Autobhop.AddChangeHook(OnConVarChanged);
|
|
||||||
gCV_LeftRight.AddChangeHook(OnConVarChanged);
|
|
||||||
gCV_Restart.AddChangeHook(OnConVarChanged);
|
gCV_Restart.AddChangeHook(OnConVarChanged);
|
||||||
gCV_Pause.AddChangeHook(OnConVarChanged);
|
gCV_Pause.AddChangeHook(OnConVarChanged);
|
||||||
gCV_NoStaminaReset.AddChangeHook(OnConVarChanged);
|
|
||||||
gCV_AllowTimerWithoutZone.AddChangeHook(OnConVarChanged);
|
gCV_AllowTimerWithoutZone.AddChangeHook(OnConVarChanged);
|
||||||
gCV_BlockPreJump.AddChangeHook(OnConVarChanged);
|
gCV_BlockPreJump.AddChangeHook(OnConVarChanged);
|
||||||
gCV_NoZAxisSpeed.AddChangeHook(OnConVarChanged);
|
gCV_NoZAxisSpeed.AddChangeHook(OnConVarChanged);
|
||||||
@ -342,11 +335,8 @@ public void OnPluginStart()
|
|||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||||
{
|
{
|
||||||
gB_Autobhop = gCV_Autobhop.BoolValue;
|
|
||||||
gB_LeftRight = gCV_LeftRight.BoolValue;
|
|
||||||
gB_Restart = gCV_Restart.BoolValue;
|
gB_Restart = gCV_Restart.BoolValue;
|
||||||
gB_Pause = gCV_Pause.BoolValue;
|
gB_Pause = gCV_Pause.BoolValue;
|
||||||
gB_NoStaminaReset = gCV_NoStaminaReset.BoolValue;
|
|
||||||
gB_AllowTimerWithoutZone = gCV_AllowTimerWithoutZone.BoolValue;
|
gB_AllowTimerWithoutZone = gCV_AllowTimerWithoutZone.BoolValue;
|
||||||
gB_BlockPreJump = gCV_BlockPreJump.BoolValue;
|
gB_BlockPreJump = gCV_BlockPreJump.BoolValue;
|
||||||
gB_NoZAxisSpeed = gCV_NoZAxisSpeed.BoolValue;
|
gB_NoZAxisSpeed = gCV_NoZAxisSpeed.BoolValue;
|
||||||
@ -801,7 +791,7 @@ void DoJump(int client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TF2 doesn't use stamina
|
// TF2 doesn't use stamina
|
||||||
if(gEV_Type != Engine_TF2 && (gB_NoStaminaReset && gA_StyleSettings[gBS_Style[client]][bEasybhop]) || Shavit_InsideZone(client, Zone_Easybhop, gI_Track[client]))
|
if(gEV_Type != Engine_TF2 && (gA_StyleSettings[gBS_Style[client]][bEasybhop]) || Shavit_InsideZone(client, Zone_Easybhop, gI_Track[client]))
|
||||||
{
|
{
|
||||||
SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
|
SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
|
||||||
}
|
}
|
||||||
@ -1040,11 +1030,11 @@ public int Native_StopChatSound(Handle handler, int numParams)
|
|||||||
public int Native_PrintToChat(Handle handler, int numParams)
|
public int Native_PrintToChat(Handle handler, int numParams)
|
||||||
{
|
{
|
||||||
int client = GetNativeCell(1);
|
int client = GetNativeCell(1);
|
||||||
static int written = 0; // useless?
|
static int iWritten = 0; // useless?
|
||||||
|
|
||||||
char[] buffer = new char[300];
|
char[] sBuffer = new char[300];
|
||||||
FormatNativeString(0, 2, 3, 300, written, buffer);
|
FormatNativeString(0, 2, 3, 300, iWritten, sBuffer);
|
||||||
Format(buffer, 300, "%s %s%s", gS_ChatStrings[sMessagePrefix], gS_ChatStrings[sMessageText], buffer);
|
Format(sBuffer, 300, "%s %s%s", gS_ChatStrings[sMessagePrefix], gS_ChatStrings[sMessageText], sBuffer);
|
||||||
|
|
||||||
if(IsSource2013(gEV_Type))
|
if(IsSource2013(gEV_Type))
|
||||||
{
|
{
|
||||||
@ -1054,7 +1044,7 @@ public int Native_PrintToChat(Handle handler, int numParams)
|
|||||||
{
|
{
|
||||||
BfWriteByte(hSayText2, 0);
|
BfWriteByte(hSayText2, 0);
|
||||||
BfWriteByte(hSayText2, !gB_StopChatSound);
|
BfWriteByte(hSayText2, !gB_StopChatSound);
|
||||||
BfWriteString(hSayText2, buffer);
|
BfWriteString(hSayText2, sBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndMessage();
|
EndMessage();
|
||||||
@ -1062,7 +1052,7 @@ public int Native_PrintToChat(Handle handler, int numParams)
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrintToChat(client, " %s", buffer);
|
PrintToChat(client, " %s", sBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
gB_StopChatSound = false;
|
gB_StopChatSound = false;
|
||||||
@ -1177,6 +1167,23 @@ public int Native_LoadSnapshot(Handle handler, int numParams)
|
|||||||
gI_SHSW_FirstCombination[client] = view_as<int>(snapshot[iSHSWCombination]);
|
gI_SHSW_FirstCombination[client] = view_as<int>(snapshot[iSHSWCombination]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int Native_LogMessage(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
char[] sPlugin = new char[32];
|
||||||
|
|
||||||
|
if(!GetPluginInfo(plugin, PlInfo_Name, sPlugin, 32))
|
||||||
|
{
|
||||||
|
GetPluginFilename(plugin, sPlugin, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iWritten = 0;
|
||||||
|
|
||||||
|
char[] sBuffer = new char[300];
|
||||||
|
FormatNativeString(0, 1, 2, 300, iWritten, sBuffer);
|
||||||
|
|
||||||
|
LogToFileEx(gS_LogPath, "[%s] %s", sPlugin, sBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
public int Native_MarkKZMap(Handle handler, int numParams)
|
public int Native_MarkKZMap(Handle handler, int numParams)
|
||||||
{
|
{
|
||||||
gB_KZMap = true;
|
gB_KZMap = true;
|
||||||
@ -1217,6 +1224,7 @@ void StartTimer(int client, int track)
|
|||||||
|
|
||||||
if(result == Plugin_Continue)
|
if(result == Plugin_Continue)
|
||||||
{
|
{
|
||||||
|
gB_ClientPaused[client] = false;
|
||||||
gI_Strafes[client] = 0;
|
gI_Strafes[client] = 0;
|
||||||
gI_Jumps[client] = 0;
|
gI_Jumps[client] = 0;
|
||||||
gI_TotalMeasures[client] = 0;
|
gI_TotalMeasures[client] = 0;
|
||||||
@ -1862,7 +1870,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
char[] sCheatDetected = new char[64];
|
char[] sCheatDetected = new char[64];
|
||||||
|
|
||||||
// +left/right block
|
// +left/right block
|
||||||
if(gB_LeftRight && (!gB_Zones || !bInStart && ((gA_StyleSettings[gBS_Style[client]][bBlockPLeft] &&
|
if(!gB_Zones || (!bInStart && ((gA_StyleSettings[gBS_Style[client]][bBlockPLeft] &&
|
||||||
(buttons & IN_LEFT) > 0) || (gA_StyleSettings[gBS_Style[client]][bBlockPRight] && (buttons & IN_RIGHT) > 0))))
|
(buttons & IN_LEFT) > 0) || (gA_StyleSettings[gBS_Style[client]][bBlockPRight] && (buttons & IN_RIGHT) > 0))))
|
||||||
{
|
{
|
||||||
FormatEx(sCheatDetected, 64, "%T", "LeftRightCheat", client);
|
FormatEx(sCheatDetected, 64, "%T", "LeftRightCheat", client);
|
||||||
@ -1949,10 +1957,10 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
bool bSHSW = (gA_StyleSettings[gBS_Style[client]][iForceHSW] == 2) && !bInStart; // don't decide on the first valid input until out of start zone!
|
bool bSHSW = (gA_StyleSettings[gBS_Style[client]][iForceHSW] == 2) && !bInStart; // don't decide on the first valid input until out of start zone!
|
||||||
int iCombination = -1;
|
int iCombination = -1;
|
||||||
|
|
||||||
bool bForward = ((buttons & IN_FORWARD) > 0 && vel[0] >= 200.0);
|
bool bForward = ((buttons & IN_FORWARD) > 0 && vel[0] >= 100.0);
|
||||||
bool bMoveLeft = ((buttons & IN_MOVELEFT) > 0 && vel[1] <= -200.0);
|
bool bMoveLeft = ((buttons & IN_MOVELEFT) > 0 && vel[1] <= -100.0);
|
||||||
bool bBack = ((buttons & IN_BACK) > 0 && vel[0] <= -200.0);
|
bool bBack = ((buttons & IN_BACK) > 0 && vel[0] <= -100.0);
|
||||||
bool bMoveRight = ((buttons & IN_MOVERIGHT) > 0 && vel[1] >= 200.0);
|
bool bMoveRight = ((buttons & IN_MOVERIGHT) > 0 && vel[1] >= 100.0);
|
||||||
|
|
||||||
if(bSHSW)
|
if(bSHSW)
|
||||||
{
|
{
|
||||||
@ -2055,7 +2063,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gA_StyleSettings[gBS_Style[client]][bAutobhop] && gB_Autobhop && gB_Auto[client] && (buttons & IN_JUMP) > 0 && mtMoveType == MOVETYPE_WALK && !bInWater)
|
if(gA_StyleSettings[gBS_Style[client]][bAutobhop] && gB_Auto[client] && (buttons & IN_JUMP) > 0 && mtMoveType == MOVETYPE_WALK && !bInWater)
|
||||||
{
|
{
|
||||||
int iOldButtons = GetEntProp(client, Prop_Data, "m_nOldButtons");
|
int iOldButtons = GetEntProp(client, Prop_Data, "m_nOldButtons");
|
||||||
SetEntProp(client, Prop_Data, "m_nOldButtons", iOldButtons & ~IN_JUMP);
|
SetEntProp(client, Prop_Data, "m_nOldButtons", iOldButtons & ~IN_JUMP);
|
||||||
@ -2133,7 +2141,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
{
|
{
|
||||||
gI_TotalMeasures[client]++;
|
gI_TotalMeasures[client]++;
|
||||||
|
|
||||||
if((fAngle > 0.0 && vel[1] < 0.0) || (fAngle < 0.0 && vel[1] > 0.0))
|
if((fAngle > 0.0 && vel[1] <= -100.0) || (fAngle < 0.0 && vel[1] >= 100.0))
|
||||||
{
|
{
|
||||||
gI_GoodGains[client]++;
|
gI_GoodGains[client]++;
|
||||||
}
|
}
|
||||||
@ -2143,7 +2151,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
{
|
{
|
||||||
gI_TotalMeasures[client]++;
|
gI_TotalMeasures[client]++;
|
||||||
|
|
||||||
if(vel[0] != 0.0)
|
if(vel[0] <= -100.0 || vel[0] >= 100.0)
|
||||||
{
|
{
|
||||||
gI_GoodGains[client]++;
|
gI_GoodGains[client]++;
|
||||||
}
|
}
|
||||||
@ -2167,7 +2175,7 @@ void UpdateAutoBhop(int client)
|
|||||||
{
|
{
|
||||||
if(sv_autobunnyhopping != null)
|
if(sv_autobunnyhopping != null)
|
||||||
{
|
{
|
||||||
sv_autobunnyhopping.ReplicateToClient(client, (gA_StyleSettings[gBS_Style[client]][bAutobhop] && gB_Autobhop && gB_Auto[client])? "1":"0");
|
sv_autobunnyhopping.ReplicateToClient(client, (gA_StyleSettings[gBS_Style[client]][bAutobhop] && gB_Auto[client])? "1":"0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,6 @@ char gS_RadioCommands[][] = {"coverme", "takepoint", "holdpos", "regroup", "foll
|
|||||||
|
|
||||||
// cache
|
// cache
|
||||||
ConVar sv_disable_immunity_alpha = null;
|
ConVar sv_disable_immunity_alpha = null;
|
||||||
ConVar sv_footsteps = null;
|
|
||||||
ConVar hostname = null;
|
ConVar hostname = null;
|
||||||
ConVar hostport = null;
|
ConVar hostport = null;
|
||||||
|
|
||||||
@ -204,9 +203,6 @@ public void OnPluginStart()
|
|||||||
|
|
||||||
sv_disable_immunity_alpha = FindConVar("sv_disable_immunity_alpha");
|
sv_disable_immunity_alpha = FindConVar("sv_disable_immunity_alpha");
|
||||||
|
|
||||||
sv_footsteps = FindConVar("sv_footsteps");
|
|
||||||
sv_footsteps.Flags &= ~(FCVAR_NOTIFY | FCVAR_REPLICATED);
|
|
||||||
|
|
||||||
// spectator list
|
// spectator list
|
||||||
RegConsoleCmd("sm_specs", Command_Specs, "Show a list of spectators.");
|
RegConsoleCmd("sm_specs", Command_Specs, "Show a list of spectators.");
|
||||||
RegConsoleCmd("sm_spectators", Command_Specs, "Show a list of spectators.");
|
RegConsoleCmd("sm_spectators", Command_Specs, "Show a list of spectators.");
|
||||||
@ -285,7 +281,7 @@ public void OnPluginStart()
|
|||||||
|
|
||||||
// cvars and stuff
|
// cvars and stuff
|
||||||
gCV_GodMode = CreateConVar("shavit_misc_godmode", "3", "Enable godmode for players?\n0 - Disabled\n1 - Only prevent fall/world damage.\n2 - Only prevent damage from other players.\n3 - Full godmode.", 0, true, 0.0, true, 3.0);
|
gCV_GodMode = CreateConVar("shavit_misc_godmode", "3", "Enable godmode for players?\n0 - Disabled\n1 - Only prevent fall/world damage.\n2 - Only prevent damage from other players.\n3 - Full godmode.", 0, true, 0.0, true, 3.0);
|
||||||
gCV_PreSpeed = CreateConVar("shavit_misc_prespeed", "1", "Stop prespeeding in the start zone?\n0 - Disabled, fully allow prespeeding.\n1 - Limit relatively to shavit_misc_prestrafelimit.\n2 - Block bunnyhopping in startzone.\n3 - Limit to shavit_misc_prestrafelimit and block bunnyhopping.", 0, true, 0.0, true, 3.0);
|
gCV_PreSpeed = CreateConVar("shavit_misc_prespeed", "1", "Stop prespeeding in the start zone?\n0 - Disabled, fully allow prespeeding.\n1 - Limit relatively to prestrafelimit.\n2 - Block bunnyhopping in startzone.\n3 - Limit to prestrafelimit and block bunnyhopping.\n4 - Limit to prestrafelimit but allow prespeeding.", 0, true, 0.0, true, 4.0);
|
||||||
gCV_HideTeamChanges = CreateConVar("shavit_misc_hideteamchanges", "1", "Hide team changes in chat?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
gCV_HideTeamChanges = CreateConVar("shavit_misc_hideteamchanges", "1", "Hide team changes in chat?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
||||||
gCV_RespawnOnTeam = CreateConVar("shavit_misc_respawnonteam", "1", "Respawn whenever a player joins a team?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
gCV_RespawnOnTeam = CreateConVar("shavit_misc_respawnonteam", "1", "Respawn whenever a player joins a team?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
||||||
gCV_RespawnOnRestart = CreateConVar("shavit_misc_respawnonrestart", "1", "Respawn a dead player if they use the timer restart command?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
gCV_RespawnOnRestart = CreateConVar("shavit_misc_respawnonrestart", "1", "Respawn a dead player if they use the timer restart command?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0);
|
||||||
@ -416,8 +412,6 @@ public void OnClientCookiesCached(int client)
|
|||||||
gB_Hide[client] = view_as<bool>(StringToInt(sSetting));
|
gB_Hide[client] = view_as<bool>(StringToInt(sSetting));
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateFootsteps(client);
|
|
||||||
|
|
||||||
GetClientCookie(client, gH_CheckpointsCookie, sSetting, 8);
|
GetClientCookie(client, gH_CheckpointsCookie, sSetting, 8);
|
||||||
|
|
||||||
if(strlen(sSetting) == 0)
|
if(strlen(sSetting) == 0)
|
||||||
@ -534,7 +528,7 @@ public void OnMapStart()
|
|||||||
{
|
{
|
||||||
for(int iTeam = 1; iTeam <= 2; iTeam++)
|
for(int iTeam = 1; iTeam <= 2; iTeam++)
|
||||||
{
|
{
|
||||||
int iSpawnPoint = CreateEntityByName((iTeam == 1)? "info_player_terrorist":"info_player_counterterrorist");
|
int iSpawnPoint = CreateEntityByName((gEV_Type == Engine_TF2)? "info_player_teamspawn":((iTeam == 1)? "info_player_terrorist":"info_player_counterterrorist"));
|
||||||
|
|
||||||
if(DispatchSpawn(iSpawnPoint))
|
if(DispatchSpawn(iSpawnPoint))
|
||||||
{
|
{
|
||||||
@ -941,12 +935,16 @@ public Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float
|
|||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gI_PreSpeed == 1 || gI_PreSpeed == 3)
|
if(gI_PreSpeed == 1 || gI_PreSpeed >= 3)
|
||||||
{
|
{
|
||||||
|
float fLimit = gF_PrestrafeLimit;
|
||||||
|
|
||||||
float fSpeed[3];
|
float fSpeed[3];
|
||||||
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
||||||
|
|
||||||
float fLimit = view_as<float>(gA_StyleSettings[gBS_Style[client]][fRunspeed]) + gF_PrestrafeLimit;
|
if(gI_PreSpeed < 4)
|
||||||
|
{
|
||||||
|
fLimit = view_as<float>(gA_StyleSettings[gBS_Style[client]][fRunspeed]) + gF_PrestrafeLimit;
|
||||||
|
|
||||||
// if trying to jump, add a very low limit to stop prespeeding in an elegant way
|
// if trying to jump, add a very low limit to stop prespeeding in an elegant way
|
||||||
// otherwise, make sure nothing weird is happening (such as sliding at ridiculous speeds, at zone enter)
|
// otherwise, make sure nothing weird is happening (such as sliding at ridiculous speeds, at zone enter)
|
||||||
@ -954,6 +952,7 @@ public Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float
|
|||||||
{
|
{
|
||||||
fLimit /= 3.0;
|
fLimit /= 3.0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float fSpeedXY = (SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)));
|
float fSpeedXY = (SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)));
|
||||||
float fScale = (fLimit / fSpeedXY);
|
float fScale = (fLimit / fSpeedXY);
|
||||||
@ -993,8 +992,6 @@ public void OnClientPutInServer(int client)
|
|||||||
gBS_Style[client] = Shavit_GetBhopStyle(client);
|
gBS_Style[client] = Shavit_GetBhopStyle(client);
|
||||||
gB_Hide[client] = false;
|
gB_Hide[client] = false;
|
||||||
gI_CheckpointsSettings[client] = CP_DEFAULT;
|
gI_CheckpointsSettings[client] = CP_DEFAULT;
|
||||||
|
|
||||||
UpdateFootsteps(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gH_GetPlayerMaxSpeed != null)
|
if(gH_GetPlayerMaxSpeed != null)
|
||||||
@ -1154,7 +1151,6 @@ public Action Command_Hide(int client, int args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gB_Hide[client] = !gB_Hide[client];
|
gB_Hide[client] = !gB_Hide[client];
|
||||||
UpdateFootsteps(client);
|
|
||||||
|
|
||||||
char[] sCookie = new char[4];
|
char[] sCookie = new char[4];
|
||||||
IntToString(view_as<int>(gB_Hide[client]), sCookie, 4);
|
IntToString(view_as<int>(gB_Hide[client]), sCookie, 4);
|
||||||
@ -1456,13 +1452,10 @@ public Action Command_Save(int client, int args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else if((bSaved = SaveCheckpoint(client, (CP_MAX - 1))))
|
||||||
{
|
|
||||||
if((bSaved = SaveCheckpoint(client, (CP_MAX - 1))))
|
|
||||||
{
|
{
|
||||||
gI_CheckpointsCache[client][iCurrentCheckpoint] = CP_MAX;
|
gI_CheckpointsCache[client][iCurrentCheckpoint] = CP_MAX;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(bSaved)
|
if(bSaved)
|
||||||
{
|
{
|
||||||
@ -1671,14 +1664,14 @@ bool SaveCheckpoint(int client, int index)
|
|||||||
int iObserverMode = GetEntProp(client, Prop_Send, "m_iObserverMode");
|
int iObserverMode = GetEntProp(client, Prop_Send, "m_iObserverMode");
|
||||||
int iObserverTarget = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
|
int iObserverTarget = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
|
||||||
|
|
||||||
if(IsClientObserver(client) && !IsFakeClient(iObserverTarget) && IsValidClient(iObserverTarget) && iObserverMode >= 3 && iObserverMode <= 5)
|
if(IsClientObserver(client) && IsValidClient(iObserverTarget) && iObserverMode >= 3 && iObserverMode <= 5)
|
||||||
{
|
{
|
||||||
target = iObserverTarget;
|
target = iObserverTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(!IsPlayerAlive(client))
|
else if(!IsPlayerAlive(client))
|
||||||
{
|
{
|
||||||
Shavit_PrintToChat(client, "%T", "CommandAliveSpectate", client, gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText]);
|
Shavit_PrintToChat(client, "%T", "CommandAliveSpectate", client, gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText]);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1705,9 +1698,32 @@ bool SaveCheckpoint(int client, int index)
|
|||||||
cpcache[iCPFlags] = GetEntityFlags(target);
|
cpcache[iCPFlags] = GetEntityFlags(target);
|
||||||
|
|
||||||
any snapshot[TIMERSNAPSHOT_SIZE];
|
any snapshot[TIMERSNAPSHOT_SIZE];
|
||||||
Shavit_SaveSnapshot(target, snapshot);
|
|
||||||
CopyArray(snapshot, cpcache[aCPSnapshot], TIMERSNAPSHOT_SIZE);
|
|
||||||
|
|
||||||
|
if(IsFakeClient(target))
|
||||||
|
{
|
||||||
|
// unfortunately replay bots don't have a snapshot, so we can generate a fake one
|
||||||
|
int style = Shavit_GetReplayBotStyle(target);
|
||||||
|
int track = Shavit_GetReplayBotTrack(target);
|
||||||
|
|
||||||
|
snapshot[bTimerEnabled] = true;
|
||||||
|
snapshot[fCurrentTime] = Shavit_GetReplayTime(style, track);
|
||||||
|
snapshot[bClientPaused] = false;
|
||||||
|
snapshot[bsStyle] = style;
|
||||||
|
snapshot[iJumps] = 0;
|
||||||
|
snapshot[iStrafes] = 0;
|
||||||
|
snapshot[iTotalMeasures] = 0;
|
||||||
|
snapshot[iGoodGains] = 0;
|
||||||
|
snapshot[fServerTime] = GetEngineTime();
|
||||||
|
snapshot[iSHSWCombination] = -1;
|
||||||
|
snapshot[iTimerTrack] = track;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Shavit_SaveSnapshot(target, snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyArray(snapshot, cpcache[aCPSnapshot], TIMERSNAPSHOT_SIZE);
|
||||||
SetCheckpoint(client, index, cpcache);
|
SetCheckpoint(client, index, cpcache);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1954,7 +1970,7 @@ public Action Shavit_OnStart(int client)
|
|||||||
return Plugin_Stop;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gB_ResetTargetname)
|
if(gB_ResetTargetname || Shavit_IsPracticeMode(client)) // practice mode can be abused to break map triggers
|
||||||
{
|
{
|
||||||
DispatchKeyValue(client, "targetname", "");
|
DispatchKeyValue(client, "targetname", "");
|
||||||
}
|
}
|
||||||
@ -2506,16 +2522,6 @@ bool SetCheckpoint(int client, int index, CheckpointsCache cpcache[PCPCACHE_SIZE
|
|||||||
return gSM_Checkpoints.SetArray(sKey, cpcache[0], view_as<int>(PCPCACHE_SIZE));
|
return gSM_Checkpoints.SetArray(sKey, cpcache[0], view_as<int>(PCPCACHE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateFootsteps(int client)
|
|
||||||
{
|
|
||||||
if(sv_footsteps != null)
|
|
||||||
{
|
|
||||||
char[] sFootsteps = new char[4];
|
|
||||||
IntToString((gB_Hide[client])? 0:sv_footsteps.IntValue, sFootsteps, 4);
|
|
||||||
sv_footsteps.ReplicateToClient(client, sFootsteps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CopyArray(const any[] from, any[] to, int size)
|
void CopyArray(const any[] from, any[] to, int size)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
|
|||||||
@ -135,7 +135,7 @@ public void OnPluginStart()
|
|||||||
RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players."); // The rewrite of rankings will not have the ability to show over 100 entries. Dynamic fetching can be exploited and overload the database.
|
RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players."); // The rewrite of rankings will not have the ability to show over 100 entries. Dynamic fetching can be exploited and overload the database.
|
||||||
|
|
||||||
RegAdminCmd("sm_settier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_settier <tier>");
|
RegAdminCmd("sm_settier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_settier <tier>");
|
||||||
RegAdminCmd("sm_setmaptier", Command_SetTier, ADMFLAG_RCON, "Prints the map's tier to chat. Usage: sm_setmaptier <tier> (sm_settier alias)");
|
RegAdminCmd("sm_setmaptier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_setmaptier <tier> (sm_settier alias)");
|
||||||
|
|
||||||
RegAdminCmd("sm_recalcmap", Command_RecalcMap, ADMFLAG_RCON, "Recalculate the current map's records' points.");
|
RegAdminCmd("sm_recalcmap", Command_RecalcMap, ADMFLAG_RCON, "Recalculate the current map's records' points.");
|
||||||
|
|
||||||
|
|||||||
@ -86,7 +86,7 @@ int gI_DefaultTeamSlots = 0;
|
|||||||
|
|
||||||
// server specific
|
// server specific
|
||||||
float gF_Tickrate = 0.0;
|
float gF_Tickrate = 0.0;
|
||||||
char gS_Map[192];
|
char gS_Map[160];
|
||||||
int gI_ExpectedBots = 0;
|
int gI_ExpectedBots = 0;
|
||||||
ConVar bot_quota = null;
|
ConVar bot_quota = null;
|
||||||
any gA_CentralCache[CENTRALBOTCACHE_SIZE];
|
any gA_CentralCache[CENTRALBOTCACHE_SIZE];
|
||||||
@ -527,28 +527,6 @@ public Action Cron(Handle Timer)
|
|||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
|
||||||
{
|
|
||||||
// trigger_once | trigger_multiple.. etc
|
|
||||||
// func_door | func_door_rotating
|
|
||||||
if(StrContains(classname, "trigger_") != -1 || StrContains(classname, "_door") != -1)
|
|
||||||
{
|
|
||||||
SDKHook(entity, SDKHook_StartTouch, HookTriggers);
|
|
||||||
SDKHook(entity, SDKHook_EndTouch, HookTriggers);
|
|
||||||
SDKHook(entity, SDKHook_Touch, HookTriggers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action HookTriggers(int entity, int other)
|
|
||||||
{
|
|
||||||
if(other >= 1 && other <= MaxClients && IsFakeClient(other))
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LoadStyling()
|
bool LoadStyling()
|
||||||
{
|
{
|
||||||
char[] sPath = new char[PLATFORM_MAX_PATH];
|
char[] sPath = new char[PLATFORM_MAX_PATH];
|
||||||
@ -606,8 +584,8 @@ public void OnMapStart()
|
|||||||
|
|
||||||
gB_ForciblyStopped = false;
|
gB_ForciblyStopped = false;
|
||||||
|
|
||||||
GetCurrentMap(gS_Map, 192);
|
GetCurrentMap(gS_Map, 160);
|
||||||
GetMapDisplayName(gS_Map, gS_Map, 192);
|
GetMapDisplayName(gS_Map, gS_Map, 160);
|
||||||
|
|
||||||
if(!gB_Enabled)
|
if(!gB_Enabled)
|
||||||
{
|
{
|
||||||
@ -1117,7 +1095,7 @@ void UpdateReplayInfo(int client, int style, float time, int track)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntProp(client, Prop_Data, "m_CollisionGroup", 1);
|
SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);
|
||||||
SetEntityMoveType(client, MOVETYPE_NOCLIP);
|
SetEntityMoveType(client, MOVETYPE_NOCLIP);
|
||||||
|
|
||||||
bool central = (gA_CentralCache[iCentralClient] == client);
|
bool central = (gA_CentralCache[iCentralClient] == client);
|
||||||
@ -1494,9 +1472,9 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
|
|
||||||
MoveType movetype = gA_Frames[style][track].Get(gI_ReplayTick[style], 7);
|
MoveType movetype = gA_Frames[style][track].Get(gI_ReplayTick[style], 7);
|
||||||
|
|
||||||
if(movetype == MOVETYPE_WALK || movetype == MOVETYPE_LADDER)
|
if(movetype == MOVETYPE_LADDER)
|
||||||
{
|
{
|
||||||
mt = movetype;
|
mt = MOVETYPE_LADDER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,8 +1533,14 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Action Timer_EndReplay(Handle Timer, any data)
|
public Action Timer_EndReplay(Handle Timer, any data)
|
||||||
|
{
|
||||||
|
if(gB_CentralBot && gB_ForciblyStopped)
|
||||||
{
|
{
|
||||||
gB_ForciblyStopped = false;
|
gB_ForciblyStopped = false;
|
||||||
|
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
gI_ReplayTick[data] = 0;
|
gI_ReplayTick[data] = 0;
|
||||||
|
|
||||||
if(gI_ReplayBotClient[data] != gA_CentralCache[iCentralClient])
|
if(gI_ReplayBotClient[data] != gA_CentralCache[iCentralClient])
|
||||||
@ -1684,9 +1668,17 @@ public Action Hook_SayText2(UserMsg msg_id, any msg, const int[] players, int pl
|
|||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// caching usermessage type rather than call it every time
|
||||||
|
static UserMessageType um = view_as<UserMessageType>(-1);
|
||||||
|
|
||||||
|
if(um == view_as<UserMessageType>(-1))
|
||||||
|
{
|
||||||
|
um = GetUserMessageType();
|
||||||
|
}
|
||||||
|
|
||||||
char[] sMessage = new char[24];
|
char[] sMessage = new char[24];
|
||||||
|
|
||||||
if(GetUserMessageType() == UM_Protobuf)
|
if(um == UM_Protobuf)
|
||||||
{
|
{
|
||||||
Protobuf pbmsg = msg;
|
Protobuf pbmsg = msg;
|
||||||
pbmsg.ReadString("msg_name", sMessage, 24);
|
pbmsg.ReadString("msg_name", sMessage, 24);
|
||||||
|
|||||||
@ -774,8 +774,14 @@ public int MenuHandler_DeleteAll(Menu menu, MenuAction action, int param1, int p
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char[] sTrack = new char[32];
|
||||||
|
GetTrackName(LANG_SERVER, gI_LastTrack[param1], sTrack, 32);
|
||||||
|
|
||||||
|
Shavit_LogMessage("%L - deleted all %s track records from map `%s`.", param1, sTrack, gS_Map);
|
||||||
|
|
||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE map = '%s' AND track = %d;", gS_MySQLPrefix, gS_Map, gI_LastTrack[param1]);
|
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE map = '%s' AND track = %d;", gS_MySQLPrefix, gS_Map, gI_LastTrack[param1]);
|
||||||
|
|
||||||
gH_SQL.Query(DeleteAll_Callback, sQuery, GetClientSerial(param1), DBPrio_High);
|
gH_SQL.Query(DeleteAll_Callback, sQuery, GetClientSerial(param1), DBPrio_High);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,6 +909,8 @@ public int MenuHandler_DeleteStyleRecords_Confirm(Menu menu, MenuAction action,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shavit_LogMessage("%L - deleted all %s style records from map `%s`.", param1, gS_StyleStrings[style][sStyleName], gS_Map);
|
||||||
|
|
||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE map = '%s' AND style = %d;", gS_MySQLPrefix, gS_Map, style);
|
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE map = '%s' AND style = %d;", gS_MySQLPrefix, gS_Map, style);
|
||||||
|
|
||||||
@ -1135,8 +1143,12 @@ public int DeleteConfirm_Handler(Menu menu, MenuAction action, int param1, int p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: display record details here (map name, player name/authid, time, rank on map) without dropping threaded queries
|
||||||
|
Shavit_LogMessage("%L - deleted record id %d.", param1, iRecordID);
|
||||||
|
|
||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE id = %d;", gS_MySQLPrefix, iRecordID);
|
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE id = %d;", gS_MySQLPrefix, iRecordID);
|
||||||
|
|
||||||
gH_SQL.Query(DeleteConfirm_Callback, sQuery, GetClientSerial(param1), DBPrio_High);
|
gH_SQL.Query(DeleteConfirm_Callback, sQuery, GetClientSerial(param1), DBPrio_High);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -956,6 +956,8 @@ public Action Command_DelSpawn(int client, int args)
|
|||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shavit_LogMessage("%L - deleted custom spawn from map `%s`.", client, gS_Map);
|
||||||
|
|
||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE type = '%d' AND map = '%s';", gS_MySQLPrefix, Zone_CustomSpawn, gS_Map);
|
FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE type = '%d' AND map = '%s';", gS_MySQLPrefix, Zone_CustomSpawn, gS_Map);
|
||||||
|
|
||||||
@ -1227,6 +1229,8 @@ public int DeleteZone_MenuHandler(Menu menu, MenuAction action, int param1, int
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
Shavit_LogMessage("%L - deleted %s (id %d) from map `%s`.", param1, gS_ZoneNames[gA_ZoneCache[id][iZoneType]], gA_ZoneCache[id][iDatabaseID], gS_Map);
|
||||||
|
|
||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE %s = %d;", gS_MySQLPrefix, (gB_MySQL)? "id":"rowid", gA_ZoneCache[id][iDatabaseID]);
|
FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE %s = %d;", gS_MySQLPrefix, (gB_MySQL)? "id":"rowid", gA_ZoneCache[id][iDatabaseID]);
|
||||||
|
|
||||||
@ -1321,6 +1325,8 @@ public int DeleteAllZones_MenuHandler(Menu menu, MenuAction action, int param1,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shavit_LogMessage("%L - deleted all zones from map `%s`.", param1, gS_Map);
|
||||||
|
|
||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE map = '%s';", gS_MySQLPrefix, gS_Map);
|
FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE map = '%s';", gS_MySQLPrefix, gS_Map);
|
||||||
|
|
||||||
@ -1901,11 +1907,15 @@ void InsertZone(int client)
|
|||||||
|
|
||||||
if(type == Zone_CustomSpawn)
|
if(type == Zone_CustomSpawn)
|
||||||
{
|
{
|
||||||
|
Shavit_LogMessage("%L - added custom spawn {%.2f, %.2f, %.2f} to map `%s`.", client, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gS_Map);
|
||||||
|
|
||||||
FormatEx(sQuery, 512, "INSERT INTO %smapzones (map, type, destination_x, destination_y, destination_z) VALUES ('%s', '%d', '%.03f', '%.03f', '%.03f');", gS_MySQLPrefix, gS_Map, type, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2]);
|
FormatEx(sQuery, 512, "INSERT INTO %smapzones (map, type, destination_x, destination_y, destination_z) VALUES ('%s', '%d', '%.03f', '%.03f', '%.03f');", gS_MySQLPrefix, gS_Map, type, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(insert) // insert
|
else if(insert) // insert
|
||||||
{
|
{
|
||||||
|
Shavit_LogMessage("%L - added %s to map `%s`.", client, gS_ZoneNames[type], gS_Map);
|
||||||
|
|
||||||
if(type != Zone_Teleport)
|
if(type != Zone_Teleport)
|
||||||
{
|
{
|
||||||
FormatEx(sQuery, 512, "INSERT INTO %smapzones (map, type, corner1_x, corner1_y, corner1_z, corner2_x, corner2_y, corner2_z, track) VALUES ('%s', '%d', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%d');", gS_MySQLPrefix, gS_Map, type, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gV_Point2[client][0], gV_Point2[client][1], gV_Point2[client][2], gI_ZoneTrack[client]);
|
FormatEx(sQuery, 512, "INSERT INTO %smapzones (map, type, corner1_x, corner1_y, corner1_z, corner2_x, corner2_y, corner2_z, track) VALUES ('%s', '%d', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%d');", gS_MySQLPrefix, gS_Map, type, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gV_Point2[client][0], gV_Point2[client][1], gV_Point2[client][2], gI_ZoneTrack[client]);
|
||||||
@ -1919,6 +1929,8 @@ void InsertZone(int client)
|
|||||||
|
|
||||||
else // update
|
else // update
|
||||||
{
|
{
|
||||||
|
Shavit_LogMessage("%L - updated %s in map `%s`.", client, gS_ZoneNames[type], gS_Map);
|
||||||
|
|
||||||
if(gI_ZoneDatabaseID[client] == -1)
|
if(gI_ZoneDatabaseID[client] == -1)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < gI_MapZones; i++)
|
for(int i = 0; i < gI_MapZones; i++)
|
||||||
@ -2409,7 +2421,7 @@ public void Shavit_OnEnd(int client, int track)
|
|||||||
|
|
||||||
bool EmptyVector(float vec[3])
|
bool EmptyVector(float vec[3])
|
||||||
{
|
{
|
||||||
return (vec[0] == 0.0 && vec[1] == 0.0 && vec[2] == 0.0);
|
return (IsNullVector(vec) || (vec[0] == 0.0 && vec[1] == 0.0 && vec[2] == 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns -1 if there's no zone
|
// returns -1 if there's no zone
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
"CCHelp_GenericVariables"
|
"CCHelp_GenericVariables"
|
||||||
{
|
{
|
||||||
"en" "- {name} - your in-game name.\n- {rand} - a random color.\n- {team} - your team color.\n- {green} - green color."
|
"en" "- {name} - your in-game name.\n- {clan} - your clan tag.\n- {rand} - a random color.\n- {team} - your team color.\n- {green} - green color."
|
||||||
}
|
}
|
||||||
"CCHelp_CSS_1"
|
"CCHelp_CSS_1"
|
||||||
{
|
{
|
||||||
@ -46,4 +46,17 @@
|
|||||||
{
|
{
|
||||||
"en" "- The following colors are also available: {blue}, {bluegrey}, {darkblue}, {darkred}, {gold}, {grey}, {grey2}, {lightgreen}, {lightred}, {lime}, {orchid}, {yellow} and {palered}."
|
"en" "- The following colors are also available: {blue}, {bluegrey}, {darkblue}, {darkred}, {gold}, {grey}, {grey2}, {lightgreen}, {lightred}, {lime}, {orchid}, {yellow} and {palered}."
|
||||||
}
|
}
|
||||||
|
// ---------- Menu ---------- //
|
||||||
|
"SelectChatRank"
|
||||||
|
{
|
||||||
|
"en" "Select chat rank:\n"
|
||||||
|
}
|
||||||
|
"AutoAssign"
|
||||||
|
{
|
||||||
|
"en" "Auto-assign\nAutomatically assign using your rank."
|
||||||
|
}
|
||||||
|
"CustomChat"
|
||||||
|
{
|
||||||
|
"en" "Custom\nUse custom chat settings. See !cchelp for more information."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user