引入属性、伤害管线

This commit is contained in:
2026-09-18 21:43:22 +08:00
parent 92e1ea0d55
commit ba25ec1926
108 changed files with 2920 additions and 720 deletions
@@ -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;
}
}
}