From 1d145a8db37fac2160c32425b2602b38e3aa4263 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Tue, 14 Mar 2023 11:12:32 +0800 Subject: [PATCH] build: :art: rebuild the skill system --- .../GameObj/Character/Character.Ghost.cs | 3 +- .../GameObj/Character/Character.Skill.cs | 17 +- .../GameObj/Character/Character.Student.cs | 17 +- .../GameClass/GameObj/Character/Character.cs | 16 +- logic/GameClass/Skill/ActiveSkill.cs | 227 ----------------- logic/GameClass/Skill/ISkill.cs | 21 -- logic/GameClass/Skill/PassiveSkill.cs | 161 ------------ logic/Gaming/ActionManager.cs | 2 +- logic/Gaming/Game.cs | 22 +- logic/Gaming/SkillManager.cs | 29 --- logic/Gaming/SkillManager/ActiveSkill.cs | 238 ++++++++++++++++++ logic/Gaming/SkillManager/PassiveSkill.cs | 131 ++++++++++ logic/Gaming/SkillManager/SkillManager.cs | 53 ++++ logic/Preparation/Interface/IOccupation.cs | 7 + logic/Preparation/Utility/EnumType.cs | 3 +- logic/Preparation/Utility/GameData.cs | 7 +- logic/规则Logic.md | 18 +- 17 files changed, 477 insertions(+), 495 deletions(-) delete mode 100644 logic/GameClass/Skill/ActiveSkill.cs delete mode 100644 logic/GameClass/Skill/ISkill.cs delete mode 100644 logic/GameClass/Skill/PassiveSkill.cs delete mode 100644 logic/Gaming/SkillManager.cs create mode 100644 logic/Gaming/SkillManager/ActiveSkill.cs create mode 100644 logic/Gaming/SkillManager/PassiveSkill.cs create mode 100644 logic/Gaming/SkillManager/SkillManager.cs diff --git a/logic/GameClass/GameObj/Character/Character.Ghost.cs b/logic/GameClass/GameObj/Character/Character.Ghost.cs index 25726f3..3ad0240 100644 --- a/logic/GameClass/GameObj/Character/Character.Ghost.cs +++ b/logic/GameClass/GameObj/Character/Character.Ghost.cs @@ -1,5 +1,4 @@ -using GameClass.Skill; -using Preparation.Interface; +using Preparation.Interface; using Preparation.Utility; using System; using System.Collections.Generic; diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 1be4129..db44536 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -1,5 +1,4 @@ -using GameClass.Skill; -using Preparation.Utility; +using Preparation.Utility; using Preparation.Interface; using System.Collections.Generic; using System; @@ -37,20 +36,6 @@ namespace GameClass.GameObj return false; } - public bool UseActiveSkill(Map map, ActiveSkillType activeSkillType) - { - if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) - return ActiveSkillFactory.FindIActiveSkill(activeSkillType).SkillEffect(map, this); - return false; - } - - public void UsePassiveSkill(Map map, PassiveSkillType passiveSkillType) - { - if (Occupation.ListOfIPassiveSkill.Contains(passiveSkillType)) - PassiveSkillFactory.FindIPassiveSkill(passiveSkillType).SkillEffect(map, this); - return; - } - public bool IsGhost() { return GameData.IsGhost(CharacterType); diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index 6ece27f..b5f7ccd 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -1,5 +1,4 @@ -using GameClass.Skill; -using Preparation.Utility; +using Preparation.Utility; using Preparation.Interface; namespace GameClass.GameObj @@ -40,20 +39,6 @@ namespace GameClass.GameObj } public int OrgTreatSpeed { get; protected set; } = GameData.basicTreatSpeed; - protected int rescueSpeed = GameData.basicRescueSpeed; - public int RescueSpeed - { - get => rescueSpeed; - set - { - lock (gameObjLock) - { - rescueSpeed = value; - } - } - } - public int OrgRescueSpeed { get; protected set; } = GameData.basicRescueSpeed; - public int MaxGamingAddiction { get; protected set; } private int gamingAddiction; public int GamingAddiction diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 88632c7..6d7b927 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -59,7 +59,6 @@ namespace GameClass.GameObj { get { - if (IsResetting) return PlayerStateType.IsDeceased; if (IsMoving) return PlayerStateType.IsMoving; return playerState; } @@ -214,6 +213,21 @@ namespace GameClass.GameObj } } + private int timeOfOpeningOrLocking; + public int TimeOfOpeningOrLocking + { + get => timeOfOpeningOrLocking; + set + { + lock (gameObjLock) + { + timeOfOpeningOrLocking = value; + } + } + } + + + /// /// 进行一次攻击 /// diff --git a/logic/GameClass/Skill/ActiveSkill.cs b/logic/GameClass/Skill/ActiveSkill.cs deleted file mode 100644 index fa0b11d..0000000 --- a/logic/GameClass/Skill/ActiveSkill.cs +++ /dev/null @@ -1,227 +0,0 @@ -using GameClass.GameObj; -using System.Threading; -using Preparation.Interface; -using Preparation.Utility; -using System; -using Timothy.FrameRateTask; - -namespace GameClass.Skill -{ - public class BecomeVampire : IActiveSkill // 化身吸血鬼 - { - public int SkillCD => GameData.commonSkillCD / 3 * 4; - public int DurationTime => GameData.commonSkillTime; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool SkillEffect(Map map, Character player) - { - return ActiveSkillFactory.SkillEffect(this, player, () => - { - player.Vampire += 0.5; - Debugger.Output(player, "becomes vampire!"); - }, - () => - { - double tempVam = player.Vampire - 0.5; - player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam; - }); - } - } - - public class BeginToCharge : IActiveSkill - { - public int SkillCD => GameData.commonSkillCD / 3 * 4; - public int DurationTime => GameData.commonSkillTime; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool SkillEffect(Map map, Character player) - { - return ActiveSkillFactory.SkillEffect(this, player, () => - { - player.Vampire += 0.5; - Debugger.Output(player, "becomes vampire!"); - }, - () => - { - double tempVam = player.Vampire - 0.5; - player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam; - }); - } - } - public class BecomeInvisible : IActiveSkill - { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => GameData.commonSkillTime / 10 * 6; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - public bool SkillEffect(Map map, Character player) - { - return ActiveSkillFactory.SkillEffect(this, player, () => - { - player.IsInvisible = true; - Debugger.Output(player, "uses atombomb!"); - }, - () => - { player.IsInvisible = false; }); - } - } - public class NuclearWeapon : IActiveSkill // 核武器 - { - public int SkillCD => GameData.commonSkillCD / 3 * 7; - public int DurationTime => GameData.commonSkillTime / 10; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - public bool SkillEffect(Map map, Character player) - { - return ActiveSkillFactory.SkillEffect(this, player, () => - { - player.BulletOfPlayer = BulletType.AtomBomb; - Debugger.Output(player, "uses atombomb!"); - }, - () => - { player.BulletOfPlayer = player.OriBulletOfPlayer; }); - } - } - public class UseKnife : IActiveSkill - { - public int SkillCD => GameData.commonSkillCD / 3 * 2; - public int DurationTime => GameData.commonSkillTime / 10; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - public bool SkillEffect(Map map, Character player) - { - return ActiveSkillFactory.SkillEffect(this, player, () => - { - player.BulletOfPlayer = BulletType.FlyingKnife; - Debugger.Output(player, "uses flyingknife!"); - }, - () => - { player.BulletOfPlayer = player.OriBulletOfPlayer; }); - } - } - public class SuperFast : IActiveSkill // 3倍速 - { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => GameData.commonSkillTime / 10 * 4; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - public bool SkillEffect(Map map, Character player) - { - return ActiveSkillFactory.SkillEffect(this, player, () => - { - player.AddMoveSpeed(this.DurationTime, 3.0); - Debugger.Output(player, "moves very fast!"); - }, - () => - { }); - } - } - public class NoCommonSkill : IActiveSkill // 这种情况不该发生,定义着以防意外 - { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => GameData.commonSkillTime; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - public bool SkillEffect(Map map, Character player) - { - return false; - } - } - - public static class ActiveSkillFactory - { - public static bool SkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) - { - lock (activeSkill.ActiveSkillLock) - { - ActiveSkillType activeSkillType = FindActiveSkillType(activeSkill); - if (player.TimeUntilActiveSkillAvailable[activeSkillType] == 0) - { - - player.SetTimeUntilActiveSkillAvailable(activeSkillType, activeSkill.SkillCD); - new Thread - (() => - { - startSkill(); - new FrameRateTaskExecutor( - () => !player.IsResetting, - () => - { - player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); - }, - timeInterval: GameData.frameDuration, - () => 0, - maxTotalDuration: (long)(activeSkill.DurationTime) - ) - { - AllowTimeExceed = true, - MaxTolerantTimeExceedCount = ulong.MaxValue, - } - .Start(); - - endSkill(); - Debugger.Output(player, "return to normal."); - - new FrameRateTaskExecutor( - () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsResetting, - () => - { - player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); - }, - timeInterval: GameData.frameDuration, - () => 0, - maxTotalDuration: (long)(activeSkill.SkillCD - activeSkill.DurationTime) - ) - { - AllowTimeExceed = true, - MaxTolerantTimeExceedCount = ulong.MaxValue, - } - .Start(); - - player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0); - Debugger.Output(player, "CommonSkill is ready."); - } - ) - { IsBackground = true }.Start(); - - return true; - } - else - { - Debugger.Output(player, "CommonSkill is cooling down!"); - return false; - } - } - } - public static IActiveSkill? FindIActiveSkill(ActiveSkillType activeSkillType) - { - switch (activeSkillType) - { - case ActiveSkillType.BecomeInvisible: - return new BecomeInvisible(); - default: - return null; - } - } - public static ActiveSkillType FindActiveSkillType(IActiveSkill ActiveSkill) - { - switch (ActiveSkill) - { - case BecomeInvisible: - return ActiveSkillType.BecomeInvisible; - case UseKnife: - return ActiveSkillType.UseKnife; - case BeginToCharge: - return ActiveSkillType.BeginToCharge; - default: - return ActiveSkillType.Null; - } - } - } - -} \ No newline at end of file diff --git a/logic/GameClass/Skill/ISkill.cs b/logic/GameClass/Skill/ISkill.cs deleted file mode 100644 index afe0aa7..0000000 --- a/logic/GameClass/Skill/ISkill.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Preparation.Utility; -using GameClass.GameObj; -using System.Collections.Generic; - -namespace GameClass.Skill -{ - public interface ISkill - { - } - public interface IPassiveSkill : ISkill - { - public void SkillEffect(Map map, Character player); - } - public interface IActiveSkill : ISkill - { - public int SkillCD { get; } - public int DurationTime { get; } //技能持续时间 - public object ActiveSkillLock { get; } - public bool SkillEffect(Map map, Character player); - } -} \ No newline at end of file diff --git a/logic/GameClass/Skill/PassiveSkill.cs b/logic/GameClass/Skill/PassiveSkill.cs deleted file mode 100644 index 16f824d..0000000 --- a/logic/GameClass/Skill/PassiveSkill.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Threading; -using GameClass.GameObj; -using Preparation.Interface; -using Preparation.Utility; -using Timothy.FrameRateTask; - -namespace GameClass.Skill // 被动技能开局时就释放,持续到游戏结束 -{ - public class RecoverAfterBattle : IPassiveSkill // 脱战回血,普通子弹 - { - public void SkillEffect(Map map, Character player) - { - const int recoverDegree = 5; // 每帧回复血量 - int nowHP = player.HP; - int lastHP = nowHP; - long waitTime = 0; - const long interval = 10000; // 每隔interval时间不受伤害,角色即开始回血 - new Thread - ( - () => - { - new FrameRateTaskExecutor - ( - () => true, - () => - { - lastHP = nowHP; // lastHP等于上一帧的HP - nowHP = player.HP; // nowHP更新为这一帧的HP - if (lastHP > nowHP) // 这一帧扣血了 - { - waitTime = 0; - } - else if (waitTime < interval) - { - waitTime += GameData.frameDuration; - } - - if (waitTime >= interval) // 回复时,每帧(50ms)回复5,即1s回复100。 - player.TryAddHp(recoverDegree); - }, - timeInterval: GameData.frameDuration, - () => 0, - maxTotalDuration: GameData.gameDuration - ) - { - AllowTimeExceed = true, - MaxTolerantTimeExceedCount = ulong.MaxValue, - TimeExceedAction = b => - { - if (b) - Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!"); - -#if DEBUG - else - { - Console.WriteLine("Debug info: passive skill time exceeds for once."); - } -#endif - } - }.Start(); - } - ) - { IsBackground = true }.Start(); - } - } - public class SpeedUpWhenLeavingGrass : IPassiveSkill // 3倍速 - { - public void SkillEffect(Map map, Character player) - { - PlaceType nowPlace = map.GetPlaceType(player.Position); - PlaceType lastPlace = nowPlace; - bool speedup = false; - const int SpeedUpTime = 2000; // 加速时间:2s - new Thread - ( - () => - { - new FrameRateTaskExecutor - ( - () => true, - () => - { - lastPlace = nowPlace; - nowPlace = map.GetPlaceType(player.Position); - if ((lastPlace == PlaceType.Grass) && nowPlace == PlaceType.Null) - { - if (!speedup) - { - new Thread(() => - { - speedup = true; - player.AddMoveSpeed(SpeedUpTime, 3.0); - speedup = false; - }) - { IsBackground = true }.Start(); - } - } - }, - timeInterval: GameData.frameDuration, - () => 0, - maxTotalDuration: GameData.gameDuration - ) - { - AllowTimeExceed = true, - MaxTolerantTimeExceedCount = ulong.MaxValue, - TimeExceedAction = b => - { - if (b) - Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!"); - -#if DEBUG - else - { - Console.WriteLine("Debug info: passive skill time exceeds for once."); - } -#endif - } - }.Start(); - } - ) - { IsBackground = true }.Start(); - } - } - public class Vampire : IPassiveSkill // 被动就是吸血,普通子弹 - { - public void SkillEffect(Map map, Character player) - { - player.OriVampire = 0.5; - player.Vampire = player.OriVampire; - } - } - - public class NoPassiveSkill : IPassiveSkill // 没技能,这种情况不应该发生,先定义着以防意外 - { - public void SkillEffect(Map map, Character player) - { - } - } - - - public static class PassiveSkillFactory - { - public static IPassiveSkill? FindIPassiveSkill(PassiveSkillType passiveSkillType) - { - switch (passiveSkillType) - { - default: - return null; - } - } - public static PassiveSkillType FindpassiveSkillType(IPassiveSkill passiveSkill) - { - switch (passiveSkill) - { - default: - return PassiveSkillType.Null; - } - } - } -} diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 6290dac..14c0441 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -28,7 +28,7 @@ namespace Gaming if (player.PlayerState == PlayerStateType.IsRescuing || player.PlayerState == PlayerStateType.IsRescued || player.PlayerState == PlayerStateType.IsFixing || player.PlayerState == PlayerStateType.IsMoving || player.PlayerState == PlayerStateType.IsTreated || player.PlayerState == PlayerStateType.IsTreating - || player.PlayerState == PlayerStateType.IsRummagingInTheDrawer || player.PlayerState == PlayerStateType.IsLockingTheDoor + || player.PlayerState == PlayerStateType.IsRummagingInTheChest || player.PlayerState == PlayerStateType.IsLockingTheDoor || player.PlayerState == PlayerStateType.IsClimbingThroughWindows) { player.PlayerState = PlayerStateType.Null; diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index aaebe29..b271b68 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -150,7 +150,7 @@ namespace Gaming finally { - gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock(); + gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock(); } }, timeInterval: GameData.checkInterval, @@ -179,11 +179,17 @@ namespace Gaming propManager.StartProducing(); - // 开始游戏 - if (!gameMap.Timer.StartGame(milliSeconds)) - return false; + new Thread + ( + () => + { + if (!gameMap.Timer.StartGame(milliSeconds)) + return; - EndGame(); // 游戏结束时要做的事 + EndGame(); // 游戏结束时要做的事 + } + ) + { IsBackground = true }.Start(); return true; } @@ -333,7 +339,7 @@ namespace Gaming Character? player = gameMap.FindPlayer(playerID); if (player != null) { - return skillManager.UseActiveSkill(this.GameMap, player, activeSkillType); + return skillManager.UseActiveSkill(player, activeSkillType); } else return false; @@ -348,7 +354,7 @@ namespace Gaming { foreach (Character player in gameMap.GameObjDict[GameObjType.Character]) { - skillManager.UseAllPassiveSkill(this.GameMap, player); + skillManager.UseAllPassiveSkill(player); } } finally @@ -439,10 +445,10 @@ namespace Gaming teamList.Add(new Team()); } - skillManager = new SkillManager(); attackManager = new AttackManager(gameMap); actionManager = new ActionManager(gameMap); propManager = new PropManager(gameMap); + skillManager = new SkillManager(gameMap, actionManager, attackManager, propManager); } } } diff --git a/logic/Gaming/SkillManager.cs b/logic/Gaming/SkillManager.cs deleted file mode 100644 index dadf9da..0000000 --- a/logic/Gaming/SkillManager.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Preparation.Utility; -using GameClass.GameObj; -using System.Reflection; -using GameClass.Skill; - -namespace Gaming -{ - public partial class Game - { - readonly SkillManager skillManager; - private class SkillManager - { - public bool UseActiveSkill(Map gamemap, Character character, ActiveSkillType activeSkillType) - { - return character.UseActiveSkill(gamemap, activeSkillType); - } - public void UsePassiveSkill(Map gamemap, Character character, PassiveSkillType passiveSkillType) - { - character.UsePassiveSkill(gamemap, passiveSkillType); - } - public void UseAllPassiveSkill(Map gamemap, Character character) - { - foreach (var passiveSkill in character.Occupation.ListOfIPassiveSkill) - character.UsePassiveSkill(gamemap, passiveSkill); - } - } - } -} diff --git a/logic/Gaming/SkillManager/ActiveSkill.cs b/logic/Gaming/SkillManager/ActiveSkill.cs new file mode 100644 index 0000000..f16c093 --- /dev/null +++ b/logic/Gaming/SkillManager/ActiveSkill.cs @@ -0,0 +1,238 @@ +using GameClass.GameObj; +using System.Threading; +using Preparation.Interface; +using Preparation.Utility; +using System; +using Timothy.FrameRateTask; + +namespace Gaming +{ + public partial class Game + { + private partial class SkillManager + { + public interface IActiveSkill + { + public int SkillCD { get; } + public int DurationTime { get; } //技能持续时间 + public object ActiveSkillLock { get; } + public bool SkillEffect(Character player); + } + public class BecomeVampire : IActiveSkill // 化身吸血鬼 + { + public int SkillCD => GameData.commonSkillCD / 3 * 4; + public int DurationTime => GameData.commonSkillTime; + + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + + public bool SkillEffect(Character player) + { + return ActiveSkillEffect(this, player, () => + { + player.Vampire += 0.5; + Debugger.Output(player, "becomes vampire!"); + }, + () => + { + double tempVam = player.Vampire - 0.5; + player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam; + }); + } + } + private IActiveSkill becomeVampire = new BecomeVampire(); + + public class BeginToCharge : IActiveSkill + { + public int SkillCD => GameData.commonSkillCD / 3 * 4; + public int DurationTime => GameData.commonSkillTime; + + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + + public bool SkillEffect(Character player) + { + return ActiveSkillEffect(this, player, () => + { + player.Vampire += 0.5; + Debugger.Output(player, "becomes vampire!"); + }, + () => + { + double tempVam = player.Vampire - 0.5; + player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam; + }); + } + } + private IActiveSkill beginToCharge = new BeginToCharge(); + + public class BecomeInvisible : IActiveSkill + { + public int SkillCD => GameData.commonSkillCD; + public int DurationTime => GameData.commonSkillTime / 10 * 6; + + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + public bool SkillEffect(Character player) + { + return ActiveSkillEffect(this, player, () => + { + player.IsInvisible = true; + Debugger.Output(player, "become invisible!"); + }, + () => + { player.IsInvisible = false; }); + } + } + private IActiveSkill becomeInvisible = new BecomeInvisible(); + + public class NuclearWeapon : IActiveSkill // 核武器 + { + public int SkillCD => GameData.commonSkillCD / 3 * 7; + public int DurationTime => GameData.commonSkillTime / 10; + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + public bool SkillEffect(Character player) + { + return ActiveSkillEffect(this, player, () => + { + player.BulletOfPlayer = BulletType.AtomBomb; + Debugger.Output(player, "uses atombomb!"); + }, + () => + { player.BulletOfPlayer = player.OriBulletOfPlayer; }); + } + } + private IActiveSkill nuclearWeapon = new NuclearWeapon(); + + public class UseKnife : IActiveSkill + { + public int SkillCD => GameData.commonSkillCD / 3 * 2; + public int DurationTime => GameData.commonSkillTime / 10; + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + public bool SkillEffect(Character player) + { + return ActiveSkillEffect(this, player, () => + { + player.BulletOfPlayer = BulletType.FlyingKnife; + Debugger.Output(player, "uses flyingknife!"); + }, + () => + { player.BulletOfPlayer = player.OriBulletOfPlayer; }); + } + } + private IActiveSkill useKnife = new UseKnife(); + + public class SuperFast : IActiveSkill // 3倍速 + { + public int SkillCD => GameData.commonSkillCD; + public int DurationTime => GameData.commonSkillTime / 10 * 4; + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + public bool SkillEffect(Character player) + { + return ActiveSkillEffect(this, player, () => + { + player.AddMoveSpeed(this.DurationTime, 3.0); + Debugger.Output(player, "moves very fast!"); + }, + () => + { }); + } + } + private IActiveSkill superFast = new SuperFast(); + + public IActiveSkill? FindIActiveSkill(ActiveSkillType activeSkillType) + { + switch (activeSkillType) + { + case ActiveSkillType.BecomeInvisible: + return this.becomeInvisible; + default: + return null; + } + } + public static ActiveSkillType FindActiveSkillType(IActiveSkill ActiveSkill) + { + switch (ActiveSkill) + { + case BecomeInvisible: + return ActiveSkillType.BecomeInvisible; + case UseKnife: + return ActiveSkillType.UseKnife; + case BeginToCharge: + return ActiveSkillType.BeginToCharge; + default: + return ActiveSkillType.Null; + } + } + + public static bool ActiveSkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) + { + lock (activeSkill.ActiveSkillLock) + { + ActiveSkillType activeSkillType = FindActiveSkillType(activeSkill); + if (player.TimeUntilActiveSkillAvailable[activeSkillType] == 0) + { + + player.SetTimeUntilActiveSkillAvailable(activeSkillType, activeSkill.SkillCD); + new Thread + (() => + { + startSkill(); + new FrameRateTaskExecutor( + () => !player.IsResetting, + () => + { + player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); + }, + timeInterval: GameData.frameDuration, + () => 0, + maxTotalDuration: (long)(activeSkill.DurationTime) + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + } + .Start(); + + endSkill(); + Debugger.Output(player, "return to normal."); + + new FrameRateTaskExecutor( + () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsResetting, + () => + { + player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); + }, + timeInterval: GameData.frameDuration, + () => 0, + maxTotalDuration: (long)(activeSkill.SkillCD - activeSkill.DurationTime) + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + } + .Start(); + + player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0); + Debugger.Output(player, "ActiveSkill is ready."); + } + ) + { IsBackground = true }.Start(); + + return true; + } + else + { + Debugger.Output(player, "CommonSkill is cooling down!"); + return false; + } + } + } + + } + + } +} diff --git a/logic/Gaming/SkillManager/PassiveSkill.cs b/logic/Gaming/SkillManager/PassiveSkill.cs new file mode 100644 index 0000000..613753c --- /dev/null +++ b/logic/Gaming/SkillManager/PassiveSkill.cs @@ -0,0 +1,131 @@ +using System; +using System.Threading; +using GameClass.GameObj; +using Preparation.Interface; +using Preparation.Utility; +using Timothy.FrameRateTask; + +namespace Gaming // 被动技能开局时就释放,持续到游戏结束 +{ + public partial class Game + { + private partial class SkillManager + { + public void RecoverAfterBattle(Character player) + { + const int recoverDegree = 5; // 每帧回复血量 + int nowHP = player.HP; + int lastHP = nowHP; + long waitTime = 0; + const long interval = 10000; // 每隔interval时间不受伤害,角色即开始回血 + new Thread + ( + () => + { + new FrameRateTaskExecutor + ( + () => true, + () => + { + lastHP = nowHP; // lastHP等于上一帧的HP + nowHP = player.HP; // nowHP更新为这一帧的HP + if (lastHP > nowHP) // 这一帧扣血了 + { + waitTime = 0; + } + else if (waitTime < interval) + { + waitTime += GameData.frameDuration; + } + + if (waitTime >= interval) // 回复时,每帧(50ms)回复5,即1s回复100。 + player.TryAddHp(recoverDegree); + }, + timeInterval: GameData.frameDuration, + () => 0, + maxTotalDuration: GameData.gameDuration + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + TimeExceedAction = b => + { + if (b) + Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!"); + +#if DEBUG + else + { + Console.WriteLine("Debug info: passive skill time exceeds for once."); + } +#endif + } + }.Start(); + } + ) + { IsBackground = true }.Start(); + } + public void SpeedUpWhenLeavingGrass(Character player) + { + PlaceType nowPlace = gameMap.GetPlaceType(player.Position); + PlaceType lastPlace = nowPlace; + bool speedup = false; + const int SpeedUpTime = 2000; // 加速时间:2s + new Thread + ( + () => + { + new FrameRateTaskExecutor + ( + () => true, + () => + { + lastPlace = nowPlace; + nowPlace = gameMap.GetPlaceType(player.Position); + if ((lastPlace == PlaceType.Grass) && nowPlace == PlaceType.Null) + { + if (!speedup) + { + new Thread(() => + { + speedup = true; + player.AddMoveSpeed(SpeedUpTime, 3.0); + speedup = false; + }) + { IsBackground = true }.Start(); + } + } + }, + timeInterval: GameData.frameDuration, + () => 0, + maxTotalDuration: GameData.gameDuration + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + TimeExceedAction = b => + { + if (b) + Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!"); + +#if DEBUG + else + { + Console.WriteLine("Debug info: passive skill time exceeds for once."); + } +#endif + } + }.Start(); + } + ) + { IsBackground = true }.Start(); + } + + public void Vampire(Character player) + { + player.OriVampire = 0.5; + player.Vampire = player.OriVampire; + } + } + } +} \ No newline at end of file diff --git a/logic/Gaming/SkillManager/SkillManager.cs b/logic/Gaming/SkillManager/SkillManager.cs new file mode 100644 index 0000000..0d5363e --- /dev/null +++ b/logic/Gaming/SkillManager/SkillManager.cs @@ -0,0 +1,53 @@ +using System; +using Preparation.Utility; +using GameClass.GameObj; +using System.Reflection; +using GameEngine; + +namespace Gaming +{ + public partial class Game + { + readonly SkillManager skillManager; + private partial class SkillManager + { + public bool UseActiveSkill(Character character, ActiveSkillType activeSkillType) + { + if (character.Occupation.ListOfIActiveSkill.Contains(activeSkillType)) + return FindIActiveSkill(activeSkillType).SkillEffect(character); + return false; + } + public void UsePassiveSkill(Character character, PassiveSkillType passiveSkillType) + { + if (character.Occupation.ListOfIPassiveSkill.Contains(passiveSkillType)) + switch (passiveSkillType) + { + default: + return; + } + return; + } + public void UseAllPassiveSkill(Character character) + { + foreach (var passiveSkill in character.Occupation.ListOfIPassiveSkill) + switch (passiveSkill) + { + default: + return; + } + } + + private readonly Map gameMap; + private readonly ActionManager actionManager; + private readonly AttackManager attackManager; + private readonly PropManager propManager; + public SkillManager(Map gameMap, ActionManager action, AttackManager attack, PropManager prop) + { + this.gameMap = gameMap; + this.actionManager = action; + this.propManager = prop; + this.attackManager = attack; + } + } + } +} diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index 3175d4b..16895a2 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -14,6 +14,7 @@ namespace Preparation.Interface public List ListOfIPassiveSkill { get; } public double Concealment { get; } public int AlertnessRadius { get; } + public int TimeOfOpeningOrLocking { get; } } public interface IGhost : IOccupation @@ -49,6 +50,9 @@ namespace Preparation.Interface public int alertnessRadius = (int)(GameData.basicAlertnessRadius * 1.3); public int AlertnessRadius => alertnessRadius; + + public int timeOfOpeningOrLocking = GameData.basicTimeOfOpeningOrLocking; + public int TimeOfOpeningOrLocking => timeOfOpeningOrLocking; } public class Athlete : IStudent { @@ -77,5 +81,8 @@ namespace Preparation.Interface public const int alertnessRadius = (int)(GameData.basicAlertnessRadius * 0.9); public int AlertnessRadius => alertnessRadius; + + public int timeOfOpeningOrLocking = GameData.basicTimeOfOpeningOrLocking; + public int TimeOfOpeningOrLocking => timeOfOpeningOrLocking; } } diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index f4367ba..c082442 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -20,7 +20,7 @@ namespace Preparation.Utility IsStunned = 11, IsTryingToAttack = 12,//指前摇 IsLockingTheDoor = 13, - IsRummagingInTheDrawer = 14, + IsRummagingInTheChest = 14, IsClimbingThroughWindows = 15, } public enum GameObjType @@ -120,6 +120,7 @@ namespace Preparation.Utility EmergencyExit = 10, Window = 11, Door = 12, + Chest = 13, } public enum BgmType { diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index a581f1b..3e0cc28 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -56,7 +56,6 @@ namespace Preparation.Utility public const int basicApOfGhost = 1500000; // 攻击力 public const int basicTreatSpeed = 100; public const int basicFixSpeed = 100; - public const int basicRescueSpeed = 100; public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 public const int BeginGamingAddiction = 10003; public const int MidGamingAddiction = 30000; @@ -73,11 +72,12 @@ namespace Preparation.Utility public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围 public const double basicAttackShortRange = 2700; // 基本近程攻击范围 public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围 - public const int basicMoveSpeed = 3800; // 基本移动速度,单位:s-1 - public const int basicBulletMoveSpeed = 5400; // 基本子弹移动速度,单位:s-1 + public const int basicMoveSpeed = 1260; // 基本移动速度,单位:s-1 + public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1 public const int characterMaxSpeed = 12000; // 最大速度 public const double basicConcealment = 1.0; public const int basicAlertnessRadius = 30700; + public const int basicTimeOfOpeningOrLocking = 3000; public const int addScoreWhenKillOneLevelPlayer = 30; // 击杀一级角色获得的加分 public const int commonSkillCD = 30000; // 普通技能标准冷却时间 public const int commonSkillTime = 10000; // 普通技能标准持续时间 @@ -106,7 +106,6 @@ namespace Preparation.Utility public const long PropProduceTime = 10000; public const int PropDuration = 10000; #endregion - #region 物体相关 public const int degreeOfFixedGenerator = 10300000; #endregion diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 7aa4128..ef62a11 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -5,6 +5,7 @@ - 该规则直接服务于Sever,并非选手版本 - *斜体表示Logic底层尚未(完全)实现* - []表示待决定 +- ~~表示暂不实现~~ ## 游戏简介 - 1位监管者对抗4位求生者的非对称竞技模式 @@ -90,11 +91,11 @@ IsStunned = 11, IsTryingToAttack = 12,//指前摇 IsLockingTheDoor = 13, - IsRummagingInTheDrawer = 14, + IsRummagingInTheChest = 14, IsClimbingThroughWindows = 15, } ~~~ -- *Bgm(字典)* +- Bgm(字典) - 得分 - ~~回血率/原始回血率~~ - 当前子弹类型 @@ -108,15 +109,15 @@ - 拥有的被动技能(列表) - 拥有的主动技能(列表) - 各个主动技能CD(字典) -- *警戒半径* -- *double 隐蔽度* -- *翻墙速度* -- *开锁门速度* +- 警戒半径 +- double 隐蔽度 +- *翻窗时间* +- 开锁门时间 ### 学生:人物 - 修理电机速度 - 治疗速度 -- 救人速度 +- ~~救人速度~~ - ~~自愈次数~~ - 沉迷游戏程度 - 最大沉迷游戏程度 @@ -171,6 +172,7 @@ ### 箱子:物体 - *里面的道具* +- *是否开启* ### 门:物体 - *属于那个教学区* @@ -225,7 +227,7 @@ - *翻越窗户是一种交互行为,执行时,实质是限定方向的减速运动* ### 箱子 -- *监管者和求生者都能与箱子交互。* +- *监管者和求生者都能与箱子交互,同一时刻就允许一人进行翻找* - *开启箱子有不同概率获得不同道具。* - *搜寻物品的基础持续时间为10秒。* - *未搜寻完成的箱子在下一次需要重新开始搜寻。*