| @@ -36,4 +36,6 @@ | |||
| # 5月15日更新 | |||
| - feat:Robot可用 | |||
| - hotfix: 修复了移动相关的bug | |||
| - hotfix: 修复了移动相关的bug | |||
| # 最新更新 | |||
| @@ -816,63 +816,63 @@ namespace Client | |||
| private void Refresh(object? sender, EventArgs e) //log未更新 | |||
| { | |||
| lock (drawPicLock) // 加锁是必要的,画图操作和接收信息操作不能同时进行 | |||
| try | |||
| { | |||
| // Bonus(); | |||
| if (WindowState == WindowState.Maximized) | |||
| MaxButton.Content = "❐"; | |||
| else | |||
| MaxButton.Content = "🗖"; | |||
| foreach (var obj in listOfHuman) | |||
| lock (drawPicLock) // 加锁是必要的,画图操作和接收信息操作不能同时进行 | |||
| { | |||
| if (!isDataFixed[obj.PlayerId] && obj.PlayerId < GameData.numOfStudent && obj.StudentType != StudentType.Robot) | |||
| // Bonus(); | |||
| if (WindowState == WindowState.Maximized) | |||
| MaxButton.Content = "❐"; | |||
| else | |||
| MaxButton.Content = "🗖"; | |||
| foreach (var obj in listOfHuman) | |||
| { | |||
| IStudentType occupation = (IStudentType)OccupationFactory.FindIOccupation(Transformation.ToStudentType(obj.StudentType)); | |||
| totalLife[obj.PlayerId] = occupation.MaxHp; | |||
| totalDeath[obj.PlayerId] = occupation.MaxGamingAddiction; | |||
| int i = 0; | |||
| foreach (var skill in occupation.ListOfIActiveSkill) | |||
| if (obj.PlayerId < GameData.numOfStudent && !isDataFixed[obj.PlayerId]) | |||
| { | |||
| var iActiveSkill = SkillFactory.FindActiveSkill(skill); | |||
| coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; | |||
| ++i; | |||
| IStudentType occupation = (IStudentType)OccupationFactory.FindIOccupation(Transformation.ToStudentType(obj.StudentType)); | |||
| totalLife[obj.PlayerId] = occupation.MaxHp; | |||
| totalDeath[obj.PlayerId] = occupation.MaxGamingAddiction; | |||
| int i = 0; | |||
| foreach (var skill in occupation.ListOfIActiveSkill) | |||
| { | |||
| var iActiveSkill = SkillFactory.FindActiveSkill(skill); | |||
| coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; | |||
| ++i; | |||
| } | |||
| isDataFixed[obj.PlayerId] = true; | |||
| } | |||
| isDataFixed[obj.PlayerId] = true; | |||
| } | |||
| } | |||
| foreach (var obj in listOfButcher) | |||
| { | |||
| if (!isDataFixed[obj.PlayerId]) | |||
| foreach (var obj in listOfButcher) | |||
| { | |||
| IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType)); | |||
| int j = 0; | |||
| foreach (var skill in occupation1.ListOfIActiveSkill) | |||
| if (!isDataFixed[obj.PlayerId]) | |||
| { | |||
| var iActiveSkill = SkillFactory.FindActiveSkill(skill); | |||
| coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; | |||
| ++j; | |||
| IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType)); | |||
| int j = 0; | |||
| foreach (var skill in occupation1.ListOfIActiveSkill) | |||
| { | |||
| var iActiveSkill = SkillFactory.FindActiveSkill(skill); | |||
| coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; | |||
| ++j; | |||
| } | |||
| isDataFixed[obj.PlayerId] = true; | |||
| } | |||
| isDataFixed[obj.PlayerId] = true; | |||
| } | |||
| } | |||
| for (int i = 0; i < GameData.numOfStudent; i++) | |||
| { | |||
| StatusBarsOfSurvivor[i].NewData(totalLife, totalDeath, coolTime); | |||
| } | |||
| for (int i = 0; i < GameData.numOfStudent; i++) | |||
| { | |||
| StatusBarsOfSurvivor[i].NewData(totalLife, totalDeath, coolTime); | |||
| } | |||
| StatusBarsOfHunter.NewData(totalLife, totalDeath, coolTime); | |||
| StatusBarsOfHunter.NewData(totalLife, totalDeath, coolTime); | |||
| for (int i = 0; i < GameData.numOfStudent; i++) | |||
| { | |||
| StatusBarsOfSurvivor[i].SetFontSize(12 * unitFontsize); | |||
| } | |||
| for (int i = 0; i < GameData.numOfStudent; i++) | |||
| { | |||
| StatusBarsOfSurvivor[i].SetFontSize(12 * unitFontsize); | |||
| } | |||
| StatusBarsOfHunter.SetFontSize(12 * unitFontsize); | |||
| StatusBarsOfCircumstance.SetFontSize(12 * unitFontsize); | |||
| if (!isClientStocked) | |||
| { | |||
| try | |||
| StatusBarsOfHunter.SetFontSize(12 * unitFontsize); | |||
| StatusBarsOfCircumstance.SetFontSize(12 * unitFontsize); | |||
| if (!isClientStocked) | |||
| { | |||
| UpperLayerOfMap.Children.Clear(); | |||
| foreach (var data in listOfAll) | |||
| @@ -885,7 +885,7 @@ namespace Client | |||
| } | |||
| foreach (var data in listOfHuman) | |||
| { | |||
| if (data.StudentType != StudentType.Robot) | |||
| if (data.PlayerId < GameData.numOfStudent) | |||
| StatusBarsOfSurvivor[data.PlayerId].SetValue(data, data.PlayerId); | |||
| if (CanSee(data)) | |||
| { | |||
| @@ -1136,15 +1136,15 @@ namespace Client | |||
| } | |||
| } | |||
| } | |||
| catch (Exception exc) | |||
| { | |||
| ErrorDisplayer error = new("Error: " + exc.ToString()); | |||
| error.Show(); | |||
| isClientStocked = true; | |||
| PorC.Content = "▶"; | |||
| } | |||
| counter++; | |||
| } | |||
| counter++; | |||
| } | |||
| catch (Exception exc) | |||
| { | |||
| ErrorDisplayer error = new("Error: " + exc.ToString()); | |||
| error.Show(); | |||
| isClientStocked = true; | |||
| PorC.Content = "▶"; | |||
| } | |||
| } | |||
| @@ -1309,6 +1309,7 @@ namespace Client | |||
| { | |||
| PlayerId = playerID, | |||
| SkillId = 0, | |||
| SkillParam = 0, | |||
| }; | |||
| client.UseSkill(msgB); | |||
| break; | |||
| @@ -442,8 +442,9 @@ namespace GameClass.GameObj | |||
| } | |||
| public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||
| public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null) | |||
| { | |||
| GameObj? gameObj = (GameObj?)obj; | |||
| lock (actionLock) | |||
| { | |||
| PlayerStateType nowPlayerState = PlayerState; | |||
| @@ -468,20 +469,21 @@ namespace GameClass.GameObj | |||
| else return -1; | |||
| case PlayerStateType.TryingToAttack: | |||
| if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows | |||
| && value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor) | |||
| if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging | |||
| || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | |||
| || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | |||
| return ChangePlayerState(value, gameObj); | |||
| else return -1; | |||
| case PlayerStateType.Stunned: | |||
| case PlayerStateType.Charmed: | |||
| if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows | |||
| && value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor | |||
| && value != PlayerStateType.Swinging) | |||
| if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased | |||
| || value == PlayerStateType.Null) | |||
| return ChangePlayerState(value, gameObj); | |||
| else return -1; | |||
| case PlayerStateType.Swinging: | |||
| if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows | |||
| && value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor) | |||
| if (value == PlayerStateType.Addicted | |||
| || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | |||
| || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | |||
| { | |||
| try | |||
| { | |||
| @@ -494,7 +496,9 @@ namespace GameClass.GameObj | |||
| } | |||
| else return -1; | |||
| case PlayerStateType.ClimbingThroughWindows: | |||
| if (value != PlayerStateType.Moving && value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor) | |||
| if (value == PlayerStateType.Addicted | |||
| || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned | |||
| || value == PlayerStateType.Charmed || value == PlayerStateType.Null) | |||
| { | |||
| Window window = (Window)WhatInteractingWith!; | |||
| try | |||
| @@ -537,6 +541,20 @@ namespace GameClass.GameObj | |||
| { | |||
| ThreadNum.Release(); | |||
| } | |||
| case PlayerStateType.UsingSkill: | |||
| if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith)) | |||
| { | |||
| try | |||
| { | |||
| ((CraftingBench)whatInteractingWith!).StopSkill(); | |||
| return ChangePlayerState(value, gameObj); | |||
| } | |||
| finally | |||
| { | |||
| ThreadNum.Release(); | |||
| } | |||
| } | |||
| return ChangePlayerState(value, gameObj); | |||
| default: | |||
| return ChangePlayerState(value, gameObj); | |||
| } | |||
| @@ -36,6 +36,35 @@ namespace GameClass.GameObj | |||
| public abstract ShapeType Shape { get; } | |||
| protected bool isRemoved = false; | |||
| public virtual bool IsRemoved | |||
| { | |||
| get | |||
| { | |||
| gameObjReaderWriterLock.EnterReadLock(); | |||
| try | |||
| { | |||
| return isRemoved; | |||
| } | |||
| finally | |||
| { | |||
| gameObjReaderWriterLock.ExitReadLock(); | |||
| } | |||
| } | |||
| } | |||
| public virtual void TryToRemove() | |||
| { | |||
| gameObjReaderWriterLock.EnterWriteLock(); | |||
| try | |||
| { | |||
| isRemoved = true; | |||
| } | |||
| finally | |||
| { | |||
| gameObjReaderWriterLock.ExitWriteLock(); | |||
| } | |||
| } | |||
| public int Radius { get; } | |||
| public virtual bool IgnoreCollideExecutor(IGameObj targetObj) => false; | |||
| @@ -231,7 +231,10 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| if (ToDel != null) | |||
| { | |||
| GameObjDict[gameObj.Type].Remove(ToDel); | |||
| ToDel.TryToRemove(); | |||
| } | |||
| } | |||
| finally | |||
| { | |||
| @@ -242,16 +245,19 @@ namespace GameClass.GameObj | |||
| public bool RemoveJustFromMap(GameObj gameObj) | |||
| { | |||
| GameObjLockDict[gameObj.Type].EnterWriteLock(); | |||
| bool flag; | |||
| try | |||
| { | |||
| flag = GameObjDict[gameObj.Type].Remove(gameObj); | |||
| if (GameObjDict[gameObj.Type].Remove(gameObj)) | |||
| { | |||
| gameObj.TryToRemove(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| finally | |||
| { | |||
| GameObjLockDict[gameObj.Type].ExitWriteLock(); | |||
| } | |||
| return flag; | |||
| } | |||
| public void Add(GameObj gameObj) | |||
| { | |||
| @@ -126,8 +126,7 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| protected bool isRemoved; | |||
| public bool IsRemoved | |||
| public override bool IsRemoved | |||
| { | |||
| get | |||
| { | |||
| @@ -1,5 +1,4 @@ | |||
| using Google.Protobuf.WellKnownTypes; | |||
| using Preparation.Interface; | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System.Threading; | |||
| @@ -1,5 +1,6 @@ | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System.Threading; | |||
| namespace GameClass.GameObj | |||
| { | |||
| @@ -32,9 +33,32 @@ namespace GameClass.GameObj | |||
| public sealed class CraftingBench : Item | |||
| { | |||
| public CraftingBench(XY initPos) : | |||
| public CraftingBench(XY initPos, Character character, int num) : | |||
| base(initPos) | |||
| { | |||
| Parent = character; | |||
| this.num = num; | |||
| } | |||
| private readonly int num; | |||
| private long parentStateNum; | |||
| public long ParentStateNum | |||
| { | |||
| get => Interlocked.Read(ref parentStateNum); | |||
| set => Interlocked.Exchange(ref parentStateNum, value); | |||
| } | |||
| public void StopSkill() | |||
| { | |||
| ((SummonGolem)Parent!.FindActiveSkill(ActiveSkillType.SummonGolem)).DeleteGolem((int)num); | |||
| } | |||
| public void TryStopSkill() | |||
| { | |||
| lock (Parent!.ActionLock) | |||
| { | |||
| if (Parent!.StateNum == parentStateNum) | |||
| { | |||
| Parent!.SetPlayerState(); | |||
| } | |||
| } | |||
| } | |||
| public override PropType GetPropType() => PropType.CraftingBench; | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| using System; | |||
| using System.Numerics; | |||
| using System.Threading; | |||
| using GameClass.GameObj; | |||
| using GameEngine; | |||
| @@ -13,26 +14,6 @@ namespace Gaming | |||
| private readonly ActionManager actionManager; | |||
| private class ActionManager | |||
| { | |||
| // 人物移动 | |||
| private void SkillWhenColliding(Character player, IGameObj collisionObj) | |||
| { | |||
| if (collisionObj.Type == GameObjType.Bullet) | |||
| { | |||
| if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty) | |||
| { | |||
| if (characterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0) | |||
| player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStunnedWhenJumpyDumpty)); | |||
| gameMap.Remove((GameObj)collisionObj); | |||
| } | |||
| } | |||
| if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost()) | |||
| { | |||
| if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) | |||
| player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); | |||
| characterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge); | |||
| } | |||
| } | |||
| public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | |||
| { | |||
| if (moveTimeInMilliseconds < 5) return false; | |||
| @@ -561,7 +542,37 @@ namespace Gaming | |||
| gameMap: gameMap, | |||
| OnCollision: (obj, collisionObj, moveVec) => | |||
| { | |||
| SkillWhenColliding((Character)obj, collisionObj); | |||
| Character player = (Character)obj; | |||
| switch (collisionObj.Type) | |||
| { | |||
| case GameObjType.Bullet: | |||
| if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty) | |||
| { | |||
| if (characterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0) | |||
| player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStunnedWhenJumpyDumpty)); | |||
| gameMap.Remove((GameObj)collisionObj); | |||
| } | |||
| break; | |||
| case GameObjType.Character: | |||
| if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && ((Character)collisionObj).IsGhost()) | |||
| { | |||
| if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) | |||
| player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); | |||
| characterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge); | |||
| } | |||
| break; | |||
| case GameObjType.Item: | |||
| if (((Item)collisionObj).GetPropType() == PropType.CraftingBench) | |||
| { | |||
| ((CraftingBench)collisionObj).TryStopSkill(); | |||
| gameMap.Remove((Item)collisionObj); | |||
| } | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| //Preparation.Utility.Debugger.Output(obj, " end move with " + collisionObj.ToString()); | |||
| //if (collisionObj is Mine) | |||
| //{ | |||
| @@ -74,6 +74,13 @@ namespace Gaming | |||
| if (bullet.CanBeBombed(GameObjType.Door)) | |||
| ; | |||
| break; | |||
| case GameObjType.Item: | |||
| if (((Item)objBeingShot).GetPropType() == PropType.CraftingBench) | |||
| { | |||
| ((CraftingBench)objBeingShot).TryStopSkill(); | |||
| gameMap.Remove(objBeingShot); | |||
| } | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -151,24 +151,61 @@ namespace Gaming | |||
| public bool SummonGolem(Character player) | |||
| { | |||
| ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem); | |||
| long num = ((SummonGolem)activeSkill).AddGolem(); | |||
| int num = ((SummonGolem)activeSkill).AddGolem(); | |||
| if (num >= GameData.maxSummonedGolemNum) return false; | |||
| num = (num + 1) * GameData.numOfPeople + player.PlayerID; | |||
| Debugger.Output(player, num.ToString()); | |||
| /* if ((!player.Commandable())) return false; | |||
| XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2); | |||
| if (actionManager.moveEngine.CheckCollision(player, res) != null) | |||
| return false; | |||
| Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player); | |||
| if (golem == null) return false; | |||
| ((SummonGolem)activeSkill).GolemSummoned = golem; | |||
| 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) | |||
| { | |||
| ((SummonGolem)activeSkill).DeleteGolem(num); | |||
| return false; | |||
| } | |||
| player.ThreadNum.WaitOne(); | |||
| 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) | |||
| { | |||
| if (stateNum == player.StateNum) | |||
| { | |||
| 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).DeleteGolem(num); | |||
| } | |||
| Debugger.Output(player, activeSkill.DurationTime.ToString()); | |||
| player.SetPlayerStateNaturally(); | |||
| Debugger.Output(player, player.StateNum.ToString()); | |||
| player.ThreadNum.Release(); | |||
| } | |||
| } | |||
| } | |||
| ); | |||
| } | |||
| public static bool UseKnife(Character player) | |||
| @@ -336,6 +373,7 @@ namespace Gaming | |||
| if (activeSkill.TimeUntilActiveSkillAvailable == 0) | |||
| { | |||
| activeSkill.TimeUntilActiveSkillAvailable = activeSkill.SkillCD; | |||
| new Thread | |||
| (() => | |||
| { | |||
| @@ -3,7 +3,7 @@ using Preparation.Utility; | |||
| namespace Preparation.Interface | |||
| { | |||
| public interface ICharacter : IGameObj | |||
| public interface ICharacter : IMoveable | |||
| { | |||
| public long TeamID { get; } | |||
| public int HP { get; set; } | |||
| @@ -13,7 +13,9 @@ namespace Preparation.Interface | |||
| public PlayerStateType PlayerState { get; } | |||
| public BulletType BulletOfPlayer { get; set; } | |||
| public CharacterType CharacterType { get; } | |||
| public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType); | |||
| public int UpdateBulletNum(int time); | |||
| public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null); | |||
| public bool IsGhost(); | |||
| } | |||
| @@ -32,7 +32,10 @@ namespace Preparation.Interface | |||
| private int timeUntilActiveSkillAvailable = 0; | |||
| public int TimeUntilActiveSkillAvailable | |||
| { | |||
| get => Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1); | |||
| get | |||
| { | |||
| return Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1); | |||
| } | |||
| set | |||
| { | |||
| if (value < 0) value = 0; | |||
| @@ -138,7 +141,7 @@ namespace Preparation.Interface | |||
| public class SummonGolem : ActiveSkill | |||
| { | |||
| public override int SkillCD => GameData.commonSkillCD * 4 / 3; | |||
| public override int DurationTime => 6; | |||
| public override int DurationTime => 6000; | |||
| private bool[] golemIDArray = new bool[GameData.maxSummonedGolemNum] { false, false, false }; | |||
| public bool[] GolemIDArray | |||
| @@ -8,6 +8,12 @@ namespace Preparation.Utility | |||
| { | |||
| #if DEBUG | |||
| Console.WriteLine(current.GetType() + " " + current.ToString() + " " + str); | |||
| #endif | |||
| } | |||
| static public void Output(string str) | |||
| { | |||
| #if DEBUG | |||
| Console.WriteLine(str); | |||
| #endif | |||
| } | |||
| } | |||
| @@ -55,6 +55,8 @@ namespace Preparation.Utility | |||
| return Protobuf.PropType.ShieldOrSpear; | |||
| case Preparation.Utility.PropType.RecoveryFromDizziness: | |||
| return Protobuf.PropType.RecoveryFromDizziness; | |||
| case PropType.CraftingBench: | |||
| return Protobuf.PropType.CraftingBench; | |||
| case Preparation.Utility.PropType.Key3: | |||
| return Protobuf.PropType.Key3; | |||
| case Preparation.Utility.PropType.Key5: | |||