using System; using System.Collections; using System.Collections.Generic; using BITFALL.Entities.Inventory; using BITFALL.Items; using BITKit; using BITKit.Entities; using UnityEditor; using UnityEngine; namespace BITFALL.Entities { [CustomType(typeof(IKnockdown))] public sealed class EntityKnockdown :EntityBehavior,IKnockdown { [SerializeField] private int knockedHealth; [SerializeField] private int initialKnockedHealth; [SerializeField] private Optional invincibilityTimes; public int KnockedHealth=>knockedHealth; public int InitialKnockedHealth { get => initialKnockedHealth; set => initialKnockedHealth = value; } public event Action OnKnockdown; public event Action OnRevive; public bool IsKnockdown { get;private set; } private readonly Optional knockedHeal=new(); private readonly IntervalUpdate invincibilityInterval = new(); [Inject] private IHealth _health; [Inject] private IEntityInventory _inventory; public override void OnStart() { _health.OnDamageFactory += OnDamageFactory; _health.OnSetAlive += OnSetAlive; _health.OnSetHealthPoint += OnSetHealthPoint; _inventory.TryUseItemFactory+=TryUseItem; _inventory.OnUsedItem += OnUseItem; } private bool TryUseItem(IBasicItem arg) { if (IsKnockdown is false) return false; if (arg is not null && arg.GetAssetable().TryGetProperty(out _)) { _inventory.UseItem(arg); return true; } return false; } private void OnSetHealthPoint(int obj) { if (obj <= 0 || !IsKnockdown || !_health.IsAlive) return; IsKnockdown = false; OnRevive?.Invoke(); } private void OnUseItem(IBasicItem arg) { if (IsKnockdown is false || arg.GetAssetable().TryGetProperty(out var reviveItem) is false) return; IsKnockdown = false; OnRevive?.Invoke(); } private void OnSetAlive(bool obj) { IsKnockdown = false; } private int OnDamageFactory(DamageMessage arg, int currentDamage) { if (Data.Get(BITConstant.Environment.sp_knockdown_disabled)) return currentDamage; if (invincibilityTimes.Allow && invincibilityInterval.AllowUpdateWithoutReset is false) { return 0; } if (IsKnockdown || _health.HealthPoint - currentDamage >= 0) return currentDamage; IsKnockdown = true; if (invincibilityTimes.Allow) { invincibilityInterval.Interval = invincibilityTimes.Value; invincibilityInterval.Reset(); } OnKnockdown?.Invoke(); _health.HealthPoint = 0; return 0; } } }