/* ****************************************************************
 * Spawn kill slaying plugin - Version 1.0                        *
 ******************************************************************
 *                                                                *
 * Name: plugin_ft_spawn_killing                                  *
 * Author: mufasa@firetiger.net                                   *
 * Web site: www.firetiger.net                                    *
 * CS server: firetiger.net:27015                                 *
 * Released: 28th February 2003                                   *
 * Comment: Spawn kill punishment. Use with CS & AdminMod plugin. *
 *                                                                *
 * Version 1.10:                                                  *
 *                                                                *
 *  -  Fixed kill_timer bug                                       *
 *                                                                *
 * Version 1.01:                                                  *
 *                                                                *
 *  -  Added admin_slap to punishment type (val: 0)               *
 *                                                                *
 * Version 1.0 (02/25/2003):                                      *
 *                                                                *
 *  -  Initial release                                            *
 *                                                                *
 * For more info:                                                 *
 *  http://www.firetiger.net/cstrike/plugins.php                  *
 *  http://www.firetiger.net/forums/                              *
 ******************************************************************
 *                                                                *
 * NOTE: This plugin requires LogD!                               *
 *       http://logd.sourceforge.net/                             *
 *                                                                *
 ******************************************************************
 */
 
#include <core>
#include <console>
#include <string>
#include <plugin>
#include <admin>
#include <adminlib>
 
/* ******************************************************
    Alter these defines if necessary to suit your needs.
   ******************************************************/
 
#define SPAWN_TIME 2          		  /* CRITICAL: How long after the freeze time is over will kills be
                                               considered 'spawn kills' -- (0 disables plugin) */
#define DEFAULT_SK_TYPE 1                   /* How should we punish spawn killers? 0=admin_slap 1=admin_slay 2=admin_kick 3=HL kick 
                                               This can also be configured via the ft_sk_type cvar in-game. */
#define MAX_SPAWN_TIME 60                   /* Don't let the spawn time to be set over this limit */
#define ANNOUNCE_TIME 1                     /* Should the spawn time var be announced after a slay? (0|1)*/
 
#define DISPLAY_TIME 7                      /* How long should the slay/announce messages stay up? */
#define DISPLAY_RED 208                     /* TSay message colors (RGB) */
#define DISPLAY_GREEN 20
#define DISPLAY_BLUE 20
 
#define ACCESS_SLAY 128                     /* Access level required to modify the cvars
							     (just change the numeric value if necessary)*/
 
 
/* ***********************************************************
       You do not need to modify anything below this line.
   ***********************************************************/
 
#define ACCESS_CONSOLE 131072               /* You can ignore this access level */
 
// Global vars
new STRING_VERSION[] = "1.01";
 
new g_Spawn_Time=SPAWN_TIME;                /* Main var for how long spawn killing is in effect*/
new g_Type=DEFAULT_SK_TYPE;                 /* Main var for which type of punishment we will use*/
new g_Announce_Time=ANNOUNCE_TIME;          /* Var for announcing how long spawn killing is set at*/
new g_Timer=0;                              /* Main timer to to detect if spawn killing is still in effect*/
new g_SpawnActive=0;                        /* True if spawn killing is active */
 
/* Function declarations */
forward FT_SK_Punish(UserName[MAX_NAME_LENGTH]);
forward SpawnTimeEnd(sParameter);
forward FTLogdKill(HLCommand,HLData,HLUserName,UserIndex);
forward FTLogdWorldAction(HLCommand,HLData,HLUserName,UserIndex);
forward ft_sk_spawn_time(HLCommand,HLData,HLUserName,UserIndex);
forward ft_sk_announce_time(HLCommand,HLData,HLUserName,UserIndex);
forward ft_sk_type(HLCommand,HLData,HLUserName,UserIndex);
 
 
// Function that actually punishes the player
// 1=admin_slay / 2=admin_kick / 3=kick
//  PS: The small language switch statement is nearly worthless --Mufasa
public FT_SK_Punish(UserName[MAX_NAME_LENGTH])
{
  new revert_cmd=0;
  new command[MAX_TEXT_LENGTH];
 
  if (g_Type==0)
  {
    if (plugin_checkcommand("admin_slap")>0)
      plugin_exec("admin_slap",UserName);
    else
      revert_cmd = 1;
  }
  else if (g_Type==1)
  {
    if (plugin_checkcommand("admin_slay")>0)
      plugin_exec("admin_slay",UserName);
    else
      revert_cmd = 1;
  }
  else if (g_Type==2)
  {
    if (plugin_checkcommand("admin_kick")>0) {
      plugin_exec("admin_kick",UserName);
    } else {
      revert_cmd = 1;
    }
  }
  else if (g_Type==3)
  {
    snprintf(command, MAX_TEXT_LENGTH, "kick '%s'", UserName);
    exec(command);
  }
  else
  {
    if (plugin_checkcommand("admin_slay")>0) {
      plugin_exec("admin_slay",UserName);
    } else {
      revert_cmd = 1;
    }
  }
 
  // If we couldn't run the admin_ command, revert to the original HL kick command
  if (revert_cmd == 1)
  {
    snprintf(command, MAX_TEXT_LENGTH, "kick '%s'", UserName);
    exec(command);
  }
 
}
 
 
/*********************************************************
 *                 LOGD CALLBACK HANDLERS                *
 *********************************************************
 heavily modified from plugin_blatt_map:
 http://www.ravenousbugblatterbeast.pwp.blueyonder.co.uk/BugblatterPlugins/plugin_blatt_map/Docs/index.htm
*/
 
public FTLogdKill(HLCommand,HLData,HLUserName,UserIndex)
{
  new name[MAX_NAME_LENGTH];
 
  // Make sure spawn killing timer is active
  if (g_SpawnActive == 1)
  {
	// Parse the values
    new Data[MAX_DATA_LENGTH];
    new Text[MAX_TEXT_LENGTH] = "";
    new iWinner;
    new idWinner[MAX_DATA_LENGTH];
    new idLoser[MAX_DATA_LENGTH];
 
    convert_string(HLData,Data,MAX_DATA_LENGTH);
    strsplit(Data, " ",idWinner,MAX_DATA_LENGTH, idLoser, MAX_DATA_LENGTH);
 
    iWinner = strtonum(idWinner);
 
    // Make sure this is a real player??
    if (!playerinfo(iWinner, name, MAX_NAME_LENGTH)) {
        return PLUGIN_CONTINUE;
    }
 
    // Punish the player who spawn killed
    FT_SK_Punish(name);
 
    // If bot protection is on (which it should be), the bot won't get kicked, but announce to people that we tried
    if ( strmatch(name,"[BOT]",5) != 1)
    {
        snprintf(Text, MAX_TEXT_LENGTH, "(Admin) The bot %s spawn killed someone. If only more humans would join...", name);
        typesay(Text, DISPLAY_TIME, DISPLAY_RED, DISPLAY_GREEN, DISPLAY_BLUE);
    }
 
    // If an admin just did the killing, shame (since it probably didn't punish the player depending on the immunity cvar
    else if (access(ACCESS_CONSOLE,name))
    {
        snprintf(Text, MAX_TEXT_LENGTH, "The admin, %s, just spawn killed. Tsk tsk...", name);
        typesay(Text, DISPLAY_TIME, DISPLAY_RED, DISPLAY_GREEN, DISPLAY_BLUE);
    }
 
    else  // Otherwise, announce to the world
    {
        snprintf(Text, MAX_TEXT_LENGTH, "(Admin) %s was slayed for a round for Spawn Killing.", name);
        typesay(Text, DISPLAY_TIME, DISPLAY_RED, DISPLAY_GREEN, DISPLAY_BLUE);
    }
 
    if ( g_Announce_Time == 1 )
    {
        if ( g_Spawn_Time == 1 )
          snprintf(Text, MAX_TEXT_LENGTH, "(Admin) Spawn Killing is any kill before %i second into the match.", g_Spawn_Time);
         else
          snprintf(Text, MAX_TEXT_LENGTH, "(Admin) Spawn Killing is any kill before %i seconds into the match.", g_Spawn_Time);
        typesay(Text, DISPLAY_TIME, DISPLAY_RED, DISPLAY_GREEN, DISPLAY_BLUE);
    }
  // End if for if spawn kill timer is still active
  }
 
  // Other plugins should be able to handle kill events if they want
  return PLUGIN_CONTINUE;
}
 
 
/* *******************************************************************
    This function runs when the round begins or ends (thanks to LogD)
   ******************************************************************* */
public FTLogdWorldAction(HLCommand,HLData,HLUserName,UserIndex)
{
  new Data[MAX_DATA_LENGTH];
  convert_string(HLData,Data,MAX_DATA_LENGTH);
 
  // Check to see if this world action is the ROUND_START action
  if (strmatch(Data,"Round_Start",11)==1)
  {
    if (g_Timer != 0) {
      kill_timer(g_Timer);
      g_Timer=0;
    }
    if (g_Spawn_Time > 0)
    {
      // set_timer ( sFunction, iWaitSeconds, iRepeatCount, sParameter)
      // The Round_Start event gets called _after_ the freeze time is over.
      g_Timer = set_timer("SpawnTimeEnd", g_Spawn_Time, 0, "");
      g_SpawnActive = 1;
    }
  }
  else if (strmatch(Data,"Round_End",9)==1) {
    if (g_Timer != 0) {
      kill_timer(g_Timer);
      g_Timer=0;
    }
    g_SpawnActive = 0;
  }
 
  // Other plugins should be able to handle world action events if they want
  return PLUGIN_CONTINUE;
}
 
/*********************************************************
 *                 COMMAND HANDLERS                      *
 *********************************************************
*/
 
public ft_sk_spawn_time(HLCommand,HLData,HLUserName,UserIndex) {
    new Text[MAX_TEXT_LENGTH] = "";
    new Data[MAX_DATA_LENGTH];
    new numData;
 
    convert_string(HLData,Data,MAX_DATA_LENGTH);
 
    numData = strtonum(Data);
    if (strlen(Data) <= 0)
    {
        snprintf(Text, MAX_TEXT_LENGTH, "ft_sk_spawn_time is set to: %i seconds", g_Spawn_Time);
        selfmessage(Text);
    }
    //else if ( (numData < 0) || numData > ( getvar("mp_roundtime") - getvar("mp_freezetime") ) )
    else if ( (numData < 0) || (numData > MAX_SPAWN_TIME) )
    {
        snprintf(Text, MAX_TEXT_LENGTH, "Bad data: %s", Data);
        selfmessage(Text);
    }
    else
    {
        g_Spawn_Time = numData;
        snprintf(Text, MAX_TEXT_LENGTH, "ft_sk_spawn_time is now set to: %i seconds", g_Spawn_Time);
        selfmessage(Text);
    }
 
    return PLUGIN_HANDLED;
}
 
public ft_sk_announce_time(HLCommand,HLData,HLUserName,UserIndex) {
    new Text[MAX_TEXT_LENGTH] = "";
    new Data[MAX_DATA_LENGTH];
    new numData;
 
    convert_string(HLData,Data,MAX_DATA_LENGTH);
 
    numData = strtonum(Data);
    if (strlen(Data) <= 0)
    {
        snprintf(Text, MAX_TEXT_LENGTH, "ft_sk_type is set to: %i", g_Type);
        selfmessage(Text);
    }
    else if ( (numData < 0) || (numData > 3) )
    {
        //snprintf(Text, MAX_TEXT_LENGTH, "Bad data: %s", Data);
        //selfmessage(Text);
    }
    else
    {
        g_Type = numData;
        snprintf(Text, MAX_TEXT_LENGTH, "ft_sk_type is now set to: %i", g_Type);
        selfmessage(Text);
    }
 
    return PLUGIN_HANDLED;
}
 
public ft_sk_type(HLCommand,HLData,HLUserName,UserIndex) {
    new Text[MAX_TEXT_LENGTH] = "";
    new Data[MAX_DATA_LENGTH];
    new numData;
 
    convert_string(HLData,Data,MAX_DATA_LENGTH);
 
    numData = strtonum(Data);
    if (strlen(Data) <= 0)
    {
        snprintf(Text, MAX_TEXT_LENGTH, "ft_sk_announce_time is set to: %i", g_Announce_Time);
        selfmessage(Text);
    }
    else if ( (numData < 0) || (numData > 1) )
    {
        //snprintf(Text, MAX_TEXT_LENGTH, "Bad data: %s", Data);
        //selfmessage(Text);
    }
    else
    {
        g_Spawn_Time = numData;
        snprintf(Text, MAX_TEXT_LENGTH, "ft_sk_announce_time is now set to: %i", g_Announce_Time);
        selfmessage(Text);
    }
 
    return PLUGIN_HANDLED;
}
 
/*********************************************************
 *                 TIMER HANDLERS                        *
 *********************************************************
*/
public SpawnTimeEnd(sParameter)
{
    if (g_Timer != 0) {
      kill_timer(g_Timer);
      g_Timer=0;
    }
    g_SpawnActive = 0;
 
    /* new Text[MAX_TEXT_LENGTH] = "";
    snprintf(Text, MAX_TEXT_LENGTH, "Spawn killer stopped after %i seconds", g_Spawn_Time);
    selfmessage(Text); */
}
 
/*********************************************************
 *                 PLUGIN INITIALIZATION                 *
 *********************************************************
*/
public plugin_init() {
    plugin_registerinfo("FT Spawn Killer slayer","Slays players who kill right after the freeze time is over (www.firetiger.net)",STRING_VERSION);
    plugin_registercmd("admin_ft_sk_spawn_time","ft_sk_spawn_time",ACCESS_SLAY,"admin_ft_sk_spawn_time: Time (in sec) (after buytime) when a kill is a spawn kill");
    plugin_registercmd("admin_ft_sk_announce_time","ft_sk_announce_time",ACCESS_SLAY,"admin_ft_sk_announce_time: Announce the spawn time after a spawn slaying? (1=yes, 0=no)");
    plugin_registercmd("admin_ft_sk_type","ft_sk_type",ACCESS_SLAY,"admin_ft_sk_type: How the spawn killer should be punished (0-3) (see docs for values)");
 
    // taken from plugin_blatt_map // http://www.ravenousbugblatterbeast.pwp.blueyonder.co.uk/BugblatterPlugins/plugin_blatt_map/Docs/index.htm
    plugin_registercmd("ft_sk_logdwa","FTLogdWorldAction",ACCESS_SLAY,"");
    // 62 is round start/end event
    exec("logd_reg 62 admin_command ft_sk_logdwa",0);
    // 57 is a kill event
    plugin_registercmd("ft_sk_logdki","FTLogdKill",ACCESS_SLAY,"");
    exec("logd_reg 57 admin_command ft_sk_logdki" );
 
    return PLUGIN_CONTINUE;
}