// Call this _only_ on server startup!
        /// <summary>
        /// Reads all NPCs from database and adds them to servers list.
        /// </summary>
        /// <returns>Number of NPCs loaded</returns>
        public static int CacheAllFromDB()
        {
            int npcCount = 0;
            SqlWrapper sqlWrapper = new SqlWrapper();

            // TODO:COUNT
            string sql = "SELECT count(*) FROM `mobspawns`";
            int numberOfNpc = sqlWrapper.SqlCount(sql);

            Console.Write("Reading spawns: 0/" + numberOfNpc.ToString());
            sql = "SELECT * FROM `mobspawns`";
            DataTable dt = sqlWrapper.ReadDatatable(sql);
            sqlWrapper = new SqlWrapper();
            DataTable dtstats = sqlWrapper.ReadDatatable("SELECT * from mobspawns_stats ORDER BY id, stat ASC");
            sqlWrapper = new SqlWrapper();
            DataTable dtinventory =
                sqlWrapper.ReadDatatable("SELECT * from mobspawnsinventory order by id, placement ASC");
            int statcount = 0;
            int invcount = 0;
            foreach (DataRow row in dt.Rows)
            {
                NonPlayerCharacterClass monster = new NonPlayerCharacterClass(0, 0)
                    { Starting = true, Id = (Int32)row["ID"], PlayField = (Int32)row["Playfield"] };

                monster.Name = (string)row["Name"]
#if DEBUG
                               + " " + monster.Id.ToString() // ID is for debug purpose only
#endif
                    ;
                monster.readcoordsheadingfast(row);
                statcount = monster.ReadStatsfast(dtstats, statcount);
                invcount = monster.readInventoryfromSqlfast(dtinventory, invcount);
                //                mMonster.readMeshsfromSql();
                //                mMonster.readNanosfromSql();
                //                mMonster.readTimersfromSql();
                //                mMonster.readWaypointsfromSql();
                //                mMonster.readWeaponpairsfromSql();

                monster.readTexturesfromSqlfast(row);
                byte[] bytes;
                long counter;
                if (!(row[15] is DBNull))
                {
                    bytes = (byte[])row[15]; // Waypoints
                    counter = 0;
                    while (counter < bytes.Length)
                    {
                        AOCoord aoCoord = new AOCoord();
                        aoCoord.x = BitConverter.ToSingle(bytes, (int)counter);
                        counter += 4;
                        aoCoord.y = BitConverter.ToSingle(bytes, (int)counter);
                        counter += 4;
                        aoCoord.z = BitConverter.ToSingle(bytes, (int)counter);
                        counter += 4;
                        monster.Waypoints.Add(aoCoord);
                    }
                }

                if (!(row[16] is DBNull))
                {
                    bytes = (byte[])row[16]; // Weaponpairs
                    counter = 0;
                    while (counter < bytes.Length)
                    {
                        AOWeaponpairs tempWeaponpairs = new AOWeaponpairs();
                        tempWeaponpairs.value1 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempWeaponpairs.value2 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempWeaponpairs.value3 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempWeaponpairs.value4 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        monster.Weaponpairs.Add(tempWeaponpairs);
                    }
                }

                if (!(row[17] is DBNull))
                {
                    bytes = (byte[])row[17]; // Running Nanos
                    counter = 0;
                    while (counter < bytes.Length)
                    {
                        AONano tempNano = new AONano();

                        tempNano.Nanotype = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempNano.Instance = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempNano.Value3 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempNano.Time1 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempNano.Time2 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        monster.ActiveNanos.Add(tempNano);
                    }
                }

                if (!(row[18] is DBNull))
                {
                    counter = 0;
                    bytes = (byte[])row[18]; // Meshs
                    while (counter < bytes.Length)
                    {
                        AOMeshs tempMeshs = new AOMeshs();
                        tempMeshs.Position = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempMeshs.Mesh = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempMeshs.OverrideTexture = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;

                        monster.Meshs.Add(tempMeshs);
                    }
                }

                if (!(row[19] is DBNull))
                {
                    counter = 0;
                    bytes = (byte[])row[19]; // Additional Meshs
                    while (counter < bytes.Length)
                    {
                        AOAddMeshs tempAdditionalMeshs = new AOAddMeshs();
                        tempAdditionalMeshs.position = bytes[counter++];
                        tempAdditionalMeshs.meshvalue1 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempAdditionalMeshs.meshvalue2 = BitConverter.ToInt32(bytes, (int)counter);
                        counter += 4;
                        tempAdditionalMeshs.priority = bytes[counter++];

                        monster.AdditionalMeshs.Add(tempAdditionalMeshs);
                    }
                }
                monster.Starting = false;

                Program.zoneServer.Monsters.Add(monster);
                npcCount += 1;
                if ((npcCount % 100) == 0)
                {
                    Console.Write("\rReading spawns: " + npcCount.ToString() + "/" + numberOfNpc.ToString());
                }
            }

            Console.Write("\r                                                    \r");
            return npcCount;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Int32 CheckAgainstDatabase()
        {
            SqlWrapper ms = new SqlWrapper();
            Int32 charCount = 0;
            // TODO:COUNT
            string sqlQuery = "SELECT count(`ID`) FROM `characters` WHERE Name = " + "'" + this.Name + "'";
            charCount = ms.SqlCount(sqlQuery);

            /* name in use */
            if (charCount > 0)
            {
                return 0;
            }
            return this.CreateNewChar();
        }