private void GetAreaOfEffectPrediction(PredictionInput9 input, PredictionOutput9 output) { var targets = new List <PredictionOutput9>(); foreach (var target in input.AreaOfEffectTargets.Where(x => !x.Equals(output.Target))) { var aoeTargetInput = new PredictionInput9 { Target = target, Caster = input.Caster, Delay = input.Delay, Speed = input.Speed, CastRange = input.CastRange, Radius = input.Radius, RequiresToTurn = input.RequiresToTurn }; var aoeTargetOutput = this.GetSimplePrediction(aoeTargetInput); var range = input.SkillShotType == SkillShotType.Line ? input.Range + input.CastRange : input.Range; if (input.Caster.Distance(aoeTargetOutput.CastPosition) < range) { targets.Add(aoeTargetOutput); } } switch (input.SkillShotType) { case SkillShotType.RangedAreaOfEffect: { targets.Insert(0, output); output.CastPosition = input.Target.Position; output.AoeTargetsHit = targets.Where(x => output.CastPosition.IsInRange(x.TargetPosition, input.Radius)).ToList(); if (!output.AoeTargetsHit.Contains(output)) { output.AoeTargetsHit.Add(output); } break; } case SkillShotType.AreaOfEffect: { targets.Insert(0, output); output.CastPosition = input.CastRange > 0 ? input.Caster.InFront(input.CastRange) : input.Caster.Position; output.AoeTargetsHit = targets.Where(x => output.CastPosition.IsInRange(x.TargetPosition, input.Radius)).ToList(); break; } case SkillShotType.Circle: { targets.Insert(0, output); if (targets.Count == 1) { output.AoeTargetsHit.Add(output); } else { while (targets.Count > 1) { var mecResult = MEC.GetMec(targets.Select(x => x.TargetPosition.ToVector2()).ToList()); if (mecResult.Radius > 0 && mecResult.Radius < input.Radius && input.Caster.Distance(mecResult.Center.ToVector3()) < input.Range) { output.CastPosition = new Vector3( targets.Count <= 2 ? (targets[0].TargetPosition.ToVector2() + targets[1].TargetPosition.ToVector2()) / 2 : mecResult.Center, output.CastPosition.Z); output.AoeTargetsHit = targets.Where(x => output.CastPosition.IsInRange(x.TargetPosition, input.Radius)) .ToList(); break; } var itemToRemove = targets.MaxOrDefault(x => targets[0].TargetPosition.DistanceSquared(x.TargetPosition)); targets.Remove(itemToRemove); output.AoeTargetsHit.Add(output); } } break; } case SkillShotType.Cone: { targets.Insert(0, output); if (targets.Count > 1) { // yolo var polygons = new Dictionary <Polygon.Trapezoid, List <PredictionOutput9> >(); if (input.UseBlink) { var targetPosition = output.TargetPosition; var otherTargets = targets.Skip(1).ToList(); foreach (var predictionOutput9 in otherTargets) { var aoeTargetPosition = predictionOutput9.TargetPosition; var averagePosition = (targetPosition + aoeTargetPosition) / 2; var start = targetPosition.Extend2D(aoeTargetPosition, -100); var end = start.Extend2D(aoeTargetPosition, input.Range); var rec = new Polygon.Trapezoid(start, end, input.Radius, input.EndRadius); foreach (var output9 in otherTargets) { if (output9.Target == predictionOutput9.Target) { continue; } var averagePosition2 = (averagePosition + output9.TargetPosition) / 2; var start2 = targetPosition.Extend2D(averagePosition2, -100); var end2 = start2.Extend2D(averagePosition2, input.Range); var rec2 = new Polygon.Trapezoid(start2, end2, input.Radius + 50, input.EndRadius + 50); if (!rec2.IsInside(aoeTargetPosition) || !rec2.IsInside(output9.TargetPosition)) { continue; } rec = rec2; } polygons[rec] = targets.Where(x => rec.IsInside(x.TargetPosition)).ToList(); } } else { var startPosition = input.Caster.Position; foreach (var predictionOutput in targets) { var endPosition = startPosition.Extend2D(predictionOutput.TargetPosition, input.Range); var rec = new Polygon.Trapezoid(startPosition, endPosition, input.Radius * 1.4f, input.EndRadius * 1.8f); if (rec.IsOutside(output.TargetPosition.To2D())) { continue; } polygons[rec] = targets.Where(x => rec.IsInside(x.TargetPosition)).ToList(); } } var polygon = polygons.MaxOrDefault(x => x.Value.Count); if (polygon.Key != null) { var positions = polygon.Value.ToList(); var center = positions.Aggregate(new Vector3(), (sum, pos) => sum + pos.TargetPosition) / positions.Count; if (positions.Count == 0) { output.HitChance = HitChance.Impossible; return; } var max = positions.Max( x => input.UseBlink ? output.TargetPosition.Distance(x.TargetPosition) : input.Caster.Distance(x.TargetPosition)); var range = Math.Min(input.UseBlink ? input.Range : input.CastRange, max); output.CastPosition = input.UseBlink ? output.TargetPosition.Extend2D(center, range) : input.Caster.Position.Extend2D(center, range); output.AoeTargetsHit = polygon.Value; } } else { output.AoeTargetsHit.Add(output); if (input.UseBlink) { input.AreaOfEffect = false; } } if (input.UseBlink) { output.BlinkLinePosition = input.Caster.Distance(output.TargetPosition) > input.CastRange ? input.Caster.Position.Extend2D(output.TargetPosition, input.CastRange) : output.TargetPosition.Extend2D(output.CastPosition, -100); if (input.Caster.Distance(output.BlinkLinePosition) > input.CastRange) { output.HitChance = HitChance.Impossible; } } break; } case SkillShotType.Line: { targets.Insert(0, output); if (targets.Count > 1) { // yolo var polygons = new Dictionary <Polygon.Rectangle, List <PredictionOutput9> >(); if (input.UseBlink) { var targetPosition = output.TargetPosition; var otherTargets = targets.Skip(1).ToList(); foreach (var predictionOutput9 in otherTargets) { var aoeTargetPosition = predictionOutput9.TargetPosition; var averagePosition = (targetPosition + aoeTargetPosition) / 2; var start = targetPosition.Extend2D(aoeTargetPosition, -100); var end = start.Extend2D(aoeTargetPosition, input.Range); var rec = new Polygon.Rectangle(start, end, input.Radius); foreach (var output9 in otherTargets) { if (output9.Target == predictionOutput9.Target) { continue; } var averagePosition2 = (averagePosition + output9.TargetPosition) / 2; var start2 = targetPosition.Extend2D(averagePosition2, -100); var end2 = start2.Extend2D(averagePosition2, input.Range); var rec2 = new Polygon.Rectangle(start2, end2, input.Radius + 50); if (!rec2.IsInside(aoeTargetPosition) || !rec2.IsInside(output9.TargetPosition)) { continue; } rec = rec2; } polygons[rec] = targets.Where(x => rec.IsInside(x.TargetPosition)).ToList(); } } else { var startPosition = input.Caster.Position; foreach (var predictionOutput in targets) { var endPosition = startPosition.Extend2D(predictionOutput.TargetPosition, input.Range); var rec = new Polygon.Rectangle(startPosition, endPosition, input.Radius * 1.3f); if (rec.IsOutside(output.TargetPosition.To2D())) { continue; } polygons[rec] = targets.Where(x => rec.IsInside(x.TargetPosition)).ToList(); } } var polygon = polygons.MaxOrDefault(x => x.Value.Count); if (polygon.Key != null) { var positions = polygon.Value.ToList(); var center = positions.Aggregate(new Vector3(), (sum, pos) => sum + pos.TargetPosition) / positions.Count; if (positions.Count == 0) { output.HitChance = HitChance.Impossible; return; } var max = positions.Max( x => input.UseBlink ? output.TargetPosition.Distance(x.TargetPosition) : input.Caster.Distance(x.TargetPosition)); var range = Math.Min(input.UseBlink ? input.Range : input.CastRange, max); output.CastPosition = input.UseBlink ? output.TargetPosition.Extend2D(center, range) : input.Caster.Position.Extend2D(center, range); output.AoeTargetsHit = polygon.Value; } } else { output.AoeTargetsHit.Add(output); if (input.UseBlink) { input.AreaOfEffect = false; } } if (input.UseBlink) { output.BlinkLinePosition = input.Caster.Distance(output.TargetPosition) > input.CastRange ? input.Caster.Position.Extend2D(output.TargetPosition, input.CastRange) : output.TargetPosition.Extend2D(output.CastPosition, -100); if (input.Caster.Distance(output.BlinkLinePosition) > input.CastRange) { output.HitChance = HitChance.Impossible; } } break; } } }
// Token: 0x0600004A RID: 74 RVA: 0x0000FBAC File Offset: 0x0000DDAC private void GetAreaOfEffectPrediction(PredictionInput9 input, PredictionOutput9 output) { List <PredictionOutput9> targets = new List <PredictionOutput9>(); IEnumerable <Unit9> areaOfEffectTargets = input.AreaOfEffectTargets; Func <Unit9, bool> < > 9__2; Func <Unit9, bool> predicate; if ((predicate = < > 9__2) == null) { predicate = (< > 9__2 = ((Unit9 x) => !x.Equals(output.Target))); } foreach (Unit9 target in areaOfEffectTargets.Where(predicate)) { PredictionInput9 input2 = new PredictionInput9 { Target = target, Caster = input.Caster, Delay = input.Delay, Speed = input.Speed, CastRange = input.CastRange, Radius = input.Radius, RequiresToTurn = input.RequiresToTurn }; PredictionOutput9 simplePrediction = this.GetSimplePrediction(input2); float num = (input.SkillShotType == SkillShotType.Line) ? (input.Range + input.CastRange) : input.Range; if (input.Caster.Distance(simplePrediction.CastPosition) < num) { targets.Add(simplePrediction); } } switch (input.SkillShotType) { case SkillShotType.AreaOfEffect: targets.Insert(0, output); output.CastPosition = ((input.CastRange > 0f) ? input.Caster.InFront(input.CastRange, 0f, true) : input.Caster.Position); output.AoeTargetsHit = (from x in targets where output.CastPosition.IsInRange(x.TargetPosition, input.Radius) select x).ToList <PredictionOutput9>(); return; case SkillShotType.RangedAreaOfEffect: targets.Insert(0, output); output.CastPosition = input.Target.Position; output.AoeTargetsHit = (from x in targets where output.CastPosition.IsInRange(x.TargetPosition, input.Radius) select x).ToList <PredictionOutput9>(); if (!output.AoeTargetsHit.Contains(output)) { output.AoeTargetsHit.Add(output); return; } break; case SkillShotType.Line: targets.Insert(0, output); if (targets.Count > 1) { Dictionary <Polygon.Rectangle, List <PredictionOutput9> > dictionary = new Dictionary <Polygon.Rectangle, List <PredictionOutput9> >(); if (input.UseBlink) { Vector3 targetPosition = output.TargetPosition; List <PredictionOutput9> list = targets.Skip(1).ToList <PredictionOutput9>(); using (List <PredictionOutput9> .Enumerator enumerator2 = list.GetEnumerator()) { while (enumerator2.MoveNext()) { PredictionOutput9 predictionOutput = enumerator2.Current; Vector3 targetPosition2 = predictionOutput.TargetPosition; Vector3 vector = (targetPosition + targetPosition2) / 2f; Vector3 vector2 = targetPosition.Extend2D(targetPosition2, -100f); Vector3 end = vector2.Extend2D(targetPosition2, input.Range); Polygon.Rectangle rec = new Polygon.Rectangle(vector2, end, input.Radius); foreach (PredictionOutput9 predictionOutput2 in list) { if (!(predictionOutput2.Target == predictionOutput.Target)) { Vector3 to = (vector + predictionOutput2.TargetPosition) / 2f; Vector3 vector3 = targetPosition.Extend2D(to, -100f); Vector3 end2 = vector3.Extend2D(to, input.Range); Polygon.Rectangle rectangle = new Polygon.Rectangle(vector3, end2, input.Radius + 50f); if (rectangle.IsInside(targetPosition2) && rectangle.IsInside(predictionOutput2.TargetPosition)) { rec = rectangle; } } } dictionary[rec] = (from x in targets where rec.IsInside(x.TargetPosition) select x).ToList <PredictionOutput9>(); } goto IL_C36; } } Vector3 position = input.Caster.Position; foreach (PredictionOutput9 predictionOutput3 in targets) { Vector3 end3 = position.Extend2D(predictionOutput3.TargetPosition, input.Range); Polygon.Rectangle rec = new Polygon.Rectangle(position, end3, input.Radius * 1.3f); if (!rec.IsOutside(output.TargetPosition.To2D())) { dictionary[rec] = (from x in targets where rec.IsInside(x.TargetPosition) select x).ToList <PredictionOutput9>(); } } IL_C36: KeyValuePair <Polygon.Rectangle, List <PredictionOutput9> > keyValuePair = dictionary.MaxOrDefault((KeyValuePair <Polygon.Rectangle, List <PredictionOutput9> > x) => x.Value.Count); if (keyValuePair.Key != null) { List <PredictionOutput9> list2 = keyValuePair.Value.ToList <PredictionOutput9>(); Vector3 to2 = list2.Aggregate(default(Vector3), (Vector3 sum, PredictionOutput9 pos) => sum + pos.TargetPosition) / (float)list2.Count; if (list2.Count == 0) { output.HitChance = HitChance.Impossible; return; } float val = list2.Max(delegate(PredictionOutput9 x) { if (!input.UseBlink) { return(input.Caster.Distance(x.TargetPosition)); } return(output.TargetPosition.Distance(x.TargetPosition)); }); float distance = Math.Min(input.UseBlink ? input.Range : input.CastRange, val); output.CastPosition = (input.UseBlink ? output.TargetPosition.Extend2D(to2, distance) : input.Caster.Position.Extend2D(to2, distance)); output.AoeTargetsHit = keyValuePair.Value; } } else { output.AoeTargetsHit.Add(output); if (input.UseBlink) { input.AreaOfEffect = false; } } if (input.UseBlink) { output.BlinkLinePosition = ((input.Caster.Distance(output.TargetPosition) > input.CastRange) ? input.Caster.Position.Extend2D(output.TargetPosition, input.CastRange) : output.TargetPosition.Extend2D(output.CastPosition, -100f)); if (input.Caster.Distance(output.BlinkLinePosition) > input.CastRange) { output.HitChance = HitChance.Impossible; } } break; case SkillShotType.Circle: { targets.Insert(0, output); if (targets.Count == 1) { output.AoeTargetsHit.Add(output); return; } Func <PredictionOutput9, bool> < > 9__4; Func <PredictionOutput9, float> < > 9__5; while (targets.Count > 1) { MEC.MecCircle mec = MEC.GetMec((from x in targets select x.TargetPosition.ToVector2()).ToList <Vector2>()); if (mec.Radius > 0f && mec.Radius < input.Radius && input.Caster.Distance(mec.Center.ToVector3(0f)) < input.Range) { output.CastPosition = new Vector3((targets.Count <= 2) ? ((targets[0].TargetPosition.ToVector2() + targets[1].TargetPosition.ToVector2()) / 2f) : mec.Center, output.CastPosition.Z); PredictionOutput9 output2 = output; IEnumerable <PredictionOutput9> targets3 = targets; Func <PredictionOutput9, bool> predicate2; if ((predicate2 = < > 9__4) == null) { predicate2 = (< > 9__4 = ((PredictionOutput9 x) => output.CastPosition.IsInRange(x.TargetPosition, input.Radius))); } output2.AoeTargetsHit = targets3.Where(predicate2).ToList <PredictionOutput9>(); return; } IEnumerable <PredictionOutput9> targets2 = targets; Func <PredictionOutput9, float> comparer; if ((comparer = < > 9__5) == null) { comparer = (< > 9__5 = ((PredictionOutput9 x) => targets[0].TargetPosition.DistanceSquared(x.TargetPosition))); } PredictionOutput9 item = targets2.MaxOrDefault(comparer); targets.Remove(item); output.AoeTargetsHit.Add(output); } return; } case SkillShotType.Cone: targets.Insert(0, output); if (targets.Count > 1) { Dictionary <Polygon.Trapezoid, List <PredictionOutput9> > dictionary2 = new Dictionary <Polygon.Trapezoid, List <PredictionOutput9> >(); if (input.UseBlink) { Vector3 targetPosition3 = output.TargetPosition; List <PredictionOutput9> list3 = targets.Skip(1).ToList <PredictionOutput9>(); using (List <PredictionOutput9> .Enumerator enumerator2 = list3.GetEnumerator()) { while (enumerator2.MoveNext()) { PredictionOutput9 predictionOutput4 = enumerator2.Current; Vector3 targetPosition4 = predictionOutput4.TargetPosition; Vector3 vector4 = (targetPosition3 + targetPosition4) / 2f; Vector3 vector5 = targetPosition3.Extend2D(targetPosition4, -100f); Vector3 end4 = vector5.Extend2D(targetPosition4, input.Range); Polygon.Trapezoid rec = new Polygon.Trapezoid(vector5, end4, input.Radius, input.EndRadius); foreach (PredictionOutput9 predictionOutput5 in list3) { if (!(predictionOutput5.Target == predictionOutput4.Target)) { Vector3 to3 = (vector4 + predictionOutput5.TargetPosition) / 2f; Vector3 vector6 = targetPosition3.Extend2D(to3, -100f); Vector3 end5 = vector6.Extend2D(to3, input.Range); Polygon.Trapezoid trapezoid = new Polygon.Trapezoid(vector6, end5, input.Radius + 50f, input.EndRadius + 50f); if (trapezoid.IsInside(targetPosition4) && trapezoid.IsInside(predictionOutput5.TargetPosition)) { rec = trapezoid; } } } dictionary2[rec] = (from x in targets where rec.IsInside(x.TargetPosition) select x).ToList <PredictionOutput9>(); } goto IL_751; } } Vector3 position2 = input.Caster.Position; foreach (PredictionOutput9 predictionOutput6 in targets) { Vector3 end6 = position2.Extend2D(predictionOutput6.TargetPosition, input.Range); Polygon.Trapezoid rec = new Polygon.Trapezoid(position2, end6, input.Radius * 1.4f, input.EndRadius * 1.8f); if (!rec.IsOutside(output.TargetPosition.To2D())) { dictionary2[rec] = (from x in targets where rec.IsInside(x.TargetPosition) select x).ToList <PredictionOutput9>(); } } IL_751: KeyValuePair <Polygon.Trapezoid, List <PredictionOutput9> > keyValuePair2 = dictionary2.MaxOrDefault((KeyValuePair <Polygon.Trapezoid, List <PredictionOutput9> > x) => x.Value.Count); if (keyValuePair2.Key != null) { List <PredictionOutput9> list4 = keyValuePair2.Value.ToList <PredictionOutput9>(); Vector3 to4 = list4.Aggregate(default(Vector3), (Vector3 sum, PredictionOutput9 pos) => sum + pos.TargetPosition) / (float)list4.Count; if (list4.Count == 0) { output.HitChance = HitChance.Impossible; return; } float val2 = list4.Max(delegate(PredictionOutput9 x) { if (!input.UseBlink) { return(input.Caster.Distance(x.TargetPosition)); } return(output.TargetPosition.Distance(x.TargetPosition)); }); float distance2 = Math.Min(input.UseBlink ? input.Range : input.CastRange, val2); output.CastPosition = (input.UseBlink ? output.TargetPosition.Extend2D(to4, distance2) : input.Caster.Position.Extend2D(to4, distance2)); output.AoeTargetsHit = keyValuePair2.Value; } } else { output.AoeTargetsHit.Add(output); if (input.UseBlink) { input.AreaOfEffect = false; } } if (input.UseBlink) { output.BlinkLinePosition = ((input.Caster.Distance(output.TargetPosition) > input.CastRange) ? input.Caster.Position.Extend2D(output.TargetPosition, input.CastRange) : output.TargetPosition.Extend2D(output.CastPosition, -100f)); if (input.Caster.Distance(output.BlinkLinePosition) > input.CastRange) { output.HitChance = HitChance.Impossible; return; } } break; default: return; } }