
/**********************************************************
*
* admin_messagemode.amx V0.1b
*
* 'messagemode-like' wrappers for admin chat commands
*
* (c) Copyright 2002, McKenzie ( mckenzie_cs@gmx.de )
* inspired by sank (plugin_sank_chatmode for AdminMod)
*
* This file is provided as is (no warranties).
*
* 
* This plugin offers commands which can be bound to
* any keys at clientside providing easy access to the
* admin chat commands.
* Just bind a key to a command. After pressing that
* key ingame you can enter your message like with standard 
* 'say' (messagemode), except that your message will be
* displayed as an admin chat message. (Actually it uses
* the messagemode-routine for input) A little help string
* is also displayed.
*
* deluxe_admin_chat.amx by EJL is supported but not
* necessarily needed.
* 
* The following commands can be bound to keys:
* 
* amx_saymode
* amx_chatmode
* amx_psaymode
* amx_tsaymode
* amx_csaymode		<== deluxe_admin_chat.amx required
* amx_fsaymode		<== deluxe_admin_chat.amx required
* amx_scrollsaymode	<== deluxe_admin_chat.amx required
* amx_tsayymode		<== deluxe_admin_chat.amx required
* amx_csayymode		<== deluxe_admin_chat.amx required
* amx_fsayymode		<== deluxe_admin_chat.amx required
* amx_scrollsayymode	<== deluxe_admin_chat.amx required
* 
* EXAMPLE (Clientside): bind "o" "amx_tsaymode"
* 
* For color sensitive functions, like amx_tsay, a client
* can set a default color by setting a local variable
* named "_mcol".
* So, e.g., every admin can assign himself another color, 
* without having to type it in again for every single
* message.
*
* EXAMPLE (Clientside): setinfo _mcol red
*
* This default color is only used, if the message doesn't
* contain any color information in the first word.
* Any color string will be converted to lower case.
* If no color is defined, white will be used.
*
* amx_tsaymode will accept messages without color
* argument (standard amx_tsay does not).
*
* Known Bugs:
* - The admin_messagmode can't be cancelled: if "say"
*   is cancelled (pressing <ESC>), the next say will be 
*   displayed as an admin message. No workaround, because
*   abort of messagemode can't be handled by server.
*
* History:
*
* V0.1	15. Dec 2002 - First release
*	- Support for Standard adminchat.amx
*	- Support for deluxe_admin_chat.amx
*	- Support for client side default color ("_mcol")
*
* V0.1b	15. Dec 2002 - Minor code changes
*	- Plugin name in "amx list" now corrected
*	- Unnecessary branch for standard tsay removed
*
***********************************************************/

#include <amxmod>
#include <amxconst>
#include <string>

// Constants

#define MAX_PLAYERS 33
#define MAX_STRING 190
#define MAX_SEARCHLEN 15


/* Array to store type of command for every player
* Value : action
* 0 : standard HL say
* adminchat.amx standard commands
* 1 : amx_say
* 2 : amx_chat
* 3 : amx_psay
* 4 : amx_tsay
* deluxe_admin_chat standard commands
* 5 : amx_csay
* 6 : amx_fsay
* 7 : amx_scrollsay
* 8 : amx_tsayy
* 9 : amx_csayy
* 10: amx_fsayy
* 11: amx_scrollsayy
*/
new aiSayType[MAX_PLAYERS] = { 0, ... }

// Array for Say-Commands
new asSayCmd[11][] = {	"amx_say",
			"amx_chat",
			"amx_psay",
			"amx_tsay",
			"amx_csay",
			"amx_fsay",
			"amx_scrollsay",
			"amx_tsayy",
			"amx_csayy",
			"amx_fsayy",
			"amx_scrollsayy"
			}

// Array for helpstrings; These are displayed right above the say-line
new asSayHelp[11][] = {	"[ amx_say ] <message>",
			"[ amx_chat ] <message>",
			"[ amx_psay ] <user> <message>",
			"[ amx_tsay ] [<color>] <message>",
			"[ amx_csay ] [<color>] <message>",
			"[ amx_fsay ] <X-%%> <Y-%%> [<color>] <message>",
			"[ amx_scrollsay ] [<color>] <message>",
			"[ amx_tsayy ] [<color>] <message>",
			"[ amx_csayy ] [<color>] <message>",
			"[ amx_fsayy ] <X-%%> <Y-%%> [<color>] <message>",
			"[ amx_scrollsayy ] [<color>] <message>"
			}
// Color codes
#define MAX_CLR 7 
new asColors[MAX_CLR][] = {"white","red","green","blue","yellow","magenta","cyan"} 
new aiColLen[MAX_CLR]   = { 5     , 3   , 5     , 4    , 6      , 7       , 4    }

// Shows Helpstring and "say"-prompt
static show_prompt(id, iSayType)
{
	client_print(id, print_notify, "%s", asSayHelp[iSayType-1]); 
	client_cmd(id, "messagemode");
}


// The following functions are just setting the right Say-Mode
// for that player
public admin_saymode(id)
{
	aiSayType[id]=1;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_chatmode(id)
{
	aiSayType[id]=2;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_psaymode(id)
{
	aiSayType[id]=3;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_tsaymode(id)
{
	aiSayType[id]=4;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_csaymode(id)
{
	aiSayType[id]=5;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_fsaymode(id)
{
	aiSayType[id]=6;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_scrollsaymode(id)
{
	aiSayType[id]=7;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_tsayymode(id)
{
	aiSayType[id]=8;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_csayymode(id)
{
	aiSayType[id]=9;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_fsayymode(id)
{
	aiSayType[id]=10;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

public admin_scrsayymode(id)
{
	aiSayType[id]=11;
	show_prompt(id, aiSayType[id]);
	return PLUGIN_HANDLED;
}

// Returns the number of words a string has
static iWordCount(str[])
{
	new i = 0;
	new iWC = 0;
	new bNextIsWord = true;
	while (str[i] != '^0')
	{
		if (bNextIsWord)
		{
			if (str[i] != ' ')
			{
				bNextIsWord = false;
				iWC++;
			}
		}
		else
		{
			if (str[i] == ' ')
			{
				bNextIsWord = true;
			}
		}
		i++;
	}
	return iWC;
}

// Returns the index of the color, if it exists
static iAllowedColor(sColor[])
{
	new iFound = 0;
	for (new i = 1; i <= MAX_CLR; i++)
		if (equali(sColor, asColors[i-1]))
			iFound = i;
	return iFound;
}

// Say-Handler
// Every clients say requests are passed through
// here. This function decides what to do with
// a client's message
public handle_say(id)
{
	new message[MAX_STRING+2];
	new sColor[11] = "";
	new iColorOmit = 0;
	new iACIndex = 0;

	// Extract Message from say command
	read_args(message, MAX_STRING);
	remove_quotes(message);

	// Extract clients setting for default color
	get_user_info(id, "_mcol", sColor, 11);
	iACIndex = iAllowedColor(sColor);

	// Check for color at start of string
	// This would override clients setting
	if (iWordCount(message) > 1)
	{
		new sFirstWord[MAX_SEARCHLEN];

		copyc(sFirstWord, MAX_SEARCHLEN, message, ' ');
		if (iAllowedColor(sFirstWord))
		{
			iACIndex = iAllowedColor(sFirstWord);
			iColorOmit = aiColLen[iACIndex-1]+1;
		}
		else
			iColorOmit = 0;
	}	

	// Get clean string from table in any case
	if (iACIndex)
		copy(sColor, MAX_SEARCHLEN, asColors[iACIndex-1]);
	else
		sColor = "white";

	// Branch on aiSayType
	switch(aiSayType[id])
	{
		case 1, 2, 3, 6, 10: // Commands without color
			client_cmd(id, "%s %s", asSayCmd[aiSayType[id]-1], message);

		case 4, 5, 7, 8, 9, 11: // Commands with color
			client_cmd(id, "%s %s %s", asSayCmd[aiSayType[id]-1], sColor, message[iColorOmit]);

		default: // standard say
		{
			aiSayType[id] = 0;
			return PLUGIN_CONTINUE;
		}
	}
	aiSayType[id] = 0;
	return PLUGIN_HANDLED;
}

// Clear flag for new player
public client_connect(id)
{
	aiSayType[id] = 0;
	return PLUGIN_CONTINUE;
}

// Clear flag for departing player (just in case)
public client_disconnect(id)
{
	aiSayType[id] = 0;
	return PLUGIN_CONTINUE;
}

// Register commands
public plugin_init() {
	register_plugin("admin_messagemode", "0.1b", "McKenzie")
	register_clcmd("amx_saymode", "admin_saymode", ADMIN_CHAT, "amx_saymode  :  amx_say with messagemode command interface")
	register_clcmd("amx_chatmode", "admin_chatmode", ADMIN_CHAT, "amx_chatmode  :  amx_chat with messagemode command interface")
	register_clcmd("amx_psaymode", "admin_psaymode", ADMIN_CHAT, "amx_psaymode  :  amx_psay with messagemode command interface")
	register_clcmd("amx_tsaymode", "admin_tsaymode", ADMIN_CHAT, "amx_tsaymode  :  amx_tsay with messagemode command interface")
	register_clcmd("amx_csaymode", "admin_csaymode", ADMIN_CHAT, "amx_csaymode  :  amx_csay with messagemode command interface")
	register_clcmd("amx_fsaymode", "admin_fsaymode", ADMIN_CHAT, "amx_fsaymode  :  amx_fsay with messagemode command interface")
	register_clcmd("amx_scrollsaymode", "admin_scrollsaymode", ADMIN_CHAT, "amx_scrollsaymode  :  amx_scrollsay with messagemode command interface")
	register_clcmd("amx_tsayymode", "admin_tsayymode", ADMIN_CHAT, "amx_tsayymode  :  amx_tsayy with messagemode command interface")
	register_clcmd("amx_csayymode", "admin_csayymode", ADMIN_CHAT, "amx_csayymode  :  amx_csayy with messagemode command interface")
	register_clcmd("amx_fsayymode", "admin_fsayymode", ADMIN_CHAT, "amx_fsayymode  :  amx_fsayy with messagemode command interface")
	register_clcmd("amx_scrollsayymode", "admin_scrsayymode", ADMIN_CHAT, "amx_scrollsayymode  :  amx_scrollsayy with messagemode command interface")
	register_clcmd("say","handle_say")
	return PLUGIN_CONTINUE
}

