Ejemplo n.º 1
0
 /// <summary>
 /// Creates a new router.
 /// </summary>
 public SequenceDirectedRouter(IDirectedWeightMatrixAlgorithm <float> weightMatrixAlgorithm, float turnPenalty, Tour sequence,
                               SolverBase <float, SequenceDirectedProblem, SequenceDirectedObjective, Tour, float> solver = null)
 {
     _turnPenalty           = turnPenalty;
     _sequence              = sequence;
     _weightMatrixAlgorithm = weightMatrixAlgorithm;
     _solver = solver;
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Creates a new TSP router.
 /// </summary>
 public TSPRouter(IWeightMatrixAlgorithm <float> weightMatrixAlgorithm, int first = 0, int?last = null,
                  SolverBase <float, TSProblem, TSPObjective, Itinero.Optimization.Tours.Tour, float> solver = null)
 {
     _first = first;
     _last  = last;
     _weightMatrixAlgorithm = weightMatrixAlgorithm;
     _solver = solver;
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Creates a new TSP router.
 /// </summary>
 public STSPRouter(IWeightMatrixAlgorithm <float> weightMatrixAlgorithm, float max, int first = 0, int?last = null,
                   SolverBase <float, STSProblem, STSPObjective, Tour, STSPFitness> solver    = null)
 {
     _first = first;
     _last  = last;
     _max   = max;
     _weightMatrixAlgorithm = weightMatrixAlgorithm;
     _solver = solver;
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Creates a new TSP router.
 /// </summary>
 public TSPRouter(IDirectedWeightMatrixAlgorithm <float> weightMatrixAlgorithm, float turnPenalty, int first, int?last = null,
                  SolverBase <float, TSProblem, TSPObjective, Itinero.Optimization.Tours.Tour, float> solver           = null)
 {
     _turnPenalty           = turnPenalty;
     _first                 = first;
     _last                  = last;
     _weightMatrixAlgorithm = weightMatrixAlgorithm;
     _solver                = solver;
 }
Ejemplo n.º 5
0
        private static void Main(string[] args)
        {
            ReadExecutionParams(args);
            Board      board    = DataReader.ReadBoard(_boardFileName);
            SolverBase solver   = InitSolver(board);
            Node       solution = solver.Solve();

            SaveSolutionData(solution);
        }
Ejemplo n.º 6
0
        public static void Solve(SolverBase <ITSPTW, ITSPTWObjective, IRoute> solver, string problemName, TSPTWObjectiveBase objective)
        {
            OsmSharp.Logging.Log.TraceEvent("Program.Solve", Logging.TraceEventType.Information,
                                            string.Format("Solving: {0}", problemName));

            var problem = OsmSharp.TSPTW.Parser.TSPTWProblemReader.Read(
                Assembly.GetExecutingAssembly().GetManifestResourceStream(problemName));

            Program.Solve(solver, problem, objective);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a new TSP router.
        /// </summary>
        public TSPTWRouter(IWeightMatrixAlgorithm <float> weightMatrixAlgorithm, TimeWindow[] windows, int first           = 0, int?last = null,
                           SolverBase <float, TSPTWProblem, TSPTWObjective, Itinero.Optimization.Tours.Tour, float> solver = null)
        {
            _weightMatrixAlgorithm = weightMatrixAlgorithm;
            _windows = windows;
            _first   = first;
            _last    = last;

            _weightMatrixAlgorithm = weightMatrixAlgorithm;
            _solver = solver;
        }
Ejemplo n.º 8
0
        public static void SolveAll(SolverBase <ITSPTW, ITSPTWObjective, IRoute> solver, string path, TSPTWObjectiveBase objective)
        {
            var resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();

            foreach (var resourceName in resourceNames)
            {
                if (resourceName.StartsWith(path))
                {
                    Program.Solve(solver, resourceName, objective);
                }
            }
        }
Ejemplo n.º 9
0
        public static void Solve(SolverBase <ITSPTW, ITSPTWObjective, IRoute> solver, ITSPTW problem, TSPTWObjectiveBase objective)
        {
            var info = new PerformanceInfoConsumer("solver");

            info.Start();

            var fitness = 0.0;
            var route   = solver.Solve(problem, objective, out fitness);

            info.Stop();

            OsmSharp.Logging.Log.TraceEvent("Program.Solve", Logging.TraceEventType.Information,
                                            string.Format("Finished with {0}", fitness));
        }
Ejemplo n.º 10
0
        //TODO: make this more pretty
        public static void Main(string[] args)
        {
            var cliApp     = new CommandLineApplication();
            var xivPathOpt = cliApp.Option("-p |--game-path <pathToFFXIV>",
                                           "Path to the FFXIV game install (folder containing boot and game)", CommandOptionType.SingleValue);

            var configOpt = cliApp.Option("-c |--config-path <pathToYaml>",
                                          "Path to configuration YAML file, default to config.yaml", CommandOptionType.SingleValue);

            var excludedOpt = cliApp.Option("-X |--exclude <itemId>",
                                            "Item ids of gear or food to exclude from solving; repeat for non-unique items", CommandOptionType.MultipleValue);

            var requiredOpt = cliApp.Option("-R |--require <itemId>",
                                            "Item ids of items required when solving", CommandOptionType.MultipleValue);

            var minIlvlOpt = cliApp.Option("-m |--min-itemlevel <ilvl>",
                                           "Minimum item level of items to consider. Uses max-20 if not passed.", CommandOptionType.SingleValue);
            var maxIlvlOpt = cliApp.Option("-M |--max-itemlevel <ilvl>",
                                           "Maximum item level of items to consider", CommandOptionType.SingleValue);

            var maxOvermeldTierOpt = cliApp.Option("-T |--max-overmeld-tier <tier>",
                                                   "The max tier of materia allowed for overmelds", CommandOptionType.SingleValue);

            var noMaximizeUnweightedOpt = cliApp.Option("--no-maximize-unweighted",
                                                        "Choose to disable maximizing unweighted stats (usually accuracy). Shouldn't be needed.",
                                                        CommandOptionType.NoValue);

            var noFoodOpt = cliApp.Option("--no-food", "Disable food", CommandOptionType.NoValue);

            var noMateriaOpt = cliApp.Option("--no-materia", "Disable materia", CommandOptionType.NoValue);

            var noRelicOpt = cliApp.Option("--no-relic", "Disable relic", CommandOptionType.NoValue);

            var tiersOpt = cliApp.Option("--use-tiers", "Enable SS tiers. Warning: slow unless using a commercial solver", CommandOptionType.NoValue);

            var outputOpt = cliApp.Option("-o |--output <file>", "Write output to <file>", CommandOptionType.SingleValue);

            var solverOpt = cliApp.Option("-s |--solver <solver>", "Solver to use (default: GLPK)",
                                          CommandOptionType.SingleValue);

            var noSolveOpt = cliApp.Option("--no-solve", "Don't solve the model; only works in conjunction with --debug", CommandOptionType.NoValue);

            var debugOpt = cliApp.Option("-d |--debug", "Print the used models in the current directory as model.lp",
                                         CommandOptionType.NoValue);

            var jobArg = cliApp.Argument("<job>", "Enter the job abbreviation to solve for");

            cliApp.HelpOption("-h |--help");

            cliApp.OnExecute(() =>
            {
                if (jobArg.Value == null)
                {
                    Console.Error.WriteLine("You must provide a job to solve for.");
                    return(1);
                }

                if (!xivPathOpt.HasValue())
                {
                    Console.Error.WriteLine("You must provide a path to FFXIV!");
                    return(1);
                }

                var realm   = new ARealmReversed(xivPathOpt.Value(), Language.English);
                var xivColl = realm.GameData;

                //TODO: can combine those converters
                var deserializer = new DeserializerBuilder()
                                   .WithTypeConverter(new BaseParamConverter(xivColl))
                                   .WithTypeConverter(new ClassJobConverter(xivColl))
                                   .WithTypeConverter(new EquipSlotConverter(xivColl))
                                   .WithTypeConverter(new ItemConverter(xivColl))
                                   .WithTypeConverter(new PiecewiseLinearConverter())
                                   .WithNamingConvention(new CamelCaseNamingConvention())
                                   .Build();

                SolverConfig solverConfig = null;

                using (var s = new FileStream(configOpt.HasValue() ? configOpt.Value() : "config.yaml", FileMode.Open))
                {
                    solverConfig = deserializer.Deserialize <SolverConfig>(new StreamReader(s));
                }

                solverConfig.MaximizeUnweightedValues = !noMaximizeUnweightedOpt.HasValue();
                solverConfig.UseTiers = tiersOpt.HasValue();

                var classJob = xivColl.GetSheet <ClassJob>().Single(x => string.Equals(x.Abbreviation, jobArg.Value, StringComparison.InvariantCultureIgnoreCase));

                var items = xivColl.GetSheet <Item>().ToList();

                if (excludedOpt.HasValue())
                {
                    var excludedIds = new List <int>();
                    foreach (var excluded in excludedOpt.Values)
                    {
                        try
                        {
                            var id   = int.Parse(excluded);
                            var item = xivColl.Items[id];
                            excludedIds.Add(id);
                        }
                        catch (KeyNotFoundException)
                        {
                            Console.Error.WriteLine($"Unknown id {excluded}, ignoring.");
                        }
                        catch (FormatException)
                        {
                            Console.Error.WriteLine($"Not an integer: {excluded}");
                        }
                        catch (OverflowException)
                        {
                            Console.Error.WriteLine($"Too large: {excluded}");
                        }
                    }
                    items = items.Where(k => !excludedIds.Contains(k.Key)).ToList();
                }

                //TODO: duplicated code
                if (requiredOpt.HasValue())
                {
                    solverConfig.RequiredItems = new List <int>();
                    requiredOpt.Values.Select(int.Parse).ForEach(solverConfig.RequiredItems.Add);
                }

                var equip = items.OfType <Equipment>().Where(e => e.ClassJobCategory.ClassJobs.Contains(classJob));

                var maxIlvl = equip.Max(x => x.ItemLevel.Key);
                if (maxIlvlOpt.HasValue())
                {
                    maxIlvl = int.Parse(maxIlvlOpt.Value());
                }

                var minIlvl = maxIlvl - 20;
                if (minIlvlOpt.HasValue())
                {
                    minIlvl = int.Parse(minIlvlOpt.Value());
                }

                equip = equip.Where(e => e.ItemLevel.Key >= minIlvl && e.ItemLevel.Key <= maxIlvl || solverConfig.RequiredItems != null && solverConfig.RequiredItems.Contains(e.Key)).ToList();

                var food = noFoodOpt.HasValue() ? new List <FoodItem>() : items.Where(FoodItem.IsFoodItem).Select(t => new FoodItem(t));

                var maxTier = items.OfType <MateriaItem>().Max(i => i.Tier);
                var materia = noMateriaOpt.HasValue() ? new Dictionary <MateriaItem, bool>() : items.OfType <MateriaItem>()
                              .Where(i => i.Tier == maxTier || (maxOvermeldTierOpt.HasValue() && i.Tier == int.Parse(maxOvermeldTierOpt.Value()) - 1))
                              .ToDictionary(i => i, i => !maxOvermeldTierOpt.HasValue() || i.Tier < int.Parse(maxOvermeldTierOpt.Value()));

                if (noRelicOpt.HasValue())
                {
                    solverConfig.RelicConfigs = new Dictionary <int, RelicConfig>();
                }

                //TODO: improve solver handling
                SolverBase solver = CreateGLPKSolver();
                if (solverOpt.HasValue())
                {
                    switch (solverOpt.Value())
                    {
                    case "Gurobi":
                        solver = new GurobiSolver();
                        solverConfig.SolverSupportsSOS = true;
                        break;
                    }
                }

                var debug    = debugOpt.HasValue();
                var settings = new OptimizationConfigSection();
                //settings.ModelElement.EnableFullNames = debug;

                using (var scope = new ModelScope(settings))
                {
                    var model = new BisModel(solverConfig, classJob,
                                             equip, food, materia);

                    if (debug)
                    {
                        using (var f = new FileStream("model.lp", FileMode.Create))
                        {
                            model.Model.Write(f, FileType.LP);
                        }
                        using (var f = new FileStream("model.mps", FileMode.Create))
                        {
                            model.Model.Write(f, FileType.MPS);
                        }

                        if (noSolveOpt.HasValue())
                        {
                            Console.WriteLine("Printed model, exiting...");
                            return(0);
                        }
                    }

                    var solution = solver.Solve(model.Model);

                    model.ApplySolution(solution);

                    if (outputOpt.HasValue())
                    {
                        using (var fs = new FileStream(outputOpt.Value(), FileMode.Create))
                        {
                            var sw = new StreamWriter(fs);
                            OutputModel(model, sw);
                            sw.Close();
                        }
                    }
                    else
                    {
                        OutputModel(model, Console.Out);
                    }
                    Console.WriteLine(solverConfig.UseTiers ? "SS tiers have been taken into account" : "SS tiers have been ignored; pass --use-tiers to enable (slow)");
                }

                return(0);
            });

            cliApp.Execute(args);
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Solves this problem using the given solver.
 /// </summary>
 public Tour Solve(SolverBase <float, STSProblem, STSPObjective, Tour, STSPFitness> solver)
 {
     return(solver.Solve(this, new STSPObjective()));
 }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string>    dictValues = new Dictionary <string, string>();
            CalculationOptionsShadowPriest calcOpts   = character.CalculationOptions as CalculationOptionsShadowPriest;
            BossOptions BossOpts  = character.BossOptions;
            Stats       baseStats = BaseStats.GetBaseStats(character.Level, character.Class, character.Race);
            bool        Ptr       = calcOpts.PTR;

            dictValues.Add("Health", BasicStats.Health.ToString());
            float ResilienceCap = 0.15f, ResilienceFromRating = StatConversion.GetCritReductionFromResilience(1);
            float Resilience = StatConversion.GetCritReductionFromResilience(BasicStats.Resilience);

            dictValues.Add("Resilience", string.Format("{0}*-{1}% Damage from DoT and Mana Drains\n\r-{1}% Chance to be crit\r\n-{2}% Damage from Crits.\r\n{3}",
                                                       BasicStats.Resilience.ToString(),
                                                       (Resilience * 100f).ToString("0.00"),
                                                       (Resilience * 100f * 2.2f).ToString("0.00"),
                                                       (Resilience > ResilienceCap) ? (string.Format("{0} rating above cap", ((float)Math.Floor((Resilience - ResilienceCap) / ResilienceFromRating)).ToString("0"))) : (string.Format("{0} rating below cap", ((float)Math.Ceiling((ResilienceCap - Resilience) / ResilienceFromRating)).ToString("0")))));
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Mana", BasicStats.Mana.ToString());
            dictValues.Add("Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Spirit", Math.Floor(BasicStats.Spirit).ToString("0"));
            dictValues.Add("Spell Power", String.Format("{0}*{1} Bonus Shadow\r\n{2} Bonus Holy\r\n{3} from Inner Fire",
                                                        Math.Floor(BasicStats.SpellPower),
                                                        Math.Floor(BasicStats.SpellPower + BasicStats.SpellShadowDamageRating),
                                                        Math.Floor(BasicStats.SpellPower /*+ BasicStats.SpellHolyDamageRating*/),
                                                        BasicStats.PriestInnerFire * CalculationsShadowPriest.GetInnerFireSpellPowerBonus(character)));
            dictValues.Add("Regen", String.Format("{0}*MP5: {1}\r\nOutFSR: {2}", RegenInFSR.ToString("0"), BasicStats.Mp5.ToString(), RegenOutFSR.ToString("0")));

            dictValues.Add("Crit", string.Format("{0}%*{1}% from {2} Spell Crit rating\r\n{3}% from Intellect\r\n{4}% from Focused Will\r\n{5}% from Base Crit\r\n{6}% from Buffs\r\n{7}% on Mind Blast, Mind Flay and Mind Sear.\r\n{8}% on VT, SW:P and DP\r\n{9}% on Smite, Holy Fire and Penance.",
                                                 (BasicStats.SpellCrit * 100f).ToString("0.00"),
                                                 (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("0.00"),
                                                 BasicStats.CritRating.ToString("0"),
                                                 (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f).ToString("0.00"),
                                                 character.PriestTalents.FocusedWill,
                                                 (baseStats.SpellCrit * 100f).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f - StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f - StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f - baseStats.SpellCrit * 100f - character.PriestTalents.FocusedWill).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f + character.PriestTalents.MindMelt * 2f).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f + character.PriestTalents.MindMelt * 3f).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f + character.PriestTalents.HolySpecialization * 1f).ToString("0.00")));

#if RAWR3 || SILVERLIGHT
            float Hit = 100 - (StatConversion.GetSpellMiss(character.Level - BossOpts.Level, false) * 100);
#else
            float Hit = 100 - (StatConversion.GetSpellMiss(-calcOpts.TargetLevel, false) * 100);
#endif
            float  BonusHit   = BasicStats.SpellHit * 100f;
            float  RacialHit  = 0;
            string RacialText = "";
            if (character.Race == CharacterRace.Draenei)
            {
                RacialHit  = 1;
                RacialText = "1% from Draenei Racial\r\n";
                if (!character.ActiveBuffsContains("Heroic Presence"))
                {
                    BonusHit += 1;
                }
            }
            float DebuffHit = character.PriestTalents.Misery * 1f;
            if (character.ActiveBuffsConflictingBuffContains("Spell Hit Chance Taken"))
            {
                DebuffHit = 3f;
            }
            else
            {
                BonusHit += DebuffHit;
            }

            float RHitRating     = 0.01f / StatConversion.GetSpellHitFromRating(1);
            float ShadowFocusHit = character.PriestTalents.ShadowFocus * 1f;
            float HitShadow      = Hit + BonusHit + ShadowFocusHit;
            float HitHoly        = Hit + BonusHit;
            dictValues.Add("Hit", string.Format("{0}%*{1}% from {2} Hit Rating\r\n{3}% from Buffs\r\n{4}% from {5} points in Misery\r\n{6}% from {7} points in Shadow Focus\r\n{8}{9}% Hit with Shadow spells, {10}\r\n{11}% Hit with Holy spells, {12}",
                                                BonusHit.ToString("0.00"),
                                                (StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f).ToString("0.00"), BasicStats.HitRating,
                                                (BonusHit - StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f - RacialHit - DebuffHit).ToString("0.00"),
                                                DebuffHit, character.PriestTalents.Misery,
                                                ShadowFocusHit, character.PriestTalents.ShadowFocus,
                                                RacialText,
                                                HitShadow.ToString("0.00"), (HitShadow > 100f) ? string.Format("{0} hit rating above cap", Math.Floor((HitShadow - 100f) * RHitRating)) : string.Format("{0} hit rating below cap", Math.Ceiling((100f - HitShadow) * RHitRating)),
                                                HitHoly.ToString("0.00"), (HitHoly > 100f) ? string.Format("{0} hit rating above cap", Math.Floor((HitHoly - 100f) * RHitRating)) : string.Format("{0} hit rating below cap", Math.Ceiling((100f - HitHoly) * RHitRating))));

            dictValues.Add("Haste", string.Format("{0}%*{1}% from {2} Haste rating\r\n{3}% ({6}) points in Enlightenment\r\n{4}% from Buffs\r\n{5}s Global Cooldown",
                                                  (BasicStats.SpellHaste * 100f).ToString("0.00"), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating) * 100f).ToString("0.00"), BasicStats.HasteRating.ToString(), (character.PriestTalents.Enlightenment * 2).ToString("0"), (((1f + BasicStats.SpellHaste) / (1f + StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating)) / (1f + character.PriestTalents.Enlightenment * 0.02f) - 1f) * 100f).ToString("0.00"), Math.Max(1.0f, 1.5f / (1 + BasicStats.SpellHaste)).ToString("0.00"), character.PriestTalents.Enlightenment));
            dictValues.Add("Armor", string.Format("{0}*{1}% Damage Reduction.",
                                                  (BasicStats.Armor + BasicStats.BonusArmor).ToString("0"),
                                                  (StatConversion.GetArmorDamageReduction(80, (BasicStats.Armor + BasicStats.BonusArmor), 0f, 0f, 0f) * 100f).ToString("0.00")));

            float[] Resistances =
            {
                0,
                BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff,
                BasicStats.FireResistance + BasicStats.FireResistanceBuff,
                BasicStats.FrostResistance + BasicStats.FrostResistanceBuff,
                BasicStats.NatureResistance + BasicStats.NatureResistanceBuff,
                BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff,
            };

            string[] ResistanceNames =
            {
                "None",
                "Arcane",
                "Fire",
                "Frost",
                "Nature",
                "Shadow",
            };

            string ResistanceString = "*Resistances:";

            float MaxResist      = Resistances[0];
            int   MaxResistIndex = 0;
            float AvgResist      = 0f;
            for (int x = 1; x < Resistances.Length; x++)
            {
                AvgResist += Resistances[x];
                if (Resistances[x] > MaxResist)
                {
                    MaxResist      = Resistances[x];
                    MaxResistIndex = x;
                }
                ResistanceString += string.Format("\r\n{0} : {1}", ResistanceNames[x], Resistances[x]);
            }
            AvgResist /= (Resistances.Length - 1);

            if (AvgResist == 0)
            {
                ResistanceString = "None" + ResistanceString;
            }
            else
            {
                string ResistanceName = (MaxResist == AvgResist) ? "All" : ResistanceNames[MaxResistIndex];
                ResistanceString  = string.Format("{0} : {1}", ResistanceName, MaxResist.ToString("0")) + ResistanceString;
                ResistanceString += string.Format("\r\n\r\nResist ({0}):", ResistanceName);
                ResistanceString += string.Format("\r\n{0}", StatConversion.GetResistanceTableString(character.Level + 3, character.Level, MaxResist, 0));
            }

            dictValues.Add("Resistance", ResistanceString);

            SolverBase solver = GetSolver(character, BasicStats);
            solver.Calculate(this);

            dictValues.Add("Rotation", string.Format("{0}*{1}", solver.Name, solver.Rotation));
            if (solver.SpellSimulation != null)
            {
                String s = "Spell Cast List:";
                int    i = 0;
                foreach (Spell spell in solver.SpellSimulation)
                {
                    if (i++ % 10 == 0)
                    {
                        s += "\r\n";
                    }
                    s += ", " + spell.Name;
                }
                s += "\r\n---Repeat---";
                dictValues.Add("Castlist", string.Format("{0}*{1}", solver.SpellSimulation.Count, s));
            }
            else
            {
                dictValues.Add("Castlist", "Empty");
            }
            dictValues.Add("DPS", string.Format("{0}*Damage Pr Second", solver.DPS.ToString("0")));
            //dictValues.Add("SustainDPS", string.Format("{0}*Mana restrained DPS", solver.SustainDPS.ToString("0")));

            float baseMana = BaseStats.GetBaseStats(character).Mana;

            dictValues.Add("SW Pain", new ShadowWordPain(BasicStats, character, baseMana, Ptr).ToString());
            DevouringPlague dp = new DevouringPlague(BasicStats, character, baseMana, Ptr);
            dictValues.Add("Devouring Plague", dp.ToString());
            if (dp.ImprovedDP != null)
            {
                dictValues.Add("Imp. Devouring Plague", dp.ImprovedDP.ToString());
            }
            else
            {
                dictValues.Add("Imp. Devouring Plague", "- *No required talents");
            }
            dictValues.Add("SW Death", new ShadowWordDeath(BasicStats, character, baseMana, Ptr).ToString());
            dictValues.Add("Mind Blast", new MindBlast(BasicStats, character, baseMana, Ptr).ToString());
            dictValues.Add("PW Shield", new PowerWordShield(BasicStats, character, baseMana, Ptr).ToString());

            if (character.PriestTalents.VampiricTouch > 0)
            {
                dictValues.Add("Vampiric Touch", new VampiricTouch(BasicStats, character, baseMana, Ptr).ToString());
            }
            else
            {
                dictValues.Add("Vampiric Touch", "- *No required talents");
            }

            if (character.PriestTalents.MindFlay > 0)
            {
                dictValues.Add("Mind Flay", new MindFlay(BasicStats, character, baseMana, Ptr).ToString());
            }
            else
            {
                dictValues.Add("Mind Flay", "- *No required talents");
            }

            dictValues.Add("Shadowfiend", new Shadowfiend(BasicStats, character, baseMana, Ptr).ToString());

            dictValues.Add("Smite", new Smite(BasicStats, character, baseMana, Ptr).ToString());
            dictValues.Add("Holy Fire", new HolyFire(BasicStats, character, baseMana, Ptr).ToString());
            if (character.PriestTalents.Penance > 0)
            {
                dictValues.Add("Penance", new Penance(BasicStats, character, baseMana, Ptr).ToString());
            }
            else
            {
                dictValues.Add("Penance", "- *No required talents");
            }

            return(dictValues);
        }