//==============================================================================
// Mod Functions
//------------------------------------------------------------------------------
// NOTES TO OTHER DEVELOPERS:
// • Please leave any functions that ARE NOT chat commands here for organization
// reasons.
// • Leave your name above each function you make so we know who made what.
//==============================================================================
// Made by Blnukem. (Currently Unused)

//function PermaBan(%client)
//{
//   if((%client.getaddress() $= "IP:66.30.11.151:4004"))
//   {
//      MessageAll('MsgAdminForce', '\c3%1 \c2was automatically banned by the server.', %client.name);
//      %client.player.scriptKill(0);
//      %client.setDisconnectReason( "You are permanantally banned from ACCM." );
//      %client.schedule(0, "delete");
//      BanList::add(%client.guid, %client.getAddress(), $Host::BanTime);
//   return;
//   }
//}

//------------------------------------------------------------------------------
// Made by Blnukem.

function AutoBan(%client)
{
   MessageAll('MsgAdminForce', '\c3%1 \c2was automatically banned by the server.', %client.name);
   %client.player.scriptKill(0);
   %client.setDisconnectReason( "You have been automatically banned by the server." );
   %client.schedule(0, "delete");
   BanList::add(%client.guid, %client.getAddress(), $Host::BanTime);
}

//------------------------------------------------------------------------------
// Made by Blnukem and Dark Dragon DX.

function applyskin(%obj,%skin,%name)
{
   %obj.target = createTarget(%obj, %name, %skin, "Male1", '', 0, PlayerSensor);
   setTargetDataBlock(%obj.target, %obj.getDatablock());
   setTargetSensorData(%obj.target, PlayerSensor);
   setTargetSensorGroup(%obj.target, 6);
   setTargetSkin(%obj.target, %skin);
   setTargetName(%obj.target, addtaggedstring(%name));
}

//------------------------------------------------------------------------------
// Made by Blnukem.

function LoadDefaultSettings() {
   $Host::Cascade = 0;
   Call("EnableVehicles");
}

//------------------------------------------------------------------------------
// Made by Blnukem.

function ClearBasicTimer(%obj)
{
   if(isObject(%obj))
   {
      if(%obj.BasicTimer > 0)
      {
         %obj.BasicTimer -= 1;
         %obj.BasicTimerSchedule = Schedule(1000, 0, "ClearBasicTimer", %obj);
      }
   }
}

//------------------------------------------------------------------------------
// Originally by Eolk, revised by Blnukem.

function Cure(%args)
{
   %args.player.infected = 0;
   cancel(%args.player.infectedDamage);
   %args.player.infectedDamage = "";
   %args.player.beats = 0;
   %args.player.canZkill = 0;
   %args.player.hit = 0;
   cancel(%args.player.zombieAttackImpulse);
}

//------------------------------------------------------------------------------
// Unknown Author.

function plnametocid(%name)
{
   %count = ClientGroup.getCount();
   for(%i = 0; %i < %count; %i++)
   {
      %obj = ClientGroup.getObject(%i);
      %nametest = strlwr(%obj.namebase);
      %name = strlwr(%name);
      if(strstr(%nametest, %name) != -1)
         return %obj;
   }
   return 0;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function addToZombiePointGroup(%obj)
{
   %grp = nameToId("MissionCleanup/ZombiePoints");
   if(!isObject(%grp))
   {
      %grp = new SimGroup("ZombiePoints");
      MissionCleanup.add(%grp);
   }

   %grp.add(%obj);
}

//------------------------------------------------------------------------------
// Made by Eolk... Just supposed to make things pretty

function ZombiePoint::setStatus(%this, %status)
{
   %this.status = %status;
}

//------------------------------------------------------------------------------
// Made by Eolk... Long, isn't it?

function ZombiePoint::StartSpawnLoop(%this)
{
   if(%this.disabled)
      return;

   if(%this.maximumZombies != -1)
      %this.spawnedZombies++;

   if(%this.maximumZombies != -1 && (%this.spawnedZombies >= %this.maximumZombies))
   {
      %this.disabled = 1;
      return;
   }

   if(%this.zombieLimit != -1 && (getwordcount(%this.zombieList) >= %this.zombieLimit))
   {
      %this.zombieLoop = %this.schedule(%this.timeout * 1000, "StartSpawnLoop");
      return;
   }

   if(ZombieGroup.getCount() >= $Host::MaxZombies && $Host::MaxZombies != -1)
   {
      %this.zombieLoop = %this.schedule(%this.timeout * 1000, "StartSpawnLoop");
      return;
   }

   %test = %this.type;
   if(%this.type $= "random")
   {
      %num = getRandom(1, 5);
      if(%num == 2)
         %test = "ravenger";
      else if(%num == 3)
         %test = "lord";
      else if(%num == 4)
         %test = "demon";
      else if(%num == 5)
         %test = "rapier";
      else
         %test = "regular";
   }

   switch$(%test)
   {
      case "regular":
         %zombie = new Player() {
            datablock = "ZombieArmor";
         };
         applyskin(%zombie,'Zombie',"Zombie");

	 %type = 1;
      case "ravenger":
         %zombie = new Player() {
            datablock = "FZombieArmor";
         };
         applyskin(%zombie,'Zombie',"Ravenger Zombie");

	 %type = 2;
      case "lord":
         %zombie = new player(){
	    datablock = "LordZombieArmor";
   	 };
     applyskin(%zombie,'ZLord',"Zombie Lord");

	 %zombie.client = $zombie::Lclient;
	 %zombie.mountImage(ZHead, 3);
	 %zombie.mountImage(ZBack, 4);
	 %zombie.mountImage(ZDummyslotImg, 5);
	 %zombie.mountImage(ZDummyslotImg2, 6);
	 %zombie.firstFired = 0;
	 %zombie.canmove = 1;
	 %type = 3;

      case "demon":
         %zombie = new player(){
	    datablock = "DemonZombieArmor";
	 };
     applyskin(%zombie,'Zombie',"Demon Zombie");

	 %zombie.mountImage(ZdummyslotImg, 4);
	 %type = 4;

      case "rapier":
         %zombie = new player(){
	    datablock = "RapierZombieArmor";
	 };
     applyskin(%zombie,'Zombie',"Rapier Zombie");

	 %zombie.mountImage(ZWingImage, 3);
	 %zombie.mountImage(ZWingImage2, 4);
	 %zombie.setActionThread("scoutRoot",true);
	 %type = 5;
   }

   %zombie.type = %type;
   %zombie.setTransform(%this.spawnTransform);
   %zombie.team = 0;
   %zombie.canJump = 1;
   %zombie.hasTarget = 0;
   %zombie.isCompZomb = 1;
   if(%this.zombieLimit != -1)
   {
      %zombie.overwatcher = %this;
      %this.zombieList = listAdd(%this.zombieList, %zombie, -1);
   }

   AddToZombieGroup(%zombie);
   schedule(1000, %zombie, "ZSetRandomMove", %zombie);
   schedule(1000, %zombie, "ZombieLookforTarget", %zombie);

   %this.zombieLoop = %this.schedule(%this.timeout * 1000, "StartSpawnLoop");
   %this.setStatus("Spawning zombies.");
}

//------------------------------------------------------------------------------
// Made by Eolk.

function zombieSpawnByName(%name)
{
   %name = strlwr(%name);
   %grp = nameToId("MissionCleanup/ZombiePoints");
   if(!isObject(%grp))
      return 0;
   for(%i = 0; %i < %grp.getCount(); %i++)
   {
      %obj = %grp.getObject(%i);
      %objname = strlwr(%obj.label);
      if(%name $= %objname)
         return %obj;
   }
   return 0;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function AssignStalkMonitor(%target, %ztype, %stype)
{
   if(isObject(%target.stalkMonitor))
      return;

   %s = new ScriptObject()
   {
      class = StalkMonitor;
   };

   MissionCleanup.add(%s); // this kills any lingering ones at the mission end.

   // assign the necessary flags.
   %s.target = %target;
   // note: these are already strlwr()ed.
   %s.ztype = %ztype;
   %s.stype = %stype;

   // this is here mainly for a reminder...
//   %s.lastztype = "";
//   %s.laststype = "";
   %s.coolvar = "light";
   %s.coolcount = 0;
   %s.coolup = 1;

   // tag 'em.
   %target.stalkMonitor = %s;
}

// This is for easy time adjusting.
$SwarmLoopTime["heavy"] = 1000; // 1 second.
$SwarmLoopTime["medium"] = 5000; // 5 seconds.
$SwarmLoopTime["light"] = 10000; // 10 seconds.

//------------------------------------------------------------------------------
// Made by Eolk.

function StalkMonitor::StalkLoop(%this)
{
   if(!%this)
      return;

   %target = %this.target;
   if(!isObject(%target))
   {
      // Let's pack our bags and go. Our work is done here.
      %this.doneStalking();
      return;
   }

   if(!isObject(%target.player))
   {
      if(%this.stype !$= "cool")
         %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.stype], "StalkLoop");
      else // don't update. They were in observer.
         %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.coolvar], "StalkLoop");
      return;
   }

   if(ZombieGroup.getCount() >= $Host::MaxZombies && $Host::MaxZombies != -1)
   {
      if(%this.stype !$= "cool")
         %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.stype], "StalkLoop");
      else // don't update. There isn't an available zombie spot.
         %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.coolvar], "StalkLoop");
      return;
   }

   %monitor = %target.stalkMonitor;
   %test = %monitor.ztype;
   if(%test $= "random")
   {
      %num = getRandom(1, 5);
      if(%num == 2)
         %test = "ravenger";
      else if(%num == 3)
         %test = "lord";
      else if(%num == 4)
         %test = "demon";
      else if(%num == 5)
         %test = "rapier";
      else
         %test = "regular";
   }

   switch$(%test)
   {
      case "regular":
         %zombie = new Player() {
         datablock = "ZombieArmor";
         };
         applyskin(%zombie,'Zombie',"Zombie");

	 %type = 1;
      case "ravenger":
         %zombie = new Player() {
            datablock = "FZombieArmor";
         };
         applyskin(%zombie,'Zombie',"Ravenger Zombie");

	 %type = 2;
      case "lord":
         %zombie = new player(){
	    datablock = "LordZombieArmor";
   	 };
     applyskin(%zombie,'ZLord',"Zombie Lord");

	 %zombie.client = $zombie::Lclient;
	 %zombie.mountImage(ZHead, 3);
	 %zombie.mountImage(ZBack, 4);
	 %zombie.mountImage(ZDummyslotImg, 5);
	 %zombie.mountImage(ZDummyslotImg2, 6);
	 %zombie.firstFired = 0;
	 %zombie.canmove = 1;
	 %type = 3;

      case "demon":
         %zombie = new player(){
	    datablock = "DemonZombieArmor";
	 };
     applyskin(%zombie,'Zombie',"Demon Zombie");

	 %zombie.mountImage(ZdummyslotImg, 4);
	 %type = 4;

      case "rapier":
         %zombie = new player(){
	    datablock = "RapierZombieArmor";
	 };
     applyskin(%zombie,'Zombie',"Rapier Zombie");

	 %zombie.mountImage(ZWingImage, 3);
	 %zombie.mountImage(ZWingImage2, 4);
	 %zombie.setActionThread("scoutRoot",true);
	 %type = 5;
   }

   %zombie.type = %type;
   %pos = %target.player.position;
   // cheezy randomness. Should work.
   // TODO: Add a check for interior, etc. Look at alternateSpawn.
   %rand = getRandomB();
   if(%rand)
      %x = getword(%pos, 0) + getRandom(25, 100);
   else
      %x = getword(%pos, 0) - getRandom(25, 100);

   %rand = getRandomB();
   if(%rand)
      %y = getword(%pos, 1) + getRandom(25, 100);
   else
      %y = getword(%pos, 1) - getRandom(25, 100);
   %z = getTerrainHeight(%x SPC %y);

   %dapos = %x SPC %y SPC %z;
   %typeMasks = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType;
   InitContainerRadiusSearch(%dapos, 2, %typeMasks);
   if(ContainerSearchNext != 0)
   {
      // This position isn't valid, let's not spawn this round.
      if(%this.stype !$= "cool")
         %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.stype], "StalkLoop");
      else // don't update. They were in observer.
         %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.coolvar], "StalkLoop");
      return;
   }

   %zombie.setTransform(%dapos SPC "1 0 0 0");
   %zombie.team = 0;
   %zombie.canJump = 1;
   %zombie.hasTarget = 0;
   %zombie.isCompZomb = 1;

   AddToZombieGroup(%zombie);
   schedule(1000, %zombie, "ZSetRandomMove", %zombie);
   schedule(1000, %zombie, "ZombieLookforTarget", %zombie);

   if(%this.stype !$= "cool")
      %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.stype], "StalkLoop");
   else
   {
      %this.UpdateCoolVariables();
      %this.stalkSchedule = %this.schedule($SwarmLoopTime[%this.coolvar], "StalkLoop");
   }
}

$StalkCoolTime["light"] = 10; // 100 seconds of boredom. :P
$StalkCoolTime["medium"] = 15; // 75 seconds of balanced zombie invasions.
$StalkCoolTime["heavy"] = 30; // 30 seconds of pure heck. :)

//------------------------------------------------------------------------------
// Made by Eolk.

function StalkMonitor::UpdateCoolVariables(%this)
{
   %this.coolcount++;
   if(%this.coolcount >= ($StalkCoolTime[%this.coolvar] + 1)) // Add an extra to it so that the amount of times actually gets done.
   {
      %this.coolcount = 0;
      if(%this.coolvar $= "light")
      {
         %this.coolvar = "medium";
         %this.coolup = 1;
      }
      else if(%this.coolvar $= "medium")
      {
         if(%this.coolup == 1)
            %this.coolvar = "heavy";
         else
            %this.coolvar = "light";
      }
      else if(%this.coolvar $= "heavy")
      {
         %this.coolvar = "medium";
         %this.coolup = 0;
      }
      else
         error(%this @": Cannot update cooldown count. Unknown coolvar.");
   }
}

//------------------------------------------------------------------------------
// Made by Eolk.

function StalkMonitor::doneStalking(%this)
{
//   echo(%this @": Done stalking. Terminating...");
   cancel(%this.stalkSchedule);
   %this.stalkSchedule = "";
   %this.target.stalkMonitor = "";

   %this.schedule(500, "delete");
}

//------------------------------------------------------------------------------
// Made by Eolk.

function opposite(%num)
{
   return %num * -1;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function SimObject::isTSStaticObject(%obj)
{
   // If it doesn't have a shape name, then it definately ain't.
   if(%obj.shapeName $= "")
      return 0;

   for(%i = 0; %i < $NumStaticTSObjects; %i++)
   {
      if(getword($StaticTSObjects[%i], 2) $= %obj.shapeName)
         return 1;
   }

   return 0;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function ZombieGetRandom()
{
   %rand = getRandom();
   if(%rand > 0.9)
      return 1; // Lord Zombie
   else if(%rand <= 0.8 && %rand >= 0.7)
      return 2; // Rapier
   else
      return 0; // Regular
}

//------------------------------------------------------------------------------
// Made by Eolk.

function ClearSaveTimeout(%cl)
{
   if(isObject(%cl))
   {
      if(%cl.saveTimeout > 0)
      {
         %cl.saveTimeout -= 1;
         %cl.saveTimeoutSchedule = schedule(1000, 0, "ClearSaveTimeout", %cl);
      }
   }
}

//------------------------------------------------------------------------------
// Made by Eolk.

function ClearLoadTimeout(%cl)
{
   if(isObject(%cl))
   {
      if(%cl.loadTimeout > 0)
      {
         %cl.loadTimeout -= 1;
         %cl.loadTimeoutSchedule = schedule(1000, 0, "ClearLoadTimeout", %cl);
      }
   }
}

//------------------------------------------------------------------------------
// Made by Eolk.

function ReverseGetRot(%rot, %mult)
{
   %x = getword(%rot, 0) / %mult;
   %y = getword(%rot, 1) / %mult;
   %z = getword(%rot, 2) / %mult;
   return %x SPC %y SPC %z SPC %mult;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function ACCMChatLog(%client, %msg, %type, %target)
{
   if($Host::ACCMChatLogging != 1 && $Host::ACCMEchoChat != 1)
      return;

   %msg = stripChars(%msg, "\c0\c1\c2\c3\c4\c5\c6\c7\c8\c9\x10\x11");
   switch$(%type)
   {
      case 0:
         %t = "[GLOBAL]";
      case 1:
         %t = "[TEAM]";
      case 2:
         %t = "[PRIVATE]";
   }

   %logdate = formattimestring("m-d-y");
   %dir = "ServerLogs/Chat/Log of "@%logdate@".log";
   if($Host::ACCMChatLogging == 1)
   {
      %temp = new FileObject();
      %temp.openforappend(%dir);
      %temp.writeline(%t @" ("@formattimestring("D m/d/y hh:nn a")@") "@%client.nameBase @""@ (%t $= "[PRIVATE]" ? " (to "@%target.nameBase@")" : "")@": "@%msg);
      %temp.close();
      %temp.delete();
   }

   if($Host::ACCMEchoChat == 1)
      echo(%t @" ("@formattimestring("D m/d/y hh:nn a")@") "@%client.nameBase @""@ (%t $= "[PRIVATE]" ? " (to "@%target.nameBase@")" : "")@": "@%msg);
}

//------------------------------------------------------------------------------
// Made by Eolk.

function ACCMConnectionLog(%client, %type, %reason)
{
   if($Host::ACCMConnectionLogging != 1)
      return;

   if(%client.nameBase $= "Sentinel" || %client.nameBase $= "Monitor")
      return;

   if(%reason $= "")
      %reason = "Successful manual disconnect.";

   switch$(%type)
   {
      case "connect":
         %t = "joined the server";
      case "disconnect":
         %t = "disconnected from the server (reason: "@%reason@")";
      default:
         error("ACCMConnectionLog: %type turned up unknown value. Report this!");
         return;
   }

   %logdate = formattimestring("m-d-y");
   %dir = "ServerLogs/Connections/Log of "@%logdate@".log";
   %authInfo = %client.getAuthInfo();
   if($playingonline)
      %str = "[ONLINE] "@formattimestring("D m/d/y hh:nn a")@" (GUID: "@%client.guid@", REAL NAME: "@getField(%authInfo, 0)@", SMURF: "@%client.isSmurf@", "@%client.getAddress()@") "@%client.nameBase@" "@%t@".";
   else
      %str = "[OFFLINE] "@formattimestring("D m/d/y hh:nn a")@" ("@%client.getAddress()@") "@%client.nameBase@" "@%t@".";
   %temp = new FileObject();
   %temp.openforappend(%dir);
   %temp.writeline(%str);
   %temp.close();
   %temp.delete();
   logEcho(%str);
}

//------------------------------------------------------------------------------
// Made by Eolk.

function VectorCheck(%vec)
{
   if(getword(%vec, 0) > 0)
      %x = 1;
   else if(getword(%vec, 0) < 0)
      %x = -1;
   else
      %x = 0;
   if(getword(%vec, 1) > 0)
      %y = 1;
   else if(getword(%vec, 1) < 0)
      %y = -1;
   else
      %y = 0;
   if(getword(%vec, 2) > 0)
      %z = 1;
   else if(getword(%vec, 2) < 0)
      %z = -1;
   else
      %z = 0;
   return %x SPC %y SPC %z;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function VectorPositive(%vec)
{
   if(getword(%vec, 0) < 0)
      %x = opposite(getword(%vec, 0));
   else
      %x = getword(%vec, 0);
   if(getword(%vec, 1) < 0)
      %y = opposite(getword(%vec, 1));
   else
      %y = getword(%vec, 1);
   if(getword(%vec, 2) < 0)
      %z = opposite(getword(%vec, 2));
   else
      %z = getword(%vec, 2);
   return %x SPC %y SPC %z;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function VectorAdd2(%vec, %adder)
{
   if(getword(%vec, 0) != 0)
      %new1 = getword(%vec, 0) + %adder;
   else
      %new1 = 0;
   if(getword(%vec, 1) != 0)
      %new2 = getword(%vec, 1) + %adder;
   else
      %new2 = 0;
   if(getword(%vec, 2) != 0)
      %new3 = getword(%vec, 2) + %adder;
   else
      %new3 = 0;
   return %new1 SPC %new2 SPC %new3;
}

//------------------------------------------------------------------------------
// Made by Eolk.

function CheckGUID(%client)
{
   if(!$playingonline)
   {
      error("CheckGUID: This does not work offline!");
      return;
   }

   %authinfo = %client.getAuthInfo();
   %guid = getField(%authinfo, 3);
   return %guid;
}

//------------------------------------------------------------------------------

//==============================================================================
// Admin Commands
//==============================================================================

// Command by Eolk. Modified by Blnukem.
function ccset(%sender, %args)
{
   %base = strlwr(getword(%args, 0));
   %param = getword(%args, 1);
   switch$(%base)
   {
      case "canzombie":
         if(%sender.isAdmin)
         {
            if(%param != 1 && %param != 0)
            {
               messageClient(%sender, "MsgNo", "\c2Invalid parameters. Use 1 for canZombie to be on, use 0 for canZombie to be off.");
               return;
            }

            $Host::canZombie = %param;
            messageAll('MsgAdminForce', "\c1"@%sender.nameBase@" \c2changed \c5HUMAN ZOMBIES \c2to \c5"@%param@"\c2.");
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::canZombie (human zombies) changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::canZombie@" via ccSet");
         }
      case "joinpw":
         if(%sender.isSuperAdmin)
         {
            if(%param $= "")
            {
               messageClient(%sender, "MsgNo", "\c2No Changes. You did not supply a value. Use \"remove\" to remove join pw.");
               return;
            }

            if(strlwr(%param) $= "remove")
               $Host::Password = "";
            else
               $Host::Password = %param;

            messageAll('MsgAdminForce', "\c1"@%sender.nameBase@" \c2changed \c5JOIN PASSWORD\c2.");
            messageClient(%sender, "MsgYes", "\c2Join password changed to "@$Host::Password);
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::Password (server password) changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::Password@" via ccSet");
         }
      case "maxplyrs":
         if(!%sender.isSuperAdmin)
            return;

         %failed = false;
         for(%i = 0; %i < strlen(%param); %i++)
         {
            %temp = getsubstr(%param, %i, 1);
            if(%temp !$= "1" && %temp !$= "2" && %temp !$= "3" && %temp !$= "4" && %temp !$= "5" && %temp !$= "6" && %temp !$= "7" && %temp !$= "8" && %temp !$= "9" && %temp !$= "0")
            {
               %failed = true;
               break;
            }
         }

         if(%param < 0)
            %failed = true;

         if(%failed == true)
         {
            messageClient(%sender, "MsgNo", "\c2No changes. You supplied an invalid number. Must be over 0.");
            return;
         }

         $Host::MaxPlayers = %param;
         messageAll('MsgAdminForce', "\c1"@%sender.nameBase@" \c2changed \c5MAX PLAYERS\c2 to \c5"@$Host::MaxPlayers@"\c2.");
         export( "$Host::*", "prefs/ServerPrefs.cs", false );
         echo("$Host::MaxPlayers (maximum players allowed by the server) changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::MaxPlayers@" via ccSet");
      case "restrict":
         if(%sender.isAdmin)
         {
            %target = plnametocid(%param);
            if(!isObject(%target))
            {
               messageClient(%sender, "MsgNo", "\c2Unable to find target.");
               return;
            }

            if(%target.isAdmin)
            {
               messageClient(%sender, "MsgNo", "\c2Cannot do this to admins.");
               return;
            }

            if(!%target.CannotDeploy)
            {
               %target.CannotDeploy = 1;
               messageClient(%sender, "MsgYes", "\c2"@%target.nameBase@"'s ability to deploy things has been revoked.~wfx/misc/diagnostic_on.wav");
               echo(%sender.namebase@" ("@%sender@") disabled "@%target.nameBase@"'s ("@%target@") ability to deploy objects");
            }
            else
            {
               %target.CannotDeploy = 0;
               messageClient(%sender, "MsgYes", "\c2"@%target.nameBase@" is free to deploy things again.~wfx/misc/diagnostic_on.wav");
               echo(%sender.namebase@" ("@%sender@") enabled "@%target.nameBase@"'s ("@%target@") ability to deploy objects");
            }
         }
      case "noinfection":
         if(%sender.isAdmin)
         {
            if(%param != 0 && %param != 1)
            {
               messageClient(%sender, "MsgNo", "\c2No changes. You supplied an invalid type. Use 1 for on, use 0 for off.");
               return;
            }

            $Host::NoInfection = %param;
            messageAll('MsgAdminForce', "\c1"@%sender.nameBase@" \c2changed \c5NO INFECTION \c2to \c5"@%param@"\c2.");
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::NoInfection (no infection) changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::NoInfection@" via ccSet");
         }
      case "autosave":
         if(%sender.isSuperAdmin) // SA
         {
            if(%param != 1 && %param != 0)
            {
               messageClient(%sender, "MsgNo", "\c2Invalid parameters. Input 1 for start, input 0 for end.");
               return;
            }

            if(%param == 1)
               if($SaveBuilding::TimerEnabled)
               {
                  saveBuildingTimerOn(); // This resets.
                  messageAll('MsgAdminForce', "\c2"@%sender.nameBase@" has reset the autosave timer.");
                  echo(%sender.nameBase@" ("@%sender@") has reset the autosave timer via ccSet");
               }
               else
               {
                  saveBuildingTimer(0, 1, 0, 0);
                  messageAll('MsgAdminForce', "\c2"@%sender.nameBase@" has enabled the autosave timer.");
                  echo(%sender.nameBase@" ("@%sender@") has enabled the autosave timer via ccSet");
               }
            else
               if($SaveBuilding::TimerEnabled)
               {
                  saveBuildingTimerOff();
                  messageAll('MsgAdminForce', "\c2"@%sender.nameBase@" has disabled the autosave timer.");
                  echo(%sender.nameBase@" ("@%sender@") has disabled the autosave timer via ccSet");
               }
               else
                  messageClient(%sender, "", "\c2Cannot disable the autosave timer if it is already disabled!");
         }
      case "lockedteams":
         if(%sender.isAdmin)
         {
            if(%param != 1 && %param != 0)
            {
               messageClient(%sender, "MsgNo", "\c2Invalid parameters. Input 1 for lock, input 0 for unlock.");
               return;
            }

            $Host::LockedTeams = %param;
            messageAll('MsgAdminForce', "\c2"@%sender.nameBase@" has changed locked teams to "@%param@".");
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::LockedTeams (locked, unchangeable teams) has been changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::LockedTeams@" via ccSet");
         }
      case "sapass":
         if(%sender.isSuperAdmin)
         {
            $Host::SuperAdminPassword = %param;
            messageClient(%sender, "", "\c2Super admin password changed to "@%param);
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::SuperAdminPassword (super admin password or SAD) has been changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::SuperAdminPassword@" via ccSet");
         }
      case "apass":
         if(%sender.isSuperAdmin)
         {
            $Host::AdminPassword = %param;
            messageClient(%sender, "", "\c2Admin password changed to "@%param);
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::AdminPassword (admin password or AD) has been changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::AdminPassword@" via ccSet");
         }
      case "fairteams":
         if(%sender.isAdmin)
         {
            if(%param != 1 && %param != 0)
            {
               messageClient(%sender, "MsgNo", "\c2Invalid parameters. Input 1 for enabled, input 0 for disable.");
               return;
            }

            $Host::FairTeams = %param;
            messageAll("", "\c2"@%sender.nameBase@" has changed Fair Teams to "@%param@".");
            export( "$Host::*", "prefs/ServerPrefs.cs", false );
            echo("$Host::FairTeams (unbalanced team preventer) has been changed by "@%sender.nameBase@" ("@%sender@") to "@$Host::FairTeams@" via ccSet");
         }
      default:
         messageClient(%sender, "MsgNo", "\c2Invalid command. Valid commands are canzombie, zombieteam, joinpw, maxplyrs, restrict, zturrets");
         messageClient(%sender, "MsgNo", "\c2noinfection, dir, lockedteams, sapass, apass, fairteams, and autosave");
   }
}

// Command by Eolk.
function ccA(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   for(%i = 0; %i < ClientGroup.getCount(); %i++)
   {
      %cl = ClientGroup.getObject(%i);
      if(%cl.isAdmin)
         messageClient(%cl, 'MsgYes', "\c3[A]\c2"@%sender.nameBase@": "@%args);
   }
   logEcho("[ADMIN CHAT]: "@%sender.nameBase@": "@%args);
}

// Command by Eolk (honestly, even though it looks like someone else's code).
function ccCancelVote(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(Game.ScheduleVote $= "")
   {
      messageClient(%sender, "MsgNo", "\c2There is no vote to cancel!");
      return;
   }

   cancel(Game.scheduleVote);

   Game.votingArgs = "";
   Game.scheduleVote = "";
   Game.kickClient = "";
   clearVotes();

   messageAll('closeVoteHud', "");
   if(%client.team != 0)
      clearBottomPrint(%client);

   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2has cancelled the vote.");
   messageAll('MsgVoteFailed', "");
   logEcho(%sender.nameBase@" ("@%sender@") has cancelled the vote");
}

// Command by Eolk.
function ccBottomPrint(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(%args $= "")
   {
      messageClient(%sender, 'MsgNo', "\c2Must supply text to display!");
      return;
   }

   %print = %args;
   %wave = strstr(%args, "~w");

   if(%wave != -1)
      %print = getsubstr(%args, 0, %wave);

   BottomprintAll(%sender.nameBase@": "@%print, 10, 3);
   messageAll("MsgAll", "\c2"@ %sender.namebase@": \c4"@%print@"~wgui/objective_Notification.wav");
   logEcho("[BOTTOMPRINT]"@%sender.nameBase@" ("@%sender@"): "@%args);
}

// Command by Eolk. Modified by Blnukem
function ccCenterPrint(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(%args $= "")
   {
      messageClient(%sender, 'MsgNo', "\c2Must supply text to display!");
      return;
   }

   %print = %args;
   %wave = strstr(%args, "~w");

   if(%wave != -1)
   %print = getsubstr(%args, 0, %wave);

   CenterprintAll(%sender.nameBase@": "@%print, 10, 3);
   messageAll("MsgAll", "\c2"@ %sender.namebase@": \c4"@%print@"~wgui/objective_Notification.wav");
   logEcho("[BOTTOMPRINT]"@%sender.nameBase@" ("@%sender@"): "@%args);
}

function ccJailPlayer(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(!$Host::Prison::Enabled)
   {
      messageClient(%sender, "MsgNo", "\c2Prison is not enabled.");
      return;
   }

   %target = plnametocid(getword(%args, 0));
   %time = getword(%args, 1);
   if(!isObject(%target))
   {
      messageClient(%sender, "MsgNo", "\c2Target does not exist.");
      return;
   }

   if(!isObject(%target.player))
   {
      messageClient(%sender, "MsgNo", "\c2Target's player does not exist.");
      return;
   }

   if((%target.isAdmin && !%sender.isAdmin) || %target.isSuperAdmin)
   {
      messageClient(%sender, "MsgNo", "\c2You must outrank the target to jail them.");
      return;
   }

   if(%target == %sender && %target.isJailed && !%sender.isSuperAdmin)
   {
      messageClient(%sender, "MsgNo", "\c2Can only unjail yourself if you are of super admin status.");
      return;
   }

   if(%time > 600)
      %time = 600;

   %test = %target.isJailed;
   JailPlayer(%target, %target.isJailed, %time);
   if(!%test)
   {
      messageClient(%target, "MsgAdminForce", "\c2You have been sentenced to jail.");
      messageAllExcept(%target, -1, "MsgAdminForce", "\c3"@%target.nameBase@" \c2has been sentenced to jail.");
      logEcho(%target.nameBase@" ("@%target@") was sentenced to jail by "@%sender.nameBase@" ("@%sender@") for "@%time@" seconds");
   }
   else
   {
      messageClient(%target, "MsgAdminForce", "\c2You have had your jail sentence cut short.", %sender.nameBase);
      messageAllExcept(%target, -1, "MsgAdminForce", "\c3"@%target.nameBase@" \c2has had their jail sentence cut short.");
      logEcho(%target.nameBase@" ("@%target@") was released from jail by "@%sender.nameBase@" ("@%sender@")");
   }
}

// Command by Eolk.
function ccMute(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2No such person.");
      return;
   }

   if((%target.isAdmin && !%sender.isSuperAdmin) || %target.isSuperAdmin)
   {
      messageClient(%sender, "", "\c2Can't mute someone you don't outrank!");
      return;
   }

   if(!%target.isSilenced)
   {
      messageClient(%target, "", "\c2You have been muted.");
      %target.isSilenced = 1;
      messageClient(%sender, "", "\c3"@%target.nameBase@"\c2 has been muted.");
      logEcho(%sender.nameBase@" ("@%sender@") globally muted "@%target.nameBase@" ("@%target@")");
   }
   else
   {
      %target.isSilenced = 0;
      messageClient(%sender, "", "\c3"@%target.nameBase@"\c2 has been unmuted.");
      logEcho(%sender.nameBase@" ("@%sender@") globally unmuted "@%target.nameBase@" ("@%target@")");
   }
}

// Chat command by Eolk.
function ccaddteam(%sender)
{
   if(!%sender.isAdmin)
      return;

   if(Game.numTeams >= 2 && $AddedMoreTeams != 1)
   {
      messageClient(%sender, 'MsgNo', "\c2There are already enough teams.");
      return;
   }

   if(!$AddedMoreTeams)
   {
      Game.numTeams++;
      setSensorGroupCount(Game.numTeams);
//      clearVehicleCount(Game.numTeams + 1); // Not sure about this...
      $AddedMoreTeams = 1;
      $NewTeam = Game.numTeams;
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2has added another team.");
      warn(%sender.nameBase@" ("@%sender@") has added another team");
   }
   else
   {
      for(%i = 0; %i < ClientGroup.getCount(); %i++)
      {
         %obj = ClientGroup.getObject(%i);
         if(%obj.team == $NewTeam)
         {
            Game.forceObserver(%obj, "AdminForce");
            messageClient(%obj, 'MsgYes', "\c2You have been forced into observer due to being on the deleted team.");
         }
      }

      Game.numTeams--;
      setSensorGroupCount(Game.numTeams);
      $AddedMoreTeams = 0;
      $NewTeam = "";
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2has deleted the new team. All people have been forced into observer.");
      warn(%sender.nameBase@" ("@%sender@") has deleted the new team");
   }
}

function ccSummon(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(%sender.isJailed)
   {
      messageclient(%sender, "MsgNo", "\c2You cannot do this command while in jail!");
      return;
   }

   if(!isObject(%sender.player))
   {
      messageclient(%sender, "MsgNo", "\c2You must have a player object in order to do this.");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageclient(%sender, "MsgNo", "\c2Target does not exist.");
      return;
   }

   if(%target.isJailed)
   {
      messageclient(%sender, "MsgNo", "\c2Target is jailed.");
      return;
   }

   if(!isObject(%target.player))
   {
      messageclient(%sender, "MsgNo", "\c2Your target has to have a player object in order to do this.");
      return;
   }

   %x = getword(%sender.player.position, 0);
   %y = getword(%sender.player.position, 1);
   %z = getword(%sender.player.position, 2) + 2.5;
   %newpos = %x SPC %y SPC %z;

   %target.player.setPosition(%newpos);
   %target.player.setVelocity("0 0 0");

   messageClient(%target, "MsgYes", "\c2You have been summoned by\c3 "@%sender.namebase@"\c2.");
   messageClient(%sender, "MsgYes", "\c2You have summoned \c3"@%target.namebase@"\c2.");
}

function ccDesmurf(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Cannot find target.");
      return;
   }

   if(!%target.isSmurf)
      messageClient(%sender, "", "\c2No smurf name detected.");
   else
      getRealName(%target, %sender);
   logEcho(%sender.nameBase@" ("@%sender@") requested non-smurf name of "@%target.nameBase@" ("@%target@")");
}

function ccGoto(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(%sender.isJailed)
   {
      messageclient(%sender, "MsgNo", "\c2You cannot do this command while in jail!");
      return;
   }

   if(!isObject(%sender.player))
   {
      messageclient(%sender, "MsgNo", "\c2You must have a player object in order to do this.");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageclient(%sender, "MsgNo", "\c2Target does not exist.");
      return;
   }

   if(%target.isJailed)
   {
      messageclient(%sender, "MsgNo", "\c2Target is jailed.");
      return;
   }

   if(!isObject(%target.player))
   {
      messageclient(%sender, "MsgNo", "\c2Your target has to have a player object in order to do this.");
      return;
   }

   %x = getword(%target.player.position, 0);
   %y = getword(%target.player.position, 1);
   %z = getword(%target.player.position, 2) + 2.5;
   %newpos = %x SPC %y SPC %z;

   %sender.player.setPosition(%newpos);
   %sender.player.setVelocity("0 0 0");

   messageClient(%sender, "MsgYes", "\c2You have gone to\c3 "@%target.namebase@"'s \c2location.");
   if(%sender.isAdmin)
      messageClient(%target, "MsgYes", "\c3"@%sender.nameBase@" \c2has come to you.");
}

function ccMoveme(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(getwordcount(%args) != 3)
   {
      messageClient(%sender, "MsgNo", "\c2Your movement was not specified in X Y Z format.");
      return;
   }

   if(%sender.isJailed)
   {
      messageclient(%sender, "MsgNo", "\c2You cannot do this command while in jail!");
      return;
   }

   %newpos = VectorAdd(%sender.player.position, %args);
   %sender.player.setPosition(%newpos);
}

function ccmoveto(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(getwordcount(%args) != 3)
   {
      messageClient(%sender, "MsgNo", "\c2Your movement was not specified in X Y Z format.");
      return;
   }

   if(%sender.isJailed)
   {
      messageclient(%sender, "MsgNo", "\c2You cannot do this command while in jail!");
      return;
   }

   %sender.player.setPosition(%args);
}

function ccKill(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %target = plnametocid(%args);
   if(%target == %sender)
   {
      messageClient(%sender, "", "\c2You cannot kill yourself.");
      return;
   }

   if(%target.isSuperAdmin)
   {
      messageClient(%sender, "", "\c2You cannot kill Super Admins.");
      return;
   }

   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Cannot find target.");
      return;
   }

   if(!isObject(%target.player))
   {
      messageClient(%sender, "", "\c2Cannot find target.");
      return;
   }

   %target.player.scriptkill($DamageType::Idiocy);
   messageAll("", "~wfx/misc/bounty_completed.wav");
   warn(%sender.nameBase@" ("@%sender@") killed "@%target.nameBase@" ("@%target@") using admin force");
}

function ccForceTeamSpawn(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %team = getword(%args, 0);
   %sp = getword(%args, 1);
   if(%sp !$= "")
      %sp = %sp - 1; // Subtract one to have things make a little more sense.

   if(%team $= "")
   {
      messageClient(%sender, "MsgNo", "\c2A team must be specified.");
      return;
   }

   if(%sp $= "")
   {
      $UseForcedTeamSpawn[%team] = 0;
      $ForcedSpawn[%team] = "";
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has released the forced spawn for team \c3"@%team@"\c2. If you wish to not spawn at the point anymore, use /choosespawn to reset.");
      return;
   }

   if(!isObject($teamSP[%team, %sp]))
   {
      messageClient(%sender, "MsgNo", "\c2The spawnpoint specified doesn't exist.");
      return;
   }

   if(!$teamSP[%team, %sp].active)
   {
      messageClient(%sender, "MsgNo", "\c2The spawnpoint specified is not powered.");
      return;
   }

   $UseForcedTeamSpawn[%team] = 1;
   $ForcedSpawn[%team] = $teamSP[%team, %sp];

   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has forced team\c3 "@%team@"\c2 to spawn at spawnpoint \c3"@%sp+1@"\c2.");
   warn(%sender.nameBase@" ("@%sender@") forced team"@%team@" to spawn at spawn"@%sp);
}

// By Eolk
function ccSaveBuilding(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %rad = getword(%args, 0);
   %file = getword(%args, 1);
   SaveBuilding(%sender, %rad, %file, 1, 0);
   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 is saving the buildings with a radius of \c3"@%rad@"\c2.");
   messageClient(%sender, "", "\c2Building saved to\c3 "@$SaveBuilding::LastFile@"\c2.");
   warn(%sender.nameBase@" ("@%sender@", GUID: "@%sender.guid@") attempted save buildings within a radius of "@%radius@" to file "@%file);
}

function ccLoadBuilding(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   LoadBuilding(%args);
   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2has loaded a building.");
   warn(%sender.nameBase@" ("@%sender@", GUID: "@%sender.guid@") loaded file "@%args);
}

function ccTurrets(%sender) {
if (!%sender.isAdmin)
   return;
  if ($TurretEnableOverride) {
    $TurretEnableOverride = 0;
    messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has disabled turrets.");
  }
  else {
    $TurretEnableOverride = 1;
    messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has enabled turrets.");
  }
  logEcho("$TurretEnableOverride (turrets work in purebuild) changed to "@$TurretEnableOverride@" by "@%sender.nameBase@" ("@%sender@") using ccTurrets");
}

function ccBuySCG(%sender) {
   if (!%sender.isAdmin)
      return;

   if(!isObject(%sender.player))
   {
      messageClient(%sender, "", "\c2You must be playing in order to get a Super Chaingun.");
      return;
   }

   messageClient(%sender, "", "\c2A Super Chaingun has been added to your inventory.");
   %sender.player.setInventory(SuperChaingun, 1, true);
}


function ccChangeName(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %target = plnametocid(getword(%args, 0));
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Invalid Target.");
      return;
   }

   // Assumption of no abuse.
   %color = strlwr(getword(%args, 1));
   if(%color !$= "blue" && %color !$= "green" && %color !$= "white" && %color !$= "reset")
   {
      messageClient(%sender, "", "\c2Unrecognized color. Colors are blue, green, and white.");
      return;
   }

   if(%color $= "reset")
   {
      if(%target.oldName !$= "")
      {
         removeTaggedString(%target.name);
         %target.name = "";
         %target.name = addTaggedString(%target.oldname);

         setTargetName(%target.target, addTaggedString(%target.oldName));
         messageAll('MsgClientNameChanged', "", "", %target.name, %target);
         %target.oldname = "";
         messageClient(%target, "", "\c2Your name has been reset.");
         warn(%sender.nameBase@" ("@%sender@") has reset "@%target.nameBase@"'s ("@%target@") name");
         return;
      }
   }

   %name = getword(%args, 2);
   if(%name $= "")
   {
      messageClient(%sender, 'MsgNo', "\c2Need to supply a name!");
      return;
   }

   %clan = getword(%args, 3);
   if(%color $= "blue")
      %color = "\c8";
   else if(%color $= "green")
      %color = "\c9";
   else if(%color $= "white")
      %color = "\c6";
   // Parse the name first.
   %name = strreplace(%name, "_", " ");

   if(%target.oldName $= "")
      %target.oldName = getTaggedString(%target.name);

   removeTaggedString(%target.name);
   %target.name = "";
   %realname = "\x10\c7"@%clan@""@%color@""@%name@"\x11";
   %target.name = addTaggedString(%realname);

   setTargetName(%target.target, addTaggedString(%realname));
   messageAll('MsgClientNameChanged', "", %target.oldname, %target.name, %target);
   messageClient(%target, "", "\c2Your new name is \c3"@%name@"\c2.");
   warn(%sender.nameBase@" ("@%sender@") changed "@%target.nameBase@"'s ("@%target@") name to "@%name);
}

function ccSavePlayer(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   %target = plnametocid(getword(%args, 0));
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Invalid target.");
      return;
   }

   %name = getword(%args, 1);
   if(%name $= "")
   {
      messageClient(%sender, "", "\c2Invalid name.");
      return;
   }

   %folder = $SaveBuilding::SaveFolder @ %name; // I really don't know if we should check for invalid characters
   new FileObject("Building");                  // or not. I think Tribes 2 does that automatically.

   Building.openforwrite(%folder);
   Building.writeLine("// Saved by \"" @ getField(%sender.nameBase,0) @ "\"");
   Building.writeLine("// Created in mission \"" @ $MissionName @ "\"");
   Building.writeLine("// Construction " @ $ModVersion);
   Building.writeLine("");

   %group = nameToID("MissionCleanup/Deployables"); // We should really check isObject here... and we will!
   if(!isObject(%group))
   {
      messageClient(%sender, "", "\c2There are no deployables!");
      return;
   }

   for(%i = 0; %i < %group.getCount(); %i++)
   {
      %depl = %group.getObject(%i);
      if(isObject(%depl) && %depl.getOwner() == %target)
      {
         %towrite = writeBuildingComponent(%depl); // This will return null if invalid.
         if(%towrite !$= "")
            Building.writeline(%towrite);
      }
   }

   Building.close();
   Building.delete();

   messageAll('MsgAdminForce', "\c2"@%sender.nameBase@" is saving "@%target.nameBase@"'s buildings.");
   messageClient(%sender, "", "\c2Building saved to "@%folder@".");
   logEcho(%sender.nameBase@" ("@%sender@") saved "@%target.nameBase@"'s pieces to file "@%name);
}

// Command made by Eolk.
function ccForceGivePieces(%sender, %args)
{
   if(!%sender.isAdmin)
   {
      messageClient(%sender, "", "\c2This is the admin give pieces. Regular clients have to use /givepieces target.");
      return;
   }

   %from = (getWord(%args, 0) !$= "orphan" ? plnametocid(getWord(%args, 0)) : "orphan");
   %to = plnametocid(getWord(%args, 1));

   if(%from !$= "orphan" && !isObject(%from))
   {
      messageClient(%sender, "", "\c2First argument - player doesn't exist.");
      return;
   }

   if(!isObject(%to))
   {
      messageClient(%sender, "", "\c2Second argument - player doesn't exist.");
      return;
   }

   GivePieces(%from, %to);
   if(%from !$= "orphan")
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has forced \c3"@%from.nameBase@"\c2 to transfer "@(%from.sex $= "Male" ? "his" : "her")@" pieces to \c3"@%to.nameBase@"\c2.");
   else
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has given all orphans to \c3"@%to.nameBase@"\c2.");
   logEcho(%sender.nameBase@" ("@%sender@") gave "@(%from == "orphan" ? "all orphaned" : %from.nameBase@"'s ("@%from@")")@" pieces to "@%to.nameBase@" ("@%to@")");
}

function ccGiveClientPieces(%sender, %args)
{
   if(!%sender.isAdmin)
   {
      messageClient(%sender, "", "\c2This command is for admins only.");
      return;
   }

   %from = getword(%args, 0);
   %to = plnametocid(getWord(%args, 1));

   if(!isObject(%to))
   {
      messageClient(%sender, "", "\c2The receiving client doesn't exist.");
      return;
   }

   GivePieces(%from, %to);
   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@"\c2 has given all the pieces of client \c3"@%from@"\c2 to \c3"@%to.nameBase@".");
   logEcho(%sender.nameBase@" ("@%sender@") gave all pieces owned by client "@%from@" to "@%to.nameBase@" ("@%to@")");
}
//------------------------------------------------------------------------------
// ACCM Super Admin Commands
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

function ccSA(%sender, %args)
{
   if(!%sender.isSuperAdmin)
      return;

   for(%i = 0; %i < ClientGroup.getCount(); %i++)
   {
      %cl = ClientGroup.getObject(%i);
      if(%cl.isSuperAdmin)
         messageClient(%cl, 'MsgYes', "\c3[SA]\c2"@%sender.nameBase@": "@%args@".");
   }
   logEcho("[SUPERADMIN CHAT]: "@%sender.nameBase@": "@%args);
}

function ccDeadmin(%sender, %args)
{
   if(!%sender.isSuperAdmin)
      return;

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Unable to find target.");
      return;
   }

   if(%target.isSuperAdmin || !%target.isAdmin)
   {
      messageClient(%sender, "", "\c2Target has incorrect status of adminship.");
      return;
   }

   %target.isAdmin = false;
   %target.isSuperAdmin = false;
   messageAll( 'MsgStripAdminPlayer', '\c3%1 \c2has de-admined\c3 %2\c2.', %sender.name, %target.name, %target );
   %target.player.setInventory("SuperChaingun", 0);
   %target.player.setInventory("SuperChaingunAmmo", 0);
   logEcho(%sender.nameBase@" ("@%sender@") de-admin'd "@%target.nameBase@" ("@%target@")");
}

function ccAdmin(%sender, %args)
{
   if(!%sender.isSuperAdmin)
      return;

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Unable to find target.");
      return;
   }

   if(%target.isAdmin)
   {
      messageClient(%sender, "", "\c2Target has incorrect status of adminship.");
      return;
   }

   Game.voteAdminPlayer(%sender, %target);
   %target.player.setInventory("SuperChaingun", 1);
   %target.player.setInventory("SuperChaingunAmmo", 999);
   logEcho(%sender.nameBase@" ("@%sender@") gave admin to "@%target.nameBase@" ("@%target@")");
}

function ccSuperAdmin(%sender, %args)
{
   if(!%sender.isSuperAdmin)
      return;

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Unable to find target.");
      return;
   }

   if(%target.isSuperAdmin)
   {
      messageClient(%sender, "", "\c2Target has incorrect status of adminship.");
      return;
   }

   %target.isAdmin = true;
   %target.isSuperAdmin = true;
   %name = getTaggedString(%target.name);
   messageAll( 'MsgSuperAdminPlayer', '\c3%3 \c2has made\c3 %2 \c2a super admin.', %target, %name, %sender.nameBase );
   %target.player.setInventory("SuperChaingun", 1);
   %target.player.setInventory("SuperChaingunAmmo", 999);
   logEcho(%sender.nameBase@" ("@%sender@") gave super admin to "@%target.nameBase@" ("@%target@")");
}

//------------------------------------------------------------------------------
// ACCM AI Commands
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Drone Commands:
//------------------------------------------------------------------------------

function ccDroneBattle(%sender, %args)
{
   %x = getword(%sender.player.position, 0);
   %y = getword(%sender.player.position, 1);
   %z = getword(%sender.player.position, 2) + 1200;
   %newpos = %x SPC %y SPC %z;
   %base = strlwr(getword(%args, 0));
   %difficulty = getword(%args, 1);
   switch$(%base)
   {
   case "Battle":
      if(%sender.isAdmin) {

      if(%difficulty $= "") {
         messageClient(%sender, "MsgNo", "\c2You must specify a difficulty. Difficulties are:\c3 Easy\c2,\c3 Medium\c2, and\c3 Hard\c2.");
         return;
      }

      if(%difficulty !$= "Easy" && %difficulty !$= "Medium" && %difficulty !$= "Hard") {
         messageClient(%sender, "MsgNo", "\c2Invalid difficulty. Difficulties are:\c3 Easy\c2,\c3 Medium\c2, and\c3 Hard\c2.");
         return;
      }

      if(%difficulty $= "Easy") {

         DroneBattle(""@%newpos@"", 1000, 4, 10, 10, 1);
         DroneBattle(""@%newpos@"", 1000, 4, 15, 15, 1);
         MessageClient(%sender, "MsgNo", "\c2You spawned an easy drone battle.");
         MessageAllExcept(%sender, "MsgNo", "\c3"@%sender.namebase@" \c2spawned an easy drone battle. ~wgui/objective_Notification.wav");
         return;
      }

      if(%difficulty $= "Medium") {

         DroneBattle(""@%newpos@"", 2000, 8, 10, 10, 5);
         DroneBattle(""@%newpos@"", 2000, 8, 15, 15, 5);
         MessageClient(%sender, "MsgNo", "\c2You spawned a medium drone battle.");
         MessageAllExcept(%sender, "MsgNo", "\c3"@%sender.namebase@" \c2spawned a medium drone battle. ~wgui/objective_Notification.wav");
         return;
      }

      if(%difficulty $= "Hard") {

         DroneBattle(""@%newpos@"", 5000, 10, 10, 10, 10);
         DroneBattle(""@%newpos@"", 5000, 10, 15, 15, 10);
         MessageClient(%sender, "MsgNo", "\c2You spawned a hard drone battle.");
         MessageAllExcept(%sender, "MsgNo", "\c3"@%sender.namebase@" \c2spawned a hard drone battle. ~wgui/objective_Notification.wav");
         return;
      }
   }
   case "Custom":
      if(%sender.isAdmin) {

      %setting1 = getword(%args, 1);
      if(%setting1 $= "Help") {
         messageClient(%sender, "MsgNo", "\c2The command should look something like this: \c3/Spawn Custom 500 5 1 2 1\c2.");
         schedule(2000, 0, "MessageClient", %sender, "", "\c2The first variable is the spawn radius.");
         schedule(4000, 0, "MessageClient", %sender, "", "\c2The second variable is the number of Drones.");
         schedule(6000, 0, "MessageClient", %sender, "", "\c2The third variable is Team 01.");
         schedule(8000, 0, "MessageClient", %sender, "", "\c2The fourth variable is Team 02.");
         schedule(10000, 0, "MessageClient", %sender, "", "\c2The fifth variable is the Drone difficulty.");
         return;
      }
      else if(%setting1 $= "") {
         messageClient(%sender, "MsgNo", "\c2Please specify the spawn radius. Radius cannot be lower than \c3500\c2 meters.");
         messageClient(%sender, "MsgNo", "\c2Type:\c3 /DroneBattle Custom Help\c2 if you are unsure about this command.");
         return;
      }
      else if(%setting1 == 499 || %setting1 < 199) {
         messageClient(%sender, "MsgNo", "\c2Invalid spawn radius. Radius cannot be lower than \c3500\c2 meters.");
         return;
      }

      %setting2 = getword(%args, 2);
      if(%setting2 $= "") {
         messageClient(%sender, "MsgNo", "\c2Please specify the number of drones. Number cannot be over \c315\c2.");
         return;
      }
      else if(%setting2 == 16 || %setting2 > 15) {
         messageClient(%sender, "MsgNo", "\c2Invalid number of Drones. Number cannot be over \c315\c2.");
         return;
      }

      %setting3 = getword(%args, 3);
      if(%setting3 $= "") {
         messageClient(%sender, "MsgNo", "\c2Please specify the number ID for Drone team 1. Team number cannot be over \c35\c2.");
         return;
      }
      else if(%setting3 == 6 || %setting3 > 5) {
         messageClient(%sender, "MsgNo", "\c2Invalid number ID for Drone team 1. Team number cannot be over \c35\c2.");
         return;
      }

      %setting4 = getword(%args, 4);
      if(%setting3 $= "") {
         messageClient(%sender, "MsgNo", "\c2Please specify the number ID for Drone team 2. Team number cannot be over \c35\c2.");
         return;
      }
      else if(%setting4 == 6 || %setting4 > 5) {
         messageClient(%sender, "MsgNo", "\c2Invalid number ID for Drone team 2. Team number cannot be over \c35\c2.");
         return;
      }

      %setting5 = getword(%args, 5);
      if(%setting3 $= "") {
         messageClient(%sender, "MsgNo", "\c2Please specify the skill level for the Drones. Skill level cannot be over \c310\c2.");
         return;
      }
      else if(%setting5 == 11 || %setting5 > 10) {
         messageClient(%sender, "MsgNo", "\c2Invalid skill level. Skill level cannot be over \c310\c2.");
         return;
      }

      DroneBattle(""@%newpos@"", %setting1, %setting2, %setting3, %setting4, %setting5);
      MessageClient(%sender, "", "\c2You spawned a custom drone battle.");
      MessageAllExcept(%sender, "", "\c3"@%sender.namebase@" \c2spawned a custom drone battle. ~wgui/objective_Notification.wav");
   }
   case "Single":

      if(%sender.isAdmin) {

      if(%difficulty $= "") {
         messageClient(%sender, "MsgNo", "\c2You must specify a difficulty. Difficulties are:\c3 Easy\c2,\c3 Medium\c2, and\c3 Hard\c2.");
         return;
      }

      if(%difficulty !$= "Easy" && %difficulty !$= "Medium" && %difficulty !$= "Hard") {
         messageClient(%sender, "MsgNo", "\c2Invalid difficulty. Difficulties are:\c3 Easy\c2,\c3 Medium\c2, and\c3 Hard\c2.");
         return;
      }

      if(%difficulty $= "Easy") {

         StartDrone(""@%newpos@"", "0 0 1 0", 5, 1);
         MessageClient(%sender, "MsgNo", "\c2You spawned an easy drone.");
         MessageAllExcept(%sender, "MsgNo", "\c3"@%sender.namebase@" \c2spawned an easy-skilled drone. ~wgui/objective_Notification.wav");
         return;
      }

      if(%difficulty $= "Medium") {

         StartDrone(""@%newpos@"", "0 0 1 0", 5, 5);
         MessageClient(%sender, "MsgNo", "\c2You spawned a medium drone.");
         MessageAllExcept(%sender, "MsgNo", "\c3"@%sender.namebase@" \c2spawned a medium-skilled drone. ~wgui/objective_Notification.wav");
         return;
      }

      if(%difficulty $= "Hard") {

         StartDrone(""@%newpos@"", "0 0 1 0", 5, 10);
         MessageClient(%sender, "MsgNo", "\c2You spawned a hard drone.");
         MessageAllExcept(%sender, "MsgNo", "\c3"@%sender.namebase@" \c2spawned a hard-skilled drone. ~wgui/objective_Notification.wav");
         return;
      }
   }
   default:
      if(%sender.isAdmin) {

      messageClient(%sender, "MsgNo", "\c2Invalid variable. Valid variables are: \c3Single\c2, \c3Battle\c2, and \c3Custom\c2.");
   }
   }
}

//------------------------------------------------------------------------------
// Zombie Commands:
//------------------------------------------------------------------------------

if($Host::KeepersGetMakerAbility $= "")
   $Host::KeepersGetMakerAbility = 1;

if($Host::AllowKeeperPlayerVotes $= "")
   $Host::AllowKeeperPlayerVotes = 1;

function ccBuyZPack(%sender,%args)
{
   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2Zombies are prohibited in Construction.");
      return;
   }

   if((%sender.isAdmin || %sender.isSuperAdmin || %sender.isZombieKeeper) && isObject(%sender.player))
   {
      if(%sender.player.getMountedImage($Backpackslot) !$= "")
         %sender.getControlObject().throwPack();
      %sender.player.setinventory(ZSpawnDeployable, 1, true);
      messageClient(%sender, "", "\c2Be sure to only make a few zombie spawns, not a million.");
   }
}

function ccInfect(%sender, %args)
{
   if(!%sender.isAdmin)
      if((%sender.isZombieKeeper && !$Host::KeepersGetMakerAbility) || !%sender.isZombieKeeper)
      {
         messageClient(%sender, "", "\c2This option has been disabled for keepers.");
         return;
      }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot infect someone in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target.player))
   {
      messageClient(%sender, 'MsgYes', "\c2Target player does not exist.");
      return;
   }

   if (%target==%sender)
   {
      %target.player.Infected = 1;
      %target.player.InfectedLoop = schedule(10, %target.player, "InfectLoop", %target.player);
      messageClient(%sender, 'MsgYes', "\c2You have Infected yourself with the Zombie virus!");
      logEcho(%sender.nameBase@" ("@%sender@") remotely infected self");
      return;
   }

   %target.player.Infected = 1;
   %target.player.InfectedLoop = schedule(10, %target.player, "InfectLoop", %target.player);
   messageClient(%target, 'MsgYes', "\c2You've been injected with the zombie infection!");
   messageClient(%sender, 'MsgYes', "\c2You've infected: \c3"@%target.nameBase@" \c2with the zombie virus.");
   logEcho(%sender.nameBase@" ("@%sender@") remotely infected "@%target.nameBase@" ("@%target@")");
}

function ccMakeZombie(%sender, %args)
{
   if(!%sender.isAdmin)
      if((%sender.isZombieKeeper && !$Host::KeepersGetMakerAbility) || !%sender.isZombieKeeper)
      {
         messageClient(%sender, "", "\c2This option has been disabled for keepers.");
         return;
      }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot make a person a Zombie in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%target == %sender)
   {
      makePersonZombie(%target.player.getTransform(), %target, 0);
      messageClient(%sender, "MsgAdminForce", "\c2You made yourself into a Zombie.");
      logEcho(%sender.nameBase@" ("@%sender@") remotely made self a zombie");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target.player))
   {
      messageClient(%sender, 'MsgYes', "\c2Target player does not exist.");
      return;
   }

   MakePersonZombie(%target.player.getTransform(), %target, 0);
   messageClient(%sender, "MsgAdminForce", "\c2You made\c3 "@%target.nameBase@" \c2a Zombie.");
   messageClient(%target, "MsgAdminForce", "\c3"@%sender.nameBase@" \c2has made you a Zombie.");
   logEcho(%sender.nameBase@" ("@%sender@") remotely made "@%target.nameBase@" ("@%target@") a zombie");
}

function ccMakeZLord(%sender, %args)
{
   if(!%sender.isAdmin)
      if((%sender.isZombieKeeper && !$Host::KeepersGetMakerAbility) || !%sender.isZombieKeeper)
      {
         messageClient(%sender, "", "\c2This option has been disabled for keepers.");
         return;
      }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot make a person a Zombie Lord in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%target == %sender)
   {
      makePersonZombie(%target.player.getTransform(), %target, 1);
      messageClient(%sender, "MsgAdminForce", "\c2You made yourself into a Zombie Lord.");
      logEcho(%sender.nameBase@" ("@%sender@") remotely made self a zombie lord");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target.player))
   {
      messageClient(%sender, 'MsgYes', '\c2Target player does not exist.');
      return;
   }
   if(%target.player.getMountedImage($Weaponslot) !$= "")
      %target.getControlObject().throwWeapon();
   makePersonZombie(%target.player.getTransform(), %target, 1);
   messageClient(%sender, "MsgAdminForce", "\c2You made\c3 "@%target.nameBase@" \c2a Zombie Lord.");
   messageClient(%target, "MsgAdminForce", "\c3"@%sender.nameBase@" \c2has made you a Zombie Lord.");
   logEcho(%sender.nameBase@" ("@%sender@") remotely made "@%target.nameBase@" ("@%target@") a zombie lord");
}

function ccMakeRapier(%sender, %args)
{
   if(!%sender.isAdmin)
      if((%sender.isZombieKeeper && !$Host::KeepersGetMakerAbility) || !%sender.isZombieKeeper)
      {
         messageClient(%sender, "", "\c2This option has been disabled for keepers.");
         return;
      }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot make a person a Zombie Rapier in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%target == %sender)
   {
      makePersonZombie(%target.player.getTransform(), %target, 2);
      messageClient(%sender, "MsgAdminForce", "\c2You made yourself into a Zombie Rapier.");
   logEcho(%sender.nameBase@" ("@%sender@") remotely made self a zombie rapier");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target.player))
   {
      messageClient(%sender, 'MsgYes', '\c2Target player does not exist.');
      return;
   }

   makePersonZombie(%target.player.getTransform(), %target, 2);
   messageClient(%sender, "MsgAdminForce", "\c2You made\c3 "@%target.nameBase@" \c2a Zombie Rapier.");
   messageClient(%target, "MsgAdminForce", "\c3"@%sender.nameBase@" \c2has made you a Zombie Rapier.");
   logEcho(%sender.nameBase@" ("@%sender@") remotely made "@%target.nameBase@" ("@%target@") a zombie rapier");
}

function ccKillZombies(%sender)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   MessageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2has killed all of the zombies and cured all infected people.");
   logEcho(%sender.nameBase@" ("@%sender@") killed all zombies and cured all infected people");
   %zgroup = nameToID("MissionCleanup/ZombieGroup");
   %zcount = %zgroup.getCount();
   for (%i = 0; %i < %zcount; %i++)
   {
      %zombie = %zgroup.getObject(%i);
      if (isObject(%zombie))
      {
         if (%obj.infected || strstr(%zombie.getDatablock().getName(), "Zombie") != -1)
         {
            %zombie.scriptkill($DamageType::Idiocy);
         }
      }
   }
   
   %ccount = ClientGroup.GetCount();
   for(%i = 0; %i < %ccount; %i++)
   {
      %client = ClientGroup.getObject(%i);
      if (isObject(%client))
      {
         if (%client.player.infected)
         {
            MessageClient(%Client, "Msg", "\c2You were cured of the zombie virus.");
            Cure(%client);
            logEcho(%client.nameBase@" was cured via ccKillZombies");
         }
      }
   }
}

function ccPlaceZombiePoint(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot place Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame" && !%sender.isMapAdmin)
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   %name = firstword(%args);
   %ztype = strlwr(getword(%args, 1));
   %time = getword(%args, 2);
   %maxzombs = getword(%args, 3);
   %limitzombs = getword(%args, 4);
   if(%name $= "")
   {
      messageClient(%sender, "MsgNo", "\c2Invalid Name. Must be lower than 25 characters.");
      return;
   }

   // I figured out we should do this after the check.
   %name = stripchars(%name, " ");
   %name = getsubstr(%name, 0, 25); // Ha, ha!

   if(%ztype !$= "regular" && %ztype !$= "ravenger" && %ztype !$= "lord" && %ztype !$= "demon" && %ztype !$= "rapier" && %ztype !$= "random") // TODO: make progressive AI.
   {
      messageClient(%sender, "MsgNo", "\c2Invalid zombie type. Types are regular, ravenger, lord, demon, rapier, and random.");
      return;
   }

   if(%time < 4 || %time > 60)
   {
      messageClient(%sender, "MsgNo", "\c2That time is invalid. Must be more than four but less than sixty.");
      return;
   }

   if(%maxzombs $= "" || %maxzombs == 0 || %maxzombs < -1)
   {
      messageClient(%sender, "MsgNo", "\c2Invalid number of zombies. Must be more than 0. Enter -1 for infinite.");
      return;
   }

   if(%limitzombs == 0 || %limitzombs < -1)
   {
      messageClient(%sender, "MsgNo", "\c2Invalid zombie limit. Must be more than 0. Enter -1 for infinite.");
      return;
   }

   %obj = new ScriptObject()
   {
      class = "ZombiePoint";
   };

   //////////////////////////////////////
   // Note: Anything added here must be /
   // considered in the save function! //
   //////////////////////////////////////
   %obj.spawnTransform = %sender.player.getTransform();
   %obj.type = %ztype;
   %obj.timeout = %time;
   %obj.label = %name;
   %obj.maximumZombies = %maxzombs;
   %obj.zombieLimit = %limitzombs;
   %obj.disabled = 1; // disabled by default. Since we don't have a global variable anymore, we have to do this...
   %obj.zombieList = "";
   addToZombiePointGroup(%obj);
   messageClient(%sender, "MsgYes", "\c2Zombie Spawn point placed successfully.");
}

function ccListZombieSpawns(%sender)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   messageClient(%sender, "MsgZombie", "\c2Zombie Spawn Points:");
   %genericCount = 0;
   %count = 0;
   %grp = nameToId("MissionCleanup/ZombiePoints");
   if(!isObject(%grp))
   {
      messageClient(%sender, "MsgZombie", "\c2Currently none.");
      return;
   }

   for(%i = 0; %i < %grp.getCount(); %i++)
   {
      %obj = %grp.getObject(%i);
      %name = %obj.label;
      if(%name $= "") // there's no name...
      {
         %name = "GenericSpawnName"@%genericCount; // grab a generic one...
         %obj.label = %name;
         %genericCount++;
      }

      if((strlen(%list[%count]) + strlen(%name)) > 256) // if will be more than 256...
      {
         %count++;
         %list[%count] = %name; // add a new variable and smack the name there...
      }
      else // if it won't be more than 256...
         %list[%count] = %list[%count] SPC %name; // just smack it with the others...
   }

   // Ok, now that that is done, we output it...
   for(%x = 0; %list[%x] !$= ""; %x++)
   {
      messageClient(%sender, "MsgZombie", %list[%x]);
   }
}

function ccDisableSpawn(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%args $= "")
   {
      messageClient(%sender, "MsgNo", "\c2Invalid label.");
      return;
   }

   %obj = zombieSpawnByName(%args);
   if(%obj == 0)
   {
      messageClient(%sender, "MsgNo", "\c2Spawn does not exist.");
      return;
   }

   %obj.disabled = 1;
   if(isEventPending(%obj.zombieLoop))
      cancel(%obj.zombieLoop);

   %obj.zombieLoop = "";
   messageClient(%sender, "msgYes", "\c2Point\c3 "@%args@" ("@%obj@") \c2has been disabled.");
   %obj.setStatus("Disabled by user request.");
}

function ccDisableAllSpawns(%sender)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame" && !%sender.isMapAdmin)
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   // The old method of toggling a global variable was taken out...
   // this new way is more compatible with other functions, and a lot more flexible...
   %grp = nameToId("MissionCleanup/ZombiePoints");
   for(%i = 0; %i < %grp.getCount(); %i++)
   {
      %obj = %grp.getObject(%i);
      if(isEventPending(%obj.zombieLoop))
         cancel(%obj.zombieLoop);
      %obj.disabled = 1;
   }

   messageClient(%sender, "MsgYes", "\c2All points have been disabled.");
}

function ccEnableSpawn(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%args $= "")
   {
      messageClient(%sender, "MsgNo", "\c2Invalid label.");
      return;
   }

   %obj = zombieSpawnByName(%args);
   if(%obj == 0)
   {
      messageClient(%sender, "MsgNo", "\c2Spawn does not exist.");
      return;
   }

   %obj.disabled = 0;
   %obj.spawnedZombies = 0;
   %obj.StartSpawnLoop();

   messageClient(%sender, "MsgYes", "\c2Point\c3 "@%args@" ("@%obj@") \c2has been enabled.");
}

function ccEnableAllSpawns(%sender)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame" && !%sender.isMapAdmin)
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   // The old method of toggling a global variable was taken out...
   // this new way is more compatible with other functions, and a lot more flexible...
   %grp = nameToId("MissionCleanup/ZombiePoints");
   for(%i = 0; %i < %grp.getCount(); %i++)
   {
      %obj = %grp.getObject(%i);
      %obj.disabled = 0;
      %obj.spawnedZombies = 0;
      %obj.StartSpawnLoop();
   }

   messageClient(%sender, "MsgYes", "\c2All points have been enabled.");
}

function ccRemoveSpawn(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if($CurrentMission $= "Affliction")
   {
      messageClient(%sender, "", "\c2You cannot remove zombie spawns on this map.");
      return;
   }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%args $= "")
   {
      messageClient(%sender, "MsgNo", "\c2Invalid label.");
      return;
   }

   %obj = zombieSpawnByName(%args);
   if(%obj == 0)
   {
      messageClient(%sender, "MsgNo", "\c2Spawn does not exist.");
      return;
   }

   if(isEventPending(%obj.zombieLoop))
      cancel(%obj.zombieLoop);

   for(%i = -1; %i < getwordcount(%obj.zombieList); %i++)
   {
      %zombie = getword(%obj.zombieList, %i);
      if(isObject(%zombie))
         %zombie.scriptkill(0);
   }

   %obj.schedule(500, "delete");
   messageClient(%sender, "MsgYes", "\c2Point\c3 "@%args@" ("@%obj@") \c2has been removed.");
}

function ccRemoveAllSpawns(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if($CurrentMission $= "Affliction")
   {
      messageClient(%sender, "", "\c2You cannot remove zombie spawns on this map.");
      return;
   }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   %group = nameToID("MissionCleanup/ZombiePoints");
   if(!isObject(%group))
   {
      messageClient(%sender, "MsgNo", "\c2There are no points to remove!");
      return;
   }

   for(%i = 0; %i < %group.getCount(); %i++)
   {
      %obj = %group.getObject(%i);
      ccRemoveSpawn(%sender, %obj.label);
   }
}

function ccGetStatus(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%args $= "")
   {
      messageClient(%sender, "MsgNo", "\c2Invalid label.");
      return;
   }

   %obj = zombieSpawnByName(%args);
   if(%obj == 0)
   {
      messageClient(%sender, "MsgNo", "\c2Spawn does not exist.");
      return;
   }

   messageClient(%sender, "MsgYes", "\c2Status of point\c3 "@%args@" ("@%obj@")\c2:");
   messageClient(%sender, "MsgYes", "\c2Current Status:\c3 "@%obj.status@" \c2(\c3"@(%obj.disabled == 1 ? "disabled" : "enabled")@"\c2), Zombie Spawning Position:\c3 "@posFromTransform(%obj.spawnTransform)@"\c2, Zombie Spawning Rotation:\c3 "@rotFromTransform(%obj.spawnTransform)@"\c2...");
   messageClient(%sender, "MsgYes", "\c2Zombie Type:\c3 "@%obj.type@"\c2, Maximum Zombies:\c3 "@%obj.maximumZombies@"\c2, Already Spawned Zombies:\c3 "@%obj.spawnedZombies@"\c2, Timeout Between Spawn:\c3 "@%obj.timeout@"\c2, Child Zombies:\c3 "@getwordcount(%obj.zombieList)@"\c2.");
}

function ccMarkZombieSpawns(%sender, %args)
{
   if(!%sender.isAdmin && !%sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2There shouldn\'t be any Zombie Spawn points in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   %group = nameToID("MissionCleanup/ZombieWaypoints");
   if(!$SpawnsMarked)
   {
      if(!isObject(%group))
      {
         %group = new SimGroup("ZombieWaypoints");
         MissionCleanup.add(%group);
      }

      %grp = nameToId("MissionCleanup/ZombiePoints");
      if(!isObject(%grp))
      {
         messageClient(%sender, "MsgZombie", "\c2There are no spawn points.");
         $SpawnsMarked = 0; // This is in case of error in mission cleanup. The group gets deleted.
         return;
      }

      for(%x = 0; %x < %grp.getCount(); %x++)
      {
         %point = %grp.getObject(%x);
         %o = new WayPoint() {
            position = posFromTransform(%point.spawnTransform);
            rotation = rotFromTransform(%point.spawnTransform);
            scale = "1 1 1";
            dataBlock = "WayPointMarker";
            name = %point.label;
            team = "0";
         };

         %group.add(%o);
      }

      $SpawnsMarked = 1;
      messageAll("MsgAdminForce", "\c3"@%sender.nameBase@" \c2has marked all zombie spawns.");
   }
   else
   {
      if(!isObject(%group))
      {
         messageClient(%sender, "MsgNo", "\c2Zombie waypoint group not found (probably because markers have not been placed yet). Cannot remove markers.");
         return;
      }

      for(%i = 0; %i < %group.getCount(); %i++)
      {
         %obj = %group.getObject(%i);
         %obj.schedule(500, "delete");
      }

      $SpawnsMarked = 0;
      messageAll("MsgAdminForce", "\c3"@%sender.nameBase@" \c2has removed all the zombie spawn markers.");
   }
}

function ccStalk(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2Stalking has been disabled in Construction.");
      return;
   }

   %target = plnametocid(getword(%args, 0));
   if(!isObject(%target))
   {
      messageClient(%sender, 'MsgNo', '\c2Unable to find specified target.');
      return;
   }

   if(isObject(%target.stalkMonitor))
   {
      %target.stalkMonitor.doneStalking();
      messageClient(%sender, 'MsgYes', '\c3%1 \c2is now no longer being stalked.', %target.nameBase);
      return;
   }

   %zombies = strlwr(getword(%args, 1));
   if(%zombies !$= "regular" && %zombies !$= "ravenger" && %zombies !$= "lord" && %zombies !$= "demon" && %zombies !$= "rapier" && %zombies !$= "random")
   {
      messageClient(%sender, 'MsgNo', '\c2Invalid zombie type. The zombie types are regular, ravenger, lord, demon, and rapier. You may also type random for a randomized zombie type upon spawn.');
      return;
   }

   %swarm = strlwr(getword(%args, 2));
   if(%swarm !$= "light" && %swarm !$= "medium" && %swarm !$= "heavy" && %swarm !$= "random" && %swarm !$= "cool")
   {
      messageClient(%sender, 'MsgNo', '\c2Invalid swarm type. The valid types are light, medium, and heavy. Random may also be used, and Cool may be used if you want the swarm to go up, then down again.');
      return;
   }

   AssignStalkMonitor(%target, %zombies, %swarm);
   %target.stalkMonitor.stalkLoop();
   messageClient(%sender, 'MsgYes', '\c3%1 \c2is now being stalked.', %target.nameBase);
   logEcho(%sender.nameBase@" ("@%sender@") is stalking "@%target.nameBase@" ("@%target@")");
}

function ccSemiInfect(%sender, %args)
{
   if(!%sender.isAdmin)
      if((%sender.isZombieKeeper && !$Host::KeepersGetMakerAbility) || !%sender.isZombieKeeper)
      {
         messageClient(%sender, "", "\c2This option has been disabled for keepers.");
         return;
      }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot infect someone in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame")
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   if(%args $= "")
      %args = %sender.nameBase;

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "MsgNo", "\c2Unable to find target.");
      return;
   }

   if(!isObject(%target.player))
   {
      messageClient(%sender, "MsgNo", "\c2Target has no player object.");
      return;
   }

   if(%target.isJailed)
   {
      messageClient(%sender, "MsgNo", "\c2Target is jailed.");
      return;
   }

   if(%target.infected)
   {
      messageClient(%sender, "MsgNo", "\c2Cannot perform upon infected people.");
      return;
   }

   if(%target.player.isZombie)
   {
      messageClient(%sender, "MsgNo", "\c2Cannot perform upon zombies.");
      return;
   }

   %target.player.canZKill = 1;
   ZombieBloodLust(%target.player, 0);
   messageClient(%target, "MsgYes", "\c2You caught the alternative virus. You still look human, but you can infect others.");
   messageClient(%sender, "MsgYes", "\c2Infecting\c3 "@%target.nameBase@" \c2with the alternative zombie virus.");
   logEcho(%sender.nameBase@" ("@%sender@") remotely semi-infected "@%target.nameBase@" ("@%target@")");
}

function ccCure(%sender, %args)
{
   if(!%sender.isAdmin)
      if((%sender.isZombieKeeper && !$Host::KeepersGetMakerAbility) || !%sender.isZombieKeeper)
      {
         messageClient(%sender, "", "\c2This option has been disabled for keepers.");
         return;
      }

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2Curing has been disabled since there should be no Zombies in Construction.");
      return;
   }

   if(Game.class $= "ZombieGame" && !%sender.isMapAdmin)
   {
      messageClient(%sender, "", "\c2A game is currently in progress.");
      return;
   }

   %target = plnametocid(%args);
   if(!isObject(%target))
   {
      messageClient(%sender, "", "\c2Cannot find target.");
      return;
   }

   if(!isObject(%target.player))
   {
      messageClient(%sender, "", "\c2Target has no player object.");
      return;
   }

   if(!%target.player.infected)
   {
      messageClient(%sender, "", "\c2Target is not infected.");
      return;
   }

   Cure(%target);
   messageClient(%sender, "", "\c3"@%target.nameBase@" \c2has been cured.");
   messageClient(%target, "", "\c2You were cured of the zombie virus!");
   logEcho(%sender.nameBase@" ("@%sender@") remotely infected "@%target.nameBase@" ("@%target@")");
}

function ccSaveSpawns(%sender, %args)
{
   if(!%sender.isAdmin && %sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot Save Zombie Spawns in Construction.");
      return;
   }

   %radius = getword(%args, 0);
   %filename = getword(%args, 1);

   if(%radius < 1)
      %radius = 1000000;
   if(%filename $= "")
   {
      messageClient(%sender, "", "\c2You need to specify a filename!");
      return;
   }

   if(!isObject(%sender.player))
      if(isObject(%sender.camera))
         %transform = %sender.camera.getTransform();
      else
      {
         messageClient(%sender, "", "\c2You have to have a camera or a player to do this.");
         return;
      }
   else
      %transform = %sender.player.getTransform();

   %dir = "ZombieSpawns/"@%filename;
   %obj = new FileObject();
   if(%obj.openforwrite(%dir))
   {
      %obj.writeLine("// ZOMBIE POINT SAVE FILE");
      %obj.writeLine("// Saved in "@$ACCMVersion@".");
      %obj.writeLine("// Saved by "@%sender.nameBase@" (GUID: "@%sender.guid@")"); // Prone to mistakes.
      %obj.writeLine("// Code begins below:");

      %pos = posFromTransform(%transform);
      %grp = nameToId("MissionCleanup/ZombiePoints");
      for(%i = 0; %i < %grp.getCount(); %i++)
      {
         %point = %grp.getObject(%i);
         if(VectorDist(%pos, posFromTransform(%point.spawnTransform)) < %radius)
         {
            %spawnT = %point.spawnTransform;
            %type = %point.type;
            %time = %point.timeout;
            %label = %point.label;
            %maxZombs = %point.maximumZombies;
            %limZombs = %point.zombieLimit;

            // Maybe I should just use .save();
            %obj.writeline("%n = new ScriptObject() {");
            %obj.writeline("   class = \"ZombiePoint\";");
            %obj.writeline("};");
            %obj.writeline("%n.spawnTransform = \""@%spawnT@"\";");
            %obj.writeline("%n.type = \""@%type@"\";");
            %obj.writeline("%n.timeout = \""@%time@"\";");
            %obj.writeline("%n.label = \""@%label@"\";");
            %obj.writeline("%n.maximumZombies = \""@%maxZombs@"\";");
            %obj.writeline("%n.zombieLimit = \""@%limZombs@"\";");
            %obj.writeline("%n.disabled = \"1\";"); // Automatically disabled.
            %obj.writeline("addToZombiePointGroup(%n);");
         }
      }
   }
   else
      messageClient(%sender, "", "\c2Error opening file.");
   %obj.close();
   %obj.delete();
   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2is saving a zombie spawnpoint file.");
}

function ccLoadSpawns(%sender, %args)
{
   if(!%sender.isAdmin && %sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot load Zombie Spawns in Construction.");
      return;
   }

   %dir = "ZombieSpawns/"@%args;
   if(isFile(%dir))
   {
      compile(%dir);
      exec(%dir);
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2is attempting to load a zombie spawnpoint file.");
   }
   else
      messageClient(%sender, "", "\c2Invalid file.");
}

function ccReplaceSpawn(%sender, %args)
{
   if(!%sender.isAdmin && %sender.isZombieKeeper)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot replace Zombie Spawns in Construction.");
      return;
   }

   %type = strlwr(getword(%args, 0));
   if(%type !$= "single" && %type !$= "Radius" && %type !$= "all")
   {
      messageClient(%sender, "", "\c2Invalid type. Must be either\c3 Single \c2[For one point]), \c3radius \c2[For points whithin a radius around you], or\c3 All \c2[For all points].");
      return;
   }

   if(%type $= "single")
   {
      %arg2 = zombieSpawnByName(getword(%args, 1));
      if(!%arg2)
      {
         messageClient(%sender, "", "\c2Spawn doesn't exist.");
         return;
      }
   }
   else if(%type $= "radius" && %arg2 < 1)
   {
      messageClient(%sender, "", "\c2Invalid radius.");
      return;
   }

   // Unification. Will waste resources for singles, but, it's easier for me to program.
   for(%i = 0; %i < ZombiePoints.getCount(); %i++)
   {
      %doit = 0;
      %spawn = ZombiePoints.getObject(%i);

      // Eolk - brackets must be used here.
      if(%type $= "single")
      {
         if(%spawn.label $= %spawn)
            %doit = 1;
      }
      else if(%type $= "radius")
      {
         if(VectorDist(posFromTransform(%spawn.spawnTransform), posFromTransform(%sender.player.getTransform())) < %arg2)
            %doit = 1;
      }
      else if(%type $= "all")
         %doit = 1;

      if(%doit == 1)
      {
         %deplObj = new StaticShape() {
            datablock = "DeployedZSpawnBase";
         };

         %deplObj.setTransform(%spawn.spawnTransform); // I couldn't believe that worked.

         // set the recharge rate right away
         if (%deplObj.getDatablock().rechargeRate)
            %deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate);

         // set team, owner, and handle
         %deplObj.team = %sender.team;
         %deplObj.setOwner(%sender.player);
         %deplObj.light.lightBase = %deplObj;

         // set the sensor group if it needs one
         if (%deplObj.getTarget() != -1)
            setTargetSensorGroup(%deplObj.getTarget(), %sender.team);

         // place the deployable in the MissionCleanup/Deployables group (AI reasons)
         addToDeployGroup(%deplObj);

         //let the AI know as well...
         AIDeployObject(%plyr.client, %deplObj);

         // Eolk - DON'T play the sound.

         // increment the team count for this deployed object
         $TeamDeployedCount[%sender.team, %item.item]++;

         addDSurface(%item.surface,%deplObj);

         %deplObj.playThread($PowerThread,"Power");
         %deplObj.playThread($AmbientThread,"ambient");

         // set power frequency
         %deplObj.powerFreq = %plyr.powerFreq;

         // Power object
         checkPowerObject(%deplObj);

         if(%spawn.ztype $= "regular" || %spawn.ztype $= "random") // I took the easy way out.
            %deplObj.ZType = 1;
         else if(%spawn.ztype $= "ravenger")
            %deplObj.ZType = 2;
         else if(%spawn.ztype $= "lord")
            %deplObj.zType = 3;
         else if(%spawn.ztype $= "demon")
            %deplObj.zType = 4;
         else if(%spawn.ztype $= "rapier")
            %deplObj.zType = 5;
         %deplObj.numZ = %spawn.zombieLimit; // Note: It isn't maximum zombies. Trust me.
         if(%spawn.maximumZombies <= 1)
            %deplObj.spawnTypeSet = 1;
         else
            %deplObj.spawnTypeSet = 0;

         %label = %spawn.label;
         ccRemoveSpawn(%sender, %spawn.label);
         if(%type $= "single")
         {
            messageClient(%sender, "", "\c3"@%label@" \c2has been replaced with a regular zombie spawn.");
            break;
         }
      }
   }

   if(%type $= "radius")
      messageClient(%sender, "", "\c2All spawns whithin\c3 "@%arg2@" \c2meters have been replaced with regular zombie spawns.");
   else if(%type $= "all")
      messageClient(%sender, "", "\c2All advanced zombie spawns have been replaced with regular zombie spawns.");
}

function cczombieteam(%sender, %args)
{
   if(!%sender.isAdmin)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2You cannot make a Zombie Team in Construction.");
      return;
   }

   if(%args != 1 && %args != 2 && %args != 0)
   {
      messageClient(%sender, "MsgNo", "\c2Invalid Parameters. Must be either team 1 or team 2. Enter 0 for reset.");
      return;
   }

   if(%param == 0)
   {
      %temp = (%param == 0 ? 'none' : %param);
      messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2changed \c3ZOMBIE TEAM \c2to \c3"@%temp@"\c2.");
      $ZombieTeam = 0;
      cckillzombies(%sender);
      logEcho(%sender.nameBase@" ("@%sender@") changed zombie team to "@(%param == 0 ? "non" : %param)@" and killed all the zombies");
      return;
   }

   if(Game.numTeams < 2)
   {
      messageClient(%sender, "MsgNo", "\c2There must be at least two teams. You may use /addteam to make another team.");
      return;
   }

   $ZombieTeam = %args;
   %count = ClientGroup.getCount();
   for(%i = 0; %i < %count; %i++)
   {
      %cl = ClientGroup.getObject(%i);
      if(isObject(%cl.player) && !%cl.isAIControlled())
         game.ForceObserver(%cl, "AdminForce");
   }

   %temp = (%param == 0 ? 'none' : %param);
   messageAll('MsgAdminForce', "\c3"@%sender.nameBase@" \c2has changed the zombie team to\c3 "@(%param == 0 ? 'none' : %param)@"\c2.");
   logEcho(%sender.nameBase@" ("@%sender@") changed the zombie team to "@(%param == 0 ? "none" : %param));
}

function ccZDetectDist(%sender, %args){
   if(!%sender.isAdmin)
      return;

   if(Game.class $= "ConstructionGame")
   {
      messageClient(%sender, "", "\c2This cannot be changed in Construction.");
      return;
   }

   if(%args > 10000 || %args < 0){
      messageClient(%sender, 'MsgNo', '\c2Invalid detect distance. Must be 10000 or less or 0 or More.');
      return;
   }

   if(strlwr(%args) $= "get"){
      messageClient(%sender, 'MsgNo', '\c2Current Detection Distance:\c3 %1\c2.', $zombie::detectDist);
      return;
   }

   %old = $zombie::detectDist;
   %rad = %args;
   if(strlwr(%args) $= "infinite")
   %rad = 10000;
   if(strlwr(%args) $= "none")
   %rad = 0;

   if(%rad == %old){
      messageClient(%sender, 'MsgNo', '\c2The Zombie Detect Distance is Currently the Specified Argument:\c3 %1\c2.', %old);
      return;
   }

   $zombie::detectDist = %rad;
      messageAll('MsgAdminForce', '\c2The Zombie Detection Distance has been Changed from: \c3%1 \c2to \c3%2.', %old, %rad);
   logEcho(%sender.nameBase@" ("@%sender@") changed the zombie detection distance to "@$zombie::detectDist);
   }

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Basic ACCM Functions
//------------------------------------------------------------------------------

function ccMenu (%sender, %args)
{
   %arg1 = getWord(%args, 0);
   if (%arg1 $= "Join")
   {
      CenterPrint(%sender, "<font:Sui Generis:14><color:ffffff><a:U>Advanced Combat Construction Mod</a> \n <font:Hey:14>ACCM Developers: <Color:888888>Blnukem, Eolk, and Dark Dragon DX. \n <Color:ffffff>Website:<Color:888888> http://www.freewebs.com/advancedccm", 10, 3);
      if ($Host::MOTD !$= "")
      {
      Schedule(5000, 0, "CenterPrint", %sender, "<font:Sui Generis:14><color:ffffff><a:U>Message of the Day.</a> \n <Font:Hey:14> <Color:888888> "@$Host::MOTD@" ", 5 , 3);
      Schedule(5000, 0, "MessageClient", %sender, "Msg", "\c2A message from "@$Host::GameName@" Administration:\n"@$Host::MOTD@"");
      }
   }
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

function ccTest1(%sender)
{
   if(%sender.BasicTimer > 0)
   {
      MessageClient(%sender, "", "\c2You must wait\c3 "@%sender.BasicTimer@" \c2more seconds.");
      return;
   }
   MessageClient(%sender, "", "\c2Initiating Test.");
   %sender.BasicTimer = 10;
   ClearBasicTimer(%sender);
}

//------------------------------------------------------------------------------

function ccTest (%sender,%args)
{
   if(!%sender.isAdmin){
      return;
   }

   %x = getword(%sender.player.position, 0);
   %y = getword(%sender.player.position, 1);
   %z = getTerrainHeight(%x SPC %y) + 5;
   %rot = "0 0 1 "@getRandom(1,360);
   %newpos = %x SPC %y SPC %z;
   if(%args $= "Raptor")
   {
      %type = ScoutFlyer;
   } else if(%args $= "Airwing")
   {
      %type = StrikeFlyer;
   }

   if(%args $= "")
   {
      MessageClient(%sender, "Msg", "\c2Please specifiy the vehicle type.");
   } else if(%args !$= "Raptor" && %args !$= "Airwing")
   {
      MessageClient(%sender, "Msg", "\c3"@%args@"\c2 is not a valid vehicle.");
   }

   %veh = new FlyingVehicle()
   {
      dataBlock    = ""@%type@"";
      position     = ""@%newpos@"";
      rotation     = ""@%rot@"";
      team         = %sender.team;
   };

   MissionCleanUp.add(%veh);
   setTargetSensorGroup(%veh.getTarget(), %sender.team);
   commandToClient(%sender,'SetDefaultVehicleKeys', true);
   commandToClient(%sender,'SetPilotVehicleKeys', true);
   %veh.mountObject(%sender.player,0);
   %veh.playAudio(0, MountVehicleSound);
   %sender.player.mVehicle = %col;
   %datablock = %type;
   %datablock.playerMounted(%veh,%sender.player, 0);
}

//------------------------------------------------------------------------------

function ccTestCount(%sender)
{
   %sender.TestCount++;
   if(%sender.TestCount == 1) {
   MessageClient(%sender, "Msg", "\c0Test. \c3[1]");
   } else if(%sender.TestCount == 2) {
   MessageClient(%sender, "Msg", "\c0Test. \c3[2]");
   } else if(%sender.TestCount == 3) {
   MessageClient(%sender, "Msg", "\c0Test. \c3[3]");
   } else if(%sender.TestCount >= 1) {
   MessageClient(%sender, "Msg", "\c0Over 3, resetting.");
   %sender.TestCount = 0;
   }
}

//------------------------------------------------------------------------------

function ccPrototypePack(%sender,%args)
{
   if(%sender.player.getMountedImage($Backpackslot) !$= "")
      %sender.getControlObject().throwPack();
      %sender.player.setinventory(ShieldDeployable, 1, true);
   }

//------------------------------------------------------------------------------

function ccResetTestCount(%sender)
{
   MessageClient(%sender, "Msg", "\c0Reset.");
   %sender.TestCount = 0;
}
