Compare commits
No commits in common. "main" and "MunitionsExpert-1.2.1" have entirely different histories.
main
...
MunitionsE
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.CustomInteractions.Prepatch</AssemblyName>
|
||||
<Version>1.6.0</Version>
|
||||
<Version>1.3.1</Version>
|
||||
<RootNamespace>IcyClawz.CustomInteractions</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
@ -10,7 +10,8 @@ public static class Prepatch
|
||||
|
||||
public static void Patch(AssemblyDefinition assembly)
|
||||
{
|
||||
TypeDefinition type = assembly.MainModule.GetType("DynamicInteractionClass");
|
||||
TypeDefinition type = assembly.MainModule.GetType("GClass2816"); // DynamicInteraction
|
||||
type.IsSealed = false;
|
||||
FieldDefinition field = type.Fields.SingleOrDefault(c => c.Name is "action_0");
|
||||
field.IsFamily = true;
|
||||
field.IsInitOnly = false;
|
||||
|
@ -1,20 +1,24 @@
|
||||
using Comfort.Common;
|
||||
using EFT.InventoryLogic;
|
||||
using EFT.UI;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
using EmptyInteractionsAbstractClass = GClass3423;
|
||||
using DynamicInteraction = GClass2816;
|
||||
using EmptyInteractions = GClass2817<System.Enum>;
|
||||
|
||||
namespace IcyClawz.CustomInteractions;
|
||||
|
||||
public interface ICustomInteractionsProvider
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public interface ICustomInteractionsProvider { } // Do not implement this directly
|
||||
|
||||
public interface IItemCustomInteractionsProvider : ICustomInteractionsProvider
|
||||
{
|
||||
IEnumerable<CustomInteraction> GetCustomInteractions(ItemUiContext context, EItemViewType viewType, Item item);
|
||||
IEnumerable<CustomInteraction> GetCustomInteractions(ItemUiContext uiContext, EItemViewType viewType, Item item);
|
||||
}
|
||||
|
||||
public static class CustomInteractionsManager
|
||||
@ -28,46 +32,72 @@ public static class CustomInteractionsManager
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomInteraction(ItemUiContext context)
|
||||
public class CustomInteraction()
|
||||
{
|
||||
internal readonly CustomInteractionImpl Impl = new(context, UnityEngine.Random.Range(0, int.MaxValue).ToString("x4"));
|
||||
internal readonly CustomInteractionImpl Impl = new();
|
||||
|
||||
public Func<string> Caption { get => Impl.Caption; set => Impl.Caption = value; }
|
||||
public Func<Sprite> Icon { get => Impl.Icon; set => Impl.Icon = value; }
|
||||
public Action Action { get => Impl.Action; set => Impl.Action = value; }
|
||||
public Func<IEnumerable<CustomInteraction>> SubMenu { get => Impl.SubMenu; set => Impl.SubMenu = value; }
|
||||
public Func<CustomSubInteractions> SubMenu { get => Impl.SubMenu; set => Impl.SubMenu = value; }
|
||||
public Func<bool> Enabled { get => Impl.Enabled; set => Impl.Enabled = value; }
|
||||
public Func<string> Error { get => Impl.Error; set => Impl.Error = value; }
|
||||
}
|
||||
|
||||
internal sealed class CustomInteractionImpl(ItemUiContext context, string id) : DynamicInteractionClass(id, id)
|
||||
internal sealed class CustomInteractionImpl()
|
||||
: DynamicInteraction(UnityEngine.Random.Range(0, int.MaxValue).ToString("x4"))
|
||||
{
|
||||
internal readonly ItemUiContext Context = context;
|
||||
|
||||
public Func<string> Caption { get; set; }
|
||||
public new Func<Sprite> Icon { get; set; }
|
||||
public Action Action { get => action_0; set => action_0 = value; }
|
||||
public Func<IEnumerable<CustomInteraction>> SubMenu { get; set; }
|
||||
public Func<CustomSubInteractions> SubMenu { get; set; }
|
||||
public Func<bool> Enabled { get; set; }
|
||||
public Func<string> Error { get; set; }
|
||||
|
||||
public bool IsInteractive() => Enabled?.Invoke() ?? true;
|
||||
}
|
||||
|
||||
internal sealed class CustomInteractionsImpl(ItemUiContext context) : EmptyInteractionsAbstractClass(context)
|
||||
public abstract class CustomSubInteractions(ItemUiContext uiContext)
|
||||
{
|
||||
internal readonly CustomSubInteractionsImpl Impl = new(uiContext);
|
||||
|
||||
public bool ExaminationRequired
|
||||
{
|
||||
get => Impl.ExaminationRequiredInternal;
|
||||
set => Impl.ExaminationRequiredInternal = value;
|
||||
}
|
||||
|
||||
public void Add(CustomInteraction interaction) => Impl.AddCustomInteraction(interaction);
|
||||
public void AddRange(IEnumerable<CustomInteraction> interactions) => interactions.ExecuteForEach(Impl.AddCustomInteraction);
|
||||
public void Remove(CustomInteraction interaction) => Impl.RemoveCustomInteraction(interaction);
|
||||
public void RemoveRange(IEnumerable<CustomInteraction> interactions) => interactions.ExecuteForEach(Impl.RemoveCustomInteraction);
|
||||
public void CallRedraw() => Impl.CallRedraw();
|
||||
public void CallRedraw(string templateId) => Impl.CallRedraw(templateId);
|
||||
}
|
||||
|
||||
internal sealed class CustomSubInteractionsImpl(ItemUiContext uiContext)
|
||||
: EmptyInteractions(uiContext)
|
||||
{
|
||||
public IEnumerable<CustomInteractionImpl> CustomInteractions => DynamicInteractions.OfType<CustomInteractionImpl>();
|
||||
|
||||
public bool ExaminationRequiredInternal { get; set; } = true;
|
||||
public override bool ExaminationRequired => ExaminationRequiredInternal;
|
||||
public override bool HasIcons => CustomInteractions.Any(interaction => interaction.Icon is not null);
|
||||
|
||||
public void CallRedraw() => itemUiContext_0.RedrawContextMenus(null);
|
||||
}
|
||||
|
||||
internal static class AbstractInteractionsExtensions
|
||||
{
|
||||
private static Dictionary<string, DynamicInteractionClass> GetDynamicInteractions<T>(this ItemInfoInteractionsAbstractClass<T> instance) where T : struct, Enum =>
|
||||
typeof(ItemInfoInteractionsAbstractClass<T>).GetField("dictionary_0", BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.GetValue(instance) as Dictionary<string, DynamicInteractionClass>;
|
||||
private static Dictionary<string, DynamicInteraction> GetDynamicInteractions<T>(this GClass2817<T> instance) where T : Enum =>
|
||||
typeof(GClass2817<T>).GetField("dictionary_1", BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.GetValue(instance) as Dictionary<string, DynamicInteraction>;
|
||||
|
||||
public static void AddCustomInteraction<T>(this ItemInfoInteractionsAbstractClass<T> instance, CustomInteractionImpl impl) where T : struct, Enum =>
|
||||
instance.GetDynamicInteractions()[impl.Key] = impl;
|
||||
public static void AddCustomInteraction<T>(this GClass2817<T> instance, CustomInteraction interaction) where T : Enum =>
|
||||
instance.GetDynamicInteractions()[interaction.Impl.Key] = interaction.Impl;
|
||||
|
||||
public static void RemoveCustomInteraction<T>(this GClass2817<T> instance, CustomInteraction interaction) where T : Enum =>
|
||||
instance.GetDynamicInteractions().Remove(interaction.Impl.Key);
|
||||
}
|
||||
|
||||
internal static class InteractionButtonsContainerExtensions
|
||||
@ -91,7 +121,7 @@ internal static class InteractionButtonsContainerExtensions
|
||||
CurrentButtonField.SetValue(instance, button);
|
||||
|
||||
private static readonly MethodInfo CreateButtonMethod =
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_1", BindingFlags.Public | BindingFlags.Instance);
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_1", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
private static SimpleContextMenuButton CreateButton(this InteractionButtonsContainer instance,
|
||||
string key, string caption, SimpleContextMenuButton template, RectTransform container,
|
||||
@ -102,13 +132,13 @@ internal static class InteractionButtonsContainerExtensions
|
||||
]);
|
||||
|
||||
private static readonly MethodInfo CloseSubMenuMethod =
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_4", BindingFlags.Public | BindingFlags.Instance);
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_4", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
private static void CloseSubMenu(this InteractionButtonsContainer instance) =>
|
||||
CloseSubMenuMethod.Invoke(instance, null);
|
||||
|
||||
private static readonly MethodInfo AddButtonMethod =
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_5", BindingFlags.Public | BindingFlags.Instance);
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_5", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
private static void AddButton(this InteractionButtonsContainer instance, SimpleContextMenuButton button) =>
|
||||
AddButtonMethod.Invoke(instance, [button]);
|
||||
@ -116,7 +146,6 @@ internal static class InteractionButtonsContainerExtensions
|
||||
public static void AddCustomButton(this InteractionButtonsContainer instance, CustomInteractionImpl impl)
|
||||
{
|
||||
bool isInteractive = impl.IsInteractive();
|
||||
IEnumerable<CustomInteraction> subMenu = impl.SubMenu?.Invoke();
|
||||
SimpleContextMenuButton button = null;
|
||||
button = instance.CreateButton(
|
||||
impl.Key,
|
||||
@ -133,19 +162,18 @@ internal static class InteractionButtonsContainerExtensions
|
||||
{
|
||||
instance.SetCurrentButton(button);
|
||||
instance.CloseSubMenu();
|
||||
if (isInteractive && subMenu != null)
|
||||
if (isInteractive)
|
||||
{
|
||||
CustomInteractionsImpl subInteractions = new CustomInteractionsImpl(impl.Context);
|
||||
foreach (CustomInteractionImpl subImpl in subMenu.Select(item => item.Impl))
|
||||
subInteractions.AddCustomInteraction(subImpl);
|
||||
instance.SetSubInteractions(subInteractions);
|
||||
CustomSubInteractions subMenu = impl.SubMenu?.Invoke();
|
||||
if (subMenu is not null)
|
||||
instance.SetSubInteractions(subMenu.Impl);
|
||||
}
|
||||
},
|
||||
subMenu?.Any() ?? false,
|
||||
impl.SubMenu is not null,
|
||||
false
|
||||
);
|
||||
button.SetButtonInteraction(
|
||||
isInteractive ? SuccessfulResult.New : new FailedResult(impl.Error?.Invoke() ?? "", 0)
|
||||
(isInteractive, impl.Error?.Invoke() ?? "")
|
||||
);
|
||||
instance.AddButton(button);
|
||||
}
|
||||
|
@ -3,27 +3,24 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.CustomInteractions</AssemblyName>
|
||||
<Version>1.6.0</Version>
|
||||
<Version>1.3.1</Version>
|
||||
<RootNamespace>IcyClawz.CustomInteractions</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Aki.Reflection">
|
||||
<HintPath>..\Shared\Aki.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\Shared\Assembly-CSharp-CustomInteractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepInEx">
|
||||
<HintPath>..\Shared\BepInEx.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Comfort">
|
||||
<HintPath>..\Shared\Comfort.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Sirenix.Serialization">
|
||||
<HintPath>..\Shared\Sirenix.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SPT.Reflection">
|
||||
<HintPath>..\Shared\spt-reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\Shared\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -1,12 +1,16 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using BepInEx;
|
||||
using EFT.UI;
|
||||
using SPT.Reflection.Patching;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using DynamicInteraction = GClass2816;
|
||||
using ItemContext = GClass2623;
|
||||
using ItemInfoInteractions = GClass2817<EFT.InventoryLogic.EItemInfoButton>;
|
||||
|
||||
namespace IcyClawz.CustomInteractions;
|
||||
|
||||
[BepInPlugin("com.IcyClawz.CustomInteractions", "IcyClawz.CustomInteractions", "1.6.0")]
|
||||
[BepInPlugin("com.IcyClawz.CustomInteractions", "IcyClawz.CustomInteractions", "1.3.1")]
|
||||
public class Plugin : BaseUnityPlugin
|
||||
{
|
||||
private void Awake()
|
||||
@ -22,16 +26,15 @@ internal class ItemUiContextPatch : ModulePatch
|
||||
typeof(ItemUiContext).GetMethod("GetItemContextInteractions", BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
[PatchPostfix]
|
||||
private static void Postfix(ref ItemInfoInteractionsAbstractClass<EFT.InventoryLogic.EItemInfoButton> __result,
|
||||
ref ItemUiContext __instance, ItemContextClass itemContext)
|
||||
private static void Postfix(ref ItemInfoInteractions __result, ref ItemUiContext __instance, ItemContext itemContext)
|
||||
{
|
||||
foreach (var provider in CustomInteractionsManager.Providers)
|
||||
foreach (var provider in CustomInteractionsManager.Providers.OfType<IItemCustomInteractionsProvider>())
|
||||
{
|
||||
var interactions = provider.GetCustomInteractions(__instance, itemContext.ViewType, itemContext.Item);
|
||||
if (interactions is null)
|
||||
continue;
|
||||
foreach (CustomInteractionImpl impl in interactions.Select(interaction => interaction.Impl))
|
||||
__result.AddCustomInteraction(impl);
|
||||
foreach (CustomInteraction interaction in interactions)
|
||||
__result.AddCustomInteraction(interaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,10 +42,10 @@ internal class ItemUiContextPatch : ModulePatch
|
||||
internal class InteractionButtonsContainerPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_3", BindingFlags.Public | BindingFlags.Instance);
|
||||
typeof(InteractionButtonsContainer).GetMethod("method_3", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
[PatchPrefix]
|
||||
private static bool Prefix(ref InteractionButtonsContainer __instance, DynamicInteractionClass interaction)
|
||||
private static bool Prefix(ref InteractionButtonsContainer __instance, DynamicInteraction interaction)
|
||||
{
|
||||
if (interaction is CustomInteractionImpl impl)
|
||||
{
|
||||
|
@ -3,21 +3,21 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.ItemAttributeFix</AssemblyName>
|
||||
<Version>1.5.0</Version>
|
||||
<Version>1.2.0</Version>
|
||||
<RootNamespace>IcyClawz.ItemAttributeFix</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Aki.Reflection">
|
||||
<HintPath>..\Shared\Aki.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\Shared\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BepInEx">
|
||||
<HintPath>..\Shared\BepInEx.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SPT.Reflection">
|
||||
<HintPath>..\Shared\spt-reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\Shared\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -1,11 +1,11 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using BepInEx;
|
||||
using EFT.UI;
|
||||
using SPT.Reflection.Patching;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IcyClawz.ItemAttributeFix;
|
||||
|
||||
[BepInPlugin("com.IcyClawz.ItemAttributeFix", "IcyClawz.ItemAttributeFix", "1.5.0")]
|
||||
[BepInPlugin("com.IcyClawz.ItemAttributeFix", "IcyClawz.ItemAttributeFix", "1.2.0")]
|
||||
public class Plugin : BaseUnityPlugin
|
||||
{
|
||||
private void Awake() =>
|
||||
|
@ -5,71 +5,89 @@ using EFT.UI;
|
||||
using IcyClawz.CustomInteractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
using ILightTemplate = GInterface357;
|
||||
using ISightTemplate = GInterface365;
|
||||
using GlobalEvents = GClass3400;
|
||||
using ILightTemplate = GInterface246;
|
||||
using ResourceCache = GClass1977;
|
||||
|
||||
namespace IcyClawz.ItemContextMenuExt;
|
||||
|
||||
internal static class SightComponentExtensions
|
||||
internal static class PlayerExtensions
|
||||
{
|
||||
public static int[] GetScopeCalibrationDistances(this SightComponent instance, int scopeIndex) =>
|
||||
((ISightTemplate)instance.Item.Template).CalibrationDistances[scopeIndex];
|
||||
private static readonly FieldInfo InventoryControllerField =
|
||||
typeof(Player).GetField("_inventoryController", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
public static float[] GetScopeZooms(this SightComponent instance, int scopeIndex) =>
|
||||
((ISightTemplate)instance.Item.Template).Zooms[scopeIndex];
|
||||
public static InventoryControllerClass GetInventoryController(this Player player) =>
|
||||
InventoryControllerField.GetValue(player) as InventoryControllerClass;
|
||||
}
|
||||
|
||||
internal static class LightComponentExtensions
|
||||
{
|
||||
public static int GetModesCount(this LightComponent instance) =>
|
||||
((ILightTemplate)instance.Item.Template).ModesCount;
|
||||
public static int GetModesCount(this LightComponent component) =>
|
||||
((ILightTemplate)component.Item.Template).ModesCount;
|
||||
}
|
||||
|
||||
internal sealed class CustomInteractionsProvider : ICustomInteractionsProvider
|
||||
internal sealed class CustomInteractionsProvider : IItemCustomInteractionsProvider
|
||||
{
|
||||
private const string IconsPrefix = "Characteristics/Icons/";
|
||||
private static StaticIcons StaticIcons => EFTHardSettings.Instance.StaticIcons;
|
||||
internal const string IconsPrefix = "Characteristics/Icons/";
|
||||
internal static StaticIcons StaticIcons => EFTHardSettings.Instance.StaticIcons;
|
||||
|
||||
public IEnumerable<CustomInteraction> GetCustomInteractions(ItemUiContext context, EItemViewType viewType, Item item)
|
||||
{
|
||||
if (viewType is EItemViewType.Inventory)
|
||||
public IEnumerable<CustomInteraction> GetCustomInteractions(ItemUiContext uiContext, EItemViewType viewType, Item item)
|
||||
{
|
||||
if (viewType is not EItemViewType.Inventory)
|
||||
yield break;
|
||||
|
||||
FireModeComponent fireModeComponent = item.GetItemComponent<FireModeComponent>();
|
||||
if (fireModeComponent is not null)
|
||||
return GetFireModeInteractions(context, fireModeComponent);
|
||||
|
||||
SightComponent sightComponent = item.GetItemComponent<SightComponent>();
|
||||
if (sightComponent is not null)
|
||||
return GetSightInteractions(context, sightComponent);
|
||||
|
||||
LightComponent lightComponent = item.GetItemComponent<LightComponent>();
|
||||
if (lightComponent is not null)
|
||||
return GetLightInteractions(context, lightComponent);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetFireModeInteractions(ItemUiContext context, FireModeComponent component)
|
||||
{
|
||||
if (component.AvailableEFireModes.Length > 1)
|
||||
{
|
||||
yield return new(context)
|
||||
// Firing mode
|
||||
yield return new()
|
||||
{
|
||||
Caption = () => "Firing mode",
|
||||
Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.Weapon),
|
||||
SubMenu = () => GetFireModeSubInteractions(context, component),
|
||||
SubMenu = () => new FireModeSubMenu(uiContext, fireModeComponent),
|
||||
Enabled = () => fireModeComponent.AvailableEFireModes.Length > 1,
|
||||
Error = () => "This weapon is incapable of selective fire"
|
||||
};
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetFireModeSubInteractions(ItemUiContext context, FireModeComponent component)
|
||||
LightComponent lightComponent = item.GetItemComponent<LightComponent>();
|
||||
if (lightComponent is not null)
|
||||
{
|
||||
foreach (Weapon.EFireMode fireMode in component.AvailableEFireModes)
|
||||
// Turn on/off
|
||||
yield return new()
|
||||
{
|
||||
yield return new(context)
|
||||
Caption = () => (lightComponent.IsActive ? "TurnOff" : "TurnOn").Localized(),
|
||||
Icon = () => ResourceCache.Pop<Sprite>(IconsPrefix + (lightComponent.IsActive ? "TurnOff" : "TurnOn")),
|
||||
Action = () =>
|
||||
{
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetLightState(lightComponent, !lightComponent.IsActive, lightComponent.SelectedMode);
|
||||
uiContext.RedrawContextMenus([item.TemplateId]);
|
||||
}
|
||||
};
|
||||
// Switch mode
|
||||
yield return new()
|
||||
{
|
||||
Caption = () => "Switch mode",
|
||||
Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState),
|
||||
SubMenu = () => new LightModeSubMenu(uiContext, lightComponent),
|
||||
Enabled = () => lightComponent.GetModesCount() > 1,
|
||||
Error = () => "This device has no alternative modes"
|
||||
};
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class FireModeSubMenu : CustomSubInteractions
|
||||
{
|
||||
public FireModeSubMenu(ItemUiContext uiContext, FireModeComponent component)
|
||||
: base(uiContext)
|
||||
{
|
||||
AddRange(component.AvailableEFireModes.Select(fireMode => new CustomInteraction()
|
||||
{
|
||||
Caption = () => fireMode.ToString().Localized(),
|
||||
Action = () =>
|
||||
@ -77,137 +95,26 @@ internal sealed class CustomInteractionsProvider : ICustomInteractionsProvider
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetFireMode(component, fireMode);
|
||||
},
|
||||
Enabled = () => fireMode != component.FireMode,
|
||||
};
|
||||
}
|
||||
Enabled = () => fireMode != component.FireMode
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetSightInteractions(ItemUiContext context, SightComponent component)
|
||||
internal class LightModeSubMenu : CustomSubInteractions
|
||||
{
|
||||
public LightModeSubMenu(ItemUiContext uiContext, LightComponent component)
|
||||
: base(uiContext)
|
||||
{
|
||||
if (component.ScopesCount > 1)
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => "Active scope",
|
||||
Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState),
|
||||
SubMenu = () => GetScopeIndexSubInteractions(context, component),
|
||||
};
|
||||
}
|
||||
if (component.GetScopeModesCount(component.SelectedScope) > 1)
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => "Active mode",
|
||||
Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState),
|
||||
SubMenu = () => GetScopeModeSubInteractions(context, component),
|
||||
};
|
||||
}
|
||||
if (component.GetScopeCalibrationDistances(component.SelectedScope).Length > 1)
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => "Zero distance",
|
||||
Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState),
|
||||
SubMenu = () => GetScopeCalibSubInteractions(context, component),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetScopeIndexSubInteractions(ItemUiContext context, SightComponent component)
|
||||
{
|
||||
foreach (int scopeIndex in Enumerable.Range(0, component.ScopesCount))
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => $"Scope {scopeIndex + 1}",
|
||||
Action = () =>
|
||||
{
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetScopeIndex(component, scopeIndex);
|
||||
},
|
||||
Enabled = () => scopeIndex != component.SelectedScope,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetScopeModeSubInteractions(ItemUiContext context, SightComponent component)
|
||||
{
|
||||
int scopeIndex = component.SelectedScope;
|
||||
float[] scopeZooms = component.GetScopeZooms(scopeIndex);
|
||||
foreach (int scopeMode in Enumerable.Range(0, component.GetScopeModesCount(scopeIndex)))
|
||||
{
|
||||
float scopeZoom = scopeZooms.Length > 0 ? scopeZooms[scopeMode] : 0f;
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => $"Mode {scopeMode + 1} ({scopeZoom}x)",
|
||||
Action = () =>
|
||||
{
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetScopeMode(component, scopeMode);
|
||||
},
|
||||
Enabled = () => scopeMode != component.ScopesSelectedModes[scopeIndex],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetScopeCalibSubInteractions(ItemUiContext context, SightComponent component)
|
||||
{
|
||||
int scopeIndex = component.SelectedScope;
|
||||
int[] scopeCalibDistances = component.GetScopeCalibrationDistances(scopeIndex);
|
||||
foreach (int scopeCalibIndex in Enumerable.Range(0, scopeCalibDistances.Length))
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => $"{scopeCalibDistances[scopeCalibIndex]}",
|
||||
Action = () =>
|
||||
{
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetScopeCalibIndex(component, scopeCalibIndex);
|
||||
},
|
||||
Enabled = () => scopeCalibIndex != component.ScopesCurrentCalibPointIndexes[scopeIndex],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetLightInteractions(ItemUiContext context, LightComponent component)
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => component.IsActive ? "Turn off" : "Turn on",
|
||||
Icon = () => CacheResourcesPopAbstractClass.Pop<Sprite>(IconsPrefix + (component.IsActive ? "TurnOff" : "TurnOn")),
|
||||
Action = () =>
|
||||
{
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetLightActive(component, !component.IsActive);
|
||||
GlobalEvents.RequestGlobalRedraw();
|
||||
},
|
||||
};
|
||||
if (component.GetModesCount() > 1)
|
||||
{
|
||||
yield return new(context)
|
||||
{
|
||||
Caption = () => "Active mode",
|
||||
Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState),
|
||||
SubMenu = () => GetLightModeSubInteractions(context, component),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CustomInteraction> GetLightModeSubInteractions(ItemUiContext context, LightComponent component)
|
||||
{
|
||||
foreach (int lightMode in Enumerable.Range(0, component.GetModesCount()))
|
||||
{
|
||||
yield return new(context)
|
||||
AddRange(Enumerable.Range(0, component.GetModesCount()).Select(lightMode => new CustomInteraction()
|
||||
{
|
||||
Caption = () => $"Mode {lightMode + 1}",
|
||||
Action = () =>
|
||||
{
|
||||
Singleton<GUISounds>.Instance.PlayUISound(EUISoundType.MenuContextMenu);
|
||||
ComponentUtils.SetLightMode(component, lightMode);
|
||||
ComponentUtils.SetLightState(component, component.IsActive, lightMode);
|
||||
},
|
||||
Enabled = () => lightMode != component.SelectedMode,
|
||||
};
|
||||
}
|
||||
Enabled = () => lightMode != component.SelectedMode
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +129,7 @@ internal static class ComponentUtils
|
||||
if (fc.Item.MalfState.State is not Weapon.EMalfunctionState.None)
|
||||
{
|
||||
fc.FirearmsAnimator.MisfireSlideUnknown(false);
|
||||
player.InventoryController.ExamineMalfunction(fc.Item, false);
|
||||
player.GetInventoryController().ExamineMalfunction(fc.Item, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -233,89 +140,18 @@ internal static class ComponentUtils
|
||||
component.SetFireMode(fireMode);
|
||||
}
|
||||
|
||||
public static void SetScopeIndex(SightComponent component, int scopeIndex)
|
||||
{
|
||||
SetScopeState(component, new()
|
||||
{
|
||||
Id = component.Item.Id,
|
||||
ScopeIndexInsideSight = scopeIndex,
|
||||
ScopeMode = component.ScopesSelectedModes[scopeIndex],
|
||||
ScopeCalibrationIndex = component.ScopesCurrentCalibPointIndexes[scopeIndex],
|
||||
});
|
||||
}
|
||||
|
||||
public static void SetScopeMode(SightComponent component, int scopeMode)
|
||||
{
|
||||
int scopeIndex = component.SelectedScope;
|
||||
SetScopeState(component, new()
|
||||
{
|
||||
Id = component.Item.Id,
|
||||
ScopeIndexInsideSight = scopeIndex,
|
||||
ScopeMode = scopeMode,
|
||||
ScopeCalibrationIndex = component.ScopesCurrentCalibPointIndexes[scopeIndex],
|
||||
});
|
||||
}
|
||||
|
||||
public static void SetScopeCalibIndex(SightComponent component, int scopeCalibIndex)
|
||||
{
|
||||
int scopeIndex = component.SelectedScope;
|
||||
SetScopeState(component, new()
|
||||
{
|
||||
Id = component.Item.Id,
|
||||
ScopeIndexInsideSight = scopeIndex,
|
||||
ScopeMode = component.ScopesSelectedModes[scopeIndex],
|
||||
ScopeCalibrationIndex = scopeCalibIndex,
|
||||
});
|
||||
}
|
||||
|
||||
private static void SetScopeState(SightComponent component, FirearmScopeStateStruct scopeState)
|
||||
public static void SetLightState(LightComponent component, bool isActive, int lightMode)
|
||||
{
|
||||
Player player = GamePlayerOwner.MyPlayer;
|
||||
|
||||
if (player is not null && player.HandsController is Player.FirearmController fc && component.Item.IsChildOf(fc.Item))
|
||||
{
|
||||
fc.SetScopeMode([scopeState]);
|
||||
fc.SetLightsState([new() { Id = component.Item.Id, IsActive = isActive, LightMode = lightMode }]);
|
||||
return;
|
||||
}
|
||||
|
||||
int scopeIndex = scopeState.ScopeIndexInsideSight;
|
||||
component.SelectedScope = scopeIndex;
|
||||
component.ScopesSelectedModes[scopeIndex] = scopeState.ScopeMode;
|
||||
component.ScopesCurrentCalibPointIndexes[scopeIndex] = scopeState.ScopeCalibrationIndex;
|
||||
}
|
||||
|
||||
public static void SetLightActive(LightComponent component, bool isActive)
|
||||
{
|
||||
SetLightState(component, new()
|
||||
{
|
||||
Id = component.Item.Id,
|
||||
IsActive = isActive,
|
||||
LightMode = component.SelectedMode,
|
||||
});
|
||||
}
|
||||
|
||||
public static void SetLightMode(LightComponent component, int lightMode)
|
||||
{
|
||||
SetLightState(component, new()
|
||||
{
|
||||
Id = component.Item.Id,
|
||||
IsActive = component.IsActive,
|
||||
LightMode = lightMode,
|
||||
});
|
||||
}
|
||||
|
||||
private static void SetLightState(LightComponent component, FirearmLightStateStruct lightState)
|
||||
{
|
||||
Player player = GamePlayerOwner.MyPlayer;
|
||||
|
||||
if (player is not null && player.HandsController is Player.FirearmController fc && component.Item.IsChildOf(fc.Item))
|
||||
{
|
||||
fc.SetLightsState([lightState]);
|
||||
return;
|
||||
}
|
||||
|
||||
component.IsActive = lightState.IsActive;
|
||||
component.SelectedMode = lightState.LightMode;
|
||||
component.IsActive = isActive;
|
||||
component.SelectedMode = lightMode;
|
||||
|
||||
if (player is not null)
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.ItemContextMenuExt</AssemblyName>
|
||||
<Version>1.6.0</Version>
|
||||
<Version>1.2.1</Version>
|
||||
<RootNamespace>IcyClawz.ItemContextMenuExt</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
@ -27,9 +27,6 @@
|
||||
<Reference Include="ItemTemplate.Types">
|
||||
<HintPath>..\Shared\ItemTemplate.Types.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SPT.Reflection">
|
||||
<HintPath>..\Shared\spt-reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\Shared\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -1,35 +1,12 @@
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using EFT.UI;
|
||||
using IcyClawz.CustomInteractions;
|
||||
using SPT.Reflection.Patching;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IcyClawz.ItemContextMenuExt;
|
||||
|
||||
[BepInPlugin("com.IcyClawz.ItemContextMenuExt", "IcyClawz.ItemContextMenuExt", "1.6.0")]
|
||||
[BepInPlugin("com.IcyClawz.ItemContextMenuExt", "IcyClawz.ItemContextMenuExt", "1.2.1")]
|
||||
[BepInDependency("com.IcyClawz.CustomInteractions")]
|
||||
public class Plugin : BaseUnityPlugin
|
||||
{
|
||||
private static ConfigEntry<float> ScaleConfig { get; set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
const string SECTION = "Item Context Menu";
|
||||
ScaleConfig = Config.Bind(SECTION, "Scale", 1f);
|
||||
new ItemUiContextPatch().Enable();
|
||||
private void Awake() =>
|
||||
CustomInteractionsManager.Register(new CustomInteractionsProvider());
|
||||
}
|
||||
|
||||
internal static float Scale => ScaleConfig.Value;
|
||||
}
|
||||
|
||||
internal class ItemUiContextPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(ItemUiContext).GetMethod("ShowContextMenu", BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
[PatchPostfix]
|
||||
private static void Postfix(ref ItemUiContext __instance) =>
|
||||
__instance.ContextMenu.Transform.localScale = new(Plugin.Scale, Plugin.Scale);
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
using Aki.Reflection.Utils;
|
||||
using Comfort.Common;
|
||||
using EFT;
|
||||
using EFT.InventoryLogic;
|
||||
using SPT.Reflection.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
using CurrencyUtil = GClass2867;
|
||||
using CurrencyUtil = GClass2334;
|
||||
|
||||
namespace IcyClawz.ItemSellPrice;
|
||||
|
||||
@ -55,7 +55,7 @@ internal static class ItemExtensions
|
||||
["po"] = ["Preço de venda ({0})", "Não pode ser vendido a comerciantes"],
|
||||
["ru"] = ["Цена продажи ({0})", "Невозможно продать торговцам"],
|
||||
["sk"] = ["Predajná cena ({0})", "Nedá sa predať obchodníkom"],
|
||||
["tu"] = ["Satış fiyatı ({0})", "Tüccarlara satılamaz"],
|
||||
["tu"] = ["Satış fiyatı ({0})", "Tüccarlara satılamaz"]
|
||||
};
|
||||
|
||||
private static ISession _Session;
|
||||
@ -91,11 +91,11 @@ internal static class ItemExtensions
|
||||
FullStringValue = () =>
|
||||
{
|
||||
IEnumerable<TraderOffer> offers = GetAllTraderOffers(item);
|
||||
return offers.Any()
|
||||
return offers is not null
|
||||
? string.Join(Environment.NewLine, offers.Select(offer => $"{offer.Name}: {offer.Currency} {offer.Price}"))
|
||||
: "";
|
||||
},
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact
|
||||
};
|
||||
item.Attributes = [attribute, .. item.Attributes];
|
||||
}
|
||||
@ -111,34 +111,38 @@ internal static class ItemExtensions
|
||||
|
||||
private static TraderOffer GetTraderOffer(Item item, TraderClass trader)
|
||||
{
|
||||
var price = trader.GetUserItemPrice(item);
|
||||
return price.HasValue ? new(
|
||||
var result = trader.GetUserItemPrice(item);
|
||||
return result is null ? null : new(
|
||||
trader.LocalizedName,
|
||||
price.Value.Amount,
|
||||
CurrencyUtil.GetCurrencyCharById(price.Value.CurrencyId.Value),
|
||||
trader.GetSupplyData().CurrencyCourses[price.Value.CurrencyId.Value],
|
||||
result.Value.Amount,
|
||||
CurrencyUtil.GetCurrencyCharById(result.Value.CurrencyId),
|
||||
trader.GetSupplyData().CurrencyCourses[result.Value.CurrencyId],
|
||||
item.StackObjectsCount
|
||||
) : null;
|
||||
);
|
||||
}
|
||||
|
||||
private static IEnumerable<TraderOffer> GetAllTraderOffers(Item item)
|
||||
{
|
||||
if (!Session.Profile.Examined(item))
|
||||
return [];
|
||||
if (item.Owner?.OwnerType is EOwnerType.RagFair or EOwnerType.Trader
|
||||
&& (item.StackObjectsCount > 1 || item.UnlimitedCount))
|
||||
return null;
|
||||
switch (item.Owner?.OwnerType)
|
||||
{
|
||||
case EOwnerType.RagFair:
|
||||
case EOwnerType.Trader:
|
||||
if (item.StackObjectsCount > 1 || item.UnlimitedCount)
|
||||
{
|
||||
item = item.CloneItem();
|
||||
item.StackObjectsCount = 1;
|
||||
item.UnlimitedCount = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return Session.Traders
|
||||
.Where(trader => !trader.Settings.AvailableInRaid)
|
||||
.Select(trader => GetTraderOffer(item, trader))
|
||||
.Where(offer => offer is not null)
|
||||
.OrderByDescending(offer => offer.Price * offer.Course);
|
||||
}
|
||||
|
||||
private static TraderOffer GetBestTraderOffer(Item item) =>
|
||||
GetAllTraderOffers(item).FirstOrDefault();
|
||||
GetAllTraderOffers(item)?.FirstOrDefault() ?? null;
|
||||
}
|
@ -3,12 +3,15 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.ItemSellPrice</AssemblyName>
|
||||
<Version>1.5.0</Version>
|
||||
<Version>1.2.1</Version>
|
||||
<RootNamespace>IcyClawz.ItemSellPrice</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Aki.Reflection">
|
||||
<HintPath>..\Shared\Aki.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\Shared\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
@ -18,9 +21,6 @@
|
||||
<Reference Include="Comfort">
|
||||
<HintPath>..\Shared\Comfort.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SPT.Reflection">
|
||||
<HintPath>..\Shared\spt-reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\Shared\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -1,20 +1,20 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using BepInEx;
|
||||
using EFT;
|
||||
using EFT.InventoryLogic;
|
||||
using SPT.Reflection.Patching;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IcyClawz.ItemSellPrice;
|
||||
|
||||
[BepInPlugin("com.IcyClawz.ItemSellPrice", "IcyClawz.ItemSellPrice", "1.5.0")]
|
||||
[BepInPlugin("com.IcyClawz.ItemSellPrice", "IcyClawz.ItemSellPrice", "1.2.1")]
|
||||
public class Plugin : BaseUnityPlugin
|
||||
{
|
||||
private void Awake()
|
||||
{
|
||||
new TraderPatch().Enable();
|
||||
new ItemPatch().Enable();
|
||||
new AmmoItemPatch().Enable();
|
||||
new ThrowWeapItemPatch().Enable();
|
||||
new AmmoPatch().Enable();
|
||||
new GrenadePatch().Enable();
|
||||
new SecureContainerPatch().Enable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,22 +38,32 @@ internal class ItemPatch : ModulePatch
|
||||
__instance.AddTraderOfferAttribute();
|
||||
}
|
||||
|
||||
internal class AmmoItemPatch : ModulePatch
|
||||
internal class AmmoPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(AmmoItemClass).GetConstructors()[0];
|
||||
typeof(BulletClass).GetConstructors()[0];
|
||||
|
||||
[PatchPostfix]
|
||||
private static void PatchPostfix(ref AmmoItemClass __instance) =>
|
||||
private static void PatchPostfix(ref BulletClass __instance) =>
|
||||
__instance.AddTraderOfferAttribute();
|
||||
}
|
||||
|
||||
internal class ThrowWeapItemPatch : ModulePatch
|
||||
internal class GrenadePatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(ThrowWeapItemClass).GetConstructors()[0];
|
||||
typeof(GrenadeClass).GetConstructors()[0];
|
||||
|
||||
[PatchPostfix]
|
||||
private static void PatchPostfix(ref ThrowWeapItemClass __instance) =>
|
||||
private static void PatchPostfix(ref GrenadeClass __instance) =>
|
||||
__instance.AddTraderOfferAttribute();
|
||||
}
|
||||
|
||||
internal class SecureContainerPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(ItemContainerClass).GetConstructors()[0];
|
||||
|
||||
[PatchPostfix]
|
||||
private static void PatchPostfix(ref ItemContainerClass __instance) =>
|
||||
__instance.AddTraderOfferAttribute();
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
using Aki.Reflection.Utils;
|
||||
using Comfort.Common;
|
||||
using EFT;
|
||||
using EFT.InventoryLogic;
|
||||
using SPT.Reflection.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
using InGameStatus = GClass2064;
|
||||
using InGameStatus = GClass1716;
|
||||
|
||||
namespace IcyClawz.MagazineInspector;
|
||||
|
||||
@ -30,7 +30,7 @@ internal static class MagazineClassExtensions
|
||||
["po"] = "Munição carregada",
|
||||
["ru"] = "Заряженные боеприпасы",
|
||||
["sk"] = "Nabitá munícia",
|
||||
["tu"] = "Yüklü mühimmat",
|
||||
["tu"] = "Yüklü mühimmat"
|
||||
};
|
||||
|
||||
private static ISession _Session;
|
||||
@ -38,7 +38,7 @@ internal static class MagazineClassExtensions
|
||||
|
||||
private static Profile ActiveProfile => InGameStatus.InRaid ? GamePlayerOwner.MyPlayer.Profile : Session.Profile;
|
||||
|
||||
public static void AddAmmoCountAttribute(this MagazineItemClass magazine)
|
||||
public static void AddAmmoCountAttribute(this MagazineClass magazine)
|
||||
{
|
||||
ItemAttributeClass attribute = magazine.Attributes.Find(attr => attr.Id is EItemAttributeId.MaxCount);
|
||||
if (attribute is null)
|
||||
@ -74,7 +74,7 @@ internal static class MagazineClassExtensions
|
||||
};
|
||||
}
|
||||
|
||||
private static int? GetAmmoCount(MagazineItemClass magazine, Profile profile, out bool magChecked)
|
||||
private static int? GetAmmoCount(MagazineClass magazine, Profile profile, out bool magChecked)
|
||||
{
|
||||
if (!InGameStatus.InRaid || magazine.Count == 0)
|
||||
{
|
||||
|
@ -3,12 +3,15 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.MagazineInspector</AssemblyName>
|
||||
<Version>1.5.0</Version>
|
||||
<Version>1.2.1</Version>
|
||||
<RootNamespace>IcyClawz.MagazineInspector</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Aki.Reflection">
|
||||
<HintPath>..\Shared\Aki.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\Shared\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
@ -18,9 +21,6 @@
|
||||
<Reference Include="Comfort">
|
||||
<HintPath>..\Shared\Comfort.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SPT.Reflection">
|
||||
<HintPath>..\Shared\spt-reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\Shared\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -1,10 +1,10 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using BepInEx;
|
||||
using SPT.Reflection.Patching;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IcyClawz.MagazineInspector;
|
||||
|
||||
[BepInPlugin("com.IcyClawz.MagazineInspector", "IcyClawz.MagazineInspector", "1.5.0")]
|
||||
[BepInPlugin("com.IcyClawz.MagazineInspector", "IcyClawz.MagazineInspector", "1.2.1")]
|
||||
public class Plugin : BaseUnityPlugin
|
||||
{
|
||||
private void Awake() =>
|
||||
@ -14,9 +14,9 @@ public class Plugin : BaseUnityPlugin
|
||||
internal class MagazinePatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(MagazineItemClass).GetConstructors()[0];
|
||||
typeof(MagazineClass).GetConstructors()[0];
|
||||
|
||||
[PatchPostfix]
|
||||
private static void PatchPostfix(ref MagazineItemClass __instance) =>
|
||||
private static void PatchPostfix(ref MagazineClass __instance) =>
|
||||
__instance.AddAmmoCountAttribute();
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ internal sealed class ConfigurationManagerAttributes
|
||||
/// Custom setting editor (OnGUI code that replaces the default editor provided by ConfigurationManager).
|
||||
/// See below for a deeper explanation. Using a custom drawer will cause many of the other fields to do nothing.
|
||||
/// </summary>
|
||||
public System.Action<ConfigEntryBase> CustomDrawer;
|
||||
public System.Action<BepInEx.Configuration.ConfigEntryBase> CustomDrawer;
|
||||
|
||||
/// <summary>
|
||||
/// Show this setting in the settings screen at all? If false, don't show.
|
||||
|
@ -31,7 +31,7 @@ internal static class ColorCache
|
||||
[ColorName.Silver] = new Color32(150, 150, 150, ALPHA),
|
||||
[ColorName.Tan] = new Color32(175, 145, 100, ALPHA),
|
||||
[ColorName.Violet] = new Color32(80, 50, 180, ALPHA),
|
||||
[ColorName.Yellow] = new Color32(170, 170, 0, ALPHA),
|
||||
[ColorName.Yellow] = new Color32(170, 170, 0, ALPHA)
|
||||
};
|
||||
|
||||
public static Color Get(ColorName name) => Cache.TryGetValue(name, out Color color) ? color : default;
|
||||
@ -39,7 +39,7 @@ internal static class ColorCache
|
||||
|
||||
internal enum EAmmoExtraAttributeId
|
||||
{
|
||||
ArmorDamage, FragmentationChance, RicochetChance
|
||||
Damage, PenetrationPower, ArmorDamage, FragmentationChance, RicochetChance
|
||||
}
|
||||
|
||||
internal static class ImageExtensions
|
||||
@ -48,8 +48,8 @@ internal static class ImageExtensions
|
||||
{
|
||||
using MemoryStream ms = new();
|
||||
instance.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
||||
Texture2D texture = new(instance.Width, instance.Height, TextureFormat.RGBA32, false);
|
||||
texture.LoadImage(ms.ToArray());
|
||||
Texture2D texture = new(instance.Width, instance.Height);
|
||||
ImageConversion.LoadImage(texture, ms.ToArray());
|
||||
return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
|
||||
}
|
||||
}
|
||||
@ -58,9 +58,11 @@ internal static class IconCache
|
||||
{
|
||||
private static readonly Dictionary<Enum, Sprite> Cache = new()
|
||||
{
|
||||
[EAmmoExtraAttributeId.Damage] = Properties.Resources.Damage.ToSprite(),
|
||||
[EAmmoExtraAttributeId.PenetrationPower] = Properties.Resources.PenetrationPower.ToSprite(),
|
||||
[EAmmoExtraAttributeId.ArmorDamage] = Properties.Resources.ArmorDamage.ToSprite(),
|
||||
[EAmmoExtraAttributeId.FragmentationChance] = Properties.Resources.FragmentationChance.ToSprite(),
|
||||
[EAmmoExtraAttributeId.RicochetChance] = Properties.Resources.RicochetChance.ToSprite(),
|
||||
[EAmmoExtraAttributeId.RicochetChance] = Properties.Resources.RicochetChance.ToSprite()
|
||||
};
|
||||
|
||||
public static Sprite Get(Enum id) => Cache.TryGetValue(id, out Sprite sprite) ? sprite : default;
|
||||
@ -68,15 +70,6 @@ internal static class IconCache
|
||||
|
||||
internal static class AmmoTemplateExtensions
|
||||
{
|
||||
private static readonly string[] MalfChancesKeys = (string[])
|
||||
typeof(AmmoTemplate).GetField("MalfChancesKeys", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
|
||||
|
||||
private static readonly FieldInfo MaxMalfMisfireChance =
|
||||
typeof(AmmoTemplate).GetField("MaxMalfMisfireChance", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
private static readonly FieldInfo MaxMalfFeedChance =
|
||||
typeof(AmmoTemplate).GetField("MaxMalfFeedChance", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
private static readonly FieldInfo CachedQualitiesField =
|
||||
typeof(AmmoTemplate).GetField("_cachedQualities", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
@ -85,33 +78,41 @@ internal static class AmmoTemplateExtensions
|
||||
|
||||
public static void AddExtraAttributes(this AmmoTemplate instance)
|
||||
{
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.Damage)
|
||||
{
|
||||
Name = EAmmoExtraAttributeId.Damage.ToString(),
|
||||
DisplayNameFunc = () => "Damage",
|
||||
Base = () => instance.Damage * instance.ProjectileCount,
|
||||
StringValue = () =>
|
||||
{
|
||||
int totalDamage = instance.Damage * instance.ProjectileCount;
|
||||
return instance.ProjectileCount > 1
|
||||
? $"{instance.ProjectileCount} × {instance.Damage} = {totalDamage}"
|
||||
: totalDamage.ToString();
|
||||
},
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.PenetrationPower)
|
||||
{
|
||||
Name = EAmmoExtraAttributeId.PenetrationPower.ToString(),
|
||||
DisplayNameFunc = () => "Penetration power",
|
||||
Base = () => instance.PenetrationPower,
|
||||
StringValue = () =>
|
||||
{
|
||||
int armorClass = instance.GetPenetrationArmorClass();
|
||||
return (armorClass > 0 ? $"Class {armorClass}" : "Unarmored") + $" ({instance.PenetrationPower})";
|
||||
},
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.ArmorDamage)
|
||||
{
|
||||
Name = EAmmoExtraAttributeId.ArmorDamage.ToString(),
|
||||
DisplayNameFunc = () => "Armor damage",
|
||||
Base = () => instance.ArmorDamage,
|
||||
StringValue = () => $"{instance.ArmorDamage}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EItemAttributeId.DurabilityBurn)
|
||||
{
|
||||
Name = EItemAttributeId.DurabilityBurn.GetName(),
|
||||
Base = () => instance.DurabilityBurnModificator - 1f,
|
||||
StringValue = () => $"{(instance.DurabilityBurnModificator - 1f) * 100f:F1}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
LabelVariations = EItemAttributeLabelVariations.Colored,
|
||||
LessIsGood = true,
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EItemAttributeId.HeatFactor)
|
||||
{
|
||||
Name = EItemAttributeId.HeatFactor.GetName(),
|
||||
Base = () => instance.HeatFactor - 1f,
|
||||
StringValue = () => $"{(instance.HeatFactor - 1f) * 100f:F1}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
LabelVariations = EItemAttributeLabelVariations.Colored,
|
||||
LessIsGood = true,
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.FragmentationChance)
|
||||
@ -119,8 +120,8 @@ internal static class AmmoTemplateExtensions
|
||||
Name = EAmmoExtraAttributeId.FragmentationChance.ToString(),
|
||||
DisplayNameFunc = () => "Fragmentation chance",
|
||||
Base = () => instance.FragmentationChance,
|
||||
StringValue = () => $"{instance.FragmentationChance * 100f:F1}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
StringValue = () => $"{Math.Round(instance.FragmentationChance * 100, 1)}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.RicochetChance)
|
||||
@ -128,44 +129,8 @@ internal static class AmmoTemplateExtensions
|
||||
Name = EAmmoExtraAttributeId.RicochetChance.ToString(),
|
||||
DisplayNameFunc = () => "Ricochet chance",
|
||||
Base = () => instance.RicochetChance,
|
||||
StringValue = () => $"{(instance.RicochetChance * 100f):F1}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EItemAttributeId.MalfMisfireChance)
|
||||
{
|
||||
Name = EItemAttributeId.MalfMisfireChance.GetName(),
|
||||
Base = () => instance.MalfMisfireChance,
|
||||
StringValue = () =>
|
||||
{
|
||||
float maxMalfMisfireChance = (float)MaxMalfMisfireChance.GetValue(null);
|
||||
int index = instance.MalfMisfireChance <= 0f ? 0
|
||||
: instance.MalfMisfireChance < 3f * maxMalfMisfireChance / 7f ? 1
|
||||
: instance.MalfMisfireChance < 4f * maxMalfMisfireChance / 7f ? 2
|
||||
: instance.MalfMisfireChance < 5f * maxMalfMisfireChance / 7f ? 3
|
||||
: instance.MalfMisfireChance < 6f * maxMalfMisfireChance / 7f ? 4
|
||||
: 5;
|
||||
return MalfChancesKeys[index].Localized();
|
||||
},
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
});
|
||||
|
||||
instance.SafelyAddQualityToList(new ItemAttributeClass(EItemAttributeId.MalfFeedChance)
|
||||
{
|
||||
Name = EItemAttributeId.MalfFeedChance.GetName(),
|
||||
Base = () => instance.MalfFeedChance,
|
||||
StringValue = () =>
|
||||
{
|
||||
float maxMalfFeedChance = (float)MaxMalfFeedChance.GetValue(null);
|
||||
int index = instance.MalfFeedChance <= 0f ? 0
|
||||
: instance.MalfFeedChance < 1f * maxMalfFeedChance / 7f ? 1
|
||||
: instance.MalfFeedChance < 3f * maxMalfFeedChance / 7f ? 2
|
||||
: instance.MalfFeedChance < 5f * maxMalfFeedChance / 7f ? 3
|
||||
: instance.MalfFeedChance < 6f * maxMalfFeedChance / 7f ? 4
|
||||
: 5;
|
||||
return MalfChancesKeys[index].Localized();
|
||||
},
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact,
|
||||
StringValue = () => $"{Math.Round(instance.RicochetChance * 100, 1)}%",
|
||||
DisplayType = () => EItemAttributeDisplayType.Compact
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,15 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>IcyClawz.MunitionsExpert</AssemblyName>
|
||||
<Version>1.5.0</Version>
|
||||
<Version>1.2.1</Version>
|
||||
<RootNamespace>IcyClawz.MunitionsExpert</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Aki.Reflection">
|
||||
<HintPath>..\Shared\Aki.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\Shared\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
@ -21,9 +24,6 @@
|
||||
<Reference Include="Sirenix.Serialization">
|
||||
<HintPath>..\Shared\Sirenix.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SPT.Reflection">
|
||||
<HintPath>..\Shared\spt-reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>..\Shared\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -1,10 +1,10 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using EFT.HandBook;
|
||||
using EFT.InventoryLogic;
|
||||
using EFT.UI;
|
||||
using EFT.UI.DragAndDrop;
|
||||
using SPT.Reflection.Patching;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
@ -13,24 +13,24 @@ using UnityEngine.UI;
|
||||
|
||||
namespace IcyClawz.MunitionsExpert;
|
||||
|
||||
[BepInPlugin("com.IcyClawz.MunitionsExpert", "IcyClawz.MunitionsExpert", "1.5.0")]
|
||||
[BepInPlugin("com.IcyClawz.MunitionsExpert", "IcyClawz.MunitionsExpert", "1.2.1")]
|
||||
public class Plugin : BaseUnityPlugin
|
||||
{
|
||||
private static ConfigEntry<bool> ColorizeConfig { get; set; }
|
||||
private static ConfigEntry<ColorName>[] ArmorClassColorConfigs { get; set; }
|
||||
private static ConfigEntry<bool> ColorizeSwitch { get; set; }
|
||||
private static ConfigEntry<ColorName>[] ArmorClassColors { get; set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
const string SECTION = "Colorize Icon Backgrounds";
|
||||
ColorizeConfig = Config.Bind(SECTION, "", true, new ConfigurationManagerAttributes { Order = 7 });
|
||||
ArmorClassColorConfigs = [
|
||||
Config.Bind(SECTION, "Unarmored", ColorName.Purple, new ConfigurationManagerAttributes { Order = 6 }),
|
||||
Config.Bind(SECTION, "Class 1", ColorName.Blue, new ConfigurationManagerAttributes { Order = 5 }),
|
||||
Config.Bind(SECTION, "Class 2", ColorName.Cyan, new ConfigurationManagerAttributes { Order = 4 }),
|
||||
Config.Bind(SECTION, "Class 3", ColorName.Green, new ConfigurationManagerAttributes { Order = 3 }),
|
||||
Config.Bind(SECTION, "Class 4", ColorName.Yellow, new ConfigurationManagerAttributes { Order = 2 }),
|
||||
Config.Bind(SECTION, "Class 5", ColorName.Orange, new ConfigurationManagerAttributes { Order = 1 }),
|
||||
Config.Bind(SECTION, "Class 6+", ColorName.Red, new ConfigurationManagerAttributes { Order = 0 }),
|
||||
const string COLORIZE = "Colorize Icon Backgrounds";
|
||||
ColorizeSwitch = Config.Bind(COLORIZE, "", true, new ConfigurationManagerAttributes { Order = 7 });
|
||||
ArmorClassColors = [
|
||||
Config.Bind(COLORIZE, "Unarmored", ColorName.Purple, new ConfigurationManagerAttributes { Order = 6 }),
|
||||
Config.Bind(COLORIZE, "Class 1", ColorName.Blue, new ConfigurationManagerAttributes { Order = 5 }),
|
||||
Config.Bind(COLORIZE, "Class 2", ColorName.Cyan, new ConfigurationManagerAttributes { Order = 4 }),
|
||||
Config.Bind(COLORIZE, "Class 3", ColorName.Green, new ConfigurationManagerAttributes { Order = 3 }),
|
||||
Config.Bind(COLORIZE, "Class 4", ColorName.Yellow, new ConfigurationManagerAttributes { Order = 2 }),
|
||||
Config.Bind(COLORIZE, "Class 5", ColorName.Orange, new ConfigurationManagerAttributes { Order = 1 }),
|
||||
Config.Bind(COLORIZE, "Class 6+", ColorName.Red, new ConfigurationManagerAttributes { Order = 0 })
|
||||
];
|
||||
new StaticIconsPatch().Enable();
|
||||
new AmmoTemplatePatch().Enable();
|
||||
@ -38,12 +38,12 @@ public class Plugin : BaseUnityPlugin
|
||||
new EntityIconPatch().Enable();
|
||||
}
|
||||
|
||||
internal static bool Colorize => ColorizeConfig.Value;
|
||||
internal static bool Colorize => ColorizeSwitch.Value;
|
||||
|
||||
internal static Color GetArmorClassColor(int index)
|
||||
{
|
||||
index = Mathf.Clamp(index, 0, ArmorClassColorConfigs.Length - 1);
|
||||
return ColorCache.Get(ArmorClassColorConfigs[index].Value);
|
||||
index = Mathf.Clamp(index, 0, ArmorClassColors.Length - 1);
|
||||
return ColorCache.Get(ArmorClassColors[index].Value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,14 +82,14 @@ internal class ItemViewPatch : ModulePatch
|
||||
typeof(ItemView).GetField("BackgroundColor", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
protected override MethodBase GetTargetMethod() =>
|
||||
typeof(ItemView).GetMethod("UpdateColor", BindingFlags.Public | BindingFlags.Instance);
|
||||
typeof(ItemView).GetMethod("UpdateColor", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
[PatchPrefix]
|
||||
private static void PatchPrefix(ref ItemView __instance)
|
||||
{
|
||||
if (!Plugin.Colorize || __instance.Item is not AmmoItemClass ammo || ammo.PenetrationPower <= 0)
|
||||
if (!Plugin.Colorize || __instance.Item is not BulletClass bullet || bullet.PenetrationPower <= 0)
|
||||
return;
|
||||
int armorClass = ammo.AmmoTemplate.GetPenetrationArmorClass();
|
||||
int armorClass = bullet.AmmoTemplate.GetPenetrationArmorClass();
|
||||
BackgroundColorField.SetValue(__instance, Plugin.GetArmorClassColor(armorClass));
|
||||
}
|
||||
}
|
||||
@ -105,11 +105,10 @@ internal class EntityIconPatch : ModulePatch
|
||||
[PatchPostfix]
|
||||
private static void PatchPostfix(ref EntityIcon __instance, Item item)
|
||||
{
|
||||
if (!Plugin.Colorize || item is not AmmoItemClass ammo || ammo.PenetrationPower <= 0)
|
||||
if (!Plugin.Colorize || item is not BulletClass bullet || bullet.PenetrationPower <= 0)
|
||||
return;
|
||||
if (ColorPanelField.GetValue(__instance) is not Image image)
|
||||
return;
|
||||
int armorClass = ammo.AmmoTemplate.GetPenetrationArmorClass();
|
||||
int armorClass = bullet.AmmoTemplate.GetPenetrationArmorClass();
|
||||
if (ColorPanelField.GetValue(__instance) is Image image)
|
||||
image.color = Plugin.GetArmorClassColor(armorClass);
|
||||
}
|
||||
}
|
||||
|
20
MunitionsExpert/Properties/Resources.Designer.cs
generated
20
MunitionsExpert/Properties/Resources.Designer.cs
generated
@ -70,6 +70,16 @@ internal class Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Damage {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Damage", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
@ -80,6 +90,16 @@ internal class Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap PenetrationPower {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("PenetrationPower", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -121,9 +121,15 @@
|
||||
<data name="ArmorDamage" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ArmorDamage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Damage" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Damage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="FragmentationChance" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\FragmentationChance.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="PenetrationPower" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\PenetrationPower.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="RicochetChance" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\RicochetChance.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
|
BIN
MunitionsExpert/Resources/Damage.png
Normal file
BIN
MunitionsExpert/Resources/Damage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 764 B |
BIN
MunitionsExpert/Resources/PenetrationPower.png
Normal file
BIN
MunitionsExpert/Resources/PenetrationPower.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 468 B |
Loading…
x
Reference in New Issue
Block a user