Esempio n. 1
0
        public MessageResult Message(Message message)
        {
            var id = message.Id;

            if (id == MapBot.Messages.NewMapEntered)
            {
                GlobalLog.Info("[KillBossTask] Reset.");
                var areaName = message.GetInput <string>();
                _bossesKilled    = 0;
                _currentTarget   = null;
                BossKilled       = false;
                _multiPhaseBoss  = false;
                _teleportingBoss = false;
                CachedBosses.Clear();
                SetBossSelector(areaName);
                SetPriorityBossName(areaName);
                SetBossRange(areaName);

                if (areaName == MapNames.VaultsOfAtziri)
                {
                    BossKilled = true;
                    GlobalLog.Info($"[KillBossTask] BossKilled is set to true ({areaName})");
                    return(MessageResult.Processed);
                }

                if (areaName == MapNames.MineralPools ||
                    areaName == MapNames.Palace ||
                    areaName == MapNames.Basilica ||
                    areaName == MapNames.MaelstromOfChaos)
                {
                    _multiPhaseBoss = true;
                    GlobalLog.Info($"[KillBossTask] MultiPhaseBoss is set to true ({areaName})");
                    return(MessageResult.Processed);
                }

                if (areaName == MapNames.Pen ||
                    areaName == MapNames.Pier ||
                    areaName == MapNames.Shrine ||
                    areaName == MapNames.DesertSpring ||
                    areaName == MapNames.Summit ||
                    areaName == MapNames.DarkForest ||
                    areaName == MapNames.PutridCloister)
                {
                    _teleportingBoss = true;
                    GlobalLog.Info($"[KillBossTask] TeleportingBoss is set to true ({areaName})");
                    return(MessageResult.Processed);
                }
                return(MessageResult.Processed);
            }
            if (id == ComplexExplorer.LocalTransitionEnteredMessage)
            {
                GlobalLog.Info("[KillBossTask] Resetting unwalkable flags.");
                foreach (var cachedBoss in CachedBosses)
                {
                    cachedBoss.Unwalkable = false;
                }
                return(MessageResult.Processed);
            }
            return(MessageResult.Unprocessed);
        }
Esempio n. 2
0
        public async Task <bool> Run()
        {
            if (BossKilled || MapExplorationTask.MapCompleted)
            {
                return(false);
            }

            var area = World.CurrentArea;

            if (!area.IsMap)
            {
                return(false);
            }

            if (_currentTarget == null)
            {
                if ((_currentTarget = CachedBosses.ClosestValid(b => !b.IsDead)) == null)
                {
                    return(false);
                }
            }

            if (Blacklist.Contains(_currentTarget.Id))
            {
                GlobalLog.Warn("[KillBossTask] Boss is in global blacklist. Now marking it as killed.");
                _currentTarget.IsDead = true;
                _currentTarget        = null;
                RegisterDeath();
                return(true);
            }

            if (_priorityBossName != null && _currentTarget.Position.Name != _priorityBossName)
            {
                var priorityBoss = CachedBosses.ClosestValid(b => !b.IsDead && b.Position.Name == _priorityBossName);
                if (priorityBoss != null)
                {
                    GlobalLog.Debug($"[KillBossTask] Switching current target to \"{priorityBoss}\".");
                    _currentTarget = priorityBoss;
                    return(true);
                }
            }

            if (_currentTarget.IsDead)
            {
                var newBoss = CachedBosses.Valid().FirstOrDefault(b => !b.IsDead);
                if (newBoss != null)
                {
                    _currentTarget = newBoss;
                }
            }

            var pos = _currentTarget.Position;

            if (pos.Distance <= 50 && pos.PathDistance <= 55)
            {
                var bossObj = _currentTarget.Object as Monster;
                if (bossObj == null)
                {
                    if (_teleportingBoss)
                    {
                        CachedBosses.Remove(_currentTarget);
                        _currentTarget = null;
                        return(true);
                    }
                    GlobalLog.Debug("[KillBossTask] We are close to last know position of map boss, but boss object does not exist anymore.");
                    GlobalLog.Debug("[KillBossTask] Most likely this boss does not spawn a corpse or was shattered/exploded.");
                    _currentTarget.IsDead = true;
                    _currentTarget        = null;
                    RegisterDeath();
                    return(true);
                }
            }

            if (pos.Distance > _bossRange)
            {
                if (LogInterval.Elapsed)
                {
                    GlobalLog.Debug($"[KillBossTask] Going to {pos}");
                }
                if (!pos.TryCome())
                {
                    GlobalLog.Error(MapData.Current.Type == MapType.Regular
                        ? $"[KillBossTask] Unexpected error. Fail to move to map boss ({pos.Name}) in a regular map."
                        : $"[KillBossTask] Fail to move to the map boss \"{pos.Name}\". Will try again after area transition.");
                    _currentTarget.Unwalkable = true;
                    _currentTarget            = null;
                }
                return(true);
            }

            var attempts = ++_currentTarget.InteractionAttempts;

            // Helps to trigger Gorge and Underground River bosses
            if (attempts == MaxKillAttempts / 4)
            {
                GlobalLog.Debug("[KillBossTask] Trying to move around to trigger a boss.");
                var distantPos = WorldPosition.FindPathablePositionAtDistance(40, 70, 5);
                if (distantPos != null)
                {
                    await Move.AtOnce(distantPos, "distant position", 10);
                }
            }
            if (attempts > MaxKillAttempts)
            {
                GlobalLog.Error("[KillBossTask] Boss did not become active. Now ignoring it.");
                _currentTarget.Ignored = true;
                _currentTarget         = null;
                RegisterDeath();
                return(true);
            }
            await Coroutines.FinishCurrentAction();

            GlobalLog.Debug($"[KillBossTask] Waiting for map boss to become active ({attempts}/{MaxKillAttempts})");
            await Wait.StuckDetectionSleep(200);

            return(true);
        }
Esempio n. 3
0
        public void Tick()
        {
            if (BossKilled || MapExplorationTask.MapCompleted)
            {
                return;
            }

            if (!TickInterval.Elapsed)
            {
                return;
            }

            if (!LokiPoe.IsInGame || !World.CurrentArea.IsMap)
            {
                return;
            }

            foreach (var obj in LokiPoe.ObjectManager.Objects)
            {
                var mob = obj as Monster;

                if (mob == null || !_isMapBoss(mob))
                {
                    continue;
                }

                var id     = mob.Id;
                var cached = CachedBosses.Find(b => b.Id == id);

                if (!mob.IsDead)
                {
                    var pos = mob.WalkablePosition(5, 20);
                    if (cached != null)
                    {
                        cached.Position = pos;
                    }
                    else
                    {
                        CachedBosses.Add(new CachedBoss(id, pos, false));
                        GlobalLog.Warn($"[KillBossTask] Registering {pos}");
                    }
                }
                else
                {
                    if (cached == null)
                    {
                        GlobalLog.Warn($"[KillBossTask] Registering dead map boss \"{mob.Name}\".");
                        CachedBosses.Add(new CachedBoss(id, mob.WalkablePosition(), true));
                        RegisterDeath();
                    }
                    else if (!cached.IsDead)
                    {
                        GlobalLog.Warn($"[KillBossTask] Registering death of \"{mob.Name}\".");
                        cached.IsDead = true;
                        if (!_multiPhaseBoss)
                        {
                            _currentTarget = null;
                        }
                        RegisterDeath();
                    }
                }
            }
        }