public static void SavingThrows(CharacterBasic character, Proficiency proficiencies)
 {
     //The stats assigned to saving throw proficiency are determined by Character Class.
     if (character.CClassSet == false)
     {
         Console.ForegroundColor = ConsoleColor.Red;
     }
     else
     {
         Console.ForegroundColor = ConsoleColor.Green;
     }
     Console.WriteLine("\r\nSaving Throws: {0} {1}", proficiencies.SavingThrows[0], proficiencies.SavingThrows[1]);
     Console.ResetColor();
 }
 public static Stats Conditionals(CharacterBasic character, CharacterRace race, Stats racialBonus, Equipment equipment, Languages languages, Proficiency proficiencies, Features features)
 {
     //Controls details of character race choice. Subraces, ability scores, Languages based on race. Subrace functionality technically not necessary due to licensing restrictions. Included in case of software repurposing.
     race = Controller(character.Race);
     character.SubRace        = race.SubRace;
     character.Draconic       = race.Draconic;
     character.Speed          = race.Speed;
     racialBonus              = race.RacialBonus;
     languages.Native         = race.NativeLanguage;
     proficiencies.RaceTools  = race.RaceToolsProficiencies;
     proficiencies.RaceArms   = race.RaceArmsProficiencies;
     proficiencies.RaceSkills = race.RaceSkillsProficiencies;
     features.Race            = race.Features;
     proficiencies.Tools      = Proficiency.Configuration.ListHelper(proficiencies.Tools, proficiencies.RaceTools, proficiencies.ClassTools);
     proficiencies.Arms       = Proficiency.Configuration.ListHelper(proficiencies.Arms, proficiencies.RaceArms, proficiencies.ClassArms);
     proficiencies.Skills     = Proficiency.Configuration.ListHelper(proficiencies.Skills, proficiencies.RaceSkills, proficiencies.ClassSkills);
     return(racialBonus);
 }
        public static void Menu(CharacterBasic character, Health health, Stats abilityScores, Stats abilityModifiers, Stats savingThrows, Equipment equipment, Languages languages, Proficiency proficiencies, Skills skills, CharacterClass characterClass, Features features, bool langProfFlag)   //Lists every important user choice. Information here will be used in future updates to launch to a webpage using HTML/CSS to allow easy porting of configs to character sheet
        {
            //Displays all the user's selections and everything they gain from said selections.
            //Red indicates unfinished, Green indicates completed
            Console.Clear();
            BasicInformation(character, abilityScores, langProfFlag);
            SavingThrows(character, proficiencies);
            HealthInformation(health, character, abilityModifiers, equipment);
            AbilityScores(abilityScores, abilityModifiers);

            Generic("\r\nRace Features: ", features.Race);
            ClassFeatures(character, features);
            Generic("\r\nLanguages: ", languages.List);
            Generic("\r\nEquipment: ", equipment.Bag);
            Generic("\r\nTools Proficiency: ", proficiencies.Tools);
            Generic("\r\nArms Proficiency: ", proficiencies.Arms);

            Generic("\r\nSkills: ", proficiencies.Skills);
            Skills(savingThrows, skills, abilityScores);
            Console.Write("\r\nEnter selection: ");
        }
        public static void Conditionals(CharacterBasic character, Health health, Stats abilityModifiers, Equipment equipment, Languages languages, Proficiency proficiencies, CharacterClass characterClass, Features features, SpellBook spellCasting)
        {
            //Collects all relevant objects from Program Main and overwrites their properties from corresponding objects from a 'Character Class' class determined by the controller.

            Console.Clear();
            characterClass             = Controller(character.CClass); //Gets character class properties
            character.SubClass         = characterClass.SubClass;
            health.HitPointsConstant   = characterClass.HitPointsConstant;
            health.HitDice             = characterClass.HitDice;
            proficiencies.ClassArms    = characterClass.ClassArmsProficiencies;
            proficiencies.SavingThrows = characterClass.SavingThrows;
            features.Class             = characterClass.Features;

            equipment.ClassBag   = Equipment.Controller(character.CClass, character, abilityModifiers, features);                                   //Gets the equipment setting/options. Determined by character class.
            equipment.Bag        = Proficiency.Configuration.ListHelper(equipment.Bag, equipment.RaceBag, equipment.ClassBag);                      //Consolidates equipment into a main list.
            proficiencies.Tools  = Proficiency.Configuration.ListHelper(proficiencies.Tools, proficiencies.RaceTools, proficiencies.ClassTools);    //Consolidates tools into a main list.
            proficiencies.Arms   = Proficiency.Configuration.ListHelper(proficiencies.Arms, proficiencies.RaceArms, proficiencies.ClassArms);       //Consolidates armaments into a main list.
            proficiencies.Skills = Proficiency.Configuration.ListHelper(proficiencies.Skills, proficiencies.RaceSkills, proficiencies.ClassSkills); //Consolidates skills into a main list.


            if (characterClass.SubClass == "Life") //Heavy armor proficiency is granted by Life Domain.
            {
                Cleric cleric = new Cleric();
                cleric.DomainSpells = new List <string> {
                    "Bless", "Cure Wounds"
                };
                cleric.Cantrips = cleric.SelectSpells(cleric, 0, abilityModifiers);
                foreach (string cantrip in cleric.Cantrips)
                {
                    features.Class.Add(cantrip);
                }
                features.Class.Add("Bless");
                features.Class.Add("Cure Wounds");
                features.Class.Add("Disciple of Life");

                characterClass.ClassArmsProficiencies.Add("Heavy Armor");
            }
            if (characterClass.SubClass == "Evocation") //Heavy armor proficiency is granted by Life Domain.
            {
                Wizard wizard = new Wizard();
                wizard.Cantrips  = wizard.SelectSpells(wizard, 0, abilityModifiers);
                wizard.SpellBook = wizard.FillSpellBook(wizard);
                foreach (string cantrip in wizard.Cantrips)
                {
                    features.Class.Add(cantrip);
                }
                foreach (string spell in wizard.SpellBook)
                {
                    features.Class.Add(spell);
                }
                features.Class.Add("Arcane Recovery");
            }
            Console.Clear();
            if (character.Background == "Acolyte")
            {
                equipment.Bag.Add("Holy Symbol");
                features.Background.Add(BackgroundFeatures.Acolyte());
            }
        }
Exemple #5
0
        static void Main(string[] args)
        {
            //Initializing objects, variables, etc.
            bool displayMenu  = true;
            bool langProfFlag = true;

            //Name, Gender, Race, Subrace, Draconic Heritage, Class, Subclass, Background, Alignment, Level, Speed
            CharacterBasic character = new CharacterBasic();

            //HP, HP constant, AC, Hit Dice, Initiative
            Health health = new Health();

            //Constitution, Strength, Dexterity, Intelligence, Wisdom, Charisma
            Stats stats            = new Stats();   //Generic object to hold numbers.
            Stats racialBonus      = new Stats();   //These values come from race selection.
            Stats abilityScores    = new Stats();   //Stat values and Racial values are added and stored here.
            Stats abilityModifiers = new Stats();   //These values are used for various skills and actions. Each number is determined directly by it's corresponding ability score from a table.
            Stats savingThrows     = new Stats();   //These values are primarily used for specific proficiencies. Each number is determined by it's corresponding ability modifier; + 2 if proficient.

            Languages languages = new Languages();
            Skills    skills    = new Skills();

            //Empty equipment list
            Equipment equipment = new Equipment(
                bag: new List <string>(),
                raceBag: new List <string>(),
                classBag: new List <string>());
            //Empty features list
            Features features = new Features(
                race: new List <string> {
                ""
            },
                cClass: new List <string> {
                ""
            },
                background: new List <string> {
                ""
            });

            //Empty proficiencies list
            Proficiency proficiencies = new Proficiency(
                2,          //Proficiency Bonus
                arms: new List <string>(),
                skills: new List <string>(),
                tools: new List <string>(),
                savingThrows: new List <string> {
                "", ""
            });                                                     //Invisible string values hard-coded in to prevent error.

            //Secondary object for collecting additional details from race decision.
            CharacterRace race = new CharacterRace(
                "", "", "", 0, 0, "", racialBonus,             //Race, Subrace, Draconic Heritage, Speed, Extra Language, Extra Proficiency, native Language, Racial Bonus
                features: new List <string>(),
                raceArms: new List <string>(),
                raceSkills: new List <string>(),
                raceTools: new List <string>(),
                cantrips: new List <string>());

            //Secondary object for collecting additional details from class decision.
            CharacterClass characterClass = new CharacterClass();
            SpellBook      spellCasting   = new SpellBook();

            StartUp();          //Display text
            while (displayMenu) //Encloses entire program
            {
                displayMenu = MainMenu();
            }
            bool MainMenu()
            {
                //This is the primary menu for selecting and editing aspects of the character.
                //When a character property is set, the display listing turns green.

                RefreshValues();                                                                                                                                                       //Assigns the end results of stat configuration. Readjusts every time user returns to Main Menu
                Dashboard.Menu(character, health, abilityScores, abilityModifiers, savingThrows, equipment, languages, proficiencies, skills, characterClass, features, langProfFlag); //Display panel
                switch (Dashboard.Controller())                                                                                                                                        //Primary configuration menu
                {
                case "Name":
                    Console.Clear();
                    Console.WriteLine("Name your character: ");
                    character.Name = Console.ReadLine();
                    if (character.Name is "")
                    {
                        character.NameSet = false;
                    }
                    else
                    {
                        character.NameSet = true;
                    }
                    return(true);

                case "Gender":
                    Console.Clear();
                    character.Gender    = "";
                    character.Gender    = character.SetGender();
                    character.GenderSet = true;
                    return(true);

                case "Race":     //Races in D&D are better described as humanoid subspecies. Dwarves differ from Elves like Pitbulls differ from Greyhounds.
                    Console.Clear();
                    character.Race = "";
                    RaceListsReset();       //Empties relevent lists used when character race is changed.
                    while (character.Race == "")
                    {
                        character.Race = race.SetRace();
                    }
                    racialBonus    = CharacterRace.Conditionals(character, race, racialBonus, equipment, languages, proficiencies, features);  //Secondary menu for character race
                    languages.List = new List <string> {
                        "Common", languages.Native
                    };                                                                      //The language list is cleared. Common and native language from race are set. Other languages known will be set under "Language/Proficiency" menu.

                    //Lists used in RaceConditionals are emptied. Preventative measure against unexpected errors.
                    equipment.RaceBag       = new List <string>();      //Reset
                    proficiencies.RaceTools = new List <string>();      //Reset
                    proficiencies.RaceArms  = new List <string>();      //Reset
                    character.RaceSet       = true;
                    langProfFlag            = true;
                    return(true);

                case "Background & Class":  //User can choose Acolyte background or None. Only the 4 classic D&D classes are included for now. The rest will be included in later updates.
                    Console.Clear();
                    ClassListsReset();      //Empties relevent lists used when character race is changed.
                    character.Background = "";
                    character.CClass     = "";
                    string backgroundPrevious = character.Background;
                    character.Background = characterClass.SetBackground();
                    if (!character.Background.Equals(backgroundPrevious))       //If the user removes the 'Acolyte' background, the language list should reset so that they don't get the extra language benefits.
                    {
                        languages.List = new List <string>();
                    }
                    character.CClass = characterClass.SetClass();
                    characterClass   = CharacterClass.Controller(character.CClass);                                                                                //Gets class features for selected class
                    CharacterClass.Conditionals(character, health, abilityModifiers, equipment, languages, proficiencies, characterClass, features, spellCasting); //Secondary menu for character class options. Includes integration of background benefits.

                    //Lists used in RaceConditionals are emptied. Preventative measure against unexpected errors.
                    equipment.ClassBag        = new List <string>();    //Reset
                    languages.Background      = new List <string>();    //Reset
                    proficiencies.ClassTools  = new List <string>();    //Reset
                    proficiencies.ClassArms   = new List <string>();    //Reset
                    proficiencies.ClassSkills = new List <string>();    //Reset
                    character.BackgroundSet   = true;
                    character.CClassSet       = true;
                    langProfFlag = true;
                    return(true);

                case "Alignment":       //Character alignment describes broad-stroked trajectory of character's moral/social tendencies. Mostly for role-play, but matters for Cleric/Paladin classes.
                    Console.Clear();
                    character.Alignment    = "";
                    character.Alignment    = character.SetAlignment();
                    character.AlignmentSet = true;
                    return(true);

                case "Stats":       //Series of menus that will ultimately facilitate assignment of character ability scores.
                    Console.Clear();
                    stats     = Stats.Menu(character, stats, racialBonus);
                    stats.Set = true;
                    return(true);

                case "Language/Proficiency":                            //Extra languages and proficiency choices will be determined here
                    if (character.Race == "" || character.CClass == "") //If race or class are not set, returns to main menu
                    {
                        Console.Clear();
                        Console.WriteLine("This menu will become available after you've selected both a race and class. \r\n" +
                                          "Press Enter to return to the main menu.");
                        Console.ReadLine();
                        return(true);
                    }
                    else          //Continues with selection
                    {
                        langProfFlag         = false;
                        languages.List       = Languages.SelectLanguages(languages.Native, character.Race, character.Background); //Adjusts for extra languages
                        proficiencies.Skills = Proficiency.Configuration.SelectSkills(character, characterClass);                 //Adjusts for skill options
                    }
                    return(true);

                case "Null":
                    return(true);

                case "Exit":
                    return(false);
                }
                return(false);
            }

            void RefreshValues()
            {
                //This function updates all settings, especially numerical, every time the user returns to the main menu.
                //Equipment
                equipment.Bag = Proficiency.Configuration.ListHelper(equipment.Bag, equipment.RaceBag, equipment.ClassBag); //equipment is consolidated into main list.
                equipment.Bag = Equipment.DuplicateItemStacker(equipment.Bag);                                              //Any duplicates are stacked. If 2 of 'x' exists, it becomes '2 x'.

                //Stats
                abilityScores    = Stats.AbilityScoreAssigner(stats, racialBonus);  //Ability Score x = Stat x + Racial Bonus x.
                abilityModifiers = Stats.AbilityModifierAssigner(abilityScores);    //Ability Modifier x assigned by charting system from AbilityModAssigner method, given Ability Score x.

                //For dashboard
                if (stats.Set == true)
                {
                    //If the user has used the 'Stats' menu, the ability scores should be assigned. So long as this is the case, the following conditions are also true.
                    //The dashboard class will use these booleans for it's processes.
                    abilityScores.Set    = true;
                    abilityModifiers.Set = true;
                    health.InitiativeSet = true;
                }
                if (health.HitPointsConstantSet == true && abilityModifiers.Set == true && character.RaceSet == true)
                {
                    health.HitPointsSet = true;
                }
                if (character.CClassSet)
                {
                    //If the user has used the 'Background & Class' menu, the following conditions are true.
                    //The dashboard class will use these booleans for it's processes.
                    health.HitPointsConstantSet = true;
                    health.HitDiceSet           = true;
                    if (abilityModifiers.Set == true)
                    {
                        health.ArmorClassSet = true;
                    }
                }


                //The following is poorly optimized code, it manually sets individual data points. Methods will be written to streamline these in the future.

                //Saving Throws
                savingThrows = Skills.SavingThrowAssigner(savingThrows, abilityModifiers);  //Saving Throw x = Ability Modifier x, +2 if proficient

                if (proficiencies.SavingThrows.Contains("Constitution"))
                {
                    savingThrows.Constitution += proficiencies.ProficiencyBonus;
                }
                if (proficiencies.SavingThrows.Contains("Strength"))
                {
                    savingThrows.Strength += proficiencies.ProficiencyBonus;
                }
                if (proficiencies.SavingThrows.Contains("Dexterity"))
                {
                    savingThrows.Dexterity += proficiencies.ProficiencyBonus;
                }
                if (proficiencies.SavingThrows.Contains("Intelligence"))
                {
                    savingThrows.Intelligence += proficiencies.ProficiencyBonus;
                }
                if (proficiencies.SavingThrows.Contains("Wisdom"))
                {
                    savingThrows.Wisdom += proficiencies.ProficiencyBonus;
                }
                if (proficiencies.SavingThrows.Contains("Charisma"))
                {
                    savingThrows.Charisma += proficiencies.ProficiencyBonus;
                }

                //Groups each skill together by their related ability modifier. Foreach loop will assign each group the value of it's modifier.
                int[][] skillsBuilder = new int[5][];
                skillsBuilder[0] = new int[] { abilityModifiers.Strength, skills.Athletics };                                                                         //Strength
                skillsBuilder[1] = new int[] { abilityModifiers.Dexterity, skills.Acrobatics, skills.SleightOfHand, skills.Stealth };                                 //Dexterity
                skillsBuilder[2] = new int[] { abilityModifiers.Intelligence, skills.Arcana, skills.History, skills.Investigation, skills.Nature, skills.Religion };  //Intelligence
                skillsBuilder[3] = new int[] { abilityModifiers.Wisdom, skills.AnimalHandling, skills.Insight, skills.Medicine, skills.Perception, skills.Survival }; //Wisdom
                skillsBuilder[4] = new int[] { abilityModifiers.Charisma, skills.Deception, skills.Intimidation, skills.Performance, skills.Persuasion };             //Charisma
                foreach (int[] item in skillsBuilder)
                {
                    for (int i = 1; i < item.Length; i++)
                    {
                        item[i] = item[0];
                    }
                }

                //skill x = related modifier + 2 (if proficient)
                skills.Athletics = skillsBuilder[0][0];
                if (proficiencies.Skills.Contains(nameof(skills.Athletics)))
                {
                    skills.Athletics += proficiencies.ProficiencyBonus;
                }
                skills.Acrobatics = skillsBuilder[1][0];
                if (proficiencies.Skills.Contains(nameof(skills.Acrobatics)))
                {
                    skills.Acrobatics += proficiencies.ProficiencyBonus;
                }
                skills.SleightOfHand = skillsBuilder[1][1];
                if (proficiencies.Skills.Contains(nameof(skills.SleightOfHand)))
                {
                    skills.SleightOfHand += proficiencies.ProficiencyBonus;
                }
                skills.Stealth = skillsBuilder[1][2];
                if (proficiencies.Skills.Contains(nameof(skills.Stealth)))
                {
                    skills.Stealth += proficiencies.ProficiencyBonus;
                }
                skills.Arcana = skillsBuilder[2][0];
                if (proficiencies.Skills.Contains(nameof(skills.Arcana)))
                {
                    skills.Arcana += proficiencies.ProficiencyBonus;
                }
                skills.History = skillsBuilder[2][1];
                if (proficiencies.Skills.Contains(nameof(skills.History)))
                {
                    skills.History += proficiencies.ProficiencyBonus;
                }
                skills.Investigation = skillsBuilder[2][2];
                if (proficiencies.Skills.Contains(nameof(skills.Investigation)))
                {
                    skills.Investigation += proficiencies.ProficiencyBonus;
                }
                skills.Nature = skillsBuilder[2][3];
                if (proficiencies.Skills.Contains(nameof(skills.Nature)))
                {
                    skills.Nature += proficiencies.ProficiencyBonus;
                }
                skills.Religion = skillsBuilder[2][4];
                if (proficiencies.Skills.Contains(nameof(skills.Religion)))
                {
                    skills.Religion += proficiencies.ProficiencyBonus;
                }
                skills.AnimalHandling = skillsBuilder[3][0];
                if (proficiencies.Skills.Contains(nameof(skills.AnimalHandling)))
                {
                    skills.AnimalHandling += proficiencies.ProficiencyBonus;
                }
                skills.Insight = skillsBuilder[3][1];
                if (proficiencies.Skills.Contains(nameof(skills.Insight)))
                {
                    skills.Insight += proficiencies.ProficiencyBonus;
                }
                skills.Medicine = skillsBuilder[3][2];
                if (proficiencies.Skills.Contains(nameof(skills.Medicine)))
                {
                    skills.Medicine += proficiencies.ProficiencyBonus;
                }
                skills.Perception = skillsBuilder[3][3];
                if (proficiencies.Skills.Contains(nameof(skills.Perception)))
                {
                    skills.Perception += proficiencies.ProficiencyBonus;
                }
                skills.Survival = skillsBuilder[3][4];
                if (proficiencies.Skills.Contains(nameof(skills.Survival)))
                {
                    skills.Survival += proficiencies.ProficiencyBonus;
                }
                skills.Deception = skillsBuilder[4][0];
                if (proficiencies.Skills.Contains(nameof(skills.Deception)))
                {
                    skills.Deception += proficiencies.ProficiencyBonus;
                }
                skills.Intimidation = skillsBuilder[4][1];
                if (proficiencies.Skills.Contains(nameof(skills.Intimidation)))
                {
                    skills.Intimidation += proficiencies.ProficiencyBonus;
                }
                skills.Performance = skillsBuilder[4][2];
                if (proficiencies.Skills.Contains(nameof(skills.Performance)))
                {
                    skills.Performance += proficiencies.ProficiencyBonus;
                }
                skills.Persuasion = skillsBuilder[4][3];
                if (proficiencies.Skills.Contains(nameof(skills.Persuasion)))
                {
                    skills.Persuasion += proficiencies.ProficiencyBonus;
                }

                //These disabled lists are part of potential strategies for replacing manually-written code with loops.
                //Each skill is grouped by the ability modifier it depends on. By default, the skill literally equals the modifier.
                //If the character is proficient in the skill, it's value = ability modifier + proficiency bonus. The bonus is always 2 so long as the application only manipulates level 1 characters.
                //Intended strategy to replace hard-coded instructons:
                //First: Use a loop to compare known proficiencies with list of all proficiencies. If a match occurs, switch the corresponding skills boolean to true, else boolean is false.
                //Second: Use another loop to compare list of all skills with skills boolean. If false, skill = modifier. If true, skill = modifier + proficiency bonus;

                //List<string> allSkillNames = new List<string> { "Athletics",
                //                                                "Acrobatics", "SleightOfHand", "Stealth",
                //                                                "Arcana", "History", "Investigation", "Nature", "Religion",
                //                                                "AnimalHandling", "Insight", "Medicine", "Perception", "Survival",
                //                                                "Deception", "Intimidation", "Performance", "Persuasion" };
                //List<int> allSkills = new List<int> { skills.Athletics,
                //                                      skills.Acrobatics, skills.SleightOfHand, skills.Stealth,
                //                                      skills.Arcana, skills.History, skills.Investigation, skills.Nature, skills.Religion,
                //                                      skills.AnimalHandling, skills.Insight, skills.Medicine, skills.Perception, skills.Survival,
                //                                      skills.Deception, skills.Intimidation, skills.Performance, skills.Persuasion };

                //List<bool> allProficiencies = new List<bool> { skills.AthleticsSet,
                //                                               skills.AcrobaticsSet, skills.SleightOfHandSet, skills.StealthSet,
                //                                               skills.ArcanaSet, skills.HistorySet, skills.InvestigationSet, skills.NatureSet, skills.ReligionSet,
                //                                               skills.AnimalHandlingSet, skills.InsightSet, skills.MedicineSet, skills.PerceptionSet, skills.SurvivalSet,
                //                                               skills.DeceptionSet, skills.IntimidationSet, skills.PerformanceSet, skills.PersuasionSet };
            }

            void ClassListsReset()
            {
                equipment.Bag      = new List <string>();        //Reset
                equipment.ClassBag = new List <string>();        //Reset

                languages.Background = new List <string>();      //Reset

                proficiencies.Tools      = new List <string>();  //Reset
                proficiencies.ClassTools = new List <string>();  //Reset

                proficiencies.Arms      = new List <string>();   //Reset
                proficiencies.ClassArms = new List <string>();   //Reset

                proficiencies.Skills      = new List <string>(); //Reset
                proficiencies.ClassSkills = new List <string>(); //Reset
            }

            void RaceListsReset()
            {
                equipment.RaceBag = new List <string>();             //Reset
                languages.List    = new List <string> {
                    "Common"
                };                                                  //Reset
                languages.Native         = "";                      //Reset
                proficiencies.Tools      = new List <string>();     //Reset
                proficiencies.RaceTools  = new List <string>();     //Reset
                proficiencies.Arms       = new List <string>();     //Reset
                proficiencies.RaceArms   = new List <string>();     //Reset
                proficiencies.Skills     = new List <string>();     //Reset
                proficiencies.RaceSkills = new List <string>();     //Reset
            }
        }