diff --git a/IRTweaks/IRTweaks/IRTweaks.csproj b/IRTweaks/IRTweaks/IRTweaks.csproj
index b3ec41c..470ee88 100644
--- a/IRTweaks/IRTweaks/IRTweaks.csproj
+++ b/IRTweaks/IRTweaks/IRTweaks.csproj
@@ -115,6 +115,7 @@
+
diff --git a/IRTweaks/IRTweaks/ModConfig.cs b/IRTweaks/IRTweaks/ModConfig.cs
index 0e7f307..a8f4844 100644
--- a/IRTweaks/IRTweaks/ModConfig.cs
+++ b/IRTweaks/IRTweaks/ModConfig.cs
@@ -131,6 +131,7 @@ public class FixesFlags
// UI
public bool BulkPurchasing = true;
+ public bool BulkScrapping = true;
public bool CombatLog = true;
public bool DisableCombatRestarts = true;
public bool DisableCombatSaves = true;
@@ -166,6 +167,7 @@ public void LogConfig()
Mod.Log.Info?.Write($" BuildingDamageColorChange: {this.Fixes.BuildingDamageColorChange}");
Mod.Log.Info?.Write($" BraceOnMeleeWithJuggernaut: {this.Fixes.BraceOnMeleeWithJuggernaut}");
Mod.Log.Info?.Write($" BulkPurchasing: {this.Fixes.BulkPurchasing}");
+ Mod.Log.Info?.Write($" BulkScrapping: {this.Fixes.BulkScrapping}");
Mod.Log.Info?.Write($" CalledShotTweaks: {this.Fixes.CalledShotTweaks}");
Mod.Log.Info?.Write($" CombatLog: {this.Fixes.CombatLog}");
Mod.Log.Info?.Write($" DisableCampaign: {this.Fixes.DisableCampaign}");
diff --git a/IRTweaks/IRTweaks/ModText.cs b/IRTweaks/IRTweaks/ModText.cs
index 1d9118f..f028604 100644
--- a/IRTweaks/IRTweaks/ModText.cs
+++ b/IRTweaks/IRTweaks/ModText.cs
@@ -4,6 +4,32 @@ namespace IRTweaks
{
public class ModText
{
+
+ public const string DT_Title_ScrapAll = "SCRAP_ALL_TITLE";
+ public const string DT_Title_ScrapAssaults = "SCRAP_ALL_ASSAULT";
+ public const string DT_Title_ScrapHeavies = "SCRAP_ALL_HEAVY";
+ public const string DT_Title_ScrapLights = "SCRAP_ALL_LIGHT";
+ public const string DT_Title_ScrapMediums = "SCRAP_ALL_MEDIUM";
+
+ public const string DT_Desc_ScrapAll = "SCRAP_ALL_DESC";
+ public const string DT_Button_Cancel = "BUTTON_CANCEL";
+ public const string DT_Button_Scrap = "BUTTON_SCRAP";
+
+ public Dictionary Dialog = new Dictionary
+ {
+ { DT_Title_ScrapAll, "SCRAP ALL IN STORAGE" },
+ { DT_Title_ScrapAssaults, "SCRAP ASSAULTS IN STORAGE" },
+ { DT_Title_ScrapHeavies, "SCRAP HEAVIES IN STORAGE" },
+ { DT_Title_ScrapLights, "SCRAP LIGHTS IN STORAGE" },
+ { DT_Title_ScrapMediums, "SCRAP MEDIUMS IN STORAGE" },
+
+ { DT_Desc_ScrapAll, "This will scrap units currently in storage, gaining {0} c-bills. This action cannot be reversed, you will need to load an earlier save. Are you sure?" },
+
+ { DT_Button_Cancel, "CANCEL" },
+ { DT_Button_Scrap, "SCRAP" }
+
+ };
+
public const string FT_InjuryResist = "INJURY_RESIST";
public Dictionary Floaties = new Dictionary
diff --git a/IRTweaks/IRTweaks/Modules/Combat/BuildingDamageColorChange.cs b/IRTweaks/IRTweaks/Modules/Combat/BuildingDamageColorChange.cs
index 0cde805..3e0892e 100644
--- a/IRTweaks/IRTweaks/Modules/Combat/BuildingDamageColorChange.cs
+++ b/IRTweaks/IRTweaks/Modules/Combat/BuildingDamageColorChange.cs
@@ -6,13 +6,16 @@ namespace IRTweaks.Modules.Combat
{
// make buildings have blue damage number floaties to differentiate
[HarmonyPatch(typeof(CombatHUDFloatie), "Init")]
- public static class CombatHUDFloatie_Init_Patch {
-
+ public static class CombatHUDFloatie_Init_Patch
+ {
+
public static bool Prepare() => Mod.Config.Fixes.BuildingDamageColorChange;
-
- public static void Postfix(CombatHUDFloatie __instance) {
+
+ public static void Postfix(CombatHUDFloatie __instance)
+ {
CombatHUDFloatieAnchor anchor = __instance.GetComponentInParent();
- if (anchor.DisplayedActor == null) {
+ if (anchor.DisplayedActor == null)
+ {
__instance.floatieText.color = Color.blue * Color.white;
}
}
diff --git a/IRTweaks/IRTweaks/Modules/Combat/ScaleObjectiveBuildingHealth.cs b/IRTweaks/IRTweaks/Modules/Combat/ScaleObjectiveBuildingHealth.cs
index 8a404ae..f1e0228 100644
--- a/IRTweaks/IRTweaks/Modules/Combat/ScaleObjectiveBuildingHealth.cs
+++ b/IRTweaks/IRTweaks/Modules/Combat/ScaleObjectiveBuildingHealth.cs
@@ -5,40 +5,9 @@
using IRBTModUtils.Extension;
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace IRTweaks.Modules.Combat
{
- //[HarmonyPatch(typeof(BattleTech.Building), "InitStats")]
- //static class ScaleObjectiveBuildingStructure_Building_InitStats
- //{
- // static bool Prepare => Mod.Config.Fixes.ScaleObjectiveBuildingStructure;
-
- // static void Postfix(BattleTech.Building __instance, bool ___isObjectiveTarget)
- // {
-
- // //float adjustedStruct = (float)Math.Floor((__instance.CurrentStructure * scale.Multi) + scale.Mod);
- // //Mod.Log.Info?.Write($" -- adjustedStructure: {adjustedStruct} = ( currentStruct: {__instance.CurrentStructure} x scaleMulti: {scale.Multi} ) + scaleMod: {scale.Mod}");
- // //__instance.StatCollection.ModifyStat("IRTweaks", -1, ModStats.HBS_Building_Structure, StatCollection.StatOperation.Set, adjustedStruct);
- // //Traverse startingStructT = Traverse.Create(__instance).Property("StartingStructure");
- // //startingStructT.SetValue(adjustedStruct);
-
- // //Mod.Log.Info?.Write($"Evaluating building: {__instance.DistinctId()} for structure scaling.");
- // //if (___isObjectiveTarget)
- // //{
-
- // //}
- // //else
- // //{
- // // Mod.Log.Info?.Write($" -- building is not objective target, it will not be scaled.");
- // //}
-
-
- // }
-
- //}
[HarmonyPatch(typeof(TurnDirector), "OnInitializeContractComplete")]
public static class ScaleObjectiveBuildingStructure_TurnDirector_OnInitializeContractComplete
diff --git a/IRTweaks/IRTweaks/Modules/UI/BulkScrapping.cs b/IRTweaks/IRTweaks/Modules/UI/BulkScrapping.cs
new file mode 100644
index 0000000..8b324a3
--- /dev/null
+++ b/IRTweaks/IRTweaks/Modules/UI/BulkScrapping.cs
@@ -0,0 +1,179 @@
+using BattleTech;
+using BattleTech.UI;
+using Harmony;
+using HBS;
+using Localize;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace IRTweaks.Modules.UI
+{
+ public static class ScrapHelper
+ {
+ public static void BuildScrapAllDialog(List widgetInventory, float scrapPartModifier, string title, Action confirmAction)
+ {
+ List activeItems = widgetInventory
+ .Where(x => x.GameObject.activeSelf)
+ .OfType()
+ .ToList();
+
+ int cbills = ScrapHelper.CalculateTotalScrap(activeItems, scrapPartModifier);
+ string cbillStr = SimGameState.GetCBillString(cbills);
+
+
+ string descLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Desc_ScrapAll], new object[] { cbillStr }).ToString();
+ string cancelLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Button_Cancel]).ToString();
+ string scrapLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Button_Scrap]).ToString();
+ GenericPopupBuilder.Create(title, descLT)
+ .AddButton(cancelLT)
+ .AddButton(scrapLT, confirmAction)
+ .CancelOnEscape()
+ .AddFader(LazySingletonBehavior.Instance.UILookAndColorConstants.PopupBackfill)
+ .Render();
+ }
+
+ public static void ScrapAllActive(List widgetInventory)
+ {
+ List activeItems = widgetInventory
+ .Where(x => x.GameObject.activeSelf)
+ .OfType()
+ .ToList();
+
+ MechBayPanel mechBayPanel = LazySingletonBehavior.Instance.GetOrCreateUIModule();
+
+ foreach (MechBayChassisUnitElement item in activeItems)
+ {
+ // parts 0 + max 0 = one unit
+ int fullMechs = (item.PartsCount == 0 && item.PartsMax == 0) ?
+ 1 : (int)Math.Floor((double)item.PartsCount / item.PartsMax);
+ int partsCount = item.PartsCount - fullMechs;
+
+ for (int i = 0; i < fullMechs; i++)
+ {
+ mechBayPanel.Sim.ScrapInactiveMech(item.ChassisDef.Description.Id, pay: true);
+ }
+
+ for (int i = 0; i < partsCount; i++)
+ {
+ mechBayPanel.Sim.ScrapMechPart(item.ChassisDef.Description.Id, 1f, item.ChassisDef.MechPartMax, pay: true);
+ }
+
+ mechBayPanel.RefreshData(resetFilters: true);
+ mechBayPanel.SelectChassis(null);
+ }
+ }
+
+ public static int CalculateTotalScrap(List activeChassis, float scrapPartModifier)
+ {
+ float total = 0;
+ foreach (MechBayChassisUnitElement item in activeChassis)
+ {
+ Mod.Log.Info?.Write($"Part : {item.ChassisDef.Description.Name} {item.PartsCount} partsCounts with {item.PartsMax} partsMax");
+ // parts 0 + max 0 = one unit
+ int fullMechs = (item.PartsCount == 0 && item.PartsMax == 0) ?
+ 1 : (int)Math.Floor((double)item.PartsCount / item.PartsMax);
+ int partsCount = item.PartsCount - fullMechs;
+ float partsFrac = item.PartsMax != 0 ? partsCount * (1f / item.PartsMax) : 0;
+ float partsMulti = fullMechs + partsFrac;
+ Mod.Log.Info?.Write($" -- {fullMechs} fullMechs, {partsCount} parts => {partsFrac} partsFrac, for partsMulti: {partsMulti}");
+
+ int perPartScrap = Mathf.RoundToInt((float)item.ChassisDef.Description.Cost * scrapPartModifier);
+ int totalScrapForChassis = (int)Math.Floor(perPartScrap * partsMulti);
+ Mod.Log.Info?.Write($" -- perPartScrap: {perPartScrap} x partsMulti: {partsMulti} => totalScrapForChassis: {totalScrapForChassis}");
+
+ total += totalScrapForChassis;
+ }
+
+ int cbills = (int)Math.Ceiling(total);
+
+ return cbills;
+ }
+ }
+
+ [HarmonyPatch(typeof(MechBayMechStorageWidget), "Filter_WeightAll")]
+ static class BulkScrapping_MechBayMechStorageWidget_Filter_WeightAll
+ {
+ static bool Prepare => Mod.Config.Fixes.BulkScrapping;
+
+ static void Postfix(MechBayMechStorageWidget __instance, List ___inventory)
+ {
+ if (___inventory != null && ___inventory.Count > 0 &&
+ Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
+ {
+ string titleLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Title_ScrapAll]).ToString();
+ ScrapHelper.BuildScrapAllDialog(___inventory, __instance.Sim.Constants.Finances.MechScrapModifier, titleLT,
+ delegate { ScrapHelper.ScrapAllActive(___inventory); });
+ }
+ }
+ }
+
+ [HarmonyPatch(typeof(MechBayMechStorageWidget), "Filter_WeightAssault")]
+ static class BulkScrapping_MechBayMechStorageWidget_Filter_WeightAssault
+ {
+ static bool Prepare => Mod.Config.Fixes.BulkScrapping;
+
+ static void Postfix(MechBayMechStorageWidget __instance, List ___inventory)
+ {
+ if (___inventory != null && ___inventory.Count > 0 &&
+ Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
+ {
+ string titleLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Title_ScrapAssaults]).ToString();
+ ScrapHelper.BuildScrapAllDialog(___inventory, __instance.Sim.Constants.Finances.MechScrapModifier, titleLT,
+ delegate { ScrapHelper.ScrapAllActive(___inventory); });
+ }
+ }
+ }
+
+ [HarmonyPatch(typeof(MechBayMechStorageWidget), "Filter_WeightHeavy")]
+ static class BulkScrapping_MechBayMechStorageWidget_Filter_WeightHeavy
+ {
+ static bool Prepare => Mod.Config.Fixes.BulkScrapping;
+
+ static void Postfix(MechBayMechStorageWidget __instance, List ___inventory)
+ {
+ if (___inventory != null && ___inventory.Count > 0 &&
+ Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
+ {
+ string titleLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Title_ScrapHeavies]).ToString();
+ ScrapHelper.BuildScrapAllDialog(___inventory, __instance.Sim.Constants.Finances.MechScrapModifier, titleLT,
+ delegate { ScrapHelper.ScrapAllActive(___inventory); });
+ }
+ }
+ }
+
+ [HarmonyPatch(typeof(MechBayMechStorageWidget), "Filter_WeightLight")]
+ static class BulkScrapping_MechBayMechStorageWidget_Filter_WeightLight
+ {
+ static bool Prepare => Mod.Config.Fixes.BulkScrapping;
+
+ static void Postfix(MechBayMechStorageWidget __instance, List ___inventory)
+ {
+ if (___inventory != null && ___inventory.Count > 0 &&
+ Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
+ {
+ string titleLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Title_ScrapLights]).ToString();
+ ScrapHelper.BuildScrapAllDialog(___inventory, __instance.Sim.Constants.Finances.MechScrapModifier, titleLT,
+ delegate { ScrapHelper.ScrapAllActive(___inventory); });
+ }
+ }
+ }
+
+ [HarmonyPatch(typeof(MechBayMechStorageWidget), "Filter_WeightMedium")]
+ static class BulkScrapping_MechBayMechStorageWidget_Filter_WeightMedium
+ {
+ static bool Prepare => Mod.Config.Fixes.BulkScrapping;
+
+ static void Postfix(MechBayMechStorageWidget __instance, List ___inventory)
+ {
+ if (___inventory != null && ___inventory.Count > 0 &&
+ Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
+ {
+ string titleLT = new Text(Mod.LocalizedText.Dialog[ModText.DT_Title_ScrapMediums]).ToString();
+ ScrapHelper.BuildScrapAllDialog(___inventory, __instance.Sim.Constants.Finances.MechScrapModifier, titleLT,
+ delegate { ScrapHelper.ScrapAllActive(___inventory); });
+ }
+ }
+ }
+}
diff --git a/IRTweaks/IRTweaks/Modules/UI/WeaponTooltips.cs b/IRTweaks/IRTweaks/Modules/UI/WeaponTooltips.cs
index 2dfe702..9fea8ab 100644
--- a/IRTweaks/IRTweaks/Modules/UI/WeaponTooltips.cs
+++ b/IRTweaks/IRTweaks/Modules/UI/WeaponTooltips.cs
@@ -1,16 +1,23 @@
using BattleTech;
using BattleTech.UI.Tooltips;
using CustAmmoCategories;
+using Harmony;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
-namespace IRTweaks.Modules.UI {
-
+namespace IRTweaks.Modules.UI
+{
+
// Update the tooltip to distinguish between different weapon types, and make CAC mannerisms clearer
- public static class WeaponTooltips {
- public static void TooltipPrefab_Weapon_SetData_Postfix(TooltipPrefab_Weapon __instance, object data,
- TextMeshProUGUI ___rangeType, TextMeshProUGUI ___damage) {
+ [HarmonyPatch(typeof(TooltipPrefab_Weapon), "SetData")]
+ static class WeaponTooltips_TooltipPrefab_Weapon_SetData
+ {
+ static bool Prepare => Mod.Config.Fixes.WeaponTooltip;
+
+ static void Postfix(TooltipPrefab_Weapon __instance, object data,
+ TextMeshProUGUI ___rangeType, TextMeshProUGUI ___damage)
+ {
Mod.Log.Debug?.Write("TP_W:SD entered.");
___rangeType.enabled = false;
diff --git a/IRTweaks/IRTweaks/Modules/UIModule.cs b/IRTweaks/IRTweaks/Modules/UIModule.cs
index 18351a6..0678931 100644
--- a/IRTweaks/IRTweaks/Modules/UIModule.cs
+++ b/IRTweaks/IRTweaks/Modules/UIModule.cs
@@ -6,15 +6,21 @@
using System;
using System.Reflection;
-namespace IRTweaks.Modules.Tooltip {
- public static class UIFixes {
+namespace IRTweaks.Modules.Tooltip
+{
+ public static class UIFixes
+ {
static bool Initialized = false;
- public static void InitModule(HarmonyInstance harmony) {
- if (!Initialized) {
- try {
+ public static void InitModule(HarmonyInstance harmony)
+ {
+ if (!Initialized)
+ {
+ try
+ {
// Updates the purchase and selling dialogs to allow multiple items to be purchased and sold at once
- if (Mod.Config.Fixes.BulkPurchasing) {
+ if (Mod.Config.Fixes.BulkPurchasing)
+ {
Mod.Log.Info?.Write("Activating Fix: BulkPurchasing");
MethodInfo refreshMI = AccessTools.Method(typeof(SG_Stores_MultiPurchasePopup), "Refresh");
HarmonyMethod mpp_R_Post = new HarmonyMethod(typeof(StoreQuantities), "MultiPurchasePopup_Refresh_Postfix");
@@ -30,7 +36,8 @@ public static void InitModule(HarmonyInstance harmony) {
}
// Enable the CombatLog
- if (Mod.Config.Fixes.CombatLog) {
+ if (Mod.Config.Fixes.CombatLog)
+ {
Mod.Log.Info?.Write("Activating Fix: CombatLog");
MethodInfo combatHUD_Init_MI = AccessTools.Method(typeof(CombatHUD), "Init", new Type[] { typeof(CombatGameState) });
HarmonyMethod cl_chud_i_post = new HarmonyMethod(typeof(CombatLog), "CombatHUD_Init_Postfix");
@@ -74,7 +81,8 @@ public static void InitModule(HarmonyInstance harmony) {
Mod.Log.Info?.Write("Activating Fix: DisableCombatRestart");
// Makes the main menu a smoother as there are fewer
- if (Mod.Config.Fixes.StreamlinedMainMenu) {
+ if (Mod.Config.Fixes.StreamlinedMainMenu)
+ {
Mod.Log.Info?.Write("Activating Fix: StreamlinedMainMenu");
MethodInfo sgnb_rftp_mi = AccessTools.Method(typeof(SGNavigationButton), "ResetFlyoutsToPrefab");
@@ -100,14 +108,12 @@ public static void InitModule(HarmonyInstance harmony) {
}
// Update the weapon tooltip to support CAC behaviors
- if (Mod.Config.Fixes.WeaponTooltip) {
+ if (Mod.Config.Fixes.WeaponTooltip)
Mod.Log.Info?.Write("Activating Fix: WeaponTooltip");
- MethodInfo tooltipPrefab_Weapon_SetData = AccessTools.Method(typeof(TooltipPrefab_Weapon), "SetData");
- HarmonyMethod tm_tp_w_sd_post = new HarmonyMethod(typeof(WeaponTooltips), "TooltipPrefab_Weapon_SetData_Postfix");
- harmony.Patch(tooltipPrefab_Weapon_SetData, null, tm_tp_w_sd_post, null);
- }
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
Mod.Log.Error?.Write($"Failed to load patches due to: {e.Message}");
Mod.Log.Error?.Write(e.StackTrace);
Mod.Log.Error?.Write(e.ToString());
diff --git a/mod_localized_text.json b/mod_localized_text.json
index 40f57e8..99476e2 100644
--- a/mod_localized_text.json
+++ b/mod_localized_text.json
@@ -1,4 +1,18 @@
{
+
+ "Dialog" : {
+ "SCRAP_ALL_TITLE" : "SCRAP ALL IN STORAGE",
+ "SCRAP_ALL_ASSAULT" : "SCRAP ASSAULTS IN STORAGE",
+ "SCRAP_ALL_HEAVY" : "SCRAP HEAVIES IN STORAGE",
+ "SCRAP_ALL_LIGHT" : "SCRAP LIGHTS IN STORAGE",
+ "SCRAP_ALL_MEDIUM" : "SCRAP MEDIUMS IN STORAGE",
+
+ "SCRAP_ALL_DESC" : "This will scrap units currently in storage, gaining {0} c-bills. This action cannot be reversed, you will need to load an earlier save. Are you sure?",
+
+ "BUTTON_CANCEL" : "CANCEL",
+ "BUTTON_SCRAP" : "SCRAP"
+ },
+
"Floaties": {
"INJURY_RESIST": "INJURY RESISTED!"
},