引入属性、伤害管线
This commit is contained in:
@@ -27,16 +27,33 @@ namespace SepCore.Entity
|
||||
|
||||
protected EntityBase _target;
|
||||
|
||||
private float _sqrRange;
|
||||
|
||||
public EntityBase Target => _target;
|
||||
|
||||
public float SqrRange => _sqrRange;
|
||||
public float CurrentCooldown
|
||||
{
|
||||
get
|
||||
{
|
||||
if (WeaponData == null) return 0f;
|
||||
float attackSpeed = _ownerAttributeProvider?.GetValue(StatType.AttackSpeed) ?? 0f;
|
||||
float speedFactor = Mathf.Max(0.2f, 1f + attackSpeed);
|
||||
return Mathf.Max(0.02f, WeaponData.Cooldown / speedFactor);
|
||||
}
|
||||
}
|
||||
|
||||
protected StatProperty AttackStat { get; private set; } = new();
|
||||
public float CurrentAttackRange
|
||||
{
|
||||
get
|
||||
{
|
||||
if (WeaponData == null) return 0f;
|
||||
float rangeBonus = _ownerAttributeProvider?.GetValue(StatType.Range) ?? 0f;
|
||||
float effectiveBonus = rangeBonus >= 50f ? rangeBonus / 1000f : rangeBonus;
|
||||
return Mathf.Max(0.5f, WeaponData.AttackRange + effectiveBonus);
|
||||
}
|
||||
}
|
||||
|
||||
private StatComponent _attackStatComponent;
|
||||
private System.Action<modifier, bool> _attackStatCallback;
|
||||
public float SqrRange => CurrentAttackRange * CurrentAttackRange;
|
||||
|
||||
private IAttributeProvider _ownerAttributeProvider;
|
||||
|
||||
private static float _rotateSpeed => GameEntry.Luban.Global.WeaponRotateSpeed;
|
||||
|
||||
@@ -63,8 +80,7 @@ namespace SepCore.Entity
|
||||
return;
|
||||
}
|
||||
|
||||
StartAttackCooldown(WeaponData.Cooldown);
|
||||
_sqrRange = WeaponData.AttackRange * WeaponData.AttackRange;
|
||||
StartAttackCooldown(CurrentCooldown);
|
||||
_cachedRotation = CachedTransform.rotation;
|
||||
|
||||
if (WeaponData.OwnerCamp == CampType.Player)
|
||||
@@ -136,14 +152,33 @@ namespace SepCore.Entity
|
||||
|
||||
public virtual ImpactData GetImpactData()
|
||||
{
|
||||
return new ImpactData(WeaponData.OwnerCamp, WeaponData.Attack, AttackStat);
|
||||
float baseCrit = GameEntry.Luban != null && GameEntry.Luban.IsReady
|
||||
? GameEntry.Luban.Global.WeaponBaseCrit
|
||||
: 0.05f;
|
||||
float critMult = GameEntry.Luban != null && GameEntry.Luban.IsReady
|
||||
? GameEntry.Luban.Global.CritMultiplier
|
||||
: 1.5f;
|
||||
|
||||
return new ImpactData(
|
||||
WeaponData.OwnerCamp,
|
||||
WeaponData.Attack,
|
||||
_ownerAttributeProvider,
|
||||
WeaponData.DamageType,
|
||||
1.0f,
|
||||
baseCrit,
|
||||
critMult);
|
||||
}
|
||||
|
||||
public abstract void Attack();
|
||||
|
||||
public void ResetAttackCooldown()
|
||||
{
|
||||
ResetAttackCooldown(CurrentCooldown);
|
||||
}
|
||||
|
||||
public virtual void Check()
|
||||
{
|
||||
_target = SelectTarget(_sqrRange);
|
||||
_target = SelectTarget(SqrRange);
|
||||
}
|
||||
|
||||
public virtual void RotateToTarget(float elapseSeconds)
|
||||
@@ -272,30 +307,18 @@ namespace SepCore.Entity
|
||||
protected void BindAttackStatFromOwner(EntityLogic parentEntity)
|
||||
{
|
||||
ReleaseAttackStatSubscription();
|
||||
AttackStat = new StatProperty();
|
||||
|
||||
if (parentEntity is not Player player) return;
|
||||
|
||||
var statComponent = player.GetComponent<StatComponent>();
|
||||
if (statComponent == null) return;
|
||||
|
||||
AttackStat = statComponent.GetStat(StatType.Attack);
|
||||
_attackStatComponent = statComponent;
|
||||
_attackStatCallback = (modifier, isApply) =>
|
||||
statComponent.UpdateStat(AttackStat, modifier, isApply);
|
||||
statComponent.Subscribe(StatType.Attack, _attackStatCallback);
|
||||
_ownerAttributeProvider = statComponent.Pipeline;
|
||||
}
|
||||
|
||||
protected void ReleaseAttackStatSubscription()
|
||||
{
|
||||
if (_attackStatComponent != null && _attackStatCallback != null)
|
||||
{
|
||||
_attackStatComponent.Unsubscribe(StatType.Attack, _attackStatCallback);
|
||||
}
|
||||
|
||||
_attackStatComponent = null;
|
||||
_attackStatCallback = null;
|
||||
AttackStat = new StatProperty();
|
||||
_ownerAttributeProvider = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user