public static float GetClosestDistanceApproach(Spell spell, Vector2 pos, float speed, float delay, Vector2 heroPos, float extraDist) { var walkDir = (pos - heroPos).Normalized(); switch (spell.SpellType) { case SpellType.Line when spell.Info.ProjectileSpeed != float.MaxValue: { var spellPos = spell.GetCurrentSpellPosition(true, delay); var spellEndPos = spell.GetSpellEndPosition(); var extendedPos = pos.ExtendDir(walkDir, ObjectCache.MyHeroCache.BoundingRadius + speed * delay / 1000); var cpa2 = MathUtils.GetCollisionDistanceEx(heroPos, walkDir * speed, ObjectCache.MyHeroCache.BoundingRadius, spellPos, spell.Direction * spell.Info.ProjectileSpeed, spell.Radius + extraDist, out var cHeroPos, out var cSpellPos); var cHeroPosProjection = cHeroPos.ProjectOn(heroPos, extendedPos); var cSpellPosProjection = cSpellPos.ProjectOn(spellPos, spellEndPos); if (cSpellPosProjection.IsOnSegment && cHeroPosProjection.IsOnSegment && cpa2 != float.MaxValue) { return(0); } var cpa = MathUtilsCpa.CPAPointsEx(heroPos, walkDir * speed, spellPos, spell.Direction * spell.Info.ProjectileSpeed, pos, spellEndPos, out cHeroPos, out cSpellPos); cHeroPosProjection = cHeroPos.ProjectOn(heroPos, extendedPos); cSpellPosProjection = cSpellPos.ProjectOn(spellPos, spellEndPos); var checkDist = ObjectCache.MyHeroCache.BoundingRadius + spell.Radius + extraDist; if (cSpellPosProjection.IsOnSegment && cHeroPosProjection.IsOnSegment) { return(Math.Max(0, cpa - checkDist)); } return(checkDist); //return MathUtils.ClosestTimeOfApproach(heroPos, walkDir * speed, spellPos, spell.Orientation * spell.info.projectileSpeed); } case SpellType.Line when spell.Info.ProjectileSpeed == float.MaxValue: { var spellHitTime = Math.Max(0, spell.EndTime - Environment.TickCount - delay); //extraDelay var walkRange = heroPos.Distance(pos); var predictedRange = speed * (spellHitTime / 1000); var tHeroPos = heroPos + walkDir * Math.Min(predictedRange, walkRange); //Hero predicted pos var projection = tHeroPos.ProjectOn(spell.StartPos, spell.EndPos); return(Math.Max(0, tHeroPos.Distance(projection.SegmentPoint) - (spell.Radius + ObjectCache.MyHeroCache.BoundingRadius + extraDist))); //+ dodgeBuffer } case SpellType.Circular: { var spellHitTime = Math.Max(0, spell.EndTime - Environment.TickCount - delay); //extraDelay var walkRange = heroPos.Distance(pos); var predictedRange = speed * (spellHitTime / 1000); var tHeroPos = heroPos + walkDir * Math.Min(predictedRange, walkRange); //Hero predicted pos switch (spell.Info.SpellName) { case "VeigarEventHorizon": { const int wallRadius = 65; var midRadius = spell.Radius - wallRadius; if (spellHitTime == 0) { return(0); } return(tHeroPos.Distance(spell.EndPos) >= spell.Radius ? Math.Max(0, tHeroPos.Distance(spell.EndPos) - midRadius - wallRadius) : Math.Max(0, midRadius - tHeroPos.Distance(spell.EndPos) - wallRadius)); } case "DariusCleave": { const int wallRadius = 115; var midRadius = spell.Radius - wallRadius; if (spellHitTime == 0) { return(0); } return(tHeroPos.Distance(spell.EndPos) >= spell.Radius ? Math.Max(0, tHeroPos.Distance(spell.EndPos) - midRadius - wallRadius) : Math.Max(0, midRadius - tHeroPos.Distance(spell.EndPos) - wallRadius)); } } var closestDist = Math.Max(0, tHeroPos.Distance(spell.EndPos) - (spell.Radius + extraDist)); if (spell.Info.ExtraEndTime > 0 && closestDist != 0) { var remainingTime = Math.Max(0, spell.EndTime + spell.Info.ExtraEndTime - Environment.TickCount - delay); var predictedRange2 = speed * (remainingTime / 1000); var tHeroPos2 = heroPos + walkDir * Math.Min(predictedRange2, walkRange); if (CheckMoveToDirection(tHeroPos, tHeroPos2)) { return(0); } } else { return(closestDist); } break; } case SpellType.Arc: { var spellPos = spell.GetCurrentSpellPosition(true, delay); var spellEndPos = spell.GetSpellEndPosition(); var pDir = spell.Direction.Perpendicular(); spellPos = spellPos - pDir * spell.Radius / 2; spellEndPos = spellEndPos - pDir * spell.Radius / 2; var extendedPos = pos.ExtendDir(walkDir, ObjectCache.MyHeroCache.BoundingRadius); var cpa = MathUtilsCpa.CPAPointsEx(heroPos, walkDir * speed, spellPos, spell.Direction * spell.Info.ProjectileSpeed, pos, spellEndPos, out var cHeroPos, out var cSpellPos); var cHeroPosProjection = cHeroPos.ProjectOn(heroPos, extendedPos); var cSpellPosProjection = cSpellPos.ProjectOn(spellPos, spellEndPos); var checkDist = spell.Radius + extraDist; if (cHeroPos.InSkillShot(spell, ObjectCache.MyHeroCache.BoundingRadius)) { if (cSpellPosProjection.IsOnSegment && cHeroPosProjection.IsOnSegment) { return(Math.Max(0, cpa - checkDist)); } return(checkDist); } break; } case SpellType.Cone: { var spellHitTime = Math.Max(0, spell.EndTime - Environment.TickCount - delay); //extraDelay var walkRange = heroPos.Distance(pos); var predictedRange = speed * (spellHitTime / 1000); var tHeroPos = heroPos + walkDir * Math.Min(predictedRange, walkRange); //Hero predicted pos var sides = new[] { heroPos.ProjectOn(spell.CnStart, spell.CnLeft).SegmentPoint, heroPos.ProjectOn(spell.CnLeft, spell.CnRight).SegmentPoint, heroPos.ProjectOn(spell.CnRight, spell.CnStart).SegmentPoint }; var p = sides.OrderBy(x => x.Distance(x)).First(); return(Math.Max(0, tHeroPos.Distance(p) - (spell.Radius + ObjectCache.MyHeroCache.BoundingRadius + extraDist))); } } return(1); }
private void Render_OnPresent() { foreach (var entry in SpellDetector.DrawSpells) { var spell = entry.Value; if (spell.SpellType != SpellType.Line) { continue; } var spellPos = spell.CurrentSpellPosition; Render.Circle(new Vector3(spellPos.X, spellPos.Y, MyHero.Position.Z), spell.Info.Radius, 50, Color.White); } if (TestMenu["(TestHeroPos)"].Enabled) { var path = MyHero.Path; if (path.Length > 0) { var heroPos2 = EvadeHelper.GetRealHeroPos(ObjectCache.GamePing + 50); var heroPos1 = ObjectCache.MyHeroCache.ServerPos2D; Render.Circle(new Vector3(heroPos2.X, heroPos2.Y, MyHero.ServerPosition.Z), ObjectCache.MyHeroCache.BoundingRadius, 50, Color.Red); Render.Circle(new Vector3(MyHero.ServerPosition.X, MyHero.ServerPosition.Y, MyHero.ServerPosition.Z), ObjectCache.MyHeroCache.BoundingRadius, 50, Color.White); Render.WorldToScreen(ObjectManager.GetLocalPlayer().Position, out var heroPos); Render.Text($" {(int) heroPos2.Distance(heroPos1)}", new Vector2(heroPos.X - 10, heroPos.Y), RenderTextFlags.Center, Color.Red); Render.Circle(new Vector3(_circleRenderPos.X, _circleRenderPos.Y, MyHero.ServerPosition.Z), 10, 50, Color.Red); } } if (TestMenu["(DrawHeroPos)"].Enabled) { Render.Circle(new Vector3(MyHero.ServerPosition.X, MyHero.ServerPosition.Y, MyHero.ServerPosition.Z), ObjectCache.MyHeroCache.BoundingRadius, 50, Color.White); } if (TestMenu["(TestMoveTo)"].As <MenuKeyBind>().Enabled) { TestMenu["(TestMoveTo)"].As <MenuKeyBind>().Value = false; MyHero.IssueOrder(OrderType.MoveTo, Game.CursorPos); var dir = (Game.CursorPos - MyHero.Position).Normalized(); var pos2 = Game.CursorPos.To2D() - dir.To2D() * 75; DelayAction.Add(20, () => MyHero.IssueOrder(OrderType.MoveTo, pos2.To3D())); } if (TestMenu["(TestPath)"].Enabled) { var tPath = MyHero.GetPath(Game.CursorPos); foreach (var point in tPath) { var point2D = point.To2D(); Render.Circle(new Vector3(point.X, point.Y, point.Z), ObjectCache.MyHeroCache.BoundingRadius, 50, Color.Violet); } } if (TestMenu["(TestPath)"].Enabled) { foreach (var entry in SpellDetector.Spells) { var spell = entry.Value; var to = Game.CursorPos.To2D(); var dir = (to - MyHero.Position.To2D()).Normalized(); var cpa = MathUtilsCpa.CPAPointsEx(MyHero.Position.To2D(), dir * ObjectCache.MyHeroCache.MoveSpeed, spell.EndPos, spell.Direction * spell.Info.ProjectileSpeed, to, spell.EndPos); if (cpa < ObjectCache.MyHeroCache.BoundingRadius + spell.Radius) { } } } if (TestMenu["(ShowBuffs)"].Enabled) { var target = MyHero; foreach (var hero in GameObjects.EnemyHeroes) { target = hero; } var buffs = target.Buffs; if (!target.IsTargetable) { ConsolePrinter.Print("invul" + Environment.TickCount); } var height = 20; foreach (var buff in buffs) { if (!buff.IsValid) { continue; } Render.Text(buff.Name, new Vector2(10, height), RenderTextFlags.Center, Color.White); height += 20; ConsolePrinter.Print(buff.Name); } } if (TestMenu["(TestTracker)"].Enabled) { foreach (var entry in ObjectTracker.ObjTracker) { var info = entry.Value; var endPos2 = !info.UsePosition ? info.Obj.Position : info.Position; Render.Circle(new Vector3(endPos2.X, endPos2.Y, MyHero.Position.Z), 50, 50, Color.Green); } } if (!TestMenu["(TestWall)"].Enabled) { return; } var posChecked = 0; const int maxPosToCheck = 50; const int posRadius = 50; var radiusIndex = 0; var heroPoint = ObjectCache.MyHeroCache.ServerPos2D; while (posChecked < maxPosToCheck) { radiusIndex++; var curRadius = radiusIndex * 2 * posRadius; var curCircleChecks = (int)Math.Ceiling(2 * Math.PI * curRadius / (2 * (double)posRadius)); for (var i = 1; i < curCircleChecks; i++) { posChecked++; var cRadians = 2 * Math.PI / (curCircleChecks - 1) * i; //check decimals var pos = new Vector2((float)Math.Floor(heroPoint.X + curRadius * Math.Cos(cRadians)), (float)Math.Floor(heroPoint.Y + curRadius * Math.Sin(cRadians))); if (!EvadeHelper.CheckPathCollision(MyHero, pos)) { Render.Circle(new Vector3(pos.X, pos.Y, MyHero.Position.Z), 25, 50, Color.White); } } } }
public static bool CheckMoveToDirection(Vector2 from, Vector2 movePos, float extraDelay = 0) { var dir = (movePos - from).Normalized(); foreach (var entry in SpellDetector.Spells) { var spell = entry.Value; if (!from.InSkillShot(spell, ObjectCache.MyHeroCache.BoundingRadius)) { var spellPos = spell.CurrentSpellPosition; switch (spell.SpellType) { case SpellType.Line: if (spell.LineIntersectLinearSpell(@from, movePos)) { return(true); } break; case SpellType.Circular: switch (spell.Info.SpellName) { case "VeigarEventHorizon": { var cpa2 = MathUtilsCpa.CPAPointsEx(@from, dir * ObjectCache.MyHeroCache.MoveSpeed, spell.EndPos, new Vector2(0, 0), movePos, spell.EndPos); if (@from.Distance(spell.EndPos) < spell.Radius && !(@from.Distance(spell.EndPos) < spell.Radius - 135 && movePos.Distance(spell.EndPos) < spell.Radius - 135)) { return(true); } if (@from.Distance(spell.EndPos) > spell.Radius && cpa2 < spell.Radius + 10) { return(true); } break; } case "DariusCleave": var cpa3 = MathUtilsCpa.CPAPointsEx(@from, dir * ObjectCache.MyHeroCache.MoveSpeed, spell.EndPos, new Vector2(0, 0), movePos, spell.EndPos); if (@from.Distance(spell.EndPos) < spell.Radius && !(@from.Distance(spell.EndPos) < spell.Radius - 230 && movePos.Distance(spell.EndPos) < spell.Radius - 230)) { return(true); } if (@from.Distance(spell.EndPos) > spell.Radius && cpa3 < spell.Radius + 10) { return(true); } break; default: { var cpa2 = MathUtils.GetCollisionDistanceEx(@from, dir * ObjectCache.MyHeroCache.MoveSpeed, 1, spell.EndPos, new Vector2(0, 0), spell.Radius, out var cHeroPos, out _); if (spell.Info.SpellName.Contains("_trap") && !(cpa2 < spell.Radius + 10)) { continue; } var cHeroPosProjection = cHeroPos.ProjectOn(@from, movePos); if (cHeroPosProjection.IsOnSegment && cpa2 != float.MaxValue) { return(true); } break; } } break; case SpellType.Arc: if (@from.IsLeftOfLineSegment(spell.StartPos, spell.EndPos)) { return(MathUtils.CheckLineIntersection(@from, movePos, spell.StartPos, spell.EndPos)); } var spellRange = spell.StartPos.Distance(spell.EndPos); var midPoint = spell.StartPos + spell.Direction * (spellRange / 2); var cpa = MathUtilsCpa.CPAPointsEx(@from, dir * ObjectCache.MyHeroCache.MoveSpeed, midPoint, new Vector2(0, 0), movePos, midPoint); if (cpa < spell.Radius + 10) { return(true); } break; case SpellType.Cone: if (LineIntersectLinearSegment(spell.CnStart, spell.CnLeft, @from, movePos) || LineIntersectLinearSegment(spell.CnLeft, spell.CnRight, @from, movePos) || LineIntersectLinearSegment(spell.CnRight, spell.CnStart, @from, movePos)) { return(true); } break; } } else if (from.InSkillShot(spell, ObjectCache.MyHeroCache.BoundingRadius)) { if (movePos.InSkillShot(spell, ObjectCache.MyHeroCache.BoundingRadius)) { return(true); } } } return(false); }