using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Preparation.Utility; namespace GameClass.GameObj { public partial class Character { private readonly BuffManager buffManager; /// /// 角色携带的buff管理器 /// private class BuffManager { /// /// buff列表 /// private readonly LinkedList[] buffList; private readonly object[] buffListLock; private void AddBuff(double bf, int buffTime, BuffType buffType, Action ReCalculateFunc) { LinkedListNode buffNode; lock (buffListLock[(int)buffType]) { buffNode = buffList[(int)buffType].AddLast(bf); } ReCalculateFunc(); new Thread ( () => { Thread.Sleep(buffTime); try { lock (buffListLock[(int)buffType]) { buffList[(int)buffType].Remove(buffNode); } } catch { } ReCalculateFunc(); } ) { IsBackground = true }.Start(); } public int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int minVal) { double times = 1.0; lock (buffListLock[(int)buffType]) { foreach (var add in buffList[(int)buffType]) { times *= add; } } return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal); } public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(add, buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed))); public bool HasFasterSpeed { get { lock (buffListLock[(int)BuffType.AddSpeed]) { return buffList[(int)BuffType.AddSpeed].Count != 0; } } } public void AddShield(int shieldTime) => AddBuff(0, shieldTime, BuffType.Shield, () => { }); public bool HasShield { get { lock (buffListLock[(int)BuffType.Shield]) { return buffList[(int)BuffType.Shield].Count != 0; } } } public bool TryUseShield() { if (HasShield) { lock (buffListLock[(int)BuffType.Shield]) { buffList[(int)BuffType.Shield].RemoveFirst(); } return true; } return false; } public void AddAp(int time) => AddBuff(0, time, BuffType.AddAp, () => { }); public bool HasAp { get { lock (buffListLock[(int)BuffType.AddAp]) { return buffList[(int)BuffType.AddAp].Count != 0; } } } public bool TryAddAp() { if (HasAp) { lock (buffListLock[(int)BuffType.AddAp]) { buffList[(int)BuffType.AddAp].RemoveFirst(); } return true; } return false; } public void AddLife(int totelTime) => AddBuff(0, totelTime, BuffType.AddLife, () => { }); public bool HasLIFE { get { lock (buffListLock[(int)BuffType.AddLife]) { return buffList[(int)BuffType.AddLife].Count != 0; } } } public bool TryActivatingLIFE() { if (HasLIFE) { lock (buffListLock[(int)BuffType.AddLife]) { buffList[(int)BuffType.AddLife].RemoveFirst(); } return true; } return false; } public void AddSpear(int spearTime) => AddBuff(0, spearTime, BuffType.Spear, () => { }); public bool HasSpear { get { lock (buffListLock[(int)BuffType.Spear]) { return buffList[(int)BuffType.Spear].Count != 0; } } } public bool TryUseSpear() { if (HasSpear) { lock (buffListLock[(int)BuffType.Spear]) { buffList[(int)BuffType.Spear].RemoveFirst(); } return true; } return false; } public bool TryDeleteInvisible() { if (HasInvisible) { lock (buffListLock[(int)BuffType.Invisible]) { buffList[(int)BuffType.Invisible].RemoveFirst(); } return true; } return false; } public void AddClairaudience(int shieldTime) => AddBuff(0, shieldTime, BuffType.Clairaudience, () => { }); public bool HasClairaudience { get { lock (buffListLock[(int)BuffType.Clairaudience]) { return buffList[(int)BuffType.Clairaudience].Count != 0; } } } public void AddInvisible(int shieldTime) => AddBuff(0, shieldTime, BuffType.Invisible, () => { }); public bool HasInvisible { get { lock (buffListLock[(int)BuffType.Invisible]) { return buffList[(int)BuffType.Invisible].Count != 0; } } } /// /// 清除所有buff /// public void ClearAll() { for (int i = 0; i < buffList.Length; ++i) { lock (buffListLock[i]) { buffList[i].Clear(); } } } public BuffManager() { var buffTypeArray = Enum.GetValues(typeof(BuffType)); buffList = new LinkedList[buffTypeArray.Length]; buffListLock = new object[buffList.Length]; int i = 0; foreach (BuffType type in buffTypeArray) { buffList[i] = new LinkedList(); buffListLock[i++] = new object(); } } } public int ReCalculateBuff(BuffType buffType, int orgVal, int maxVal, int minVal) { return buffManager.ReCalculateFloatBuff(buffType, orgVal, maxVal, minVal); } } }