Bindable tactical devices
This commit is contained in:
@@ -3,10 +3,13 @@ using Comfort.Common;
|
|||||||
using EFT.InputSystem;
|
using EFT.InputSystem;
|
||||||
using EFT.InventoryLogic;
|
using EFT.InventoryLogic;
|
||||||
using EFT.UI;
|
using EFT.UI;
|
||||||
|
using EFT.UI.DragAndDrop;
|
||||||
using EFT.UI.Settings;
|
using EFT.UI.Settings;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using SPT.Reflection.Patching;
|
using SPT.Reflection.Patching;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace UIFixes;
|
namespace UIFixes;
|
||||||
|
|
||||||
@@ -17,6 +20,7 @@ public static class QuickAccessPanelPatches
|
|||||||
new FixWeaponBindsDisplayPatch().Enable();
|
new FixWeaponBindsDisplayPatch().Enable();
|
||||||
new FixVisibilityPatch().Enable();
|
new FixVisibilityPatch().Enable();
|
||||||
new TranslateCommandHackPatch().Enable();
|
new TranslateCommandHackPatch().Enable();
|
||||||
|
new RotationPatch().Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FixWeaponBindsDisplayPatch : ModulePatch
|
public class FixWeaponBindsDisplayPatch : ModulePatch
|
||||||
@@ -101,4 +105,30 @@ public static class QuickAccessPanelPatches
|
|||||||
FixVisibilityPatch.Ignorable = false;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
138
Patches/TacticalBindsPatches.cs
Normal file
138
Patches/TacticalBindsPatches.cs
Normal file
@@ -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<IHandsController> callback)
|
||||||
|
{
|
||||||
|
Item boundItem = __instance.InventoryControllerClass.Inventory.FastAccess.GetBoundItem(quickSlot);
|
||||||
|
if (boundItem == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LightComponent lightComponent = boundItem.GetItemComponent<LightComponent>();
|
||||||
|
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<LightComponent>();
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,6 +74,7 @@ public class Plugin : BaseUnityPlugin
|
|||||||
new HideoutCameraPatch().Enable();
|
new HideoutCameraPatch().Enable();
|
||||||
WeaponModdingPatches.Enable();
|
WeaponModdingPatches.Enable();
|
||||||
TagPatches.Enable();
|
TagPatches.Enable();
|
||||||
|
TacticalBindsPatches.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool InRaid()
|
public static bool InRaid()
|
||||||
|
|||||||
17
Settings.cs
17
Settings.cs
@@ -45,6 +45,13 @@ internal enum AutoFleaPrice
|
|||||||
Maximum
|
Maximum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal enum TacticalBindModifier
|
||||||
|
{
|
||||||
|
Shift,
|
||||||
|
Control,
|
||||||
|
Alt
|
||||||
|
}
|
||||||
|
|
||||||
internal class Settings
|
internal class Settings
|
||||||
{
|
{
|
||||||
// Categories
|
// Categories
|
||||||
@@ -71,6 +78,7 @@ internal class Settings
|
|||||||
public static ConfigEntry<bool> ToggleOrHoldTactical { get; set; }
|
public static ConfigEntry<bool> ToggleOrHoldTactical { get; set; }
|
||||||
public static ConfigEntry<bool> ToggleOrHoldHeadlight { get; set; }
|
public static ConfigEntry<bool> ToggleOrHoldHeadlight { get; set; }
|
||||||
public static ConfigEntry<bool> ToggleOrHoldGoggles { get; set; }
|
public static ConfigEntry<bool> ToggleOrHoldGoggles { get; set; }
|
||||||
|
public static ConfigEntry<TacticalBindModifier> TacticalModeModifier { get; set; }
|
||||||
public static ConfigEntry<bool> UseHomeEnd { get; set; }
|
public static ConfigEntry<bool> UseHomeEnd { get; set; }
|
||||||
public static ConfigEntry<bool> RebindPageUpDown { get; set; }
|
public static ConfigEntry<bool> RebindPageUpDown { get; set; }
|
||||||
public static ConfigEntry<int> MouseScrollMulti { get; set; }
|
public static ConfigEntry<int> MouseScrollMulti { get; set; }
|
||||||
@@ -270,6 +278,15 @@ internal class Settings
|
|||||||
null,
|
null,
|
||||||
new ConfigurationManagerAttributes { })));
|
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(
|
configEntries.Add(UseHomeEnd = config.Bind(
|
||||||
InputSection,
|
InputSection,
|
||||||
"Enable Home/End Keys",
|
"Enable Home/End Keys",
|
||||||
|
|||||||
Reference in New Issue
Block a user