perf: ⚡ optimize the logic about CD
tags/v0.1.0
| @@ -88,5 +88,8 @@ | |||||
| - fix:修复了卡窗的问题 | - fix:修复了卡窗的问题 | ||||
| - hotfix:修复了救人线程崩溃的问题 | - hotfix:修复了救人线程崩溃的问题 | ||||
| # 5月26日12:00更新 | |||||
| - fix:修复了救人中断后不继续沉迷的问题 | |||||
| # 5月26日更新 | # 5月26日更新 | ||||
| - fix:修复了救人中断后不继续沉迷的问题 | |||||
| - improve:优化CD逻辑 | |||||
| @@ -23,25 +23,6 @@ namespace GameClass.GameObj | |||||
| return new NullSkill(); | return new NullSkill(); | ||||
| } | } | ||||
| public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable) | |||||
| { | |||||
| if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) | |||||
| { | |||||
| ActiveSkillDictionary[activeSkillType].TimeUntilActiveSkillAvailable = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0; | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| public bool AddTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int addTimeUntilActiveSkillAvailable) | |||||
| { | |||||
| if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) | |||||
| { | |||||
| ActiveSkillDictionary[activeSkillType].TimeUntilActiveSkillAvailable += addTimeUntilActiveSkillAvailable; | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| public bool IsGhost() | public bool IsGhost() | ||||
| { | { | ||||
| return GameData.IsGhost(CharacterType); | return GameData.IsGhost(CharacterType); | ||||
| @@ -498,52 +498,18 @@ namespace Gaming | |||||
| { | { | ||||
| lock (activeSkill.ActiveSkillUseLock) | lock (activeSkill.ActiveSkillUseLock) | ||||
| { | { | ||||
| if (activeSkill.TimeUntilActiveSkillAvailable == 0) | |||||
| if (activeSkill.StartSkill()) | |||||
| { | { | ||||
| activeSkill.TimeUntilActiveSkillAvailable = activeSkill.SkillCD; | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| startSkill(); | startSkill(); | ||||
| activeSkill.IsBeingUsed = 1; | activeSkill.IsBeingUsed = 1; | ||||
| new FrameRateTaskExecutor<int>( | |||||
| () => !player.IsRemoved, | |||||
| () => | |||||
| { | |||||
| activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration; | |||||
| }, | |||||
| timeInterval: GameData.frameDuration, | |||||
| () => 0, | |||||
| maxTotalDuration: (long)(activeSkill.DurationTime) | |||||
| ) | |||||
| { | |||||
| AllowTimeExceed = true, | |||||
| MaxTolerantTimeExceedCount = ulong.MaxValue, | |||||
| } | |||||
| .Start(); | |||||
| Thread.Sleep(activeSkill.DurationTime); | |||||
| endSkill(); | endSkill(); | ||||
| activeSkill.IsBeingUsed = 0; | activeSkill.IsBeingUsed = 0; | ||||
| Debugger.Output(player, "return to normal."); | Debugger.Output(player, "return to normal."); | ||||
| new FrameRateTaskExecutor<int>( | |||||
| loopCondition: () => activeSkill.TimeUntilActiveSkillAvailable > 0, | |||||
| loopToDo: () => | |||||
| { | |||||
| activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration; | |||||
| }, | |||||
| timeInterval: GameData.frameDuration, | |||||
| finallyReturn: () => 0 | |||||
| ) | |||||
| { | |||||
| AllowTimeExceed = true, | |||||
| MaxTolerantTimeExceedCount = ulong.MaxValue, | |||||
| } | |||||
| .Start(); | |||||
| activeSkill.TimeUntilActiveSkillAvailable = 0; | |||||
| Debugger.Output(player, "ActiveSkill is ready."); | |||||
| } | } | ||||
| ) | ) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| @@ -1,5 +1,6 @@ | |||||
| using Preparation.Interface; | using Preparation.Interface; | ||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using System; | |||||
| using System.Threading; | using System.Threading; | ||||
| namespace Preparation.Interface | namespace Preparation.Interface | ||||
| @@ -29,18 +30,25 @@ namespace Preparation.Interface | |||||
| private readonly object skillLock = new(); | private readonly object skillLock = new(); | ||||
| public object SkillLock => skillLock; | public object SkillLock => skillLock; | ||||
| private int timeUntilActiveSkillAvailable = 0; | |||||
| public int TimeUntilActiveSkillAvailable | |||||
| private int openStartTime = 0; | |||||
| public int OpenStartTime | |||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| return Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 0); | |||||
| lock (skillLock) | |||||
| return openStartTime; | |||||
| } | } | ||||
| set | |||||
| } | |||||
| public bool StartSkill() | |||||
| { | |||||
| lock (skillLock) | |||||
| { | { | ||||
| if (value < 0) value = 0; | |||||
| else if (value > SkillCD) value = SkillCD; | |||||
| Interlocked.Exchange(ref timeUntilActiveSkillAvailable, value); | |||||
| if (Environment.TickCount - openStartTime >= SkillCD) | |||||
| { | |||||
| openStartTime = Environment.TickCount; | |||||
| return true; | |||||
| } | |||||
| else return false; | |||||
| } | } | ||||
| } | } | ||||
| @@ -15,8 +15,8 @@ namespace Server | |||||
| case Preparation.Utility.GameObjType.Character: | case Preparation.Utility.GameObjType.Character: | ||||
| Character character = (Character)gameObj; | Character character = (Character)gameObj; | ||||
| if (character.IsGhost()) | if (character.IsGhost()) | ||||
| return Tricker((Ghost)character); | |||||
| else return Student((Student)character); | |||||
| return Tricker((Ghost)character, time); | |||||
| else return Student((Student)character, time); | |||||
| case Preparation.Utility.GameObjType.Bullet: | case Preparation.Utility.GameObjType.Bullet: | ||||
| return Bullet((Bullet)gameObj); | return Bullet((Bullet)gameObj); | ||||
| case Preparation.Utility.GameObjType.BombedBullet: | case Preparation.Utility.GameObjType.BombedBullet: | ||||
| @@ -49,7 +49,7 @@ namespace Server | |||||
| return objMsg; | return objMsg; | ||||
| } | } | ||||
| private static MessageOfObj? Student(Student player) | |||||
| private static MessageOfObj? Student(Student player, int time) | |||||
| { | { | ||||
| if (player.IsGhost()) return null; | if (player.IsGhost()) return null; | ||||
| MessageOfObj msg = new() | MessageOfObj msg = new() | ||||
| @@ -81,7 +81,10 @@ namespace Server | |||||
| }; | }; | ||||
| foreach (var keyValue in player.ActiveSkillDictionary) | foreach (var keyValue in player.ActiveSkillDictionary) | ||||
| msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value.TimeUntilActiveSkillAvailable); | |||||
| { | |||||
| int progress = keyValue.Value.SkillCD - Environment.TickCount + keyValue.Value.OpenStartTime; | |||||
| msg.StudentMessage.TimeUntilSkillAvailable.Add(progress < 0 ? 0 : progress); | |||||
| } | |||||
| 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); | ||||
| @@ -97,7 +100,7 @@ namespace Server | |||||
| return msg; | return msg; | ||||
| } | } | ||||
| private static MessageOfObj? Tricker(Character player) | |||||
| private static MessageOfObj? Tricker(Character player, int time) | |||||
| { | { | ||||
| if (!player.IsGhost()) return null; | if (!player.IsGhost()) return null; | ||||
| MessageOfObj msg = new() | MessageOfObj msg = new() | ||||
| @@ -122,7 +125,10 @@ namespace Server | |||||
| } | } | ||||
| }; | }; | ||||
| foreach (var keyValue in player.ActiveSkillDictionary) | foreach (var keyValue in player.ActiveSkillDictionary) | ||||
| msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value.TimeUntilActiveSkillAvailable); | |||||
| { | |||||
| int progress = keyValue.Value.SkillCD - Environment.TickCount + keyValue.Value.OpenStartTime; | |||||
| msg.TrickerMessage.TimeUntilSkillAvailable.Add(progress < 0 ? 0 : progress); | |||||
| } | |||||
| 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); | ||||
| @@ -0,0 +1,2 @@ | |||||
| @echo off | |||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --playbackFile .\test.thuaipb --playbackSpeed 1 | |||||