using Cysharp.Threading.Tasks; using SepCore.AsyncTask; using SepCore.Definition; using SepCore.Entity; using SepCore.Timer; using UnityEngine; public abstract class EnemyBase : TargetableObject { protected Transform _target; public abstract override ImpactData GetImpactData(); public virtual float AttackRange => 1f; public virtual void SetTarget(Transform target) => _target = target; protected EnemyData _enemyData; protected bool _canAttack; protected TimerHandle _attackTimerHandle; protected void StartAttackCooldown(float cooldown) { _canAttack = false; _attackTimerHandle = GameEntry.Timer.ScheduleOnce(cooldown, () => _canAttack = true, this); } protected void ResetAttackCooldown(float cooldown) { GameEntry.Timer.Cancel(_attackTimerHandle); _canAttack = false; _attackTimerHandle = GameEntry.Timer.ScheduleOnce(cooldown, () => _canAttack = true, this); } protected void CancelAttackCooldown() { GameEntry.Timer.Cancel(_attackTimerHandle); _attackTimerHandle = TimerHandle.Invalid; _canAttack = false; } protected override void OnShow(object userData) { base.OnShow(userData); if (userData is EnemyData enemyData) { ApplyVisualParams(enemyData); } } protected override void OnDead(EntityBase attacker) { if (Random.value < _enemyData.DropPercent) { var data = new CoinData(_enemyData.DropCoin, GameEntry.Entity.NextId(), 10001) { Position = this.CachedTransform.position }; GameEntry.Entity.ShowCoinAsync(data).Forget(); } if (Random.value < _enemyData.DropPercent) { var data = new ExpData(_enemyData.DropExp, GameEntry.Entity.NextId(), 10002) { Position = this.CachedTransform.position }; GameEntry.Entity.ShowExpAsync(data).Forget(); } base.OnDead(attacker); } private void ApplyVisualParams(EnemyData data) { CachedTransform.localScale = Vector3.one * Mathf.Max(0.1f, data.Scale); var renderer = GetComponentInChildren(); if (renderer != null) { var block = new MaterialPropertyBlock(); block.SetColor("_BaseColor", data.Color); renderer.SetPropertyBlock(block); } } }