From 812a5bf343c2a60c023a087ef70358678782cfc8 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Wed, 22 Mar 2023 23:34:53 +0800 Subject: [PATCH 01/15] feat: :sparkles: finish the fuction of Escape from EmergencyExit --- logic/GameClass/GameObj/Map/EmergencyExit.cs | 23 ++++++ logic/GameClass/GameObj/Map/Map.cs | 23 +++++- logic/Gaming/ActionManager.cs | 78 +++++++++----------- logic/Gaming/AttackManager.cs | 51 +++++-------- logic/Gaming/PropManager.cs | 23 ++---- logic/Preparation/Utility/GameData.cs | 4 +- 6 files changed, 108 insertions(+), 94 deletions(-) diff --git a/logic/GameClass/GameObj/Map/EmergencyExit.cs b/logic/GameClass/GameObj/Map/EmergencyExit.cs index 95de4d5..0e2911b 100644 --- a/logic/GameClass/GameObj/Map/EmergencyExit.cs +++ b/logic/GameClass/GameObj/Map/EmergencyExit.cs @@ -25,5 +25,28 @@ namespace GameClass.GameObj return true; // 不是鬼不碰撞 return false; } + + + private bool canOpen = false; + public bool CanOpen + { + get => canOpen; + set + { + lock (gameObjLock) + canOpen = value; + } + } + + private bool isOpen = false; + public bool IsOpen + { + get => isOpen; + set + { + lock (gameObjLock) + isOpen = value; + } + } } } diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index 549a1ea..02d8dee 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -13,6 +13,28 @@ namespace GameClass.GameObj private readonly Dictionary birthPointList; // 出生点列表 public Dictionary BirthPointList => birthPointList; + private object lockForNum = new(); + private uint numOfRepairedGenerators = 0; + public uint NumOfRepairedGenerators + { + get => numOfRepairedGenerators; + set + { + lock (lockForNum) + numOfRepairedGenerators = value; + } + } + private uint numOfSurvivingStudent = GameData.numOfStudent; + public uint NumOfSurvivingStudent + { + get => numOfSurvivingStudent; + set + { + lock (lockForNum) + numOfSurvivingStudent = value; + } + } + private Dictionary> gameObjDict; public Dictionary> GameObjDict => gameObjDict; private Dictionary gameObjLockDict; @@ -31,7 +53,6 @@ namespace GameClass.GameObj return PlaceType.Null; } } - public PlaceType GetPlaceType(XY pos) { try diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index d22a5f9..b232220 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -58,34 +58,33 @@ namespace Gaming .Start(); if (generatorForFix.DegreeOfRepair >= GameData.degreeOfFixedGenerator) { + gameMap.NumOfRepairedGenerators++; if (player.PlayerState == PlayerStateType.Fixing) player.PlayerState = PlayerStateType.Null; - Doorway exit = (Doorway)gameMap.GameObjDict[GameObjType.Doorway][1]; - if (!exit.PowerSupply) + if (gameMap.NumOfRepairedGenerators == GameData.numOfGeneratorRequiredForEmergencyExit) { - gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock(); + gameMap.GameObjLockDict[GameObjType.EmergencyExit].EnterWriteLock(); try { - int numOfFixedGenerator = 0; - foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator]) - if (generator.DegreeOfRepair == GameData.degreeOfFixedGenerator) - ++numOfFixedGenerator; - if (numOfFixedGenerator >= GameData.numOfGeneratorRequiredForRepair) - { - gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock(); - try - { - foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway]) - doorway.PowerSupply = true; - } - finally - { - gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock(); - } - } + Random r = new Random(Environment.TickCount); + ((EmergencyExit)(gameMap.GameObjDict[GameObjType.EmergencyExit][r.Next(0, gameMap.GameObjDict[GameObjType.EmergencyExit].Count)])).CanOpen = true; } finally { - gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock(); + gameMap.GameObjLockDict[GameObjType.EmergencyExit].ExitWriteLock(); + } + } + else + if (gameMap.NumOfRepairedGenerators == GameData.numOfGeneratorRequiredForRepair) + { + gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock(); + try + { + foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway]) + doorway.PowerSupply = true; + } + finally + { + gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock(); } } @@ -141,33 +140,28 @@ namespace Gaming { if (!(player.Commandable())) return false; - Doorway? doorwayForEscape = null; - - gameMap.GameObjLockDict[GameObjType.Doorway].EnterReadLock(); - try + Doorway? doorwayForEscape = (Doorway?)gameMap.OneInTheSameCell(player.Position, GameObjType.Doorway); + if (doorwayForEscape != null) { - foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway]) + if (doorwayForEscape.IsOpen()) { - if (GameData.IsInTheSameCell(doorway.Position, player.Position)) - { - doorwayForEscape = doorway; - break; - } + player.Die(PlayerStateType.Escaped); + return true; } + else + return false; } - finally - { - gameMap.GameObjLockDict[GameObjType.Doorway].ExitReadLock(); - } - - - if (doorwayForEscape != null && doorwayForEscape.IsOpen()) + else { - player.Die(PlayerStateType.Escaped); - return true; + EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneInTheSameCell(player.Position, GameObjType.EmergencyExit); + if (emergencyExit != null && emergencyExit.IsOpen) + { + player.Die(PlayerStateType.Escaped); + return true; + } + else + return false; } - else - return false; } public bool Treat(Student player, Student playerTreated) diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 6080b19..bcb5cd1 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -98,15 +98,6 @@ namespace Gaming { player.Die(PlayerStateType.Deceased); - // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); - // try - //{ - // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot); - // } - // finally - //{ - // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); - // } for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++) { @@ -117,34 +108,28 @@ namespace Gaming gameMap.Add(prop); } } + --gameMap.NumOfSurvivingStudent; + if (gameMap.NumOfSurvivingStudent == 1) + { + gameMap.GameObjLockDict[GameObjType.EmergencyExit].EnterReadLock(); + try + { + foreach (EmergencyExit emergencyExit in gameMap.GameObjDict[GameObjType.EmergencyExit]) + if (emergencyExit.CanOpen) + { + emergencyExit.IsOpen = true; + break; + } + } + finally + { + gameMap.GameObjLockDict[GameObjType.EmergencyExit].ExitReadLock(); + } + } // player.Reset(); // ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 - /* new Thread - (() => - { - - Thread.Sleep(GameData.reviveTime); - - playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾 - - // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); - // try - //{ - // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot); - // } - // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); } - - if (gameMap.Timer.IsGaming) - { - playerBeingShot.CanMove = true; - } - playerBeingShot.Deceased = false; - } - ) - { IsBackground = true }.Start(); - */ } private void BombObj(Bullet bullet, GameObj objBeingShot) diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index 198b7cd..fc786e9 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -59,24 +59,13 @@ namespace Gaming if (indexing == GameData.maxNumOfPropInPropInventory) return false; - Prop pickProp = new NullProp(); + Prop? pickProp = new NullProp(); if (propType == PropType.Null) // 自动检查有无道具可捡 { - gameMap.GameObjLockDict[GameObjType.Prop].EnterReadLock(); - try - { - foreach (Prop prop in gameMap.GameObjDict[GameObjType.Prop]) - { - if (GameData.IsInTheSameCell(prop.Position, player.Position)) - { - player.PropInventory[indexing] = prop; - } - } - } - finally - { - gameMap.GameObjLockDict[GameObjType.Prop].ExitReadLock(); - } + pickProp = (Prop?)gameMap.OneInTheSameCell(player.Position, GameObjType.Prop); + if (pickProp != null) + player.PropInventory[indexing] = pickProp; + else player.PropInventory[indexing] = pickProp = new NullProp(); } else { @@ -89,7 +78,7 @@ namespace Gaming { if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false) { - player.PropInventory[indexing] = prop; + pickProp = player.PropInventory[indexing] = prop; } } } diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 192f9e4..076bba6 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -21,7 +21,6 @@ namespace Preparation.Utility public const int numOfBirthPoint = 5; // public const int numOfGenerator = 9; - public const int numOfGeneratorRequiredForRepair = 7; public const int numOfChest = 8; private const int numOfObjNotMap = 5; @@ -61,6 +60,7 @@ namespace Preparation.Utility } #endregion #region 角色相关 + public const int numOfStudent = 4; public const int characterRadius = numOfPosGridPerCell / 2 / 5 * 4; // 人物半径 public const int basicTreatSpeed = 100; @@ -143,6 +143,8 @@ namespace Preparation.Utility public const int degreeOfLockingOrOpeningTheDoor = 10000; public const int degreeOfOpenedDoorway = 18000; public const int maxNumOfPropInChest = 2; + public const int numOfGeneratorRequiredForRepair = 7; + public const int numOfGeneratorRequiredForEmergencyExit = 3; #endregion #region 游戏帧相关 public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 From e4d40e835089bad335423c59a73ace2255675e49 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 00:10:37 +0800 Subject: [PATCH 02/15] build: :art: use speed rather than time of open chest --- .../GameObj/Character/Character.Skill.cs | 2 +- .../GameClass/GameObj/Character/Character.cs | 8 +++---- logic/GameClass/GameObj/Map/Chest.cs | 15 ++++++++----- logic/GameClass/GameObj/Map/Door.cs | 14 ++++++------ logic/Gaming/ActionManager.cs | 12 +++++----- logic/Preparation/Interface/IOccupation.cs | 4 ++-- logic/Preparation/Utility/GameData.cs | 3 ++- logic/规则Logic.md | 22 +++++++++---------- 8 files changed, 43 insertions(+), 37 deletions(-) diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 1f72ae2..5bed851 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -88,7 +88,7 @@ namespace GameClass.GameObj this.characterType = characterType; this.SpeedOfOpeningOrLocking = Occupation.TimeOfOpeningOrLocking; this.SpeedOfClimbingThroughWindows = Occupation.SpeedOfClimbingThroughWindows; - this.TimeOfOpenChest = Occupation.TimeOfOpenChest; + this.SpeedOfOpenChest = Occupation.TimeOfOpenChest; foreach (var activeSkill in this.Occupation.ListOfIActiveSkill) { diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 0ffbb05..bcdf7fb 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -256,15 +256,15 @@ namespace GameClass.GameObj } } - private int timeOfOpenChest; - public int TimeOfOpenChest + private int speedOfOpenChest; + public int SpeedOfOpenChest { - get => timeOfOpenChest; + get => speedOfOpenChest; set { lock (gameObjLock) { - timeOfOpenChest = value; + speedOfOpenChest = value; } } } diff --git a/logic/GameClass/GameObj/Map/Chest.cs b/logic/GameClass/GameObj/Map/Chest.cs index 1046c23..78f2996 100644 --- a/logic/GameClass/GameObj/Map/Chest.cs +++ b/logic/GameClass/GameObj/Map/Chest.cs @@ -20,15 +20,20 @@ namespace GameClass.GameObj private Prop[] propInChest = new Prop[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; public Prop[] PropInChest => propInChest; - private bool isOpen = false; - public bool IsOpen + private int openDegree = 0; + public int OpenDegree { - get => isOpen; + get => openDegree; set { - lock (gameObjLock) - isOpen = value; + if (value > 0) + lock (gameObjLock) + openDegree = (value > GameData.degreeOfOpeningChest) ? GameData.degreeOfOpeningChest : value; + else + lock (gameObjLock) + openDegree = 0; } } + public bool IsOpen() => (OpenDegree == GameData.degreeOfOpeningChest); } } diff --git a/logic/GameClass/GameObj/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs index fd95768..8828ee0 100644 --- a/logic/GameClass/GameObj/Map/Door.cs +++ b/logic/GameClass/GameObj/Map/Door.cs @@ -14,12 +14,8 @@ namespace GameClass.GameObj this.place = placeType; this.CanMove = false; } - public override bool IsRigid => true; + public override bool IsRigid => !isOpen; public override ShapeType Shape => ShapeType.Square; - protected override bool IgnoreCollideExecutor(IGameObj targetObj) - { - return isOpen; - } private bool isOpen = false; public bool IsOpen @@ -38,8 +34,12 @@ namespace GameClass.GameObj get => openOrLockDegree; set { - lock (gameObjLock) - openOrLockDegree = (value > 0) ? value : 0; + if (value > 0) + lock (gameObjLock) + openOrLockDegree = (value > GameData.degreeOfLockingOrOpeningTheDoor) ? GameData.degreeOfLockingOrOpeningTheDoor : value; + else + lock (gameObjLock) + openOrLockDegree = 0; } } } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index b232220..3f7d187 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -257,7 +257,7 @@ namespace Gaming return false; Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest); - if (chestToOpen == null || chestToOpen.IsOpen) + if (chestToOpen == null || chestToOpen.IsOpen()) return false; player.PlayerState = PlayerStateType.OpeningTheChest; @@ -265,12 +265,11 @@ namespace Gaming ( () => { - int OpenDegree = 0; new FrameRateTaskExecutor( - loopCondition: () => player.PlayerState == PlayerStateType.OpeningTheChest && gameMap.Timer.IsGaming && OpenDegree < player.TimeOfOpenChest, + loopCondition: () => player.PlayerState == PlayerStateType.OpeningTheChest && gameMap.Timer.IsGaming && (!chestToOpen.IsOpen()), loopToDo: () => { - OpenDegree += GameData.frameDuration; + chestToOpen.OpenDegree += GameData.frameDuration * player.SpeedOfOpenChest; }, timeInterval: GameData.frameDuration, finallyReturn: () => 0 @@ -278,9 +277,8 @@ namespace Gaming .Start(); - if (OpenDegree >= player.TimeOfOpenChest) + if (chestToOpen.IsOpen()) { - chestToOpen.IsOpen = true; if (player.PlayerState == PlayerStateType.OpeningTheChest) player.PlayerState = PlayerStateType.Null; for (int i = 0; i < GameData.maxNumOfPropInChest; ++i) @@ -291,6 +289,8 @@ namespace Gaming gameMap.Add(prop); } } + else chestToOpen.OpenDegree = 0; + } ) diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index f64ce10..71fb6fc 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -64,7 +64,7 @@ namespace Preparation.Interface public int speedOfClimbingThroughWindows = GameData.basicGhostSpeedOfClimbingThroughWindows; public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows; - public int timeOfOpenChest = GameData.basicTimeOfOpenChest; + public int timeOfOpenChest = GameData.basicSpeedOfOpenChest; public int TimeOfOpenChest => timeOfOpenChest; } public class Athlete : IStudent @@ -107,7 +107,7 @@ namespace Preparation.Interface public int speedOfClimbingThroughWindows = GameData.basicStudentSpeedOfClimbingThroughWindows * 12 / 10; public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows; - public int timeOfOpenChest = GameData.basicTimeOfOpenChest; + public int timeOfOpenChest = GameData.basicSpeedOfOpenChest; public int TimeOfOpenChest => timeOfOpenChest; } } diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 076bba6..c8c4dbe 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -68,7 +68,7 @@ namespace Preparation.Utility public const int basicSpeedOfOpeningOrLocking = 3280; public const int basicStudentSpeedOfClimbingThroughWindows = 611; public const int basicGhostSpeedOfClimbingThroughWindows = 1270; - public const int basicTimeOfOpenChest = 10000; + public const int basicSpeedOfOpenChest = 1000; public const int basicHp = 3000000; // 初始血量 public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 @@ -141,6 +141,7 @@ namespace Preparation.Utility #region 物体相关 public const int degreeOfFixedGenerator = 10300000; public const int degreeOfLockingOrOpeningTheDoor = 10000; + public const int degreeOfOpeningChest = 10000; public const int degreeOfOpenedDoorway = 18000; public const int maxNumOfPropInChest = 2; public const int numOfGeneratorRequiredForRepair = 7; diff --git a/logic/规则Logic.md b/logic/规则Logic.md index f4223a5..a1de8a5 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -28,7 +28,7 @@ - 只展示外部需要的属性,部分属性被省略 ### BgmType -- *枚举类BgmType* +- 枚举类BgmType 1. 不详的感觉:监管者进入(求生者的警戒半径/监管者的隐蔽度)时,求生者收到;监管者距离求生者越近,Bgm音量越大。bgmVolume=(警戒半径/二者距离) 2. 期待搞事的感觉:求生者进入(监管者的警戒半径/求生者的隐蔽度)时,监管者收到;监管者距离求生者越近,Bgm音量越大。bgmVolume=(警戒半径/可被发觉的最近的求生者距离) 3. 修理电机的声音: 监管者警戒半径内有电机正在被修理时收到;bgmVolume=(警戒半径*电机修理程度/二者距离)/10300000 @@ -124,7 +124,7 @@ - double 隐蔽度 - 翻窗时间 - 开锁门速度 -- *开箱速度* +- 开箱速度 - 视野范围 ### 学生:人物 @@ -231,16 +231,16 @@ 6. 开启箱子 ### 门 -- *门分别属于三个教学区:三教,五教,六教* -- *监管者或求生者都需要拿到对应教学区的钥匙才能打开或锁住对应的门* -- *锁门和开门都需要一定时间,进出门为正常移动过程* -- *门只有开、锁两种状态,锁住时门有碰撞体积* -- *当门所在格子内有人时,无法锁门(必须从门外锁门)* -- *锁门时其他人可以进入门所在格子,锁门过程中断* +- 门分别属于三个教学区:三教,五教,六教 +- 监管者或求生者都需要拿到对应教学区的钥匙才能打开或锁住对应的门 +- 锁门和开门都需要一定时间,进出门为正常移动过程 +- 门只有开、锁两种状态,锁住时门有碰撞体积 +- 当门所在格子内有人时,无法锁门(必须从门外锁门) +- 锁门时其他人可以进入门所在格子,锁门过程中断 - *钥匙只会出现在箱子中,每个教学区都有2把钥匙* -- *一扇门只允许同时一个人开锁门* -- *开锁门未完成前,门状态表现为原来的状态* -- *开锁门进度中断后清空* +- 一扇门只允许同时一个人开锁门 +- 开锁门未完成前,门状态表现为原来的状态 +- 开锁门进度中断后清空 ### 窗 - 求生者和监管者都可以翻越窗户,但通常情况下监管者翻越窗户的速度**高于**求生者。 From be9712d63eb70a41fa4ac5044f073962678ed6cc Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 00:39:45 +0800 Subject: [PATCH 03/15] feat: :sparkles: make people able to be Stunned because of being attacked --- .../GameObj/Character/Character.Student.cs | 41 ++++++++++++++ .../GameClass/GameObj/Character/Character.cs | 53 ++++-------------- logic/Gaming/ActionManager.cs | 3 +- logic/Gaming/AttackManager.cs | 2 +- logic/规则Logic.md | 56 +++++++++---------- 5 files changed, 82 insertions(+), 73 deletions(-) diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index dfe586a..1be3f9b 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -1,10 +1,51 @@ using Preparation.Utility; using Preparation.Interface; +using System; namespace GameClass.GameObj { public class Student : Character { + + private readonly object beAttackedLock = new(); + /// + /// 遭受攻击 + /// + /// + /// + /// 伤害来源 + /// 人物在受到攻击后死了吗 + public bool BeAttacked(Bullet bullet) + { + + lock (beAttackedLock) + { + if (hp <= 0 || NoHp()) + return false; // 原来已经死了 + if (bullet.Parent.TeamID != this.TeamID) + { + if (CanBeAwed()) PlayerState = PlayerStateType.Stunned; + if (HasShield) + { + if (bullet.HasSpear) + _ = TrySubHp(bullet.AP); + else + return false; + } + else + { + bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP))); + } +#if DEBUG + Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}."); +#endif + if (hp <= 0) + TryActivatingLIFE(); // 如果有复活甲 + } + return hp <= 0; + } + } + protected int fixSpeed; /// /// 修理电机速度 diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index bcdf7fb..19a3487 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -10,9 +10,8 @@ namespace GameClass.GameObj { public partial class Character : Moveable, ICharacter // 负责人LHR摆烂终了 { - private readonly object beAttackedLock = new(); - #region 装弹相关的基本属性及方法 + #region 装弹攻击相关的基本属性及方法 /// /// 装弹冷却 /// @@ -93,43 +92,7 @@ namespace GameClass.GameObj } } - /// - /// 遭受攻击 - /// - /// - /// - /// 伤害来源 - /// 人物在受到攻击后死了吗 - public bool BeAttacked(Bullet bullet) - { - - lock (beAttackedLock) - { - if (hp <= 0) - return false; // 原来已经死了 - if (bullet.Parent.TeamID != this.TeamID) - { - - if (HasShield) - { - if (bullet.HasSpear) - _ = TrySubHp(bullet.AP); - else - return false; - } - else - { - bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP))); - } -#if DEBUG - Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}."); -#endif - if (hp <= 0) - TryActivatingLIFE(); // 如果有复活甲 - } - return hp <= 0; - } - } + /* /// /// 攻击被反弹,反弹伤害不会再被反弹 /// @@ -152,7 +115,7 @@ namespace GameClass.GameObj } return hp <= 0; } - } + }*/ #endregion #region 感知相关的基本属性及方法 /// @@ -372,12 +335,18 @@ namespace GameClass.GameObj } } + public bool NoHp() => (playerState != PlayerStateType.Deceased && playerState != PlayerStateType.Escaped + && playerState != PlayerStateType.Addicted && playerState != PlayerStateType.Rescued); public bool Commandable() => (playerState != PlayerStateType.Deceased && playerState != PlayerStateType.Escaped - && playerState != PlayerStateType.Addicted && playerState != PlayerStateType.Rescuing + && playerState != PlayerStateType.Addicted && playerState != PlayerStateType.Rescued && playerState != PlayerStateType.Swinging && playerState != PlayerStateType.TryingToAttack && playerState != PlayerStateType.ClimbingThroughWindows && playerState != PlayerStateType.Stunned); public bool InteractingWithMapWithoutMoving() => (playerState == PlayerStateType.LockingOrOpeningTheDoor || playerState == PlayerStateType.Fixing || playerState == PlayerStateType.OpeningTheChest); public bool NullOrMoving() => (playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving); + public bool CanBeAwed() => !(playerState == PlayerStateType.Deceased || playerState == PlayerStateType.Escaped + || playerState == PlayerStateType.Addicted || playerState == PlayerStateType.Rescued + || playerState == PlayerStateType.Treated || playerState != PlayerStateType.Stunned + || playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving); private int score = 0; public int Score @@ -542,7 +511,7 @@ namespace GameClass.GameObj return false; } } - private void TryActivatingLIFE() + protected void TryActivatingLIFE() { if (buffManager.TryActivatingLIFE()) { diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 3f7d187..3327eae 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -398,8 +398,7 @@ namespace Gaming loopCondition: () => flag && player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor && gameMap.Timer.IsGaming && doorToLock.OpenOrLockDegree < GameData.degreeOfLockingOrOpeningTheDoor, loopToDo: () => { - Character? character = (Character?)gameMap.OneInTheSameCell(doorToLock.Position, GameObjType.Character); - flag = (character != null); + flag = ((gameMap.OneInTheSameCell(doorToLock.Position, GameObjType.Character)) != null); doorToLock.OpenOrLockDegree += GameData.frameDuration * player.SpeedOfOpeningOrLocking; }, timeInterval: GameData.frameDuration, diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index bcb5cd1..0932f22 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -139,7 +139,7 @@ namespace Gaming case GameObjType.Character: if ((!((Character)objBeingShot).IsGhost()) && bullet.Parent.IsGhost()) - if (((Character)objBeingShot).BeAttacked(bullet)) + if (((Student)objBeingShot).BeAttacked(bullet)) { BeAddictedToGame((Student)objBeingShot); } diff --git a/logic/规则Logic.md b/logic/规则Logic.md index a1de8a5..42378d0 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -81,22 +81,23 @@ public enum PlayerStateType { Null = 0, - IsAddicted = 1, - IsEscaped = 2, - IsSwinging = 3,//指后摇 - IsDeceased = 4, - IsMoving = 5, - IsTreating = 6, - IsRescuing = 7, - IsFixing = 8, - IsTreated = 9, - IsRescued = 10, - IsStunned = 11, - IsTryingToAttack = 12,//指前摇 - IsLockingTheDoor = 13, - IsOpeningTheChest = 14, - IsClimbingThroughWindows = 15, - IsUsingSpecialSkill = 16, + Addicted = 1, + Escaped = 2, + Swinging = 3,//指后摇 + Deceased = 4, + Moving = 5, + Treating = 6, + Rescuing = 7, + Fixing = 8, + Treated = 9, + Rescued = 10, + Stunned = 11, + TryingToAttack = 12,//指前摇 + LockingOrOpeningTheDoor = 13, + OpeningTheChest = 14, + ClimbingThroughWindows = 15, + UsingSkill = 16, + OpeningTheDoorWay = 17, } ~~~ - 可执行指令的(不用给选手) @@ -174,22 +175,21 @@ - 开启进度 ### 紧急出口:物体 -- *是否显现* -- *是否打开* +- 是否显现 +- 是否打开 ### 墙:物体 ### 窗:物体 -- *正在翻窗的人* +- 正在翻窗的人 ### 箱子:物体 -- *是否开启* -- *开箱进度* +- 开箱进度 ### 门:物体 -- *属于那个教学区* -- *是否锁上* -- *开锁门进度* +- 属于那个教学区 +- 是否锁上 +- 开锁门进度 - 不提供是否可以锁上的属性 ### 电机(建议称为homework):物体 @@ -205,14 +205,14 @@ - 除了逃离和翻窗,交互目标与交互者在一个九宫格内则为可交互 - 逃离时学生应当与出口在同一格子内 - 翻窗时玩家应当在窗前后一个格子内 -- *在指令仍在进行时,重复发出同一类型的交互指令是无效的,你需要先发出Stop指令终止进行的指令* +- 在指令仍在进行时,重复发出同一类型的交互指令是无效的,你需要先发出Stop指令终止进行的指令 ### 破译与逃脱 -- *每张地图都会刷新 9台电机,求生者需要破译其中的7台*,并开启任意一个大门后从任意一个开启的大门- 逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱; +- 每张地图都会刷新 9台电机,求生者需要破译其中的7台,并开启任意一个大门后从任意一个开启的大门- 逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱; - 求生者和监管者在靠近电机时,可以看到电机的破译进度条。 - 紧急出口会在电机破译完成3台的情况下在地图的3-5个固定紧急出口刷新点之一随机刷新。 - 当求生者只剩1名时,紧急出口盖将会自动打开,该求生者可从紧急出口逃脱。 -- *开启大门所需时间为18秒。* +- 开启大门所需时间为18秒。 - 大门开启的进度不清空 - 一个大门同时最多可以由一人开启 @@ -222,7 +222,7 @@ - 无论搞蛋鬼或学生,攻击时,从播放攻击动作到可以开始产生伤害的期间,称为前摇。(前摇阶段,搞蛋鬼产生通常为不可爆炸(部分搞蛋鬼能可以产生可爆炸)子弹(爆炸范围=0),[子弹大小待商榷],期间监管者攻击被打断时,子弹消失)(无论近战远程均产生子弹) - 无论搞蛋鬼或学生,攻击后,通常会出现一段无伤害判定的攻击动作后置时间,称为后摇。击中物体时后摇更长 -- *假如监管者攻击或一些监管者的特定技能击中正在交互的求生者,将使求生者眩晕* +- 假如监管者攻击或一些监管者的特定技能击中正在交互或处于攻击前后摇或使用部分技能(指PlayerState==UsingSkill)的求生者,将使求生者眩晕 1. 处于前摇或后摇 2. 治疗或解救他人 3. 修理电机 From 6e311a2e748179b7d52fdc9b46e9a72b1b4ad897 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 00:45:15 +0800 Subject: [PATCH 04/15] build: :construction: make the chest allow to be opened by ONLY one people --- logic/Gaming/ActionManager.cs | 2 +- logic/规则Logic.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 3327eae..0a2a44f 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -257,7 +257,7 @@ namespace Gaming return false; Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest); - if (chestToOpen == null || chestToOpen.IsOpen()) + if (chestToOpen == null || chestToOpen.IsOpen() || chestToOpen.OpenDegree > 0) return false; player.PlayerState = PlayerStateType.OpeningTheChest; diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 42378d0..74beaeb 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -237,7 +237,7 @@ - 门只有开、锁两种状态,锁住时门有碰撞体积 - 当门所在格子内有人时,无法锁门(必须从门外锁门) - 锁门时其他人可以进入门所在格子,锁门过程中断 -- *钥匙只会出现在箱子中,每个教学区都有2把钥匙* +- 钥匙只会出现在箱子中,每个教学区都有2把钥匙 - 一扇门只允许同时一个人开锁门 - 开锁门未完成前,门状态表现为原来的状态 - 开锁门进度中断后清空 @@ -254,7 +254,7 @@ ### 箱子 - *监管者和求生者都能与箱子交互,同一时刻只允许一人进行开启* -- *开启箱子有不同概率获得不同道具。* +- 开启箱子有不同概率获得不同道具。 - *开启箱子的基础持续时间为10秒。* - *未开启完成的箱子在下一次需要重新开始开启。* - *箱子开启后其中道具才可以被观测和拿取* From 1ef1fcb7764e755d4672d4331bdb3f95d8afa891 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 00:58:50 +0800 Subject: [PATCH 05/15] style: :art: resolve the conversation about the NullProp --- logic/GameClass/GameObj/Character/Character.Student.cs | 2 -- logic/GameClass/GameObj/Character/Character.cs | 4 +++- logic/Gaming/PropManager.cs | 7 ++----- logic/规则Logic.md | 10 +++++----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index 1be3f9b..fc09937 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -6,8 +6,6 @@ namespace GameClass.GameObj { public class Student : Character { - - private readonly object beAttackedLock = new(); /// /// 遭受攻击 /// diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 19a3487..78d3136 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -10,8 +10,10 @@ namespace GameClass.GameObj { public partial class Character : Moveable, ICharacter // 负责人LHR摆烂终了 { + #region 装弹、攻击相关的基本属性及方法 + + protected readonly object beAttackedLock = new(); - #region 装弹攻击相关的基本属性及方法 /// /// 装弹冷却 /// diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index fc786e9..fa64622 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -59,13 +59,10 @@ namespace Gaming if (indexing == GameData.maxNumOfPropInPropInventory) return false; - Prop? pickProp = new NullProp(); + Prop pickProp = new NullProp(); if (propType == PropType.Null) // 自动检查有无道具可捡 { - pickProp = (Prop?)gameMap.OneInTheSameCell(player.Position, GameObjType.Prop); - if (pickProp != null) - player.PropInventory[indexing] = pickProp; - else player.PropInventory[indexing] = pickProp = new NullProp(); + pickProp = player.PropInventory[indexing] = ((Prop?)gameMap.OneInTheSameCell(player.Position, GameObjType.Prop)) ?? new NullProp(); } else { diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 74beaeb..21ecc27 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -253,11 +253,11 @@ - 窗必须在两个墙之间,另外两侧不能为墙 ### 箱子 -- *监管者和求生者都能与箱子交互,同一时刻只允许一人进行开启* +- 监管者和求生者都能与箱子交互,同一时刻只允许一人进行开启 - 开启箱子有不同概率获得不同道具。 -- *开启箱子的基础持续时间为10秒。* -- *未开启完成的箱子在下一次需要重新开始开启。* -- *箱子开启后其中道具才可以被观测和拿取* +- 开启箱子的基础持续时间为10秒。 +- 未开启完成的箱子在下一次需要重新开始开启。 +- 箱子开启后其中道具才可以被观测和拿取 - [箱子道具不刷新] - [箱子不可被关闭] - [箱子内道具最多两个] @@ -294,4 +294,4 @@ ### 救人 - 一般情况下,救人时间为1秒。 -- *不能两人同时救一个人* +- 不能两人同时救一个人 From af88026d6e5da7b8c136dad346882c4176e658c8 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 01:20:16 +0800 Subject: [PATCH 06/15] build: :construction: finish the CopyInfo --- logic/Server/CopyInfo.cs | 47 +++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs index 0765668..a2b7698 100644 --- a/logic/Server/CopyInfo.cs +++ b/logic/Server/CopyInfo.cs @@ -173,9 +173,16 @@ namespace Server return PickedProp((PickedProp)gameObj); case Preparation.Utility.GameObjType.Generator: return Classroom((Generator)gameObj); - // case Preparation.Utility.GameObjType.Chest: + case Preparation.Utility.GameObjType.Chest: + return Chest((Chest)gameObj); case Preparation.Utility.GameObjType.Doorway: return Gate((Doorway)gameObj); + case Preparation.Utility.GameObjType.EmergencyExit: + if (((EmergencyExit)gameObj).CanOpen) + return HiddenGate((EmergencyExit)gameObj); + else return null; + case Preparation.Utility.GameObjType.Door: + return Door((Door)gameObj); default: return null; } } @@ -341,14 +348,34 @@ namespace Server msg.GateMessage.Progress = doorway.OpenDegree; return msg; } - /* private static MessageOfObj Chest(Chest chest) - { - MessageOfObj msg = new MessageOfObj(); - msg.ChestMessage = new(); - msg.ChestMessage.X=chest.Position.x; - msg.ChestMessage.Y=chest.Position.y; - // msg.ChestMessage.Progress=generator.DegreeOfRepair; - return msg; - }*/ + private static MessageOfObj HiddenGate(EmergencyExit Exit) + { + MessageOfObj msg = new MessageOfObj(); + msg.HiddenGateMessage = new(); + msg.HiddenGateMessage.X = Exit.Position.x; + msg.HiddenGateMessage.Y = Exit.Position.y; + msg.HiddenGateMessage.Opened = Exit.IsOpen; + return msg; + } + + private static MessageOfObj Door(Door door) + { + MessageOfObj msg = new MessageOfObj(); + msg.DoorMessage = new(); + msg.DoorMessage.X = door.Position.x; + msg.DoorMessage.Y = door.Position.y; + msg.DoorMessage.Progress = door.OpenOrLockDegree; + msg.DoorMessage.IsOpen = door.IsOpen; + return msg; + } + private static MessageOfObj Chest(Chest chest) + { + MessageOfObj msg = new MessageOfObj(); + msg.ChestMessage = new(); + msg.ChestMessage.X = chest.Position.x; + msg.ChestMessage.Y = chest.Position.y; + msg.ChestMessage.Progress = chest.OpenDegree; + return msg; + } } } \ No newline at end of file From 3efd0ea96309b63825102a4c581cf4043f31c283 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 01:28:21 +0800 Subject: [PATCH 07/15] build: :construction: nothing --- dependency/proto/Message2Clients.proto | 3 +-- logic/Gaming/PropManager.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dependency/proto/Message2Clients.proto b/dependency/proto/Message2Clients.proto index 51e581b..7ccc4f6 100755 --- a/dependency/proto/Message2Clients.proto +++ b/dependency/proto/Message2Clients.proto @@ -122,8 +122,7 @@ message MessageOfDoor int32 x = 1; int32 y = 2; bool is_open = 3; - int32 number = 4; - int32 progress = 5; + int32 progress = 4; } message MessageOfChest diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index fa64622..0349a98 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -121,7 +121,7 @@ namespace Gaming case 3: return new Spear(Pos, gameMap.GetPlaceType(Pos)); default: - return null; + return new NullProp(); } } From 774f7697555071e855096847b2e28d8a4378f9e7 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 08:19:44 +0800 Subject: [PATCH 08/15] build: :construction: finish the Game.cs --- logic/Gaming/ActionManager.cs | 12 ++--- logic/Gaming/Game.cs | 52 +++++++++++++++++++--- logic/Preparation/Interface/IOccupation.cs | 43 ++++++++++++++++++ logic/Preparation/Utility/EnumType.cs | 2 +- logic/Preparation/Utility/GameData.cs | 24 ++++++++-- logic/Server/CopyInfo.cs | 2 +- logic/规则Logic.md | 2 +- 7 files changed, 118 insertions(+), 19 deletions(-) diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 0a2a44f..5145469 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -34,7 +34,7 @@ namespace Gaming public bool Fix(Student player)// 自动检查有无发电机可修 { - if (player.IsGhost() || (!player.Commandable()) || player.PlayerState == PlayerStateType.Fixing) + if ((!player.Commandable()) || player.PlayerState == PlayerStateType.Fixing) return false; Generator? generatorForFix = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator); @@ -97,22 +97,22 @@ namespace Gaming return true; } - public bool OpenDoorWay(Student player) + public bool OpenDoorway(Student player) { - if (!(player.Commandable()) || player.PlayerState == PlayerStateType.OpeningTheDoorWay) + if (!(player.Commandable()) || player.PlayerState == PlayerStateType.OpeningTheDoorway) return false; Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); if (doorwayToOpen == null || doorwayToOpen.IsOpening || !doorwayToOpen.PowerSupply) return false; - player.PlayerState = PlayerStateType.OpeningTheDoorWay; + player.PlayerState = PlayerStateType.OpeningTheDoorway; doorwayToOpen.IsOpening = true; new Thread ( () => { new FrameRateTaskExecutor( - loopCondition: () => player.PlayerState == PlayerStateType.OpeningTheDoorWay && gameMap.Timer.IsGaming && doorwayToOpen.OpenDegree < GameData.degreeOfOpenedDoorway, + loopCondition: () => player.PlayerState == PlayerStateType.OpeningTheDoorway && gameMap.Timer.IsGaming && doorwayToOpen.OpenDegree < GameData.degreeOfOpenedDoorway, loopToDo: () => { doorwayToOpen.OpenDegree += GameData.frameDuration; @@ -125,7 +125,7 @@ namespace Gaming doorwayToOpen.IsOpening = false; if (doorwayToOpen.OpenDegree >= GameData.degreeOfOpenedDoorway) { - if (player.PlayerState == PlayerStateType.OpeningTheDoorWay) + if (player.PlayerState == PlayerStateType.OpeningTheDoorway) player.PlayerState = PlayerStateType.Null; } } diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index c7d90aa..06ed125 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -252,11 +252,8 @@ namespace Gaming if (!gameMap.Timer.IsGaming) return false; ICharacter? player = gameMap.FindPlayer(playerID); - if (player != null) - { - if (!player.IsGhost()) - return actionManager.Fix((Student)player); - } + if (player != null && !player.IsGhost()) + return actionManager.Fix((Student)player); return false; } public bool Escape(long playerID) @@ -282,7 +279,50 @@ namespace Gaming } return false; } - + public bool OpenDoorway(long playerID) + { + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null && !player.IsGhost()) + { + return actionManager.OpenDoorway((Student)player); + } + return false; + } + public bool OpenChest(long playerID) + { + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + return actionManager.OpenChest(player); + } + return false; + } + public bool ClimbingThroughWindow(long playerID) + { + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + return actionManager.ClimbingThroughWindow(player); + } + return false; + } + public bool LockOrOpenDoor(long playerID) + { + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + return actionManager.LockOrOpenDoor(player); + } + return false; + } public void Attack(long playerID, double angle) { if (!gameMap.Timer.IsGaming) diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index 71fb6fc..70fe818 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -67,6 +67,49 @@ namespace Preparation.Interface public int timeOfOpenChest = GameData.basicSpeedOfOpenChest; public int TimeOfOpenChest => timeOfOpenChest; } + public class Teacher : IStudent + { + private const int moveSpeed = GameData.basicMoveSpeed / 38 * 40; + public int MoveSpeed => moveSpeed; + + private const int maxHp = GameData.basicHp / 30 * 32; + public int MaxHp => maxHp; + + public const int cd = 0; + public int CD => cd; + + public const int maxBulletNum = 0; + public int MaxBulletNum => maxBulletNum; + + public BulletType InitBullet => BulletType.Null; + + public List ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.CanBeginToCharge }); + public List ListOfIPassiveSkill => new(new PassiveSkillType[] { }); + + public const int fixSpeed = GameData.basicFixSpeed / 10 * 6; + public int FixSpeed => fixSpeed; + + public const int treatSpeed = GameData.basicTreatSpeed / 10 * 8; + public int TreatSpeed => treatSpeed; + + public const double concealment = GameData.basicConcealment * 0.9; + public double Concealment => concealment; + + public const int alertnessRadius = (int)(GameData.basicAlertnessRadius * 0.9); + public int AlertnessRadius => alertnessRadius; + + public int viewRange = (int)(GameData.basicViewRange * 1.1); + public int ViewRange => viewRange; + + public int timeOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking * 12 / 10; + public int TimeOfOpeningOrLocking => timeOfOpeningOrLocking; + + public int speedOfClimbingThroughWindows = GameData.basicStudentSpeedOfClimbingThroughWindows * 12 / 10; + public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows; + + public int timeOfOpenChest = GameData.basicSpeedOfOpenChest; + public int TimeOfOpenChest => timeOfOpenChest; + } public class Athlete : IStudent { private const int moveSpeed = GameData.basicMoveSpeed / 38 * 40; diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 42787b2..c7447ac 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -23,7 +23,7 @@ namespace Preparation.Utility OpeningTheChest = 14, ClimbingThroughWindows = 15, UsingSkill = 16, - OpeningTheDoorWay = 17, + OpeningTheDoorway = 17, } public enum GameObjType { diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index c8c4dbe..90c0766 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -1,4 +1,5 @@ using System; +using System.Net.NetworkInformation; namespace Preparation.Utility { @@ -7,6 +8,7 @@ namespace Preparation.Utility #region 基本常数 public const int numOfStepPerSecond = 20; // 每秒行走的步数 public const int frameDuration = 50; // 每帧时长 + public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 public const long gameDuration = 600000; // 游戏时长600000ms = 10min @@ -85,7 +87,6 @@ namespace Preparation.Utility public const int basicAlertnessRadius = 30700; public const int basicViewRange = 5 * numOfPosGridPerCell; public const int maxNumOfPropInPropInventory = 3; - public const int addScoreWhenKillOneLevelPlayer = 30; // 击杀一级角色获得的加分 public static XY PosWhoDie = new XY(1, 1); @@ -98,6 +99,24 @@ namespace Preparation.Utility }; } #endregion + #region 得分相关 + public static int TrickerScoreAttackStudent(int damage) + { + return damage * 100 / basicApOfGhost; + } + public const int TrickerScoreStudentBeAddicted = 50; + public const int TrickerScoreStudentBeStunned = 25; + public const int TrickerScoreStudentDie = 1000; + + public static int StudentScoreFix(int degreeOfFix) + { + return degreeOfFix; + } + public static int StudentScorePinDown(int timeOfPiningDown) + { + return 0; + } + #endregion #region 攻击与子弹相关 public const int basicApOfGhost = 1500000; // 捣蛋鬼攻击力 public const int MinAP = 0; // 最小攻击力 @@ -147,8 +166,5 @@ namespace Preparation.Utility public const int numOfGeneratorRequiredForRepair = 7; public const int numOfGeneratorRequiredForEmergencyExit = 3; #endregion - #region 游戏帧相关 - public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 - #endregion } } diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs index a2b7698..4f698fc 100644 --- a/logic/Server/CopyInfo.cs +++ b/logic/Server/CopyInfo.cs @@ -96,7 +96,7 @@ namespace Server return PlayerState.Attacking; case Preparation.Utility.PlayerStateType.UsingSkill: return PlayerState.UsingSpecialSkill; - case Preparation.Utility.PlayerStateType.OpeningTheDoorWay: + case Preparation.Utility.PlayerStateType.OpeningTheDoorway: return PlayerState.OpeningAGate; default: return PlayerState.NullStatus; diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 21ecc27..2f82cf2 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -97,7 +97,7 @@ OpeningTheChest = 14, ClimbingThroughWindows = 15, UsingSkill = 16, - OpeningTheDoorWay = 17, + OpeningTheDoorway = 17, } ~~~ - 可执行指令的(不用给选手) From 2143e2a7241561d00db054874ee94f8b14b21d30 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 08:53:43 +0800 Subject: [PATCH 09/15] fix: :bug: fix a problem about being stunned --- .../GameObj/Character/Character.Student.cs | 1 - logic/Gaming/ActionManager.cs | 1 - logic/Gaming/AttackManager.cs | 21 ++++++++++++++++++- logic/Preparation/Utility/GameData.cs | 6 +++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index fc09937..203f737 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -22,7 +22,6 @@ namespace GameClass.GameObj return false; // 原来已经死了 if (bullet.Parent.TeamID != this.TeamID) { - if (CanBeAwed()) PlayerState = PlayerStateType.Stunned; if (HasShield) { if (bullet.HasSpear) diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 5145469..11adda1 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -317,7 +317,6 @@ namespace Gaming ( () => { - new FrameRateTaskExecutor( loopCondition: () => player.PlayerState == PlayerStateType.ClimbingThroughWindows && gameMap.Timer.IsGaming, loopToDo: () => { }, diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 0932f22..1484599 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -139,10 +139,29 @@ namespace Gaming case GameObjType.Character: if ((!((Character)objBeingShot).IsGhost()) && bullet.Parent.IsGhost()) - if (((Student)objBeingShot).BeAttacked(bullet)) + { + Student oneBeAttacked = (Student)objBeingShot; + if (oneBeAttacked.CanBeAwed()) + { + oneBeAttacked.PlayerState = PlayerStateType.Stunned; + new Thread + ( + () => + { + Thread.Sleep(GameData.basicStunnedTimeOfStudent); + if (oneBeAttacked.PlayerState == PlayerStateType.Stunned) + { + oneBeAttacked.PlayerState = PlayerStateType.Null; + } + } + ) + { IsBackground = true }.Start(); + } + if (oneBeAttacked.BeAttacked(bullet)) { BeAddictedToGame((Student)objBeingShot); } + } // if (((Character)objBeingShot).IsGhost() && !bullet.Parent.IsGhost() && bullet.TypeOfBullet == BulletType.Ram) // BeStunned((Character)objBeingShot, bullet.AP); break; diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 90c0766..0608f2a 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -116,6 +116,9 @@ namespace Preparation.Utility { return 0; } + public const int StudentScoreTrickerBeStunned = 25; + + public const int ScoreUseProp = 0; #endregion #region 攻击与子弹相关 public const int basicApOfGhost = 1500000; // 捣蛋鬼攻击力 @@ -124,8 +127,9 @@ namespace Preparation.Utility public const int basicCD = 3000; // 初始子弹冷却 public const int basicCastTime = 500;//基本前摇时间 - public const int basicBackswing = 500;//基本后摇时间 + public const int basicBackswing = 818;//基本后摇时间 public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长 + public const int basicStunnedTimeOfStudent = 4130; public const int bulletRadius = 200; // 默认子弹半径 public const int basicBulletNum = 3; // 基本初始子弹量 From 3fa6b6d5e9ff040e8db744e8bb5ea49128a8f3c8 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 10:39:23 +0800 Subject: [PATCH 10/15] build: :construction: finishing the Score system --- .../GameObj/Character/Character.Student.cs | 2 +- logic/Gaming/ActionManager.cs | 19 +++++++- logic/Gaming/AttackManager.cs | 13 +++--- logic/Gaming/Game.cs | 10 ++++- logic/Preparation/Interface/ICharacter.cs | 2 + logic/Preparation/Utility/GameData.cs | 7 +++ logic/规则Logic.md | 43 +++++++++++++++++++ 7 files changed, 87 insertions(+), 9 deletions(-) diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index 203f737..8c73851 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -25,7 +25,7 @@ namespace GameClass.GameObj if (HasShield) { if (bullet.HasSpear) - _ = TrySubHp(bullet.AP); + bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(TrySubHp(bullet.AP))); else return false; } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 11adda1..2d60b26 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -46,11 +46,14 @@ namespace Gaming ( () => { + int ScoreAdded = GameData.StudentScoreFix(generatorForFix.DegreeOfRepair); new FrameRateTaskExecutor( loopCondition: () => player.PlayerState == PlayerStateType.Fixing && gameMap.Timer.IsGaming && generatorForFix.DegreeOfRepair < GameData.degreeOfFixedGenerator, loopToDo: () => { generatorForFix.Repair(player.FixSpeed * GameData.frameDuration); + player.AddScore(GameData.StudentScoreFix(generatorForFix.DegreeOfRepair - ScoreAdded)); + ScoreAdded = GameData.StudentScoreFix(generatorForFix.DegreeOfRepair); }, timeInterval: GameData.frameDuration, finallyReturn: () => 0 @@ -145,6 +148,7 @@ namespace Gaming { if (doorwayForEscape.IsOpen()) { + player.AddScore(GameData.StudentScoreEscape); player.Die(PlayerStateType.Escaped); return true; } @@ -205,12 +209,14 @@ namespace Gaming if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp) { + player.AddScore(GameData.StudentScoreTreat(playerTreated.MaxHp - playerTreated.HP)); playerTreated.HP = playerTreated.MaxHp; playerTreated.DegreeOfTreatment = 0; } else if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree) { + player.AddScore(GameData.StudentScoreTreat(GameData.basicTreatmentDegree)); playerTreated.HP += GameData.basicTreatmentDegree; playerTreated.DegreeOfTreatment = 0; } @@ -242,8 +248,17 @@ namespace Gaming ) .Start(); - if (playerRescued.PlayerState == PlayerStateType.Rescued) playerRescued.PlayerState = PlayerStateType.Null; - if (player.PlayerState == PlayerStateType.Rescuing) player.PlayerState = (player.TimeOfRescue >= GameData.basicTimeOfRescue) ? PlayerStateType.Null : PlayerStateType.Addicted; + if (playerRescued.PlayerState == PlayerStateType.Rescued) + { + if (player.TimeOfRescue >= GameData.basicTimeOfRescue) + { + playerRescued.PlayerState = PlayerStateType.Null; + player.AddScore(GameData.StudentScoreRescue); + } + else + playerRescued.PlayerState = PlayerStateType.Addicted; + } + if (player.PlayerState == PlayerStateType.Rescuing) player.PlayerState = PlayerStateType.Null; player.TimeOfRescue = 0; } ) diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 1484599..7118de4 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -38,8 +38,9 @@ namespace Gaming ); } - private void BeAddictedToGame(Student player) + private void BeAddictedToGame(Student player, Ghost ghost) { + ghost.AddScore(GameData.TrickerScoreStudentBeAddicted); new Thread (() => { @@ -57,6 +58,7 @@ namespace Gaming { if (player.GamingAddiction == player.MaxGamingAddiction && gameMap.Timer.IsGaming) { + ghost.AddScore(GameData.TrickerScoreStudentDie); Die(player); } return 0; @@ -141,9 +143,14 @@ namespace Gaming if ((!((Character)objBeingShot).IsGhost()) && bullet.Parent.IsGhost()) { Student oneBeAttacked = (Student)objBeingShot; + if (oneBeAttacked.BeAttacked(bullet)) + { + BeAddictedToGame(oneBeAttacked, (Ghost)bullet.Parent); + } if (oneBeAttacked.CanBeAwed()) { oneBeAttacked.PlayerState = PlayerStateType.Stunned; + bullet.Parent.AddScore(GameData.TrickerScoreStudentBeStunned); new Thread ( () => @@ -157,10 +164,6 @@ namespace Gaming ) { IsBackground = true }.Start(); } - if (oneBeAttacked.BeAttacked(bullet)) - { - BeAddictedToGame((Student)objBeingShot); - } } // if (((Character)objBeingShot).IsGhost() && !bullet.Parent.IsGhost() && bullet.TypeOfBullet == BulletType.Ram) // BeStunned((Character)objBeingShot, bullet.AP); diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 06ed125..0a387fd 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -85,13 +85,14 @@ namespace Gaming ) { IsBackground = true }.Start(); #endregion - #region BGM更新 + #region BGM,牵制得分更新 new Thread ( () => { while (!gameMap.Timer.IsGaming) Thread.Sleep((int)GameData.checkInterval); + int TimePinningDown = 0, ScoreAdded = 0; new FrameRateTaskExecutor( loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, loopToDo: () => @@ -121,6 +122,13 @@ namespace Gaming { if (XY.Distance(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment)) newPlayer.AddBgm(BgmType.GhostIsComing, (double)newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position)); + if (XY.Distance(newPlayer.Position, person.Position) <= GameData.basicViewRange) + { + TimePinningDown += (int)GameData.checkInterval; + newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded); + ScoreAdded = GameData.StudentScorePinDown(TimePinningDown); + } + else TimePinningDown = ScoreAdded = 0; break; } } diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index ea40d91..fe79716 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -7,6 +7,8 @@ namespace Preparation.Interface { public long TeamID { get; } public int HP { get; set; } + public int Score { get; } + public void AddScore(int add); public double Vampire { get; } public PlayerStateType PlayerState { get; set; } public bool IsGhost(); diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 0608f2a..dda36ba 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -112,11 +112,18 @@ namespace Preparation.Utility { return degreeOfFix; } + public const int StudentScoreFixed = 25; public static int StudentScorePinDown(int timeOfPiningDown) { return 0; } public const int StudentScoreTrickerBeStunned = 25; + public const int StudentScoreRescue = 100; + public static int StudentScoreTreat(int degree) + { + return degree; + } + public const int StudentScoreEscape = 1000; public const int ScoreUseProp = 0; #endregion diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 2f82cf2..963c22a 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -295,3 +295,46 @@ ### 救人 - 一般情况下,救人时间为1秒。 - 不能两人同时救一个人 + +## 得分 + +### 屠夫 + +#### 伤害得分 +[Tricker对Student造成伤害时,得伤害*100/基本伤害(1500000)分。] + +#### *[使用道具/技能得分——需要造成一定效果才能获取分数,仅使用不得分]* + +#### 沉迷 +使Student进入沉迷状态时,得50分。 + +#### 眩晕 +使人类进入眩晕状态时,得25分。 + +#### 淘汰 +每淘汰一个Student,得1000分 + +#### ~~主动/被动解除特殊状态得分(如解除眩晕)~~ +~~解除眩晕,得15分~~ + +### 人类 + +#### 修机得分 +- 人类每修n%的电机,得n分 +- 修完一台电机,额外得?分 + +#### [牵制得分] + +#### 使用道具/技能得分 + +#### 使屠夫进入特殊状态得分(如使之眩晕) + +#### 救人 + +#### 治疗 + +#### 逃脱 + +#### ~~解除眩晕~~ + +#### ~~自愈~~ \ No newline at end of file From a7286a41d049337742231d245814905facd0bd51 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 11:00:21 +0800 Subject: [PATCH 11/15] fix: :bug: fix a bug that Failing to Rescue still can interrupt the process of being Addicted --- logic/Gaming/AttackManager.cs | 4 ++-- logic/Preparation/Utility/GameData.cs | 9 ++++++++- logic/规则Logic.md | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 7118de4..f975b35 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -48,10 +48,10 @@ namespace Gaming player.GamingAddiction = GameData.MidGamingAddiction; player.PlayerState = PlayerStateType.Addicted; new FrameRateTaskExecutor( - () => player.PlayerState == PlayerStateType.Addicted && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming, + () => (player.PlayerState == PlayerStateType.Addicted || player.PlayerState == PlayerStateType.Rescued) && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming, () => { - player.GamingAddiction += GameData.frameDuration; + player.GamingAddiction += (player.PlayerState == PlayerStateType.Addicted) ? GameData.frameDuration : 0; }, timeInterval: GameData.frameDuration, () => diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index dda36ba..efbc747 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -125,7 +125,14 @@ namespace Preparation.Utility } public const int StudentScoreEscape = 1000; - public const int ScoreUseProp = 0; + public static int ScoreUseProp(PropType prop, bool IsGhost) + { + return 0; + } + public static int ScoreUseSkill(ActiveSkillType activeSkillType) + { + return 0; + } #endregion #region 攻击与子弹相关 public const int basicApOfGhost = 1500000; // 捣蛋鬼攻击力 diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 963c22a..2a8004c 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -288,6 +288,7 @@ ### 沉迷 - 当求生者血量归零时,求生者自动原地进入沉迷状态,每毫秒增加1沉迷度 +- 在被救时沉迷度不增加 - 该求生者可由其他的求生者救下,救下后,*血量恢复至1/2并可以重新行动*。沉迷程度不清空。 - 进入沉迷状态时,如果求生者原本沉迷程度在【10003,30000】中,求生者沉迷程度直接变为30000 - 当求生者沉迷程度达到该玩家最大沉迷程度(学生有的属性)时,从游戏中出局 @@ -304,6 +305,7 @@ [Tricker对Student造成伤害时,得伤害*100/基本伤害(1500000)分。] #### *[使用道具/技能得分——需要造成一定效果才能获取分数,仅使用不得分]* +- 不同道具/技能有不同得分 #### 沉迷 使Student进入沉迷状态时,得50分。 @@ -326,6 +328,7 @@ #### [牵制得分] #### 使用道具/技能得分 +- 不同道具/技能有不同得分 #### 使屠夫进入特殊状态得分(如使之眩晕) From fb13679bc0f47d6f642e1c8450293a597a54bdbe Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 17:46:24 +0800 Subject: [PATCH 12/15] refactor: :art: rebuild the CD system --- .../GameClass/GameObj/Bullet/Bullet.Ghost.cs | 24 +++++++++++- logic/GameClass/GameObj/Bullet/Bullet.cs | 38 +++++++++++++------ .../GameObj/Character/Character.Skill.cs | 2 +- .../GameClass/GameObj/Character/Character.cs | 3 ++ logic/Gaming/Game.cs | 8 ++-- logic/Preparation/Interface/IOccupation.cs | 14 +------ logic/Preparation/Utility/GameData.cs | 2 +- 7 files changed, 60 insertions(+), 31 deletions(-) diff --git a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs index 5af9533..514ec8f 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs @@ -15,9 +15,13 @@ namespace GameClass.GameObj public override int AP => GameData.basicApOfGhost; public override int Speed => GameData.basicBulletMoveSpeed; public override bool IsToBomb => false; + public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; public override int RecoveryFromHit => GameData.basicRecoveryFromHit; + public const int cd = GameData.basicBackswing; + public override int CD => cd; + public override bool CanAttack(GameObj target) { return false; @@ -41,9 +45,13 @@ namespace GameClass.GameObj public override int AP => GameData.basicApOfGhost / 5 * 4; public override int Speed => GameData.basicBulletMoveSpeed * 2; public override bool IsToBomb => false; + public override int CastTime => GameData.basicCastTime; - public override int Backswing => GameData.basicBackswing / 5 * 3; - public override int RecoveryFromHit => GameData.basicRecoveryFromHit / 4 * 3; + public override int Backswing => GameData.basicBackswing / 5 * 2; + public override int RecoveryFromHit => GameData.basicBackswing / 4 * 3; + public const int cd = GameData.basicBackswing / 5 * 2 + 100; + public override int CD => cd; + public override bool CanAttack(GameObj target) { return false; @@ -68,9 +76,13 @@ namespace GameClass.GameObj public override double BulletAttackRange => GameData.basicAttackShortRange / 9 * 7; public override int AP => GameData.basicApOfGhost / 3 * 7; public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2; + public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; public override int RecoveryFromHit => GameData.basicRecoveryFromHit; + public const int cd = GameData.basicCD; + public override int CD => cd; + public override bool IsToBomb => true; public override bool CanAttack(GameObj target) { @@ -97,9 +109,13 @@ namespace GameClass.GameObj public override double BulletAttackRange => GameData.basicAttackShortRange / 2; public override int AP => GameData.basicApOfGhost / 6 * 5; public override int Speed => GameData.basicBulletMoveSpeed / 6 * 5; + public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; public override int RecoveryFromHit => GameData.basicRecoveryFromHit; + public const int cd = GameData.basicCD; + public override int CD => cd; + public override bool IsToBomb => true; public override bool CanAttack(GameObj target) { @@ -128,6 +144,8 @@ namespace GameClass.GameObj public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; public override int RecoveryFromHit => GameData.basicRecoveryFromHit; + public const int cd = GameData.basicCD; + public override int CD => cd; public override bool IsToBomb => true; public override bool CanAttack(GameObj target) @@ -157,6 +175,8 @@ namespace GameClass.GameObj public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; public override int RecoveryFromHit => GameData.basicRecoveryFromHit; + public const int cd = GameData.basicCD; + public override int CD => cd; public override bool IsToBomb => true; public override bool CanBeBombed(GameObjType gameObjType) diff --git a/logic/GameClass/GameObj/Bullet/Bullet.cs b/logic/GameClass/GameObj/Bullet/Bullet.cs index 0020a2f..4960244 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.cs @@ -17,6 +17,7 @@ namespace GameClass.GameObj public abstract int CastTime { get; } public abstract int Backswing { get; } public abstract int RecoveryFromHit { get; } + public abstract int CD { get; } private readonly bool hasSpear; /// @@ -56,25 +57,23 @@ namespace GameClass.GameObj { public static Bullet? GetBullet(Character character, PlaceType place, XY pos) { - Bullet? newBullet = null; switch (character.BulletOfPlayer) { + case BulletType.FlyingKnife: + return new FlyingKnife(character, place, pos); + case BulletType.CommonAttackOfGhost: + return new CommonAttackOfGhost(character, place, pos); case BulletType.AtomBomb: - newBullet = new AtomBomb(character, place, pos); - break; + return new AtomBomb(character, place, pos); case BulletType.LineBullet: - newBullet = new LineBullet(character, place, pos); - break; + return new LineBullet(character, place, pos); case BulletType.FastBullet: - newBullet = new FastBullet(character, place, pos); - break; + return new FastBullet(character, place, pos); case BulletType.OrdinaryBullet: - newBullet = new OrdinaryBullet(character, place, pos); - break; + return new OrdinaryBullet(character, place, pos); default: - break; + return null; } - return newBullet; } public static int BulletRadius(BulletType bulletType) { @@ -84,9 +83,26 @@ namespace GameClass.GameObj case BulletType.LineBullet: case BulletType.FastBullet: case BulletType.OrdinaryBullet: + case BulletType.FlyingKnife: default: return GameData.bulletRadius; } } + public static int BulletCD(BulletType bulletType) + { + switch (bulletType) + { + case BulletType.CommonAttackOfGhost: + return CommonAttackOfGhost.cd; + case BulletType.FlyingKnife: + return FlyingKnife.cd; + case BulletType.AtomBomb: + case BulletType.LineBullet: + case BulletType.FastBullet: + case BulletType.OrdinaryBullet: + default: + return GameData.basicCD; + } + } } } diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 5bed851..2e803d3 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -77,7 +77,7 @@ namespace GameClass.GameObj this.hp = Occupation.MaxHp; this.OrgMoveSpeed = Occupation.MoveSpeed; this.moveSpeed = Occupation.MoveSpeed; - this.cd = Occupation.CD; + this.OrgCD = this.cd = BulletFactory.BulletCD(Occupation.InitBullet); this.maxBulletNum = Occupation.MaxBulletNum; this.bulletNum = maxBulletNum; this.bulletOfPlayer = Occupation.InitBullet; diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 78d3136..be21099 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -45,7 +45,10 @@ namespace GameClass.GameObj set { lock (gameObjLock) + { bulletOfPlayer = value; + CD = BulletFactory.BulletCD(value); + } } } diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 0a387fd..d8e7670 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -54,7 +54,7 @@ namespace Gaming () => { while (!gameMap.Timer.IsGaming) - Thread.Sleep(newPlayer.CD); + Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval)); long lastTime = Environment.TickCount64; new FrameRateTaskExecutor( loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, @@ -63,7 +63,7 @@ namespace Gaming long nowTime = Environment.TickCount64; if (newPlayer.BulletNum == newPlayer.MaxBulletNum) lastTime = nowTime; - if (nowTime - lastTime >= newPlayer.CD) + else if (nowTime - lastTime >= newPlayer.CD) { _ = newPlayer.TryAddBulletNum(); lastTime = nowTime; @@ -91,7 +91,7 @@ namespace Gaming () => { while (!gameMap.Timer.IsGaming) - Thread.Sleep((int)GameData.checkInterval); + Thread.Sleep(GameData.checkInterval); int TimePinningDown = 0, ScoreAdded = 0; new FrameRateTaskExecutor( loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, @@ -124,7 +124,7 @@ namespace Gaming newPlayer.AddBgm(BgmType.GhostIsComing, (double)newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position)); if (XY.Distance(newPlayer.Position, person.Position) <= GameData.basicViewRange) { - TimePinningDown += (int)GameData.checkInterval; + TimePinningDown += GameData.checkInterval; newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded); ScoreAdded = GameData.StudentScorePinDown(TimePinningDown); } diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index 70fe818..cf21399 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -8,7 +8,6 @@ namespace Preparation.Interface public int MoveSpeed { get; } public int MaxHp { get; } public BulletType InitBullet { get; } - public int CD { get; } public int MaxBulletNum { get; } public List ListOfIActiveSkill { get; } public List ListOfIPassiveSkill { get; } @@ -38,9 +37,6 @@ namespace Preparation.Interface private const int maxHp = GameData.basicHp; public int MaxHp => maxHp; - public const int cd = 0; - public int CD => cd; - public const int maxBulletNum = 1; public int MaxBulletNum => maxBulletNum; @@ -69,15 +65,12 @@ namespace Preparation.Interface } public class Teacher : IStudent { - private const int moveSpeed = GameData.basicMoveSpeed / 38 * 40; + private const int moveSpeed = GameData.basicMoveSpeed / 42 * 36; public int MoveSpeed => moveSpeed; - private const int maxHp = GameData.basicHp / 30 * 32; + private const int maxHp = GameData.basicHp * 10; public int MaxHp => maxHp; - public const int cd = 0; - public int CD => cd; - public const int maxBulletNum = 0; public int MaxBulletNum => maxBulletNum; @@ -118,9 +111,6 @@ namespace Preparation.Interface private const int maxHp = GameData.basicHp / 30 * 32; public int MaxHp => maxHp; - public const int cd = 0; - public int CD => cd; - public const int maxBulletNum = 0; public int MaxBulletNum => maxBulletNum; diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index efbc747..744e396 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -8,7 +8,7 @@ namespace Preparation.Utility #region 基本常数 public const int numOfStepPerSecond = 20; // 每秒行走的步数 public const int frameDuration = 50; // 每帧时长 - public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 + public const int checkInterval = 50; // 检查位置标志、补充子弹的帧时长 public const long gameDuration = 600000; // 游戏时长600000ms = 10min From 5c5cff64a69b776c131784c5233b44f7b956f94b Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Fri, 24 Mar 2023 18:05:29 +0800 Subject: [PATCH 13/15] style: :bug: use NullSkill to avoid warning --- .../GameClass/GameObj/Bullet/Bullet.Ghost.cs | 28 +++++++++---------- .../GameObj/Character/Character.Skill.cs | 11 +++----- logic/GameClass/GameObj/Character/Skill.cs | 22 ++++++--------- logic/Preparation/Interface/IOccupation.cs | 16 +++++------ logic/Preparation/Interface/ISkill.cs | 1 - 5 files changed, 35 insertions(+), 43 deletions(-) diff --git a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs index 514ec8f..7c8d545 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs @@ -42,14 +42,14 @@ namespace GameClass.GameObj } public override double BulletBombRange => 0; public override double BulletAttackRange => GameData.basicRemoteAttackRange * 13; - public override int AP => GameData.basicApOfGhost / 5 * 4; + public override int AP => GameData.basicApOfGhost * 4 / 5; public override int Speed => GameData.basicBulletMoveSpeed * 2; public override bool IsToBomb => false; public override int CastTime => GameData.basicCastTime; - public override int Backswing => GameData.basicBackswing / 5 * 2; - public override int RecoveryFromHit => GameData.basicBackswing / 4 * 3; - public const int cd = GameData.basicBackswing / 5 * 2 + 100; + public override int Backswing => GameData.basicBackswing * 2 / 5; + public override int RecoveryFromHit => GameData.basicBackswing * 3 / 4; + public const int cd = GameData.basicBackswing * 2 / 5 + 100; public override int CD => cd; public override bool CanAttack(GameObj target) @@ -72,10 +72,10 @@ namespace GameClass.GameObj base(player, radius, placeType, pos) { } - public override double BulletBombRange => GameData.basicBulletBombRange / 3 * 7; - public override double BulletAttackRange => GameData.basicAttackShortRange / 9 * 7; - public override int AP => GameData.basicApOfGhost / 3 * 7; - public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2; + public override double BulletBombRange => GameData.basicBulletBombRange * 7 / 3; + public override double BulletAttackRange => GameData.basicAttackShortRange * 7 / 9; + public override int AP => GameData.basicApOfGhost * 7 / 3; + public override int Speed => GameData.basicBulletMoveSpeed * 2 / 3; public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; @@ -105,10 +105,10 @@ namespace GameClass.GameObj base(player, radius, placeType, pos) { } - public override double BulletBombRange => GameData.basicBulletBombRange / 6 * 5; + public override double BulletBombRange => GameData.basicBulletBombRange * 5 / 6; public override double BulletAttackRange => GameData.basicAttackShortRange / 2; - public override int AP => GameData.basicApOfGhost / 6 * 5; - public override int Speed => GameData.basicBulletMoveSpeed / 6 * 5; + public override int AP => GameData.basicApOfGhost * 5 / 6; + public override int Speed => GameData.basicBulletMoveSpeed * 5 / 6; public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; @@ -137,7 +137,7 @@ namespace GameClass.GameObj base(player, radius, placeType, pos) { } - public override double BulletBombRange => GameData.basicBulletBombRange / 4 * 2; + public override double BulletBombRange => GameData.basicBulletBombRange * 2 / 4; public override double BulletAttackRange => GameData.basicAttackShortRange; public override int AP => (int)(0.5 * GameData.basicApOfGhost); public override int Speed => 5 * GameData.basicBulletMoveSpeed / 3; @@ -168,9 +168,9 @@ namespace GameClass.GameObj base(player, radius, placeType, pos) { } - public override double BulletBombRange => GameData.basicBulletBombRange / 3 * 4; + public override double BulletBombRange => GameData.basicBulletBombRange * 4 / 3; public override double BulletAttackRange => 0.1 * GameData.basicAttackShortRange; - public override int AP => GameData.basicApOfGhost / 3 * 2; + public override int AP => GameData.basicApOfGhost * 2 / 3; public override int Speed => GameData.basicBulletMoveSpeed / 3; public override int CastTime => GameData.basicCastTime; public override int Backswing => GameData.basicBackswing; diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 2e803d3..1519427 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -9,23 +9,22 @@ namespace GameClass.GameObj { private readonly CharacterType characterType; public CharacterType CharacterType => characterType; - private readonly IOccupation? occupation; + private readonly IOccupation occupation; public IOccupation Occupation => occupation; - private Dictionary timeUntilActiveSkillAvailable = new(); public Dictionary TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable; private Dictionary iActiveSkillDictionary = new(); public Dictionary IActiveSkillDictionary => iActiveSkillDictionary; - public IActiveSkill? UseIActiveSkill(ActiveSkillType activeSkillType) + public IActiveSkill UseIActiveSkill(ActiveSkillType activeSkillType) { if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) { return IActiveSkillDictionary[activeSkillType]; } - return null; + return new NullSkill(); } public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable) @@ -67,10 +66,8 @@ namespace GameClass.GameObj this.occupation = new Assassin(); break; case CharacterType.Athlete: - this.occupation = new Athlete(); - break; default: - this.occupation = null; + this.occupation = new Athlete(); break; } this.MaxHp = Occupation.MaxHp; diff --git a/logic/GameClass/GameObj/Character/Skill.cs b/logic/GameClass/GameObj/Character/Skill.cs index 0a28727..6ce89e3 100644 --- a/logic/GameClass/GameObj/Character/Skill.cs +++ b/logic/GameClass/GameObj/Character/Skill.cs @@ -10,8 +10,6 @@ namespace GameClass.GameObj private readonly object commonSkillLock = new object(); public object ActiveSkillLock => commonSkillLock; - - public bool IsBeingUsed { get; set; } } public class CanBeginToCharge : IActiveSkill { @@ -20,8 +18,6 @@ namespace GameClass.GameObj private readonly object commonSkillLock = new object(); public object ActiveSkillLock => commonSkillLock; - - public bool IsBeingUsed { get; set; } } public class BecomeInvisible : IActiveSkill @@ -31,8 +27,6 @@ namespace GameClass.GameObj private readonly object commonSkillLock = new object(); public object ActiveSkillLock => commonSkillLock; - - public bool IsBeingUsed { get; set; } } public class NuclearWeapon : IActiveSkill // 核武器 @@ -41,8 +35,6 @@ namespace GameClass.GameObj public int DurationTime => GameData.commonSkillTime / 10; private readonly object commonSkillLock = new object(); public object ActiveSkillLock => commonSkillLock; - - public bool IsBeingUsed { get; set; } } public class UseKnife : IActiveSkill @@ -51,8 +43,6 @@ namespace GameClass.GameObj public int DurationTime => GameData.commonSkillTime / 10; private readonly object commonSkillLock = new object(); public object ActiveSkillLock => commonSkillLock; - - public bool IsBeingUsed { get; set; } } public class SuperFast : IActiveSkill // 3倍速 @@ -61,13 +51,19 @@ namespace GameClass.GameObj public int DurationTime => GameData.commonSkillTime / 10 * 4; private readonly object commonSkillLock = new object(); public object ActiveSkillLock => commonSkillLock; + } - public bool IsBeingUsed { get; set; } + public class NullSkill : IActiveSkill + { + public int SkillCD => GameData.commonSkillCD; + public int DurationTime => GameData.commonSkillTime; + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; } public static class SkillFactory { - public static IActiveSkill? FindIActiveSkill(ActiveSkillType activeSkillType) + public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType) { switch (activeSkillType) { @@ -76,7 +72,7 @@ namespace GameClass.GameObj case ActiveSkillType.UseKnife: return new UseKnife(); default: - return null; + return new NullSkill(); } } diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index cf21399..8dfaf05 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -31,7 +31,7 @@ namespace Preparation.Interface public class Assassin : IGhost { - private const int moveSpeed = GameData.basicMoveSpeed / 380 * 473; + private const int moveSpeed = GameData.basicMoveSpeed * 473 / 380; public int MoveSpeed => moveSpeed; private const int maxHp = GameData.basicHp; @@ -65,7 +65,7 @@ namespace Preparation.Interface } public class Teacher : IStudent { - private const int moveSpeed = GameData.basicMoveSpeed / 42 * 36; + private const int moveSpeed = GameData.basicMoveSpeed * 3 / 4; public int MoveSpeed => moveSpeed; private const int maxHp = GameData.basicHp * 10; @@ -79,10 +79,10 @@ namespace Preparation.Interface public List ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.CanBeginToCharge }); public List ListOfIPassiveSkill => new(new PassiveSkillType[] { }); - public const int fixSpeed = GameData.basicFixSpeed / 10 * 6; + public const int fixSpeed = GameData.basicFixSpeed * 6 / 10; public int FixSpeed => fixSpeed; - public const int treatSpeed = GameData.basicTreatSpeed / 10 * 8; + public const int treatSpeed = GameData.basicTreatSpeed * 8 / 10; public int TreatSpeed => treatSpeed; public const double concealment = GameData.basicConcealment * 0.9; @@ -105,10 +105,10 @@ namespace Preparation.Interface } public class Athlete : IStudent { - private const int moveSpeed = GameData.basicMoveSpeed / 38 * 40; + private const int moveSpeed = GameData.basicMoveSpeed * 40 / 38; public int MoveSpeed => moveSpeed; - private const int maxHp = GameData.basicHp / 30 * 32; + private const int maxHp = GameData.basicHp * 32 / 30; public int MaxHp => maxHp; public const int maxBulletNum = 0; @@ -119,10 +119,10 @@ namespace Preparation.Interface public List ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.CanBeginToCharge }); public List ListOfIPassiveSkill => new(new PassiveSkillType[] { }); - public const int fixSpeed = GameData.basicFixSpeed / 10 * 6; + public const int fixSpeed = GameData.basicFixSpeed * 6 / 10; public int FixSpeed => fixSpeed; - public const int treatSpeed = GameData.basicTreatSpeed / 10 * 8; + public const int treatSpeed = GameData.basicTreatSpeed * 8 / 10; public int TreatSpeed => treatSpeed; public const double concealment = GameData.basicConcealment * 0.9; diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index c38663b..c5d7797 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -11,6 +11,5 @@ public int SkillCD { get; } public int DurationTime { get; } //技能持续时间 public object ActiveSkillLock { get; } - public bool IsBeingUsed { get; set; } } } \ No newline at end of file From ae9235a4ebb7503bfbb3fa4fddbaebecc9cf3b8b Mon Sep 17 00:00:00 2001 From: Shawqeem <1004837646@qq.com> Date: Sat, 25 Mar 2023 01:41:13 +0800 Subject: [PATCH 14/15] feat: :art: improve the appearance and the function of status bars improve the appearance and the function of status bars --- logic/Client/StatusBarOfCircumstance.xaml | 15 +- logic/Client/StatusBarOfCircumstance.xaml.cs | 8 +- logic/Client/StatusBarOfHunter.xaml | 37 ++-- logic/Client/StatusBarOfHunter.xaml.cs | 191 ++++++++++++++++--- logic/Client/StatusBarOfSurvivor.xaml | 33 ++-- logic/Client/StatusBarOfSurvivor.xaml.cs | 84 ++++++-- logic/规则Logic.md | 5 +- 7 files changed, 285 insertions(+), 88 deletions(-) diff --git a/logic/Client/StatusBarOfCircumstance.xaml b/logic/Client/StatusBarOfCircumstance.xaml index 849396a..a690fb2 100644 --- a/logic/Client/StatusBarOfCircumstance.xaml +++ b/logic/Client/StatusBarOfCircumstance.xaml @@ -9,20 +9,17 @@ - - + + - - - - - - - + + + + \ No newline at end of file diff --git a/logic/Client/StatusBarOfCircumstance.xaml.cs b/logic/Client/StatusBarOfCircumstance.xaml.cs index 57b7303..2900d5e 100644 --- a/logic/Client/StatusBarOfCircumstance.xaml.cs +++ b/logic/Client/StatusBarOfCircumstance.xaml.cs @@ -31,7 +31,9 @@ namespace Client } public void SetFontSize(double fontsize) { - time.FontSize = scoresofstudents.FontSize = scoresoftrickers.FontSize = status.FontSize = prop.FontSize = fontsize; + status.FontSize = 13 * fontsize / 12; + time.FontSize = 13 * fontsize / 12; + scoresOfStudents.FontSize = scoresOfTrickers.FontSize = fontsize; } public void SetValue(MessageOfAll obj) @@ -63,8 +65,8 @@ namespace Client } status.Text += Convert.ToString(obj.StudentGraduated)+ "\n⚰️: "; status.Text += Convert.ToString(obj.StudentQuited); - scoresofstudents.Text = "Scores of Survivors: " + Convert.ToString(obj.StudentScore); - scoresoftrickers.Text = "Scores of Hunters: " + Convert.ToString(obj.TrickerScore); + scoresOfStudents.Text = "Scores of Students:" + Convert.ToString(obj.StudentScore); + scoresOfTrickers.Text = "Scores of Tricker:" + Convert.ToString(obj.TrickerScore); } } } diff --git a/logic/Client/StatusBarOfHunter.xaml b/logic/Client/StatusBarOfHunter.xaml index 583f442..8536b3a 100644 --- a/logic/Client/StatusBarOfHunter.xaml +++ b/logic/Client/StatusBarOfHunter.xaml @@ -8,21 +8,34 @@ d:DesignHeight="174" d:DesignWidth="180"> - - - - - + + + + + + + - + + + - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/logic/Client/StatusBarOfHunter.xaml.cs b/logic/Client/StatusBarOfHunter.xaml.cs index 23ced7a..23c0f93 100644 --- a/logic/Client/StatusBarOfHunter.xaml.cs +++ b/logic/Client/StatusBarOfHunter.xaml.cs @@ -36,7 +36,7 @@ namespace Client } public void SetFontSize(double fontsize) { - serial.FontSize = scores.FontSize = star.FontSize = status.FontSize = prop.FontSize = fontsize; + serial.FontSize = scores.FontSize = state.FontSize = status.FontSize=activeSkill0.FontSize = activeSkill1.FontSize = activeSkill2.FontSize = prop0.FontSize = prop1.FontSize = prop2.FontSize = prop3.FontSize = fontsize; } private void SetStaticValue(MessageOfTricker obj) @@ -44,58 +44,197 @@ namespace Client switch (obj.TrickerType) // 参数未设定 { case TrickerType.Assassin: - coolTime = 10000; - serial.Text = "👥" + Convert.ToString(1) + "👻" + Convert.ToString(obj.PlayerId) + "\n职业:TrickerType1"; + coolTime0 = coolTime1 = coolTime2 = 10000; + serial.Text = "👥" + Convert.ToString(1) + "👻" + Convert.ToString(obj.PlayerId) + "\n职业:Assassin"; break; case TrickerType._2: - coolTime = 20000; + coolTime0 = coolTime1 = coolTime2 = 20000; serial.Text = "👥" + Convert.ToString(1) + "👻" + Convert.ToString(obj.PlayerId) + "\n职业:TrickerType2"; break; case TrickerType._3: - coolTime = 30000; + coolTime0 = coolTime1 = coolTime2 = 30000; serial.Text = "👥" + Convert.ToString(1) + "👻" + Convert.ToString(obj.PlayerId) + "\n职业:TrickerType3"; break; case TrickerType._4: - coolTime = 40000; + coolTime0 = coolTime1 = coolTime2 = 40000; serial.Text = "👥" + Convert.ToString(1) + "👻" + Convert.ToString(obj.PlayerId) + "\n职业:TrickerType4"; break; case TrickerType.NullTrickerType: - coolTime = 10000; + coolTime0 = coolTime1 = coolTime2 = -1; serial.Text = "👥" + Convert.ToString(1) + "👻" + Convert.ToString(obj.PlayerId) + "\n职业:NullTrickerType"; break; } + activeSkill0.Text = "Skill0"; + activeSkill1.Text = "Skill1"; + activeSkill2.Text = "Skill2"; initialized = true; } private void SetDynamicValue(MessageOfTricker obj) { - if (obj.PlayerState==PlayerState.Stunned) + status.Text = "🏃🏿‍:"+Convert.ToString(obj.Speed); + switch (obj.PlayerState) { - skillprogress.Value = 0; - skillprogress.Background = Brushes.Gray; + case PlayerState.Idle: + state.Text = "Idle"; + break; + case PlayerState.Learning: + state.Text = "Learning"; + break; + case PlayerState.Addicted: + state.Text = "Addicted"; + break; + case PlayerState.Graduated: + state.Text = "Graduated"; + break; + case PlayerState.Quit: + state.Text = "Quit"; + break; + case PlayerState.Treated: + state.Text = "Treated"; + break; + case PlayerState.Rescued: + state.Text = "Rescued"; + break; + case PlayerState.Stunned: + state.Text = "Stunned"; + break; + case PlayerState.Treating: + state.Text = "Treating"; + break; + case PlayerState.Rescuing: + state.Text = "Rescuing"; + break; + case PlayerState.Swinging: + state.Text = "Swinging"; + break; + case PlayerState.Attacking: + state.Text = "Attacking"; + break; + case PlayerState.Locking: + state.Text = "Locking"; + break; + case PlayerState.Rummaging: + state.Text ="Rummaging"; + break; + case PlayerState.Climbing: + state.Text ="Climbing"; + break; + case PlayerState.OpeningAChest: + state.Text = "OpeningAChest"; + break; + case PlayerState.UsingSpecialSkill: + state.Text = "UsingSpecialSkill"; + break; + case PlayerState.OpeningAGate: + state.Text = "OpeningAGate"; + break; + default: + break; + } + scores.Text = "Scores:" + Convert.ToString(obj.Score); + if (obj.TimeUntilSkillAvailable[0] >= 0) + skillprogress0.Value = 100 - obj.TimeUntilSkillAvailable[0] / coolTime0 * 100; + if (obj.TimeUntilSkillAvailable[1] >= 0) + skillprogress1.Value = 100 - obj.TimeUntilSkillAvailable[1] / coolTime1 * 100; + if (obj.TimeUntilSkillAvailable[2] >= 0) + skillprogress2.Value = 100 - obj.TimeUntilSkillAvailable[2] / coolTime2 * 100; + if (obj.PlayerState == PlayerState.Quit) + { + skillprogress0.Value = skillprogress1.Value = skillprogress2.Value = 0; + skillprogress0.Background = skillprogress1.Background = skillprogress2.Background = Brushes.Gray; } else - skillprogress.Background = Brushes.White; - // star.Text = "⭐:";不知道要放什么 - status.Text = "🏹:" + Convert.ToString(1) + "\n🏃:" + Convert.ToString(obj.Speed) + "\n🤺:" + Convert.ToString(2) + "\n🗡:" + Convert.ToString(0); - scores.Text = "Scores:" + Convert.ToString(0); - foreach(var icon in obj.Prop) + skillprogress0.Background = skillprogress1.Background = skillprogress2.Background = Brushes.White; + int cnt = 0; + foreach (var icon in obj.Prop) { - switch (icon) + switch (cnt) { - case PropType.Key3: - prop.Text = "🔧"; + case 0: + switch (icon) + { + case PropType.Key3: + prop0.Text = "🔧"; + break; + case PropType.Key5: + prop0.Text = "🛡"; + break; + case PropType.Key6: + prop0.Text = "♥"; + break; + case PropType.Ptype4: + prop0.Text = "⛸"; + break; + default: + prop0.Text = " "; + break; + } + cnt++; break; - case PropType.Key5: - prop.Text = "🛡"; + case 1: + switch (icon) + { + case PropType.Key3: + prop1.Text = "🔧"; + break; + case PropType.Key5: + prop1.Text = "🛡"; + break; + case PropType.Key6: + prop1.Text = "♥"; + break; + case PropType.Ptype4: + prop1.Text = "⛸"; + break; + default: + prop1.Text = " "; + break; + } + cnt++; break; - case PropType.Key6: - prop.Text = "♥"; + case 2: + switch (icon) + { + case PropType.Key3: + prop2.Text = "🔧"; + break; + case PropType.Key5: + prop2.Text = "🛡"; + break; + case PropType.Key6: + prop2.Text = "♥"; + break; + case PropType.Ptype4: + prop2.Text = "⛸"; + break; + default: + prop2.Text = " "; + break; + } + cnt++; break; - case PropType.Ptype4: - prop.Text = "⛸"; + case 3: + switch (icon) + { + case PropType.Key3: + prop3.Text = "🔧"; + break; + case PropType.Key5: + prop3.Text = "🛡"; + break; + case PropType.Key6: + prop3.Text = "♥"; + break; + case PropType.Ptype4: + prop3.Text = "⛸"; + break; + default: + prop3.Text = " "; + break; + } + cnt++; break; default: - prop.Text = " "; break; } } @@ -106,7 +245,7 @@ namespace Client SetStaticValue(obj); SetDynamicValue(obj); } - private int coolTime; + private int coolTime0, coolTime1, coolTime2; private bool initialized; } } diff --git a/logic/Client/StatusBarOfSurvivor.xaml b/logic/Client/StatusBarOfSurvivor.xaml index 3fd8ed4..a21c559 100644 --- a/logic/Client/StatusBarOfSurvivor.xaml +++ b/logic/Client/StatusBarOfSurvivor.xaml @@ -11,9 +11,10 @@ - - - + + + + @@ -22,18 +23,18 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/logic/Client/StatusBarOfSurvivor.xaml.cs b/logic/Client/StatusBarOfSurvivor.xaml.cs index 8b35d13..d2bd725 100644 --- a/logic/Client/StatusBarOfSurvivor.xaml.cs +++ b/logic/Client/StatusBarOfSurvivor.xaml.cs @@ -35,60 +35,103 @@ namespace Client private void SetStaticValue(MessageOfStudent obj) { - switch (obj.StudentType) // 参数未设定 + switch (obj.StudentType) // coolTime参数未设定, { case StudentType.Athlete: - coolTime = 10000; - serial.Text = "👥" + Convert.ToString(2) + "🧓" + Convert.ToString(obj.PlayerId) + "\n职业:StudentType1"; + coolTime0 = coolTime1 = coolTime2 = 10000; + serial.Text = "👥" + Convert.ToString(2) + "🧓" + Convert.ToString(obj.PlayerId) + "\n职业:Athlete"; break; case StudentType._2: - coolTime = 20000; + coolTime0 = coolTime1 = coolTime2 = 20000; serial.Text = "👥" + Convert.ToString(2) + "🧓" + Convert.ToString(obj.PlayerId) + "\n职业:StudentType2"; break; case StudentType._3: - coolTime = 30000; + coolTime0 = coolTime1 = coolTime2 = 30000; serial.Text = "👥" + Convert.ToString(2) + "🧓" + Convert.ToString(obj.PlayerId) + "\n职业:StudentType3"; break; case StudentType._4: - coolTime = 40000; + coolTime0 = coolTime1 = coolTime2 = 40000; serial.Text = "👥" + Convert.ToString(2) + "🧓" + Convert.ToString(obj.PlayerId) + "\n职业:StudentType4"; break; case StudentType.NullStudentType: - coolTime = 10000; + coolTime0 = coolTime1 = coolTime2 = -1; serial.Text = "👥" + Convert.ToString(2) + "🧓" + Convert.ToString(obj.PlayerId) + "\n职业:NullStudentType"; break; } + activeSkill0.Text = "Skill0"; + activeSkill1.Text = "Skill1"; + activeSkill2.Text = "Skill2"; initialized = true; } private void SetDynamicValue(MessageOfStudent obj) { - int life; + int life= obj.Determination,death=obj.Addiction; switch(obj.PlayerState) { case PlayerState.Idle: - life = obj.Determination; - status.Text = "♥:" + Convert.ToString(life); + status.Text = "♥:" + Convert.ToString(life)+"\nIdle"; + break; + case PlayerState.Learning: + status.Text = "♥:" + Convert.ToString(life)+ "\nLearning"; break; case PlayerState.Addicted: - life = obj.Addiction; - status.Text = "💀:" + Convert.ToString(life); + status.Text = "💀:" + Convert.ToString(death)+ "\nAddicted"; break; case PlayerState.Graduated: - status.Text = "Graduated"; + status.Text = status.Text = "♥" + "\nGraduated"; break; case PlayerState.Quit: - status.Text = "Quit"; + status.Text = "💀"+"\nQuit"; + break; + case PlayerState.Treated: + status.Text = "♥:" + Convert.ToString(life) + "\nTreated"; + break; + case PlayerState.Rescued: + status.Text = "💀:" + Convert.ToString(death)+ "\nRescued"; + break; + case PlayerState.Stunned: + status.Text = "♥:" + Convert.ToString(life) + "\nStunned"; + break; + case PlayerState.Treating: + status.Text = "♥:" + Convert.ToString(life) + "\nTreating"; + break; + case PlayerState.Rescuing: + status.Text = "♥:" + Convert.ToString(life) + "\nRescuing"; + break; + case PlayerState.Swinging: + status.Text = "♥:" + Convert.ToString(life) + "\nSwinging"; + break; + case PlayerState.Attacking: + status.Text = "♥:" + Convert.ToString(life) + "\nAttacking"; + break; + case PlayerState.Locking: + status.Text = "♥:" + Convert.ToString(life) + "\nLocking"; + break; + case PlayerState.Rummaging: + status.Text = "♥:" + Convert.ToString(life) + "\nRummaging"; + break; + case PlayerState.Climbing: + status.Text = "♥:" + Convert.ToString(life) + "\nClimbing"; + break; + case PlayerState.OpeningAChest: + status.Text = "♥:" + Convert.ToString(life) + "\nOpeningAChest"; + break; + case PlayerState.UsingSpecialSkill: + status.Text = "♥:" + Convert.ToString(life) + "\nUsingSpecialSkill"; + break; + case PlayerState.OpeningAGate: + status.Text = "♥:" + Convert.ToString(life) + "\nOpeningAGate"; break; default: break; - }//不完全 + } scores.Text = "Scores:" + obj.Score; if (obj.TimeUntilSkillAvailable[0]>=0) - skillprogress0.Value = 100 - obj.TimeUntilSkillAvailable[0] / coolTime * 100; + skillprogress0.Value = 100 - obj.TimeUntilSkillAvailable[0] / coolTime0 * 100; if(obj.TimeUntilSkillAvailable[1] >= 0) - skillprogress1.Value = 100 - obj.TimeUntilSkillAvailable[1] / coolTime * 100; + skillprogress1.Value = 100 - obj.TimeUntilSkillAvailable[1] / coolTime1 * 100; if(obj.TimeUntilSkillAvailable[2] >= 0) - skillprogress2.Value = 100 - obj.TimeUntilSkillAvailable[2] / coolTime * 100; + skillprogress2.Value = 100 - obj.TimeUntilSkillAvailable[2] / coolTime2 * 100; if (obj.PlayerState == PlayerState.Quit) { skillprogress0.Value = skillprogress1.Value = skillprogress2.Value = 0; @@ -187,8 +230,7 @@ namespace Client break; default: break; - } - + } } } public void SetValue(MessageOfStudent obj) @@ -197,7 +239,7 @@ namespace Client SetStaticValue(obj); SetDynamicValue(obj); } - private int coolTime; + private int coolTime0, coolTime1, coolTime2; private bool initialized; } } diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 2a8004c..27a8fee 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -304,7 +304,10 @@ #### 伤害得分 [Tricker对Student造成伤害时,得伤害*100/基本伤害(1500000)分。] -#### *[使用道具/技能得分——需要造成一定效果才能获取分数,仅使用不得分]* +#### *[使用道具/技能得分]* + +——需要造成一定效果才能获取分数,仅使用不得分 + - 不同道具/技能有不同得分 #### 沉迷 From dca582650cb283fba597399c19dbeae1a4265b1e Mon Sep 17 00:00:00 2001 From: Shawqeem <1004837646@qq.com> Date: Sat, 25 Mar 2023 02:35:35 +0800 Subject: [PATCH 15/15] feat: :art: complete drawMap function complete drawMap function --- logic/Client/MainWindow.xaml.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/logic/Client/MainWindow.xaml.cs b/logic/Client/MainWindow.xaml.cs index 50257a3..5113482 100644 --- a/logic/Client/MainWindow.xaml.cs +++ b/logic/Client/MainWindow.xaml.cs @@ -300,6 +300,20 @@ namespace Client } } break;//emergency + case 11: + mapPatches[i, j].Fill = Brushes.Gray; + mapPatches[i, j].Stroke = Brushes.Gray; + break;//window + case 12: + case 13: + case 14: + mapPatches[i, j].Fill = Brushes.Khaki; + mapPatches[i, j].Stroke = Brushes.Khaki; + break;//door + case 15: + mapPatches[i, j].Fill = Brushes.Orange; + mapPatches[i, j].Stroke = Brushes.Orange; + break;//chest default: break; } @@ -767,7 +781,7 @@ namespace Client UpperLayerOfMap.Children.Add(icon); break; } - /* case BulletType.LineBullet: + /*case BulletType.LineBullet: { double bombRange = data.BombRange / 1000; DrawLaser(new Point(data.Y * unitWidth / 1000.0, data.X * unitHeight / 1000.0), -data.FacingDirection + Math.PI / 2, bombRange * unitHeight, 0.5 * unitWidth); @@ -848,11 +862,11 @@ namespace Client }; if (data.IsOpen) { - icon.Text = Convert.ToString("1"); + icon.Text = Convert.ToString("开"); } else { - icon.Text = Convert.ToString("0"); + icon.Text = Convert.ToString("闭"); } UpperLayerOfMap.Children.Add(icon); }