/// <summary> /// Will resend update packet of the given object /// </summary> public void InvalidateKnowledgeOf(WorldObject obj) { KnownObjects.Remove(obj); NearbyObjects.Remove(obj); obj.SendDestroyToPlayer(this); }
/// <summary> /// Adds an object. /// </summary> /// <param name="o"></param> /// <returns>The object's ID. IDs are unique within any any given object type but not across types.</returns> public int Add(object o) { if (o == null) { return(-1); } var type = o.GetType(); if (!KnownTypes.ContainsKey(type.AssemblyQualifiedName)) { KnownTypes.Add(type.AssemblyQualifiedName, type); } if (!KnownObjects.ContainsKey(type)) { KnownObjects.Add(type, new List <object>()); } // if (!KnownObjects[type].Contains(o)) KnownObjects[type].Add(o); if (!KnownIDs.ContainsKey(type)) { KnownIDs.Add(type, new SafeDictionary <object, int>()); } var id = KnownObjects[type].Count - 1; KnownIDs[type].Add(o, id); AddProperties(type); return(id); }
/// <summary> /// Adds an object to the list of known objects /// only maintained for players /// </summary> /// <returns>true if previously an unknown object</returns> public bool AddKnownObject(PhysicsObj obj) { rwLock.EnterWriteLock(); try { if (KnownObjects.ContainsKey(obj.ID)) { return(false); } KnownObjects.TryAdd(obj.ID, obj); // maintain KnownPlayers for both parties if (obj.IsPlayer) { AddKnownPlayer(obj); } obj.ObjMaint.AddKnownPlayer(PhysicsObj); return(true); } finally { rwLock.ExitWriteLock(); } }
/// <summary> /// Adds an object to the list of visible objects /// only maintained for players /// </summary> /// <returns>TRUE if object was previously not visible, and added to the visible list</returns> public bool AddVisibleObject(PhysicsObj obj) { rwLock.EnterWriteLock(); try { if (VisibleObjects.ContainsKey(obj.ID)) { return(false); } if (InitialClamp && !KnownObjects.ContainsKey(obj.ID)) { var distSq = PhysicsObj.Position.Distance2DSquared(obj.Position); if (distSq > InitialClamp_DistSq) { return(false); } } //Console.WriteLine($"{PhysicsObj.Name}.AddVisibleObject({obj.Name})"); VisibleObjects.TryAdd(obj.ID, obj); if (obj.WeenieObj.IsMonster) { obj.ObjMaint.AddVisibleTarget(PhysicsObj, false); } return(true); } finally { rwLock.ExitWriteLock(); } }
/// <summary> /// Is called whenever a new object appears within vision range of this Character /// </summary> public void OnEncountered(WorldObject obj) { if (obj != this) { obj.OnEncounteredBy(this); } KnownObjects.Add(obj); }
/// <summary> /// Clears all of the ObjMaint tables for an object /// </summary> private void RemoveAllObjects() { KnownObjects.Clear(); VisibleObjects.Clear(); DestructionQueue.Clear(); KnownPlayers.Clear(); VisibleTargets.Clear(); }
public void RemoveKnownObject(PhysicsObj obj, bool inversePlayer = true) { KnownObjects.Remove(obj.ID); if (PhysicsObj.IsPlayer && inversePlayer) { obj.ObjMaint.RemoveKnownPlayer(PhysicsObj); } }
public bool KnownObjectsContainsKey(uint guid) { rwLock.EnterReadLock(); try { return(KnownObjects.ContainsKey(guid)); } finally { rwLock.ExitReadLock(); } }
public List <KeyValuePair <uint, PhysicsObj> > GetKnownObjectsWhere(Func <KeyValuePair <uint, PhysicsObj>, bool> predicate) { rwLock.EnterReadLock(); try { return(KnownObjects.Where(predicate).ToList()); } finally { rwLock.ExitReadLock(); } }
public void Update() { if (Owner == null || Owner.Data == null || Owner.Data.GetBody() == null) { Active = false; return; } bool isPlayer = Owner is Player; Collider2D[] hits = Physics2D.OverlapCircleAll(Owner.Data.GetBody().transform.position, VisibleRadius); if (isPlayer) { foreach (GameObject o in KnownObjects) { if (o == null) { continue; } AbstractData d = o.GetData(); if (d != null) { d.IsVisibleToPlayer = false; } } } KnownObjects.Clear(); foreach (Collider2D h in hits) { if ("Cave Generator".Equals(h.gameObject.name) || h.gameObject.Equals(Owner.GetData().gameObject)) { continue; } if (isPlayer) { AbstractData d = h.gameObject.GetData(); if (d != null) { d.IsVisibleToPlayer = true; } } KnownObjects.Add(h.gameObject); } }
public PhysicsObj GetKnownObject(uint objectGuid) { rwLock.EnterReadLock(); try { KnownObjects.TryGetValue(objectGuid, out var obj); return(obj); } finally { rwLock.ExitReadLock(); } }
/// <summary> /// Is called whenever an object leaves this Character's sight /// </summary> public void OnOutOfRange(WorldObject obj) { obj.AreaCharCount--; if (obj == Asda2DuelingOponent) { if (Asda2Duel != null) { Asda2Duel.StopPvp(); } } if (obj == m_target) { // unset current Target ClearTarget(); } if (obj == m_activePet) { ActivePet = null; } if (GossipConversation != null && obj == GossipConversation.Speaker && GossipConversation.Character == this) { // stop conversation with a vanished object GossipConversation.Dispose(); } if (!(obj is Transport)) { KnownObjects.Remove(obj); } var chr = obj as Character; if (chr != null) { if (EnemyCharacters.Contains(chr)) { EnemyCharacters.Remove(chr); CheckEnemysCount(); } GlobalHandler.SendCharacterDeleteResponse(chr, Client); } else { var loot = obj as Asda2Loot; if (loot != null) { GlobalHandler.SendRemoveLootResponse(this, loot); } } }
/// <summary> /// Is called whenever an object leaves this Character's sight /// </summary> public void OnOutOfRange(WorldObject obj) { obj.AreaCharCount--; if (obj is Character && m_observers != null) { if (m_observers.Remove((Character)obj)) { // Character was observing: Now destroy items for him for (var i = (InventorySlot)0; i < InventorySlot.Bag1; i++) { var item = m_inventory[i]; if (item != null) { item.SendDestroyToPlayer((Character)obj); } } } } if (obj == DuelOpponent && !Duel.IsActive) { // opponent vanished before Duel started: Cancel duel Duel.Dispose(); } if (obj == m_target) { // unset current Target ClearTarget(); } if (obj == m_activePet) { ActivePet = null; } if (GossipConversation != null && obj == GossipConversation.Speaker && GossipConversation.Character == this) { // stop conversation with a vanished object GossipConversation.Dispose(); } if (!(obj is Transport)) { KnownObjects.Remove(obj); // send the destroy packet //obj.SendDestroyToPlayer(this); } }
/// <summary> /// Clears known objects and leads to resending of the creation packet /// during the next Map-Update. /// This is only needed for teleporting or body-transfer. /// Requires map context. /// </summary> internal void ClearSelfKnowledge() { KnownObjects.Clear(); NearbyObjects.Clear(); if (m_observers != null) { m_observers.Clear(); } /*foreach (var item in m_inventory.GetAllItems(true)) * { * item.m_unknown = true; * m_itemsRequiringUpdates.Add(item); * }*/ }
public bool RemoveKnownObject(PhysicsObj obj, bool inversePlayer = true) { rwLock.EnterWriteLock(); try { var result = KnownObjects.Remove(obj.ID, out _); if (inversePlayer && PhysicsObj.IsPlayer) { obj.ObjMaint.RemoveKnownPlayer(PhysicsObj); } return(result); } finally { rwLock.ExitWriteLock(); } }
/// <summary> /// Adds an object to the list of known objects /// only maintained for players /// </summary> /// <returns>true if previously an unknown object</returns> public bool AddKnownObject(PhysicsObj obj) { if (KnownObjects.ContainsKey(obj.ID)) { return(false); } KnownObjects.Add(obj.ID, obj); // maintain KnownPlayers for both parties if (obj.IsPlayer) { AddKnownPlayer(obj); } obj.ObjMaint.AddKnownPlayer(PhysicsObj); return(true); }
/// <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 (!Observing.IsInPhase(obj)) { 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 obj.WriteObjectCreationUpdate(this); OnEncountered(obj); if (obj.RequiresUpdate) { // make sure that it won't send its values next round again updatedObjects.Add(obj); } } else if (obj.RequiresUpdate) { updatedObjects.Add(obj); obj.WriteObjectValueUpdate(this); } toRemove.Remove(obj); // still in range, no need to remove it return(true); }); // Update Items if (m_itemsRequiringUpdates.Count > 0) { foreach (var item in m_itemsRequiringUpdates) { if (item.m_unknown) { // creation update item.m_unknown = false; if (m_observers != null && item.IsEquippedItem) { foreach (var chr in m_observers) { item.WriteObjectCreationUpdate(chr); } } item.WriteObjectCreationUpdate(this); } else { // value update if (m_observers != null && item.IsEquippedItem) { foreach (var chr in m_observers) { item.WriteObjectValueUpdate(chr); } } item.WriteObjectValueUpdate(this); } item.ResetUpdateInfo(); } m_itemsRequiringUpdates.Clear(); } //update group member stats for out of range players if (m_groupMember != null) { m_groupMember.Group.UpdateOutOfRangeMembers(m_groupMember); } // send update packet if (UpdateCount > 0) { SendOwnUpdates(); } // delete objects that are not in range anymore foreach (var obj in toRemove) { OnOutOfRange(obj); } if (toRemove.Count > 0) { SendOutOfRangeUpdate(this, toRemove); } } // 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); }
public void RemoveKnownObject(GameObject o) { KnownObjects.Remove(o); }
/// <summary> /// Performs any needed object/object pool cleanup. /// </summary> public override void Dispose(bool disposing) { base.Dispose(disposing); CancelSummon(false); if (m_bgInfo != null) { m_bgInfo.Character = null; m_bgInfo = null; } m_InstanceCollection = null; if (m_activePet != null) { m_activePet.Delete(); m_activePet = null; } m_minions = null; m_activePet = null; if (m_skills != null) { m_skills.m_owner = null; m_skills = null; } if (m_talents != null) { m_talents.Owner = null; m_talents = null; } if (m_inventory != null) { m_inventory.m_container = null; m_inventory.m_owner = null; m_inventory.m_ammo = null; m_inventory.m_currentBanker = null; m_inventory = null; } if (m_mailAccount != null) { m_mailAccount.Owner = null; m_mailAccount = null; } m_groupMember = null; if (m_reputations != null) { m_reputations.Owner = null; m_reputations = null; } if (m_InstanceCollection != null) { m_InstanceCollection.Dispose(); } if (m_achievements != null) { m_achievements.m_owner = null; m_achievements = null; } if (m_CasterReference != null) { m_CasterReference.Object = null; m_CasterReference = null; } if (m_looterEntry != null) { m_looterEntry.m_owner = null; m_looterEntry = null; } if (m_ExtraInfo != null) { m_ExtraInfo.Dispose(); m_ExtraInfo = null; } KnownObjects.Clear(); WorldObjectSetPool.Recycle(KnownObjects); }
/// <summary> /// Whether the given Object is visible to (and thus in broadcast-range of) this Character /// </summary> /// <param name="obj"></param> /// <returns></returns> public bool KnowsOf(WorldObject obj) { return(KnownObjects.Contains(obj)); }
/// <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); }
public void AddKnownObject(GameObject o) { KnownObjects.Add(o); }