// Assets/_Project/Scripts/Gameplay/ActiveBuff.cs using System; using Unity.Collections; using Unity.Netcode; using TD.Core; namespace TD.Gameplay { /// /// One buff currently held by a player. Stored in /// 's NetworkList so all peers see the same set. /// /// /// IEquatable. NGO's NetworkList indexer setter short-circuits when /// Equals returns true, silently dropping the write. Every mutable field /// (only ) is included in the comparison so toggling a /// buff correctly propagates to clients. /// public struct ActiveBuff : INetworkSerializable, IEquatable { /// Which tower stat this buff multiplies. public BuffStat Stat; /// Multiplicative factor, e.g. 1.25 for +25%. public float Multiplier; /// /// False when disabled (e.g. by an enemy ability). Excluded from /// while false. /// public bool IsActive; /// Human-readable name for the HUD buff list. public FixedString64Bytes DisplayName; // ----- INetworkSerializable --------------------------------------- public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { byte statByte = (byte)Stat; serializer.SerializeValue(ref statByte); Stat = (BuffStat)statByte; serializer.SerializeValue(ref Multiplier); serializer.SerializeValue(ref IsActive); serializer.SerializeValue(ref DisplayName); } // ----- IEquatable ------------------------------------------------- public bool Equals(ActiveBuff other) => Stat == other.Stat && Multiplier == other.Multiplier && IsActive == other.IsActive && DisplayName == other.DisplayName; public override bool Equals(object obj) => obj is ActiveBuff other && Equals(other); public override int GetHashCode() => HashCode.Combine((int)Stat, Multiplier, IsActive); } }