From ea2a421b9d0117865a2c08c9bd68a2570f5e801d Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Sat, 12 Aug 2023 12:49:31 +0800 Subject: [PATCH] fix: :bug: fix the problem about CD about Trickers and Locking the doors --- logic/Client/MainWindow.xaml.cs | 6 +- logic/Gaming/ActionManager.cs | 2 +- .../SkillManager/SkillManager.ActiveSkill.cs | 2 +- logic/Preparation/Interface/ISkill.cs | 58 ++++------- logic/Preparation/Utility/SafeValue.cs | 98 ++++++++++++++++++- logic/Server/CopyInfo.cs | 13 +-- 6 files changed, 125 insertions(+), 54 deletions(-) diff --git a/logic/Client/MainWindow.xaml.cs b/logic/Client/MainWindow.xaml.cs index 3874f30..2d4c213 100644 --- a/logic/Client/MainWindow.xaml.cs +++ b/logic/Client/MainWindow.xaml.cs @@ -836,7 +836,7 @@ namespace Client foreach (var skill in occupation.ListOfIActiveSkill) { var iActiveSkill = SkillFactory.FindActiveSkill(skill); - coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; + coolTime[i, obj.PlayerId] = (int)(iActiveSkill.SkillCD.GetCD()); ++i; } isDataFixed[obj.PlayerId] = true; @@ -844,14 +844,14 @@ namespace Client } foreach (var obj in listOfButcher) { - if (obj.PlayerId < GameData.numOfStudent && !isDataFixed[obj.PlayerId]) + if (obj.PlayerId < GameData.numOfPeople && !isDataFixed[obj.PlayerId]) { IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType)); int j = 0; foreach (var skill in occupation1.ListOfIActiveSkill) { var iActiveSkill = SkillFactory.FindActiveSkill(skill); - coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; + coolTime[j, GameData.numOfStudent] = (int)(iActiveSkill.SkillCD.GetCD()); ++j; } isDataFixed[obj.PlayerId] = true; diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 6d83ff1..1b565d1 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -513,7 +513,7 @@ namespace Gaming { if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null) return false; - if (doorToLock.LockDegree.Add(GameData.checkInterval * player.SpeedOfOpeningOrLocking) >= GameData.basicSpeedOfOpeningOrLocking) + if (doorToLock.LockDegree.Add(GameData.checkInterval * player.SpeedOfOpeningOrLocking) >= GameData.degreeOfLockingOrOpeningTheDoor) return false; return true; }, diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index 88398ae..1a480b1 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -499,7 +499,7 @@ namespace Gaming { lock (activeSkill.ActiveSkillUseLock) { - if (activeSkill.StartSkill()) + if (activeSkill.SkillCD.TryUse()) { new Thread (() => diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index 65b6270..d7b9330 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -13,7 +13,7 @@ namespace Preparation.Interface } public interface IActiveSkill : ISkill { - public int SkillCD { get; } + public LongProgressCoolingDownByCD SkillCD { get; } public int DurationTime { get; } //技能持续时间 public object ActiveSkillUseLock { get; } public bool IsBeingUsed { get; set; } @@ -21,7 +21,7 @@ namespace Preparation.Interface public abstract class ActiveSkill : IActiveSkill { - public abstract int SkillCD { get; } + public abstract LongProgressCoolingDownByCD SkillCD { get; } public abstract int DurationTime { get; } private readonly object activeSkillUseLock = new(); @@ -30,28 +30,6 @@ namespace Preparation.Interface private readonly object skillLock = new(); public object SkillLock => skillLock; - private long startTime = Environment.TickCount64 - 600000; - public long StartTime - { - get - { - lock (skillLock) - return startTime; - } - } - public bool StartSkill() - { - lock (skillLock) - { - if (Environment.TickCount64 - startTime >= SkillCD) - { - startTime = Environment.TickCount64; - return true; - } - } - return false; - } - public int isBeingUsed = 0;//实为bool public bool IsBeingUsed { @@ -62,79 +40,79 @@ namespace Preparation.Interface public class CanBeginToCharge : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 2; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 2); public override int DurationTime => GameData.commonSkillTime * 3 / 10; } public class BecomeInvisible : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 4 / 3; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4 / 3); public override int DurationTime => GameData.commonSkillTime; } public class Punish : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 45 / 30; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 45 / 30); public override int DurationTime => 0; } public class HaveTea : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 3; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 3); public override int DurationTime => 0; } public class Rouse : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 4; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4); public override int DurationTime => 0; } public class Encourage : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 4; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4); public override int DurationTime => 0; } public class Inspire : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 4; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4); public override int DurationTime => 0; } public class Howl : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 25 / 30; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 25 / 30); public override int DurationTime => 0; } public class ShowTime : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 8 / 3; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 8 / 3); public override int DurationTime => GameData.commonSkillTime; } public class JumpyBomb : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD / 2; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD / 2); public override int DurationTime => GameData.commonSkillTime * 3 / 10; } public class SparksNSplash : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 45 / 30; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 45 / 30); public override int DurationTime => GameData.commonSkillTime; } public class UseKnife : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD); public override int DurationTime => GameData.commonSkillTime / 10; } public class UseRobot : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD / 300; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD / 300); public override int DurationTime => 0; private int nowPlayerID; @@ -171,7 +149,7 @@ namespace Preparation.Interface public class WriteAnswers : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD); public override int DurationTime => 0; private AtomicInt degreeOfMeditation = new(0); @@ -180,7 +158,7 @@ namespace Preparation.Interface public class SummonGolem : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD * 4 / 3; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4 / 3); public override int DurationTime => 6000; private int[] golemStateArray = new int[GameData.maxSummonedGolemNum] { 0, 0, 0 }; @@ -233,7 +211,7 @@ namespace Preparation.Interface public class NullSkill : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD; + public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD); public override int DurationTime => GameData.commonSkillTime; } diff --git a/logic/Preparation/Utility/SafeValue.cs b/logic/Preparation/Utility/SafeValue.cs index 934fbe2..286b721 100644 --- a/logic/Preparation/Utility/SafeValue.cs +++ b/logic/Preparation/Utility/SafeValue.cs @@ -504,7 +504,7 @@ namespace Preparation.Utility } /// - /// 一个保证在[0,maxNum],每CDms自动更新的可变int,支持可变的CD、maxNum(请确保大于0) + /// 一个保证在[0,maxNum],每CDms自动+1的int,支持可变的CD、maxNum(请确保大于0) /// public class IntNumUpdateByCD { @@ -679,4 +679,100 @@ namespace Preparation.Utility } } } + + /// + /// 一个每CDms自动更新冷却的bool,支持可变的无锁CD,不支持查看当前进度,初始为True + /// + public class BoolCoolingDownByCD + { + private long cd; + private long nextUpdateTime = 0; + public BoolCoolingDownByCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public BoolCoolingDownByCD(long cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public BoolCoolingDownByCD(long cd, long startTime) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + this.nextUpdateTime = startTime; + } + + public long GetCD() => Interlocked.Read(ref cd); + + public bool TryUse() + { + long needTime = Interlocked.Exchange(ref nextUpdateTime, long.MaxValue); + if (needTime <= Environment.TickCount64) + { + Interlocked.Exchange(ref nextUpdateTime, Environment.TickCount64 + Interlocked.Read(ref cd)); + return true; + } + Interlocked.Exchange(ref nextUpdateTime, needTime); + return false; + } + public void SetCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); + Interlocked.Exchange(ref this.cd, cd); + } + } + + /// + /// 一个每CDms自动更新的进度条,支持可变的CD,初始为满 + /// + public class LongProgressCoolingDownByCD + { + private int isusing = 0; + private long cd; + private long nextUpdateTime = 0; + public LongProgressCoolingDownByCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public LongProgressCoolingDownByCD(long cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public LongProgressCoolingDownByCD(long cd, long startTime) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + this.nextUpdateTime = startTime; + } + + public long GetRemainingTime() + { + long v = Interlocked.Read(ref nextUpdateTime) - Environment.TickCount64; + return v < 0 ? 0 : v; + } + public long GetCD() => Interlocked.Read(ref cd); + + public bool TryUse() + { + if (Interlocked.Exchange(ref isusing, 1) == 1) return false; + long needTime = Interlocked.Read(ref nextUpdateTime); + if (needTime <= Environment.TickCount64) + { + Interlocked.Exchange(ref nextUpdateTime, Environment.TickCount64 + Interlocked.Read(ref cd)); + Interlocked.Exchange(ref isusing, 0); + return true; + } + Interlocked.Exchange(ref isusing, 0); + return false; + } + public void SetCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); + Interlocked.Exchange(ref this.cd, cd); + } + } } \ No newline at end of file diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs index 7532cd6..57863dc 100644 --- a/logic/Server/CopyInfo.cs +++ b/logic/Server/CopyInfo.cs @@ -2,6 +2,7 @@ using Protobuf; using GameClass.GameObj; using Preparation.Utility; using Gaming; +using Preparation.Interface; namespace Server { @@ -81,10 +82,8 @@ namespace Server }; foreach (var keyValue in player.ActiveSkillDictionary) - { - int progress = (int)((keyValue.Value.StartTime - time) + keyValue.Value.SkillCD); - msg.StudentMessage.TimeUntilSkillAvailable.Add(progress < 0 ? 0 : progress); - } + msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value.SkillCD.GetRemainingTime()); + for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i) msg.StudentMessage.TimeUntilSkillAvailable.Add(-1); @@ -124,11 +123,9 @@ namespace Server BulletType = Transformation.ToBulletType((Preparation.Utility.BulletType)player.BulletOfPlayer) } }; + foreach (var keyValue in player.ActiveSkillDictionary) - { - int progress = (int)(keyValue.Value.SkillCD + (keyValue.Value.StartTime - time)); - msg.TrickerMessage.TimeUntilSkillAvailable.Add(progress < 0 ? 0 : progress); - } + msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value.SkillCD.GetRemainingTime()); for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i) msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1);