Exemple #1
0
        /* handling Plagueborn Horror's */
        private BTNode KaI_AddsBehaviour()
        {
            long _guidForCtm = 0;
            var  adds        = new LeafAction(() =>
            {
                var horrors = tank.ObjectManager.Where(obj =>
                                                       obj.Type == GameObjectType.Unit && obj.EntryID == PlaguebornHorrorId && obj.Health > 0).ToList();

                if (!horrors.Any())
                {
                    return(BTStatus.Success);
                }

                // attack horrors in combat
                var target = horrors.FirstOrDefault(horror => horror.IsInCombat());
                if (target != null)
                {
                    mbox.GroupTargetGuids[0] = target.GUID;
                }

                // step out of puddles (if not tank)
                foreach (var client in mbox.clients.Where(cli => cli != tank))
                {
                    if (client.Player.Auras.Select(aura => aura.auraID).Any(auraId => ToxicWasteIds.Contains(auraId)))
                    {
                        var playerCoords      = client.Player.Coordinates;
                        var finalTargetCoords = playerCoords + new Vector3(2.5f, 0f, 0f);
                        client
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                    }
                }


                return(BTStatus.Running);
            });

            return(adds);
        }
Exemple #2
0
        private BTNode KaI_BossFightBehaviour()
        {
            long _guidForCtm = 0;

            GameObject ick = null;

            var prep = new LeafAction(() =>
            {
                tank.ExecLua("print('KaI bhv ON!')");


                ick = tank.ObjectManager.FirstOrDefault(obj => obj.EntryID == IckId);

                return(ick != null ?  BTStatus.Success : BTStatus.Running);
            });

            var bossDeadCheck = new Decorator((() =>
            {
                return(ick.Health == 0);
            }), new LeafAction(() =>
            {
                return(BTStatus.Success);
            }));

            var nova = new Decorator((() =>
            {
                /* act when Ick casting Poison Nova */
                return(ick.CastingSpellId == 68989);
            }), new LeafAction(() =>
            {
                var targetCoords = ick.Coordinates;

                var desiredDistance = 20;

                foreach (var client in mbox.clients)
                {
                    var playerCoords = client.Player.Coordinates;
                    var diff         = (targetCoords - playerCoords);
                    var distance     = diff.Length();

                    if (distance < desiredDistance)
                    {
                        var adjusted          = ((diff * desiredDistance) / distance);
                        var finalTargetCoords = targetCoords - adjusted;

                        client
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                    }
                }

                return(BTStatus.Failed);
            }));

            var mines = new Decorator((() =>
            {
                return(true);
            }), new LeafAction(() =>
            {
                return(BTStatus.Failed);
            }));

            var pursuit = new Decorator((() =>
            {
                /* act when Ick casting Pursuit */
                return(ick.CastingSpellId == 68987);
            }), new LeafAction(() =>
            {
                var targetCoords = ick.Coordinates;

                var desiredDistance = 20;

                foreach (var client in mbox.clients)
                {
                    var playerCoords = client.Player.Coordinates;
                    var diff         = (targetCoords - playerCoords);
                    var distance     = diff.Length();

                    if (distance < desiredDistance)
                    {
                        var adjusted          = ((diff * desiredDistance) / distance);
                        var finalTargetCoords = targetCoords - adjusted;

                        client
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                    }
                }

                return(BTStatus.Failed);
            }));

            var basic = new Decorator((() =>
            {
                return(true);
            }), new LeafAction(() =>
            {
                mbox.GroupTargetGuids[0] = ick.GUID;

                // step out of puddles (if not tank)
                foreach (var client in mbox.clients.Where(cli => cli != tank))
                {
                    if (client.Player.Auras.Select(aura => aura.auraID).Any(auraId => ToxicWasteIds.Contains(auraId)))
                    {
                        var playerCoords      = client.Player.Coordinates;
                        var finalTargetCoords = playerCoords + new Vector3(2.5f, 0f, 0f);
                        client
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                    }
                }

                return(BTStatus.Failed);
            }));

            var stratSelector = new Selector(bossDeadCheck, nova, mines, pursuit, basic);

            return(new Sequence(false, prep, stratSelector));
        }
            private BTNode MountedCombatBehaviour()
            {
                var  nodes       = new List <BTNode>();
                long _guidForCtm = 0;

                allWarhorses = new LinkedList <GameObject>(mbox.me.ObjectManager.Where(obj =>
                                                                                       obj.Type == GameObjectType.Unit && totch.GetName(mbox.me.ControlInterface, obj) == vehicleName));
                int[] defendSpellIds = new[] { 62552 };

                for (int i = 0; i < mbox.clients.Count(); i++)
                {
                    var client = mbox.clients.ElementAt(i);
                    int originalClientWepId = GetMainHandId(client);
                    var associatedVeh       = allWarhorses.First.Value;
                    allWarhorses.RemoveFirst();
                    squadData.Add(client, new PlayerData
                    {
                        warhorseGuid     = associatedVeh.GUID,
                        originalWeaponId = originalClientWepId
                    });
                }

                var equipLances = new LeafAction((() =>
                {
                    mbox.me.ExecLua("print('Running mounted combat now')");
                    bool allEquipped = true;
                    foreach (var entry in squadData)
                    {
                        entry.Key.ExecLua("EquipItemByName('Argent Lance')");

                        allEquipped &= GetMainHandId(entry.Key) == argentLanceId;
                    }

                    return(allEquipped ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(equipLances);

                var goToVehicles = new LeafAction((() =>
                {
                    bool allCloseToVehicles = true;
                    foreach (var entry in squadData)
                    {
                        var target = entry.Key.ObjectManager.First(obj => obj.GUID == entry.Value.warhorseGuid).Coordinates;

                        entry.Key
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            entry.Key.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref target, 1f);

                        allCloseToVehicles &= entry.Key.Player.Coordinates.Distance(target) < 5f;
                    }

                    return(allCloseToVehicles ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(goToVehicles);

                Func <Client, bool> IsInVehicle = (player) =>
                {
                    var vehicleCheck = "canExit = CanExitVehicle()";
                    var res          = player.ExecLuaAndGetResult(vehicleCheck, "canExit");
                    return(!String.IsNullOrEmpty(res));
                };

                var enterVehicles = new LeafAction((() =>
                {
                    var allEnteredVehicle = true;
                    foreach (var entry in squadData)
                    {
                        var target = entry.Key.ObjectManager.First(obj => obj.GUID == entry.Value.warhorseGuid);

                        entry.Key.ControlInterface.remoteControl.InteractUnit(target.GetAddress());

                        allEnteredVehicle &= IsInVehicle(entry.Key);
                    }

                    return(allEnteredVehicle ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(enterVehicles);

                var goToEventStarter = new LeafAction((() =>
                {
                    var allCloseToStarterNPC = true;


                    GameObject targetObj = null;
                    foreach (var eventStarterName in eventStarterNames)
                    {
                        targetObj = mbox.me.ObjectManager
                                    .FirstOrDefault(obj => obj.Type == GameObjectType.Unit && totch.GetName(mbox.me.ControlInterface, obj) == eventStarterName);
                        if (targetObj != null)
                        {
                            break;
                        }
                    }

                    var target = targetObj.Coordinates;

                    foreach (var entry in squadData)
                    {
                        entry.Key
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            entry.Key.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref target, 1f);


                        var veh = entry.Key.ObjectManager.First(obj => obj.GUID == entry.Value.warhorseGuid);
                        allCloseToStarterNPC &= veh.Coordinates.Distance(target) < 5f;
                    }

                    return(allCloseToStarterNPC ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(goToEventStarter);

                mbox.me.LuaEventListener.Bind("GOSSIP_CLOSED", args =>
                {
                    eventStarted = true;
                    mbox.me.LuaEventListener.Unbind("GOSSIP_CLOSED");
                });

                GameObject targetObj  = null;
                var        startEvent = new LeafAction((() =>
                {
                    foreach (var eventStarterName in eventStarterNames)
                    {
                        if (targetObj != null)
                        {
                            break;
                        }

                        targetObj = mbox.me.ObjectManager
                                    .FirstOrDefault(obj => obj.Type == GameObjectType.Unit && totch.GetName(mbox.me.ControlInterface, obj) == eventStarterName);
                    }

                    mbox.me.ControlInterface.remoteControl.InteractUnit(targetObj.GetAddress());

                    Thread.Sleep(100);

                    mbox.me.ExecLua("SelectGossipOption(2)");

                    return(eventStarted ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(startEvent);

                var mountedCombat = new LeafAction((() =>
                {
                    var allVehiclesDisappeared = true;
                    var threateners = SelectThreateningUnitsForMountedCombat(mbox.me.ControlInterface, mbox.me.ObjectManager);
                    foreach (var key in squadData.Keys.ToList())
                    {
                        var myVehicle = key.ObjectManager.FirstOrDefault(obj => obj.GUID == squadData[key].warhorseGuid);
                        if (myVehicle == null)
                        {
                            continue;
                        }
                        else
                        {
                            allVehiclesDisappeared = false;
                        }



                        // ensure 3 stacks of Defend
                        var myVehicleAuras = myVehicle.Auras;
                        Aura?defendAura = null;
                        foreach (var aura in myVehicleAuras)
                        {
                            if (defendSpellIds.Contains(aura.auraID))
                            {
                                defendAura = aura;
                                break;
                            }
                        }

                        if (defendAura == null || defendAura.Value.stackCount != 3)
                        {
                            key.ExecLua("CastSpellByName('Defend')");
                        }


                        // get to new mount, when low health or warhorse dead
                        if (myVehicle.HealthPct < 35)
                        {
                            if (allWarhorses.Any())
                            {
                                var myPlayerCoords = Vector3.Zero;
                                if (myVehicle.Health == 0)
                                {
                                    myPlayerCoords = key.Player.Coordinates;
                                }
                                else
                                {
                                    myPlayerCoords = myVehicle.Coordinates;
                                }

                                var freeClosestWarhorse = allWarhorses.Aggregate(
                                    (unit1, unit2) => unit1.Coordinates.Distance(myPlayerCoords) < unit2.Coordinates.Distance(myPlayerCoords) ? unit1 : unit2);
                                var freeWarhorseCoords = freeClosestWarhorse.Coordinates;

                                if (myPlayerCoords.Distance(freeWarhorseCoords) < 3f && !myVehicle.IsMoving())
                                {
                                    var localizedWarhorse =
                                        key.ObjectManager.First(obj => obj.GUID == freeClosestWarhorse.GUID);
                                    key.ControlInterface.remoteControl.InteractUnit(localizedWarhorse.GetAddress());
                                    allWarhorses.Remove(freeClosestWarhorse);

                                    var entryToModify = squadData[key];
                                    entryToModify.warhorseGuid = localizedWarhorse.GUID;
                                    squadData[key] = entryToModify;
                                }
                                else
                                {
                                    key
                                    .ControlInterface
                                    .remoteControl
                                    .CGPlayer_C__ClickToMove(
                                        key.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref freeWarhorseCoords, 1f);
                                }
                            }
                            else
                            {
                                Console.WriteLine("No warhorses left!");
                            }
                            continue;
                        }

                        if (!threateners.Any())
                        {
                            continue;
                        }

                        // get threatener object local to given client obj manager
                        var threatener = key.ObjectManager.First(obj => obj.GUID == threateners.First().GUID);

                        var myVehicleCoords = myVehicle.Coordinates;
                        var target = threatener.Coordinates;

                        // always try to go to gather point
                        target = totch.gatherPoint;

                        float dist = target.Distance(myVehicle.Coordinates);
                        if (dist > 24)
                        {
                            // get close, if far
                            key
                            .ControlInterface
                            .remoteControl
                            .CGPlayer_C__ClickToMove(
                                key.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref target, 1f);
                        }

                        var bouncePoint = target - (Vector3.Random() * 5);

                        key
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            key.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref bouncePoint, 1f);

                        // face
                        float angle = myVehicleCoords.AngleBetween(target);
                        key.ControlInterface.remoteControl.CGPlayer_C__ClickToMove(
                            key.Player.GetAddress(), ClickToMoveType.Face, ref _guidForCtm, ref target, angle);

                        key.ControlInterface.remoteControl.SelectUnit(threatener.GUID);

                        key.ExecLua("CastSpellByName('Charge')");
                        key.ExecLua("CastSpellByName('Thrust')");
                    }

                    return(allVehiclesDisappeared ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(mountedCombat);

                Func <Client, int, bool> FinishUpCheck = (player, origWepId) =>
                {
                    var vehicleCheck = "canExit = CanExitVehicle()";
                    var res          = player.ExecLuaAndGetResult(vehicleCheck, "canExit");

                    var vehicleExited        = String.IsNullOrEmpty(res);
                    var equippedOriginalItem = GetMainHandId(player) == origWepId;
                    var atCenter             = player.Player.Coordinates.Distance(totch.gatherPoint) < 3f;

                    return(vehicleExited && equippedOriginalItem && atCenter);
                };

                var finishUp = new LeafAction((() =>
                {
                    bool allFinished = true;
                    foreach (var entry in squadData)
                    {
                        entry.Key.ExecLua($"VehicleExit()");
                        entry.Key.ExecLua($"EquipItemByName({entry.Value.originalWeaponId})");
                        entry.Key
                        .ControlInterface
                        .remoteControl
                        .CGPlayer_C__ClickToMove(
                            entry.Key.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref totch.gatherPoint, 1f);

                        allFinished &= FinishUpCheck(entry.Key, entry.Value.originalWeaponId);
                    }

                    return(allFinished ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(finishUp);

                return(new Sequence(false, nodes.ToArray()));
            }
            private List <BTNode> ConfessorPaletressBehaviour()
            {
                var nodes = new List <BTNode>();

                GameObject memoryMonster = null;

                var shaman = mbox.clients.FirstOrDefault(client =>
                                                         client.Player.UnitClass == UnitClass.Shaman);
                var pala = mbox.clients.FirstOrDefault(client =>
                                                       client.Player.UnitClass == UnitClass.Paladin);
                var priest = mbox.clients.FirstOrDefault(client =>
                                                         client.Player.UnitClass == UnitClass.Priest);

                var common = new LeafAction((() =>
                {
                    if (paletress == null)
                    {
                        paletress = mbox.me.ObjectManager.FirstOrDefault(obj =>
                                                                         obj.Type == GameObjectType.Unit && totch.GetName(mbox.me.ControlInterface, obj) == PaletressName);

                        if (paletress != null)
                        {
                            paletressGUID = paletress.GUID;
                        }
                    }

                    // ensure tremor totem
                    if (!mbox.me.ObjectManager.Any(obj => obj.EntryID == TremorTotem))
                    {
                        if (shaman != null && shaman.Player.HealthPct > 0)
                        {
                            shaman.EnqueuePrioritySpellCast(
                                new SpellCast
                            {
                                Coordinates = null,
                                SpellName = "Tremor Totem",
                                TargetGUID = 0
                            }
                                );
                            Thread.Sleep(1000);
                        }
                    }

                    // cleanse Paletress's debuffs
                    int lowPlayerCount = 0;
                    foreach (var player in mbox.clients.Select(cli => cli.Player).Where(pla => pla.HealthPct > 0))
                    {
                        if (player.HealthPct < 50)
                        {
                            lowPlayerCount++;
                        }

                        foreach (var aura in player.Auras)
                        {
                            if (PaletressDebuffIds.Contains(aura.auraID))
                            {
                                if (pala != null && pala.Player.HealthPct > 0)
                                {
                                    pala.EnqueuePrioritySpellCast(
                                        new SpellCast
                                    {
                                        Coordinates = null,
                                        SpellName = "Cleanse",
                                        TargetGUID = player.GUID
                                    }
                                        );
                                    break;
                                }
                            }
                        }
                    }

                    if (lowPlayerCount >= 2)
                    {
                        if (pala != null && pala.Player.HealthPct > 0)
                        {
                            if (!pala.IsOnCooldown("Divine Sacrifice"))
                            {
                                pala.EnqueuePrioritySpellCast(
                                    new SpellCast
                                {
                                    Coordinates = null,
                                    SpellName = "Divine Sacrifice",
                                    TargetGUID = 0
                                }
                                    );
                            }
                        }
                    }

                    return(BTStatus.Success);
                }));

                // Paletress disappeared - end condition
                var paletressGone =
                    new Decorator(
                        (() => { return(!mbox.me.ObjectManager.Any(obj => obj.GUID == paletressGUID)); }),
                        new LeafAction((() =>
                {
                    return(BTStatus.Success);
                })));

                var argentAdds =
                    new Decorator(
                        (() => { return(!totch.IsAttackableByTank(paletress)); }),
                        new LeafAction((() =>
                {
                    foreach (var argentAdd in ArgentAdds)
                    {
                        foreach (var unit in mbox.me.ObjectManager.Where(obj => obj.Type == GameObjectType.Unit && obj.IsInCombat()))
                        {
                            if (argentAdd == unit.EntryID)
                            {
                                mbox.GroupTargetGuids[0] = unit.GUID;
                                goto end;
                            }
                        }
                    }


                    end:
                    return(BTStatus.Failed);
                })));

                var memoryAsTarget = new Decorator((() =>
                {
                    return(paletress.Auras.Select(aura => aura.auraID).Contains(PaletressReflectiveShield));
                }), new LeafAction((() =>
                {
                    if (memoryMonster != null)
                    {
                        mbox.GroupTargetGuids[0] = memoryMonster.GUID;
                        mbox.me.ControlInterface.remoteControl.SelectUnit(memoryMonster.GUID);
                        mbox.me.CastSpellOnGuid(GenericGroupManager.GetTauntAbilityForTankClass(mbox.me.Player.UnitClass), memoryMonster.GUID);

                        foreach (var aura in memoryMonster.Auras)
                        {
                            if (PaletressRenewIds.Contains(aura.auraID))
                            {
                                if (priest != null && priest.Player.HealthPct > 0)
                                {
                                    priest.EnqueuePrioritySpellCast(
                                        new SpellCast
                                    {
                                        Coordinates = null,
                                        SpellName = "Dispel Magic",
                                        TargetGUID = memoryMonster.GUID
                                    }
                                        );
                                    break;
                                }
                            }
                        }

                        if (priest != null && priest.Player.HealthPct > 0)
                        {
                            if (!priest.IsOnCooldown("Power Infusion"))
                            {
                                priest.EnqueuePrioritySpellCast(
                                    new SpellCast
                                {
                                    Coordinates = null,
                                    SpellName = "Power Infusion",
                                    TargetGUID = priest.Player.GUID
                                }
                                    );
                            }
                        }

                        if (shaman != null && shaman.Player.HealthPct > 0)
                        {
                            if (!shaman.IsOnCooldown("Bloodlust"))
                            {
                                shaman.EnqueuePrioritySpellCast(
                                    new SpellCast
                                {
                                    Coordinates = null,
                                    SpellName = "Bloodlust",
                                    TargetGUID = 0
                                }
                                    );
                            }
                        }
                    }
                    else
                    {
                        mbox.GroupTargetGuids[0] = 0;
                        memoryMonster = mbox.me.ObjectManager.FirstOrDefault(obj =>
                                                                             obj.Type == GameObjectType.Unit && totch.GetName(mbox.me.ControlInterface, obj).Contains("Memory"));
                    }

                    return(BTStatus.Failed);
                })));


                var paletressAsTarget = new Decorator((() =>
                {
                    return(totch.IsAttackableByTank(paletress) && !paletress.Auras.Select(aura => aura.auraID).Contains(PaletressReflectiveShield));
                }), new LeafAction((() =>
                {
                    mbox.GroupTargetGuids[0] = paletress.GUID;
                    mbox.me.ControlInterface.remoteControl.SelectUnit(paletress.GUID);
                    mbox.me.CastSpellOnGuid(GenericGroupManager.GetTauntAbilityForTankClass(mbox.me.Player.UnitClass), paletress.GUID);

                    foreach (var aura in paletress.Auras)
                    {
                        if (PaletressRenewIds.Contains(aura.auraID))
                        {
                            var priest = mbox.clients.FirstOrDefault(client =>
                                                                     client.Player.UnitClass == UnitClass.Priest);
                            if (priest != null && priest.Player.HealthPct > 0)
                            {
                                priest.EnqueuePrioritySpellCast(
                                    new SpellCast
                                {
                                    Coordinates = null,
                                    SpellName = "Dispel Magic",
                                    TargetGUID = paletress.GUID
                                }
                                    );
                                break;
                            }
                        }
                    }

                    return(BTStatus.Failed);
                })));


                var select = new Selector(paletressGone, argentAdds, memoryAsTarget, paletressAsTarget);

                nodes.Add(common);
                nodes.Add(select);


                return(nodes);
            }
            private BTNode NormalCombatBehaviour()
            {
                var nodes = new List <BTNode>();

                var getTargets = new LeafAction((() =>
                {
                    mbox.me.ExecLua("print('Running normal combat now')");
                    var units = mbox.me.ObjectManager.Where(obj => obj.Type == GameObjectType.Unit)
                                .Select(unit => new Tuple <string, GameObject>(totch.GetName(mbox.me.ControlInterface, unit), unit));
                    foreach (var championName in GrandChampionsNames)
                    {
                        foreach (var unit in units)
                        {
                            if (unit.Item1 == championName)
                            {
                                GrandChampionsUnits.Add(unit.Item2);
                            }
                        }
                    }


                    return(GrandChampionsUnits.Count == 3 ? BTStatus.Success : BTStatus.Running);
                }));

                nodes.Add(getTargets);

                var prepare = new LeafAction((() =>
                {
                    var needsRegen = false;
                    foreach (var client in mbox.clients)
                    {
                        // if have mana, drink until regenerated
                        if (client.Player.MaxMana != 0)
                        {
                            if (client.Player.ManaPct < 70)
                            {
                                needsRegen = true;
                                if (!mbox.me.HasAura(client.Player, "Drink"))
                                {
                                    client.ExecLua(mbox.UtilScript);
                                    client.ExecLua(
                                        $"filter = function(itemName) return itemName == \"{drink}\" end;" +
                                        $"sfUseInventoryItem(filter)");
                                }
                            }
                        }
                    }

                    if (needsRegen)
                    {
                        return(BTStatus.Running);
                    }

                    return(BTStatus.Success);
                }));

                nodes.Add(prepare);

                long _guidForCtm = 0;
                var  combat      = new LeafAction((() =>
                {
                    // target champion
                    GameObject currentlyTargetedChampion = null;
                    foreach (var champion in GrandChampionsUnits)
                    {
                        if (champion.HealthPct > 0)
                        {
                            currentlyTargetedChampion = champion;
                            mbox.me.ControlInterface.remoteControl.SelectUnit(champion.GUID);
                            mbox.GroupTargetGuids[0] = champion.GUID;
                            break;
                        }
                    }

                    if (currentlyTargetedChampion == null)
                    {
                        return(BTStatus.Success);
                    }


                    var targetCoords = currentlyTargetedChampion.Coordinates;

                    // check for Bladestorm
                    GameObject bladestormingChampion = null;
                    var bladestormCoords = Vector3.Zero;
                    foreach (var champion in GrandChampionsUnits)
                    {
                        if (champion.HealthPct > 0)
                        {
                            foreach (var aura in champion.Auras)
                            {
                                if (aura.auraID == BladestormId)
                                {
                                    bladestormingChampion = champion;
                                    bladestormCoords = bladestormingChampion.Coordinates;
                                    break;
                                }
                            }
                        }
                    }

                    // aggregate threateners
                    _ = totch.grpMgr.Execute();

                    float getCloseDist = 30;
                    float runAwayFromBsDist = 14;
                    foreach (var client in mbox.clients)
                    {
                        var playerCoords = client.Player.Coordinates;
                        var diff = (targetCoords - playerCoords);
                        var distance = diff.Length();

                        // if not tank
                        if (client != totch.tank)
                        {
                            // run away from Bladestorm
                            if (bladestormingChampion != null)
                            {
                                diff = (bladestormCoords - playerCoords);
                                distance = diff.Length();

                                if (distance <= 6)
                                {
                                    var adjusted = ((diff * runAwayFromBsDist) / distance);
                                    var finalTargetCoords = targetCoords - adjusted;
                                    client
                                    .ControlInterface
                                    .remoteControl
                                    .CGPlayer_C__ClickToMove(
                                        client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                                    break;
                                }
                            }

                            // step out of Poison
                            if (client.Player.Auras.Select(aura => aura.auraID).Any(auraId => PoisonBottleIds.Contains(auraId)))
                            {
                                var finalTargetCoords = playerCoords + new Vector3(5f, 0f, 0f);
                                client
                                .ControlInterface
                                .remoteControl
                                .CGPlayer_C__ClickToMove(
                                    client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                                continue;
                            }

                            // get close, if far
                            if (distance > getCloseDist)
                            {
                                var adjusted = ((diff * getCloseDist) / distance);
                                var finalTargetCoords = targetCoords - adjusted;

                                client
                                .ControlInterface
                                .remoteControl
                                .CGPlayer_C__ClickToMove(
                                    client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                            }
                        }
                        else
                        {
                            var tankDist = 4;
                            // as tank, always sit on target
                            var adjusted = ((diff * tankDist) / distance);
                            var finalTargetCoords = targetCoords - adjusted;

                            client
                            .ControlInterface
                            .remoteControl
                            .CGPlayer_C__ClickToMove(
                                client.Player.GetAddress(), ClickToMoveType.Move, ref _guidForCtm, ref finalTargetCoords, 1f);
                        }
                    }

                    return(BTStatus.Running);
                }));

                nodes.Add(combat);

                return(new Sequence(false, nodes.ToArray()));
            }