public bool Cast(PartyHealBuffRule rule)
        {
            if ((rule.NukeType == NukeType.Item ? _data.Inventory.Any(item => item.Value.ItemId == rule.PartyHealBuffId) : true) &&
                (rule.NukeType == NukeType.Skill ? _data.Skills.Any(skill => skill.Value.SkillId == rule.PartyHealBuffId) : true))
            {
                if (rule != null)
                {
                    if (rule.RequiresTarget)
                    {
                        if (rule.ChosenTarget == null || _data.SurroundingPlayers.All(player => player.ObjectId != rule.ChosenTarget.ObjectId))
                        {
                            LogHelper.GetLogger().Debug("Invalid target");
                            return(false);
                        }

                        if (_actionsController.TargetByObjectId(rule.ChosenTarget.ObjectId))
                        {
                            if (rule.NukeType == NukeType.Skill)
                            {
                                _actionsController.UseSkill(rule.PartyHealBuffId, false, false);
                            }
                            else if (rule.NukeType == NukeType.Item)
                            {
                                _actionsController.UseItem(
                                    _data.Inventory.First(item => item.Value.ItemId == rule.PartyHealBuffId).Key, false);
                            }

                            rule.LastUsed = Environment.TickCount;
                            _data.RequestBuffSkillCastStamp = Environment.TickCount;
                            OutOfPartyStamp = Environment.TickCount;
                            return(true);
                        }
                    }
                    else
                    {
                        if (rule.NukeType == NukeType.Skill)
                        {
                            _actionsController.UseSkill(rule.PartyHealBuffId, false, false);
                        }
                        else if (rule.NukeType == NukeType.Item)
                        {
                            _actionsController.UseItem(
                                _data.Inventory.First(item => item.Value.ItemId == rule.PartyHealBuffId).Key, false);
                        }

                        _data.RequestBuffSkillCastStamp = Environment.TickCount;
                        rule.LastUsed   = Environment.TickCount;
                        OutOfPartyStamp = Environment.TickCount;
                        return(true);
                    }
                }
            }

            return(false);
        }
        private void PartyHealBuffBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (((ViewModel)this.DataContext).SelectedBot != null && partyHealBuffBox.SelectedIndex != -1)
            {
                PartyHealRulesListBox.SelectedIndex = -1;
                var newNuke = new PartyHealBuffRule(((ViewModel)this.DataContext).SelectedBot.PlayerData)
                {
                    Enabled  = true,
                    NukeType =
                        (NukeType)((ViewModel)this.DataContext).SelectedBot.Engine.PartyHealBuffHandler.NukeTypeToAdd
                };

                int index  = partyHealBuffBox.SelectedIndex;
                int nukeId = ((MultiThreadObservableCollection <dynamic>)partyHealBuffBox.ItemsSource)[index].Id;
                newNuke.PartyHealBuffId = nukeId;
                ((ViewModel)this.DataContext).SelectedBot.Engine.PartyHealBuffHandler.SelectedRule = newNuke;
            }
        }
        private void PartyHealBuffRulesListBox_Drop(object sender, DragEventArgs e)
        {
            PartyHealBuffRule droppedData = e.Data.GetData(typeof(PartyHealBuffRule)) as PartyHealBuffRule;
            PartyHealBuffRule target      = ((ListBoxItem)(sender)).DataContext as PartyHealBuffRule;

            int removedIdx = PartyHealRulesListBox.Items.IndexOf(droppedData);
            int targetIdx  = PartyHealRulesListBox.Items.IndexOf(target);

            if (removedIdx < targetIdx)
            {
                MainWindow.ViewModel.SelectedBot.Engine.PartyHealBuffHandler.NukesToUse.Insert(targetIdx + 1, droppedData);
                MainWindow.ViewModel.SelectedBot.Engine.PartyHealBuffHandler.NukesToUse.RemoveAt(removedIdx);
            }
            else
            {
                int remIdx = removedIdx + 1;
                if (MainWindow.ViewModel.SelectedBot.Engine.PartyHealBuffHandler.NukesToUse.Count + 1 > remIdx)
                {
                    MainWindow.ViewModel.SelectedBot.Engine.PartyHealBuffHandler.NukesToUse.Insert(targetIdx, droppedData);
                    MainWindow.ViewModel.SelectedBot.Engine.PartyHealBuffHandler.NukesToUse.RemoveAt(remIdx);
                }
            }
        }
        public PartyHealBuffRule GetRuleForCast(bool inCombat)
        {
            if (Math.Abs(Environment.TickCount - _timeStamp) < 50)
            {
                return(_latestRule);
            }

            _timeStamp = Environment.TickCount;
            PartyHealBuffRule nuke = null;

            foreach (var nukeRule in NukesToUse)
            {
                if ((nukeRule.NukeType == NukeType.Item ? !_data.Inventory.Any(item => item.Value.ItemId == nukeRule.PartyHealBuffId) : false) ||
                    (nukeRule.NukeType == NukeType.Skill ? !_data.Skills.Any(skill => skill.Value.SkillId == nukeRule.PartyHealBuffId) : false))
                {
                    continue;
                }

                foreach (var partyUnit in nukeRule.PlayersToBuff)
                {
                    if (partyUnit.Enable)
                    {
                        Player ptMember =
                            _data.PartyMembers.FirstOrDefault(
                                member =>
                                member.Name.Equals(
                                    partyUnit.Name.Split(new string[] { "'s" }, StringSplitOptions.None)[0]));

                        if (ptMember == null)
                        {
                            continue;
                        }

                        GameFigure target = (partyUnit.Name.Contains("'s")
                            ? (GameFigure)ptMember.PlayerSummons.FirstOrDefault(
                                                 summ =>
                                                 summ.Name.Trim()
                                                 .Equals(
                                                     partyUnit.Name.Split(new string[] { "'s" }, StringSplitOptions.None)[1].Trim(),
                                                     StringComparison.OrdinalIgnoreCase))
                            : (GameFigure)ptMember);

                        if (target == null)
                        {
                            continue;
                        }

                        GameFigure condFigure = _data.MainHero;

                        if (_data.SurroundingPlayers.All(player => player.ObjectId != target.ObjectId))
                        {
                            continue;
                        }

                        if (!nukeRule.Enabled)
                        {
                            continue;
                        }

                        //cond checks
                        if (condFigure != null)
                        {
                            if (nukeRule.HealthPercentOver > 0 &&
                                nukeRule.HealthPercentOver > condFigure.HealthPercent)
                            {
                                continue;
                            }

                            if (nukeRule.HealthPercentBelow > 0 &&
                                nukeRule.HealthPercentBelow < condFigure.HealthPercent)
                            {
                                continue;
                            }

                            if (nukeRule.ManaPercentOver > 0 && nukeRule.ManaPercentOver > condFigure.ManaPercent)
                            {
                                continue;
                            }

                            if (nukeRule.ManaPercentBelow > 0 && nukeRule.ManaPercentBelow < condFigure.ManaPercent)
                            {
                                continue;
                            }

                            if (condFigure is MainHero && nukeRule.CombatPointsPercentOver > 0 &&
                                nukeRule.CombatPointsPercentOver > condFigure.CombatPointsPercent)
                            {
                                continue;
                            }

                            if (condFigure is MainHero && nukeRule.CombatPointsPercentBelow > 0 &&
                                nukeRule.CombatPointsPercentBelow < condFigure.CombatPointsPercent)
                            {
                                continue;
                            }
                        }

                        condFigure = target;

                        if (condFigure != null)
                        {
                            if (nukeRule.PartyMemberHealthPercentOver > 0 && nukeRule.PartyMemberHealthPercentOver > condFigure.HealthPercent)
                            {
                                continue;
                            }

                            if (nukeRule.PartyMemberHealthPercentBelow > 0 && nukeRule.PartyMemberHealthPercentBelow < condFigure.HealthPercent)
                            {
                                continue;
                            }

                            if (nukeRule.PartyMemberManaPercentOver > 0 && nukeRule.PartyMemberManaPercentOver > condFigure.ManaPercent)
                            {
                                continue;
                            }

                            if (nukeRule.PartyMemberManaPercentBelow > 0 && nukeRule.PartyMemberManaPercentBelow < condFigure.ManaPercent)
                            {
                                continue;
                            }

                            if (nukeRule.PartyMemberCombatPointsPercentOver > 0 && nukeRule.PartyMemberCombatPointsPercentOver > condFigure.CombatPointsPercent)
                            {
                                continue;
                            }

                            if (nukeRule.PartyMemberCombatPointsPercentBelow > 0 && nukeRule.PartyMemberCombatPointsPercentBelow < condFigure.CombatPointsPercent)
                            {
                                continue;
                            }

                            if (nukeRule.PartyMemberIsDead && !condFigure.IsDead)
                            {
                                continue;
                            }

                            if (!nukeRule.PartyMemberIsDead && condFigure.IsDead)
                            {
                                continue;
                            }
                        }

                        int health = 0, maxHealth = 0, ptMembersAroundCount = 0;

                        if (nukeRule.AveragePartyMemberHealthPercentOver > 0 || nukeRule.AveragePartyMemberHealthPercentBelow > 0)
                        {
                            foreach (var partyMember in _data.PartyMembers)
                            {
                                if (_data.MainHero.RangeTo(partyMember) < 1000)
                                {
                                    ptMembersAroundCount++;
                                    health    += partyMember.Health;
                                    maxHealth += partyMember.MaxHealth;
                                }
                            }
                        }

                        double avrgPtHealthPercent = ptMembersAroundCount > 0 ? (health / (double)maxHealth) * 100.0 : 0;

                        if (nukeRule.AveragePartyMemberHealthPercentOver > 0 && avrgPtHealthPercent > 0 && nukeRule.AveragePartyMemberHealthPercentOver > avrgPtHealthPercent)
                        {
                            continue;
                        }

                        if (nukeRule.AveragePartyMemberHealthPercentBelow > 0 && avrgPtHealthPercent > 0 && nukeRule.AveragePartyMemberHealthPercentBelow < avrgPtHealthPercent)
                        {
                            continue;
                        }

                        if (nukeRule.DeadPartyMembersOver > 0 && nukeRule.DeadPartyMembersOver > _data.PartyMembers.Count(member => member.IsDead))
                        {
                            continue;
                        }

                        if (nukeRule.DeadPartyMembersBelow > 0 && nukeRule.DeadPartyMembersBelow < _data.PartyMembers.Count(member => member.IsDead))
                        {
                            continue;
                        }

                        if (Math.Abs(Environment.TickCount - nukeRule.LastUsed) < nukeRule.Interval * 1000)
                        {
                            continue;
                        }

                        if (nukeRule.UseIfBuffIsMissing && nukeRule.SelectedBuffsStr.Trim().Length > 0
                            &&
                            nukeRule.SelectedBuffsFilter.Any(
                                buffRule =>
                                buffRule.Enable &&
                                target.Buffs.Any(
                                    buff =>
                                    buff.Value.BuffName.Equals(buffRule.Name,
                                                               StringComparison.OrdinalIgnoreCase))))
                        {
                            var rule = nukeRule.SelectedBuffsFilter.First(
                                buffRule =>
                                buffRule.Enable &&
                                target.Buffs.Any(
                                    buff =>
                                    buff.Value.BuffName.Equals(buffRule.Name,
                                                               StringComparison.OrdinalIgnoreCase)));
                            var name = rule.Name;

                            if (nukeRule.TimerCheckActivated)
                            {
                                var seconds =
                                    target.Buffs.First(
                                        buff =>
                                        buff.Value.BuffName.Equals(name,
                                                                   StringComparison.OrdinalIgnoreCase))
                                    .Value.SecondsLeft;
                                if (nukeRule.TimerComparisonTypeEnum == ComparisonType.Less &&
                                    seconds > nukeRule.TimerSeconds)
                                {
                                    continue;
                                }
                                else if (nukeRule.TimerComparisonTypeEnum == ComparisonType.More &&
                                         seconds < nukeRule.TimerSeconds)
                                {
                                    continue;
                                }
                            }

                            if (nukeRule.SkillLevelComparisonActivated)
                            {
                                var level =
                                    target.Buffs.First(
                                        buff =>
                                        buff.Value.BuffName.Equals(name,
                                                                   StringComparison.OrdinalIgnoreCase))
                                    .Value.Level;
                                if (nukeRule.SkillLevelComparisonTypeEnum == ComparisonType.Less &&
                                    level > nukeRule.SkillLevelRequired)
                                {
                                    continue;
                                }
                                else if (nukeRule.SkillLevelComparisonTypeEnum == ComparisonType.More &&
                                         level < nukeRule.SkillLevelRequired)
                                {
                                    continue;
                                }
                                else if (nukeRule.SkillLevelComparisonTypeEnum == ComparisonType.Equal &&
                                         level != nukeRule.SkillLevelRequired)
                                {
                                    continue;
                                }
                            }
                        }

                        if (nukeRule.UseIfBuffIsMissing && nukeRule.SelectedBuffsStr.Trim().Length > 0 &&
                            !nukeRule.TimerCheckActivated && !nukeRule.SkillLevelComparisonActivated
                            &&
                            nukeRule.SelectedBuffsFilter.Any(
                                buffRule =>
                                buffRule.Enable &&
                                target.Buffs.Any(
                                    buff =>
                                    buff.Value.BuffName.Equals(buffRule.Name,
                                                               StringComparison.OrdinalIgnoreCase))))
                        {
                            continue;
                        }

                        if (nukeRule.UseIfBuffIsPresent && nukeRule.SelectedBuffsStr.Trim().Length > 0
                            &&
                            nukeRule.SelectedBuffsFilter.Any(
                                buffRule =>
                                buffRule.Enable &&
                                target.Buffs.Any(
                                    buff =>
                                    buff.Value.BuffName.Equals(buffRule.Name,
                                                               StringComparison.OrdinalIgnoreCase))))
                        {
                            var rule = nukeRule.SelectedBuffsFilter.First(
                                buffRule =>
                                buffRule.Enable &&
                                target.Buffs.Any(
                                    buff =>
                                    buff.Value.BuffName.Equals(buffRule.Name,
                                                               StringComparison.OrdinalIgnoreCase)));
                            var name = rule.Name;

                            if (nukeRule.TimerCheckActivated)
                            {
                                var seconds =
                                    target.Buffs.First(
                                        buff =>
                                        buff.Value.BuffName.Equals(name,
                                                                   StringComparison.OrdinalIgnoreCase))
                                    .Value.SecondsLeft;
                                if (nukeRule.TimerComparisonTypeEnum == ComparisonType.Less &&
                                    seconds > nukeRule.TimerSeconds)
                                {
                                    continue;
                                }
                                else if (nukeRule.TimerComparisonTypeEnum == ComparisonType.More &&
                                         seconds < nukeRule.TimerSeconds)
                                {
                                    continue;
                                }
                            }

                            if (nukeRule.SkillLevelComparisonActivated)
                            {
                                var level =
                                    target.Buffs.First(
                                        buff =>
                                        buff.Value.BuffName.Equals(name,
                                                                   StringComparison.OrdinalIgnoreCase))
                                    .Value.Level;
                                if (nukeRule.SkillLevelComparisonTypeEnum == ComparisonType.Less &&
                                    level > nukeRule.SkillLevelRequired)
                                {
                                    continue;
                                }
                                else if (nukeRule.SkillLevelComparisonTypeEnum == ComparisonType.More &&
                                         level < nukeRule.SkillLevelRequired)
                                {
                                    continue;
                                }
                                else if (nukeRule.SkillLevelComparisonTypeEnum == ComparisonType.Equal &&
                                         level != nukeRule.SkillLevelRequired)
                                {
                                    continue;
                                }
                            }
                        }

                        if (nukeRule.UseIfBuffIsPresent && nukeRule.SelectedBuffsStr.Trim().Length > 0
                            &&
                            !nukeRule.SelectedBuffsFilter.Any(
                                buffRule =>
                                buffRule.Enable &&
                                target.Buffs.Any(
                                    buff =>
                                    buff.Value.BuffName.Equals(buffRule.Name,
                                                               StringComparison.OrdinalIgnoreCase))))
                        {
                            continue;
                        }

                        if (nukeRule.NukeType == NukeType.Skill && !_data.Skills[nukeRule.PartyHealBuffId].CanBeUsed())
                        {
                            continue;
                        }

                        if (!nukeRule.UseInCombat && inCombat)
                        {
                            continue;
                        }

                        if (nukeRule.NukeType == NukeType.Skill && _data.MainHero.Mana <
                            ExportedData.SkillManaConsumption[nukeRule.PartyHealBuffId][
                                _data.Skills[nukeRule.PartyHealBuffId].SkillLevel] * 0.75)
                        {
                            continue;
                        }

                        if (nukeRule.RequiresTarget)
                        {
                            if (_data.MainHero.RangeTo(target) > nukeRule.MaxDistance)
                            {
                                continue;
                            }
                        }

                        nuke = nukeRule;
                        nuke.ChosenTarget = target;
                        break;
                    }
                }
            }

            _latestRule = nuke;
            return(nuke);
        }