2023-07-08 23:42:42 +03:00
|
|
|
|
using Comfort.Common;
|
|
|
|
|
using EFT.InventoryLogic;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
namespace IcyClawz.MunitionsExpert;
|
|
|
|
|
|
|
|
|
|
internal enum ColorName
|
|
|
|
|
{
|
|
|
|
|
Blue, Brown, Cyan, Gray, Green, Magenta, Orange, Pink, Purple, Red, Silver, Tan, Violet, Yellow
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static class ColorCache
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
private const byte ALPHA = 38;
|
|
|
|
|
private static readonly Dictionary<ColorName, Color> Cache = new()
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
[ColorName.Blue] = new Color32(0, 60, 170, ALPHA),
|
|
|
|
|
[ColorName.Brown] = new Color32(140, 85, 30, ALPHA),
|
|
|
|
|
[ColorName.Cyan] = new Color32(0, 150, 150, ALPHA),
|
|
|
|
|
[ColorName.Gray] = new Color32(70, 70, 70, ALPHA),
|
|
|
|
|
[ColorName.Green] = new Color32(70, 140, 0, ALPHA),
|
|
|
|
|
[ColorName.Magenta] = new Color32(215, 0, 100, ALPHA),
|
|
|
|
|
[ColorName.Orange] = new Color32(140, 70, 0, ALPHA),
|
|
|
|
|
[ColorName.Pink] = new Color32(215, 120, 150, ALPHA),
|
|
|
|
|
[ColorName.Purple] = new Color32(120, 40, 135, ALPHA),
|
|
|
|
|
[ColorName.Red] = new Color32(170, 20, 0, ALPHA),
|
|
|
|
|
[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)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public static Color Get(ColorName name) => Cache.TryGetValue(name, out Color color) ? color : default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal enum EAmmoExtraAttributeId
|
|
|
|
|
{
|
|
|
|
|
Damage, PenetrationPower, ArmorDamage, FragmentationChance, RicochetChance
|
|
|
|
|
}
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
internal static class ImageExtensions
|
|
|
|
|
{
|
|
|
|
|
public static Sprite ToSprite(this System.Drawing.Image instance)
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
using MemoryStream ms = new();
|
|
|
|
|
instance.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
|
|
|
|
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);
|
2023-07-08 23:42:42 +03:00
|
|
|
|
}
|
2024-03-05 22:48:21 +02:00
|
|
|
|
}
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
internal static class IconCache
|
|
|
|
|
{
|
|
|
|
|
private static readonly Dictionary<Enum, Sprite> Cache = new()
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
[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()
|
|
|
|
|
};
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
public static Sprite Get(Enum id) => Cache.TryGetValue(id, out Sprite sprite) ? sprite : default;
|
|
|
|
|
}
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
internal static class AmmoTemplateExtensions
|
|
|
|
|
{
|
|
|
|
|
private static readonly FieldInfo CachedQualitiesField =
|
|
|
|
|
typeof(AmmoTemplate).GetField("_cachedQualities", BindingFlags.NonPublic | BindingFlags.Instance);
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
public static List<ItemAttributeClass> GetCachedQualities(this AmmoTemplate instance) =>
|
|
|
|
|
CachedQualitiesField.GetValue(instance) as List<ItemAttributeClass>;
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
public static void AddExtraAttributes(this AmmoTemplate instance)
|
|
|
|
|
{
|
|
|
|
|
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.Damage)
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
Name = EAmmoExtraAttributeId.Damage.ToString(),
|
|
|
|
|
DisplayNameFunc = () => "Damage",
|
|
|
|
|
Base = () => instance.Damage * instance.ProjectileCount,
|
|
|
|
|
StringValue = () =>
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
int totalDamage = instance.Damage * instance.ProjectileCount;
|
|
|
|
|
return instance.ProjectileCount > 1
|
|
|
|
|
? $"{instance.ProjectileCount} <20> {instance.Damage} = {totalDamage}"
|
|
|
|
|
: totalDamage.ToString();
|
|
|
|
|
},
|
|
|
|
|
DisplayType = () => EItemAttributeDisplayType.Compact
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.PenetrationPower)
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
Name = EAmmoExtraAttributeId.PenetrationPower.ToString(),
|
|
|
|
|
DisplayNameFunc = () => "Penetration power",
|
|
|
|
|
Base = () => instance.PenetrationPower,
|
|
|
|
|
StringValue = () =>
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
int armorClass = instance.GetPenetrationArmorClass();
|
|
|
|
|
return (armorClass > 0 ? $"Class {armorClass}" : "Unarmored") + $" ({instance.PenetrationPower})";
|
|
|
|
|
},
|
|
|
|
|
DisplayType = () => EItemAttributeDisplayType.Compact
|
|
|
|
|
});
|
2023-07-08 23:42:42 +03:00
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.ArmorDamage)
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
Name = EAmmoExtraAttributeId.ArmorDamage.ToString(),
|
|
|
|
|
DisplayNameFunc = () => "Armor damage",
|
|
|
|
|
Base = () => instance.ArmorDamage,
|
|
|
|
|
StringValue = () => $"{instance.ArmorDamage}%",
|
|
|
|
|
DisplayType = () => EItemAttributeDisplayType.Compact
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.FragmentationChance)
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
Name = EAmmoExtraAttributeId.FragmentationChance.ToString(),
|
|
|
|
|
DisplayNameFunc = () => "Fragmentation chance",
|
|
|
|
|
Base = () => instance.FragmentationChance,
|
|
|
|
|
StringValue = () => $"{Math.Round(instance.FragmentationChance * 100, 1)}%",
|
|
|
|
|
DisplayType = () => EItemAttributeDisplayType.Compact
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
instance.SafelyAddQualityToList(new ItemAttributeClass(EAmmoExtraAttributeId.RicochetChance)
|
|
|
|
|
{
|
|
|
|
|
Name = EAmmoExtraAttributeId.RicochetChance.ToString(),
|
|
|
|
|
DisplayNameFunc = () => "Ricochet chance",
|
|
|
|
|
Base = () => instance.RicochetChance,
|
|
|
|
|
StringValue = () => $"{Math.Round(instance.RicochetChance * 100, 1)}%",
|
|
|
|
|
DisplayType = () => EItemAttributeDisplayType.Compact
|
|
|
|
|
});
|
2023-07-08 23:42:42 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 22:48:21 +02:00
|
|
|
|
public static int GetPenetrationArmorClass(this AmmoTemplate instance)
|
2023-07-08 23:42:42 +03:00
|
|
|
|
{
|
2024-03-05 22:48:21 +02:00
|
|
|
|
var armorClasses = Singleton<BackendConfigSettingsClass>.Instance.Armor.ArmorClass;
|
|
|
|
|
for (int i = armorClasses.Length - 1; i >= 0; i--)
|
|
|
|
|
if (armorClasses[i].Resistance <= instance.PenetrationPower)
|
|
|
|
|
return i;
|
|
|
|
|
return 0;
|
2023-07-08 23:42:42 +03:00
|
|
|
|
}
|
2024-03-05 22:48:21 +02:00
|
|
|
|
}
|