Patching correct armor values

This commit is contained in:
bepis69 2022-06-22 21:20:17 -04:00
parent 79384d4f92
commit 39d494b196
12 changed files with 164 additions and 218 deletions

13
.gitignore vendored
View File

@ -10,6 +10,7 @@ obj/
.idea
slnx.sqlite
slnx-journal.sqlite
Built/
## nodejs
node_modules
@ -20,14 +21,8 @@ package-lock.json
desktop.ini
## ALT-Mods
Faupi-HideoutMod/Project/bin
Faupi-HideoutMod/Project/obj
Faupi-MunitionsExpert/MunitionsExpert/bin
Faupi-MunitionsExpert/MunitionsExpert/obj
bepis69-ExpandedArmorDetails/ExpandedArmorDetails/bin
bepis69-ExpandedArmorDetails/ExpandedArmorDetails/obj
KcY-SeeItemValue/itemValue/bin
KcY-SeeItemValue/itemValue/obj
Built/
Folder.DotSettings.user

View File

@ -30,14 +30,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<!-- <PropertyGroup>-->
<!-- <SignAssembly>true</SignAssembly>-->
<!-- </PropertyGroup>-->
<!-- <PropertyGroup>-->
<!-- <AssemblyOriginatorKeyFile>-->
<!-- </AssemblyOriginatorKeyFile>-->
<!-- </PropertyGroup>-->
<ItemGroup>
<Compile Include="src\client\ArmorTemplate.cs" />
<Compile Include="src\client\StaticIconsPatch.cs" />
<Compile Include="src\client\CachedAttributesPatch.cs" />
<Compile Include="src\client\ModInformation.cs" />

View File

@ -6,12 +6,12 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MunitionsExpert - Ammo stats in inspect view")]
[assembly: AssemblyDescription("Adds ammo stats to inspect view as well as improving the format a little")]
[assembly: AssemblyTitle("ExpandedArmorDetails - Ammo stats in inspect view")]
[assembly: AssemblyDescription("Adds armor stats to inspect view as well as improving the format a little")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SPT-AKI - MunitionsExpert")]
[assembly: AssemblyCopyright("Faupi © 2021")]
[assembly: AssemblyProduct("SPT-AKI - ExpandedArmorDetails")]
[assembly: AssemblyCopyright("bepis69 © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@ -0,0 +1,7 @@
namespace ExpandedArmorDetails
{
public class ArmorTemplate : GClass1898
{
}
}

View File

@ -1,30 +1,21 @@
namespace MunitionsExpert
namespace ExpandedArmorDetails
{
public static class Attributes
{
public enum ENewItemAttributeId
{
Damage,
ArmorDamage,
Penetration,
FragmentationChance,
RicochetChance
DurabilityFactor,
EffectiveDurability
}
public static string GetName(this ENewItemAttributeId id)
{
switch (id)
{
case ENewItemAttributeId.Damage:
return "DAMAGE";
case ENewItemAttributeId.ArmorDamage:
return "ARMOR DAMAGE";
case ENewItemAttributeId.Penetration:
return "PENETRATION";
case ENewItemAttributeId.FragmentationChance:
return "FRAGMENTATION CHANCE";
case ENewItemAttributeId.RicochetChance:
return "RICOCHET CHANCE";
case ENewItemAttributeId.DurabilityFactor:
return "DESTRUCTIBILITY";
case ENewItemAttributeId.EffectiveDurability:
return "EFFECTIVE DURABILITY";
default:
return id.ToString();
}

View File

@ -5,23 +5,19 @@ using System.Linq;
using System.Reflection;
using ItemAttributes = GClass2100;
namespace MunitionsExpert
namespace ExpandedArmorDetails
{
internal class CachedAttributesPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return typeof(AmmoTemplate).GetMethod("GetCachedReadonlyQualities", BindingFlags.Instance | BindingFlags.Public);
return typeof(ArmorTemplate).GetMethod("GetCachedReadonlyQualities", BindingFlags.Instance | BindingFlags.Public);
}
[PatchPostfix]
private static void PatchPostfix(ref AmmoTemplate __instance, ref List<ItemAttributes> __result)
private static void PatchPostfix(ref ArmorTemplate __instance, ref List<ItemAttributes> __result)
{
if (!__result.Any((ItemAttributes a) => (Attributes.ENewItemAttributeId)a.Id == Attributes.ENewItemAttributeId.Damage))
{
//ExpandedArmorDetails.FormatExistingAttributes(ref __result, __instance);
MunitionsExpert.AddNewAttributes(ref __result, __instance);
}
ExpandedArmorDetails.AddNewAttributes(ref __result, __instance);
}
}
}

View File

@ -0,0 +1,131 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using EFT.InventoryLogic;
using UnityEngine.Networking;
using System.Threading.Tasks;
using BepInEx;
using Comfort.Common;
using ItemAttribute = GClass2100;
using static ExpandedArmorDetails.Attributes;
using ServerSettings = GClass1087;
namespace ExpandedArmorDetails
{
[BepInPlugin("com.bepis69.ExpandedArmorDetails", "bepis69-ExpandedArmorDetails", "0.0.1")]
public class ExpandedArmorDetails : BaseUnityPlugin
{
private void Awake()
{
new CachedAttributesPatch().Enable();
new StaticIconsPatch().Enable();
CacheIcons();
}
private static ModInformation _modInfo;
public static ModInformation ModInfo
{
private set
{
_modInfo = value;
}
get
{
if (_modInfo == null)
_modInfo = ModInformation.Load();
return _modInfo;
}
}
public static Dictionary<Enum, Sprite> iconCache = new Dictionary<Enum, Sprite>();
public static List<ItemAttribute> penAttributes = new List<ItemAttribute>(); // For refreshing armor class rating
public static string modName = ModInfo.name;
public static void CacheIcons()
{
_ = LoadTexture(ENewItemAttributeId.DurabilityFactor, Path.Combine(ModInfo.path, "res/ricochet.png"));
_ = LoadTexture(ENewItemAttributeId.EffectiveDurability, Path.Combine(ModInfo.path, "res/ricochet.png"));
}
public static async Task LoadTexture(Enum id, string path)
{
using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(path))
{
uwr.SendWebRequest();
while (!uwr.isDone)
await Task.Delay(5);
if (uwr.responseCode != 200)
{
//Log.Error($"[{modName}] Request error {uwr.responseCode}: {uwr.error}");
}
else
{
// Get downloaded asset bundle
//Log.Info($"[{modName}] Retrieved texture! {id.ToString()} from {path}");
Texture2D cachedTexture = DownloadHandlerTexture.GetContent(uwr);
iconCache.Add(id, Sprite.Create(cachedTexture, new Rect(0, 0, cachedTexture.width, cachedTexture.height), new Vector2(0, 0)));
}
}
}
private static float CalculateDurabilityFactor(EArmorMaterial material)
{
switch (material)
{
case EArmorMaterial.Aluminium:
return 0.6f;
case EArmorMaterial.Aramid:
return 0.25f;
case EArmorMaterial.Ceramic:
return 0.8f;
case EArmorMaterial.Combined:
return 0.5f;
case EArmorMaterial.Glass:
return 0.8f;
case EArmorMaterial.Titan:
return 0.55f;
case EArmorMaterial.ArmoredSteel:
return 0.7f;
case EArmorMaterial.UHMWPE:
return 0.45f;
default:
return 1f;
}
}
public static void AddNewAttributes(ref List<ItemAttribute> attributes, ArmorTemplate template)
{
if (template.ArmorMaterial > 0)
{
float durabilityFactor = CalculateDurabilityFactor(template.ArmorMaterial);
ItemAttribute atDurabilityFact = new ItemAttribute(ENewItemAttributeId.DurabilityFactor)
{
Name = ENewItemAttributeId.DurabilityFactor.GetName(),
Base = () => durabilityFactor,
StringValue = () => $"{(( 1-durabilityFactor+1) * 100).ToString()}%",
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(atDurabilityFact);
if (template.MaxDurability > 0)
{
int effectiveDurability = (int)(template.MaxDurability / durabilityFactor);
ItemAttribute atDurabilityEff = new ItemAttribute(ENewItemAttributeId.EffectiveDurability)
{
Name = ENewItemAttributeId.EffectiveDurability.GetName(),
Base = () => effectiveDurability,
StringValue = () => effectiveDurability.ToString(),
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(atDurabilityEff);
}
}
}
}
}

View File

@ -4,7 +4,7 @@ using System;
using UnityEngine;
using UnityEngine.Assertions;
namespace MunitionsExpert
namespace ExpandedArmorDetails
{
public class ModInformation
{
@ -27,7 +27,7 @@ namespace MunitionsExpert
}
catch (Exception getModInfoException)
{
string errMsg = $"[{typeof(MunitionsExpert)}] Package.json couldn't be found! Make sure you've installed the mod on the server as well!";
string errMsg = $"[{typeof(ExpandedArmorDetails)}] Package.json couldn't be found! Make sure you've installed the mod on the server as well!";
Debug.LogError(errMsg);
throw getModInfoException;
}

View File

@ -1,165 +0,0 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using EFT.InventoryLogic;
using UnityEngine.Networking;
using System.Threading.Tasks;
using BepInEx;
using Comfort.Common;
using ItemAttribute = GClass2100;
using static MunitionsExpert.Attributes;
using ServerSettings = GClass1087;
namespace MunitionsExpert
{
[BepInPlugin("com.FAUPI.ExpandedArmorDetails", "FAUPI-ExpandedArmorDetails", "1.4.0")]
public class MunitionsExpert : BaseUnityPlugin
{
private void Awake()
{
new CachedAttributesPatch().Enable();
new StaticIconsPatch().Enable();
CacheIcons();
}
private static ModInformation _modInfo;
public static ModInformation ModInfo
{
private set
{
_modInfo = value;
}
get
{
if (_modInfo == null)
_modInfo = ModInformation.Load();
return _modInfo;
}
}
public static Dictionary<Enum, Sprite> iconCache = new Dictionary<Enum, Sprite>();
public static List<ItemAttribute> penAttributes = new List<ItemAttribute>(); // For refreshing armor class rating
public static string modName = ModInfo.name;
public static void CacheIcons()
{
iconCache.Add(ENewItemAttributeId.Damage, Resources.Load<Sprite>("characteristics/icons/icon_info_damage"));
iconCache.Add(ENewItemAttributeId.FragmentationChance, Resources.Load<Sprite>("characteristics/icons/icon_info_shrapnelcount"));
iconCache.Add(EItemAttributeId.LightBleedingDelta, Resources.Load<Sprite>("characteristics/icons/icon_info_bloodloss"));
iconCache.Add(EItemAttributeId.HeavyBleedingDelta, Resources.Load<Sprite>("characteristics/icon_info_hydration"));
iconCache.Add(ENewItemAttributeId.Penetration, Resources.Load<Sprite>("characteristics/icon_info_penetration"));
_ = LoadTexture(ENewItemAttributeId.ArmorDamage, Path.Combine(ModInfo.path, "res/armorDamage.png"));
_ = LoadTexture(ENewItemAttributeId.RicochetChance, Path.Combine(ModInfo.path, "res/ricochet.png"));
}
public static async Task LoadTexture(Enum id, string path)
{
using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(path))
{
uwr.SendWebRequest();
while (!uwr.isDone)
await Task.Delay(5);
if (uwr.responseCode != 200)
{
//Log.Error($"[{modName}] Request error {uwr.responseCode}: {uwr.error}");
}
else
{
// Get downloaded asset bundle
//Log.Info($"[{modName}] Retrieved texture! {id.ToString()} from {path}");
Texture2D cachedTexture = DownloadHandlerTexture.GetContent(uwr);
iconCache.Add(id, Sprite.Create(cachedTexture, new Rect(0, 0, cachedTexture.width, cachedTexture.height), new Vector2(0, 0)));
}
}
}
public static void AddNewAttributes(ref List<ItemAttribute> attributes, AmmoTemplate template)
{
int projCount = template.ProjectileCount;
int totalDamage = template.Damage * template.ProjectileCount;
string damageStr = totalDamage.ToString(); // Total damage
if (template.ProjectileCount > 1)
{
damageStr += $" ({template.Damage} x {template.ProjectileCount})"; // Add the "damage calculation" after total damage (damage per pellet * pellet count)
}
ItemAttribute at_damage = new ItemAttribute(ENewItemAttributeId.Damage)
{
Name = ENewItemAttributeId.Damage.GetName(),
Base = () => totalDamage,
StringValue = () => damageStr,
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(at_damage);
if (template.ArmorDamage > 0)
{
ItemAttribute at_armordmg = new ItemAttribute(ENewItemAttributeId.ArmorDamage)
{
Name = ENewItemAttributeId.ArmorDamage.GetName(),
Base = () => template.ArmorDamage,
StringValue = () => $"{(template.ArmorDamage).ToString()}%",
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(at_armordmg);
}
if (template.PenetrationPower > 0)
{
string getStringValue()
{
int ratedClass = 0;
if (!Singleton<ServerSettings>.Instantiated) { return $"CLASS_DATA_MISSING {template.PenetrationPower.ToString()}"; }
ServerSettings.GClass1134.GClass1135[] classes = Singleton<ServerSettings>.Instance.Armor.ArmorClass;
for (int i = 0; i < classes.Length; i++)
{
if (classes[i].Resistance > template.PenetrationPower) continue;
ratedClass = Math.Max(ratedClass, i);
}
return $"{(ratedClass > 0 ? $"{"ME_class".Localized()} {ratedClass}" : "ME_noarmor".Localized())} ({template.PenetrationPower.ToString()})";
}
ItemAttribute at_pen = new ItemAttribute(ENewItemAttributeId.Penetration)
{
Name = ENewItemAttributeId.Penetration.GetName(),
Base = () => template.PenetrationPower,
StringValue = getStringValue,
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(at_pen);
}
if (template.FragmentationChance > 0)
{
ItemAttribute at_frag = new ItemAttribute(ENewItemAttributeId.FragmentationChance)
{
Name = ENewItemAttributeId.FragmentationChance.GetName(),
Base = () => template.FragmentationChance,
StringValue = () => $"{(template.FragmentationChance * 100).ToString()}%",
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(at_frag);
}
if (template.RicochetChance > 0)
{
ItemAttribute at_ricochet = new ItemAttribute(ENewItemAttributeId.RicochetChance)
{
Name = ENewItemAttributeId.RicochetChance.GetName(),
Base = () => template.RicochetChance,
StringValue = () => $"{(template.RicochetChance * 100).ToString()}%",
DisplayType = () => EItemAttributeDisplayType.Compact
};
attributes.Add(at_ricochet);
}
}
}
}

View File

@ -4,7 +4,7 @@ using Aki.Reflection.Patching;
using EFT.UI;
using UnityEngine;
namespace MunitionsExpert
namespace ExpandedArmorDetails
{
internal class StaticIconsPatch : ModulePatch
{
@ -16,12 +16,12 @@ namespace MunitionsExpert
[PatchPrefix]
private static bool PatchPrefix(ref Sprite __result, Enum id)
{
if (id == null || !MunitionsExpert.iconCache.ContainsKey(id))
if (id == null || !ExpandedArmorDetails.iconCache.ContainsKey(id))
{
return true;
}
Sprite sprite = MunitionsExpert.iconCache[id];
Sprite sprite = ExpandedArmorDetails.iconCache[id];
if (sprite != null)
{

View File

@ -3,7 +3,7 @@
"author": "bepis69",
"version": "0.0.1",
"license": "NCSA Open Source",
"main": "./src/MunitionsExpert.js",
"main": "./src/ExpandedArmorDetails.js",
"akiVersion": "2.3.1",
"updatedBy": "CWX",
"scripts": {

View File

@ -1,3 +0,0 @@
{
"BulletBackgroundColours": true
}