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; // 检查位置标志、补充子弹的帧时长