Mercurial > repos > IBDev-IBBoard.WarFoundry.API
view api/Objects/Unit.cs @ 65:aa2d05a9c635
Re #61 - Complete structure of WarFoundry API objects
* Add parent links to Units (inverse of r97)
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Thu, 09 Apr 2009 18:27:51 +0000 |
parents | 2094bd0ba652 |
children | aa66dd18cdae |
line wrap: on
line source
// This file (Unit.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 under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license. using System; using System.Collections.Generic; using System.Text; using System.Xml; using IBBoard.Lang; namespace IBBoard.WarFoundry.API.Objects { /// <summary> /// Summary description for UnitInstance. /// </summary> public class Unit : WarFoundryObject { private UnitType type; private int size; private Army army; private Unit parentUnit; private double points; private ArmyCategory cat; private Dictionary<EquipmentItem, double> equipment = new Dictionary<EquipmentItem, double>(); private List<Unit> containedUnits = new List<Unit>(); public event DoubleValChangedDelegate PointsValueChanged; public event IntValChangedDelegate UnitSizeChanged; public event DoubleValChangedDelegate UnitEquipmentAmountChanged; public Unit(UnitType unitType, Army parentArmy) : this(unitType, unitType.MinSize, parentArmy){} public Unit(UnitType unitType, int startSize, Army parentArmy) { Army = parentArmy; type = unitType; Size = startSize; SetInitialEquipment(); CalcCost(); } 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)) { equipment[unitEquip.EquipmentItem] = unitEquip.MinNumber; } } } } private void CalcCost() { String oldName = HasDefaultName() ? Name : null; double oldpoints = points; points = type.CostPerTrooper * AdditionalTroopers + type.BaseUnitCost; foreach (EquipmentItem equipItem in equipment.Keys) { double count = equipment[equipItem]; UnitEquipmentItem unitEquipItem = UnitType.GetEquipmentItem(equipItem); if (unitEquipItem.IsRatioLimit) { if (unitEquipItem.RoundNumberUp) { points+= Math.Ceiling(size * count) * equipItem.Cost; } else { points+= Math.Floor(size * count) * equipItem.Cost; } } else { if (count == WarFoundryCore.INFINITY) { points+= size * equipItem.Cost; } else { points+= count * equipItem.Cost; } } } if (oldpoints!=points) { OnPointsValueChanged(oldpoints, points); } if (oldName!=null) { OnNameChanged(oldName, Name); } } 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); CalcCost(); OnUnitSizeChanged(oldValue, size); } } } public UnitType UnitType { get { return type; } } public Army Army { get { return army; } set { army = value; if (army == null) { Category = null; } } } public Race Race { get { return UnitType.Race; } } public ArmyCategory Category { get { if (cat==null) { if (Army!=null) { return Army.GetCategory(UnitType.MainCategory); } else { return null; } } else { return cat; } } set { cat = value; } } public double PointsValue { 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[] GetAllowedOptionalEquipment() { List<UnitEquipmentItem> list = new List<UnitEquipmentItem>(); foreach (UnitEquipmentItem item in UnitType.GetEquipmentItems()) { if (!item.IsRequired) { list.Add(item); } } return list.ToArray(); } public EquipmentItem[] GetEquipment() { return DictionaryUtils.ToKeyArray(equipment); } private UnitEquipmentItem[] GetUnitEquipmentItemsForEquipment() { EquipmentItem[] items = GetEquipment(); int arrLength = items.Length; UnitEquipmentItem[] unitItems = new UnitEquipmentItem[arrLength]; for (int i = 0; i < arrLength; i++) { UnitType.GetEquipmentItem(items[i]); } return unitItems; } public EquipmentItem[] GetRequiredEquipment() { List<EquipmentItem> list = new List<EquipmentItem>(); foreach(UnitEquipmentItem item in GetUnitEquipmentItemsForEquipment()) { if (item.IsRequired) { list.Add(item.EquipmentItem); } } return list.ToArray(); } public double GetEquipmentAmount(UnitEquipmentItem item) { return GetEquipmentAmount(item.EquipmentItem); } public double GetEquipmentAmount(EquipmentItem item) { if (equipment.ContainsKey(item)) { return equipment[item]; } else { return 0; } } public double GetEquipmentAmount(string equipID) { return GetEquipmentAmount(UnitType.GetEquipmentItem(equipID)); } public void SetEquipmentAmount(UnitEquipmentItem equip, int amount) { SetEquipmentAmount(equip.EquipmentItem, amount); } public void SetEquipmentAmount(EquipmentItem equip, int amount) { if (UnitType.IsRatioLimitedEquipmentItem(equip)) { throw new InvalidOperationException("Equipment with ID "+equip.ID+" for unit of type "+UnitType.ID+" has a ratio limit, not an absolute limit"); } if (amount <1 && amount != WarFoundryCore.INFINITY) { amount = 0; } SetEquipmentAmount(equip, amount); } public void SetEquipmentRatio(UnitEquipmentItem equip, double ratio) { SetEquipmentRatio(equip.EquipmentItem, ratio); } public void SetEquipmentRatio(EquipmentItem equip, double ratio) { if (UnitType.IsAbsoluteLimitedEquipmentItem(equip)) { throw new InvalidOperationException("Equipment with ID "+equip.ID+" for unit of type "+UnitType.ID+" has an absolute limit, not a ratio limit"); } if (ratio > 1) { ratio = 1; } else if (ratio < 0) { ratio = 0; } SetEquipmentAmount(equip, ratio); } private void SetEquipmentAmount(EquipmentItem equip, double amount) { double oldAmount = 0; if (equipment.ContainsKey(equip)) { oldAmount = equipment[equip]; } if (amount!=oldAmount) { if (amount != 0) { equipment[equip] = amount; } else { equipment.Remove(equip); } OnUnitEquipmentAmountChanged(equip, oldAmount, amount); CalcCost(); } } public bool CanEquipWithItem(UnitEquipmentItem item) { string mutex = item.MutexGroup; if (mutex == "") { return true; } foreach (UnitEquipmentItem unitItem in GetUnitEquipmentItemsForEquipment()) { if (unitItem.MutexGroup == mutex) { return false; } } return true; } 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(EquipmentItem equip, double oldValue, double newValue) { if (UnitEquipmentAmountChanged!=null) { UnitEquipmentAmountChanged(equip, oldValue, newValue); } } public Stats UnitStats { get { return UnitType.UnitStats; } } } }