Пример #1
0
        // Gets the minimum divisor from A and B per type
        public static RuneFilter Min(RuneFilter a, RuneFilter b)
        {
            RuneFilter m = new RuneFilter();

            m.Flat = MinNZero(a.Flat, b.Flat);
            m.Percent = MinNZero(a.Percent, b.Percent);
            m.Test = MinNZero(a.Test, b.Test);

            return m;
        }
Пример #2
0
        // Gets the minimum divisor from A and B per type
        public static RuneFilter Min(RuneFilter a, RuneFilter b)
        {
            RuneFilter m = new RuneFilter();

            m.Flat    = MinNZero(a.Flat, b.Flat);
            m.Percent = MinNZero(a.Percent, b.Percent);
            m.Test    = MinNZero(a.Test, b.Test);

            return(m);
        }
Пример #3
0
        /// <summary>
        /// Fills the instance with acceptable runes from save
        /// </summary>
        /// <param name="save">The Save data that contais the runes</param>
        /// <param name="useLocked">If it should include locked runes</param>
        /// <param name="useEquipped">If it should include equipped runes (other than the current monster)</param>
        public void GenRunes(Save save, bool useLocked = false, bool useEquipped = false, bool saveStats = false)
        {
            if (save == null)
                return;
            if (save.Runes == null)
                return;

            IEnumerable<Rune> rsGlobal = save.Runes;

            // Only using 'inventory' or runes on mon
            // also, include runes which have been unequipped (should only look above)
            if (!useEquipped)
                rsGlobal = rsGlobal.Where(r => (r.AssignedName == "Unknown name" || r.AssignedName == mon.Name) || r.Swapped);
            // only if the rune isn't currently locked for another purpose
            if (!useLocked)
                rsGlobal = rsGlobal.Where(r => r.Locked == false);

            // Only runes which we've included
            rsGlobal = rsGlobal.Where(r => BuildSets.Contains(r.Set));

            if (saveStats)
            {
                foreach (Rune r in rsGlobal)
                {
                    r.manageStats_Set++;
                }
            }

            int[] slotFakes = new int[6];
            bool[] slotPred = new bool[6];

            // For each runeslot
            for (int i = 0; i < 6; i++)
            {
                // put the right ones in
                runes[i] = rsGlobal.Where(r => r.Slot == i + 1).ToArray();

                // crank the rune prediction
                Rune[] rs = runes[i];
                int raiseTo = 0;
                bool predictSubs = false;

                // find the largest number to raise to
                // if any along the tree say to predict, do it
                if (runePrediction.ContainsKey("g"))
                {
                    int glevel = runePrediction["g"].Key;
                    if (glevel > raiseTo)
                        raiseTo = glevel;
                    predictSubs |= runePrediction["g"].Value;
                }
                if (runePrediction.ContainsKey(((i % 2 == 0) ? "o" : "e")))
                {
                    int mlevel = runePrediction[((i % 2 == 0) ? "o" : "e")].Key;
                    if (mlevel > raiseTo)
                        raiseTo = mlevel;
                    predictSubs |= runePrediction[((i % 2 == 0) ? "o" : "e")].Value;
                }
                if (runePrediction.ContainsKey((i + 1).ToString()))
                {
                    int slevel = runePrediction[(i + 1).ToString()].Key;
                    if (slevel > raiseTo)
                        raiseTo = slevel;
                    predictSubs |= runePrediction[(i + 1).ToString()].Value;
                }

                slotFakes[i] = raiseTo;
                slotPred[i] = predictSubs;

                // default fail OR
                Predicate<Rune> slotTest = r => false;
                int and = 0;
                // this means that runes won't get in unless they meet at least 1 criteria

                // which tab we pulled the filter from
                string gotScore = "";
                // the value to test SUM against
                int testVal = 0;

                // TODO: check what inheriting SUM (eg. Odd and 3) does
                // TODO: check what inheriting AND/OR then SUM (or visa versa)

                // find the most significant operatand of joining checks
                if (runeScoring.ContainsKey("g") && runeFilters.ContainsKey("g") && runeFilters["g"].Any(r => r.Value.NonZero))
                {
                    var kv = runeScoring["g"];
                    gotScore = "g";
                    and = kv.Key;
                    if (kv.Key == 1)
                    {
                        slotTest = r => true;
                    }
                    else if (kv.Key == 2)
                    {
                        testVal = kv.Value;
                    }
                }
                // is it and odd or even slot?
                string tmk = (i % 2 == 1 ? "e" : "o");
                if (runeScoring.ContainsKey(tmk) && runeFilters.ContainsKey(tmk) && runeFilters[tmk].Any(r => r.Value.NonZero))
                {
                    var kv = runeScoring[tmk];
                    gotScore = tmk;
                    and = kv.Key;
                    if (kv.Key == 1)
                    {
                        slotTest = r => true;
                    }
                    else if (kv.Key == 2)
                    {
                        testVal = kv.Value;
                    }
                }
                // turn the 0-5 to a 1-6
                tmk = (i + 1).ToString();
                if (runeScoring.ContainsKey(tmk) && runeFilters.ContainsKey(tmk) && runeFilters[tmk].Any(r => r.Value.NonZero))
                {
                    var kv = runeScoring[tmk];
                    gotScore = tmk;
                    and = kv.Key;
                    if (kv.Key == 1)
                    {
                        slotTest = r => true;
                    }
                    else if (kv.Key == 2)
                    {
                        testVal = kv.Value;
                    }
                }

                // if an operand was found, ensure the tab contains filter data
                if (gotScore != "")
                {
                    if (runeFilters.ContainsKey(gotScore))
                    {
                        // if all the filters for the tab are zero
                        if (runeFilters[gotScore].All(r => !r.Value.NonZero))
                        {
                            // set to OR TRUE
                            slotTest = r => true;
                            and = 0;
                        }
                    }
                }
                else
                {
                    // if there wasn't any relevant data for how to pick runes, just take 'em all!
                    slotTest = r => true;
                }

                // pull the filters (flat, perc, test) for all the tabs and stats
                Dictionary<string, RuneFilter> rfG = new Dictionary<string, RuneFilter>();
                if (runeFilters.ContainsKey("g"))
                    rfG = runeFilters["g"];

                Dictionary<string, RuneFilter> rfM = new Dictionary<string, RuneFilter>();
                if (runeFilters.ContainsKey((i % 2 == 1 ? "e" : "o")))
                    rfM = runeFilters[(i % 2 == 1 ? "e" : "o")];

                Dictionary<string, RuneFilter> rfS = new Dictionary<string, RuneFilter>();
                if (runeFilters.ContainsKey((i+1).ToString()))
                    rfS = runeFilters[(i + 1).ToString()];

                // if there where no filters with data
                bool blank = true;

                Stats rFlat = new Stats();
                Stats rPerc = new Stats();
                Stats rTest = new Stats();

                foreach (string stat in statNames)
                {
                    RuneFilter rf = new RuneFilter();
                    if (rfS.ContainsKey(stat))
                    {
                        rf = rfS[stat];
                        if (rfM.ContainsKey(stat))
                            rf = RuneFilter.Min(rf, rfM[stat]);

                        if (rfG.ContainsKey(stat))
                            rf = RuneFilter.Min(rf, rfG[stat]);

                    }
                    else
                    {
                        if (rfM.ContainsKey(stat))
                        {
                            rf = rfM[stat];
                            if (rfG.ContainsKey(stat))
                                rf = RuneFilter.Min(rf, rfG[stat]);
                        }
                        else
                        {
                            if (rfG.ContainsKey(stat))
                                rf = rfG[stat];
                        }
                    }
                    if (rf.NonZero)
                    {
                        // put the most relevant divisor in?
                        rFlat[stat] = rf.Flat;
                        rPerc[stat] = rf.Percent;
                        rTest[stat] = rf.Test;
                        blank = false;
                    }
                }

                // TODO: seems like it just ignores all the slotTesting before now

                // no filter data = use all
                if (blank)
                    slotTest = r => true;
                else
                {
                    // Set the test based on the type found
                    if (and == 0)
                    {
                        slotTest = r => r.Or(rFlat, rPerc, rTest, raiseTo, predictSubs);
                    }
                    else if (and == 1)
                    {
                        slotTest = r => r.And(rFlat, rPerc, rTest, raiseTo, predictSubs);
                    }
                    else if (and == 2)
                    {
                        slotTest = r => r.Test(rFlat, rPerc, raiseTo, predictSubs) >= testVal;
                    }
                }
                runes[i] = runes[i].Where(r => slotTest.Invoke(r)).ToArray();

                if (saveStats)
                {
                    foreach (Rune r in runes[i])
                    {
                        r.manageStats_RuneFilt++;
                    }
                }

                if (i % 2 == 1) // actually evens because off by 1
                {
                    // makes sure that the primary stat type is in the selection
                    if (slotStats[i].Count > 0)
                        runes[i] = runes[i].Where(r => slotStats[i].Contains(r.MainType.ToForms())).ToArray();
                }

                if (saveStats)
                {
                    foreach (Rune r in runes[i])
                    {
                        r.manageStats_TypeFilt++;
                    }
                }
            }

            // Make sure that for each set type, there are enough slots with runes in them
            // Eg. if only 1,4,5 have Violent, remove all violent runes because you need 4
            // for each included set
            foreach (RuneSet s in BuildSets)
            {
                // find how many slots have acceptable runes for it
                int slots = 0;
                for (int i = 0; i < 6; i++)
                {
                    if (runes[i].Any(r => r.Set == s))
                        slots += 1;
                }
                // if there isn't enough slots
                if (slots < Rune.SetRequired(s))
                {
                    // remove that set
                    for (int i = 0; i < 6; i++)
                    {
                        runes[i] = runes[i].Where(r => r.Set != s).ToArray();
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Fills the instance with acceptable runes from save
        /// </summary>
        /// <param name="save">The Save data that contais the runes</param>
        /// <param name="useLocked">If it should include locked runes</param>
        /// <param name="useEquipped">If it should include equipped runes (other than the current monster)</param>
        public void GenRunes(Save save, bool useLocked = false, bool useEquipped = false, bool saveStats = false)
        {
            if (save == null)
            {
                return;
            }
            if (save.Runes == null)
            {
                return;
            }

            IEnumerable <Rune> rsGlobal = save.Runes;

            // Only using 'inventory' or runes on mon
            if (!useEquipped)
            {
                rsGlobal = rsGlobal.Where(r => (r.AssignedName == "Unknown name" || r.AssignedName == mon.Name));
            }
            // only if the rune isn't currently locked for another purpose
            if (!useLocked)
            {
                rsGlobal = rsGlobal.Where(r => r.Locked == false);
            }

            // Only runes which we've included
            rsGlobal = rsGlobal.Where(r => BuildSets.Contains(r.Set));

            if (saveStats)
            {
                foreach (Rune r in rsGlobal)
                {
                    r.manageStats_Set++;
                }
            }

            int[]  slotFakes = new int[6];
            bool[] slotPred  = new bool[6];

            // For each runeslot
            for (int i = 0; i < 6; i++)
            {
                // put the right ones in
                runes[i] = rsGlobal.Where(r => r.Slot == i + 1).ToArray();

                // crank the rune prediction
                Rune[] rs          = runes[i];
                int    raiseTo     = 0;
                bool   predictSubs = false;

                // find the largest number to raise to
                // if any along the tree say to predict, do it
                if (runePrediction.ContainsKey("g"))
                {
                    int glevel = runePrediction["g"].Key;
                    if (glevel > raiseTo)
                    {
                        raiseTo = glevel;
                    }
                    predictSubs |= runePrediction["g"].Value;
                }
                if (runePrediction.ContainsKey(((i % 2 == 0) ? "o" : "e")))
                {
                    int mlevel = runePrediction[((i % 2 == 0) ? "o" : "e")].Key;
                    if (mlevel > raiseTo)
                    {
                        raiseTo = mlevel;
                    }
                    predictSubs |= runePrediction[((i % 2 == 0) ? "o" : "e")].Value;
                }
                if (runePrediction.ContainsKey((i + 1).ToString()))
                {
                    int slevel = runePrediction[(i + 1).ToString()].Key;
                    if (slevel > raiseTo)
                    {
                        raiseTo = slevel;
                    }
                    predictSubs |= runePrediction[(i + 1).ToString()].Value;
                }

                slotFakes[i] = raiseTo;
                slotPred[i]  = predictSubs;


                // default fail OR
                Predicate <Rune> slotTest = r => false;
                int and = 0;
                // this means that runes won't get in unless they meet at least 1 criteria

                // which tab we pulled the filter from
                string gotScore = "";
                // the value to test SUM against
                int testVal = 0;

                // TODO: check what inheriting SUM (eg. Odd and 3) does
                // TODO: check what inheriting AND/OR then SUM (or visa versa)

                // find the most significant operatand of joining checks
                if (runeScoring.ContainsKey("g") && runeFilters.ContainsKey("g") && runeFilters["g"].Any(r => r.Value.NonZero))
                {
                    var kv = runeScoring["g"];
                    gotScore = "g";
                    and      = kv.Key;
                    if (kv.Key == 1)
                    {
                        slotTest = r => true;
                    }
                    else if (kv.Key == 2)
                    {
                        testVal = kv.Value;
                    }
                }
                // is it and odd or even slot?
                string tmk = (i % 2 == 1 ? "e" : "o");
                if (runeScoring.ContainsKey(tmk) && runeFilters.ContainsKey(tmk) && runeFilters[tmk].Any(r => r.Value.NonZero))
                {
                    var kv = runeScoring[tmk];
                    gotScore = tmk;
                    and      = kv.Key;
                    if (kv.Key == 1)
                    {
                        slotTest = r => true;
                    }
                    else if (kv.Key == 2)
                    {
                        testVal = kv.Value;
                    }
                }
                // turn the 0-5 to a 1-6
                tmk = (i + 1).ToString();
                if (runeScoring.ContainsKey(tmk) && runeFilters.ContainsKey(tmk) && runeFilters[tmk].Any(r => r.Value.NonZero))
                {
                    var kv = runeScoring[tmk];
                    gotScore = tmk;
                    and      = kv.Key;
                    if (kv.Key == 1)
                    {
                        slotTest = r => true;
                    }
                    else if (kv.Key == 2)
                    {
                        testVal = kv.Value;
                    }
                }


                // if an operand was found, ensure the tab contains filter data
                if (gotScore != "")
                {
                    if (runeFilters.ContainsKey(gotScore))
                    {
                        // if all the filters for the tab are zero
                        if (runeFilters[gotScore].All(r => !r.Value.NonZero))
                        {
                            // set to OR TRUE
                            slotTest = r => true;
                            and      = 0;
                        }
                    }
                }
                else
                {
                    // if there wasn't any relevant data for how to pick runes, just take 'em all!
                    slotTest = r => true;
                }

                // pull the filters (flat, perc, test) for all the tabs and stats
                Dictionary <string, RuneFilter> rfG = new Dictionary <string, RuneFilter>();
                if (runeFilters.ContainsKey("g"))
                {
                    rfG = runeFilters["g"];
                }

                Dictionary <string, RuneFilter> rfM = new Dictionary <string, RuneFilter>();
                if (runeFilters.ContainsKey((i % 2 == 1 ? "e" : "o")))
                {
                    rfM = runeFilters[(i % 2 == 1 ? "e" : "o")];
                }

                Dictionary <string, RuneFilter> rfS = new Dictionary <string, RuneFilter>();
                if (runeFilters.ContainsKey((i + 1).ToString()))
                {
                    rfS = runeFilters[(i + 1).ToString()];
                }

                // if there where no filters with data
                bool blank = true;

                Stats rFlat = new Stats();
                Stats rPerc = new Stats();
                Stats rTest = new Stats();

                foreach (string stat in statNames)
                {
                    RuneFilter rf = new RuneFilter();
                    if (rfS.ContainsKey(stat))
                    {
                        rf = rfS[stat];
                        if (rfM.ContainsKey(stat))
                        {
                            rf = RuneFilter.Min(rf, rfM[stat]);
                        }

                        if (rfG.ContainsKey(stat))
                        {
                            rf = RuneFilter.Min(rf, rfG[stat]);
                        }
                    }
                    else
                    {
                        if (rfM.ContainsKey(stat))
                        {
                            rf = rfM[stat];
                            if (rfG.ContainsKey(stat))
                            {
                                rf = RuneFilter.Min(rf, rfG[stat]);
                            }
                        }
                        else
                        {
                            if (rfG.ContainsKey(stat))
                            {
                                rf = rfG[stat];
                            }
                        }
                    }
                    if (rf.NonZero)
                    {
                        // put the most relevant divisor in?
                        rFlat[stat] = rf.Flat;
                        rPerc[stat] = rf.Percent;
                        rTest[stat] = rf.Test;
                        blank       = false;
                    }
                }

                // TODO: seems like it just ignores all the slotTesting before now

                // no filter data = use all
                if (blank)
                {
                    slotTest = r => true;
                }
                else
                {
                    // Set the test based on the type found
                    if (and == 0)
                    {
                        slotTest = r => r.Or(rFlat, rPerc, rTest, raiseTo, predictSubs);
                    }
                    else if (and == 1)
                    {
                        slotTest = r => r.And(rFlat, rPerc, rTest, raiseTo, predictSubs);
                    }
                    else if (and == 2)
                    {
                        slotTest = r => r.Test(rFlat, rPerc, raiseTo, predictSubs) >= testVal;
                    }
                }
                runes[i] = runes[i].Where(r => slotTest.Invoke(r)).ToArray();

                if (saveStats)
                {
                    foreach (Rune r in runes[i])
                    {
                        r.manageStats_RuneFilt++;
                    }
                }

                if (i % 2 == 1) // actually evens because off by 1
                {
                    // makes sure that the primary stat type is in the selection
                    if (slotStats[i].Count > 0)
                    {
                        runes[i] = runes[i].Where(r => slotStats[i].Contains(r.MainType.ToForms())).ToArray();
                    }
                }

                if (saveStats)
                {
                    foreach (Rune r in runes[i])
                    {
                        r.manageStats_TypeFilt++;
                    }
                }
            }

            // Make sure that for each set type, there are enough slots with runes in them
            // Eg. if only 1,4,5 have Violent, remove all violent runes because you need 4
            // for each included set
            foreach (RuneSet s in BuildSets)
            {
                // find how many slots have acceptable runes for it
                int slots = 0;
                for (int i = 0; i < 6; i++)
                {
                    if (runes[i].Any(r => r.Set == s))
                    {
                        slots += 1;
                    }
                }
                // if there isn't enough slots
                if (slots < Rune.SetRequired(s))
                {
                    // remove that set
                    for (int i = 0; i < 6; i++)
                    {
                        runes[i] = runes[i].Where(r => r.Set != s).ToArray();
                    }
                }
            }
        }