Files
d20-srd-spell-lists/d20 SRD Spell Lists/Models/SpellSet.cs
2011-09-16 21:01:32 -04:00

241 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using d20_SRD_Spell_Lists.Exceptions;
using System.Text.RegularExpressions;
namespace d20_SRD_Spell_Lists.Models {
public class SpellSet {
private XElement masterSpellList;
private XElement userSpellList;
private XElement charSpellList;
private string userXmlFile;
private Character character;
public SpellSet(string _masterXmlFile = null, string _userXmlFile = null, Character _character = null) {
userXmlFile = _userXmlFile;
character = _character;
loadXML(ref _masterXmlFile);
}
private void loadXML(ref string _masterXmlFile) {
// Load the XML file.
if (_masterXmlFile == null) {
_masterXmlFile = Properties.Settings.Default.MasterSpells;
}
if (userXmlFile == null) {
userXmlFile = Properties.Settings.Default.UserSpells;
}
masterSpellList = XElement.Load(_masterXmlFile);
userSpellList = XElement.Load(userXmlFile);
if (character != null) {
charSpellList = character.spells();
}
}
/// <summary>
/// Adds a spell to the application's list of custom spells.
/// </summary>
/// <param name="xElement">The XML details of the new spell.</param>
public void addUserSpell(XElement xElement) {
userSpellList.Add(xElement);
}
public IEnumerable<Spell> byClass(Character.SpellCastingClasses spellCastingClass) {
List<Spell> spells = new List<Spell>();
filterMasterSpellsByClass(spellCastingClass, spells);
filterUserSpellsByClass(spellCastingClass, spells);
filterCharacterSpellsByClass(spellCastingClass, spells);
removeHiddenSpells(spells);
return spells;
}
private void filterMasterSpellsByClass(Character.SpellCastingClasses spellCastingClass, List<Spell> spells) {
spells.AddRange(querySpellsByClass(masterSpellList, spellCastingClass, false, false).ToList<Spell>());
}
private void filterCharacterSpellsByClass(Character.SpellCastingClasses spellCastingClass, List<Spell> spells) {
if (characterSpellCount() > 0) {
spells.AddRange(querySpellsByClass(charSpellList, spellCastingClass, false, true));
}
}
private void filterUserSpellsByClass(Character.SpellCastingClasses spellCastingClass, List<Spell> spells) {
if (userSpellCount() > 0) {
spells.AddRange(querySpellsByClass(userSpellList, spellCastingClass, true, false).ToList<Spell>());
}
}
private void removeHiddenSpells(List<Spell> spells) {
if (hiddenSpellCount() > 0) {
foreach (string hiddenSpellName in (from hp in userSpellList.Elements("hidden_spell").Elements("spell")
select (string)hp.Element("name"))) {
spells.RemoveAll(sp => sp.Name == hiddenSpellName);
}
}
if (hiddenCharacterSpellCount() > 0) {
foreach (string hiddenSpellName in (from hp in charSpellList.Elements("hidden_spell").Elements("spell")
select (string)hp.Element("name"))) {
spells.RemoveAll(sp => sp.Name == hiddenSpellName);
}
}
}
public IEnumerable<Spell> byClassAndLevel(Character.SpellCastingClasses spellCastingClass, int level) {
List<Spell> spells = new List<Spell>();
filterMasterSpellsByClassAndLevel(spellCastingClass, level, spells);
filterUserSpellsByClassAndLevel(spellCastingClass, level, spells);
filterCharacterSpellsByClassAndLevel(spellCastingClass, level, spells);
removeHiddenSpells(spells);
return spells;
}
private void filterCharacterSpellsByClassAndLevel(Character.SpellCastingClasses spellCastingClass, int level, List<Spell> spells) {
if (characterSpellCount() > 0) {
spells.AddRange(querySpellsByClassAndLevel(charSpellList, spellCastingClass, level, false, true));
}
}
private void filterUserSpellsByClassAndLevel(Character.SpellCastingClasses spellCastingClass, int level, List<Spell> spells) {
if (userSpellCount() > 0) {
spells.AddRange(querySpellsByClassAndLevel(userSpellList, spellCastingClass, level, true, false).ToList<Spell>());
}
}
private IEnumerable<Spell> querySpellsByClassAndLevel(XElement list, Character.SpellCastingClasses spellCastingClass, int level, bool isCustom, bool isCharCustom) {
string c = Character.getClassName(spellCastingClass);
Regex levelReg = new Regex(@" (\d+)?");
return (from sp in list.Elements("spell")
let xmlLevel = (string)sp.Element("level")
let xmlComp = (string)sp.Element("components")
let xmlDesc = (string)sp.Element("short_description")
where xmlLevel != null && xmlLevel.Contains(c + " " + level.ToString())
orderby levelReg.Match(xmlLevel, xmlLevel.IndexOf(c)).Groups[1].Value
select new Spell {
IsPrepped = false,
Name = sp.Element("name").Value,
Level = int.Parse(levelReg.Match(xmlLevel, xmlLevel.IndexOf(c)).Groups[1].Value),
Components = (xmlComp != null ? xmlComp : ""),
ShortDescription = (xmlDesc != null ? xmlDesc : ""),
IsCustom = isCustom,
IsCharCustom = isCharCustom
});
}
private IEnumerable<Spell> querySpellsByClass(XElement list, Character.SpellCastingClasses spellCastingClass, bool isCustom, bool isCharCustom) {
string c = Character.getClassName(spellCastingClass);
Regex levelReg = new Regex(@" (\d+),?");
return (from sp in list.Elements("spell")
let xmlLevel = (string)sp.Element("level")
let xmlComp = (string)sp.Element("components")
let xmlDesc = (string)sp.Element("short_description")
where xmlLevel != null && xmlLevel.Contains(c)
orderby levelReg.Match(xmlLevel, xmlLevel.IndexOf(c)).Groups[1].Value
select new Spell {
IsPrepped = false,
Name = sp.Element("name").Value,
Level = int.Parse(levelReg.Match(xmlLevel, xmlLevel.IndexOf(c)).Groups[1].Value),
Components = (xmlComp != null ? xmlComp : ""),
ShortDescription = (xmlDesc != null ? xmlDesc : ""),
IsCustom = isCustom,
IsCharCustom = isCharCustom
});
}
private void filterMasterSpellsByClassAndLevel(Character.SpellCastingClasses spellCastingClass, int level, List<Spell> spells) {
spells.AddRange(querySpellsByClassAndLevel(masterSpellList, spellCastingClass, level, false, false).ToList<Spell>());
}
/// <summary>
/// Saves all XML files to the system.
/// </summary>
public void save() {
userSpellList.Save(userXmlFile);
if (character != null) {
character.save();
}
}
/// <summary>
/// Remove a node from the application's custom spell list.
/// </summary>
/// <param name="nodeName">The name of the node to be searched on. Could be "name", "school", etc.</param>
/// <param name="nodeValue">The value of the node matching the nodeName.</param>
public void removeUserSpell(string nodeName, string nodeValue) {
(from sp in userSpellList.Elements("spell")
where (string)sp.Element(nodeName) == nodeValue
select sp).Remove();
}
public void hideMasterSpell(string nodeName, string nodeValue) {
userSpellList.Add(new XElement("hidden_spell", (from msp in masterSpellList.Elements("spell")
where (string)msp.Element(nodeName) == nodeValue
select msp)));
}
public void hideMasterSpellForCharacter(string nodeName, string nodeValue) {
charSpellList.Add(new XElement("hidden_spell", (from msp in masterSpellList.Elements("spell")
where (string)msp.Element(nodeName) == nodeValue
select msp)));
}
public void showMasterSpell(string nodeName, string nodeValue) {
(from hsp in userSpellList.Elements("hidden_spell")
where (string)hsp.Element("spell").Element(nodeName) == nodeValue
select hsp).Remove();
}
public void showMasterSpellForCharacter(string nodeName, string nodeValue) {
(from hsp in charSpellList.Elements("hidden_spell")
where (string)hsp.Element("spell").Element(nodeName) == nodeValue
select hsp).Remove();
}
public int hiddenSpellCount() {
return userSpellList.Descendants("hidden_spell").Count();
}
public int hiddenCharacterSpellCount() {
if (charSpellList != null) {
return charSpellList.Descendants("hidden_spell").Count();
}
return 0;
}
public int totalCount() {
int total = masterSpellList.Elements("spell").Count() + userSpellList.Elements("spell").Count();
if (charSpellList != null) {
total += charSpellList.Elements("spell").Count();
}
return total;
}
public int masterSpellCount() {
return masterSpellList.Elements("spell").Count();
}
public int userSpellCount() {
return userSpellList.Elements("spell").Count();
}
public int characterSpellCount() {
if (character != null) {
return character.spells().Elements("spell").Count();
}
return 0;
}
}
}