private static void NPCUpdateThreadStart() { bool running = true; if (log.IsDebugEnabled) log.Debug("NPCUpdateThread ThreadId=" + Thread.CurrentThread.ManagedThreadId); while (running) { try { int start = Environment.TickCount; for (int i = 0; i < m_clients.Length; i++) { GameClient client = m_clients[i]; if (client == null) continue; GamePlayer player = client.Player; if (client.ClientState == GameClient.eClientState.Playing && player == null) { if (log.IsErrorEnabled) log.Error("account has no active player but is playing, disconnecting! => " + client.Account.Name); GameServer.Instance.Disconnect(client); Thread.Sleep(200); } if (client.ClientState != GameClient.eClientState.Playing) continue; if (player.ObjectState != GameObject.eObjectState.Active) continue; if (Environment.TickCount - player.LastNPCUpdate > PLAYER_UPDATE_TIME) { BitArray carray = player.CurrentUpdateArray; BitArray narray = player.NewUpdateArray; narray.SetAll(false); lock (player.CurrentRegion.ObjectsSyncLock) { foreach (GameNPC npc in player.GetNPCsInRadius(VISIBILITY_DISTANCE)) { try { narray[npc.ObjectID-1] = true; /* if(npc.IsMoving && npc.IsOnTarget() && !npc.HasArriveOnTargetHandlers() && !npc.HasCloseToTargetHandlers()) { npc.StopMoving(); } else*/ if ((uint)Environment.TickCount - npc.LastUpdateTickCount > NPC_UPDATE_INTERVAL) { npc.BroadcastUpdate(); } else if (carray[npc.ObjectID-1] == false) { client.Out.SendNPCUpdate(npc); } } catch (Exception e) { if (log.IsErrorEnabled) log.Error("NPC update: " + e.GetType().FullName + " (" + npc.ToString() + ")", e); } } } player.SwitchUpdateArrays(); player.LastNPCUpdate = Environment.TickCount; } } int took = Environment.TickCount - start; if (took > 500) { if (log.IsWarnEnabled) log.WarnFormat("NPC update took {0}ms", took); } Thread.Sleep(50); } catch (ThreadAbortException) { if (log.IsDebugEnabled) log.Debug("NPC Update Thread stopping..."); running = false; } catch (Exception e) { if (log.IsErrorEnabled) log.Error("Error in NPC Update Thread!", e); } } }