Mercurial > repos > IBDev-IBBoard.WarFoundry.API
changeset 411:20274b5b0fd6
* Merge branch (code already merged in Subversion, but Mercurial kept the branch)
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 26 Aug 2011 20:04:52 +0100 |
parents | 376da2b24de1 (diff) 47ae48fd1f02 (current diff) |
children | 48098a2d17d0 |
files | IBBoard.WarFoundry.API.csproj schemas/system.xsd |
diffstat | 176 files changed, 9946 insertions(+), 8570 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,4 @@ +obj/* +bin/* +IBBoard.WarFoundry.API.suo +IBBoard.WarFoundry.API.pidb \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgtags Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,12 @@ +40362a9adf20cc0293f913d16195fac67176fe64 WarFoundry_v0.1 +7f13ffcb876583f948d4c41efa5158f14b301eeb WarFoundry_v0.1beta2_Winforms +938409fc24cc07bef9e945bea34acbd0dfdca378 WarFoundry_v0.1beta3_Winforms +678054e2bc0207b7f8dd9eb3c1c976c211b283f4 WarFoundry_v0.1beta_Winforms +3045a168714ac06fef31e0ae2a9f8a02fae3c5d2 WarFoundry_v0.1beta4_Winforms +3045a168714ac06fef31e0ae2a9f8a02fae3c5d2 WarFoundry_v0.1beta5_Winforms +3e74bf7b0f725144ae64c268c40d988d53408725 WarFoundry_v0.1.1 +b8b6a1c50023b8a5b68635322abc1a25877f0e87 WarFoundry_v0.1RC1_Winforms +b8b6a1c50023b8a5b68635322abc1a25877f0e87 WarFoundry_v0.1beta7_Winforms +b8b6a1c50023b8a5b68635322abc1a25877f0e87 WarFoundry_v0.1beta8_Winforms +b8b6a1c50023b8a5b68635322abc1a25877f0e87 WarFoundry_v0.1beta9_Winforms +06b4beb3e1568ef9b22ccc4e135430a6714dd2bc WarFoundry_v0.1beta6_Winforms
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/AbstractWarFoundryLoader.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,695 @@ +// This file (AbstractWarFoundryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using System.IO; +using IBBoard.Collections; +using IBBoard.IO; +using IBBoard.Logging; +using IBBoard.WarFoundry.API.Factories; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API +{ + /// <summary> + /// The base abstract implementation of a WarFoundry file loader + /// </summary> + public abstract class AbstractWarFoundryLoader + { + private ICollection<DirectoryInfo> directories; + private ICollection<INativeWarFoundryFactory> factories; + private ICollection<INonNativeWarFoundryFactory> nonNativeFactories; + private Dictionary<IWarFoundryFactory, SimpleSet<IWarFoundryObject>> loadedObjects; + + public delegate void FileLoadingCompleteDelegate(List<FileLoadFailure> failures); + + public event MethodInvoker FileLoadingStarted; + + public event FileLoadingCompleteDelegate FileLoadingFinished; + + protected AbstractWarFoundryLoader() + { + directories = new List<DirectoryInfo>(); + factories = new List<INativeWarFoundryFactory>(); + nonNativeFactories = new List<INonNativeWarFoundryFactory>(); + loadedObjects = new Dictionary<IWarFoundryFactory,SimpleSet<IWarFoundryObject>>(); + } + + /// <summary> + /// Adds a directory to the collection of directories that will be searched for WarFoundry data files. + /// </summary> + /// <param name="directory"> + /// The <see cref="DirectoryInfo"/> to add to the list for searching for data files + /// </param> + public void AddLoadDirectory(DirectoryInfo directory) + { + if (!directories.Contains(directory)) + { + directories.Add(directory); + } + } + + /// <summary> + /// Removes a directory from the collection of directories that will be searched for WarFoundry data files. + /// </summary> + /// <param name="directory"> + /// A <see cref="DirectoryInfo"/> + /// </param> + public void RemoveLoadDirectory(DirectoryInfo directory) + { + if (directories.Contains(directory)) + { + directories.Remove(directory); + } + } + + /// <summary> + /// Registers a <see cref="INativeWarFoundryFactory"/> as a factory that can parse native data files. + /// </summary> + /// <param name="factory"> + /// The <see cref="INativeWarFoundryFactory"/> to register to parse native data files. + /// </param> + public virtual void RegisterFactory(INativeWarFoundryFactory factory) + { + if (!factories.Contains(factory)) + { + factories.Add(factory); + } + } + + /// <summary> + /// Unregisters a <see cref="INativeWarFoundryFactory"/> so that it will no longer be used to try to parse native data files. + /// </summary> + /// <param name="factory"> + /// The <see cref="INativeWarFoundryFactory"/> to remove from the collection of factories that are used to try to parse native data files. + /// </param> + public virtual void UnregisterFactory(INativeWarFoundryFactory factory) + { + if (factories.Contains(factory)) + { + factories.Remove(factory); + } + } + + /// <summary> + /// Registers a <see cref="INonNativeWarFoundryFactory"/> so that it will be used to try to parse non-native data files from other applications. + /// </summary> + /// <param name="factory"> + /// The <see cref="INonNativeWarFoundryFactory"/> to register to parse non-native data files. + /// </param> + public virtual void RegisterNonNativeFactory(INonNativeWarFoundryFactory factory) + { + if (!nonNativeFactories.Contains(factory)) + { + nonNativeFactories.Add(factory); + } + } + + /// <summary> + /// Unregisters a <see cref="INonNativeWarFoundryFactory"/> so that it will no longer be used to try to parse non-native data files from other applications. + /// </summary> + /// <param name="factory"> + /// The <see cref="INonNativeWarFoundryFactory"/> to remove from the collection of factories that are used to try to parse non-native data files. + /// </param> + public virtual void UnregisterNonNativeFactory(INonNativeWarFoundryFactory factory) + { + if (nonNativeFactories.Contains(factory)) + { + nonNativeFactories.Remove(factory); + } + } + + /// <summary> + /// Loads all of the data files in the registered directories. + /// </summary> + /// <returns> + /// A <see cref="List"/> of <see cref="FileLoadFailure"/> for files that failed to load + /// </returns> + public List<FileLoadFailure> LoadFiles() + { + PrepareForFileLoad(); + Dictionary<FileInfo, IWarFoundryFactory> loadableRaces = new Dictionary<FileInfo, IWarFoundryFactory>(); + Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems = new Dictionary<FileInfo, IWarFoundryFactory>(); + List<FileLoadFailure> failedLoads = FillLoadableFiles(loadableRaces, loadableGameSystems); + failedLoads.AddRange(LoadGameSystems(loadableGameSystems)); + failedLoads.AddRange(LoadRaces(loadableRaces)); + OnFileLoadingFinished(failedLoads); + FinishFileLoad(); + return failedLoads; + } + + private void OnFileLoadingFinished(List<FileLoadFailure> failures) + { + if (FileLoadingFinished != null) + { + FileLoadingFinished(failures); + } + } + + protected virtual void PrepareForFileLoad() + { + //Do nothing special + } + + protected virtual void FinishFileLoad() + { + //Do nothing special + } + + private List<FileLoadFailure> FillLoadableFiles(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + + foreach (DirectoryInfo directory in directories) + { + directory.Refresh(); + + if (directory.Exists) + { + List<FileLoadFailure> directoryFails = FillLoadableFilesForDirectory(loadableRaces, loadableGameSystems, directory); + fails.AddRange(directoryFails); + } + else + { + LogNotifier.WarnFormat(GetType(), "Load for {0} failed because directory didn't exist", directory.FullName); + } + } + + return fails; + } + + private List<FileLoadFailure> FillLoadableFilesForDirectory(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems, DirectoryInfo directory) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + LogNotifier.Debug(GetType(), "Load from " + directory.FullName); + + foreach (FileInfo file in directory.GetFiles()) + { + IWarFoundryFactory factory = GetGameSystemLoadingFactoryForFile(file); + + if (factory != null) + { + loadableGameSystems.Add(file, factory); + } + else + { + factory = GetRaceLoadingFactoryForFile(file); + + if (factory != null) + { + loadableRaces.Add(file, factory); + } + else + { + FileLoadFailure failure = new FileLoadFailure(file, "File not handled as a Race or Game System definition: {0}", "FileNotHandled"); + fails.Add(failure); + LogNotifier.Info(GetType(), failure.Message); + } + } + } + + foreach (DirectoryInfo subdir in directory.GetDirectories()) + { + fails.AddRange(FillLoadableFilesForDirectory(loadableRaces, loadableGameSystems, subdir)); + } + + return fails; + } + + private IWarFoundryFactory GetGameSystemLoadingFactoryForFile(FileInfo file) + { + IWarFoundryFactory loadingFactory = null; + + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + { + if (factory.CanHandleFileAsGameSystem(file)) + { + loadingFactory = factory; + break; + } + } + + if (loadingFactory == null) + { + foreach (INativeWarFoundryFactory factory in factories) + { + if (factory.CanHandleFileAsGameSystem(file)) + { + loadingFactory = factory; + break; + } + } + } + + return loadingFactory; + } + + private IWarFoundryFactory GetRaceLoadingFactoryForFile(FileInfo file) + { + IWarFoundryFactory loadingFactory = null; + + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + { + if (factory.CanHandleFileAsRace(file)) + { + loadingFactory = factory; + break; + } + } + + if (loadingFactory == null) + { + foreach (INativeWarFoundryFactory factory in factories) + { + if (factory.CanHandleFileAsRace(file)) + { + loadingFactory = factory; + break; + } + } + } + + return loadingFactory; + } + + private List<FileLoadFailure> LoadGameSystems(Dictionary<FileInfo, IWarFoundryFactory> gameSystemFiles) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + + + foreach (FileInfo file in gameSystemFiles.Keys) + { + FileLoadFailure failure = null; + + try + { + bool loaded = LoadObject(file, gameSystemFiles[file]); + + if (!loaded) + { + failure = new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as GameSystem using {1}"); + } + } + catch (Exception ex) + { + failure = new FileLoadFailure(file, null, ex.Message, null, ex); + } + + if (failure != null) + { + fails.Add(failure); + LogNotifier.Warn(GetType(), failure.Message, failure.Exception); + } + } + + return fails; + } + + private List<FileLoadFailure> LoadRaces(Dictionary<FileInfo, IWarFoundryFactory> raceFiles) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + + foreach (FileInfo file in raceFiles.Keys) + { + FileLoadFailure failure = null; + + try + { + bool loaded = LoadObject(file, raceFiles[file]); + + if (!loaded) + { + failure = new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}"); + } + } + catch (Exception ex) + { + failure = new FileLoadFailure(file, null, ex.Message, null, ex); + } + + if (failure != null) + { + fails.Add(failure); + LogNotifier.Warn(GetType(), failure.Message, failure.Exception); + } + } + + return fails; + } + + private bool LoadObject(FileInfo file, IWarFoundryFactory factory) + { + LogNotifier.DebugFormat(GetType(), "Loading {0} using {1}", file.FullName, factory.GetType().Name); + factory.RaceLoaded+= StoreRace; + factory.GameSystemLoaded+= StoreGameSystem; + ICollection<IWarFoundryObject> objects = factory.CreateObjectsFromFile(file); + return objects.Count > 0; + } + + + /// <summary> + /// Loads a single file through the registered WarFoundryFactories, if a factory exists that supports the file format. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to attempt to load + /// </param> + /// <returns> + /// An ICollection of IWarFoundryObjects loaded from <code>file</code> + /// </returns> + public ICollection<IWarFoundryObject> LoadFile(FileInfo file) + { + ICollection<IWarFoundryObject> objs = null; + IWarFoundryFactory loadFactory = null; + + try + { + objs = LoadFileWithNonNativeFactories(file, out loadFactory); + + if (objs == null) + { + objs = LoadFileWithNativeFactories(file, out loadFactory); + } + } + catch (InvalidFileException ex) + { + LogNotifier.Error(GetType(), file.FullName + " failed to load", ex); + } + + if (objs != null) + { + AddLoadedObjects(objs, loadFactory); + } + else + { + objs = new List<IWarFoundryObject>(); + } + + return objs; + } + + private ICollection<IWarFoundryObject> LoadFileWithNonNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) + { + ICollection<IWarFoundryObject> objs = null; + loadFactory = null; + + if (nonNativeFactories.Count > 0) + { + LogNotifier.Debug(GetType(), "Attempting to load " + file.FullName + " as a non-native file"); + + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + { + bool canLoad = factory.CanHandleFileFormat(file); + LogNotifier.Debug(GetType(), "Load using " + factory.GetType().FullName + "? " + (canLoad ? "yes" : "no")); + + if (canLoad) + { + objs = factory.CreateObjectsFromFile(file); + + if (objs != null) + { + loadFactory = factory; + break; + } + } + } + } + + return objs; + } + + private ICollection<IWarFoundryObject> LoadFileWithNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) + { + ICollection<IWarFoundryObject> objs = null; + loadFactory = null; + + if (factories.Count > 0) + { + LogNotifier.Debug(GetType(), "Attempting to load " + file.FullName + " as native file"); + + foreach (INativeWarFoundryFactory factory in factories) + { + if (factory.CanHandleFileFormat(file)) + { + objs = factory.CreateObjectsFromFile(file); + + if (objs != null) + { + loadFactory = factory; + break; + } + } + } + } + + return objs; + } + + private void AddLoadedObjects(ICollection<IWarFoundryObject> loadedObjs, IWarFoundryFactory factory) + { + SimpleSet<IWarFoundryObject> objs; + loadedObjects.TryGetValue(factory, out objs); + + if (objs == null) + { + objs = new SimpleSet<IWarFoundryObject>(); + loadedObjects.Add(factory, objs); + } + + objs.AddRange(loadedObjs); + StoreObjects(loadedObjs); + } + + private void StoreObjects(ICollection<IWarFoundryObject> loadedObjects) + { + foreach (IWarFoundryObject loadedObject in loadedObjects) + { + if (loadedObject is GameSystem) + { + StoreGameSystem((GameSystem)loadedObject); + } + else if (loadedObject is Race) + { + StoreRace((Race)loadedObject); + } + } + } + + protected void StoreGameSystem(GameSystem system) + { + GameSystem existingSystem = GetExistingSystemForSystem(system); + + if (existingSystem != null) + { + if (!system.Equals(existingSystem)) + { + //TODO: Raise an event to say we got a different duplicate + //We can't just fail, because failing is for completely unhandled files, not for objects in a file + } + } + else + { + DoStoreGameSystem(system); + } + } + + /// <summary> + /// Gets a game system that has already been loaded that duplicates the supplied game system's ID, if one exists. + /// </summary> + /// <param name="system"> + /// The <see cref="GameSystem"/> to find pre-existing duplicates of + /// </param> + /// <returns> + /// <code>null</code> if no existing duplicate exists, else the duplicate <see cref="GameSystem"/> + /// </returns> + protected abstract GameSystem GetExistingSystemForSystem(GameSystem system); + + /// <summary> + /// Stores a GameSystem in the loader's relevant storage structure + /// </summary> + /// <param name="system"> + /// The loaded <see cref="GameSystem"/> to store + /// </param> + protected abstract void DoStoreGameSystem(GameSystem system); + + protected void StoreRace(Race race) + { + if (race.GameSystem == null) + { + throw new InvalidOperationException("Race cannot have null game system. Game system should be loaded before race."); + } + + DoStoreRace(race); + } + + /// <summary> + /// Performs the implementation specific storage of a race + /// </summary> + /// <param name="race"> + /// The <see cref="Race"/> to store + /// </param> + protected abstract void DoStoreRace(Race race); + + /// <summary> + /// Gets all <see cref="GameSystem"/>s that are currently available, determined by those that can be loaded with the current <see cref="IWarFoundryFactory"/>s. + /// </summary> + /// <returns> + /// An array of <see cref="GameSystem"/>s that are currently available. + /// </returns> + public abstract GameSystem[] GetGameSystems(); + + /// <summary> + /// Gets a single <see cref="GameSystem"/> with a given ID. + /// </summary> + /// <param name="systemID"> + /// The ID of the <see cref="GameSystem"/> to get, as a <see cref="System.String"/>. + /// </param> + /// <returns> + /// The <see cref="GameSystem"/> with the given ID, or <code>null</code> if one doesn't exist. + /// </returns> + public abstract GameSystem GetGameSystem(string systemID); + + /// <summary> + /// Removes a loaded <see cref="GameSystem"/>. Used when a GameSystem fails to complete loading + /// </summary> + /// <param name="system">The GameSystem to remove</param> + protected internal abstract void RemoveGameSystem(GameSystem system); + + /// <summary> + /// Gets an array of the races for the specified <see cref="GameSystem"/>. + /// </summary> + /// <param name="system"> + /// The <see cref="GameSystem"/> to get the available races for. + /// </param> + /// <returns> + /// An array of <see cref="Race"/>s for the <see cref="GameSystem"/> + /// </returns> + public abstract Race[] GetRaces(GameSystem system); + + /// <summary> + /// Gets a single race for a given <see cref="GameSystem"/> by ID of the race. + /// </summary> + /// <param name="system"> + /// The <see cref="GameSystem"/> that the race is part of. + /// </param> + /// <param name="raceID"> + /// A <see cref="System.String"/> ID for the race to load. + /// </param> + /// <returns> + /// A <see cref="Race"/> with the specified ID from the <see cref="GameSystem"/>, or <code>null</code> if one doesn't exist. + /// </returns> + public abstract Race GetRace(GameSystem system, string raceID); + + /// <summary> + /// Gets a single race for a given <see cref="GameSystem"/> by the race's ID and sub-race ID. + /// </summary> + /// <param name="system"> + /// The <see cref="GameSystem"/> that the race is part of. + /// </param> + /// <param name="raceID"> + /// The <see cref="System.String"/> ID for the race to load. + /// </param> + /// <param name="raceSubID"> + /// A <see cref="System.String"/> + /// </param> + /// <returns> + /// A <see cref="Race"/> + /// </returns> + public abstract Race GetRace(GameSystem system, string raceID, string raceSubID); + + protected internal abstract void RemoveRace(Race race); + + /// <summary> + /// Gets the IDs of all of the game systems currently available. + /// </summary> + /// <returns> + /// An array of <see cref="System.String"/>s representing the IDs of the game systems. + /// </returns> + public virtual string[] GetGameSystemIDs() + { + GameSystem[] systems = GetGameSystems(); + return GetWarFoundryObjectIDs(systems); + } + + protected string[] GetWarFoundryObjectIDs(WarFoundryObject[] objs) + { + int objCount = objs.Length; + string[] keys = new string[objCount]; + + for (int i = 0; i < objCount; i++) + { + keys[i] = objs[i].ID; + } + + return keys; + } + + /// <summary> + /// Gets the IDs of all of the races of a specified game system. + /// </summary> + /// <param name="system"> + /// The <see cref="GameSystem"/> to get the available races for. + /// </param> + /// <returns> + /// An array of <see cref="System.String"/>s representing the IDs of the races of the specified game system. + /// </returns> + public virtual string[] GetSystemRaceIDs(GameSystem system) + { + Race[] races = GetRaces(system); + return GetWarFoundryObjectIDs(races); + } + + public Army LoadArmy(FileInfo file) + { + IWarFoundryFactory factory = GetArmyLoadingFactoryForFile(file); + Army loadedArmy = null; + + if (factory != null) + { + ICollection<IWarFoundryObject> objs = factory.CreateObjectsFromFile(file); + + if (objs.Count == 1) + { + foreach (IWarFoundryObject systemCount in objs) + { + if (systemCount is Army) + { + loadedArmy = (Army)systemCount; + } + } + } + } + + return loadedArmy; + } + + private IWarFoundryFactory GetArmyLoadingFactoryForFile(FileInfo file) + { + IWarFoundryFactory loadingFactory = null; + + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + { + if (factory.CanHandleFileAsArmy(file)) + { + loadingFactory = factory; + break; + } + } + + if (loadingFactory == null) + { + foreach (INativeWarFoundryFactory factory in factories) + { + if (factory.CanHandleFileAsArmy(file)) + { + loadingFactory = factory; + break; + } + } + } + + return loadingFactory; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/AbstractReplaceUnitEquipmentCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,74 @@ +// This file (AbstractReplaceUnitEquipmentCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// An abstract implementation of the core method for replacing one equipment item with another + /// </summary> + public abstract class AbstractReplaceUnitEquipmentCommand : Command + { + private SetUnitEquipmentNumericAmountCommand removeOldCommand; + private AbstractSetUnitEquipmentAmountCommand addNewCommand; + + public AbstractReplaceUnitEquipmentCommand(Unit unit, UnitEquipmentItem oldItem, AbstractSetUnitEquipmentAmountCommand addNewEquipmentCommand) + { + //We can get away with a numeric amount here even if it is a ratio item because we're setting it to 0 + removeOldCommand = new SetUnitEquipmentNumericAmountCommand(unit, oldItem, 0); + addNewCommand = addNewEquipmentCommand; + } + + public override bool CanExecute() + { + return removeOldCommand.CanExecute() && addNewCommand.CanExecute(); + } + + public override string Description + { + get + { + return Translation.GetTranslation("replaceUnitEquipmentCommandDescription", "replace {0} with {1} for {2}", removeOldCommand.EquipItem.Name, addNewCommand.EquipItem.Name, removeOldCommand.Unit.Name); + } + } + + public override string UndoDescription + { + get + { + return Translation.GetTranslation("replaceUnitEquipmentCommandUndoDescription", "replace {0} with {1} for {2}", addNewCommand.EquipItem.Name, removeOldCommand.EquipItem.Name, removeOldCommand.Unit.Name); + } + } + + public override bool Execute() + { + this.Redo(); + return true; + } + + public override void Redo() + { + removeOldCommand.Redo(); + addNewCommand.Redo(); + } + + public override void Undo() + { + addNewCommand.Undo(); + removeOldCommand.Undo(); + } + + public override string Name + { + get + { + return "Replace required equipment"; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/AbstractSetUnitEquipmentAmountCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,120 @@ +// This file (AbstractSetUnitEquipmentAmountCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Util; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// Abstract parent class for commands that set the amount of an equipment item a unit has to a fixed numeric or ratio value + /// </summary> + public abstract class AbstractSetUnitEquipmentAmountCommand : Command + { + private Unit unit; + private UnitEquipmentItem equip; + private double oldAmount; + private bool oldAmountWasRatio; + + public AbstractSetUnitEquipmentAmountCommand(Unit unit, UnitEquipmentItem item) + { + this.unit = unit; + equip = item; + oldAmount = UnitEquipmentUtil.GetEquipmentAmount(unit, equip); + oldAmountWasRatio = UnitEquipmentUtil.GetEquipmentAmountIsRatio(unit, equip); + } + + public override bool CanExecute() + { + return (unit != null && equip != null); + } + + public override string Description + { + get + { + return Translation.GetTranslation("setEquipmentAmountCommandDescription", "set {0} amount for {1} to {2}", equip.Name, unit.Name, GetNewAmountString()); + } + } + + /// <summary> + /// Gets the string representation for the new amount of the equipment item to take + /// </summary> + /// <returns> + /// the string representation for the new amount of the equipment item to take + /// </returns> + protected abstract string GetNewAmountString(); + + public override string UndoDescription + { + get + { + return Translation.GetTranslation("setEquipmentAmountCommandUndoDescription", "set {0} amount for {1} to {2}", equip.Name, unit.Name, GetOldAmountString()); + } + } + + /// <summary> + /// Gets the string representation for the old amount of the equipment item to take + /// </summary> + /// <returns> + /// the string representation for the old amount of the equipment item to take + /// </returns> + protected string GetOldAmountString() + { + return oldAmountWasRatio ? GetRatioAmountString(oldAmount, UnitEquipmentRatioSelection.CalculateNumberTaken(Unit, EquipItem, oldAmount)) : GetNumberAmountString((int)oldAmount); + } + + protected string GetNumberAmountString(int number) + { + return Translation.GetTranslation("equipmentAmountNumber", "{0}", number); + } + + protected string GetRatioAmountString(double amount, int number) + { + string amountString; + + if (amount == 100) + { + amountString = Translation.GetTranslation("equipmentAmountAll", "all ({1})", amount, number); + } + else + { + amountString = Translation.GetTranslation("equipmentAmountPercentage", "{0}% ({1})", amount, number); + } + + return amountString; + } + + public override bool Execute() + { + this.Redo(); + return true; + } + + public override void Undo() + { + if (oldAmountWasRatio) + { + unit.SetEquipmentRatio(equip, oldAmount); + } + else + { + unit.SetEquipmentAmount(equip, (int)oldAmount); + } + } + + public UnitEquipmentItem EquipItem + { + get { return equip; } + } + + public Unit Unit + { + get { return unit; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/CreateAndAddUnitCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,72 @@ +// This file (CreateAndAddUnitCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + public class CreateAndAddUnitCommand : Command + { + private UnitType addedUnitType; + private ArmyCategory armyCat; + private Unit addedUnit; + + public CreateAndAddUnitCommand(UnitType toAdd, ArmyCategory armyCatTo) + { + addedUnitType = toAdd; + armyCat = armyCatTo; + } + + public override bool CanExecute() + { + return (addedUnitType != null && armyCat != null); + } + + public override string Description + { + get + { + return Translation.GetTranslation("createAndAddUnitCommandDescription", "add unit of {0} to the army", addedUnitType.Name); + } + } + + public override string UndoDescription + { + get + { + return Translation.GetTranslation("createAndAddUnitCommandUndoDescription", "remove unit of {0} from army", addedUnitType.Name); + } + } + + public override bool Execute() + { + addedUnit = new Unit(addedUnitType, armyCat); + this.Redo(); + return true; + } + + public override void Redo() + { + armyCat.AddUnit(addedUnit); + } + + public override void Undo() + { + armyCat.RemoveUnit(addedUnit); + } + + public override string Name + { + get { return "Add new unit"; } + } + + public Unit Unit + { + get { return addedUnit; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/RemoveUnitCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,68 @@ +// This file (RemoveUnitCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// Summary description for RemoveUnitCommand. + /// </summary> + public class RemoveUnitCommand : Command + { + private Unit unit; + private ArmyCategory cat; + + public RemoveUnitCommand(Unit toRemove) + { + unit = toRemove; + cat = unit.Category; + } + + public override bool CanExecute() + { + return (unit != null); + } + + public override string Description + { + get + { + return Translation.GetTranslation("removeUnitCommandDescription", "remove {0} from the army", unit.Name); + } + } + + public override string UndoDescription + { + get + { + return Translation.GetTranslation("removeUnitCommandUndoDescription", "re-add {0} to the army", unit.Name); + } + } + + public override bool Execute() + { + this.Redo(); + return true; + } + + public override void Redo() + { + cat.RemoveUnit(unit); + } + + public override void Undo() + { + cat.AddUnit(unit); + } + + public override string Name + { + get { return "Remove unit"; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/ReplaceUnitEquipmentWithNumericAmountItemCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,21 @@ +// This file (ReplaceUnitEquipmentWithNumericAmountItemCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// A concrete implementation of an equipment replacing command that replaces a given equipment item with a different item that has an absolute numeric amount. + /// </summary> + public class ReplaceUnitEquipmentWithNumericAmountItemCommand : AbstractReplaceUnitEquipmentCommand + { + public ReplaceUnitEquipmentWithNumericAmountItemCommand(Unit unit, UnitEquipmentItem oldItem, UnitEquipmentItem newItem, int newItemAmount) : base(unit, oldItem, new SetUnitEquipmentNumericAmountCommand(unit, newItem, newItemAmount)) + { + //Do nothing special + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/ReplaceUnitEquipmentWithRatioAmountItemCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,21 @@ +// This file (ReplaceUnitEquipmentWithRatioAmountItemCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// A concrete implementation of an equipment replacing command that replaces a given equipment item with a different item that has a ratio/percentage amount. + /// </summary> + public class ReplaceUnitEquipmentWithRatioAmountItemCommand : AbstractReplaceUnitEquipmentCommand + { + public ReplaceUnitEquipmentWithRatioAmountItemCommand(Unit unit, UnitEquipmentItem oldItem, UnitEquipmentItem newItem, double newItemRatio) : base(unit, oldItem, new SetUnitEquipmentRatioAmountCommand(unit, newItem, newItemRatio)) + { + //Do nothing special + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/SetNameCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,69 @@ +// This file (SetNameCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// Summary description for SetNameCommand. + /// </summary> + public class SetNameCommand : Command + { + private WarFoundryObject obj; + private string newName, oldName; + + public SetNameCommand(WarFoundryObject toRename, string name) + { + obj = toRename; + newName = name; + oldName = obj.Name; + } + + public override bool CanExecute() + { + return (obj != null && newName != null && newName != ""); + } + + public override string Description + { + get + { + return Translation.GetTranslation("setUnitNameCommandDescription", "rename \"{0}\" to \"{1}\"", oldName, newName); + } + } + + public override string UndoDescription + { + get + { + return Translation.GetTranslation("setUnitNameCommandUndoDescription", "rename \"{0}\" to \"{1}\"", newName, oldName); + } + } + + public override bool Execute() + { + this.Redo(); + return true; + } + + public override void Redo() + { + obj.Name = newName; + } + + public override void Undo() + { + obj.Name = oldName; + } + + public override string Name + { + get { return "Rename item"; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/SetUnitEquipmentNumericAmountCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,39 @@ +// This file (SetUnitEquipmentNumericAmountCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// Summary description for SetUnitEquipmentNumericAmountCommand. + /// </summary> + public class SetUnitEquipmentNumericAmountCommand : AbstractSetUnitEquipmentAmountCommand + { + private int newAmount; + + public SetUnitEquipmentNumericAmountCommand(Unit unit, UnitEquipmentItem item, int amount) : base(unit, item) + { + newAmount = amount; + } + + protected override string GetNewAmountString () + { + return GetNumberAmountString(newAmount); + } + + public override void Redo() + { + Unit.SetEquipmentAmount(EquipItem, newAmount); + } + + public override string Name + { + get { return "Set equipment amount"; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/SetUnitEquipmentRatioAmountCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,39 @@ +// This file (SetUnitEquipmentRatioAmountCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// Summary description for SetUnitEquipmentRatioAmountCommand. + /// </summary> + public class SetUnitEquipmentRatioAmountCommand : AbstractSetUnitEquipmentAmountCommand + { + private double newAmount; + + public SetUnitEquipmentRatioAmountCommand(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item) + { + newAmount = amount; + } + + protected override string GetNewAmountString () + { + return GetRatioAmountString(newAmount, UnitEquipmentRatioSelection.CalculateNumberTaken(Unit, EquipItem, newAmount)); + } + + public override void Redo() + { + Unit.SetEquipmentRatio(EquipItem, newAmount); + } + + public override string Name + { + get { return "Set equipment ratio"; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Commands/SetUnitSizeCommand.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,69 @@ +// This file (SetUnitSizeCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.Commands; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Commands +{ + /// <summary> + /// Summary description for SetNameCommand. + /// </summary> + public class SetUnitSizeCommand : Command + { + private Unit unit; + private int newSize, oldSize; + + public SetUnitSizeCommand(Unit toResize, int size) + { + unit = toResize; + newSize = size; + oldSize = unit.Size; + } + + public override bool CanExecute() + { + return (unit != null && newSize > 0 && oldSize > 0); + } + + public override string Description + { + get + { + return Translation.GetTranslation("setUnitSizeCommandDescription", "set size of {0} to {1}", unit.Name, newSize); + } + } + + public override string UndoDescription + { + get + { + return Translation.GetTranslation("setUnitSizeCommandUndoDescription", "set size of {0} to {1}", unit.Name, oldSize); + } + } + + public override bool Execute() + { + this.Redo(); + return true; + } + + public override void Redo() + { + unit.Size = newSize; + } + + public override void Undo() + { + unit.Size = oldSize; + } + + public override string Name + { + get { return "Change unit size"; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/DefaultWarFoundryLoader.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,304 @@ +// This file (DefaultWarFoundryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API +{ + /// <summary> + /// The default implementation of a <see cref="AbstractWarFoundryLoader"/> + /// </summary> + public class DefaultWarFoundryLoader : AbstractWarFoundryLoader + { + private Dictionary<string, GameSystem> systemsTable; + private Dictionary<string, Dictionary<string, Dictionary<string, Race>>> racesTable; //Keys are: System, Race, SubRace + private bool loaded = false; + private bool loading = false; + + public DefaultWarFoundryLoader() + { + systemsTable = new Dictionary<string,GameSystem>(); + racesTable = new Dictionary<string,Dictionary<string,Dictionary<string,Race>>>(); + } + + protected override void PrepareForFileLoad() + { + loading = true; + systemsTable.Clear(); + racesTable.Clear(); + } + + protected override void FinishFileLoad() + { + loaded = true; + loading = false; + } + + protected override GameSystem GetExistingSystemForSystem(GameSystem system) + { + return DictionaryUtils.GetValue(systemsTable, system.ID.ToLower()); + } + + protected override void DoStoreGameSystem(GameSystem system) + { + systemsTable[system.ID.ToLower()] = system; + } + + protected override void DoStoreRace(Race race) + { + Dictionary<string, Dictionary<string, Race>> systemRaces; + + string systemID = race.GameSystem.ID.ToLower(); + racesTable.TryGetValue(systemID, out systemRaces); + + if (systemRaces == null) + { + systemRaces = new Dictionary<string,Dictionary<string,Race>>(); + racesTable.Add(systemID, systemRaces); + } + + Dictionary<string, Race> subRaces; + systemRaces.TryGetValue(race.ID.ToLower(), out subRaces); + + if (subRaces == null) + { + subRaces = new Dictionary<string,Race>(); + systemRaces.Add(race.ID.ToLower(), subRaces); + } + + string subID = race.SubID.ToLower(); + + if (subRaces.ContainsKey(subID)) + { + Race existingRace = subRaces[subID]; + + if (!race.Equals(existingRace)) + { + //TODO: Raise an event to say we got a different duplicate + //We can't just fail, because failing is for completely unhandled files, not for objects in a file + } + } + else + { + subRaces.Add(race.SubID.ToLower(), race); + } + } + + public override GameSystem[] GetGameSystems() + { + if (!loaded && !loading) + { + LoadFiles(); + } + + return DictionaryUtils.ToArray<string, GameSystem>(systemsTable); + } + + public override GameSystem GetGameSystem(string systemID) + { + if (!loaded && !loading) + { + LoadFiles(); + } + + GameSystem system; + systemsTable.TryGetValue(systemID.ToLower(), out system); + return system; + } + + protected internal override void RemoveGameSystem(GameSystem system) + { + systemsTable.Remove(system.ID.ToLower()); + } + + public override Race[] GetRaces(GameSystem system) + { + return GetRaces(system.ID); + } + + /// <summary> + /// Gets an array of the races for a game system by ID. + /// </summary> + /// <param name="systemID"> + /// The <see cref="System.String"/> ID of the game system to get races for + /// </param> + /// <returns> + /// An array of <see cref="Race"/>s for the specified game system + /// </returns> + public Race[] GetRaces(string systemID) + { + if (!loaded && !loading) + { + LoadFiles(); + } + + systemID = systemID.ToLower(); + Dictionary<string, Dictionary<string, Race>> system; + racesTable.TryGetValue(systemID, out system); + + if (system == null) + { + return new Race[0]; + } + + int count = 0; + + foreach (Dictionary<string, Race> racesDict in system.Values) + { + count += racesDict.Count; + } + + Race[] races = new Race[count]; + int i = 0; + + foreach (string raceID in system.Keys) + { + foreach (string raceSubId in system[raceID].Keys) + { + races[i++] = GetRace(systemID, raceID, raceSubId); + } + } + + return races; + } + + public override Race GetRace(GameSystem system, string raceID) + { + return GetRace(system.ID, raceID); + } + + /// <summary> + /// Gets a single race for a given game system by ID of the game system and race. + /// </summary> + /// <param name="systemID"> + /// The <see cref="System.String"/> ID of the game system that the race is part of. + /// </param> + /// <param name="raceID"> + /// The <see cref="System.String"/> ID for the race to load. + /// </param> + /// <returns> + /// A <see cref="Race"/> with the specified ID from the game system with the specified ID, or <code>null</code> if there is no race or game system with those IDs. + /// </returns> + public Race GetRace(string systemID, string raceID) + { + return GetRace(systemID, raceID, ""); + } + + public override Race GetRace(GameSystem system, string raceID, string raceSubID) + { + return GetRace(system.ID, raceID, raceSubID); + } + + /// <summary> + /// Gets a single race for a given game system by the game system's ID and the race's ID and sub-race ID. + /// </summary> + /// <param name="systemID"> + /// The <see cref="System.String"/> ID of the game system that the race is part of. + /// </param> + /// <param name="raceID"> + /// The <see cref="System.String"/> ID for the race to load. + /// </param> + /// <param name="raceSubID"> + /// A <see cref="System.String"/> + /// </param> + /// <returns> + /// A <see cref="Race"/> + /// </returns> + public Race GetRace(string systemID, string raceID, string raceSubID) + { + if (!loaded && !loading) + { + LoadFiles(); + } + + Race race = null; + + Dictionary<string, Race> subraces = GetRaceTable(systemID, raceID); + + if (subraces != null) + { + subraces.TryGetValue(raceSubID.ToLower(), out race); + } + + return race; + } + + private Dictionary<string, Race> GetRaceTable(string systemID, string raceID) + { + Dictionary<string, Dictionary<string, Race>> races; + racesTable.TryGetValue(systemID.ToLower(), out races); + Dictionary<string, Race> subraces = null; + + if (races != null) + { + races.TryGetValue(raceID.ToLower(), out subraces); + } + + return subraces; + } + + protected internal override void RemoveRace(Race race) + { + Dictionary<string, Race> subraces = GetRaceTable(race.GameSystem.ID, race.ID); + + if (subraces != null) + { + subraces.Remove(race.SubID.ToLower()); + } + } + + public override string[] GetGameSystemIDs() + { + if (!loaded && !loading) + { + LoadFiles(); + } + + return DictionaryUtils.ToKeyArray(systemsTable); + } + + public override string[] GetSystemRaceIDs(GameSystem system) + { + return GetSystemRaceIDs(system.ID); + } + + /// <summary> + /// Gets the IDs of all of the races of a specified game system. + /// </summary> + /// <param name="systemID"> + /// The <see cref="System.String"/> ID of the game system to get the available races for. + /// </param> + /// <returns> + /// An array of <see cref="System.String"/>s representing the IDs of the races of the specified game system. + /// </returns> + public string[] GetSystemRaceIDs(string systemID) + { + if (!loaded && !loading) + { + LoadFiles(); + } + + Dictionary<string, Dictionary<string, Race>> races = racesTable[systemID.ToLower()]; + + if (races == null) + { + return new string[0]; + } + else + { + string[] keys = new string[races.Keys.Count]; + int i = 0; + + foreach (string key in races.Keys) + { + keys[i++] = key; + } + + return keys; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Delegates.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,23 @@ +// This file (Delegates.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API +{ + public delegate void ObjectChangedDelegate(WarFoundryObject oldValue, WarFoundryObject newValue); + public delegate void ArmyChangedDelegate(Army oldValue, Army newValue); + public delegate void GameSystemChangedDelegate(GameSystem oldValue, GameSystem newValue); + public delegate void ObjectAddDelegate(WarFoundryObject val); + public delegate void ObjectRemoveDelegate(WarFoundryObject val); + public delegate void UnitAddDelegate(Unit val); + public delegate void UnitRemoveDelegate(Unit val); + public delegate void ObjectUpdatedDelegate(WarFoundryObject val, string updatedValName); + public delegate void DoubleValChangedDelegate(WarFoundryObject obj, double oldValue, double newValue); + public delegate void FloatValChangedDelegate(WarFoundryObject obj, float oldValue, float newValue); + public delegate void StringValChangedDelegate(WarFoundryObject obj, string oldValue, string newValue); + public delegate void IntValChangedDelegate(WarFoundryObject obj, int oldValue, int newValue); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Exporters/IWarFoundryExporter.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,26 @@ +// This file (IWarFoundryExporter.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Exporters +{ + /// <summary> + /// An interface to be implemented by classes that export WarFoundry armies to other formats than "saved armies" (e.g. HTML) + /// </summary> + public interface IWarFoundryExporter + { + /// <summary> + /// Exports the army to the specified path + /// </summary> + /// <param name="army"> + /// The <see cref="Army"/> to export + /// </param> + /// <param name="path"> + /// The file path to export to + /// </param> + void ExportArmy(Army army, string path); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Exporters/WarFoundryHtmlExporter.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,389 @@ +// This file (WarFoundryHtmlExporter.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Schema; +using IBBoard.Lang; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Util; + +namespace IBBoard.WarFoundry.API.Exporters +{ + /// <summary> + /// Custom exporter that exports an army as a basic HTML file + /// </summary> + public class WarFoundryHtmlExporter : IWarFoundryExporter + { + private static WarFoundryHtmlExporter exporter; + private delegate string GetStatCellTextDelegate(Stat stat); + + public static WarFoundryHtmlExporter GetDefault() + { + if (exporter == null) + { + exporter = new WarFoundryHtmlExporter(); + } + + return exporter; + } + + private WarFoundryHtmlExporter() + { + //Hide constructor + } + + public void ExportArmy(Army army, string path) + { + XmlDocument doc = new XmlDocument(); + CustomXmlResolver resolver = new CustomXmlResolver(); + Uri localUri = new Uri("file://" + IBBoard.Constants.ExecutablePath + "/schemas/xhtml1-strict.dtd"); + resolver.AddMapping("-//W3C//DTD XHTML 1.0 Strict//EN", localUri); + resolver.AddMapping("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", localUri); + doc.XmlResolver = resolver; + doc.AppendChild(doc.CreateDocumentType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", null)); + XmlElement html = doc.CreateElement("html"); + doc.AppendChild(html); + XmlElement head = doc.CreateElement("head"); + html.AppendChild(head); + XmlElement title = doc.CreateElement("title"); + title.InnerXml = army.Name; + head.AppendChild(title); + XmlElement metaCharset = doc.CreateElement("meta"); + metaCharset.SetAttribute("http-equiv", "Content-Type"); + metaCharset.SetAttribute("content", "text/html;charset=UTF-8"); + head.AppendChild(metaCharset); + XmlElement style = doc.CreateElement("style"); + style.InnerText = "table, th, td { border: 1px solid #000; border-spacing: 0; border-collapse: collapse; margin: 0 }\n" + +"table table { width: 100%; border-width: 0; margin: -2px }\n" + +"table table td { border-width:0 1px }"; + head.AppendChild(style); + XmlElement body = doc.CreateElement("body"); + html.AppendChild(body); + XmlElement header = doc.CreateElement("h1"); + header.InnerText = Translation.GetTranslation("armyHtmlOutputBodyHeader", "{0} - {1}pts", army.Name, army.Points); + body.AppendChild(header); + + foreach (XmlElement table in CreateTables(army, doc)) + { + if (!IsTableOnlyHeader(table)) + { + body.AppendChild(table); + } + } + + File.WriteAllText(path, doc.OuterXml); + } + + private bool IsTableOnlyHeader(XmlElement table) + { + return table.ChildNodes.Count == 1; + } + + private XmlElement[] CreateTables(Army army, XmlDocument doc) + { + Dictionary<string, XmlElement> tables = new Dictionary<string, XmlElement>(); + + foreach (SystemStats statSets in army.GameSystem.SystemStats) + { + tables[statSets.ID] = CreateTable(statSets, doc); + } + + foreach (Unit unit in army.GetUnits()) + { + CreateUnitRow(unit, tables[GetFirstStatType(unit)]); + } + + return DictionaryUtils.ToArray(tables); + } + + private static string GetFirstStatType(Unit unit) + { + string[] unitStatIDs = unit.UnitStatsArrayIDs; + return GetFirstStatType(unitStatIDs); + } + + public static string GetFirstStatType(string[] unitStatIDs) + { + return unitStatIDs[0]; + } + + private XmlElement CreateTable(SystemStats stats, XmlDocument doc) + { + XmlElement table = doc.CreateElement("table"); + XmlElement headerRow = doc.CreateElement("tr"); + table.AppendChild(headerRow); + XmlElement name = doc.CreateElement("th"); + name.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitName", "name"); + headerRow.AppendChild(name); + + XmlElement unitTypeName = doc.CreateElement("th"); + unitTypeName.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitTypeName", "type name"); + headerRow.AppendChild(unitTypeName); + + foreach (StatSlot stat in stats.StatSlots) + { + XmlElement statHeader = doc.CreateElement("th"); + statHeader.InnerText = stat.Name; + headerRow.AppendChild(statHeader); + } + + XmlElement notes = doc.CreateElement("th"); + notes.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitNotes", "name");; + headerRow.AppendChild(notes); + + XmlElement points = doc.CreateElement("th"); + points.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitPoints", "name");; + headerRow.AppendChild(points); + + return table; + } + + private XmlElement CreateUnitRow(Unit unit, XmlElement tableElem) + { + XmlDocument doc = tableElem.OwnerDocument; + XmlElement row = doc.CreateElement("tr"); + tableElem.AppendChild(row); + Stat[][] memberStats = unit.UnitStatsArraysWithName; + string[] statTypeIDs = unit.UnitStatsArrayIDs; + string defaultStatType = GetFirstStatType(statTypeIDs); + int statRowCount = 0; + bool hasOther = false; + + foreach (string statTypeID in statTypeIDs) + { + if (statTypeID.Equals(defaultStatType)) + { + statRowCount++; + } + else if (!hasOther) + { + statRowCount++; + hasOther = true; + } + } + + XmlElement name = doc.CreateElement("td"); + name.InnerText = unit.Name; + SetRowSpan(name, statRowCount); + row.AppendChild(name); + CreateStatsBlock(row, memberStats, statTypeIDs); + + StringBuilder sb = new StringBuilder(); + UnitEquipmentItem[] unitEquipment = unit.GetEquipment(); + + if (unitEquipment.Length > 0) + { + bool addSeparator = false; + + foreach (UnitEquipmentItem equip in unitEquipment) + { + if (!addSeparator) + { + addSeparator = true; + } + else + { + sb.Append(", "); + } + + string amountString; + double amount = UnitEquipmentUtil.GetEquipmentAmount(unit, equip); + + if (UnitEquipmentUtil.GetEquipmentAmountIsRatio(unit, equip)) + { + + if (amount == 100) + { + amountString = GetEquipmentAmountAllTranslation(unit); + } + else + { + int number = UnitEquipmentUtil.GetEquipmentAmountTaken(unit, equip); + amountString = GetEquipmentAmountRatioTranslation(amount, number); + } + } + else + { + if (amount == -1) + { + amountString = GetEquipmentAmountAllTranslation(unit); + } + else + { + amountString = GetEquipmentAmountNumberTranslation((int)amount); + } + } + + sb.Append(Translation.GetTranslation("armyHtmlExportEquipAmountRatio", "{0} for {1}", equip.Name, amountString)); + } + + sb.Append(". "); + } + + ICollection<Ability> abilities = unit.Abilities; + + if (abilities.Count > 0) + { + bool addSeparator = false; + + foreach (Ability ability in abilities) + { + if (!addSeparator) + { + addSeparator = true; + } + else + { + sb.Append(", "); + } + + sb.Append(ability.Name); + } + + sb.Append(". "); + } + + XmlElement notes = doc.CreateElement("td"); + notes.InnerText = sb.ToString(); + SetRowSpan(notes, statRowCount); + row.AppendChild(notes); + + XmlElement points = doc.CreateElement("td"); + points.InnerText = unit.Points.ToString(); + SetRowSpan(points, statRowCount); + row.AppendChild(points); + + return row; + } + + private static void SetRowSpan(XmlElement xmlElement, int statRowCount) + { + if (statRowCount > 1) + { + xmlElement.SetAttribute("rowspan", statRowCount.ToString()); + } + } + + private void CreateStatsBlock(XmlElement unitRow, Stat[][] memberStats, string[] statTypeIDs) + { + XmlDocument doc = unitRow.OwnerDocument; + string defaultStatType = GetFirstStatType(statTypeIDs); + + Stat[] defaultStatLine = memberStats[0]; + int defaultStatLineCount = defaultStatLine.Length; + AddStatCell(defaultStatLine[0].SlotValueString, unitRow); + + for (int i = 1; i < defaultStatLineCount; i++) + { + string statText = GetDefaultStatCellText(defaultStatLine[i]); + AddStatCell(statText, unitRow); + } + + int statCount = statTypeIDs.Length; + + if (statCount > 1) + { + XmlElement unitTable = (XmlElement)unitRow.ParentNode; + Dictionary<string, XmlElement> statParents = CreateStatsParentElements(statTypeIDs, unitTable); + + for (int i = 1; i < statCount; i++) + { + Stat[] statLine = memberStats[i]; + string statTypeID = statTypeIDs[i]; + XmlElement tableElement = DictionaryUtils.GetValue(statParents, statTypeID); + int statLineCount = statLine.Length; + XmlElement statRow = doc.CreateElement("tr"); + tableElement.AppendChild(statRow); + GetStatCellTextDelegate statCellTextDelegate = (statTypeID.Equals(defaultStatType) ? new GetStatCellTextDelegate(GetDefaultStatCellText) : new GetStatCellTextDelegate(GetOtherStatCellText)); + AddStatCell(statLine[0].SlotValueString, statRow); + + for (int j = 1; j < statLineCount; j++) + { + string statText = statCellTextDelegate(statLine[j]); + AddStatCell(statText, statRow); + } + } + + if (statParents.Count > 1) + { + AddOtherUnitStatTables(statParents, unitTable, defaultStatLineCount); + } + } + } + + private static void AddOtherUnitStatTables(Dictionary<string, XmlElement> statParents, XmlElement unitTable, int defaultStatLineCount) + { + XmlDocument doc = unitTable.OwnerDocument; + XmlElement otherStatsRow = doc.CreateElement("tr"); + unitTable.AppendChild(otherStatsRow); + XmlElement otherStatsCell = doc.CreateElement("td"); + otherStatsCell.SetAttribute("colspan", defaultStatLineCount.ToString()); + otherStatsRow.AppendChild(otherStatsCell); + + foreach (XmlElement tableElem in statParents.Values) + { + if (tableElem != unitTable) + { + otherStatsCell.AppendChild(tableElem); + } + } + } + + private Dictionary<string, XmlElement> CreateStatsParentElements(string[] statTypeIDs, XmlElement parentTable) + { + Dictionary<string, XmlElement> statParents = new Dictionary<string, XmlElement>(); + XmlDocument doc = parentTable.OwnerDocument; + string defaultStatTypeID = GetFirstStatType(statTypeIDs); + statParents[defaultStatTypeID] = parentTable; + + foreach (string statTypeID in statTypeIDs) + { + if (!statParents.ContainsKey(statTypeID)) + { + XmlElement tableElement = doc.CreateElement("table"); + statParents[statTypeID] = tableElement; + } + } + + return statParents; + } + + private string GetDefaultStatCellText(Stat stat) + { + return Translation.GetTranslation("armyHtmlExportDefaultStatCellText", "{0}", stat.SlotValueString, stat.ParentSlotName); + } + + private string GetOtherStatCellText(Stat stat) + { + return Translation.GetTranslation("armyHtmlExportOtherStatCellText", "{1}: {0}", stat.SlotValueString, stat.ParentSlotName); + } + + private static void AddStatCell(string statValue, XmlElement row) + { + XmlElement statCell = row.OwnerDocument.CreateElement("td"); + statCell.InnerText = statValue; + row.AppendChild(statCell); + } + + private string GetEquipmentAmountRatioTranslation (double amount, int number) + { + return Translation.GetTranslation ("armyHtmlExportEquipAmountPercentage", "{0}% ({1})", amount, number); + } + + private string GetEquipmentAmountNumberTranslation(int amount) + { + return Translation.GetTranslation("armyHtmlExportEquipAmountNumber", "{0}", amount); + } + + private string GetEquipmentAmountAllTranslation(Unit unit) + { + return Translation.GetTranslation("armyHtmlExportEquipAmountAll", "all ({1})", 100, unit.Size); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Exporters/WarFoundryXMLWithXSLExporter.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,196 @@ +// This file (WarFoundryXmlWithXslExporter.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 Dan Kulinski +// +// 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; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Xsl; +using System.Xml.XPath; +using System.Xml.Schema; +using IBBoard.Lang; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Util; + +namespace IBBoard.WarFoundry.API.Exporters +{ + /// <summary> + /// Custom exporter that exports an army as an XML file with an XSLT applied + /// </summary> + public class WarFoundryXmlWithXslExporter : IWarFoundryExporter + { + private static WarFoundryXmlWithXslExporter exporter; + + // Return the default class associated with this exporter + public static WarFoundryXmlWithXslExporter GetDefault() + { + if (exporter == null) + { + exporter = new WarFoundryXmlWithXslExporter(); + } + + return exporter; + } + + private WarFoundryXmlWithXslExporter() + { + // Hide constructor + } + + // Write to file + public void ExportArmy(Army army, string path) + { + XmlDocument xmlDoc = BuildXml(army); + // Simple XML output settings + XmlWriterSettings xmlSettings = new XmlWriterSettings(); + xmlSettings.Indent = true; + xmlSettings.IndentChars = " "; + + // Write XML to file + using (XmlWriter writer = XmlWriter.Create(path, xmlSettings)) + { + xmlDoc.Save(writer); + writer.Flush(); + writer.Close(); + } + } + + // Write to file with transform + public void ExportArmyWithTransform(Army army, string savePath, string xslPath) + { + XmlDocument xmlDoc = BuildXml(army); + XslCompiledTransform xslTransform = new XslCompiledTransform(); + + xslTransform.Load(xslPath); + XmlWriter writer = XmlWriter.Create(savePath, xslTransform.OutputSettings); + xslTransform.Transform(xmlDoc, writer); + writer.Flush(); + writer.Close(); + } + + // Build the XML document to save or transform + private XmlDocument BuildXml(Army army) + { + XmlDocument armyList = new XmlDocument(); + + // Everything will be a child of the army element + XmlElement root = armyList.CreateElement("army"); + + // Basic army information + XmlElement armyRace = armyList.CreateElement("race"); + armyRace.InnerText = army.Race.Name; + root.AppendChild(armyRace); + + XmlElement armyName = armyList.CreateElement("name"); + armyName.InnerText = army.Name; + root.AppendChild(armyName); + + XmlElement armyAvailablePoints = armyList.CreateElement("pointsAvailable"); + armyAvailablePoints.InnerText = army.MaxPoints.ToString(); + root.AppendChild(armyAvailablePoints); + + XmlElement armyUsedPoints = armyList.CreateElement("pointsUsed"); + armyUsedPoints.InnerText = army.Points.ToString(); + root.AppendChild(armyUsedPoints); + + // Get Categories and interate through each + foreach(ArmyCategory cat in army.Categories) + { + if (cat.GetUnits().Length == 0) + continue; + XmlElement armyCategory = armyList.CreateElement("category"); + armyCategory.SetAttribute("type", cat.Name); + + + // Get units and iterate through each + foreach(Unit uni in cat.GetUnits()) + { + XmlElement armyUnit = armyList.CreateElement("unit"); + armyUnit.SetAttribute("name", uni.UnitType.Name); + + foreach (Stat[] stat in uni.UnitStatsArraysWithName) + { + XmlElement armyStatLine = armyList.CreateElement("statLine"); + foreach (Stat singleStat in stat) + { + XmlElement armyStat = armyList.CreateElement("stat"); + armyStat.SetAttribute("name", singleStat.ParentSlotName); + armyStat.SetAttribute("value", singleStat.SlotValueString); + armyStatLine.AppendChild(armyStat); + } + armyUnit.AppendChild(armyStatLine); + } + armyUnit.SetAttribute("points", uni.Points.ToString()); + armyUnit.SetAttribute("models", uni.Size.ToString()); + + foreach (UnitEquipmentItem equip in uni.GetEquipment()) + { + XmlElement armyEquipmentItem = armyList.CreateElement("equipmentItem"); + armyEquipmentItem.SetAttribute("name", equip.Name); + + int armyEquipAmount = 0; + + if (UnitEquipmentUtil.GetEquipmentAmount(uni, equip) == null) + { + armyEquipAmount = 0; + } + else + { + armyEquipAmount = (int)UnitEquipmentUtil.GetEquipmentAmount(uni, equip); + } + + if (UnitEquipmentUtil.GetEquipmentAmountIsRatio(uni, equip)) + { + float fraction = (float)(armyEquipAmount / 100.0); + armyEquipAmount = (int)(fraction * uni.Size); + } + + armyEquipmentItem.SetAttribute("count", armyEquipAmount.ToString()); + + armyUnit.AppendChild(armyEquipmentItem); + } + + foreach (Ability abil in uni.Abilities) + { + XmlElement armyAbilityItem = armyList.CreateElement("abilityItem"); + + armyAbilityItem.SetAttribute("name", abil.Name); + armyAbilityItem.SetAttribute("description", abil.Description); + + armyUnit.AppendChild(armyAbilityItem); + } + + armyCategory.AppendChild(armyUnit); + } + root.AppendChild(armyCategory); + } + + + + + // Append all Categories to the XML doc + + // Append tree to document + armyList.AppendChild(root); + + return armyList; + } + private string GetEquipmentAmountRatioTranslation(double amount, int number) + { + return Translation.GetTranslation("armyHtmlExportEquipAmountPercentage", "{0}% ({1})", amount, number); + } + + private string GetEquipmentAmountNumberTranslation(int amount) + { + return Translation.GetTranslation("armyHtmlExportEquipAmountNumber", "{0}", amount); + } + + private string GetEquipmentAmountAllTranslation(Unit unit) + { + return Translation.GetTranslation("armyHtmlExportEquipAmountAll", "all ({1})", 100, unit.Size); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/AbstractNativeWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,194 @@ +// This file (AbstractNativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using System.Collections.Generic; +using System.Text; +using IBBoard; +using IBBoard.IO; +using IBBoard.Lang; +using IBBoard.Logging; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Objects; +using ICSharpCode.SharpZipLib.Zip; + +namespace IBBoard.WarFoundry.API.Factories +{ + /// <summary> + /// Base abstract class for all factories that load native WarFoundry data. + /// </summary> + public abstract class AbstractNativeWarFoundryFactory : AbstractWarFoundryFactory<ZipFile>, INativeWarFoundryFactory + { + protected AbstractNativeWarFoundryFactory() + { + //Do nothing - just make the constructor non-public + } + + protected override ZipFile GetFileAsSupportedType (FileInfo file) + { + ZipFile zip = null; + + try + { + zip = new ZipFile(file.FullName); + } + catch(ZipException) + { + //Silently dispose as per spec for the method + } + catch (IOException) + { + //Silently dispose as per spec for the method + } + + return zip; + } + + protected override bool CheckCanHandleFileFormat (ZipFile file) + { + return CheckCanHandleFileAsGameSystem(file) || CheckCanHandleFileAsRace(file) || CheckCanHandleFileAsArmy(file); + } + + protected override bool CheckCanHandleFileAsGameSystem(ZipFile file) + { + return CheckCanFindSystemFileContent(file); + } + + protected abstract bool CheckCanFindSystemFileContent(ZipFile file); + + protected override bool CheckCanHandleFileAsRace(ZipFile file) + { + return CheckCanFindRaceFileContent(file); + } + + protected abstract bool CheckCanFindRaceFileContent(ZipFile file); + + protected override bool CheckCanHandleFileAsArmy(ZipFile file) + { + return CheckCanFindArmyFileContent(file); + } + + protected abstract bool CheckCanFindArmyFileContent(ZipFile file); + + protected override ICollection<IWarFoundryObject> DoCreateObjectsFromFile (ZipFile file) + { + ICollection<IWarFoundryObject> objects = new List<IWarFoundryObject>(); + + try + { + if (CheckCanFindSystemFileContent(file)) + { + foreach (GameSystem system in CreateGameSystemsFromFile(file)) + { + OnGameSystemLoaded(system); + objects.Add(system); + } + } + + if (CheckCanFindRaceFileContent(file)) + { + foreach(Race race in CreateRacesFromFile(file)) + { + OnRaceLoaded(race); + objects.Add(race); + } + } + + if (CheckCanFindArmyFileContent(file)) + { + foreach (Army army in CreateArmiesFromFile(file)) + { + OnArmyLoaded(army); + objects.Add(army); + } + } + } + finally + { + file.Close(); + } + + return objects; + } + + protected ICollection<Army> CreateArmiesFromFile(ZipFile file) + { + ICollection<ZipEntry> dataStreams = GetArmyZipEntries(file); + ICollection<Army> armies = new List<Army>(); + + foreach (ZipEntry entry in dataStreams) + { + using (Stream dataStream = file.GetInputStream(entry)) + { + armies.Add(CreateArmyFromStream(file, dataStream)); + } + } + + return armies; + } + + protected abstract ICollection<ZipEntry> GetArmyZipEntries(ZipFile file); + protected abstract Army CreateArmyFromStream(ZipFile file, Stream dataStream); + + protected ICollection<Race> CreateRacesFromFile(ZipFile file) + { + ICollection<ZipEntry> dataStreams = GetRaceZipEntries(file); + ICollection<Race> races = new List<Race>(); + + foreach (ZipEntry entry in dataStreams) + { + using (Stream dataStream = file.GetInputStream(entry)) + { + races.Add(CreateRaceFromStream(file, dataStream)); + } + } + + return races; + } + + protected abstract ICollection<ZipEntry> GetRaceZipEntries(ZipFile file); + protected abstract Race CreateRaceFromStream(ZipFile file, Stream dataStream); + + protected ICollection<GameSystem> CreateGameSystemsFromFile(ZipFile file) + { + ICollection<ZipEntry> dataStreams = GetGameSystemZipEntries(file); + ICollection<GameSystem> systems = new List<GameSystem>(); + + foreach (ZipEntry entry in dataStreams) + { + using (Stream dataStream = file.GetInputStream(entry)) + { + systems.Add(CreateGameSystemFromStream(file, dataStream)); + } + } + + return systems; + } + + protected abstract ICollection<ZipEntry> GetGameSystemZipEntries(ZipFile file); + protected abstract GameSystem CreateGameSystemFromStream(ZipFile file, Stream dataStream); + + public override bool Equals (object o) + { + if (o == this) + { + return true; + } + else if (o == null || !(this.GetType().Equals(o.GetType()))) + { + return false; + } + + return true; + } + + public override int GetHashCode () + { + return GetType().FullName.GetHashCode(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/AbstractNonNativeFileExtensionWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,85 @@ +// This file (AbstractNonNativeFileExtensionWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; +using System.IO; +using IBBoard.Logging; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories +{ + public abstract class AbstractNonNativeFileExtensionWarFoundryFactory : AbstractNonNativeWarFoundryFactory<FileInfo> + { + protected abstract string ArmyFileExtension { get; } + protected abstract string RaceFileExtension { get; } + protected abstract string GameSystemFileExtension { get; } + + protected override bool CheckCanHandleFileFormat (FileInfo file) + { + return CheckCanHandleFileAsArmy(file) || CheckCanHandleFileAsRace(file) || CheckCanHandleFileAsGameSystem(file); + } + + protected override bool CheckCanHandleFileAsArmy(FileInfo file) + { + return ArmyFileExtension!=null && file.Name.ToLower().EndsWith(ArmyFileExtension); + } + + protected override bool CheckCanHandleFileAsRace(FileInfo file) + { + return RaceFileExtension!=null && file.Name.ToLower().EndsWith(RaceFileExtension); + } + + protected override bool CheckCanHandleFileAsGameSystem(FileInfo file) + { + return GameSystemFileExtension!=null && file.Name.ToLower().EndsWith(GameSystemFileExtension); + } + + protected override FileInfo GetFileAsSupportedType (FileInfo file) + { + return file; + } + + protected abstract Army CreateArmyFromFile(FileInfo file); + protected abstract Race CreateRaceFromFile(FileInfo file); + protected abstract GameSystem CreateGameSystemFromFile(FileInfo file); + + protected override ICollection<IWarFoundryObject> DoCreateObjectsFromFile (FileInfo file) + { + IWarFoundryObject obj = null; + + if (CheckCanHandleFileAsGameSystem(file)) + { + GameSystem gameSystem = CreateGameSystemFromFile (file); + OnGameSystemLoaded(gameSystem); + obj = gameSystem; + } + else if (CheckCanHandleFileAsRace(file)) + { + Race race = CreateRaceFromFile (file); + OnRaceLoaded(race); + obj = race; + } + else if (CheckCanHandleFileAsArmy(file)) + { + Army army = CreateArmyFromFile (file); + OnArmyLoaded(army); + obj = army; + } + else + { + LogNotifier.Warn(GetType(), "Failed trying to create from "+file.FullName+" - not a Race, Army or GameSystem"); + } + + ICollection<IWarFoundryObject> objects = new List<IWarFoundryObject>(); + + if (obj != null) + { + objects.Add(obj); + } + + return objects; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/AbstractNonNativeWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,15 @@ +// This file (AbstractNonNativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories +{ + public abstract class AbstractNonNativeWarFoundryFactory<FILE_TYPE> : AbstractWarFoundryFactory<FILE_TYPE>, INonNativeWarFoundryFactory + { + public abstract string NonNativeDataType { get; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/AbstractWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,181 @@ +// This file (AbstractWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories +{ + public abstract class AbstractWarFoundryFactory<FILE_TYPE> : IWarFoundryFactory + { + public event SingleArgMethodInvoker<GameSystem> GameSystemLoaded; + + public event SingleArgMethodInvoker<Race> RaceLoaded; + + public event SingleArgMethodInvoker<Army> ArmyLoaded; + + public virtual void CompleteLoading(IWarFoundryStagedLoadObject obj) + { + //Pretend we've fully loaded, as this will probably be standard for non-native factories and some native factories + obj.SetAsFullyLoaded(); + } + + public bool CanHandleFileFormat (FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + bool canHandle = typedFile != null && CheckCanHandleFileFormat(typedFile); + + if (typedFile != null) + { + CleanUpFileAsSupportedType(typedFile); + } + + return canHandle; + } + + public bool CanHandleFileAsRace(FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + bool canHandle = typedFile != null && CheckCanHandleFileAsRace(typedFile); + + if (typedFile != null) + { + CleanUpFileAsSupportedType(typedFile); + } + + return canHandle; + } + + public bool CanHandleFileAsGameSystem(FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + bool canHandle = typedFile != null && CheckCanHandleFileAsGameSystem(typedFile); + + if (typedFile != null) + { + CleanUpFileAsSupportedType(typedFile); + } + + return canHandle; + } + + public bool CanHandleFileAsArmy(FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + bool canHandle = typedFile != null && CheckCanHandleFileAsArmy(typedFile); + + if (typedFile != null) + { + CleanUpFileAsSupportedType(typedFile); + } + + return canHandle; + } + + protected virtual void CleanUpFileAsSupportedType(FILE_TYPE typedFile) + { + //Do nothing by default + } + + /// <summary> + /// Converts the <see cref="FileInfo"/> object in to the appropriate type for this class so that it can perform its checks. If no conversion is required (the test can be performed on a <see cref="FileInfo"/> object) the object should be returned with no modification. + /// If the file is not of supported type the <code>null</code> should be returned. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> to get the supported source object from. + /// </param> + /// <returns> + /// An object of type <see cref="FILE_TYPE"/> that has been converted from the input <see cref="FileInfo"/> object, or <code>null</code> if the conversion cannot be made. + /// </returns> + protected abstract FILE_TYPE GetFileAsSupportedType(FileInfo file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileFormat(FILE_TYPE file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type as a Race object. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file as a Race, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileAsRace(FILE_TYPE file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type as a GameSystem object. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file as a GameSystem, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileAsGameSystem(FILE_TYPE file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type as an Army object. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file as a Army, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileAsArmy(FILE_TYPE file); + + + public ICollection<IWarFoundryObject> CreateObjectsFromFile(FileInfo file) + { + return DoCreateObjectsFromFile(GetFileAsSupportedType(file)); + } + + /// <summary> + /// Reads the data from the supplied converted <see cref="FILE_TYPE"/> object and returns it as a collection of loadable objects. + /// In addition, the method fires the appropriate XxxLoaded event for each object created for asynchronous use. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> for the file to load data from + /// </param> + /// <returns> + /// A <see cref="ICollection`1"/> of <see cref="IWarFoundryObject"/>s that were loaded from the file object + /// </returns> + protected abstract ICollection<IWarFoundryObject> DoCreateObjectsFromFile(FILE_TYPE file); + + protected void OnGameSystemLoaded(GameSystem system) + { + if (GameSystemLoaded != null) + { + GameSystemLoaded(system); + } + } + + protected void OnRaceLoaded(Race race) + { + if (RaceLoaded != null) + { + RaceLoaded(race); + } + } + + protected void OnArmyLoaded(Army army) + { + if (ArmyLoaded != null) + { + ArmyLoaded(army); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/DummyWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,59 @@ +// This file (DummyWarFoundryFactory.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 IBBoard.WarFoundry.API.Factories; +using IBBoard.WarFoundry.API.Objects; +using System.IO; +using System.Collections.Generic; + +namespace IBBoard.WarFoundry.API.Factories +{ + ///<summary> + ///A dummy factory for use with <see cref="WarFoundryStagedLoadingObject"/>s that implements the bare minimum of the methods but won't load anything + ///</summary> + public class DummyWarFoundryFactory : IWarFoundryFactory + { + public event SingleArgMethodInvoker<GameSystem> GameSystemLoaded; + + public event SingleArgMethodInvoker<Race> RaceLoaded; + + public event SingleArgMethodInvoker<Army> ArmyLoaded; + + public DummyWarFoundryFactory() + { + //Public constructor + } + + public void CompleteLoading(IWarFoundryStagedLoadObject obj) + { + obj.SetAsFullyLoaded(); + } + + public bool CanHandleFileFormat(FileInfo file) + { + return false; + } + + public bool CanHandleFileAsRace(FileInfo file) + { + return false; + } + + public bool CanHandleFileAsGameSystem(FileInfo file) + { + return false; + } + + public bool CanHandleFileAsArmy(FileInfo file) + { + return false; + } + + public ICollection<IWarFoundryObject> CreateObjectsFromFile(FileInfo file) + { + return new List<IWarFoundryObject>(); + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/INativeWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,13 @@ +// This file (INativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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.Factories +{ + public interface INativeWarFoundryFactory : IWarFoundryFactory + { + //Marker interface + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/INonNativeWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,13 @@ +// This file (INonNativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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.Factories +{ + public interface INonNativeWarFoundryFactory : IWarFoundryFactory + { + string NonNativeDataType { get; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/IRaceFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,20 @@ +// This file (IRaceFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories +{ + /// <summary> + /// Interface for factory that creates races. SOURCE_FILE_TYPE is the class of the source 'file' or object. ENTRY_TYPE is the class of the object that data is loaded from. + /// </summary> + public interface IRaceFactory<SOURCE_FILE_TYPE, ENTRY_TYPE> + { + Race CreateRace(ENTRY_TYPE entry); + void CompleteLoading(Race race); + UnitType GetUnitType(string id, Race parentRace); + UnitType GetUnitType(string id, Race parentRace, SOURCE_FILE_TYPE src); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/IWarFoundryFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,86 @@ +// This file (IWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories +{ + public interface IWarFoundryFactory + { + event SingleArgMethodInvoker<GameSystem> GameSystemLoaded; + + event SingleArgMethodInvoker<Race> RaceLoaded; + + event SingleArgMethodInvoker<Army> ArmyLoaded; + + /// <summary> + /// Completes the loading of an object if it is loaded in stages. + /// </summary> + /// <param name="obj"> + /// The <see cref="IWarFoundryStagedLoadObject"/> that should be fully loaded. + /// </param> + void CompleteLoading(IWarFoundryStagedLoadObject obj); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory, else returns <code>false</code> + /// </returns> + bool CanHandleFileFormat(FileInfo file); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file as a Race. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for as a file containing Race information. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory as a Race, else returns <code>false</code> + /// </returns> + bool CanHandleFileAsRace(FileInfo file); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file as a GameSystem. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for as a file containing GameSystem information. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory as a GameSystem, else returns <code>false</code> + /// </returns> + bool CanHandleFileAsGameSystem(FileInfo file); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file as a Army. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for as a file containing Army information. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory as a Army, else returns <code>false</code> + /// </returns> + bool CanHandleFileAsArmy(FileInfo file); + + /// <summary> + /// Reads the data from the supplied file and returns it as a collection of loadable objects. In addition, it fires the appropriate XxxLoaded event + /// for each object loaded for asynchronous use. + /// + /// May throw a <see cref=" IBBoard.IO.InvalidFileException"/> if the file is supported by the Factory but the content is invalid. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to load data from + /// </param> + /// <returns> + /// A <see cref="ICollection`1"/> of <see cref="IWarFoundryObject"/>s that were loaded from the file + /// </returns> + ICollection<IWarFoundryObject> CreateObjectsFromFile(FileInfo file); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/RequiredDataMissingException.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,19 @@ +// This file (RequiredDataMissingException.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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.Factories +{ + /// <summary> + /// An exception that is thrown when a file cannot be loaded because one of the data files that it depends on has + /// not been loaded. Normally occurs when loading an army file without having the correct game system or race. + /// </summary> + public class RequiredDataMissingException : Exception + { + public RequiredDataMissingException(String file, String missingObjectType, String requiredValue) : base(String.Format("Could not find data for {1} object with ID {2} required by {0}", file, missingObjectType, requiredValue)) + { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Requirement/IRequirementFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,16 @@ +// This file (IRequirementFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Objects.Requirement; + +namespace IBBoard.WarFoundry.API.Factories.Requirement +{ + public interface IRequirementFactory + { + IRequirement CreateRequirement<SOURCE_FILE_TYPE, ENTRY_TYPE>(UnitType type, string data, IRaceFactory<SOURCE_FILE_TYPE, ENTRY_TYPE> raceFactory); + string AppliesToID { get; } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Requirement/InvalidRequirementException.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,15 @@ +// This file (InvalidRequirementException.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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.Factories.Requirement +{ + public class InvalidRequirementException : Exception + { + public InvalidRequirementException(string message) : base(message) + { + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Requirement/UnitRequiresAtLeastNUnitsRequirementFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,65 @@ +// This file (UnitRequiresAtLeastNUnitsRequirementFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Objects.Requirement; + +namespace IBBoard.WarFoundry.API.Factories.Requirement +{ + public class UnitRequiresAtLeastNUnitsRequirementFactory : IRequirementFactory + { + public UnitRequiresAtLeastNUnitsRequirementFactory() + { + //Do nothing special + } + + public string AppliesToID { + get { + return "RequiresAtLeastNUnits"; + } + } + + public IRequirement CreateRequirement<SOURCE_FILE_TYPE, ENTRY_TYPE>(UnitType type, string data, IRaceFactory<SOURCE_FILE_TYPE, ENTRY_TYPE> raceFactory) + { + UnitRequiresAtLeastNUnitsRequirement req = new UnitRequiresAtLeastNUnitsRequirement(type); + Race race = type.Race; + AddRequirements(req, race, data, raceFactory); + return req; + } + + private void AddRequirements<SOURCE_FILE_TYPE, ENTRY_TYPE>(UnitRequiresAtLeastNUnitsRequirement req, Race race, string data, IRaceFactory<SOURCE_FILE_TYPE, ENTRY_TYPE> raceFactory) + { + foreach (string requirement in data.Split('|')) + { + string[] requirementParts = requirement.Split(':'); + string unitID = requirementParts[0]; + UnitType unitType = raceFactory.GetUnitType(unitID, race); + + if (unitType == null) + { + throw new InvalidRequirementException(String.Format("Invalid unit type '{0}' for 'Requires at least N units' requirement", unitID)); + } + + if (requirementParts.Length == 2) + { + string amount = requirementParts[1]; + + try + { + req.AddUnitTypeRequirement(unitType, Int32.Parse(amount)); + } + catch (FormatException) + { + throw new InvalidRequirementException(String.Format("Invalid amount '{0}' for unit type '{1}' for 'Requires at least N units' requirement", amount, unitID)); + } + } + else + { + req.AddUnitTypeRequirement(unitType); + } + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/CategoryLoader.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,26 @@ +// This file (CategoryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.Xml; +using System.Xml; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + public class CategoryLoader + { + public static Category CreateFromElement(XmlElement elem) + { + string id = elem.GetAttribute("id"); + string name = elem.GetAttribute("name"); + Category cat = new Category(id, name); + cat.MaximumPercentage = XmlTools.GetIntValueFromAttribute(elem, "maxPercentage"); + cat.MinimumPercentage = XmlTools.GetIntValueFromAttribute(elem, "minPercentage"); + cat.MaximumPoints = XmlTools.GetIntValueFromAttribute(elem, "maxPoints"); + cat.MinimumPoints = XmlTools.GetIntValueFromAttribute(elem, "minPoints"); + return cat; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlArmyFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,23 @@ +// This file (WarFoundryXmlArmyFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Xml; +using IBBoard.Xml; +using ICSharpCode.SharpZipLib.Zip; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// A sub-factory for loading WarFoundry Army XML files + /// </summary> + public class WarFoundryXmlArmyFactory + { + public Army CreateArmyFromElement(ZipFile file, XmlElement elem) + { + return new WarFoundryXmlArmyParser(file, elem).GetArmy(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlArmyParser.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,131 @@ +// This file (WarFoundryXmlArmyParser.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using System.Xml; +using IBBoard.IO; +using IBBoard.Xml; +using ICSharpCode.SharpZipLib.Zip; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + public class WarFoundryXmlArmyParser + { + private ZipFile file; + private XmlElement elem; + private Army army; + private Dictionary<String, Unit> units; + + public WarFoundryXmlArmyParser(ZipFile file, XmlElement elem) + { + this.file = file; + this.elem = elem; + } + + public Army GetArmy() + { + if (army == null) + { + ParseArmy(); + } + + return army; + } + + private void ParseArmy() + { + string name = elem.GetAttribute("name"); + string systemID = elem.GetAttribute("system"); + GameSystem system = WarFoundryLoader.GetDefault().GetGameSystem(systemID); + + if (system == null) + { + throw new RequiredDataMissingException(file.Name, "Game System", systemID); + } + + string raceID = elem.GetAttribute("race"); + Race race = WarFoundryLoader.GetDefault().GetRace(system, raceID); + + if (race == null) + { + throw new RequiredDataMissingException(file.Name, "Race", raceID); + } + + int points = XmlTools.GetIntValueFromAttribute(elem, "maxPoints"); + army = new Army(race, name, points, file); + LoadUnits(); + } + + private void LoadUnits() + { + units = new Dictionary<string, Unit>(); + + foreach (XmlElement unitElem in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/army:army/army:units/army:unit")) + { + string id = unitElem.GetAttribute("id"); + + if (!units.ContainsKey(id)) + { + string unitTypeId = unitElem.GetAttribute("unitType"); + UnitType unitType = army.Race.GetUnitType(unitTypeId); + + if (unitType == null) + { + throw new RequiredDataMissingException(file.Name, "Unit Type", unitTypeId); + } + + string name = unitElem.GetAttribute("unitName"); + int size = XmlTools.GetIntValueFromAttribute(unitElem, "size"); + + string catID = unitElem.GetAttribute("category"); + Category cat = army.Race.GetCategory(catID); + + if (cat == null) + { + cat = unitType.MainCategory; + } + + Unit unit = new Unit(id, name, size, unitType, army.GetCategory(cat)); + army.AddUnit(unit, cat); + units.Add(id, unit); + + LoadUnitEquipment(unitElem, unit); + } + else + { + throw new InvalidFileException("Duplicate unit ID found in army file: "+id); + } + } + } + + private void LoadUnitEquipment(XmlElement unitElem, Unit unit) + { + foreach (XmlElement elem in WarFoundryXmlFactoryUtils.SelectNodes(unitElem, "army:equipment/army:equipItem")) + { + string equipID = elem.GetAttribute("id"); + UnitEquipmentItem item = unit.UnitType.GetEquipmentItem(equipID); + + if (item == null) + { + throw new RequiredDataMissingException(file.Name, "Equipment Item", equipID); + } + + double amount = XmlTools.GetDoubleValueFromAttribute(elem, "amount"); + string equipTypeString = elem.GetAttribute("amountType"); + + if (equipTypeString == "ratio") + { + unit.SetEquipmentRatio(item, amount); + } + else + { + //amount should be a whole number, so do type-cast rounding + unit.SetEquipmentAmount(item, (int) amount); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlElementName.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,67 @@ +// This file (WarFoundryXmlElementName.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using IBBoard.Xml; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// An enumeration class for valid WarFoundry XML elements, designed to imitate Java's extensible complex object enumerations. + /// </summary> + public class WarFoundryXmlElementName : IXmlElementName, IExtendedEnum<string> + { + public static WarFoundryXmlElementName SYSTEM_ELEMENT = new WarFoundryXmlElementName("SYSTEM_ELEMENT", "system"); + public static WarFoundryXmlElementName ARMY_ELEMENT = new WarFoundryXmlElementName("ARMY_ELEMENT", "army"); + public static WarFoundryXmlElementName RACE_ELEMENT = new WarFoundryXmlElementName("RACE_ELEMENT", "race"); + public static WarFoundryXmlElementName ARMY_DEFAULTNAME_ELEMENT = new WarFoundryXmlElementName("ARMY_DEFAULTNAME_ELEMENT", "defaultName"); + public static WarFoundryXmlElementName CATEGORIES_ELEMENT = new WarFoundryXmlElementName("CATEGORIES_ELEMENT", "categories"); + public static WarFoundryXmlElementName CATEGORY_ELEMENT = new WarFoundryXmlElementName("CATEGORY_ELEMENT", "cat"); + public static WarFoundryXmlElementName UNITTYPES_ELEMENT = new WarFoundryXmlElementName("UNITTYPES_ELEMENT", "units"); + public static WarFoundryXmlElementName UNITTYPE_ELEMENT = new WarFoundryXmlElementName("UNITTYPE_ELEMENT", "unit"); + public static WarFoundryXmlElementName RACE_EQUIPMENT_ITEMS_ELEMENT = new WarFoundryXmlElementName("RACE_EQUIPMENT_ITEMS_ELEMENT", "equipment"); + public static WarFoundryXmlElementName RACE_EQUIPMENT_ITEM_ELEMENT = new WarFoundryXmlElementName("RACE_EQUIPMENT_ITEMS_ELEMENT", "equipmentItem"); + + private static ICollection<WarFoundryXmlElementName> enumValues; + private string name; + private string val; + + private WarFoundryXmlElementName(string elemName, string elemVal) + { + name = elemName; + val = elemVal; + } + + public string Name + { + get { + return name; + } + } + + public string Value + { + get { + return val; + } + } + + /// <summary> + /// Gets an ICollection of the values so that they can be looped over like a standard enumeration. + /// </summary> + /// <returns> + /// A <see cref="ICollection`1"/> of all of the static 'enumeration' values of the class. + /// </returns> + public static ICollection<WarFoundryXmlElementName> GetEnumValues() + { + if (enumValues == null) + { + enumValues = new WarFoundryXmlElementName[]{SYSTEM_ELEMENT, ARMY_ELEMENT, RACE_ELEMENT, CATEGORIES_ELEMENT, CATEGORY_ELEMENT, UNITTYPES_ELEMENT, UNITTYPE_ELEMENT}; + } + + return enumValues; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,190 @@ +// This file (WarFoundryXmlFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using System.Xml.XPath; +using System.Collections.Generic; +using System.Text; +using IBBoard; +using IBBoard.IO; +using IBBoard.Lang; +using IBBoard.Logging; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Objects; +using ICSharpCode.SharpZipLib.Zip; +using System.Text.RegularExpressions; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// The WarFoundryXmlFactory loads WarFoundry classes from the native "XML in a zip" file format. Files are validated using the schema for the file type, so structurally invalid files should be identified at initial load. + /// </summary> + public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory + { + private static WarFoundryXmlFactory factory; + private WarFoundryXmlGameSystemFactory gameSystemFactory; + private WarFoundryXmlRaceFactory raceFactory; + private WarFoundryXmlArmyFactory armyFactory; + + public static WarFoundryXmlFactory GetFactory() + { + if (factory == null) + { + factory = new WarFoundryXmlFactory(); + } + + return factory; + } + + private WarFoundryXmlFactory() : base() + { + gameSystemFactory = new WarFoundryXmlGameSystemFactory(this); + raceFactory = new WarFoundryXmlRaceFactory(this); + armyFactory = new WarFoundryXmlArmyFactory(); + } + + public WarFoundryXmlGameSystemFactory GetSystemFactory() + { + return gameSystemFactory; + } + + public WarFoundryXmlRaceFactory GetRaceFactory() + { + return raceFactory; + } + + public WarFoundryXmlArmyFactory GetArmyFactory() + { + return armyFactory; + } + + protected override bool CheckCanFindArmyFileContent(ZipFile file) + { + return FindEntries(file, "*.armyx").Count > 0; + } + + protected override bool CheckCanFindSystemFileContent(ZipFile file) + { + return FindEntries(file, "*.systemx").Count > 0; + } + + protected override bool CheckCanFindRaceFileContent(ZipFile file) + { + return FindEntries(file, "*.racex").Count > 0; + } + + protected override ICollection<ZipEntry> GetArmyZipEntries(ZipFile file) + { + return FindEntries(file, "*.armyx"); + } + + private ICollection<ZipEntry> FindEntries(ZipFile file, string wildcardPattern) + { + Regex re = new Regex("^" + Regex.Escape(wildcardPattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$", RegexOptions.IgnoreCase | RegexOptions.Singleline); + ICollection<ZipEntry> entries = new List<ZipEntry>(); + + foreach (ZipEntry entry in file) + { + if (re.IsMatch(entry.Name)) + { + entries.Add(entry); + } + } + + return entries; + } + + protected override Army CreateArmyFromStream (ZipFile file, Stream dataStream) + { + XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.ARMY_ELEMENT); + return armyFactory.CreateArmyFromElement(file, elem); + } + + private XmlElement GetRootElementFromStream(Stream stream, WarFoundryXmlElementName elementName) + { + XmlDocument doc = WarFoundryXmlFactoryUtils.CreateXmlDocumentFromStream(stream); + + XmlElement elem = (XmlElement)doc.LastChild; + + if (!elem.LocalName.Equals(elementName.Value)) + { + throw new InvalidFileException(String.Format("Root element of XML was not valid. Expected {0} but got {1}", elementName.Value, elem.Name)); + } + + return elem; + } + + protected override ICollection<ZipEntry> GetGameSystemZipEntries(ZipFile file) + { + return FindEntries(file, "*.systemx"); + } + + protected override GameSystem CreateGameSystemFromStream (ZipFile file, Stream dataStream) + { + XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.SYSTEM_ELEMENT); + LogNotifier.Debug(GetType(), "Create GameSystem"); + return gameSystemFactory.CreateSystemFromElement(file, elem); + } + + protected override ICollection<ZipEntry> GetRaceZipEntries(ZipFile file) + { + return FindEntries(file, "*.racex"); + } + + protected override Race CreateRaceFromStream (ZipFile file, Stream dataStream) + { + XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.RACE_ELEMENT); + LogNotifier.Debug(GetType(), "Create Race"); + return raceFactory.CreateRace(elem); + } + + protected override void CleanUpFileAsSupportedType(ZipFile typedFile) + { + typedFile.Close(); + } + + public override void CompleteLoading(IWarFoundryStagedLoadObject obj) + { + LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); + + if (obj is GameSystem) + { + CompleteLoadingGameSystem((GameSystem) obj); + } + else if (obj is Race) + { + CompleteLoadingRace((Race) obj); + } + } + + private void CompleteLoadingRace(Race race) + { + try + { + raceFactory.CompleteLoading(race); + } + catch (InvalidFileException ex) + { + WarFoundryLoader.GetDefault().RemoveRace(race); + throw; + } + } + + private void CompleteLoadingGameSystem(GameSystem system) + { + try + { + gameSystemFactory.CompleteLoading(system); + } + catch (InvalidFileException ex) + { + WarFoundryLoader.GetDefault().RemoveGameSystem(system); + throw; + } + } + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlFactoryUtils.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,149 @@ +// This file (WarFoundryXmlFactoryUtils.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.IO; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// A collection of useful utility methods for loading WarFoundry data from XML files + /// </summary> + public class WarFoundryXmlFactoryUtils + { + public static readonly string NS_BASE = "http://ibboard.co.uk/warfoundry/"; + private static XmlReaderSettings settings; + private static XmlNamespaceManager nsManager; + + public static XmlNodeList SelectNodes(XmlNode element, string xpathQuery) + { + return element.SelectNodes(xpathQuery, GetNamespaceManager()); + } + + public static XmlNode SelectSingleNode(XmlNode element, string xpathQuery) + { + return element.SelectSingleNode(xpathQuery, GetNamespaceManager()); + } + + public static XmlElement SelectSingleElement(XmlNode element, string xpathQuery) + { + XmlNode node = SelectSingleNode(element, xpathQuery); + return (node is XmlElement) ? (XmlElement) node : null; + } + + public static XmlNamespaceManager GetNamespaceManager() + { + if (nsManager == null) + { + nsManager = new XmlNamespaceManager(new NameTable()); + nsManager.AddNamespace("core", NS_BASE + "core"); + nsManager.AddNamespace("cat", NS_BASE + "cats"); + nsManager.AddNamespace("race", NS_BASE + "race"); + nsManager.AddNamespace("system", NS_BASE + "system"); + nsManager.AddNamespace("army", NS_BASE + "army"); + } + + return nsManager; + } + + /// <summary> + /// Lazy-getter for XML reader settings. May throw a <see cref="InvalidDataException"/> if there is a problem with the translation schema. + /// </summary> + /// <returns> + /// A <see cref="XmlReaderSettings"/> with the default values for validating the translation document against the translation schema + /// </returns> + public static XmlReaderSettings GetReaderSettings() + { + if (settings == null) + { + settings = new XmlReaderSettings(); + settings.ValidationType = ValidationType.Schema; + //settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings; + settings.ProhibitDtd = true; + settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); + XmlSchemaSet cache = new XmlSchemaSet(); + string path = Path.Combine(IBBoard.Constants.ExecutablePath, "schemas"); + AddSchemaToCache(cache, NS_BASE + "core", Path.Combine(path, "warfoundry-core.xsd")); + AddSchemaToCache(cache, NS_BASE + "cats", Path.Combine(path, "warfoundry-cats.xsd")); + AddSchemaToCache(cache, NS_BASE + "race", Path.Combine(path, "race.xsd")); + AddSchemaToCache(cache, NS_BASE + "system", Path.Combine(path, "system.xsd")); + AddSchemaToCache(cache, NS_BASE + "army", Path.Combine(path, "army.xsd")); + settings.Schemas.Add(cache); + settings.Schemas.CompilationSettings.EnableUpaCheck = false; + } + + return settings; + } + + private static void ValidationEventMethod(object sender, ValidationEventArgs e) + { + if (e.Severity == XmlSeverityType.Error) + { + throw new InvalidFileException("Problem validating against schema for WarFoundry data: " + e.Message, e.Exception); + } + else + { + //TODO: Fire some kind of warning event + } + } + + private static void AddSchemaToCache(XmlSchemaSet cache, string xmlNamespace, string schemaLocation) + { + try + { + cache.Add(xmlNamespace, schemaLocation); + } + catch (IOException ex) + { + //TODO: Warn on schema failure + } + catch (XmlSchemaException ex) + { + //TODO: Warn on schema failure + } + catch (XmlException ex) + { + //TODO: Warn on schema failure + } + } + + public static XmlDocument CreateXmlDocumentFromStream(Stream stream) + { + XmlDocument doc = new XmlDocument(); + XmlReader reader = XmlReader.Create(stream, GetReaderSettings()); + + try + { + doc.Load(reader); + } + //Don't catch XMLSchemaExceptions - let them get thrown out + finally + { + reader.Close(); + } + + return doc; + } + + public static bool CanCompleteLoading(IWarFoundryStagedLoadObject obj) + { + bool canLoad = true; + + if (obj.IsFullyLoaded) + { + canLoad = false; + } + else if (obj.IsLoading) + { + canLoad = false; + } + + return canLoad; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlGameSystemFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,104 @@ +// This file (WarFoundryXmlGameSystemFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using ICSharpCode.SharpZipLib.Zip; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// A sub-factory specifically for loading GameSystems from WarFoundry XML files + /// </summary> + public class WarFoundryXmlGameSystemFactory + { + private Dictionary<GameSystem, XmlDocument> extraData = new Dictionary<GameSystem, XmlDocument>(); + private WarFoundryXmlFactory mainFactory; + + public WarFoundryXmlGameSystemFactory(WarFoundryXmlFactory factory) + { + this.mainFactory = factory; + } + + private void StoreExtraData(GameSystem wfObject, XmlElement elem) + { + extraData[wfObject] = elem.OwnerDocument; + } + + private XmlDocument GetExtraData(GameSystem obj) + { + XmlDocument extra = null; + extraData.TryGetValue(obj, out extra); + return extra; + } + + public GameSystem CreateSystemFromElement(ZipFile file, XmlElement elem) + { + string id = elem.GetAttribute("id"); + string name = elem.GetAttribute("name"); + GameSystem system = new GameSystem(id, name, mainFactory); + system.SystemArmyDefaultSize = XmlTools.GetIntValueFromAttribute (elem, "defaultArmySize"); + system.SystemPtsAbbrevSingle = elem.GetAttribute ("defaultPtsAbbreviationSingular"); + system.SystemPtsAbbrevPlural = elem.GetAttribute ("defaultPtsAbbreviationPlural"); + system.SystemPtsNameSingle = elem.GetAttribute ("defaultPtsNameSingular"); + system.SystemPtsNamePlural = elem.GetAttribute ("defaultPtsNamePlural"); + StoreExtraData(system, elem); + return system; + } + + public void CompleteLoading(GameSystem system) + { + if (!WarFoundryXmlFactoryUtils.CanCompleteLoading(system)) + { + return; + } + + system.SetAsLoading(); + XmlDocument extraData = GetExtraData(system); + LoadCategoriesForSystem(system, extraData); + XmlElement statsElem = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "/system:system/system:sysStatsList"); + string defaultStatsID = statsElem.GetAttribute("defaultStats"); + LoadSystemStatsForSystem(system, extraData); + system.StandardSystemStatsID = defaultStatsID; + XmlElement systemElement = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "/system:system"); + system.WarnOnError = XmlTools.GetBoolValueFromAttribute(systemElement, "warn"); + system.AllowAllies = XmlTools.GetBoolValueFromAttribute(systemElement, "allowAllies"); + system.SetAsFullyLoaded(); + } + + + private void LoadCategoriesForSystem(GameSystem system, XmlNode elem) + { + foreach (XmlElement cat in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/system:system/system:categories/cat:cat")) + { + system.AddCategory(CategoryLoader.CreateFromElement(cat)); + } + } + + private void LoadSystemStatsForSystem(GameSystem system, XmlNode elem) + { + foreach (XmlElement stats in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/system:system/system:sysStatsList/system:sysStats")) + { + SystemStats sysStats = CreateSystemStatsFromElement(stats); + system.AddSystemStats(sysStats); + } + } + + private SystemStats CreateSystemStatsFromElement(XmlElement elem) + { + SystemStats sysStats = new SystemStats(elem.GetAttribute("id")); + + foreach (XmlElement slot in WarFoundryXmlFactoryUtils.SelectNodes(elem, "system:sysStat")) + { + sysStats.AddStatSlot(slot.GetAttribute("name")); + } + + return sysStats; + } + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlLimitParser.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,91 @@ +// This file (WarFoundryXmlLimitParser.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.Collections.Generic; +using System.Xml; +using IBBoard.Limits; +using IBBoard.Xml; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + public class WarFoundryXmlLimitParser + { + public ILimit GetMinLimit(XmlElement elem) + { + XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:minLimit/*[1]"); + return GetLimitFromElement(limitElem); + } + + public ILimit GetMaxLimit(XmlElement equipSlot) + { + XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]"); + return GetLimitFromElement(limitElem); + } + + public ILimit GetLimitFromElement(XmlElement limitElem) + { + ILimit limit = null; + + if (limitElem != null) + { + switch (limitElem.LocalName) + { + case "percentageLimit": + double limitPercent = XmlTools.GetDoubleValueFromAttribute(limitElem, "limit"); + bool roundUp = limitElem.GetAttribute("round").Equals("up"); + limit = new SimpleRoundedPercentageLimit(limitPercent, roundUp); + break; + case "sizeConstrainedLimit": + limit = new NumericSizeConstrainedLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); + break; + case "absoluteLimit": + limit = new AbsoluteNumericLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); + break; + case "unitSizeLimit": + limit = new SimpleRoundedPercentageLimit(100); + break; + case "compositeMaxLimit": + ICollection<ILimit> maxSubLimits = GetSubLimits(limitElem); + limit = new CompositeMaximumLimit(maxSubLimits); + break; + case "compositeMinLimit": + ICollection<ILimit> minSubLimits = GetSubLimits(limitElem); + limit = new CompositeMinimumLimit(minSubLimits); + break; + default: + //TODO: Warn of missing handler for when we've extended the limit list + break; + } + } + + return limit; + } + + private ICollection<ILimit> GetSubLimits(XmlElement limitElem) + { + XmlNodeList subLimitNodes = GetSubLimitElements(limitElem); + ICollection<ILimit> limits = new List<ILimit>(); + + foreach (XmlNode node in subLimitNodes) + { + if (node is XmlElement) + { + ILimit limit = GetLimitFromElement((XmlElement)node); + + if (limit != null) + { + limits.Add(limit); + } + } + } + + return limits; + } + + private XmlNodeList GetSubLimitElements(XmlElement limitElem) + { + return limitElem.ChildNodes; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/WarFoundryXmlRaceFactory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,512 @@ +// This file (WarFoundryXmlRaceFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using IBBoard.Xml; +using IBBoard.IO; +using IBBoard.Limits; +using IBBoard.CustomMath; +using ICSharpCode.SharpZipLib.Zip; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Objects.Requirement; +using IBBoard.WarFoundry.API.Factories.Requirement; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + /// <summary> + /// A sub-factory for loading WarFoundry Race XML files + /// </summary> + public class WarFoundryXmlRaceFactory : IRaceFactory<XmlDocument, XmlElement> + { + private Dictionary<Race, XmlDocument> extraData = new Dictionary<Race, XmlDocument>(); + private WarFoundryXmlLimitParser limitParser = new WarFoundryXmlLimitParser(); + private WarFoundryXmlFactory mainFactory; + + public WarFoundryXmlRaceFactory(WarFoundryXmlFactory factory) + { + this.mainFactory = factory; + } + + private void StoreExtraData(Race wfObject, XmlElement elem) + { + extraData[wfObject] = elem.OwnerDocument; + } + + private XmlDocument GetExtraData(Race obj) + { + XmlDocument extra = null; + extraData.TryGetValue(obj, out extra); + return extra; + } + + public Race CreateRace(XmlElement elem) + { + string id = elem.GetAttribute("id"); + string subid = elem.GetAttribute("subid"); + string systemID = elem.GetAttribute("system"); + string name = elem.GetAttribute("name"); + string armyDefaultName = elem.GetAttribute("defaultArmyName"); + GameSystem gameSystem = WarFoundryLoader.GetDefault ().GetGameSystem (systemID); + + if (gameSystem == null) + { + throw new InvalidFileException("Referenced game system, '"+systemID+"', did not exist"); + } + + Race race = new Race(id, subid, name, gameSystem, mainFactory); + race.ArmyDefaultName = armyDefaultName; + StoreExtraData(race, elem); + return race; + } + + public void CompleteLoading(Race race) + { + if (!WarFoundryXmlFactoryUtils.CanCompleteLoading(race)) + { + return; + } + + race.SetAsLoading(); + XmlDocument extraData = GetExtraData(race); + + foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:categories/cat:cat")) + { + CreateCategoryFromElement(node, race); + } + + foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:equipment/race:equipmentItem")) + { + CreateEquipmentItemFromElement(node, race); + } + + foreach (XmlElement node in WarFoundryXmlFactoryUtils.SelectNodes(extraData, "/race:race/race:abilities/race:ability")) + { + 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")) + { + GetUnitTypeForElement(node, race); + } + + race.SetAsFullyLoaded(); + } + + private Category CreateCategoryFromElement(XmlElement elem, Race parentRace) + { + Category cat = CategoryLoader.CreateFromElement(elem); + parentRace.AddCategory(cat); + return cat; + } + + + public UnitType GetUnitType(string id, Race parentRace) + { + return GetUnitType(id, parentRace, GetExtraData(parentRace)); + } + + public UnitType GetUnitType(string id, Race parentRace, XmlDocument doc) + { + UnitType type = parentRace.GetUnitType(id); + + if (type==null) + { + type = GetUnitTypeFromDocument(doc, id, parentRace); + } + + return type; + } + + private UnitType GetUnitTypeFromDocument(XmlDocument doc, string id, Race parentRace) + { + XmlElement unitWithId = WarFoundryXmlFactoryUtils.SelectSingleElement (doc, "/race:race/race:units/race:unit[@id='" + id + "']"); + + if (unitWithId == null) + { + throw new InvalidFileException("Could not find unit with ID "+id); + } + + return GetUnitTypeForElement(unitWithId, parentRace); + } + + private UnitType GetUnitTypeForElement(XmlElement elem, Race parentRace) + { + string id = elem.GetAttribute("id"); + UnitType type = parentRace.GetUnitType(id); + + if (type==null) + { + type = CreateUnitTypeFromElement(elem, id, parentRace); + } + + return type; + } + + private UnitType CreateUnitTypeFromElement(XmlElement elem, string id, Race parentRace) + { + string name = elem.GetAttribute("typeName"); + UnitType type = new UnitType(id, name, parentRace); + LoadCoreValuesForUnitType(elem, type); + LoadEquipmentSlotsForUnitType(elem, type); + LoadEquipmentForUnitType(elem, type); + LoadAbilitiesForUnitType(elem, type); + LoadContainedUnitsForUnitType(elem, type); + LoadRequirementsForUnitType(elem, type); + LoadExtraDataForUnitType(elem, type); + LoadNotesForUnitType(elem, type); + parentRace.AddUnitType(type); + return type; + } + + private void LoadCoreValuesForUnitType(XmlElement elem, UnitType type) + { + try + { + type.MaxNumber = XmlTools.GetIntValueFromAttribute(elem, "maxNum"); + type.MinNumber = XmlTools.GetIntValueFromAttribute(elem, "minNum"); + type.MaxSize = XmlTools.GetIntValueFromAttribute(elem, "maxSize"); + type.MinSize = XmlTools.GetIntValueFromAttribute(elem, "minSize"); + type.BaseSize = XmlTools.GetIntValueFromAttribute(elem, "baseSize"); + type.CostPerTrooper = XmlTools.GetDoubleValueFromAttribute(elem, "points"); + type.BaseUnitCost = XmlTools.GetDoubleValueFromAttribute(elem, "basePoints"); + } + catch (FormatException ex) + { + throw new InvalidFileException(ex.Message, ex); + } + + Race race = type.Race; + string mainCatID = elem.GetAttribute("cat"); + Category cat = race.GetCategory(mainCatID); + + if (cat == null) + { + throw new InvalidFileException(String.Format("Category with ID '{1}' did not exist for UnitType '{0}'", type.Name, mainCatID)); + } + + type.MainCategory = cat; + + XmlNodeList unitCategories = WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:unitCategories/race:unitCategory"); + + foreach (XmlElement unitCategory in unitCategories) + { + string catID = unitCategory.GetAttribute("catID"); + Category unitCat = race.GetCategory(catID); + + if (unitCat == null) + { + throw new InvalidFileException(String.Format("Category with ID '{1}' did not exist for UnitType '{0}'", type.Name, catID)); + } + + type.AddCategory(unitCat); + } + + XmlElement statsElement = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:stats"); + + 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 = race.GetUnitMemberType(typeID); + type.AddUnitMemberType(unitMemberType); + } + } + + private void LoadEquipmentSlotsForUnitType(XmlElement elem, UnitType type) + { + foreach (XmlElement equipSlot in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:equipmentSlots/race:equipmentSlot")) + { + LoadEquipmentSlotForUnitType (type, equipSlot); + } + } + + private void LoadEquipmentSlotForUnitType(UnitType type, XmlElement equipSlot) + { + string slotName = equipSlot.GetAttribute("name"); + ILimit limit = GetMaxLimit(equipSlot); + + if (limit != null) + { + type.AddEquipmentSlot(slotName, limit); + } + } + + private ILimit GetMinLimit(XmlElement elem) + { + return limitParser.GetMinLimit(elem); + } + + private ILimit GetMaxLimit(XmlElement elem) + { + return limitParser.GetMaxLimit(elem); + } + + private void LoadEquipmentForUnitType(XmlElement elem, UnitType type) + { + foreach (XmlElement equip in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:unitEquipment/race:unitEquipmentItem")) + { + string id = equip.GetAttribute("id"); + EquipmentItem equipItem = type.Race.GetEquipmentItem(id); + + if (equipItem!=null) + { + string mutexGroupString = equip.GetAttribute("exclusivityGroups"); + string[] mutexGroups; + + if (mutexGroupString == "") + { + mutexGroupString = equip.GetAttribute("exclusivityGroup"); + } + + if (mutexGroupString != "") + { + string[] groups = mutexGroupString.Split(','); + int groupCount = groups.Length; + + for (int i = 0; i < groupCount; i++) + { + groups[i] = groups[i].Trim(); + } + + mutexGroups = groups; + } + else + { + mutexGroups = new string[0]; + } + + UnitEquipmentItem unitEquipItem = new UnitEquipmentItem(equipItem, type, mutexGroups); + + string equipSlot = equip.GetAttribute("equipmentSlot"); + + if (equipSlot != "") + { + if (type.HasEquipmentSlot(equipSlot)) + { + unitEquipItem.SlotName = equipSlot; + } + else + { + throw new InvalidFileException("Attribute 'equipmentSlot' of unit equipment item " + id + " for " + type.Name + " was not a valid slot name"); + } + } + + ILimit limit = GetMaxLimit(equip); + + if (limit != null) + { + unitEquipItem.MaxLimit = limit; + } + + limit = GetMinLimit(equip); + + if (limit != null) + { + unitEquipItem.MinLimit = limit; + } + + unitEquipItem.RoundNumberUp = equip.GetAttribute("roundDirection").Equals("up"); + + try + { + unitEquipItem.IsRequired = XmlTools.GetBoolValueFromAttribute(equip, "required"); + } + catch(FormatException e) + { + throw new InvalidFileException("Attribute 'required' of unit equipment item " + id + " for " + type.Name + " was not a valid boolean", e); + } + + try + { + unitEquipItem.CostMultiplier = XmlTools.GetDoubleValueFromAttribute(equip, "costMultiplier"); + } + catch (FormatException e) + { + throw new InvalidFileException("Attribute 'costMultiplier' of unit equipment item " + id + " for " + type.Name + " was not a valid decimal number", e); + } + + try + { + unitEquipItem.CostRoundType = (RoundType) Enum.Parse(typeof(RoundType), equip.GetAttribute("costRounding")); + } + catch (ArgumentException e) + { + throw new InvalidFileException("Attribute 'costRounding' of unit equipment item " + id + " for " + type.Name + " was not a valid rounding type", e); + } + } + else + { + throw new InvalidFileException("Equipment item with ID '" + id + "' was required by " + type.Name + " but was not found"); + } + } + } + + private void LoadAbilitiesForUnitType(XmlElement elem, UnitType type) + { + foreach (XmlElement abilityElem in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:unitAbilities/race:unitAbility")) + { + string id = abilityElem.GetAttribute("abilityID"); + Ability ability = type.Race.GetAbility(id); + + if (ability == null) + { + throw new InvalidFileException("Ability for "+type.Name+ " with ID "+id+ " did not exist in race definition"); + } + + bool required = XmlTools.GetBoolValueFromAttribute(abilityElem, "required"); + type.AddAbility(ability, required); + } + } + + private void LoadContainedUnitsForUnitType(XmlElement elem, UnitType type) + { + foreach (XmlElement containedUnitType in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:contains/race:containedUnit")) + { + string id = containedUnitType.GetAttribute("containedID"); + UnitType containedType = GetUnitTypeFromDocument(elem.OwnerDocument, id, type.Race); + + if (containedType!=null) + { + type.AddContainedUnitType(containedType); + } + else + { + throw new InvalidFileException("Unit type " + type.Name + " tried to contain undefined unit with ID "+id); + } + } + } + + private void LoadRequirementsForUnitType(XmlElement elem, UnitType type) + { + foreach (XmlElement extraData in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:requirements/race:requirement")) + { + string name = extraData.GetAttribute("requirementName"); + IRequirementFactory reqFactory = WarFoundryLoader.GetRequirementFactory(name); + + if (reqFactory != null) { + string data = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "race:data").InnerText; + IRequirement req = reqFactory.CreateRequirement(type, data, this); + type.AddRequirement(req); + } + } + } + + private void LoadExtraDataForUnitType(XmlElement elem, UnitType type) + { + foreach (XmlElement extraData in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:extraData/race:data")) + { + string id = extraData.GetAttribute("id"); + string data = extraData.InnerXml; + type.AddExtraData(id, data); + } + } + + private void LoadNotesForUnitType(XmlElement elem, UnitType type) + { + XmlNode node = WarFoundryXmlFactoryUtils.SelectSingleNode(elem, "race:notes"); + + if (node!=null) + { + type.Notes = node.InnerText; + } + } + + private Stats ParseUnitStats(XmlElement elem, GameSystem system) + { + if (elem == null) + { + return null; + } + + String statsID = elem.GetAttribute("statSet"); + SystemStats statsSet; + + if (statsID == "") + { + statsSet = system.StandardSystemStats; + } + else + { + statsSet = system.GetSystemStatsForID(statsID); + } + + Stats stats = new Stats(statsSet); + + foreach (XmlElement stat in WarFoundryXmlFactoryUtils.SelectNodes(elem, "race:stat")) + { + String statName = stat.GetAttribute("name"); + stats.SetStatValue(statName, stat.InnerText); + } + + return stats; + } + + private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, Race race) + { + string id = elem.GetAttribute("id"); + EquipmentItem item = race.GetEquipmentItem(id); + + if (item == null) + { + item = CreateEquipmentItemFromElement(elem, id, race); + } + + return item; + } + + private EquipmentItem CreateEquipmentItemFromElement(XmlElement elem, string id, Race race) + { + string name = elem.GetAttribute("name"); + EquipmentItem item = new EquipmentItem(id, name, race); + double cost = 0; + + try + { + cost = XmlTools.GetDoubleValueFromAttribute(elem, "cost"); + } + catch(FormatException ex) + { + throw new InvalidFileException("Attribute 'cost' of equipment item "+id+" was not a valid number", ex); + } + + //TODO: Parse equipment stats if there are any + item.Cost = cost; + race.AddEquipmentItem(item); + return item; + } + + private Ability CreateAbilityFromElement(XmlElement elem, Race race) + { + string id = elem.GetAttribute("id"); + string name = elem.GetAttribute("name"); + Ability ability = new Ability(id, name); + XmlNode node = WarFoundryXmlFactoryUtils.SelectSingleNode(elem, "race:description"); + 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); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Factories/Xml/Zip/StringZipEntrySource.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,30 @@ +// This file (StringZipEntrySource.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard +// +// 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; +using System.IO; +using IBBoard.Lang; +using ICSharpCode.SharpZipLib.Zip; + +namespace IBBoard.WarFoundry.API.Factories.Xml.Zip +{ + /// <summary> + /// A simple implementation of IStaticDataSource that lets us add a string directly to a Zip file + /// </summary> + public class StringZipEntrySource : IStaticDataSource + { + private byte[] entryContent; + + public StringZipEntrySource(String content) + { + entryContent = StringManipulation.StringToBytes(content); + } + + public Stream GetSource() + { + return new MemoryStream(entryContent); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/FileLoadFailure.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,121 @@ +// This file (FileLoadFailure.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.IO; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Factories; + +namespace IBBoard.WarFoundry.API +{ + /// <summary> + /// A container class that holds information about file load failures. Core information covers the file that failed and a message. Additional information includes the factory loading the file and the excetion that was thrown. Messages are passed through <code>String.Format</code> and supplied with the failed file path and the failing factory + /// </summary> + public class FileLoadFailure + { + private FileInfo failedFile; + private IWarFoundryFactory loadingFactory; + private string defaultMessage; + private string messageTranslationID; + private string message; + private Exception cause; + + /// <summary> + /// Constructor for a failed file load where no factory was found. Translatable messages can be providied through a <code>translationID</code> or skipped by passing <code>null</code>. + /// </summary> + /// <param name="file"> + /// The <see cref="FileInfo"/> that failed to load + /// </param> + /// <param name="message"> + /// A message about the failure in English - used as a default fall-back message. + /// </param> + /// <param name="translationID"> + /// The ID of a translation for the message. + /// </param> + public FileLoadFailure(FileInfo file, string message, string translationID) : this (file, null, message, "") + { + } + + /// <summary> + /// Constructor for a failed file load where a factory was identified as supporting the file but failed to load it. Translatable messages can be providied through a <code>translationID</code> or skipped by passing <code>null</code>. + /// </summary> + /// <param name="file"> + /// The <see cref="FileInfo"/> that failed to load + /// </param> + /// <param name="factory"> + /// The <see cref="IWarFoundryFactory"/> that failed to load the file + /// </param> + /// <param name="message"> + /// A message about the failure in English - used as a default fall-back message. + /// </param> + /// <param name="translationID"> + /// The ID of a translation for the message. + /// </param> + public FileLoadFailure(FileInfo file, IWarFoundryFactory factory, string message, string translationID) : this(file, factory, message, translationID, null) + { + } + + /// <summary> + /// Constructor for a failed file load where a factory was identified as supporting the file but an exception occurred while loading it. Translatable messages can be providied through a <code>translationID</code> or skipped by passing <code>null</code>. + /// </summary> + /// <param name="file"> + /// The <see cref="FileInfo"/> that failed to load + /// </param> + /// <param name="factory"> + /// The <see cref="IWarFoundryFactory"/> that failed to load the file + /// </param> + /// <param name="message"> + /// A message about the failure in English - used as a default fall-back message. + /// </param> + /// <param name="translationID"> + /// The ID of a translation for the message. + /// </param> + /// <param name="exception"> + /// The <see cref="Exception"/> that occurred to cause the load to fail + /// </param> + public FileLoadFailure(FileInfo file, IWarFoundryFactory factory, string message, string translationID, Exception exception) + { + failedFile = file; + loadingFactory = factory; + defaultMessage = message; + messageTranslationID = translationID; + cause = exception; + } + + public FileInfo FailedFile + { + get + { + return failedFile; + } + } + + public string Message + { + get + { + if (message == null) + { + string fileName = FailedFile.FullName; + string factoryType = (loadingFactory == null ? "" : loadingFactory.GetType().Name); + if (String.IsNullOrEmpty(messageTranslationID)) + { + message = String.Format(defaultMessage, fileName, factoryType); + } + else + { + message = Translation.GetTranslation(messageTranslationID, defaultMessage, fileName, factoryType); + } + } + + return message; + } + } + + public Exception Exception + { + get { return cause; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Ability.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,32 @@ +// This file (Ability.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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> + /// An Ability is a special rule that a UnitType has, made up of an ability name and a description. + /// </summary> + public class Ability : WarFoundryObject + { + private string description; + + public Ability(String id, String name) : base(id, name) + { + } + + public string Description + { + get { return description; } + set + { + if (value!=null) + { + description = value.Trim(); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/AbstractUnitEquipmentItemSelection.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,92 @@ +// This file (AbstractUnitEquipmentItemSelection.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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> + /// An abstract class that defines a selection of equipment for a unit + /// </summary> + public abstract class AbstractUnitEquipmentItemSelection + { + private Unit selectionForUnit; + private UnitEquipmentItem selectedItem; + private double amountTaken; + + public AbstractUnitEquipmentItemSelection(Unit unit, UnitEquipmentItem item, double amount) + { + selectionForUnit = unit; + selectedItem = item; + AmountTaken = amount; + } + + public Unit EquipmentForUnit + { + get + { + return selectionForUnit; + } + } + + public UnitEquipmentItem EquipmentItem + { + get + { + return selectedItem; + } + } + + public double AmountTaken + { + get + { + return amountTaken; + } + set + { + amountTaken = value; + + if (!IsValidValue(value)) + { + //Fire validation failed event (once we have one) + } + } + } + + public bool IsValid + { + get + { + return IsValidValue(AmountTaken) && IsInRange(AmountTaken); + } + } + + protected virtual bool IsValidValue(double newValue) + { + return true; + } + + protected bool IsInRange(double newValue) + { + int unitSize = EquipmentForUnit.Size; + int minLimit = EquipmentItem.MinLimit.GetLimit(unitSize); + int maxLimit = EquipmentItem.MaxLimit.GetLimit(unitSize); + return (minLimit <= newValue) && (newValue <= maxLimit); + } + + public double TotalCost + { + get + { + return NumberTaken * EquipmentItem.Cost; + } + } + + public abstract int NumberTaken + { + get; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Army.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,233 @@ +// This file (Army.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using IBBoard.WarFoundry.API; +using IBBoard.WarFoundry.API.Factories; +using ICSharpCode.SharpZipLib.Zip; +using IBBoard.WarFoundry.API.Objects.Requirement; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for Army. + /// </summary> + public class Army : WarFoundryLoadedObject, ICostedWarFoundryObject + { + //private GameSystem system; + private Race armyRace; + private int maxPoints; + private double pointsTotal; + private Dictionary<Category, ArmyCategory> categories; + + public event ObjectAddDelegate UnitAdded; + public event ObjectRemoveDelegate UnitRemoved; + public event DoubleValChangedDelegate PointsValueChanged; + private DoubleValChangedDelegate PointsValueChangedMethod; + + public Army(Race race, string armyName, int maxArmyPoints) : this(race, armyName, maxArmyPoints, null) + { + } + + public Army(Race race, string armyName, int maxArmyPoints, ZipFile file) : base(armyName) + { + armyRace = race; + Name = armyName; + maxPoints = maxArmyPoints; + PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler); + } + + public ArmyCategory GetCategory(Category cat) + { + ArmyCategory armyCat = null; + ArmyCategories.TryGetValue(cat, out armyCat); + return armyCat; + } + + private Dictionary<Category, ArmyCategory> ArmyCategories + { + get + { + if (categories==null) + { + categories = new Dictionary<Category, ArmyCategory>(); + Category[] raceCats = Race.Categories; + ArmyCategory cat; + int raceCatCount = raceCats.Length; + + for (int i = 0; i < raceCatCount; i++) + { + Category raceCat = raceCats[i]; + cat = new ArmyCategory(this, raceCat); + categories[raceCat] = cat; + cat.PointsValueChanged+= PointsValueChangedMethod; + cat.UnitAdded+=new ObjectAddDelegate(Army_UnitAdded); + cat.UnitRemoved+=new ObjectRemoveDelegate(Army_UnitRemoved); + } + } + + return categories; + } + } + + public ArmyCategory[] Categories + { + get + { + return DictionaryUtils.ToArray<Category, ArmyCategory>(ArmyCategories); + } + } + + public Race Race + { + get { return armyRace; } + } + + public GameSystem GameSystem + { + get { return (armyRace!=null ? armyRace.GameSystem : null); } + } + + protected void OnUnitAdded(Unit unit) + { + if (UnitAdded != null) + { + UnitAdded(unit); + } + } + + protected void OnUnitRemoved(Unit unit) + { + if (UnitRemoved!=null) + { + UnitRemoved(unit); + } + } + + private void OnPointsValueChanged(double oldValue, double newValue) + { + if (PointsValueChanged!=null) + { + PointsValueChanged(this, oldValue, newValue); + } + } + + private double TotalPoints + { + get { return pointsTotal; } + set + { + double oldPoints = pointsTotal; + pointsTotal = value; + + if (oldPoints!=pointsTotal) + { + OnPointsValueChanged(oldPoints, pointsTotal); + } + } + } + + public double Points + { + get { return TotalPoints; } + } + + public void AddUnit(Unit unit) + { + Category category = unit.UnitType.MainCategory; + AddUnit(unit, category); + } + + public void AddUnit(Unit unit, Category category) + { + ArmyCategory armyCat = GetCategory(category); + armyCat.AddUnit(unit); + } + + public void RemoveUnit(Unit unit) + { + unit.Category.RemoveUnit(unit); + } + + public Unit[] GetUnits(Category cat) + { + return GetUnits(this.GetCategory(cat)); + } + + public Unit[] GetUnits(ArmyCategory cat) + { + return cat.GetUnits(); + } + + public Unit[] GetUnits() + { + List<Unit> fullList = new List<Unit>(); + + foreach(ArmyCategory cat in Categories) + { + fullList.AddRange(cat.GetUnits()); + } + + return fullList.ToArray(); + } + + public int MaxPoints + { + get { return maxPoints; } + set + { + if (value > 0) + { + maxPoints = value; + } + } + } + + private void PointsValueChangedHandler(WarFoundryObject obj, double oldVal, double newVal) + { + if (obj is ArmyCategory) + { + double points = 0; + + foreach (ArmyCategory cat in Categories) + { + points+= cat.Points; + } + + TotalPoints = points; + } + } + + public int GetUnitTypeCount(UnitType unitType) + { + int count = 0; + + foreach (ArmyCategory cat in Categories) + { + count+= cat.GetUnitTypeCount(unitType); + } + + return count; + } + + private void Army_UnitAdded(WarFoundryObject val) + { + OnUnitAdded((Unit)val); + } + + private void Army_UnitRemoved(WarFoundryObject val) + { + OnUnitRemoved((Unit)val); + } + + public ICollection<IRequirement> GetRequirements () + { + return Race.GetRequirements(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/ArmyCategory.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,164 @@ +// This file (ArmyCategory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for ArmyCategory. + /// </summary> + public class ArmyCategory : WarFoundryObject, ICostedWarFoundryObject + { + private Category category; + private Army parentArmy; + private double pointsTotal; + private List<Unit> units; + private Dictionary<string, int> unitTypes; + private DoubleValChangedDelegate PointsValueChangedMethod; + public event ObjectAddDelegate UnitAdded; + public event ObjectRemoveDelegate UnitRemoved; + public event DoubleValChangedDelegate PointsValueChanged; + + public ArmyCategory(Army army, Category cat) : base() + { + parentArmy = army; + category = cat; + cat.NameChanged+=new StringValChangedDelegate(cat_NameChanged); + PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler); + units = new List<Unit>(); + unitTypes = new Dictionary<string,int>(); + } + + public Category Category + { + get { return category; } + } + + public Army ParentArmy + { + get { return parentArmy; } + } + + public override string ID + { + get + { + return Category.ID; + } + set + { + Category.ID = value; + } + } + + public override string Name + { + get { return category.Name; } + set + { + category.Name = value; + } + } + + internal void AddUnit(Unit unit) + { + //TODO: Put back a similar check + //List<FailedUnitRequirement> failedReqs = ParentArmy.CanAddUnit(unit); + units.Add(unit); + unit.Category = this; + unit.PointsValueChanged+= PointsValueChangedMethod; + int unitTypeCount; + unitTypes.TryGetValue(unit.UnitType.ID, out unitTypeCount); + unitTypes[unit.UnitType.ID] = (int)unitTypeCount + 1; + TotalPoints+= unit.Points; + OnUnitAdded(unit); + } + + internal void RemoveUnit(Unit unit) + { + //TODO: Put back a similar check + //List<FailedUnitRequirement> failedReqs = ParentArmy.CanRemoveUnit(unit); + units.Remove(unit); + unitTypes[unit.UnitType.ID] = ((int)unitTypes[unit.UnitType.ID])-1; + TotalPoints-= unit.Points; + unit.PointsValueChanged-= PointsValueChangedMethod; + OnUnitRemoved(unit); + } + + public int GetUnitTypeCount(UnitType unitType) + { + return unitTypes.ContainsKey(unitType.ID) ? (int)unitTypes[unitType.ID] : 0; + } + + public Unit[] GetUnits() + { + return units.ToArray(); + } + + private double TotalPoints + { + get { return pointsTotal; } + set + { + double oldVal = pointsTotal; + pointsTotal = value; + + if (oldVal!=pointsTotal) + { + OnPointsValueChanged(oldVal, pointsTotal); + } + } + } + + public double Points + { + get { return TotalPoints; } + } + + private void PointsValueChangedHandler(WarFoundryObject obj, double oldVal, double newVal) + { + if (obj is Unit) + { + double diff = newVal - oldVal; + TotalPoints+= diff; + } + } + + protected void OnUnitAdded(Unit unit) + { + if (UnitAdded != null) + { + UnitAdded(unit); + } + } + + protected void OnUnitRemoved(Unit unit) + { + if (UnitRemoved != null) + { + UnitRemoved(unit); + } + } + + protected virtual void OnPointsValueChanged(double oldValue, double newValue) + { + if (PointsValueChanged!=null) + { + PointsValueChanged(this, oldValue, newValue); + } + } + + protected void cat_NameChanged(WarFoundryObject obj, string oldValue, string newValue) + { + OnNameChanged(oldValue, newValue); + } + + public int GetPointsPercentage() + { + return (int)Math.Round((Points / ParentArmy.MaxPoints) * 100, 0); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Category.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,119 @@ +// This file (Category.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Xml; +using IBBoard.Logging; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// A Category is a definition at the <see cref=" GameSystem"/> or <see cref=" Race"/> level of a group that <see cref=" UnitType"/>s belong to. Each category has a name and a min/max limit on points or percentage of a total army cost that units in the category can total. + /// </summary> + public class Category : WarFoundryObject + { + private int minPts = 0; + private int maxPts = WarFoundryCore.INFINITY; + private int minPc = 0; + private int maxPc = 100; + + + public Category(string id, string name) : base(id, name) + { + } + + protected override string DefaultName() + { + return ""; + } + + /// <value> + /// Gets or sets the minimum number of points that the units of this category can cost. Note: This should be set AFTER MaximumPoints, otherwise an unintended default value may be set for the minimum + /// </value> + public int MinimumPoints + { + get { return minPts; } + set + { + minPts = (value >= 0 ? value : 0); + CheckMinimumPoints(); + } + } + + /// <value> + /// Gets or sets the maximum number of points that the units of this category can cost. Note: This should be set BEFORE MinimumPoints, otherwise an unintended default value may be set for the minimum + /// </value> + public int MaximumPoints + { + get { return maxPts; } + set + { + maxPts = (value >= 0 ? value : WarFoundryCore.INFINITY); + CheckMinimumPoints(); + } + } + + /// <summary> + /// Makes sure that the minimum points value isn't more than the maximum points value, hence the warning on the properties + /// </summary> + private void CheckMinimumPoints() + { + if (MinimumPoints > MaximumPoints && MaximumPoints!=WarFoundryCore.INFINITY) + { + MinimumPoints = MaximumPoints; + LogNotifier.WarnFormat(GetType(), "Category {0} ({1}) had a minimum points limit greater than its maximum points limit.", Name, ID); + } + } + + /// <value> + /// Gets or sets the minimum percentage of the total army points value that the units of this category can cost. Note: This should be set AFTER MaximumPercentage, otherwise an unintended default value may be set for the minimum + /// </value> + public int MinimumPercentage + { + get { return minPc; } + set + { + minPc = (value >= 0 ? value : 0); + CheckMinimumPercentage(); + } + } + + /// <value> + /// Gets or sets the maximum percentage of the total army points value that the units of this category can cost. Note: This should be set BEFORE MinimumPercentage, otherwise an unintended default value may be set for the minimum + /// </value> + public int MaximumPercentage + { + get { return maxPc; } + set + { + if (value < 0) + { + maxPc = 0; + } + else if (value > 100) + { + maxPc = 100; + } + else + { + maxPc = value; + } + + CheckMinimumPercentage(); + } + } + + /// <summary> + /// Makes sure that the minimum percentage value isn't more than the maximum points value, hence the warning on the properties + /// </summary> + private void CheckMinimumPercentage() + { + if (MinimumPercentage > MaximumPercentage) + { + MinimumPercentage = MaximumPercentage; + LogNotifier.WarnFormat(GetType(), "Category {0} ({1}) had a minimum percentage limit greater than its maximum percentage limit.", Name, ID); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/CompositeEquipmentItem.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,39 @@ +// This file (CompositeEquipmentItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// A special <see cref=" EquipmentItem"/> that is made up of a number of other <code>EquipmentItem</code>s + /// </summary> + public class CompositeEquipmentItem : EquipmentItem + { + private List<EquipmentItem> compositeItems; + + public CompositeEquipmentItem(string id, string name, Race race) : base(id, name, race) + { + compositeItems = new List<EquipmentItem>(); + } + + public void AddItem(EquipmentItem item) + { + compositeItems.Add(item); + Cost+= item.Cost; + } + + public void RemoveItem(EquipmentItem item) + { + compositeItems.Remove(item); + Cost-= item.Cost; + } + + public EquipmentItem[] Items + { + get { return compositeItems.ToArray(); } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/DuplicateItemException.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,15 @@ +// This file (DuplicateItemException.cs) is a part of IBBoard.WarFoundry.API and is copyright 2009 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 +{ + public class DuplicateItemException + { + public DuplicateItemException() + { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/EquipmentItem.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,58 @@ +// This file (EquipmentItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Xml; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for EquipmentItem. + /// </summary> + public class EquipmentItem : WarFoundryObject + { + private double cost; + private string description; + private Race equipForRace; + + public EquipmentItem(string id, string name, Race race) : base(id, name) + { + equipForRace = race; + description = ""; + } + + public double Cost + { + get { return cost; } + set + { + if (value >= 0) + { + cost = value; + } + } + } + + public string Description + { + get { return description; } + set { description = (value == null ? "" : value); } + } + + public Race EquipmentForRace + { + get { return equipForRace; } + } + + public GameSystem GameSystem + { + get { return equipForRace.GameSystem; } + } + + public bool CanBeUsedWithItem(EquipmentItem item) + { + return true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/GameSystem.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,360 @@ +// This file (GameSystem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009, 2010, 2011 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.Collections.Generic; +using IBBoard.WarFoundry.API.Factories; +using Col = IBBoard.Collections; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for GameSystem. + /// </summary> + public class GameSystem : WarFoundryStagedLoadingObject + { + private static readonly int SYSTEM_DEFAULT_ARMY_SIZE = 1000; + private bool warnOnError = true; + private bool allowAllies = false; + private Dictionary<string, Category> categories = new Dictionary<string, Category>(); + private Dictionary<string, SystemStats> stats = new Dictionary<string, SystemStats>(); + private string defaultStats = ""; + private int defaultArmySize = SYSTEM_DEFAULT_ARMY_SIZE; + + public GameSystem(string systemID, string systemName, IWarFoundryFactory creatingFactory) : base(systemID, systemName, creatingFactory) + { + //Do nothing special + } + + public int SystemArmyDefaultSize + { + get { return defaultArmySize; } + set + { + if (value == 0) + { + defaultArmySize = SYSTEM_DEFAULT_ARMY_SIZE; + } + else + { + defaultArmySize = value; + } + } + } + + public string SystemPtsAbbrevSingle + { + get; set; + } + public string SystemPtsAbbrevPlural + { + get; set; + } + public string SystemPtsNameSingle + { + get; set; + } + public string SystemPtsNamePlural + { + get; set; + } + public bool AllowAllies + { + get { return allowAllies; } + set { allowAllies = value; } + } + + public void AddCategory(Category cat) + { + RawCategories[cat.ID] = cat; + } + + public Category GetCategory(string id) + { + EnsureFullyLoaded(); + Category cat = null; + RawCategories.TryGetValue(id, out cat); + return cat; + } + + public void SetCategory(Category cat) + { + Category old; + RawCategories.TryGetValue(cat.ID, out old); + + if (old == null) + { + AddCategory(cat); + } + else + { + if (!old.Equals(cat)) + { + RawCategories[old.ID] = cat; + } + } + } + + public void RemoveCategory(string id) + { + RawCategories.Remove(id); + } + + public Category[] Categories + { + get + { + EnsureFullyLoaded(); + return DictionaryUtils.ToArray<string, Category>(RawCategories); + } + } + + protected Dictionary<string, Category> RawCategories + { + get { return categories; } + } + + public bool WarnOnError + { + get + { + return warnOnError; + } + set { warnOnError = value; } + } + + public void AddSystemStats(SystemStats sysStats) + { + stats[sysStats.ID] = sysStats; + } + + public SystemStats StandardSystemStats + { + get + { + EnsureFullyLoaded(); + return stats[defaultStats]; + } + } + + public string StandardSystemStatsID + { + get + { + EnsureFullyLoaded(); + return defaultStats; + } + + set + { + if (value != null && value.Trim().Length > 0) + { + defaultStats = value; + } + } + } + + public SystemStats[] SystemStats + { + get + { + EnsureFullyLoaded(); + SystemStats[] statsArray = new SystemStats[stats.Count]; + stats.Values.CopyTo(statsArray, 0); + return statsArray; + } + } + + public SystemStats GetSystemStatsForID(string id) + { + EnsureFullyLoaded(); + SystemStats statsForID; + stats.TryGetValue(id, out statsForID); + return statsForID; + } + + public void SetSystemStats(SystemStats newStats) + { + SystemStats old; + stats.TryGetValue(newStats.ID, out old); + + if (old == null) + { + AddSystemStats(newStats); + } + else + { + if (!old.Equals(newStats)) + { + stats[old.ID] = newStats; + } + } + } + + public void RemoveSystemStats(string id) + { + stats.Remove(id); + } + + public Race SystemDefaultRace + { + get { return WarFoundryLoader.GetDefault().GetRace(this, Race.SYSTEM_DEFAULT_RACE_ID); } + } + + public bool Matches(GameSystem otherSystem) + { + if (otherSystem == null) + { + return false; + } + + return this.ID == otherSystem.ID; + } + + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + if (obj.GetType().Equals(this.GetType())) + { + GameSystem otherSystem = (GameSystem)obj; + if (!ID.Equals(otherSystem.ID) || !Name.Equals(otherSystem.Name) || !Col.Collections.AreEqual(RawCategories, otherSystem.RawCategories)) + { + return false; + } + else + { + return true; + } + } + else + { + return false; + } + } + + public override int GetHashCode() + { + return ID.GetHashCode() + Name.GetHashCode() + (RawCategories != null ? RawCategories.GetHashCode() : 0) + warnOnError.GetHashCode(); + } + + public bool UnitTypeMaxed(UnitType unitType, Army army) + { + return unitType.MaxNumber != WarFoundryCore.INFINITY && army.GetUnitTypeCount(unitType) >= unitType.MaxNumber; + } + + public bool UnitTypeMinned(UnitType unitType, Army army) + { + return army.GetUnitTypeCount(unitType) <= unitType.MinNumber; + } + + public List<EquipmentItem> GetSystemEquipmentList() + { + List<EquipmentItem> items = new List<EquipmentItem>(); + Race defaultRace = SystemDefaultRace; + + if (defaultRace != null) + { + items = defaultRace.GetEquipmentList(); + } + + return items; + } + + public EquipmentItem GetSystemEquipmentItem(string id) + { + EquipmentItem item = null; + Race defaultRace = SystemDefaultRace; + + if (defaultRace != null) + { + item = defaultRace.GetEquipmentItem(id); + } + + return item; + } + + public UnitType[] GetSystemUnitTypes(Category cat) + { + UnitType[] items = new UnitType[0]; + Race defaultRace = SystemDefaultRace; + + if (defaultRace != null) + { + items = defaultRace.GetUnitTypes(cat); + } + + return items; + } + + public UnitType GetSystemUnitType(string id) + { + UnitType unit = null; + Race defaultRace = SystemDefaultRace; + + if (defaultRace != null) + { + unit = defaultRace.GetUnitType(id); + } + + return unit; + } + + public List<Ability> GetSystemAbilityList() + { + List<Ability> items = new List<Ability>(); + Race defaultRace = SystemDefaultRace; + + if (defaultRace != null) + { + items = defaultRace.GetAbilityList(); + } + + return items; + } + + public Ability GetSystemAbility(string id) + { + Ability ability = null; + Race defaultRace = SystemDefaultRace; + + if (defaultRace != null) + { + ability = defaultRace.GetAbility(id); + } + + return ability; + } + + public string GetPointsAbbrev(double pointTemp) + { + string abbrev = (pointTemp == 1 ? GetPreferredString(SystemPtsAbbrevSingle, SystemPtsAbbrevPlural) : GetPreferredString(SystemPtsAbbrevPlural, SystemPtsAbbrevSingle)); + return abbrev; + } + + public string GetPointsName(double pointTemp) + { + string ptsName = (pointTemp == 1 ? GetPreferredString(SystemPtsNameSingle, SystemPtsNamePlural) : GetPreferredString(SystemPtsNamePlural, SystemPtsNameSingle)); + return ptsName; + } + + private string GetPreferredString(string str1, string str2) + { + string preferred = ""; + + if (str1 != null) + { + preferred = str1; + } + else if (str2 != null) + { + preferred = str2; + } + + return preferred; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/ICostedWarFoundryObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,24 @@ +// This file (ICostedNamedObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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> + /// An interface for WarFoundry objects that have a points value (cost) + /// </summary> + public interface ICostedWarFoundryObject : IWarFoundryObject + { + /// <summary> + /// A getter for the points value of the costed object + /// </summary> + double Points { get; } + + /// <summary> + /// An event that is fired when the points value of the object changes + /// </summary> + event DoubleValChangedDelegate PointsValueChanged; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/IWarFoundryNativeSourceObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,17 @@ +// This file (IWarFoundryNativeSourceObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using ICSharpCode.SharpZipLib.Zip; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Interface for native WarFoundry objects that are the main object in a file and need to reference the file at a later date. + /// </summary> + public interface IWarFoundryNativeSourceObject : IWarFoundryObject + { + ZipFile SourceFile { get; set; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/IWarFoundryObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,22 @@ +// This file (IWarFoundryObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.WarFoundry.API.Factories; + +namespace IBBoard.WarFoundry.API.Objects +{ + public interface IWarFoundryObject + { + /// <value> + /// The unique identifier for the object + /// </value> + string ID { get; set; } + + /// <value> + /// The display name of the WarFoundry object + /// </value> + string Name { get; set; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/IWarFoundryStagedLoadObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,44 @@ +// This file (IWarFoundryStagedLoadObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using ICSharpCode.SharpZipLib.Zip; +using IBBoard.WarFoundry.API.Factories; + +namespace IBBoard.WarFoundry.API.Objects +{ + public interface IWarFoundryStagedLoadObject : IWarFoundryObject + { + /// <summary> + /// Checks whether the object has been fully loaded or whether only the first stage of loading has been performed. + /// If the object is not fully loaded then the method must finish loading the object. + /// </summary> + void EnsureFullyLoaded(); + + /// <value> + /// Gets the <code>AbstractNativeWarFoundryFactory</code> that created the object. + /// </value> + IWarFoundryFactory Factory { get; } + + /// <value> + /// Returns <code>true</code> if the object has been fully loaded with all data, else returns <code>false</code> + /// </value> + bool IsFullyLoaded { get; } + + /// <value> + /// Returns <code>true</code> if the object is in the process of being fully loaded with all data, else returns <code>false</code> + /// </value> + bool IsLoading { get; } + + /// <summary> + /// Marks the object as fully loaded so that no more load checking is required. + /// </summary> + void SetAsFullyLoaded(); + + /// <summary> + /// Markes the object as being in the process of being fully loaded. + /// </summary> + void SetAsLoading(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/InvalidContainershipException.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,46 @@ +// This file (InvalidContainershipException.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.Lang; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// A custom exception for when a unit was added as a sub-unit of another unit, but was not of a <see cref=" UnitType"/> that can be contained + /// by that unit. + /// </summary> + public class InvalidContainershipException : Exception + { + private Unit containing; + private Unit contained; + + public InvalidContainershipException(Unit containingUnit, Unit containedUnit) : base(CreateMessageString(containingUnit, containedUnit)) + { + containing = containingUnit; + contained = containedUnit; + } + + private static string CreateMessageString(Unit containingUnit, Unit containedUnit) + { + return String.Format("{0} cannot contain {1} because units of type {2} cannot contain units of type {3}", containingUnit.Name, containedUnit.Name, containingUnit.UnitType.Name, containedUnit.UnitType.Name); + } + + /// <value> + /// The <see cref=" Unit"/> that the contained unit was added to + /// </value> + public Unit ContainingUnit + { + get { return containing; } + } + + /// <value> + /// The <see cref=" Unit"/> that was added as a contained unit, but which was not of an allowed type + /// </value> + public Unit ContainedUnit + { + get { return contained; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Race.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,348 @@ +// This file (Race.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using IBBoard.IO; +using IBBoard.WarFoundry.API.Factories; +using IBBoard.WarFoundry.API.Objects.Requirement; + +namespace IBBoard.WarFoundry.API.Objects +{ + public class Race : WarFoundryStagedLoadingObject + { + public static string SYSTEM_DEFAULT_RACE_ID = "GameDefault"; + + private string subID; + private GameSystem system; + private string defaultArmyName = ""; + private Dictionary<Category, Dictionary<string, UnitType>> unitTypesByCat; + private Dictionary<string, UnitType> unitTypes = new Dictionary<string,UnitType>(); + 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) + { + } + + public Race(string raceID, string raceSubID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : base(raceID + (raceSubID != "" ? "_" + raceSubID : ""), raceName, creatingFactory) + { + subID = (raceSubID == null ? "" : raceSubID); + system = gameSystem; + } + + public override bool Equals (object obj) + { + if (obj == null) + { + return false; + } + else if (!(obj is Race)) + { + return false; + } + else + { + Race other = (Race)obj; + + if (!ID.Equals(other.ID) || !SubID.Equals(other.SubID) || !GameSystem.Equals(other.GameSystem)) + { + return false; + } + else + { + return true; + } + } + } + + public string SubID + { + get { return subID; } + set { subID = (value == null ? "" : value.Trim()); } + } + + public GameSystem GameSystem + { + get { return system; } + set + { + if (value == null) + { + throw new ArgumentException("Game system for a race cannot be null"); + } + + system = value; + } + } + + public string ArmyDefaultName + { + get { return defaultArmyName; } + set + { + if (value == null) + { + throw new ArgumentException("No default army name"); + } + + defaultArmyName = value; + } + } + + public void AddCategory(Category cat) + { + categories[cat.ID] = cat; + } + + /// <summary> + /// Gets a category from its ID. Attempts to get the category from the race's overrides, or else it falls back to getting the Game System's category with that ID. + /// </summary> + /// <param name="id"> + /// The ID of the category to get + /// </param> + /// <returns> + /// The <code>Category</code> with the specified ID, or null if one doesn't exist. + /// </returns> + public Category GetCategory(string id) + { + EnsureFullyLoaded(); + Category cat = null; + categories.TryGetValue(id, out cat); + + if (cat == null) + { + cat = GameSystem.GetCategory(id); + } + + return cat; + } + + public Category[] Categories + { + get + { + EnsureFullyLoaded(); + Category[] cats; + + if (!HasCategoryOverrides()) + { + cats = GameSystem.Categories; + } + else + { + cats = DictionaryUtils.ToArray<string, Category>(categories); + } + + return cats; + } + } + + public bool HasCategoryOverrides() + { + EnsureFullyLoaded(); + return categories.Count > 0; + } + + public void AddEquipmentItem(EquipmentItem item) + { + //TODO: Throw DuplicateItemException + equipment.Add(item.ID, item); + } + + public EquipmentItem GetEquipmentItem(string id) + { + EnsureFullyLoaded(); + return DictionaryUtils.GetValue(equipment, id); + } + + public List<EquipmentItem> GetEquipmentList() + { + EnsureFullyLoaded(); + List<EquipmentItem> items = new List<EquipmentItem>(); + + foreach (EquipmentItem item in equipment.Values) + { + items.Add(item); + } + + return items; + } + + public void AddUnitType(UnitType type) + { + CacheUnitType(type); + unitTypes.Add(type.ID, type); + } + + public UnitType[] GetUnitTypes(Category cat) + { + EnsureFullyLoaded(); + BuildUnitTypesByCategoryCache(); + Dictionary<string, UnitType> unitTypesDictionary; + unitTypesByCat.TryGetValue(cat, out unitTypesDictionary); + UnitType[] unitTypesArray; + + if (unitTypesDictionary == null) + { + unitTypesArray = new UnitType[0]; + } + else + { + unitTypesArray = DictionaryUtils.ToArray<string, UnitType>(unitTypesDictionary); + } + + return unitTypesArray; + } + + private void CacheUnitType(UnitType unit) + { + BuildUnitTypesByCategoryCache(); + + foreach (Category cat in unit.Categories) + { + Dictionary<string, UnitType> catUnitTypes = DictionaryUtils.GetValue(unitTypesByCat, cat); + + if (catUnitTypes == null) + { + throw new InvalidFileException(String.Format("Unit type {0} with name {1} is a unit of an undefined category ({2})", unit.ID, unit.Name, cat.ID)); + } + + catUnitTypes.Add(unit.ID, unit); + } + } + + private void BuildUnitTypesByCategoryCache() + { + if (unitTypesByCat == null) + { + DoBuildUnitTypesByCategoryCache(); + } + } + + private void DoBuildUnitTypesByCategoryCache() + { + unitTypesByCat = new Dictionary<Category,Dictionary<string,UnitType>>(); + + foreach (Category category in Categories) + { + unitTypesByCat.Add(category, new Dictionary<string, UnitType>()); + } + + foreach (UnitType unit in unitTypes.Values) + { + CacheUnitType(unit); + } + } + + public UnitType GetUnitType(string id) + { + EnsureFullyLoaded(); + return DictionaryUtils.GetValue(unitTypes, id); + } + + public List<Ability> GetAbilityList() + { + EnsureFullyLoaded(); + List<Ability> items = new List<Ability>(); + items.AddRange(abilities.Values); + return items; + } + + public void AddAbility(Ability newAbility) + { + //TODO: Throw DuplicateItemException + abilities.Add(newAbility.ID, newAbility); + } + + public Ability GetAbility(string id) + { + EnsureFullyLoaded(); + return DictionaryUtils.GetValue(abilities, id); + } + + protected virtual Dictionary<string, UnitType> RaceUnitTypes + { + get { return RaceRawUnitTypes; } + set { RaceRawUnitTypes = value; } + } + + protected virtual Dictionary<string, EquipmentItem> RaceEquipment + { + get { return RaceRawEquipment; } + set { RaceRawEquipment = value; } + } + + protected virtual Dictionary<string, Ability> RaceAbilities + { + get { return RaceRawAbilities; } + set { RaceRawAbilities = value; } + } + + protected Dictionary<string, UnitType> RaceRawUnitTypes + { + get { return unitTypes; } + set { unitTypes = value; } + } + + protected Dictionary<string, EquipmentItem> RaceRawEquipment + { + get { return equipment; } + set { equipment = value; } + } + + protected Dictionary<string, Ability> RaceRawAbilities + { + 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); + } + } + + public ICollection<IRequirement> GetRequirements() + { + ICollection<IRequirement> reqs = new List<IRequirement>(); + + foreach (UnitType unitType in unitTypes.Values) + { + foreach (IRequirement requirement in unitType.GetRequirements()) + { + reqs.Add(requirement); + } + } + + return reqs; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/AbstractRequirement.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,89 @@ +// This file (AbstractRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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.Requirement +{ + public abstract class AbstractRequirement : IRequirement + { + public override bool Equals (object obj) + { + if (obj == null) + { + return false; + } + else if (obj.GetType().Equals(this.GetType())) + { + return TypeEquals(obj); + } + else + { + return false; + } + } + + /// <summary> + /// Type-specific equality checking - must be implemented by each class + /// </summary> + /// <returns> + /// <code>true</code> if this object is equal to <code>obj</code>, else <code>false</code> + /// </returns> + /// <param name='obj'> + /// The object to compare to + /// </param> + protected abstract bool TypeEquals(object obj); + + protected virtual bool IsApplicable(WarFoundryObject toObjectAdded, Army toArmy) + { + return IsApplicable(toArmy) || IsApplicable(toObjectAdded); + } + + protected virtual bool IsApplicable(Army toArmy) + { + return true; + } + + protected virtual bool IsApplicable(WarFoundryObject toObject) + { + return true; + } + + + public string GetValidationMessage(Army army) + { + string message = ""; + + Validation result = ValidatesArmy(army); + if (!Validates.AsOkay(result)) + { + message = GetValidationFailedMessage(army); + } + + return message; + } + + protected abstract string GetValidationFailedMessage(Army army); + + public string GetAllowsAddingMessage(UnitType toAdd, Army toArmy) + { + string message = ""; + + Validation result = AllowsAdding(toAdd, toArmy); + if (!Validates.AsOkay(result)) + { + message = GetAllowsAddingFailedMessage(toAdd, toArmy); + } + + return message; + } + + protected abstract string GetAllowsAddingFailedMessage(UnitType toAdd, Army toArmy); + + public abstract Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy); + + public abstract Validation ValidatesArmy(Army army); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/IRequirement.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,64 @@ +// This file (Requirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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.Requirement +{ + /// <summary> + /// Base interface for a Requirement that constrains the units/equipment that can be taken in an army + /// </summary> + public interface IRequirement + { + /// <summary> + /// Checks whether the supplied WarFoundryObject can be added to the supplied army. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='wfObject'> + /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement + /// </param> + /// <param name='toArmy'> + /// The army to add the object to. + /// </param> + Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy); + + /// <summary> + /// Checks whether the supplied army is currently valid according to this requirement. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='toValidate'> + /// The army to validate + /// </param> + Validation ValidatesArmy(Army army); + + /// <summary> + /// Gets the validation message from validating the army + /// </summary> + /// <returns> + /// A validation message, if the validation fails, else an empty string. + /// </returns> + /// <param name='army'> + /// The army to validate. + /// </param> + string GetValidationMessage(Army army); + + /// <summary> + /// Gets the validation message for adding a unit to the army + /// </summary> + /// <returns> + /// A validation message, if the type cannot be added, else an empty string. + /// </returns> + /// <param name='toAdd'> + /// The unit type to try to add + /// </param> + /// <param name='toArmy'> + /// The army the unit will be added to + /// </param> + string GetAllowsAddingMessage(UnitType toAdd, Army toArmy); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/RequirementHandler.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,66 @@ +// This file (RequirementHandler.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using System.Collections.Generic; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + /// <summary> + /// The requirement handler that tests the validity of armies. + /// </summary> + public class RequirementHandler + { + private RequirementHandler() + { + } + + + public static Validation ValidateArmy(Army army) + { + ICollection<string> ignored; + return ValidateArmy(army, out ignored); + } + + public static Validation ValidateArmy(Army army, out ICollection<string> failureMessages) + { + Validation result = Validation.Passed; + failureMessages = new List<string>(); + + foreach (IRequirement requirement in army.GetRequirements()) + { + if (!Validates.AsOkay(requirement.ValidatesArmy(army))) + { + result = Validation.Failed; + failureMessages.Add(requirement.GetValidationMessage(army)); + } + } + + return result; + } + + public static Validation AllowsAdding(UnitType unitType, Army army) + { + ICollection<string> ignored; + return AllowsAdding(unitType, army, out ignored); + } + + public static Validation AllowsAdding(UnitType unitType, Army army, out ICollection<string> failureMessages) + { + Validation result = Validation.Passed; + failureMessages = new List<string>(); + + foreach (IRequirement requirement in army.GetRequirements()) + { + if (!Validates.AsOkay(requirement.AllowsAdding(unitType, army))) + { + result = Validation.Failed; + failureMessages.Add(requirement.GetAllowsAddingMessage(unitType, army)); + } + } + + return result; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/RequiresAtLeastNUnitsRequirement.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,238 @@ +// This file (UnitRequiresAtLeastNUnitsRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; +using System.Text; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + /// <summary> + /// A requirement where a WarFoundryObject requires at least N units of one or more unit types before any number of that object can be taken in an army. + /// </summary> + public class RequiresAtLeastNUnitsRequirement : AbstractRequirement + { + private List<UnitCountRequirementData> requiredTypes; + + public RequiresAtLeastNUnitsRequirement(params UnitType[] requiredUnitTypes) + { + FailureStringPrefix = "Army must contain: "; + requiredTypes = new List<UnitCountRequirementData>(); + + foreach (UnitType unitType in requiredUnitTypes) + { + AddUnitTypeRequirement(unitType); + } + } + + protected override bool TypeEquals (object obj) + { + RequiresAtLeastNUnitsRequirement otherReq = (RequiresAtLeastNUnitsRequirement)obj; + if (!Collections.Collections.AreEqual(requiredTypes, otherReq.requiredTypes)) + { + return false; + } + else + { + return true; + } + } + + /// <summary> + /// Checks whether the supplied WarFoundryObject can be added to the supplied army. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='wfObject'> + /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement + /// </param> + /// <param name='toArmy'> + /// The army to add the object to. + /// </param> + public override Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy) + { + return IsApplicable(wfObject, toArmy) ? CheckAllowsAdding(wfObject, toArmy) : Validation.NotApplicable; + } + + protected override bool IsApplicable(Army toArmy) + { + return false; + } + + protected override bool IsApplicable(WarFoundryObject toObject) + { + bool isApplicable = false; + UnitType unitType = GetUnitTypeFromObject(toObject); + + if (unitType != null) + { + isApplicable = IsApplicable(unitType); + } + + return isApplicable; + } + + protected UnitType GetUnitTypeFromObject (WarFoundryObject toObject) + { + UnitType unitType = null; + + if (toObject is UnitType) + { + unitType = (UnitType)toObject; + } + else if (toObject is Unit) + { + unitType = ((Unit)toObject).UnitType; + } + + return unitType; + } + + private bool IsApplicable (UnitType unitType) + { + bool isApplicable = false; + foreach (UnitCountRequirementData requirement in requiredTypes) + { + if (requirement.UnitType.Equals(unitType)) + { + isApplicable = true; + break; + } + } + return isApplicable; + } + + private Validation CheckAllowsAdding(WarFoundryObject wfObject, Army toArmy) + { + Validation isValid = Validation.Passed; + + foreach (UnitCountRequirementData requirement in requiredTypes) + { + if (GetUnitTypeCount(toArmy, requirement.UnitType, wfObject) < requirement.Count) + { + isValid = Validation.Failed; + break; + } + } + + return isValid; + } + + private int GetUnitTypeCount(Army toArmy, UnitType unitType, WarFoundryObject wfObject) + { + return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType); + } + + private int GetCountFromObject(WarFoundryObject wfObject, UnitType limitedType) + { + return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0; + } + + /// <summary> + /// Adds a requirement for there to be at least minCount of a given UnitType + /// </summary> + /// <param name='unitType'> + /// The unit type to require. + /// </param> + /// <param name='minCount'> + /// The minimum number of that type that must exist. + /// </param> + public void AddUnitTypeRequirement(UnitType unitType, int minCount) + { + requiredTypes.Add(new UnitCountRequirementData(unitType, minCount)); + } + + /// <summary> + /// Adds a requirement for there to be one or more of a given UnitType + /// </summary> + /// <param name='unitType'> + /// The unit type to require. + /// </param> + public void AddUnitTypeRequirement (UnitType unitType) + { + AddUnitTypeRequirement(unitType, 1); + } + + /// <summary> + /// Checks whether the supplied army is currently valid according to this requirement. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='toValidate'> + /// The army to validate + /// </param> + public override Validation ValidatesArmy(Army toValidate) + { + Validation isValid = Validation.Passed; + + foreach (UnitCountRequirementData requirement in requiredTypes) + { + if (toValidate.GetUnitTypeCount(requirement.UnitType) < requirement.Count) + { + isValid = Validation.Failed; + break; + } + } + + return isValid; + } + + protected string FailureStringPrefix { get; set; } + + protected override string GetValidationFailedMessage(Army army) + { + StringBuilder sb = new StringBuilder(); + sb.Append(FailureStringPrefix); + sb.Append(String.Join("; ", GetFailedRequirements(army).ToArray())); + sb.Append("."); + return sb.ToString(); + } + + private List<string> GetFailedRequirements(Army army) + { + List<string> failures = new List<string>(); + + foreach (UnitCountRequirementData requirement in requiredTypes) + { + int unitCount = army.GetUnitTypeCount(requirement.UnitType); + + if (unitCount < requirement.Count) + { + failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (have " + unitCount + ")"); + } + } + + return failures; + } + + protected override string GetAllowsAddingFailedMessage(UnitType toAdd, Army toArmy) + { + StringBuilder sb = new StringBuilder(); + sb.Append(FailureStringPrefix); + sb.Append(String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray())); + sb.Append("."); + return sb.ToString(); + } + + private List<string> GetFailedAddingRequirements(UnitType unitType, Army army) + { + List<string> failures = new List<string>(); + + foreach (UnitCountRequirementData requirement in requiredTypes) + { + int unitCount = GetUnitTypeCount(army, requirement.UnitType, unitType); + + if (unitCount < requirement.Count) + { + failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")"); + } + } + + return failures; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/RequiresNoMoreThanNOfUnitTypeRequirement.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,178 @@ +// This file (RequiresNoMoreThanNOfUnitTypeRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using IBBoard.WarFoundry.API.Objects; +using System.Collections.Generic; +using System.Text; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + /// <summary> + /// A requirement where a WarFoundryObject cannot be taken in an army if more than N of a UnitType will be in the army. + /// </summary> + public class RequiresNoMoreThanNOfUnitTypeRequirement : AbstractRequirement + { + private List<UnitCountRequirementData> limitedTypes; + + public RequiresNoMoreThanNOfUnitTypeRequirement(params UnitType[] limitedUnitTypes) + { + FailureStringPrefix = "Army cannot contain more than: "; + limitedTypes = new List<UnitCountRequirementData>(); + + foreach (UnitType unitType in limitedUnitTypes) + { + AddUnitTypeRequirement(unitType); + } + } + + /// <summary> + /// Checks whether the supplied WarFoundryObject can be added to the supplied army. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='wfObject'> + /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement + /// </param> + /// <param name='toArmy'> + /// The army to add the object to. + /// </param> + public override Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy) + { + Validation canAdd = Validation.Passed; + + foreach (UnitCountRequirementData limit in limitedTypes) + { + if (GetUnitTypeCount(toArmy, limit.UnitType, wfObject) > limit.Count) + { + canAdd = Validation.Failed; + break; + } + } + + return canAdd; + } + + private int GetUnitTypeCount(Army toArmy, UnitType unitType, WarFoundryObject wfObject) + { + return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType); + } + + private int GetCountFromObject(WarFoundryObject wfObject, UnitType limitedType) + { + return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0; + } + + /// <summary> + /// Adds a requirement for there to be no more than maxCount of a given UnitType + /// </summary> + /// <param name='unitType'> + /// The unit type to limit. + /// </param> + /// <param name='minCount'> + /// The maximum number of that type that must exist. + /// </param> + public void AddUnitTypeRequirement(UnitType unitType, int maxCount) + { + limitedTypes.Add(new UnitCountRequirementData(unitType, maxCount)); + } + + /// <summary> + /// Adds a requirement for there to be none of a given UnitType + /// </summary> + /// <param name='unitType'> + /// The unit type to limit. + /// </param> + public void AddUnitTypeRequirement(UnitType unitType) + { + AddUnitTypeRequirement(unitType, 0); + } + + /// <summary> + /// Checks whether the supplied army is currently valid according to this requirement. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='toValidate'> + /// The army to validate + /// </param> + public override Validation ValidatesArmy(Army army) + { + Validation canAdd = Validation.Passed; + + foreach (UnitCountRequirementData limit in limitedTypes) + { + if (army.GetUnitTypeCount(limit.UnitType) > limit.Count) + { + canAdd = Validation.Failed; + break; + } + } + + return canAdd; + } + + protected override bool TypeEquals(object obj) + { + RequiresNoMoreThanNOfUnitTypeRequirement other = (RequiresNoMoreThanNOfUnitTypeRequirement)obj; + return Collections.Collections.AreEqual(limitedTypes, other.limitedTypes); + } + + protected string FailureStringPrefix { get; set; } + + protected override string GetValidationFailedMessage (Army army) + { + StringBuilder sb = new StringBuilder(); + sb.Append(FailureStringPrefix); + sb.Append(String.Join("; ", GetFailedRequirements(army).ToArray())); + sb.Append("."); + return sb.ToString(); + } + + private List<string> GetFailedRequirements(Army army) + { + List<string> failures = new List<string>(); + + foreach (UnitCountRequirementData requirement in limitedTypes) + { + int unitCount = army.GetUnitTypeCount(requirement.UnitType); + + if (unitCount > requirement.Count) + { + failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (have " + unitCount + ")"); + } + } + + return failures; + } + + protected override string GetAllowsAddingFailedMessage(UnitType toAdd, Army toArmy) + { + StringBuilder sb = new StringBuilder(); + sb.Append(FailureStringPrefix); + sb.Append(String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray())); + sb.Append("."); + return sb.ToString(); + } + + private List<string> GetFailedAddingRequirements(UnitType unitType, Army army) + { + List<string> failures = new List<string>(); + + foreach (UnitCountRequirementData requirement in limitedTypes) + { + int unitCount = GetUnitTypeCount(army, requirement.UnitType, unitType); + + if (unitCount > requirement.Count) + { + failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")"); + } + } + + return failures; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/UnitCountRequirementData.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,53 @@ +// This file (UnitCountRequirementData.cs) is a part of the IBBoard.WarFoundry.API.Tests project and is copyright 2011 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; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + public class UnitCountRequirementData + { + private UnitType unitType; + private int count; + + public UnitCountRequirementData(UnitType unitType, int count) + { + this.unitType = unitType; + this.count = count; + } + + public UnitType UnitType + { + get { return unitType; } + } + + public int Count + { + get { return count; } + } + + public override bool Equals (object obj) + { + if (obj == null) + { + return false; + } + else if (!(obj is UnitCountRequirementData)) + { + return false; + } + else + { + UnitCountRequirementData other = (UnitCountRequirementData)obj; + return UnitType.Equals(other.UnitType) && Count == other.Count; + } + } + + public override int GetHashCode() + { + return UnitType.GetHashCode() + Count; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/UnitRequiresAtLeastNUnitsRequirement.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,44 @@ +// This file (UnitRequiresAtLeastNUnitsRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + /// <summary> + /// A requirement where a UnitType requires at least N units of one or more unit types before any number of that object can be taken in an army. + /// </summary> + public class UnitRequiresAtLeastNUnitsRequirement : RequiresAtLeastNUnitsRequirement + { + private UnitType requirementOnType; + + public UnitRequiresAtLeastNUnitsRequirement(UnitType requirementOn) : base() + { + requirementOnType = requirementOn; + FailureStringPrefix = "Army contains " + requirementOn.Name + " and so must contain: "; + } + + protected override bool IsApplicable(WarFoundryObject toObjectAdded) + { + return base.IsApplicable(toObjectAdded) || IsRequirementOnType(toObjectAdded); + } + + private bool IsRequirementOnType(WarFoundryObject toObjectAdded) + { + return requirementOnType.Equals(toObjectAdded) || (toObjectAdded is Unit && requirementOnType.Equals(((Unit)toObjectAdded).UnitType)); + } + + protected override bool IsApplicable(Army toArmy) + { + return toArmy.GetUnitTypeCount(requirementOnType) > 0; + } + + public override Validation ValidatesArmy(Army toArmy) + { + return IsApplicable(toArmy) ? base.ValidatesArmy(toArmy) : Validation.NotApplicable; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/UnitRequiresNoMoreThanNOfUnitTypeRequirement.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,59 @@ +// This file (UnitRequiresAtLeastNUnitsRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + /// <summary> + /// A requirement where a UnitType can only be taken if there are no more than N units of one or more unit in an army. + /// </summary> + public class UnitRequiresNoMoreThanNOfUnitTypeRequirement : RequiresNoMoreThanNOfUnitTypeRequirement + { + private UnitType requirementOnType; + + public UnitRequiresNoMoreThanNOfUnitTypeRequirement(UnitType requirementOn) : base() + { + requirementOnType = requirementOn; + FailureStringPrefix = "Army contains " + requirementOn.Name + " and so cannot contain more than: "; + } + + /// <summary> + /// Checks whether the supplied WarFoundryObject can be added to the supplied army. + /// </summary> + /// <returns> + /// A <code>Validation</code> enum to show the result of the validation + /// </returns> + /// <param name='wfObject'> + /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement + /// </param> + /// <param name='toArmy'> + /// The army to add the object to. + /// </param> + public override Validation AllowsAdding(WarFoundryObject wfObject, Army toArmy) + { + return IsApplicable(wfObject, toArmy) ? base.AllowsAdding(wfObject, toArmy) : Validation.NotApplicable; + } + + + private bool IsApplicable(WarFoundryObject toObject, Army toArmy) + { + return IsApplicable(toArmy) || IsApplicable(toObject); + } + + + private bool IsApplicable(Army toArmy) + { + return toArmy.GetUnitTypeCount(requirementOnType) > 0; + } + + + private bool IsApplicable(WarFoundryObject toObject) + { + return requirementOnType.Equals(toObject) || (toObject is Unit && requirementOnType.Equals(((Unit)toObject).UnitType)); + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/Validation.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,54 @@ +// This file (Validation.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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.Requirement +{ + /// <summary> + /// A custom enum for validation to distinguish between "validation wasn't necessary" and "validation passed". + /// This should allow for easier handling of failed requirements later being satisfied. + /// </summary> + public enum Validation + { + Passed = 1, + Failed = 2, + NotApplicable = 3 + } + + /// <summary> + /// A helper class to handle the enums and treat them as booleans where a pass/fail is all that is necessary. + /// </summary> + public class Validates + { + /// <summary> + /// Checks if the validation was okay (pass or not applicable) + /// </summary> + /// <returns> + /// <code>true</code> if the validation passed or was not applicable, else <code>false</code> + /// </returns> + /// <param name='passed'> + /// The Validation enum value to check + /// </param> + public static bool AsOkay(Validation result) + { + return (result & Validation.Passed) == Validation.Passed; + } + + /// <summary> + /// Checks if the validation result was not okay (failed or not applicable). Note that this is different + /// to <code>!Validates.AsOkay(result)</code> because this method treats not applicable as not being okay. + /// </summary> + /// <returns> + /// <code>true</code> if the validation failed or was not applicable, else <code>false</code> + /// </returns> + /// <param name='result'> + /// The Validation enum value to check + /// </param> + public static bool AsNotOkay (Validation result) + { + return (result & Validation.Failed) == Validation.Failed; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Stat.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,40 @@ +// This file (Stat.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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> + /// Summary description for Stat. + /// </summary> + public class Stat + { + private StatSlot parentStatSlot; + private string statString; + + public Stat(StatSlot parentSlot, string statValue) + { + parentStatSlot = parentSlot; + statString = statValue; + } + + public StatSlot ParentSlot + { + get { return parentStatSlot; } + set { parentStatSlot = value; } + } + + public string ParentSlotName + { + get { return ParentSlot.Name; } + } + + public string SlotValueString + { + get { return statString; } + set { statString = (value == null ? "" : value); } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/StatSlot.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,37 @@ +// This file (StatSlot.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Text.RegularExpressions; +using System.Xml; +using IBBoard; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for StatSlot. + /// </summary> + public class StatSlot + { + private string name; + private SystemStats sysStats; + + public StatSlot(String statName) + { + name = statName; + } + + public string Name + { + get { return name; } + set { value = name; } + } + + public SystemStats SystemStats + { + get { return sysStats; } + set { sysStats = value; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Stats.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,104 @@ +// This file (Stats.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Stats defines the statistic/attribute values for an entity (for example a unit or any of their equipment that has a stat line) paired against a <see cref=" SystemStats"/> stat line definition. + /// </summary> + public class Stats + { + private List<Stat> stats; + private SystemStats sysStats; + + public Stats(SystemStats systemStats) + { + sysStats = systemStats; + int statCount = sysStats.SlotCount; + stats = new List<Stat>(statCount); + + foreach (StatSlot slot in sysStats.StatSlots) + { + stats.Add(new Stat(slot, "")); + } + } + + public Stat[] StatsArray + { + get { return stats.ToArray(); } + } + + public void SetStatValue(string statName, string statValue) + { + StatSlot slot = sysStats[statName.ToLower()]; + + if (slot!=null) + { + int pos = sysStats.GetStatSlotPosition(slot); + + if (pos > -1) + { + stats[pos] = new Stat(slot, statValue); + } + } + } + + public Stat this[string id] + { + get + { + StatSlot slot = sysStats[id.ToLower()]; + int pos = sysStats.GetStatSlotPosition(slot); + Stat stat = null; + + try + { + stat = this[pos]; + } + catch (ArgumentException ex) + { + throw new ArgumentException(String.Format("Invalid statistic ID {0} for stats based on system stats set {1}", new object[]{id, sysStats.ID}), ex); + } + + return stat; + } + } + + public Stat this[int pos] + { + get + { + if (pos < stats.Count && pos >= 0) + { + return stats[pos]; + } + else + { + throw new ArgumentException(String.Format("Invalid statistic position {0} for stats based on system stats set {1}", new object[]{pos, sysStats.ID})); + } + } + } + + public string GetStatValue(string id) + { + return this[id.ToLower()].SlotValueString; + } + + public int StatCount + { + get { return stats.Count; } + } + + public string StatsID + { + get + { + return sysStats.ID; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/SystemStats.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,71 @@ +// This file (SystemStats.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// SystemStats defines the available statistics/attributes that entity types can use (either a unit or an equipment item that has a stats line). Statistic/attribute values will be defined by a <see cref="Stats"/> object. + /// </summary> + public class SystemStats + { + private Dictionary<string, StatSlot> statsByName; + private List<StatSlot> stats; + private string id; + + public SystemStats(string statsID) + { + id = statsID; + statsByName = new Dictionary<string, StatSlot>(); + stats = new List<StatSlot>(); + } + + public void AddStatSlot(string slotName) + { + StatSlot slot = new StatSlot(slotName); + slot.SystemStats = this; + statsByName[slot.Name.ToLower()] = slot; + stats.Add(slot); + } + + public StatSlot[] StatSlots + { + get + { + return stats.ToArray(); + } + } + + public StatSlot this[string statName] + { + get + { + return DictionaryUtils.GetValue(statsByName, statName.ToLower()); + } + } + + public int GetStatSlotPosition(StatSlot slot) + { + return stats.IndexOf(slot); + } + + public void RemoveStatSlot(string name) + { + statsByName.Remove(name); + stats.Remove(this[name]); + } + + public int SlotCount + { + get { return stats.Count; } + } + + public string ID + { + get { return id; } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Unit.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,544 @@ +// This file (Unit.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 2007, 2008, 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; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using IBBoard.Lang; +using IBBoard.Limits; +using IBBoard.WarFoundry.API.Util; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for UnitInstance. + /// </summary> + public class Unit : WarFoundryObject, ICostedWarFoundryObject + { + private UnitType type; + private int size; + private Unit parentUnit; + private double points; + private ArmyCategory cat; + private Dictionary<UnitEquipmentItem, AbstractUnitEquipmentItemSelection> equipment = new Dictionary<UnitEquipmentItem, AbstractUnitEquipmentItemSelection>(); + private Dictionary<string, List<AbstractUnitEquipmentItemSelection>> equipmentSlots = new Dictionary<string, List<AbstractUnitEquipmentItemSelection>>(); + private List<Unit> containedUnits = new List<Unit>(); + + public event DoubleValChangedDelegate PointsValueChanged; + public event IntValChangedDelegate UnitSizeChanged; + public event DoubleValChangedDelegate UnitEquipmentAmountChanged; + + public Unit(UnitType unitType, ArmyCategory parentArmyCat) : this(unitType, unitType.MinSize, parentArmyCat) + { + //Do nothing extra + } + + public Unit(UnitType unitType, int startSize, ArmyCategory parentArmyCat) : this("", "", startSize, unitType, parentArmyCat) + { + SetInitialEquipment(); + UnitSizeChanged += new IntValChangedDelegate(RefreshUnitEquipmentAmounts); + } + + public Unit(string id, string name, int startSize, UnitType unitType, ArmyCategory parentArmyCat) : base(id, name) + { + Category = parentArmyCat; + type = unitType; + Size = startSize; + CalcCost(); + UnitEquipmentAmountChanged += new DoubleValChangedDelegate(UnitEquipmentAmountChangedHandler); + UnitSizeChanged += new IntValChangedDelegate(UnitSizeChangedHandler); + Translation.TranslationChanged += HandleTranslationChanged; + } + + private void UnitEquipmentAmountChangedHandler(WarFoundryObject obj, double oldVal, double newVal) + { + CalcCost(); + } + + private void UnitSizeChangedHandler(WarFoundryObject obj, int oldVal, int newVal) + { + CalcCost(); + + if (HasDefaultName()) + { + OnNameChanged("", Name); + } + } + + protected override string DefaultName() + { + if (type != null) + { + if (size == 1) + { + return type.Name; + } + else + { + return String.Format(Translation.GetTranslation("defaultUnitName"), size, type.Name); + } + } + else + { + return "Unknown Unit"; + } + } + + private void HandleTranslationChanged() + { + if (type != null && HasDefaultName() && size != 1) + { + OnNameChanged(null, DefaultName()); + } + } + + private void SetInitialEquipment() + { + foreach (UnitEquipmentItem unitEquip in UnitType.GetEquipmentItems()) + { + if (unitEquip.IsRequired) + { + if (CanEquipWithItem(unitEquip)) + { + ILimit minLimit = unitEquip.MinLimit; + + if (minLimit is IPercentageLimit) + { + SetEquipmentRatio(unitEquip, UnitEquipmentUtil.GetMinEquipmentPercentage(this, unitEquip)); + } + else + { + SetEquipmentAmount(unitEquip, UnitEquipmentUtil.GetMinEquipmentCount(this, unitEquip)); + } + } + } + } + } + + private void CalcCost() + { + double oldpoints = points; + points = type.CostPerTrooper * AdditionalTroopers + type.BaseUnitCost; + + foreach (AbstractUnitEquipmentItemSelection equipSelection in equipment.Values) + { + points += equipSelection.TotalCost; + } + + if (oldpoints != points) + { + OnPointsValueChanged(oldpoints, points); + } + } + + public int AdditionalTroopers + { + get { return Math.Max(Size - type.BaseSize, 0); } + } + + public int Size + { + get { return size; } + set + { + if (value != size) + { + int oldValue = size; + size = (value > 0 ? value : 1); + OnUnitSizeChanged(oldValue, size); + } + } + } + + public UnitType UnitType + { + get { return type; } + } + + public Army Army + { + get { return (Category == null ? null : Category.ParentArmy); } + } + + public Race Race + { + get { return UnitType.Race; } + } + + public ArmyCategory Category + { + get + { + return cat; + } + set { cat = value; } + } + + public double Points + { + get + { + if (points == 0) + { + CalcCost(); + } + + return points; + } + } + + public Unit[] ContainedUnits + { + get { return containedUnits.ToArray(); } + } + + public void AddContainedUnit(Unit unit) + { + if (UnitType.CanContainUnit(unit)) + { + if (!containedUnits.Contains(unit)) + { + containedUnits.Add(unit); + } + + unit.ParentUnit = this; + } + else + { + throw new InvalidContainershipException(this, unit); + } + } + + public void RemoveContainedUnit(Unit unit) + { + containedUnits.Remove(unit); + } + + public Unit ParentUnit + { + get { return parentUnit; } + set + { + if (!(parentUnit == value || (parentUnit != null && parentUnit.Equals(value)))) + { + parentUnit = value; + + if (value != null) + { + value.AddContainedUnit(this); + } + } + } + } + + public UnitEquipmentItem[] GetEquipment() + { + return DictionaryUtils.ToKeyArray(equipment); + } + + public EquipmentItem[] GetRequiredEquipment() + { + List<EquipmentItem> list = new List<EquipmentItem>(); + + foreach (UnitEquipmentItem item in GetEquipment()) + { + if (item.IsRequired) + { + list.Add(item.EquipmentItem); + } + } + + return list.ToArray(); + } + + internal AbstractUnitEquipmentItemSelection GetEquipmentSelection(UnitEquipmentItem item) + { + return DictionaryUtils.GetValue(equipment, item); + } + + public void SetEquipmentAmount(UnitEquipmentItem equip, int amount) + { + if (amount < 1 && amount != WarFoundryCore.INFINITY) + { + amount = 0; + } + + if (amount == 0) + { + RemoveEquipmentItem(equip); + } + else + { + AbstractUnitEquipmentItemSelection currSelection = DictionaryUtils.GetValue(equipment, equip); + double oldAmount = (currSelection == null ? 0 : currSelection.AmountTaken); + + if (amount != oldAmount) + { + if (oldAmount == 0) + { + AddEquipmentAmount(equip, amount); + } + else if (currSelection is UnitEquipmentNumericSelection) + { + //A UnitEquipmentItem shouldn't change its IsRatio value, so assume we already have the right sub-type + currSelection.AmountTaken = amount; + } + else + { + RemoveEquipmentItem(equip); + AddEquipmentAmount(equip, amount); + } + + OnUnitEquipmentAmountChanged(equip, oldAmount, amount); + } + } + } + + private void AddEquipmentAmount(UnitEquipmentItem equip, int amount) + { + AbstractUnitEquipmentItemSelection newItem = new UnitEquipmentNumericSelection(this, equip, amount); + equipment[equip] = newItem; + List<AbstractUnitEquipmentItemSelection> selections = DictionaryUtils.GetValue(equipmentSlots, equip.SlotName); + + if (selections == null) + { + selections = new List<AbstractUnitEquipmentItemSelection>(); + equipmentSlots[equip.SlotName] = selections; + } + + selections.Add(newItem); + } + + public void SetEquipmentRatio(UnitEquipmentItem equip, double ratio) + { + if (!equip.IsRatioLimit) + { + throw new InvalidOperationException("Equipment with ID " + equip.ID + " for unit of type " + UnitType.ID + " has an absolute limit, not a ratio limit"); + } + + if (ratio > 100) + { + ratio = 100; + } + else if (ratio < 0) + { + ratio = 0; + } + + if (ratio == 0) + { + RemoveEquipmentItem(equip); + } + else + { + AbstractUnitEquipmentItemSelection currSelection = DictionaryUtils.GetValue(equipment, equip); + double oldRatio = (currSelection == null ? 0 : currSelection.AmountTaken); + + if (ratio != oldRatio) + { + if (oldRatio == 0) + { + AddEquipmentRatio(equip, ratio); + } + else if (currSelection is UnitEquipmentRatioSelection) + { + currSelection.AmountTaken = ratio; + } + else + { + RemoveEquipmentItem(equip); + AddEquipmentRatio(equip, ratio); + } + + OnUnitEquipmentAmountChanged(equip, oldRatio, ratio); + } + } + } + + private void AddEquipmentRatio(UnitEquipmentItem equip, double ratio) + { + UnitEquipmentRatioSelection newItem = new UnitEquipmentRatioSelection(this, equip, ratio); + equipment[equip] = newItem; + List<AbstractUnitEquipmentItemSelection> selections = DictionaryUtils.GetValue(equipmentSlots, equip.SlotName); + + if (selections == null) + { + selections = new List<AbstractUnitEquipmentItemSelection>(); + equipmentSlots[equip.SlotName] = selections; + } + + selections.Add(newItem); + } + + private void RemoveEquipmentItem(UnitEquipmentItem equip) + { + double oldAmount = UnitEquipmentUtil.GetEquipmentAmount(this, equip); + + if (oldAmount != 0) + { + AbstractUnitEquipmentItemSelection selection = DictionaryUtils.GetValue(equipment, equip); + equipment.Remove(equip); + List<AbstractUnitEquipmentItemSelection> slotSelections = DictionaryUtils.GetValue(equipmentSlots, equip.SlotName); + slotSelections.Remove(selection); + OnUnitEquipmentAmountChanged(equip, oldAmount, 0); + } + } + + public bool CanEquipWithItem(UnitEquipmentItem item) + { + string[] mutexes = item.MutexGroups; + bool canEquip = false; + + if (mutexes.Length == 0) + { + canEquip = true; + } + else + { + canEquip = UnitEquipmentUtil.GetBlockingEquipmentItems(this, item).Count == 0; + } + + return canEquip; + } + + public bool CanEquipWithItem(string equipID) + { + return CanEquipWithItem(UnitType.GetEquipmentItem(equipID)); + } + + private void OnPointsValueChanged(double oldValue, double newValue) + { + if (PointsValueChanged != null) + { + PointsValueChanged(this, oldValue, newValue); + } + } + + private void OnUnitSizeChanged(int oldValue, int newValue) + { + if (UnitSizeChanged != null) + { + UnitSizeChanged(this, oldValue, newValue); + } + } + + private void OnUnitEquipmentAmountChanged(UnitEquipmentItem equip, double oldValue, double newValue) + { + if (UnitEquipmentAmountChanged != null) + { + UnitEquipmentAmountChanged(equip, oldValue, newValue); + } + } + + public Stat[][] UnitStatsArrays + { + get { return UnitType.UnitStatsArrays; } + } + + public Stat[][] UnitStatsArraysWithName + { + get { return UnitType.UnitStatsArraysWithName; } + } + + public string[] UnitStatsArrayIDs + { + get + { + return UnitType.UnitStatsArrayIDs; + } + } + + public string GetStatValue(string statName) + { + return UnitType.GetStatValue(statName); + } + + public int GetEquipmentAmountInSlot(string slotName) + { + int amount = 0; + + List<AbstractUnitEquipmentItemSelection> selections = GetEquipmentSlotSelections(slotName); + + if (selections != null) + { + amount = GetSelectionTotal(selections); + } + + return amount; + } + + internal List<AbstractUnitEquipmentItemSelection> GetEquipmentSlotSelections(string slotName) + { + return DictionaryUtils.GetValue(equipmentSlots, slotName); + } + + /// <summary> + /// Gets the total amount of items taken for the item's slot, excluding the provided item + /// </summary> + /// <param name="item">the item to exclude from the count</param> + /// <returns>the total number of items</returns> + public int GetEquipmentAmountInSlotExcludingItem(UnitEquipmentItem item) + { + int amount = 0; + + List<AbstractUnitEquipmentItemSelection> selections = DictionaryUtils.GetValue(equipmentSlots, item.SlotName); + + if (selections != null) + { + selections = new List<AbstractUnitEquipmentItemSelection>(selections); + RemoveSelectionFromList(item, selections); + amount = GetSelectionTotal(selections); + } + + return amount; + } + + private void RemoveSelectionFromList(UnitEquipmentItem item, List<AbstractUnitEquipmentItemSelection> selections) + { + AbstractUnitEquipmentItemSelection selection = GetEquipmentSelection(item); + + if (selection != null) + { + selections.Remove(selection); + } + } + + private int GetSelectionTotal(List<AbstractUnitEquipmentItemSelection> selections) + { + int amount = 0; + + foreach (AbstractUnitEquipmentItemSelection selection in selections) + { + amount += selection.NumberTaken; + } + + return amount; + } + + /// <summary> + /// Default stub implementation of getting the unit's abilities - defaults to just the unit type's required abilities until we get a way to modify them + /// </summary> + public ICollection<Ability> Abilities + { + get + { + return UnitType.GetRequiredAbilities(); + } + } + + private void RefreshUnitEquipmentAmounts(WarFoundryObject obj, int oldValue, int newValue) + { + foreach (UnitEquipmentItem item in equipment.Keys) + { + AbstractUnitEquipmentItemSelection selection = equipment[item]; + + if (selection is UnitEquipmentRatioSelection) + { + OnUnitEquipmentAmountChanged(item, selection.AmountTaken, selection.AmountTaken); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/UnitEquipmentItem.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,248 @@ +// This file (UnitEquipmentItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.CustomMath; +using IBBoard.Limits; +using IBBoard.WarFoundry.API.Util; +using IBBoard.Lang; +//using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for UnitEquipmentItem. + /// </summary> + public class UnitEquipmentItem : WarFoundryObject + { + private EquipmentItem item; + private bool required; + private bool roundUp; + private double costMultiplier; + private RoundType roundType; + private string[] mutexGroups; + private UnitType unitType; + private string slotName = ""; + private ILimit minLimit; + private ILimit maxLimit; + public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) + : this(equipmentItem, equipmentFor, new string[0]) + { + //Do nothing extra + } + + public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor, params string[] mutexGroups) + { + item = equipmentItem; + unitType = equipmentFor; + this.mutexGroups = mutexGroups; + unitType.AddEquipmentItem(this); + } + + public override string Name + { + get + { + return item.Name; + } + set + { + base.Name = value; + } + } + + public override string ID + { + get + { + return (EquipmentForUnit == null ? base.ID : EquipmentForUnit.ID) + EquipmentItemID; + } + set + { + base.ID = value; + } + } + + public string EquipmentItemID + { + get { return item.ID; } + } + + public double Cost + { + get + { + return IBBMath.Round(EquipmentItem.Cost * CostMultiplier, CostRoundType); + } + } + + public double CostMultiplier + { + get { return costMultiplier; } + set + { + costMultiplier = value; + } + } + + public RoundType CostRoundType + { + get { return roundType; } + set + { + roundType = value; + } + } + + public bool IsRequired + { + get { return required; } + set { required = value; } + } + + public bool RoundNumberUp + { + get { return roundUp; } + set { roundUp = value; } + } + + public GameSystem GameSystem + { + get { return EquipmentItem.GameSystem; } + } + + public String[] MutexGroups + { + get { return (string[]) mutexGroups.Clone(); } + } + + public UnitType EquipmentForUnit + { + get { return unitType; } + } + + public bool IsRatioLimit + { + get { return MinLimit is IPercentageLimit && MaxLimit is IPercentageLimit; } + } + + /// <summary> + /// Gets the Limit object for the minimum number of items that can be taken + /// </summary> + public ILimit MinLimit + { + get + { + ILimit limit = minLimit; + + if (limit == null) + { + if (maxLimit != null) + { + limit = maxLimit; + } + else + { + limit = new SimpleRoundedPercentageLimit(100, false); + } + } + + return limit; + } + set + { + if (value != null) + { + minLimit = value; + } + } + } + + /// <summary> + /// Gets the Limit object for the maximum number of items that can be taken + /// </summary> + public ILimit MaxLimit + { + get + { + ILimit limit = maxLimit; + + if (limit == null) + { + if (minLimit != null) + { + limit = minLimit; + } + else + { + limit = new SimpleRoundedPercentageLimit(100, false); + } + } + + return limit; + } + set + { + if (value != null) + { + maxLimit = value; + } + } + } + + public EquipmentItem EquipmentItem + { + get { return item; } + } + + public override string ToString() + { + return Translation.GetTranslation("UnitEquipmentItemName", "{0} ({1}{2} each)", Name, Cost, GameSystem.GetPointsAbbrev(Cost)); + } + + public bool HasAlternatives() + { + if (MutexGroups.Length == 0) + { + return false; + } + else if (EquipmentForUnit == null) + { + return false; + } + else + { + //If the number of items in the MutEx group is greater than one then it must be this item plus another + return EquipmentForUnit.GetEquipmentItemsByExclusionGroups(MutexGroups).Length > 1; + } + } + + public string Description + { + get { return EquipmentItem.Description; } + } + + public Race EquipmentForRace + { + get { return EquipmentItem.EquipmentForRace; } + } + + public bool CanBeUsedWithItem(EquipmentItem item) + { + return EquipmentItem.CanBeUsedWithItem(item); + } + + public string SlotName + { + get { return slotName; } + set + { + if (value != null && value != "") + { + slotName = value; + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/UnitEquipmentNumericSelection.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,40 @@ +// This file (UnitEquipmentNumericSelection.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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> + /// An object to hold the selection of a unit's equipment where the selection was made as an absolute number + /// </summary> + public class UnitEquipmentNumericSelection : AbstractUnitEquipmentItemSelection + { + public UnitEquipmentNumericSelection(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item, amount) + { + } + + public UnitEquipmentNumericSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, item.MinLimit.GetLimit(unit.Size)) + { + } + + public override int NumberTaken + { + get + { + return (int) AmountTaken; + } + } + + protected bool IsWholeNumber(double newValue) + { + return newValue == Math.Round(newValue); + } + + protected override bool IsValidValue (double newValue) + { + return base.IsValidValue(newValue) && IsWholeNumber(newValue); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/UnitEquipmentRatioSelection.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,43 @@ +// This file (UnitEquipmentRatioSelection.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using IBBoard.CustomMath; +using IBBoard.Limits; +using IBBoard.WarFoundry.API.Util; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// An object to hold the selection of a unit's equipment where the selection was made as a percentage or ratio + /// of the total size of the unit + /// </summary> + public class UnitEquipmentRatioSelection : AbstractUnitEquipmentItemSelection + { + public UnitEquipmentRatioSelection(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item, amount) + { + } + + public UnitEquipmentRatioSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, ((IPercentageLimit)item.MinLimit).Percentage) + { + } + + public override int NumberTaken + { + get + { + return CalculateNumberTaken (EquipmentForUnit, EquipmentItem, AmountTaken); + } + } + + internal static int CalculateNumberTaken (Unit unit, UnitEquipmentItem item, double ratioTaken) + { + double exactNumberTaken = (ratioTaken / 100) * unit.Size; + int wholeNumberTaken = (int)IBBMath.Round (exactNumberTaken, item.RoundNumberUp); + int maxTaken = UnitEquipmentUtil.GetMaxEquipmentCount (unit, item); + int minTaken = UnitEquipmentUtil.GetMinEquipmentCount (unit, item); + return Math.Min (Math.Max (wholeNumberTaken, minTaken), maxTaken); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/UnitMemberType.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,53 @@ +// 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; + } + + public string StatsID + { + get + { + return stats.StatsID; + } + } + + /// <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; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/UnitType.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,594 @@ +// This file (UnitType.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.Collections.Generic; +using System.Xml; +using IBBoard.Limits; +using IBBoard.Logging; +using IBBoard.WarFoundry.API.Objects.Requirement; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// A UnitType is a type for a <see cref=" Unit"/>, normally relating to an entry in an army list. The UnitType defines the name, cost, minimum and maximum limits of a unit, and the equipment units of the type can take. + /// </summary> + public class UnitType : WarFoundryObject + { + private Category mainCat; + private Race race; + private int min = 0; + private int max = WarFoundryCore.INFINITY; + private int baseSize = 0; + private int minSize, maxSize; + private double baseUnitCost; + private double costPerTrooper; + private Stats stats; + private List<IRequirement> requirements = new List<IRequirement>(); + private Dictionary<string, UnitEquipmentItem> equipment = new Dictionary<string, UnitEquipmentItem>(); + private Dictionary<string, List<UnitEquipmentItem>> equipmentExclusionGroups = new Dictionary<string, List<UnitEquipmentItem>>(); + private List<string> equipmentKeyOrder = new List<string>(); + private Dictionary<string, Ability> requiredAbilities = new Dictionary<string, Ability>(); + private Dictionary<string, Ability> optionalAbilities = new Dictionary<string, Ability>(); + private String notes = ""; + private List<UnitType> containedTypes = new List<UnitType>(); + private Dictionary<string, string> extraData = new Dictionary<string, string>(); + private Dictionary<string, ILimit> slotLimits = new Dictionary<string, ILimit>(); + private Dictionary<string, UnitMemberType> unitMemberTypes = new Dictionary<string, UnitMemberType>(); + private List<Category> cats = new List<Category>(); + + + public UnitType(string id, string typeName, Race parentRace) : base(id, typeName) + { + race = parentRace; + } + + public override bool Equals (object obj) + { + if (obj == null) + { + return false; + } + else if (!(obj is UnitType)) + { + return false; + } + else + { + UnitType other = (UnitType)obj; + + if (!ID.Equals(other.ID) || !Name.Equals(other.Name) || !Race.Equals(other.Race)) + { + return false; + } + else + { + return true; + } + } + } + + public GameSystem GameSystem + { + get { return Race.GameSystem; } + } + + /// <value> + /// Gets the <see cref=" Race"/> that this unit belongs to. + /// </value> + public Race Race + { + get { return race; } + } + + /// <value> + /// Gets or sets the default <see cref=" Category"/> that this unit type is a member of. + /// If it is not already in the collection of categories then it will be added. + /// </value> + public virtual Category MainCategory + { + get + { + return mainCat; + } + set + { + mainCat = value; + AddCategory(value); + } + } + /// <summary> + /// Gets the collection of <see cref="Category"/> objects that this UnitType can be a member of + /// </summary> + public Category[] Categories + { + get + { + return cats.ToArray(); + } + } + + /// <summary> + /// Adds a category to the set of categories that this unit can be taken from. The first category added will automatically become the MainCategory. + /// </summary> + /// <param name="cat"> + /// A <see cref="Category"/> that this unit can be taken from + /// </param> + public void AddCategory(Category cat) + { + if (!cats.Contains(cat)) + { + cats.Add(cat); + + if (MainCategory == null) + { + MainCategory = cat; + } + } + } + + /// <value> + /// Gets or sets the minimum size of each unit of this type. Note: This should be set AFTER MaxSize, otherwise an unintended default value may be set for the minimum + /// </value> + public int MinSize + { + get { return minSize; } + set + { + minSize = (value >= 0 ? value : 0); + CheckMinimumSize(); + } + } + + /// <value> + /// Gets or sets the maximum size of each unit of this type. Note: This should be set BEFORE MinSize, otherwise an unintended default value may be set for the minimum + /// </value> + public int MaxSize + { + get { return maxSize; } + set + { + maxSize = (value >= 0 ? value : WarFoundryCore.INFINITY); + CheckMinimumSize(); + } + } + + /// <value> + /// Gets or sets the minimum number of units of this type that must be taken in an army. Note: This should be set AFTER MaxNumber, otherwise an unintended default value may be set for the minimum + /// </value> + public int MinNumber + { + get { return min; } + set + { + min = (value >= 0 ? value : 0); + CheckMinimumNumber(); + } + } + + /// <value> + /// Gets or sets the maximum number of units of this type that can be taken in an army. Note: This should be set BEFORE MinNumber, otherwise an unintended default value may be set for the minimum + /// </value> + public int MaxNumber + { + get { return max; } + set + { + max = (value >= 0 ? value : WarFoundryCore.INFINITY); + CheckMinimumNumber(); + } + } + + /// <summary> + /// Makes sure that the minimum number isn't more than the maximum number, hence the warning on the properties + /// </summary> + private void CheckMinimumNumber() + { + if (MinNumber > MaxNumber && MaxNumber!=WarFoundryCore.INFINITY) + { + MinNumber = MaxNumber; + LogNotifier.WarnFormat(GetType(), "Unit type {0} ({1}) had a minimum number greater than their maximum number.", Name, ID); + } + } + + /// <summary> + /// Makes sure that the minimum unit size isn't more than the maximum unit size, hence the warning on the properties + /// </summary> + private void CheckMinimumSize() + { + if (MinSize > MaxSize && MaxSize!=WarFoundryCore.INFINITY) + { + MinSize = MaxSize; + LogNotifier.WarnFormat(GetType(), "Unit type {0} ({1}) had a minimum size greater than their maximum size.", Name, ID); + } + } + + //// <value> + /// Gets or sets the "base size" of a unit, which is the number of troopers the unit has in it for its "base cost". For a lot of units this value will be 0 as the cost is worked out based on the total number of members. + /// </value> + public int BaseSize + { + get { return baseSize; } + set { baseSize = (value >= 0 ? value : 0); } + } + + /// <value> + /// The number of points that a "base unit" of <code>BaseSize</code> models costs. Additional models are charged at <code>CostPerTrooper</code> each. + /// </value> + public double BaseUnitCost + { + get { return baseUnitCost; } + set { baseUnitCost = (value >= 0 ? value : 0); } + } + + //// <value> + /// The cost of an individual trooper. This value is the cost for a basic trooper without weapons, which are added on top of the cost before calculating a unit cost. + /// </value> + public double CostPerTrooper + { + get { return costPerTrooper; } + set { costPerTrooper = (value >= 0 ? value : 0); } + } + + protected override string DefaultName() + { + throw new InvalidOperationException("Unit type with id "+id+" did not have a name specified"); + } + + /// <value> + /// The array of <see cref="Stat"/>s for each of the unit's stat lines + /// </value> + public Stat[][] UnitStatsArrays + { + get + { + Stat[][] statsArray; + + if (stats != null) + { + statsArray = new Stat[][]{ stats.StatsArray }; + } + else if (unitMemberTypes.Count > 0) + { + int memTypeCount = unitMemberTypes.Count; + statsArray = new Stat[memTypeCount][]; + int i = 0; + + foreach (UnitMemberType memType in unitMemberTypes.Values) + { + statsArray[i] = memType.StatsArray; + i++; + } + } + else + { + SystemStats systemStats = GameSystem.StandardSystemStats; + Stats tempStats = new Stats(systemStats); + statsArray = new Stat[][]{ tempStats.StatsArray }; + } + + return statsArray; + } + } + + public string[] UnitStatsArrayIDs + { + get + { + string[] ids; + + if (stats != null) + { + ids = new string[]{ stats.StatsID }; + } + else if (unitMemberTypes.Count > 0) + { + ids = new string[unitMemberTypes.Count]; + int i = 0; + + foreach (UnitMemberType memType in unitMemberTypes.Values) + { + ids[i] = memType.StatsID; + i++; + } + } + else + { + ids = new string[]{ GameSystem.StandardSystemStatsID }; + } + + return ids; + } + } + + //// <value> + /// The array of <see cref="Stat"/>s for each of the unit's stat lines including an additional column that contains the unit type name + /// </value> + public Stat[][] UnitStatsArraysWithName + { + get + { + Stat[][] statsArray; + + if (stats != null) + { + statsArray = new Stat[][]{ ExtendStatsArrayWithName(stats.StatsArray) }; + } + else if (unitMemberTypes.Count > 0) + { + int memTypeCount = unitMemberTypes.Count; + statsArray = new Stat[memTypeCount][]; + int i = 0; + + foreach (UnitMemberType memType in unitMemberTypes.Values) + { + statsArray[i] = memType.StatsArrayWithName; + i++; + } + } + else + { + SystemStats systemStats = GameSystem.StandardSystemStats; + Stats tempStats = new Stats(systemStats); + statsArray = new Stat[][]{ 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) + { + stats = newStats; + } + + public string GetStatValue(string statName) + { + return stats.GetStatValue(statName.ToLower()); + } + + internal void AddEquipmentItem(UnitEquipmentItem item) + { + if (!equipment.ContainsKey(item.ID)) + { + equipment.Add(item.ID, item); + equipmentKeyOrder.Add(item.ID); + AddToMutexGroups(item); + } + } + + private void AddToMutexGroups(UnitEquipmentItem item) + { + string[] mutexGroups = item.MutexGroups; + + foreach (string mutexGroup in mutexGroups) + { + List<UnitEquipmentItem> items = DictionaryUtils.GetValue(equipmentExclusionGroups, mutexGroup); + + if (items == null) + { + items = new List<UnitEquipmentItem>(); + equipmentExclusionGroups.Add(mutexGroup, items); + } + + items.Add(item); + } + } + + /// <summary> + /// Gets a <see cref="UnitEquipmentItem"/> for the given ID string, or <code>null</code> if nothing exists for that ID + /// </summary> + /// <param name="id"> + /// The ID of the UnitEquipmentItem to get + /// </param> + /// <returns> + /// The <see cref="UnitEquipmentItem"/> for the given ID string, or <code>null</code> if nothing exists for that ID + /// </returns> + public UnitEquipmentItem GetEquipmentItem(string id) + { + return DictionaryUtils.GetValue(equipment, id); + } + + /// <summary> + /// Gets a <see cref=" UnitEquipmentItem"/> for the given <see cref=" EquipmentItem"/>, or <code>null</code> if the unit can't take that <code>EquipmentItem</code> + /// </summary> + /// <param name="item"> + /// The <see cref="EquipmentItem"/> to get the <see cref=" UnitEquipmentItem"/> + /// </param> + /// <returns> + /// The <see cref="UnitEquipmentItem"/> that definies the UnitType's restrictions for taking the <see cref=" EquipmentItem"/> + /// </returns> + public UnitEquipmentItem GetEquipmentItem(EquipmentItem item) + { + return GetEquipmentItem(item.ID); + } + + /// <summary> + /// Gets an array of all available <see cref="UnitEquipmentItem"/>s for this UnitType + /// </summary> + /// <returns> + /// An array of all available <see cref="UnitEquipmentItem"/>s for this UnitType + /// </returns> + public UnitEquipmentItem[] GetEquipmentItems() + { + return DictionaryUtils.ToArray<string, UnitEquipmentItem>(equipment); + } + + public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroup(string group) + { + return GetEquipmentItemsByExclusionGroups(new string[] { group }); + } + + public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroups(string[] groups) + { + List<UnitEquipmentItem> list = new List<UnitEquipmentItem>(); + + foreach (string group in groups) + { + List<UnitEquipmentItem> groupList = DictionaryUtils.GetValue(equipmentExclusionGroups, group); + + if (groupList != null) + { + list.AddRange(groupList); + } + } + + return list.ToArray(); + } + + public bool IsRatioLimitedEquipmentItem(EquipmentItem item) + { + UnitEquipmentItem equip = GetEquipmentItem(item); + return equip != null && equip.IsRatioLimit; + } + + public bool IsAbsoluteLimitedEquipmentItem(EquipmentItem item) + { + UnitEquipmentItem equip = GetEquipmentItem(item); + return equip != null && !equip.IsRatioLimit; + } + + public ICollection<Ability> GetRequiredAbilities() + { + return requiredAbilities.Values; + } + + public ICollection<Ability> GetOptionalAbilities() + { + return optionalAbilities.Values; + } + + public void AddAbility(Ability ability, bool isRequired) + { + string id = ability.ID; + + if (!requiredAbilities.ContainsKey(id) && !optionalAbilities.ContainsKey(id)) + { + if (isRequired) + { + requiredAbilities[id] = ability; + } + else + { + optionalAbilities[id] = ability; + } + } + } + + public void AddRequirement(IRequirement requirement) + { + requirements.Add(requirement); + } + + public IRequirement[] GetRequirements() + { + List<IRequirement> reqs = new List<IRequirement>(requirements); + + if (MinNumber != 0) + { + RequiresAtLeastNUnitsRequirement req = new RequiresAtLeastNUnitsRequirement(); + req.AddUnitTypeRequirement(this, MinNumber); + reqs.Add(req); + } + + if (MaxNumber != WarFoundryCore.INFINITY) + { + RequiresNoMoreThanNOfUnitTypeRequirement req = new RequiresNoMoreThanNOfUnitTypeRequirement(); + req.AddUnitTypeRequirement(this, MaxNumber); + reqs.Add(req); + } + + return reqs.ToArray(); + } + + public string Notes + { + get { return notes; } + set { notes = value; } + } + + public bool CanContainUnit(Unit unit) + { + return CanContainUnitType(unit.UnitType); + } + + public bool CanContainUnitType(UnitType unitType) + { + return containedTypes.Contains(unitType); + } + + public UnitType[] ContainedUnitTypes + { + get { return containedTypes.ToArray(); } + } + + public void AddContainedUnitType(UnitType containedType) + { + containedTypes.Add(containedType); + } + + public void AddExtraData(string id, string data) + { + extraData[id] = data; + } + + public string GetExtraData(string id) + { + return DictionaryUtils.GetValue(extraData, id); + } + + public string StatsID + { + get + { + return stats.StatsID; + } + } + + public void AddEquipmentSlot(string slotName, ILimit slotLimit) + { + slotLimits.Add(slotName, slotLimit); + } + + public bool HasEquipmentSlot(string slotName) + { + return slotLimits.ContainsKey(slotName); + } + + /// <summary> + /// Gets the maximum limit on the number of items allowed in a single slot + /// </summary> + /// <param name="slotName">The name of the equipment slot to get the limit for</param> + /// <returns>The limit of the number of items allowed in a slot, or an infinite limit if the slot is the default one or has not been specified</returns> + public ILimit GetEquipmentSlotLimit(string slotName) + { + ILimit slotLimit = null; + + if (HasEquipmentSlot(slotName)) + { + slotLimit = DictionaryUtils.GetValue(slotLimits, slotName); + } + + if (slotLimit == null) + { + slotLimit = new UnlimitedLimit(); + } + + return slotLimit; + } + + public void AddUnitMemberType(UnitMemberType unitMemberType) + { + unitMemberTypes.Add(unitMemberType.ID, unitMemberType); + } + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/WarFoundryLoadedObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,26 @@ +using System; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// A marker class for objects that are loaded from a file + /// </summary> + public class WarFoundryLoadedObject : WarFoundryObject + { + protected WarFoundryLoadedObject() : base() + { + //Do nothing + } + + protected WarFoundryLoadedObject(string objName) : base(objName) + { + //Do nothing + } + + protected WarFoundryLoadedObject(string objId, string objName) : base(objId, objName) + { + //Do nothing + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/WarFoundryObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,100 @@ +// This file (WarFoundryObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.WarFoundry.API.Factories; + +namespace IBBoard.WarFoundry.API.Objects +{ + /// <summary> + /// Summary description for WarFoundryObject. + /// </summary> + public abstract class WarFoundryObject : IWarFoundryObject + { + protected string id; + protected string name; + public event StringValChangedDelegate NameChanged; + + protected WarFoundryObject() + { + } + + protected WarFoundryObject(string objName) : this() + { + Name = objName; + } + + protected WarFoundryObject(string objId, string objName) : this(objName) + { + ID = objId; + } + + public virtual string ID + { + get + { + if (id == null || id == "") + { + id = GenerateID(); + } + + return id; + } + + set + { + string newId = (value == null ? "" : value.Trim()); + id = (newId == "" ? GenerateID() : newId); + } + } + + public virtual string Name + { + get + { + if (HasDefaultName()) + { + return DefaultName(); + } + else + { + return name; + } + } + set + { + string oldValue = name; + name = value; + + if (name!=oldValue) + { + OnNameChanged(oldValue, name); + } + } + } + + public bool HasDefaultName() + { + return String.IsNullOrEmpty(name); + } + + protected void OnNameChanged(string oldValue, string newValue) + { + if (NameChanged!=null) + { + NameChanged(this, oldValue, newValue); + } + } + + protected virtual string DefaultName() + { + return "-"; + } + + protected string GenerateID() + { + return Name + UnixTimestamp.GetTimestamp(DateTime.Now) + "." + DateTime.Now.Millisecond; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/WarFoundryStagedLoadingObject.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,80 @@ +// This file (WarFoundryStagedLoadingObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using System.IO; +using IBBoard.WarFoundry.API.Factories; + +namespace IBBoard.WarFoundry.API.Objects +{ + public class WarFoundryStagedLoadingObject : WarFoundryLoadedObject, IWarFoundryStagedLoadObject + { + private bool isFullyLoaded; + private bool isLoading; + private IWarFoundryFactory creatingFactory; + private FileInfo sourceFile; + + protected WarFoundryStagedLoadingObject(IWarFoundryFactory creatingFactory) : this (null, creatingFactory) + { + } + + protected WarFoundryStagedLoadingObject(string objName, IWarFoundryFactory creatingFactory) : this(null, objName, creatingFactory) + { + } + + protected WarFoundryStagedLoadingObject(string objId, string objName, IWarFoundryFactory creatingFactory) : base(objId, objName) + { + this.creatingFactory = creatingFactory; + isFullyLoaded = false; + } + + public FileInfo SourceFile + { + get { return sourceFile; } + set { sourceFile = value; } + } + + public void EnsureFullyLoaded () + { + if (!IsFullyLoaded && !IsLoading) + { + if (Factory == null) + { + throw new InvalidOperationException("No factory set for partially loaded object with ID "+ID); + } + + Factory.CompleteLoading(this); + } + } + + public IWarFoundryFactory Factory + { + get { return creatingFactory; } + } + + public bool IsFullyLoaded + { + get { return isFullyLoaded; } + } + + public bool IsLoading + { + get { return isLoading; } + } + + public void SetAsFullyLoaded() + { + isLoading = false; + isFullyLoaded = true; + } + + public void SetAsLoading() + { + if (!isFullyLoaded) + { + isLoading = true; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Savers/IWarFoundryFileSaver.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,19 @@ +// This file (IWarFoundryFileSaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Savers +{ + /// <summary> + /// Saves one or more objects into a native-format zip file. + /// </summary> + public interface IWarFoundryFileSaver + { + bool Save(string path, params WarFoundryLoadedObject[] objects); + + string GetFileExtension (WarFoundryLoadedObject obj); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Savers/WarFoundrySaver.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,23 @@ +// This file (WarFoundrySaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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.Savers +{ + public class WarFoundrySaver + { + private static IWarFoundryFileSaver fileSaver; + + public static IWarFoundryFileSaver GetSaver() + { + return fileSaver; + } + + public static void SetFileSaver(IWarFoundryFileSaver newFileSaver) + { + fileSaver = newFileSaver; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Savers/Xml/WarFoundryXmlArmySaver.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,143 @@ +// This file (WarFoundryXmlSaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using IBBoard.Lang; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Factories.Xml.Zip; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Savers; +using IBBoard.WarFoundry.API.Util; +using ICSharpCode.SharpZipLib.Zip; + +namespace IBBoard.WarFoundry.API.Savers.Xml +{ + public class WarFoundryXmlArmySaver + { + public string CreateXmlString(Army toSave) + { + XmlDocument doc = new XmlDocument(); + XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null); + doc.AppendChild(declaration); + XmlSchema schema = new XmlSchema(); + schema.Namespaces.Add("", "http://ibboard.co.uk/warfoundry/army"); + schema.Namespaces.Add("core", "http://ibboard.co.uk/warfoundry/core"); + doc.Schemas.Add(schema); + XmlElement root = doc.CreateElement("army"); + root.SetAttribute("xmlns", "http://ibboard.co.uk/warfoundry/army"); + root.SetAttribute("xmlns:core", "http://ibboard.co.uk/warfoundry/core"); + doc.AppendChild(root); + root.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(toSave.ID)); + root.SetAttribute("name", toSave.Name); + //Don't convert system and race to ID format as they could be stored in non-XML file formats + //If they are in XML files then they'll already be valid + root.SetAttribute("system", toSave.GameSystem.ID); + root.SetAttribute("race", toSave.Race.ID); + root.SetAttribute("maxPoints", toSave.MaxPoints.ToString()); + XmlElement units = doc.CreateElement("units"); + root.AppendChild(units); + + foreach (Unit unit in toSave.GetUnits()) + { + units.AppendChild(CreateUnitElement(unit, doc)); + } + + return doc.OuterXml; + } + + private XmlElement CreateUnitElement(Unit unit, XmlDocument doc) + { + XmlElement unitElem = doc.CreateElement("unit"); + unitElem.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(unit.ID)); + unitElem.SetAttribute("unitName", (unit.HasDefaultName() ? "" : unit.Name)); + unitElem.SetAttribute("unitType", unit.UnitType.ID); + unitElem.SetAttribute("size", unit.Size.ToString()); + + if (!unit.Race.Equals(unit.Army.Race)) + { + unitElem.SetAttribute("race", unit.Race.ID); + } + + Category unitCategory = unit.Category.Category; + if (!unit.UnitType.MainCategory.Equals(unitCategory)) + { + unitElem.SetAttribute("category", unitCategory.ID); + } + + XmlElement equipmentElem = CreateEquipmentItemsElement(unit, doc); + + if (equipmentElem != null) + { + unitElem.AppendChild(equipmentElem); + } + + XmlElement containedElem = CreateContainedUnitsElement(unit, doc); + + if (containedElem != null) + { + unitElem.AppendChild(containedElem); + } + + return unitElem; + } + + private XmlElement CreateEquipmentItemsElement(Unit unit, XmlDocument doc) + { + UnitEquipmentItem[] equipItems = unit.GetEquipment(); + int equipItemCount = equipItems.Length; + XmlElement equipmentElem = null; + + if (equipItemCount > 0) + { + equipmentElem = doc.CreateElement("equipment"); + + for (int i = 0; i < equipItemCount; i++) + { + equipmentElem.AppendChild(CreateEquipmentElement(equipItems[i], unit, doc)); + } + } + + return equipmentElem; + } + + private XmlElement CreateEquipmentElement(UnitEquipmentItem item, Unit unit, XmlDocument doc) + { + XmlElement equipmentItemElem = doc.CreateElement("equipItem"); + equipmentItemElem.SetAttribute("id", item.ID); + equipmentItemElem.SetAttribute("amount", UnitEquipmentUtil.GetEquipmentAmount(unit, item).ToString()); + equipmentItemElem.SetAttribute("amountType", UnitEquipmentUtil.GetEquipmentAmountIsRatio(unit, item) ? "ratio" : "fixed"); + return equipmentItemElem; + } + + private XmlElement CreateContainedUnitsElement(Unit unit, XmlDocument doc) + { + Unit[] containedUnits = unit.ContainedUnits; + int containedCount = containedUnits.Length; + XmlElement containedElem = null; + + if (containedCount > 0) + { + containedElem = doc.CreateElement("contained"); + + for (int i = 0; i < containedCount; i++) + { + containedElem.AppendChild(CreateContainedUnitElement(containedUnits[i], doc)); + } + } + + return containedElem; + } + + private XmlElement CreateContainedUnitElement(Unit unit, XmlDocument doc) + { + XmlElement containedUnitElem = doc.CreateElement("containedUnit"); + containedUnitElem.SetAttribute("containedID", XmlTools.GetAsciiXmlIdForString(unit.ID)); + return containedUnitElem; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Savers/Xml/WarFoundryXmlFileSaver.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,92 @@ +using System; +using IBBoard.WarFoundry.API.Savers; +using IBBoard.WarFoundry.API.Objects; +using ICSharpCode.SharpZipLib.Zip; +using System.IO; +using IBBoard.IO; +using IBBoard.Lang; + +namespace IBBoard.WarFoundry.API.Savers.Xml +{ + public class WarFoundryXmlFileSaver : IWarFoundryFileSaver + { + public WarFoundryXmlFileSaver() + { + } + + public bool Save(string path, params WarFoundryLoadedObject[] objects) + { + ZipOutputStream zipStream = new ZipOutputStream(new FileStream(path, FileMode.Create)); + AddFiles(zipStream, objects); + zipStream.Close(); + return true; + } + + public void AddFiles(ZipOutputStream zipStream, WarFoundryLoadedObject[] objects) + { + foreach (WarFoundryLoadedObject obj in objects) + { + AddFile(zipStream, obj); + } + } + + public void AddFile(ZipOutputStream zipStream, WarFoundryLoadedObject obj) + { + ZipEntry entry = new ZipEntry(GetZipEntryName(obj)); + zipStream.PutNextEntry(entry); + byte[] bytes = GetObjectBytes(obj); + zipStream.Write(bytes, 0, bytes.Length); + } + + public byte[] GetObjectBytes(WarFoundryLoadedObject obj) + { + string xmlString = ""; + + if (obj is GameSystem) + { + xmlString = GetGameSystemString((GameSystem)obj); + } + else if (obj is Army) + { + xmlString = GetArmyString((Army)obj); + } + + return StringManipulation.StringToBytes(xmlString); + } + + public string GetGameSystemString(GameSystem obj) + { + return new WarFoundryXmlGameSystemSaver().CreateXmlString(obj); + } + + public string GetArmyString(Army obj) + { + return new WarFoundryXmlArmySaver().CreateXmlString(obj); + } + + private string GetZipEntryName(WarFoundryLoadedObject obj) + { + return obj.ID + GetFileExtension(obj); + } + + public string GetFileExtension(WarFoundryLoadedObject obj) + { + string ext = ""; + + if (obj is Army) + { + ext = ".armyx"; + } + else if (obj is Race) + { + ext = ".racex"; + } + else if (obj is GameSystem) + { + ext = ".systemx"; + } + + return ext; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Savers/Xml/WarFoundryXmlGameSystemSaver.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,106 @@ +// This file (WarFoundryXmlGameSystemSaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using IBBoard.Lang; +using IBBoard.Xml; +using IBBoard.WarFoundry.API.Factories.Xml.Zip; +using IBBoard.WarFoundry.API.Objects; +using IBBoard.WarFoundry.API.Savers; +using IBBoard.WarFoundry.API.Util; +using ICSharpCode.SharpZipLib.Zip; + +namespace IBBoard.WarFoundry.API.Savers.Xml +{ + public class WarFoundryXmlGameSystemSaver + { + public string CreateXmlString(GameSystem toSave) + { + XmlDocument doc = new XmlDocument(); + XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null); + doc.AppendChild(declaration); + XmlSchema schema = new XmlSchema(); + schema.Namespaces.Add("", "http://ibboard.co.uk/warfoundry/system"); + schema.Namespaces.Add("cats", "http://ibboard.co.uk/warfoundry/cats"); + doc.Schemas.Add(schema); + XmlElement root = doc.CreateElement("system"); + root.SetAttribute("xmlns", "http://ibboard.co.uk/warfoundry/system"); + root.SetAttribute("xmlns:cats", "http://ibboard.co.uk/warfoundry/cats"); + doc.AppendChild(root); + root.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(toSave.ID)); + root.SetAttribute("name", toSave.Name); + root.SetAttribute("defaultArmySize", toSave.SystemArmyDefaultSize.ToString()); + root.SetAttribute("warn", toSave.WarnOnError.ToString().ToLowerInvariant()); + root.SetAttribute("allowAllies", toSave.AllowAllies.ToString().ToLowerInvariant()); + XmlElement cats = doc.CreateElement("categories"); + root.AppendChild(cats); + + foreach (Category cat in toSave.Categories) + { + cats.AppendChild(CreateCategoryElement(cat, doc)); + } + + XmlElement sysStatsList = doc.CreateElement("sysStatsList"); + sysStatsList.SetAttribute("defaultStats", XmlTools.GetAsciiXmlIdForString(toSave.StandardSystemStatsID)); + root.AppendChild(sysStatsList); + + foreach(SystemStats stats in toSave.SystemStats) + { + sysStatsList.AppendChild(CreateSystemStatsElement(stats, doc)); + } + + return doc.OuterXml; + } + + private XmlElement CreateCategoryElement(Category cat, XmlDocument doc) + { + XmlElement catElem = doc.CreateElement("cats:cat"); + catElem.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(cat.ID)); + catElem.SetAttribute("name", (cat.HasDefaultName() ? "" : cat.Name)); + if (cat.MinimumPoints > 0) + { + catElem.SetAttribute("minPoints", cat.MaximumPercentage.ToString()); + } + if (cat.MaximumPoints < 100) + { + catElem.SetAttribute("maxPoints", cat.MaximumPercentage.ToString()); + } + if(cat.MinimumPercentage > 0) + { + catElem.SetAttribute("minPercentage", cat.MaximumPercentage.ToString()); + } + if(cat.MaximumPercentage < 100) + { + catElem.SetAttribute("maxPercentage", cat.MaximumPercentage.ToString()); + } + + return catElem; + } + + private XmlElement CreateSystemStatsElement(SystemStats stats, XmlDocument doc) + { + XmlElement statsElem = doc.CreateElement("sysStats"); + statsElem.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(stats.ID)); + + foreach(StatSlot stat in stats.StatSlots) + { + statsElem.AppendChild(CreateSystemStatElement(stat, doc)); + } + + return statsElem; + } + + private XmlElement CreateSystemStatElement(StatSlot stat, XmlDocument doc) + { + XmlElement statElem = doc.CreateElement("sysStat"); + statElem.SetAttribute("name", stat.Name); + + return statElem; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Util/UnitEquipmentUtil.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,211 @@ +// This file (UnitEquipmentUtil.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; +using System.Collections.Generic; +using System.Text; +using IBBoard.CustomMath; +using IBBoard.Limits; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API.Util +{ + public class UnitEquipmentUtil + { + /// <summary> + /// Gets an array of allowed <see cref="UnitEquipmentItem"/>s based on the current selections of the unit, taking in to account Mutex groups and other limits. + /// </summary> + /// <param name="unit">The <see cref="Unit"/> to get equipment items for</param> + /// <returns>The array of allowed <see cref="UnitEquipmentItem"/>s</returns> + public static UnitEquipmentItem[] GetAllowedEquipmentItems(Unit unit) + { + List<UnitEquipmentItem> list = new List<UnitEquipmentItem>(); + UnitEquipmentItem[] currItems = unit.GetEquipment(); + + foreach (UnitEquipmentItem item in GetAllEquipmentItems(unit)) + { + bool allowed = IsAllowedByMutex(item, currItems); + + if (allowed) + { + list.Add(item); + } + } + + return list.ToArray(); + } + + private static bool IsAllowedByMutex(UnitEquipmentItem item, UnitEquipmentItem[] currItems) + { + bool allowed = true; + + foreach (UnitEquipmentItem currItem in currItems) + { + if (ItemsAreMutuallyExclusive(currItem, item)) + { + allowed = false; + break; + } + } + + return allowed; + } + + /// <summary> + /// Gets a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code> because of mutex groups. + /// </summary> + /// <param name="unit">The unit that wants to take the equipment item</param> + /// <param name="item">The item to check blocking items for</param> + /// <returns>a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code></returns> + public static List<UnitEquipmentItem> GetBlockingEquipmentItems(Unit unit, UnitEquipmentItem item) + { + List<UnitEquipmentItem> items = new List<UnitEquipmentItem>(); + UnitEquipmentItem[] currItems = unit.GetEquipment(); + + foreach (UnitEquipmentItem unitItem in currItems) + { + if (ItemsAreMutuallyExclusive(unitItem, item)) + { + items.Add(unitItem); + } + } + + return items; + } + + public static UnitEquipmentItem[] GetAllEquipmentItems(Unit unit) + { + return unit.UnitType.GetEquipmentItems(); + } + + public static bool ItemsAreMutuallyExclusive(UnitEquipmentItem item1, UnitEquipmentItem item2) + { + bool areMutex = false; + string[] item1mutex = item1.MutexGroups; + string[] item2mutex = item2.MutexGroups; + + foreach (string mutex in item1mutex) + { + foreach (string otherMutex in item2mutex) + { + if (mutex.Equals(otherMutex)) + { + areMutex = true; + goto postLoop; + } + } + } + postLoop: + + return areMutex; + } + + public static int GetMaxEquipmentCount (Unit unit, UnitEquipmentItem equip) + { + return GetEquipmentCountLimit (unit, equip.MaxLimit.GetLimit(unit.Size), equip); + } + + private static int GetEquipmentCountLimit (Unit unit, int currLimit, UnitEquipmentItem equip) + { + int newLimit = currLimit; + ILimit limit = GetSlotLimitForItem(unit, equip); + + if (!(limit is UnlimitedLimit)) + { + int slotMax = limit.GetLimit (unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip); + newLimit = Math.Min (slotMax, newLimit); + } + + return newLimit; + } + + private static ILimit GetSlotLimitForItem(Unit unit, UnitEquipmentItem equip) + { + return unit.UnitType.GetEquipmentSlotLimit(equip.SlotName); + } + + + public static int GetMinEquipmentCount (Unit unit, UnitEquipmentItem equip) + { + return GetEquipmentCountLimit (unit, equip.MinLimit.GetLimit(unit.Size), equip); + } + + public static bool IsEquipmentRatioLimited(Unit unit, UnitEquipmentItem equip) + { + ILimit limit = GetSlotLimitForItem(unit, equip); + return equip.IsRatioLimit && (limit is IPercentageLimit || limit is UnlimitedLimit); + } + + public static double GetMaxEquipmentPercentage(Unit unit, UnitEquipmentItem equip) + { + return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MaxLimit, unit); + } + + private static double GetPercentageOfUnitSize(int number, Unit unit) + { + return IBBMath.Percentage(number, unit.Size); + } + + private static double GetMinOfSlotLimitAndEquipmentLimit(UnitEquipmentItem equip, ILimit equipLimit, Unit unit) + { + double limit = 0; + ILimit slotLimit = GetSlotLimitForItem(unit, equip); + + if (slotLimit is IPercentageLimit) + { + limit = ((IPercentageLimit)slotLimit).Percentage - GetPercentageOfUnitSize(unit.GetEquipmentAmountInSlotExcludingItem(equip), unit); + } + else + { + int remaining = slotLimit.GetLimit(unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip); + limit = GetPercentageOfUnitSize(remaining, unit); + } + + if (equip.IsRatioLimit) + { + limit = Math.Min(limit, ((IPercentageLimit)equipLimit).Percentage); + } + else + { + limit = Math.Min(limit, GetPercentageOfUnitSize(equipLimit.GetLimit(unit.Size), unit)); + } + + return limit; + } + + public static double GetMinEquipmentPercentage(Unit unit, UnitEquipmentItem equip) + { + return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MinLimit, unit); + } + + public static double GetEquipmentAmount(Unit unit, UnitEquipmentItem item) + { + double amount = 0; + AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item); + + if (selection != null) + { + amount = selection.AmountTaken; + } + + return amount; + } + + public static bool GetEquipmentAmountIsRatio(Unit unit, UnitEquipmentItem item) + { + return (unit.GetEquipmentSelection(item) is UnitEquipmentRatioSelection); + } + + public static int GetEquipmentAmountTaken(Unit unit, UnitEquipmentItem item) + { + AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item); + return (selection == null ? 0 : selection.NumberTaken); + } + + public static bool CanEditEquipmentAmount(Unit unit, UnitEquipmentItem item) + { + return item !=null && (item.MaxLimit.GetLimit(unit.Size) != item.MinLimit.GetLimit(unit.Size)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/WarFoundryCore.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,77 @@ +// This file (WarFoundryCore.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using IBBoard.Logging; +using IBBoard.WarFoundry.API.Objects; + +namespace IBBoard.WarFoundry.API +{ + public class WarFoundryCore + { + public static readonly int INFINITY = -1; + public static event GameSystemChangedDelegate GameSystemChanged; + public static event ArmyChangedDelegate ArmyChanged; + + private static GameSystem system; + private static Army currentArmy; + + public static GameSystem CurrentGameSystem + { + get { return system; } + set + { + if (system==null || !system.Equals(value)) + { + GameSystem oldSystem = system; + system = value; + + if (system==null) + { + LogNotifier.Debug(typeof(WarFoundryCore), "Game system set to null"); + } + else + { + LogNotifier.DebugFormat(typeof(WarFoundryCore), "Game system set to {0} with ID {1}", system.Name, system.ID); + } + + if (GameSystemChanged!=null) + { + GameSystemChanged(oldSystem, system); + } + + //If we've changed the game system then we can't keep the current army + CurrentArmy = null; + } + } + } + + public static Army CurrentArmy + { + get { return currentArmy; } + set + { + if (currentArmy==null || !currentArmy.Equals(value)) + { + Army oldArmy = currentArmy; + + if (value != null) + { + CurrentGameSystem = value.GameSystem; //Set the game system in case the new army is from a different system + currentArmy = value; + } + else + { + currentArmy = null; + } + + if (ArmyChanged!=null) + { + ArmyChanged(oldArmy, currentArmy); + } + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/WarFoundryLoader.cs Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,53 @@ +// This file (WarFoundryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; +using ICSharpCode.SharpZipLib.Zip; +using System.Collections.Generic; +using IBBoard.WarFoundry.API.Factories.Requirement; +using IBBoard.WarFoundry.API.Objects.Requirement; + +namespace IBBoard.WarFoundry.API +{ + public class WarFoundryLoader + { + private static AbstractWarFoundryLoader loader; + private static Dictionary<string, IRequirementFactory> requirementFactories = new Dictionary<string, IRequirementFactory>(); + + /// <summary> + /// Gets the default <see cref="WarFoundryLoader"/> used to load WarFoundry data files. + /// </summary> + /// <returns> + /// The default <see cref="WarFoundryLoader"/> + /// </returns> + public static AbstractWarFoundryLoader GetDefault() + { + if (loader == null) + { + loader = new DefaultWarFoundryLoader(); + } + + return loader; + } + + public static void SetDefault(AbstractWarFoundryLoader newLoader) + { + loader = newLoader; + } + + private WarFoundryLoader() + { + //Hide constructor + } + + public static void RegisterRequirementFactory(IRequirementFactory factory) + { + requirementFactories[factory.AppliesToID] = factory; + } + + public static IRequirementFactory GetRequirementFactory(string requirementID) + { + return DictionaryUtils.GetValue(requirementFactories, requirementID); + } + } +}
--- a/IBBoard.WarFoundry.API.csproj Sat Aug 13 14:13:13 2011 -0500 +++ b/IBBoard.WarFoundry.API.csproj Fri Aug 26 20:04:52 2011 +0100 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> @@ -8,16 +8,15 @@ <ProjectGuid>{951E6C7A-7FBA-4F68-9D9E-F48618BB9626}</ProjectGuid> <OutputType>Library</OutputType> <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>IBBoard.WarFoundry.API</RootNamespace> + <RootNamespace>IBBoard.WarFoundry</RootNamespace> <AssemblyName>IBBoard.WarFoundry.API</AssemblyName> <FileUpgradeFlags> </FileUpgradeFlags> - <OldToolsVersion>2.0</OldToolsVersion> + <OldToolsVersion>3.5</OldToolsVersion> <UpgradeBackupLocation> </UpgradeBackupLocation> + <IsWebBootstrapper>false</IsWebBootstrapper> <TargetFrameworkVersion>v2.0</TargetFrameworkVersion> - <TargetFrameworkSubset> - </TargetFrameworkSubset> <PublishUrl>publish\</PublishUrl> <Install>true</Install> <InstallFrom>Disk</InstallFrom> @@ -30,7 +29,6 @@ <MapFileExtensions>true</MapFileExtensions> <ApplicationRevision>0</ApplicationRevision> <ApplicationVersion>1.0.0.%2a</ApplicationVersion> - <IsWebBootstrapper>false</IsWebBootstrapper> <UseApplicationTrust>false</UseApplicationTrust> <BootstrapperEnabled>true</BootstrapperEnabled> </PropertyGroup> @@ -60,86 +58,10 @@ </Target> --> <ItemGroup> + <None Include="app.config" /> <None Include="COPYING" /> - <Compile Include="api\Objects\ICostedWarFoundryObject.cs" /> - <Compile Include="api\Commands\CreateAndAddUnitCommand.cs" /> - <Compile Include="api\Commands\RemoveUnitCommand.cs" /> - <Compile Include="api\Commands\AbstractReplaceUnitEquipmentCommand.cs" /> - <Compile Include="api\Commands\SetNameCommand.cs" /> - <Compile Include="api\Commands\SetUnitEquipmentNumericAmountCommand.cs" /> - <Compile Include="api\Commands\SetUnitSizeCommand.cs" /> - <Compile Include="api\Delegates.cs" /> - <Compile Include="api\Factories\AbstractNativeWarFoundryFactory.cs" /> - <Compile Include="api\Factories\AbstractNonNativeFileExtensionWarFoundryFactory.cs" /> - <Compile Include="api\Factories\AbstractNonNativeWarFoundryFactory.cs" /> - <Compile Include="api\Factories\AbstractWarFoundryFactory.cs" /> - <Compile Include="api\Factories\INativeWarFoundryFactory.cs" /> - <Compile Include="api\Factories\INonNativeWarFoundryFactory.cs" /> - <Compile Include="api\Factories\IWarFoundryFactory.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlElementName.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlFactory.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlSaver.cs" /> - <Compile Include="api\FileLoadFailure.cs" /> - <Compile Include="api\Objects\Ability.cs" /> - <Compile Include="api\Objects\Army.cs" /> - <Compile Include="api\Objects\ArmyCategory.cs" /> - <Compile Include="api\Objects\Category.cs" /> - <Compile Include="api\Objects\DuplicateItemException.cs" /> - <Compile Include="api\Objects\EquipmentItem.cs" /> - <Compile Include="api\Objects\GameSystem.cs" /> - <Compile Include="api\Objects\IWarFoundryNativeSourceObject.cs" /> - <Compile Include="api\Objects\IWarFoundryObject.cs" /> - <Compile Include="api\Objects\IWarFoundryStagedLoadObject.cs" /> - <Compile Include="api\Objects\Race.cs" /> - <Compile Include="api\Objects\Stat.cs" /> - <Compile Include="api\Objects\Stats.cs" /> - <Compile Include="api\Objects\StatSlot.cs" /> - <Compile Include="api\Objects\SystemStats.cs" /> - <Compile Include="api\Objects\Unit.cs" /> - <Compile Include="api\Objects\UnitEquipmentItem.cs" /> - <Compile Include="api\Objects\UnitType.cs" /> - <Compile Include="api\Objects\WarFoundryObject.cs" /> - <Compile Include="api\Objects\WarFoundryStagedLoadingObject.cs" /> - <Compile Include="api\Requirements\AbstractArmyRequirement.cs" /> - <Compile Include="api\Requirements\AbstractFailedRequirement.cs" /> - <Compile Include="api\Requirements\AbstractRequirement.cs" /> - <Compile Include="api\Requirements\AbstractUnitRequirement.cs" /> - <Compile Include="api\Requirements\Delegates.cs" /> - <Compile Include="api\Requirements\FailedRequirement.cs" /> - <Compile Include="api\Requirements\FailedUnitRequirement.cs" /> - <Compile Include="api\Requirements\RequirementAND.cs" /> - <Compile Include="api\Requirements\RequirementOR.cs" /> - <Compile Include="api\Requirements\UnitExcludesRequirement.cs" /> - <Compile Include="api\Requirements\UnitRequirement.cs" /> - <Compile Include="api\Requirements\UnitRequirementItem.cs" /> - <Compile Include="api\Requirements\UnitRequirementMaxNumber.cs" /> - <Compile Include="api\Requirements\UnitRequirementMinNumber.cs" /> - <Compile Include="api\Requirements\UnitRequiresAtLeastRequirement.cs" /> - <Compile Include="api\Savers\IWarFoundryFileSaver.cs" /> - <Compile Include="api\Savers\WarFoundrySaver.cs" /> - <Compile Include="api\Util\UnitEquipmentUtil.cs" /> - <Compile Include="api\WarFoundryCore.cs" /> - <Compile Include="api\WarFoundryLoader.cs" /> + <Compile Include="API\Exporters\WarFoundryXMLWithXSLExporter.cs" /> <Compile Include="AssemblyInfo.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlGameSystemFactory.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlRaceFactory.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlArmyFactory.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlFactoryUtils.cs" /> - <Compile Include="api\Factories\Xml\AbstractStagedLoadedSubFactory.cs" /> - <Compile Include="api\Objects\InvalidContainershipException.cs" /> - <Compile Include="api\Objects\CompositeEquipmentItem.cs" /> - <Compile Include="api\Objects\AbstractUnitEquipmentItemSelection.cs" /> - <Compile Include="api\Objects\UnitEquipmentNumericSelection.cs" /> - <Compile Include="api\Objects\UnitEquipmentRatioSelection.cs" /> - <Compile Include="api\Commands\SetUnitEquipmentRatioAmountCommand.cs" /> - <Compile Include="api\Commands\AbstractSetUnitEquipmentAmountCommand.cs" /> - <Compile Include="api\Commands\ReplaceUnitEquipmentWithNumericAmountItemCommand.cs" /> - <Compile Include="api\Commands\ReplaceUnitEquipmentWithRatioAmountItemCommand.cs" /> - <Compile Include="api\Factories\Xml\Zip\StringZipEntrySource.cs" /> - <Compile Include="api\Factories\RequiredDataMissingException.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlArmyParser.cs" /> - <Compile Include="api\Exporters\IWarFoundryExporter.cs" /> - <Compile Include="api\Exporters\WarFoundryHtmlExporter.cs" /> <None Include="schemas\army.xsd"> <Gettext-ScanForTranslations>false</Gettext-ScanForTranslations> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> @@ -176,57 +98,121 @@ <Gettext-ScanForTranslations>false</Gettext-ScanForTranslations> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> - <Compile Include="api\AbstractWarFoundryLoader.cs" /> - <Compile Include="api\DefaultWarFoundryLoader.cs" /> - <Compile Include="api\Objects\UnitMemberType.cs" /> - <Compile Include="api\Factories\Xml\WarFoundryXmlLimitParser.cs" /> - </ItemGroup> - <ItemGroup> - <Content Include="libs\ICSharpCode.SharpZipLib.dll" /> - </ItemGroup> - <ItemGroup> - <Reference Include="IBBoard, Version=1.0.3896.41664, Culture=neutral, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\IBBoard\bin\Release\IBBoard.dll</HintPath> - </Reference> - <Reference Include="System.Data" /> - <Reference Include="System.Xml" /> - <Reference Include="System" /> - <Reference Include="ICSharpCode.SharpZipLib, Version=0.85.5.452, Culture=neutral, PublicKeyToken=1b03e6acf1164f73"> - <SpecificVersion>False</SpecificVersion> - <HintPath>libs\ICSharpCode.SharpZipLib.dll</HintPath> - </Reference> + <Compile Include="API\Objects\ICostedWarFoundryObject.cs" /> + <Compile Include="API\Commands\CreateAndAddUnitCommand.cs" /> + <Compile Include="API\Commands\RemoveUnitCommand.cs" /> + <Compile Include="API\Commands\AbstractReplaceUnitEquipmentCommand.cs" /> + <Compile Include="API\Commands\SetNameCommand.cs" /> + <Compile Include="API\Commands\SetUnitEquipmentNumericAmountCommand.cs" /> + <Compile Include="API\Commands\SetUnitSizeCommand.cs" /> + <Compile Include="API\Delegates.cs" /> + <Compile Include="API\Factories\AbstractNativeWarFoundryFactory.cs" /> + <Compile Include="API\Factories\AbstractNonNativeFileExtensionWarFoundryFactory.cs" /> + <Compile Include="API\Factories\AbstractNonNativeWarFoundryFactory.cs" /> + <Compile Include="API\Factories\AbstractWarFoundryFactory.cs" /> + <Compile Include="API\Factories\INativeWarFoundryFactory.cs" /> + <Compile Include="API\Factories\INonNativeWarFoundryFactory.cs" /> + <Compile Include="API\Factories\IWarFoundryFactory.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlElementName.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlFactory.cs" /> + <Compile Include="API\FileLoadFailure.cs" /> + <Compile Include="API\Objects\Ability.cs" /> + <Compile Include="API\Objects\Army.cs" /> + <Compile Include="API\Objects\ArmyCategory.cs" /> + <Compile Include="API\Objects\Category.cs" /> + <Compile Include="API\Objects\DuplicateItemException.cs" /> + <Compile Include="API\Objects\EquipmentItem.cs" /> + <Compile Include="API\Objects\GameSystem.cs" /> + <Compile Include="API\Objects\IWarFoundryNativeSourceObject.cs" /> + <Compile Include="API\Objects\IWarFoundryObject.cs" /> + <Compile Include="API\Objects\IWarFoundryStagedLoadObject.cs" /> + <Compile Include="API\Objects\Race.cs" /> + <Compile Include="API\Objects\Stat.cs" /> + <Compile Include="API\Objects\Stats.cs" /> + <Compile Include="API\Objects\StatSlot.cs" /> + <Compile Include="API\Objects\SystemStats.cs" /> + <Compile Include="API\Objects\Unit.cs" /> + <Compile Include="API\Objects\UnitEquipmentItem.cs" /> + <Compile Include="API\Objects\UnitType.cs" /> + <Compile Include="API\Objects\WarFoundryObject.cs" /> + <Compile Include="API\Objects\WarFoundryStagedLoadingObject.cs" /> + <Compile Include="API\Savers\IWarFoundryFileSaver.cs" /> + <Compile Include="API\Savers\WarFoundrySaver.cs" /> + <Compile Include="API\Util\UnitEquipmentUtil.cs" /> + <Compile Include="API\WarFoundryCore.cs" /> + <Compile Include="API\WarFoundryLoader.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlGameSystemFactory.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlRaceFactory.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlArmyFactory.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlFactoryUtils.cs" /> + <Compile Include="API\Objects\InvalidContainershipException.cs" /> + <Compile Include="API\Objects\CompositeEquipmentItem.cs" /> + <Compile Include="API\Objects\AbstractUnitEquipmentItemSelection.cs" /> + <Compile Include="API\Objects\UnitEquipmentNumericSelection.cs" /> + <Compile Include="API\Objects\UnitEquipmentRatioSelection.cs" /> + <Compile Include="API\Commands\SetUnitEquipmentRatioAmountCommand.cs" /> + <Compile Include="API\Commands\AbstractSetUnitEquipmentAmountCommand.cs" /> + <Compile Include="API\Commands\ReplaceUnitEquipmentWithNumericAmountItemCommand.cs" /> + <Compile Include="API\Commands\ReplaceUnitEquipmentWithRatioAmountItemCommand.cs" /> + <Compile Include="API\Factories\Xml\Zip\StringZipEntrySource.cs" /> + <Compile Include="API\Factories\RequiredDataMissingException.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlArmyParser.cs" /> + <Compile Include="API\Exporters\IWarFoundryExporter.cs" /> + <Compile Include="API\Exporters\WarFoundryHtmlExporter.cs" /> + <Compile Include="API\AbstractWarFoundryLoader.cs" /> + <Compile Include="API\DefaultWarFoundryLoader.cs" /> + <Compile Include="API\Objects\UnitMemberType.cs" /> + <Compile Include="API\Factories\Xml\WarFoundryXmlLimitParser.cs" /> + <Compile Include="API\Factories\DummyWarFoundryFactory.cs" /> + <Compile Include="API\Objects\WarFoundryLoadedObject.cs" /> + <Compile Include="API\Savers\Xml\WarFoundryXmlArmySaver.cs" /> + <Compile Include="API\Savers\Xml\WarFoundryXmlGameSystemSaver.cs" /> + <Compile Include="API\Savers\Xml\WarFoundryXmlFileSaver.cs" /> + <Compile Include="API\Objects\Requirement\RequiresAtLeastNUnitsRequirement.cs" /> + <Compile Include="API\Objects\Requirement\UnitCountRequirementData.cs" /> + <Compile Include="API\Objects\Requirement\RequiresNoMoreThanNOfUnitTypeRequirement.cs" /> + <Compile Include="API\Objects\Requirement\UnitRequiresAtLeastNUnitsRequirement.cs" /> + <Compile Include="API\Objects\Requirement\Validation.cs" /> + <Compile Include="API\Objects\Requirement\UnitRequiresNoMoreThanNOfUnitTypeRequirement.cs" /> + <Compile Include="API\Objects\Requirement\IRequirement.cs" /> + <Compile Include="API\Objects\Requirement\RequirementHandler.cs" /> + <Compile Include="API\Objects\Requirement\AbstractRequirement.cs" /> + <Compile Include="API\Factories\Requirement\UnitRequiresAtLeastNUnitsRequirementFactory.cs" /> + <Compile Include="API\Factories\Requirement\InvalidRequirementException.cs" /> + <Compile Include="API\Factories\Xml\CategoryLoader.cs" /> + <Compile Include="API\Factories\IRaceFactory.cs" /> + <Compile Include="API\Factories\Requirement\IRequirementFactory.cs" /> </ItemGroup> <ItemGroup> - <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> - <Visible>False</Visible> - <ProductName>.NET Framework Client Profile</ProductName> - <Install>false</Install> - </BootstrapperPackage> - <BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> - <Visible>False</Visible> - <ProductName>.NET Framework 2.0 %28x86%29</ProductName> - <Install>false</Install> - </BootstrapperPackage> - <BootstrapperPackage Include="Microsoft.Net.Framework.3.0"> - <Visible>False</Visible> - <ProductName>.NET Framework 3.0 %28x86%29</ProductName> - <Install>false</Install> - </BootstrapperPackage> - <BootstrapperPackage Include="Microsoft.Net.Framework.3.5"> - <Visible>False</Visible> - <ProductName>.NET Framework 3.5</ProductName> - <Install>false</Install> - </BootstrapperPackage> - <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> - <Visible>False</Visible> - <ProductName>.NET Framework 3.5 SP1</ProductName> - <Install>true</Install> - </BootstrapperPackage> - <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> - <Visible>False</Visible> - <ProductName>Windows Installer 3.1</ProductName> - <Install>true</Install> - </BootstrapperPackage> + <Reference Include="System.Xml" /> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\IBBoard\IBBoard.csproj"> + <Project>{5DFD64F6-FC2B-4B4F-B92E-483BAC468105}</Project> + <Name>IBBoard</Name> + </ProjectReference> + <ProjectReference Include="..\SharpZipLib\ICSharpCode.SharpZLib.csproj"> + <Project>{0E7413FF-EB9E-4714-ACF2-BE3A6A7B2FFD}</Project> + <Name>ICSharpCode.SharpZLib</Name> + </ProjectReference> </ItemGroup> + <ItemGroup> + <Content Include="xsl\default_html.xsl"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="xsl\unitcard.xsl"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + </ItemGroup> + <ProjectExtensions> + <MonoDevelop> + <Properties> + <Policies> + <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="FileFormatDefault" /> + </Policies> + </Properties> + </MonoDevelop> + <VisualStudio /> + </ProjectExtensions> </Project> \ No newline at end of file
--- a/api/AbstractWarFoundryLoader.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,685 +0,0 @@ -// This file (AbstractWarFoundryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using System.IO; -using IBBoard.Collections; -using IBBoard.IO; -using IBBoard.Logging; -using IBBoard.WarFoundry.API.Factories; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API -{ - /// <summary> - /// The base abstract implementation of a WarFoundry file loader - /// </summary> - public abstract class AbstractWarFoundryLoader - { - private ICollection<DirectoryInfo> directories; - private ICollection<INativeWarFoundryFactory> factories; - private ICollection<INonNativeWarFoundryFactory> nonNativeFactories; - private Dictionary<IWarFoundryFactory, SimpleSet<IWarFoundryObject>> loadedObjects; - public delegate void FileLoadingCompleteDelegate(List<FileLoadFailure> failures); - public event MethodInvoker FileLoadingStarted; - public event FileLoadingCompleteDelegate FileLoadingFinished; - - protected AbstractWarFoundryLoader() - { - directories = new List<DirectoryInfo>(); - factories = new List<INativeWarFoundryFactory>(); - nonNativeFactories = new List<INonNativeWarFoundryFactory>(); - loadedObjects = new Dictionary<IWarFoundryFactory,SimpleSet<IWarFoundryObject>>(); - } - - /// <summary> - /// Adds a directory to the collection of directories that will be searched for WarFoundry data files. - /// </summary> - /// <param name="directory"> - /// The <see cref="DirectoryInfo"/> to add to the list for searching for data files - /// </param> - public void AddLoadDirectory(DirectoryInfo directory) - { - if (!directories.Contains(directory)) - { - directories.Add(directory); - } - } - - /// <summary> - /// Removes a directory from the collection of directories that will be searched for WarFoundry data files. - /// </summary> - /// <param name="directory"> - /// A <see cref="DirectoryInfo"/> - /// </param> - public void RemoveLoadDirectory(DirectoryInfo directory) - { - if (directories.Contains(directory)) - { - directories.Remove(directory); - } - } - - /// <summary> - /// Registers a <see cref="INativeWarFoundryFactory"/> as a factory that can parse native data files. - /// </summary> - /// <param name="factory"> - /// The <see cref="INativeWarFoundryFactory"/> to register to parse native data files. - /// </param> - public void RegisterFactory(INativeWarFoundryFactory factory) - { - if (!factories.Contains(factory)) - { - factories.Add(factory); - } - } - - /// <summary> - /// Unregisters a <see cref="INativeWarFoundryFactory"/> so that it will no longer be used to try to parse native data files. - /// </summary> - /// <param name="factory"> - /// The <see cref="INativeWarFoundryFactory"/> to remove from the collection of factories that are used to try to parse native data files. - /// </param> - public void UnregisterFactory(INativeWarFoundryFactory factory) - { - if (factories.Contains(factory)) - { - factories.Remove(factory); - } - } - - /// <summary> - /// Registers a <see cref="INonNativeWarFoundryFactory"/> so that it will be used to try to parse non-native data files from other applications. - /// </summary> - /// <param name="factory"> - /// The <see cref="INonNativeWarFoundryFactory"/> to register to parse non-native data files. - /// </param> - public void RegisterNonNativeFactory(INonNativeWarFoundryFactory factory) - { - if (!nonNativeFactories.Contains(factory)) - { - nonNativeFactories.Add(factory); - } - } - - /// <summary> - /// Unregisters a <see cref="INonNativeWarFoundryFactory"/> so that it will no longer be used to try to parse non-native data files from other applications. - /// </summary> - /// <param name="factory"> - /// The <see cref="INonNativeWarFoundryFactory"/> to remove from the collection of factories that are used to try to parse non-native data files. - /// </param> - public void UnregisterNonNativeFactory(INonNativeWarFoundryFactory factory) - { - if (nonNativeFactories.Contains(factory)) - { - nonNativeFactories.Remove(factory); - } - } - - /// <summary> - /// Loads all of the data files in the registered directories. - /// </summary> - /// <returns> - /// A <see cref="List"/> of <see cref="FileLoadFailure"/> for files that failed to load - /// </returns> - public List<FileLoadFailure> LoadFiles() - { - PrepareForFileLoad(); - Dictionary<FileInfo, IWarFoundryFactory> loadableRaces = new Dictionary<FileInfo, IWarFoundryFactory>(); - Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems = new Dictionary<FileInfo, IWarFoundryFactory>(); - List<FileLoadFailure> failedLoads = FillLoadableFiles(loadableRaces, loadableGameSystems); - failedLoads.AddRange(LoadGameSystems(loadableGameSystems)); - failedLoads.AddRange(LoadRaces(loadableRaces)); - OnFileLoadingFinished(failedLoads); - return failedLoads; - } - - private void OnFileLoadingFinished(List<FileLoadFailure> failures) - { - if (FileLoadingFinished!=null) - { - FileLoadingFinished(failures); - } - } - - protected abstract void PrepareForFileLoad(); - - private List<FileLoadFailure> FillLoadableFiles(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems) - { - List<FileLoadFailure> fails = new List<FileLoadFailure>(); - - foreach (DirectoryInfo directory in directories) - { - directory.Refresh(); - - if (directory.Exists) - { - List<FileLoadFailure> directoryFails = FillLoadableFilesForDirectory(loadableRaces, loadableGameSystems, directory); - fails.AddRange(directoryFails); - } - else - { - LogNotifier.WarnFormat(GetType(), "Load for {0} failed because directory didn't exist", directory.FullName); - } - } - - return fails; - } - - private List<FileLoadFailure> FillLoadableFilesForDirectory(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems, DirectoryInfo directory) - { - List<FileLoadFailure> fails = new List<FileLoadFailure>(); - LogNotifier.Debug(GetType(), "Load from "+directory.FullName); - - foreach (FileInfo file in directory.GetFiles()) - { - IWarFoundryFactory factory = GetGameSystemLoadingFactoryForFile(file); - - if (factory != null) - { - loadableGameSystems.Add(file, factory); - } - else - { - factory = GetRaceLoadingFactoryForFile(file); - - if (factory!=null) - { - loadableRaces.Add(file, factory); - } - else - { - FileLoadFailure failure = new FileLoadFailure(file, "File not handled as a Race or Game System definition: {0}", "FileNotHandled"); - fails.Add(failure); - LogNotifier.Info(GetType(), failure.Message); - } - } - } - - return fails; - } - - private IWarFoundryFactory GetGameSystemLoadingFactoryForFile(FileInfo file) - { - IWarFoundryFactory loadingFactory = null; - - foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) - { - if (factory.CanHandleFileAsGameSystem(file)) - { - loadingFactory = factory; - break; - } - } - - if (loadingFactory == null) - { - foreach (INativeWarFoundryFactory factory in factories) - { - if (factory.CanHandleFileAsGameSystem(file)) - { - loadingFactory = factory; - break; - } - } - } - - return loadingFactory; - } - - private IWarFoundryFactory GetRaceLoadingFactoryForFile(FileInfo file) - { - IWarFoundryFactory loadingFactory = null; - - foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) - { - if (factory.CanHandleFileAsRace(file)) - { - loadingFactory = factory; - break; - } - } - - if (loadingFactory == null) - { - foreach (INativeWarFoundryFactory factory in factories) - { - if (factory.CanHandleFileAsRace(file)) - { - loadingFactory = factory; - break; - } - } - } - - return loadingFactory; - } - - private List<FileLoadFailure> LoadGameSystems(Dictionary<FileInfo, IWarFoundryFactory> gameSystemFiles) - { - List<FileLoadFailure> fails = new List<FileLoadFailure>(); - - - foreach (FileInfo file in gameSystemFiles.Keys) - { - FileLoadFailure failure = null; - - try - { - bool loaded = LoadObject(file, gameSystemFiles[file]); - - if (!loaded) - { - failure = new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as GameSystem using {1}"); - } - } - catch (Exception ex) - { - failure = new FileLoadFailure(file, null, ex.Message, null, ex); - } - - if (failure!=null) - { - fails.Add(failure); - LogNotifier.Warn(GetType(), failure.Message, failure.Exception); - } - } - - return fails; - } - - private List<FileLoadFailure> LoadRaces(Dictionary<FileInfo, IWarFoundryFactory> raceFiles) - { - List<FileLoadFailure> fails = new List<FileLoadFailure>(); - - foreach (FileInfo file in raceFiles.Keys) - { - FileLoadFailure failure = null; - - try - { - bool loaded = LoadObject(file, raceFiles[file]); - - if (!loaded) - { - failure = new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}"); - } - } - catch (Exception ex) - { - failure = new FileLoadFailure(file, null, ex.Message, null, ex); - } - - if (failure!=null) - { - fails.Add(failure); - LogNotifier.Warn(GetType(), failure.Message, failure.Exception); - } - } - - return fails; - } - - private bool LoadObject(FileInfo file, IWarFoundryFactory factory) - { - bool loaded = false; - - LogNotifier.DebugFormat(GetType(), "Loading {0} using {1}", file.FullName, factory.GetType().Name); - ICollection<IWarFoundryObject> objects = factory.CreateObjectsFromFile(file); - - if (objects.Count > 0) - { - AddLoadedObjects(objects, factory); - loaded = true; - } - - return loaded; - } - - - /// <summary> - /// Loads a single file through the registered WarFoundryFactories, if a factory exists that supports the file format. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> for the file to attempt to load - /// </param> - /// <returns> - /// An ICollection of IWarFoundryObjects loaded from <code>file</code> - /// </returns> - public ICollection<IWarFoundryObject> LoadFile(FileInfo file) - { - ICollection<IWarFoundryObject> objs = null; - IWarFoundryFactory loadFactory = null; - - try - { - objs = LoadFileWithNonNativeFactories(file, out loadFactory); - - if (objs == null) - { - objs = LoadFileWithNativeFactories(file, out loadFactory); - } - } - catch (InvalidFileException ex) - { - LogNotifier.Error(GetType(), file.FullName+" failed to load", ex); - } - - if (objs!=null) - { - AddLoadedObjects(objs, loadFactory); - } - else - { - objs = new List<IWarFoundryObject>(); - } - - return objs; - } - - private ICollection<IWarFoundryObject> LoadFileWithNonNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) - { - ICollection<IWarFoundryObject> objs = null; - loadFactory = null; - - if (nonNativeFactories.Count > 0) - { - LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as a non-native file"); - - foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) - { - bool canLoad = factory.CanHandleFileFormat(file); - LogNotifier.Debug(GetType(), "Load using "+factory.GetType().FullName+"? " + (canLoad ? "yes" : "no")); - - if (canLoad) - { - objs = factory.CreateObjectsFromFile(file); - - if (objs!=null) - { - loadFactory = factory; - break; - } - } - } - } - - return objs; - } - - private ICollection<IWarFoundryObject> LoadFileWithNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) - { - ICollection<IWarFoundryObject> objs = null; - loadFactory = null; - - if (factories.Count > 0) - { - LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as native file"); - - foreach (INativeWarFoundryFactory factory in factories) - { - if (factory.CanHandleFileFormat(file)) - { - objs = factory.CreateObjectsFromFile(file); - - if (objs!=null) - { - loadFactory = factory; - break; - } - } - } - } - - return objs; - } - - private void AddLoadedObjects(ICollection<IWarFoundryObject> loadedObjs, IWarFoundryFactory factory) - { - SimpleSet<IWarFoundryObject> objs; - loadedObjects.TryGetValue(factory, out objs); - - if (objs == null) - { - objs = new SimpleSet<IWarFoundryObject>(); - loadedObjects.Add(factory, objs); - } - - objs.AddRange(loadedObjs); - StoreObjects(loadedObjs); - } - - private void StoreObjects(ICollection<IWarFoundryObject> loadedObjects) - { - foreach (IWarFoundryObject loadedObject in loadedObjects) - { - if (loadedObject is GameSystem) - { - StoreGameSystem((GameSystem)loadedObject); - } - else if (loadedObject is Race) - { - StoreRace((Race)loadedObject); - } - } - } - - protected void StoreGameSystem(GameSystem system) - { - GameSystem existingSystem = GetExistingSystemForSystem(system); - - if (existingSystem!=null) - { - if (!system.Equals(existingSystem)) - { - //TODO: Raise an event to say we got a different duplicate - //We can't just fail, because failing is for completely unhandled files, not for objects in a file - } - } - else - { - DoStoreGameSystem(system); - } - } - - /// <summary> - /// Gets a game system that has already been loaded that duplicates the supplied game system's ID, if one exists. - /// </summary> - /// <param name="system"> - /// The <see cref="GameSystem"/> to find pre-existing duplicates of - /// </param> - /// <returns> - /// <code>null</code> if no existing duplicate exists, else the duplicate <see cref="GameSystem"/> - /// </returns> - protected abstract GameSystem GetExistingSystemForSystem(GameSystem system); - - /// <summary> - /// Stores a GameSystem in the loader's relevant storage structure - /// </summary> - /// <param name="system"> - /// The loaded <see cref="GameSystem"/> to store - /// </param> - protected abstract void DoStoreGameSystem(GameSystem system); - - protected void StoreRace(Race race) - { - if (race.GameSystem == null) - { - throw new InvalidOperationException("Race cannot have null game system. Game system should be loaded before race."); - } - - DoStoreRace(race); - } - - /// <summary> - /// Performs the implementation specific storage of a race - /// </summary> - /// <param name="race"> - /// The <see cref="Race"/> to store - /// </param> - protected abstract void DoStoreRace(Race race); - - /// <summary> - /// Gets all <see cref="GameSystem"/>s that are currently available, determined by those that can be loaded with the current <see cref="IWarFoundryFactory"/>s. - /// </summary> - /// <returns> - /// An array of <see cref="GameSystem"/>s that are currently available. - /// </returns> - public abstract GameSystem[] GetGameSystems(); - - /// <summary> - /// Gets a single <see cref="GameSystem"/> with a given ID. - /// </summary> - /// <param name="systemID"> - /// The ID of the <see cref="GameSystem"/> to get, as a <see cref="System.String"/>. - /// </param> - /// <returns> - /// The <see cref="GameSystem"/> with the given ID, or <code>null</code> if one doesn't exist. - /// </returns> - public abstract GameSystem GetGameSystem(string systemID); - - /// <summary> - /// Removes a loaded <see cref="GameSystem"/>. Used when a GameSystem fails to complete loading - /// </summary> - /// <param name="system">The GameSystem to remove</param> - protected internal abstract void RemoveGameSystem(GameSystem system); - - /// <summary> - /// Gets an array of the races for the specified <see cref="GameSystem"/>. - /// </summary> - /// <param name="system"> - /// The <see cref="GameSystem"/> to get the available races for. - /// </param> - /// <returns> - /// An array of <see cref="Race"/>s for the <see cref="GameSystem"/> - /// </returns> - public abstract Race[] GetRaces(GameSystem system); - - /// <summary> - /// Gets a single race for a given <see cref="GameSystem"/> by ID of the race. - /// </summary> - /// <param name="system"> - /// The <see cref="GameSystem"/> that the race is part of. - /// </param> - /// <param name="raceID"> - /// A <see cref="System.String"/> ID for the race to load. - /// </param> - /// <returns> - /// A <see cref="Race"/> with the specified ID from the <see cref="GameSystem"/>, or <code>null</code> if one doesn't exist. - /// </returns> - public abstract Race GetRace(GameSystem system, string raceID); - - /// <summary> - /// Gets a single race for a given <see cref="GameSystem"/> by the race's ID and sub-race ID. - /// </summary> - /// <param name="system"> - /// The <see cref="GameSystem"/> that the race is part of. - /// </param> - /// <param name="raceID"> - /// The <see cref="System.String"/> ID for the race to load. - /// </param> - /// <param name="raceSubID"> - /// A <see cref="System.String"/> - /// </param> - /// <returns> - /// A <see cref="Race"/> - /// </returns> - public abstract Race GetRace(GameSystem system, string raceID, string raceSubID); - - protected internal abstract void RemoveRace(Race race); - - /// <summary> - /// Gets the IDs of all of the game systems currently available. - /// </summary> - /// <returns> - /// An array of <see cref="System.String"/>s representing the IDs of the game systems. - /// </returns> - public virtual string[] GetGameSystemIDs() - { - GameSystem[] systems = GetGameSystems(); - return GetWarFoundryObjectIDs(systems); - } - - protected string[] GetWarFoundryObjectIDs(WarFoundryObject[] objs) - { - int objCount = objs.Length; - string[] keys = new string[objCount]; - - for (int i = 0; i < objCount; i++) - { - keys[i] = objs[i].ID; - } - - return keys; - } - - /// <summary> - /// Gets the IDs of all of the races of a specified game system. - /// </summary> - /// <param name="system"> - /// The <see cref="GameSystem"/> to get the available races for. - /// </param> - /// <returns> - /// An array of <see cref="System.String"/>s representing the IDs of the races of the specified game system. - /// </returns> - public virtual string[] GetSystemRaceIDs(GameSystem system) - { - Race[] races = GetRaces(system); - return GetWarFoundryObjectIDs(races); - } - - public Army LoadArmy(FileInfo file) - { - IWarFoundryFactory factory = GetArmyLoadingFactoryForFile(file); - Army loadedArmy = null; - - if (factory != null) - { - ICollection<IWarFoundryObject> objs = factory.CreateObjectsFromFile(file); - - if (objs.Count == 1) - { - foreach (IWarFoundryObject systemCount in objs) - { - if (systemCount is Army) - { - loadedArmy = (Army) systemCount; - } - } - } - } - - return loadedArmy; - } - - private IWarFoundryFactory GetArmyLoadingFactoryForFile(FileInfo file) - { - IWarFoundryFactory loadingFactory = null; - - foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) - { - if (factory.CanHandleFileAsArmy(file)) - { - loadingFactory = factory; - break; - } - } - - if (loadingFactory == null) - { - foreach (INativeWarFoundryFactory factory in factories) - { - if (factory.CanHandleFileAsArmy(file)) - { - loadingFactory = factory; - break; - } - } - } - - return loadingFactory; - } - } -}
--- a/api/Commands/AbstractReplaceUnitEquipmentCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -// This file (AbstractReplaceUnitEquipmentCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// An abstract implementation of the core method for replacing one equipment item with another - /// </summary> - public abstract class AbstractReplaceUnitEquipmentCommand : Command - { - private SetUnitEquipmentNumericAmountCommand removeOldCommand; - private AbstractSetUnitEquipmentAmountCommand addNewCommand; - private string description; - private string undoDescription; - - public AbstractReplaceUnitEquipmentCommand(Unit unit, UnitEquipmentItem oldItem, AbstractSetUnitEquipmentAmountCommand addNewEquipmentCommand) - { - //We can get away with a numeric amount here even if it is a ratio item because we're setting it to 0 - removeOldCommand = new SetUnitEquipmentNumericAmountCommand(unit, oldItem, 0); - addNewCommand = addNewEquipmentCommand; - } - - public override bool CanExecute() - { - return removeOldCommand.CanExecute() && addNewCommand.CanExecute(); - } - - public override string Description - { - get - { - if (description == null) - { - description = Translation.GetTranslation("replaceUnitEquipmentCommandDescription", "replace {0} with {1} for {2}", removeOldCommand.EquipItem.Name, addNewCommand.EquipItem.Name, removeOldCommand.Unit.Name); - } - - return description; - } - } - - public override string UndoDescription - { - get - { - if (undoDescription == null) - { - undoDescription = Translation.GetTranslation("replaceUnitEquipmentCommandUndoDescription", "replace {0} with {1} for {2}", addNewCommand.EquipItem.Name, removeOldCommand.EquipItem.Name, removeOldCommand.Unit.Name); - } - - return undoDescription; - } - } - - public override bool Execute() - { - this.Redo(); - return true; - } - - public override void Redo() - { - removeOldCommand.Redo(); - addNewCommand.Redo(); - } - - public override void Undo() - { - addNewCommand.Undo(); - removeOldCommand.Undo(); - } - - - public override string Name - { - get - { - return "Replace required equipment"; - } - } - } -}
--- a/api/Commands/AbstractSetUnitEquipmentAmountCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -// This file (AbstractSetUnitEquipmentAmountCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; -using IBBoard.WarFoundry.API.Util; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// Abstract parent class for commands that set the amount of an equipment item a unit has to a fixed numeric or ratio value - /// </summary> - public abstract class AbstractSetUnitEquipmentAmountCommand : Command - { - private Unit unit; - private UnitEquipmentItem equip; - private double oldAmount; - private bool oldAmountWasRatio; - private string description; - private string undoDescription; - - public AbstractSetUnitEquipmentAmountCommand(Unit unit, UnitEquipmentItem item) - { - this.unit = unit; - equip = item; - oldAmount = UnitEquipmentUtil.GetEquipmentAmount(unit, equip); - oldAmountWasRatio = UnitEquipmentUtil.GetEquipmentAmountIsRatio(unit, equip); - } - - public override bool CanExecute() - { - return (unit!=null && equip!=null); - } - - public override string Description - { - get - { - if (description == null) - { - description = Translation.GetTranslation("setEquipmentAmountCommandDescription", "set {0} amount for {1} to {2}", equip.Name, unit.Name, GetNewAmountString()); - } - - return description; - } - } - - /// <summary> - /// Gets the string representation for the new amount of the equipment item to take - /// </summary> - /// <returns> - /// the string representation for the new amount of the equipment item to take - /// </returns> - protected abstract string GetNewAmountString(); - - public override string UndoDescription - { - get - { - if (undoDescription == null) - { - undoDescription = Translation.GetTranslation("setEquipmentAmountCommandUndoDescription", "set {0} amount for {1} to {2}", equip.Name, unit.Name, GetOldAmountString()); - } - - return undoDescription; - } - } - - /// <summary> - /// Gets the string representation for the old amount of the equipment item to take - /// </summary> - /// <returns> - /// the string representation for the old amount of the equipment item to take - /// </returns> - protected string GetOldAmountString() - { - return oldAmountWasRatio ? GetRatioAmountString(oldAmount, UnitEquipmentRatioSelection.CalculateNumberTaken(Unit, EquipItem, oldAmount)) : GetNumberAmountString((int)oldAmount); - } - - protected string GetNumberAmountString(int number) - { - return Translation.GetTranslation ("equipmentAmountNumber", "{0}", number); - } - - protected string GetRatioAmountString (double amount, int number) - { - string amountString; - - if (amount == 100) - { - amountString = Translation.GetTranslation ("equipmentAmountAll", "all ({1})", amount, number); - } - else - { - amountString = Translation.GetTranslation ("equipmentAmountPercentage", "{0}% ({1})", amount, number); - } - - return amountString; - } - - public override bool Execute() - { - this.Redo(); - return true; - } - - public override void Undo () - { - if (oldAmountWasRatio) - { - unit.SetEquipmentRatio(equip, oldAmount); - } - else - { - unit.SetEquipmentAmount(equip, (int)oldAmount); - } - } - - - public UnitEquipmentItem EquipItem - { - get { return equip; } - } - - public Unit Unit - { - get { return unit; } - } - } -}
--- a/api/Commands/CreateAndAddUnitCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -// This file (CreateAndAddUnitCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - public class CreateAndAddUnitCommand : Command - { - private UnitType addedUnitType; - private ArmyCategory armyCat; - private Unit addedUnit; - private string description; - private string undoDescription; - - public CreateAndAddUnitCommand(UnitType toAdd, ArmyCategory armyCatTo) - { - addedUnitType = toAdd; - armyCat = armyCatTo; - } - - public override bool CanExecute() - { - return (addedUnitType!=null && armyCat!=null); - } - - public override string Description - { - get - { - if (description == null) - { - description = Translation.GetTranslation("createAndAddUnitCommandDescription", "add unit of {0} to the army", addedUnitType.Name); - } - - return description; - } - } - - public override string UndoDescription - { - get - { - if (undoDescription == null) - { - undoDescription = Translation.GetTranslation("createAndAddUnitCommandUndoDescription", "remove unit of {0} from army", addedUnitType.Name); - } - - return undoDescription; - } - } - - public override bool Execute() - { - addedUnit = new Unit(addedUnitType, armyCat); - this.Redo(); - return true; - } - - public override void Redo() - { - armyCat.AddUnit(addedUnit); - } - - public override void Undo() - { - armyCat.RemoveUnit(addedUnit); - } - - public override string Name - { - get { return "Add new unit"; } - } - - public Unit Unit - { - get { return addedUnit; } - } - } -}
--- a/api/Commands/RemoveUnitCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -// This file (RemoveUnitCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// Summary description for RemoveUnitCommand. - /// </summary> - public class RemoveUnitCommand : Command - { - private Unit unit; - private ArmyCategory cat; - private string description; - private string undoDescription; - - public RemoveUnitCommand(Unit toRemove) - { - unit = toRemove; - cat = unit.Category; - } - - public override bool CanExecute() - { - return (unit!=null); - } - - public override string Description - { - get - { - if (description == null) - { - description = Translation.GetTranslation("removeUnitCommandDescription", "remove {0} from the army", unit.Name); - } - - return description; - } - } - - public override string UndoDescription - { - get - { - if (undoDescription == null) - { - undoDescription = Translation.GetTranslation("removeUnitCommandUndoDescription", "re-add {0} to the army", unit.Name); - } - - return undoDescription; - } - } - - public override bool Execute() - { - this.Redo(); - return true; - } - - public override void Redo() - { - cat.RemoveUnit(unit); - } - - public override void Undo() - { - cat.AddUnit(unit); - } - - public override string Name - { - get { return "Remove unit"; } - } - } -}
--- a/api/Commands/ReplaceUnitEquipmentWithNumericAmountItemCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -// This file (ReplaceUnitEquipmentWithNumericAmountItemCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// A concrete implementation of an equipment replacing command that replaces a given equipment item with a different item that has an absolute numeric amount. - /// </summary> - public class ReplaceUnitEquipmentWithNumericAmountItemCommand : AbstractReplaceUnitEquipmentCommand - { - public ReplaceUnitEquipmentWithNumericAmountItemCommand(Unit unit, UnitEquipmentItem oldItem, UnitEquipmentItem newItem, int newItemAmount) : base(unit, oldItem, new SetUnitEquipmentNumericAmountCommand(unit, newItem, newItemAmount)) - { - //Do nothing special - } - } -}
--- a/api/Commands/ReplaceUnitEquipmentWithRatioAmountItemCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -// This file (ReplaceUnitEquipmentWithRatioAmountItemCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// A concrete implementation of an equipment replacing command that replaces a given equipment item with a different item that has a ratio/percentage amount. - /// </summary> - public class ReplaceUnitEquipmentWithRatioAmountItemCommand : AbstractReplaceUnitEquipmentCommand - { - public ReplaceUnitEquipmentWithRatioAmountItemCommand(Unit unit, UnitEquipmentItem oldItem, UnitEquipmentItem newItem, double newItemRatio) : base(unit, oldItem, new SetUnitEquipmentRatioAmountCommand(unit, newItem, newItemRatio)) - { - //Do nothing special - } - } -}
--- a/api/Commands/SetNameCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -// This file (SetNameCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// Summary description for SetNameCommand. - /// </summary> - public class SetNameCommand : Command - { - private WarFoundryObject obj; - private string newName, oldName; - private string description; - private string undoDescription; - - public SetNameCommand(WarFoundryObject toRename, string name) - { - obj = toRename; - newName = name; - oldName = obj.Name; - } - - public override bool CanExecute() - { - return (obj!=null && newName!=null && newName!=""); - } - - public override string Description - { - get - { - if (description == null) - { - description = Translation.GetTranslation("setUnitNameCommandDescription", "rename \"{0}\" to \"{1}\"", oldName, newName); - } - - return description; - } - } - - public override string UndoDescription - { - get - { - if (undoDescription == null) - { - undoDescription = Translation.GetTranslation("setUnitNameCommandUndoDescription", "rename \"{0}\" to \"{1}\"", newName, oldName); - } - - return undoDescription; - } - } - - public override bool Execute() - { - this.Redo(); - return true; - } - - public override void Redo() - { - obj.Name = newName; - } - - public override void Undo() - { - obj.Name = oldName; - } - - public override string Name - { - get { return "Rename item"; } - } - } -}
--- a/api/Commands/SetUnitEquipmentNumericAmountCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -// This file (SetUnitEquipmentNumericAmountCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// Summary description for SetUnitEquipmentNumericAmountCommand. - /// </summary> - public class SetUnitEquipmentNumericAmountCommand : AbstractSetUnitEquipmentAmountCommand - { - private int newAmount; - - public SetUnitEquipmentNumericAmountCommand(Unit unit, UnitEquipmentItem item, int amount) : base(unit, item) - { - newAmount = amount; - } - - protected override string GetNewAmountString () - { - return GetNumberAmountString(newAmount); - } - - public override void Redo() - { - Unit.SetEquipmentAmount(EquipItem, newAmount); - } - - public override string Name - { - get { return "Set equipment amount"; } - } - } -}
--- a/api/Commands/SetUnitEquipmentRatioAmountCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -// This file (SetUnitEquipmentRatioAmountCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// Summary description for SetUnitEquipmentRatioAmountCommand. - /// </summary> - public class SetUnitEquipmentRatioAmountCommand : AbstractSetUnitEquipmentAmountCommand - { - private double newAmount; - - public SetUnitEquipmentRatioAmountCommand(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item) - { - newAmount = amount; - } - - protected override string GetNewAmountString () - { - return GetRatioAmountString(newAmount, UnitEquipmentRatioSelection.CalculateNumberTaken(Unit, EquipItem, newAmount)); - } - - public override void Redo() - { - Unit.SetEquipmentRatio(EquipItem, newAmount); - } - - public override string Name - { - get { return "Set equipment ratio"; } - } - } -}
--- a/api/Commands/SetUnitSizeCommand.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -// This file (SetUnitSizeCommand.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.Commands; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Commands -{ - /// <summary> - /// Summary description for SetNameCommand. - /// </summary> - public class SetUnitSizeCommand : Command - { - private Unit unit; - private int newSize, oldSize; - private string description; - private string undoDescription; - - public SetUnitSizeCommand(Unit toResize, int size) - { - unit = toResize; - newSize = size; - oldSize = unit.Size; - } - - public override bool CanExecute() - { - return (unit!=null && newSize >0 && oldSize > 0); - } - - public override string Description - { - get - { - if (description == null) - { - description = Translation.GetTranslation("setUnitSizeCommandDescription", "set size of {0} to {1}", unit.Name, newSize); - } - - return description; - } - } - - public override string UndoDescription - { - get - { - if (undoDescription == null) - { - undoDescription = Translation.GetTranslation("setUnitSizeCommandUndoDescription", "set size of {0} to {1}", unit.Name, oldSize); - } - - return undoDescription; - } - } - - public override bool Execute() - { - this.Redo(); - return true; - } - - public override void Redo() - { - unit.Size = newSize; - } - - public override void Undo() - { - unit.Size = oldSize; - } - - public override string Name - { - get { return "Change unit size"; } - } - } -}
--- a/api/DefaultWarFoundryLoader.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -// This file (DefaultWarFoundryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API -{ - /// <summary> - /// The default implementation of a <see cref="AbstractWarFoundryLoader"/> - /// </summary> - public class DefaultWarFoundryLoader : AbstractWarFoundryLoader - { - private Dictionary<string, GameSystem> systemsTable; - private Dictionary<string, Dictionary<string, Dictionary<string, Race>>> racesTable; //Keys are: System, Race, SubRace - - public DefaultWarFoundryLoader () - { - } - - protected override void PrepareForFileLoad() - { - //Just set up blank dictionaries for now - may try different and more complex handling in future - systemsTable = new Dictionary<string,GameSystem>(); - racesTable = new Dictionary<string,Dictionary<string,Dictionary<string,Race>>>(); - } - - protected override GameSystem GetExistingSystemForSystem (GameSystem system) - { - return DictionaryUtils.GetValue(systemsTable, system.ID.ToLower()); - } - - protected override void DoStoreGameSystem (GameSystem system) - { - systemsTable[system.ID.ToLower()] = system; - } - - protected override void DoStoreRace (Race race) - { - Dictionary<string, Dictionary<string, Race>> systemRaces; - - string systemID = race.GameSystem.ID.ToLower(); - racesTable.TryGetValue(systemID, out systemRaces); - - if (systemRaces==null) - { - systemRaces = new Dictionary<string,Dictionary<string,Race>>(); - racesTable.Add(systemID, systemRaces); - } - - Dictionary<string, Race> subRaces; - systemRaces.TryGetValue(race.ID.ToLower(), out subRaces); - - if (subRaces==null) - { - subRaces = new Dictionary<string,Race>(); - systemRaces.Add(race.ID.ToLower(), subRaces); - } - - string subID = race.SubID.ToLower(); - - if (subRaces.ContainsKey(subID)) - { - Race existingRace = subRaces[subID]; - - if (!race.Equals(existingRace)) - { - //TODO: Raise an event to say we got a different duplicate - //We can't just fail, because failing is for completely unhandled files, not for objects in a file - } - } - else - { - subRaces.Add(race.SubID.ToLower(), race); - } - } - - public override GameSystem[] GetGameSystems() - { - if (systemsTable==null) - { - LoadFiles(); - } - - return DictionaryUtils.ToArray<string, GameSystem>(systemsTable); - } - - public override GameSystem GetGameSystem(string systemID) - { - if (systemsTable==null) - { - LoadFiles(); - } - - GameSystem system; - systemsTable.TryGetValue(systemID.ToLower(), out system); - return system; - } - - protected internal override void RemoveGameSystem(GameSystem system) - { - systemsTable.Remove(system.ID.ToLower()); - } - - public override Race[] GetRaces(GameSystem system) - { - return GetRaces(system.ID); - } - - /// <summary> - /// Gets an array of the races for a game system by ID. - /// </summary> - /// <param name="systemID"> - /// The <see cref="System.String"/> ID of the game system to get races for - /// </param> - /// <returns> - /// An array of <see cref="Race"/>s for the specified game system - /// </returns> - public Race[] GetRaces(string systemID) - { - if (racesTable==null) - { - LoadFiles(); - } - - systemID = systemID.ToLower(); - Dictionary<string, Dictionary<string, Race>> system; - racesTable.TryGetValue(systemID, out system); - - if (system==null) - { - return new Race[0]; - } - - int count = 0; - - foreach (Dictionary<string, Race> racesDict in system.Values) - { - count+= racesDict.Count; - } - - Race[] races = new Race[count]; - int i = 0; - - foreach (string raceID in system.Keys) - { - foreach (string raceSubId in system[raceID].Keys) - { - races[i++] = GetRace(systemID, raceID, raceSubId); - } - } - - return races; - } - - public override Race GetRace(GameSystem system, string raceID) - { - return GetRace(system.ID, raceID); - } - - /// <summary> - /// Gets a single race for a given game system by ID of the game system and race. - /// </summary> - /// <param name="systemID"> - /// The <see cref="System.String"/> ID of the game system that the race is part of. - /// </param> - /// <param name="raceID"> - /// The <see cref="System.String"/> ID for the race to load. - /// </param> - /// <returns> - /// A <see cref="Race"/> with the specified ID from the game system with the specified ID, or <code>null</code> if there is no race or game system with those IDs. - /// </returns> - public Race GetRace(string systemID, string raceID) - { - return GetRace(systemID, raceID, ""); - } - - public override Race GetRace(GameSystem system, string raceID, string raceSubID) - { - return GetRace(system.ID, raceID, raceSubID); - } - - /// <summary> - /// Gets a single race for a given game system by the game system's ID and the race's ID and sub-race ID. - /// </summary> - /// <param name="systemID"> - /// The <see cref="System.String"/> ID of the game system that the race is part of. - /// </param> - /// <param name="raceID"> - /// The <see cref="System.String"/> ID for the race to load. - /// </param> - /// <param name="raceSubID"> - /// A <see cref="System.String"/> - /// </param> - /// <returns> - /// A <see cref="Race"/> - /// </returns> - public Race GetRace(string systemID, string raceID, string raceSubID) - { - if (racesTable==null) - { - LoadFiles(); - } - - Race race = null; - - Dictionary<string, Race> subraces = GetRaceTable(systemID, raceID); - - if (subraces != null) - { - subraces.TryGetValue(raceSubID.ToLower(), out race); - } - - return race; - } - - private Dictionary<string, Race> GetRaceTable(string systemID, string raceID) - { - Dictionary<string, Dictionary<string, Race>> races; - racesTable.TryGetValue(systemID.ToLower(), out races); - Dictionary<string, Race> subraces = null; - - if (races != null) - { - races.TryGetValue(raceID.ToLower(), out subraces); - } - - return subraces; - } - - protected internal override void RemoveRace(Race race) - { - Dictionary<string, Race> subraces = GetRaceTable(race.GameSystem.ID, race.ID); - - if (subraces != null) - { - subraces.Remove(race.SubID.ToLower()); - } - } - - public override string[] GetGameSystemIDs() - { - if (systemsTable==null) - { - LoadFiles(); - } - - return DictionaryUtils.ToKeyArray(systemsTable); - } - - public override string[] GetSystemRaceIDs(GameSystem system) - { - return GetSystemRaceIDs(system.ID); - } - - /// <summary> - /// Gets the IDs of all of the races of a specified game system. - /// </summary> - /// <param name="systemID"> - /// The <see cref="System.String"/> ID of the game system to get the available races for. - /// </param> - /// <returns> - /// An array of <see cref="System.String"/>s representing the IDs of the races of the specified game system. - /// </returns> - public string[] GetSystemRaceIDs(string systemID) - { - if (racesTable == null) - { - LoadFiles(); - } - - Dictionary<string, Dictionary<string, Race>> races = racesTable[systemID.ToLower()]; - - if (races==null) - { - return new string[0]; - } - else - { - string[] keys = new string[races.Keys.Count]; - int i = 0; - - foreach (string key in races.Keys) - { - keys[i++] = key; - } - - return keys; - } - } - } -}
--- a/api/Delegates.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -// This file (Delegates.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API -{ - public delegate void ObjectChangedDelegate(WarFoundryObject oldValue, WarFoundryObject newValue); - public delegate void ArmyChangedDelegate(Army oldValue, Army newValue); - public delegate void GameSystemChangedDelegate(GameSystem oldValue, GameSystem newValue); - public delegate void ObjectAddDelegate(WarFoundryObject val); - public delegate void ObjectRemoveDelegate(WarFoundryObject val); - public delegate void UnitAddDelegate(Unit val); - public delegate void UnitRemoveDelegate(Unit val); - public delegate void ObjectUpdatedDelegate(WarFoundryObject val, string updatedValName); - public delegate void DoubleValChangedDelegate(WarFoundryObject obj, double oldValue, double newValue); - public delegate void FloatValChangedDelegate(WarFoundryObject obj, float oldValue, float newValue); - public delegate void StringValChangedDelegate(WarFoundryObject obj, string oldValue, string newValue); - public delegate void IntValChangedDelegate(WarFoundryObject obj, int oldValue, int newValue); -}
--- a/api/Exporters/IWarFoundryExporter.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// This file (IWarFoundryExporter.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Exporters -{ - /// <summary> - /// An interface to be implemented by classes that export WarFoundry armies to other formats than "saved armies" (e.g. HTML) - /// </summary> - public interface IWarFoundryExporter - { - /// <summary> - /// Exports the army to the specified path - /// </summary> - /// <param name="army"> - /// The <see cref="Army"/> to export - /// </param> - /// <param name="path"> - /// The file path to export to - /// </param> - void ExportArmy(Army army, string path); - } -}
--- a/api/Exporters/WarFoundryHtmlExporter.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,396 +0,0 @@ -// This file (WarFoundryHtmlExporter.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Xml; -using System.Xml.Schema; -using IBBoard.Lang; -using IBBoard.Xml; -using IBBoard.WarFoundry.API.Objects; -using IBBoard.WarFoundry.API.Util; - -namespace IBBoard.WarFoundry.API.Exporters -{ - /// <summary> - /// Custom exporter that exports an army as a basic HTML file - /// </summary> - public class WarFoundryHtmlExporter : IWarFoundryExporter - { - private static WarFoundryHtmlExporter exporter; - private delegate string GetStatCellTextDelegate(Stat stat); - - public static WarFoundryHtmlExporter GetDefault() - { - if (exporter == null) - { - exporter = new WarFoundryHtmlExporter(); - } - - return exporter; - } - - private WarFoundryHtmlExporter() - { - //Hide constructor - } - - public void ExportArmy(Army army, string path) - { - XmlDocument doc = new XmlDocument(); - CustomXmlResolver resolver = new CustomXmlResolver(); - resolver.AddMapping("-//W3C//DTD XHTML 1.0 Strict//EN", new Uri("file://" + IBBoard.Constants.ExecutablePath + "/schemas/xhtml1-strict.dtd")); - doc.XmlResolver = resolver; - doc.AppendChild(doc.CreateDocumentType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", null)); - XmlElement html = doc.CreateElement("html"); - doc.AppendChild(html); - XmlElement head = doc.CreateElement("head"); - html.AppendChild(head); - XmlElement title = doc.CreateElement("title"); - title.InnerXml = army.Name; - head.AppendChild(title); - XmlElement metaCharset = doc.CreateElement("meta"); - metaCharset.SetAttribute("http-equiv", "Content-Type"); - metaCharset.SetAttribute("content", "text/html;charset=UTF-8"); - head.AppendChild(metaCharset); - XmlElement style = doc.CreateElement("style"); - style.InnerText = "table, th, td { border: 1px solid #000; border-spacing: 0; border-collapse: collapse; margin: 0 }\n" - +"table table { width: 100%; border-width: 0; margin: -2px }\n" - +"table table td { border-width:0 1px }"; - head.AppendChild(style); - XmlElement body = doc.CreateElement("body"); - html.AppendChild(body); - XmlElement header = doc.CreateElement("h1"); - header.InnerText = Translation.GetTranslation("armyHtmlOutputBodyHeader", "{0} - {1}pts", army.Name, army.Points); - body.AppendChild(header); - - foreach (XmlElement table in CreateTables(army, doc)) - { - if (!IsTableOnlyHeader(table)) - { - body.AppendChild(table); - } - } - - StreamWriter writer = new StreamWriter(path, false); - - try - { - writer.Write(doc.OuterXml); - } - finally - { - writer.Close(); - } - } - - private bool IsTableOnlyHeader(XmlElement table) - { - return table.ChildNodes.Count == 1; - } - - private XmlElement[] CreateTables(Army army, XmlDocument doc) - { - Dictionary<string, XmlElement> tables = new Dictionary<string, XmlElement>(); - - foreach (SystemStats statSets in army.GameSystem.SystemStats) - { - tables[statSets.ID] = CreateTable(statSets, doc); - } - - foreach (Unit unit in army.GetUnits()) - { - CreateUnitRow(unit, tables[GetFirstStatType(unit)]); - } - - return DictionaryUtils.ToArray(tables); - } - - private static string GetFirstStatType(Unit unit) - { - string[] unitStatIDs = unit.UnitStatsArrayIDs; - return GetFirstStatType(unitStatIDs); - } - - public static string GetFirstStatType(string[] unitStatIDs) - { - return unitStatIDs[0]; - } - - private XmlElement CreateTable(SystemStats stats, XmlDocument doc) - { - XmlElement table = doc.CreateElement("table"); - XmlElement headerRow = doc.CreateElement("tr"); - table.AppendChild(headerRow); - XmlElement name = doc.CreateElement("th"); - name.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitName", "name"); - headerRow.AppendChild(name); - - XmlElement unitTypeName = doc.CreateElement("th"); - unitTypeName.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitTypeName", "type name"); - headerRow.AppendChild(unitTypeName); - - foreach (StatSlot stat in stats.StatSlots) - { - XmlElement statHeader = doc.CreateElement("th"); - statHeader.InnerText = stat.Name; - headerRow.AppendChild(statHeader); - } - - XmlElement notes = doc.CreateElement("th"); - notes.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitNotes", "name");; - headerRow.AppendChild(notes); - - XmlElement points = doc.CreateElement("th"); - points.InnerText = Translation.GetTranslation("armyHtmlOutputTableHeaderUnitPoints", "name");; - headerRow.AppendChild(points); - - return table; - } - - private XmlElement CreateUnitRow(Unit unit, XmlElement tableElem) - { - XmlDocument doc = tableElem.OwnerDocument; - XmlElement row = doc.CreateElement("tr"); - tableElem.AppendChild(row); - Stat[][] memberStats = unit.UnitStatsArraysWithName; - string[] statTypeIDs = unit.UnitStatsArrayIDs; - string defaultStatType = GetFirstStatType(statTypeIDs); - int statRowCount = 0; - bool hasOther = false; - - foreach (string statTypeID in statTypeIDs) - { - if (statTypeID.Equals(defaultStatType)) - { - statRowCount++; - } - else if (!hasOther) - { - statRowCount++; - hasOther = true; - } - } - - XmlElement name = doc.CreateElement("td"); - name.InnerText = unit.Name; - SetRowSpan(name, statRowCount); - row.AppendChild(name); - CreateStatsBlock(row, memberStats, statTypeIDs); - - StringBuilder sb = new StringBuilder(); - UnitEquipmentItem[] unitEquipment = unit.GetEquipment(); - - if (unitEquipment.Length > 0) - { - bool addSeparator = false; - - foreach (UnitEquipmentItem equip in unitEquipment) - { - if (!addSeparator) - { - addSeparator = true; - } - else - { - sb.Append(", "); - } - - string amountString; - double amount = UnitEquipmentUtil.GetEquipmentAmount(unit, equip); - - if (UnitEquipmentUtil.GetEquipmentAmountIsRatio(unit, equip)) - { - - if (amount == 100) - { - amountString = GetEquipmentAmountAllTranslation(unit); - } - else - { - int number = UnitEquipmentUtil.GetEquipmentAmountTaken(unit, equip); - amountString = GetEquipmentAmountRatioTranslation(amount, number); - } - } - else - { - if (amount == -1) - { - amountString = GetEquipmentAmountAllTranslation(unit); - } - else - { - amountString = GetEquipmentAmountNumberTranslation((int)amount); - } - } - - sb.Append(Translation.GetTranslation("armyHtmlExportEquipAmountRatio", "{0} for {1}", equip.Name, amountString)); - } - - sb.Append(". "); - } - - ICollection<Ability> abilities = unit.Abilities; - - if (abilities.Count > 0) - { - bool addSeparator = false; - - foreach (Ability ability in abilities) - { - if (!addSeparator) - { - addSeparator = true; - } - else - { - sb.Append(", "); - } - - sb.Append(ability.Name); - } - - sb.Append(". "); - } - - XmlElement notes = doc.CreateElement("td"); - notes.InnerText = sb.ToString(); - SetRowSpan(notes, statRowCount); - row.AppendChild(notes); - - XmlElement points = doc.CreateElement("td"); - points.InnerText = unit.Points.ToString(); - SetRowSpan(points, statRowCount); - row.AppendChild(points); - - return row; - } - - private static void SetRowSpan(XmlElement xmlElement, int statRowCount) - { - if (statRowCount > 1) - { - xmlElement.SetAttribute("rowspan", statRowCount.ToString()); - } - } - - private void CreateStatsBlock(XmlElement unitRow, Stat[][] memberStats, string[] statTypeIDs) - { - XmlDocument doc = unitRow.OwnerDocument; - string defaultStatType = GetFirstStatType(statTypeIDs); - - Stat[] defaultStatLine = memberStats[0]; - int defaultStatLineCount = defaultStatLine.Length; - AddStatCell(defaultStatLine[0].SlotValueString, unitRow); - - for (int i = 1; i < defaultStatLineCount; i++) - { - string statText = GetDefaultStatCellText(defaultStatLine[i]); - AddStatCell(statText, unitRow); - } - - int statCount = statTypeIDs.Length; - - if (statCount > 1) - { - XmlElement unitTable = (XmlElement)unitRow.ParentNode; - Dictionary<string, XmlElement> statParents = CreateStatsParentElements(statTypeIDs, unitTable); - - for (int i = 1; i < statCount; i++) - { - Stat[] statLine = memberStats[i]; - string statTypeID = statTypeIDs[i]; - XmlElement tableElement = DictionaryUtils.GetValue(statParents, statTypeID); - int statLineCount = statLine.Length; - XmlElement statRow = doc.CreateElement("tr"); - tableElement.AppendChild(statRow); - GetStatCellTextDelegate statCellTextDelegate = (statTypeID.Equals(defaultStatType) ? new GetStatCellTextDelegate(GetDefaultStatCellText) : new GetStatCellTextDelegate(GetOtherStatCellText)); - AddStatCell(statLine[0].SlotValueString, statRow); - - for (int j = 1; j < statLineCount; j++) - { - string statText = statCellTextDelegate(statLine[j]); - AddStatCell(statText, statRow); - } - } - - if (statParents.Count > 1) - { - AddOtherUnitStatTables(statParents, unitTable, defaultStatLineCount); - } - } - } - - private static void AddOtherUnitStatTables(Dictionary<string, XmlElement> statParents, XmlElement unitTable, int defaultStatLineCount) - { - XmlDocument doc = unitTable.OwnerDocument; - XmlElement otherStatsRow = doc.CreateElement("tr"); - unitTable.AppendChild(otherStatsRow); - XmlElement otherStatsCell = doc.CreateElement("td"); - otherStatsCell.SetAttribute("colspan", defaultStatLineCount.ToString()); - otherStatsRow.AppendChild(otherStatsCell); - - foreach (XmlElement tableElem in statParents.Values) - { - if (tableElem != unitTable) - { - otherStatsCell.AppendChild(tableElem); - } - } - } - - private Dictionary<string, XmlElement> CreateStatsParentElements(string[] statTypeIDs, XmlElement parentTable) - { - Dictionary<string, XmlElement> statParents = new Dictionary<string, XmlElement>(); - XmlDocument doc = parentTable.OwnerDocument; - string defaultStatTypeID = GetFirstStatType(statTypeIDs); - statParents[defaultStatTypeID] = parentTable; - - foreach (string statTypeID in statTypeIDs) - { - if (!statParents.ContainsKey(statTypeID)) - { - XmlElement tableElement = doc.CreateElement("table"); - statParents[statTypeID] = tableElement; - } - } - - return statParents; - } - - private string GetDefaultStatCellText(Stat stat) - { - return Translation.GetTranslation("armyHtmlExportDefaultStatCellText", "{0}", stat.SlotValueString, stat.ParentSlotName); - } - - private string GetOtherStatCellText(Stat stat) - { - return Translation.GetTranslation("armyHtmlExportOtherStatCellText", "{1}: {0}", stat.SlotValueString, stat.ParentSlotName); - } - - private static void AddStatCell(string statValue, XmlElement row) - { - XmlElement statCell = row.OwnerDocument.CreateElement("td"); - statCell.InnerText = statValue; - row.AppendChild(statCell); - } - - private string GetEquipmentAmountRatioTranslation (double amount, int number) - { - return Translation.GetTranslation ("armyHtmlExportEquipAmountPercentage", "{0}% ({1})", amount, number); - } - - private string GetEquipmentAmountNumberTranslation(int amount) - { - return Translation.GetTranslation("armyHtmlExportEquipAmountNumber", "{0}", amount); - } - - private string GetEquipmentAmountAllTranslation(Unit unit) - { - return Translation.GetTranslation("armyHtmlExportEquipAmountAll", "all ({1})", 100, unit.Size); - } - } -}
--- a/api/Factories/AbstractNativeWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -// This file (AbstractNativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using System.Xml; -using System.Xml.Schema; -using System.Collections.Generic; -using System.Text; -using IBBoard; -using IBBoard.IO; -using IBBoard.Lang; -using IBBoard.Logging; -using IBBoard.Xml; -using IBBoard.WarFoundry.API.Objects; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Factories -{ - /// <summary> - /// Base abstract class for all factories that load native WarFoundry data. - /// </summary> - public abstract class AbstractNativeWarFoundryFactory : AbstractWarFoundryFactory<ZipFile>, INativeWarFoundryFactory - { - protected AbstractNativeWarFoundryFactory() - { - //Do nothing - just make the constructor non-public - } - - protected override ZipFile GetFileAsSupportedType (FileInfo file) - { - ZipFile zip = null; - - try - { - zip = new ZipFile(file.FullName); - } - catch(ZipException) - { - //Silently dispose as per spec for the method - } - catch (IOException) - { - //Silently dispose as per spec for the method - } - - return zip; - } - - protected override bool CheckCanHandleFileFormat (ZipFile file) - { - return CheckCanHandleFileAsGameSystem(file) || CheckCanHandleFileAsRace(file) || CheckCanHandleFileAsArmy(file); - } - - protected override bool CheckCanHandleFileAsGameSystem(ZipFile file) - { - return CheckCanFindSystemFileContent(file); - } - - protected abstract bool CheckCanFindSystemFileContent(ZipFile file); - - protected override bool CheckCanHandleFileAsRace(ZipFile file) - { - return CheckCanFindRaceFileContent(file); - } - - protected abstract bool CheckCanFindRaceFileContent(ZipFile file); - - protected override bool CheckCanHandleFileAsArmy(ZipFile file) - { - return CheckCanFindArmyFileContent(file); - } - - protected abstract bool CheckCanFindArmyFileContent(ZipFile file); - - protected override ICollection<IWarFoundryObject> DoCreateObjectsFromFile (ZipFile file) - { - ICollection<IWarFoundryObject> objects = null; - IWarFoundryObject obj = null; - - try - { - if (CheckCanFindSystemFileContent(file)) - { - obj = CreateGameSystemFromFile(file); - } - else if (CheckCanFindRaceFileContent(file)) - { - obj = CreateRaceFromFile(file); - } - else if (CheckCanFindArmyFileContent(file)) - { - obj = CreateArmyFromFile(file); - } - } - finally - { - file.Close(); - } - - if (obj!=null) - { - objects = new List<IWarFoundryObject>(); - objects.Add(obj); - } - - return objects; - } - - protected Army CreateArmyFromFile(ZipFile file) - { - Stream dataStream = GetArmyDataStream(file); - - try - { - return CreateArmyFromStream(file, dataStream); - } - finally - { - dataStream.Close(); - } - } - - protected abstract Stream GetArmyDataStream(ZipFile file); - protected abstract Army CreateArmyFromStream(ZipFile file, Stream dataStream); - - protected Race CreateRaceFromFile(ZipFile file) - { - Stream dataStream = GetRaceDataStream(file); - - try - { - return CreateRaceFromStream(file, dataStream); - } - finally - { - dataStream.Close(); - } - } - - protected abstract Stream GetRaceDataStream(ZipFile file); - protected abstract Race CreateRaceFromStream(ZipFile file, Stream dataStream); - - protected GameSystem CreateGameSystemFromFile(ZipFile file) - { - Stream dataStream = GetGameSystemDataStream(file); - - try - { - return CreateGameSystemFromStream(file, dataStream); - } - finally - { - dataStream.Close(); - } - } - - protected abstract Stream GetGameSystemDataStream(ZipFile file); - protected abstract GameSystem CreateGameSystemFromStream(ZipFile file, Stream dataStream); - - public override bool Equals (object o) - { - if (o == this) - { - return true; - } - else if (o == null || !(this.GetType().Equals(o.GetType()))) - { - return false; - } - - return true; - } - - public override int GetHashCode () - { - return GetType().FullName.GetHashCode(); - } - } -}
--- a/api/Factories/AbstractNonNativeFileExtensionWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -// This file (AbstractNonNativeFileExtensionWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; -using System.IO; -using IBBoard.Logging; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories -{ - public abstract class AbstractNonNativeFileExtensionWarFoundryFactory : AbstractNonNativeWarFoundryFactory<FileInfo> - { - protected abstract string ArmyFileExtension { get; } - protected abstract string RaceFileExtension { get; } - protected abstract string GameSystemFileExtension { get; } - - protected override bool CheckCanHandleFileFormat (FileInfo file) - { - return CheckCanHandleFileAsArmy(file) || CheckCanHandleFileAsRace(file) || CheckCanHandleFileAsGameSystem(file); - } - - protected override bool CheckCanHandleFileAsArmy(FileInfo file) - { - return ArmyFileExtension!=null && file.Name.ToLower().EndsWith(ArmyFileExtension); - } - - protected override bool CheckCanHandleFileAsRace(FileInfo file) - { - return RaceFileExtension!=null && file.Name.ToLower().EndsWith(RaceFileExtension); - } - - protected override bool CheckCanHandleFileAsGameSystem(FileInfo file) - { - return GameSystemFileExtension!=null && file.Name.ToLower().EndsWith(GameSystemFileExtension); - } - - protected override FileInfo GetFileAsSupportedType (FileInfo file) - { - return file; - } - - protected abstract Army CreateArmyFromFile(FileInfo file); - protected abstract Race CreateRaceFromFile(FileInfo file); - protected abstract GameSystem CreateGameSystemFromFile(FileInfo file); - - protected override ICollection<IWarFoundryObject> DoCreateObjectsFromFile (FileInfo file) - { - ICollection<IWarFoundryObject> objects = new List<IWarFoundryObject>(); - - if (CheckCanHandleFileAsRace(file)) - { - objects.Add(CreateRaceFromFile(file)); - } - else if (CheckCanHandleFileAsGameSystem(file)) - { - objects.Add(CreateGameSystemFromFile(file)); - } - else if (CheckCanHandleFileAsArmy(file)) - { - objects.Add(CreateArmyFromFile(file)); - } - else - { - LogNotifier.Warn(GetType(), "Failed trying to create from "+file.FullName+" - not a Race, Army or GameSystem"); - } - - return objects; - } - } -}
--- a/api/Factories/AbstractNonNativeWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -// This file (AbstractNonNativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories -{ - public abstract class AbstractNonNativeWarFoundryFactory<FILE_TYPE> : AbstractWarFoundryFactory<FILE_TYPE>, INonNativeWarFoundryFactory - { - public abstract string NonNativeDataType { get; } - } -}
--- a/api/Factories/AbstractWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -// This file (AbstractWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using System.Collections.Generic; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories -{ - public abstract class AbstractWarFoundryFactory<FILE_TYPE> : IWarFoundryFactory - { - public virtual void CompleteLoading(IWarFoundryStagedLoadObject obj) - { - //Pretend we've fully loaded, as this will probably be standard for non-native factories and some native factories - obj.SetAsFullyLoaded(); - } - - public bool CanHandleFileFormat (FileInfo file) - { - FILE_TYPE typedFile = GetFileAsSupportedType(file); - bool canHandle = typedFile != null && CheckCanHandleFileFormat(typedFile); - - if (typedFile != null) - { - CleanUpFileAsSupportedType(typedFile); - } - - return canHandle; - } - - public bool CanHandleFileAsRace(FileInfo file) - { - FILE_TYPE typedFile = GetFileAsSupportedType(file); - bool canHandle = typedFile != null && CheckCanHandleFileAsRace(typedFile); - - if (typedFile != null) - { - CleanUpFileAsSupportedType(typedFile); - } - - return canHandle; - } - - public bool CanHandleFileAsGameSystem(FileInfo file) - { - FILE_TYPE typedFile = GetFileAsSupportedType(file); - bool canHandle = typedFile != null && CheckCanHandleFileAsGameSystem(typedFile); - - if (typedFile != null) - { - CleanUpFileAsSupportedType(typedFile); - } - - return canHandle; - } - - public bool CanHandleFileAsArmy(FileInfo file) - { - FILE_TYPE typedFile = GetFileAsSupportedType(file); - bool canHandle = typedFile != null && CheckCanHandleFileAsArmy(typedFile); - - if (typedFile != null) - { - CleanUpFileAsSupportedType(typedFile); - } - - return canHandle; - } - - protected virtual void CleanUpFileAsSupportedType(FILE_TYPE typedFile) - { - //Do nothing by default - } - - /// <summary> - /// Converts the <see cref="FileInfo"/> object in to the appropriate type for this class so that it can perform its checks. If no conversion is required (the test can be performed on a <see cref="FileInfo"/> object) the object should be returned with no modification. - /// If the file is not of supported type the <code>null</code> should be returned. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> to get the supported source object from. - /// </param> - /// <returns> - /// An object of type <see cref="FILE_TYPE"/> that has been converted from the input <see cref="FileInfo"/> object, or <code>null</code> if the conversion cannot be made. - /// </returns> - protected abstract FILE_TYPE GetFileAsSupportedType(FileInfo file); - - /// <summary> - /// Checks whether the factory thinks it can load data from the file in its paramaterised type. - /// </summary> - /// <param name="file"> - /// An object of the converted <see cref="FILE_TYPE"/> to check support for - /// </param> - /// <returns> - /// <code>true</code> if the factory thinks it can support the file, else <code>false</code> - /// </returns> - protected abstract bool CheckCanHandleFileFormat(FILE_TYPE file); - - /// <summary> - /// Checks whether the factory thinks it can load data from the file in its paramaterised type as a Race object. - /// </summary> - /// <param name="file"> - /// An object of the converted <see cref="FILE_TYPE"/> to check support for - /// </param> - /// <returns> - /// <code>true</code> if the factory thinks it can support the file as a Race, else <code>false</code> - /// </returns> - protected abstract bool CheckCanHandleFileAsRace(FILE_TYPE file); - - /// <summary> - /// Checks whether the factory thinks it can load data from the file in its paramaterised type as a GameSystem object. - /// </summary> - /// <param name="file"> - /// An object of the converted <see cref="FILE_TYPE"/> to check support for - /// </param> - /// <returns> - /// <code>true</code> if the factory thinks it can support the file as a GameSystem, else <code>false</code> - /// </returns> - protected abstract bool CheckCanHandleFileAsGameSystem(FILE_TYPE file); - - /// <summary> - /// Checks whether the factory thinks it can load data from the file in its paramaterised type as an Army object. - /// </summary> - /// <param name="file"> - /// An object of the converted <see cref="FILE_TYPE"/> to check support for - /// </param> - /// <returns> - /// <code>true</code> if the factory thinks it can support the file as a Army, else <code>false</code> - /// </returns> - protected abstract bool CheckCanHandleFileAsArmy(FILE_TYPE file); - - - public ICollection<IWarFoundryObject> CreateObjectsFromFile(FileInfo file) - { - return DoCreateObjectsFromFile(GetFileAsSupportedType(file)); - } - - /// <summary> - /// Reads the data from the supplied converted <see cref="FILE_TYPE"/> object and returns it as a collection of loadable objects. - /// </summary> - /// <param name="file"> - /// An object of the converted <see cref="FILE_TYPE"/> for the file to load data from - /// </param> - /// <returns> - /// A <see cref="ICollection`1"/> of <see cref="IWarFoundryObject"/>s that were loaded from the file object - /// </returns> - protected abstract ICollection<IWarFoundryObject> DoCreateObjectsFromFile(FILE_TYPE file); - } -}
--- a/api/Factories/INativeWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -// This file (INativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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.Factories -{ - public interface INativeWarFoundryFactory : IWarFoundryFactory - { - //Marker interface - } -}
--- a/api/Factories/INonNativeWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -// This file (INonNativeWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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.Factories -{ - public interface INonNativeWarFoundryFactory : IWarFoundryFactory - { - string NonNativeDataType { get; } - } -}
--- a/api/Factories/IWarFoundryFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -// This file (IWarFoundryFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using System.Collections.Generic; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories -{ - public interface IWarFoundryFactory - { - /// <summary> - /// Completes the loading of an object if it is loaded in stages. - /// </summary> - /// <param name="obj"> - /// The <see cref="IWarFoundryStagedLoadObject"/> that should be fully loaded. - /// </param> - void CompleteLoading(IWarFoundryStagedLoadObject obj); - - /// <summary> - /// Checks if the factory thinks it can handle the supplied file. Checks can be performed on file extension or some basic check of file content, or some other method. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> for the file to check support for. - /// </param> - /// <returns> - /// <code>true</code> if the file appears to be supported for loading by this factory, else returns <code>false</code> - /// </returns> - bool CanHandleFileFormat(FileInfo file); - - /// <summary> - /// Checks if the factory thinks it can handle the supplied file as a Race. Checks can be performed on file extension or some basic check of file content, or some other method. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> for the file to check support for as a file containing Race information. - /// </param> - /// <returns> - /// <code>true</code> if the file appears to be supported for loading by this factory as a Race, else returns <code>false</code> - /// </returns> - bool CanHandleFileAsRace(FileInfo file); - - /// <summary> - /// Checks if the factory thinks it can handle the supplied file as a GameSystem. Checks can be performed on file extension or some basic check of file content, or some other method. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> for the file to check support for as a file containing GameSystem information. - /// </param> - /// <returns> - /// <code>true</code> if the file appears to be supported for loading by this factory as a GameSystem, else returns <code>false</code> - /// </returns> - bool CanHandleFileAsGameSystem(FileInfo file); - - /// <summary> - /// Checks if the factory thinks it can handle the supplied file as a Army. Checks can be performed on file extension or some basic check of file content, or some other method. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> for the file to check support for as a file containing Army information. - /// </param> - /// <returns> - /// <code>true</code> if the file appears to be supported for loading by this factory as a Army, else returns <code>false</code> - /// </returns> - bool CanHandleFileAsArmy(FileInfo file); - - /// <summary> - /// Reads the data from the supplied file and returns it as a collection of loadable objects. - /// May throw a <see cref=" IBBoard.IO.InvalidFileException"/> if the file is supported by the Factory but the content is invalid. - /// </summary> - /// <param name="file"> - /// A <see cref="FileInfo"/> for the file to load data from - /// </param> - /// <returns> - /// A <see cref="ICollection`1"/> of <see cref="IWarFoundryObject"/>s that were loaded from the file - /// </returns> - ICollection<IWarFoundryObject> CreateObjectsFromFile(FileInfo file); - } -}
--- a/api/Factories/RequiredDataMissingException.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -// This file (RequiredDataMissingException.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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.Factories -{ - /// <summary> - /// An exception that is thrown when a file cannot be loaded because one of the data files that it depends on has - /// not been loaded. Normally occurs when loading an army file without having the correct game system or race. - /// </summary> - public class RequiredDataMissingException : Exception - { - public RequiredDataMissingException(String file, String missingObjectType, String requiredValue) : base(String.Format("Could not find data for {1} object with ID {2} required by {0}", file, missingObjectType, requiredValue)) - { - } - } -}
--- a/api/Factories/Xml/AbstractStagedLoadedSubFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -// This file (AbstractStagedLoadedSubFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Xml; -using IBBoard.Xml; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - public class AbstractStagedLoadedSubFactory - { - protected WarFoundryXmlFactory mainFactory; - - protected AbstractStagedLoadedSubFactory(WarFoundryXmlFactory factory) - { - mainFactory = factory; - } - - protected Category CreateCategoryFromElement(XmlElement elem) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - Category cat = new Category(id, name); - cat.MaximumPercentage = XmlTools.GetIntValueFromAttribute(elem, "maxPercentage"); - cat.MinimumPercentage = XmlTools.GetIntValueFromAttribute(elem, "minPercentage"); - cat.MaximumPoints = XmlTools.GetIntValueFromAttribute(elem, "maxPoints"); - cat.MinimumPoints = XmlTools.GetIntValueFromAttribute(elem, "minPoints"); - return cat; - } - } -}
--- a/api/Factories/Xml/WarFoundryXmlArmyFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -// This file (WarFoundryXmlArmyFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Xml; -using IBBoard.Xml; -using ICSharpCode.SharpZipLib.Zip; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - /// <summary> - /// A sub-factory for loading WarFoundry Army XML files - /// </summary> - public class WarFoundryXmlArmyFactory - { - public Army CreateArmyFromElement(ZipFile file, XmlElement elem) - { - return new WarFoundryXmlArmyParser(file, elem).GetArmy(); - } - } -}
--- a/api/Factories/Xml/WarFoundryXmlArmyParser.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -// This file (WarFoundryXmlArmyParser.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using System.Xml; -using IBBoard.IO; -using IBBoard.Xml; -using ICSharpCode.SharpZipLib.Zip; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - public class WarFoundryXmlArmyParser - { - private ZipFile file; - private XmlElement elem; - private Army army; - private Dictionary<String, Unit> units; - - public WarFoundryXmlArmyParser(ZipFile file, XmlElement elem) - { - this.file = file; - this.elem = elem; - } - - public Army GetArmy() - { - if (army == null) - { - ParseArmy(); - } - - return army; - } - - private void ParseArmy() - { - string name = elem.GetAttribute("name"); - string systemID = elem.GetAttribute("system"); - GameSystem system = WarFoundryLoader.GetDefault().GetGameSystem(systemID); - - if (system == null) - { - throw new RequiredDataMissingException(file.Name, "Game System", systemID); - } - - string raceID = elem.GetAttribute("race"); - Race race = WarFoundryLoader.GetDefault().GetRace(system, raceID); - - if (race == null) - { - throw new RequiredDataMissingException(file.Name, "Race", raceID); - } - - int points = XmlTools.GetIntValueFromAttribute(elem, "maxPoints"); - army = new Army(race, name, points, file); - LoadUnits(); - } - - private void LoadUnits() - { - units = new Dictionary<string, Unit>(); - - foreach (XmlElement unitElem in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/army:army/army:units/army:unit")) - { - string id = unitElem.GetAttribute("id"); - - if (!units.ContainsKey(id)) - { - string unitTypeId = unitElem.GetAttribute("unitType"); - UnitType unitType = army.Race.GetUnitType(unitTypeId); - - if (unitType == null) - { - throw new RequiredDataMissingException(file.Name, "Unit Type", unitTypeId); - } - - string name = unitElem.GetAttribute("unitName"); - int size = XmlTools.GetIntValueFromAttribute(unitElem, "size"); - - string catID = unitElem.GetAttribute("category"); - Category cat = army.Race.GetCategory(catID); - - if (cat == null) - { - cat = unitType.MainCategory; - } - - Unit unit = new Unit(id, name, size, unitType, army.GetCategory(cat)); - army.AddUnit(unit, cat); - units.Add(id, unit); - - LoadUnitEquipment(unitElem, unit); - } - else - { - throw new InvalidFileException("Duplicate unit ID found in army file: "+id); - } - } - } - - private void LoadUnitEquipment(XmlElement unitElem, Unit unit) - { - foreach (XmlElement elem in WarFoundryXmlFactoryUtils.SelectNodes(unitElem, "army:equipment/army:equipItem")) - { - string equipID = elem.GetAttribute("id"); - UnitEquipmentItem item = unit.UnitType.GetEquipmentItem(equipID); - - if (item == null) - { - throw new RequiredDataMissingException(file.Name, "Equipment Item", equipID); - } - - double amount = XmlTools.GetDoubleValueFromAttribute(elem, "amount"); - string equipTypeString = elem.GetAttribute("amountType"); - - if (equipTypeString == "ratio") - { - unit.SetEquipmentRatio(item, amount); - } - else - { - //amount should be a whole number, so do type-cast rounding - unit.SetEquipmentAmount(item, (int) amount); - } - } - } - } -}
--- a/api/Factories/Xml/WarFoundryXmlElementName.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -// This file (WarFoundryXmlElementName.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using IBBoard.Xml; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - /// <summary> - /// An enumeration class for valid WarFoundry XML elements, designed to imitate Java's extensible complex object enumerations. - /// </summary> - public class WarFoundryXmlElementName : IXmlElementName, IExtendedEnum<string> - { - public static WarFoundryXmlElementName SYSTEM_ELEMENT = new WarFoundryXmlElementName("SYSTEM_ELEMENT", "system"); - public static WarFoundryXmlElementName ARMY_ELEMENT = new WarFoundryXmlElementName("ARMY_ELEMENT", "army"); - public static WarFoundryXmlElementName RACE_ELEMENT = new WarFoundryXmlElementName("RACE_ELEMENT", "race"); - public static WarFoundryXmlElementName ARMY_DEFAULTNAME_ELEMENT = new WarFoundryXmlElementName("ARMY_DEFAULTNAME_ELEMENT", "defaultName"); - public static WarFoundryXmlElementName CATEGORIES_ELEMENT = new WarFoundryXmlElementName("CATEGORIES_ELEMENT", "categories"); - public static WarFoundryXmlElementName CATEGORY_ELEMENT = new WarFoundryXmlElementName("CATEGORY_ELEMENT", "cat"); - public static WarFoundryXmlElementName UNITTYPES_ELEMENT = new WarFoundryXmlElementName("UNITTYPES_ELEMENT", "units"); - public static WarFoundryXmlElementName UNITTYPE_ELEMENT = new WarFoundryXmlElementName("UNITTYPE_ELEMENT", "unit"); - public static WarFoundryXmlElementName RACE_EQUIPMENT_ITEMS_ELEMENT = new WarFoundryXmlElementName("RACE_EQUIPMENT_ITEMS_ELEMENT", "equipment"); - public static WarFoundryXmlElementName RACE_EQUIPMENT_ITEM_ELEMENT = new WarFoundryXmlElementName("RACE_EQUIPMENT_ITEMS_ELEMENT", "equipmentItem"); - - private static ICollection<WarFoundryXmlElementName> enumValues; - private string name; - private string val; - - private WarFoundryXmlElementName(string elemName, string elemVal) - { - name = elemName; - val = elemVal; - } - - public string Name - { - get { - return name; - } - } - - public string Value - { - get { - return val; - } - } - - /// <summary> - /// Gets an ICollection of the values so that they can be looped over like a standard enumeration. - /// </summary> - /// <returns> - /// A <see cref="ICollection`1"/> of all of the static 'enumeration' values of the class. - /// </returns> - public static ICollection<WarFoundryXmlElementName> GetEnumValues() - { - if (enumValues == null) - { - enumValues = new WarFoundryXmlElementName[]{SYSTEM_ELEMENT, ARMY_ELEMENT, RACE_ELEMENT, CATEGORIES_ELEMENT, CATEGORY_ELEMENT, UNITTYPES_ELEMENT, UNITTYPE_ELEMENT}; - } - - return enumValues; - } - } -}
--- a/api/Factories/Xml/WarFoundryXmlFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -// This file (WarFoundryXmlFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using System.Xml; -using System.Xml.Schema; -using System.Xml.XPath; -using System.Collections.Generic; -using System.Text; -using IBBoard; -using IBBoard.IO; -using IBBoard.Lang; -using IBBoard.Logging; -using IBBoard.Xml; -using IBBoard.WarFoundry.API.Requirements; -using IBBoard.WarFoundry.API.Objects; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - /// <summary> - /// The WarFoundryXmlFactory loads WarFoundry classes from the native "XML in a zip" file format. Files are validated using the schema for the file type, so structurally invalid files should be identified at initial load. - /// </summary> - public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory - { - private static WarFoundryXmlFactory factory; - private WarFoundryXmlGameSystemFactory gameSystemFactory; - private WarFoundryXmlRaceFactory raceFactory; - private WarFoundryXmlArmyFactory armyFactory; - - public static WarFoundryXmlFactory GetFactory() - { - if (factory == null) - { - factory = new WarFoundryXmlFactory(); - } - - return factory; - } - - private WarFoundryXmlFactory() : base() - { - gameSystemFactory = new WarFoundryXmlGameSystemFactory(this); - raceFactory = new WarFoundryXmlRaceFactory(this); - armyFactory = new WarFoundryXmlArmyFactory(); - } - - public WarFoundryXmlGameSystemFactory GetSystemFactory() - { - return gameSystemFactory; - } - - public WarFoundryXmlRaceFactory GetRaceFactory() - { - return raceFactory; - } - - public WarFoundryXmlArmyFactory GetArmyFactory() - { - return armyFactory; - } - - protected override bool CheckCanFindArmyFileContent(ZipFile file) - { - return file.FindEntry("data.armyx", true) > -1; - } - - protected override bool CheckCanFindSystemFileContent(ZipFile file) - { - return file.FindEntry("data.systemx", true) > -1; - } - - protected override bool CheckCanFindRaceFileContent(ZipFile file) - { - return file.FindEntry("data.racex", true) > -1; - } - - protected override Stream GetArmyDataStream(ZipFile file) - { - return file.GetInputStream(file.FindEntry("data.armyx", true)); - } - - protected override Army CreateArmyFromStream (ZipFile file, Stream dataStream) - { - XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.ARMY_ELEMENT); - return armyFactory.CreateArmyFromElement(file, elem); - } - - private XmlElement GetRootElementFromStream(Stream stream, WarFoundryXmlElementName elementName) - { - XmlDocument doc = WarFoundryXmlFactoryUtils.CreateXmlDocumentFromStream(stream); - - XmlElement elem = (XmlElement)doc.LastChild; - - if (!elem.LocalName.Equals(elementName.Value)) - { - throw new InvalidFileException(String.Format("Root element of XML was not valid. Expected {0} but got {1}", elementName.Value, elem.Name)); - } - - return elem; - } - - protected override Stream GetGameSystemDataStream (ZipFile file) - { - return file.GetInputStream(file.FindEntry("data.systemx", true)); - } - - protected override GameSystem CreateGameSystemFromStream (ZipFile file, Stream dataStream) - { - XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.SYSTEM_ELEMENT); - LogNotifier.Debug(GetType(), "Create GameSystem"); - return gameSystemFactory.CreateSystemFromElement(file, elem); - } - - protected override Stream GetRaceDataStream (ZipFile file) - { - return file.GetInputStream(file.FindEntry("data.racex", true)); - } - - protected override Race CreateRaceFromStream (ZipFile file, Stream dataStream) - { - XmlElement elem = GetRootElementFromStream(dataStream, WarFoundryXmlElementName.RACE_ELEMENT); - LogNotifier.Debug(GetType(), "Create Race"); - return raceFactory.CreateRaceFromElement(file, elem); - } - - protected override void CleanUpFileAsSupportedType(ZipFile typedFile) - { - typedFile.Close(); - } - - public override void CompleteLoading(IWarFoundryStagedLoadObject obj) - { - LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); - - if (obj is GameSystem) - { - CompleteLoadingGameSystem((GameSystem) obj); - } - else if (obj is Race) - { - CompleteLoadingRace((Race) obj); - } - } - - private void CompleteLoadingRace(Race race) - { - try - { - raceFactory.CompleteLoading(race); - } - catch (InvalidFileException ex) - { - WarFoundryLoader.GetDefault().RemoveRace(race); - throw; - } - } - - private void CompleteLoadingGameSystem(GameSystem system) - { - try - { - gameSystemFactory.CompleteLoading(system); - } - catch (InvalidFileException ex) - { - WarFoundryLoader.GetDefault().RemoveGameSystem(system); - throw; - } - } - } -} \ No newline at end of file
--- a/api/Factories/Xml/WarFoundryXmlFactoryUtils.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -// This file (WarFoundryXmlFactoryUtils.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.IO; -using System.Xml; -using System.Xml.Schema; -using IBBoard.WarFoundry.API.Objects; -using IBBoard.IO; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - /// <summary> - /// A collection of useful utility methods for loading WarFoundry data from XML files - /// </summary> - public class WarFoundryXmlFactoryUtils - { - public static readonly string NS_BASE = "http://ibboard.co.uk/warfoundry/"; - private static XmlReaderSettings settings; - private static XmlNamespaceManager nsManager; - - public static XmlNodeList SelectNodes(XmlNode element, string xpathQuery) - { - return element.SelectNodes(xpathQuery, GetNamespaceManager()); - } - - public static XmlNode SelectSingleNode(XmlNode element, string xpathQuery) - { - return element.SelectSingleNode(xpathQuery, GetNamespaceManager()); - } - - public static XmlElement SelectSingleElement(XmlNode element, string xpathQuery) - { - XmlNode node = SelectSingleNode(element, xpathQuery); - return (node is XmlElement) ? (XmlElement) node : null; - } - - public static XmlNamespaceManager GetNamespaceManager() - { - if (nsManager == null) - { - nsManager = new XmlNamespaceManager(new NameTable()); - nsManager.AddNamespace("core", NS_BASE + "core"); - nsManager.AddNamespace("cat", NS_BASE + "cats"); - nsManager.AddNamespace("race", NS_BASE + "race"); - nsManager.AddNamespace("system", NS_BASE + "system"); - nsManager.AddNamespace("army", NS_BASE + "army"); - } - - return nsManager; - } - - /// <summary> - /// Lazy-getter for XML reader settings. May throw a <see cref="InvalidDataException"/> if there is a problem with the translation schema. - /// </summary> - /// <returns> - /// A <see cref="XmlReaderSettings"/> with the default values for validating the translation document against the translation schema - /// </returns> - public static XmlReaderSettings GetReaderSettings() - { - if (settings == null) - { - settings = new XmlReaderSettings(); - settings.ValidationType = ValidationType.Schema; - //settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings; - settings.ProhibitDtd = true; - settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); - XmlSchemaSet cache = new XmlSchemaSet(); - string path = IBBoard.Constants.ExecutablePath + "/schemas/"; - AddSchemaToCache(cache, NS_BASE + "core", path + "warfoundry-core.xsd"); - AddSchemaToCache(cache, NS_BASE + "cats", path + "warfoundry-cats.xsd"); - AddSchemaToCache(cache, NS_BASE + "race", path + "race.xsd"); - AddSchemaToCache(cache, NS_BASE + "system", path + "system.xsd"); - AddSchemaToCache(cache, NS_BASE + "army", path + "army.xsd"); - settings.Schemas.Add(cache); - settings.Schemas.CompilationSettings.EnableUpaCheck = false; - } - - return settings; - } - - private static void ValidationEventMethod(object sender, ValidationEventArgs e) - { - if (e.Severity == XmlSeverityType.Error) - { - throw new InvalidFileException("Problem validating against schema for WarFoundry data: " + e.Message, e.Exception); - } - else - { - //TODO: Fire some kind of warning event - } - } - - private static void AddSchemaToCache(XmlSchemaSet cache, string xmlNamespace, string schemaLocation) - { - try - { - cache.Add(xmlNamespace, schemaLocation); - } - catch (IOException ex) - { - //TODO: Warn on schema failure - } - catch (XmlSchemaException ex) - { - //TODO: Warn on schema failure - } - catch (XmlException ex) - { - //TODO: Warn on schema failure - } - } - - public static XmlDocument CreateXmlDocumentFromStream(Stream stream) - { - XmlDocument doc = new XmlDocument(); - XmlReader reader = XmlReader.Create(stream, GetReaderSettings()); - - try - { - doc.Load(reader); - } - //Don't catch XMLSchemaExceptions - let them get thrown out - finally - { - reader.Close(); - } - - return doc; - } - - public static bool CanCompleteLoading(IWarFoundryStagedLoadObject obj) - { - bool canLoad = true; - - if (obj.IsFullyLoaded) - { - canLoad = false; - } - else if (obj.IsLoading) - { - canLoad = false; - } - - return canLoad; - } - } -}
--- a/api/Factories/Xml/WarFoundryXmlGameSystemFactory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -// This file (WarFoundryXmlGameSystemFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using System.IO; -using System.Xml; -using ICSharpCode.SharpZipLib.Zip; -using IBBoard.Xml; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - /// <summary> - /// A sub-factory specifically for loading GameSystems from WarFoundry XML files - /// </summary> - public class WarFoundryXmlGameSystemFactory : AbstractStagedLoadedSubFactory - { - private Dictionary<GameSystem, XmlDocument> extraData = new Dictionary<GameSystem, XmlDocument>(); - - public WarFoundryXmlGameSystemFactory(WarFoundryXmlFactory factory) : base(factory) - { - } - - private void StoreExtraData(GameSystem wfObject, XmlElement elem) - { - extraData[wfObject] = elem.OwnerDocument; - } - - private XmlDocument GetExtraData(GameSystem obj) - { - XmlDocument extra = null; - extraData.TryGetValue(obj, out extra); - return extra; - } - - public GameSystem CreateSystemFromElement(ZipFile file, XmlElement elem) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - GameSystem system = new GameSystem(id, name, mainFactory); - int defaultarmysize = XmlTools.GetIntValueFromAttribute(elem,"defaultArmySize"); - system.SystemArmyDefaultSize = defaultarmysize; - StoreExtraData(system, elem); - return system; - - } - - public void CompleteLoading(GameSystem system) - { - if (!WarFoundryXmlFactoryUtils.CanCompleteLoading(system)) - { - return; - } - - system.SetAsLoading(); - XmlDocument extraData = GetExtraData(system); - LoadCategoriesForSystem(system, extraData); - XmlElement statsElem = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "/system:system/system:sysStatsList"); - string defaultStatsID = statsElem.GetAttribute("defaultStats"); - LoadSystemStatsForSystem(system, extraData); - system.StandardSystemStatsID = defaultStatsID; - XmlElement systemElement = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "/system:system"); - system.WarnOnError = XmlTools.GetBoolValueFromAttribute(systemElement, "warn"); - system.AllowAllies = XmlTools.GetBoolValueFromAttribute(systemElement, "allowAllies"); - system.SetAsFullyLoaded(); - } - - - private void LoadCategoriesForSystem(GameSystem system, XmlNode elem) - { - foreach (XmlElement cat in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/system:system/system:categories/cat:cat")) - { - system.AddCategory(CreateCategoryFromElement(cat)); - } - } - - private void LoadSystemStatsForSystem(GameSystem system, XmlNode elem) - { - foreach (XmlElement stats in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/system:system/system:sysStatsList/system:sysStats")) - { - SystemStats sysStats = CreateSystemStatsFromElement(stats); - system.AddSystemStats(sysStats); - } - } - - private SystemStats CreateSystemStatsFromElement(XmlElement elem) - { - SystemStats sysStats = new SystemStats(elem.GetAttribute("id")); - - foreach (XmlElement slot in WarFoundryXmlFactoryUtils.SelectNodes(elem, "system:sysStat")) - { - sysStats.AddStatSlot(slot.GetAttribute("name")); - } - - return sysStats; - } - } -}
--- a/api/Factories/Xml/WarFoundryXmlLimitParser.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -// This file (WarFoundryXmlLimitParser.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.Collections.Generic; -using System.Xml; -using IBBoard.Limits; -using IBBoard.Xml; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - public class WarFoundryXmlLimitParser - { - public ILimit GetMinLimit(XmlElement elem) - { - XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:minLimit/*[1]"); - return GetLimitFromElement(limitElem); - } - - public ILimit GetMaxLimit(XmlElement equipSlot) - { - XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]"); - return GetLimitFromElement(limitElem); - } - - public ILimit GetLimitFromElement(XmlElement limitElem) - { - ILimit limit = null; - - if (limitElem != null) - { - switch (limitElem.LocalName) - { - case "percentageLimit": - double limitPercent = XmlTools.GetDoubleValueFromAttribute(limitElem, "limit"); - bool roundUp = limitElem.GetAttribute("round").Equals("up"); - limit = new SimpleRoundedPercentageLimit(limitPercent, roundUp); - break; - case "sizeConstrainedLimit": - limit = new NumericSizeConstrainedLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); - break; - case "absoluteLimit": - limit = new AbsoluteNumericLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); - break; - case "unitSizeLimit": - limit = new SimpleRoundedPercentageLimit(100); - break; - case "compositeMaxLimit": - ICollection<ILimit> maxSubLimits = GetSubLimits(limitElem); - limit = new CompositeMaximumLimit(maxSubLimits); - break; - case "compositeMinLimit": - ICollection<ILimit> minSubLimits = GetSubLimits(limitElem); - limit = new CompositeMinimumLimit(minSubLimits); - break; - default: - //TODO: Warn of missing handler for when we've extended the limit list - break; - } - } - - return limit; - } - - private ICollection<ILimit> GetSubLimits(XmlElement limitElem) - { - XmlNodeList subLimitNodes = GetSubLimitElements(limitElem); - ICollection<ILimit> limits = new List<ILimit>(); - - foreach (XmlNode node in subLimitNodes) - { - if (node is XmlElement) - { - ILimit limit = GetLimitFromElement((XmlElement)node); - - if (limit != null) - { - limits.Add(limit); - } - } - } - - return limits; - } - - private XmlNodeList GetSubLimitElements(XmlElement limitElem) - { - return limitElem.ChildNodes; - } - } -} -
--- a/api/Factories/Xml/WarFoundryXmlSaver.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -// This file (WarFoundryXmlSaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using System.IO; -using System.Xml; -using System.Xml.Schema; -using IBBoard.Lang; -using IBBoard.Xml; -using IBBoard.WarFoundry.API.Factories.Xml.Zip; -using IBBoard.WarFoundry.API.Objects; -using IBBoard.WarFoundry.API.Savers; -using IBBoard.WarFoundry.API.Util; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Factories.Xml -{ - public class WarFoundryXmlSaver : IWarFoundryFileSaver - { - public const string ARMY_FILE_EXTENSION = ".army"; - - public bool Save(Army toSave, string savePath) - { - bool success = false; - ZipFile file = null; - - if (!savePath.EndsWith(ARMY_FILE_EXTENSION)) - { - savePath = savePath + ARMY_FILE_EXTENSION; - } - - try - { - file = ZipFile.Create(savePath); - file.BeginUpdate(); - file.Add(new StringZipEntrySource(CreateXmlString(toSave)), "data.armyx"); - file.CommitUpdate(); - success = true; - } - finally - { - if (file != null) - { - file.Close(); - } - } - - return success; - } - - private string CreateXmlString(WarFoundryObject toSave) - { - string xmlString = ""; - - if (toSave is Army) - { - xmlString = CreateArmyXmlString((Army)toSave); - } - - return xmlString; - } - - private string CreateArmyXmlString(Army toSave) - { - XmlDocument doc = new XmlDocument(); - XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", null, null); - doc.AppendChild(declaration); - XmlSchema schema = new XmlSchema(); - schema.Namespaces.Add("", "http://ibboard.co.uk/warfoundry/army"); - schema.Namespaces.Add("core", "http://ibboard.co.uk/warfoundry/core"); - doc.Schemas.Add(schema); - XmlElement root = doc.CreateElement("army"); - root.SetAttribute("xmlns", "http://ibboard.co.uk/warfoundry/army"); - root.SetAttribute("xmlns:core", "http://ibboard.co.uk/warfoundry/core"); - doc.AppendChild(root); - root.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(toSave.ID)); - root.SetAttribute("name", toSave.Name); - //Don't convert system and race to ID format as they could be stored in non-XML file formats - //If they are in XML files then they'll already be valid - root.SetAttribute("system", toSave.GameSystem.ID); - root.SetAttribute("race", toSave.Race.ID); - root.SetAttribute("maxPoints", toSave.MaxPoints.ToString()); - XmlElement units = doc.CreateElement("units"); - root.AppendChild(units); - - foreach (Unit unit in toSave.GetUnits()) - { - units.AppendChild(CreateUnitElement(unit, doc)); - } - - return doc.OuterXml; - } - - private XmlElement CreateUnitElement(Unit unit, XmlDocument doc) - { - XmlElement unitElem = doc.CreateElement("unit"); - unitElem.SetAttribute("id", XmlTools.GetAsciiXmlIdForString(unit.ID)); - unitElem.SetAttribute("unitName", (unit.HasDefaultName() ? "" : unit.Name)); - unitElem.SetAttribute("unitType", unit.UnitType.ID); - unitElem.SetAttribute("size", unit.Size.ToString()); - - if (!unit.Race.Equals(unit.Army.Race)) - { - unitElem.SetAttribute("race", unit.Race.ID); - } - - Category unitCategory = unit.Category.Category; - if (!unit.UnitType.MainCategory.Equals(unitCategory)) - { - unitElem.SetAttribute("category", unitCategory.ID); - } - - XmlElement equipmentElem = CreateEquipmentItemsElement(unit, doc); - - if (equipmentElem != null) - { - unitElem.AppendChild(equipmentElem); - } - - XmlElement containedElem = CreateContainedUnitsElement(unit, doc); - - if (containedElem != null) - { - unitElem.AppendChild(containedElem); - } - - return unitElem; - } - - private XmlElement CreateEquipmentItemsElement(Unit unit, XmlDocument doc) - { - UnitEquipmentItem[] equipItems = unit.GetEquipment(); - int equipItemCount = equipItems.Length; - XmlElement equipmentElem = null; - - if (equipItemCount > 0) - { - equipmentElem = doc.CreateElement("equipment"); - - for (int i = 0; i < equipItemCount; i++) - { - equipmentElem.AppendChild(CreateEquipmentElement(equipItems[i], unit, doc)); - } - } - - return equipmentElem; - } - - private XmlElement CreateEquipmentElement(UnitEquipmentItem item, Unit unit, XmlDocument doc) - { - XmlElement equipmentItemElem = doc.CreateElement("equipItem"); - equipmentItemElem.SetAttribute("id", item.ID); - equipmentItemElem.SetAttribute("amount", UnitEquipmentUtil.GetEquipmentAmount(unit, item).ToString()); - equipmentItemElem.SetAttribute("amountType", UnitEquipmentUtil.GetEquipmentAmountIsRatio(unit, item) ? "ratio" : "fixed"); - return equipmentItemElem; - } - - private XmlElement CreateContainedUnitsElement(Unit unit, XmlDocument doc) - { - Unit[] containedUnits = unit.ContainedUnits; - int containedCount = containedUnits.Length; - XmlElement containedElem = null; - - if (containedCount > 0) - { - containedElem = doc.CreateElement("contained"); - - for (int i = 0; i < containedCount; i++) - { - containedElem.AppendChild(CreateContainedUnitElement(containedUnits[i], doc)); - } - } - - return containedElem; - } - - private XmlElement CreateContainedUnitElement(Unit unit, XmlDocument doc) - { - XmlElement containedUnitElem = doc.CreateElement("containedUnit"); - containedUnitElem.SetAttribute("containedID", XmlTools.GetAsciiXmlIdForString(unit.ID)); - return containedUnitElem; - } - } -}
--- a/api/Factories/Xml/Zip/StringZipEntrySource.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -// This file (StringZipEntrySource.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard -// -// 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; -using System.IO; -using IBBoard.Lang; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Factories.Xml.Zip -{ - /// <summary> - /// A simple implementation of IStaticDataSource that lets us add a string directly to a Zip file - /// </summary> - public class StringZipEntrySource : IStaticDataSource - { - private byte[] entryContent; - - public StringZipEntrySource(String content) - { - entryContent = StringManipulation.StringToBytes(content); - } - - public Stream GetSource() - { - return new MemoryStream(entryContent); - } - } -}
--- a/api/FileLoadFailure.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -// This file (FileLoadFailure.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.IO; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Factories; - -namespace IBBoard.WarFoundry.API -{ - /// <summary> - /// A container class that holds information about file load failures. Core information covers the file that failed and a message. Additional information includes the factory loading the file and the excetion that was thrown. Messages are passed through <code>String.Format</code> and supplied with the failed file path and the failing factory - /// </summary> - public class FileLoadFailure - { - private FileInfo failedFile; - private IWarFoundryFactory loadingFactory; - private string defaultMessage; - private string messageTranslationID; - private string message; - private Exception cause; - - /// <summary> - /// Constructor for a failed file load where no factory was found. Translatable messages can be providied through a <code>translationID</code> or skipped by passing <code>null</code>. - /// </summary> - /// <param name="file"> - /// The <see cref="FileInfo"/> that failed to load - /// </param> - /// <param name="message"> - /// A message about the failure in English - used as a default fall-back message. - /// </param> - /// <param name="translationID"> - /// The ID of a translation for the message. - /// </param> - public FileLoadFailure(FileInfo file, string message, string translationID) : this (file, null, message, "") - { - } - - /// <summary> - /// Constructor for a failed file load where a factory was identified as supporting the file but failed to load it. Translatable messages can be providied through a <code>translationID</code> or skipped by passing <code>null</code>. - /// </summary> - /// <param name="file"> - /// The <see cref="FileInfo"/> that failed to load - /// </param> - /// <param name="factory"> - /// The <see cref="IWarFoundryFactory"/> that failed to load the file - /// </param> - /// <param name="message"> - /// A message about the failure in English - used as a default fall-back message. - /// </param> - /// <param name="translationID"> - /// The ID of a translation for the message. - /// </param> - public FileLoadFailure(FileInfo file, IWarFoundryFactory factory, string message, string translationID) : this(file, factory, message, translationID, null) - { - } - - /// <summary> - /// Constructor for a failed file load where a factory was identified as supporting the file but an exception occurred while loading it. Translatable messages can be providied through a <code>translationID</code> or skipped by passing <code>null</code>. - /// </summary> - /// <param name="file"> - /// The <see cref="FileInfo"/> that failed to load - /// </param> - /// <param name="factory"> - /// The <see cref="IWarFoundryFactory"/> that failed to load the file - /// </param> - /// <param name="message"> - /// A message about the failure in English - used as a default fall-back message. - /// </param> - /// <param name="translationID"> - /// The ID of a translation for the message. - /// </param> - /// <param name="exception"> - /// The <see cref="Exception"/> that occurred to cause the load to fail - /// </param> - public FileLoadFailure(FileInfo file, IWarFoundryFactory factory, string message, string translationID, Exception exception) - { - failedFile = file; - loadingFactory = factory; - defaultMessage = message; - messageTranslationID = translationID; - cause = exception; - } - - public FileInfo FailedFile - { - get - { - return failedFile; - } - } - - public string Message - { - get - { - if (message == null) - { - string fileName = FailedFile.FullName; - string factoryType = (loadingFactory == null ? "" : loadingFactory.GetType().Name); - if (messageTranslationID == "" || messageTranslationID == null) - { - message = String.Format(defaultMessage, fileName, factoryType); - } - else - { - message = Translation.GetTranslation(messageTranslationID, defaultMessage, fileName, factoryType); - } - } - - return message; - } - } - - public Exception Exception - { - get { return cause; } - } - } -}
--- a/api/Objects/Ability.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -// This file (Ability.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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> - /// An Ability is a special rule that a UnitType has, made up of an ability name and a description. - /// </summary> - public class Ability : WarFoundryObject - { - private string description; - - public Ability(String id, String name) : base(id, name) - { - } - - public string Description - { - get { return description; } - set - { - if (value!=null) - { - description = value.Trim(); - } - } - } - } -}
--- a/api/Objects/AbstractUnitEquipmentItemSelection.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -// This file (AbstractUnitEquipmentItemSelection.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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> - /// An abstract class that defines a selection of equipment for a unit - /// </summary> - public abstract class AbstractUnitEquipmentItemSelection - { - private Unit selectionForUnit; - private UnitEquipmentItem selectedItem; - private double amountTaken; - - public AbstractUnitEquipmentItemSelection(Unit unit, UnitEquipmentItem item, double amount) - { - selectionForUnit = unit; - selectedItem = item; - AmountTaken = amount; - } - - public Unit EquipmentForUnit - { - get - { - return selectionForUnit; - } - } - - public UnitEquipmentItem EquipmentItem - { - get - { - return selectedItem; - } - } - - public double AmountTaken - { - get - { - return amountTaken; - } - set - { - amountTaken = value; - - if (!IsValidValue(value)) - { - //Fire validation failed event (once we have one) - } - } - } - - public bool IsValid - { - get - { - return IsValidValue(AmountTaken) && IsInRange(AmountTaken); - } - } - - protected virtual bool IsValidValue(double newValue) - { - return true; - } - - protected bool IsInRange(double newValue) - { - int unitSize = EquipmentForUnit.Size; - int minLimit = EquipmentItem.MinLimit.GetLimit(unitSize); - int maxLimit = EquipmentItem.MaxLimit.GetLimit(unitSize); - return (minLimit <= newValue) && (newValue <= maxLimit); - } - - public double TotalCost - { - get - { - return NumberTaken * EquipmentItem.Cost; - } - } - - public abstract int NumberTaken - { - get; - } - - [Obsolete("Implementation is down to the UI")] - public abstract string GetEquipmentAmountString(); - } -}
--- a/api/Objects/Army.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,283 +0,0 @@ -// This file (Army.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using System.Collections.Generic; -using System.Text; -using System.Xml; -using IBBoard.WarFoundry.API; -using IBBoard.WarFoundry.API.Factories; -using IBBoard.WarFoundry.API.Requirements; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for Army. - /// </summary> - public class Army : WarFoundryObject, ICostedWarFoundryObject - { - //private GameSystem system; - private Race armyRace; - private int maxPoints; - private double pointsTotal; - private Dictionary<Category, ArmyCategory> categories; - - public event ObjectAddDelegate UnitAdded; - public event ObjectRemoveDelegate UnitRemoved; - public event FailedUnitRequirementDelegate FailedRequirement; - public event DoubleValChangedDelegate PointsValueChanged; - private DoubleValChangedDelegate PointsValueChangedMethod; - - public Army(Race race, string armyName, int maxArmyPoints) : this(race, armyName, maxArmyPoints, null) - { - } - - public Army(Race race, string armyName, int maxArmyPoints, ZipFile file) : base(armyName) - { - armyRace = race; - Name = armyName; - maxPoints = maxArmyPoints; - PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler); - } - - public ArmyCategory GetCategory(Category cat) - { - ArmyCategory armyCat = null; - ArmyCategories.TryGetValue(cat, out armyCat); - return armyCat; - } - - private Dictionary<Category, ArmyCategory> ArmyCategories - { - get - { - if (categories==null) - { - categories = new Dictionary<Category, ArmyCategory>(); - Category[] raceCats = Race.Categories; - ArmyCategory cat; - int raceCatCount = raceCats.Length; - - for (int i = 0; i < raceCatCount; i++) - { - Category raceCat = raceCats[i]; - cat = new ArmyCategory(this, raceCat); - categories[raceCat] = cat; - cat.PointsValueChanged+= PointsValueChangedMethod; - cat.UnitAdded+=new ObjectAddDelegate(Army_UnitAdded); - cat.UnitRemoved+=new ObjectRemoveDelegate(Army_UnitRemoved); - cat.FailedRequirement+=new FailedUnitRequirementDelegate(Army_FailedRequirement); - } - } - - return categories; - } - } - - public ArmyCategory[] Categories - { - get - { - return DictionaryUtils.ToArray<Category, ArmyCategory>(ArmyCategories); - } - } - - public Race Race - { - get { return armyRace; } - } - - public GameSystem GameSystem - { - get { return (armyRace!=null ? armyRace.GameSystem : null); } - } - - protected void OnUnitAdded(Unit unit) - { - OnUnitAdded(unit, null); - } - - protected void OnUnitAdded(Unit unit, List<FailedUnitRequirement> failedReqs) - { - if (UnitAdded != null) - { - UnitAdded(unit); - } - - OnFailedRequirement(failedReqs); - } - - protected void OnUnitRemoved(Unit unit) - { - OnUnitRemoved(unit, null); - } - - protected void OnUnitRemoved(Unit unit, List<FailedUnitRequirement> failedReqs) - { - if (UnitRemoved!=null) - { - UnitRemoved(unit); - } - - OnFailedRequirement(failedReqs); - } - - protected void OnFailedRequirement(List<FailedUnitRequirement> failedReqs) - { - if (FailedRequirement != null && failedReqs != null && failedReqs.Count > 0) - { - FailedRequirement(failedReqs); - } - } - - private void OnPointsValueChanged(double oldValue, double newValue) - { - if (PointsValueChanged!=null) - { - PointsValueChanged(this, oldValue, newValue); - } - } - - private double TotalPoints - { - get { return pointsTotal; } - set - { - double oldPoints = pointsTotal; - pointsTotal = value; - - if (oldPoints!=pointsTotal) - { - OnPointsValueChanged(oldPoints, pointsTotal); - } - } - } - - [Obsolete("Use Points instead")] - public double PointsTotal - { - get { return TotalPoints; } - } - - public double Points - { - get { return TotalPoints; } - } - - public void AddUnit(Unit unit) - { - Category category = unit.UnitType.MainCategory; - AddUnit(unit, category); - } - - public void AddUnit(Unit unit, Category category) - { - ArmyCategory armyCat = GetCategory(category); - armyCat.AddUnit(unit); - } - - public void RemoveUnit(Unit unit) - { - unit.Category.RemoveUnit(unit); - } - - public Unit[] GetUnits(Category cat) - { - return GetUnits(this.GetCategory(cat)); - } - - public Unit[] GetUnits(ArmyCategory cat) - { - return cat.GetUnits(); - } - - public Unit[] GetUnits() - { - List<Unit> fullList = new List<Unit>(); - - foreach(ArmyCategory cat in Categories) - { - fullList.AddRange(cat.GetUnits()); - } - - return fullList.ToArray(); - } - - public int MaxPoints - { - get { return maxPoints; } - set - { - if (value > 0) - { - maxPoints = value; - } - } - } - - private void PointsValueChangedHandler(WarFoundryObject obj, double oldVal, double newVal) - { - if (obj is ArmyCategory) - { - double points = 0; - - foreach (ArmyCategory cat in Categories) - { - points+= cat.Points; - } - - TotalPoints = points; - } - } - - public List<FailedUnitRequirement> CanAddUnit(Unit unit) - { - return CanAddUnitType(unit.UnitType); - } - - public List<FailedUnitRequirement> CanAddUnitType(UnitType unitType) - { - return unitType.CanAddToArmy(this); - } - - public List<FailedUnitRequirement> CanRemoveUnit(Unit unit) - { - return CanRemoveUnitType(unit.UnitType); - } - - public List<FailedUnitRequirement> CanRemoveUnitType(UnitType unitType) - { - return unitType.CanRemoveFromArmy(this); - } - - public int GetUnitTypeCount(UnitType unitType) - { - int count = 0; - - foreach (ArmyCategory cat in Categories) - { - count+= cat.GetUnitTypeCount(unitType); - } - - return count; - } - - private void Army_UnitAdded(WarFoundryObject val) - { - OnUnitAdded((Unit)val); - } - - private void Army_UnitRemoved(WarFoundryObject val) - { - OnUnitRemoved((Unit)val); - } - - private void Army_FailedRequirement(List<FailedUnitRequirement> val) - { - OnFailedRequirement(val); - } - } -}
--- a/api/Objects/ArmyCategory.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -// This file (ArmyCategory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; -using IBBoard.WarFoundry.API.Requirements; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for ArmyCategory. - /// </summary> - public class ArmyCategory : WarFoundryObject, ICostedWarFoundryObject - { - private Category category; - private Army parentArmy; - private double pointsTotal; - private List<Unit> units; - private Dictionary<string, int> unitTypes; - private DoubleValChangedDelegate PointsValueChangedMethod; - public event ObjectAddDelegate UnitAdded; - public event ObjectRemoveDelegate UnitRemoved; - public event FailedUnitRequirementDelegate FailedRequirement; - public event DoubleValChangedDelegate PointsValueChanged; - - public ArmyCategory(Army army, Category cat) : base() - { - parentArmy = army; - category = cat; - cat.NameChanged+=new StringValChangedDelegate(cat_NameChanged); - PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler); - units = new List<Unit>(); - unitTypes = new Dictionary<string,int>(); - } - - public Category Category - { - get { return category; } - } - - public Army ParentArmy - { - get { return parentArmy; } - } - - public override string ID - { - get - { - return Category.ID; - } - set - { - Category.ID = value; - } - } - - public override string Name - { - get { return category.Name; } - set - { - category.Name = value; - } - } - - internal void AddUnit(Unit unit) - { - List<FailedUnitRequirement> failedReqs = ParentArmy.CanAddUnit(unit); - units.Add(unit); - unit.Category = this; - unit.PointsValueChanged+= PointsValueChangedMethod; - int unitTypeCount; - unitTypes.TryGetValue(unit.UnitType.ID, out unitTypeCount); - unitTypes[unit.UnitType.ID] = (int)unitTypeCount + 1; - TotalPoints+= unit.Points; - OnUnitAdded(unit, failedReqs); - } - - internal void RemoveUnit(Unit unit) - { - List<FailedUnitRequirement> failedReqs = ParentArmy.CanRemoveUnit(unit); - units.Remove(unit); - unitTypes[unit.UnitType.ID] = ((int)unitTypes[unit.UnitType.ID])-1; - TotalPoints-= unit.Points; - unit.PointsValueChanged-= PointsValueChangedMethod; - OnUnitRemoved(unit, failedReqs); - } - - public int GetUnitTypeCount(UnitType unitType) - { - return unitTypes.ContainsKey(unitType.ID) ? (int)unitTypes[unitType.ID] : 0; - } - - public Unit[] GetUnits() - { - return units.ToArray(); - } - - private double TotalPoints - { - get { return pointsTotal; } - set - { - double oldVal = pointsTotal; - pointsTotal = value; - - if (oldVal!=pointsTotal) - { - OnPointsValueChanged(oldVal, pointsTotal); - } - } - } - - [Obsolete("Use Points instead")] - public double PointsTotal - { - get { return TotalPoints; } - } - - public double Points - { - get { return TotalPoints; } - } - - private void PointsValueChangedHandler(WarFoundryObject obj, double oldVal, double newVal) - { - if (obj is Unit) - { - double diff = newVal - oldVal; - TotalPoints+= diff; - } - } - - protected void OnUnitAdded(Unit unit) - { - OnUnitAdded(unit, null); - } - - protected void OnUnitAdded(Unit unit, List<FailedUnitRequirement> failedReqs) - { - if (UnitAdded != null) - { - UnitAdded(unit); - } - - if (FailedRequirement != null && failedReqs != null && failedReqs.Count > 0) - { - FailedRequirement(failedReqs); - } - } - - protected void OnUnitRemoved(Unit unit) - { - OnUnitRemoved(unit, null); - } - - protected void OnUnitRemoved(Unit unit, List<FailedUnitRequirement> failedReqs) - { - if (UnitRemoved != null) - { - UnitRemoved(unit); - } - - if (FailedRequirement != null && failedReqs != null && failedReqs.Count > 0) - { - FailedRequirement(failedReqs); - } - } - - protected virtual void OnPointsValueChanged(double oldValue, double newValue) - { - if (PointsValueChanged!=null) - { - PointsValueChanged(this, oldValue, newValue); - } - } - - protected void cat_NameChanged(WarFoundryObject obj, string oldValue, string newValue) - { - OnNameChanged(oldValue, newValue); - } - - public int GetPointsPercentage() - { - return (int)Math.Round((Points / ParentArmy.MaxPoints) * 100, 0); - } - } -}
--- a/api/Objects/Category.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -// This file (Category.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Xml; -using IBBoard.Logging; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// A Category is a definition at the <see cref=" GameSystem"/> or <see cref=" Race"/> level of a group that <see cref=" UnitType"/>s belong to. Each category has a name and a min/max limit on points or percentage of a total army cost that units in the category can total. - /// </summary> - public class Category : WarFoundryObject - { - private int minPts = 0; - private int maxPts = WarFoundryCore.INFINITY; - private int minPc = 0; - private int maxPc = 100; - - - public Category(string id, string name) : base(id, name) - { - } - - [Obsolete("Use the two argument constructor and the appropriate 'set' methods")] - public Category(string id, string name, int minPoints, int maxPoints, int minPercent, int maxPercent, int minChoices, int maxChoices, int baseValue, int incrementValue, int incrementAmount) : base(id, name) - { - MinimumPoints = minPoints; - MaximumPoints = maxPoints; - MinimumPercentage = minPercent; - MaximumPercentage = maxPercent; - } - - protected override string DefaultName() - { - return ""; - } - - /// <value> - /// Gets or sets the minimum number of points that the units of this category can cost. Note: This should be set AFTER MaximumPoints, otherwise an unintended default value may be set for the minimum - /// </value> - public int MinimumPoints - { - get { return minPts; } - set - { - minPts = (value >= 0 ? value : 0); - CheckMinimumPoints(); - } - } - - /// <value> - /// Gets or sets the maximum number of points that the units of this category can cost. Note: This should be set BEFORE MinimumPoints, otherwise an unintended default value may be set for the minimum - /// </value> - public int MaximumPoints - { - get { return maxPts; } - set - { - maxPts = (value >= 0 ? value : WarFoundryCore.INFINITY); - CheckMinimumPoints(); - } - } - - /// <summary> - /// Makes sure that the minimum points value isn't more than the maximum points value, hence the warning on the properties - /// </summary> - private void CheckMinimumPoints() - { - if (MinimumPoints > MaximumPoints && MaximumPoints!=WarFoundryCore.INFINITY) - { - MinimumPoints = MaximumPoints; - LogNotifier.WarnFormat(GetType(), "Category {0} ({1}) had a minimum points limit greater than its maximum points limit.", Name, ID); - } - } - - /// <value> - /// Gets or sets the minimum percentage of the total army points value that the units of this category can cost. Note: This should be set AFTER MaximumPercentage, otherwise an unintended default value may be set for the minimum - /// </value> - public int MinimumPercentage - { - get { return minPc; } - set - { - minPc = (value >= 0 ? value : 0); - CheckMinimumPercentage(); - } - } - - /// <value> - /// Gets or sets the maximum percentage of the total army points value that the units of this category can cost. Note: This should be set BEFORE MinimumPercentage, otherwise an unintended default value may be set for the minimum - /// </value> - public int MaximumPercentage - { - get { return maxPc; } - set - { - if (value < 0) - { - maxPc = 0; - } - else if (value > 100) - { - maxPc = 100; - } - else - { - maxPc = value; - } - - CheckMinimumPercentage(); - } - } - - /// <summary> - /// Makes sure that the minimum percentage value isn't more than the maximum points value, hence the warning on the properties - /// </summary> - private void CheckMinimumPercentage() - { - if (MinimumPercentage > MaximumPercentage) - { - MinimumPercentage = MaximumPercentage; - LogNotifier.WarnFormat(GetType(), "Category {0} ({1}) had a minimum percentage limit greater than its maximum percentage limit.", Name, ID); - } - } - } -}
--- a/api/Objects/CompositeEquipmentItem.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -// This file (CompositeEquipmentItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// A special <see cref=" EquipmentItem"/> that is made up of a number of other <code>EquipmentItem</code>s - /// </summary> - public class CompositeEquipmentItem : EquipmentItem - { - private List<EquipmentItem> compositeItems; - - public CompositeEquipmentItem(string id, string name, Race race) : base(id, name, race) - { - compositeItems = new List<EquipmentItem>(); - } - - public void AddItem(EquipmentItem item) - { - compositeItems.Add(item); - Cost+= item.Cost; - } - - public void RemoveItem(EquipmentItem item) - { - compositeItems.Remove(item); - Cost-= item.Cost; - } - - public EquipmentItem[] Items - { - get { return compositeItems.ToArray(); } - } - } -}
--- a/api/Objects/DuplicateItemException.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -// This file (DuplicateItemException.cs) is a part of IBBoard.WarFoundry.API and is copyright 2009 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 -{ - public class DuplicateItemException - { - public DuplicateItemException() - { - } - } -}
--- a/api/Objects/EquipmentItem.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -// This file (EquipmentItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Xml; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for EquipmentItem. - /// </summary> - public class EquipmentItem : WarFoundryObject - { - private double cost; - private string description; - private Race equipForRace; - - public EquipmentItem(string id, string name, Race race) : base(id, name) - { - equipForRace = race; - description = ""; - } - - public double Cost - { - get { return cost; } - set - { - if (value >= 0) - { - cost = value; - } - } - } - - public string Description - { - get { return description; } - set { description = (value == null ? "" : value); } - } - - public Race EquipmentForRace - { - get { return equipForRace; } - } - - public bool CanBeUsedWithItem(EquipmentItem item) - { - return true; - } - } -}
--- a/api/Objects/GameSystem.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,269 +0,0 @@ -// This file (GameSystem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; -using System.Xml; -using System.IO; -using IBBoard.Logging; -using IBBoard.WarFoundry.API.Factories; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for GameSystem. - /// </summary> - public class GameSystem : WarFoundryStagedLoadingObject - { - private static int SYSTEM_DEFAULT_ARMY_SIZE = 1000; - private bool warnOnError; - private bool allowAllies; - private Dictionary<string, Category> categories = new Dictionary<string,Category>(); - private Dictionary<string, SystemStats> stats = new Dictionary<string,SystemStats>(); - private string defaultStats; - private int defaultArmySize; - - public GameSystem(string systemID, string systemName, IWarFoundryFactory creatingFactory) - : base(systemID, systemName, creatingFactory) - { - stats = new Dictionary<string,SystemStats>(); - } - - public int SystemArmyDefaultSize - { - get { return defaultArmySize; } - set - { - if (value == 0) - { - defaultArmySize = SYSTEM_DEFAULT_ARMY_SIZE; - } - else - { - defaultArmySize = value; - } - } - } - - public bool AllowAllies - { - get { return allowAllies; } - set { allowAllies = value; } - } - - public void AddCategory(Category cat) - { - RawCategories[cat.ID] = cat; - } - - public Category GetCategory(string id) - { - EnsureFullyLoaded(); - Category cat = null; - RawCategories.TryGetValue(id, out cat); - return cat; - } - - public Category[] Categories - { - get - { - EnsureFullyLoaded(); - return DictionaryUtils.ToArray<string, Category>(RawCategories); - } - } - - protected Dictionary<string, Category> RawCategories - { - get { return categories; } - } - - public bool WarnOnError - { - get - { - return warnOnError; - } - set { warnOnError = value; } - } - - public void AddSystemStats(SystemStats sysStats) - { - stats[sysStats.ID] = sysStats; - } - - public SystemStats StandardSystemStats - { - get - { - EnsureFullyLoaded(); - return stats[defaultStats]; - } - } - - public string StandardSystemStatsID - { - get - { - EnsureFullyLoaded(); - return defaultStats; - } - - set - { - if (value != null && value.Trim().Length > 0) - { - defaultStats = value; - } - } - } - - public SystemStats[] SystemStats - { - get - { - EnsureFullyLoaded(); - SystemStats[] statsArray = new SystemStats[stats.Count]; - stats.Values.CopyTo(statsArray, 0); - return statsArray; - } - } - - public SystemStats GetSystemStatsForID(string id) - { - EnsureFullyLoaded(); - SystemStats statsForID; - stats.TryGetValue(id, out statsForID); - return statsForID; - } - - public Race SystemDefaultRace - { - get { return WarFoundryLoader.GetDefault().GetRace(this, Race.SYSTEM_DEFAULT_RACE_ID); } - } - - public bool Matches(GameSystem otherSystem) - { - if (otherSystem==null) - { - return false; - } - - return this.ID == otherSystem.ID; - } - - public override bool Equals(object obj) - { - if (obj == null) - { - return false; - } - - if (obj.GetType().Equals(this.GetType())) - { - GameSystem otherSystem = (GameSystem)obj; - - return this.ID == otherSystem.ID && this.Name == otherSystem.Name && ((this.RawCategories == null && otherSystem.RawCategories == null) || this.RawCategories.Equals(otherSystem.RawCategories)); - } - else - { - return false; - } - } - - public override int GetHashCode() - { - return ID.GetHashCode() + Name.GetHashCode() + (RawCategories!=null ? RawCategories.GetHashCode() : 0) + warnOnError.GetHashCode(); - } - - public bool UnitTypeMaxed(UnitType unitType, Army army) - { - return unitType.MaxNumber!=WarFoundryCore.INFINITY && army.GetUnitTypeCount(unitType) >= unitType.MaxNumber; - } - - public bool UnitTypeMinned(UnitType unitType, Army army) - { - return army.GetUnitTypeCount(unitType) <= unitType.MinNumber; - } - - public List<EquipmentItem> GetSystemEquipmentList() - { - List<EquipmentItem> items = new List<EquipmentItem>(); - Race defaultRace = SystemDefaultRace; - - if (defaultRace!=null) - { - items = defaultRace.GetEquipmentList(); - } - - return items; - } - - public EquipmentItem GetSystemEquipmentItem(string id) - { - EquipmentItem item = null; - Race defaultRace = SystemDefaultRace; - - if (defaultRace!=null) - { - item = defaultRace.GetEquipmentItem(id); - } - - return item; - } - - public UnitType[] GetSystemUnitTypes(Category cat) - { - UnitType[] items = new UnitType[0]; - Race defaultRace = SystemDefaultRace; - - if (defaultRace!=null) - { - items = defaultRace.GetUnitTypes(cat); - } - - return items; - } - - public UnitType GetSystemUnitType(string id) - { - UnitType unit = null; - Race defaultRace = SystemDefaultRace; - - if (defaultRace!=null) - { - unit = defaultRace.GetUnitType(id); - } - - return unit; - } - - public List<Ability> GetSystemAbilityList() - { - List<Ability> items = new List<Ability>(); - Race defaultRace = SystemDefaultRace; - - if (defaultRace!=null) - { - items = defaultRace.GetAbilityList(); - } - - return items; - } - - public Ability GetSystemAbility(string id) - { - Ability ability = null; - Race defaultRace = SystemDefaultRace; - - if (defaultRace!=null) - { - ability = defaultRace.GetAbility(id); - } - - return ability; - } - } -}
--- a/api/Objects/ICostedWarFoundryObject.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -// This file (ICostedNamedObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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> - /// An interface for WarFoundry objects that have a points value (cost) - /// </summary> - public interface ICostedWarFoundryObject : IWarFoundryObject - { - /// <summary> - /// A getter for the points value of the costed object - /// </summary> - double Points { get; } - - /// <summary> - /// An event that is fired when the points value of the object changes - /// </summary> - event DoubleValChangedDelegate PointsValueChanged; - } -}
--- a/api/Objects/IWarFoundryNativeSourceObject.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -// This file (IWarFoundryNativeSourceObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Interface for native WarFoundry objects that are the main object in a file and need to reference the file at a later date. - /// </summary> - public interface IWarFoundryNativeSourceObject : IWarFoundryObject - { - ZipFile SourceFile { get; set; } - } -}
--- a/api/Objects/IWarFoundryObject.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -// This file (IWarFoundryObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.WarFoundry.API.Factories; - -namespace IBBoard.WarFoundry.API.Objects -{ - public interface IWarFoundryObject - { - /// <value> - /// The unique identifier for the object - /// </value> - string ID { get; set; } - - /// <value> - /// The display name of the WarFoundry object - /// </value> - string Name { get; set; } - } -}
--- a/api/Objects/IWarFoundryStagedLoadObject.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -// This file (IWarFoundryStagedLoadObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using ICSharpCode.SharpZipLib.Zip; -using IBBoard.WarFoundry.API.Factories; - -namespace IBBoard.WarFoundry.API.Objects -{ - public interface IWarFoundryStagedLoadObject : IWarFoundryObject - { - /// <summary> - /// Checks whether the object has been fully loaded or whether only the first stage of loading has been performed. - /// If the object is not fully loaded then the method must finish loading the object. - /// </summary> - void EnsureFullyLoaded(); - - /// <value> - /// Gets the <code>AbstractNativeWarFoundryFactory</code> that created the object. - /// </value> - IWarFoundryFactory Factory { get; } - - /// <value> - /// Returns <code>true</code> if the object has been fully loaded with all data, else returns <code>false</code> - /// </value> - bool IsFullyLoaded { get; } - - /// <value> - /// Returns <code>true</code> if the object is in the process of being fully loaded with all data, else returns <code>false</code> - /// </value> - bool IsLoading { get; } - - /// <summary> - /// Marks the object as fully loaded so that no more load checking is required. - /// </summary> - void SetAsFullyLoaded(); - - /// <summary> - /// Markes the object as being in the process of being fully loaded. - /// </summary> - void SetAsLoading(); - } -}
--- a/api/Objects/InvalidContainershipException.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -// This file (InvalidContainershipException.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.Lang; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// A custom exception for when a unit was added as a sub-unit of another unit, but was not of a <see cref=" UnitType"/> that can be contained - /// by that unit. - /// </summary> - public class InvalidContainershipException : Exception - { - private Unit containing; - private Unit contained; - - public InvalidContainershipException(Unit containingUnit, Unit containedUnit) : base(CreateMessageString(containingUnit, containedUnit)) - { - containing = containingUnit; - contained = containedUnit; - } - - private static string CreateMessageString(Unit containingUnit, Unit containedUnit) - { - return String.Format("{0} cannot contain {1} because units of type {2} cannot contain units of type {3}", containingUnit.Name, containedUnit.Name, containingUnit.UnitType.Name, containedUnit.UnitType.Name); - } - - /// <value> - /// The <see cref=" Unit"/> that the contained unit was added to - /// </value> - public Unit ContainingUnit - { - get { return containing; } - } - - /// <value> - /// The <see cref=" Unit"/> that was added as a contained unit, but which was not of an allowed type - /// </value> - public Unit ContainedUnit - { - get { return contained; } - } - } -}
--- a/api/Objects/Race.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,317 +0,0 @@ -// This file (Race.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; -using System.IO; -using System.Xml; -using IBBoard.IO; -using IBBoard.WarFoundry.API.Factories; - -namespace IBBoard.WarFoundry.API.Objects -{ - public class Race : WarFoundryStagedLoadingObject - { - public static string SYSTEM_DEFAULT_RACE_ID = "GameDefault"; - - private string subID; - private GameSystem system; - private string defaultArmyName = ""; - private Dictionary<Category, Dictionary<string, UnitType>> unitTypesByCat; - private Dictionary<string, UnitType> unitTypes = new Dictionary<string,UnitType>(); - 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) - { - } - - public Race(string raceID, string raceSubID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : base(raceID + (raceSubID != "" ? "_" + raceSubID : ""), raceName, creatingFactory) - { - subID = (raceSubID == null ? "" : raceSubID); - system = gameSystem; - } - - public string SubID - { - get { return subID; } - set { subID = (value == null ? "" : value.Trim()); } - } - - public GameSystem GameSystem - { - get { return system; } - set - { - if (value == null) - { - throw new ArgumentException("Game system for a race cannot be null"); - } - - system = value; - } - } - - public string ArmyDefaultName - { - get { return defaultArmyName; } - set - { - if (value == null) - { - throw new ArgumentException("No default army name"); - } - - defaultArmyName = value; - } - } - - public void AddCategory(Category cat) - { - categories[cat.ID] = cat; - } - - /// <summary> - /// Gets a category from its ID. Attempts to get the category from the race's overrides, or else it falls back to getting the Game System's category with that ID. - /// </summary> - /// <param name="id"> - /// The ID of the category to get - /// </param> - /// <returns> - /// The <code>Category</code> with the specified ID, or null if one doesn't exist. - /// </returns> - public Category GetCategory(string id) - { - EnsureFullyLoaded(); - Category cat = null; - categories.TryGetValue(id, out cat); - - if (cat == null) - { - cat = GameSystem.GetCategory(id); - } - - return cat; - } - - public Category[] Categories - { - get - { - EnsureFullyLoaded(); - Category[] cats; - - if (!HasCategoryOverrides()) - { - cats = GameSystem.Categories; - } - else - { - cats = DictionaryUtils.ToArray<string, Category>(categories); - } - - return cats; - } - } - - public bool HasCategoryOverrides() - { - EnsureFullyLoaded(); - return categories.Count > 0; - } - - public void AddEquipmentItem(EquipmentItem item) - { - //TODO: Throw DuplicateItemException - equipment.Add(item.ID, item); - } - - public EquipmentItem GetEquipmentItem(string id) - { - EnsureFullyLoaded(); - return DictionaryUtils.GetValue(equipment, id); - } - - public List<EquipmentItem> GetEquipmentList() - { - EnsureFullyLoaded(); - List<EquipmentItem> items = new List<EquipmentItem>(); - - foreach (EquipmentItem item in equipment.Values) - { - items.Add(item); - } - - return items; - } - - public void AddUnitType(UnitType type) - { - CacheUnitType(type); - unitTypes.Add(type.ID, type); - } - - public UnitType[] GetUnitTypes(Category cat) - { - EnsureFullyLoaded(); - BuildUnitTypesByCategoryCache(); - Dictionary<string, UnitType> unitTypesDictionary; - unitTypesByCat.TryGetValue(cat, out unitTypesDictionary); - UnitType[] unitTypesArray; - - if (unitTypesDictionary == null) - { - unitTypesArray = new UnitType[0]; - } - else - { - unitTypesArray = DictionaryUtils.ToArray<string, UnitType>(unitTypesDictionary); - } - - return unitTypesArray; - } - - private void CacheUnitType(UnitType unit) - { - BuildUnitTypesByCategoryCache(); - - foreach (Category cat in unit.Categories) - { - Dictionary<string, UnitType> catUnitTypes = DictionaryUtils.GetValue(unitTypesByCat, cat); - - if (catUnitTypes == null) - { - throw new InvalidFileException(String.Format("Unit type {0} with name {1} is a unit of an undefined category ({2})", unit.ID, unit.Name, cat.ID)); - } - - catUnitTypes.Add(unit.ID, unit); - } - } - - private void BuildUnitTypesByCategoryCache() - { - if (unitTypesByCat == null) - { - DoBuildUnitTypesByCategoryCache(); - } - } - - private void DoBuildUnitTypesByCategoryCache() - { - unitTypesByCat = new Dictionary<Category,Dictionary<string,UnitType>>(); - - foreach (Category category in Categories) - { - unitTypesByCat.Add(category, new Dictionary<string, UnitType>()); - } - - foreach (UnitType unit in unitTypes.Values) - { - CacheUnitType(unit); - } - } - - public UnitType GetUnitType(string id) - { - EnsureFullyLoaded(); - return DictionaryUtils.GetValue(unitTypes, id); - } - - public List<Ability> GetAbilityList() - { - EnsureFullyLoaded(); - List<Ability> items = new List<Ability>(); - items.AddRange(abilities.Values); - return items; - } - - public void AddAbility(Ability newAbility) - { - //TODO: Throw DuplicateItemException - abilities.Add(newAbility.ID, newAbility); - } - - [Obsolete("Use AddAbility method instead")] - public void SetAbilities(Dictionary<string, Ability> newAbilities) - { - foreach (Ability ability in newAbilities.Values) - { - AddAbility(ability); - } - } - - public Ability GetAbility(string id) - { - EnsureFullyLoaded(); - return DictionaryUtils.GetValue(abilities, id); - } - - protected virtual Dictionary<string, UnitType> RaceUnitTypes - { - get { return RaceRawUnitTypes; } - set { RaceRawUnitTypes = value; } - } - - protected virtual Dictionary<string, EquipmentItem> RaceEquipment - { - get { return RaceRawEquipment; } - set { RaceRawEquipment = value; } - } - - protected virtual Dictionary<string, Ability> RaceAbilities - { - get { return RaceRawAbilities; } - set { RaceRawAbilities = value; } - } - - protected Dictionary<string, UnitType> RaceRawUnitTypes - { - get { return unitTypes; } - set { unitTypes = value; } - } - - protected Dictionary<string, EquipmentItem> RaceRawEquipment - { - get { return equipment; } - set { equipment = value; } - } - - protected Dictionary<string, Ability> RaceRawAbilities - { - 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/Stat.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -// This file (Stat.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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> - /// Summary description for Stat. - /// </summary> - public class Stat - { - private StatSlot parentStatSlot; - private string statString; - - public Stat(StatSlot parentSlot, string statValue) - { - parentStatSlot = parentSlot; - statString = statValue; - } - - public StatSlot ParentSlot - { - get { return parentStatSlot; } - set { parentStatSlot = value; } - } - - public string ParentSlotName - { - get { return ParentSlot.Name; } - } - - public string SlotValueString - { - get { return statString; } - set { statString = (value == null ? "" : value); } - } - } -}
--- a/api/Objects/StatSlot.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -// This file (StatSlot.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Text.RegularExpressions; -using System.Xml; -using IBBoard; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for StatSlot. - /// </summary> - public class StatSlot - { - private string name; - private SystemStats sysStats; - - public StatSlot(String statName) - { - name = statName; - } - - public string Name - { - get { return name; } - set { value = name; } - } - - public SystemStats SystemStats - { - get { return sysStats; } - set { sysStats = value; } - } - } -}
--- a/api/Objects/Stats.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -// This file (Stats.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Stats defines the statistic/attribute values for an entity (for example a unit or any of their equipment that has a stat line) paired against a <see cref=" SystemStats"/> stat line definition. - /// </summary> - public class Stats - { - private List<Stat> stats; - private SystemStats sysStats; - - public Stats(SystemStats systemStats) - { - sysStats = systemStats; - int statCount = sysStats.SlotCount; - stats = new List<Stat>(statCount); - - foreach (StatSlot slot in sysStats.StatSlots) - { - stats.Add(new Stat(slot, "")); - } - } - - public Stat[] StatsArray - { - get { return stats.ToArray(); } - } - - public void SetStatValue(string statName, string statValue) - { - StatSlot slot = sysStats[statName.ToLower()]; - - if (slot!=null) - { - int pos = sysStats.GetStatSlotPosition(slot); - - if (pos > -1) - { - stats[pos] = new Stat(slot, statValue); - } - } - } - - public Stat this[string id] - { - get - { - StatSlot slot = sysStats[id.ToLower()]; - int pos = sysStats.GetStatSlotPosition(slot); - Stat stat = null; - - try - { - stat = this[pos]; - } - catch (ArgumentException ex) - { - throw new ArgumentException(String.Format("Invalid statistic ID {0} for stats based on system stats set {1}", new object[]{id, sysStats.ID}), ex); - } - - return stat; - } - } - - public Stat this[int pos] - { - get - { - if (pos < stats.Count && pos >= 0) - { - return stats[pos]; - } - else - { - throw new ArgumentException(String.Format("Invalid statistic position {0} for stats based on system stats set {1}", new object[]{pos, sysStats.ID})); - } - } - } - - public string GetStatValue(string id) - { - return this[id.ToLower()].SlotValueString; - } - - public int StatCount - { - get { return stats.Count; } - } - - public string StatsID - { - get - { - return sysStats.ID; - } - } - } -}
--- a/api/Objects/SystemStats.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -// This file (SystemStats.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// SystemStats defines the available statistics/attributes that entity types can use (either a unit or an equipment item that has a stats line). Statistic/attribute values will be defined by a <see cref="Stats"/> object. - /// </summary> - public class SystemStats - { - private Dictionary<string, StatSlot> statsByName; - private List<StatSlot> stats; - private string id; - - public SystemStats(string statsID) - { - id = statsID; - statsByName = new Dictionary<string, StatSlot>(); - stats = new List<StatSlot>(); - } - - public void AddStatSlot(string slotName) - { - StatSlot slot = new StatSlot(slotName); - slot.SystemStats = this; - statsByName[slot.Name.ToLower()] = slot; - stats.Add(slot); - } - - public StatSlot[] StatSlots - { - get - { - return stats.ToArray(); - } - } - - public StatSlot this[string statName] - { - get - { - return DictionaryUtils.GetValue(statsByName, statName.ToLower()); - } - } - - public int GetStatSlotPosition(StatSlot slot) - { - return stats.IndexOf(slot); - } - - public int SlotCount - { - get { return stats.Count; } - } - - public string ID - { - get { return id; } - } - } -}
--- a/api/Objects/Unit.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,597 +0,0 @@ -// This file (Unit.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 2007, 2008, 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; -using System.Collections.Generic; -using System.Text; -using System.Xml; -using IBBoard.Lang; -using IBBoard.Limits; -using IBBoard.WarFoundry.API.Util; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for UnitInstance. - /// </summary> - public class Unit : WarFoundryObject, ICostedWarFoundryObject - { - private UnitType type; - private int size; - private Unit parentUnit; - private double points; - private ArmyCategory cat; - private Dictionary<UnitEquipmentItem, AbstractUnitEquipmentItemSelection> equipment = new Dictionary<UnitEquipmentItem, AbstractUnitEquipmentItemSelection>(); - private Dictionary<string, List<AbstractUnitEquipmentItemSelection>> equipmentSlots = new Dictionary<string, List<AbstractUnitEquipmentItemSelection>>(); - private List<Unit> containedUnits = new List<Unit>(); - public event DoubleValChangedDelegate PointsValueChanged; - public event IntValChangedDelegate UnitSizeChanged; - public event DoubleValChangedDelegate UnitEquipmentAmountChanged; - - public Unit(UnitType unitType, ArmyCategory parentArmyCat) : this(unitType, unitType.MinSize, parentArmyCat) { } - - public Unit(UnitType unitType, int startSize, ArmyCategory parentArmyCat) : this("", "", startSize, unitType, parentArmyCat) - { - SetInitialEquipment(); - UnitSizeChanged += new IntValChangedDelegate(RefreshUnitEquipmentAmounts); - } - - public Unit(string id, string name, int startSize, UnitType unitType, ArmyCategory parentArmyCat) : base(id, name) - { - Category = parentArmyCat; - type = unitType; - Size = startSize; - CalcCost(); - UnitEquipmentAmountChanged+= new DoubleValChangedDelegate(UnitEquipmentAmountChangedHandler); - UnitSizeChanged+= new IntValChangedDelegate(UnitSizeChangedHandler); - } - - private void UnitEquipmentAmountChangedHandler(WarFoundryObject obj, double oldVal, double newVal) - { - CalcCost(); - } - - private void UnitSizeChangedHandler(WarFoundryObject obj, int oldVal, int newVal) - { - CalcCost(); - - if (HasDefaultName()) - { - OnNameChanged("", Name); - } - } - - protected override string DefaultName() - { - if (type != null) - { - if (size == 1) - { - return type.Name; - } - else - { - return String.Format(Translation.GetTranslation("defaultUnitName"), size, type.Name); - } - } - else - { - return "Unknown Unit"; - } - } - - private void SetInitialEquipment() - { - foreach (UnitEquipmentItem unitEquip in UnitType.GetEquipmentItems()) - { - if (unitEquip.IsRequired) - { - if (CanEquipWithItem(unitEquip)) - { - ILimit minLimit = unitEquip.MinLimit; - - if (minLimit is IPercentageLimit) - { - SetEquipmentRatio(unitEquip, UnitEquipmentUtil.GetMinEquipmentPercentage(this, unitEquip)); - } - else - { - SetEquipmentAmount(unitEquip, UnitEquipmentUtil.GetMinEquipmentCount(this, unitEquip)); - } - } - } - } - } - - private void CalcCost() - { - double oldpoints = points; - points = type.CostPerTrooper * AdditionalTroopers + type.BaseUnitCost; - - foreach (AbstractUnitEquipmentItemSelection equipSelection in equipment.Values) - { - points += equipSelection.TotalCost; - } - - if (oldpoints!=points) - { - OnPointsValueChanged(oldpoints, points); - } - } - - public int AdditionalTroopers - { - get { return Math.Max(Size - type.BaseSize, 0); } - } - - public int Size - { - get { return size; } - set - { - if (value!=size) - { - int oldValue = size; - size = (value>0 ? value : 1); - OnUnitSizeChanged(oldValue, size); - } - } - } - - public UnitType UnitType - { - get { return type; } - } - - public Army Army - { - get { return (Category == null ? null : Category.ParentArmy); } - } - - public Race Race - { - get { return UnitType.Race; } - } - - public ArmyCategory Category - { - get - { - return cat; - } - set { cat = value; } - } - - [Obsolete("Use Points instead")] - public double PointsValue - { - get { return Points; } - } - - public double Points - { - get - { - if (points == 0) - { - CalcCost(); - } - - return points; - } - } - - public Unit[] ContainedUnits - { - get { return containedUnits.ToArray(); } - } - - public void AddContainedUnit(Unit unit) - { - if (UnitType.CanContainUnit(unit)) - { - if (!containedUnits.Contains(unit)) - { - containedUnits.Add(unit); - } - - unit.ParentUnit = this; - } - else - { - throw new InvalidContainershipException(this, unit); - } - } - - public void RemoveContainedUnit(Unit unit) - { - containedUnits.Remove(unit); - } - - public Unit ParentUnit - { - get { return parentUnit; } - set - { - if (!(parentUnit == value || (parentUnit != null && parentUnit.Equals(value)))) - { - parentUnit = value; - - if (value!=null) - { - value.AddContainedUnit(this); - } - } - } - } - - [Obsolete("Use UnitEquipmentUtil.GetAllowedEquipmentItems(Unit) instead")] - public UnitEquipmentItem[] GetAllowedAdditionalEquipment() - { - return UnitEquipmentUtil.GetAllowedEquipmentItems(this); - } - - public UnitEquipmentItem[] GetEquipment() - { - return DictionaryUtils.ToKeyArray(equipment); - } - - public EquipmentItem[] GetRequiredEquipment() - { - List<EquipmentItem> list = new List<EquipmentItem>(); - - foreach(UnitEquipmentItem item in GetEquipment()) - { - if (item.IsRequired) - { - list.Add(item.EquipmentItem); - } - } - - return list.ToArray(); - } - - internal AbstractUnitEquipmentItemSelection GetEquipmentSelection(UnitEquipmentItem item) - { - return DictionaryUtils.GetValue(equipment, item); - } - - [Obsolete("Use UnitEquipmentUtil method instead")] - public double GetEquipmentAmount(UnitEquipmentItem item) - { - return UnitEquipmentUtil.GetEquipmentAmount(this, item); - } - - [Obsolete("Use UnitEquipmentUtil method instead")] - public double GetEquipmentAmount(string equipID) - { - return GetEquipmentAmount(UnitType.GetEquipmentItem(equipID)); - } - - [Obsolete("Use UnitEquipmentUtil method instead")] - public bool GetEquipmentAmountIsRatio(UnitEquipmentItem item) - { - return UnitEquipmentUtil.GetEquipmentAmountIsRatio(this, item); - } - - [Obsolete("Use UnitEquipmentUtil method instead")] - public bool GetEquipmentAmountIsRatio(string itemID) - { - return GetEquipmentAmountIsRatio(UnitType.GetEquipmentItem(itemID)); - } - - [Obsolete("Implementation is down to the UI")] - public string GetEquipmentAmountString(string equipID) - { - return ""; - } - - [Obsolete("Implementation is down to the UI")] - public string GetEquipmentAmountString(UnitEquipmentItem item) - { - return ""; - } - - public void SetEquipmentAmount(UnitEquipmentItem equip, int amount) - { - if (amount <1 && amount != WarFoundryCore.INFINITY) - { - amount = 0; - } - - if (amount == 0) - { - RemoveEquipmentItem(equip); - } - else - { - AbstractUnitEquipmentItemSelection currSelection = DictionaryUtils.GetValue(equipment, equip); - double oldAmount = (currSelection == null ? 0 : currSelection.AmountTaken); - - if (amount != oldAmount) - { - if (oldAmount == 0) - { - AddEquipmentAmount(equip, amount); - } - else if (currSelection is UnitEquipmentNumericSelection) - { - //A UnitEquipmentItem shouldn't change its IsRatio value, so assume we already have the right sub-type - currSelection.AmountTaken = amount; - } - else - { - RemoveEquipmentItem(equip); - AddEquipmentAmount(equip, amount); - } - - OnUnitEquipmentAmountChanged(equip, oldAmount, amount); - } - } - } - - private void AddEquipmentAmount(UnitEquipmentItem equip, int amount) - { - AbstractUnitEquipmentItemSelection newItem = new UnitEquipmentNumericSelection(this, equip, amount); - equipment[equip] = newItem; - List<AbstractUnitEquipmentItemSelection> selections = DictionaryUtils.GetValue(equipmentSlots, equip.SlotName); - - if (selections == null) - { - selections = new List<AbstractUnitEquipmentItemSelection>(); - equipmentSlots[equip.SlotName] = selections; - } - - selections.Add(newItem); - } - - public void SetEquipmentRatio(UnitEquipmentItem equip, double ratio) - { - if (!equip.IsRatioLimit) - { - throw new InvalidOperationException("Equipment with ID "+equip.ID+" for unit of type "+UnitType.ID+" has an absolute limit, not a ratio limit"); - } - - if (ratio > 100) - { - ratio = 100; - } - else if (ratio < 0) - { - ratio = 0; - } - - if (ratio == 0) - { - RemoveEquipmentItem(equip); - } - else - { - AbstractUnitEquipmentItemSelection currSelection = DictionaryUtils.GetValue(equipment, equip); - double oldRatio = (currSelection == null ? 0 : currSelection.AmountTaken); - - if (ratio != oldRatio) - { - if (oldRatio == 0) - { - AddEquipmentRatio(equip, ratio); - } - else if (currSelection is UnitEquipmentRatioSelection) - { - currSelection.AmountTaken = ratio; - } - else - { - RemoveEquipmentItem(equip); - AddEquipmentRatio(equip, ratio); - } - - OnUnitEquipmentAmountChanged(equip, oldRatio, ratio); - } - } - } - - private void AddEquipmentRatio(UnitEquipmentItem equip, double ratio) - { - UnitEquipmentRatioSelection newItem = new UnitEquipmentRatioSelection (this, equip, ratio); - equipment[equip] = newItem; - List<AbstractUnitEquipmentItemSelection> selections = DictionaryUtils.GetValue(equipmentSlots, equip.SlotName); - - if (selections == null) - { - selections = new List<AbstractUnitEquipmentItemSelection>(); - equipmentSlots[equip.SlotName] = selections; - } - - selections.Add(newItem); - } - - private void RemoveEquipmentItem(UnitEquipmentItem equip) - { - double oldAmount = UnitEquipmentUtil.GetEquipmentAmount(this, equip); - - if (oldAmount != 0) - { - AbstractUnitEquipmentItemSelection selection = DictionaryUtils.GetValue (equipment, equip); - equipment.Remove(equip); - List<AbstractUnitEquipmentItemSelection> slotSelections = DictionaryUtils.GetValue (equipmentSlots, equip.SlotName); - slotSelections.Remove(selection); - OnUnitEquipmentAmountChanged(equip, oldAmount, 0); - } - } - - public bool CanEquipWithItem(UnitEquipmentItem item) - { - string[] mutexes = item.MutexGroups; - bool canEquip = false; - - if (mutexes.Length == 0) - { - canEquip = true; - } - else - { - canEquip = UnitEquipmentUtil.GetBlockingEquipmentItems(this, item).Count == 0; - } - - return canEquip; - } - - [Obsolete("Use UnitEquipmentUtil.GetBlockingEquipmentItems(Unit, UnitEquipmentItem) instead")] - public List<UnitEquipmentItem> GetBlockingEquipmentItems(UnitEquipmentItem item) - { - return UnitEquipmentUtil.GetBlockingEquipmentItems(this, item); - } - - public bool CanEquipWithItem(string equipID) - { - return CanEquipWithItem(UnitType.GetEquipmentItem(equipID)); - } - - private void OnPointsValueChanged(double oldValue, double newValue) - { - if (PointsValueChanged!=null) - { - PointsValueChanged(this, oldValue, newValue); - } - } - - private void OnUnitSizeChanged(int oldValue, int newValue) - { - if (UnitSizeChanged!=null) - { - UnitSizeChanged(this, oldValue, newValue); - } - } - - private void OnUnitEquipmentAmountChanged(UnitEquipmentItem equip, double oldValue, double newValue) - { - if (UnitEquipmentAmountChanged!=null) - { - UnitEquipmentAmountChanged(equip, oldValue, newValue); - } - } - - [Obsolete("Use UnitStatsArrays instead")] - public Stat[] UnitStatsArray - { - get { return UnitType.UnitStatsArray; } - } - - public Stat[][] UnitStatsArrays - { - get { return UnitType.UnitStatsArrays; } - } - - [Obsolete("Use UnitStatsArraysWithName instead")] - public Stat[] UnitStatsArrayWithName - { - get { return UnitType.UnitStatsArrayWithName; } - } - - public Stat[][] UnitStatsArraysWithName - { - get { return UnitType.UnitStatsArraysWithName; } - } - - public string[] UnitStatsArrayIDs - { - get - { - return UnitType.UnitStatsArrayIDs; - } - } - - public string GetStatValue(string statName) - { - return UnitType.GetStatValue(statName); - } - - public int GetEquipmentAmountInSlot (string slotName) - { - int amount = 0; - - List<AbstractUnitEquipmentItemSelection> selections = GetEquipmentSlotSelections(slotName); - - if (selections != null) - { - amount = GetSelectionTotal(selections); - } - - return amount; - } - - internal List<AbstractUnitEquipmentItemSelection> GetEquipmentSlotSelections(string slotName) - { - return DictionaryUtils.GetValue(equipmentSlots, slotName); - } - - /// <summary> - /// Gets the total amount of items taken for the item's slot, excluding the provided item - /// </summary> - /// <param name="item">the item to exclude from the count</param> - /// <returns>the total number of items</returns> - public int GetEquipmentAmountInSlotExcludingItem(UnitEquipmentItem item) - { - int amount = 0; - - List<AbstractUnitEquipmentItemSelection> selections = DictionaryUtils.GetValue(equipmentSlots, item.SlotName); - - if (selections != null) - { - selections = new List<AbstractUnitEquipmentItemSelection>(selections); - RemoveSelectionFromList(item, selections); - amount = GetSelectionTotal(selections); - } - - return amount; - } - - private void RemoveSelectionFromList(UnitEquipmentItem item, List<AbstractUnitEquipmentItemSelection> selections) - { - AbstractUnitEquipmentItemSelection selection = GetEquipmentSelection(item); - - if (selection != null) - { - selections.Remove(selection); - } - } - - private int GetSelectionTotal (List<AbstractUnitEquipmentItemSelection> selections) - { - int amount = 0; - - foreach (AbstractUnitEquipmentItemSelection selection in selections) - { - amount+= selection.NumberTaken; - } - - return amount; - } - - /// <summary> - /// Default stub implementation of getting the unit's abilities - defaults to just the unit type's required abilities until we get a way to modify them - /// </summary> - public ICollection<Ability> Abilities - { - get - { - return UnitType.GetRequiredAbilities(); - } - } - - private void RefreshUnitEquipmentAmounts(WarFoundryObject obj, int oldValue, int newValue) - { - foreach (UnitEquipmentItem item in equipment.Keys) - { - AbstractUnitEquipmentItemSelection selection = equipment[item]; - - if (selection is UnitEquipmentRatioSelection) - { - OnUnitEquipmentAmountChanged(item, selection.AmountTaken, selection.AmountTaken); - } - } - } - } -}
--- a/api/Objects/UnitEquipmentItem.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,255 +0,0 @@ -// This file (UnitEquipmentItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.CustomMath; -using IBBoard.Limits; -using IBBoard.WarFoundry.API.Util; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for UnitEquipmentItem. - /// </summary> - public class UnitEquipmentItem : WarFoundryObject - { - private EquipmentItem item; - private bool required; - private bool roundUp; - private double costMultiplier; - private RoundType roundType; - private string[] mutexGroups; - private UnitType unitType; - private string slotName = ""; - private ILimit minLimit; - private ILimit maxLimit; - - public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) - : this(equipmentItem, equipmentFor, new string[0]) - { - //Do nothing extra - } - - public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor, params string[] mutexGroups) - { - item = equipmentItem; - unitType = equipmentFor; - this.mutexGroups = mutexGroups; - unitType.AddEquipmentItem(this); - } - - public override string Name - { - get - { - return item.Name; - } - set - { - base.Name = value; - } - } - - public override string ID - { - get - { - return (EquipmentForUnit == null ? base.ID : EquipmentForUnit.ID) + EquipmentItemID; - } - set - { - base.ID = value; - } - } - - - public string EquipmentItemID - { - get { return item.ID; } - } - - public double Cost - { - get - { - return IBBMath.Round(EquipmentItem.Cost * CostMultiplier, CostRoundType); - } - } - - public double CostMultiplier - { - get { return costMultiplier; } - set - { - costMultiplier = value; - } - } - - public RoundType CostRoundType - { - get { return roundType; } - set - { - roundType = value; - } - } - - public bool IsRequired - { - get { return required; } - set { required = value; } - } - - public bool RoundNumberUp - { - get { return roundUp; } - set { roundUp = value; } - } - - [Obsolete("Use MutexGroups instead for greater flexibility")] - public string MutexGroup - { - get { return (mutexGroups.Length == 0 ? "" : mutexGroups[0]); } - } - - public String[] MutexGroups - { - get { return (string[]) mutexGroups.Clone(); } - } - - public UnitType EquipmentForUnit - { - get { return unitType; } - } - - public bool IsRatioLimit - { - get { return MinLimit is IPercentageLimit && MaxLimit is IPercentageLimit; } - } - - /// <summary> - /// Gets the Limit object for the minimum number of items that can be taken - /// </summary> - public ILimit MinLimit - { - get - { - ILimit limit = minLimit; - - if (limit == null) - { - if (maxLimit != null) - { - limit = maxLimit; - } - else - { - limit = new SimpleRoundedPercentageLimit(100, false); - } - } - - return limit; - } - set - { - if (value != null) - { - minLimit = value; - } - } - } - - /// <summary> - /// Gets the Limit object for the maximum number of items that can be taken - /// </summary> - public ILimit MaxLimit - { - get - { - ILimit limit = maxLimit; - - if (limit == null) - { - if (minLimit != null) - { - limit = minLimit; - } - else - { - limit = new SimpleRoundedPercentageLimit(100, false); - } - } - - return limit; - } - set - { - if (value != null) - { - maxLimit = value; - } - } - } - - public EquipmentItem EquipmentItem - { - get { return item; } - } - - public override string ToString() - { - return EquipmentItem.Name + " (" + Cost + "pts each)"; - } - - public bool HasAlternatives() - { - if (MutexGroups.Length == 0) - { - return false; - } - else if (EquipmentForUnit == null) - { - return false; - } - else - { - //If the number of items in the MutEx group is greater than one then it must be this item plus another - return EquipmentForUnit.GetEquipmentItemsByExclusionGroups(MutexGroups).Length > 1; - } - } - - public string Description - { - get { return EquipmentItem.Description; } - } - - public Race EquipmentForRace - { - get { return EquipmentItem.EquipmentForRace; } - } - - public bool CanBeUsedWithItem(EquipmentItem item) - { - return EquipmentItem.CanBeUsedWithItem(item); - } - - [Obsolete("Use UnitEquipmentUtil method instead")] - public bool IsMutuallyExclusive(UnitEquipmentItem item) - { - return UnitEquipmentUtil.ItemsAreMutuallyExclusive(this, item); - } - - public string SlotName - { - get { return slotName; } - set - { - if (value != null && value != "") - { - slotName = value; - } - } - } - } -}
--- a/api/Objects/UnitEquipmentNumericSelection.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -// This file (UnitEquipmentNumericSelection.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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> - /// An object to hold the selection of a unit's equipment where the selection was made as an absolute number - /// </summary> - public class UnitEquipmentNumericSelection : AbstractUnitEquipmentItemSelection - { - public UnitEquipmentNumericSelection(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item, amount) - { - } - - public UnitEquipmentNumericSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, item.MinLimit.GetLimit(unit.Size)) - { - } - - public override int NumberTaken - { - get - { - return (int) AmountTaken; - } - } - - protected bool IsWholeNumber(double newValue) - { - return newValue == Math.Round(newValue); - } - - protected override bool IsValidValue (double newValue) - { - return base.IsValidValue(newValue) && IsWholeNumber(newValue); - } - - [Obsolete("Implementation is down to the UI")] - public override string GetEquipmentAmountString () - { - return GetEquipmentAmountString(AmountTaken); - } - - [Obsolete("Implementation is down to the UI")] - public static string GetEquipmentAmountString(double amount) - { - return amount.ToString(); - } - } -}
--- a/api/Objects/UnitEquipmentRatioSelection.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -// This file (UnitEquipmentRatioSelection.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using IBBoard.CustomMath; -using IBBoard.Limits; -using IBBoard.WarFoundry.API.Util; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// An object to hold the selection of a unit's equipment where the selection was made as a percentage or ratio - /// of the total size of the unit - /// </summary> - public class UnitEquipmentRatioSelection : AbstractUnitEquipmentItemSelection - { - public UnitEquipmentRatioSelection(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item, amount) - { - } - - public UnitEquipmentRatioSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, ((IPercentageLimit)item.MinLimit).Percentage) - { - } - - public override int NumberTaken - { - get - { - return CalculateNumberTaken (EquipmentForUnit, EquipmentItem, AmountTaken); - } - } - - internal static int CalculateNumberTaken (Unit unit, UnitEquipmentItem item, double ratioTaken) - { - double exactNumberTaken = (ratioTaken / 100) * unit.Size; - int wholeNumberTaken = (int)IBBMath.Round (exactNumberTaken, item.RoundNumberUp); - int maxTaken = UnitEquipmentUtil.GetMaxEquipmentCount (unit, item); - int minTaken = UnitEquipmentUtil.GetMinEquipmentCount (unit, item); - return Math.Min (Math.Max (wholeNumberTaken, minTaken), maxTaken); - } - - [Obsolete("Implementation is down to the UI")] - public override string GetEquipmentAmountString () - { - return GetEquipmentAmountString(AmountTaken); - } - - [Obsolete("Implementation is down to the UI")] - public static string GetEquipmentAmountString(double amount) - { - string amountString; - - if (amount == 100) - { - amountString = "all"; - } - else - { - amountString = amount + "%"; - } - - return amountString; - } - - } -}
--- a/api/Objects/UnitMemberType.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -// 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; - } - - public string StatsID - { - get - { - return stats.StatsID; - } - } - - /// <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 Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,633 +0,0 @@ -// This file (UnitType.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.Collections.Generic; -using System.Xml; -using IBBoard.Limits; -using IBBoard.Logging; -using IBBoard.WarFoundry.API.Requirements; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// A UnitType is a type for a <see cref=" Unit"/>, normally relating to an entry in an army list. The UnitType defines the name, cost, minimum and maximum limits of a unit, and the equipment units of the type can take. - /// </summary> - public class UnitType : WarFoundryObject - { - private Category mainCat; - private Race race; - private int min, max, baseSize = 0; - private int minSize, maxSize; - private double baseUnitCost; - private double costPerTrooper; - private Stats stats; - private List<UnitRequirement> requirements = new List<UnitRequirement>(); - private Dictionary<string, UnitEquipmentItem> equipment = new Dictionary<string, UnitEquipmentItem>(); - private Dictionary<string, List<UnitEquipmentItem>> equipmentExclusionGroups = new Dictionary<string, List<UnitEquipmentItem>>(); - private List<string> equipmentKeyOrder = new List<string>(); - private Dictionary<string, Ability> requiredAbilities = new Dictionary<string, Ability>(); - private Dictionary<string, Ability> optionalAbilities = new Dictionary<string, Ability>(); - private String notes = ""; - private List<UnitType> containedTypes = new List<UnitType>(); - private Dictionary<string, string> extraData = new Dictionary<string, string>(); - private Dictionary<string, ILimit> slotLimits = new Dictionary<string, ILimit>(); - private Dictionary<string, UnitMemberType> unitMemberTypes = new Dictionary<string, UnitMemberType>(); - private List<Category> cats = new List<Category>(); - - - public UnitType(string id, string typeName, Race parentRace) : base(id, typeName) - { - race = parentRace; - } - - [Obsolete("Use three parameter constructor and setters")] - public UnitType(string id, string typeName, string mainCategoryID, string[] allCategoryIDs, int minNum, int maxNum, int minimumSize, int maximumSize, double unitCost, double trooperCost, Stats unitStats, UnitRequirement[] unitRequirements, Race parentRace) : this (id, typeName, parentRace) - { - mainCat = race.GetCategory(mainCategoryID); - MinNumber = minNum; - MaxNumber = maxNum; - MinSize = minimumSize; - MaxSize = maximumSize; - BaseUnitCost = unitCost; - CostPerTrooper = trooperCost; - SetUnitStats(unitStats); - - foreach (UnitRequirement requirement in requirements) - { - AddRequirement(requirement); - } - } - - public GameSystem GameSystem - { - get { return Race.GameSystem; } - } - - /// <value> - /// Gets the <see cref=" Race"/> that this unit belongs to. - /// </value> - public Race Race - { - get { return race; } - } - - /// <value> - /// Gets or sets the default <see cref=" Category"/> that this unit type is a member of. - /// If it is not already in the collection of categories then it will be added. - /// </value> - public virtual Category MainCategory - { - get - { - return mainCat; - } - set - { - mainCat = value; - AddCategory(value); - } - } - /// <summary> - /// Gets the collection of <see cref="Category"/> objects that this UnitType can be a member of - /// </summary> - public Category[] Categories - { - get - { - return cats.ToArray(); - } - } - - /// <summary> - /// Adds a category to the set of categories that this unit can be taken from. The first category added will automatically become the MainCategory. - /// </summary> - /// <param name="cat"> - /// A <see cref="Category"/> that this unit can be taken from - /// </param> - public void AddCategory(Category cat) - { - if (!cats.Contains(cat)) - { - cats.Add(cat); - - if (MainCategory == null) - { - MainCategory = cat; - } - } - } - - /// <value> - /// Gets or sets the minimum size of each unit of this type. Note: This should be set AFTER MaxSize, otherwise an unintended default value may be set for the minimum - /// </value> - public int MinSize - { - get { return minSize; } - set - { - minSize = (value >= 0 ? value : 0); - CheckMinimumSize(); - } - } - - /// <value> - /// Gets or sets the maximum size of each unit of this type. Note: This should be set BEFORE MinSize, otherwise an unintended default value may be set for the minimum - /// </value> - public int MaxSize - { - get { return maxSize; } - set - { - maxSize = (value >= 0 ? value : WarFoundryCore.INFINITY); - CheckMinimumSize(); - } - } - - /// <value> - /// Gets or sets the minimum number of units of this type that must be taken in an army. Note: This should be set AFTER MaxNumber, otherwise an unintended default value may be set for the minimum - /// </value> - public int MinNumber - { - get { return min; } - set - { - min = (value >= 0 ? value : 0); - CheckMinimumNumber(); - } - } - - /// <value> - /// Gets or sets the maximum number of units of this type that can be taken in an army. Note: This should be set BEFORE MinNumber, otherwise an unintended default value may be set for the minimum - /// </value> - public int MaxNumber - { - get { return max; } - set - { - max = (value >= 0 ? value : WarFoundryCore.INFINITY); - CheckMinimumNumber(); - } - } - - /// <summary> - /// Makes sure that the minimum number isn't more than the maximum number, hence the warning on the properties - /// </summary> - private void CheckMinimumNumber() - { - if (MinNumber > MaxNumber && MaxNumber!=WarFoundryCore.INFINITY) - { - MinNumber = MaxNumber; - LogNotifier.WarnFormat(GetType(), "Unit type {0} ({1}) had a minimum number greater than their maximum number.", Name, ID); - } - } - - /// <summary> - /// Makes sure that the minimum unit size isn't more than the maximum unit size, hence the warning on the properties - /// </summary> - private void CheckMinimumSize() - { - if (MinSize > MaxSize && MaxSize!=WarFoundryCore.INFINITY) - { - MinSize = MaxSize; - LogNotifier.WarnFormat(GetType(), "Unit type {0} ({1}) had a minimum size greater than their maximum size.", Name, ID); - } - } - - //// <value> - /// Gets or sets the "base size" of a unit, which is the number of troopers the unit has in it for its "base cost". For a lot of units this value will be 0 as the cost is worked out based on the total number of members. - /// </value> - public int BaseSize - { - get { return baseSize; } - set { baseSize = (value >= 0 ? value : 0); } - } - - /// <value> - /// The number of points that a "base unit" of <code>BaseSize</code> models costs. Additional models are charged at <code>CostPerTrooper</code> each. - /// </value> - public double BaseUnitCost - { - get { return baseUnitCost; } - set { baseUnitCost = (value >= 0 ? value : 0); } - } - - //// <value> - /// The cost of an individual trooper. This value is the cost for a basic trooper without weapons, which are added on top of the cost before calculating a unit cost. - /// </value> - public double CostPerTrooper - { - get { return costPerTrooper; } - set { costPerTrooper = (value >= 0 ? value : 0); } - } - - protected override string DefaultName() - { - throw new InvalidOperationException("Unit type with id "+id+" did not have a name specified"); - } - - /// <value> - /// The first of the <see cref="Stat"/>s lines for the unit. - /// </value> - [Obsolete("Use UnitStatsArrays instead")] - public Stat[] UnitStatsArray - { - get - { - return UnitStatsArrays[0]; - } - } - - //// <value> - /// The first ot the <see cref="Stat"/>s lines for the unit including an additional column that contains the unit type name - /// </value> - [Obsolete("Use UnitStatsArrays instead")] - public Stat[] UnitStatsArrayWithName - { - get - { - return UnitStatsArraysWithName[0]; - } - } - - /// <value> - /// The array of <see cref="Stat"/>s for each of the unit's stat lines - /// </value> - public Stat[][] UnitStatsArrays - { - get - { - Stat[][] statsArray; - - if (stats != null) - { - statsArray = new Stat[][]{ stats.StatsArray }; - } - else if (unitMemberTypes.Count > 0) - { - int memTypeCount = unitMemberTypes.Count; - statsArray = new Stat[memTypeCount][]; - int i = 0; - - foreach (UnitMemberType memType in unitMemberTypes.Values) - { - statsArray[i] = memType.StatsArray; - i++; - } - } - else - { - SystemStats systemStats = GameSystem.StandardSystemStats; - Stats tempStats = new Stats(systemStats); - statsArray = new Stat[][]{ tempStats.StatsArray }; - } - - return statsArray; - } - } - - public string[] UnitStatsArrayIDs - { - get - { - string[] ids; - - if (stats != null) - { - ids = new string[]{ stats.StatsID }; - } - else if (unitMemberTypes.Count > 0) - { - ids = new string[unitMemberTypes.Count]; - int i = 0; - - foreach (UnitMemberType memType in unitMemberTypes.Values) - { - ids[i] = memType.StatsID; - i++; - } - } - else - { - ids = new string[]{ GameSystem.StandardSystemStatsID }; - } - - return ids; - } - } - - //// <value> - /// The array of <see cref="Stat"/>s for each of the unit's stat lines including an additional column that contains the unit type name - /// </value> - public Stat[][] UnitStatsArraysWithName - { - get - { - Stat[][] statsArray; - - if (stats != null) - { - statsArray = new Stat[][]{ ExtendStatsArrayWithName(stats.StatsArray) }; - } - else if (unitMemberTypes.Count > 0) - { - int memTypeCount = unitMemberTypes.Count; - statsArray = new Stat[memTypeCount][]; - int i = 0; - - foreach (UnitMemberType memType in unitMemberTypes.Values) - { - statsArray[i] = memType.StatsArrayWithName; - i++; - } - } - else - { - SystemStats systemStats = GameSystem.StandardSystemStats; - Stats tempStats = new Stats(systemStats); - statsArray = new Stat[][]{ 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) - { - stats = newStats; - } - - public string GetStatValue(string statName) - { - return stats.GetStatValue(statName.ToLower()); - } - - internal void AddEquipmentItem(UnitEquipmentItem item) - { - if (!equipment.ContainsKey(item.ID)) - { - equipment.Add(item.ID, item); - equipmentKeyOrder.Add(item.ID); - AddToMutexGroups(item); - } - } - - private void AddToMutexGroups(UnitEquipmentItem item) - { - string[] mutexGroups = item.MutexGroups; - - foreach (string mutexGroup in mutexGroups) - { - List<UnitEquipmentItem> items = DictionaryUtils.GetValue(equipmentExclusionGroups, mutexGroup); - - if (items == null) - { - items = new List<UnitEquipmentItem>(); - equipmentExclusionGroups.Add(mutexGroup, items); - } - - items.Add(item); - } - } - - /// <summary> - /// Gets a <see cref="UnitEquipmentItem"/> for the given ID string, or <code>null</code> if nothing exists for that ID - /// </summary> - /// <param name="id"> - /// The ID of the UnitEquipmentItem to get - /// </param> - /// <returns> - /// The <see cref="UnitEquipmentItem"/> for the given ID string, or <code>null</code> if nothing exists for that ID - /// </returns> - public UnitEquipmentItem GetEquipmentItem(string id) - { - return DictionaryUtils.GetValue(equipment, id); - } - - /// <summary> - /// Gets a <see cref=" UnitEquipmentItem"/> for the given <see cref=" EquipmentItem"/>, or <code>null</code> if the unit can't take that <code>EquipmentItem</code> - /// </summary> - /// <param name="item"> - /// The <see cref="EquipmentItem"/> to get the <see cref=" UnitEquipmentItem"/> - /// </param> - /// <returns> - /// The <see cref="UnitEquipmentItem"/> that definies the UnitType's restrictions for taking the <see cref=" EquipmentItem"/> - /// </returns> - public UnitEquipmentItem GetEquipmentItem(EquipmentItem item) - { - return GetEquipmentItem(item.ID); - } - - /// <summary> - /// Gets an array of all available <see cref="UnitEquipmentItem"/>s for this UnitType - /// </summary> - /// <returns> - /// An array of all available <see cref="UnitEquipmentItem"/>s for this UnitType - /// </returns> - public UnitEquipmentItem[] GetEquipmentItems() - { - return DictionaryUtils.ToArray<string, UnitEquipmentItem>(equipment); - } - - public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroup(string group) - { - return GetEquipmentItemsByExclusionGroups(new string[] { group }); - } - - public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroups(string[] groups) - { - List<UnitEquipmentItem> list = new List<UnitEquipmentItem>(); - - foreach (string group in groups) - { - List<UnitEquipmentItem> groupList = DictionaryUtils.GetValue(equipmentExclusionGroups, group); - - if (groupList != null) - { - list.AddRange(groupList); - } - } - - return list.ToArray(); - } - - public bool IsRatioLimitedEquipmentItem(EquipmentItem item) - { - UnitEquipmentItem equip = GetEquipmentItem(item); - return equip != null && equip.IsRatioLimit; - } - - public bool IsAbsoluteLimitedEquipmentItem(EquipmentItem item) - { - UnitEquipmentItem equip = GetEquipmentItem(item); - return equip != null && !equip.IsRatioLimit; - } - - public ICollection<Ability> GetRequiredAbilities() - { - return requiredAbilities.Values; - } - - public ICollection<Ability> GetOptionalAbilities() - { - return optionalAbilities.Values; - } - - public void AddAbility(Ability ability, bool isRequired) - { - string id = ability.ID; - - if (!requiredAbilities.ContainsKey(id) && !optionalAbilities.ContainsKey(id)) - { - if (isRequired) - { - requiredAbilities[id] = ability; - } - else - { - optionalAbilities[id] = ability; - } - } - } - - public void AddRequirement(UnitRequirement requirement) - { - requirements.Add(requirement); - } - - public UnitRequirement[] Requirements - { - get { return requirements.ToArray(); } - } - - public List<FailedUnitRequirement> CanAddToArmy(Army army) - { - List<FailedUnitRequirement> failures = new List<FailedUnitRequirement>(); - - if (requirements!=null && requirements.Count > 0) - { - foreach (UnitRequirement requirement in requirements) - { - FailedUnitRequirement failure = (FailedUnitRequirement)requirement.CanAddToWarFoundryObject(army); - - if (failure!=null) - { - failures.Add(failure); - } - } - } - - return failures; - } - - public List<FailedUnitRequirement> CanRemoveFromArmy(Army army) - { - List<FailedUnitRequirement> failures = new List<FailedUnitRequirement>(); - - if (requirements!=null && requirements.Count > 0) - { - foreach (UnitRequirement requirement in requirements) - { - FailedUnitRequirement failure = (FailedUnitRequirement)requirement.CanRemoveFromWarFoundryObject(army); - - if (failure!=null) - { - failures.Add(failure); - } - } - } - - return failures; - } - - public string Notes - { - get { return notes; } - set { notes = value; } - } - - public bool CanContainUnit(Unit unit) - { - return CanContainUnitType(unit.UnitType); - } - - public bool CanContainUnitType(UnitType unitType) - { - return containedTypes.Contains(unitType); - } - - public UnitType[] ContainedUnitTypes - { - get { return containedTypes.ToArray(); } - } - - public void AddContainedUnitType(UnitType containedType) - { - containedTypes.Add(containedType); - } - - public void AddExtraData(string id, string data) - { - extraData[id] = data; - } - - public string GetExtraData(string id) - { - return DictionaryUtils.GetValue(extraData, id); - } - - public string StatsID - { - get - { - return stats.StatsID; - } - } - - public void AddEquipmentSlot(string slotName, ILimit slotLimit) - { - slotLimits.Add(slotName, slotLimit); - } - - public bool HasEquipmentSlot(string slotName) - { - return slotLimits.ContainsKey(slotName); - } - - /// <summary> - /// Gets the maximum limit on the number of items allowed in a single slot - /// </summary> - /// <param name="slotName">The name of the equipment slot to get the limit for</param> - /// <returns>The limit of the number of items allowed in a slot, or an infinite limit if the slot is the default one or has not been specified</returns> - public ILimit GetEquipmentSlotLimit(string slotName) - { - ILimit slotLimit = null; - - if (HasEquipmentSlot(slotName)) - { - slotLimit = DictionaryUtils.GetValue(slotLimits, slotName); - } - - if (slotLimit == null) - { - slotLimit = new UnlimitedLimit(); - } - - return slotLimit; - } - - public void AddUnitMemberType(UnitMemberType unitMemberType) - { - unitMemberTypes.Add(unitMemberType.ID, unitMemberType); - } - } -} \ No newline at end of file
--- a/api/Objects/WarFoundryObject.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -// This file (WarFoundryObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.WarFoundry.API.Factories; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// <summary> - /// Summary description for WarFoundryObject. - /// </summary> - public abstract class WarFoundryObject : IWarFoundryObject - { - protected string id; - protected string name; - public event StringValChangedDelegate NameChanged; - - protected WarFoundryObject() - { - } - - protected WarFoundryObject(string objName) : this() - { - Name = objName; - } - - protected WarFoundryObject(string objId, string objName) : this(objName) - { - ID = objId; - } - - public virtual string ID - { - get - { - if (id == null || id == "") - { - id = GenerateID(); - } - - return id; - } - - set - { - string newId = (value == null ? "" : value.Trim()); - id = (newId == "" ? GenerateID() : newId); - } - } - - public virtual string Name - { - get - { - if (HasDefaultName()) - { - return DefaultName(); - } - else - { - return name; - } - } - set - { - string oldValue = name; - name = value; - - if (name!=oldValue) - { - OnNameChanged(oldValue, name); - } - } - } - - public bool HasDefaultName() - { - return (name == null || name == ""); - } - - protected void OnNameChanged(string oldValue, string newValue) - { - if (NameChanged!=null) - { - NameChanged(this, oldValue, newValue); - } - } - - protected virtual string DefaultName() - { - return "-"; - } - - protected string GenerateID() - { - return Name + UnixTimestamp.GetTimestamp(DateTime.Now) + "." + DateTime.Now.Millisecond; - } - } -}
--- a/api/Objects/WarFoundryStagedLoadingObject.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -// This file (WarFoundryStagedLoadingObject.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using System.IO; -using IBBoard.WarFoundry.API.Factories; - -namespace IBBoard.WarFoundry.API.Objects -{ - public class WarFoundryStagedLoadingObject : WarFoundryObject, IWarFoundryStagedLoadObject - { - private bool isFullyLoaded; - private bool isLoading; - private IWarFoundryFactory creatingFactory; - private FileInfo sourceFile; - - protected WarFoundryStagedLoadingObject(IWarFoundryFactory creatingFactory) : this (null, creatingFactory) - { - } - - protected WarFoundryStagedLoadingObject(string objName, IWarFoundryFactory creatingFactory) : this(null, objName, creatingFactory) - { - } - - protected WarFoundryStagedLoadingObject(string objId, string objName, IWarFoundryFactory creatingFactory) : base(objId, objName) - { - this.creatingFactory = creatingFactory; - isFullyLoaded = false; - } - - public FileInfo SourceFile - { - get { return sourceFile; } - set { sourceFile = value; } - } - - public void EnsureFullyLoaded () - { - if (!IsFullyLoaded && !IsLoading) - { - if (Factory == null) - { - throw new InvalidOperationException("No factory set for partially loaded object with ID "+ID); - } - - Factory.CompleteLoading(this); - } - } - - public IWarFoundryFactory Factory - { - get { return creatingFactory; } - } - - public bool IsFullyLoaded - { - get { return isFullyLoaded; } - } - - public bool IsLoading - { - get { return isLoading; } - } - - public void SetAsFullyLoaded() - { - isLoading = false; - isFullyLoaded = true; - } - - public void SetAsLoading() - { - if (!isFullyLoaded) - { - isLoading = true; - } - } - } -}
--- a/api/Requirements/AbstractArmyRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -// This file (AbstractArmyRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using IBBoard.WarFoundry.API.Objects; - - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Abstract class for any requirement for adding an object to an army, e.g. adding units. - /// </summary> - public abstract class AbstractArmyRequirement : AbstractRequirement - { - protected abstract AbstractFailedRequirement CanAddToArmy(Army army); - protected abstract AbstractFailedRequirement CanRemoveFromArmy(Army army); - - public override AbstractFailedRequirement CanAddToWarFoundryObject (WarFoundryObject obj) - { - AbstractFailedRequirement fail = null; - - if (obj is Army) - { - fail = CanAddToArmy((Army)obj); - } - else - { - fail = new FailedRequirement(this); - } - - return fail; - } - - public override AbstractFailedRequirement CanRemoveFromWarFoundryObject (WarFoundryObject obj) - { - AbstractFailedRequirement fail = null; - - if (obj is Army) - { - fail = CanRemoveFromArmy((Army)obj); - } - else - { - fail = new FailedRequirement(this); - } - - return fail; - } - } -}
--- a/api/Requirements/AbstractFailedRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -// This file (AbstractFailedRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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.Requirements -{ - public abstract class AbstractFailedRequirement - { - protected AbstractRequirement failedReq; - - public AbstractFailedRequirement(AbstractRequirement req) - { - failedReq = req; - } - - public abstract string Description { get; } - } -}
--- a/api/Requirements/AbstractRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -// This file (AbstractRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// The base class for Requirements. Specific types of abstract requirement should extend this class. - /// </summary> - public abstract class AbstractRequirement - { - public abstract string Description { get; } - public abstract AbstractFailedRequirement CanAddToWarFoundryObject(WarFoundryObject obj); - public abstract AbstractFailedRequirement CanRemoveFromWarFoundryObject(WarFoundryObject obj); - } -}
--- a/api/Requirements/AbstractUnitRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -// This file (AbstractUnitRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Base abstract class for all requirements related to adding/removing something from a Unit (e.g. adding equipment or abilities) - /// </summary> - public abstract class AbstractUnitRequirement : AbstractRequirement - { - protected abstract AbstractFailedRequirement CanAddToUnit(Unit unit); - protected abstract AbstractFailedRequirement CanRemoveFromUnit(Unit unit); - - public override AbstractFailedRequirement CanAddToWarFoundryObject (WarFoundryObject obj) - { - AbstractFailedRequirement fail = null; - - if (obj is Unit) - { - fail = CanAddToUnit((Unit)obj); - } - else - { - fail = new FailedRequirement(this); - } - - return fail; - } - - public override AbstractFailedRequirement CanRemoveFromWarFoundryObject (WarFoundryObject obj) - { - AbstractFailedRequirement fail = null; - - if (obj is Unit) - { - fail = CanRemoveFromUnit((Unit)obj); - } - else - { - fail = new FailedRequirement(this); - } - - return fail; - } - } -}
--- a/api/Requirements/Delegates.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -// This file (Delegates.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; - -namespace IBBoard.WarFoundry.API.Requirements -{ - public delegate void FailedUnitRequirementDelegate(List<FailedUnitRequirement> failedRequirements); -}
--- a/api/Requirements/FailedRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -// This file (FailedRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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.Requirements -{ - public class FailedRequirement : AbstractFailedRequirement - { - public FailedRequirement(AbstractRequirement req) : base(req) - { - } - - public override string Description - { - get { return failedReq.Description; } - } - } -}
--- a/api/Requirements/FailedUnitRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -// This file (FailedUnitRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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.Requirements -{ - /// <summary> - /// Summary description for UnitRequirement. - /// </summary> - public class FailedUnitRequirement : AbstractFailedRequirement - { - public FailedUnitRequirement(UnitRequirement requirement) : base(requirement) - { - } - - public override string Description - { - get { return failedReq.Description; } - } - - } -}
--- a/api/Requirements/RequirementAND.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -// This file (RequirementAND.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Summary description for RequirementAND. - /// </summary> - public class RequirementAND : AbstractRequirement - { - private static string and = Translation.GetTranslation("requirementAND", "{0} and {1}"); - - private AbstractRequirement reqA, reqB; - - public RequirementAND(AbstractRequirement requirementA, AbstractRequirement requirementB) - { - reqA = requirementA; - reqB = requirementB; - } - - public override AbstractFailedRequirement CanAddToWarFoundryObject(WarFoundryObject obj) - { - FailedRequirement failed = null; - - if (reqA.CanAddToWarFoundryObject(obj) !=null || reqB.CanAddToWarFoundryObject(obj)!=null) - { - failed = new FailedRequirement(this); - } - - return failed; - } - - public override AbstractFailedRequirement CanRemoveFromWarFoundryObject(WarFoundryObject obj) - { - FailedRequirement failed = null; - - if (reqA.CanRemoveFromWarFoundryObject(obj) !=null || reqB.CanRemoveFromWarFoundryObject(obj)!=null) - { - failed = new FailedRequirement(this); - } - - return failed; - } - - public override string Description - { - get { return String.Format(and, reqA.Description, reqB.Description); } - } - } -}
--- a/api/Requirements/RequirementOR.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -// This file (RequirementOR.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Summary description for UnitRequirementOR. - /// </summary> - public class RequirementOR : AbstractRequirement - { - private static string or = Translation.GetTranslation("requirementOR", "{0} or {1}"); - - private AbstractRequirement reqA, reqB; - - public RequirementOR(AbstractRequirement requirementA, AbstractRequirement requirementB) - { - reqA = requirementA; - reqB = requirementB; - } - - public override AbstractFailedRequirement CanAddToWarFoundryObject(WarFoundryObject obj) - { - FailedRequirement failed = null; - - if (reqA.CanAddToWarFoundryObject(obj) !=null && reqB.CanAddToWarFoundryObject(obj)!=null) - { - failed = new FailedRequirement(this); - } - - return failed; - } - - public override AbstractFailedRequirement CanRemoveFromWarFoundryObject(WarFoundryObject obj) - { - FailedRequirement failed = null; - - if (reqA.CanRemoveFromWarFoundryObject(obj)!=null && reqB.CanRemoveFromWarFoundryObject(obj)!=null) - { - failed = new FailedRequirement(this); - } - - return failed; - } - - public override string Description - { - get { return String.Format(or, reqA.Description, reqB.Description); } - } - } -}
--- a/api/Requirements/UnitExcludesRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -// This file (UnitExcludesRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using System.Text; -using IBBoard.WarFoundry.API.Objects; -using IBBoard.Lang; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Summary description for UnitExcludesRequirement. - /// </summary> - public class UnitExcludesRequirement : UnitRequirement - { - private UnitRequirementItem[] excludingTypes; - - public UnitExcludesRequirement(UnitType type, UnitRequirementItem[] excludingUnitTypes) : base(type) - { - excludingTypes = excludingUnitTypes; - } - - public override string Description - { - get - { - string otherUnits = GetOtherUnitTypeNames(); - return Translation.GetTranslation("requirementUnitExcludesDescription", "{0} can only be taken if none of the following are taken: {1}", unitType.Name, otherUnits); - } - } - - private string GetOtherUnitTypeNames() - { - StringBuilder sb = new StringBuilder(); - - foreach (UnitRequirementItem req in excludingTypes) - { - sb.Append(req.UnitType.Name); - } - - return sb.ToString(); - } - - protected override AbstractFailedRequirement CanAddToArmy(Army army, UnitType type) - { - FailedUnitRequirement failed = null; - - for (int i = 0; i<excludingTypes.Length; i++) - { - if (army.GetUnitTypeCount(excludingTypes[i].UnitType) > 0) - { - failed = new FailedUnitRequirement(this); - break; - } - } - - return failed; - } - - protected override AbstractFailedRequirement CanRemoveFromArmy(Army army, UnitType type) - { - return null; - } - - } -}
--- a/api/Requirements/UnitRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -// This file (UnitRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using IBBoard.WarFoundry.API; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Summary description for UnitRequirement. - /// </summary> - public abstract class UnitRequirement : AbstractArmyRequirement - { - protected UnitType unitType; - - protected UnitRequirement(UnitType requirementFor) - { - unitType = requirementFor; - } - - /// <summary> - /// Checks whether the specified unit type can be added to the specified army. Returns a <see cref="FailedRequirement"> obejct if a unit of that type cannot legally be added, or no failure (null) if it can be added. - /// </summary> - /// <param name="army"> - /// The <see cref="Army"/> that the unit should be checked for adding to - /// </param> - /// <param name="type"> - /// The <see cref="UnitType"/> that is being checked. - /// </param> - /// <returns> - /// A <see cref="AbstractFailedRequirement"/> if the requirement means the <see cref="UnitType"/> cannot be legally added, else <code>null</code>. - /// </returns> - protected abstract AbstractFailedRequirement CanAddToArmy(Army army, UnitType type); - - /// <summary> - /// Checks whether the specified unit can be added to the specified army. Returns a <see cref="FailedRequirement"> obejct if the unit cannot legally be added, or no failure (null) if it can be added. - /// </summary> - /// <param name="army"> - /// The <see cref="Army"/> that the unit should be checked for adding to - /// </param> - /// <param name="type"> - /// The <see cref="Unit"/> that is being checked. - /// </param> - /// <returns> - /// A <see cref="AbstractFailedRequirement"/> if the requirement means the <see cref="Unit"/> cannot be legally added, else <code>null</code>. - /// </returns> - protected AbstractFailedRequirement CanAddToArmy(Army army, Unit unit) - { - return CanAddToArmy(army, unit.UnitType); - } - - /// <summary> - /// Checks whether the specified unit type can be removed from the specified army. Returns a <see cref="FailedRequirement"> obejct if a unit of that type cannot legally be removed, or no failure (null) if it can be removed. - /// </summary> - /// <param name="army"> - /// The <see cref="Army"/> that the unit should be checked for adding to - /// </param> - /// <param name="type"> - /// The <see cref="UnitType"/> that is being checked. - /// </param> - /// <returns> - /// A <see cref="AbstractFailedRequirement"/> if the requirement means the <see cref="UnitType"/> cannot be legally added, else <code>null</code>. - /// </returns> - protected abstract AbstractFailedRequirement CanRemoveFromArmy(Army army, UnitType type); - - /// <summary> - /// Checks whether the specified unit can be removed from the specified army. Returns a <see cref="FailedRequirement"> obejct if the unit cannot legally be removed, or no failure (null) if it can be removed. - /// </summary> - /// <param name="army"> - /// The <see cref="Army"/> that the unit should be checked for adding to - /// </param> - /// <param name="type"> - /// The <see cref="Unit"/> that is being checked. - /// </param> - /// <returns> - /// A <see cref="AbstractFailedRequirement"/> if the requirement means the <see cref="Unit"/> cannot be legally removed, else <code>null</code>. - /// </returns> - protected AbstractFailedRequirement CanRemoveFromArmy(Army army, Unit unit) - { - return CanRemoveFromArmy(army, unit.UnitType); - } - - protected override AbstractFailedRequirement CanAddToArmy(Army army) - { - return CanAddToArmy(army, unitType); - } - - protected override AbstractFailedRequirement CanRemoveFromArmy(Army army) - { - return CanRemoveFromArmy(army, unitType); - } - } -}
--- a/api/Requirements/UnitRequirementItem.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -// This file (UnitRequirementItem.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Summary description for UnitRequirementItem. - /// </summary> - public class UnitRequirementItem - { - private UnitType type; - private int requiredNum; - - public UnitRequirementItem(UnitType unitType, int reqNumber) - { - type = unitType; - requiredNum = reqNumber; - } - - public UnitRequirementItem(UnitType type) : this(type, 1) { } - - public UnitType UnitType - { - get { return type; } - } - - public int Amount - { - get { return requiredNum; } - } - } -}
--- a/api/Requirements/UnitRequirementMaxNumber.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -// This file (UnitRequirementMaxNumber.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - public class UnitRequirementMaxNumber : UnitRequirement - { - private int maxUnitCount; - - public UnitRequirementMaxNumber(UnitType type, int maxNumber) : base(type) - { - maxUnitCount = maxNumber; - } - - public override string Description - { - get { return Translation.GetTranslation("requirementUnitMaxNumber", "an army can contain up to {0} units of type {1}", maxUnitCount, unitType.Name); } - } - - protected override AbstractFailedRequirement CanAddToArmy (Army army, UnitType type) - { - FailedUnitRequirement failed = null; - - if (army.GetUnitTypeCount(type) >= maxUnitCount) - { - failed = new FailedUnitRequirement(this); - } - - return failed; - } - - protected override AbstractFailedRequirement CanRemoveFromArmy (Army army, UnitType type) - { - return null; - } - } -}
--- a/api/Requirements/UnitRequirementMinNumber.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -// This file (UnitRequirementMinNumber.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using IBBoard.Lang; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - public class UnitRequirementMinNumber : UnitRequirement - { - private int minUnitCount; - - public UnitRequirementMinNumber(UnitType type, int minNumber) : base(type) - { - minUnitCount = minNumber; - } - - public override string Description - { - get { return Translation.GetTranslation("requirementUnitMinNumber", "you must include at least {0} of {1} in an army", minUnitCount, unitType.Name); } - } - - protected override AbstractFailedRequirement CanAddToArmy(Army army, UnitType type) - { - return null; - } - - protected override AbstractFailedRequirement CanRemoveFromArmy (Army army, UnitType type) - { - FailedUnitRequirement failed = null; - - if (army.GetUnitTypeCount(type) <= minUnitCount) - { - failed = new FailedUnitRequirement(this); - } - - return failed; - } - } -}
--- a/api/Requirements/UnitRequiresAtLeastRequirement.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -// This file (UnitRequiresAtLeastRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using System.Collections.Generic; -using System.Text; -using IBBoard.Lang; -using IBBoard.WarFoundry.API; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Requirements -{ - /// <summary> - /// Summary description for UnitRequiresRequirement. - /// </summary> - public class UnitRequiresAtLeastRequirement : UnitRequirement - { - private UnitRequirementItem[] requiredTypes; - private String unitList; - - public UnitRequiresAtLeastRequirement(UnitType type, UnitType requiredUnitType) : this(type, new UnitRequirementItem[]{new UnitRequirementItem(requiredUnitType)}) - { - } - - public UnitRequiresAtLeastRequirement(UnitType type, UnitRequirementItem[] requiredUnitTypes) : base(type) - { - requiredTypes = requiredUnitTypes; - bool first = true; - - foreach (UnitRequirementItem req in requiredTypes) - { - string reqString = Translation.GetTranslation("requirementUnitTypeAtLeastSingle", "{1} {0}", req.UnitType.Name, req.Amount); - - if (first) - { - first = false; - unitList = reqString; - } - else - { - unitList = Translation.GetTranslation("requirementUnitTypeAtLeastJoiner", "{0}, {1}", unitList, reqString); - } - } - } - - public override string Description - { - get { return Translation.GetTranslation("requirementUnitTypeAtLeast", "the army must include at least the following units to include a unit of type {0}: {1}", unitType.Name, unitList); } - } - - protected override AbstractFailedRequirement CanRemoveFromArmy(Army army, UnitType type) - { - return null; - } - - protected override AbstractFailedRequirement CanAddToArmy(Army army, UnitType type) - { - FailedRequirement failure = null; - - foreach (UnitRequirementItem req in requiredTypes) - { - if (army.GetUnitTypeCount(req.UnitType) < req.Amount) - { - failure = new FailedRequirement(this); - break; - } - } - - return failure; - } - } -}
--- a/api/Savers/IWarFoundryFileSaver.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// This file (IWarFoundryFileSaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Savers -{ - public interface IWarFoundryFileSaver - { - /// <summary> - /// Saves an <see cref="Army"/> to a file on disk. - /// </summary> - /// <param name="army"> - /// The <see cref="Army"/> to save - /// </param> - /// <param name="path"> - /// The path to save the army to - /// </param> - /// <returns> - /// TRUE if saving succedes, else FALSE - /// </returns> - bool Save(Army army, string path); - } -}
--- a/api/Savers/WarFoundrySaver.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -// This file (WarFoundrySaver.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2008, 2009 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.Savers -{ - public class WarFoundrySaver - { - private static IWarFoundryFileSaver fileSaver; - - public static IWarFoundryFileSaver GetSaver() - { - return fileSaver; - } - - public static void SetFileSaver(IWarFoundryFileSaver newFileSaver) - { - fileSaver = newFileSaver; - } - } -}
--- a/api/Util/UnitEquipmentUtil.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,206 +0,0 @@ -// This file (UnitEquipmentUtil.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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; -using System.Collections.Generic; -using System.Text; -using IBBoard.CustomMath; -using IBBoard.Limits; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API.Util -{ - public class UnitEquipmentUtil - { - /// <summary> - /// Gets an array of allowed <see cref="UnitEquipmentItem"/>s based on the current selections of the unit, taking in to account Mutex groups and other limits. - /// </summary> - /// <param name="unit">The <see cref="Unit"/> to get equipment items for</param> - /// <returns>The array of allowed <see cref="UnitEquipmentItem"/>s</returns> - public static UnitEquipmentItem[] GetAllowedEquipmentItems(Unit unit) - { - List<UnitEquipmentItem> list = new List<UnitEquipmentItem>(); - UnitEquipmentItem[] currItems = unit.GetEquipment(); - - foreach (UnitEquipmentItem item in GetAllEquipmentItems(unit)) - { - bool allowed = IsAllowedByMutex(item, currItems); - - if (allowed) - { - list.Add(item); - } - } - - return list.ToArray(); - } - - private static bool IsAllowedByMutex(UnitEquipmentItem item, UnitEquipmentItem[] currItems) - { - bool allowed = true; - - foreach (UnitEquipmentItem currItem in currItems) - { - if (ItemsAreMutuallyExclusive(currItem, item)) - { - allowed = false; - break; - } - } - - return allowed; - } - - /// <summary> - /// Gets a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code> because of mutex groups. - /// </summary> - /// <param name="unit">The unit that wants to take the equipment item</param> - /// <param name="item">The item to check blocking items for</param> - /// <returns>a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code></returns> - public static List<UnitEquipmentItem> GetBlockingEquipmentItems(Unit unit, UnitEquipmentItem item) - { - List<UnitEquipmentItem> items = new List<UnitEquipmentItem>(); - UnitEquipmentItem[] currItems = unit.GetEquipment(); - - foreach (UnitEquipmentItem unitItem in currItems) - { - if (ItemsAreMutuallyExclusive(unitItem, item)) - { - items.Add(unitItem); - } - } - - return items; - } - - public static UnitEquipmentItem[] GetAllEquipmentItems(Unit unit) - { - return unit.UnitType.GetEquipmentItems(); - } - - public static bool ItemsAreMutuallyExclusive(UnitEquipmentItem item1, UnitEquipmentItem item2) - { - bool areMutex = false; - string[] item1mutex = item1.MutexGroups; - string[] item2mutex = item2.MutexGroups; - - foreach (string mutex in item1mutex) - { - foreach (string otherMutex in item2mutex) - { - if (mutex.Equals(otherMutex)) - { - areMutex = true; - goto postLoop; - } - } - } - postLoop: - - return areMutex; - } - - public static int GetMaxEquipmentCount (Unit unit, UnitEquipmentItem equip) - { - return GetEquipmentCountLimit (unit, equip.MaxLimit.GetLimit(unit.Size), equip); - } - - private static int GetEquipmentCountLimit (Unit unit, int currLimit, UnitEquipmentItem equip) - { - int newLimit = currLimit; - ILimit limit = GetSlotLimitForItem(unit, equip); - - if (!(limit is UnlimitedLimit)) - { - int slotMax = limit.GetLimit (unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip); - newLimit = Math.Min (slotMax, newLimit); - } - - return newLimit; - } - - private static ILimit GetSlotLimitForItem(Unit unit, UnitEquipmentItem equip) - { - return unit.UnitType.GetEquipmentSlotLimit(equip.SlotName); - } - - - public static int GetMinEquipmentCount (Unit unit, UnitEquipmentItem equip) - { - return GetEquipmentCountLimit (unit, equip.MinLimit.GetLimit(unit.Size), equip); - } - - public static bool IsEquipmentRatioLimited(Unit unit, UnitEquipmentItem equip) - { - ILimit limit = GetSlotLimitForItem(unit, equip); - return equip.IsRatioLimit && (limit is IPercentageLimit || limit is UnlimitedLimit); - } - - public static double GetMaxEquipmentPercentage(Unit unit, UnitEquipmentItem equip) - { - return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MaxLimit, unit); - } - - private static double GetPercentageOfUnitSize(int number, Unit unit) - { - return IBBMath.Percentage(number, unit.Size); - } - - private static double GetMinOfSlotLimitAndEquipmentLimit(UnitEquipmentItem equip, ILimit equipLimit, Unit unit) - { - double limit = 0; - ILimit slotLimit = GetSlotLimitForItem(unit, equip); - - if (slotLimit is IPercentageLimit) - { - limit = ((IPercentageLimit)slotLimit).Percentage - GetPercentageOfUnitSize(unit.GetEquipmentAmountInSlotExcludingItem(equip), unit); - } - else - { - int remaining = slotLimit.GetLimit(unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip); - limit = GetPercentageOfUnitSize(remaining, unit); - } - - if (equip.IsRatioLimit) - { - limit = Math.Min(limit, ((IPercentageLimit)equipLimit).Percentage); - } - else - { - limit = Math.Min(limit, GetPercentageOfUnitSize(equipLimit.GetLimit(unit.Size), unit)); - } - - return limit; - } - - public static double GetMinEquipmentPercentage(Unit unit, UnitEquipmentItem equip) - { - return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MinLimit, unit); - } - - public static double GetEquipmentAmount(Unit unit, UnitEquipmentItem item) - { - double amount = 0; - AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item); - - if (selection != null) - { - amount = selection.AmountTaken; - } - - return amount; - } - - public static bool GetEquipmentAmountIsRatio(Unit unit, UnitEquipmentItem item) - { - return (unit.GetEquipmentSelection(item) is UnitEquipmentRatioSelection); - } - - public static int GetEquipmentAmountTaken(Unit unit, UnitEquipmentItem item) - { - AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item); - return (selection == null ? 0 : selection.NumberTaken); - } - } -}
--- a/api/WarFoundryCore.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -// This file (WarFoundryCore.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using IBBoard.Logging; -using IBBoard.WarFoundry.API.Objects; - -namespace IBBoard.WarFoundry.API -{ - public class WarFoundryCore - { - public static readonly int INFINITY = -1; - public static event GameSystemChangedDelegate GameSystemChanged; - public static event ArmyChangedDelegate ArmyChanged; - - private static GameSystem system; - private static Army currentArmy; - - public static GameSystem CurrentGameSystem - { - get { return system; } - set - { - if (system==null || !system.Equals(value)) - { - GameSystem oldSystem = system; - system = value; - - if (system==null) - { - LogNotifier.Debug(typeof(WarFoundryCore), "Game system set to null"); - } - else - { - LogNotifier.DebugFormat(typeof(WarFoundryCore), "Game system set to {0} with ID {1}", system.Name, system.ID); - } - - if (GameSystemChanged!=null) - { - GameSystemChanged(oldSystem, system); - } - - //If we've changed the game system then we can't keep the current army - CurrentArmy = null; - } - } - } - - public static Army CurrentArmy - { - get { return currentArmy; } - set - { - if (currentArmy==null || !currentArmy.Equals(value)) - { - Army oldArmy = currentArmy; - - if (value != null) - { - CurrentGameSystem = value.GameSystem; //Set the game system in case the new army is from a different system - currentArmy = value; - } - else - { - currentArmy = null; - } - - if (ArmyChanged!=null) - { - ArmyChanged(oldArmy, currentArmy); - } - } - } - } - } -}
--- a/api/WarFoundryLoader.cs Sat Aug 13 14:13:13 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -// This file (WarFoundryLoader.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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; -using ICSharpCode.SharpZipLib.Zip; - -namespace IBBoard.WarFoundry.API -{ - public class WarFoundryLoader - { - private static AbstractWarFoundryLoader loader; - - /// <summary> - /// Gets the default <see cref="WarFoundryLoader"/> used to load WarFoundry data files. - /// </summary> - /// <returns> - /// The default <see cref="WarFoundryLoader"/> - /// </returns> - public static AbstractWarFoundryLoader GetDefault() - { - if (loader == null) - { - loader = new DefaultWarFoundryLoader(); - } - - return loader; - } - - public static void SetDefault(AbstractWarFoundryLoader newLoader) - { - loader = newLoader; - } - - private WarFoundryLoader() - { - //Hide constructor - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app.config Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,3 @@ +<?xml version="1.0"?> +<configuration> + <startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
--- a/schemas/race.xsd Sat Aug 13 14:13:13 2011 -0500 +++ b/schemas/race.xsd Fri Aug 26 20:04:52 2011 +0100 @@ -173,12 +173,20 @@ <xs:sequence> <xs:element name="requirement"> <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="requirementName" type="xs:string" use="required"/> - <xs:anyAttribute processContents="lax"/> - </xs:extension> - </xs:simpleContent> + <xs:sequence> + <xs:element name="data" minOccurs="0" maxOccurs="1"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:anyAttribute processContents="lax"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> + </xs:sequence> + <xs:attribute name="requirementName" type="xs:string" use="required"/> + <xs:anyAttribute processContents="lax"/> </xs:complexType> </xs:element> </xs:sequence>
--- a/schemas/system.xsd Sat Aug 13 14:13:13 2011 -0500 +++ b/schemas/system.xsd Fri Aug 26 20:04:52 2011 +0100 @@ -40,6 +40,10 @@ <xs:attribute name="id" type="xs:string" /> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="defaultArmySize" type="core:nonNegativeNonInfiniteDouble" default="0"/> + <xs:attribute name="defaultPtsAbbreviationSingular" type="xs:string" default="pt"/> + <xs:attribute name="defaultPtsAbbreviationPlural" type="xs:string" default="pts"/> + <xs:attribute name="defaultPtsNameSingular" type="xs:string" default="point"/> + <xs:attribute name="defaultPtsNamePlural" type="xs:string" default="points"/> <xs:attribute name="warn" type="xs:boolean" default="false"/> <xs:attribute name="allowAllies" type="xs:boolean" default="true"/> <xs:anyAttribute processContents="lax"/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xsl/default_html.xsl Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,59 @@ +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" method="html" indent="yes" omit-xml-declaration="yes"/> +<xsl:template match="/"> + <html> + <head> + <style> + table, th, td { border: 1px solid #000; border-spacing: 0; border-collapse: collapse; margin: 0 } + table table { width: 100%; border-width: 0; margin: -2px } + table table td { border-width:0 1px } + </style> + <title> + <xsl:value-of select="/army/name"/> + </title> + </head> + <body> + <div id="armyInfo"> + <h1> + <xsl:value-of select="/army/name"/> - <xsl:value-of select="/army/pointsUsed"/>pts + </h1> + <xsl:for-each select="/army/category"> + <table> + <xsl:for-each select="./unit/statLine[1]"> + <tr> + <xsl:for-each select="./stat"> + <td> + <xsl:value-of select="./@name"/> + </td> + </xsl:for-each> + <td>Notes</td> + <td>Points</td> + </tr> + </xsl:for-each> + <xsl:for-each select="./unit/statLine"> + <tr> + <xsl:for-each select="./stat"> + <td> + <xsl:value-of select="./@value"/> + </td> + </xsl:for-each> + <td> + <xsl:for-each select="../equipmentItem"> + <xsl:value-of select="./@name"/> (<xsl:value-of select="./@count"/>), + </xsl:for-each> + <xsl:for-each select="../abilityItem"> + <xsl:value-of select="./@name"/> (<xsl:value-of select="./@description"/>), + </xsl:for-each> + </td> + <td> + <xsl:value-of select="../@points"/> + </td> + </tr> + </xsl:for-each> + </table> + </xsl:for-each> + </div> + </body> + </html> +</xsl:template> +</xsl:stylesheet> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xsl/unitcard.xsl Fri Aug 26 20:04:52 2011 +0100 @@ -0,0 +1,118 @@ +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" method="html" indent="yes" omit-xml-declaration="yes"/> + <xsl:variable name="lower">abcdefghijklmnopqrstuvwxyz</xsl:variable> + <xsl:variable name="upper">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable> + <xsl:template match="/"> + <html> + <head> + <title> + <xsl:value-of select="/army/name"/> - Created in WarFoundry + </title> + <style media="all"> + div#armyInfo { font-size: x-large; width: 100%; margin-bottom: 2em; } + div.unitcard { border: 1px solid black; width: 75%; margin-bottom: 2em; } + div.unitcard table.title { width: 100%; } + div.unitcard table.title th { background-color: #999999; } + table.stats { border-collapse: collapse; width: 100%;} + table.lists { padding: 0px; margins: 0px; border: 1px solid black; width: 100%} + table.lists th { font-size: small; font-variant: small-caps; text-align: left; } + table.lists td { width: 45%; } + ul.equipmentList { font-size: small; display: inline; list-style-type: none; } + ul.abilityList { font-size: small; display: inline; list-style-type: none; } + </style> + <style media="print"> + div.unitcard { page-break-inside: avoid; } + div.specialrules { page-break-inside: avoid; } + div.pagebreak { page-break-after: always; display: none; } + </style> + </head> + <body> + <div id="armyInfo"> + Name: <xsl:value-of select="/army/name"/> <br /> + Points: <xsl:value-of select="/army/pointsUsed"/> of + <xsl:value-of select="/army/pointsAvailable"/> + </div> + <xsl:for-each select="/army/category"> + <xsl:for-each select="./unit"> + <div class="unitcard"> + <table class="title"> + <th align="left" width="50%"> + <xsl:value-of select="../@type"/>:<xsl:value-of select="./@name"/> + </th> + <th width="25%"> + Models: <xsl:value-of select="sum(.//@models)"/> + </th> + <th width="25%"> + Points: <xsl:value-of select="./@points"/> + </th> + </table> + <table class="stats" border="1"> + <xsl:for-each select="./statLine[1]"> + <tr> + <xsl:for-each select="./stat"> + <td> + <b> + <xsl:value-of select="translate(./@name,$lower,$upper)"/> + </b> + </td> + </xsl:for-each> + </tr> + </xsl:for-each> + <xsl:for-each select="./statLine"> + <tr> + <xsl:for-each select="./stat"> + <td> + <xsl:value-of select="./@value"/> + </td> + </xsl:for-each> + </tr> + </xsl:for-each> + </table> + <table class="lists"> + <tr> + <th> + Equipment + </th> + <th> + Abilities + </th> + </tr> + <tr> + <td> + <ul class="equipmentList"> + <xsl:for-each select="./equipmentItem"> + <li> + <xsl:value-of select="./@name"/> (<xsl:value-of select="./@count"/>) + </li> + </xsl:for-each> + </ul> + </td> + <td> + <ul class="abilityList"> + <xsl:for-each select="./abilityItem"> + <li> + <xsl:value-of select="./@name"/> + </li> + </xsl:for-each> + </ul> + </td> + </tr> + </table> + </div> + </xsl:for-each> + </xsl:for-each> + <div class="pagebreak"></div> + <div class="specialrules"> + <h2>Special Rules</h2> + <ul class="abilityDescriptions"> + <xsl:for-each select='//abilityItem[not(@name = preceding::abilityItem/@name)]'> + <li> + <xsl:value-of select='@name'/> - <xsl:value-of select='@description'/> + </li> + </xsl:for-each> + </ul> + </div> + </body> + </html> + </xsl:template> +</xsl:stylesheet> \ No newline at end of file