| @@ -35,7 +35,7 @@ namespace GameClass.GameObj | |||
| public override bool IgnoreCollideExecutor(IGameObj targetObj) | |||
| { | |||
| if (targetObj == Parent) return true; | |||
| if (targetObj.Type == GameObjType.Consumables || targetObj.Type == GameObjType.Bullet) | |||
| if (targetObj.Type == GameObjType.Gadget || targetObj.Type == GameObjType.Bullet) | |||
| return true; | |||
| return false; | |||
| } | |||
| @@ -11,6 +11,8 @@ namespace GameClass.GameObj | |||
| private readonly ReaderWriterLockSlim hpReaderWriterLock = new(); | |||
| public ReaderWriterLockSlim HPReadWriterLock => hpReaderWriterLock; | |||
| private readonly object vampireLock = new(); | |||
| public object VampireLock => vampire; | |||
| #region 装弹、攻击相关的基本属性及方法 | |||
| /// <summary> | |||
| @@ -331,32 +333,18 @@ namespace GameClass.GameObj | |||
| { | |||
| get | |||
| { | |||
| HPReadWriterLock.EnterReadLock(); | |||
| try | |||
| { | |||
| lock (vampireLock) | |||
| return vampire; | |||
| } | |||
| finally | |||
| { | |||
| HPReadWriterLock.ExitReadLock(); | |||
| } | |||
| } | |||
| set | |||
| { | |||
| HPReadWriterLock.EnterWriteLock(); | |||
| try | |||
| { | |||
| lock (vampireLock) | |||
| if (value > 1) | |||
| vampire = 1; | |||
| else if (value < 0) | |||
| vampire = 0; | |||
| else | |||
| vampire = value; | |||
| } | |||
| finally | |||
| { | |||
| HPReadWriterLock.ExitWriteLock(); | |||
| } | |||
| } | |||
| } | |||
| public double OriVampire { get; protected set; } | |||
| @@ -596,9 +584,9 @@ namespace GameClass.GameObj | |||
| } | |||
| #region 道具和buff相关属性、方法 | |||
| private Consumables[] propInventory = new Consumables[GameData.maxNumOfPropInPropInventory] | |||
| private Gadget[] propInventory = new Gadget[GameData.maxNumOfPropInPropInventory] | |||
| {new NullProp(), new NullProp(),new NullProp() }; | |||
| public Consumables[] PropInventory | |||
| public Gadget[] PropInventory | |||
| { | |||
| get => propInventory; | |||
| set | |||
| @@ -615,19 +603,19 @@ namespace GameClass.GameObj | |||
| /// 使用物品栏中的道具 | |||
| /// </summary> | |||
| /// <returns>被使用的道具</returns> | |||
| public Consumables UseProp(int indexing) | |||
| public Gadget UseProp(int indexing) | |||
| { | |||
| if (indexing < 0 || indexing >= GameData.maxNumOfPropInPropInventory) | |||
| return new NullProp(); | |||
| lock (gameObjLock) | |||
| { | |||
| Consumables prop = propInventory[indexing]; | |||
| Gadget prop = propInventory[indexing]; | |||
| PropInventory[indexing] = new NullProp(); | |||
| return prop; | |||
| } | |||
| } | |||
| public Consumables UseProp(PropType propType) | |||
| public Gadget UseProp(PropType propType) | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| @@ -637,7 +625,7 @@ namespace GameClass.GameObj | |||
| { | |||
| if (PropInventory[indexing].GetPropType() != PropType.Null) | |||
| { | |||
| Consumables prop = PropInventory[indexing]; | |||
| Gadget prop = PropInventory[indexing]; | |||
| PropInventory[indexing] = new NullProp(); | |||
| return prop; | |||
| } | |||
| @@ -648,7 +636,7 @@ namespace GameClass.GameObj | |||
| { | |||
| if (PropInventory[indexing].GetPropType() == propType) | |||
| { | |||
| Consumables prop = PropInventory[indexing]; | |||
| Gadget prop = PropInventory[indexing]; | |||
| PropInventory[indexing] = new NullProp(); | |||
| return prop; | |||
| } | |||
| @@ -787,7 +775,7 @@ namespace GameClass.GameObj | |||
| { | |||
| if (IsRemoved) | |||
| return true; | |||
| if (targetObj.Type == GameObjType.Consumables) | |||
| if (targetObj.Type == GameObjType.Gadget) | |||
| { | |||
| return true; | |||
| } | |||
| @@ -15,8 +15,8 @@ namespace GameClass.GameObj | |||
| public override bool IsRigid => true; | |||
| public override ShapeType Shape => ShapeType.Square; | |||
| private readonly Consumables[] propInChest = new Consumables[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; | |||
| public Consumables[] PropInChest => propInChest; | |||
| private readonly Gadget[] propInChest = new Gadget[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; | |||
| public Gadget[] PropInChest => propInChest; | |||
| private int openStartTime = 0; | |||
| public int OpenStartTime => openStartTime; | |||
| @@ -1,15 +1,16 @@ | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System.Threading; | |||
| namespace GameClass.GameObj | |||
| { | |||
| public abstract class Consumables : ObjOfCharacter | |||
| public abstract class Gadget : ObjOfCharacter | |||
| { | |||
| public override bool IsRigid => true; | |||
| public override bool IgnoreCollideExecutor(IGameObj targetObj) | |||
| { | |||
| if (targetObj.Type == GameObjType.Consumables || targetObj.Type == GameObjType.Bullet | |||
| if (targetObj.Type == GameObjType.Gadget || targetObj.Type == GameObjType.Bullet | |||
| || targetObj.Type == GameObjType.Character || targetObj.Type == GameObjType.Chest) | |||
| return true; | |||
| return false; | |||
| @@ -19,19 +20,42 @@ namespace GameClass.GameObj | |||
| public abstract PropType GetPropType(); | |||
| public Consumables(XY initPos, int radius = GameData.PropRadius) : | |||
| base(initPos, radius, GameObjType.Consumables) | |||
| public Gadget(XY initPos, int radius = GameData.PropRadius) : | |||
| base(initPos, radius, GameObjType.Gadget) | |||
| { | |||
| this.canMove = false; | |||
| this.MoveSpeed = GameData.PropMoveSpeed; | |||
| } | |||
| } | |||
| public abstract class Tool : Gadget | |||
| { | |||
| private bool isUsed = false; | |||
| public bool IsUsed | |||
| { | |||
| get | |||
| { | |||
| lock (gameObjLock) | |||
| return isUsed; | |||
| } | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| isUsed = value; | |||
| } | |||
| } | |||
| } | |||
| public Tool(XY initPos) : base(initPos) { } | |||
| } | |||
| public abstract class Consumables : Gadget | |||
| { | |||
| public Consumables(XY initPos) : base(initPos) { } | |||
| } | |||
| ///// <summary> | |||
| ///// 坑人地雷 | |||
| ///// </summary> | |||
| // public abstract class DebuffMine : Consumables | |||
| // public abstract class DebuffMine : Gadget | |||
| //{ | |||
| // public DebuffMine(XYPosition initPos) : base(initPos) { } | |||
| // } | |||
| @@ -86,35 +110,35 @@ namespace GameClass.GameObj | |||
| } | |||
| public override PropType GetPropType() => PropType.ShieldOrSpear; | |||
| } | |||
| public sealed class Key3 : Consumables | |||
| #endregion | |||
| public sealed class Key3 : Tool | |||
| { | |||
| public Key3(XY initPos) : base(initPos) | |||
| { | |||
| } | |||
| public override PropType GetPropType() => PropType.Key3; | |||
| } | |||
| public sealed class Key5 : Consumables | |||
| public sealed class Key5 : Tool | |||
| { | |||
| public Key5(XY initPos) : base(initPos) | |||
| { | |||
| } | |||
| public override PropType GetPropType() => PropType.Key5; | |||
| } | |||
| public sealed class Key6 : Consumables | |||
| public sealed class Key6 : Tool | |||
| { | |||
| public Key6(XY initPos) : base(initPos) | |||
| { | |||
| } | |||
| public override PropType GetPropType() => PropType.Key6; | |||
| } | |||
| public sealed class NullProp : Consumables | |||
| public sealed class NullProp : Gadget | |||
| { | |||
| public NullProp() : base(new XY(1, 1)) | |||
| { | |||
| } | |||
| public override PropType GetPropType() => PropType.Null; | |||
| } | |||
| #endregion | |||
| // #region 所有坑人地雷 | |||
| ///// <summary> | |||
| ///// 减速 | |||
| @@ -143,7 +167,7 @@ namespace GameClass.GameObj | |||
| // #endregion | |||
| public static class PropFactory | |||
| { | |||
| public static Consumables GetConsumables(PropType propType, XY pos) | |||
| public static Gadget GetConsumables(PropType propType, XY pos) | |||
| { | |||
| switch (propType) | |||
| { | |||
| @@ -3,7 +3,7 @@ using Preparation.Utility; | |||
| namespace GameClass.GameObj | |||
| { | |||
| public abstract class Prop : ObjOfCharacter | |||
| public abstract class Item : ObjOfCharacter | |||
| { | |||
| public override bool IsRigid => true; | |||
| @@ -13,11 +13,11 @@ namespace GameClass.GameObj | |||
| public abstract PropType GetPropType(); | |||
| public Prop(XY initPos, int radius = GameData.PropRadius) : | |||
| base(initPos, radius, GameObjType.Prop) | |||
| public Item(XY initPos, int radius = GameData.PropRadius) : | |||
| base(initPos, radius, GameObjType.Item) | |||
| { | |||
| this.canMove = false; | |||
| this.MoveSpeed = GameData.PropMoveSpeed; | |||
| this.MoveSpeed = 0; | |||
| } | |||
| } | |||
| @@ -25,12 +25,12 @@ namespace GameClass.GameObj | |||
| ///// <summary> | |||
| ///// 坑人地雷 | |||
| ///// </summary> | |||
| // public abstract class DebuffMine : Consumables | |||
| // public abstract class DebuffMine : Gadget | |||
| //{ | |||
| // public DebuffMine(XYPosition initPos) : base(initPos) { } | |||
| // } | |||
| public sealed class CraftingBench : Prop | |||
| public sealed class CraftingBench : Item | |||
| { | |||
| public CraftingBench(XY initPos) : | |||
| base(initPos) | |||
| @@ -4,14 +4,14 @@ namespace GameClass.GameObj | |||
| { | |||
| // 为方便界面组做道具拾起特效,现引入“被捡起的道具”,在每帧发送给界面组 | |||
| /* | |||
| public class Prop : Immovable | |||
| public class Item : Immovable | |||
| { | |||
| public override ShapeType Shape => ShapeType.Circle; | |||
| public override bool IsRigid => false; | |||
| public long MappingID { get; } | |||
| public readonly Consumables propHasPicked; | |||
| public Prop(Consumables prop) : | |||
| base(prop.Position, prop.Radius, GameObjType.Prop) | |||
| public readonly Gadget propHasPicked; | |||
| public Item(Gadget prop) : | |||
| base(prop.Position, prop.Radius, GameObjType.Item) | |||
| { | |||
| this.propHasPicked = prop; | |||
| this.MappingID = prop.ID; | |||
| @@ -303,7 +303,7 @@ namespace Gaming | |||
| player.SetPlayerStateNaturally(); | |||
| for (int i = 0; i < GameData.maxNumOfPropInChest; ++i) | |||
| { | |||
| Consumables prop = chestToOpen.PropInChest[i]; | |||
| Gadget prop = chestToOpen.PropInChest[i]; | |||
| chestToOpen.PropInChest[i] = new NullProp(); | |||
| prop.ReSetPos(player.Position); | |||
| gameMap.Add(prop); | |||
| @@ -395,7 +395,7 @@ namespace Gaming | |||
| Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door); | |||
| if (doorToLock == null) return false; | |||
| bool flag = false; | |||
| foreach (Consumables prop in player.PropInventory) | |||
| foreach (Gadget prop in player.PropInventory) | |||
| { | |||
| switch (prop.GetPropType()) | |||
| { | |||
| @@ -370,7 +370,7 @@ namespace Gaming | |||
| for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++) | |||
| { | |||
| Consumables? prop = player.UseProp(i); | |||
| Gadget? prop = player.UseProp(i); | |||
| if (prop != null) | |||
| { | |||
| prop.ReSetPos(player.Position); | |||
| @@ -23,7 +23,7 @@ namespace Gaming | |||
| { | |||
| if (player.IsRemoved || player.CharacterType == CharacterType.Robot) | |||
| return; | |||
| Consumables prop = player.UseProp(propType); | |||
| Gadget prop = player.UseProp(propType); | |||
| switch (prop.GetPropType()) | |||
| { | |||
| case PropType.ShieldOrSpear: | |||
| @@ -79,17 +79,17 @@ namespace Gaming | |||
| if (indexing == GameData.maxNumOfPropInPropInventory) | |||
| return false; | |||
| Consumables pickProp = new NullProp(); | |||
| Gadget pickProp = new NullProp(); | |||
| if (propType == PropType.Null) // 自动检查有无道具可捡 | |||
| { | |||
| pickProp = player.PropInventory[indexing] = ((Consumables?)gameMap.OneInTheSameCell(player.Position, GameObjType.Consumables)) ?? new NullProp(); | |||
| pickProp = player.PropInventory[indexing] = ((Gadget?)gameMap.OneInTheSameCell(player.Position, GameObjType.Gadget)) ?? new NullProp(); | |||
| } | |||
| else | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Consumables].EnterReadLock(); | |||
| gameMap.GameObjLockDict[GameObjType.Gadget].EnterReadLock(); | |||
| try | |||
| { | |||
| foreach (Consumables prop in gameMap.GameObjDict[GameObjType.Consumables]) | |||
| foreach (Gadget prop in gameMap.GameObjDict[GameObjType.Gadget]) | |||
| { | |||
| if (prop.GetPropType() == propType) | |||
| { | |||
| @@ -102,14 +102,14 @@ namespace Gaming | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Consumables].ExitReadLock(); | |||
| gameMap.GameObjLockDict[GameObjType.Gadget].ExitReadLock(); | |||
| } | |||
| } | |||
| if (pickProp.GetPropType() != PropType.Null) | |||
| { | |||
| gameMap.Remove(pickProp); | |||
| //gameMap.Add(new Prop(pickProp)); | |||
| //gameMap.Add(new Item(pickProp)); | |||
| return true; | |||
| } | |||
| else | |||
| @@ -120,7 +120,7 @@ namespace Gaming | |||
| { | |||
| if (!gameMap.Timer.IsGaming || player.IsRemoved) | |||
| return; | |||
| Consumables prop = player.UseProp(propType); | |||
| Gadget prop = player.UseProp(propType); | |||
| if (prop.GetPropType() == PropType.Null) | |||
| return; | |||
| @@ -128,7 +128,7 @@ namespace Gaming | |||
| gameMap.Add(prop); | |||
| } | |||
| private static Consumables ProduceOnePropNotKey(Random r, XY Pos) | |||
| private static Gadget ProduceOnePropNotKey(Random r, XY Pos) | |||
| { | |||
| return PropFactory.GetConsumables((PropType)r.Next(GameData.numOfTeachingBuilding + 1, GameData.numOfPropSpecies + 1), Pos); | |||
| } | |||
| @@ -30,8 +30,8 @@ namespace Preparation.Utility | |||
| { | |||
| Null = 0, | |||
| Character = 1, | |||
| Consumables = 2, | |||
| Prop = 3, | |||
| Gadget = 2, | |||
| Item = 3, | |||
| Bullet = 4, | |||
| BombedBullet = 5, | |||
| @@ -45,8 +45,8 @@ namespace Preparation.Utility | |||
| { | |||
| return gameObjType != GameObjType.Null && gameObjType != GameObjType.Grass | |||
| && gameObjType != GameObjType.OutOfBoundBlock && gameObjType != GameObjType.Window | |||
| && gameObjType != GameObjType.Bullet&&gameObjType != GameObjType.Consumables | |||
| &&gameObjType != GameObjType.Prop&&gameObjType != GameObjType.BombedBullet | |||
| && gameObjType != GameObjType.Bullet&&gameObjType != GameObjType.Gadget | |||
| &&gameObjType != GameObjType.Item&&gameObjType != GameObjType.BombedBullet | |||
| &&gameObjType != GameObjType.EmergencyExit&&gameObjType != GameObjType.Doorway; | |||
| }*/ | |||
| @@ -33,10 +33,10 @@ namespace Server | |||
| else return null; | |||
| case Preparation.Utility.GameObjType.Door: | |||
| return Door((Door)gameObj); | |||
| case GameObjType.Prop: | |||
| return Prop((Prop)gameObj); | |||
| case Preparation.Utility.GameObjType.Consumables: | |||
| return Prop((Consumables)gameObj); | |||
| case GameObjType.Item: | |||
| return Prop((Item)gameObj); | |||
| case Preparation.Utility.GameObjType.Gadget: | |||
| return Prop((Gadget)gameObj); | |||
| default: return null; | |||
| } | |||
| } | |||
| @@ -157,7 +157,7 @@ namespace Server | |||
| return msg; | |||
| } | |||
| private static MessageOfObj Prop(Consumables prop) | |||
| private static MessageOfObj Prop(Gadget prop) | |||
| { | |||
| MessageOfObj msg = new() | |||
| { | |||
| @@ -173,7 +173,7 @@ namespace Server | |||
| return msg; | |||
| } | |||
| private static MessageOfObj Prop(Prop prop) | |||
| private static MessageOfObj Prop(Item prop) | |||
| { | |||
| MessageOfObj msg = new() | |||
| { | |||