public static ICharacter InstantiateMobSpawn(
            DBMobSpawn mob,
            DBMobSpawnStat[] stats,
            IController npccontroller,
            IPlayfield playfield)
        {
            if (playfield != null)
            {
                Identity mobId = new Identity() { Type = IdentityType.CanbeAffected, Instance = mob.Id };
                if (Pool.Instance.GetObject(playfield.Identity, mobId) != null)
                {
                    throw new Exception("Object " + mobId.ToString(true) + " already exists!!");
                }
                Character cmob = new Character(playfield.Identity, mobId, npccontroller);
                cmob.Read();
                cmob.Playfield = playfield;
                cmob.Coordinates(new Coordinate() { x = mob.X, y = mob.Y, z = mob.Z });
                cmob.RawHeading = new Quaternion(mob.HeadingX, mob.HeadingY, mob.HeadingZ, mob.HeadingW);
                cmob.Name = mob.Name;
                cmob.FirstName = "";
                cmob.LastName = "";
                foreach (DBMobSpawnStat stat in stats)
                {
                    cmob.Stats.SetBaseValueWithoutTriggering(stat.Stat, (uint)stat.Value);
                }

                cmob.Stats.SetBaseValueWithoutTriggering((int)StatIds.visualprofession, cmob.Stats[StatIds.profession].BaseValue);
                // initiate affected stats calculation
                int temp = cmob.Stats[StatIds.level].Value;
                temp = cmob.Stats[StatIds.agility].Value;
                temp = cmob.Stats[StatIds.headmesh].Value;
                cmob.MeshLayer.AddMesh(0, cmob.Stats[StatIds.headmesh].Value, 0, 4);
                cmob.SocialMeshLayer.AddMesh(0, cmob.Stats[StatIds.headmesh].Value, 0, 4);
                List<MobSpawnWaypoint> waypoints =
                    MessagePackZip.DeserializeData<MobSpawnWaypoint>(mob.Waypoints.ToArray());
                foreach (MobSpawnWaypoint wp in waypoints)
                {
                    Waypoint mobwp = new Waypoint();
                    mobwp.Position.x = wp.X;
                    mobwp.Position.y = wp.Y;
                    mobwp.Position.z = wp.Z;
                    mobwp.Running = wp.WalkMode == 1;
                    cmob.Waypoints.Add(mobwp);
                }
                npccontroller.Character = cmob;
                if (cmob.Waypoints.Count > 2)
                {
                    cmob.Controller.State = CharacterState.Patrolling;
                }
                cmob.DoNotDoTimers = false;
                return cmob;
            }
            return null;
        }
        private static Character CreateMob(
            DBMobTemplate mob,
            Identity playfieldIdentity,
            Coordinate coord,
            Quaternion heading,
            IController controller,
            int level)
        {
            IPlayfield playfield = Pool.Instance.GetObject<IPlayfield>(Identity.None, playfieldIdentity);
            if (playfield != null)
            {
                int newInstanceId = Pool.Instance.GetFreeInstance<Character>(1000000, IdentityType.CanbeAffected);
                Identity newIdentity = new Identity() { Type = IdentityType.CanbeAffected, Instance = newInstanceId };
                Character mobCharacter = new Character(playfield.Identity, newIdentity, controller);
                mobCharacter.Read();
                mobCharacter.Coordinates(coord);
                mobCharacter.Playfield = Pool.Instance.GetObject<IPlayfield>(Identity.None, playfieldIdentity);
                mobCharacter.RawHeading = new Quaternion(heading.xf, heading.yf, heading.zf, heading.wf);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.life, (uint)mob.Health);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.level, (uint)level);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.npcfamily, (uint)mob.NPCFamily);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.side, (uint)mob.Side);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.fatness, (uint)mob.Fatness);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.breed, (uint)mob.Breed);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.sex, (uint)mob.Sex);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.race, (uint)mob.Race);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.flags, (uint)mob.Flags);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterdata, (uint)mob.MonsterData);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterscale, (uint)mob.MonsterScale);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.profession, 15);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.accountflags, 0);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.expansion, 0);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.runspeed, 513);
                mobCharacter.Stats[StatIds.headmesh].BaseValue = (uint)mob.HeadMesh;
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.losheight, 15);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.visualprofession, 15);

                /*
                // For testing only, blue trousers and a helmet
                IItem trousers = new Item(1, ItemLoader.ItemList[27350].GetLowId(1),ItemLoader.ItemList[27350].GetLowId(1));
                IItem helmet = new Item(1, ItemLoader.ItemList[85534].GetLowId(1), ItemLoader.ItemList[85534].GetHighId(1));
                mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Legs + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, trousers);
                mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Head + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, helmet);
                */

                // Set the MeshLayers correctly ( Head mesh!! )  /!\
                // TODO: This needs to be in StatHeadmesh.cs (somehow)
                mobCharacter.MeshLayer.AddMesh(0, mob.HeadMesh, 0, 4);
                mobCharacter.SocialMeshLayer.AddMesh(0, mob.HeadMesh, 0, 4);

                mobCharacter.Name = mob.Name;
                mobCharacter.FirstName = "";
                mobCharacter.LastName = "";
                controller.Character = mobCharacter;
                return mobCharacter;
            }
            return null;
        }