| @@ -80,7 +80,8 @@ v1.6 | |||||
| - 新造的Robot的PlayerId的n总是尽量小 | - 新造的Robot的PlayerId的n总是尽量小 | ||||
| 1. UseRobot | 1. UseRobot | ||||
| - CD:2s,持续时间:0s | - CD:2s,持续时间:0s | ||||
| - 输入额外参数PlayerID,切换到要使用的角色 | |||||
| - 输入额外参数PlayerID,切换到要使用的角色。 | |||||
| - 切换到其他角色时,自己进入UsingSkill状态。 | |||||
| 修改后: | 修改后: | ||||
| @@ -448,7 +448,7 @@ namespace GameClass.GameObj | |||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| PlayerStateType nowPlayerState = PlayerState; | PlayerStateType nowPlayerState = PlayerState; | ||||
| if (nowPlayerState == value) return -1; | |||||
| if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1; | |||||
| switch (nowPlayerState) | switch (nowPlayerState) | ||||
| { | { | ||||
| case PlayerStateType.Escaped: | case PlayerStateType.Escaped: | ||||
| @@ -542,16 +542,24 @@ namespace GameClass.GameObj | |||||
| ThreadNum.Release(); | ThreadNum.Release(); | ||||
| } | } | ||||
| case PlayerStateType.UsingSkill: | 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); | return ChangePlayerState(value, gameObj); | ||||
| @@ -61,7 +61,7 @@ namespace Gaming | |||||
| return true; | return true; | ||||
| } | } | ||||
| public bool Stop(Character player) | |||||
| public static bool Stop(Character player) | |||||
| { | { | ||||
| lock (player.ActionLock) | lock (player.ActionLock) | ||||
| { | { | ||||
| @@ -383,7 +383,15 @@ namespace Gaming | |||||
| if (parent != null && parent.CharacterType == CharacterType.TechOtaku) | if (parent != null && parent.CharacterType == CharacterType.TechOtaku) | ||||
| { | { | ||||
| ((SummonGolem)(parent.FindActiveSkill(ActiveSkillType.SummonGolem))).DeleteGolem((int)(player.PlayerID - parent.PlayerID) / GameData.numOfPeople - 1); | ((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; | return; | ||||
| } | } | ||||
| @@ -160,7 +160,7 @@ namespace Gaming | |||||
| Character? player = gameMap.FindPlayerToAction(playerID); | Character? player = gameMap.FindPlayerToAction(playerID); | ||||
| if (player != null) | if (player != null) | ||||
| { | { | ||||
| return actionManager.Stop(player); | |||||
| return ActionManager.Stop(player); | |||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -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) | public static bool JumpyBomb(Character player) | ||||
| @@ -151,61 +173,61 @@ namespace Gaming | |||||
| public bool SummonGolem(Character player) | public bool SummonGolem(Character player) | ||||
| { | { | ||||
| ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem); | ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem); | ||||
| int num = ((SummonGolem)activeSkill).AddGolem(); | |||||
| int num = ((SummonGolem)activeSkill).BuildGolem(); | |||||
| if (num >= GameData.maxSummonedGolemNum) return false; | if (num >= GameData.maxSummonedGolemNum) return false; | ||||
| Debugger.Output(player, num.ToString()); | |||||
| XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2); | 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) | public static bool UseKnife(Character player) | ||||
| @@ -37,7 +37,7 @@ namespace Gaming | |||||
| case ActiveSkillType.SummonGolem: | case ActiveSkillType.SummonGolem: | ||||
| return SummonGolem(character); | return SummonGolem(character); | ||||
| case ActiveSkillType.UseRobot: | case ActiveSkillType.UseRobot: | ||||
| return UseRobot(character); | |||||
| return UseRobot(character, parameter); | |||||
| case ActiveSkillType.Rouse: | case ActiveSkillType.Rouse: | ||||
| return Rouse(character); | return Rouse(character); | ||||
| case ActiveSkillType.ShowTime: | case ActiveSkillType.ShowTime: | ||||
| @@ -120,8 +120,32 @@ namespace Preparation.Interface | |||||
| private int nowPlayerID; | private int nowPlayerID; | ||||
| public 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 SkillCD => GameData.commonSkillCD * 4 / 3; | ||||
| public override int DurationTime => 6000; | 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 | get | ||||
| { | { | ||||
| lock (SkillLock) { return golemIDArray; } | |||||
| lock (SkillLock) { return golemStateArray; } | |||||
| } | } | ||||
| } | } | ||||
| private int nowPtr = 0; | private int nowPtr = 0; | ||||
| @@ -159,14 +184,14 @@ namespace Preparation.Interface | |||||
| lock (SkillLock) { return nowPtr; } | lock (SkillLock) { return nowPtr; } | ||||
| } | } | ||||
| } | } | ||||
| public int AddGolem() | |||||
| public int BuildGolem() | |||||
| { | { | ||||
| lock (SkillLock) | lock (SkillLock) | ||||
| { | { | ||||
| if (nowPtr == GameData.maxSummonedGolemNum) return GameData.maxSummonedGolemNum; | if (nowPtr == GameData.maxSummonedGolemNum) return GameData.maxSummonedGolemNum; | ||||
| int num = nowPtr; | int num = nowPtr; | ||||
| golemIDArray[nowPtr] = true; | |||||
| while ((++nowPtr) < GameData.maxSummonedGolemNum && golemIDArray[nowPtr]) ; | |||||
| golemStateArray[nowPtr] = 1; | |||||
| while ((++nowPtr) < GameData.maxSummonedGolemNum && golemStateArray[nowPtr] != 0) ; | |||||
| return num; | return num; | ||||
| } | } | ||||
| } | } | ||||
| @@ -174,13 +199,20 @@ namespace Preparation.Interface | |||||
| { | { | ||||
| lock (SkillLock) | lock (SkillLock) | ||||
| { | { | ||||
| golemIDArray[num] = false; | |||||
| golemStateArray[num] = 0; | |||||
| if (num < nowPtr) | if (num < nowPtr) | ||||
| { | { | ||||
| nowPtr = num; | nowPtr = num; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| public void AddGolem(int num) | |||||
| { | |||||
| lock (SkillLock) | |||||
| { | |||||
| golemStateArray[num] = 2; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| public class NullSkill : ActiveSkill | public class NullSkill : ActiveSkill | ||||