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);