public static bool InSkillShot(this Vector2 position, Spell spell, float radius, bool predictCollision = true)
        {
            if (spell.SpellType == SpellType.Line)
            {
                Vector2 spellPos = spell.CurrentSpellPosition;
                Vector2 spellEndPos = predictCollision ? spell.GetSpellEndPosition() : spell.EndPos;

                //spellPos = spellPos - spell.direction * radius; //leave some space at back of spell
                //spellEndPos = spellEndPos + spell.direction * radius; //leave some space at the front of spell

                /*if (spell.info.projectileSpeed == float.MaxValue
                    && Evade.GetTickCount - spell.startTime > spell.info.spellDelay)
                {
                    return false;
                }*/

                var projection = position.ProjectOn(spellPos, spellEndPos);

                /*if (projection.SegmentPoint.Distance(spellEndPos) < 100) //Check Skillshot endpoints
                {
                    //unfinished
                }*/

                return projection.IsOnSegment && projection.SegmentPoint.Distance(position) <= spell.Radius + radius;
            }
            else if (spell.SpellType == SpellType.Circular)
            {
                if (spell.Info.SpellName == "VeigarEventHorizon")
                {
                    return position.Distance(spell.EndPos) <= spell.Radius + radius - GameData.HeroInfo.BoundingRadius
                        && position.Distance(spell.EndPos) >= spell.Radius + radius - GameData.HeroInfo.BoundingRadius - 125;
                }

                return position.Distance(spell.EndPos) <= spell.Radius + radius - GameData.HeroInfo.BoundingRadius;
            }
            else if (spell.SpellType == SpellType.Arc)
            {
                if (position.IsLeftOfLineSegment(spell.StartPos, spell.EndPos))
                {
                    return false;
                }

                var spellRange = spell.StartPos.Distance(spell.EndPos);
                var midPoint = spell.StartPos + spell.Direction * (spellRange/2);

                return position.Distance(midPoint) <= spell.Radius + radius - GameData.HeroInfo.BoundingRadius;
            }
            else if (spell.SpellType == SpellType.Cone)
            {

            }
            return false;
        }
Beispiel #2
0
        public static PositionInfo InitPositionInfo(Vector2 pos, float extraDelayBuffer, float extraEvadeDistance, Vector2 lastMovePos, Spell lowestEvadeTimeSpell) //clean this shit up
        {
            if (!GameData.HeroInfo.IsMoving &&
                 GameData.HeroInfo.ServerPos2D.Distance(pos) <= 75)
            {
                pos = GameData.HeroInfo.ServerPos2D;
            }

            var extraDist = ConfigValue.ExtraCpaDistance.GetInt();

            var posInfo = CanHeroWalkToPos(pos, GameData.HeroInfo.MoveSpeed, extraDelayBuffer + Game.Ping, extraDist);
            posInfo.IsDangerousPos = pos.CheckDangerousPos(6);
            posInfo.HasExtraDistance = extraEvadeDistance > 0 ? pos.CheckDangerousPos(extraEvadeDistance) : false;// ? 1 : 0;            
            posInfo.ClosestDistance = posInfo.DistanceToMouse; //GetMovementBlockPositionValue(pos, lastMovePos);
            posInfo.IntersectionTime = GetMinCpaDistance(pos);
            //GetIntersectDistance(lowestEvadeTimeSpell, GameData.HeroInfo.serverPos2D, pos);               
            //GetClosestDistanceApproach(lowestEvadeTimeSpell, pos, GameData.HeroInfo.moveSpeed, Game.Ping, GameData.HeroInfo.serverPos2D, 0);
            posInfo.DistanceToMouse = pos.GetPositionValue();
            posInfo.PosDistToChamps = pos.GetDistanceToChampions();
            posInfo.Speed = GameData.HeroInfo.MoveSpeed;

            if (ConfigValue.RejectMinDistance.GetInt() > 0
                && ConfigValue.RejectMinDistance.GetInt() >
                posInfo.ClosestDistance) //reject closestdistance
            {
                posInfo.RejectPosition = true;
            }

            if (ConfigValue.MinimumComfortZone.GetInt() >
                posInfo.PosDistToChamps)
            {
                posInfo.HasComfortZone = false;
            }

            return posInfo;
        }
        public static float GetLowestEvadeTime(out Spell lowestSpell)
        {
            float lowest = float.MaxValue;
            lowestSpell = null;

            foreach (KeyValuePair<int, Spell> entry in Spells)
            {
                Spell spell = entry.Value;

                if (spell.SpellHitTime != float.MinValue)
                {
                    //ConsoleDebug.WriteLine("spellhittime: " + spell.spellHitTime);
                    lowest = Math.Min(lowest, (spell.SpellHitTime - spell.EvadeTime));
                    lowestSpell = spell;
                }
            }

            return lowest;
        }
        //public static int CreateTestSpell(SpellPoint spell, SpellData data)
        //{
        //    if (spell.StartPosition.Distance(MyHero.Position) < data.Range + ConfigValue.ExtraDetectionRange.GetInt())
        //    {
        //        Vector2 startPosition = spell.StartPosition.To2D();
        //        Vector2 endPosition = spell.EndPosition.To2D();
        //        Vector2 direction = (endPosition - startPosition).Normalized();
        //        float endTick = 0;

        //        if (data.FixedRange) //for diana q
        //        {
        //            if (endPosition.Distance(startPosition) > data.Range)
        //            {
        //                endPosition = startPosition + direction*data.Range;
        //            }
        //        }
        //        if (data.SpellType == SpellType.Line)
        //        {
        //            endTick = data.SpellDelay + (data.Range/data.ProjectileSpeed)*1000;
        //            endPosition = startPosition + direction*data.Range;

        //            if (data.UseEndPosition)
        //            {
        //                var range = endPosition.Distance(startPosition);
        //                endTick = data.SpellDelay + (range/data.ProjectileSpeed)*1000;
        //            }
        //        }
        //        else if (data.SpellType == SpellType.Circular)
        //        {
        //            endTick = data.SpellDelay;

        //            if (data.ProjectileSpeed == 0)
        //            {
        //                endPosition = startPosition;
        //            }
        //            else if (data.ProjectileSpeed > 0)
        //            {
        //                if (data.SpellType == SpellType.Line &&
        //                    data.HasEndExplosion &&
        //                    data.UseEndPosition == false)
        //                {
        //                    endPosition = startPosition + direction*data.Range;
        //                }

        //                endTick = endTick + 1000*startPosition.Distance(endPosition)/data.ProjectileSpeed;
        //            }
        //        }
        //        else if (data.SpellType == SpellType.Arc)
        //        {
        //            endTick = endTick + 1000*startPosition.Distance(endPosition)/data.ProjectileSpeed;
        //        }
        //        else if (data.SpellType == SpellType.Cone)
        //        {
        //            return 0;
        //        }
        //        else
        //        {
        //            return 0;
        //        }
        //        Spell newSpell = new Spell();
        //        newSpell.StartTime = EvadeUtils.TickCount;
        //        newSpell.EndTime = EvadeUtils.TickCount + endTick;
        //        newSpell.StartPos = startPosition;
        //        newSpell.EndPos = endPosition;
        //        newSpell.Height = spell.EndPosition.Z + data.ExtraDrawHeight;
        //        newSpell.Direction = direction;
        //        newSpell.HeroId = 0;
        //        newSpell.Info = data;
        //        newSpell.SpellType = data.SpellType;
        //        newSpell.Radius = data.Radius > 0 ? data.Radius : newSpell.GetSpellRadius();
        //        int spellId = CreateSpell(newSpell);
        //        Core.DelayAction(() => DeleteSpell(spellId), (int) (endTick + data.ExtraEndTime));
        //        return spellId;
        //    }
        //    return 0;
        //}

        private static int CreateSpell(Spell newSpell, bool processSpell = true)
        {
            //Debug.DrawTopLeft(newSpell);
            int spellId = _spellIdCount++;
            newSpell.SpellId = spellId;

            newSpell.UpdateSpellInfo();
            DetectedSpells.Add(spellId, newSpell);

            if (processSpell)
            {
                CheckSpellCollision();
                AddDetectedSpells();
            }
            if (OnCreateSpell != null)
                OnCreateSpell.Invoke(newSpell);
            return spellId;
        }
        public static bool CanHeroWalkIntoSpell(Spell spell)
        {
            if (ConfigValue.AdvancedSpellDetection.GetBool())
            {
                Vector2 heroPos = MyHero.Position.To2D();
                var extraDist = MyHero.Distance(GameData.HeroInfo.ServerPos2D);

                if (spell.SpellType == SpellType.Line)
                {
                    var walkRadius = GameData.HeroInfo.MoveSpeed * (spell.EndTime - EvadeUtils.TickCount) / 1000 +
                                     GameData.HeroInfo.BoundingRadius + spell.Info.Radius + extraDist + 10;
                    var spellPos = spell.CurrentSpellPosition;
                    var spellEndPos = spell.GetSpellEndPosition();

                    var projection = heroPos.ProjectOn(spellPos, spellEndPos);

                    return projection.SegmentPoint.Distance(heroPos) <= walkRadius;
                }
                else if (spell.SpellType == SpellType.Circular)
                {
                    var walkRadius = GameData.HeroInfo.MoveSpeed * (spell.EndTime - EvadeUtils.TickCount) / 1000 +
                                     GameData.HeroInfo.BoundingRadius + spell.Info.Radius + extraDist + 10;

                    if (heroPos.Distance(spell.EndPos) < walkRadius)
                    {
                        return true;
                    }

                }
                else if (spell.SpellType == SpellType.Arc)
                {
                    var spellRange = spell.StartPos.Distance(spell.EndPos);
                    var midPoint = spell.StartPos + spell.Direction * (spellRange / 2);
                    var arcRadius = spell.Info.Radius * (1 + spellRange / 100);

                    var walkRadius = GameData.HeroInfo.MoveSpeed * (spell.EndTime - EvadeUtils.TickCount) / 1000 +
                                     GameData.HeroInfo.BoundingRadius + arcRadius + extraDist + 10;

                    if (heroPos.Distance(midPoint) < walkRadius)
                    {
                        return true;
                    }

                }

                return false;
            }


            return true;
        }
        public static void CreateSpellData(
            Obj_AI_Base hero,
            Vector3 spellStartPos,
            Vector3 spellEndPos,
            SpellData spellData,
            GameObject obj = null,
            float extraEndTick = 0.0f,
            bool processSpell = true,
            SpellType spellType = SpellType.None,
            bool checkEndExplosion = true,
            float spellRadius = 0)
        {
            if (checkEndExplosion && spellData.HasEndExplosion)
            {
                CreateSpellData(hero, spellStartPos, spellEndPos,
                    spellData, obj, extraEndTick, false,
                    spellData.SpellType, false);

                CreateSpellData(hero, spellStartPos, spellEndPos,
                    spellData, obj, extraEndTick, true,
                    SpellType.Circular, false);

                return;
            }
            if (spellStartPos.Distance(MyHero.Position) < spellData.Range + ConfigValue.ExtraDetectionRange.GetInt())
            {
                Vector2 startPosition = spellStartPos.To2D();
                Vector2 endPosition = spellEndPos.To2D();
                Vector2 direction = (endPosition - startPosition).Normalized();
                float endTick = 0;

                if (spellType == SpellType.None)
                {
                    spellType = spellData.SpellType;
                }

                if (spellData.FixedRange) //for diana q
                {
                    if (endPosition.Distance(startPosition) > spellData.Range)
                    {
                        endPosition = startPosition + direction * spellData.Range;
                    }
                }
                if (spellType == SpellType.Line)
                {
                    endTick = spellData.SpellDelay + (spellData.Range / spellData.ProjectileSpeed) * 1000;
                    endPosition = startPosition + direction * spellData.Range;

                    if (spellData.UseEndPosition)
                    {
                        var range = spellEndPos.To2D().Distance(spellStartPos.To2D());
                        endTick = spellData.SpellDelay + (range / spellData.ProjectileSpeed) * 1000;
                        endPosition = spellEndPos.To2D();
                    }

                    if (obj != null)
                        endTick -= spellData.SpellDelay;
                }
                else if (spellType == SpellType.Circular)
                {
                    endTick = spellData.SpellDelay;

                    if (spellData.ProjectileSpeed == 0)
                    {
                        endPosition = hero.ServerPosition.To2D();
                    }
                    else if (spellData.ProjectileSpeed > 0)
                    {
                        if (spellData.SpellType == SpellType.Line &&
                            spellData.HasEndExplosion &&
                            spellData.UseEndPosition == false)
                        {
                            endPosition = startPosition + direction * spellData.Range;
                        }

                        endTick = endTick + 1000 * startPosition.Distance(endPosition) / spellData.ProjectileSpeed;
                    }
                }
                else if (spellType == SpellType.Arc)
                {
                    endTick = endTick + 1000 * startPosition.Distance(endPosition) / spellData.ProjectileSpeed;

                    if (obj != null)
                        endTick -= spellData.SpellDelay;
                }
                else if (spellType == SpellType.Cone)
                {
                    return;
                }
                else
                {
                    return;
                }
                endTick += extraEndTick;
                Spell newSpell = new Spell();
                newSpell.StartTime = EvadeUtils.TickCount;
                newSpell.EndTime = EvadeUtils.TickCount + endTick;
                newSpell.StartPos = startPosition;
                newSpell.EndPos = endPosition;
                newSpell.Height = spellEndPos.Z + spellData.ExtraDrawHeight;
                newSpell.Direction = direction;
                newSpell.HeroId = hero.NetworkId;
                newSpell.Info = spellData;
                newSpell.SpellType = spellType;
                newSpell.Radius = spellRadius > 0 ? spellRadius : newSpell.GetSpellRadius();
                if (obj != null)
                {
                    newSpell.SpellObject = obj;
                    newSpell.ProjectileId = obj.NetworkId;
                }
                int spellId = CreateSpell(newSpell, processSpell);
                Core.DelayAction(() => DeleteSpell(spellId), (int) (endTick + spellData.ExtraEndTime));
            }
        }
Beispiel #7
0
        private static bool ShouldActivateEvadeSpell(Spell spell)
        {
            if (AdEvade.LastPosInfo == null)
                return false;

            if (ConfigValue.DodgeSkillShots.GetBool())
            {
                if (AdEvade.LastPosInfo.UndodgeableSpells.Contains(spell.SpellId)
                && GameData.HeroInfo.ServerPos2D.InSkillShot(spell, GameData.HeroInfo.BoundingRadius))
                {
                    return true;
                }
            }
            else
            {
                if (GameData.HeroInfo.ServerPos2D.InSkillShot(spell, GameData.HeroInfo.BoundingRadius))
                {
                    return true;
                }
            }


            /*float activationTime = Evade.Menu.SubMenu("MiscSettings").SubMenu("EvadeSpellMisc").Item("EvadeSpellActivationTime")
                .Cast<Slider>().CurrentValue + ObjectCache.gamePing;

            if (spell.spellHitTime != float.MinValue && activationTime > spell.spellHitTime - spell.evadeTime)
            {
                return true;
            }*/

            return false;
        }
Beispiel #8
0
        public static bool ActivateEvadeSpell(Spell spell, bool checkSpell = false)
        {
            var sortedEvadeSpells = EvadeSpells.OrderBy(s => s.Dangerlevel);

            var extraDelayBuffer = Config.Properties.GetInt(ConfigValue.ExtraPingBuffer);
            float spellActivationTime = ConfigValue.SpellActivationTime.GetInt() + Game.Ping + extraDelayBuffer;

            if (ConfigValue.CalculateWindupDelay.GetBool())
            {
                var extraWindupDelay = AdEvade.LastWindupTime - EvadeUtils.TickCount;
                if (extraWindupDelay > 0)
                {
                    return false;
                }
            }

            foreach (var evadeSpell in sortedEvadeSpells)
            {
                var processSpell = true;
                if (!Config.Properties.GetEvadeSpell(evadeSpell.Name).Use ||
                    ((int) GetSpellDangerLevel(evadeSpell) > (int) spell.GetSpellDangerLevel()) ||
                    (!evadeSpell.IsItem && MyHero.Spellbook.CanUseSpell(evadeSpell.SpellKey) != SpellState.Ready)||
                    (evadeSpell.IsItem && !(Items.CanUseItem((int) evadeSpell.ItemId))) ||
                    (evadeSpell.CheckSpellName &&
                     MyHero.Spellbook.GetSpell(evadeSpell.SpellKey).Name != evadeSpell.SpellName))
                {
                    continue; //can't use spell right now               
                }


                float evadeTime, spellHitTime;
                spell.CanHeroEvade(MyHero, out evadeTime, out spellHitTime);

                float finalEvadeTime = (spellHitTime - evadeTime);

                if (checkSpell)
                {
                    var mode = Config.Properties.GetEvadeSpell(evadeSpell.Name).SpellMode;

                    switch (mode)
                    {
                        case SpellModes.Undodgeable:
                            continue;
                        case SpellModes.ActivationTime:
                            if (spellActivationTime < finalEvadeTime)
                            {
                                continue;
                            }
                            break;
                    }
                }
                else
                {
                    //if (ObjectCache.menuCache.cache[evadeSpell.name + "LastResort"].Cast<CheckBox>().CurrentValue)
                    if (evadeSpell.SpellDelay <= 50 && evadeSpell.EvadeType != EvadeType.Dash)
                    {
                        var path = MyHero.Path;
                        if (path.Length > 0)
                        {
                            var movePos = path[path.Length - 1].To2D();
                            var posInfo = EvadeHelper.CanHeroWalkToPos(movePos, GameData.HeroInfo.MoveSpeed, 0, 0);

                            if ((int) GetSpellDangerLevel(evadeSpell) > (int) posInfo.PosDangerLevel)
                            {
                                continue;
                            }
                        }
                    }
                }

                if (evadeSpell.EvadeType != EvadeType.Dash && spellHitTime > evadeSpell.SpellDelay + 100 + Game.Ping +
                    Config.Properties.GetInt(ConfigValue.ExtraPingBuffer))
                {
                    processSpell = false;

                    if (checkSpell == false)
                    {
                        continue;
                    }
                }

                if (evadeSpell.IsSpecial)
                {
                    if (evadeSpell.UseSpellFunc != null)
                        if (evadeSpell.UseSpellFunc(evadeSpell, processSpell))
                            return true;
                    continue;
                }

                if (evadeSpell.EvadeType == EvadeType.Blink)
                {
                    if (evadeSpell.CastType == CastType.Position)
                    {
                        var posInfo = EvadeHelper.GetBestPositionBlink();
                        if (posInfo != null)
                        {
                            CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell, posInfo.Position), processSpell);
                            //DelayAction.Add(50, () => myHero.IssueOrder(GameObjectOrder.MoveTo, posInfo.position.To3D()));
                            return true;
                        }
                    }
                    else if (evadeSpell.CastType == CastType.Target)
                    {
                        var posInfo = EvadeHelper.GetBestPositionTargetedDash(evadeSpell);
                        if (posInfo != null && posInfo.Target != null && posInfo.PosDangerLevel == 0)
                        {
                            CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell, posInfo.Target), processSpell);
                            //DelayAction.Add(50, () => myHero.IssueOrder(GameObjectOrder.MoveTo, posInfo.position.To3D()));
                            return true;
                        }
                    }
                }
                else if (evadeSpell.EvadeType == EvadeType.Dash)
                {
                    if (evadeSpell.CastType == CastType.Position)
                    {
                        var posInfo = EvadeHelper.GetBestPositionDash(evadeSpell);
                        if (posInfo != null && CompareEvadeOption(posInfo, checkSpell))
                        {
                            if (evadeSpell.IsReversed)
                            {
                                var dir = (posInfo.Position - GameData.HeroInfo.ServerPos2D).Normalized();
                                var range = GameData.HeroInfo.ServerPos2D.Distance(posInfo.Position);
                                var pos = GameData.HeroInfo.ServerPos2D - dir * range;

                                posInfo.Position = pos;
                            }

                            CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell, posInfo.Position), processSpell);
                            //DelayAction.Add(50, () => myHero.IssueOrder(GameObjectOrder.MoveTo, posInfo.position.To3D()));
                            return true;
                        }
                    }
                    else if (evadeSpell.CastType == CastType.Target)
                    {
                        var posInfo = EvadeHelper.GetBestPositionTargetedDash(evadeSpell);
                        if (posInfo != null && posInfo.Target != null && posInfo.PosDangerLevel == 0)
                        {
                            CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell, posInfo.Target), processSpell);
                            //DelayAction.Add(50, () => myHero.IssueOrder(GameObjectOrder.MoveTo, posInfo.position.To3D()));
                            return true;
                        }
                    }
                }
                else if (evadeSpell.EvadeType == EvadeType.WindWall)
                {
                    if (spell.HasProjectile() || evadeSpell.SpellName == "FioraW") //TODO: temp fix, don't have fiora :'(
                    {
                        var dir = (spell.StartPos - GameData.HeroInfo.ServerPos2D).Normalized();
                        var pos = GameData.HeroInfo.ServerPos2D + dir * 100;

                        CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell, pos), processSpell);
                        return true;
                    }
                }
                else if (evadeSpell.EvadeType == EvadeType.SpellShield)
                {
                    if (evadeSpell.IsItem)
                    {
                        CastEvadeSpell(() => Items.UseItem((int)evadeSpell.ItemId), processSpell);
                        return true;
                    }
                    else
                    {
                        if (evadeSpell.CastType == CastType.Target)
                        {
                            CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell, MyHero), processSpell);
                            return true;
                        }
                        else if (evadeSpell.CastType == CastType.Self)
                        {
                            CastEvadeSpell(() => EvadeCommand.CastSpell(evadeSpell), processSpell);
                            return true;
                        }
                    }
                }
                else if (evadeSpell.EvadeType == EvadeType.MovementSpeedBuff)
                {
                    
                }
            }

            return false;
        }
Beispiel #9
0
        public static float GetClosestDistanceApproach(Spell spell, Vector2 pos, float speed, float delay, Vector2 heroPos, float extraDist)
        {
            var walkDir = (pos - heroPos).Normalized();

            if (spell.SpellType == SpellType.Line && spell.Info.ProjectileSpeed != float.MaxValue)
            {
                var spellPos = spell.GetCurrentSpellPosition(true, delay);
                var spellStartPos = spell.CurrentSpellPosition;
                var spellEndPos = spell.GetSpellEndPosition();
                var extendedPos = pos.ExtendDir(walkDir, GameData.HeroInfo.BoundingRadius + speed * delay / 1000);

                Vector2 cHeroPos;
                Vector2 cSpellPos;

                var cpa2 = MathUtils.GetCollisionDistanceEx(
                    heroPos, walkDir * speed, GameData.HeroInfo.BoundingRadius,
                    spellPos, spell.Direction * spell.Info.ProjectileSpeed, spell.Radius + extraDist,
                    out cHeroPos, out 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 = GameData.HeroInfo.BoundingRadius + spell.Radius + extraDist;

                if (cSpellPosProjection.IsOnSegment && cHeroPosProjection.IsOnSegment)
                {
                    return Math.Max(0, cpa - checkDist);
                }
                else
                {
                    return checkDist;
                }


                //return MathUtils.ClosestTimeOfApproach(heroPos, walkDir * speed, spellPos, spell.direction * spell.info.projectileSpeed);
            }
            else if (spell.SpellType == SpellType.Line && spell.Info.ProjectileSpeed == float.MaxValue)
            {
                var spellHitTime = Math.Max(0, spell.EndTime - EvadeUtils.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 + GameData.HeroInfo.BoundingRadius + extraDist)); //+ dodgeBuffer
            }
            else if (spell.SpellType == SpellType.Circular)
            {
                var spellHitTime = Math.Max(0, spell.EndTime - EvadeUtils.TickCount - delay);  //extraDelay
                var walkRange = heroPos.Distance(pos);
                var predictedRange = speed * (spellHitTime / 1000);
                var tHeroPos = heroPos + walkDir * Math.Min(predictedRange, walkRange); //Hero predicted pos

                if (spell.Info.SpellName == "VeigarEventHorizon")
                {
                    var wallRadius = 65;
                    var midRadius = spell.Radius - wallRadius;

                    if (spellHitTime == 0)
                    {
                        return 0;
                    }

                    if (tHeroPos.Distance(spell.EndPos) >= spell.Radius)
                    {
                        return Math.Max(0, tHeroPos.Distance(spell.EndPos) - midRadius - wallRadius);
                    }
                    else
                    {
                        return 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 - EvadeUtils.TickCount - delay);
                    var predictedRange2 = speed * (remainingTime / 1000);
                    var tHeroPos2 = heroPos + walkDir * Math.Min(predictedRange2, walkRange);

                    if (CheckMoveToDirection(tHeroPos, tHeroPos2))
                    {
                        return 0;
                    }
                }
                else
                {
                    return closestDist;
                }
            }
            else if (spell.SpellType == 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, GameData.HeroInfo.BoundingRadius);

                Vector2 cHeroPos;
                Vector2 cSpellPos;

                var cpa = MathUtilsCpa.CPAPointsEx(heroPos, walkDir * speed, spellPos, spell.Direction * spell.Info.ProjectileSpeed, pos, spellEndPos, out cHeroPos, out cSpellPos);

                var cHeroPosProjection = cHeroPos.ProjectOn(heroPos, extendedPos);
                var cSpellPosProjection = cSpellPos.ProjectOn(spellPos, spellEndPos);

                var checkDist = spell.Radius + extraDist;

                if (cHeroPos.InSkillShot(spell, GameData.HeroInfo.BoundingRadius))
                {
                    if (cSpellPosProjection.IsOnSegment && cHeroPosProjection.IsOnSegment)
                    {
                        return Math.Max(0, cpa - checkDist);
                    }
                    else
                    {
                        return checkDist;
                    }
                }
            }

            return 1;
        }
Beispiel #10
0
        public static float GetIntersectDistance(Spell spell, Vector2 start, Vector2 end)
        {
            if (spell == null)
                return float.MaxValue;

            Vector3 start3D = new Vector3(start.X, start.Y, 0);
            Vector2 walkDir = (end - start);
            Vector3 walkDir3D = new Vector3(walkDir.X, walkDir.Y, 0);

            var heroPath = new Ray(start3D, walkDir3D);

            if (spell.SpellType == SpellType.Line)
            {
                Vector2 intersection;
                bool hasIntersection = spell.LineIntersectLinearSpellEx(start, end, out intersection);
                if (hasIntersection)
                {
                    return start.Distance(intersection);
                }
            }
            else if (spell.SpellType == SpellType.Circular)
            {
                if (end.InSkillShot(spell, GameData.HeroInfo.BoundingRadius) == false)
                {
                    Vector2 intersection1, intersection2;
                    MathUtils.FindLineCircleIntersections(spell.EndPos, spell.Radius, start, end, out intersection1, out intersection2);

                    if (intersection1.X != float.NaN && MathUtils.IsPointOnLineSegment(intersection1, start, end))
                    {
                        return start.Distance(intersection1);
                    }
                    else if (intersection2.X != float.NaN && MathUtils.IsPointOnLineSegment(intersection2, start, end))
                    {
                        return start.Distance(intersection2);
                    }
                }
            }

            return float.MaxValue;
        }
Beispiel #11
0
        public static float CompareFastestPosition(Spell spell, Vector2 start, Vector2 movePos)
        {
            var fastestPos = GetFastestPosition(spell);
            var moveDir = (movePos - start).Normalized();
            var fastestDir = (GetFastestPosition(spell) - start).Normalized();

            return moveDir.AngleBetween(fastestDir); // * (180 / ((float)Math.PI));
        }
Beispiel #12
0
        public static Vector2 GetFastestPosition(Spell spell)
        {
            var heroPos = GameData.HeroInfo.ServerPos2D;

            if (spell.SpellType == SpellType.Line)
            {
                var projection = heroPos.ProjectOn(spell.StartPos, spell.EndPos).SegmentPoint;
                return projection.Extend(heroPos, spell.Radius + GameData.HeroInfo.BoundingRadius + 10);
            }
            else if (spell.SpellType == SpellType.Circular)
            {
                return spell.EndPos.Extend(heroPos, spell.Radius + 10);
            }

            return Vector2.Zero;
        }
Beispiel #13
0
 public static bool PlayerInSkillShot(Spell spell)
 {
     return GameData.HeroInfo.ServerPos2D.InSkillShot(spell, GameData.HeroInfo.BoundingRadius);
 }
Beispiel #14
0
        public static bool PredictSpellCollision(Spell spell, Vector2 pos, float speed, float delay, Vector2 heroPos, float extraDist, bool useServerPosition = true)
        {
            extraDist = extraDist + 10;

            if (useServerPosition == false)
            {
                return GetClosestDistanceApproach(spell, pos, speed, 0,
                    GameData.HeroInfo.ServerPos2D, 0) == 0;
            }

            return
                    GetClosestDistanceApproach(spell, pos, speed, delay, //Game.Ping + Extra Buffer
                    GameData.HeroInfo.ServerPos2DPing, extraDist) == 0
                 || GetClosestDistanceApproach(spell, pos, speed, Game.Ping, //Game.Ping
                    GameData.HeroInfo.ServerPos2DPing, extraDist) == 0;
        }