using System.Collections.Generic; using System.Runtime.CompilerServices; using Entitas; using xFrame; using Proto; using Sog; namespace CoreGame.Render { public struct Modifer { public Fixed64 val; public int def; } public delegate void OnPropertyChange(PropertyDef def, float dt, float val); // PropertyContainer 是 PropertyComponent 的友元类 public partial class PropertyContainer { [Combat] public class PropertyComponent : IComponent, IReset { public CombatEntity ent; public PropertyContainer container; private readonly Dictionary> m_PostChange = new(); private readonly Dictionary m_Modifiers = new(); public void SetLinkProperty(PropertyDef def) { container.SetLinkProperty(def, true); } public void SetLinkEid(int eid) { container.m_Eid = eid; } public void RegisterPostChange(PropertyDef propertyDef, OnPropertyChange onPostChange) { if (m_PostChange.TryGetValue(propertyDef, out var acts) == false) { acts = ListPool.Pop(); m_PostChange.Add(propertyDef, acts); return; } acts.Add(onPostChange); } public void SetProperty(PropertyDef propertyDef, Fixed64 baseVal, bool force = false) { if (container.m_Properties[(int)propertyDef] != 0) { if (force == false) { XLog.LogWarning($"PropertyDef {propertyDef} has been set"); return; } } container.m_Properties[(int)propertyDef] = baseVal; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetProperty_TenThousand(in PropertyDef propertyDef, long val, bool force = false) { if (container.m_Properties[(int)propertyDef] != 0) { if (force == false) { XLog.LogWarning($"PropertyDef {propertyDef} has been set"); return; } } container.m_Properties[(int)propertyDef] = val * Fixed64.EN4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Fixed64 GetProperty(in PropertyDef propertyDef) { return container.GetProperty(propertyDef); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long GetProperty_Long(in PropertyDef propertyDef) { return container.GetProperty_Long(propertyDef); } //没有modifyid的话,是isntant的,无法撤销 [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Rest(PropertyDef propertyDef) { container.m_Properties[(int)propertyDef] = 0; } //没有modifyid的话,是isntant的,无法撤销 [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddValue(PropertyDef propertyDef, Fixed64 value) { PushModifer(propertyDef, value, 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PushModifer_TenThousand(PropertyDef propertyDef, long value, int modifyId) { PushModifer(propertyDef, value * Fixed64.EN4, modifyId); } //没有modifyid的话,是isntant的,无法撤销 //[MethodImpl(MethodImplOptions.AggressiveInlining)] public void PushModifer(PropertyDef propertyDef, Fixed64 value, int modifyId) { if (modifyId == 0) { BattleLogger.LogInfoByEntity(ent, $"PushModifer [{propertyDef}] = [{value}] modifyId:{modifyId}"); container.AddProperty(propertyDef, value); return; } if (m_Modifiers.TryGetValue(modifyId, out var modifer)) { if (modifer.def == (int)propertyDef) { container.AddProperty(propertyDef, -modifer.val); m_Modifiers.Remove(modifyId); } } modifer = new Modifer { val = value, def = (int)propertyDef }; m_Modifiers.Add(modifyId, modifer); BattleLogger.LogInfoByEntity(ent, $"PushModifer [{propertyDef}] = [{modifer.val}] modifyId:{modifyId}"); container.AddProperty(propertyDef, modifer.val); } //没有modifyid的话,是isntant的,无法撤销 //[MethodImpl(MethodImplOptions.AggressiveInlining)] public void PopModifer(PropertyDef propertyDef, int modifyId, bool nocheck = false) { if (m_Modifiers.TryGetValue(modifyId, out var modifer)) { if (modifer.def == (int)propertyDef) { BattleLogger.LogInfoByEntity(ent, $"PopModifer [{propertyDef}] = [{modifer.val}] modifyId:{modifyId}"); container.AddProperty(propertyDef, -modifer.val); m_Modifiers.Remove(modifyId); } else { BattleLogger.LogInfoByEntity(ent,$"RevertModifer failed, modifyId:{modifyId} propertyDef:{propertyDef}"); } } else { if (nocheck == false) BattleLogger.LogInfoByEntity(ent,$"RevertModifer failed, modifyId:{modifyId} propertyDef:{propertyDef}"); } } public void TaskSnapShot(PropertyContainer cont) { for (int i = 0; i < container.m_Properties.Length; i++) { if (container.m_PropIsLink[i]) { cont.m_Properties[i] = container.GetProperty((PropertyDef)i); } else { cont.m_Properties[i] = container.m_Properties[i]; } } } public bool HasModifer() { return m_Modifiers.Count > 0; } #region 计算属性_中间属性 public Fixed64 Atk => container.Atk; public Fixed64 MoveSpeed => container.MoveSpeed; public Fixed64 PickupRange => container.PickupRange; public long TotalHp => container.TotalHp; #endregion public void Reset() { foreach (var value in m_PostChange) { var onPropertyChanges = value.Value; ListPool.Push(ref onPropertyChanges); } m_PostChange.Clear(); SptPool.Free(ref container); m_Modifiers.Clear(); } } } }