Example #1
0
 public void CopyFrom(MissionReward other)
 {
     this.Category = other.Category;
     this.Name = other.Name;
     this.Id = other.Id;
     this.RequiredPlayerLevel = other.RequiredPlayerLevel;
     this.RequiredSuccessChance = other.RequiredSuccessChance;
     this._ItemInfo = other._ItemInfo;
     this._CurrencyInfo = other._CurrencyInfo;
 }
Example #2
0
 /// <summary>
 ///     Return true if the specified mission has x or less than x count of ItemId as a reward.
 /// </summary>
 /// <param name="itemId"></param>
 /// <param name="x"></param>
 /// <returns></returns>
 private static bool IsNumberRewardInferiorOrEqualTo(MissionReward reward, int x)
 {
     return reward.Quantity <= x;
 }
Example #3
0
 /// <summary>
 ///     Return array of items to respect the following rule: if the specified mission has x or less than x count
 ///     of itemId as a reward, return everything.
 /// </summary>
 /// <param name="itemId"></param>
 /// <returns></returns>
 private static IEnumerable<object> GetNumberRewardInferiorOrEqualTo(MissionReward reward)
 {
     var retval = new List<object>();
     retval.Add(reward.Quantity);
     return retval;
 }
Example #4
0
 /// <summary>
 ///     Return array of items to respect the following rule: if the specified character have x or less than x count
 ///     of itemId carried, return everything.
 /// </summary>
 /// <param name="itemId"></param>
 /// <returns></returns>
 private static IEnumerable<object> GetNumberPlayerHasInferiorOrEqualTo(MissionReward reward)
 {
     var numCarried = Enumerable.Empty<object>();
     if (reward.IsItemReward)
     {
         numCarried = HbApi.GetItemCarried((uint)reward.Id);
     }
     else if (reward.IsCurrencyReward)
     {
         var currency = WoWCurrency.GetCurrencyById((uint)reward.Id);
         numCarried = new List<WoWCurrency>();
         ((List<WoWCurrency>)numCarried).Add(currency);
     }
     else if (reward.IsGold)
     {
         var gold = (int)StyxWoW.Me.Gold;
         numCarried = new List<object>();
         ((List<object>)numCarried).Add((object)gold);
     }
     return numCarried;
 }
Example #5
0
 //*****************************
 //*****************************
 //*****************************
 /// <summary>
 ///     Return true if the specified mission has reward more than x count of ItemId.
 /// </summary>
 /// <param name="itemId"></param>
 /// <param name="x"></param>
 /// <returns></returns>
 private static bool IsNumberRewardSuperiorTo(MissionReward reward, int x)
 {
     return reward.Quantity > x;
 }
Example #6
0
        /// <summary>
        ///     Return true if the specified character have x or less than x count of ItemId carried.
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        private static bool IsNumberPlayerHasInferiorOrEqualTo(MissionReward reward, int x)
        {
            uint numCarried = 0;

            if (reward.IsItemReward)
            {
                numCarried = (uint)HbApi.GetNumberItemCarried((uint)reward.Id);
            }
            else if (reward.IsCurrencyReward)
            {
                numCarried = reward._CurrencyInfo.Amount;
            }
            else if (reward.IsGold)
            {
                numCarried = (uint)StyxWoW.Me.Gold;
            }
            return numCarried != 0 && numCarried <= x;
        }
Example #7
0
        // A rule must have a method returning a bool and a method returning the list of items

        /// <summary>
        ///     Return true if the specified character has more than x count of ItemId carried.
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        private static bool IsNumberPlayerHasSuperiorTo(MissionReward reward, int x)
        {
            uint numCarried = 0;

            if (reward.IsItemReward)
            {
                numCarried = (uint)HbApi.GetNumberItemCarried((uint)reward.Id);
            }
            else if (reward.IsCurrencyReward)
            {
                numCarried = reward._CurrencyInfo.Amount;
            }
            else if (reward.IsGold)
            {
                numCarried = (uint)StyxWoW.Me.Gold;
            }
            //else if (reward.IsFollowerXP)
            //{
            //    numCarried = x;
            //}
            return numCarried > x;
        }
Example #8
0
        /// <summary>
        ///     Returns items to send or null if none.
        /// </summary>
        /// <param name="itemId"></param>
        /// <returns></returns>
        public async Task<IEnumerable<object>> GetItemsOrNull(MissionReward reward)
        {
            switch (_condition)
            {
                case Conditions.NumberPlayerHasSuperiorTo:
                    return GetNumberPlayerHasSuperiorTo(reward);

                case Conditions.NumberPlayerHasSuperiorOrEqualTo:
                    return GetNumberPlayerHasSuperiorOrEqualTo(reward);

                case Conditions.NumberPlayerHasInferiorTo:
                    return GetNumberPlayerHasInferiorTo(reward);

                case Conditions.NumberPlayerHasInferiorOrEqualTo:
                    return GetNumberPlayerHasInferiorOrEqualTo(reward);

                case Conditions.NumberRewardSuperiorTo:
                    return (IEnumerable<object>)GetNumberRewardSuperiorTo(reward);

                case Conditions.NumberRewardSuperiorOrEqualTo:
                    return GetNumberRewardSuperiorOrEqualTo(reward);

                case Conditions.NumberRewardInferiorTo:
                    return GetNumberRewardInferiorTo(reward);

                case Conditions.NumberRewardInferiorOrEqualTo:
                    return GetNumberRewardInferiorOrEqualTo(reward);

                //case Conditions.NumberInBagsSuperiorTo:
                //    return GetNumberInBagsSuperiorTo(itemId);

                //case Conditions.NumberInBagsSuperiorOrEqualTo:
                //    return GetNumberInBagsSuperiorOrEqualTo(itemId);

                //case Conditions.KeepNumberInBags:
                //    return await GetNumberKeepNumberInBags(itemId, _checkValue);

                case Conditions.None:
                    return null;

                default:
                    GarrisonButler.Diagnostic("GetItemsOrNull: This mission rule has not been implemented! Id: " + reward.Id + " Name: " + reward.Name);
                    break;
            }
            return null;
        }
Example #9
0
        /// <summary>
        ///     Returns value of the condition
        /// </summary>
        /// <param name="itemId"></param>
        /// <returns></returns>
        public bool GetCondition(MissionReward reward)
        {
            switch (_condition)
            {
                case Conditions.NumberPlayerHasSuperiorTo:
                    return IsNumberPlayerHasSuperiorTo(reward, _checkValue);

                case Conditions.NumberPlayerHasSuperiorOrEqualTo:
                    return IsNumberPlayerHasSuperiorOrEqualTo(reward, _checkValue);

                case Conditions.NumberPlayerHasInferiorTo:
                    return IsNumberPlayerHasInferiorTo(reward, _checkValue);

                case Conditions.NumberPlayerHasInferiorOrEqualTo:
                    return IsNumberPlayerHasInferiorOrEqualTo(reward, _checkValue);

                case Conditions.NumberRewardSuperiorTo:
                    return IsNumberRewardSuperiorTo(reward, _checkValue);

                case Conditions.NumberRewardSuperiorOrEqualTo:
                    return IsNumberRewardSuperiorOrEqualTo(reward, _checkValue);

                case Conditions.NumberRewardInferiorTo:
                    return IsNumberRewardInferiorTo(reward, _checkValue);

                case Conditions.NumberRewardInferiorOrEqualTo:
                    return IsNumberRewardInferiorOrEqualTo(reward, _checkValue);

                case Conditions.None:
                    return true;

                default:
                    GarrisonButler.Diagnostic("GetCondition: This mission rule has not been implemented! Id: {0} Name: {1}",
                        reward.Id, reward.Name);
                    break;
            }
            return true;
        }
Example #10
0
        // Returns list mission/followers combos with combosTried, acceptedCombos, totalSuccessChance
        public static Tuple<List<Tuple<Mission, Follower[]>>, long, int, double> DoMissionCalc(
            List<Follower> followersToConsider, List<Mission> missionsThatMeetRequirement, MissionReward reward,
            List<Follower> followers)
        {
            long combosTried = 0;
            var acceptedCombos = 0;
            double totalSuccessChance = 0;
            var toStart = new List<Tuple<Mission, Follower[]>>();
            var followersToRemoveIfFailure = new List<Follower>();
            var excludedFollowers = new List<Follower>();

            foreach (var mission in missionsThatMeetRequirement)
            {
                GarrisonButler.Diagnostic("************* BEGIN Mission=" + mission.Name + "**************");
                if (followersToConsider.Count < mission.NumFollowers)
                {
                    var shouldBreak = true;

                    // Attempt to "fill up" slots if they didn't enable AllowFollowerXPMissionsToFillAllSlotsWithEpicMaxLevelFollowers
                    if (!GaBSettings.Get().AllowFollowerXPMissionsToFillAllSlotsWithEpicMaxLevelFollowers
                        && reward.Category == MissionReward.MissionRewardCategory.FollowerExperience)
                    {
                        followersToRemoveIfFailure = FillFollowersWithEpicLevel100(followersToConsider, followers,
                            mission);
                        if (followersToRemoveIfFailure.Count > 0)
                        {
                            shouldBreak = false;
                        }
                        // Followers were excluded (followers.Count > followersToConsider.Count)
                        // but still a follower remaining in the queue that needs experience (followersToConsider.Count > 0)
                        //if (followersToConsider.Count > 0
                        //    && followers.Count > followersToConsider.Count)
                        //{
                        //    var reducedFollowerSet = followers.Except(followersToConsider).ToList();
                        //    if (!reducedFollowerSet.Any())
                        //        continue;
                        //    // Get only the followers that were excluded
                        //    //var reducedFollowerSet =
                        //    //    followers
                        //    //    .SkipWhile((f, i) => f.FollowerId == followersToConsider[i].FollowerId)
                        //    //    .ToList();
                        //    // Adding some followers back in would allow us to complete the mission
                        //    if ((followersToConsider.Count + reducedFollowerSet.Count) >= mission.NumFollowers)
                        //    {
                        //        var amount = mission.NumFollowers - followersToConsider.Count;
                        //        followersToRemoveIfFailure = reducedFollowerSet.Take(amount).ToList();

                        //        if (followersToRemoveIfFailure.Count > 0)
                        //        {
                        //            GarrisonButler.Diagnostic("Using epic level 100 followers to help fill up mission slots:");
                        //            followersToRemoveIfFailure.ForEach(f => GarrisonButler.Diagnostic(" -> " + f.Name));
                        //            followersToConsider.AddRange(followersToRemoveIfFailure);
                        //            shouldBreak = false;
                        //        }
                        //    }
                        //}
                    }

                    if (shouldBreak)
                    {
                        GarrisonButler.Diagnostic(
                            "Breaking mission loop due to followersToConsider < mission.NumFollowers");
                        continue;
                    }
                }

                // Abort if we don't have enough Garrison Resources
                var gr = WoWCurrency.GetCurrencyById(824).Amount;
                var mingr = GaBSettings.Get().MinimumGarrisonResourcesToStartMissions;
                if (gr < mingr)
                {
                    GarrisonButler.Diagnostic(
                        "[Missions] Breaking MissionCalc due to Minimum Required Garrison Resources.  Have {0} and need {1}.",
                        gr, mingr);
                }

                if (mission.Cost > gr)
                {
                    GarrisonButler.Diagnostic(
                        "[Missions] Breaking MissionCalc due to insufficient Garrison Resources to start mission ({0}) {1}.  Have {2} and need {3}.",
                        mission.MissionId, mission.Name, gr, mission.Cost);
                    break;
                }

                // Garrison Resources
                if (mission.Rewards.Any(r => r.IsGarrisonResources))
                {
                    if (GaBSettings.Get().PreferFollowersWithScavengerForGarrisonResourcesReward)
                    {
                        GarrisonButler.Diagnostic(
                            "[Missions] Mission reward is GARRISON RESOURCES and user settings indicate to prefer followers with Scavenger trait.  {0} followers have Scavenger",
                            followersToConsider.Count(f => f.HasScavenger));
                        followersToConsider = followersToConsider.OrderByDescending(f => f.HasScavenger).ToList();
                    }
                }
                // NOT Garrison Resources & user wants to disallow followers with Scavenger on these missions
                else if (GaBSettings.Get().DisallowScavengerOnNonGarrisonResourcesMissions)
                {
                    GarrisonButler.Diagnostic(
                        "[Missions] Mission reward is ***NOT*** GARRISON RESOURCES and user settings indicate to NOT allow followers with Scavenger.  {0} followers have Scavenger",
                        followersToConsider.Count(f => f.HasScavenger));
                    excludedFollowers = followersToConsider.Where(f => f.HasScavenger).ToList();
                    followersToConsider.RemoveAll(f => excludedFollowers.Any(e => e.FollowerId == f.FollowerId));
                }

                // Gold
                if (mission.Rewards.Any(r => r.IsGold))
                {
                    if (GaBSettings.Get().PreferFollowersWithTreasureHunterForGoldReward)
                    {
                        GarrisonButler.Diagnostic(
                            "[Missions] Mission reward is GOLD and user settings indicate to prefer followers with Treasure Hunter trait.  {0} followers have Treasure Hunter",
                            followersToConsider.Count(f => f.HasTreasureHunter));
                        followersToConsider = followersToConsider.OrderByDescending(f => f.HasTreasureHunter).ToList();
                    }
                }
                // NOTGold & user wants to disallow followers with Treasure Hunter on these missions
                else if (GaBSettings.Get().DisallowTreasureHunterOnNonGoldMissions)
                {
                    GarrisonButler.Diagnostic(
                        "[Missions] Mission reward is ***NOT*** GOLD and user settings indicate to NOT allow followers with Treasure Hunter.  {0} followers have Treasure Hunter",
                        followersToConsider.Count(f => f.HasTreasureHunter));
                    excludedFollowers = followersToConsider.Where(f => f.HasTreasureHunter).ToList();
                    followersToConsider.RemoveAll(f => excludedFollowers.Any(e => e.FollowerId == f.FollowerId));
                }

                DateTime startedAt = DateTime.Now;
                Combinations<Follower> followerCombinations = new Combinations<Follower>(followersToConsider,
                    mission.NumFollowers);
                MissionCalc.mission = mission;
                var bestCombo = Enumerable.Empty<Follower>();
                var bestSuccess = 0.0d;
                List<Tuple<IList<Follower>, double>> successChances = new List<Tuple<IList<Follower>, double>>();
                foreach (var combo in followerCombinations)
                {
                    var allMaxLevelEpic = combo.All(c => c.IsMaxLevelEpic);
                    var isFollowerExperienceCategory = reward.Category ==
                                                       MissionReward.MissionRewardCategory.FollowerExperience;
                    if (!GaBSettings.Get().AllowFollowerXPMissionsToFillAllSlotsWithEpicMaxLevelFollowers
                        && isFollowerExperienceCategory
                        && allMaxLevelEpic)
                    {
                        // Don't fill all slots with epic max level followers
                        continue;
                    }
                    // Restrict combinations based on user settings
                    // Only for FollowerExperience
                    if (GaBSettings.Get().UseEpicMaxLevelFollowersToBoostLowerFollowers
                        && reward.Category == MissionReward.MissionRewardCategory.FollowerExperience)
                    {
                        // Skip any combinations where # of epic followers is greater than allowed
                        var maxEpicFollowers = GaBSettings.Get().MaxNumberOfEpicMaxLevelFollowersToUseWhenBoosting;
                        maxEpicFollowers = maxEpicFollowers < 0 ? 0 : maxEpicFollowers;
                        if (combo.Count(c => c.IsMaxLevelEpic) > maxEpicFollowers)
                            continue;
                    }
                    MissionCalc.followers = combo.ToList();
                    var result = MissionCalc.CalculateSuccessChance();
                    successChances.Add(new Tuple<IList<Follower>, double>(combo, result.Item1));
                }

                if (successChances != null && successChances.Count > 0)
                {
                    GarrisonButler.Diagnostic("Total combinations tried = " + followerCombinations.Count);
                    GarrisonButler.DiagnosticLogTimeTaken("Trying all " + followerCombinations.Count + " combinations",
                        startedAt);
                    var first = successChances.OrderByDescending(sc => sc.Item2).FirstOrDefault();
                    if (first != null)
                    {
                        bestCombo = first.Item1;
                        bestSuccess = first.Item2;

                        var sucChanceToCompareAgainst = reward.IndividualSuccessChanceEnabled
                            ? reward.RequiredSuccessChance
                            : GaBSettings.Get().DefaultMissionSuccessChance;

                        if (Convert.ToInt32(bestSuccess) < sucChanceToCompareAgainst)
                        {
                            GarrisonButler.Diagnostic(
                                "Best combo doesn't meet minimum success chance requirements!  Need {0}% and only have {1}%",
                                sucChanceToCompareAgainst, Convert.ToInt32(bestSuccess));
                            bestCombo.ForEach(c => GarrisonButler.Diagnostic(" -> Follower: " + c.Name));
                            RemoveAddedMaxLevelFollowers(followersToConsider, followersToRemoveIfFailure);
                            AddExcludedFollowers(followersToConsider, excludedFollowers);
                            GarrisonButler.Diagnostic("************* END Mission=" + mission.Name + "**************");
                            continue;
                        }
                    }
                    else
                    {
                        GarrisonButler.Diagnostic(
                            "Error retrieving success chance for best combo: bestCombo.Count={0}, successChances.Count={1}",
                            bestCombo.GetEmptyIfNull().Count(), successChances.GetEmptyIfNull().Count());
                        RemoveAddedMaxLevelFollowers(followersToConsider, followersToRemoveIfFailure);
                        AddExcludedFollowers(followersToConsider, excludedFollowers);
                        GarrisonButler.Diagnostic("************* END Mission=" + mission.Name + "**************");
                        continue;
                    }

                    combosTried += (int) followerCombinations.Count;

                    if (bestCombo.IsNullOrEmpty())
                    {
                        GarrisonButler.Diagnostic("[Missions] No best combo found for mission {0}", mission.Name);
                        RemoveAddedMaxLevelFollowers(followersToConsider, followersToRemoveIfFailure);
                        AddExcludedFollowers(followersToConsider, excludedFollowers);
                        GarrisonButler.Diagnostic("************* END Mission=" + mission.Name + "**************");
                        continue;
                    }
                    acceptedCombos++;
                    GarrisonButler.Diagnostic("[Missions] Best Combination with success=" + bestSuccess +
                                              "% for Mission=" + mission.Name + " is ");
                    bestCombo.ForEach(c => GarrisonButler.Diagnostic(" -> Follower: " + c.Name));
                    //successChances.ForEach(c =>
                    //{
                    //    totalSuccessChance += c.Item2;
                    //});
                    totalSuccessChance += bestSuccess;
                    toStart.Add(new Tuple<Mission, Follower[]>(mission, bestCombo.ToArray()));
                    GarrisonButler.Diagnostic("[Missions] Followers before removal: " + followersToConsider.Count);
                    bestCombo.ForEach(c =>
                    {
                        followersToConsider.RemoveAll(f => f.FollowerId == c.FollowerId);
                        followers.RemoveAll(f => f.FollowerId == c.FollowerId);
                    });
                    GarrisonButler.Diagnostic("Followers after removal: " + followersToConsider.Count);
                    AddExcludedFollowers(followersToConsider, excludedFollowers);
                } // if (bestCombo != null)

                GarrisonButler.Diagnostic("************* END Mission=" + mission.Name + "**************");
            } // if (successChances != null && successChances.Any())

            return new Tuple<List<Tuple<Mission, Follower[]>>, long, int, double>(toStart, combosTried, acceptedCombos,
                totalSuccessChance);
        }