Click here to Skip to main content
15,395,583 members
Home / Discussions / C#
   

C#

 
AnswerRe: WPF Filtering DataGrid causes UI Freeze Pin
Gerry Schmitz26-Dec-21 6:54
mveGerry Schmitz26-Dec-21 6:54 
AnswerRe: WPF Filtering DataGrid causes UI Freeze Pin
Mycroft Holmes26-Dec-21 11:41
professionalMycroft Holmes26-Dec-21 11:41 
QuestionWMI Connection to Remote PC with ManegementScope too slow(8-10 seconds). The WMI Query itself is OK (under 1 second) Pin
Mustafa Levrek26-Dec-21 1:47
MemberMustafa Levrek26-Dec-21 1:47 
AnswerRe: WMI Connection to Remote PC with ManegementScope too slow(8-10 seconds). The WMI Query itself is OK (under 1 second) Pin
Gerry Schmitz26-Dec-21 2:13
mveGerry Schmitz26-Dec-21 2:13 
GeneralRe: WMI Connection to Remote PC with ManegementScope too slow(8-10 seconds). The WMI Query itself is OK (under 1 second) Pin
OriginalGriff26-Dec-21 2:25
mveOriginalGriff26-Dec-21 2:25 
GeneralRe: WMI Connection to Remote PC with ManegementScope too slow(8-10 seconds). The WMI Query itself is OK (under 1 second) Pin
Mustafa Levrek26-Dec-21 2:36
MemberMustafa Levrek26-Dec-21 2:36 
GeneralRe: WMI Connection to Remote PC with ManegementScope too slow(8-10 seconds). The WMI Query itself is OK (under 1 second) Pin
Dave Kreskowiak26-Dec-21 4:42
mveDave Kreskowiak26-Dec-21 4:42 
Questionnewbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith21-Dec-21 2:23
Memberbiull smith21-Dec-21 2:23 
Sorry if this is the wrong place to ask or post is too long. I've studied examples and read up on factory design, factory pattern, abstract factory, & factory method; I followed a tutorial for a c# wpf rpg game that works well. But I'd like to enhance and expand on it so that I can understand the fundamentals of c# and object-oriented programming. There are seven factories in the game, for example. The factories I have in-game are an item factory, a Quest factory, a recipe factory, a monster factory, a spell factory, a trader factory, and a world factory. Is it possible to implement an abstract factory that combines all the factories? Would keeping them separate be best? Thank you for any assistance you may provide as well as any feedback you provide to.

here are the factories.

Itemfactory.cs   

   using System.Collections.Generic;
   using System.IO;
   using System.Linq;
   using System.Xml;
   using Engine.Actions;
   using Engine.Models;
   using Engine.Shared;
   using SOSCSRPG.Core;

   namespace Engine.Factories
  {
    public static class ItemFactory
    {
        private const string GAME_DATA_FILENAME = 
        ".\\GameData\\GameItems.xml";

        private static readonly List<GameItem> _standardGameItems = new 
        List<GameItem> 
        ();

        static ItemFactory()
        {
            if(File.Exists(GAME_DATA_FILENAME))
            {
                XmlDocument data = new XmlDocument();
                data.LoadXml(File.ReadAllText(GAME_DATA_FILENAME));

                LoadItemsFromNodes(data.SelectNodes("/GameItems/Weapons/Weapon"));
                
LoadItemsFromNodes(data.SelectNodes("/GameItems/HealingItems/HealingItem"));
                
LoadItemsFromNodes(data.SelectNodes("/GameItems/MiscellaneousItems/MiscellaneousItem"));
            }
            else
            {
                throw new FileNotFoundException($"Missing data file: 
                {GAME_DATA_FILENAME}");
            }
        }

        public static GameItem CreateGameItem(int itemTypeID)
        {
            return _standardGameItems.FirstOrDefault(item => 
            item.ItemTypeID == 
            itemTypeID)?.Clone();
        }

        private static void LoadItemsFromNodes(XmlNodeList nodes)
        {
            if(nodes == null)
            {
                return;
            }

            foreach(XmlNode node in nodes)
            {
                GameItem.ItemCategory itemCategory = 
                DetermineItemCategory(node.Name);
                
                GameItem gameItem =
                    new GameItem(itemCategory,
                                 node.AttributeAsInt("ID"),
                                 node.AttributeAsString("Name"),
                                 node.AttributeAsInt("Price"),
                                 itemCategory == 
                                 GameItem.ItemCategory.Weapon);

                if(itemCategory == GameItem.ItemCategory.Weapon)
                {
                    gameItem.Action =
                        new AttackWithWeapon(gameItem, 
                        node.AttributeAsString("DamageDice"));
                }
                else if(itemCategory == 
                GameItem.ItemCategory.Consumable)
                {
                    gameItem.Action =
                        new Heal(gameItem,
                                 
                        node.AttributeAsInt("HitPointsToHeal"));
                }

                _standardGameItems.Add(gameItem);
            }
        }

        private static GameItem.ItemCategory 
        DetermineItemCategory(string itemType)
        {
            switch(itemType)
            {
                case "Weapon":
                    return GameItem.ItemCategory.Weapon;
                case "HealingItem":
                    return GameItem.ItemCategory.Consumable;
                default:
                    return GameItem.ItemCategory.Miscellaneous;
            }
        }
    }
}


MonsterFactory.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Xml;
    using Engine.Models;
    using Engine.Services;
    using Engine.Shared;
    using SOSCSRPG.Core;

    namespace Engine.Factories
    {
        public static class MonsterFactory
        {
            private const string GAME_DATA_FILENAME = 
            ".\\GameData\\Monsters.xml";

            private static readonly GameDetails s_gameDetails;
            private static readonly List<Monster> s_baseMonsters = new 
            List<Monster>();

            static MonsterFactory()
            {
                if(File.Exists(GAME_DATA_FILENAME))
                {
                    s_gameDetails = 
                    GameDetailsService.ReadGameDetails();
                
                    XmlDocument data = new XmlDocument();
                    data.LoadXml(File.ReadAllText(GAME_DATA_FILENAME));

                    string rootImagePath =
                    data.SelectSingleNode("/Monsters")
                   .AttributeAsString("RootImagePath");

                    LoadMonstersFromNodes(data.SelectNodes("/Monsters/Monster"), 
                    rootImagePath);
                    }
                    else
                    {
                        throw new FileNotFoundException($"Missing data 
                        file: 
                        {GAME_DATA_FILENAME}");
                    }
                }

                public static Monster GetMonsterFromLocation(Location 
                location)
               {
                    if (!location.MonstersHere.Any())
                    {
                        return null;
                    }

                    // Total the percentages of all monsters at this 
                       location.
                    int totalChances = location.MonstersHere.Sum(m => 
                    m.ChanceOfEncountering);

                   // Select a random number between 1 and the total 
                      (in case the total 
                  chances is not 100).
                  int randomNumber = 
                  DiceService.Instance.Roll(totalChances, 1).Value;

                 // Loop through the monster list, 
                 // adding the monster's percentage chance of appearing 
                    to the 
                    runningTotal 
                    variable.
               // When the random number is lower than the 
                 runningTotal,
              // that is the monster to return.
             int runningTotal = 0;

            foreach (MonsterEncounter monsterEncounter in 
            location.MonstersHere)
            {
                runningTotal += monsterEncounter.ChanceOfEncountering;

                if (randomNumber <= runningTotal)
                {
                    return GetMonster(monsterEncounter.MonsterID);
                }
            }

            // If there was a problem, return the last monster in the 
               list.
            return GetMonster(location.MonstersHere.Last().MonsterID);
        }

        private static void LoadMonstersFromNodes(XmlNodeList nodes, 
        string 
        rootImagePath)
        {
            if(nodes == null)
            {
                return;
            }

            foreach(XmlNode node in nodes)
            {
                var attributes = s_gameDetails.PlayerAttributes;

                attributes.First(a => a.Key.Equals("DEX")).BaseValue =
                    Convert.ToInt32(node.SelectSingleNode("./Dexterity").InnerText);
                attributes.First(a => 
                a.Key.Equals("DEX")).ModifiedValue =
                    Convert.ToInt32(node.SelectSingleNode("./Dexterity").InnerText);
                
                Monster monster =
                    new Monster(node.AttributeAsInt("ID"),
                                node.AttributeAsString("Name"),
                                $".{rootImagePath} 
                                {node.AttributeAsString("ImageName")}",
                                
                               node.AttributeAsInt("MaximumHitPoints"),
                                attributes,
                                ItemFactory.CreateGameItem(node.AttributeAsInt("WeaponID")),
                                node.AttributeAsInt("RewardXP"),
                                node.AttributeAsInt("Gold"));

                XmlNodeList lootItemNodes = 
                node.SelectNodes("./LootItems/LootItem");
                
                if(lootItemNodes != null)
                {
                    foreach(XmlNode lootItemNode in lootItemNodes)
                    {
                        monster.AddItemToLootTable(lootItemNode.AttributeAsInt("ID"),
                                                   
                        lootItemNode.AttributeAsInt("Percentage"));
                    }
                }

                s_baseMonsters.Add(monster);
            }
        }

        private static Monster GetMonster(int id)
        {
            Monster newMonster = s_baseMonsters.FirstOrDefault(m => 
            m.ID == 
            id).Clone();

            foreach (ItemPercentage itemPercentage in 
            newMonster.LootTable)
            {
                // Populate the new monster's inventory, using the loot 
                   table
                if (DiceService.Instance.Roll(100).Value <= 
                    itemPercentage.Percentage)
                {
                    newMonster.AddItemToInventory(ItemFactory.CreateGameItem(itemPercentage.ID));
                }
            }

            return newMonster;
        }
    }
}

QuestFactory.cs


    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Xml;
    using Engine.Models;
    using Engine.Shared;

    namespace Engine.Factories
    {
        internal static class QuestFactory
        {
            private const string GAME_DATA_FILENAME = 
            ".\\GameData\\Quests.xml";

            private static readonly List<Quest> _quests = new 
            List<Quest>();

        static QuestFactory()
        {
            if(File.Exists(GAME_DATA_FILENAME))
            {
                XmlDocument data = new XmlDocument();
                data.LoadXml(File.ReadAllText(GAME_DATA_FILENAME));

                LoadQuestsFromNodes(data.SelectNodes("/Quests/Quest"));
            }
            else
            {
                throw new FileNotFoundException($"Missing data file: 
                {GAME_DATA_FILENAME}");
            }
        }

        private static void LoadQuestsFromNodes(XmlNodeList nodes)
        {
            foreach(XmlNode node in nodes)
            {
                // Declare the items need to complete the quest, and 
                   its reward items
                List<ItemQuantity> itemsToComplete = new 
                List<ItemQuantity>();
                List<ItemQuantity> rewardItems = new List<ItemQuantity> 
                ();

                foreach(XmlNode childNode in 
                node.SelectNodes("./ItemsToComplete/Item"))
                {
                    GameItem item = ItemFactory.CreateGameItem(childNode.AttributeAsInt("ID"));

                    itemsToComplete.Add(new ItemQuantity(item, 
                    childNode.AttributeAsInt("Quantity")));
                }

                foreach(XmlNode childNode in 
                node.SelectNodes("./RewardItems/Item"))
                {
                    GameItem item = ItemFactory.CreateGameItem(childNode.AttributeAsInt("ID"));

                    rewardItems.Add(new ItemQuantity(item, 
                    childNode.AttributeAsInt("Quantity")));
                }

                _quests.Add(new Quest(node.AttributeAsInt("ID"),
                                      
                node.SelectSingleNode("./Name")?.InnerText ?? "",
                                      
                node.SelectSingleNode("./Description")?.InnerText 
                                      ?? "",
                                      itemsToComplete,
                                      
                         node.AttributeAsInt("RewardExperiencePoints"),
                                      
                         node.AttributeAsInt("RewardGold"),
                                      rewardItems));
            }
        }

        internal static Quest GetQuestByID(int id)
        {
            return _quests.FirstOrDefault(quest => quest.ID == id);
        }
    }
}


RecipeFactory.cs

    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Xml;
    using Engine.Models;
    using Engine.Shared;

    namespace Engine.Factories
   {
    public static class RecipeFactory
    {
        private const string GAME_DATA_FILENAME = 
        ".\\GameData\\Recipes.xml";

        private static readonly List<Recipe> _recipes = new 
        List<Recipe>();

        static RecipeFactory()
        {
            if(File.Exists(GAME_DATA_FILENAME))
            {
                XmlDocument data = new XmlDocument();
                data.LoadXml(File.ReadAllText(GAME_DATA_FILENAME));

                LoadRecipesFromNodes(data.SelectNodes("/Recipes/Recipe"));
            }
            else
            {
                throw new FileNotFoundException($"Missing data file: 
                {GAME_DATA_FILENAME}");
            }
        }

        private static void LoadRecipesFromNodes(XmlNodeList nodes)
        {
            foreach(XmlNode node in nodes)
            {
                var ingredients = new List<ItemQuantity>();

                foreach(XmlNode childNode in 
                node.SelectNodes("./Ingredients/Item"))
                {
                    GameItem item = ItemFactory.CreateGameItem(childNode.AttributeAsInt("ID"));

                    ingredients.Add(new ItemQuantity(item, 
                    childNode.AttributeAsInt("Quantity")));
                }

                var outputItems = new List<ItemQuantity>();

                foreach (XmlNode childNode in 
                node.SelectNodes("./OutputItems/Item"))
                {
                    GameItem item = ItemFactory.CreateGameItem(childNode.AttributeAsInt("ID"));

                    outputItems.Add(new ItemQuantity(item, 
                    childNode.AttributeAsInt("Quantity")));
                }

                Recipe recipe =
                    new Recipe(node.AttributeAsInt("ID"),
                        node.SelectSingleNode("./Name")?.InnerText ?? 
                        "",
                        ingredients, outputItems);

                _recipes.Add(recipe);
            }
        }

        public static Recipe RecipeByID(int id)
        {
            return _recipes.FirstOrDefault(x => x.ID == id);
        }
    }
}


Traderfactory.cs


    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Xml;
    using Engine.Models;
    using Engine.Shared;

    namespace Engine.Factories
    {
        public static class TraderFactory
        {
            private const string GAME_DATA_FILENAME = 
            ".\\GameData\\Traders.xml";

            private static readonly List<Trader> _traders = new 
            List<Trader>();

            static TraderFactory()
        {
            if(File.Exists(GAME_DATA_FILENAME))
            {
                XmlDocument data = new XmlDocument();
                data.LoadXml(File.ReadAllText(GAME_DATA_FILENAME));

                LoadTradersFromNodes(data.SelectNodes("/Traders/Trader"));
            }
            else
            {
                throw new FileNotFoundException($"Missing data file: 
                {GAME_DATA_FILENAME}");
            }
        }

        private static void LoadTradersFromNodes(XmlNodeList nodes)
        {
            foreach(XmlNode node in nodes)
            {
                Trader trader =
                    new Trader(node.AttributeAsInt("ID"),
                               
                    node.SelectSingleNode("./Name")?.InnerText ?? "");

                foreach(XmlNode childNode in 
                node.SelectNodes("./InventoryItems/Item"))
                {
                    int quantity = 
                    childNode.AttributeAsInt("Quantity");

                    // Create a new GameItem object for each item we 
                       add.
                    // This is to allow for unique items, like swords 
                       with 
                       enchantments.
                    for(int i = 0; i < quantity; i++)
                    {
                        trader.AddItemToInventory(ItemFactory.CreateGameItem(childNode.AttributeAsInt("ID")));
                    }
                }

                _traders.Add(trader);
            }
        }

        public static Trader GetTraderByID(int id)
        {
            return _traders.FirstOrDefault(t => t.ID == id);
        }
    }
}


WorldFactory.cs


    using System.IO;
    using System.Xml;
    using Engine.Models;
    using Engine.Shared;

    namespace Engine.Factories
    {
        internal static class WorldFactory
        {
            private const string GAME_DATA_FILENAME = 
            ".\\GameData\\Locations.xml";

            internal static World CreateWorld()
            {
                World world = new World();

                if(File.Exists(GAME_DATA_FILENAME))
                {
                    XmlDocument data = new XmlDocument();
                    data.LoadXml(File.ReadAllText(GAME_DATA_FILENAME));

                    string rootImagePath =
                    data.SelectSingleNode("/Locations")
                   .AttributeAsString("RootImagePath");

                LoadLocationsFromNodes(world, 
                rootImagePath, 
                data.SelectNodes("/Locations/Location"));
            }
            else
            {
                throw new FileNotFoundException($"Missing data file: 
                {GAME_DATA_FILENAME}");
            }

            return world;
        }

        private static void LoadLocationsFromNodes(World world, string 
        rootImagePath, 
        XmlNodeList nodes)
        {
            if(nodes == null)
            {
                return;
            }

            foreach(XmlNode node in nodes)
            {
                Location location =
                    new Location(node.AttributeAsInt("X"),
                                 node.AttributeAsInt("Y"),
                                 node.AttributeAsString("Name"),
                                 node.SelectSingleNode("./Description")?.InnerText ?? 
                                 "",
                                 $".{rootImagePath} 
                                 
                              {node.AttributeAsString("ImageName")}");

                AddMonsters(location, 
                node.SelectNodes("./Monsters/Monster"));
                AddQuests(location, 
                node.SelectNodes("./Quests/Quest"));
                AddTrader(location, node.SelectSingleNode("./Trader"));

                world.AddLocation(location);
            }
        }

        private static void AddMonsters(Location location, XmlNodeList 
        monsters)
        {
            if(monsters == null)
            {
                return;
            }

            foreach(XmlNode monsterNode in monsters)
            {
                location.AddMonster(monsterNode.AttributeAsInt("ID"),
                monsterNode.AttributeAsInt("Percent"));
            }
        }

        private static void AddQuests(Location location, XmlNodeList 
        quests)
        {
            if(quests == null)
            {
                return;
            }

            foreach(XmlNode questNode in quests)
            {
                location.QuestsAvailableHere
                        
               .Add(QuestFactory.GetQuestByID(questNode.AttributeAsInt("ID")));
            }
        }

        private static void AddTrader(Location location, XmlNode 
        traderHere)
        {
            if(traderHere == null)
            {
                return;
            }

            location.TraderHere =
            TraderFactory.GetTraderByID(traderHere.AttributeAsInt("ID"));
        }
    }
}


SpellFactory.cs


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Engine.Models;

    namespace Engine.Factories
    {
        public static class SpellFactory
        {
            private static readonly List<spells> _standardSpell = new 
            List<Spells> 
            ();

            static SpellFactory()
        {
            _standardSpell.Add(new Spell(8000, "Fireball", 5));
            _standardSpell.Add(new Spell(8001, "Lightning", 5));
            _standardSpell.Add(new Spell(8002, "Frost Bolt", 5));
        }

        public static Spell CreateSpell(int SpellID)
        {
            standardSpell = _standardSpell.FirstOrDefault(spell =>
            spell.SpellID == SpellID);

            if (standardSpell != null)
            {
                return standardSpell.Clone();
            }
            return null;
        }
    }
}

AnswerRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
#realJSOP21-Dec-21 2:37
mva#realJSOP21-Dec-21 2:37 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith21-Dec-21 3:04
Memberbiull smith21-Dec-21 3:04 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
Pete O'Hanlon21-Dec-21 4:06
mvaPete O'Hanlon21-Dec-21 4:06 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith21-Dec-21 4:17
Memberbiull smith21-Dec-21 4:17 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
lmoelleb22-Dec-21 0:34
Memberlmoelleb22-Dec-21 0:34 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith6-Jan-22 10:08
Memberbiull smith6-Jan-22 10:08 
AnswerRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
Gerry Schmitz21-Dec-21 6:30
mveGerry Schmitz21-Dec-21 6:30 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith21-Dec-21 7:01
Memberbiull smith21-Dec-21 7:01 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
Gerry Schmitz21-Dec-21 7:22
mveGerry Schmitz21-Dec-21 7:22 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith21-Dec-21 8:29
Memberbiull smith21-Dec-21 8:29 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
Gerry Schmitz21-Dec-21 10:04
mveGerry Schmitz21-Dec-21 10:04 
QuestionRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith21-Dec-21 13:15
Memberbiull smith21-Dec-21 13:15 
AnswerRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
Gerry Schmitz21-Dec-21 17:56
mveGerry Schmitz21-Dec-21 17:56 
GeneralRe: newbie using a game to learn c# and object-oriented programming Could I make an abstract factory to merge the other factories in a game? Pin
biull smith6-Jan-22 10:18
Memberbiull smith6-Jan-22 10:18 
QuestionTotal Newbie... just installing Visual Studio... Pin
Audio Babble17-Dec-21 6:08
MemberAudio Babble17-Dec-21 6:08 
AnswerRe: Total Newbie... just installing Visual Studio... Pin
OriginalGriff17-Dec-21 6:12
mveOriginalGriff17-Dec-21 6:12 
GeneralRe: Total Newbie... just installing Visual Studio... Pin
Audio Babble17-Dec-21 6:24
MemberAudio Babble17-Dec-21 6:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.