using System.Collections.Generic; using BepInEx.Logging; using Comfort.Common; using EFT; using EFT.InventoryLogic; using HarmonyLib; using UnityEngine; namespace armorMod { internal class AssComponent : MonoBehaviour { internal static ManualLogSource Logger; internal static GameWorld gameWorld; internal static Player player; internal static float timeSinceLastHit = 0f; internal static float timeSinceLastRepair = 0f; // New variable to control repair frequency internal static Slot slotContents; internal static InventoryControllerClass inventoryController; internal static List equipmentSlotDictionary = new List { { EquipmentSlot.ArmorVest}, { EquipmentSlot.TacticalVest}, { EquipmentSlot.Eyewear}, { EquipmentSlot.FaceCover}, { EquipmentSlot.Headwear}, }; internal static List weaponSlotDictionary = new List { { EquipmentSlot.FirstPrimaryWeapon }, { EquipmentSlot.SecondPrimaryWeapon }, { EquipmentSlot.Holster }, }; private void Awake() { if (Logger == null) Logger = BepInEx.Logging.Logger.CreateLogSource(nameof(AssComponent)); } private void Start() { player = gameWorld.MainPlayer; inventoryController = (InventoryControllerClass)AccessTools.Field(typeof(Player), "_inventoryController").GetValue(player); player.BeingHitAction += ResetTimeSinceLastHit; Logger.LogDebug("AssComponent enabled successfully."); } private void Update() { timeSinceLastHit += Time.deltaTime; timeSinceLastRepair += Time.deltaTime; if (timeSinceLastRepair >= 1.0f) { if (timeSinceLastHit >= AssPlugin.TimeDelayRepairInSec.Value && AssPlugin.ArmorServiceMode.Value) { RepairItems(equipmentSlotDictionary, true); } if (timeSinceLastHit >= AssPlugin.weaponTimeDelayRepairInSec.Value && AssPlugin.WeaponServiceMode.Value) { RepairItems(weaponSlotDictionary, false); } timeSinceLastRepair = 0f; } } private static void RepairItems(List slots, bool isArmor) { float repairRate = isArmor ? AssPlugin.ArmorRepairRateOverTime.Value : AssPlugin.weaponRepairRateOverTime.Value; float maxDurabilityDrainRate = isArmor ? AssPlugin.MaxDurabilityDegradationRateOverTime.Value : AssPlugin.weaponMaxDurabilityDegradationRateOverTime.Value; foreach (var slot in slots) { var slotContents = GetEquipSlot(slot); if (slotContents?.ContainedItem == null) continue; foreach (Item item in slotContents.ContainedItem.GetAllItems()) { if (isArmor) { // Specifically for face shields, if the item has a FaceShieldComponent. if (item.TryGetItemComponent(out var faceShield) && AssPlugin.fixFaceShieldBullets.Value) { // Check if face shield has been hit and reset hits if so. if (faceShield.Hits > 0) { faceShield.Hits = 0; faceShield.HitsChanged?.Invoke(); } } } if (item.TryGetItemComponent(out var component)) { float maxCap = isArmor ? AssPlugin.MaxDurabilityCap.Value : AssPlugin.weaponMaxDurabilityCap.Value; float maxRepairableDurability = (maxCap / 100) * component.TemplateDurability; // Logger.LogInfo(component.Item.Id + " " + component.TemplateDurability + " " + component.MaxDurability); if (component.Durability < maxRepairableDurability) { #if DEBUG Logger.LogWarning($"Repairing {item.Name.Localized()} in {slot} with {component.Durability} / {component.MaxDurability} durability"); #endif component.Durability = Mathf.Min(component.Durability + repairRate, component.TemplateDurability); component.MaxDurability = Mathf.Max(component.TemplateDurability - maxDurabilityDrainRate, 0); } } } } } private static void ResetTimeSinceLastHit(DamageInfo dmgInfo, EBodyPart bodyPart, float hitEffectId) { timeSinceLastHit = 0f; } private static Slot GetEquipSlot(EquipmentSlot slot) { if (inventoryController != null) { slotContents = inventoryController.Inventory.Equipment.GetSlot(slot); return slotContents.ContainedItem == null ? null : slotContents; } return null; } internal static void Enable() { if (Singleton.Instantiated) { gameWorld = Singleton.Instance; gameWorld.GetOrAddComponent(); } } } }