# HG changeset patch # User IBBoard # Date 1272208028 0 # Node ID a54da5a8b5bb22372187e0dd2b3cc9b564aa2984 # Parent 22509bd03ca236e32b9eceb58f4e9f56934707aa 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 diff -r 22509bd03ca2 -r a54da5a8b5bb IBBoard.WarFoundry.API.csproj --- 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 @@ + diff -r 22509bd03ca2 -r a54da5a8b5bb api/Factories/Xml/WarFoundryXmlRaceFactory.cs --- 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); } } } diff -r 22509bd03ca2 -r a54da5a8b5bb api/Objects/Race.cs --- 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 equipment = new Dictionary(); private Dictionary abilities = new Dictionary(); private Dictionary categories = new Dictionary(); + private Dictionary memberTypes = new Dictionary(); 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; + } + + /// + /// Gets a unit member type by its ID. + /// + /// + /// The ID of the unit member type to get + /// + /// + /// The UnitMemberType with the specified ID, or null if one doesn't exist. + /// + public UnitMemberType GetUnitMemberType(string id) + { + EnsureFullyLoaded(); + return DictionaryUtils.GetValue(memberTypes, id); + } + + public UnitMemberType[] UnitMemberTypes + { + get + { + EnsureFullyLoaded(); + return DictionaryUtils.ToArray(memberTypes); + } + } } } diff -r 22509bd03ca2 -r a54da5a8b5bb api/Objects/Stats.cs --- 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(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, "")); } } diff -r 22509bd03ca2 -r a54da5a8b5bb api/Objects/UnitMemberType.cs --- /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 +{ + /// + /// 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 UnitTypes, but also the types of type, as Archer and Swordsmen + /// are often just differently equipped versions of the same member type (Infantry). + /// + public class UnitMemberType : WarFoundryObject + { + private Stats stats; + + public UnitMemberType(string typeID, string typeName, Stats typeStats) : base(typeID, typeName) + { + stats = typeStats; + } + + /// + /// The set of s for the unit member type in a format that is valid for the game system. + /// + 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; + } + } + } +} diff -r 22509bd03ca2 -r a54da5a8b5bb api/Objects/UnitType.cs --- 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 containedTypes = new List(); private Dictionary extraData = new Dictionary(); private Dictionary slotLimits = new Dictionary(); - + private Dictionary unitMemberTypes = new Dictionary(); public UnitType(string id, string typeName, Race parentRace) : base(id, typeName) { @@ -199,9 +199,27 @@ /// 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 diff -r 22509bd03ca2 -r a54da5a8b5bb schemas/race.xsd --- 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 @@ + + + + + + + + + + + + + + + + @@ -45,7 +61,7 @@ - + @@ -163,6 +179,21 @@ + + + + + + + + + + + + + + +