public static DesignStats StatsOf(Design design, StaticsDB statics) { var shipVars = DesignPoweredVars(design.Hull, design.Reactor, design.MissionEquipment, design.SpecialEquipment, statics); var hullVars = new Var(AComponentType.LevelKey, design.Hull.Level).Get; var armorVars = new Var(AComponentType.LevelKey, design.Armor.Level).Get; var thrusterVars = new Var(AComponentType.LevelKey, design.Thrusters.Level).Get; var sensorVars = new Var(AComponentType.LevelKey, design.Sensors.Level).Get; shipVars.And("armorFactor", design.Armor.TypeInfo.ArmorFactor.Evaluate(armorVars)). And("baseEvasion", design.Thrusters.TypeInfo.Evasion.Evaluate(thrusterVars)). And("thrust", design.Thrusters.TypeInfo.Speed.Evaluate(thrusterVars)). And("sensor", design.Sensors.TypeInfo.Detection.Evaluate(sensorVars)); var driveSize = statics.ShipFormulas.IsDriveSize.Evaluate(shipVars.Get); double galaxySpeed = 0; if (design.IsDrive != null) { shipVars[AComponentType.LevelKey] = design.IsDrive.Level; shipVars[IsDriveType.SizeKey] = driveSize; galaxySpeed = design.IsDrive.TypeInfo.Speed.Evaluate(shipVars.Get); } var buildings = new Dictionary <string, double>(); foreach (var colonyBuilding in statics.ShipFormulas.ColonizerBuildings) { double amount = colonyBuilding.Value.Evaluate(shipVars.Get); if (amount > 0) { buildings.Add(colonyBuilding.Key, amount); } } shipVars[AComponentType.LevelKey] = design.Armor.Level; double baseArmorReduction = design.Armor.TypeInfo.Absorption.Evaluate(shipVars.Get); shipVars[AComponentType.LevelKey] = design.Hull.Level; double hullArFactor = design.Hull.TypeInfo.ArmorAbsorption.Evaluate(shipVars.Get); double shieldCloaking = 0; double shieldJamming = 0; double shieldHp = 0; double shieldReduction = 0; double shieldRegeneration = 0; double shieldThickness = 0; double shieldPower = 0; var shieldSize = statics.ShipFormulas.ShieldSize.Evaluate(shipVars.Get); if (design.Shield != null) { shipVars[AComponentType.LevelKey] = design.Shield.Level; shipVars[ShieldType.SizeKey] = shieldSize; var hullShieldHp = design.Hull.TypeInfo.ShieldBase.Evaluate(hullVars); shieldCloaking = design.Shield.TypeInfo.Cloaking.Evaluate(shipVars.Get) * hullShieldHp; shieldJamming = design.Shield.TypeInfo.Jamming.Evaluate(shipVars.Get) * hullShieldHp; shieldHp = design.Shield.TypeInfo.HpFactor.Evaluate(shipVars.Get) * hullShieldHp; shieldReduction = design.Shield.TypeInfo.Reduction.Evaluate(shipVars.Get); shieldRegeneration = design.Shield.TypeInfo.RegenerationFactor.Evaluate(shipVars.Get) * hullShieldHp; shieldThickness = design.Shield.TypeInfo.Thickness.Evaluate(shipVars.Get); shieldPower = design.Shield.TypeInfo.PowerUsage.Evaluate(shipVars.Get); } shipVars.And("shieldCloak", shieldCloaking); shipVars.And("shieldJamming", shieldJamming); var abilities = new List <AbilityStats>(design.MissionEquipment.SelectMany( equip => equip.TypeInfo.Abilities.Select( x => AbilityStatsFactory.Create(x, equip.TypeInfo, equip.Level, equip.Quantity, statics) ) )); shipVars[HullType.SizeKey] = design.Hull.TypeInfo.SpaceFree.Evaluate(hullVars); return(new DesignStats( calculateCost(design, shipVars.Get, statics.ShipFormulas), design.Hull.TypeInfo.Size, driveSize, statics.ShipFormulas.ReactorSize.Evaluate(shipVars.Get), shieldSize, galaxySpeed, shipVars[ReactorType.TotalPowerKey], statics.ShipFormulas.ScanRange.Evaluate(shipVars.Get), statics.ShipFormulas.CombatSpeed.Evaluate(shipVars.Get), shipVars[ReactorType.TotalPowerKey] - shieldPower, abilities, statics.ShipFormulas.CarryCapacity.Evaluate(shipVars.Get), statics.ShipFormulas.TowCapacity.Evaluate(shipVars.Get), statics.ShipFormulas.ColonizerPopulation.Evaluate(shipVars.Get), buildings, statics.ShipFormulas.HitPoints.Evaluate(shipVars.Get), shieldHp, statics.ShipFormulas.Evasion.Evaluate(shipVars.Get), baseArmorReduction * hullArFactor, shieldReduction, shieldRegeneration, shieldThickness, statics.ShipFormulas.Detection.Evaluate(shipVars.Get), statics.ShipFormulas.Cloaking.Evaluate(shipVars.Get), statics.ShipFormulas.Jamming.Evaluate(shipVars.Get) )); }