public override int GetAvailableTime(Vector2 pos) { if (Missile == null) { return(Math.Max(0, OwnSpellData.Delay - (Environment.TickCount - TimeDetected))); } var proj = pos.ProjectOn(RealCurrentPosition.To2D(), RealEndPosition.To2D()); if (!proj.IsOnSegment) { return(short.MaxValue); } float skillDist = proj.SegmentPoint.Distance(RealCurrentPosition) - OwnSpellData.Radius; return(Math.Max(0, (int)(skillDist / OwnSpellData.MissileSpeed * 1000))); }
public override bool IsSafePath(Vector2[] path, int timeOffset = 0, int speed = -1, int delay = 0) { timeOffset += Game.Ping; speed = speed == -1 ? (int)Player.Instance.MoveSpeed : speed; if (path.Length <= 1) //lastissue = playerpos { //timeNeeded = -11; if (!Player.Instance.IsRecalling()) { return(IsSafe()); } if (IsSafe()) { return(true); } float timeLeft = (Player.Instance.GetBuff("recall").EndTime - Game.Time) * 1000; return(GetAvailableTime(Player.Instance.Position.To2D()) - timeOffset > timeLeft); } //Skillshot with missile. if (!string.IsNullOrEmpty(OwnSpellData.ObjectCreationName) && !OwnSpellData.NoMissile) { float r = Missile == null ? TimeDetected + OwnSpellData.Delay - Environment.TickCount : 0; r -= timeOffset + delay; Vector3 pathDir = path[1].To3D() - path[0].To3D(); Vector3 skillDir = RealEndPosition - RealCurrentPosition; float a = path[0].X; float w = path[0].Y; float m = path[0].To3D().Z; float v = RealCurrentPosition.X; float k = RealCurrentPosition.Y; float o = RealCurrentPosition.Z; float b = pathDir.X; float j = pathDir.Y; float n = pathDir.Z; float f = skillDir.X; float l = skillDir.Y; float p = skillDir.Z; float c = speed; float d = pathDir.Length(); float g = OwnSpellData.MissileSpeed; float h = skillDir.Length(); /*nullstelle d/dt - min distance*/ double t = ((1000 * Math.Pow(d, 2) * g * h * l - 1000 * c * d * Math.Pow(h, 2) * j) * w + (1000 * b * c * d * Math.Pow(h, 2) - 1000 * Math.Pow(d, 2) * f * g * h) * v + (c * d * g * h * n * p - Math.Pow(c, 2) * Math.Pow(h, 2) * Math.Pow(n, 2) + c * d * g * h * j * l - Math.Pow(c, 2) * Math.Pow(h, 2) * Math.Pow(j, 2) - Math.Pow(b, 2) * Math.Pow(c, 2) * Math.Pow(h, 2) + b * c * d * f * g * h) * r + (1000 * Math.Pow(d, 2) * g * h * m - 1000 * Math.Pow(d, 2) * g * h * o) * p + 1000 * c * d * Math.Pow(h, 2) * n * o - 1000 * c * d * Math.Pow(h, 2) * m * n - 1000 * Math.Pow(d, 2) * g * h * k * l + 1000 * c * d * Math.Pow(h, 2) * j * k - 1000 * a * b * c * d * Math.Pow(h, 2) + 1000 * a * Math.Pow(d, 2) * f * g * h) / (1000 * Math.Pow(d, 2) * Math.Pow(g, 2) * Math.Pow(p, 2) - 2000 * c * d * g * h * n * p + 1000 * Math.Pow(c, 2) * Math.Pow(h, 2) * Math.Pow(n, 2) + 1000 * Math.Pow(d, 2) * Math.Pow(g, 2) * Math.Pow(l, 2) - 2000 * c * d * g * h * j * l + 1000 * Math.Pow(c, 2) * Math.Pow(h, 2) * Math.Pow(j, 2) + 1000 * Math.Pow(b, 2) * Math.Pow(c, 2) * Math.Pow(h, 2) - 2000 * b * c * d * f * g * h + 1000 * Math.Pow(d, 2) * Math.Pow(f, 2) * Math.Pow(g, 2)); Vector3 myPosition = path[0].To3D() + (float)t * pathDir * c / pathDir.Length(); Vector3 misPosition = RealCurrentPosition + (float)t * skillDir * g / skillDir.Length(); bool valid = myPosition.Distance(Player.Instance) <= path[0].Distance(path[1]) && misPosition.Distance(RealCurrentPosition) <= RealCurrentPosition.Distance(RealEndPosition) && t >= 0; if (!valid && t >= 0) { /*t out of skill range => set t to skillshot maxrange*/ if (misPosition.Distance(RealCurrentPosition) > RealCurrentPosition.Distance(RealEndPosition)) { t = RealCurrentPosition.Distance(RealEndPosition) / OwnSpellData.MissileSpeed + r / 1000; myPosition = path[0].To3D() + (float)t * pathDir * c / pathDir.Length(); misPosition = RealEndPosition; return(myPosition.Distance(misPosition) > OwnSpellData.Radius); } /*t out of path range*/ if (myPosition.Distance(Player.Instance) > Player.Instance.Distance(path[1])) { t = path[0].Distance(path[1]) / speed; myPosition = path[1].To3D(); misPosition = RealCurrentPosition + (float)t * skillDir * g / skillDir.Length(); bool pathEndSafe = myPosition.Distance(misPosition) > OwnSpellData.Radius; return(pathEndSafe && ToPolygon().IsOutside(path[1])); } } return(!valid || myPosition.Distance(misPosition) > OwnSpellData.Radius); } var timeToExplode = TimeDetected + OwnSpellData.Delay - Environment.TickCount; if (timeToExplode <= 0) { int timeLeft = OwnSpellData.ExtraExistingTime - timeToExplode - timeOffset - delay; bool intersects; var intersectionP = MyUtils.GetLinesIntersectionPoint(RealCurrentPosition.To2D(), RealEndPosition.To2D(), path[0], path[1], out intersects); float walkDistance = intersectionP.Distance(path[0]) / speed * 1000; return(ToPolygon().IsOutside(Player.Instance.Position.To2D()) && (!intersects || timeLeft < walkDistance)); } var myPositionWhenExplodes = path.PositionAfter(timeToExplode, speed, delay + timeOffset); return(IsSafe(myPositionWhenExplodes)); }