static void evaluateWeaponAttackOnBuilding(float expectedDamage, Weapon w, ref DamageExpectationRecord damageExpectationRecord, Vector3 attackerPosition, Building targetBuilding, Vector3 targetPosition, Quaternion targetRotation) { float existingArmor = targetBuilding.CurrentArmor; float armorThatWillBeRemoved = Mathf.Min(existingArmor, expectedDamage); float damageRemaining = expectedDamage - existingArmor; damageExpectationRecord.AddArmorDamage(armorThatWillBeRemoved, ArmorLocation.None); if (damageRemaining > 0) { // some goes in to the structure float currentStructure = targetBuilding.CurrentStructure; float structureDamage = Mathf.Min(damageRemaining, currentStructure); damageExpectationRecord.AddStructureDamage(structureDamage, ChassisLocations.None); } }
public void flattenInto(DamageExpectationRecord target, DamageExpectationRecord source, float probability) { foreach (KeyValuePair <ComponentLocator, float> kvp in source.componentDamageDictionary) { ComponentLocator key = kvp.Key; float dmg = kvp.Value; target.AddComponentDamage(dmg * probability, key); } foreach (ChassisLocations loc in source.chassisLocationDictionary.Keys) { float dmg = source.chassisLocationDictionary[loc]; target.AddStructureDamage(dmg * probability, loc); } foreach (ArmorLocation loc in source.armorLocationDictionary.Keys) { float dmg = source.armorLocationDictionary[loc]; target.AddArmorDamage(dmg * probability, loc); } foreach (VehicleChassisLocations loc in source.vehicleChassisLocationDictionary.Keys) { float dmg = source.vehicleChassisLocationDictionary[loc]; target.AddVehicleStructureDamage(dmg * probability, loc); } foreach (VehicleChassisLocations loc in source.vehicleArmorLocationDictionary.Keys) { float dmg = source.vehicleArmorLocationDictionary[loc]; target.AddVehicleArmorDamage(dmg * probability, loc); } target.AddPilotDamage(pilotDamage * probability); target.lethalProbability += lethalProbability * probability; for (int childIndex = 0; childIndex < source.children.Count; ++childIndex) { ChildWithProbability c = source.children[childIndex]; flattenInto(target, c.DamageExpectationRecord, c.Probability); } }
static void evaluateWeaponAttackOnMech(float expectedDamage, Weapon w, ref DamageExpectationRecord damageExpectationRecord, Vector3 attackerPosition, Mech targetMech, Vector3 targetPosition, Quaternion targetRotation) { // use hit table to figure out where this will go Dictionary <ArmorLocation, float> locations = GetLocationDictionary(attackerPosition, targetMech, targetPosition, targetRotation); foreach (KeyValuePair <ArmorLocation, float> locKVP in locations) { ArmorLocation loc = locKVP.Key; float probability = locKVP.Value; DamageExpectationRecord locRecord = new DamageExpectationRecord(); damageExpectationRecord.AddChildRecord(probability, locRecord); float existingArmor = targetMech.ArmorForLocation((int)loc); float armorThatWillBeRemoved = Mathf.Min(existingArmor, expectedDamage); float damageRemaining = expectedDamage - existingArmor; locRecord.AddArmorDamage(armorThatWillBeRemoved, loc); ChassisLocations sLoc = MechStructureRules.GetChassisLocationFromArmorLocation((ArmorLocation)loc); // there's a chance this hit will be a critical hit if (!targetMech.IsLocationDestroyed(sLoc)) { float critChance = targetMech.Combat.CritChance.GetCritChance(targetMech, sLoc, w); if (critChance > 0) { DamageExpectationRecord critRecord = new DamageExpectationRecord(); locRecord.AddChildRecord(critChance, critRecord); // iterate over components, apply one point of damage to each location. Dictionary <ComponentLocator, float> componentDict = getComponentDictionary(targetMech, sLoc); float probOfHittingAmmo = 0.0f; foreach (KeyValuePair <ComponentLocator, float> componentKVP in componentDict) { ComponentLocator compLoc = componentKVP.Key; MechComponent component = compLoc.GetComponent(); float componentProbability = componentKVP.Value; DamageExpectationRecord componentRecord = new DamageExpectationRecord(); critRecord.AddChildRecord(componentProbability, componentRecord); componentRecord.AddComponentDamage(1.0f, compLoc); // if this component is ammo, there's a chance we could lose this location and all child locations if (component.componentType == ComponentType.AmmunitionBox) { AmmunitionBox abComponent = component as AmmunitionBox; int remainingAmmo = abComponent.CurrentAmmo; int capacity = abComponent.ammunitionBoxDef.Capacity; float percentage = ((float)remainingAmmo) / ((float)capacity); if (percentage > 0.5f) { probOfHittingAmmo += componentProbability; } } } if (probOfHittingAmmo > 0.0f) { DamageExpectationRecord ammoBlownRecord = new DamageExpectationRecord(); locRecord.AddChildRecord(probOfHittingAmmo, ammoBlownRecord); foreach (KeyValuePair <ComponentLocator, float> componentKVP in componentDict) { ComponentLocator compLoc = componentKVP.Key; ammoBlownRecord.AddComponentDamage(2.0f, compLoc); } } } } if (damageRemaining > 0) { // some goes in to the structure float currentStructure = targetMech.GetCurrentStructure(sLoc); float structureDamage = Mathf.Min(damageRemaining, currentStructure); float damageAfterStructure = damageRemaining - structureDamage; locRecord.AddStructureDamage(structureDamage, sLoc); if (damageAfterStructure > 0) { // some hits a component Dictionary <ComponentLocator, float> componentDict = getComponentDictionary(targetMech, sLoc); float probOfHittingAmmo = 0.0f; foreach (KeyValuePair <ComponentLocator, float> componentKVP in componentDict) { ComponentLocator compLoc = componentKVP.Key; MechComponent component = compLoc.GetComponent(); float componentProbability = componentKVP.Value; DamageExpectationRecord componentRecord = new DamageExpectationRecord(); locRecord.AddChildRecord(componentProbability, componentRecord); componentRecord.AddComponentDamage(1.0f, compLoc); // if this component is ammo, there's a chance we could lose this location and all child locations if (component.componentType == ComponentType.AmmunitionBox) { AmmunitionBox abComponent = component as AmmunitionBox; int remainingAmmo = abComponent.CurrentAmmo; int capacity = abComponent.ammunitionBoxDef.Capacity; float percentage = ((float)remainingAmmo) / ((float)capacity); if (percentage > 0.5f) { probOfHittingAmmo += componentProbability; } } } if (probOfHittingAmmo > 0) { DamageExpectationRecord ammoBlownRecord = new DamageExpectationRecord(); locRecord.AddChildRecord(probOfHittingAmmo, ammoBlownRecord); foreach (KeyValuePair <ComponentLocator, float> componentKVP in componentDict) { ComponentLocator compLoc = componentKVP.Key; ammoBlownRecord.AddComponentDamage(2.0f, compLoc); } } } } } }