コード例 #1
0
        private Item parseWikiItem(WikiItemData wikiItem)
        {
            var item = new Item();

            item.ItemName     = wikiItem.Name.Trim();
            item.IconFileName = wikiItem.IconFileName?.Trim();

            foreach (string statLine in wikiItem.Stats)
            {
                try
                {
                    parseStatLine(wikiItem, item, statLine);
                }
                catch (UnknownStatTokenException)
                {
                    // add any unparseable lines as InfoText
                    item.Info.Add(new ItemInfoLine()
                    {
                        ItemName = item.ItemName,
                        Item     = item,
                        Text     = statLine
                    });
                }
            }

            return(item);
        }
コード例 #2
0
        private void parseStatLine(WikiItemData wikiItem, Item item, string statLine)
        {
            var lineChunks = statLine
                             .Replace(")(", ") (") // make life easier when parsing Effect corner cases
                             .Split(' ', StringSplitOptions.RemoveEmptyEntries)
                             .Select(chunk => chunk.Trim())
                             .Where(chunk => chunk != ":" && chunk != "+")
                             .ToArray();

            string firstChunk  = cleanChunk(lineChunks[0]);
            string secondChunk = (lineChunks.Length == 1 ? null : cleanChunk(lineChunks[1]));

            // first check for tokens that we know will take up an entire line
            if (firstChunk == "AC")
            {
                if (item.ArmorClass != null)
                {
                    throw new Exception("Multiple AC lines found for " + wikiItem.ToString());
                }
                item.ArmorClass = Int32.Parse(secondChunk);
            }
            else if (firstChunk == "DMG")
            {
                if (item.AttackDamage != null)
                {
                    throw new Exception("Multiple DMG lines found for " + wikiItem.ToString());
                }
                item.AttackDamage = Int32.Parse(secondChunk);
            }
            else if (firstChunk == "SKILL" && secondChunk != "MOD")
            {
                if (item.WeaponSkillCode != null)
                {
                    throw new Exception("Multiple Skill lines found for " + wikiItem.ToString());
                }
                parseWeaponSkillLine(lineChunks, item);
            }
            else if (firstChunk == "SLOT" && secondChunk != "1")
            {
                if (item.Slots.Count > 0)
                {
                    throw new Exception("Multiple Slot lines found for " + wikiItem.ToString());
                }
                parseSlotsLine(lineChunks, item);
            }
            else if (firstChunk == "CLASS")
            {
                if (item.Classes.Count > 0)
                {
                    throw new Exception("Multiple Class lines found for " + wikiItem.ToString());
                }
                parseClassLine(lineChunks, item);
            }
            else if (firstChunk == "RACE")
            {
                if (item.Races.Count > 0)
                {
                    throw new Exception("Multiple Race lines found for " + wikiItem.ToString());
                }
                parseRaceLine(lineChunks, item);
            }
            else if (firstChunk == "DEITY" || firstChunk == "DIETY")
            {
                if (item.Deities.Count > 0)
                {
                    throw new Exception("Multiple Deity lines found for " + wikiItem.ToString());
                }
                parseDeityLine(lineChunks, item);
            }
            else if (firstChunk == "EFFECT")
            {
                if (item.EffectSpellName != null)
                {
                    throw new Exception("Multiple Effect values found for " + wikiItem.ToString());
                }
                parseEffectLine(lineChunks, item);
            }
            else if (firstChunk == "REQUIRED")
            {
                if (item.RequiredLevel != null)
                {
                    throw new Exception("Multiple Required Level values for " + wikiItem.ToString());
                }
                item.RequiredLevel = Int32.Parse(lineChunks.Last().TrimEnd('.'));
            }
            else if (firstChunk == "SINGING")
            {
                if (item.SingingModifier != null)
                {
                    throw new Exception("Multiple Singing lines found for " + wikiItem.ToString());
                }

                if (lineChunks.Length < 3)
                {
                    item.SingingModifier = 0;
                }
                else
                {
                    item.SingingModifier = Convert.ToInt32(cleanChunk(lineChunks[2]));
                }
            }
            else if (firstChunk == "PERCUSSION")
            {
                if (item.PercussionModifier != null)
                {
                    throw new Exception("Multiple Percussion lines found for " + wikiItem.ToString());
                }

                if (lineChunks.Length < 3)
                {
                    item.PercussionModifier = 0;
                }
                else
                {
                    item.PercussionModifier = Convert.ToInt32(cleanChunk(lineChunks[2]));
                }
            }
            else if (firstChunk == "STRINGED")
            {
                if (item.StringedModifier != null)
                {
                    throw new Exception("Multiple Stringed lines found for " + wikiItem.ToString());
                }

                if (lineChunks.Length < 3)
                {
                    item.StringedModifier = 0;
                }
                else
                {
                    item.StringedModifier = Convert.ToInt32(cleanChunk(lineChunks[2]));
                }
            }
            else if (firstChunk == "BRASS")
            {
                if (item.BrassModifier != null)
                {
                    throw new Exception("Multiple Brass lines found for " + wikiItem.ToString());
                }

                if (lineChunks.Length < 3)
                {
                    item.BrassModifier = 0;
                }
                else
                {
                    item.BrassModifier = Convert.ToInt32(cleanChunk(lineChunks[2]));
                }
            }
            else if (firstChunk == "WIND")
            {
                if (item.WindModifier != null)
                {
                    throw new Exception("Multiple Wind lines found for " + wikiItem.ToString());
                }

                if (lineChunks.Length < 3)
                {
                    item.WindModifier = 0;
                }
                else
                {
                    item.WindModifier = Convert.ToInt32(cleanChunk(lineChunks[2]));
                }
            }
            else
            {
                // it wasn't a whole-line token, so next check for tokens that can share a line

                int currentIndex = 0;
                while (currentIndex < lineChunks.Length)
                {
                    string currentChunk   = cleanChunk(lineChunks[currentIndex]);
                    bool   isChunkHandled = false;

                    if (currentChunk == "NODROP")
                    {
                        item.IsNoDrop  = true;
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "TEMPORARY" || currentChunk == "NORENT")
                    {
                        item.IsTemporary = true;
                        isChunkHandled   = true;
                    }
                    else if (currentChunk == "EXPENDABLE")
                    {
                        item.IsExpendable = true;
                        isChunkHandled    = true;
                    }
                    else if (currentChunk == "ARTIFACT")
                    {
                        item.IsArtifact = true;
                        isChunkHandled  = true;
                    }
                    else if (currentChunk == "WT")
                    {
                        if (item.Weight != 0)
                        {
                            throw new Exception("Multiple WT values found for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        string nextChunk = cleanChunk(lineChunks[currentIndex]);


                        item.Weight    = float.Parse(nextChunk);
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "SIZE")
                    {
                        currentIndex++;
                        string nextChunk = cleanChunk(lineChunks[currentIndex]);

                        if (nextChunk == "CAPACITY")
                        {
                            currentIndex++;
                            var nextNextChunk = cleanChunk(lineChunks[currentIndex]);

                            if (item.CapacitySizeCode != null)
                            {
                                throw new Exception("Multiple Size Capacity values found for " + wikiItem.ToString());
                            }

                            item.CapacitySizeCode = SizeCodes.All.Where(code => code.Equals(nextNextChunk, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

                            if (String.IsNullOrWhiteSpace(item.CapacitySizeCode))
                            {
                                throw new Exception("Unrecognized Size Capacity" + nextNextChunk);
                            }
                        }
                        else
                        {
                            if (item.SizeCode != null)
                            {
                                throw new Exception("Multiple Size values found for " + wikiItem.ToString());
                            }

                            item.SizeCode = SizeCodes.All.Where(code => code.Equals(nextChunk, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

                            if (String.IsNullOrWhiteSpace(item.SizeCode))
                            {
                                throw new Exception("Unrecognized Size " + nextChunk);
                            }
                        }

                        isChunkHandled = true;
                    }
                    else if (currentChunk == "CAPACITY")
                    {
                        if (item.Capacity != null)
                        {
                            throw new Exception("Multiple Capacity values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Capacity  = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "RANGE")
                    {
                        if (item.Range != null)
                        {
                            throw new Exception("Multiple Range values found for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        string rangeString = cleanChunk(lineChunks[currentIndex]);
                        if (rangeString.Contains('/') || (lineChunks.Length > currentIndex + 1 && lineChunks[currentIndex + 1].Contains('/')))
                        {
                            // there are multiple possible ranges (i.e. crafted arrows), so just set Range = null
                            item.Range = null;

                            while (cleanChunk(lineChunks[currentIndex + 1]) != "SIZE")
                            {
                                currentIndex++;
                            }
                        }
                        else
                        {
                            item.Range = Int32.Parse(rangeString);
                        }
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "HASTE")
                    {
                        if (item.Haste != null)
                        {
                            throw new Exception("Multiple Haste lines found for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Haste     = float.Parse("0." + cleanChunk(lineChunks[currentIndex]).TrimStart('+').TrimEnd('%'));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "STR")
                    {
                        if (item.Strength != null)
                        {
                            throw new Exception("Multiple STR values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Strength  = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "STA")
                    {
                        if (item.Stamina != null)
                        {
                            throw new Exception("Multiple STA values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Stamina   = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "AGI")
                    {
                        if (item.Agility != null)
                        {
                            throw new Exception("Multiple AGI values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Agility   = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "DEX")
                    {
                        if (item.Dexterity != null)
                        {
                            throw new Exception("Multiple DEX values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Dexterity = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "WIS")
                    {
                        if (item.Wisdom != null)
                        {
                            throw new Exception("Multiple WIS values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Wisdom    = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "INT")
                    {
                        if (item.Intelligence != null)
                        {
                            throw new Exception("Multiple INT values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Intelligence = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled    = true;
                    }
                    else if (currentChunk == "CHA")
                    {
                        if (item.Charisma != null)
                        {
                            throw new Exception("Multiple CHA values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.Charisma  = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled = true;
                    }
                    else if (currentChunk == "HP")
                    {
                        currentIndex++;
                        var nextChunk = cleanChunk(lineChunks[currentIndex]);

                        int hpValue;
                        if (Int32.TryParse(nextChunk, out hpValue))
                        {
                            if (item.HitPoints != null)
                            {
                                throw new Exception("Multiple HP values for " + wikiItem.ToString());
                            }

                            item.HitPoints = hpValue;
                            isChunkHandled = true;
                        }
                    }
                    else if (currentChunk == "MANA")
                    {
                        currentIndex++;
                        string nextChunk = cleanChunk(lineChunks[currentIndex]);

                        int manaValue;
                        if (Int32.TryParse(nextChunk, out manaValue))
                        {
                            if (item.Mana != null)
                            {
                                throw new Exception("Multiple MANA values for " + wikiItem.ToString());
                            }

                            item.Mana      = manaValue;
                            isChunkHandled = true;
                        }
                    }
                    else if (currentChunk == "AC")
                    {
                        if (item.ArmorClass != null)
                        {
                            throw new Exception("Multiple AC values for " + wikiItem.ToString());
                        }

                        currentIndex++;
                        item.ArmorClass = Int32.Parse(cleanChunk(lineChunks[currentIndex]));
                        isChunkHandled  = true;
                    }
                    else if (currentIndex + 1 < lineChunks.Length)
                    {
                        // this is NOT the last token in the line, so check for two-token combos

                        string nextChunk = cleanChunk(lineChunks[currentIndex + 1]);

                        // for stats that are two tokens ("SV MAGIC", "SV POISON", etc)
                        if (currentChunk == "SV")
                        {
                            currentIndex += 2;
                            int value = Int32.Parse(cleanChunk(lineChunks[currentIndex]));

                            if (nextChunk == "MAGIC")
                            {
                                if (item.MagicResist != null)
                                {
                                    throw new Exception("Multiple SV MAGIC values found for " + wikiItem.ToString());
                                }
                                item.MagicResist = value;
                            }
                            else if (nextChunk == "POISON")
                            {
                                if (item.PoisonResist != null)
                                {
                                    throw new Exception("Multiple SV POISON values found for " + wikiItem.ToString());
                                }
                                item.PoisonResist = value;
                            }
                            else if (nextChunk == "DISEASE")
                            {
                                if (item.DiseaseResist != null)
                                {
                                    throw new Exception("Multiple SV DISEASE values found for " + wikiItem.ToString());
                                }
                                item.DiseaseResist = value;
                            }
                            else if (nextChunk == "FIRE")
                            {
                                if (item.FireResist != null)
                                {
                                    throw new Exception("Multiple SV FIRE values found for " + wikiItem.ToString());
                                }
                                item.FireResist = value;
                            }
                            else if (nextChunk == "COLD")
                            {
                                if (item.ColdResist != null)
                                {
                                    throw new Exception("Multiple SV COLD values found for " + wikiItem.ToString());
                                }
                                item.ColdResist = value;
                            }
                            else
                            {
                                throw new Exception("Unrecognized resist SV " + nextChunk);
                            }

                            isChunkHandled = true;
                        }
                        else if (currentChunk == "MAGIC" && nextChunk == "ITEM")
                        {
                            item.IsMagic = true;
                            currentIndex++;
                            isChunkHandled = true;
                        }
                        else if (currentChunk == "LORE" && nextChunk == "ITEM")
                        {
                            item.IsLore = true;
                            currentIndex++;
                            isChunkHandled = true;
                        }
                        else if (currentChunk == "QUEST" && nextChunk == "ITEM")
                        {
                            item.IsQuestItem = true;
                            currentIndex++;
                            isChunkHandled = true;
                        }
                        else if (currentChunk == "NO" && nextChunk == "DROP")
                        {
                            item.IsNoDrop = true;
                            currentIndex++;
                            isChunkHandled = true;
                        }
                        else if (currentChunk == "NO" && nextChunk == "RENT")
                        {
                            item.IsTemporary = true;
                            currentIndex++;
                            isChunkHandled = true;
                        }
                        else if (currentChunk == "NO" && nextChunk == "TRADE")
                        {
                            item.IsNoTrade = true;
                            currentIndex++;
                            isChunkHandled = true;
                        }
                        else if (currentChunk == "WEIGHT" && nextChunk == "REDUCTION")
                        {
                            if (item.WeightReduction != null)
                            {
                                throw new Exception("Multiple Weight Reduction values found for " + wikiItem.ToString());
                            }

                            isChunkHandled = true;
                            currentIndex  += 2;
                            var nextNextChunk = cleanChunk(lineChunks[currentIndex]);

                            item.WeightReduction = float.Parse("0." + nextNextChunk.TrimEnd('%'));
                        }
                        else if (currentChunk == "CHARGES")
                        {
                            if (item.MaxCharges != null)
                            {
                                throw new Exception("Multiple Charges values found for " + wikiItem.ToString());
                            }

                            currentIndex++;
                            isChunkHandled = true;

                            if (nextChunk == "UNLIMITED")
                            {
                                item.MaxCharges = null;
                            }
                            else
                            {
                                item.MaxCharges = Int32.Parse(nextChunk);
                            }
                        }
                    }

                    if (!isChunkHandled)
                    {
                        throw new UnknownStatTokenException(currentChunk);
                    }

                    currentIndex++;
                } // end while (currentIndex < lineChunks.Length)
            }     // end else
        }