public static Vector2 GetPrediction(Obj_AI_Hero t, Spell s, List <Vector2> path, float avgt, float movt, float filterHPPercent, byte minHit, out HitChance hc, Vector3 rangeCheckFrom) { Vector2 castPos = Prediction.GetPrediction(t, s, path, avgt, movt, out hc, rangeCheckFrom); var posibleTargets = new List <PossibleTarget> { new PossibleTarget { Position = t.ServerPosition.To2D(), Unit = t } }; if (hc >= HitChance.Low) { //Add the posible targets in range: posibleTargets.AddRange(GetPossibleTargets(t, s, rangeCheckFrom, filterHPPercent)); if (posibleTargets.Count < minHit) { hc = HitChance.Impossible; return(castPos); } } if (posibleTargets.Count > 1) { var candidates = new List <Vector2>(); foreach (var target in posibleTargets) { target.Position = target.Position - rangeCheckFrom.To2D(); } for (var i = 0; i < posibleTargets.Count; i++) { for (var j = 0; j < posibleTargets.Count; j++) { if (i != j) { var p = (posibleTargets[i].Position + posibleTargets[j].Position) * 0.5f; if (!candidates.Contains(p)) { candidates.Add(p); } } } } var bestCandidateHits = -1; var bestCandidate = new Vector2(); var positionsList = posibleTargets.Select(p => p.Position).ToList(); foreach (var candidate in candidates) { var hits = GetHits(candidate, s.Range, s.Width, positionsList); if (hits > bestCandidateHits) { bestCandidate = candidate; bestCandidateHits = hits; } } if (bestCandidateHits < minHit) { hc = HitChance.Impossible; } if (bestCandidateHits > 1 && rangeCheckFrom.To2D().Distance(bestCandidate, true) > 50 * 50) { return(bestCandidate); } } hc = HitChance.Impossible; return(castPos); }
public static Vector2 GetPrediction(Obj_AI_Hero t, Spell s, List <Vector2> path, float avgt, float movt, float filterHPPercent, byte minHit, out HitChance hc, Vector3 rangeCheckFrom) { Vector2 castPos = Prediction.GetPrediction(t, s, path, avgt, movt, out hc, rangeCheckFrom); var posibleTargets = new List <PossibleTarget> { new PossibleTarget { Position = t.ServerPosition.To2D(), Unit = t } }; if (hc >= HitChance.Low) { //Add the posible targets in range: posibleTargets.AddRange(GetPossibleTargets(t, s, rangeCheckFrom, filterHPPercent)); if (posibleTargets.Count < minHit) { hc = HitChance.Impossible; return(castPos); } } if (posibleTargets.Count > 1) { var candidates = new List <Vector2>(); foreach (var target in posibleTargets) { Vector2[] v; if (GetCandidates(rangeCheckFrom.To2D(), target.Position, s.Width, s.Range, out v)) { candidates.AddRange(v); } } var bestCandidateHits = -1; var bestCandidate = new Vector2(); var bestCandidateHitPoints = new List <Vector2>(); var positionsList = posibleTargets.Select(p => p.Position).ToList(); foreach (var candidate in candidates) { if (GetHits(rangeCheckFrom.To2D(), candidate, s.Width, new List <Vector2> { posibleTargets[0].Position }).Count() == 1) { var hits = GetHits(rangeCheckFrom.To2D(), candidate, s.Width, positionsList).ToList(); var hitsCount = hits.Count; if (hitsCount >= bestCandidateHits) { bestCandidateHits = hitsCount; bestCandidate = candidate; bestCandidateHitPoints = hits.ToList(); } } } if (bestCandidateHits > 1) { float maxDistance = -1; Vector2 p1 = new Vector2(), p2 = new Vector2(); //Center the position for (var i = 0; i < bestCandidateHitPoints.Count; i++) { for (var j = 0; j < bestCandidateHitPoints.Count; j++) { var startP = rangeCheckFrom.To2D(); var endP = bestCandidate; var proj1 = positionsList[i].ProjectOn(startP, endP); var proj2 = positionsList[j].ProjectOn(startP, endP); var dist = Vector2.DistanceSquared(bestCandidateHitPoints[i], proj1.LinePoint) + Vector2.DistanceSquared(bestCandidateHitPoints[j], proj2.LinePoint); if (dist >= maxDistance && (proj1.LinePoint - positionsList[i]).AngleBetween( proj2.LinePoint - positionsList[j]) > 90) { maxDistance = dist; p1 = positionsList[i]; p2 = positionsList[j]; } } } if (bestCandidateHits < minHit) { hc = HitChance.Impossible; } return((p1 + p2) * 0.5f); } } hc = HitChance.Impossible; return(castPos); }