public static bool TryToMoveToSafePosition() { //timeUntilHit in form of MS CustomPolygon closestTimePolygon = Player.Instance.FindSpellInfoWithClosestTime(); if (closestTimePolygon == null) { return(false); } if (safePosition != Vector3.Zero && safePosition.IsSafe(Player.Instance)) { Orbwalker.MoveTo(safePosition.Extend(Player.Instance.Position, -100).To3DFromNavMesh()); return(true); } TimeOfLastMovementCheck = Game.Time; float timeUntilHit = closestTimePolygon.TimeUntilHitsChampion(Player.Instance); float movementSpeed = Player.Instance.MoveSpeed; //d = ts/1000 //capped at 500 to remove massive fps drops float DistancePlayerCanWalkToBeforeBeingHit = Math.Min(timeUntilHit * movementSpeed / 1000, 500); List <Vector3> walkingPositions = GetSafePositions(Player.Instance, DistancePlayerCanWalkToBeforeBeingHit); if (walkingPositions.Count > 0) { Console.WriteLine("PossibleSafePositions: " + walkingPositions.Count); Vector3 safePos = walkingPositions.Where(a => a != null && a != Vector3.Zero && Player.Instance.GetPath(a).All(b => !b.IsWall()) && IsSafer(Player.Instance.GetPath(a), timeUntilHit)).OrderBy(a => a.Distance(Player.Instance)).FirstOrDefault(); if (safePos != null && safePos != Vector3.Zero) { Console.WriteLine("Set"); //move past the position so that the player isn't hit by the skillshot Orbwalker.MoveTo(safePos.Extend(Player.Instance.Position, -Player.Instance.BoundingRadius).To3DFromNavMesh()); safePosition = safePos; return(true); } } else { Console.WriteLine("No Safe Positions"); } return(false); }
private static void DrawSafeWalkingDistance() { if (MenuHandler.DrawMenu.GetCheckboxValue("Draw Safe Position Radius")) { CustomPolygon closestTimePolygon = Player.Instance.FindSpellInfoWithClosestTime(); if (closestTimePolygon == null) { return; } float timeUntilHit = closestTimePolygon.TimeUntilHitsChampion(Player.Instance); float movementSpeed = Player.Instance.MoveSpeed; //d = ts/1000 float DistancePlayerCanWalkToBeforeBeingHit = timeUntilHit * movementSpeed / 1000; Drawing.DrawCircle(Player.Instance.Position, DistancePlayerCanWalkToBeforeBeingHit, drawColor); } }
public static void HandleDodging() { AIHeroClient self = Player.Instance; if (!self.IsSafe()) { //every 20th of a second it can check for movements. This is to avoid FPS drops. if (Game.Time - TimeOfLastMovementCheck >= 0.05f && !TryToMoveToSafePosition()) { List <CustomPolygon> polysThatHitMe = self.GetPolygonsThatHitMe(); List <SpellInfo> selfSpells = self.GetSpells(); Menu mainMenu = MenuHandler.mainChampionEvadeMenu; float highestDangerValueIncoming = polysThatHitMe.OrderByDescending(a => a.GetDangerValue()).FirstOrDefault().GetDangerValue(); CustomPolygon closestSpell = self.FindSpellInfoWithClosestTime(); #region UseSpellShield if (highestDangerValueIncoming >= mainMenu.GetSliderValue("Spell Shield Danger Level") && selfSpells.Any(a => a.BuffType == SpellInfo.Buff.SpellShield && closestSpell.TimeUntilHitsChampion(self) <= a.Duration && a.IsOffCooldown())) { SpellInfo spellShield = selfSpells.FirstOrDefault(a => a.BuffType == SpellInfo.Buff.SpellShield && closestSpell.TimeUntilHitsChampion(self) <= a.Duration && a.IsOffCooldown()); //Sivir W/Nocturne W if (spellShield.SpellType == SpellInfo.SpellTypeInfo.PassiveSpell || spellShield.SpellType == SpellInfo.SpellTypeInfo.PassiveSpellWithBuff || spellShield.SpellType == SpellInfo.SpellTypeInfo.PassiveSpellWithDuration) { Spell.Active spell = new Spell.Active(self.GetSpellSlotFromName(spellShield.SpellName)); bool casted = spell.Cast(); if (casted) { return; } } //Morgana W else if (spellShield.SpellType == SpellInfo.SpellTypeInfo.TargetedPassiveSpell) { Spell.Targeted spell = new Spell.Targeted(self.GetSpellSlotFromName(spellShield.SpellName), (uint)spellShield.Range); bool casted = spell.Cast(self); if (casted) { return; } } } #endregion #region FlashFromSpell if (highestDangerValueIncoming >= mainMenu.GetSliderValue("Spell Shield Danger Level")) { Spell.Skillshot flash = new Spell.Skillshot(self.GetSpellSlotFromName("SummonerFlash"), 425, SkillShotType.Linear, 0, 0, 0); if (flash.IsReady()) { Vector3 flashPos = GetSafePositions(self, flash.Range - 5).OrderByDescending(a => a.DistanceFromClosestEnemy()).FirstOrDefault(); bool casted = flash.Cast(flashPos); if (casted) { return; } } } #endregion } } else { safePosition = Vector3.Zero; } }
private static void CreatePolygons() { //reset polygon list to have no entities SpellDatabase.Polygons = new List <CustomPolygon>(); #region Spells foreach (SpellInfo info in SpellDatabase.activeSpells) { if (info.SpellType == SpellInfo.SpellTypeInfo.CircularSkillshot || info.SpellType == SpellInfo.SpellTypeInfo.CircularSpell || info.SpellType == SpellInfo.SpellTypeInfo.CircularSpellWithBuff || info.SpellType == SpellInfo.SpellTypeInfo.CircularSpellWithDuration || info.SpellType == SpellInfo.SpellTypeInfo.CircularSkillshotDash) { if (info.missile != null) { SpellDatabase.Polygons.Add(PolygonCreater.CreateCircularSkillshot(info, info.missile.EndPosition, info.Radius)); } else { SpellDatabase.Polygons.Add(PolygonCreater.CreateCircularSkillshot(info, info.endPosition, info.Radius)); } } else if (info.SpellType == SpellInfo.SpellTypeInfo.SelfActive || info.SpellType == SpellInfo.SpellTypeInfo.SelfActiveWithBuff || info.SpellType == SpellInfo.SpellTypeInfo.SelfActiveToggleable || info.SpellType == SpellInfo.SpellTypeInfo.SelfActiveNoDamage || info.SpellType == SpellInfo.SpellTypeInfo.SelfActiveNoDamageWithBuff) { SpellDatabase.Polygons.Add(PolygonCreater.CreateCircularSkillshot(info, info.caster.Position, info.Radius)); } else if (info.SpellType == SpellInfo.SpellTypeInfo.CircularWall) { SpellDatabase.Polygons.Add(PolygonCreater.CreateCircularWall(info, info.endPosition, info.Radius, info.SecondRadius)); } else if (info.SpellType == SpellInfo.SpellTypeInfo.LinearSpellWithBuff) { SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.caster.Position, info.caster.Position.Extend(info.caster.Position + info.caster.Direction, info.Range).To3D((int)info.caster.Position.Z), info.Width)); } else if (info.SpellType == SpellInfo.SpellTypeInfo.LinearSpellWithDuration) { SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.startPosition, info.endPosition, info.Width)); } if (info.SpellType == SpellInfo.SpellTypeInfo.LinearDash) { SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.caster.Position, info.endPosition, info.Width)); } else if (info.SpellType == SpellInfo.SpellTypeInfo.LinearSkillshot || info.SpellType == SpellInfo.SpellTypeInfo.LinearMissile || info.SpellType == SpellInfo.SpellTypeInfo.LinearSkillshotNoDamage) { if (info.missile != null) { //sivir Q and draven R return //Graves Q Does not work likes this //Gnar Q returns to where it started if ((info.MissileName.ToLower().Contains("return") && info.MissileName != "GravesQReturn" && info.MissileName != "GnarQMissileReturn") || ((info.MissileName == "DravenR" || info.MissileName == "TalonWMissileTwo" || info.MissileName == "TalonRMisTwo") && info.missile.EndPosition.Distance(info.caster.Position) <= 50)) { SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.missile.Position, info.missile.SpellCaster.Position, info.Width)); } //ahri rotating w orbs else if (info.MissileName == "AhriFoxFireMissile" || info.MissileName == "AhriFoxFireMissileTwo") { if (info.missile.Position.Distance(info.caster.Position) > 200) { SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.missile.Position, info.endPosition, info.Width)); } } else { SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.missile.Position, info.endPosition, info.Width)); } } //for on spell cast spells that dont have their missiles created yet. else if (info.MissileName == "" && info.BuffName == "") { //the start position was set to info.caster.position. I changed it to info.startPosition to fix JannaQ. This might affect other spells SpellDatabase.Polygons.Add(PolygonCreater.CreateLinearSkillshot(info, info.caster.Position, info.endPosition, info.Width)); } } else if (info.SpellType == SpellInfo.SpellTypeInfo.TargetedMissile || info.SpellType == SpellInfo.SpellTypeInfo.AutoAttack) { if (info.missile != null) { SpellDatabase.Polygons.Add(PolygonCreater.CreateTargetedSpell(info, info.missile.Position, info.target)); } else { SpellDatabase.Polygons.Add(PolygonCreater.CreateTargetedSpell(info, info.caster.Position, info.target)); } } else if (info.SpellType == SpellInfo.SpellTypeInfo.TargetedDash) { if (info.DashType == SpellInfo.Dashtype.Targeted && info.target != null) { SpellDatabase.Polygons.Add(PolygonCreater.CreateTargetedSpell(info, info.caster.Position, info.target)); } else if (info.DashType == SpellInfo.Dashtype.TargetedLinear && info.target != null) { SpellDatabase.Polygons.Add(PolygonCreater.CreateTargetedSpell(info, info.caster.Position, info.endPosition)); } } else if (info.SpellType == SpellInfo.SpellTypeInfo.ConeSpell) { SpellDatabase.Polygons.Add(PolygonCreater.CreateCone(info, info.startPosition, info.endPosition, info.ConeDegrees, info.Range)); } else if (info.SpellType == SpellInfo.SpellTypeInfo.ConeSpellWithBuff) { if (info.startingDirection == Vector3.Zero || info.SpellName == "MissFortuneBulletTime") { SpellDatabase.Polygons.Add(PolygonCreater.CreateCone(info, info.caster.Position, info.caster.Position.Extend(info.caster.Position + info.caster.Direction, info.Range).To3D((int)info.caster.Position.Z), info.ConeDegrees, info.Range)); } else { //camille w SpellDatabase.Polygons.Add(PolygonCreater.CreateCone(info, info.caster.Position, info.caster.Position - (info.startPosition - info.startingDirection), info.ConeDegrees, info.Range)); } } else if (info.SpellType == SpellInfo.SpellTypeInfo.Wall) { SpellDatabase.Polygons.Add(PolygonCreater.CreateWall(info, info.startPosition, info.endPosition, info.Width, info.Radius)); } else if (info.SpellType == SpellInfo.SpellTypeInfo.ArcSkillshot) { SpellDatabase.Polygons.Add(PolygonCreater.CreateArc(info, info.startPosition, info.endPosition, info.Width)); } } #endregion #region Particles foreach (Obj_GeneralParticleEmitter particle in ObjectManager.Get <Obj_GeneralParticleEmitter>()) { ParticleInfo info = ParticleDatabase.GetParticleInfo(particle.Name); if (info != null) { info.particle = particle; if (info.CreationTime == -1f) { info.CreationTime = Game.Time; } if (info.SpellType == ParticleInfo.SpellTypeInfo.Wall) { SpellDatabase.Polygons.Add(PolygonCreater.CreateRectangleAroundPoint(info, info.Length, info.Width, particle.Position, info.XOffset, info.YOffset)); } else if (info.SpellType == ParticleInfo.SpellTypeInfo.CircularSkillshot) { CustomPolygon poly = PolygonCreater.CreateCircularSkillshot(null, particle.Position, info.Radius); poly.partinfo = info; SpellDatabase.Polygons.Add(poly); } else if (info.SpellType == ParticleInfo.SpellTypeInfo.LinearSkillshot) { if (info.ParticleName == "Illaoi_Base_Q_IndicatorBLU.troy") { Obj_AI_Base tentacle = ObjectManager.Get <Obj_AI_Base>().Where(a => a.Name == "God" && a.Position.Distance(particle.Position) <= 10).OrderBy(a => a.Distance(particle)).FirstOrDefault(); if (tentacle != null && (tentacle.BaseSkinName == "Illaoi" || info.CanDraw())) { CustomPolygon poly = PolygonCreater.CreateLinearSkillshot(null, tentacle.Position, tentacle.Position.Extend(tentacle.Position + tentacle.Direction, info.Length).To3D((int)tentacle.Position.Z), info.Width); poly.partinfo = info; SpellDatabase.Polygons.Add(poly); } } else { SpellDatabase.Polygons.Add(PolygonCreater.CreateRectangleAroundPoint(info, info.Length, info.Width, particle.Position, info.XOffset, info.YOffset)); } } } } #endregion #region Traps foreach (Obj_AI_Minion trap in ObjectManager.Get <Obj_AI_Minion>().Where(a => a != null && (a.IsEnemy || MenuHandler.DrawMenu.GetCheckboxValue("Draw Friendly Spells/Missiles")) && !a.IsDead && TrapDatabase.AllTrapNames().Contains(a.Name))) { CustomPolygon poly = PolygonCreater.CreateCircularSkillshot(null, trap.Position, TrapDatabase.getTrap(trap.Name).Radius); poly.trap = trap; SpellDatabase.Polygons.Add(poly); } #endregion #region Singed Poisons List <ParticleInfo> replacementPoisonList = new List <ParticleInfo>(); foreach (ParticleInfo info in ParticleDatabase.SingedPoisonTrails) { if (Game.Time - (info.CreationTime + info.Delay) <= 0) { CustomPolygon poly = PolygonCreater.CreateCircularSkillshot(null, info.Position, info.Radius); poly.partinfo = info; SpellDatabase.Polygons.Add(poly); replacementPoisonList.Add(info); } } ParticleDatabase.SingedPoisonTrails = replacementPoisonList; #endregion }