public static void Initialize() { if (EntityManager.Heroes.Enemies.Count > 0) { if (Menu == null) { MenuManager.AddSubMenu("Evader"); } if (Menu != null) { foreach (var enemy in EntityManager.Heroes.Enemies) { Menu.AddLabel(enemy.Hero.ToString()); foreach (var slot in AllowedSlots) { if (!SpellsAddedToMenu.Contains(enemy.Hero.ToString() + slot)) { Menu.AddValue(enemy.Hero.ToString() + slot, new CheckBox(slot.ToString(), false)); SpellsAddedToMenu.Add(enemy.Hero.ToString() + slot); } } } } } Obj_AI_Base.OnProcessSpellCast += delegate(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args) { var hero = sender as AIHeroClient; if (hero != null && sender.IsEnemy && AllowedSlots.Contains(args.Slot) && hero.IsValidTarget(1500f) && SpellsAddedToMenu.Contains(hero.Hero.ToString() + args.Slot) && Menu.CheckBox(hero.Hero.ToString() + args.Slot)) { if (DangerousSpellSlots.ContainsKey(hero.Hero) && DangerousSpellSlots[hero.Hero] == args.Slot) { if (DangerousSpellNames.ContainsKey(hero.Hero) && DangerousSpellNames[hero.Hero] != args.SData.Name) { return; } } var evadeArgs = new EvaderArgs { Sender = hero, StartTick = Core.GameTickCount, Spell = args, SData = args.SData }; EvaderList.Add(evadeArgs); if (OnEvader != null && evadeArgs.WillHitMyHero()) { OnEvader(evadeArgs); } } }; GameObject.OnCreate += delegate(GameObject sender, EventArgs args) { var missile = sender as MissileClient; if (missile != null) { var hero = missile.SpellCaster as AIHeroClient; if (hero != null && hero.IsEnemy && hero.IsValidTarget(1500f)) { var evaderArgs = EvaderList.FirstOrDefault( args1 => args1.Sender.IdEquals(hero) && args1.SData.AlternateName == missile.SData.AlternateName); if (evaderArgs != null) { evaderArgs.SData = missile.SData; evaderArgs.Missile = missile; } else if (EvaderList.Count(args1 => args1.Sender.IdEquals(hero)) == 1) { evaderArgs = EvaderList.FirstOrDefault(args1 => args1.Sender.IdEquals(hero)); if (evaderArgs != null) { evaderArgs.SData = missile.SData; evaderArgs.Missile = missile; } } } } }; GameObject.OnDelete += delegate(GameObject sender, EventArgs args) { var missile = sender as MissileClient; if (missile != null) { var hero = missile.SpellCaster as AIHeroClient; if (hero != null) { foreach (var evaderArgs in EvaderList.Where(evaderArgs => evaderArgs.Missile != null)) { evaderArgs.Missile = null; } } } }; Game.OnTick += delegate { EvaderList.RemoveAll(args => Core.GameTickCount - args.StartTick > 1800 || !args.Sender.IsValidTarget()); if (EvaderList.Count == 0 || OnEvader == null) { return; } foreach (var args in EvaderList.Where(args => args.WillHitMyHero())) { OnEvader(args); } }; }
public static bool WillHitMyHero(this EvaderArgs args, Vector3?vector = null) { SpellType spellType; switch (args.Spell.SData.TargettingType) { case SpellDataTargetType.Self: spellType = SpellType.Self; break; case SpellDataTargetType.Unit: if (args.Spell.Target != null || (args.Missile != null && args.Missile.IsValidMissile() && args.Missile.Target != null)) { spellType = SpellType.Targeted; } else { spellType = SpellType.Circular; } break; case SpellDataTargetType.LocationAoe: spellType = SpellType.Circular; break; case SpellDataTargetType.Cone: spellType = SpellType.Cone; break; case SpellDataTargetType.SelfAoe: spellType = SpellType.Self; break; case SpellDataTargetType.Location: spellType = SpellType.Linear; break; case SpellDataTargetType.SelfAndUnit: spellType = SpellType.Self; break; case SpellDataTargetType.Location2: spellType = SpellType.Linear; break; case SpellDataTargetType.LocationVector: spellType = SpellType.Linear; break; case SpellDataTargetType.LocationTunnel: spellType = SpellType.Linear; break; case SpellDataTargetType.LocationSummon: spellType = SpellType.Linear; break; case SpellDataTargetType.Location3: spellType = SpellType.Linear; break; default: spellType = SpellType.Self; break; } var currentPosition = vector ?? Player.Instance.Position; var missileIsValid = args.Missile != null && args.Missile.IsValidMissile(); var range = Math.Min(args.Spell.SData.CastRangeDisplayOverride > 0 ? args.Spell.SData.CastRangeDisplayOverride : args.Spell.SData.CastRange, args.SData.CastRangeDisplayOverride > 0 ? args.SData.CastRangeDisplayOverride : args.SData.CastRange); var startVector = missileIsValid ? args.Missile.Position : args.Spell.Start; var realEnd = args.Spell.Start + (args.Spell.End - args.Spell.Start).Normalized() * range; var endVector = missileIsValid ? args.Missile.EndPosition : realEnd; var width = AIO.MyHero.BoundingRadius * 1.5f; var willHit = false; var containsMissile = args.ContainsMissile; switch (spellType) { case SpellType.Self: break; case SpellType.Targeted: break; case SpellType.Linear: width += args.SData.LineWidth; break; case SpellType.Circular: width += Math.Max(args.SData.CastRadius, args.SData.CastRadiusSecondary) / 2f; //Math.Max(args.SData.CastRadius, args.SData.CastRadiusSecondary); break; case SpellType.Cone: width += args.SData.LineWidth; break; } if (missileIsValid) { if (spellType == SpellType.Targeted) { willHit = args.Spell.Target != null && args.Spell.Target.IsMe && args.Missile.IsInRange(currentPosition, 200f); } else if (spellType == SpellType.Linear || spellType == SpellType.Circular || spellType == SpellType.Cone) { var distance = spellType == SpellType.Circular ? currentPosition.Distance(endVector) : currentPosition.To2D().Distance(startVector.To2D(), endVector.To2D(), true, false); if (distance <= width && distance > 0 && distance < float.MaxValue) { var timeToEvade = (width - distance) / AIO.MyHero.MoveSpeed + Game.Ping / 2000f; var timeToArrive = args.SData.MissileFixedTravelTime > 0 ? args.SData.MissileFixedTravelTime : currentPosition.Distance(args.Missile) / args.Missile.SData.MissileSpeed; willHit = timeToEvade >= timeToArrive; } } } else if (!containsMissile) { switch (spellType) { case SpellType.Self: if (args.Sender.Hero == Champion.Orianna) { var ballObject = ObjectManager.Get <Obj_GeneralParticleEmitter>() .FirstOrDefault(o => o.IsValid && !o.IsDead && o.Name == Orianna.BallName) ?? (args.Sender.HasBuff("orianaghostself") ? args.Sender : null) ?? UnitManager.ValidHeroes.FirstOrDefault(h => h.HasBuff("orianaghost")) as GameObject; if (ballObject != null) { if (currentPosition.IsInRange(ballObject, range + width)) { willHit = true; } } } else { if (currentPosition.IsInRange(startVector, range + width)) { willHit = true; } } break; case SpellType.Targeted: willHit = args.Spell.Target != null && args.Spell.Target.IsMe; break; case SpellType.Linear: willHit = currentPosition.To2D().Distance(startVector.To2D(), endVector.To2D(), true, true) <= width.Pow(); break; case SpellType.Circular: if (currentPosition.IsInRange(endVector, width)) { willHit = true; } break; case SpellType.Cone: willHit = currentPosition.To2D().Distance(startVector.To2D(), endVector.To2D(), true, true) <= width.Pow(); break; } } return(willHit); }
public static void Initialize() { if (EntityManager.Heroes.Enemies.Count > 0) { if (Menu == null) { MenuManager.AddSubMenu("Evader"); } if (Menu != null) { foreach (var enemy in EntityManager.Heroes.Enemies) { Menu.AddLabel(enemy.Hero.ToString()); foreach (var slot in AllowedSlots) { if (!SpellsAddedToMenu.Contains(enemy.Hero.ToString() + slot)) { Menu.AddValue(enemy.Hero.ToString() + slot, new CheckBox(slot.ToString(), false)); SpellsAddedToMenu.Add(enemy.Hero.ToString() + slot); } } } } } Obj_AI_Base.OnProcessSpellCast += delegate (Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args) { var hero = sender as AIHeroClient; if (hero != null && sender.IsEnemy && AllowedSlots.Contains(args.Slot) && hero.IsValidTarget(1500f) && SpellsAddedToMenu.Contains(hero.Hero.ToString() + args.Slot) && Menu.CheckBox(hero.Hero.ToString() + args.Slot)) { if (DangerousSpellSlots.ContainsKey(hero.Hero) && DangerousSpellSlots[hero.Hero] == args.Slot) { if (DangerousSpellNames.ContainsKey(hero.Hero) && DangerousSpellNames[hero.Hero] != args.SData.Name) { return; } } var evadeArgs = new EvaderArgs { Sender = hero, StartTick = Core.GameTickCount, Spell = args, SData = args.SData }; EvaderList.Add(evadeArgs); if (OnEvader != null && evadeArgs.WillHitMyHero()) { OnEvader(evadeArgs); } } }; GameObject.OnCreate += delegate (GameObject sender, EventArgs args) { var missile = sender as MissileClient; if (missile != null) { var hero = missile.SpellCaster as AIHeroClient; if (hero != null && hero.IsEnemy && hero.IsValidTarget(1500f)) { var evaderArgs = EvaderList.FirstOrDefault( args1 => args1.Sender.IdEquals(hero) && args1.SData.AlternateName == missile.SData.AlternateName); if (evaderArgs != null) { evaderArgs.SData = missile.SData; evaderArgs.Missile = missile; } else if (EvaderList.Count(args1 => args1.Sender.IdEquals(hero)) == 1) { evaderArgs = EvaderList.FirstOrDefault(args1 => args1.Sender.IdEquals(hero)); if (evaderArgs != null) { evaderArgs.SData = missile.SData; evaderArgs.Missile = missile; } } } } }; GameObject.OnDelete += delegate (GameObject sender, EventArgs args) { var missile = sender as MissileClient; if (missile != null) { var hero = missile.SpellCaster as AIHeroClient; if (hero != null) { foreach (var evaderArgs in EvaderList.Where(evaderArgs => evaderArgs.Missile != null)) { evaderArgs.Missile = null; } } } }; Game.OnTick += delegate { EvaderList.RemoveAll(args => Core.GameTickCount - args.StartTick > 1800 || !args.Sender.IsValidTarget()); if (EvaderList.Count == 0 || OnEvader == null) { return; } foreach (var args in EvaderList.Where(args => args.WillHitMyHero())) { OnEvader(args); } }; }