示例#1
0
        /// <summary>
        /// Gets the line representing the entry as a CSV row.
        /// </summary>
        /// <param name="entry">The entry to convert.</param>
        /// <returns>A Comma-Separated Values row containing the monster entry, as a string.</returns>
        private static string getLineFromEntry(BestiaryEntry entry)
        {
            StringBuilder sb = new StringBuilder();

            // Join together the strings so they will be in one entry.
            string joinedActions = JoinStrings(entry.Actions);
            string joinedTraits = JoinStrings(entry.Traits);

            // Beast Size AC HP Speed Senses Str Mod Dex Mod Con Mod Int Mod Wis Mod Cha Mod Alignment Traits Actions Level XP
            object[] values = new object[]
            {
                entry.Name, entry.Size, entry.ArmorClass, entry.HitPoints, entry.Speed, entry.Senses, entry.Strength, null,
                entry.Dexterity, null, entry.Constitution, null, entry.Intelligence, null, entry.Wisdom, null, entry.Charisma, null,
                entry.Alignment, joinedTraits, joinedActions, entry.Level, entry.XP
            };

            // Append all the values in csv format
            foreach (object value in values)
            {
                sb.Append(string.Format("{0}~", value));
            }

            return sb.ToString();
        }
        /// <summary>
        /// Parses a creature from the entry text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>The parsed creature, or null if an error occurred.</returns>
        public static BestiaryEntry CreateFromText(string text)
        {
            // Clean the whitespace from the entries, remove the carriage returns, and then split on newlines.
            // Ideally, this is make every string in lines a line of the text.
            text = text.Trim();
            text.Replace("\r", "");
            var lines = text.Split('\n');

            // LINQ syntax. Select only the lines that have something and that don't contain "&nbsp"
            lines =
                (from line in lines
                 where !string.IsNullOrWhiteSpace(line) && !line.Contains("&nbsp")
                 select line.Trim()).ToArray();

            var entry = new BestiaryEntry();
            entry.Text = text;
            // Try parsing the entry. If fails, return null and log the error.
            try
            {
                entry.Name = lines[0];
                entry.SizeType = lines[1];
                entry.Size = entry.SizeType.Split().First();
                entry.Type = entry.SizeType.Split().Last();
                entry.ArmorClass = JoinStrings(lines[2].Split().Skip(2));
                entry.HitPoints = lines[3].Split().Skip(2).First();
                entry.Speed = lines[4].Split()[1];
                entry.Senses = JoinStrings(lines[5].Split().Skip(1));
                entry.Strength = lines[6].Split().Skip(1).First();
                entry.Dexterity = lines[7].Split().Skip(1).First();
                entry.Constitution = lines[8].Split().Skip(1).First();
                entry.Intelligence = lines[9].Split().Skip(1).First();
                entry.Wisdom = lines[10].Split().Skip(1).First();
                entry.Charisma = lines[11].Split().Skip(1).First();
                entry.Alignment = lines[12].Split().Skip(1).First();
                entry.Languages = JoinStrings(lines[13].Split().Skip(1));

                // LINQ Shenanigans. Get all the strings in between TRAITS and ACTION, making sure to stop before ENCOUNTER BUILDING.
                entry.Traits =
                (from line in lines.SkipWhile(x => x != "TRAITS").TakeWhile(x => x != "ACTIONS" && x != "ENCOUNTER BUILDING")
                 select line).Skip(1).ToList();

                // Get all strings between ACTIONS and ENCOUNTER BUILDING
                entry.Actions =
                    (from line in lines.SkipWhile(x => x != "ACTIONS").TakeWhile(x => x != "ENCOUNTER BUILDING")
                     select line).Skip(1).ToList();

                // The last line should be the XP lines
                entry.XPLine = lines.Last();
                int result;

                // Pull out the Level and XP as ints from the XPLine
                var xpResults =
                (from word in entry.XPLine.Split()
                 where Int32.TryParse(word, out result)
                 select Convert.ToInt32(word));

                entry.Level = xpResults.First();
                entry.XP = xpResults.Last();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Caught in {0}: {1}", entry.Name, ex.Message);

                // Log the error
                using (StreamWriter logFile = File.AppendText(LOG_FILE_PATH))
                {
                    logFile.WriteLine(text);

                    logFile.WriteLine(string.Format("========{0}========", errCount++));
                }

                // Return null
                return null;
            }

            // Log the success and return the parsed creature.
            using (StreamWriter logFile = File.AppendText(LOG_FILE_PATH))
            {
                logFile.WriteLine("{0} successfully parsed.", entry.Name);
                logFile.WriteLine(string.Format("========{0}========", errCount++));
            }
            return entry;
        }