Browse Source

Merge pull request #670 from shangfengh/new

feat:  Add the progress TimeBasedProgressAtVariableSpeed
dev
shangfengh GitHub 2 years ago
parent
commit
f345eee27b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 480 additions and 219 deletions
  1. +1
    -1
      logic/GameClass/GameObj/Character/Character.cs
  2. +3
    -55
      logic/GameClass/GameObj/Map/Doorway.cs
  3. +1
    -1
      logic/GameClass/GameObj/Map/Map.cs
  4. +4
    -3
      logic/Gaming/ActionManager.cs
  5. +1
    -4
      logic/Preparation/Interface/IDoorway.cs
  6. +225
    -18
      logic/Preparation/Utility/SafeValue/Atomic.cs
  7. +53
    -56
      logic/Preparation/Utility/SafeValue/InTheRange.cs
  8. +191
    -79
      logic/Preparation/Utility/SafeValue/TimeBased.cs
  9. +1
    -2
      logic/Server/CopyInfo.cs

+ 1
- 1
logic/GameClass/GameObj/Character/Character.cs View File

@@ -327,7 +327,7 @@ namespace GameClass.GameObj
case PlayerStateType.OpeningTheDoorway:
if (value == PlayerStateType.Rescued) return -1;
Doorway doorway = (Doorway)lastObj!;
doorway.StopOpenning();
doorway.ProgressOfDoorway.TryStop();
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.OpeningTheDoor:
if (value == PlayerStateType.Rescued) return -1;


+ 3
- 55
logic/GameClass/GameObj/Map/Doorway.cs View File

@@ -17,70 +17,18 @@ namespace GameClass.GameObj
public override ShapeType Shape => ShapeType.Square;
public override bool IgnoreCollideExecutor(IGameObj targetObj)
{
if (!IsOpen()) return false;
if (!ProgressOfDoorway.IsFinished()) return false;
if (targetObj.Type != GameObjType.Character)
return true; // 非玩家不碰撞
return false;
}

public AtomicBool PowerSupply { get; } = new(false);

private long openStartTime = 0;
public long OpenStartTime
{
get
{
lock (gameObjLock)
return openStartTime;
}
}
public TimeBasedProgressAtVariableSpeed ProgressOfDoorway { get; } = new(GameData.degreeOfOpenedDoorway, 1);
public bool TryToOpen()
{
if (!PowerSupply) return false;
lock (gameObjLock)
{
if (openStartTime > 0) return false;
openStartTime = Environment.TickCount64;
return true;
}
return ProgressOfDoorway.Start();
}

public bool StopOpenning()
{
lock (gameObjLock)
{
if (Environment.TickCount64 - openStartTime + openDegree >= GameData.degreeOfOpenedDoorway)
{
openDegree = GameData.degreeOfOpenedDoorway;
return true;
}
else
{
openDegree = (int)(Environment.TickCount64 - openStartTime) + openDegree;
openStartTime = 0;
return false;
}
}
}

public void FinishOpenning()
{
lock (gameObjLock)
{
openDegree = GameData.degreeOfOpenedDoorway;
}
}

private int openDegree = 0;
public int OpenDegree
{
get
{
lock (gameObjLock)
return openDegree;
}
}

public bool IsOpen() => (OpenDegree == GameData.degreeOfOpenedDoorway);
}
}

+ 1
- 1
logic/GameClass/GameObj/Map/Map.cs View File

@@ -24,7 +24,7 @@ namespace GameClass.GameObj
GameObjLockDict[GameObjType.EmergencyExit].EnterReadLock();
try
{
Random r = new Random(Environment.TickCount);
Random r = new(Environment.TickCount);
EmergencyExit emergencyExit = (EmergencyExit)(GameObjDict[GameObjType.EmergencyExit][r.Next(0, GameObjDict[GameObjType.EmergencyExit].Count)]);
emergencyExit.CanOpen.SetReturnOri(true);
Preparation.Utility.Debugger.Output(emergencyExit, emergencyExit.Position.ToString());


+ 4
- 3
logic/Gaming/ActionManager.cs View File

@@ -2,6 +2,7 @@
using System.Threading;
using GameClass.GameObj;
using GameEngine;
using Preparation.Interface;
using Preparation.Utility;
using Timothy.FrameRateTask;

@@ -148,11 +149,11 @@ namespace Gaming
player.ThreadNum.Release();
return;
}
Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree);
Thread.Sleep(GameData.degreeOfOpenedDoorway - (int)doorwayToOpen.ProgressOfDoorway.GetProgressNow());

if (player.ResetPlayerState(stateNum))
{
doorwayToOpen.FinishOpenning();
doorwayToOpen.ProgressOfDoorway.Finish();
player.ThreadNum.Release();
}
}
@@ -168,7 +169,7 @@ namespace Gaming
return false;

Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
if (doorwayForEscape != null && doorwayForEscape.IsOpen())
if (doorwayForEscape != null && doorwayForEscape.ProgressOfDoorway.IsProgressing())
{
if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false;
player.AddScore(GameData.StudentScoreEscape);


+ 1
- 4
logic/Preparation/Interface/IDoorway.cs View File

@@ -4,9 +4,6 @@ namespace Preparation.Interface
{
public interface IDoorway : IGameObj
{
public long OpenStartTime { get; }
public int OpenDegree { get; }
public bool StopOpenning();
public bool TryToOpen();
public TimeBasedProgressAtVariableSpeed ProgressOfDoorway { get; }
}
}

+ 225
- 18
logic/Preparation/Utility/SafeValue/Atomic.cs View File

@@ -1,4 +1,5 @@
using System;
using Google.Protobuf.WellKnownTypes;
using System;
using System.Threading;

namespace Preparation.Utility
@@ -10,7 +11,7 @@ namespace Preparation.Utility

public class AtomicInt : Atomic
{
private int v;
protected int v;
public AtomicInt(int x)
{
v = x;
@@ -19,33 +20,239 @@ namespace Preparation.Utility
public int Get() => Interlocked.CompareExchange(ref v, -1, -1);
public static implicit operator int(AtomicInt aint) => Interlocked.CompareExchange(ref aint.v, -1, -1);
/// <returns>返回操作前的值</returns>
public int SetReturnOri(int value) => Interlocked.Exchange(ref v, value);
public int Add(int x) => Interlocked.Add(ref v, x);
public int Sub(int x) => Interlocked.Add(ref v, -x);
public int Inc() => Interlocked.Increment(ref v);
public int Dec() => Interlocked.Decrement(ref v);
public virtual int SetReturnOri(int value) => Interlocked.Exchange(ref v, value);
public virtual int Add(int x) => Interlocked.Add(ref v, x);
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public virtual int AddPositive(int x) => Interlocked.Add(ref v, x);
public virtual int Sub(int x) => Interlocked.Add(ref v, -x);
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public virtual int SubPositive(int x) => Interlocked.Add(ref v, -x);
public virtual int Inc() => Interlocked.Increment(ref v);
public virtual int Dec() => Interlocked.Decrement(ref v);
/// <returns>返回操作前的值</returns>
public int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
public virtual int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
}

/// <summary>
/// 参数要求倍率speed(默认1)以及AtomicInt类的Score,
/// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed取整。
/// 注意:AtomicIntOnlyAddScore本身为AtomicInt,提供的Score可能构成环而死锁。
/// </summary>
public class AtomicIntOnlyAddScore : AtomicInt
{
public AtomicInt Score { get; set; }
public AtomicDouble speed;
public AtomicIntOnlyAddScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
{
this.Score = Score;
this.speed = new(speed);
}
/// <returns>返回操作前的值</returns>
public override int SetReturnOri(int value)
{
int previousV = Interlocked.Exchange(ref v, value);
if (value - previousV > 0)
Score.AddPositive((int)(speed * (value - previousV)));
return previousV;
}
public override int Add(int x)
{
if (x > 0) Score.AddPositive((int)(speed * x));
return Interlocked.Add(ref v, x);
}
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public override int AddPositive(int x)
{
Score.AddPositive((int)(speed * x));
return Interlocked.Add(ref v, x);
}
public override int Sub(int x)
{
if (x < 0) Score.AddPositive((int)(speed * -x));
return Interlocked.Add(ref v, -x);
}
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public override int SubPositive(int x)
{
return Interlocked.Add(ref v, -x);
}
public override int Inc()
{
Score.AddPositive((int)(speed));
return Interlocked.Increment(ref v);
}
/// <returns>返回操作前的值</returns>
public override int CompareExReturnOri(int newV, int compareTo)
{
int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
if (newV - previousV > 0)
Score.AddPositive((int)(speed * (newV - previousV)));
return previousV;
}
}

/// <summary>
/// 参数要求倍率speed(默认1)以及AtomicInt类的Score,
/// 在发生变化时,自动给Score加上变化的差乘以speed取整。
/// 注意:AtomicIntChangeAffectScore本身为AtomicInt,提供的Score可能构成环而死锁。
/// </summary>
public class AtomicIntChangeAffectScore : AtomicInt
{
public AtomicInt Score { get; set; }
public AtomicDouble speed;
public AtomicIntChangeAffectScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
{
this.Score = Score;
this.speed = new(speed);
}
/// <returns>返回操作前的值</returns>
public override int SetReturnOri(int value)
{
int previousV = Interlocked.Exchange(ref v, value);
Score.Add((int)(speed * (value - previousV)));
return previousV;
}
public override int Add(int x)
{
Score.Add((int)(speed * x));
return Interlocked.Add(ref v, x);
}
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public override int AddPositive(int x)
{
Score.AddPositive((int)(speed * x));
return Interlocked.Add(ref v, x);
}
public override int Sub(int x)
{
Score.Sub((int)(speed * x));
return Interlocked.Add(ref v, -x);
}
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public override int SubPositive(int x)
{
Score.SubPositive((int)(speed * x));
return Interlocked.Add(ref v, -x);
}
public override int Inc()
{
Score.AddPositive((int)(speed));
return Interlocked.Increment(ref v);
}
public override int Dec()
{
Score.SubPositive((int)(speed));
return Interlocked.Decrement(ref v);
}
/// <returns>返回操作前的值</returns>
public override int CompareExReturnOri(int newV, int compareTo)
{
int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
Score.Add((int)(speed * (newV - previousV)));
return previousV;
}
}

public class AtomicLong : Atomic
{
private long v;
protected long v;
public AtomicLong(long x)
{
v = x;
}
public override string ToString() => Interlocked.Read(ref v).ToString();
public long Get() => Interlocked.Read(ref v);
public static implicit operator long(AtomicLong along) => Interlocked.Read(ref along.v);
public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString();
public long Get() => Interlocked.CompareExchange(ref v, -1, -1);
public static implicit operator long(AtomicLong along) => Interlocked.CompareExchange(ref along.v, -1, -1);
/// <returns>返回操作前的值</returns>
public long SetReturnOri(long value) => Interlocked.Exchange(ref v, value);
public long Add(long x) => Interlocked.Add(ref v, x);
public long Sub(long x) => Interlocked.Add(ref v, -x);
public long Inc() => Interlocked.Increment(ref v);
public long Dec() => Interlocked.Decrement(ref v);
public virtual long SetReturnOri(long value) => Interlocked.Exchange(ref v, value);
public virtual long Add(long x) => Interlocked.Add(ref v, x);
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public virtual long AddPositive(long x) => Interlocked.Add(ref v, x);
public virtual long Sub(long x) => Interlocked.Add(ref v, -x);
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public virtual long SubPositive(long x) => Interlocked.Add(ref v, -x);
public virtual long Inc() => Interlocked.Increment(ref v);
public virtual long Dec() => Interlocked.Decrement(ref v);
/// <returns>返回操作前的值</returns>
public long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
public virtual long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
}

/// <summary>
/// 参数要求倍率speed(默认1)以及AtomicLong类的Score,
/// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed取整。
/// 注意:AtomicLongOnlyAddScore本身为AtomicLong,提供的Score可能构成环而死锁。
/// </summary>
public class AtomicLongOnlyAddScore : AtomicLong
{
public AtomicLong Score { get; set; }
public AtomicDouble speed;
public AtomicLongOnlyAddScore(long x, AtomicLong score, double speed = 1.0) : base(x)
{
this.Score = score;
this.speed = new(speed);
}
/// <returns>返回操作前的值</returns>
public override long SetReturnOri(long value)
{
long previousV = Interlocked.Exchange(ref v, value);
if (value - previousV > 0)
Score.AddPositive((long)(speed * (value - previousV)));
return previousV;
}
public override long Add(long x)
{
if (x > 0) Score.AddPositive((long)(speed * x));
return Interlocked.Add(ref v, x);
}
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public override long AddPositive(long x)
{
Score.AddPositive((long)(speed * x));
return Interlocked.Add(ref v, x);
}
public override long Sub(long x)
{
if (x < 0) Score.AddPositive((long)(speed * -x));
return Interlocked.Add(ref v, -x);
}
/// <summary>
/// 注意:确保参数为非负数
/// </summary>
public override long SubPositive(long x)
{
return Interlocked.Add(ref v, -x);
}
public override long Inc()
{
Score.AddPositive((long)(speed));
return Interlocked.Increment(ref v);
}
/// <returns>返回操作前的值</returns>
public override long CompareExReturnOri(long newV, long compareTo)
{
long previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
if (newV - previousV > 0)
Score.AddPositive((long)(speed * (newV - previousV)));
return previousV;
}
}

public class AtomicDouble : Atomic


+ 53
- 56
logic/Preparation/Utility/SafeValue/InTheRange.cs View File

@@ -24,8 +24,8 @@ namespace Preparation.Utility
/// </summary>
public class IntInTheVariableRange : InTheVariableRange
{
private int v;
private int maxV;
protected int v;
protected int maxV;
#region 构造与读取
public IntInTheVariableRange(int value, int maxValue) : base()
{
@@ -157,6 +157,13 @@ namespace Preparation.Utility
return true;
}
}
public void SetVToMaxV()
{
lock (vLock)
{
v = maxV;
}
}
public bool Set0IfNotMaxor0()
{
lock (vLock)
@@ -397,6 +404,32 @@ namespace Preparation.Utility
return v - previousV;
}
}

/// <summary>
/// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue
/// 如果无法加到maxValue则清零
/// </summary>
/// <returns>返回是否清零</returns>
public bool Set0IfNotAddToMaxV(StartTime startTime, double speed = 1.0)
{
lock (vLock)
{
if (v == maxV) return false;
int addV = (int)(startTime.StopIfPassing(maxV - v) * speed);
if (addV < 0)
{
v = 0;
return true;
}
if (maxV - v < addV)
{
v = maxV;
return false;
}
v = 0;
return false;
}
}
#endregion
}

@@ -405,8 +438,8 @@ namespace Preparation.Utility
/// </summary>
public class LongInTheVariableRange : InTheVariableRange
{
private long v;
private long maxV;
protected long v;
protected long maxV;
#region 构造与读取
public LongInTheVariableRange(long value, long maxValue) : base()
{
@@ -455,23 +488,6 @@ namespace Preparation.Utility
}
#endregion

#region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据)
public (long, long) GetValue(StartTime startTime)
{
lock (vLock)
{
return (v, startTime.Get());
}
}
public (long, long, long) GetValueAndMaxV(StartTime startTime)
{
lock (vLock)
{
return (v, maxV, startTime.Get());
}
}
#endregion

#region 普通设置MaxV与Value的值的方法
/// <summary>
/// 若maxValue<=0则maxValue设为0并返回False
@@ -645,6 +661,13 @@ namespace Preparation.Utility
return true;
}
}
public void SetVToMaxV()
{
lock (vLock)
{
v = maxV;
}
}

public bool Set0IfNotMax()
{
@@ -709,22 +732,6 @@ namespace Preparation.Utility
}
}

/// <summary>
/// 增加量为时间差*速度,并将startTime变为long.MaxValue
/// </summary>
/// <returns>返回实际改变量</returns>
public long AddV(StartTime startTime, double speed = 1.0)
{
lock (vLock)
{
long previousV = v;
long addV = (Environment.TickCount64 - startTime.Stop());
if (addV < 0) v += (long)(addV * speed);
else return 0;
if (v > maxV) v = maxV;
return v - previousV;
}
}
#endregion
}

@@ -733,8 +740,8 @@ namespace Preparation.Utility
/// </summary>
public class DoubleInTheVariableRange : InTheVariableRange
{
private double v;
private double maxV;
protected double v;
protected double maxV;
#region 构造与读取
public DoubleInTheVariableRange(double value, double maxValue) : base()
{
@@ -783,23 +790,6 @@ namespace Preparation.Utility
}
#endregion

#region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据)
public (double, long) GetValue(StartTime startTime)
{
lock (vLock)
{
return (v, startTime.Get());
}
}
public (double, double, long) GetValueAndMaxValue(StartTime startTime)
{
lock (vLock)
{
return (v, maxV, startTime.Get());
}
}
#endregion

#region 普通设置MaxV与Value的值的方法
/// <summary>
/// 若maxValue<=0则maxValue设为0并返回False
@@ -949,6 +939,13 @@ namespace Preparation.Utility
return true;
}
}
public void SetVToMaxV()
{
lock (vLock)
{
v = maxV;
}
}

public bool Set0IfNotMax()
{


+ 191
- 79
logic/Preparation/Utility/SafeValue/TimeBased.cs View File

@@ -35,6 +35,197 @@ namespace Preparation.Utility
}
}

public class LongInTheVariableRangeWithStartTime : LongInTheVariableRange
{
public StartTime startTime = new();
public LongInTheVariableRangeWithStartTime(long value, long maxValue) : base(value, maxValue) { }
/// <summary>
/// 默认使Value=maxValue
/// </summary>
public LongInTheVariableRangeWithStartTime(long maxValue) : base(maxValue) { }
public LongInTheVariableRangeWithStartTime() : base() { }

#region 读取
public (long, long) GetValueWithStartTime()
{
lock (vLock)
{
return (v, startTime.Get());
}
}
public (long, long, long) GetValueAndMaxVWithStartTime()
{
lock (vLock)
{
return (v, maxV, startTime.Get());
}
}
#endregion

/// <summary>
/// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue
/// 如果无法加到maxValue则不加
/// </summary>
/// <returns>返回试图加到的值与最大值</returns>
public (long, long, long) AddStartTimeToMaxV(double speed = 1.0)
{
lock (vLock)
{
long addV = (long)(startTime.StopIfPassing(maxV - v) * speed);
if (addV < 0) return (v, maxV, startTime.Get());
if (maxV - v < addV) return (v = maxV, maxV, startTime.Get());
return (v + addV, maxV, startTime.Get());
}
}

/// <summary>
/// 增加量为时间差*速度,并将startTime变为long.MaxValue
/// </summary>
/// <returns>返回实际改变量</returns>
public long AddStartTime(double speed = 1.0)
{
lock (vLock)
{
long previousV = v;
long addV = (Environment.TickCount64 - startTime.Stop());
if (addV < 0) v += (long)(addV * speed);
else return 0;
if (v > maxV) v = maxV;
return v - previousV;
}
}

/// <summary>
/// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上
/// 如果无法加到maxValue则清零
/// 无论如何startTime变为long.MaxValue
/// </summary>
/// <returns>返回是否清零</returns>
public bool Set0IfNotAddStartTimeToMaxV(double speed = 1.0)
{
lock (vLock)
{
if (v == maxV) return false;
long addV = (long)(startTime.Stop() * speed);
if (addV < 0)
{
v = 0;
return true;
}
if (maxV - v < addV)
{
v = maxV;
return false;
}
v = 0;
return false;
}
}

public void SetAndStop(long value = 0)
{
lock (vLock)
{
this.v = value;
startTime.Stop();
}
}
}

public class TimeBasedProgressAtVariableSpeed
{
private LongInTheVariableRangeWithStartTime progress;
public AtomicDouble speed;

#region 构造
public TimeBasedProgressAtVariableSpeed(long needProgress, double speed = 1.0)
{
progress = new LongInTheVariableRangeWithStartTime(0, needProgress);
if (needProgress <= 0) Debugger.Output("Bug:TimeBasedProgressAtVariableSpeed.needProgress (" + needProgress.ToString() + ") is less than 0.");
this.speed = new(speed);
}
public TimeBasedProgressAtVariableSpeed()
{
progress = new LongInTheVariableRangeWithStartTime(0, 0);
this.speed = new(1.0);
}
#endregion

#region 读取
public override string ToString()
{
long progressStored, lastStartTime;
(progressStored, lastStartTime) = progress.GetValueWithStartTime();
return "ProgressStored: " + progressStored.ToString()
+ " ; LastStartTime: " + lastStartTime.ToString() + "ms"
+ " ; Speed: " + speed.ToString();
}
public long GetProgressNow() => progress.AddStartTimeToMaxV((double)speed).Item1;
public (long, long, long) GetProgressNowAndNeedTimeAndLastStartTime() => progress.AddStartTimeToMaxV((double)speed);
public long GetProgressStored() => progress.GetValue();
public (long, long) GetProgressStoredAndNeedTime() => progress.GetValueAndMaxV();
public (long, long, long) GetProgressStoredAndNeedTimeAndLastStartTime() => progress.GetValueAndMaxVWithStartTime();

public bool IsFinished()
{
long progressNow, needTime;
(progressNow, needTime, _) = progress.AddStartTimeToMaxV((double)speed);
return progressNow == needTime;
}
public bool IsProgressing()
{
long progressNow, needTime, startT;
(progressNow, needTime, startT) = progress.AddStartTimeToMaxV((double)speed);
return (startT != long.MaxValue && progressNow != needTime);
}
#endregion

public bool Start(long needTime)
{
if (needTime <= 2)
{
Debugger.Output("Warning:Start TimeBasedProgressAtVariableSpeed with the needProgress (" + needTime.ToString() + ") which is less than 0.");
return false;
}
if (progress.startTime.Start() != long.MaxValue) return false;
progress.SetMaxV(needTime);
return true;
}
public bool Start()
{
return progress.startTime.Start() == long.MaxValue;
}
/// <summary>
/// 使进度条强制终止清零
/// </summary>
public void Set0()
{
progress.SetAndStop();
}
/// <summary>
/// 如果进度条加上时间差不能为满,使进度条强制终止清零
/// </summary>
public void TryStop()
{
progress.Set0IfNotAddStartTimeToMaxV(speed);
}
/// <summary>
/// 使进度条暂停
/// </summary>
public bool Pause()
{
return progress.AddStartTime((double)speed) != 0;
}
/// <summary>
/// 使进度条进度为满
/// </summary>
public void Finish()
{
progress.SetVToMaxV();
progress.startTime.Stop();
}
}

/// <summary>
/// 根据时间推算Start后完成多少进度的进度条(long)。
/// 只允许Start(清零状态的进度条才可以Start)时修改needTime(请确保大于0);
@@ -158,85 +349,6 @@ namespace Preparation.Utility
//增加其他新的写操作可能导致不安全
}

public class TimeBasedProgressAtVariableSpeed
{
public LongInTheVariableRange progress;
public StartTime startTime = new();
public AtomicDouble speed;

#region 构造
public TimeBasedProgressAtVariableSpeed(long needProgress, double speed)
{
if (needProgress <= 0) Debugger.Output("Bug:TimeBasedProgressAtVariableSpeed.needProgress (" + needProgress.ToString() + ") is less than 0.");
this.progress = new(0, needProgress);
this.speed = new(speed);
}
public TimeBasedProgressAtVariableSpeed()
{
this.progress = new(0, 0);
this.speed = new(1.0);
}
#endregion

#region 读取
public override string ToString()
{
return "ProgressStored: " + progress.ToString()
+ " ; LastStartTime: " + startTime.ToString() + "ms"
+ " ; Speed: " + speed.ToString();
}
public long GetProgressNow() => progress.TryAddToMaxV(startTime, (double)speed).Item1;
public (long, long, long) GetProgressNowAndNeedTimeAndLastStartTime() => progress.TryAddToMaxV(startTime, (double)speed);
public long GetProgressStored() => progress.GetValue();
public (long, long) GetProgressStoredAndNeedTime() => progress.GetValueAndMaxV();
public (long, long, long) GetProgressStoredAndNeedTimeAndLastStartTime() => progress.GetValueAndMaxV(startTime);

public bool IsFinished()
{
long progressNow, needTime;
(progressNow, needTime, _) = progress.TryAddToMaxV(startTime);
return progressNow == needTime;
}
public bool IsProgressing()
{
long progressNow, needTime, startT;
(progressNow, needTime, startT) = progress.TryAddToMaxV(startTime);
return (startT != long.MaxValue && progressNow != needTime);
}
#endregion

public bool Start(long needTime)
{
if (needTime <= 2)
{
Debugger.Output("Warning:Start TimeBasedProgressAtVariableSpeed with the needProgress (" + needTime.ToString() + ") which is less than 0.");
return false;
}
if (startTime.Start() != long.MaxValue) return false;
progress.SetMaxV(needTime);
return true;
}
public bool Start()
{
return startTime.Start() == long.MaxValue;
}
/// <summary>
/// 使进度条强制终止清零
/// </summary>
public void Set0()
{
startTime.Stop();
progress.SetPositiveV(0);
}
/// <summary>
/// 使进度条暂停
/// </summary>
public bool Pause()
{
return progress.AddV(startTime, (double)speed) != 0;
}
}

/// <summary>
/// 冷却时间为可变的CDms的bool,不支持查看当前进度,初始为True
/// </summary>


+ 1
- 2
logic/Server/CopyInfo.cs View File

@@ -232,8 +232,7 @@ namespace Server
Y = doorway.Position.y
}
};
int progress = ((doorway.OpenStartTime > 0) ? ((int)(time - doorway.OpenStartTime)) : 0) + doorway.OpenDegree;
msg.GateMessage.Progress = (progress > GameData.degreeOfOpenedDoorway) ? GameData.degreeOfOpenedDoorway : progress;
msg.GateMessage.Progress = (int)doorway.ProgressOfDoorway.GetProgressNow();
return msg;
}
private static MessageOfObj HiddenGate(EmergencyExit Exit)


Loading…
Cancel
Save