/// <summary> /// Collects all update-masks from nearby objects /// </summary> internal void UpdateEnvironment(HashSet <WorldObject> updatedObjects) { var toRemove = WorldObjectSetPool.Obtain(); toRemove.AddRange(KnownObjects); toRemove.Remove(this); NearbyObjects.Clear(); if (m_initialized) { Observing.IterateEnvironment(BroadcastRange, (obj) => { if (Client == null || Client.ActiveCharacter == null) { if (Client == null) { LogUtil.WarnException("Client is null. removeing from map and world? {0}[{1}]", Name, AccId); } else { if (Client.ActiveCharacter == null) { LogUtil.WarnException("Client.ActiveCharacter is null. removeing from map and world? {0}[{1}]", Name, AccId); } } if (Map != null) { Map.AddMessage(() => { Map.RemoveObject(this); World.RemoveCharacter(this); }); } return(false); } if (!Observing.IsInPhase(obj)) { return(true); } if (obj is GameObject && obj.GetDistance(this) > BroadcastRangeNpc) { return(true); } NearbyObjects.Add(obj); //ensure "this" never goes out of range //if we are observing another units broadcasts if (!Observing.CanSee(obj) && !ReferenceEquals(obj, this)) { return(true); } if (!KnownObjects.Contains(obj)) { // encountered new object //TODO Send upadte Packets here ASDA var visibleChr = obj as Character; if (visibleChr != null && visibleChr != this) { GlobalHandler.SendCharacterVisibleNowResponse(Client, visibleChr); if (visibleChr.Asda2Pet != null) { GlobalHandler.SendCharacterInfoPetResponse(Client, visibleChr); } if (visibleChr.IsAsda2TradeDescriptionEnabled) { Asda2PrivateShopHandler.SendtradeStatusTextWindowResponseToOne( visibleChr, Client); } GlobalHandler.SendCharacterPlaceInTitleRatingResponse(Client, visibleChr); GlobalHandler.SendBuffsOnCharacterInfoResponse(Client, visibleChr); if (visibleChr.IsInGuild) { GlobalHandler.SendCharacterInfoClanNameResponse(Client, visibleChr); } GlobalHandler.SendCharacterFactionAndFactionRankResponse(Client, visibleChr); GlobalHandler.SendCharacterFriendShipResponse(Client, visibleChr); if (visibleChr.ChatRoom != null) { ChatMgr.SendChatRoomVisibleResponse(visibleChr, ChatRoomVisibilityStatus.Visible, visibleChr.ChatRoom, this); } CheckAtackStateWithCharacter(visibleChr); if (visibleChr.Asda2WingsItemId != -1) { FunctionalItemsHandler.SendWingsInfoResponse(visibleChr, Client); } if (visibleChr.TransformationId != -1) { GlobalHandler.SendTransformToPetResponse(visibleChr, true, Client); } if (visibleChr.IsOnTransport) { FunctionalItemsHandler.SendShopItemUsedResponse(Client, visibleChr, int.MaxValue); } if (visibleChr.IsOnMount) { Asda2MountHandler.SendCharacterOnMountStatusChangedToPneClientResponse(Client, visibleChr); } } else { var visibleMonstr = obj as NPC; if (visibleMonstr != null && visibleMonstr.IsAlive) { GlobalHandler.SendMonstrVisibleNowResponse(Client, visibleMonstr); } else { var npc = obj as GameObject; if (npc != null && npc.GoId != GOEntryId.Portal) { if (!IsAsda2BattlegroundInProgress || CurrentBattleGround.WarType != Asda2BattlegroundType.Deathmatch || MapId != MapId.BatleField) { GlobalHandler.SendNpcVisiableNowResponse(Client, npc); } } else { var loot = obj as Asda2Loot; if (loot != null) { GlobalHandler.SendItemVisible(this, loot); } } } } OnEncountered(obj); } toRemove.Remove(obj); // still in range, no need to remove it return(true); }); //update group member stats for out of range players if (m_groupMember != null) { m_groupMember.Group.UpdateOutOfRangeMembers(m_groupMember); } // delete objects that are not in range anymore foreach (var obj in toRemove) { OnOutOfRange(obj); } } // init player, delete Items etc Action action; while (m_environmentQueue.TryDequeue(out action)) { var ac = action; // need to Add a message because Update state will be reset after method call AddMessage(ac); } // check rest state if (m_restTrigger != null) { UpdateRestState(); } toRemove.Clear(); WorldObjectSetPool.Recycle(toRemove); }