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 1/5] 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 2/5] 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 3/5] 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 4/5] 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 5/5] 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秒。 -- *不能两人同时救一个人* +- 不能两人同时救一个人