Esempio n. 1
0
        internal static PredictionOutput WayPointAnalysis(PredictionOutput result, PredictionInput input)
        {
            if (!input.Unit.IsValid() || !(input.Unit is AIHeroClient) || Math.Abs(input.Radius - 1) < 0.01)
            {
                result.Hitchance = HitChance.VeryHigh;
                return result;
            }

            //Program.debug("PRED: FOR CHAMPION " + input.Unit.BaseSkinName);

            // CAN'T MOVE SPELLS ///////////////////////////////////////////////////////////////////////////////////

            if (UnitTracker.GetSpecialSpellEndTime(input.Unit) > 0 || input.Unit.HasBuff("Recall"))
            {

                result.Hitchance = HitChance.VeryHigh;
                return result;

            }

            // PREPARE MATH ///////////////////////////////////////////////////////////////////////////////////

            result.Hitchance = HitChance.Medium;

            var lastWaypiont = input.Unit.GetWaypoints().Last().To3D();
            var distanceUnitToWaypoint = lastWaypiont.Distance(input.Unit.ServerPosition);
            var distanceFromToUnit = input.From.Distance(input.Unit.ServerPosition);
            var distanceFromToWaypoint = lastWaypiont.Distance(input.From);

            float speedDelay;

            if (Math.Abs(input.Speed - float.MaxValue) < float.Epsilon)
                speedDelay = 0;
            else
                speedDelay = distanceFromToUnit / input.Speed;

            float totalDelay = speedDelay + input.Delay;
            float moveArea = input.Unit.MoveSpeed * totalDelay;
            float fixRange = moveArea * 0.5f;
            double angleMove = 30 + (input.Radius / 13) - (totalDelay * 2);
            float backToFront = moveArea * 1.5f;
            float pathMinLen = 1000f;

            if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d)
            {
                pathMinLen = 700f + backToFront;
                result.Hitchance = HitChance.High;
            }

            if (input.Type == SkillshotType.SkillshotCircle)
            {
                fixRange -= input.Radius / 2;
            }

            // SPAM CLICK ///////////////////////////////////////////////////////////////////////////////////

            if (UnitTracker.PathCalc(input.Unit))
            {
                //Program.debug("PRED: SPAM CLICK");
                if (distanceFromToUnit < input.Range - fixRange)
                {
                    result.Hitchance = HitChance.VeryHigh;
                    return result;
                }

                result.Hitchance = HitChance.High;
                return result;
            }

            // NEW Visible ///////////////////////////////////////////////////////////////////////////////////

            if (UnitTracker.GetLastVisibleTime(input.Unit) < 0.08d)
            {
                //Program.debug("PRED: NEW Visible");
                result.Hitchance = HitChance.Medium;
                return result;
            }

            // SPECIAL CASES ///////////////////////////////////////////////////////////////////////////////////

            if (distanceFromToUnit < 300 || distanceFromToWaypoint < 200)
            {
                //Program.debug("PRED: SPECIAL CASES");
                result.Hitchance = HitChance.VeryHigh;
                return result;

            }

            // LONG CLICK DETECTION ///////////////////////////////////////////////////////////////////////////////////

            if (distanceUnitToWaypoint > pathMinLen)
            {
                //Program.debug("PRED: LONG CLICK DETECTION");
                result.Hitchance = HitChance.VeryHigh;
                return result;
            }

            // RUN IN LANE DETECTION ///////////////////////////////////////////////////////////////////////////////////

            if (distanceFromToWaypoint > distanceFromToUnit + fixRange && GetAngle(input.From, input.Unit) < angleMove)
            {
                //Program.debug(GetAngle(input.From, input.Unit) + " PRED: RUN IN LANE DETECTION " + angleMove);
                result.Hitchance = HitChance.VeryHigh;
                return result;
            }

            // FIX RANGE ///////////////////////////////////////////////////////////////////////////////////

            if (distanceFromToWaypoint <= input.Unit.Distance(input.From) && distanceFromToUnit > input.Range - fixRange)
            {
                //debug("PRED: FIX RANGE");
                result.Hitchance = HitChance.Medium;
                return result;
            }

            // AUTO ATTACK LOGIC ///////////////////////////////////////////////////////////////////////////////////

            if (UnitTracker.GetLastAutoAttackTime(input.Unit) < 0.1d)
            {
                if (input.Type == SkillshotType.SkillshotLine && totalDelay < 0.6 + (input.Radius * 0.001))
                    result.Hitchance = HitChance.VeryHigh;
                else if (input.Type == SkillshotType.SkillshotCircle && totalDelay < 0.7 + (input.Radius * 0.001))
                    result.Hitchance = HitChance.VeryHigh;
                else
                    result.Hitchance = HitChance.High;

                //Program.debug("PRED: AUTO ATTACK DETECTION");
                return result;
            }

            // STOP LOGIC ///////////////////////////////////////////////////////////////////////////////////

            else
            {
                if (input.Unit.IsAttackingPlayer)
                {
                    result.Hitchance = HitChance.High;
                    return result;
                }
                else if (input.Unit.Path.Count() == 0 && !input.Unit.IsMoving)
                {
                    if (distanceFromToUnit > input.Range - fixRange)
                        result.Hitchance = HitChance.Medium;
                    else if (UnitTracker.GetLastStopMoveTime(input.Unit) < 0.8d)
                        result.Hitchance = HitChance.High;
                    else
                        result.Hitchance = HitChance.VeryHigh;

                    //Program.debug("PRED: STOP LOGIC");
                    return result;
                }
            }

            // ANGLE HIT CHANCE ///////////////////////////////////////////////////////////////////////////////////

            if (input.Type == SkillshotType.SkillshotLine && input.Unit.Path.Count() > 0 && input.Unit.IsMoving)
            {
                if (GetAngle(input.From, input.Unit) < angleMove)
                {
                    //Program.debug("PRED: ANGLE HIT CHANCE");
                    result.Hitchance = HitChance.VeryHigh;
                    return result;

                }
            }

            // CIRCLE NEW PATH ///////////////////////////////////////////////////////////////////////////////////

            if (input.Type == SkillshotType.SkillshotCircle)
            {
                if (UnitTracker.GetLastNewPathTime(input.Unit) < 0.1d && distanceFromToUnit < input.Range - fixRange && distanceUnitToWaypoint > fixRange)
                {
                    //Program.debug("PRED: CIRCLE NEW PATH");
                    result.Hitchance = HitChance.VeryHigh;
                    return result;
                }
            }
            //Program.debug("PRED: NO DETECTION");

            return result;
        }
Esempio n. 2
0
        internal static PredictionOutput GetDashingPrediction(PredictionInput input)
        {
            var dashData = input.Unit.GetDashInfo();
            var result = new PredictionOutput { Input = input };
            //Normal dashes.
            if (!dashData.IsBlink)
            {
                //Mid air:
                var endP = dashData.Path.Last();
                var dashPred = GetPositionOnPath(
                    input, new List<Vector2> { input.Unit.ServerPosition.To2D(), endP }, dashData.Speed);
                if (dashPred.Hitchance >= HitChance.High && dashPred.UnitPosition.To2D().Distance(input.Unit.Position.To2D(), endP, true) < 200)
                {
                    dashPred.CastPosition = dashPred.UnitPosition;
                    dashPred.Hitchance = HitChance.Dashing;
                    return dashPred;
                }

                //At the end of the dash:
                if (dashData.Path.GetPathLength() > 200)
                {
                    var timeToPoint = input.Delay / 2f + input.From.To2D().Distance(endP) / input.Speed - 0.25f;
                    if (timeToPoint <=
                        input.Unit.Distance(endP) / dashData.Speed + input.RealRadius / input.Unit.MoveSpeed)
                    {
                        return new PredictionOutput
                        {
                            CastPosition = endP.To3D(),
                            UnitPosition = endP.To3D(),
                            Hitchance = HitChance.Dashing
                        };
                    }
                }
                result.CastPosition = dashData.Path.Last().To3D();
                result.UnitPosition = result.CastPosition;

                //Figure out where the unit is going.
            }

            return result;
        }