Пример #1
0
        public override void OnPulse()
        {
            //don't run if we don't have a navigation provider
            if (Navigator.NavigationProvider == null)
            {
                return;
            }

            using (new PerformanceLogger("Pulse"))
            {
                //remove tracked avoidances that have completed
                var removable = _tracked.Where(i => !i.Condition() && AvoidanceManager.Avoids.All(z => z.AvoidInfo != i)).ToList();

                if (removable.Any())
                {
                    Logger.Info($"Removing {removable.Count} completed spells");
                    AvoidanceManager.RemoveAllAvoids(i => removable.Contains(i));
                    _tracked.RemoveAll(x => removable.Contains(x));
                }


                var newSpellCasts = GameObjectManager.GetObjectsOfType <BattleCharacter>()
                                    .Where(IsValid)
                                    .SelectMany(HandleNewCast)
                                    .ToList();

                if (newSpellCasts.Any())
                {
                    _tracked.AddRange(newSpellCasts);
                    //AvoidanceManager.AvoidInfos.AddRange(newSpellCasts);
                    Logger.Info($"Added: {newSpellCasts.Count()} to the avoidance manager");
                }
            }
        }
Пример #2
0
        public override void OnPulse()
        {
            //don't run if we don't have a navigation provider
            if (Navigator.NavigationProvider == null)
            {
                return;
            }

            using (new PerformanceLogger("Pulse"))
            {
                //remove tracked avoidances that have completed
                var removeable = _tracked.Where(i => !i.Condition() && !AvoidanceManager.Avoids.Any(z => z.AvoidInfo == i)).ToList();

                if (removeable.Any())
                {
                    Logger.Info($"Removing {removeable.Count()} completed spells");
                    AvoidanceManager.RemoveAllAvoids(i => removeable.Contains(i));
                    _tracked.RemoveAll(x => removeable.Contains(x));
                }
                var newSpellCasts = GameObjectManager.GetObjectsOfType <BattleCharacter>()
                                    .Where(c => c.InCombat && !c.IsMe && c.StatusFlags.HasFlag(StatusFlags.Hostile) && c.CastingSpellId != 0 && IsNearby(c) &&

                                           c.SpellCastInfo.SpellData.Omen != 0 && //skip spells that don't have an omen

                                           !AvoidanceManager.AvoidInfos.Any(s => s.Collection.Contains(c)))
                                    .GroupBy(p => p.ObjectId)
                                    .SelectMany(o =>
                {
                    var c = o.First();
                    if (_owners.ContainsKey((ulong)AvoiderType.Spell + c.CastingSpellId))
                    {
                        Logger.Verbose($"{c.SpellCastInfo.SpellData.LocalizedName} [Spell][Id: {c.CastingSpellId}][Omen: {c.SpellCastInfo.SpellData.Omen}][RawCastType: {c.SpellCastInfo.SpellData.RawCastType}][ObjId: {c.ObjectId}]");
                        return(_owners[(ulong)AvoiderType.Spell + c.CastingSpellId].Handle(c));
                    }

                    if (_owners.ContainsKey((ulong)AvoiderType.Omen + c.SpellCastInfo.SpellData.Omen))
                    {
                        Logger.Verbose($"{c.SpellCastInfo.SpellData.LocalizedName} [Omen][Id: {c.CastingSpellId}][Omen: {c.SpellCastInfo.SpellData.Omen}][RawCastType: {c.SpellCastInfo.SpellData.RawCastType}][ObjId: {c.ObjectId}]");
                        return(_owners[(ulong)AvoiderType.Omen + c.SpellCastInfo.SpellData.Omen].Handle(c));
                    }

                    if (_owners.ContainsKey((ulong)AvoiderType.CastType + c.SpellCastInfo.SpellData.RawCastType))
                    {
                        Logger.Verbose($"{c.SpellCastInfo.SpellData.LocalizedName} [CastType][Id: {c.CastingSpellId}][Omen: {c.SpellCastInfo.SpellData.Omen}][RawCastType: {c.SpellCastInfo.SpellData.RawCastType}][ObjId: {c.ObjectId}]");
                        return(_owners[(ulong)AvoiderType.CastType + c.SpellCastInfo.SpellData.RawCastType].Handle(c));
                    }

                    Logger.Verbose($"No Avoid info for: {c.SpellCastInfo.SpellData.LocalizedName} [None][Id: {c.CastingSpellId}][Omen: {c.SpellCastInfo.SpellData.Omen}][RawCastType: {c.SpellCastInfo.SpellData.RawCastType}][ObjId: {c.ObjectId}]");
                    return(null);
                })
                                    .Where(i => i != null).ToList();

                if (newSpellCasts.Any())
                {
                    _tracked.AddRange(newSpellCasts);
                    //AvoidanceManager.AvoidInfos.AddRange(newSpellCasts);
                    Logger.Info($"Added: {newSpellCasts.Count()} to the avoidance manager");
                }
            }
        }
Пример #3
0
        private void RemoveHook()
        {
            if (s_hook == null)
            {
                return;
            }
            TreeHooks.Instance.RemoveHook("Combat_Main", s_hook);
            Navigator.NavigationProvider = s_prevNavigator;

            // Make sure maps for the previous navigator are up-to-date
            var meshNav = Navigator.NavigationProvider as MeshNavigator;

            if (meshNav != null)
            {
                meshNav.UpdateMaps();
            }

            s_prevNavigator = null;
            s_hook          = null;
            foreach (var kv in s_avoidDictionary)
            {
                AvoidanceManager.RemoveAvoid(kv.Value);
                QBCLog.DeveloperInfo("Removed the \"{0}\" avoidance definition", kv.Key);
            }
            s_avoidDictionary.Clear();
            BotEvents.OnPulse      -= BotEvents_OnPulse;
            BotEvents.OnBotStopped -= BotEvents_OnBotStopped;
            BotEvents.Profile.OnNewOuterProfileLoaded  -= Profile_OnNewOuterProfileLoaded;
            LootTargeting.Instance.RemoveTargetsFilter -= Instance_RemoveTargetsFilter;
            QBCLog.Info("Uninstalled avoidance system");
        }
Пример #4
0
        public override IEnumerable <AvoidInfo> OmenHandle(BattleCharacter spellCaster)
        {
            if (spellCaster.SpellCastInfo.SpellData.EffectRange > 45)
            {
                Logger.Info("Spell range is > 45. Does this require specific logic?");
            }
            //var loc = spellCaster.SpellCastInfo.CastLocation != Vector3.Zero ? spellCaster.SpellCastInfo.CastLocation : spellCaster.Location;

            Vector3 center;
            float   range = 0f;

            if (OmenOverrideManager.TryGetOverride(spellCaster.SpellCastInfo.ActionId, out var omenOverride))
            {
                range = Range(spellCaster, out center, omenOverride.MatrixOverride, omenOverride.RangeOverride);
            }
            else
            {
                range = Range(spellCaster, out center);
            }



            Logger.Info($"Avoid Cirlce: [{center}][Range: {range}]");
            var cached = spellCaster.CastingSpellId;

            return(new[] { AvoidanceManager.AddAvoidLocation(
                               () => spellCaster.IsValid && spellCaster.CastingSpellId == cached, //can run
                               () => center,                                                      //LeashPoint
                               50f,                                                               //Leash Radius
                               bc => range + 0.5f,                                                //radiusProducer
                               bc => center,                                                      //locationProducer
                               () => new[] { spellCaster } //collectionProducer
                               ) });
        }
        public void HookAvoidance()
        {
            avoidanceManager  = new AvoidanceManager(Database);
            avoidanceBehavoir = avoidanceManager.GetAvoidanceBehavior();

            TreeHooks.Instance.AddHook("PreCombatLogic", avoidanceBehavoir);
            Logger.WriteMessage("Avoidance hooked.");
        }
Пример #6
0
        public override IEnumerable <AvoidInfo> OmenHandle(BattleCharacter spellCaster)
        {
            var cached = spellCaster.CastingSpellId;
            var square = Square(spellCaster);
            var result = new List <AvoidInfo>();

            result.Add(AvoidanceManager.AddAvoidPolygon(
                           () => spellCaster.IsValid && spellCaster.CastingSpellId == cached,
                           null,
                           40f,
                           bc => 0f,     //rotation
                           bc => 1.0f,   //scale
                           bc => 15.0f,  //height
                           bc => square, //points
                           bc => spellCaster.Location,
                           () => new[] { spellCaster } //objs
                           ));

            result.Add(AvoidanceManager.AddAvoidPolygon(
                           () => spellCaster.IsValid && spellCaster.CastingSpellId == cached,
                           null,
                           40f,
                           bc => (float)Math.PI, //rotation
                           bc => 1.0f,           //scale
                           bc => 15.0f,          //height
                           bc => square,         //points
                           bc => spellCaster.Location,
                           () => new[] { spellCaster } //objs
                           ));
            result.Add(AvoidanceManager.AddAvoidPolygon(
                           () => spellCaster.IsValid && spellCaster.CastingSpellId == cached,
                           null,
                           40f,
                           bc => - (float)Math.PI / 2, //rotation
                           bc => 1.0f,                 //scale
                           bc => 15.0f,                //height
                           bc => square,               //points
                           bc => spellCaster.Location,
                           () => new[] { spellCaster } //objs
                           ));
            result.Add(AvoidanceManager.AddAvoidPolygon(
                           () => spellCaster.IsValid && spellCaster.CastingSpellId == cached,
                           null,
                           40f,
                           bc => (float)Math.PI / 2, //rotation
                           bc => 1.0f,               //scale
                           bc => 15.0f,              //height
                           bc => square,             //points
                           bc => spellCaster.Location,
                           () => new[] { spellCaster } //objs
                           ));


            return(result);
        }
        public void UnhookAvoidance()
        {
            avoidanceManager = null;

            if (avoidanceBehavoir != null)
            {
                TreeHooks.Instance.RemoveHook("PreCombatLogic", avoidanceBehavoir);
            }
            avoidanceBehavoir = null;

            Logger.WriteMessage("Avoidance unhooked.");
        }
Пример #8
0
        public IEnumerable <AvoidInfo> AddCone(BattleCharacter spellCaster, float arcDegrees)
        {
            try
            {
                var cachedSpell = spellCaster.CastingSpellId;
                var m4x4        = spellCaster.OmenMatrix;

                //sin(0), 0, cos(0)
                m4x4.Transform(new Vector3(0, 0, 1), out var transformed);
                var center = m4x4.Center();

                var depth = transformed.Distance2D(center);
                var d     = transformed - center;

                var rot = MathEx.Rotation(d);

                var rad = (float)Math.Round(MathEx.NormalizeRadian(rot - spellCaster.Heading), 2);

                var me = Core.Me.Location;
                Logger.Info("Debug: Rotation: {0} vs Mob heading: {1} = {2}", rot, spellCaster.Heading, rad);


                return(new[] { AvoidanceManager.AddAvoidUnitCone <BattleCharacter>(
                                   () => spellCaster.IsValid && spellCaster.CastingSpellId == cachedSpell, //can run
                                   bc => bc.ObjectId == spellCaster.ObjectId,                              //object selector
                                   () => me,                                                               //LeashPoint
                                   120,                                                                    //leash size
                                   rad,                                                                    //rotation
                                   depth,                                                                  //radius / Depth
                                   arcDegrees * 1.55f,                                                     //arcDegrees
                                   bc => bc.Location
                                   ),

                               //add something under the mob so we don't get hit by standing at the mobs location.
                               AvoidanceManager.AddAvoidLocation(
                                   () => spellCaster.IsValid && spellCaster.CastingSpellId == cachedSpell, //can run
                                   spellCaster.CombatReach / 2,
                                   () => spellCaster.Location
                                   ) });
            }
            catch (Exception ex)
            {
                Logger.Error("failed to make cone: {0}", ex);
                return(null);
            }
        }
Пример #9
0
        //public async Task<bool> Handle(SpellCast spellCaster)
        //{

        //    var res = inside(spellCaster.CasterLocation, spellCaster.CasterHeading, spellCaster.Data.EffectRange,
        //        spellCaster.Data.XAxisModified > 0 ? spellCast.Data.XAxisModified : spellCaster.Caster.CombatReach);
        //    if (res.Item1)
        //    {
        //        await Help.MoveTo(res.Item2, spellCaster);
        //    }
        //    return Core.Me.IsMelee();
        //}

        public override IEnumerable <AvoidInfo> OmenHandle(BattleCharacter spellCaster)
        {
            var cached = spellCaster.CastingSpellId;
            //var rotation = Rotation(spellCaster);
            //var cl = spellCaster.SpellCastInfo.CastLocation;
            var square = Square(spellCaster);

            return(new[] { AvoidanceManager.AddAvoidPolygon(
                               () => spellCaster.IsValid && spellCaster.CastingSpellId == cached,
                               null,
                               40f,
                               bc => 0f,     //rotation
                               bc => 1.0f,   //scale
                               bc => 15.0f,  //height
                               bc => square, //points
                               bc => spellCaster.Location,
                               () => new[] { spellCaster } //objs
                               ) });
        }
Пример #10
0
        public override void OnStart()
        {
            // Acquisition and checking of any sub-elements go here.
            // A common example:
            //     HuntingGrounds = HuntingGroundsType.GetOrCreate(Element, "HuntingGrounds", HuntingGroundCenter);
            //     IsAttributeProblem |= HuntingGrounds.IsAttributeProblem;

            // Let QuestBehaviorBase do basic initialization of the behavior, deal with bad or deprecated attributes,
            // capture configuration state, install BT hooks, etc.  This will also update the goal text.
            var isBehaviorShouldRun = OnStart_QuestBehaviorCore();

            if (isBehaviorShouldRun)
            {
                if (Command == CommandType.Remove)
                {
                    if (s_avoidDictionary.ContainsKey(AvoidName))
                    {
                        QBCLog.DeveloperInfo("Removing \"{0}\" avoid", AvoidName);
                        var avoidInfo = s_avoidDictionary[AvoidName];
                        s_avoidDictionary.Remove(AvoidName);
                        AvoidanceManager.RemoveAvoid(avoidInfo);
                    }
                }
                else if (Command == CommandType.Add)
                {
                    AvoidInfo avoidInfo = BuildAvoidInfo();
                    QBCLog.DeveloperInfo("Adding \"{0}\" avoid - Radius: {1}, ObjectId: ({2}), ObjectType: {3}",
                                         AvoidName, Radius, string.Join(", ", ObjectIds), ObjectType);
                    s_avoidDictionary[AvoidName] = avoidInfo;
                    AvoidanceManager.AddAvoid(avoidInfo);
                }
            }

            if (s_hook == null && s_avoidDictionary.Any())
            {
                InstallHook();
            } // remove hook if no avoid definitions are active
            else if (s_hook != null && !s_avoidDictionary.Any())
            {
                RemoveHook();
            }
            BehaviorDone();
        }
Пример #11
0
        public override IEnumerable <AvoidInfo> OmenHandle(BattleCharacter spellCaster)
        {
            if (spellCaster.SpellCastInfo.SpellData.EffectRange > 45)
            {
                Logger.Info("Spell range is > 45. Does this require specific logic?");
            }
            //var loc = spellCaster.SpellCastInfo.CastLocation != Vector3.Zero ? spellCaster.SpellCastInfo.CastLocation : spellCaster.Location;

            var range = Range(spellCaster, out var center);

            Logger.Info($"Avoid Cirlce: [{center}][Range: {range}]");
            var cached = spellCaster.CastingSpellId;

            return(new[] { AvoidanceManager.AddAvoidLocation(
                               () => spellCaster.IsValid && spellCaster.CastingSpellId == cached,
                               null,
                               40f,
                               bc => range + 0.5f,
                               bc => center,
                               () => new[] { spellCaster }
                               ) });
        }
Пример #12
0
        public static async Task <bool> Run()
        {
            // NOT TESTED

            #region Spell Filters

            HashSet <uint> Spells = new HashSet <uint>()
            {
                16333, 16334                                    //Temporary Current
                , 16337, 16335, 16336                           //Undersea Quake
                , 16338, 16339                                  //TidalWave (Preview and Execute)
                //,16328                //Drenching Pulse (Needs a way to avoid others) && Freak Wave
                //Needs Mechanic for Blue Circle with Red Squares over head to seperate
                , 16344                                         //Spinning Dive (Dive Bombs after Maelstrom)
                , 16376                                         //Surging Tsunami (Pushback Mechanic)
                //,16341				//Swirling Tsunami (Donut AOE) need way to detect if me or other player
                , 16332                                         //Killer Wave (Stacking Mechanic)
                //,16326			//Rip Current (Tank Buster to be coded later)
            };
            #endregion

            #region Custom Mechanics



            HashSet <uint> SurgingTsunami = new HashSet <uint>()
            {
                16376
            };
            if (SurgingTsunami.IsCasting() && Core.Me.CurrentHealthPercent > 0)
            {
                Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Swirling Tsunami Handling - Triggered - To Center");

                Vector3 _loc = new Vector3(99, 0, 99);

                while (Core.Me.Distance(_loc) > 2f)
                {
                    await CommonTasks.MoveTo(_loc);

                    await Coroutine.Yield();
                }
                Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Swirling Tsunami Handling - Sleeping");
                await Coroutine.Sleep(3000);

                if (ActionManager.IsSprintReady)
                {
                    ActionManager.Sprint();
                    await Coroutine.Wait(1000, () => !ActionManager.IsSprintReady);
                }
                Stopwatch sw = new Stopwatch();
                sw.Start();

                Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Swirling Tsunami Handling - Sleeping 2");
                await Coroutine.Sleep(1000);

                await Coroutine.Yield();

                sw.Stop();

                Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Swirling Tsunami Handling -  - Complete");
            }


            #endregion

            /// Default (缺省)
            if (Spells.IsCasting() && Core.Me.CurrentHealthPercent > 0)
            {
                Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Generic Default Handling - Triggered");
                //Core.Me.ClearTarget();						//Clears Target

                await Coroutine.Sleep(700);

                while (Core.Me.Location.Distance2D(PartyManager.VisibleMembers.Where(x => !x.IsMe && x.BattleCharacter.IsAlive).FirstOrDefault().BattleCharacter.Location) > 1)
                {
                    if (ActionManager.IsSprintReady)
                    {
                        ActionManager.Sprint();
                        await Coroutine.Wait(1000, () => !ActionManager.IsSprintReady);
                    }
                    //if (AvoidanceManager.IsRunningOutOfAvoid)     //&& in that zone  (Mechanics file is loaded only for this zone
                    //{
                    AvoidanceManager.RemoveAllAvoids((info => true));
                    AvoidanceManager.ResetNavigation();
                    //}
                    MovementManager.SetFacing(PartyManager.VisibleMembers.Where(x => !x.IsMe && x.BattleCharacter.IsAlive).FirstOrDefault().BattleCharacter.Location);
                    Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Generic Default Handling - Moving to Nearest Alive Party Character");
                    MovementManager.MoveForwardStart();
                    if (Core.Me.CurrentHealthPercent <= 0)
                    {
                        break;
                    }
                    Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Generic Default Handling - Waiting");
                    await Coroutine.Sleep(100);

                    MovementManager.MoveStop();
                }
                Logging.Write(Colors.Aquamarine, $"Dungeon Assist Eden Mechanic - Generic Default Handling - Complete");
                //await Coroutine.Sleep(1000);
                await Coroutine.Yield();
            }
            return(false);
        }
Пример #13
0
 private void BotEvents_OnPulse(object sender, EventArgs args)
 {
     AvoidanceManager.Pulse();
 }