diff --git a/Patches/QuickAccessPanelPatches.cs b/Patches/QuickAccessPanelPatches.cs index 580568c..f2c15d9 100644 --- a/Patches/QuickAccessPanelPatches.cs +++ b/Patches/QuickAccessPanelPatches.cs @@ -3,10 +3,13 @@ using Comfort.Common; using EFT.InputSystem; using EFT.InventoryLogic; using EFT.UI; +using EFT.UI.DragAndDrop; using EFT.UI.Settings; using HarmonyLib; using SPT.Reflection.Patching; using System.Reflection; +using UnityEngine; +using UnityEngine.UI; namespace UIFixes; @@ -17,6 +20,7 @@ public static class QuickAccessPanelPatches new FixWeaponBindsDisplayPatch().Enable(); new FixVisibilityPatch().Enable(); new TranslateCommandHackPatch().Enable(); + new RotationPatch().Enable(); } public class FixWeaponBindsDisplayPatch : ModulePatch @@ -101,4 +105,30 @@ public static class QuickAccessPanelPatches FixVisibilityPatch.Ignorable = false; } } + + public class RotationPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(QuickSlotItemView), nameof(QuickSlotItemView.UpdateScale)); + } + + [PatchPostfix] + public static void Postfix(QuickSlotItemView __instance, Image ___MainImage) + { + if (__instance.IconScale == null) + { + return; + } + + // Already square items don't need to be rotated + XYCellSizeStruct size = __instance.Item.CalculateCellSize(); + if (size.X == size.Y) + { + Transform transform = ___MainImage.transform; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one; + } + } + } } diff --git a/Patches/TacticalBindsPatches.cs b/Patches/TacticalBindsPatches.cs new file mode 100644 index 0000000..7365281 --- /dev/null +++ b/Patches/TacticalBindsPatches.cs @@ -0,0 +1,138 @@ +using Comfort.Common; +using EFT; +using EFT.InventoryLogic; +using HarmonyLib; +using SPT.Reflection.Patching; +using System.Reflection; +using UnityEngine; + +namespace UIFixes; + +public static class TacticalBindsPatches +{ + public static void Enable() + { + new BindableTacticalPatch().Enable(); + new ReachableTacticalPatch().Enable(); + new UseTacticalPatch().Enable(); + } + + public class BindableTacticalPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(InventoryControllerClass), nameof(InventoryControllerClass.IsAtBindablePlace)); + } + + [PatchPostfix] + public static void Postfix(InventoryControllerClass __instance, Item item, ref bool __result) + { + if (__result) + { + return; + } + + __result = IsEquippedTacticalDevice(__instance, item); + } + } + + public class ReachableTacticalPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(InventoryControllerClass), nameof(InventoryControllerClass.IsAtReachablePlace)); + } + + [PatchPostfix] + public static void Postfix(InventoryControllerClass __instance, Item item, ref bool __result) + { + if (__result) + { + return; + } + + __result = IsEquippedTacticalDevice(__instance, item); + } + } + + public class UseTacticalPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(Player), nameof(Player.SetQuickSlotItem)); + } + + [PatchPrefix] + public static bool Prefix(Player __instance, EBoundItem quickSlot, Callback callback) + { + Item boundItem = __instance.InventoryControllerClass.Inventory.FastAccess.GetBoundItem(quickSlot); + if (boundItem == null) + { + return true; + } + + LightComponent lightComponent = boundItem.GetItemComponent(); + if (lightComponent == null) + { + return true; + } + + // Don't return true past this point; if the default handler tries to use a tactical device, very bad things happen + + if (__instance.HandsController is not Player.FirearmController firearmController || + firearmController.Item != boundItem.GetRootItem()) + { + callback(null); + return false; + } + + FirearmLightStateStruct lightState = new() + { + Id = lightComponent.Item.Id, + IsActive = lightComponent.IsActive, + LightMode = lightComponent.SelectedMode + }; + + if (IsTacticalModeModifierPressed()) + { + lightState.LightMode++; + } + else + { + lightState.IsActive = !lightState.IsActive; + } + + firearmController.SetLightsState([lightState], false); + + callback(null); + return false; + } + } + + private static bool IsEquippedTacticalDevice(InventoryControllerClass inventoryController, Item item) + { + LightComponent lightComponent = item.GetItemComponent(); + if (lightComponent == null) + { + return false; + } + + if (item.GetRootItem() is Weapon weapon) + { + return inventoryController.Inventory.Equipment.Contains(weapon); + } + + return false; + } + + private static bool IsTacticalModeModifierPressed() + { + return Settings.TacticalModeModifier.Value switch + { + TacticalBindModifier.Shift => Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift), + TacticalBindModifier.Control => Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl), + TacticalBindModifier.Alt => Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt), + _ => false, + }; + } +} \ No newline at end of file diff --git a/Plugin.cs b/Plugin.cs index 9384555..7c4a0bd 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -74,6 +74,7 @@ public class Plugin : BaseUnityPlugin new HideoutCameraPatch().Enable(); WeaponModdingPatches.Enable(); TagPatches.Enable(); + TacticalBindsPatches.Enable(); } public static bool InRaid() diff --git a/Settings.cs b/Settings.cs index ac40102..2c26dea 100644 --- a/Settings.cs +++ b/Settings.cs @@ -45,6 +45,13 @@ internal enum AutoFleaPrice Maximum } +internal enum TacticalBindModifier +{ + Shift, + Control, + Alt +} + internal class Settings { // Categories @@ -71,6 +78,7 @@ internal class Settings public static ConfigEntry ToggleOrHoldTactical { get; set; } public static ConfigEntry ToggleOrHoldHeadlight { get; set; } public static ConfigEntry ToggleOrHoldGoggles { get; set; } + public static ConfigEntry TacticalModeModifier { get; set; } public static ConfigEntry UseHomeEnd { get; set; } public static ConfigEntry RebindPageUpDown { get; set; } public static ConfigEntry MouseScrollMulti { get; set; } @@ -270,6 +278,15 @@ internal class Settings null, new ConfigurationManagerAttributes { }))); + configEntries.Add(TacticalModeModifier = config.Bind( + InputSection, + "Change Quickbound Tactical Mode", + TacticalBindModifier.Shift, + new ConfigDescription( + "Holding this modifer when activating a quickbound tactical device will switch its active mode", + null, + new ConfigurationManagerAttributes { }))); + configEntries.Add(UseHomeEnd = config.Bind( InputSection, "Enable Home/End Keys",