コード例 #1
0
ファイル: Program.cs プロジェクト: yashine59fr/PortAIO-1
        private static void TryToEvade(List<Skillshot> HitBy, Vector2 to)
        {
            var dangerLevel = 0;

            foreach (var skillshot in HitBy)
            {
                //dangerLevel = Math.Max(dangerLevel, skillshot.GetValue<Slider>("DangerLevel").Value);
            }

            foreach (var evadeSpell in EvadeSpellDatabase.Spells)
            {
                if (evadeSpell.Enabled && evadeSpell.DangerLevel <= dangerLevel)
                {
                    //SpellShields
                    if (evadeSpell.IsSpellShield &&
                        ObjectManager.Player.Spellbook.CanUseSpell(evadeSpell.Slot) == SpellState.Ready)
                    {
                        if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                        {
                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, ObjectManager.Player);
                        }
                        //Let the user move freely inside the skillshot.
                        NoSolutionFound = true;
                        return;
                    }

                    //Walking
                    if (evadeSpell.Name == "Walking")
                    {
                        var points = Evader.GetEvadePoints();
                        if (points.Count > 0)
                        {
                            EvadePoint = to.Closest(points);
                            var nEvadePoint = EvadePoint.LSExtend(PlayerPosition, -100);
                            if (
                                Program.IsSafePath(
                                    ObjectManager.Player.GetPath(nEvadePoint.To3D()).To2DList(),
                                    Config.EvadingSecondTimeOffset, (int) ObjectManager.Player.MoveSpeed, 100).IsSafe)
                            {
                                EvadePoint = nEvadePoint;
                            }

                            Evading = true;
                            return;
                        }
                    }

                    if (evadeSpell.IsReady())
                    {
                        //MovementSpeed Buff
                        if (evadeSpell.IsMovementSpeedBuff)
                        {
                            var points = Evader.GetEvadePoints((int) evadeSpell.MoveSpeedTotalAmount());

                            if (points.Count > 0)
                            {
                                EvadePoint = to.Closest(points);
                                Evading = true;

                                if (evadeSpell.IsSummonerSpell)
                                {
                                  //  ObjectManager.Player.Spellbook.CastSpell(
                                      //  evadeSpell.Slot, ObjectManager.Player);
                                }
                                else
                                {
                                    //ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, ObjectManager.Player);
                                }

                                return;
                            }
                        }

                        //Dashes
                        if (evadeSpell.IsDash)
                        {
                            //Targetted dashes
                            if (evadeSpell.IsTargetted) //Lesinga W.
                            {
                                var targets = Evader.GetEvadeTargets(
                                    evadeSpell.ValidTargets, evadeSpell.Speed, evadeSpell.Delay, evadeSpell.MaxRange,
                                    false, false);

                                if (targets.Count > 0)
                                {
                                    var closestTarget = Utils.Closest(targets, to);
                                    EvadePoint = closestTarget.ServerPosition.LSTo2D();
                                    Evading = true;

                                    if (evadeSpell.IsSummonerSpell)
                                    {
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                                    }
                                    else
                                    {
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                                    }

                                    return;
                                }
                                if (Utils.TickCount - LastWardJumpAttempt < 250)
                                {
                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }

                                if (evadeSpell.IsTargetted &&
                                    evadeSpell.ValidTargets.Contains(SpellValidTargets.AllyWards) &&
                                    Config.evadeSpells["WardJump" + evadeSpell.Name].Cast<CheckBox>().CurrentValue)
                                {
                                    var wardSlot = Items.GetWardSlot();
                                    if (wardSlot != null)
                                    {
                                        var points = Evader.GetEvadePoints(evadeSpell.Speed, evadeSpell.Delay, false);

                                        // Remove the points out of range
                                        points.RemoveAll(
                                            item => item.LSDistance(ObjectManager.Player.ServerPosition) > 600);

                                        if (points.Count > 0)
                                        {
                                            //Dont dash just to the edge:
                                            for (var i = 0; i < points.Count; i++)
                                            {
                                                var k =
                                                    (int)
                                                        (600 -
                                                         PlayerPosition.LSDistance(points[i]));

                                                k = k - new Random(Utils.TickCount).Next(k);
                                                var extended = points[i] +
                                                               k *
                                                               (points[i] - PlayerPosition)
                                                                   .LSNormalized();
                                                if (IsSafe(extended).IsSafe)
                                                {
                                                    points[i] = extended;
                                                }
                                            }

                                            var ePoint = to.Closest(points);
                                            ObjectManager.Player.Spellbook.CastSpell(wardSlot.SpellSlot, ePoint.To3D());
                                            LastWardJumpAttempt = Utils.TickCount;
                                            //Let the user move freely inside the skillshot.
                                            NoSolutionFound = true;
                                            return;
                                        }
                                    }
                                }
                            }
                                //Skillshot type dashes.
                            else
                            {
                                var points = Evader.GetEvadePoints(evadeSpell.Speed, evadeSpell.Delay, false);

                                // Remove the points out of range
                                points.RemoveAll(
                                    item => item.LSDistance(ObjectManager.Player.ServerPosition) > evadeSpell.MaxRange);

                                //If the spell has a fixed range (Vaynes Q), calculate the real dashing location. TODO: take into account walls in the future.
                                if (evadeSpell.FixedRange)
                                {
                                    for (var i = 0; i < points.Count; i++)
                                    {
                                        points[i] = PlayerPosition
                                            .LSExtend(points[i], evadeSpell.MaxRange);
                                    }

                                    for (var i = points.Count - 1; i > 0; i--)
                                    {
                                        if (!IsSafe(points[i]).IsSafe)
                                        {
                                            points.RemoveAt(i);
                                        }
                                    }
                                }
                                else
                                {
                                    for (var i = 0; i < points.Count; i++)
                                    {
                                        var k =
                                            (int)
                                                (evadeSpell.MaxRange -
                                                 PlayerPosition.LSDistance(points[i]));
                                        k -= Math.Max(RandomN.Next(k) - 100, 0);
                                        var extended = points[i] +
                                                       k *
                                                       (points[i] - PlayerPosition)
                                                           .LSNormalized();
                                        if (IsSafe(extended).IsSafe)
                                        {
                                            points[i] = extended;
                                        }
                                    }
                                }

                                if (points.Count > 0)
                                {
                                    EvadePoint = to.Closest(points);
                                    Evading = true;

                                    if (!evadeSpell.Invert)
                                    {
                                        if (evadeSpell.RequiresPreMove)
                                        {
                                            ObjectManager.Player.SendMovePacket(EvadePoint);
                                            var theSpell = evadeSpell;
                                            LeagueSharp.Common.Utility.DelayAction.Add(
                                                Game.Ping / 2 + 100,
                                                delegate
                                                {
                                                    ObjectManager.Player.Spellbook.CastSpell(
                                                        theSpell.Slot, EvadePoint.To3D());
                                                });
                                        }
                                        else
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, EvadePoint.To3D());
                                        }
                                    }
                                    else
                                    {
                                        var castPoint = PlayerPosition -
                                                        (EvadePoint - PlayerPosition);
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, castPoint.To3D());
                                    }

                                    return;
                                }
                            }
                        }

                        //Blinks
                        if (evadeSpell.IsBlink)
                        {
                            //Targetted blinks
                            if (evadeSpell.IsTargetted)
                            {
                                var targets = Evader.GetEvadeTargets(
                                    evadeSpell.ValidTargets, int.MaxValue, evadeSpell.Delay, evadeSpell.MaxRange, true,
                                    false);

                                if (targets.Count > 0)
                                {
                                    if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                    {
                                        var closestTarget = Utils.Closest(targets, to);
                                        EvadePoint = closestTarget.ServerPosition.LSTo2D();
                                        Evading = true;

                                        if (evadeSpell.IsSummonerSpell)
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(
                                                evadeSpell.Slot, closestTarget);
                                        }
                                        else
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                                        }
                                    }

                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }
                                if (Utils.TickCount - LastWardJumpAttempt < 250)
                                {
                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }

                                if (evadeSpell.IsTargetted &&
                                    evadeSpell.ValidTargets.Contains(SpellValidTargets.AllyWards) &&
                                    Config.evadeSpells["WardJump" + evadeSpell.Name].Cast<CheckBox>().CurrentValue)
                                {
                                    var wardSlot = Items.GetWardSlot();
                                    if (wardSlot != null)
                                    {
                                        var points = Evader.GetEvadePoints(int.MaxValue, evadeSpell.Delay, true);

                                        // Remove the points out of range
                                        points.RemoveAll(
                                            item => item.LSDistance(ObjectManager.Player.ServerPosition) > 600);

                                        if (points.Count > 0)
                                        {
                                            //Dont blink just to the edge:
                                            for (var i = 0; i < points.Count; i++)
                                            {
                                                var k =
                                                    (int)
                                                        (600 -
                                                         PlayerPosition.LSDistance(points[i]));

                                                k = k - new Random(Utils.TickCount).Next(k);
                                                var extended = points[i] +
                                                               k *
                                                               (points[i] - PlayerPosition)
                                                                   .LSNormalized();
                                                if (IsSafe(extended).IsSafe)
                                                {
                                                    points[i] = extended;
                                                }
                                            }

                                            var ePoint = to.Closest(points);
                                            ObjectManager.Player.Spellbook.CastSpell(wardSlot.SpellSlot, ePoint.To3D());
                                            LastWardJumpAttempt = Utils.TickCount;
                                            //Let the user move freely inside the skillshot.
                                            NoSolutionFound = true;
                                            return;
                                        }
                                    }
                                }
                            }

                                //Skillshot type blinks.
                            else
                            {
                                var points = Evader.GetEvadePoints(int.MaxValue, evadeSpell.Delay, true);

                                // Remove the points out of range
                                points.RemoveAll(
                                    item => item.LSDistance(ObjectManager.Player.ServerPosition) > evadeSpell.MaxRange);

                                //Dont blink just to the edge:
                                for (var i = 0; i < points.Count; i++)
                                {
                                    var k =
                                        (int)
                                            (evadeSpell.MaxRange -
                                             PlayerPosition.LSDistance(points[i]));

                                    k = k - new Random(Utils.TickCount).Next(k);
                                    var extended = points[i] +
                                                   k *
                                                   (points[i] - PlayerPosition).LSNormalized();
                                    if (IsSafe(extended).IsSafe)
                                    {
                                        points[i] = extended;
                                    }
                                }

                                if (points.Count > 0)
                                {
                                    if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                    {
                                        EvadePoint = to.Closest(points);
                                        Evading = true;
                                        if (evadeSpell.IsSummonerSpell)
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(
                                                evadeSpell.Slot, EvadePoint.To3D());
                                        }
                                        else
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, EvadePoint.To3D());
                                        }
                                    }

                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }
                            }
                        }

                        //Invulnerabilities, like Fizz's E
                        if (evadeSpell.IsInvulnerability)
                        {
                            if (evadeSpell.IsTargetted)
                            {
                                var targets = Evader.GetEvadeTargets(
                                    evadeSpell.ValidTargets, int.MaxValue, 0, evadeSpell.MaxRange, true, false, true);

                                if (targets.Count > 0)
                                {
                                    if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                    {
                                        var closestTarget = Utils.Closest(targets, to);
                                        EvadePoint = closestTarget.ServerPosition.LSTo2D();
                                        Evading = true;
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                                    }

                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }
                            }
                            else
                            {
                                if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                {
                                    if (evadeSpell.SelfCast)
                                    {
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot);
                                    }
                                    else
                                    {
                                        ObjectManager.Player.Spellbook.CastSpell(
                                            evadeSpell.Slot, ObjectManager.Player.ServerPosition);
                                    }
                                }
                            }

                            //Let the user move freely inside the skillshot.
                            NoSolutionFound = true;
                            return;
                        }
                    }

                    //Zhonyas
                    if (evadeSpell.Name == "Zhonyas" && (Items.CanUseItem("ZhonyasHourglass")))
                    {
                        if (IsAboutToHit(ObjectManager.Player, 100))
                        {
                            Items.UseItem("ZhonyasHourglass");
                        }

                        //Let the user move freely inside the skillshot.
                        NoSolutionFound = true;

                        return;
                    }

                    //Shields
                    if (evadeSpell.IsShield &&
                        ObjectManager.Player.Spellbook.CanUseSpell(evadeSpell.Slot) == SpellState.Ready)
                    {
                        if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                        {
                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, ObjectManager.Player);
                        }

                        //Let the user move freely inside the skillshot.
                        NoSolutionFound = true;
                        return;
                    }
                }
            }

            NoSolutionFound = true;
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: Chogart/LeagueSharp-2
        /// <summary>
        /// Used to block the movement to avoid entering in dangerous areas.
        /// </summary>
        private static void Game_OnGameSendPacket(GamePacketEventArgs args)
        {
            //Move Packet
            if (args.PacketData[0] == Packet.C2S.Move.Header)
            {
                CutPathPoint = new Vector2();
                //Don't block the movement packets if cant find an evade point.
                if (NoSolutionFound)
                {
                    return;
                }

                //Evading disabled
                if (!Config.Menu.Item("Enabled").GetValue<KeyBind>().Active)
                {
                    return;
                }

                //Spell Shielded
                if (IsSpellShielded(ObjectManager.Player))
                {
                    return;
                }

                var decodedPacket = Packet.C2S.Move.Decoded(args.PacketData);

                if(decodedPacket.UnitNetworkId != ObjectManager.Player.NetworkId) return;

                if (decodedPacket.MoveType == 2)
                {
                    EvadeToPoint.X = decodedPacket.X;
                    EvadeToPoint.Y = decodedPacket.Y;
                }

                var myPath =
                    ObjectManager.Player.GetPath(
                        new Vector3(decodedPacket.X, decodedPacket.Y, ObjectManager.Player.ServerPosition.Z)).To2DList();
                var safeResult = IsSafe(ObjectManager.Player.ServerPosition.To2D());
                var safePath = IsSafePath(myPath, Config.EvadingRouteChangeTimeOffset);

                //If we are evading:
                if (Evading || !safeResult.IsSafe)
                {
                    if (decodedPacket.MoveType == 2)
                    {
                        AfterEvadePoint = new Vector2(decodedPacket.X, decodedPacket.Y);
                        if (Evading &&
                            Environment.TickCount - Config.LastEvadePointChangeT > Config.EvadePointChangeInterval)
                        {
                            //Update the evade point to the closest one:
                            var points = Evader.GetEvadePoints(-1, 0, false, true);
                            if (points.Count > 0)
                            {
                                var to = new Vector2(decodedPacket.X, decodedPacket.Y);
                                EvadePoint = to.Closest(points);
                                Evading = true;
                                Config.LastEvadePointChangeT = Environment.TickCount;
                            }
                        }

                        //If the path is safe let the user follow it.
                        if (safePath.IsSafe && IsSafe(myPath[myPath.Count - 1]).IsSafe && decodedPacket.MoveType == 2)
                        {
                            EvadePoint = myPath[myPath.Count - 1];
                            Evading = true;
                        }

                        CutPathPoint = new Vector2(decodedPacket.X, decodedPacket.Y);
                    }

                    //Block the packets if we are evading or not safe.
                    args.Process = false;
                    return;
                }

                //Not evading, outside the skillshots.
                //The path is not safe, stop in the intersection point.
                if (!safePath.IsSafe && decodedPacket.MoveType != 3)
                {
                    if (safePath.Intersection.Valid)
                    {
                        ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                    }
                    CutPathPoint = new Vector2(decodedPacket.X, decodedPacket.Y);
                    args.Process = false;
                }

                //AutoAttacks.
                if (!safePath.IsSafe && decodedPacket.MoveType == 3)
                {
                    var target = ObjectManager.GetUnitByNetworkId<Obj_AI_Base>(decodedPacket.TargetNetworkId);
                    if (target != null && target.IsValid && target.IsVisible)
                    {
                        //Out of attack range.
                        if (ObjectManager.Player.ServerPosition.To2D().Distance(target.ServerPosition) >
                            ObjectManager.Player.AttackRange + ObjectManager.Player.BoundingRadius +
                            target.BoundingRadius)
                        {
                            if (safePath.Intersection.Valid)
                            {
                                ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                            }
                            args.Process = false;
                        }
                    }
                }
            }
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: yashine59fr/PortAIO-1
        /// <summary>
        /// Used to block the movement to avoid entering in dangerous areas.
        /// </summary>
        /// 
        private static void ObjAiHeroOnOnIssueOrder(Obj_AI_Base sender, PlayerIssueOrderEventArgs args)
        {
            if (!sender.IsMe)
            {
                return;
            }

            //Don't block the movement packets if cant find an evade point.
            if (NoSolutionFound)
            {
                return;
            }

            //Spell Shielded
            if (ObjectManager.Player.IsSpellShielded())
            {
                return;
            }

            if (args.Order == GameObjectOrder.MoveTo || args.Order == GameObjectOrder.AttackTo)
            {
                EvadeToPoint.X = args.TargetPosition.X;
                EvadeToPoint.Y = args.TargetPosition.Y;
                Keepfollowing = false;
                FollowPath = false;
            }
            else
            {
                EvadeToPoint.X = 0;
                EvadeToPoint.Y = 0;
            }

            var myPath =
                ObjectManager.Player.GetPath(
                    new Vector3(args.TargetPosition.X, args.TargetPosition.Y, ObjectManager.Player.ServerPosition.Z)).To2DList();
            var safeResult = IsSafe(PlayerPosition);

            //If we are evading:
            if (Evading || !safeResult.IsSafe)
            {
                var rcSafePath = IsSafePath(myPath, Config.EvadingRouteChangeTimeOffset);
                if (args.Order == GameObjectOrder.MoveTo)
                {
                    if (Evading &&
                        Utils.TickCount - Config.LastEvadePointChangeT > Config.EvadePointChangeInterval)
                    {
                        //Update the evade point to the closest one:
                        var points = Evader.GetEvadePoints(-1, 0, false, true);
                        if (points.Count > 0)
                        {
                            var to = new Vector2(args.TargetPosition.X, args.TargetPosition.Y);
                            EvadePoint = to.Closest(points);
                            Evading = true;
                            Config.LastEvadePointChangeT = Utils.TickCount;
                        }
                    }

                    //If the path is safe let the user follow it.
                    if (rcSafePath.IsSafe && IsSafe(myPath[myPath.Count - 1]).IsSafe && args.Order == GameObjectOrder.MoveTo)
                    {
                        EvadePoint = myPath[myPath.Count - 1];
                        Evading = true;
                    }
                }

                //Block the packets if we are evading or not safe.
                args.Process = false;
                return;
            }

            var safePath = IsSafePath(myPath, Config.CrossingTimeOffset);

            //Not evading, outside the skillshots.
            //The path is not safe, stop in the intersection point.
            if (!safePath.IsSafe && args.Order != GameObjectOrder.AttackUnit)
            {
                if (safePath.Intersection.Valid)
                {
                    if (ObjectManager.Player.LSDistance(safePath.Intersection.Point) > 75)
                    {
                        ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                    }
                }
                FollowPath = true;
                args.Process = false;
            }
            else if(safePath.IsSafe && args.Order != GameObjectOrder.AttackUnit)
            {
                FollowPath = false;
            }

            //AutoAttacks.
            if (!safePath.IsSafe && args.Order == GameObjectOrder.AttackUnit)
            {
                var target = args.Target;
                if (target != null && target.IsValid<Obj_AI_Base>() && target.IsVisible)
                {
                    //Out of attack range.
                    if (PlayerPosition.LSDistance(((Obj_AI_Base)target).ServerPosition) >
                        ObjectManager.Player.AttackRange + ObjectManager.Player.BoundingRadius +
                        target.BoundingRadius)
                    {
                        if (safePath.Intersection.Valid)
                        {
                            ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                        }
                        args.Process = false;
                    }
                }
            }
        }
コード例 #4
0
ファイル: Evade.cs プロジェクト: Deprive/Private
        /// <summary>
        /// Used to block the movement to avoid entering in dangerous areas.
        /// </summary>
        /// 
        private static void ObjAiHeroOnOnIssueOrder(Obj_AI_Base sender, GameObjectIssueOrderEventArgs args)
        {
            if (!sender.IsMe)
            {
                return;
            }

            //Don't block the movement packets if cant find an evade point.
            if (NoSolutionFound)
            {
                return;
            }

            //Evading disabled
            if (!Config.Menu.Item("Enabled").GetValue<KeyBind>().Active)
            {
                return;
            }

            //Spell Shielded
            if (IsSpellShielded(ObjectManager.Player))
            {
                return;
            }

            if (args.Order == GameObjectOrder.MoveTo)
            {
                EvadeToPoint.X = args.TargetPosition.X;
                EvadeToPoint.Y = args.TargetPosition.Y;
            }
            else
            {
                EvadeToPoint.X = 0;
                EvadeToPoint.Y = 0;
            }
            
            var myPath =
                ObjectManager.Player.GetPath(
                    new Vector3(args.TargetPosition.X, args.TargetPosition.Y, ObjectManager.Player.ServerPosition.Z)).To2DList();
            var safeResult = IsSafe(ObjectManager.Player.ServerPosition.To2D());


            //If we are evading:
            if (Evading || !safeResult.IsSafe)
            {
                var rcSafePath = IsSafePath(myPath, Config.EvadingRouteChangeTimeOffset);
                if (args.Order == GameObjectOrder.MoveTo)
                {
                    if (Evading &&
                        Utils.TickCount - Config.LastEvadePointChangeT > Config.EvadePointChangeInterval)
                    {
                        //Update the evade point to the closest one:
                        var points = Evader.GetEvadePoints(-1, 0, false, true);
                        if (points.Count > 0)
                        {
                            var to = new Vector2(args.TargetPosition.X, args.TargetPosition.Y);
                            EvadePoint = to.Closest(points);
                            Evading = true;
                            Config.LastEvadePointChangeT = Utils.TickCount;
                        }
                    }

                    //If the path is safe let the user follow it.
                    if (rcSafePath.IsSafe && IsSafe(myPath[myPath.Count - 1]).IsSafe && args.Order == GameObjectOrder.MoveTo)
                    {
                        EvadePoint = myPath[myPath.Count - 1];
                        Evading = true;
                    }
                }

                //Block the packets if we are evading or not safe.
                args.Process = false;
                return;
            }

            var safePath = IsSafePath(myPath, Config.CrossingTimeOffset);

            //Not evading, outside the skillshots.
            //The path is not safe, stop in the intersection point.
            if (!safePath.IsSafe && args.Order != GameObjectOrder.AttackUnit)
            {
                if (safePath.Intersection.Valid)
                {
                    if (ObjectManager.Player.Distance(safePath.Intersection.Point) > 75)
                    {
                        ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                    }
                    else
                    {
                        if (/*DetectedSkillshots.Count == 1 &&*/ Utils.TickCount - lastSMovePacketT > 400)
                        {
                            lastSMovePacketT = Utils.TickCount;

                            var perpendicular =
                                (ObjectManager.Player.ServerPosition.To2D() - safePath.Intersection.Point)
                                    .Normalized();
                            var direction = perpendicular.Perpendicular();

                            var p = ObjectManager.Player.ServerPosition.To2D() + 1 * perpendicular + 150 * direction;
                            var p2 = ObjectManager.Player.ServerPosition.To2D() + 1 * perpendicular - 150 * direction;

                            if (!IsSafePath(ObjectManager.Player.GetPath(p.To3D()).To2DList(), 100).IsSafe)
                            {
                                p = new Vector2();
                            }

                            if (!IsSafePath(ObjectManager.Player.GetPath(p2.To3D()).To2DList(), 100).IsSafe)
                            {
                                p2 = new Vector2();
                            }

                            EvadeToPoint2 = (p.IsValid() && (p.Distance(EvadeToPoint) < p2.Distance(EvadeToPoint))) ? p : p2;

                            if (EvadeToPoint2.IsValid())
                            {
                                ObjectManager.Player.SendMovePacket(EvadeToPoint2);
                            }
                        }
                    }
                }
                args.Process = false;
            }

            //AutoAttacks.
            if (!safePath.IsSafe && args.Order == GameObjectOrder.AttackUnit)
            {
                var target = args.Target;
                if (target != null && target.IsValid<Obj_AI_Base>() && target.IsVisible)
                {
                    //Out of attack range.
                    if (ObjectManager.Player.ServerPosition.To2D().Distance(((Obj_AI_Base)target).ServerPosition) >
                        ObjectManager.Player.AttackRange + ObjectManager.Player.BoundingRadius +
                        target.BoundingRadius)
                    {
                        if (safePath.Intersection.Valid)
                        {
                            ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                        }
                        args.Process = false;
                    }
                }
            }
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: guskate/LeagueSharp
        /// <summary>
        /// Used to block the movement to avoid entering in dangerous areas.
        /// </summary>
        private static void Game_OnGameSendPacket(GamePacketEventArgs args)
        {
            //Move Packet
            if (args.PacketData[0] == Packet.C2S.Move.Header)
            {
                //Don't block the movement packets if cant find an evade point.
                if (NoSolutionFound)
                {
                    return;
                }

                //Evading disabled
                if (!Config.Menu.Item("Enabled").GetValue<KeyBind>().Active)
                {
                    return;
                }

                if (EvadeSpellDatabase.Spells.Any(evadeSpell => evadeSpell.Name == "Walking" && !evadeSpell.Enabled))
                {
                    return;
                }

                //Spell Shielded
                if (IsSpellShielded(ObjectManager.Player))
                {
                    return;
                }

                var decodedPacket = Packet.C2S.Move.Decoded(args.PacketData);

                if(decodedPacket.UnitNetworkId != ObjectManager.Player.NetworkId) return;

                if (decodedPacket.MoveType == 2)
                {
                    EvadeToPoint.X = decodedPacket.X;
                    EvadeToPoint.Y = decodedPacket.Y;
                }
                else
                {
                    EvadeToPoint.X = 0;
                    EvadeToPoint.Y = 0;
                }

                var myPath =
                    ObjectManager.Player.GetPath(
                        new Vector3(decodedPacket.X, decodedPacket.Y, ObjectManager.Player.ServerPosition.Z)).To2DList();
                var safeResult = IsSafe(ObjectManager.Player.ServerPosition.To2D());

                //If we are evading:
                if (Evading || !safeResult.IsSafe)
                {
                    var rcSafePath = IsSafePath(myPath, Config.EvadingRouteChangeTimeOffset);
                    if (decodedPacket.MoveType == 2)
                    {
                        if (Evading &&
                            Environment.TickCount - Config.LastEvadePointChangeT > Config.EvadePointChangeInterval)
                        {
                            //Update the evade point to the closest one:
                            var points = Evader.GetEvadePoints(-1, 0, false, true);
                            if (points.Count > 0)
                            {
                                var to = new Vector2(decodedPacket.X, decodedPacket.Y);
                                EvadePoint = to.Closest(points);
                                Evading = true;
                                Config.LastEvadePointChangeT = Environment.TickCount;
                            }
                        }

                        //If the path is safe let the user follow it.
                        if (rcSafePath.IsSafe && IsSafe(myPath[myPath.Count - 1]).IsSafe && decodedPacket.MoveType == 2)
                        {
                            EvadePoint = myPath[myPath.Count - 1];
                            Evading = true;
                        }
                    }

                    //Block the packets if we are evading or not safe.
                    args.Process = false;
                    return;
                }

                var safePath = IsSafePath(myPath, Config.CrossingTimeOffset);

                //Not evading, outside the skillshots.
                //The path is not safe, stop in the intersection point.
                if (!safePath.IsSafe && decodedPacket.MoveType != 3)
                {
                    if (safePath.Intersection.Valid)
                    {
                        if (ObjectManager.Player.Distance(safePath.Intersection.Point) > 75)
                        {
                            ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                        }
                        else
                        {
                            if (/*DetectedSkillshots.Count == 1 &&*/ Environment.TickCount - LastSMovePacketT > 400)
                            {
                                LastSMovePacketT = Environment.TickCount;

                                    var perpendicular =
                                        (ObjectManager.Player.ServerPosition.To2D() - safePath.Intersection.Point)
                                            .Normalized();
                                    var direction = perpendicular.Perpendicular();

                                    var p = ObjectManager.Player.ServerPosition.To2D() + 1 * perpendicular + 150 * direction;
                                    var p2 = ObjectManager.Player.ServerPosition.To2D() + 1 * perpendicular - 150 * direction;

                                    if (!IsSafePath(ObjectManager.Player.GetPath(p.To3D()).To2DList(), 100).IsSafe)
                                    {
                                        p = new Vector2();
                                    }

                                    if (!IsSafePath(ObjectManager.Player.GetPath(p2.To3D()).To2DList(), 100).IsSafe)
                                    {
                                        p2 = new Vector2();
                                    }

                                    EvadeToPoint2 = (p.IsValid() && (p.Distance(EvadeToPoint) < p2.Distance(EvadeToPoint))) ? p : p2;

                                    if (EvadeToPoint2.IsValid())
                                    {
                                        ObjectManager.Player.SendMovePacket(EvadeToPoint2);
                                    }
                            }
                        }
                    }
                    args.Process = false;
                }

                //AutoAttacks.
                if (!safePath.IsSafe && decodedPacket.MoveType == 3)
                {
                    var target = ObjectManager.GetUnitByNetworkId<Obj_AI_Base>(decodedPacket.TargetNetworkId);
                    if (target != null && target.IsValid && target.IsVisible)
                    {
                        //Out of attack range.
                        if (ObjectManager.Player.ServerPosition.To2D().Distance(target.ServerPosition) >
                            ObjectManager.Player.AttackRange + ObjectManager.Player.BoundingRadius +
                            target.BoundingRadius)
                        {
                            if (safePath.Intersection.Valid)
                            {
                                ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                            }
                            args.Process = false;
                        }
                    }
                }
            }

            if (args.PacketData[0] == Packet.C2S.Cast.Header)
            {
                if (Packet.C2S.Cast.Decoded(args.PacketData).Slot == SpellSlot.Recall)
                {
                    EvadeToPoint = new Vector2();
                }
            }
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: JizzHub/LeagueSharp
        private static void TryToEvade(List<Skillshot> HitBy, Vector2 to)
        {
            var dangerLevel = 0;

            foreach (var skillshot in HitBy)
            {
                dangerLevel = Math.Max(dangerLevel, skillshot.GetValue<Slider>("DangerLevel").Value);
            }

            foreach (var evadeSpell in EvadeSpellDatabase.Spells)
            {
                if (evadeSpell.Enabled && evadeSpell.DangerLevel <= dangerLevel)
                {
                    //SpellShields
                    if (evadeSpell.IsSpellShield &&
                        ObjectManager.Player.Spellbook.CanUseSpell(evadeSpell.Slot) == SpellState.Ready)
                    {
                        if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                        {
                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, EvadePoint.To3D());
                        }

                        //Let the user move freely inside the skillshot.
                        NoSolutionFound = true;
                        return;
                    }

                    //Walking
                    if (evadeSpell.Name == "Walking")
                    {
                        var points = Evader.GetEvadePoints();
                        if (points.Count > 0)
                        {
                            EvadePoint = to.Closest(points);
                            Evading = true;
                            return;
                        }
                    }

                    if ((evadeSpell.CheckSpellName == "" ||
                         ObjectManager.Player.Spellbook.GetSpell(evadeSpell.Slot).Name == evadeSpell.CheckSpellName) &&
                        ((evadeSpell.IsSummonerSpell &&
                          ObjectManager.Player.SummonerSpellbook.CanUseSpell(evadeSpell.Slot) == SpellState.Ready) ||
                         (!evadeSpell.IsSummonerSpell &&
                          ObjectManager.Player.Spellbook.CanUseSpell(evadeSpell.Slot) == SpellState.Ready)))
                    {
                        //Dashes
                        if (evadeSpell.IsDash)
                        {
                            //Targetted dashes
                            if (evadeSpell.IsTargetted)//Lesinga W.
                            {
                                //Todo.
                            }

                                //Skillshot type dashes.
                            else
                            {
                                var points = Evader.GetEvadePoints(evadeSpell.Speed, evadeSpell.Delay, false);

                                // Remove the points out of range
                                points.RemoveAll(
                                    item => item.Distance(ObjectManager.Player.ServerPosition) > evadeSpell.MaxRange);

                                //If the spell has a fixed range (Vaynes Q), calculate the real dashing location. TODO: take into account walls in the future.
                                if (evadeSpell.FixedRange)
                                {
                                    for (var i = 0; i < points.Count; i++)
                                    {
                                        points[i] = ObjectManager.Player.ServerPosition.To2D() +
                                                    evadeSpell.MaxRange*
                                                    (points[i] - ObjectManager.Player.ServerPosition.To2D()).Normalized();
                                    }
                                }

                                if (points.Count > 0)
                                {
                                    EvadePoint = to.Closest(points);
                                    Evading = true;

                                    if (!evadeSpell.Invert)
                                    {
                                        if (evadeSpell.RequiresPreMove)
                                        {
                                            ObjectManager.Player.SendMovePacket(EvadePoint);
                                            var theSpell = evadeSpell;
                                            Utility.DelayAction.Add(Game.Ping/2 + 100, delegate
                                            {
                                                ObjectManager.Player.Spellbook.CastSpell(theSpell.Slot, EvadePoint.To3D());
                                            });
                                        }
                                        else
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, EvadePoint.To3D());
                                        }
                                    }
                                    else
                                    {
                                        var castPoint = ObjectManager.Player.ServerPosition.To2D() -
                                                        (EvadePoint - ObjectManager.Player.ServerPosition.To2D());
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, castPoint.To3D());
                                    }

                                    return;
                                }
                            }
                        }

                        //Blinks
                        if (evadeSpell.IsBlink)
                        {
                            //Targetted blinks
                            if (evadeSpell.IsTargetted)
                            {
                                var targets = Evader.GetEvadeTargets(evadeSpell.ValidTargets, int.MaxValue,
                                    evadeSpell.Delay,
                                    evadeSpell.MaxRange, true, false);

                                if (targets.Count > 0)
                                {
                                    if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                    {
                                        var closestTarget = Utils.Closest(targets, to);
                                        EvadePoint = closestTarget.ServerPosition.To2D();
                                        Evading = true;

                                        if (evadeSpell.IsSummonerSpell)
                                        {
                                            ObjectManager.Player.SummonerSpellbook.CastSpell(evadeSpell.Slot,
                                                closestTarget);
                                        }
                                        else
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                                        }
                                    }

                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }
                            }

                                //Skillshot type blinks.
                            else
                            {
                                var points = Evader.GetEvadePoints(int.MaxValue, evadeSpell.Delay, true);

                                // Remove the points out of range
                                points.RemoveAll(
                                    item => item.Distance(ObjectManager.Player.ServerPosition) > evadeSpell.MaxRange);

                                //Dont blink just to the edge:
                                for (var i = 0; i < points.Count; i++)
                                {
                                    var k = (int) (evadeSpell.MaxRange -
                                                   ObjectManager.Player.ServerPosition.To2D().Distance(points[i]));

                                    k = k - new Random(Environment.TickCount).Next(k);
                                    var extended = points[i] +
                                                   k*
                                                   (points[i] - ObjectManager.Player.ServerPosition.To2D()).Normalized();
                                    if (IsSafe(extended).IsSafe)
                                    {
                                        points[i] = extended;
                                    }
                                }

                                if (points.Count > 0)
                                {
                                    if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                    {
                                        EvadePoint = to.Closest(points);
                                        Evading = true;
                                        if (evadeSpell.IsSummonerSpell)
                                        {
                                            ObjectManager.Player.SummonerSpellbook.CastSpell(evadeSpell.Slot,
                                                EvadePoint.To3D());
                                        }
                                        else
                                        {
                                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, EvadePoint.To3D());
                                        }
                                    }

                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }
                            }
                        }

                        //Invulnerabilities, like Fizz's E
                        if (evadeSpell.IsInvulnerability)
                        {
                            if (evadeSpell.IsTargetted)
                            {
                                var targets = Evader.GetEvadeTargets(evadeSpell.ValidTargets, int.MaxValue, 0, evadeSpell.MaxRange, true, false, true);

                                if (targets.Count > 0)
                                {
                                    if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                    {
                                        var closestTarget = Utils.Closest(targets, to);
                                        EvadePoint = closestTarget.ServerPosition.To2D();
                                        Evading = true;
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                                    }

                                    //Let the user move freely inside the skillshot.
                                    NoSolutionFound = true;
                                    return;
                                }

                            }
                            else
                            {
                                if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                                {
                                    if (evadeSpell.SelfCast)
                                    {
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot);
                                    }
                                    else
                                    {
                                        ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, ObjectManager.Player.ServerPosition);
                                    }
                                }
                            }

                            //Let the user move freely inside the skillshot.
                            NoSolutionFound = true;
                            return;
                        }
                    }

                    //Zhonyas
                    if (evadeSpell.Name == "Zhonyas" && (Items.CanUseItem("ZhonyasHourglass")))
                    {
                        if (IsAboutToHit(ObjectManager.Player, 100))
                        {
                            Items.UseItem("ZhonyasHourglass");
                        }

                        //Let the user move freely inside the skillshot.
                        NoSolutionFound = true;

                        return;
                    }

                    //Shields
                    if (evadeSpell.IsShield &&
                        ObjectManager.Player.Spellbook.CanUseSpell(evadeSpell.Slot) == SpellState.Ready)
                    {
                        if (IsAboutToHit(ObjectManager.Player, evadeSpell.Delay))
                        {
                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, ObjectManager.Player);
                        }

                        //Let the user move freely inside the skillshot.
                        NoSolutionFound = true;
                        return;
                    }
                }
            }

            NoSolutionFound = true;
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: ReSrReCTion/elobuddy
        /// <summary>
        /// Used to block the movement to avoid entering in dangerous areas.
        /// </summary>
        /// 
        private static void ObjAiHeroOnOnIssueOrder(Obj_AI_Base sender, PlayerIssueOrderEventArgs args)
        {
            if (!sender.IsMe)
            {
                return;
            }

            //Don't block the movement packets if cant find an evade point.
            if (NoSolutionFound)
            {
                return;
            }

            //Evading disabled
            if (!Config.Menu["Enabled"].Cast<KeyBind>().CurrentValue)
            {
                return;
            }

            if (EvadeSpellDatabase.Spells.Any(evadeSpell => evadeSpell.Name == "Walking" && !evadeSpell.Enabled))
            {
                return;
            }

            //Spell Shielded
            if (ObjectManager.Player.MagicShield > 0)
            {
                return;
            }

            if (PlayerChampionName == "Olaf" && Config.misc["DisableEvadeForOlafR"].Cast<CheckBox>().CurrentValue && ObjectManager.Player.HasBuff("OlafRagnarok"))
            {
                return;
            }

            if (args.Order == GameObjectOrder.MoveTo || args.Order == GameObjectOrder.AttackTo)
            {
                EvadeToPoint.X = args.TargetPosition.X;
                EvadeToPoint.Y = args.TargetPosition.Y;
                Keepfollowing = false;
                FollowPath = false;
            }
            else
            {
                EvadeToPoint.X = 0;
                EvadeToPoint.Y = 0;
            }

            var myPath =
                ObjectManager.Player.GetPath(
                    new Vector3(args.TargetPosition.X, args.TargetPosition.Y, ObjectManager.Player.ServerPosition.Z)).To2DList();
            var safeResult = IsSafe(PlayerPosition);

            // Check for the unnessasary moving
            if (Evading || safeResult.IsSafe)
            {
                Evading = false;
                NoSolutionFound = true;
            }

            //If we are evading:
            if (Evading || !safeResult.IsSafe)
            {
                var rcSafePath = IsSafePath(myPath, Config.EvadingRouteChangeTimeOffset);
                if (args.Order == GameObjectOrder.MoveTo)
                {
                    if (Evading &&
                        Utils.TickCount - Config.LastEvadePointChangeT > Config.EvadePointChangeInterval)
                    {
                        //Update the evade point to the closest one:
                        var points = Evader.GetEvadePoints(-1, 0, false, true);
                        if (points.Count > 0)
                        {
                            var to = new Vector2(args.TargetPosition.X, args.TargetPosition.Y);
                            EvadePoint = to.Closest(points);
                            Evading = true;
                            Config.LastEvadePointChangeT = Utils.TickCount;
                        }
                    }

                    //If the path is safe let the user follow it.
                    if (rcSafePath.IsSafe && IsSafe(myPath[myPath.Count - 1]).IsSafe && args.Order == GameObjectOrder.MoveTo)
                    {
                        EvadePoint = myPath[myPath.Count - 1];
                        Evading = true;
                    }
                }

                //Block the packets if we are evading or not safe.
                args.Process = false;
                return;
            }

            var safePath = IsSafePath(myPath, Config.CrossingTimeOffset);

            //Not evading, outside the skillshots.
            //The path is not safe, stop in the intersection point.
            if (!safePath.IsSafe && args.Order != GameObjectOrder.AttackUnit)
            {
                if (safePath.Intersection.Valid)
                {
                    if (ObjectManager.Player.Distance(safePath.Intersection.Point) > 75)
                    {
                        ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                    }
                }
                FollowPath = true;
                args.Process = false;
            }
            else if(safePath.IsSafe && args.Order != GameObjectOrder.AttackUnit)
            {
                FollowPath = false;
            }

            //AutoAttacks.
            if (!safePath.IsSafe && args.Order == GameObjectOrder.AttackUnit)
            {
                var target = args.Target;
                if (target != null && target.IsValid && target.IsVisible)
                {
                    //Out of attack range.
                    if (PlayerPosition.Distance(((Obj_AI_Base)target).ServerPosition) >
                        ObjectManager.Player.AttackRange + ObjectManager.Player.BoundingRadius +
                        target.BoundingRadius)
                    {
                        if (safePath.Intersection.Valid)
                        {
                            ObjectManager.Player.SendMovePacket(safePath.Intersection.Point);
                        }
                        args.Process = false;
                    }
                }
            }
        }
コード例 #8
0
ファイル: EvadeManager.cs プロジェクト: Kysamaa/EloBuddy
            private static void TryToEvade(List<Skillshot> hitBy, Vector2 to)
            {
                var dangerLevel =
                    hitBy.Select(i => Manager.MenuManager.EDLVL.Cast<Slider>().CurrentValue) //championmenu["DangerLevel"].Cast<Slider>().CurrentValue
                        .Concat(new[] { 0 })
                        .Max();
                foreach (var evadeSpell in
                    EvadeSpellDatabase.Spells.Where(i => i.Enabled && i.DangerLevel <= dangerLevel && i.IsReady)
                        .OrderBy(i => i.DangerLevel))
                {
                    if (evadeSpell.EvadeType == EvadeTypes.Dash && evadeSpell.CastType == CastTypes.Target)
                    {
                        var targets =
                            GetEvadeTargets(evadeSpell)
                                .Where(
                                    i =>
                                    IsSafePoint(Extensions.PosAfterE(i).To2D()).IsSafe
                                    && (!Extensions.PosAfterE(i).IsUnderTurret()) || Manager.MenuManager.EvadeMenu["ETower"].Cast<CheckBox>().CurrentValue)
                                .ToList();
                        if (targets.Count > 0)
                        {
                            var closestTarget = targets.MinOrDefault(i => Extensions.PosAfterE(i).To2D().Distance(to));
                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, closestTarget);
                            return;
                        }
                    }
                    if (evadeSpell.EvadeType == EvadeTypes.WindWall
                        && hitBy.Where(
                            i =>
                            i.SpellData.CollisionObjects.Contains(CollisionObjectTypes.YasuoWall)
                            && i.IsAboutToHit(
                                150 + evadeSpell.Delay - Manager.MenuManager.EvadeMenu["WDelay"].Cast<Slider>().CurrentValue,
                                ObjectManager.Player))
                               .OrderByDescending(
                                   i => Manager.MenuManager.EDLVL.Cast<Slider>().CurrentValue)
                               .Any(
                                   i =>
                                   ObjectManager.Player.Spellbook.CastSpell(
                                       evadeSpell.Slot,
                                       ObjectManager.Player.ServerPosition.Extend(i.Start.To3D(), 100).To3D(), true)))
                    {
                        return;
                    }
                    if (evadeSpell.EvadeType == EvadeTypes.Dash && evadeSpell.CastType == CastTypes.Position)
                    {
                        var points = GetEvadePoints(evadeSpell.Speed, evadeSpell.Delay, false);

                        points.RemoveAll(
                            item => item.Distance(ObjectManager.Player.ServerPosition) > evadeSpell.MaxRange);

                        if (evadeSpell.FixedRange)
                        {
                            for (var i = 0; i < points.Count; i++)
                            {
                                points[i] = ObjectManager.Player.Position
                                    .Extend(points[i], evadeSpell.MaxRange);
                            }

                            for (var i = points.Count - 1; i > 0; i--)
                            {
                                if (!IsSafePoint(points[i]).IsSafe)
                                {
                                    points.RemoveAt(i);
                                }
                            }
                        }

                        if (points.Count > 0)
                        {
                            var EvadePoint = to.Closest(points);

                            var castPoint = ObjectManager.Player.Position -
                                            (EvadePoint.To3D() - ObjectManager.Player.Position);
                            ObjectManager.Player.Spellbook.CastSpell(evadeSpell.Slot, castPoint);
                        }

                        return;
                    }
                }
            }