view api/Objects/Army.cs @ 6:150a5669cd7b

Re #9 - more granular loading * Remove SystemStatsSet class so that other classes don't know the internals of how GameSystem stores its stats (cleaner code principle) * Make XML loader each stats set and add to the game system * Add methods to GameSystem to remove use of SystemStatsSet and hide internal handling * Add methods to add SystemStats to GameSystem
author IBBoard <dev@ibboard.co.uk>
date Sun, 04 Jan 2009 12:13:59 +0000
parents 520818033bb6
children 613bc5eaac59
line wrap: on
line source

using System;
using System.IO;
using System.Collections;
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
	{
		//private GameSystem system;
		private Race armyRace;
		private int maxPoints;
		private double pointsTotal;
		private 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/*, AbstractNativeWarFoundryFactory factory*/) : this(race, armyName, maxArmyPoints, null/*, factory*/)
		{
		}

		public Army(Race race, string armyName, int maxArmyPoints, ZipFile file/*, AbstractNativeWarFoundryFactory factory*/) : base(armyName/*, factory*/)
		{
			armyRace = race;
			Name = armyName;
			maxPoints = maxArmyPoints;
			PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler);
		}
		
		public ArmyCategory GetCategory(Category cat)
		{
			foreach (ArmyCategory armyCat in Categories)
			{
				if (armyCat.Category.Equals(cat))
				{
					return armyCat;
				}
			}

			return null;
		}

		public ArmyCategory[] Categories
		{
			get 
			{
				if (categories==null)
				{
					Category[] raceCats = Race.Categories;
					ArmyCategory cat;
					int raceCatCount = raceCats.Length;
					categories = new ArmyCategory[raceCatCount];

					for (int i = 0; i < raceCatCount; i++)
					{
						cat = new ArmyCategory(this, raceCats[i]);
						categories[i] = cat;
						cat.PointsValueChanged+= PointsValueChangedMethod;
						cat.UnitAdded+=new ObjectAddDelegate(Army_UnitAdded);
						cat.UnitRemoved+=new ObjectRemoveDelegate(Army_UnitRemoved);
						cat.RequirementsFailed+=new FailedUnitRequirementDelegate(Army_FailedRequirement);
					}
				}

				return categories;
			}
		}

		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);
			}

			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);
			}
		}

		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 PointsTotal
		{
			get { return TotalPoints; }
		}

		public Unit[] GetUnits(Category cat)
		{
			return GetUnits(this.GetCategory(cat));
		}

		public Unit[] GetUnits(ArmyCategory cat)
		{
			return cat.GetUnits();
		}

		public Unit[] GetUnits()
		{
			ArrayList fullList = new ArrayList();

			foreach(ArmyCategory cat in Categories)
			{
				foreach(Unit unit in cat.GetUnits())
				{
					if (!fullList.Contains(unit))
					{
						fullList.Add(unit);
					}
				}
			}

			return (Unit[])fullList.ToArray(typeof(Unit));
		}

		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.PointsTotal;
				}

				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(object val)
		{
			OnUnitAdded((Unit)val);
		}

		private void Army_UnitRemoved(object val)
		{
			OnUnitRemoved((Unit)val);
		}

		private void Army_FailedRequirement(List<FailedUnitRequirement> failedRequirements)
		{
			if (FailedRequirement!=null)
			{
				FailedRequirement(failedRequirements);
			}
		}
	}
}