Color full panel bars, swap containers, fix black text, fix non-delta parens
This commit is contained in:
@@ -8,7 +8,7 @@ using System.Reflection;
|
||||
|
||||
namespace UIFixes
|
||||
{
|
||||
internal class ContainerStackPatch : ModulePatch
|
||||
public class ContainerStackPatch : ModulePatch
|
||||
{
|
||||
private static Type MergeableItemType;
|
||||
|
||||
|
@@ -21,18 +21,23 @@ namespace UIFixes
|
||||
|
||||
private static FieldInfo ItemComponentItemField;
|
||||
|
||||
private static FieldInfo CompactCharacteristicPanelItemAttributeField;
|
||||
|
||||
public static void Enable()
|
||||
{
|
||||
AttributeCompactPanelDictionaryField = AccessTools.GetDeclaredFields(typeof(ItemSpecificationPanel)).First(f => typeof(IEnumerable<KeyValuePair<ItemAttributeClass, CompactCharacteristicPanel>>).IsAssignableFrom(f.FieldType));
|
||||
AttributeCompactDropdownDictionaryField = AccessTools.GetDeclaredFields(typeof(ItemSpecificationPanel)).First(f => typeof(IEnumerable<KeyValuePair<ItemAttributeClass, CompactCharacteristicDropdownPanel>>).IsAssignableFrom(f.FieldType));
|
||||
|
||||
Type ItemComponentType = PatchConstants.EftTypes.First(t => typeof(IItemComponent).IsAssignableFrom(t) && AccessTools.Field(t, "Item") != null);
|
||||
ItemComponentItemField = AccessTools.Field(ItemComponentType, "Item");
|
||||
Type itemComponentType = PatchConstants.EftTypes.First(t => typeof(IItemComponent).IsAssignableFrom(t) && t.GetField("Item") != null); // GClass2754
|
||||
ItemComponentItemField = AccessTools.Field(itemComponentType, "Item");
|
||||
|
||||
CompactCharacteristicPanelItemAttributeField = AccessTools.Field(typeof(CompactCharacteristicPanel), "ItemAttribute");
|
||||
|
||||
new InjectButtonPatch().Enable();
|
||||
new LoadModStatsPatch().Enable();
|
||||
new CompareModPatch().Enable();
|
||||
new FormatValuesPatch().Enable();
|
||||
new FormatCompactValuesPatch().Enable();
|
||||
new FormatFullValuesPatch().Enable();
|
||||
}
|
||||
|
||||
private class LoadModStatsPatch : ModulePatch
|
||||
@@ -238,105 +243,133 @@ namespace UIFixes
|
||||
}
|
||||
}
|
||||
|
||||
private class FormatValuesPatch : ModulePatch
|
||||
private class FormatCompactValuesPatch : ModulePatch
|
||||
{
|
||||
// These fields are percents, but have been manually multipied by 100 already
|
||||
private static EItemAttributeId[] NonPercentPercents = [EItemAttributeId.ChangeMovementSpeed, EItemAttributeId.ChangeTurningSpeed, EItemAttributeId.Ergonomics];
|
||||
|
||||
private static FieldInfo ItemAttributeField;
|
||||
private static FieldInfo IncreasingColorField;
|
||||
private static FieldInfo DecreasingColorField;
|
||||
|
||||
protected override MethodBase GetTargetMethod()
|
||||
{
|
||||
ItemAttributeField = AccessTools.Field(typeof(CompactCharacteristicPanel), "ItemAttribute");
|
||||
IncreasingColorField = AccessTools.Field(typeof(CompactCharacteristicPanel), "_increasingColor");
|
||||
DecreasingColorField = AccessTools.Field(typeof(CompactCharacteristicPanel), "_decreasingColor");
|
||||
|
||||
return AccessTools.Method(typeof(CompactCharacteristicPanel), "SetValues");
|
||||
}
|
||||
|
||||
[PatchPostfix]
|
||||
private static void Postfix(CompactCharacteristicPanel __instance, TextMeshProUGUI ___ValueText)
|
||||
{
|
||||
// Comparisons are shown as <value>(<changed>)
|
||||
// <value> is from each attribute type's StringValue() function, so is formatted *mostly* ok
|
||||
// <changed> is just naively formatted with ToString("F2"), so I have to figure out what it is and fix that
|
||||
// This method is a gnarly pile of regex and replacements, blame BSG
|
||||
try
|
||||
{
|
||||
FormatText(__instance, ___ValueText);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Color increasingColor = (Color)IncreasingColorField.GetValue(__instance);
|
||||
string increasingColorHex = "#" + ColorUtility.ToHtmlStringRGB(increasingColor);
|
||||
private class FormatFullValuesPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod()
|
||||
{
|
||||
return AccessTools.Method(typeof(CharacteristicPanel), "SetValues");
|
||||
}
|
||||
|
||||
Color decreasingColor = (Color)DecreasingColorField.GetValue(__instance);
|
||||
string decreasingColorHex = "#" + ColorUtility.ToHtmlStringRGB(decreasingColor);
|
||||
[PatchPostfix]
|
||||
private static void Postfix(CharacteristicPanel __instance, TextMeshProUGUI ___ValueText)
|
||||
{
|
||||
try
|
||||
{
|
||||
FormatText(__instance, ___ValueText);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string text = ___ValueText.text;
|
||||
ItemAttributeClass attribute = ItemAttributeField.GetValue(__instance) as ItemAttributeClass;
|
||||
// These fields are percents, but have been manually multipied by 100 already
|
||||
private static readonly EItemAttributeId[] NonPercentPercents = [EItemAttributeId.ChangeMovementSpeed, EItemAttributeId.ChangeTurningSpeed, EItemAttributeId.Ergonomics];
|
||||
|
||||
// Some percents are formatted with ToString("P1"), which puts a space before the %. These are percents from 0-1, so the <changed> value need to be converted
|
||||
var match = Regex.Match(text, @" %\((.*)\)");
|
||||
private static void FormatText(CompactCharacteristicPanel panel, TextMeshProUGUI textMesh)
|
||||
{
|
||||
// Comparisons are shown as <value>(<changed>)
|
||||
// <value> is from each attribute type's StringValue() function, so is formatted *mostly* ok
|
||||
// <changed> is just naively formatted with ToString("F2"), so I have to figure out what it is and fix that
|
||||
// This method is a gnarly pile of regex and replacements, blame BSG
|
||||
if (!Settings.StyleItemPanel.Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// These come from CompactCharacteristicPanel._increasingColor and _decreasingColor, which are hardcoded. Hardcoding here too because
|
||||
// CharacteristicPanel doesn't define and you get clear
|
||||
const string IncreasingColorHex = "#5EC1FF";
|
||||
const string DecreasingColorHex = "#C40000";
|
||||
|
||||
string text = textMesh.text;
|
||||
ItemAttributeClass attribute = CompactCharacteristicPanelItemAttributeField.GetValue(panel) as ItemAttributeClass;
|
||||
|
||||
// Some percents are formatted with ToString("P1"), which puts a space before the %. These are percents from 0-1, so the <changed> value need to be converted
|
||||
var match = Regex.Match(text, @" %\(([+-].*)\)");
|
||||
if (match.Success)
|
||||
{
|
||||
float value;
|
||||
// If this fails to parse, I don't know what it is, leave it be
|
||||
if (float.TryParse(match.Groups[1].Value, out value))
|
||||
{
|
||||
string sign = value > 0 ? "+" : "";
|
||||
string color = (attribute.LessIsGood && value < 0) || (!attribute.LessIsGood && value > 0) ? IncreasingColorHex : DecreasingColorHex;
|
||||
|
||||
// Except some that have a space weren't actually formatted with P1 and are 0-100 with a manually added " %"
|
||||
if (NonPercentPercents.Contains((EItemAttributeId)attribute.Id))
|
||||
{
|
||||
text = Regex.Replace(text, @"%\([+-].*\)", "%<color=" + color + ">(" + sign + value + "%)</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
text = Regex.Replace(text, @"%\([+-].*\)", "%<color=" + color + ">(" + sign + value.ToString("P1") + ")</color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Others are rendered as num + "%", so there's no space before the %. These are percents but are from 0-100, not 0-1.
|
||||
match = Regex.Match(text, @"(\S)%\(([+-].*)\)");
|
||||
if (match.Success)
|
||||
{
|
||||
float value;
|
||||
// If this fails to parse, I don't know what it is, leave it be
|
||||
if (float.TryParse(match.Groups[1].Value, out value))
|
||||
if (float.TryParse(match.Groups[2].Value, out value))
|
||||
{
|
||||
string sign = value > 0 ? "+" : "";
|
||||
string color = (attribute.LessIsGood && value < 0) || (!attribute.LessIsGood && value > 0) ? increasingColorHex : decreasingColorHex;
|
||||
|
||||
// Except some that have a space weren't actually formatted with P1 and are 0-100 with a manually added " %"
|
||||
if (NonPercentPercents.Contains((EItemAttributeId)attribute.Id))
|
||||
{
|
||||
text = Regex.Replace(text, @"%\(.*\)", "%<color=" + color + ">(" + sign + value + "%)</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
text = Regex.Replace(text, @"%\(.*\)", "%<color=" + color + ">(" + sign + value.ToString("P1") + ")</color>");
|
||||
}
|
||||
string color = (attribute.LessIsGood && value < 0) || (!attribute.LessIsGood && value > 0) ? IncreasingColorHex : DecreasingColorHex;
|
||||
text = Regex.Replace(text, @"(\S)%\(([+-].*)\)", match.Groups[1].Value + "%<color=" + color + ">(" + sign + value + "%)</color>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Others are rendered as num + "%", so there's no space before the %. These are percents but are from 0-100, not 0-1.
|
||||
match = Regex.Match(text, @"(\S)%\((.*)\)");
|
||||
// Finally the ones that aren't percents
|
||||
match = Regex.Match(text, @"\(([+-].*)\)");
|
||||
if (match.Success)
|
||||
{
|
||||
float value;
|
||||
// If this fails to parse, I don't know what it is, leave it be
|
||||
if (float.TryParse(match.Groups[2].Value, out value))
|
||||
if (float.TryParse(match.Groups[1].Value, out value))
|
||||
{
|
||||
string sign = value > 0 ? "+" : "";
|
||||
string color = (attribute.LessIsGood && value < 0) || (!attribute.LessIsGood && value > 0) ? increasingColorHex : decreasingColorHex;
|
||||
text = Regex.Replace(text, @"(\S)%\((.*)\)", match.Groups[1].Value + "%<color=" + color + ">(" + sign + value + "%)</color>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Finally the ones that aren't percents
|
||||
match = Regex.Match(text, @"\((.*)\)");
|
||||
if (match.Success)
|
||||
{
|
||||
float value;
|
||||
// If this fails to parse, I don't know what it is, leave it be
|
||||
if (float.TryParse(match.Groups[1].Value, out value))
|
||||
{
|
||||
string sign = value > 0 ? "+" : "";
|
||||
string color = (attribute.LessIsGood && value < 0) || (!attribute.LessIsGood && value > 0) ? increasingColorHex : decreasingColorHex;
|
||||
text = Regex.Replace(text, @"\((.*)\)", "<color=" + color + ">(" + sign + value + ")</color>");
|
||||
}
|
||||
string color = (attribute.LessIsGood && value < 0) || (!attribute.LessIsGood && value > 0) ? IncreasingColorHex : DecreasingColorHex;
|
||||
text = Regex.Replace(text, @"\(([+-].*)\)", "<color=" + color + ">(" + sign + value + ")</color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing 0s
|
||||
text = RemoveTrailingZeros(text);
|
||||
|
||||
// Fix spacing
|
||||
text = text.Replace(" %", "%");
|
||||
text = text.Replace("(", " (");
|
||||
|
||||
___ValueText.text = text;
|
||||
}
|
||||
|
||||
// Remove trailing 0s
|
||||
text = RemoveTrailingZeros(text);
|
||||
|
||||
// Fix spacing
|
||||
text = text.Replace(" %", "%");
|
||||
text = text.Replace("(", " (");
|
||||
|
||||
textMesh.text = text;
|
||||
}
|
||||
|
||||
private static List<ItemAttributeClass> GetDeepAttributes(Item item, out bool changed)
|
||||
@@ -421,7 +454,7 @@ namespace UIFixes
|
||||
// b) a dot and some trailing 0
|
||||
// And all that is replaced to the original integer, and the significantDigits (if they exist)
|
||||
// If neither matches this doesn't match and does nothing
|
||||
return Regex.Replace(input, @"(?<integer>\d)((?<significantDecimals>\.[0-9]*[^0])0*\b)?(\.0+\b)?", "${integer}${significantDecimals}");
|
||||
return Regex.Replace(input, @"(?<integer>\d)((?<significantDecimals>\.[0-9]*[1-9])0*\b)?(\.0+\b)?", "${integer}${significantDecimals}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using Aki.Reflection.Utils;
|
||||
using Comfort.Common;
|
||||
using EFT;
|
||||
using EFT.InventoryLogic;
|
||||
using EFT.UI;
|
||||
using EFT.UI.DragAndDrop;
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
@@ -35,20 +36,24 @@ namespace UIFixes
|
||||
// Whether we're being called from the "check every slot" loop
|
||||
private static bool InHighlight = false;
|
||||
|
||||
// The most recent CheckItemFilter result
|
||||
private static string LastCheckItemFilterId;
|
||||
private static bool LastCheckItemFilterResult;
|
||||
|
||||
public static void Enable()
|
||||
{
|
||||
GridItemAddressType = PatchConstants.EftTypes.First(t => typeof(ItemAddress).IsAssignableFrom(t) && AccessTools.Property(t, "Grid") != null);
|
||||
GridItemAddressType = PatchConstants.EftTypes.First(t => typeof(ItemAddress).IsAssignableFrom(t) && t.GetProperty("Grid") != null); // GClass2769
|
||||
GridItemAddressLocationInGridField = AccessTools.Field(GridItemAddressType, "LocationInGrid");
|
||||
GridItemAddressGridProperty = AccessTools.Property(GridItemAddressType, "Grid");
|
||||
|
||||
SlotItemAddressType = PatchConstants.EftTypes.First(t => typeof(ItemAddress).IsAssignableFrom(t) && AccessTools.Field(t, "Slot") != null);
|
||||
SlotItemAddressType = PatchConstants.EftTypes.First(t => typeof(ItemAddress).IsAssignableFrom(t) && t.GetField("Slot") != null); // GClass2767
|
||||
SlotItemAddressSlotField = AccessTools.Field(SlotItemAddressType, "Slot");
|
||||
|
||||
CanAcceptOperationType = AccessTools.Method(typeof(GridView), "CanAccept").GetParameters()[2].ParameterType.GetElementType(); // parameter is a ref type, get underlying type
|
||||
CanAcceptOperationType = AccessTools.Method(typeof(GridView), "CanAccept").GetParameters()[2].ParameterType.GetElementType(); // GStruct413, parameter is a ref type, get underlying type
|
||||
CanAcceptOperationSucceededProperty = AccessTools.Property(CanAcceptOperationType, "Succeeded");
|
||||
CanAcceptOperationErrorProperty = AccessTools.Property(CanAcceptOperationType, "Error");
|
||||
|
||||
SwapOperationType = AccessTools.Method(typeof(InteractionsHandlerClass), "Swap").ReturnType;
|
||||
SwapOperationType = AccessTools.Method(typeof(InteractionsHandlerClass), "Swap").ReturnType; // GStruct414<GClass2797>
|
||||
SwapOperationToCanAcceptOperationOperator = SwapOperationType.GetMethods().First(m => m.Name == "op_Implicit" && m.ReturnType == CanAcceptOperationType);
|
||||
|
||||
GridViewNonInteractableField = AccessTools.Field(typeof(GridView), "_nonInteractable");
|
||||
@@ -57,6 +62,12 @@ namespace UIFixes
|
||||
new GridViewCanAcceptPatch().Enable();
|
||||
new GetHightLightColorPatch().Enable();
|
||||
new SlotViewCanAcceptPatch().Enable();
|
||||
new CheckItemFilterPatch().Enable();
|
||||
}
|
||||
private static bool InRaid()
|
||||
{
|
||||
bool? inRaid = Singleton<AbstractGame>.Instance?.InRaid;
|
||||
return inRaid.HasValue && inRaid.Value;
|
||||
}
|
||||
|
||||
private static bool ValidPrerequisites(ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, object operation)
|
||||
@@ -75,6 +86,7 @@ namespace UIFixes
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the source container is a non-interactable GridView. Specifically for StashSearch, but may exist in other scenarios?
|
||||
if (SourceContainer != null && SourceContainer is GridView && (bool)GridViewNonInteractableField.GetValue(SourceContainer))
|
||||
{
|
||||
@@ -82,6 +94,21 @@ namespace UIFixes
|
||||
}
|
||||
|
||||
string error = CanAcceptOperationErrorProperty.GetValue(operation).ToString();
|
||||
if (Settings.SwapImpossibleContainers.Value && !InRaid() && error.StartsWith("No free room"))
|
||||
{
|
||||
// Check if it isn't allowed in that container, if so try to swap
|
||||
if (LastCheckItemFilterId == itemContext.Item.Id && !LastCheckItemFilterResult)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it would ever fit no matter what, if not try to swap
|
||||
if (!CouldEverFit(itemContext, targetItemContext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error.StartsWith("Cannot add") && !error.StartsWith("Cannot apply") && error != "InventoryError/NoPossibleActions")
|
||||
{
|
||||
return false;
|
||||
@@ -90,6 +117,30 @@ namespace UIFixes
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CouldEverFit(ItemContextClass itemContext, ItemContextAbstractClass containerItemContext)
|
||||
{
|
||||
Item item = itemContext.Item;
|
||||
LootItemClass container = containerItemContext.Item as LootItemClass;
|
||||
if (container == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var size = item.CalculateCellSize();
|
||||
var rotatedSize = item.CalculateRotatedSize(itemContext.ItemRotation == ItemRotation.Horizontal ? ItemRotation.Vertical : ItemRotation.Horizontal);
|
||||
|
||||
foreach (StashGridClass grid in container.Grids)
|
||||
{
|
||||
if (size.X <= grid.GridWidth.Value && size.Y <= grid.GridHeight.Value ||
|
||||
rotatedSize.X <= grid.GridWidth.Value && rotatedSize.Y <= grid.GridHeight.Value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public class ItemViewOnDragPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod()
|
||||
@@ -219,10 +270,10 @@ namespace UIFixes
|
||||
{
|
||||
// Try original rotations
|
||||
var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, traderControllerClass, true);
|
||||
operation = SwapOperationToCanAcceptOperationOperator.Invoke(null, [result]);
|
||||
__result = (bool)CanAcceptOperationSucceededProperty.GetValue(operation);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
operation = SwapOperationToCanAcceptOperationOperator.Invoke(null, [result]);
|
||||
__result = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -301,5 +352,22 @@ namespace UIFixes
|
||||
}
|
||||
}
|
||||
|
||||
// CanApply, when dealing with containers, eventually calls down into FindPlaceForItem, which calls CheckItemFilter. For reasons,
|
||||
// if an item fails the filters, it returns the error "no space", instead of "no action". Try to detect this, so we can swap.
|
||||
public class CheckItemFilterPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod()
|
||||
{
|
||||
Type type = PatchConstants.EftTypes.First(t => t.GetMethod("CheckItemFilter", BindingFlags.Public | BindingFlags.Static) != null); // GClass2510
|
||||
return AccessTools.Method(type, "CheckItemFilter");
|
||||
}
|
||||
|
||||
[PatchPostfix]
|
||||
private static void Postfix(Item item, ref bool __result)
|
||||
{
|
||||
LastCheckItemFilterId = item.Id;
|
||||
LastCheckItemFilterResult = __result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
Settings.cs
24
Settings.cs
@@ -25,6 +25,7 @@ namespace UIFixes
|
||||
private const string InputSection = "2. Input";
|
||||
private const string InventorySection = "3. Inventory";
|
||||
private const string InRaidSection = "4. In Raid";
|
||||
private const string AdvancedSection = "5. Advanced";
|
||||
|
||||
// General
|
||||
public static ConfigEntry<WeaponPresetConfirmationOption> ShowPresetConfirmations { get; set; }
|
||||
@@ -38,6 +39,7 @@ namespace UIFixes
|
||||
|
||||
// Inventory
|
||||
public static ConfigEntry<bool> SwapItems { get; set; }
|
||||
public static ConfigEntry<bool> SwapImpossibleContainers { get; set; }
|
||||
public static ConfigEntry<bool> MergeFIRMoney { get; set; }
|
||||
public static ConfigEntry<bool> MergeFIRAmmo { get; set; }
|
||||
public static ConfigEntry<bool> MergeFIROther { get; set; }
|
||||
@@ -45,6 +47,9 @@ namespace UIFixes
|
||||
// In Raid
|
||||
public static ConfigEntry<bool> RemoveDisabledActions { get; set; }
|
||||
|
||||
// Advanced
|
||||
public static ConfigEntry<bool> StyleItemPanel { get; set; }
|
||||
|
||||
public static void Init(ConfigFile config)
|
||||
{
|
||||
var configEntries = new List<ConfigEntryBase>();
|
||||
@@ -115,6 +120,15 @@ namespace UIFixes
|
||||
null,
|
||||
new ConfigurationManagerAttributes { })));
|
||||
|
||||
configEntries.Add(SwapImpossibleContainers = config.Bind(
|
||||
InventorySection,
|
||||
"Swap with Incompatible Containers",
|
||||
false,
|
||||
new ConfigDescription(
|
||||
"Enable swapping items with containers that could never fit that item due to size or filter restrictions. Disabled in raid to avoid costly mistakes.",
|
||||
null,
|
||||
new ConfigurationManagerAttributes { })));
|
||||
|
||||
configEntries.Add(MergeFIRMoney = config.Bind(
|
||||
InventorySection,
|
||||
"Autostack Money with FiR Money",
|
||||
@@ -152,6 +166,16 @@ namespace UIFixes
|
||||
null,
|
||||
new ConfigurationManagerAttributes { })));
|
||||
|
||||
// Advanced
|
||||
configEntries.Add(StyleItemPanel = config.Bind(
|
||||
AdvancedSection,
|
||||
"Style Item Panel",
|
||||
true,
|
||||
new ConfigDescription(
|
||||
"Clean up and colorize item stats",
|
||||
null,
|
||||
new ConfigurationManagerAttributes { IsAdvanced = true })));
|
||||
|
||||
RecalcOrder(configEntries);
|
||||
}
|
||||
private static void RecalcOrder(List<ConfigEntryBase> configEntries)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UIFixes.Test
|
||||
{
|
||||
[TestClass]
|
||||
@@ -21,13 +23,16 @@ namespace UIFixes.Test
|
||||
{ "del. 2sec", "del. 2sec" },
|
||||
{ "Hello.world", "Hello.world" },
|
||||
{ "2Fast20Furious0", "2Fast20Furious0" },
|
||||
{ "1.0.2", "1.0.2" }
|
||||
{ "2.720(+0.57)", "2.72(+0.57)" },
|
||||
{ "2.720<color=#FFFFFF>(+0.64)</color>", "2.72<color=#FFFFFF>(+0.64)</color>" },
|
||||
{ "Class 3 (34)", "Class 3 (34)" },
|
||||
{ "$1234 (30)", "$1234 (30)" }
|
||||
};
|
||||
|
||||
foreach (var testCase in testCases)
|
||||
{
|
||||
string result = ItemPanelPatches.RemoveTrailingZeros(testCase.Key);
|
||||
Assert.AreEqual(result, testCase.Value);
|
||||
Assert.AreEqual(testCase.Value, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net471</TargetFramework>
|
||||
<AssemblyName>Tyfon.UIFixes</AssemblyName>
|
||||
<Description>SPT UI Fixes</Description>
|
||||
<Version>1.3.2</Version>
|
||||
<Version>1.3.3</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
@@ -25,6 +25,9 @@
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Comfort">
|
||||
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\Comfort.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ItemComponent.Types">
|
||||
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\ItemComponent.Types.dll</HintPath>
|
||||
</Reference>
|
||||
|
Reference in New Issue
Block a user