| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -13,6 +13,28 @@ namespace GameClass.GameObj | |||
| private readonly Dictionary<uint, XY> birthPointList; // 出生点列表 | |||
| public Dictionary<uint, XY> 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<GameObjType, IList<IGameObj>> gameObjDict; | |||
| public Dictionary<GameObjType, IList<IGameObj>> GameObjDict => gameObjDict; | |||
| private Dictionary<GameObjType, ReaderWriterLockSlim> gameObjLockDict; | |||
| @@ -31,7 +53,6 @@ namespace GameClass.GameObj | |||
| return PlaceType.Null; | |||
| } | |||
| } | |||
| public PlaceType GetPlaceType(XY pos) | |||
| { | |||
| try | |||
| @@ -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) | |||
| @@ -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) | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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; // 检查位置标志、补充子弹的帧时长 | |||