Exemplo n.º 1
0
        private void WorldItemScan()
        {
            foreach (var obj in LokiPoe.ObjectManager.Objects)
            {
                var worldItem = obj as WorldItem;

                if (worldItem == null)
                {
                    continue;
                }

                if (worldItem.IsAllocatedToOther && DateTime.Now < worldItem.PublicTime)
                {
                    continue;
                }

                var id = worldItem.Id;

                if (_processedItems.Contains(id))
                {
                    continue;
                }

                var item = worldItem.Item;

                if ((Settings.Instance.LootVisibleItems && worldItem.HasVisibleHighlightLabel) ||
                    ItemEvaluator.Match(item, EvaluationType.PickUp) ||
                    PickupEvaluators.Exists(e => e.Eval(item)))
                {
                    var pos = worldItem.WalkablePosition();
                    pos.Initialized = true; //disable walkable position searching for items
                    Items.Add(new CachedWorldItem(id, pos, item.Size, item.Rarity));
                }
                _processedItems.Add(id);
            }
        }
Exemplo n.º 2
0
        private void OnTick()
        {
            //if (Explorer != null)
            //{
            //    Explorer.Tick();
            //}

            var update = false;

            if (!_itemThrottle.IsRunning)
            {
                _itemThrottle.Start();
                update = true;
            }
            else
            {
                if (_itemThrottle.ElapsedMilliseconds >= ItemThrottleMs)
                {
                    update = true;
                }
            }

            //using (new PerformanceTimer("Tick::WorldItem", 1))
            {
                if (update)
                {
                    var myPos = LokiPoe.MyPosition;

                    var added = 0;
                    foreach (var worldItem in LokiPoe.ObjectManager.GetObjectsByType <WorldItem>())
                    {
                        var doAdd = false;

                        Vector2i pos;
                        if (!_ignoreItems.TryGetValue(worldItem.Id, out pos))
                        {
                            doAdd = true;
                        }
                        else
                        {
                            if (pos != worldItem.Position)
                            {
                                Log.InfoFormat("[AreaStateCache] An item collision has been detected! Item id {0}.", worldItem.Id);
                                _ignoreItems.Remove(worldItem.Id);
                                doAdd = true;
                            }
                        }

                        if (doAdd)
                        {
                            if (added > 10)
                            {
                                break;
                            }

                            ++added;

                            var item = worldItem.Item;

                            if (worldItem.IsAllocatedToOther)
                            {
                                if (DateTime.Now < worldItem.PublicTime)
                                {
                                    //Log.InfoFormat("[AreaStateCache] The item {0} is not being marked for pickup because it is allocated to another player.", item.FullName);
                                    //_ignoreItems.Add(worldItem.Id, worldItem.Position);
                                    continue;
                                }
                            }

                            var visibleOverride = false;
                            if (LootVisibleItemsOverride)
                            {
                                // We can only consider items when they are visible, otherwise we ignore stuff we might want.
                                if (!LokiPoe.ConfigManager.IsAlwaysHighlightEnabled)
                                {
                                    continue;
                                }

                                if (LokiPoe.Input.GetClickableHighlightLabelPosition(worldItem) != Vector2.Zero)
                                {
                                    visibleOverride = true;
                                }
                            }

                            IItemFilter filter = null;
                            if (visibleOverride || ItemEvaluator.Match(item, EvaluationType.PickUp, out filter))
                            {
                                var location = new ItemLocation
                                {
                                    Id       = worldItem.Id,
                                    Name     = worldItem.Name,
                                    Position = worldItem.Position,
                                    Rarity   = worldItem.Item.Rarity,
                                    Metadata = worldItem.Item.Metadata
                                };

                                if (_itemLocations.ContainsKey(location.Id))
                                {
                                    _itemLocations[location.Id] = location;
                                }
                                else
                                {
                                    _itemLocations.Add(location.Id, location);
                                }

                                Log.InfoFormat("[AreaStateCache] The location {0} [{1}] is being added from filter [{3}].{2}", location.Id,
                                               location.Name,
                                               worldItem.HasAllocation ? " [Allocation " + worldItem.PublicTime + "]" : "",
                                               filter != null ? filter.Name : "(null)");
                            }

                            _ignoreItems.Add(worldItem.Id, worldItem.Position);
                        }
                    }

                    var toRemove = new List <int>();
                    foreach (var kvp in _itemLocations)
                    {
                        if (Blacklist.Contains(kvp.Key))
                        {
                            Log.InfoFormat("[AreaStateCache] The location {0} [{1}] is being removed because the id has been Blacklisted.",
                                           kvp.Value.Id, kvp.Value.Name);
                            toRemove.Add(kvp.Value.Id);
                        }
                        else if (myPos.Distance(kvp.Value.Position) < 30)
                        {
                            if (LokiPoe.ObjectManager.GetObjectById <WorldItem>(kvp.Value.Id) == null)
                            {
                                Log.InfoFormat("[AreaStateCache] The location {0} [{1}] is being removed because the WorldItem does not exist.",
                                               kvp.Value.Id, kvp.Value.Name);
                                toRemove.Add(kvp.Value.Id);
                            }
                        }
                    }

                    foreach (var id in toRemove)
                    {
                        _itemLocations.Remove(id);
                    }

                    _itemThrottle.Restart();
                }
            }

            if (!_chestThrottle.IsRunning)
            {
                _chestThrottle.Start();
            }
            else
            {
                if (_chestThrottle.ElapsedMilliseconds >= ChestThrottleMs)
                {
                    //using (new PerformanceTimer("Tick::Chest", 1))
                    {
                        var addedChests = new List <ChestLocation>();
                        foreach (var chest in LokiPoe.ObjectManager.GetObjectsByType <Chest>().ToList())
                        {
                            ChestLocation location;
                            if (!_chestLocations.TryGetValue(chest.Id, out location))
                            {
                                location = new ChestLocation
                                {
                                    Id            = chest.Id,
                                    Name          = chest.Name,
                                    IsTargetable  = chest.IsTargetable,
                                    IsOpened      = chest.IsOpened,
                                    IsStrongBox   = chest.IsStrongBox,
                                    IsVaalVessel  = chest.IsVaalVessel,
                                    OpensOnDamage = chest.OpensOnDamage,
                                    Position      = chest.Position,
                                    Stats         = chest.Stats.ToList(),
                                    IsIdentified  = chest.IsIdentified,
                                    IsBreakable   = chest.OpensOnDamage,
                                    Rarity        = chest.Rarity,
                                    Metadata      = chest.Type
                                };

                                _chestLocations.Add(location.Id, location);

                                addedChests.Add(location);
                            }

                            if (!location.IsOpened)
                            {
                                location.IsOpened     = chest.IsOpened;
                                location.IsLocked     = chest.IsLocked;
                                location.IsTargetable = chest.IsTargetable;
                                // Support for chests that change locked state, without the lock state updating.
                                var tc = chest.Components.TransitionableComponent;
                                if (tc != null)
                                {
                                    if ((tc.Flag1 & 2) != 0)
                                    {
                                        location.IsLocked = false;
                                    }
                                }
                                if (chest.IsVaalVessel)
                                {
                                    location.IsLocked = false;
                                }
                                if (!location.IsCorrupted && chest.IsCorrupted)
                                {
                                    location.IsCorrupted = chest.IsCorrupted;
                                    location.Stats       = chest.Stats.ToList();
                                }
                                if (!location.IsIdentified && chest.IsIdentified)
                                {
                                    location.IsIdentified = chest.IsIdentified;
                                    location.Stats        = chest.Stats.ToList();
                                }
                            }

                            if (addedChests.Count > 10)
                            {
                                break;
                            }
                        }

                        foreach (var location in addedChests)
                        {
                            if (!location.IsBreakable)
                            {
                                location.Position = ExilePather.FastWalkablePositionFor(location.Position);
                            }

                            LokiPoe.InvokeEvent(OnChestLocationAdded, null, new OnChestLocationAddedEventArgs(location));
                        }

                        addedChests.Clear();

                        _chestThrottle.Restart();
                    }
                }
            }

            if (!_questThrottle.IsRunning)
            {
                _questThrottle.Start();
            }
            else
            {
                if (_questThrottle.ElapsedMilliseconds >= QuestThrottleMs)
                {
                    if (LokiPoe.CurrentWorldArea.IsMissionArea)
                    {
                        if (!HasKaruiSpiritLocation)
                        {
                            var obj = LokiPoe.ObjectManager.GetObjectByName("Karui Spirit");
                            if (obj != null)
                            {
                                AddLocation(ExilePather.FastWalkablePositionFor(obj), obj.Id, obj.Name);
                                HasKaruiSpiritLocation = true;
                            }
                        }
                    }

                    _questThrottle.Restart();
                }
            }

            if (!_throttle.IsRunning)
            {
                _throttle.Start();
            }
            else
            {
                if (_throttle.ElapsedMilliseconds >= ThrottleMs)
                {
                    if (!_timeInInstance.IsRunning)
                    {
                        _timeInInstance.Start();
                    }

                    if (!_timeInArea.IsRunning)
                    {
                        _timeInArea.Start();
                    }

                    // Do we need to update wp state flags.
                    if (_updateCheckForWaypoint)
                    {
                        // If the current area doesn't have a wp, we do not want to do any more logic processing.
                        if (!LokiPoe.CurrentWorldArea.HasWaypoint)
                        {
                            _updateCheckForWaypoint = false;
                            ShouldCheckForWaypoint  = false;
                            HasWaypointLocation     = false;
                            HasWaypointEntry        = false;
                        }
                        else
                        {
                            ShouldCheckForWaypoint = true;
                        }
                    }

                    // Do we need to update at state flags.
                    if (_updateAreaTransition)
                    {
                        ShouldCheckForAreaTransition = true;
                    }

                    if (ShouldCheckForStash)
                    {
                        //using (new PerformanceTimer("ShouldCheckForStash", 1))
                        {
                            if (!HasStashLocation)
                            {
                                var stash = LokiPoe.ObjectManager.Stash;
                                if (stash != null)
                                {
                                    // Save the location so we know where it is when the entity isn't in view.
                                    AddLocation(ExilePather.FastWalkablePositionFor(stash), stash.Id, "Stash");

                                    // We now have the waypoint location.
                                    HasStashLocation = true;
                                }
                            }
                            else
                            {
                                ShouldCheckForStash = false;
                            }
                        }
                    }

                    // If we need to handle wps.
                    if (ShouldCheckForWaypoint)
                    {
                        //using (new PerformanceTimer("ShouldCheckForWaypoint", 1))
                        {
                            // If we don't have the wp location yet, check to see if we see one.
                            if (!HasWaypointLocation)
                            {
                                var wp = LokiPoe.ObjectManager.Waypoint;
                                if (wp != null)
                                {
                                    // Save the location so we know where it is when the entity isn't in view.
                                    AddLocation(ExilePather.FastWalkablePositionFor(wp), wp.Id, "Waypoint");

                                    // We now have the waypoint location.
                                    HasWaypointLocation = true;
                                }
                            }

                            // If we don't have the wp entry yet, poll for us having it now.
                            // But only if we've seen the waypoint, since otherwise there's no way we have it.
                            if (HasWaypointLocation && !HasWaypointEntry)
                            {
                                var areaId = WorldArea.Id;
                                HasWaypointEntry = LokiPoe.InstanceInfo.AvailableWaypoints.ContainsKey(areaId);
                            }

                            // Once we have both the location and the entry, we do not need to execute wp logic anymore.
                            if (HasWaypointLocation && HasWaypointEntry)
                            {
                                _updateCheckForWaypoint = false;
                                ShouldCheckForWaypoint  = false;
                            }
                        }
                    }

                    // If we need to handle ats.
                    if (ShouldCheckForAreaTransition)
                    {
                        //using (new PerformanceTimer("ShouldCheckForAreaTransition", 1))
                        {
                            // If there are any area transitions on screen, add them if we don't already know of them.
                            foreach (var transition in LokiPoe.ObjectManager.Objects.OfType <AreaTransition>().ToList())
                            {
                                var name = transition.Name;

                                // We have to check all this in order to handle the areas that have transitions with the same name, but different
                                // entity ids.
                                if (HasLocation(name, transition.Id))
                                {
                                    continue;
                                }

                                AddLocation(ExilePather.FastWalkablePositionFor(transition), transition.Id, name);

                                if (!SeenAreaTransitions.Contains(name))
                                {
                                    SeenAreaTransitions.Add(name);
                                }
                            }
                        }
                    }

                    // Check to see if we need a new anchor point to kite back towards.
                    if (!_hasAnchorPoint || LokiPoe.LocalData.AreaHash != _anchorPointSeed)
                    {
                        ResetAnchorPoint();
                        ResetCurrentAnchorPoint();
                    }

                    _throttle.Restart();
                }
            }
        }