public static bool GenerateSalvage(List <UnitResult> enemyMechs, List <VehicleDef> enemyVehicles, List <UnitResult> lostUnits, bool logResults, Contract __instance, ref List <SalvageDef> ___finalPotentialSalvage) { if (!Control.Settings.OverrideSalvageGeneration) { return(true); } try { Control.LogDebug(DType.SalvageProccess, $"Start GenerateSalvage for {__instance.Name}"); ___finalPotentialSalvage = new List <SalvageDef>(); var Contract = new ContractHelper(__instance); Contract.SalvagedChassis = new List <SalvageDef>(); Contract.LostMechs = new List <MechDef>(); Contract.SalvageResults = new List <SalvageDef>(); var simgame = __instance.BattleTechGame.Simulation; if (simgame == null) { Control.LogError("No simgame - cancel salvage"); return(false); } var Constants = simgame.Constants; Control.LogDebug(DType.SalvageProccess, $"- Lost Units {__instance.Name}"); for (int i = 0; i < lostUnits.Count; i++) { var mech = lostUnits[i].mech; if (!IsDestroyed(mech)) { Control.LogDebug(DType.SalvageProccess, $"-- {mech.Name} not destroyed, skiping"); continue; } if (Control.Settings.OverrideRecoveryChance) { Control.LogDebug(DType.SalvageProccess, $"-- Recovery {mech.Name} CC method"); float chance = Constants.Salvage.DestroyedMechRecoveryChance; chance -= mech.IsLocationDamaged(ChassisLocations.Head) ? Control.Settings.HeadRecoveryPenaly : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? Control.Settings.TorsoRecoveryPenalty : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? Control.Settings.TorsoRecoveryPenalty : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? Control.Settings.TorsoRecoveryPenalty : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.RightArm) ? Control.Settings.LimbRecoveryPenalty : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? Control.Settings.LimbRecoveryPenalty : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? Control.Settings.LimbRecoveryPenalty : 0; chance -= mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? Control.Settings.LimbRecoveryPenalty : 0; chance += lostUnits[i].pilot.HasEjected ? Control.Settings.EjectRecoveryBonus : 0; float num = simgame.NetworkRandom.Float(0f, 1f); lostUnits[i].mechLost = chance < num; if (lostUnits[i].mechLost) { Control.LogDebug(DType.SalvageProccess, $"--- {chance:0.00} < {num:0.00} - roll failed, no recovery"); } else { Control.LogDebug(DType.SalvageProccess, $"--- {chance:0.00} >= {num:0.00} - roll success, recovery"); } } else { Control.LogDebug(DType.SalvageProccess, $"-- Recovery {mech.Name} vanila method"); float num = simgame.NetworkRandom.Float(0f, 1f); if (mech.IsLocationDestroyed(ChassisLocations.CenterTorso)) { Control.LogDebug(DType.SalvageProccess, $"--- CenterTorso Destroyed - no recovery"); lostUnits[i].mechLost = true; } else { lostUnits[i].mechLost = Constants.Salvage.DestroyedMechRecoveryChance < num; if (lostUnits[i].mechLost) { Control.LogDebug(DType.SalvageProccess, $"--- {Constants.Salvage.DestroyedMechRecoveryChance:0.00} < {num:0.00} - roll failed, no recovery"); } else { Control.LogDebug(DType.SalvageProccess, $"--- {Constants.Salvage.DestroyedMechRecoveryChance:0.00} >= {num:0.00} - roll success, recovery"); } } } if (lostUnits[i].mechLost) { if (Control.Settings.SalvageUnrecoveredMech) { AddMechToSalvage(mech, Contract, simgame, Constants, ___finalPotentialSalvage); } else { int old_diff = __instance.Override.finalDifficulty; float old_rare_u = Constants.Salvage.RareUpgradeChance; float old_rare_w = Constants.Salvage.RareWeaponChance; float old_vrare_i = Constants.Salvage.VeryRareUpgradeChance; float old_vrare_w = Constants.Salvage.VeryRareWeaponChance; Constants.Salvage.RareUpgradeChance = 0; Constants.Salvage.RareWeaponChance = 0; Constants.Salvage.VeryRareUpgradeChance = 0; Constants.Salvage.VeryRareWeaponChance = 0; __instance.Override.finalDifficulty = 0; AddMechToSalvage(mech, Contract, simgame, Constants, __instance.SalvageResults); Constants.Salvage.RareUpgradeChance = old_rare_u; Constants.Salvage.RareWeaponChance = old_rare_w; Constants.Salvage.VeryRareUpgradeChance = old_vrare_i; Constants.Salvage.VeryRareWeaponChance = old_vrare_w; __instance.Override.finalDifficulty = old_diff; } } } Control.LogDebug(DType.SalvageProccess, $"- Enemy Mechs {__instance.Name}"); foreach (var unit in enemyMechs) { AddMechToSalvage(unit.mech, Contract, simgame, Constants, ___finalPotentialSalvage); } Control.LogDebug(DType.SalvageProccess, $"- Enemy Vechicle {__instance.Name}"); foreach (var vechicle in enemyVehicles) { Control.LogDebug(DType.SalvageProccess, $"-- Salvaging {vechicle?.Chassis?.Description?.Name}"); foreach (var component in vechicle.Inventory.Where(item => item.DamageLevel != ComponentDamageLevel.Destroyed)) { Control.LogDebug(DType.SalvageProccess, $"--- Adding {component.ComponentDefID}"); Contract.AddMechComponentToSalvage(___finalPotentialSalvage, component.Def, ComponentDamageLevel.Functional, false, Constants, simgame.NetworkRandom, true); } } Contract.FilterPotentialSalvage(___finalPotentialSalvage); int num2 = __instance.SalvagePotential; float num3 = Constants.Salvage.VictorySalvageChance; float num4 = Constants.Salvage.VictorySalvageLostPerMechDestroyed; if (__instance.State == BattleTech.Contract.ContractState.Failed) { num3 = Constants.Salvage.DefeatSalvageChance; num4 = Constants.Salvage.DefeatSalvageLostPerMechDestroyed; } else if (__instance.State == BattleTech.Contract.ContractState.Retreated) { num3 = Constants.Salvage.RetreatSalvageChance; num4 = Constants.Salvage.RetreatSalvageLostPerMechDestroyed; } float num5 = num3; float num6 = (float)num2 * __instance.PercentageContractSalvage; if (num2 > 0) { num6 += (float)Constants.Finances.ContractFloorSalvageBonus; } num3 = Mathf.Max(0f, num5 - num4 * (float)lostUnits.Count); int num7 = Mathf.FloorToInt(num6 * num3); if (num2 > 0) { num2 += Constants.Finances.ContractFloorSalvageBonus; } Contract.FinalSalvageCount = num7; Contract.FinalPrioritySalvageCount = Math.Min(7, Mathf.FloorToInt((float)num7 * Constants.Salvage.PrioritySalvageModifier)); } catch (Exception e) { Control.LogError("Unhandled error in salvage", e); } return(false); }
private static void AddMechToSalvage(MechDef mech, ContractHelper contract, SimGameState simgame, SimGameConstants constants, List <SalvageDef> salvage) { Control.LogDebug(DType.SalvageProccess, $"-- Salvaging {mech.Name}"); int numparts = 0; if (Control.Settings.OverrideMechPartCalculation) { if (mech.IsLocationDestroyed(ChassisLocations.CenterTorso)) { numparts = Control.Settings.CenterTorsoDestroyedParts; } else { float total = Control.Settings.SalvageArmWeight * 2 + Control.Settings.SalvageHeadWeight + Control.Settings.SalvageLegWeight * 2 + Control.Settings.SalvageTorsoWeight * 2 + 1; float val = total; val -= mech.IsLocationDestroyed(ChassisLocations.Head) ? Control.Settings.SalvageHeadWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? Control.Settings.SalvageTorsoWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? Control.Settings.SalvageTorsoWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? Control.Settings.SalvageLegWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? Control.Settings.SalvageLegWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? Control.Settings.SalvageArmWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? Control.Settings.SalvageArmWeight : 0; numparts = (int)(constants.Story.DefaultMechPartMax * val / total + 0.5f); if (numparts <= 0) { numparts = 1; } if (numparts > constants.Story.DefaultMechPartMax) { numparts = constants.Story.DefaultMechPartMax; } } } else { numparts = 3; if (mech.IsLocationDestroyed(ChassisLocations.CenterTorso)) { numparts = 1; } else if (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) && mech.IsLocationDestroyed(ChassisLocations.RightLeg)) { numparts = 2; } } try { Control.LogDebug(DType.SalvageProccess, $"--- Adding {numparts} parts"); contract.CreateAndAddMechPart(constants, mech, numparts, salvage); } catch (Exception e) { Control.LogError("Error in adding parts", e); } try { if (Control.Settings.NoLootCTDestroyed && mech.IsLocationDestroyed(ChassisLocations.CenterTorso)) { Control.LogDebug(DType.SalvageProccess, $"--- CT Destroyed - no component loot"); } else { foreach (var component in mech.Inventory.Where(item => !mech.IsLocationDestroyed(item.MountedLocation) && item.DamageLevel != ComponentDamageLevel.Destroyed)) { Control.LogDebug(DType.SalvageProccess, $"--- Adding {component.ComponentDefID}"); contract.AddMechComponentToSalvage(salvage, component.Def, ComponentDamageLevel.Functional, false, constants, simgame.NetworkRandom, true); } } } catch (Exception e) { Control.LogError("Error in adding component", e); } }