public static void fillWeaponPredictRecord(ref DamagePredictRecord record, AbstractActor unit, ICombatant target, Weapon weapon, ref List <int> hitLocations, ref float AverageArmor) { CustomAmmoCategoriesLog.Log.LogWrite("fillWeaponPredictRecord " + unit.DisplayName + " target " + target.DisplayName + " weapon " + weapon.defId + "\n"); CustomAmmoCategories.applyWeaponAmmoMode(weapon, record.Id.modeId, record.Id.ammoId); AbstractActor targetActor = target as AbstractActor; if (hitLocations == null) { hitLocations = target.GetPossibleHitLocations(unit); foreach (int hitLocation in hitLocations) { CustomAmmoCategoriesLog.Log.LogWrite("Hit Location " + hitLocation + "\n"); } } if (float.IsNaN(AverageArmor)) { AverageArmor = CustomAmmoCategories.getTargetAvarageArmor(hitLocations, target); } float toHit = 0; if (weapon.WillFireAtTargetFromPosition(target, unit.CurrentPosition) == true) { toHit = weapon.GetToHitFromPosition(target, 1, unit.CurrentPosition, target.CurrentPosition, true, (targetActor != null) ? targetActor.IsEvasive : false, false); } if (toHit < Epsilon) { record.HeatDamageCoeff = 0f; record.NormDamageCoeff = 0f; record.PredictHeatDamage = 0f; } ; float coolDownCoeff = 1.0f / (1.0f + CustomAmmoCategories.getWeaponCooldown(weapon)); float jammCoeff = 1.0f - CustomAmmoCategories.getWeaponFlatJammingChance(weapon); float damageJammCoeff = CustomAmmoCategories.getWeaponDamageOnJamming(weapon) ? 0.5f : 1.0f; float damageShotsCount = (float)weapon.ShotsWhenFired; float damagePerShot = weapon.DamagePerShot; float heatPerShot = weapon.HeatDamagePerShot; if (weapon.componentDef.ComponentTags.Contains("wr-clustered_shots") || (CustomAmmoCategories.getWeaponDisabledClustering(weapon) == false)) { damageShotsCount *= (float)weapon.ProjectilesPerShot; } float piercedLocationsCount = (float)CustomAmmoCategories.getWeaponPierceLocations(hitLocations, target, damagePerShot); float hitLocationsCount = (hitLocations.Count > 0) ? (float)hitLocations.Count : 1.0f; float clusterCoeff = 1.0f + ((piercedLocationsCount / hitLocationsCount) * damageShotsCount) * CustomAmmoCategories.Settings.ClusterAIMult; float pierceCoeff = 1.0f; if (AverageArmor > damagePerShot) { pierceCoeff += (damagePerShot / AverageArmor) * CustomAmmoCategories.Settings.PenetrateAIMult; } record.NormDamageCoeff = damagePerShot * damageShotsCount * toHit * coolDownCoeff * jammCoeff * damageJammCoeff * clusterCoeff * pierceCoeff; record.HeatDamageCoeff = heatPerShot * damageShotsCount * toHit * jammCoeff * damageJammCoeff; record.PredictHeatDamage = heatPerShot * damageShotsCount * toHit; CustomAmmoCategoriesLog.Log.LogWrite(" toHit = " + toHit + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" coolDownCoeff = " + coolDownCoeff + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" jammCoeff = " + jammCoeff + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" damageJammCoeff = " + damageJammCoeff + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" damageShotsCount = " + damageShotsCount + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" damagePerShot = " + damagePerShot + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" heatPerShot = " + heatPerShot + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" piercedLocationsCount = " + piercedLocationsCount + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" hitLocationsCount = " + hitLocationsCount + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" AverageArmor = " + AverageArmor + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" clusterCoeff = " + clusterCoeff + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" pierceCoeff = " + pierceCoeff + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" NormDamageCoeff = " + record.NormDamageCoeff + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" HeatDamageCoeff = " + record.HeatDamageCoeff + "\n"); }
public static int DecrementAmmo(Weapon instance, int stackItemUID, int StreakHitCount) { int shotsWhenFired = instance.ShotsWhenFired; if (StreakHitCount != 0) { if (instance.weaponDef.ComponentTags.Contains("wr-clustered_shots") || (CustomAmmoCategories.getWeaponDisabledClustering(instance) == false)) { shotsWhenFired = StreakHitCount / instance.ProjectilesPerShot; } else { shotsWhenFired = StreakHitCount; } } bool streakEffect = CustomAmmoCategories.getExtWeaponDef(instance.weaponDef.Description.Id).StreakEffect; if ((streakEffect == false) && (StreakHitCount == 0)) { StreakHitCount = shotsWhenFired; } CustomAmmoCategoriesLog.Log.LogWrite("Weapon.DecrementAmmo " + instance.UIName + " real fire count:" + StreakHitCount + "\n"); int result = 0; if ((CustomAmmoCategories.getWeaponCustomAmmoCategory(instance).Index == CustomAmmoCategories.NotSetCustomAmmoCategoty.Index) || (instance.parent != null && instance.parent is Turret)) { if (instance.weaponDef.ComponentTags.Contains("wr-clustered_shots") || CustomAmmoCategories.getWeaponDisabledClustering(instance)) { result = shotsWhenFired; } else { result = shotsWhenFired * instance.ProjectilesPerShot; } CustomAmmoCategoriesLog.Log.LogWrite(" weapon has no ammo (energy or turret) " + instance.UIName + "\n"); return(result); } int modValue; if (instance.InternalAmmo >= shotsWhenFired) { if (StreakHitCount != 0) { instance.StatCollection.ModifyStat <int>(instance.uid, stackItemUID, "InternalAmmo", StatCollection.StatOperation.Int_Subtract, shotsWhenFired, -1, true); } modValue = 0; } else { modValue = shotsWhenFired - instance.InternalAmmo; if (StreakHitCount != 0) { instance.StatCollection.ModifyStat <int>(instance.uid, stackItemUID, "InternalAmmo", StatCollection.StatOperation.Set, 0, -1, true); } } string CurrentAmmoId = ""; if (CustomAmmoCategories.checkExistance(instance.StatCollection, CustomAmmoCategories.AmmoIdStatName) == true) { CurrentAmmoId = instance.StatCollection.GetStatistic(CustomAmmoCategories.AmmoIdStatName).Value <string>(); } else { if (instance.ammoBoxes.Count > 0) { CurrentAmmoId = instance.ammoBoxes[0].ammoDef.Description.Id; CustomAmmoCategoriesLog.Log.LogWrite($"WARNING! strange behavior " + instance.UIName + " has no data in statistics. fallback to default ammo " + CurrentAmmoId + "\n"); } else { CustomAmmoCategoriesLog.Log.LogWrite($"WARNING! strange behavior " + instance.UIName + " not energy, parent no turret but no ammo boxes\n"); if (instance.weaponDef.ComponentTags.Contains("wr-clustered_shots") || CustomAmmoCategories.getWeaponDisabledClustering(instance)) { result = shotsWhenFired; } else { result = shotsWhenFired * instance.ProjectilesPerShot; } return(result); } } //ExtAmmunitionDef extAmmo = CustomAmmoCategories.findExtAmmo(CurrentAmmoId); //ExtWeaponDef extWeapon = CustomAmmoCategories.getExtWeaponDef(__instance.weaponDef.Description.Id); if (modValue == 0) { if (instance.weaponDef.ComponentTags.Contains("wr-clustered_shots") || CustomAmmoCategories.getWeaponDisabledClustering(instance)) { result = shotsWhenFired; } else { result = shotsWhenFired * instance.ProjectilesPerShot; } CustomAmmoCategoriesLog.Log.LogWrite(" fire internal ammo. projectiles:" + result + "\n"); return(result); } for (int index = 0; index < instance.ammoBoxes.Count; ++index) { AmmunitionBox ammoBox = instance.ammoBoxes[index]; if (ammoBox.IsFunctional == false) { continue; } if (ammoBox.CurrentAmmo <= 0) { continue; } if ((string.IsNullOrEmpty(CurrentAmmoId) == false) && (ammoBox.ammoDef.Description.Id != CurrentAmmoId)) { continue; } if (ammoBox.CurrentAmmo >= modValue) { if (StreakHitCount != 0) { ammoBox.StatCollection.ModifyStat <int>(instance.uid, stackItemUID, "CurrentAmmo", StatCollection.StatOperation.Int_Subtract, modValue, -1, true); } modValue = 0; } else { modValue -= ammoBox.CurrentAmmo; if (StreakHitCount != 0) { ammoBox.StatCollection.ModifyStat <int>(instance.uid, stackItemUID, "CurrentAmmo", StatCollection.StatOperation.Set, 0, -1, true); } } } if (instance.weaponDef.ComponentTags.Contains("wr-clustered_shots") || CustomAmmoCategories.getWeaponDisabledClustering(instance)) { result = (instance.ShotsWhenFired - modValue); } else { result = (instance.ShotsWhenFired - modValue) * instance.ProjectilesPerShot; } CustomAmmoCategoriesLog.Log.LogWrite(" fire exteranl ammo. projectiles:" + result + "\n"); return(result); }