diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 0040e5f..31c19e5 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -61,6 +61,7 @@ namespace GameClass.GameObj this.CanMove = true; this.score = 0; this.buffManager = new BuffManager(); + Debugger.Output(this, characterType.ToString()); switch (characterType) { case CharacterType.Assassin: diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 0f79450..a836e43 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -373,8 +373,8 @@ namespace GameClass.GameObj /// /// 角色所属队伍ID /// - private long teamID = long.MaxValue; - public long TeamID + private int teamID = int.MaxValue; + public int TeamID { get => teamID; set @@ -386,8 +386,8 @@ namespace GameClass.GameObj } } } - private long playerID = long.MaxValue; - public long PlayerID + private int playerID = int.MaxValue; + public int PlayerID { get => playerID; set diff --git a/logic/GameClass/GameObj/Character/Skill.cs b/logic/GameClass/GameObj/Character/Skill.cs index e83d9c1..af45952 100644 --- a/logic/GameClass/GameObj/Character/Skill.cs +++ b/logic/GameClass/GameObj/Character/Skill.cs @@ -91,6 +91,20 @@ namespace GameClass.GameObj } } + public class UseRobot : IActiveSkill + { + public int SkillCD => 0; + public int DurationTime => 0; + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + + public bool isBeingUsed = false; + public bool IsBeingUsed + { + get => isBeingUsed; set => isBeingUsed = value; + } + } + public class WriteAnswers : IActiveSkill { public int SkillCD => GameData.commonSkillCD; @@ -110,6 +124,32 @@ namespace GameClass.GameObj } } } + public bool isBeingUsed = false; + public bool IsBeingUsed + { + get => isBeingUsed; set => isBeingUsed = value; + } + } + + public class SummonGolem : IActiveSkill + { + public int SkillCD => GameData.commonSkillCD; + public int DurationTime => 0; + private readonly object commonSkillLock = new object(); + public object ActiveSkillLock => commonSkillLock; + + private Golem? golemSummoned = null; + public Golem? GolemSummoned + { + get => golemSummoned; + set + { + lock (commonSkillLock) + { + golemSummoned = value; + } + } + } public bool isBeingUsed = false; public bool IsBeingUsed @@ -152,6 +192,8 @@ namespace GameClass.GameObj return new JumpyBomb(); case ActiveSkillType.WriteAnswers: return new WriteAnswers(); + case ActiveSkillType.SummonGolem: + return new SummonGolem(); default: return new NullSkill(); } @@ -175,6 +217,8 @@ namespace GameClass.GameObj return ActiveSkillType.JumpyBomb; case WriteAnswers: return ActiveSkillType.WriteAnswers; + case SummonGolem: + return ActiveSkillType.SummonGolem; default: return ActiveSkillType.Null; } diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index 3b5d9b1..3aaa3a9 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -119,6 +119,38 @@ namespace GameClass.GameObj } return player; } + public Character? FindPlayerToAction(long playerID) + { + Character? player = null; + gameObjLockDict[GameObjType.Character].EnterReadLock(); + try + { + foreach (Character person in gameObjDict[GameObjType.Character]) + { + if (playerID == person.ID) + { + if (person.CharacterType == CharacterType.TechOtaku && person.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed) + { + foreach (Character character in gameObjDict[GameObjType.Character]) + { + if (playerID + GameData.numOfPeople == character.ID) + { + player = character; + break; + } + } + } + else player = person; + break; + } + } + } + finally + { + gameObjLockDict[GameObjType.Character].ExitReadLock(); + } + return player; + } public bool Remove(GameObj gameObj) { bool flag = false; diff --git a/logic/GameEngine/CollisionChecker.cs b/logic/GameEngine/CollisionChecker.cs index 82802c5..43298ba 100644 --- a/logic/GameEngine/CollisionChecker.cs +++ b/logic/GameEngine/CollisionChecker.cs @@ -7,46 +7,33 @@ namespace GameEngine { internal class CollisionChecker { - /// - /// 碰撞检测,如果这样行走是否会与之碰撞,返回与之碰撞的物体 - /// - /// 移动的物体 - /// 移动的位移向量 - /// 和它碰撞的物体 - public IGameObj? CheckCollision(IMoveable obj, XY moveVec) + public IGameObj? CheckCollision(IMoveable obj, XY Pos) { - XY nextPos = obj.Position + moveVec; - if (!obj.IsRigid) - { - if (gameMap.IsOutOfBound(obj)) - return gameMap.GetOutOfBound(nextPos); - return null; - } // 在列表中检查碰撞 Func, ReaderWriterLockSlim, IGameObj?> CheckCollisionInList = (IEnumerable lst, ReaderWriterLockSlim listLock) => - { - IGameObj? collisionObj = null; - listLock.EnterReadLock(); - try { - foreach (var listObj in lst) + IGameObj? collisionObj = null; + listLock.EnterReadLock(); + try { - if (obj.WillCollideWith(listObj, nextPos)) + foreach (var listObj in lst) { - collisionObj = listObj; - break; + if (obj.WillCollideWith(listObj, Pos)) + { + collisionObj = listObj; + break; + } } } - } - finally - { - listLock.ExitReadLock(); - } - return collisionObj; - }; + finally + { + listLock.ExitReadLock(); + } + return collisionObj; + }; - IGameObj? collisionObj = null; + IGameObj? collisionObj; foreach (var list in lists) { if ((collisionObj = CheckCollisionInList(list.Item1, list.Item2)) != null) @@ -58,6 +45,23 @@ namespace GameEngine return null; } /// + /// 碰撞检测,如果这样行走是否会与之碰撞,返回与之碰撞的物体 + /// + /// 移动的物体 + /// 移动的位移向量 + /// 和它碰撞的物体 + public IGameObj? CheckCollisionWhenMoving(IMoveable obj, XY moveVec) + { + XY nextPos = obj.Position + moveVec; + if (!obj.IsRigid) + { + if (gameMap.IsOutOfBound(obj)) + return gameMap.GetOutOfBound(nextPos); + return null; + } + return CheckCollision(obj, nextPos); + } + /// /// /// 可移动物体(圆)向矩形物体移动时,可移动且不会碰撞的最大距离。直接用double计算,防止误差 /// /// diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs index 020c6e4..795460e 100644 --- a/logic/GameEngine/MoveEngine.cs +++ b/logic/GameEngine/MoveEngine.cs @@ -33,6 +33,12 @@ namespace GameEngine return PlaceType.Null; } } + + public IGameObj? CheckCollision(IMoveable obj, XY Pos) + { + return collisionChecker.CheckCollision(obj, Pos); + } + private readonly CollisionChecker collisionChecker; private readonly Func OnCollision; /// @@ -65,7 +71,7 @@ namespace GameEngine XY nextPos = obj.Position + moveVec; double maxLen = collisionChecker.FindMax(obj, nextPos, moveVec); maxLen = Math.Min(maxLen, obj.MoveSpeed / GameData.numOfStepPerSecond); - obj.MovingSetPos(new XY(moveVec.Angle(), maxLen), GetPlaceType(nextPos)); + obj.MovingSetPos(new XY(moveVec, maxLen), GetPlaceType(nextPos)); } public void MoveObj(IMoveable obj, int moveTime, double direction) @@ -98,7 +104,7 @@ namespace GameEngine do { flag = false; - collisionObj = collisionChecker.CheckCollision(obj, res); + collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res); if (collisionObj == null) break; @@ -135,7 +141,7 @@ namespace GameEngine { moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell; res = new XY(direction, moveVecLength); - if ((collisionObj = collisionChecker.CheckCollision(obj, res)) == null) + if ((collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res)) == null) { obj.MovingSetPos(res, GetPlaceType(obj.Position + res)); } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 165b05f..5955ecf 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -375,7 +375,7 @@ namespace Gaming loopToDo: () => { }, timeInterval: GameData.frameDuration, finallyReturn: () => 0, - maxTotalDuration: (int)((windowToPlayer + windowForClimb.Position - player.Position).Length() / player.MoveSpeed) + maxTotalDuration: (int)((windowToPlayer + windowForClimb.Position - player.Position).Length() * 1000 / player.MoveSpeed) ) .Start(); if (player.PlayerState != PlayerStateType.ClimbingThroughWindows) @@ -386,13 +386,13 @@ namespace Gaming player.ReSetPos(windowToPlayer + windowForClimb.Position, PlaceType.Window); player.MoveSpeed = player.SpeedOfClimbingThroughWindows; - MovePlayer(player, (int)(windowToPlayer.Length() * 3.0 / player.MoveSpeed), (-1 * windowToPlayer).Angle()); + MovePlayer(player, (int)(windowToPlayer.Length() * 3.0 * 1000 / player.MoveSpeed), (-1 * windowToPlayer).Angle()); new FrameRateTaskExecutor( loopCondition: () => player.PlayerState == PlayerStateType.ClimbingThroughWindows && player.IsMoving && gameMap.Timer.IsGaming, loopToDo: () => { }, timeInterval: GameData.frameDuration, finallyReturn: () => 0, - maxTotalDuration: (int)(windowToPlayer.Length() * 3.0 / player.MoveSpeed) + maxTotalDuration: (int)(windowToPlayer.Length() * 3.0 * 1000 / player.MoveSpeed) ) .Start(); XY PosJumpOff = windowForClimb.Position - 2 * windowToPlayer; @@ -497,7 +497,7 @@ namespace Gaming */ private readonly Map gameMap; - private readonly MoveEngine moveEngine; + public readonly MoveEngine moveEngine; public ActionManager(Map gameMap) { this.gameMap = gameMap; diff --git a/logic/Gaming/CharacterManager .cs b/logic/Gaming/CharacterManager .cs index 1f7e867..0f404da 100644 --- a/logic/Gaming/CharacterManager .cs +++ b/logic/Gaming/CharacterManager .cs @@ -287,7 +287,15 @@ namespace Gaming gameMap.Add(prop); } } - if (player.CharacterType == CharacterType.Robot) return; + if (player.CharacterType == CharacterType.Robot) + { + if (((Golem)player).Parent != null && ((Golem)player).Parent.CharacterType == CharacterType.TechOtaku) + { + ((SummonGolem)player.FindIActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned = null; + player.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false; + } + return; + } ++gameMap.NumOfDeceasedStudent; if (GameData.numOfStudent - gameMap.NumOfDeceasedStudent - gameMap.NumOfEscapedStudent == 1) { diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 8db79ed..3ff184c 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -77,7 +77,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { bool res = actionManager.MovePlayer(player, moveTimeInMilliseconds, angle); @@ -100,7 +100,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - ICharacter? player = gameMap.FindPlayer(playerID); + ICharacter? player = gameMap.FindPlayerToAction(playerID); if (playerTreatedID == -1) { if (player != null && !player.IsGhost()) @@ -121,7 +121,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - ICharacter? player = gameMap.FindPlayer(playerID); + ICharacter? player = gameMap.FindPlayerToAction(playerID); if (playerRescuedID == -1) { if (player != null && !player.IsGhost()) @@ -143,7 +143,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - ICharacter? player = gameMap.FindPlayer(playerID); + ICharacter? player = gameMap.FindPlayerToAction(playerID); if (player != null && !player.IsGhost()) return actionManager.Fix((Student)player); return false; @@ -152,7 +152,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - ICharacter? player = gameMap.FindPlayer(playerID); + ICharacter? player = gameMap.FindPlayerToAction(playerID); if (player != null) { if (!player.IsGhost()) @@ -164,7 +164,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { return ActionManager.Stop(player); @@ -175,7 +175,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null && !player.IsGhost()) { return actionManager.OpenDoorway((Student)player); @@ -186,7 +186,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { return actionManager.OpenChest(player); @@ -197,7 +197,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { return actionManager.ClimbingThroughWindow(player); @@ -208,7 +208,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { return actionManager.LockOrOpenDoor(player); @@ -219,7 +219,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { _ = attackManager.Attack(player, angle); @@ -229,7 +229,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { PropManager.UseProp(player, propType); @@ -239,7 +239,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { propManager.ThrowProp(player, propType); @@ -249,7 +249,7 @@ namespace Gaming { if (!gameMap.Timer.IsGaming) return false; - Character? player = gameMap.FindPlayer(playerID); + Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { return propManager.PickProp(player, propType); diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index d31fc36..1fc3dad 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -186,7 +186,7 @@ namespace Gaming { gameMap.GameObjLockDict[GameObjType.Chest].ExitWriteLock(); } - + /* new Thread ( () => @@ -208,6 +208,7 @@ namespace Gaming } ) { IsBackground = true }.Start(); + */ } public PropManager(Map gameMap) // 道具不能扔过墙 { diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index e03d4c5..d247cd5 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -11,20 +11,6 @@ namespace Gaming { private partial class SkillManager { - public bool BecomeVampire(Character player) - { - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.BecomeVampire), player, () => - { - player.Vampire += 0.5; - Debugger.Output(player, "becomes vampire!"); - }, - () => - { - double tempVam = player.Vampire - 0.5; - player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam; - }); - } - public bool CanBeginToCharge(Character player) { @@ -42,9 +28,9 @@ namespace Gaming { }); } - public static bool BecomeInvisible(Character player) { + if ((!player.Commandable())) return false; IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.BecomeInvisible); return ActiveSkillEffect(activeSkill, player, () => { @@ -55,6 +41,14 @@ namespace Gaming { }); } + public static bool UseRobot(Character player) + { + if ((!player.Commandable()) || ((SummonGolem)player.FindIActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned == null) return false; + IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.UseRobot); + activeSkill.IsBeingUsed = (activeSkill.IsBeingUsed) ? false : true; + return true; + } + public bool JumpyBomb(Character player) { return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.JumpyBomb), player, () => @@ -68,6 +62,7 @@ namespace Gaming public bool WriteAnswers(Character player) { + if ((!player.Commandable())) return false; IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.WriteAnswers); return ActiveSkillEffect(activeSkill, player, () => { @@ -83,6 +78,22 @@ namespace Gaming { }); } + public bool SummonGolem(Character player) + { + if ((!player.Commandable())) return false; + IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.SummonGolem); + if (((SummonGolem)activeSkill).GolemSummoned != null) return false; + XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2); + if (actionManager.moveEngine.CheckCollision(player, res) != null) + return false; + + return ActiveSkillEffect(activeSkill, player, () => + { + characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player); + }, + () => + { }); + } public static bool UseKnife(Character player) { @@ -97,6 +108,7 @@ namespace Gaming public bool Howl(Character player) { + if ((!player.Commandable())) return false; return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Howl), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); @@ -125,6 +137,7 @@ namespace Gaming public bool Punish(Character player) { + if ((!player.Commandable())) return false; return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Punish), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); @@ -153,18 +166,6 @@ namespace Gaming { }); } - public bool SuperFast(Character player) - { - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.SuperFast), player, () => - { - player.AddMoveSpeed(player.FindIActiveSkill(ActiveSkillType.SuperFast).DurationTime, 3.0); - Debugger.Output(player, "moves very fast!"); - }, - () => - { }); - } - - public static bool ActiveSkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) { lock (activeSkill.ActiveSkillLock) diff --git a/logic/Gaming/SkillManager/SkillManager.cs b/logic/Gaming/SkillManager/SkillManager.cs index b676d16..365f3de 100644 --- a/logic/Gaming/SkillManager/SkillManager.cs +++ b/logic/Gaming/SkillManager/SkillManager.cs @@ -37,6 +37,9 @@ namespace Gaming case ActiveSkillType.WriteAnswers: WriteAnswers(character); break; + case ActiveSkillType.SummonGolem: + SummonGolem(character); + break; default: return false; } diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index a40d280..4f69fba 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -5,7 +5,7 @@ namespace Preparation.Interface { public interface ICharacter : IGameObj { - public long TeamID { get; } + public int TeamID { get; } public int HP { get; set; } public int Score { get; } public void AddScore(int add); diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index 0a1d07f..8466e23 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -295,7 +295,7 @@ namespace Preparation.Interface public BulletType InitBullet => BulletType.Null; - public List ListOfIActiveSkill => new(new ActiveSkillType[] { }); + public List ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.SummonGolem, ActiveSkillType.UseRobot }); public List ListOfIPassiveSkill => new(new PassiveSkillType[] { }); public const int fixSpeed = (int)(GameData.basicFixSpeed * 1.1); diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 8defceb..4928265 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -89,12 +89,13 @@ namespace Preparation.Utility BecomeInvisible = 1, BecomeVampire = 2, JumpyBomb = 3, - SuperFast = 4, + SummonGolem = 4, UseKnife = 5, CanBeginToCharge = 6, Punish = 7, WriteAnswers = 8, Howl = 9, + UseRobot = 10, } public enum PassiveSkillType { diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 1deaaef..e4b94b3 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -16,6 +16,9 @@ namespace Preparation.Utility public const int MinSpeed = 1; // 最小速度 public const int MaxSpeed = int.MaxValue; // 最大速度 + + public const int numOfStudent = 4; + public const int numOfPeople = 5; #endregion #region 地图相关 public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 @@ -24,7 +27,7 @@ namespace Preparation.Utility public const int cols = 50; // 列数 public const int numOfBirthPoint = 5; - public const int numOfGenerator = 9; + public const int numOfGenerator = 10; public const int numOfChest = 8; public static bool IsMap(GameObjType gameObjType) @@ -77,7 +80,6 @@ namespace Preparation.Utility } #endregion #region 角色相关 - public const int numOfStudent = 4; public const int characterRadius = numOfPosGridPerCell * 4 / 10; // 人物半径 public const int basicTreatSpeed = 100; diff --git a/logic/cmd/gameServer.cmd b/logic/cmd/gameServer.cmd index 1cf4d77..4eb0cdf 100644 --- a/logic/cmd/gameServer.cmd +++ b/logic/cmd/gameServer.cmd @@ -12,6 +12,6 @@ start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --ch ping -n 2 127.0.0.1 > NUL -start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --characterID 1 --type 1 --occupation 3 +start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --characterID 1 --type 1 --occupation 5 ping -n 2 127.0.0.1 > NUL \ No newline at end of file diff --git a/logic/规则Logic.md b/logic/规则Logic.md index 0daa84f..bc871df 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -208,7 +208,7 @@ - 在指令仍在进行时,重复发出同一类型的交互指令是无效的,你需要先发出Stop指令终止进行的指令 ### 破译与逃脱 -- 每张地图都会刷新 9台电机,求生者需要破译其中的7台,并开启任意一个大门后从任意一个开启的大门- 逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱; +- 每张地图都有10台电机,求生者需要破译其中的7台,并开启任意一个大门后从任意一个开启的大门- 逃脱,亦或者在只剩1名求生者的情况下从紧急出口逃脱; - 求生者和监管者在靠近电机时,可以看到电机的破译进度条。 - 紧急出口会在电机破译完成3台的情况下在地图的3-5个固定紧急出口刷新点之一随机刷新。 - 当求生者只剩1名时,紧急出口盖将会自动打开,该求生者可从紧急出口逃脱。