using System.Collections.Generic; using System.Linq; using BepInEx.Logging; using Comfort.Common; using EFT; using EFT.InventoryLogic; using HarmonyLib; using UnityEngine; #pragma warning disable IDE0044 namespace armorMod { internal class AssComponent : MonoBehaviour { private static GameWorld gameWorld = new GameWorld(); private static Player player = new Player(); private static InventoryControllerClass _cachedInventoryController; private static float newRepairRate; private static float newMaxDurabilityDrainRate; private static float newWeaponRepairRate; private static float newWeaponMaxDurabilityDrainRate; private static RepairableComponent armor; private static FaceShieldComponent faceShield; private static RepairableComponent weapon; private static float maxRepairableDurabilityBasedOnCap; private static float maxWeaponRepairableDurabilityBasedOnCap; private static float timeSinceLastHit = 0f; private static Slot tempSlot; private int frameCount = 0; private static Dictionary> equipmentSlotDictionary = new Dictionary> { { EquipmentSlot.ArmorVest, new List() }, { EquipmentSlot.TacticalVest, new List() }, { EquipmentSlot.Eyewear, new List() }, { EquipmentSlot.FaceCover, new List() }, { EquipmentSlot.Headwear, new List() }, }; private static Dictionary> weaponSlotDictionary = new Dictionary> { { EquipmentSlot.FirstPrimaryWeapon, new List() }, { EquipmentSlot.SecondPrimaryWeapon, new List() }, { EquipmentSlot.Holster, new List() }, }; protected static ManualLogSource Logger { get; private set; } private AssComponent() { if (Logger == null) { Logger = BepInEx.Logging.Logger.CreateLogSource(nameof(AssComponent)); } } private void Start() { player = Singleton.Instance.MainPlayer; player.BeingHitAction += Player_BeingHitAction; timeSinceLastHit = 0; _cachedInventoryController = (InventoryControllerClass)AccessTools.Field(typeof(Player), "_inventoryController").GetValue(player); } internal static void Enable() { if (Singleton.Instantiated) { gameWorld = Singleton.Instance; gameWorld.GetOrAddComponent(); Logger.LogDebug("AssComponent enabled"); } } private void Update() { frameCount++; // Perform actions every 60 frames if (frameCount >= 60) { frameCount = 0; // Reset frame count // Assuming Time.deltaTime accumulates over 60 frames for calculations float accumulatedDeltaTime = Time.deltaTime * 60; timeSinceLastHit += accumulatedDeltaTime; if (AssPlugin.ArmorServiceMode.Value && timeSinceLastHit >= AssPlugin.TimeDelayRepairInSec.Value) { var armorItems = equipmentSlotDictionary.Values.SelectMany(slot => slot).SelectMany(slot => slot.GetAllItems()); RepairItems(armorItems, isWeapon: false, accumulatedDeltaTime); } if (AssPlugin.WeaponServiceMode.Value && timeSinceLastHit >= AssPlugin.weaponTimeDelayRepairInSec.Value) { var weaponItems = weaponSlotDictionary.Values.SelectMany(slot => slot).SelectMany(slot => slot.GetAllItems()); RepairItems(weaponItems, isWeapon: true, accumulatedDeltaTime); } } } private void RepairItems(IEnumerable items, bool isWeapon, float accumulatedDeltaTime) { float repairRate = isWeapon ? AssPlugin.weaponRepairRateOverTime.Value * accumulatedDeltaTime : AssPlugin.ArmorRepairRateOverTime.Value * accumulatedDeltaTime; float maxDurabilityDrainRate = isWeapon ? AssPlugin.weaponMaxDurabilityDegradationRateOverTime.Value * accumulatedDeltaTime : AssPlugin.MaxDurabilityDegradationRateOverTime.Value * accumulatedDeltaTime; foreach (var item in items) { if (!isWeapon) { if (item.TryGetItemComponent(out var faceShield) && AssPlugin.fixFaceShieldBullets.Value) { if (faceShield.Hits > 0) { faceShield.Hits = 0; faceShield.HitsChanged?.Invoke(); } } } if (item.TryGetItemComponent(out var repairable)) { float maxRepairableDurabilityBasedOnCap = ((isWeapon ? AssPlugin.weaponMaxDurabilityCap.Value : AssPlugin.MaxDurabilityCap.Value) / 100) * repairable.MaxDurability; if (repairable.Durability < maxRepairableDurabilityBasedOnCap) { repairable.Durability = Mathf.Min(repairable.Durability + repairRate, repairable.MaxDurability); repairable.MaxDurability = Mathf.Max(repairable.MaxDurability - maxDurabilityDrainRate, 0); } } } } private void Player_BeingHitAction(DamageInfo dmgInfo, EBodyPart bodyPart, float hitEffectId) => timeSinceLastHit = 0f; private static Slot slotContents; private static InventoryControllerClass inventoryController; private Slot getEquipSlot(EquipmentSlot slot) { if (_cachedInventoryController != null) { var slotContents = _cachedInventoryController.Inventory.Equipment.GetSlot(slot); return slotContents.ContainedItem == null ? null : slotContents; } return null; } } }