using System; using System.Runtime.CompilerServices; using Proto; using Sog; using xFrame; namespace CoreGame.Render { public class PropRelation { public int propTotal = 0; public int propTotalRate = 0; } public partial class PropertyContainer : ISptPool { private static readonly float s_Epsilon = 0.000001f; public static float Epsilon => s_Epsilon * 2; public static readonly PropertyContainer s_Empty = new(); private static readonly PropRelation[] s_PropRelations = new PropRelation[(int)PropertyDef.Size]; // 进来的全是万分比 private readonly Fixed64[] m_Properties = new Fixed64[(int)PropertyDef.Size]; // 是否是链式属性,比如被关联的存活,就要取被关联者是属性 private readonly bool[] m_PropIsLink = new bool[(int)PropertyDef.Size]; private int m_Eid; static PropertyContainer() { s_PropRelations[(int)PropertyDef.CurHp] = new PropRelation() { propTotal = (int)PropertyDef.HpFixedIncrease, propTotalRate = (int)PropertyDef.HpPercentIncrease, }; s_PropRelations[(int)PropertyDef.Ammo] = new PropRelation() { propTotal = (int)PropertyDef.AmmoMax, }; // s_TypeDict[(int)PropertyDef.Atk] = true; // s_TypeDict[(int)PropertyDef.AtkFixedIncrease] = true; // s_TypeDict[(int)PropertyDef.CurHp] = true; // s_TypeDict[(int)PropertyDef.TotalHp] = true; } public void Awake() { Awake(this, 0); } public void Awake(PropertyContainer other) { Awake(other, 0); } public void Awake(PropertyContainer other, int eid) { Array.Copy(other.m_Properties, m_Properties, m_Properties.Length); Array.Copy(other.m_PropIsLink, m_PropIsLink, m_PropIsLink.Length); m_Properties[(int)PropertyDef.Calc_GunBalance] = 1; } private void SetLinkProperty(in PropertyDef propertyDef, bool isLink) { m_PropIsLink[(int)propertyDef] = isLink; } public void AddProperty(in PropertyDef propertyDef, Fixed64 val) { #if UNITY_EDITOR if (propertyDef == PropertyDef.None && val != 0) { XLog.LogWarning("给PropertyDef.None属性赋值了,请检查配置..."); return; } #endif var index = (int)propertyDef; m_Properties[index] += val; var propRelation = s_PropRelations[index]; if (propRelation != null) { var total = m_Properties[propRelation.propTotal]; var rate = m_Properties[propRelation.propTotalRate]; var max = total * (1 + rate); if (m_Properties[index] > max) { m_Properties[index] = max; // XLog.LogWarning($"PropertyDef {propertyDef} is over max"); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long GetProperty_Long(in PropertyDef propertyDef) { var index = (int)propertyDef; if (m_PropIsLink[index]) { var entity = Contexts.Combat.GetEntity(m_Eid); if (entity != null) { var propertyLong = entity.property.GetProperty_Long(propertyDef); m_Properties[index] = propertyLong; } } return m_Properties[index].AsLong; // 防止精度问题 } // [MethodImpl(MethodImplOptions.AggressiveInlining)] public Fixed64 GetProperty(in PropertyDef propertyDef) { var index = (int)propertyDef; if (m_PropIsLink[index]) { var entity = Contexts.Combat.GetEntity(m_Eid); if (entity != null) { var propertyLong = entity.property.GetProperty(propertyDef); m_Properties[index] = propertyLong; } } return m_Properties[(int)propertyDef]; // 防止精度问题 } // [MethodImpl(MethodImplOptions.AggressiveInlining)] // public float GetProperty_Float(in PropertyDef propertyDef) // { // var index = (int)propertyDef; // if (m_PropIsLink[index]) // { // var entity = Contexts.Combat.GetEntity(m_Eid); // if (entity != null) // { // var propertyLong = entity.property.GetProperty(propertyDef); // m_Properties[index] = propertyLong; // } // } // return (float)(m_Properties[(int)propertyDef]); // 防止精度问题 // } /// /// 攻击力 /// public Fixed64 Atk => m_Properties[(int)PropertyDef.AtkFixedIncrease] * (1 + m_Properties[(int)PropertyDef.AtkPercentIncrease]); public Fixed64 Def => m_Properties[(int)PropertyDef.DefFixedIncrease] * (1 + m_Properties[(int)PropertyDef.DefPercentIncrease]); public Fixed64 MoveSpeed => GetProperty(PropertyDef.SpeedFixedIncrease) * (1 + GetProperty(PropertyDef.SpeedPercentIncrease)); public Fixed64 PickupRange => GetProperty(PropertyDef.BasePickupRange) * (1 + GetProperty(PropertyDef.PickupRangeIncrease)); public long TotalHp => (GetProperty(PropertyDef.HpFixedIncrease) * (1 + GetProperty(PropertyDef.HpPercentIncrease))).AsLong; public void Reset() { Array.Clear(m_Properties, 0, m_Properties.Length); } } }