public void CalculateStats() { //TODO: Step 1A ProtoMech Adjustments double dSize = 0; List <MovementMode> lstMovementModes = new List <MovementMode>(); Dictionary <string, int> dicTypes = new Dictionary <string, int>(); double dTotalGroundMovement = 0; double dLowestInfantryOrBattleArmorMP = double.MaxValue; double dJumpMovement = 0; double dSlowestAerospace = double.MaxValue; double dArmorValue = 0; double dShortRangeDamage = 0; double dMediumRangeDamage = 0; double dLongRangeDamage = 0; double dExtremeRangeDamage = 0; double dIndirectDamage = 0; double dFlakDamage = 0; double dArtilleryDamage = 0; double dBombDamage = 0; List <string> CandidateMovementModes = new List <string>(); int iRestrictionRank = int.MaxValue; foreach (Element curElement in Elements) { dSize += (double)curElement.Size; //Step 1C, IO327 //Step 1E, IO327 dArmorValue += (double)curElement.CurrentArmor + (double)curElement.CurrentStructure; if (curElement.CurrentStructure >= 3 || curElement.HasSpecialAbility("AMS", true) || curElement.HasSpecialAbility("CASE", true)) { dArmorValue += 0.5; } if (curElement.HasSpecialAbility("ENE", true) || curElement.HasSpecialAbility("CASEII", true) || curElement.HasSpecialAbility("CR", true) || curElement.HasSpecialAbility("RAMS", true)) { dArmorValue += 1; } //Used to determine Unit Type (Step 1B, IO326) if (!dicTypes.ContainsKey(curElement.UnitType.Code)) { dicTypes.Add(curElement.UnitType.Code, 0); } dicTypes[curElement.UnitType.Code]++; //Step 1D, IO327 foreach (MovementMode curMode in curElement.MovementModes) { bool bModeAlreadyInList = false; //Used to determine Jump value if (curMode.Code.Equals("j", StringComparison.CurrentCultureIgnoreCase)) { dJumpMovement += curMode.Points; } if (IsGroundMovement(curMode.Code)) { dTotalGroundMovement += curMode.Points; } if (IsAerospaceMovement(curMode.Code)) { if (dSlowestAerospace > curMode.Points) { dSlowestAerospace = curMode.Points; } } int iRestriction = RestrictionRank(curMode.Code, curElement.UnitType.Code); if (iRestriction < iRestrictionRank) { iRestrictionRank = iRestriction; CandidateMovementModes = new List <string>(); CandidateMovementModes.Add(curMode.Code); } foreach (MovementMode lstMode in lstMovementModes) { //If the element MovementMode code equals the unit MovementMode //that we're currently examining... if (lstMode.Code == curMode.Code) { //Note that this mode is already in the list (so we don't need to add it.) bModeAlreadyInList = true; //If this element has a lower movement point value than the unit as a whole, //return the unit's movement points to match. if (lstMode.Points > curMode.Points) { lstMode.Points = curMode.Points; } } } //If we didn't already see this MovementMode Code in the unit MovementMode list... if (!bModeAlreadyInList) { //Add a copy of this unit's MovementMode to the Unit's MovementMode List. lstMovementModes.Add(curMode.Clone() as MovementMode); } } //Step 1F foreach (Common.Element.Arc arc in curElement.Arcs) { dShortRangeDamage += arc.Short; dMediumRangeDamage += arc.Medium; dLongRangeDamage += arc.Long; dExtremeRangeDamage += arc.Extreme; } } //Note that we may have Movement Modes in the list at this point that only some of the //unit have. We need that every Element can move at least the unit's MovementModes. MovementModes = new List <MovementMode>(); //For each movement mode we think the unit has... foreach (MovementMode UnitMovementMode in lstMovementModes) { bool bMovementModeIsValid = true; //Cycle through each Element in the Unit. foreach (Element currentElement in Elements) { bool bElementMeetsMovementRequirement = false; foreach (MovementMode ElementMovementMode in currentElement.MovementModes) { //If the Element has the appropriate Movement Mode and at least as many points as the Unit, //Mark the Element as meeting the Movement Requirement. if (UnitMovementMode.Code == ElementMovementMode.Code && ElementMovementMode.Points >= UnitMovementMode.Points) { bElementMeetsMovementRequirement = true; } } //If this unit didn't meet the Requirement for the UnitMovementMode, //mark this MovementMode as invalid. if (!bElementMeetsMovementRequirement) { bMovementModeIsValid = false; } } //If Every element of the unit can move at least this many points in this //movement mode, add the MovementMode to the Unit. if (bMovementModeIsValid) { MovementModes.Add(UnitMovementMode.Clone() as MovementMode); } } int iAerospace = 0; int iGround = 0; //Find the Movment Type //Step 1D IO327 List <string> lstMovementTypes = new List <string>(); foreach (string sCode in dicTypes.Keys) { SBFType sbfType = SBFType.GetCanonicalTypeByCode(sCode); if (sbfType.AeroType) { iAerospace += dicTypes[sCode]; } else { iGround += dicTypes[sCode]; } string sInsertValue = sCode; if (sCode == "") { sInsertValue = "BM"; } lstMovementTypes.Add(sInsertValue); } //Disallow units with both Aerospace //and Ground Components (Step 1B, IO328) if (iAerospace > 0 && iGround > 0) { throw new Exception("Unit cannot contain both Aerospace and Ground Elements"); } //Compute MP Value (Step 1D, IO329) int MP = 0; if (dTotalGroundMovement > 0) { double dMP = Math.Round(dTotalGroundMovement / (double)Elements.Count); dMP = Math.Min(dMP, dLowestInfantryOrBattleArmorMP); MP = (int)dMP; } else { MP = (int)dSlowestAerospace; } MovementModes.Add(new MovementMode(MP, GetPreferredMovementType(lstMovementTypes.ToArray()))); //Step 1D, IO329 //TODO: Transport Movement UnitType = SBFType.GetAggregateUnitType(dicTypes); //Step 1B, IO326 Jump = (int)Math.Round((dJumpMovement / (double)Elements.Count) / 2D, 0); //Step 1D, IO329 TMM = TargetMovementModifier(MP, UnitType.Code); //Step 1D, IO329 Armor = (int)Math.Round(dArmorValue / 3D); Size = (int)Math.Round(dSize / (double)Elements.Count); //Step 1C, IO327 }
public void CalculatedValues() { //Calculate Values for a Formation (IO329) double dSize = 0; int iPV = 0; List <MovementMode> lstMovementModes = new List <MovementMode>(); Dictionary <string, int> dicTypes = new Dictionary <string, int>(); foreach (Unit curElement in mUnits) { dSize += (double)curElement.Size; iPV += curElement.PointValue; foreach (MovementMode curMode in curElement.MovementModes) { bool bModeAlreadyInList = false; foreach (MovementMode lstMode in lstMovementModes) { //If the element MovementMode code equals the unit MovementMode //that we're currently examining... if (lstMode.Code == curMode.Code) { //Note that this mode is already in the list (so we don't need to add it.) bModeAlreadyInList = true; //If this element has a lower movement point value than the unit as a whole, //return the unit's movement points to match. if (lstMode.Points > curMode.Points) { lstMode.Points = curMode.Points; } } } //If we didn't already see this MovementMode Code in the unit MovementMode list... if (!bModeAlreadyInList) { //Add a copy of this unit's MovementMode to the Unit's MovementMode List. lstMovementModes.Add(curMode.Clone() as MovementMode); } } } //Note that we may have Movement Modes in the list at this point that only some of the //unit have. We need that every Element can move at least the unit's MovementModes. MovementModes = new List <MovementMode>(); //For each movement mode we think the unit has... foreach (MovementMode UnitMovementMode in lstMovementModes) { bool bMovementModeIsValid = true; //Cycle through each Element in the Unit. foreach (Unit currentElement in mUnits) { bool bElementMeetsMovementRequirement = false; foreach (MovementMode ElementMovementMode in currentElement.MovementModes) { //If the Element has the appropriate Movement Mode and at least as many points as the Unit, //Mark the Element as meeting the Movement Requirement. if (UnitMovementMode.Code == ElementMovementMode.Code && ElementMovementMode.Points >= UnitMovementMode.Points) { bElementMeetsMovementRequirement = true; } } //If this unit didn't meet the Requirement for the UnitMovementMode, //mark this MovementMode as invalid. if (!bElementMeetsMovementRequirement) { bMovementModeIsValid = false; } } //If Every element of the unit can move at least this many points in this //movement mode, add the MovementMode to the Unit. if (bMovementModeIsValid) { MovementModes.Add(UnitMovementMode.Clone() as MovementMode); } } Type = SBFType.GetAggregateUnitType(dicTypes); Size = (int)Math.Round(dSize / (double)mUnits.Count); PointValue = iPV; }