/* Commands selected by ProgramMan, such as:
   --Advanced vsay (allows question and up to 6 answers as params)
   --Multi-slapping capabilities (slap someone multiple times)
   --Allowing all glow colors (from (0,0,0) to (255,255,255))
   --Temp. ignore immunity (for one command)
   --Freeze/Unfreeze (mod-independent)
*/
 
/* Created by ProgramMan */
/* Thanks to Da Rope for helping me out in the Admin Mod forums 
    with the Advanced vsay */
/* Thanks to KaReL for the original admin_bury/admin_unbury
   (used here as admin_freeze/admin_unfreeze) and to [fah-q] Dio 
   for giving me permission to use the two */
/* Thanks to [TFL]ShadowCaster and others for alerting me to
   use admin_command for my admin_noimmune function */
 
#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
 
// Same access level as vsay
#define ACCESS_VSAY2 ACCESS_SAY
// Same access level as slap
#define ACCESS_MSLAP ACCESS_KICK
// Same access level as funmode
#define ACCESS_GLOW2 8192
// There's a good reason why this is equal
// to ACCESS_RCON, so leave it like this
#define ACCESS_NOIMMUNE ACCESS_RCON
// Same access level as the original bury/unbury
#define ACCESS_FREEZE ACCESS_KICK
 
// This shouldn't be changed, unless
// you have a *really* good reason
#define VSAY2_MAX_RESPONSES 6
 
// Max. of 50 chars. for each vote option (up to 6 options)
new VoteResponses[VSAY2_MAX_RESPONSES][MAX_NAME_LENGTH];
 
new STRING_VERSION[MAX_DATA_LENGTH] = "1.0.0";
 
/*  admin_vsay2
    Functions like admin_vsay, but:
    Asks a question with up to 6 responses allowed
    (admin_vsay asks a Yes-No question)
    Usage:
      admin_vsay2 <question> <response1> <response2> ... <response6>
 
    Notes:
      *You MUST enclose <question> and each <response>
       with single quotes if they have spaces in them
       (or else your vote menu will look all screwed up)
      *Be careful when doing this vote menu (or vsay for that matter)
       in Science & Industry.  If the tech vote menu shows up, your
       next number press will register to the vsay/vsay2 vote menu 
       and you will have to manually "menuselect <#>" in the console
       to select the Science & Industry tech menu item
*/
public admin_vsay2(HLCommand,HLData,HLUserName,UserIndex)
{
  new Data[MAX_DATA_LENGTH];
  new Question[MAX_DATA_LENGTH];
  new Responses[MAX_NAME_LENGTH * 6];
  new I;
  new MaxResponses;
 
  if (vote_allowed() != 1) 
  {
    selfmessage("Vote not allowed at this time.");
    return PLUGIN_HANDLED;
  }
 
  convert_string(HLData,Data,MAX_DATA_LENGTH);
 
  // Re-Init all of the responses
  for (I = 0;I < VSAY2_MAX_RESPONSES;I++)
  {
    strinit(VoteResponses[I]);
  }
 
  // Get all of the parameters for this function
  // First separate the question from the responses
  strgsep(Data," ","'",Question,MAX_DATA_LENGTH,Responses,MAX_NAME_LENGTH * 6);
 
  // Get all of the responses in one hit
  strgsplit(Responses," ","'",VoteResponses[0],MAX_NAME_LENGTH,VoteResponses[1],MAX_NAME_LENGTH, VoteResponses[2],MAX_NAME_LENGTH,VoteResponses[3],MAX_NAME_LENGTH,VoteResponses[4], MAX_NAME_LENGTH,VoteResponses[5],MAX_NAME_LENGTH);
 
  // Check the number of responses
  for (I = 0;I < VSAY2_MAX_RESPONSES;I++)
  {
    if (strlen(VoteResponses[I]) == 0)
    {
      MaxResponses = I;
      break;
    }
  }
  // If none of the responses are null strings,
  // assume that all 6 responses are given
  if (strlen(VoteResponses[VSAY2_MAX_RESPONSES - 1]) > 0)
    MaxResponses = VSAY2_MAX_RESPONSES;
 
  // These make the vote menu look better
  // Trim the leading/trailing spaces off of the question
  strtrim(Question," ");
  // Trim the leading/trailing spaces off of each response, if any
  for (I = 0;I < MaxResponses;I++)
  {
    strtrim(VoteResponses[I]," ");
  }
 
  // Now determine vote depending on number of options
  // If VSAY2_MAX_RESPONSES is changed, additional
  // responses must be added manually
  if (MaxResponses <= 1)
    selfmessage("Sorry, but you must have at least two responses.");
  else if (MaxResponses == 2)
    vote(Question,VoteResponses[0],VoteResponses[1],"HandleVSay2",Question);
  else if (MaxResponses == 3)
    vote(Question,VoteResponses[0],VoteResponses[1],VoteResponses[2],"HandleVSay2",Question);
  else if (MaxResponses == 4)
    vote(Question,VoteResponses[0],VoteResponses[1],VoteResponses[2], VoteResponses[3],"HandleVSay2",Question);
  else if (MaxResponses == 5)
    vote(Question,VoteResponses[0],VoteResponses[1],VoteResponses[2], VoteResponses[3],VoteResponses[4],"HandleVSay2",Question);
  else if (MaxResponses == 6)
    vote(Question,VoteResponses[0],VoteResponses[1],VoteResponses[2], VoteResponses[3],VoteResponses[4],VoteResponses[5],"HandleVSay2",Question);
 
  return PLUGIN_HANDLED;
}
 
public HandleVSay2(WinningOption,HLData,VoteCount,UserCount)
{
  new Data[MAX_DATA_LENGTH];
  new Text[MAX_TEXT_LENGTH];
  new WinningResponse[MAX_NAME_LENGTH];
 
  convert_string(HLData,Data,MAX_DATA_LENGTH);
  strcpy(WinningResponse,VoteResponses[WinningOption - 1],MAX_NAME_LENGTH);
  strtrim(Data," ");
  strtrim(WinningResponse," ");
  snprintf(Text, MAX_TEXT_LENGTH, "^"%s^": ^"%s^" won with %i / %i votes.",Data,WinningResponse, VoteCount, UserCount);
  say(Text);
}
 
/* admin_mslap
   Slaps target multiple times
   Usage:
     admin_mslap <target> <# slaps>
*/
public admin_mslap(HLCommand,HLData,HLUserName,UserIndex)
{
  new Data[MAX_DATA_LENGTH];
  new Target[MAX_NAME_LENGTH];
  new TargetName[MAX_NAME_LENGTH];
  new strNumSlaps[MAX_NUMBER_LENGTH];
  new Text[MAX_TEXT_LENGTH];
  new Dummy[MAX_NAME_LENGTH];  // A "dummy" string used when slapping target
  new NumSlaps = 1;
  new PlayerIndex;
  new IsDead = 0,UserID,WONID,Team;  // UserID,WONID,Team are "dummy" variables
  new I;
 
  convert_string(HLData,Data,MAX_DATA_LENGTH);
 
  strbreak(Data,Target,strNumSlaps,MAX_DATA_LENGTH);
 
  NumSlaps = strtonum(strNumSlaps);
  get_username(Target,TargetName,MAX_NAME_LENGTH);
  get_userindex(TargetName,PlayerIndex);
 
  // Make sure that this user exists
  if (check_user(TargetName) == 0)
  {
    selfmessage("Unrecognized player:");
    selfmessage(TargetName);
  }
  else
  {
    // Make sure that this user can be slapped
    if (check_immunity(TargetName) == 1)
    {
      snprintf(Text,MAX_TEXT_LENGTH,"Laf. You can't slap %s, you silly bear.",TargetName);
      say(Text);
    }
    else
    {
      // Slap the player multiple times, check for death
      for (I = 1;I <= NumSlaps;I++)
      {
        playerinfo(PlayerIndex,Dummy,MAX_NAME_LENGTH,UserID,WONID,Team,IsDead);  // Just get death status
        if (IsDead != 0)
        {
          snprintf(Text,MAX_TEXT_LENGTH,"Cannot slap %s anymore, player is dead.",TargetName);
          say(Text);
          break;
        }
        else
          slap(TargetName);
      }
    }
  }
 
  return PLUGIN_HANDLED;
}
 
/* admin_glow2
   Makes the selected user glow the specified color
   (uses exact RGB colors by specifying each individually)
   Plus, it's allowed on specific individuals
   Usage:
     admin_glow2 <target> <R> <G> <B>
 
   Note: to turn off glow, use 0 0 0 for R G B
*/
public admin_glow2(HLCommand,HLData,HLUserName,UserIndex)
{
  new Command[MAX_COMMAND_LENGTH];
  new Data[MAX_DATA_LENGTH];
  new Target[MAX_NAME_LENGTH];
  new TargetName[MAX_NAME_LENGTH];
  new RGBData[MAX_DATA_LENGTH];
  new strR[MAX_NUMBER_LENGTH];
  new strG[MAX_NUMBER_LENGTH];
  new strB[MAX_NUMBER_LENGTH];
  new R;
  new G;
  new B;
 
  // Check fun mode first
  if (getvar("admin_fun_mode") == 0)
  {
    say("Glowing is only allowed during fun mode.");
    return PLUGIN_HANDLED;
  }
 
  convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);
  convert_string(HLData,Data,MAX_DATA_LENGTH);
 
  // Break the string into its counterparts, first the name
  strbreak(Data,Target,RGBData,MAX_DATA_LENGTH);
 
  // Get the target's name
  get_username(Target,TargetName,MAX_NAME_LENGTH);
 
  // Check the player, if he exists make him glow
  if (check_user(TargetName) == 0)
  {
    selfmessage("Unrecognized player:");
    selfmessage(TargetName);
  }
  else
  {
    // Now get the numbers from the RGBData string
    strsplit(RGBData," ",strR,MAX_NUMBER_LENGTH,strG,MAX_NUMBER_LENGTH,strB,MAX_NUMBER_LENGTH);
    R = strtonum(strR);
    G = strtonum(strG);
    B = strtonum(strB);
 
    glow(TargetName,R,G,B);
  }
 
  return PLUGIN_HANDLED;
}
 
/* admin_noimmune
   Ignores immunity for this command
   Usage:
     admin_noimmune <command + params>
*/
public admin_noimmune(HLCommand,HLData,HLUserName,UserIndex)
{
  new Data[MAX_DATA_LENGTH];
  new Data2[MAX_COMMAND_LENGTH];
  new PrevImmune;
 
  convert_string(HLData,Data,MAX_DATA_LENGTH);
  PrevImmune = getvar("admin_ignore_immunity");
 
  // Execute the command
  // First turn off immunity
  if (PrevImmune == 0)
    setstrvar("admin_ignore_immunity","1");
  strsep(Data," ",Data2,MAX_COMMAND_LENGTH,Data,MAX_DATA_LENGTH);
  plugin_exec(Data2,Data);
  // In other words, if immunity was on before...
  if (PrevImmune == 0)
    set_timer("NoImmuneTimer",1,1);
 
  return PLUGIN_HANDLED;
}
 
/* Used by admin_noimmune to restore admin_ignore_immunity to 0
   (would have just put this command up in admin_ignore_immunity,
    but it does not complete the command in time to beat the
    turn off of admin_ignore_immunity); in other words, you get
   the "Laf. You can't <command> <admin>, you silly bear." message
*/
public NoImmuneTimer(Timer,Repeat,HLName,HLParam)
{
  setstrvar("admin_ignore_immunity","0");
}
 
/* admin_freeze
   Freezes the target by planting him in the ground
   Usage:
     admin_freeze <target>
 
   Note: this is similar to admin_bury, but
    it is mod-independent.  You can add mod-
    specific code to punish the offender in
    other ways (like admin_bury makes the
    target drop his weapons)
*/
public admin_freeze(HLCommand,HLData,HLUserName,UserIndex)
{
  new Target[MAX_NAME_LENGTH];
  new TargetName[MAX_NAME_LENGTH];
  new Text[MAX_TEXT_LENGTH];
  new X;
  new Y;
  new Z;
 
  convert_string(HLData,Target,MAX_NAME_LENGTH);
  get_username(Target,TargetName,MAX_NAME_LENGTH);
 
  if (check_user(TargetName) != 0)
  {
    // Check that user can be frozen
    if (check_immunity(TargetName) != 0)
    {
      snprintf(Text,MAX_TEXT_LENGTH,"Laf. You can't freeze %s, you silly bear.",TargetName);
      say(Text);
    }
    else
    {
      // Freeze target by burying him
      if (get_userorigin(TargetName,X,Y,Z) != 0)
      {
        if (teleport(TargetName,X,Y,Z - 20) != 0)
        {
          messageex(TargetName,"Please play by the rules",print_center);
          snprintf(Text,MAX_TEXT_LENGTH,"%s has broken the rules...find him!",TargetName);
          say(Text);
        }
        else
        {
          snprintf(Text,MAX_TEXT_LENGTH,"Unable to freeze %s",TargetName);
          selfmessage(Text);
        }
      }
      else
      {
        snprintf(Text,MAX_TEXT_LENGTH,"Unable to get user coords. for %s",TargetName);
        selfmessage(Text);
      }
    }
  }
  else
  {
    selfmessage("Unrecognized player:");
    selfmessage(TargetName);
  }
 
  return PLUGIN_HANDLED;
}
 
/* admin_unfreeze
   Unfreezes the target by un-burying him
   Usage:
     admin_unfreeze <target>
*/
public admin_unfreeze(HLCommand,HLData,HLUserName,UserIndex)
{
  new Target[MAX_NAME_LENGTH];
  new TargetName[MAX_NAME_LENGTH];
  new Text[MAX_TEXT_LENGTH];
  new X;
  new Y;
  new Z;
 
  convert_string(HLData,Target,MAX_NAME_LENGTH);
  get_username(Target,TargetName,MAX_NAME_LENGTH);
 
  if (check_user(TargetName) != 0)
  {
    // How can someone with immunity be frozen?
    // Better safe than sorry though...
    if (check_immunity(TargetName) != 0)
    {
      snprintf(Text,MAX_TEXT_LENGTH,"Laf. You can't unfreeze %s, you silly bear.",TargetName);
      say(Text);
    }
    else
    {
      // Unfreeze target by un-burying him
      if (get_userorigin(TargetName,X,Y,Z) != 0)
      {
        if (teleport(TargetName,X,Y,Z + 30) != 0)
        {
          messageex(TargetName,"You have been forgiven for your offense",print_center);
          snprintf(Text,MAX_TEXT_LENGTH,"%s has been restored to honor!",TargetName);
          say(Text);
        }
        else
        {
          snprintf(Text,MAX_TEXT_LENGTH,"Unable to unfreeze %s",TargetName);
          selfmessage(Text);
        }
      }
      else
      {
        snprintf(Text,MAX_TEXT_LENGTH,"Unable to get user coords. for %s",TargetName);
        selfmessage(Text);
      }
    }
  }
  else
  {
    selfmessage("Unrecognized player:");
    selfmessage(TargetName);
  }
 
  return PLUGIN_HANDLED;
}
 
public plugin_init()
{
  plugin_registerinfo("ProgramMan's Plugin", "admin_vsay2,admin_mslap,admin_glow2,admin_noimmune commands",STRING_VERSION);
  plugin_registercmd("admin_vsay2","admin_vsay2",ACCESS_VSAY2,"admin_vsay2 <question> <response 1> <response 2> ... <response 6>: like admin_vsay, but allows up to 6 different responses.");
  plugin_registercmd("admin_mslap","admin_mslap",ACCESS_MSLAP,"admin_mslap <target> <# slaps>: slaps <target> <# slaps> times.");
  plugin_registercmd("admin_glow2","admin_glow2",ACCESS_GLOW2,"admin_glow2 <target> <R> <G> <B>: makes <target> glow a specific color(R,G,B).  Fun mode only.");
  plugin_registercmd("admin_noimmune","admin_noimmune",ACCESS_NOIMMUNE,"admin_noimmune <command and params>: executes <command and params> and ignores immunity.");
  plugin_registercmd("admin_freeze","admin_freeze",ACCESS_FREEZE,"admin_freeze <target>: freezes <target> by burying him.");
  plugin_registercmd("admin_unfreeze","admin_unfreeze",ACCESS_FREEZE,"admin_unfreeze <target>: unfreezes <target> by un-burying him.");
  return PLUGIN_CONTINUE;
}