/// <summary> /// Gets Aoe Prediction result /// </summary> /// <param name="width">Spell width</param> /// <param name="delay">Spell delay</param> /// <param name="missileSpeed">Spell missile speed</param> /// <param name="range">Spell range</param> /// <param name="from">Spell casted position</param> /// <param name="rangeCheckFrom"></param> /// <returns>Prediction result as <see cref="SpellAoeResult"/></returns> public static SpellAoeResult GetLineAoePrediction(float width, float delay, float missileSpeed, float range, Vector2 from, Vector2 rangeCheckFrom) { var result = new SpellAoeResult(); var enemies = GameObjects.EnemyHeroes.Where(p => p.IsValidTarget() && PredictionExtensions.GetFastUnitPosition(p, delay, 0, from).Distance(rangeCheckFrom) < range); foreach (var enemy in enemies) { var prediction = GetLinePrediction(enemy, width, delay, missileSpeed, range, false, enemy.GetWaypoints(), enemy.AvgMovChangeTime(), enemy.LastMovChangeTime(), enemy.AvgPathLenght(), enemy.LastAngleDiff(), from, rangeCheckFrom); if (prediction.HitChance > HitChance.Medium) { var to = from + (prediction.CastPosition - from).Normalized() * range; var colResult = Collision.GetCollisions(from, to, range, width, delay, missileSpeed); if (colResult.Objects.HasFlag(CollisionFlags.EnemyChampions)) { var collisionCount = colResult.Units.Count(p => p.IsEnemy && p.Type == GameObjectType.AIHeroClient && p.IsValid); if (collisionCount > result.HitCount) { return(new SpellAoeResult { CastPosition = prediction.CastPosition, HitCount = collisionCount, CollisionResult = colResult }); } } } } return(result); }
/// <summary> /// Gets Aoe Prediction result /// </summary> /// <param name="width">Spell width</param> /// <param name="delay">Spell delay</param> /// <param name="missileSpeed">Spell missile speed</param> /// <param name="range">Spell range</param> /// <param name="from">Spell casted position</param> /// <param name="rangeCheckFrom"></param> /// <returns>Prediction result as <see cref="SpellAoeResult"/></returns> public static SpellAoeResult GetAoePrediction(float width, float delay, float missileSpeed, float range, Vector2 from, Vector2 rangeCheckFrom) { var result = new SpellAoeResult(); var enemies = GameObjects.EnemyHeroes.Where(p => p.IsValidTarget() && PredictionExtensions.GetFastUnitPosition(p, delay, 0, from).Distance(rangeCheckFrom) < range); foreach (var enemy in enemies) { var prediction = GetPrediction(enemy, width, delay, missileSpeed, range, false, enemy.GetWaypoints(), enemy.AvgMovChangeTime(), enemy.LastMovChangeTime(), enemy.AvgPathLenght(), enemy.LastAngleDiff(), from, rangeCheckFrom); if (prediction.HitChance > HitChance.Medium) { var to = from + (prediction.CastPosition - from).Normalized() * range; var spellHitBox = ClipperWrapper.DefineSector(from, to, width, range); var collidedEnemies = GameObjects.EnemyHeroes.AsParallel().Where(p => !spellHitBox.IsOutside(PredictionExtensions.GetFastUnitPosition(p, delay, missileSpeed, from))).ToList(); var collisionCount = collidedEnemies.Count; if (collisionCount > result.HitCount) { var collisionResult = new CollisionResult(collidedEnemies.ToList <AIBaseClient>(), CollisionFlags.EnemyChampions); return(new SpellAoeResult { CastPosition = prediction.CastPosition, HitCount = collisionCount, CollisionResult = collisionResult }); } } } return(result); }
/// <summary> /// Gets Aoe Prediction result /// </summary> /// <param name="width">Spell width</param> /// <param name="delay">Spell delay</param> /// <param name="missileSpeed">Spell missile speed</param> /// <param name="range">Spell range</param> /// <param name="from">Spell casted position</param> /// <param name="rangeCheckFrom"></param> /// <returns>Prediction result as <see cref="PredictionExtensions.AoeResult"/></returns> public static SpellAoeResult GetAoePrediction(float width, float delay, float missileSpeed, float range, Vector2 from, Vector2 rangeCheckFrom) { var result = new SpellAoeResult(); var enemies = GameObjects.EnemyHeroes.Where(p => p.IsValidTarget() && PredictionExtensions.GetFastUnitPosition(p, delay, 0, from).Distance(rangeCheckFrom) < range); foreach (var enemy in enemies) { var prediction = GetPrediction(enemy, width, delay, missileSpeed, range, false, enemy.GetWaypoints(), enemy.AvgMovChangeTime(), enemy.LastMovChangeTime(), enemy.AvgPathLenght(), enemy.LastAngleDiff(), from, rangeCheckFrom); if (prediction.HitChance > HitChance.Medium) { var multp = (result.CastPosition.Distance(from) / 875.0f); var spellHitBox = new Geometry.Polygon( ClipperWrapper.DefineArc(from - new Vector2(875 / 2f, 20), result.CastPosition, (float)Math.PI * multp, 410, 200 * multp), ClipperWrapper.DefineArc(from - new Vector2(875 / 2f, 20), result.CastPosition, (float)Math.PI * multp, 410, 320 * multp)); var collidedEnemies = GameObjects.EnemyHeroes.AsParallel().Where(p => ClipperWrapper.IsIntersects(ClipperWrapper.MakePaths(ClipperWrapper.DefineCircle(PredictionExtensions.GetFastUnitPosition(p, delay, missileSpeed), p.BoundingRadius)), ClipperWrapper.MakePaths(spellHitBox))).ToList(); var collisionCount = collidedEnemies.Count; if (collisionCount > result.HitCount) { var collisionResult = new CollisionResult(collidedEnemies.ToList <AIBaseClient>(), CollisionFlags.EnemyChampions); return(new SpellAoeResult { CastPosition = prediction.CastPosition, HitCount = collisionCount, CollisionResult = collisionResult }); } } } return(result); }
/// <summary> /// Gets Aoe Prediction result /// </summary> /// <param name="width">Spell width</param> /// <param name="delay">Spell delay</param> /// <param name="missileSpeed">Spell missile speed</param> /// <param name="range">Spell range</param> /// <param name="from">Spell casted position</param> /// <param name="rangeCheckFrom"></param> /// <returns>Prediction result as <see cref="SpellAoeResult"/></returns> public static SpellAoeResult GetAoePrediction(float width, float delay, float missileSpeed, float range, Vector2 from, Vector2 rangeCheckFrom) { var result = new SpellAoeResult(); var enemies = GameObjects.EnemyHeroes.Where(p => p.IsValidTarget() && PredictionExtensions.GetFastUnitPosition(p, delay, 0, from).Distance(rangeCheckFrom) < range).ToList(); if (enemies.Count > 0) { var posSummary = Vector2.Zero; // ReSharper disable once AccessToModifiedClosure enemies.AsParallel().ForAll(p => posSummary += PredictionExtensions.GetFastUnitPosition(p, delay, missileSpeed, from)); var center = posSummary / enemies.Count; float flyTime = 0; if (missileSpeed != 0) { flyTime = from.Distance(center) / missileSpeed; } posSummary = Vector2.Zero; var predictionResults = new List <Tuple <PredictionResult, float> >(); foreach (var enemy in enemies) { var prediction = GetPrediction(enemy, width, delay + flyTime, 0, range, false, enemy.GetWaypoints(), enemy.AvgMovChangeTime(), enemy.LastMovChangeTime(), enemy.AvgPathLenght(), enemy.LastAngleDiff(), from, rangeCheckFrom); if (prediction.HitChance > HitChance.Medium) { posSummary += prediction.UnitPosition; predictionResults.Add(new Tuple <PredictionResult, float>(prediction, enemy.BoundingRadius)); } } if (predictionResults.Count > 0) { center = posSummary / predictionResults.Count; result.CastPosition = center; foreach (var unused in predictionResults.Where(res => center.CircleCircleIntersection(res.Item1.UnitPosition, width, res.Item2).Length > 1)) { result.HitCount++; } } predictionResults.Clear(); GC.Collect(GC.GetGeneration(predictionResults)); } return(result); }