-1

Sorry if the title isn't very descriptive, I don't really know how to phrase this.

Basically, I'm writing a small script in C# for a video game I'm playing. There's 49 different weapons that you can use to attack with, each having its own damage output, and other data about it. The script takes the damage output of the weapon(s) chosen, and it tells you whether or not it will be able to kill an enemy.

I'm completely able to create objects for all 49 weapons and manually assign the data to them in the script, but I know that there's probably a way to just import all of that data straight from a text file or something like that. Any help at all would be appreciated!

I should mention as well, I've only been doing C# for like two weeks, so I'm not the most experienced.

  • "there's probably a way to just import all of that data straight from a text file." Why not do *just that*? – Sweeper May 21 '20 at 11:28
  • @Sweeper If that's something that I can do, then I'm all for it. I'm just wondering if that's the best possible course of action, and if it is, how to do it – Judeman222 May 21 '20 at 11:36
  • 2
    Look up "reading a file C#" and you will find how to do it. See [how much research effort do I need?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users) – Sweeper May 21 '20 at 11:37
  • There isn't, as far as i know, straight ready to use solution. What you need is to do your text file stuff (ex : a csv exported from a spreadshett) then, in your code, open the file, and for each line parse the data and use them to populate your object. There are tons of CSV reader library out there to do the parsing for you. (i don't have any suggestion about which to use) – ker2x May 21 '20 at 12:13
  • I recommend saving the data in XML files. C# can serialize objects using the objects in `System.Xml.Serialization`. You can even edit the data in Excel and have it save back to XML. Then you can embed the XML file in your application resources and read it when the application is run. – John Alexiou May 21 '20 at 13:27

1 Answers1

0

Here is the first step in a) saving a weapon library in an XML file, and b) reading the library if such a file exists.

Run the following code twice to see both behaviors.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace SO
{
    public enum WeaponCategory
    {
        Cosmetic,
        Blunt,
        Cutting,
        Piercing,
        Magic,
    }

    public class Weapon
    {
        [XmlAttribute]
        public string Name { get; set; }
        [XmlAttribute]
        public float Damage { get; set; }
        [XmlAttribute]
        public float Speed { get; set; }
        [XmlAttribute]
        public int MinLevel { get; set; }
        [XmlAttribute]
        public WeaponCategory Category { get; set; }

        public override string ToString() 
            => $"{Name} : (Category={Category}, Damage={Damage}, Speed={Speed}, Min={MinLevel})";
    }


    public class WeaponLibrary
    {
        public WeaponLibrary()
        {
            Weapons = new List<Weapon>();
        }

        public static WeaponLibrary FromXml(string xml)
        {
            var fs = new StringReader(xml);
            var settings = new XmlReaderSettings()
            {
                CloseInput = true,
                IgnoreWhitespace = true,
                IgnoreComments = true
            };
            var xr = XmlReader.Create(fs, settings);
            var xs = new XmlSerializer(typeof(WeaponLibrary));
            var result = xs.Deserialize(xr) as WeaponLibrary;
            xr.Close();
            return result;
        }

        public List<Weapon> Weapons { get; }

        [XmlAttribute]
        public string Realm { get; set; }

        public string ToXml()
        {
            var sb = new StringBuilder();
            var settings = new XmlWriterSettings()
            {
                Encoding = Encoding.UTF7,                
                Indent = true,
                CloseOutput = true,
            };
            var xw = XmlWriter.Create(sb, settings);
            var xs = new XmlSerializer(typeof(WeaponLibrary));
            // Ref: https://stackoverflow.com/a/935749/380384
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "");
            xs.Serialize(xw, this, ns);
            xw.Close();
            return sb.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var filename = "Weapons.xml";
            WeaponLibrary library;

            if (File.Exists(filename))
            {
                library = ReadLibrary(filename);
            }
            else
            {
                library = CreateLibrary(filename);
#if DEBUG
                Process.Start(filename);
#endif
            }

            Console.WriteLine($"Weapon Library for {library.Realm}:");
            foreach (var item in library.Weapons)
            {
                Console.WriteLine(item);
            }
        }

        static WeaponLibrary CreateLibrary(string filename)
        {
            var weps = new WeaponLibrary
            {
                Realm = "Umbra"
            };
            weps.Weapons.Add(new Weapon() { Category = WeaponCategory.Cutting, Name = "Longsword", MinLevel = 10, Damage = 100f, Speed = 5f });
            weps.Weapons.Add(new Weapon() { Category = WeaponCategory.Piercing, Name = "Dagger", MinLevel = 1, Damage = 30f, Speed = 2.0f });
            weps.Weapons.Add(new Weapon() { Category = WeaponCategory.Blunt, Name = "Mace", MinLevel = 3, Damage = 130f, Speed = 8f });
            weps.Weapons.Add(new Weapon() { Category = WeaponCategory.Magic, Name = "Staff", MinLevel = 14, Damage = 50f, Speed = 1.7f });

            var xml = weps.ToXml();
            File.WriteAllText(filename, xml);

            return weps;
        }

        static WeaponLibrary ReadLibrary(string filename)
        {
            var xml = File.ReadAllText(filename);
            return WeaponLibrary.FromXml(xml);
        }
    }
}

and the resulting XML file

<?xml version="1.0" encoding="utf-16"?>
<WeaponLibrary Realm="Umbra">
  <Weapons>
    <Weapon Name="Longsword" Damage="100" Speed="5" MinLevel="10" Category="Cutting" />
    <Weapon Name="Dagger" Damage="30" Speed="2" MinLevel="1" Category="Piercing" />
    <Weapon Name="Mace" Damage="130" Speed="8" MinLevel="3" Category="Blunt" />
    <Weapon Name="Staff" Damage="50" Speed="1.7" MinLevel="14" Category="Magic" />
  </Weapons>
</WeaponLibrary>

The second time the code runs, it read the above XML file and populates the list of Weapon. Here are the contents of the list:

Weapon Library for Umbra:
Longsword : (Category=Cutting, Damage=100, Speed=5, Min=10)
Dagger : (Category=Piercing, Damage=30, Speed=2, Min=1)
Mace : (Category=Blunt, Damage=130, Speed=8, Min=3)
Staff : (Category=Magic, Damage=50, Speed=1.7, Min=14)
John Alexiou
  • 28,472
  • 11
  • 77
  • 133