forked from CWX/ALT-Mods
Patching correct armor values
This commit is contained in:
parent
79384d4f92
commit
39d494b196
13
.gitignore
vendored
13
.gitignore
vendored
@ -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
|
||||
|
@ -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" />
|
||||
|
@ -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("")]
|
||||
|
||||
|
7
src/client/ArmorTemplate.cs
Normal file
7
src/client/ArmorTemplate.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace ExpandedArmorDetails
|
||||
{
|
||||
public class ArmorTemplate : GClass1898
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
131
src/client/ExpandedArmorDetails.cs
Normal file
131
src/client/ExpandedArmorDetails.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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": {
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"BulletBackgroundColours": true
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user