Resxt e235b76ebe chat_commands 1.1
Allow configuration of the commands prefix

Added a function to easily create commands

Added the ability to pass an array of server ports instead of just one port per command

Added the ability to add a command to all servers using level.commands_servers_ports

Fixed the warning when running a function command by explicitly defining whether a command is of type text or function

Fixed commands not working when using the say command through the console instead of the chat. Now both works
2022-10-15 14:31:59 +02:00

216 lines
5.6 KiB
Plaintext

/*
==========================================================================
| Game: Plutonium IW5 |
| Description : Display text and run GSC code |
| by typing commands in the chat |
| Author: Resxt |
==========================================================================
| https://github.com/Resxt/Plutonium-IW5-Scripts/tree/main/small_scripts |
==========================================================================
*/
/* Init section */
Init()
{
InitChatCommands();
}
InitChatCommands()
{
level.commands_prefix = "!";
level.commands_servers_ports = ["27016", "27017"];
InitCommands();
level thread ChatListener();
}
InitCommands()
{
CreateCommand(["27016"], "rules", "text", ["Do not camp", "Do not spawnkill", "Do not disrespect other players"]);
CreateCommand(["27017"], "rules", "text", ["Leave your spot and don't camp after using a M.O.A.B", "Don't leave while being infected", "Do not disrespect other players"]);
CreateCommand(level.commands_servers_ports, "suicide", "function", ::SuicideCommand);
CreateCommand(level.commands_servers_ports, "map", "function", ::ChangeMapCommand);
CreateCommand(level.commands_servers_ports, "mode", "function", ::ChangeModeCommand);
CreateCommand(level.commands_servers_ports, "mapmode", "function", ::ChangeMapAndModeCommand);
}
/*
<serverPorts> the ports of the servers this command will be created for
<commandName> the name of the command, this is what players will type in the chat
<commandType> the type of the command: <text> is for arrays of text to display text in the player's chat and <function> is to execute a function
*/
CreateCommand(serverPorts, commandName, commandType, commandValue)
{
foreach (serverPort in serverPorts)
{
level.commands[serverPort][commandName]["type"] = commandType;
if (commandType == "text")
{
level.commands[serverPort][commandName]["text"] = commandValue;
}
else if (commandType == "function")
{
level.commands[serverPort][commandName]["function"] = commandValue;
}
}
}
/* Chat section */
ChatListener()
{
while (true)
{
level waittill("say", message, player);
if (message[0] != level.commands_prefix) // For some reason checking for the buggy character doesn't work so we start at the second character if the first isn't the command prefix
{
message = GetSubStr(message, 1); // Remove the random/buggy character at index 0, get the real message
}
if (message[0] != level.commands_prefix) // If the message doesn't start with the command prefix
{
continue; // stop
}
commandArray = StrTok(message, " "); // Separate the command by space character. Example: ["!map", "mp_dome"]
command = commandArray[0]; // The command as text. Example: !map
args = []; // The arguments passed to the command. Example: ["mp_dome"]
for (i = 1; i < commandArray.size; i++)
{
args[args.size] = commandArray[i];
}
if (command == level.commands_prefix + "commands")
{
player thread TellPlayer(GetArrayKeys(level.commands[GetDvar("net_port")]), 2, true);
}
else
{
commandValue = level.commands[GetDvar("net_port")][GetSubStr(command, 1)];
if (IsDefined(commandValue))
{
if (commandValue["type"] == "text")
{
player thread TellPlayer(commandValue["text"], 2);
}
else if (commandValue["type"] == "function")
{
error = player [[commandValue["function"]]](args);
if (IsDefined(error))
{
player thread TellPlayer(error, 1.5);
}
}
}
else
{
player thread TellPlayer(CommandDoesNotExistError(), 1);
}
}
}
}
TellPlayer(messages, waitTime, isCommand)
{
for (i = 0; i < messages.size; i++)
{
message = messages[i];
if (IsDefined(isCommand) && isCommand)
{
message = level.commands_prefix + message;
}
self tell(message);
if (i < (messages.size - 1)) // Don't unnecessarily wait after the last message has been displayed
{
wait waitTime;
}
}
}
/* Command functions section */
SuicideCommand(args)
{
self Suicide();
}
ChangeMapCommand(args)
{
if (args.size < 1)
{
return NotEnoughArgsError(1);
}
ChangeMap(args[0]);
}
ChangeModeCommand(args)
{
if (args.size < 1)
{
return NotEnoughArgsError(1);
}
ChangeMode(args[0], true);
}
ChangeMapAndModeCommand(args)
{
if (args.size < 2)
{
return NotEnoughArgsError(2);
}
ChangeMode(args[1], false);
ChangeMap(args[0]);
}
/* Logic functions section */
ChangeMap(mapName)
{
cmdexec("map " + mapName);
}
ChangeMode(modeName, restart)
{
cmdexec("load_dsr " + modeName + ";");
if (restart)
{
cmdexec("map_restart");
}
}
/* Error functions section */
CommandDoesNotExistError()
{
return ["This command doesn't exist", "Type " + level.commands_prefix + "commands" + " to get a list of commands"];
}
NotEnoughArgsError(minimumArgs)
{
return ["Not enough arguments supplied", "At least " + minimumArgs + " argument expected"];
}