Browse Source

Merge pull request #663 from shangfengh/new

fix: 🐛 fix the problem about CD about Trickers and Locking the doors
dev
shangfengh GitHub 2 years ago
parent
commit
12e04cfb3a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 54 deletions
  1. +3
    -3
      logic/Client/MainWindow.xaml.cs
  2. +1
    -1
      logic/Gaming/ActionManager.cs
  3. +1
    -1
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  4. +18
    -40
      logic/Preparation/Interface/ISkill.cs
  5. +97
    -1
      logic/Preparation/Utility/SafeValue.cs
  6. +5
    -8
      logic/Server/CopyInfo.cs

+ 3
- 3
logic/Client/MainWindow.xaml.cs View File

@@ -836,7 +836,7 @@ namespace Client
foreach (var skill in occupation.ListOfIActiveSkill) foreach (var skill in occupation.ListOfIActiveSkill)
{ {
var iActiveSkill = SkillFactory.FindActiveSkill(skill); var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD;
coolTime[i, obj.PlayerId] = (int)(iActiveSkill.SkillCD.GetCD());
++i; ++i;
} }
isDataFixed[obj.PlayerId] = true; isDataFixed[obj.PlayerId] = true;
@@ -844,14 +844,14 @@ namespace Client
} }
foreach (var obj in listOfButcher) 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)); IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType));
int j = 0; int j = 0;
foreach (var skill in occupation1.ListOfIActiveSkill) foreach (var skill in occupation1.ListOfIActiveSkill)
{ {
var iActiveSkill = SkillFactory.FindActiveSkill(skill); var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD;
coolTime[j, GameData.numOfStudent] = (int)(iActiveSkill.SkillCD.GetCD());
++j; ++j;
} }
isDataFixed[obj.PlayerId] = true; isDataFixed[obj.PlayerId] = true;


+ 1
- 1
logic/Gaming/ActionManager.cs View File

@@ -513,7 +513,7 @@ namespace Gaming
{ {
if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null) if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null)
return false; 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 false;
return true; return true;
}, },


+ 1
- 1
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -499,7 +499,7 @@ namespace Gaming
{ {
lock (activeSkill.ActiveSkillUseLock) lock (activeSkill.ActiveSkillUseLock)
{ {
if (activeSkill.StartSkill())
if (activeSkill.SkillCD.TryUse())
{ {
new Thread new Thread
(() => (() =>


+ 18
- 40
logic/Preparation/Interface/ISkill.cs View File

@@ -13,7 +13,7 @@ namespace Preparation.Interface
} }
public interface IActiveSkill : ISkill public interface IActiveSkill : ISkill
{ {
public int SkillCD { get; }
public LongProgressCoolingDownByCD SkillCD { get; }
public int DurationTime { get; } //技能持续时间 public int DurationTime { get; } //技能持续时间
public object ActiveSkillUseLock { get; } public object ActiveSkillUseLock { get; }
public bool IsBeingUsed { get; set; } public bool IsBeingUsed { get; set; }
@@ -21,7 +21,7 @@ namespace Preparation.Interface


public abstract class ActiveSkill : IActiveSkill public abstract class ActiveSkill : IActiveSkill
{ {
public abstract int SkillCD { get; }
public abstract LongProgressCoolingDownByCD SkillCD { get; }
public abstract int DurationTime { get; } public abstract int DurationTime { get; }


private readonly object activeSkillUseLock = new(); private readonly object activeSkillUseLock = new();
@@ -30,28 +30,6 @@ namespace Preparation.Interface
private readonly object skillLock = new(); private readonly object skillLock = new();
public object SkillLock => skillLock; 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 int isBeingUsed = 0;//实为bool
public bool IsBeingUsed public bool IsBeingUsed
{ {
@@ -62,79 +40,79 @@ namespace Preparation.Interface


public class CanBeginToCharge : ActiveSkill 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 override int DurationTime => GameData.commonSkillTime * 3 / 10;
} }


public class BecomeInvisible : ActiveSkill 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 override int DurationTime => GameData.commonSkillTime;
} }


public class Punish : ActiveSkill 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 override int DurationTime => 0;
} }


public class HaveTea : ActiveSkill 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 override int DurationTime => 0;
} }


public class Rouse : ActiveSkill 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 override int DurationTime => 0;
} }


public class Encourage : ActiveSkill 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 override int DurationTime => 0;
} }


public class Inspire : ActiveSkill 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 override int DurationTime => 0;
} }


public class Howl : ActiveSkill 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 override int DurationTime => 0;
} }


public class ShowTime : ActiveSkill 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 override int DurationTime => GameData.commonSkillTime;
} }


public class JumpyBomb : ActiveSkill 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 override int DurationTime => GameData.commonSkillTime * 3 / 10;
} }


public class SparksNSplash : ActiveSkill 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 override int DurationTime => GameData.commonSkillTime;
} }


public class UseKnife : ActiveSkill 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 override int DurationTime => GameData.commonSkillTime / 10;
} }


public class UseRobot : ActiveSkill 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; public override int DurationTime => 0;


private int nowPlayerID; private int nowPlayerID;
@@ -171,7 +149,7 @@ namespace Preparation.Interface


public class WriteAnswers : ActiveSkill public class WriteAnswers : ActiveSkill
{ {
public override int SkillCD => GameData.commonSkillCD;
public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD);
public override int DurationTime => 0; public override int DurationTime => 0;


private AtomicInt degreeOfMeditation = new(0); private AtomicInt degreeOfMeditation = new(0);
@@ -180,7 +158,7 @@ namespace Preparation.Interface


public class SummonGolem : ActiveSkill 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; public override int DurationTime => 6000;


private int[] golemStateArray = new int[GameData.maxSummonedGolemNum] { 0, 0, 0 }; private int[] golemStateArray = new int[GameData.maxSummonedGolemNum] { 0, 0, 0 };
@@ -233,7 +211,7 @@ namespace Preparation.Interface


public class NullSkill : ActiveSkill public class NullSkill : ActiveSkill
{ {
public override int SkillCD => GameData.commonSkillCD;
public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD);
public override int DurationTime => GameData.commonSkillTime; public override int DurationTime => GameData.commonSkillTime;
} }




+ 97
- 1
logic/Preparation/Utility/SafeValue.cs View File

@@ -504,7 +504,7 @@ namespace Preparation.Utility
} }


/// <summary> /// <summary>
/// 一个保证在[0,maxNum],每CDms自动更新的可变int,支持可变的CD、maxNum(请确保大于0)
/// 一个保证在[0,maxNum],每CDms自动+1的int,支持可变的CD、maxNum(请确保大于0)
/// </summary> /// </summary>
public class IntNumUpdateByCD public class IntNumUpdateByCD
{ {
@@ -679,4 +679,100 @@ namespace Preparation.Utility
} }
} }
} }

/// <summary>
/// 一个每CDms自动更新冷却的bool,支持可变的无锁CD,不支持查看当前进度,初始为True
/// </summary>
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);
}
}

/// <summary>
/// 一个每CDms自动更新的进度条,支持可变的CD,初始为满
/// </summary>
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);
}
}
} }

+ 5
- 8
logic/Server/CopyInfo.cs View File

@@ -2,6 +2,7 @@ using Protobuf;
using GameClass.GameObj; using GameClass.GameObj;
using Preparation.Utility; using Preparation.Utility;
using Gaming; using Gaming;
using Preparation.Interface;


namespace Server namespace Server
{ {
@@ -81,10 +82,8 @@ namespace Server
}; };


foreach (var keyValue in player.ActiveSkillDictionary) 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) for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i)
msg.StudentMessage.TimeUntilSkillAvailable.Add(-1); msg.StudentMessage.TimeUntilSkillAvailable.Add(-1);


@@ -124,11 +123,9 @@ namespace Server
BulletType = Transformation.ToBulletType((Preparation.Utility.BulletType)player.BulletOfPlayer) BulletType = Transformation.ToBulletType((Preparation.Utility.BulletType)player.BulletOfPlayer)
} }
}; };

foreach (var keyValue in player.ActiveSkillDictionary) 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) for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i)
msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1); msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1);




Loading…
Cancel
Save