Mercurial > repos > IBBoard.WarFoundry.API
changeset 252:a54da5a8b5bb
Re #268: Restructure stats for re-use
* Add "Member Type" class
* Add member type setting and getting to Race
* Load member types from XML files
* Make unit type pull stat line from stats or first member type, or fall back to a blank stat line
* Change Stats object to initialise blank values
* Change schema
* Make stats optional
* Add member type list to race
* Add optional member type references to units
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 25 Apr 2010 15:07:08 +0000 |
parents | 22509bd03ca2 |
children | 79943fcf4de2 |
files | IBBoard.WarFoundry.API.csproj api/Factories/Xml/WarFoundryXmlRaceFactory.cs api/Objects/Race.cs api/Objects/Stats.cs api/Objects/UnitMemberType.cs api/Objects/UnitType.cs schemas/race.xsd |
diffstat | 7 files changed, 197 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/IBBoard.WarFoundry.API.csproj Fri Apr 23 20:00:06 2010 +0000 +++ b/IBBoard.WarFoundry.API.csproj Sun Apr 25 15:07:08 2010 +0000 @@ -156,6 +156,7 @@ </None> <Compile Include="api\AbstractWarFoundryLoader.cs" /> <Compile Include="api\DefaultWarFoundryLoader.cs" /> + <Compile Include="api\Objects\UnitMemberType.cs" /> </ItemGroup> <ItemGroup> <Content Include="libs\ICSharpCode.SharpZipLib.dll" />
--- a/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Fri Apr 23 20:00:06 2010 +0000 +++ b/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Sun Apr 25 15:07:08 2010 +0000 @@ -81,6 +81,11 @@ { CreateAbilityFromElement(node, race); } + + foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:memberTypes/race:memberType")) + { + CreateMemberTypeFromElement(node, race); + } foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:units/race:unit")) { @@ -165,8 +170,21 @@ type.MainCategory = cat; XmlElement statsElement = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:stats"); - Stats unitStats = ParseUnitStats(statsElement, type.GameSystem); - type.SetUnitStats(unitStats); + + if (statsElement!=null) + { + Stats unitStats = ParseUnitStats(statsElement, type.GameSystem); + type.SetUnitStats(unitStats); + } + + XmlNodeList unitMemberReferences = WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:unitMembers/race:unitMember"); + + foreach (XmlElement unitMemberRef in unitMemberReferences) + { + string typeID = unitMemberRef.GetAttribute("typeID"); + UnitMemberType unitMemberType = type.Race.GetUnitMemberType(typeID); + type.AddUnitMemberType(unitMemberType); + } } private void LoadEquipmentSlotsForUnitType(XmlElement elem, UnitType type) @@ -388,6 +406,11 @@ private Stats ParseUnitStats(XmlElement elem, GameSystem system) { + if (elem == null) + { + return null; + } + String statsID = elem.GetAttribute("statSet"); SystemStats statsSet; @@ -467,6 +490,13 @@ ability.Description = (node == null) ? "" : node.InnerText; race.AddAbility(ability); return ability; + } + + private void CreateMemberTypeFromElement(XmlElement elem, Race race) + { + Stats stats = ParseUnitStats(WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:stats"), race.GameSystem); + UnitMemberType unitMemberType = new UnitMemberType(elem.GetAttribute("id"), elem.GetAttribute("name"), stats); + race.AddUnitMemberType(unitMemberType); } } }
--- a/api/Objects/Race.cs Fri Apr 23 20:00:06 2010 +0000 +++ b/api/Objects/Race.cs Sun Apr 25 15:07:08 2010 +0000 @@ -22,6 +22,7 @@ private Dictionary<string, EquipmentItem> equipment = new Dictionary<string,EquipmentItem>(); private Dictionary<string, Ability> abilities = new Dictionary<string,Ability>(); private Dictionary<string, Category> categories = new Dictionary<string,Category>(); + private Dictionary<string, UnitMemberType> memberTypes = new Dictionary<string, UnitMemberType>(); public Race(string raceID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : this(raceID, "", raceName, gameSystem, creatingFactory) { @@ -265,5 +266,34 @@ get { return abilities; } set { abilities = value; } } + + public void AddUnitMemberType(UnitMemberType memberType) + { + memberTypes[memberType.ID] = memberType; + } + + /// <summary> + /// Gets a unit member type by its ID. + /// </summary> + /// <param name="id"> + /// The ID of the unit member type to get + /// </param> + /// <returns> + /// The <code>UnitMemberType</code> with the specified ID, or null if one doesn't exist. + /// </returns> + public UnitMemberType GetUnitMemberType(string id) + { + EnsureFullyLoaded(); + return DictionaryUtils.GetValue(memberTypes, id); + } + + public UnitMemberType[] UnitMemberTypes + { + get + { + EnsureFullyLoaded(); + return DictionaryUtils.ToArray(memberTypes); + } + } } }
--- a/api/Objects/Stats.cs Fri Apr 23 20:00:06 2010 +0000 +++ b/api/Objects/Stats.cs Sun Apr 25 15:07:08 2010 +0000 @@ -20,10 +20,11 @@ sysStats = systemStats; int statCount = sysStats.SlotCount; stats = new List<Stat>(statCount); + int i = 0; - for (int i = 0; i < statCount; i++) + foreach (StatSlot slot in sysStats.StatSlots) { - stats.Add(null); + stats.Add(new Stat(slot, "")); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/Objects/UnitMemberType.cs Sun Apr 25 15:07:08 2010 +0000 @@ -0,0 +1,45 @@ +// This file (UnitMember.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2010 IBBoard +// +// // The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license. + +using System; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// A container object for representations of different unit member types, such as "Infantry", "Elite Infantry" and "Commoner". + /// The idea of the UnitMemberType is to define not just the <see>UnitType</see>s, but also the types of type, as Archer and Swordsmen + /// are often just differently equipped versions of the same member type (Infantry). + /// </summary> + public class UnitMemberType : WarFoundryObject + { + private Stats stats; + + public UnitMemberType(string typeID, string typeName, Stats typeStats) : base(typeID, typeName) + { + stats = typeStats; + } + + /// <value> + /// The set of <see cref="Stat"/>s for the unit member type in a format that is valid for the game system. + /// </value> + public Stat[] StatsArray + { + get + { + return stats.StatsArray; + } + } + + public Stat[] StatsArrayWithName + { + get + { + Stat[] extendedStats = new Stat[stats.StatCount+1]; + extendedStats[0] = new Stat(new StatSlot("name"), Name); + stats.StatsArray.CopyTo(extendedStats, 1); + return extendedStats; + } + } + } +}
--- a/api/Objects/UnitType.cs Fri Apr 23 20:00:06 2010 +0000 +++ b/api/Objects/UnitType.cs Sun Apr 25 15:07:08 2010 +0000 @@ -33,7 +33,7 @@ private List<UnitType> containedTypes = new List<UnitType>(); private Dictionary<string, string> extraData = new Dictionary<string, string>(); private Dictionary<string, AbstractLimit> slotLimits = new Dictionary<string, AbstractLimit>(); - + private Dictionary<string, UnitMemberType> unitMemberTypes = new Dictionary<string, UnitMemberType>(); public UnitType(string id, string typeName, Race parentRace) : base(id, typeName) { @@ -199,9 +199,27 @@ /// </value> public Stat[] UnitStatsArray { - get + get { - return stats.StatsArray; + Stat[] statsArray = null; + + if (stats != null) + { + statsArray = stats.StatsArray; + } + else if (unitMemberTypes.Count > 0) + { + UnitMemberType[] memberTypeArray = DictionaryUtils.ToArray(unitMemberTypes); + statsArray = memberTypeArray[0].StatsArray; + } + else + { + SystemStats systemStats = GameSystem.StandardSystemStats; + Stats tempStats = new Stats(systemStats); + statsArray = tempStats.StatsArray; + } + + return statsArray; } } @@ -211,13 +229,36 @@ public Stat[] UnitStatsArrayWithName { get - { - Stat[] extendedStats = new Stat[stats.StatCount+1]; - extendedStats[0] = new Stat(new StatSlot("name"), Name); - stats.StatsArray.CopyTo(extendedStats, 1); - return extendedStats; + { + Stat[] statsArray = null; + + if (stats != null) + { + statsArray = ExtendStatsArrayWithName(stats.StatsArray); + } + else if (unitMemberTypes.Count > 0) + { + UnitMemberType[] memberTypeArray = DictionaryUtils.ToArray(unitMemberTypes); + statsArray = memberTypeArray[0].StatsArrayWithName; + } + else + { + SystemStats systemStats = GameSystem.StandardSystemStats; + Stats tempStats = new Stats(systemStats); + statsArray = ExtendStatsArrayWithName(tempStats.StatsArray); + } + + return statsArray; } } + + public Stat[] ExtendStatsArrayWithName(Stat[] statsArray) + { + Stat[] extendedStats = new Stat[statsArray.Length+1]; + extendedStats[0] = new Stat(new StatSlot("name"), Name); + statsArray.CopyTo(extendedStats, 1); + return extendedStats; + } public void SetUnitStats(Stats newStats) { @@ -482,5 +523,10 @@ return slotLimit; } + + public void AddUnitMemberType(UnitMemberType unitMemberType) + { + unitMemberTypes.Add(unitMemberType.ID, unitMemberType); + } } } \ No newline at end of file
--- a/schemas/race.xsd Fri Apr 23 20:00:06 2010 +0000 +++ b/schemas/race.xsd Sun Apr 25 15:07:08 2010 +0000 @@ -32,6 +32,22 @@ <xs:anyAttribute processContents="lax"/> </xs:complexType> </xs:element> + <xs:element name="memberTypes" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="memberType" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="stats" type="stats" minOccurs="0"/> + </xs:sequence> + <xs:attribute name="id" type="xs:ID" use="required"/> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:anyAttribute processContents="lax"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" /> @@ -45,7 +61,7 @@ <!--Reusable complex types --> <xs:complexType name="unit"> <xs:sequence> - <xs:element name="stats" type="stats"/> + <xs:element name="stats" type="stats" minOccurs="0"/> <xs:element name="equipmentSlots" minOccurs="0"> <xs:complexType> <xs:sequence> @@ -163,6 +179,21 @@ <xs:anyAttribute processContents="lax"/> </xs:complexType> </xs:element> + <xs:element name="unitMembers" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="unitMember" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> + </xs:sequence> + <xs:attribute name="typeID" type="xs:IDREF" use="required"/> + <xs:anyAttribute processContents="lax"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> <xs:element name="notes" type="xs:string" minOccurs="0" /> <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> </xs:sequence>