context: /*
   * DAWN OF LIGHT - The first free open source DAoC server emulator
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   *
   */
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Linq;
  using System.Reflection;
  
  using DOL.AI;
  using DOL.AI.Brain;
  using DOL.Database;
  using DOL.GS.Effects;
  using DOL.GS.Housing;
  using DOL.GS.Movement;
  using DOL.GS.PacketHandler;
  using DOL.GS.Quests;
  using DOL.GS.Utils;
  
  namespace DOL.GS.Commands
  {
  	[Cmd("&mob", //command to handle
  	     ePrivLevel.GM, //minimum privelege level
  	     "Mob creation and modification commands.", //command description
  	     // usage
  	     "'/mob create [ClassName(DOL.GS.GameNPC)] [eRealm(0)]' to create a new mob.",
  	     "'/mob fastcreate <ModelID> <level> [save(default = 0; use 1 to save)] <name>' to create mob with specified info.",
  	     "'/mob nfastcreate <ModelID> <level> <number> [radius(10)] [name]' to create multiple mobs within radius.",
  	     "'/mob nrandcreate <number> [radius(50)]' to create multiple random mobs within radius.",
  	     "'/mob model <ModelID> [OID]' to set the mob's model, optionally using OID if mob isn't targeted.",
  	     "'/mob modelinc <#> Increments the mob model by 1.",
  	     "'/mob modeldec <#> Decrements the mob model by 1.",
  	     "'/mob size <size>' to set the mob's size (1..255).",
  	     "'/mob translationid <translation id>' to set the mob's translation id.",
  	     "'/mob name <name>' to set the mob's name.",
  	     "'/mob suffix <suffix>' to set the mob's suffix.",
  	     "'/mob guild <guild name>' to set the mob's guild name (blank to remove).",
  	     "'/mob examinearticle <examine article>' to set the mob's examine article.",
  	     "'/mob messagearticle <message article>' to set the mob's message article.",
  	     "'/mob peace' toggle whether the mob can be attacked.",
  	     "'/mob aggro <level>' to set mob's aggro level (0..100)%.",
  	     "'/mob range <distance>' to set mob's aggro range.",
  	     "'/mob distance <maxdistance>' set mob max distance from its spawn (>0=real, 0=no check, <0=percent of aggro range).",
  	     "'/mob roaming <distance>' set mob random range radius (0=noroaming, -1=standard, >0=individual).",
  	     "'/mob damagetype <eDamageType>' set mob damage type.",
  	     "'/mob movehere' move mob to player's location.",
  	     "'/mob location' say location information in the chat window.",
  	     "'/mob remove [true]' to remove this mob from the DB; specify true to also remove loot templates (if no other mobs of same name exist).",
  	     "'/mob ghost' makes this mob ghost-like.",
  	     "'/mob stealth' makes the mob stealthed (invisible).",
  	     "'/mob torch' turns this mobs torch on and off.",
  	     "'/mob statue' toggles statue effect.",
  	     "'/mob fly [height]' makes this mob able to fly by changing the Z coordinate; moves mob up by height.",
  	     "'/mob swimming' toggles mob's swimming flag (helpful for flying mobs).",
  	     "'/mob noname' still possible to target this mob, but removes the name from above mob.",
  	     "'/mob notarget' makes it impossible to target this mob and removes the name from above it.",
  	     "'/mob kill' kills the mob without removing it from the DB.",
  	     "'/mob heal' restores the mob's health to maximum.",
  	     "'/mob attack <PlayerName>' command mob to attack a player.",
  	     "'/mob state' show mob state (attackers, effects).",
  	     "'/mob info' extended information about the mob.",
  	     "'/mob realm <eRealm>' set the mob's realm.",
  	     "'/mob speed <speed>' set the mob's max speed.",
  	     "'/mob level <level>' set the mob's level.",
  	     "'/mob levela <level>' set the mob's level and auto adjust stats.",
  	     "'/mob brain <ClassName>' set the mob's brain.",
  	     "'/mob respawn <duration>' set the mob's respawn time (in ms).",
  	     "'/mob questinfo' show mob's quest info.",
  	     "'/mob refreshquests' Update this mobs list of data quests.",
  	     "'/mob equipinfo' show mob's inventory info.",
  	     "'/mob equiptemplate load <EquipmentTemplateID>' to load the inventory template from the database, it is open for modification after.",
  	     "'/mob equiptemplate create' to create an empty inventory template.",
  	     "'/mob equiptemplate add <slot> <model> [color] [effect] [extension]' to add an item to the inventory template.",
  	     "'/mob equiptemplate remove <slot>' to remove item from the specified slot in the inventory template.",
  	     "'/mob equiptemplate clear' to remove the inventory template from mob.",
  	     "'/mob equiptemplate save <EquipmentTemplateID> [replace]' to save the inventory template with a new name.",
  	     "'/mob equiptemplate close' to finish the inventory template you are creating.",
  	     "'/mob visibleslot <slot>' to set the visible weapon slot.  use slot names (left, right, two, distance).",
  	     "'/mob dropcount [number]' to set the max number of drops for mob (omit number to view current value).",
  	     "'/mob dropcount2 [number]' same as '/mob dropcount' but for the 'MobDrop' generator.",
  	     "'/mob addloot <ItemTemplateID> <chance> [count]' to add loot to the mob's unique drop table.  Optionally specify count of how many to drop if chance = 100%.",
  	     "'/mob addloot2 <ItemTemplateID> <chance> [count]' to add loot to the mob's drop table. Optionally specify count of how many item to drop if chance < 100%.",
  	     "'/mob addotd <ItemTemplateID> <min level>' add a one time drop to this mob..",
  	     "'/mob viewloot [random] [inv]' to view the selected mob's loot table.  Use random to simulate a kill drop, random inv to simulate and generate the loots.",
  	     "'/mob removeloot <ItemTemplateID>' to remove loot from the mob's unique drop table.",
  	     "'/mob removeloot2 <ItemTemplateID>' same as '/mob removeloot' but for the 'MobDrop' generator.",
  	     "'/mob removeotd <ItemTemplateID>' to remove a one time drop from the mob's unique drop table.",
  	     "'/mob refreshloot' to refresh all loot generators for this mob.",
  	     "'/mob copy [name]' copies a mob exactly and places it at your location.",
  	     "'/mob npctemplate <NPCTemplateID>' creates a mob with npc template, or modifies target.",
  	     "'/mob npctemplate create <NPCTemplateID>' creates a new template from selected mob.",
  	     "'/mob class <ClassName>' replaces mob with a clone of the specified class.",
  	     "'/mob path <PathID>' associate the mob to the specified path.",
  	     "'/mob house <HouseNumber>' set NPC's house number.",
  	     "'/mob <stat> <amount>' Set the mob's stats (str, con, dex, qui, int, emp, pie, cha).",
  	     "'/mob tether <tether range>' set mob tether range (>0: check, <=0: no check).",
  	     "'/mob hood' toggle cloak hood visibility.",
  	     "'/mob cloak' toggle cloak visibility.",
  	     "'/mob race [ID]' view or set NPC's race (ID can be # or name).",
  	     "'/mob race reload' reload race resists from the database.",
  	     "'/mob bodytype <ID>' changing the mob's bodytype.",
  	     "'/mob gender <0 = neutral | 1 = male | 2 = female>' set gender for this mob.",
  	     "'/mob packageid <string>' set the package ID for this mob.",
  	     "'/mob select' select the mob within 100 radius (used for selection of non-targettable GameNPC).",
  	     "'/mob load <Mob_ID>' load the Mob_ID from the DB and update the Mob cache.",
  	     "'/mob reload <name>' reload the targetted or named mob(s) from the database.",
  	     "'/mob findname <name> <#>' search for a mob with a name like <name> with maximum <#> (def. 10) matches.",
  	     "'/mob trigger <type> <chance> <emote> <text>' adds a trigger to targeted mob class.  Use '/mob trigger help' for more info.",
  	     "'/mob trigger info' Give trigger informations.",
  	     "'/mob trigger remove <id>' Remove a trigger.",
  	     "'/mob ownerid <id>' Sets and saves the OwnerID for this mob."
  	    )]
  	public class MobCommandHandler : AbstractCommandHandler, ICommandHandler
  	{
  		private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  
  		private const ushort AUTOSELECT_RADIUS = 100; // /mob select command
  
  		public void OnCommand(GameClient client, string[] args)
  		{
  			if (args.Length == 1)
  			{
  				DisplaySyntax(client);
  				return;
  			}
  
  			try
  			{
  				GameNPC targetMob = null;
  				if (client.Player.TargetObject != null && client.Player.TargetObject is GameNPC)
  					targetMob = (GameNPC)client.Player.TargetObject;
  
  				if (args[1] != "create"
  				    && args[1] != "fastcreate"
  				    && args[1] != "nrandcreate"
  				    && args[1] != "nfastcreate"
  				    && args[1] != "npctemplate"
  				    && args[1] != "model"
  				    && args[1] != "modelinc"
  				    && args[1] != "modeldec"
  				    && args[1] != "copy"
  				    && args[1] != "select"
  				    && args[1] != "reload"
  				    && args[1] != "findname"
  				    && targetMob == null)
  				{
  					// it is not a mob
  					if (client.Player.TargetObject != null)
  					{
  						client.Out.SendMessage("Cannot use " + client.Player.TargetObject + " for /mob command.", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  						return;
  					}
  
  					// nothing selected - trying to autoselect a mob within AUTOSELECT_RADIUS radius
  					if (client.Player.TargetObject == null)
  					{
  						select(AUTOSELECT_RADIUS, client);
  						return;
  					}
  				}
  
  				switch (args[1])
  				{
  						case "create": create(client, args); break;
  						case "fastcreate": fastcreate(client, args); break;
  						case "nfastcreate": nfastcreate(client, args); break;
  						case "nrandcreate": nrandcreate(client, args); break;
  						case "model": model(client, targetMob, args); break;
  						case "modelinc": modelinc(client, targetMob, args); break;
  						case "modeldec": modeldec(client, targetMob, args); break;
  						case "size": size(client, targetMob, args); break;
  						//case "translationid": translationid(client, targetMob, args); break;
  						case "name": name(client, targetMob, args); break;
  						case "suffix": suffix(client, targetMob, args); break;
  						case "guild": guild(client, targetMob, args); break;
  						case "examinearticle": examinearticle(client, targetMob, args); break;
  						case "messagearticle": messagearticle(client, targetMob, args); break;
  						case "peace": peace(client, targetMob, args); break;
  						case "aggro": aggro(client, targetMob, args); break;
  						case "range": range(client, targetMob, args); break;
  						case "distance": distance(client, targetMob, args); break;
  						case "roaming": roaming(client, targetMob, args); break;
  						case "damagetype": damagetype(client, targetMob, args); break;
  						case "movehere": movehere(client, targetMob, args); break;
  						case "location": location(client, targetMob, args); break;
  						case "remove": remove(client, targetMob, args); break;
  						case "ghost": ghost(client, targetMob, args); break;
  						case "stealth": stealth(client, targetMob, args); break;
  						case "torch": torch(client, targetMob, args); break;
  						case "statue": statue(client, targetMob, args); break;
  						case "fly": fly(client, targetMob, args); break;
  						case "swimming": swimming(client, targetMob, args); break;
  						case "noname": noname(client, targetMob, args); break;
  						case "notarget": notarget(client, targetMob, args); break;
  						case "kill": kill(client, targetMob, args); break;
  						case "flags": flags(client, targetMob, args); break;
  						case "heal": heal(client, targetMob, args); break;
  						case "attack": attack(client, targetMob, args); break;
  						case "info": info(client, targetMob, args); break;
  						case "stats": stats(client, targetMob, args); break;
  						case "state": state(client, targetMob); break;
  						case "realm": realm(client, targetMob, args); break;
  						case "speed": speed(client, targetMob, args); break;
  						case "level": level(client, targetMob, args); break;
  						case "levela": levela(client, targetMob, args); break;
  						case "brain": brain(client, targetMob, args); break;
  						case "respawn": respawn(client, targetMob, args); break;
  						case "questinfo": questinfo(client, targetMob, args); break;
  						case "refreshquests": refreshquests(client, targetMob, args); break;
  						case "equipinfo": equipinfo(client, targetMob, args); break;
  						case "equiptemplate": equiptemplate(client, targetMob, args); break;
  						case "visibleslot": visibleslot(client, targetMob, args); break;
  						case "dropcount": dropcount<MobXLootTemplate>(client, targetMob, args); break;
  						case "dropcount2": dropcount<MobDropTemplate>(client, targetMob, args); break;
  						case "addloot": addloot<MobXLootTemplate, LootTemplate>(client, targetMob, args); break;
  						case "addloot2": addloot<MobDropTemplate, DropTemplateXItemTemplate>(client, targetMob, args); break;
  						case "addotd": addotd(client, targetMob, args); break;
  						case "viewloot": viewloot(client, targetMob, args); break;
  						case "removeloot": removeloot<LootTemplate>(client, targetMob, args); break;
  						case "removeloot2": removeloot<DropTemplateXItemTemplate>(client, targetMob, args); break;
  						case "removeotd": removeotd(client, targetMob, args); break;
  						case "refreshloot": refreshloot(client, targetMob, args); break;
  						case "copy": copy(client, targetMob, args); break;
  						case "npctemplate": npctemplate(client, targetMob, args); break;
  						case "class": setClass(client, targetMob, args); break;
  						case "path": path(client, targetMob, args); break;
  						case "house": house(client, targetMob, args); break;
  					case "str":
  					case "con":
  					case "dex":
  					case "qui":
  					case "int":
  					case "emp":
  					case "pie":
  						case "cha": stat(client, targetMob, args); break;
  						case "tether": tether(client, targetMob, args); break;
  						case "hood": hood(client, targetMob, args); break;
  						case "cloak": cloak(client, targetMob, args); break;
  						case "bodytype": bodytype(client, targetMob, args); break;
  						case "race": race(client, targetMob, args); break;
  						case "gender": gender(client, targetMob, args); break;
  						case "packageid": packageid(client, targetMob, args); break;
  						case "ownerid": ownerid(client, targetMob, args); break;
  						case "select": select(AUTOSELECT_RADIUS, client); break;
  						case "load": load(client, args); break;
  						case "reload": reload(client, targetMob, args); break;
  						case "findname": findname(client, args); break;
  						case "trigger": trigger(client, targetMob, args); break;
  					default:
  						DisplaySyntax(client);
  						return;
  				}
  			}
  			catch (Exception ex)
  			{
  				client.Out.SendMessage(ex.ToString(), eChatType.CT_System, eChatLoc.CL_PopupWindow);
  				DisplaySyntax(client);
  			}
  		}
  
  
  		private void create(GameClient client, string[] args)
  		{
  			string theType = "DOL.GS.GameNPC";
  			byte realm = 0;
  
  			if (args.Length > 2)
  				theType = args[2];
  
  			if (args.Length > 3)
  			{
  				if (!byte.TryParse(args[3], out realm))
  				{
  					DisplaySyntax(client, args[1]);
  					return;
  				}
  			}
  
  			//Create a new mob
  			GameNPC mob = null;
  
  			foreach (Assembly script in ScriptMgr.GameServerScripts)
  			{
  				try
  				{
  					client.Out.SendDebugMessage(script.FullName);
  					mob = (GameNPC)script.CreateInstance(theType, false);
  
  					if (mob != null)
  						break;
  				}
  				catch (Exception e)
  				{
  					client.Out.SendMessage(e.ToString(), eChatType.CT_System, eChatLoc.CL_PopupWindow);
  				}
  			}
  
  			if (mob == null)
  			{
  				client.Out.SendMessage("There was an error creating an instance of " + theType + "!", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  				return;
  			}
  
  			//Fill the object variables
  			mob.X = client.Player.X;
  			mob.Y = client.Player.Y;
  			mob.Z = client.Player.Z;
  			mob.CurrentRegion = client.Player.CurrentRegion;
  			mob.Heading = client.Player.Heading;
  			mob.Level = 1;
  			mob.Realm = (eRealm)realm;
  			mob.Name = "New Mob";
  			mob.Model = 408;
  
  			//Fill the living variables
  			mob.CurrentSpeed = 0;
  			mob.MaxSpeedBase = 200;
  			mob.GuildName = "";
  			mob.Size = 50;
  			mob.Flags |= GameNPC.eFlags.PEACE;
  			mob.AddToWorld();
  			mob.LoadedFromScript = false; // allow saving
  			mob.SaveIntoDatabase();
  			client.Out.SendMessage("Mob created: OID=" + mob.ObjectID, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			client.Out.SendMessage("The mob has been created with the peace flag, so it can't be attacked, to remove type /mob peace", eChatType.CT_Important, eChatLoc.CL_SystemWindow);
  		}
  
  		private void fastcreate(GameClient client, string[] args)
  		{
  			byte level = 1;
  			ushort model = 408;
  			string name = "New Mob";
  			bool saveMob = false;
  
  			if (args.Length < 5)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  
  			try
  			{
  				if (args[4] == "0" || args[4] == "1")
  				{
  					if (args.Length < 6)
  					{
  						DisplaySyntax(client, args[1]);
  						return;
  					}
  
  					saveMob = args[4].Equals("1");
  					name = String.Join(" ", args, 5, args.Length - 5);
  				}
  				else
  				{
  					name = String.Join(" ", args, 4, args.Length - 4);
  				}
  
  				level = Convert.ToByte(args[3]);
  				model = Convert.ToUInt16(args[2]);
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  
  			name = CheckName(name, client);
  			GameNPC mob = new GameNPC();
  
  			//Fill the object variables
  			mob.X = client.Player.X;
  			mob.Y = client.Player.Y;
  			mob.Z = client.Player.Z;
  			mob.CurrentRegion = client.Player.CurrentRegion;
  			mob.Heading = client.Player.Heading;
  			mob.Level = level;
  			mob.Realm = 0;
  			mob.Name = name;
  			mob.Model = model;
  
  			//Fill the living variables
  			if (mob.Brain is IOldAggressiveBrain)
  			{
  				((IOldAggressiveBrain)mob.Brain).AggroLevel = 100;
  				((IOldAggressiveBrain)mob.Brain).AggroRange = 500;
  			}
  
  			mob.CurrentSpeed = 0;
  			mob.MaxSpeedBase = 200;
  			mob.GuildName = "";
  			mob.Size = 50;
  			mob.AddToWorld();
  
  			if (saveMob)
  			{
  				mob.LoadedFromScript = false;
  				mob.SaveIntoDatabase();
  			}
  
  			client.Out.SendMessage("Mob created: OID=" + mob.ObjectID, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  		}
  
  		private void nfastcreate(GameClient client, string[] args)
  		{
  			byte level = 1;
  			ushort model = 408;
  			byte realm = 0;
  			ushort number = 1;
  			string name = "New Mob";
  			ushort radius = 10;
  
  			if (args.Length < 5)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  
  			try
  			{
  				if (args.Length > 5)
  				{
  					if (ushort.TryParse(args[5], out radius))
  					{
  						if (args.Length > 6)
  							name = String.Join(" ", args, 6, args.Length - 6);
  					}
  					else
  					{
  						radius = 10;
  						name = String.Join(" ", args, 5, args.Length - 5);
  					}
  				}
  
  				number = Convert.ToUInt16(args[4]);
  				level = Convert.ToByte(args[3]);
  				model = Convert.ToUInt16(args[2]);
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  
  			for (int i = 0; i < number; ++i)
  			{
  				GameNPC mob = new GameNPC();
  
  				//Fill the object variables
  				int x = client.Player.X + Util.Random(-radius, radius);
  				int y = client.Player.Y + Util.Random(-radius, radius);
  				mob.X = FastMath.Abs(x);
  				mob.Y = FastMath.Abs(y);
  				mob.Z = client.Player.Z;
  				mob.CurrentRegion = client.Player.CurrentRegion;
  				mob.Heading = client.Player.Heading;
  				mob.Level = level;
  				mob.Realm = (eRealm)realm;
  				mob.Name = name;
  				mob.Model = model;
  
  				//Fill the living variables
  				if (mob.Brain is IOldAggressiveBrain)
  				{
  					((IOldAggressiveBrain)mob.Brain).AggroLevel = 100;
  					((IOldAggressiveBrain)mob.Brain).AggroRange = 500;
  				}
  
  				mob.CurrentSpeed = 0;
  				mob.MaxSpeedBase = 200;
  				mob.GuildName = "";
  				mob.Size = 50;
  				mob.AddToWorld();
  				client.Out.SendMessage("Mob created: OID=" + mob.ObjectID, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			}
  		}
  
  		private void nrandcreate(GameClient client, string[] args)
  		{
  			ushort number = 1;
  			ushort radius = 50;
  
  			if (args.Length < 3)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  
  			try
  			{
  				number = ushort.Parse(args[2]);
  
  				if (args.Length > 3)
  				{
  					if (ushort.TryParse(args[3], out radius) == false)
  						radius = 50;
  				}
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[2]);
  				return;
  			}
  
  			for (int i = 0; i < number; ++i)
  			{
  				GameNPC mob = new GameNPC();
  
  				//Fill the object variables
  				int x = client.Player.X + DOL.GS.Util.Random(-radius, radius);
  				int y = client.Player.Y + DOL.GS.Util.Random(-radius, radius);
  				mob.X = FastMath.Abs(x);
  				mob.Y = FastMath.Abs(y);
  				mob.Z = client.Player.Z;
  				mob.CurrentRegion = client.Player.CurrentRegion;
  				mob.Heading = client.Player.Heading;
  				mob.Level = (byte)Util.Random(10, 50);
  				mob.Realm = (eRealm)Util.Random(1, 3);
  				mob.Name = "rand_" + i;
  				mob.Model = (byte)Util.Random(568, 699);
  
  				//Fill the living variables
  				if (mob.Brain is IOldAggressiveBrain)
  				{
  					((IOldAggressiveBrain)mob.Brain).AggroLevel = 100;
  					((IOldAggressiveBrain)mob.Brain).AggroRange = 500;
  				}
  
  				mob.CurrentSpeed = 0;
  				mob.MaxSpeedBase = 200;
  				mob.GuildName = "";
  				mob.Size = 50;
  				mob.AddToWorld();
  			}
  
  			client.Out.SendMessage("Created " + number + " mobs", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  		}
  		
  		#region auto increment/decrement model display
  		// List of non-displayed models
  		// used with modelinc and modeldec
  		List<ushort> invmodel = new List<ushort>() { 3, 4, 604, 666, 1000, 1001, 1002, 1003, 1004, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246,
  			1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1275, 1391, 1392, 1393, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449,
  			1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470,
  			1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491,
  			1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512,
  			1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533,
  			1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554,
  			1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1587, 1588, 1589, 1590, 1591, 1592,
  			1593, 1594, 1595, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617,
  			1618, 1619, 1620, 1621, 1622, 1624, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640,
  			1641, 1643, 1644, 1645, 1646, 1671, 1673, 1674, 1675, 1677, 1678, 1679, 1680, 1682, 1683, 1684, 1685, 1686, 1737, 1738, 1739,
  			1761, 1762,	1763, 1764, 1765, 1766, 1767, 1768, 1769, 1822, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1880, 1881, 1882, 1886,
  			1907, 1923,	1926, 1927, 1928, 1943, 2004, 2005, 2006, 2007, 2008, 2019, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2280, 2281,
  			2282, 2283,	2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2299, 2300, 2302, 2305, 2319, 2333, 2334, 2335,
  			2336, 2337,	2338, 2364 };
  		
  		private void modelinc(GameClient client, GameNPC targetMob, string[] args)
  		{
  			if (targetMob == null)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  			
  			if (targetMob.Model >= 2363)
  			{
  				client.Out.SendMessage("Highest mob model reached!", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  				return;
  			}
  			
  			ushort model = targetMob.Model;
  			model++;
  			
  			//Some models are not used, or cannot be targetted, i.e. ambient mobs and some invisible mobs, don't set mobs to these models
  			while (invmodel.Contains(model))
  				model++;
  			
  			try
  			{
  				targetMob.Model = model;
  				targetMob.SaveIntoDatabase();
  				client.Out.SendMessage("Mob model changed to: " + targetMob.Model, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  		}
  
  		private void modeldec(GameClient client, GameNPC targetMob, string[] args)
  		{
  			if (targetMob == null)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  			
  			if (targetMob.Model == 1)
  			{
  				client.Out.SendMessage("Mob model cannot be 0!", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  				return;
  			}
  			
  			ushort model = targetMob.Model;
  			model--;
  			
  			//Some models are not used, or cannot be targetted, i.e. ambient mobs and some invisible mobs, don't set mobs to these models
  			while (invmodel.Contains(model))
  				model--;
  			
  			try
  			{
  				targetMob.Model = model;
  				targetMob.SaveIntoDatabase();
  				client.Out.SendMessage("Mob model changed to: " + targetMob.Model, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  		}
  		#endregion
  		
  		private void model(GameClient client, GameNPC targetMob, string[] args)
  		{
  			if (args.Length == 4)
  				targetMob = FindOID(client, targetMob, args);
  
  			if (targetMob == null)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  
  			ushort model;
  
  			try
  			{
  				model = Convert.ToUInt16(args[2]);
  				targetMob.Model = model;
  				targetMob.SaveIntoDatabase();
  				client.Out.SendMessage("Mob model changed to: " + targetMob.Model, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  		}
  
  		GameNPC FindOID(GameClient client, GameNPC targetMob, string[] args)
  		{
  			ushort mobOID;
  			if (ushort.TryParse(args[3], out mobOID))
  			{
  				GameObject obj = client.Player.CurrentRegion.GetObject(mobOID);
  				if (obj == null)
  				{
  					client.Out.SendMessage("No object with OID: " + args[1] + " in current Region.", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  					return null;
  				}
  				else
  				{
  					if (obj is GameNPC)
  					{
  						return (GameNPC)obj;
  					}
  					else
  					{
  						client.Out.SendMessage("Object " + mobOID + " is a " + obj.GetType().ToString() + ", not a GameNPC.", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  						return null;
  					}
  				}
  			}
  			else
  			{
  				DisplaySyntax(client, args[1]);
  				return null;
  			}
  		}
  
  		private void size(GameClient client, GameNPC targetMob, string[] args)
  		{
  			ushort mobSize;
  
  			try
  			{
  				mobSize = Convert.ToUInt16(args[2]);
  
  				if (mobSize > 255)
  				{
  					mobSize = 255;
  				}
  
  				targetMob.Size = (byte)mobSize;
  				targetMob.SaveIntoDatabase();
  				client.Out.SendMessage("Mob size changed to: " + targetMob.Size, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			}
  			catch (Exception)
  			{
  				DisplaySyntax(client, args[1]);
  				return;
  			}
  		}
  
  		//private void translationid(GameClient client, GameNPC targetMob, string[] args)
  		//{
  		//    if (targetMob.GetType().IsSubclassOf(typeof(GameMovingObject)))
  		//    {
  		//        // Can be funny when we remove (e.g.) a ram or a boat (why are we dropped on the sea???) from the world. ;-)
  		//        client.Out.SendMessage("The selected object is type of GameMovingObject and it's translation id cannot be changed " +
  		//                               "via command. Please change the translation id in your code / database.",
  		//                               eChatType.CT_System, eChatLoc.CL_SystemWindow);
  		//        return;
  		//    }
  
  		//    string id = "";
  
  		//    if (args.Length > 2)
  		//        id = String.Join("", args, 2, args.Length - 2);
  
  		//    if (id != "")
  		//    {
  		//        targetMob.TranslationId = id;
  		//        targetMob.SaveIntoDatabase();
  
  		//        targetMob.RemoveFromWorld();
  		//        GameNPC.RefreshTranslation(null, id);
  		//        targetMob.AddToWorld();
  
  		//        client.Out.SendMessage("Mob translation id changed to: " + id, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  		//    }
  		//    else
  		//        DisplaySyntax(client, args[1]);
  		//}
  
  		private void name(GameClient client, GameNPC targetMob, string[] args)
  		{
  			string mobName = "";
  
  			if (args.Length > 2)
  				mobName = String.Join(" ", args, 2, args.Length - 2);
  
  			if (mobName != "")
  			{
  				targetMob.Name = CheckName(mobName, client);
  				targetMob.SaveIntoDatabase();
  				client.Out.SendMessage("Mob name changed to: " + targetMob.Name, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  			}
  			else
  			{
  				DisplaySyntax(client, args[1]);
  			}
  		}
  
  		private void suffix(GameClient client, GameNPC targetMob, string[] args)
  		{
  			if (targetMob.GetType().IsSubclassOf(typeof(GameMovingObject)))
  			{
  				client.Out.SendMessage("You cannot set a suffix for GameMovingObjects.", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  				return;
  			}
  
  			string suf = "";
  
  			if (args.Length > 2)
  				suf = String.Join(" ", args, 2, args.Length - 2);
  
  
gt: 			if (suf != "")