diff --git a/docs/游戏机制与平衡性调整更新草案.md b/docs/游戏机制与平衡性调整更新草案.md index 3078a65..66dec27 100644 --- a/docs/游戏机制与平衡性调整更新草案.md +++ b/docs/游戏机制与平衡性调整更新草案.md @@ -80,7 +80,8 @@ v1.6 - 新造的Robot的PlayerId的n总是尽量小 1. UseRobot - CD:2s,持续时间:0s - - 输入额外参数PlayerID,切换到要使用的角色 + - 输入额外参数PlayerID,切换到要使用的角色。 + - 切换到其他角色时,自己进入UsingSkill状态。 修改后: diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index e879d5e..f7e6597 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -448,7 +448,7 @@ namespace GameClass.GameObj lock (actionLock) { PlayerStateType nowPlayerState = PlayerState; - if (nowPlayerState == value) return -1; + if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1; switch (nowPlayerState) { case PlayerStateType.Escaped: @@ -542,16 +542,24 @@ namespace GameClass.GameObj ThreadNum.Release(); } case PlayerStateType.UsingSkill: - if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith)) + if (CharacterType == CharacterType.TechOtaku) { - try + if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith)) { - ((CraftingBench)whatInteractingWith!).StopSkill(); - return ChangePlayerState(value, gameObj); + try + { + ((CraftingBench)whatInteractingWith!).StopSkill(); + return ChangePlayerState(value, gameObj); + } + finally + { + ThreadNum.Release(); + } } - finally + else { - ThreadNum.Release(); + if (value != PlayerStateType.UsingSkill) + ((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID; } } return ChangePlayerState(value, gameObj); diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 9c47b94..987200f 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -61,7 +61,7 @@ namespace Gaming return true; } - public bool Stop(Character player) + public static bool Stop(Character player) { lock (player.ActionLock) { diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs index f7a3f19..614d6bf 100644 --- a/logic/Gaming/CharacterManager.cs +++ b/logic/Gaming/CharacterManager.cs @@ -383,7 +383,15 @@ namespace Gaming if (parent != null && parent.CharacterType == CharacterType.TechOtaku) { ((SummonGolem)(parent.FindActiveSkill(ActiveSkillType.SummonGolem))).DeleteGolem((int)(player.PlayerID - parent.PlayerID) / GameData.numOfPeople - 1); - //player.FindActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false; + UseRobot useRobot = (UseRobot)parent.FindActiveSkill(ActiveSkillType.UseRobot); + if (useRobot.TryResetNowPlayerID((int)player.PlayerID)) + { + lock (parent.ActionLock) + { + if (parent.PlayerState == PlayerStateType.UsingSkill) + parent.SetPlayerState(); + } + } } return; } diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 8a973c9..a76ac2a 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -160,7 +160,7 @@ namespace Gaming Character? player = gameMap.FindPlayerToAction(playerID); if (player != null) { - return actionManager.Stop(player); + return ActionManager.Stop(player); } return false; } diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index eca57f3..3e4391c 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -104,17 +104,39 @@ namespace Gaming { }); } - public bool UseRobot(Character player) + public bool UseRobot(Character player, int robotID) { - /* - IGolem? golem = (IGolem?)(((SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned); - if ((!player.Commandable()) || ((SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned == null) return false; - Debugger.Output(player, "use robot!"); - IActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.UseRobot); - activeSkill.IsBeingUsed = (activeSkill.IsBeingUsed) ? false : true; - if (activeSkill.IsBeingUsed) player.SetPlayerState(PlayerStateType.UsingSkill); - else player.SetPlayerState();*/ - return true; + if ((robotID - player.PlayerID) % GameData.numOfPeople != 0) return false; + if ((robotID - (int)player.PlayerID) / GameData.numOfPeople < 0 || (robotID - (int)player.PlayerID) / GameData.numOfPeople > GameData.maxSummonedGolemNum) return false; + UseRobot activeSkill = (UseRobot)player.FindActiveSkill(ActiveSkillType.UseRobot); + lock (activeSkill.ActiveSkillUseLock) + { + if (robotID == player.PlayerID) + { + lock (player.ActionLock) + { + if (player.PlayerState == PlayerStateType.UsingSkill && player.WhatInteractingWith == null) + player.SetPlayerStateNaturally(); + activeSkill.NowPlayerID = robotID; + } + } + else + { + SummonGolem summonGolemSkill = (SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem); + if (summonGolemSkill.GolemStateArray[(robotID - (int)player.PlayerID) / GameData.numOfPeople - 1] == 2) + { + activeSkill.NowPlayerID = robotID; + } + else return false; + long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill); + if (stateNum == -1) + { + activeSkill.NowPlayerID = (int)player.PlayerID; + return false; + } + } + return ActiveSkillEffect(activeSkill, player, () => { }, () => { }); + } } public static bool JumpyBomb(Character player) @@ -151,61 +173,61 @@ namespace Gaming public bool SummonGolem(Character player) { ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem); - int num = ((SummonGolem)activeSkill).AddGolem(); + int num = ((SummonGolem)activeSkill).BuildGolem(); if (num >= GameData.maxSummonedGolemNum) return false; - Debugger.Output(player, num.ToString()); XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2); - CraftingBench craftingBench = new(res, player, num); - - long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill, craftingBench); - if (stateNum == -1) + lock (activeSkill.ActiveSkillUseLock) { - ((SummonGolem)activeSkill).DeleteGolem(num); - return false; - } + CraftingBench craftingBench = new(res, player, num); - player.ThreadNum.WaitOne(); - if (stateNum != player.StateNum) - { - ((SummonGolem)activeSkill).DeleteGolem(num); - player.ThreadNum.Release(); - return false; - } + long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill, craftingBench); + if (stateNum == -1) + { + ((SummonGolem)activeSkill).DeleteGolem(num); + return false; + } - if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null) - { - ((SummonGolem)activeSkill).DeleteGolem(num); - player.ThreadNum.Release(); - return false; - } - craftingBench.ParentStateNum = stateNum; - gameMap.Add(craftingBench); - /* - */ - return ActiveSkillEffect(activeSkill, player, () => - { - }, - () => - { - lock (player.ActionLock) + player.ThreadNum.WaitOne(); + if (stateNum != player.StateNum) { - if (stateNum == player.StateNum) + ((SummonGolem)activeSkill).DeleteGolem(num); + player.ThreadNum.Release(); + return false; + } + + if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null) + { + ((SummonGolem)activeSkill).DeleteGolem(num); + player.ThreadNum.Release(); + return false; + } + craftingBench.ParentStateNum = stateNum; + gameMap.Add(craftingBench); + /* + */ + return ActiveSkillEffect(activeSkill, player, () => + { + }, + () => + { + lock (player.ActionLock) { - gameMap.RemoveJustFromMap(craftingBench); - Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player); - if (golem == null) + if (stateNum == player.StateNum) { - ((SummonGolem)activeSkill).DeleteGolem(num); + gameMap.RemoveJustFromMap(craftingBench); + Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player); + if (golem == null) + { + ((SummonGolem)activeSkill).AddGolem(num); + } + player.SetPlayerStateNaturally(); + player.ThreadNum.Release(); } - Debugger.Output(player, activeSkill.DurationTime.ToString()); - player.SetPlayerStateNaturally(); - Debugger.Output(player, player.StateNum.ToString()); - player.ThreadNum.Release(); } } + ); } - ); } public static bool UseKnife(Character player) diff --git a/logic/Gaming/SkillManager/SkillManager.cs b/logic/Gaming/SkillManager/SkillManager.cs index 754785d..e35785e 100644 --- a/logic/Gaming/SkillManager/SkillManager.cs +++ b/logic/Gaming/SkillManager/SkillManager.cs @@ -37,7 +37,7 @@ namespace Gaming case ActiveSkillType.SummonGolem: return SummonGolem(character); case ActiveSkillType.UseRobot: - return UseRobot(character); + return UseRobot(character, parameter); case ActiveSkillType.Rouse: return Rouse(character); case ActiveSkillType.ShowTime: diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index d995ab9..cbba972 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -120,8 +120,32 @@ namespace Preparation.Interface private int nowPlayerID; public int NowPlayerID { - get => Interlocked.CompareExchange(ref nowPlayerID, 0, 1); - set => Interlocked.Exchange(ref nowPlayerID, value); + get + { + lock (SkillLock) + { + return nowPlayerID; + } + } + set + { + lock (SkillLock) + { + nowPlayerID = value; + } + } + } + public bool TryResetNowPlayerID(int tryPlayerID) + { + lock (SkillLock) + { + if (nowPlayerID == tryPlayerID) + { + nowPlayerID %= GameData.numOfPeople; + return true; + } + else return false; + } } } @@ -143,12 +167,13 @@ namespace Preparation.Interface public override int SkillCD => GameData.commonSkillCD * 4 / 3; public override int DurationTime => 6000; - private bool[] golemIDArray = new bool[GameData.maxSummonedGolemNum] { false, false, false }; - public bool[] GolemIDArray + private int[] golemStateArray = new int[GameData.maxSummonedGolemNum] { 0, 0, 0 }; + //0未建造,1建造中,2已建造 + public int[] GolemStateArray { get { - lock (SkillLock) { return golemIDArray; } + lock (SkillLock) { return golemStateArray; } } } private int nowPtr = 0; @@ -159,14 +184,14 @@ namespace Preparation.Interface lock (SkillLock) { return nowPtr; } } } - public int AddGolem() + public int BuildGolem() { lock (SkillLock) { if (nowPtr == GameData.maxSummonedGolemNum) return GameData.maxSummonedGolemNum; int num = nowPtr; - golemIDArray[nowPtr] = true; - while ((++nowPtr) < GameData.maxSummonedGolemNum && golemIDArray[nowPtr]) ; + golemStateArray[nowPtr] = 1; + while ((++nowPtr) < GameData.maxSummonedGolemNum && golemStateArray[nowPtr] != 0) ; return num; } } @@ -174,13 +199,20 @@ namespace Preparation.Interface { lock (SkillLock) { - golemIDArray[num] = false; + golemStateArray[num] = 0; if (num < nowPtr) { nowPtr = num; } } } + public void AddGolem(int num) + { + lock (SkillLock) + { + golemStateArray[num] = 2; + } + } } public class NullSkill : ActiveSkill