add NullProp to fix the initialization errortags/0.1.0
| @@ -60,7 +60,6 @@ namespace GameClass.GameObj | |||
| this.place = PlaceType.Null; | |||
| this.CanMove = true; | |||
| this.score = 0; | |||
| this.propInventory = null; | |||
| this.buffManager = new BuffManager(); | |||
| switch (characterType) | |||
| { | |||
| @@ -12,7 +12,7 @@ namespace GameClass.GameObj | |||
| { | |||
| private readonly object beAttackedLock = new(); | |||
| #region 角色的基本属性及方法,包括与道具的交互方法 | |||
| #region 装弹相关的基本属性及方法 | |||
| /// <summary> | |||
| /// 装弹冷却 | |||
| /// </summary> | |||
| @@ -36,149 +36,125 @@ namespace GameClass.GameObj | |||
| protected int bulletNum; | |||
| public int BulletNum => bulletNum; // 目前持有的子弹数 | |||
| public int MaxHp { get; protected set; } // 最大血量 | |||
| protected int hp; | |||
| public int HP | |||
| { | |||
| get => hp; | |||
| set | |||
| { | |||
| if (value > 0) | |||
| { | |||
| lock (gameObjLock) | |||
| hp = value <= MaxHp ? value : MaxHp; | |||
| } | |||
| else | |||
| lock (gameObjLock) | |||
| hp = 0; | |||
| } | |||
| } | |||
| private PlayerStateType playerState = PlayerStateType.Null; | |||
| public PlayerStateType PlayerState | |||
| public readonly BulletType OriBulletOfPlayer; | |||
| private BulletType bulletOfPlayer; | |||
| public BulletType BulletOfPlayer | |||
| { | |||
| get | |||
| { | |||
| if (IsMoving) return PlayerStateType.IsMoving; | |||
| return playerState; | |||
| } | |||
| get => bulletOfPlayer; | |||
| set | |||
| { | |||
| if (!(value == PlayerStateType.IsMoving)) | |||
| lock (gameObjLock) | |||
| IsMoving = false; | |||
| lock (gameObjLock) playerState = (value == PlayerStateType.IsMoving) ? PlayerStateType.Null : value; | |||
| lock (gameObjLock) | |||
| bulletOfPlayer = value; | |||
| } | |||
| } | |||
| public bool Commandable() => (playerState != PlayerStateType.IsDeceased && playerState != PlayerStateType.IsEscaped | |||
| && playerState != PlayerStateType.IsAddicted && playerState != PlayerStateType.IsRescuing | |||
| && playerState != PlayerStateType.IsSwinging && playerState != PlayerStateType.IsTryingToAttack | |||
| && playerState != PlayerStateType.IsClimbingThroughWindows && playerState != PlayerStateType.IsStunned); | |||
| public bool InteractingWithMapWithoutMoving() => (playerState == PlayerStateType.IsLockingOrOpeningTheDoor || playerState == PlayerStateType.IsFixing || playerState == PlayerStateType.IsOpeningTheChest); | |||
| public bool NullOrMoving() => (playerState == PlayerStateType.Null || playerState == PlayerStateType.IsMoving); | |||
| // private int deathCount = 0; | |||
| // public int DeathCount => deathCount; // 玩家的死亡次数 | |||
| private int score = 0; | |||
| public int Score | |||
| /// <summary> | |||
| /// 进行一次攻击 | |||
| /// </summary> | |||
| /// <returns>攻击操作发出的子弹</returns> | |||
| public Bullet? Attack(XY pos, PlaceType place) | |||
| { | |||
| get => score; | |||
| if (TrySubBulletNum()) | |||
| return BulletFactory.GetBullet(this, place, pos); | |||
| else | |||
| return null; | |||
| } | |||
| // public double AttackRange => BulletFactory.BulletAttackRange(this.BulletOfPlayer); | |||
| private double vampire = 0; // 回血率:0-1之间 | |||
| public double Vampire | |||
| /// <summary> | |||
| /// 尝试将子弹数量减1 | |||
| /// </summary> | |||
| /// <returns>减操作是否成功</returns> | |||
| private bool TrySubBulletNum() | |||
| { | |||
| get => vampire; | |||
| set | |||
| lock (gameObjLock) | |||
| { | |||
| if (value > 1) | |||
| lock (gameObjLock) | |||
| vampire = 1; | |||
| else if (value < 0) | |||
| lock (gameObjLock) | |||
| vampire = 0; | |||
| else | |||
| lock (gameObjLock) | |||
| vampire = value; | |||
| if (bulletNum > 0) | |||
| { | |||
| --bulletNum; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| private double oriVampire = 0; | |||
| public double OriVampire | |||
| /// <summary> | |||
| /// 尝试将子弹数量加1 | |||
| /// </summary> | |||
| /// <returns>加操作是否成功</returns> | |||
| public bool TryAddBulletNum() | |||
| { | |||
| get => oriVampire; | |||
| set | |||
| lock (gameObjLock) | |||
| { | |||
| if (value > 1) | |||
| lock (gameObjLock) | |||
| vampire = 1; | |||
| else if (value < 0) | |||
| lock (gameObjLock) | |||
| vampire = 0; | |||
| else | |||
| lock (gameObjLock) | |||
| vampire = value; | |||
| if (bulletNum < maxBulletNum) | |||
| { | |||
| ++bulletNum; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| public readonly BulletType OriBulletOfPlayer; | |||
| private BulletType bulletOfPlayer; | |||
| public BulletType BulletOfPlayer | |||
| /// <summary> | |||
| /// 遭受攻击 | |||
| /// </summary> | |||
| /// <param name="subHP"></param> | |||
| /// <param name="hasSpear"></param> | |||
| /// <param name="attacker">伤害来源</param> | |||
| /// <returns>人物在受到攻击后死了吗</returns> | |||
| public bool BeAttacked(Bullet bullet) | |||
| { | |||
| get => bulletOfPlayer; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| bulletOfPlayer = value; | |||
| } | |||
| } | |||
| private Prop[] propInventory = new Prop[GameData.maxNumOfPropInPropInventory]; | |||
| public Prop[] PropInventory | |||
| { | |||
| get => propInventory; | |||
| set | |||
| lock (beAttackedLock) | |||
| { | |||
| lock (gameObjLock) | |||
| if (hp <= 0) | |||
| return false; // 原来已经死了 | |||
| if (bullet.Parent.TeamID != this.TeamID) | |||
| { | |||
| propInventory = value; | |||
| Debugger.Output(this, " prop becomes " + (PropInventory == null ? "null" : PropInventory.ToString())); | |||
| if (HasShield) | |||
| { | |||
| if (bullet.HasSpear) | |||
| _ = TrySubHp(bullet.AP); | |||
| else | |||
| return false; | |||
| } | |||
| else | |||
| { | |||
| bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP))); | |||
| } | |||
| #if DEBUG | |||
| Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}."); | |||
| #endif | |||
| if (hp <= 0) | |||
| TryActivatingLIFE(); // 如果有复活甲 | |||
| } | |||
| return hp <= 0; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 使用物品栏中的道具 | |||
| /// 攻击被反弹,反弹伤害不会再被反弹 | |||
| /// </summary> | |||
| /// <returns>被使用的道具</returns> | |||
| public Prop? UseProp(int indexing) | |||
| /// <param name="subHP"></param> | |||
| /// <param name="hasSpear"></param> | |||
| /// <param name="bouncer">反弹伤害者</param> | |||
| /// <returns>是否因反弹伤害而死</returns> | |||
| private bool BeBounced(int subHP, bool hasSpear, Character? bouncer) | |||
| { | |||
| if (indexing < 0 || indexing >= GameData.maxNumOfPropInPropInventory) | |||
| return null; | |||
| lock (gameObjLock) | |||
| lock (beAttackedLock) | |||
| { | |||
| Prop prop = propInventory[indexing]; | |||
| PropInventory[indexing] = null; | |||
| return prop; | |||
| if (hp <= 0) | |||
| return false; | |||
| if (!(bouncer?.TeamID == this.TeamID)) | |||
| { | |||
| if (hasSpear || !HasShield) | |||
| _ = TrySubHp(subHP); | |||
| if (hp <= 0) | |||
| TryActivatingLIFE(); | |||
| } | |||
| return hp <= 0; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 如果indexing==GameData.maxNumOfPropInPropInventory表明道具栏为满 | |||
| /// </summary> | |||
| public int IndexingOfAddProp() | |||
| { | |||
| int indexing = 0; | |||
| for (; indexing < GameData.maxNumOfPropInPropInventory; ++indexing) | |||
| if (PropInventory[indexing] == null) | |||
| break; | |||
| return indexing; | |||
| } | |||
| #endregion | |||
| #region 感知相关的基本属性及方法 | |||
| /// <summary> | |||
| /// 是否在隐身 | |||
| /// </summary> | |||
| @@ -246,7 +222,8 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| } | |||
| #endregion | |||
| #region 交互相关的基本属性及方法 | |||
| private int timeOfOpeningOrLocking; | |||
| public int TimeOfOpeningOrLocking | |||
| { | |||
| @@ -285,49 +262,23 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 进行一次攻击 | |||
| /// </summary> | |||
| /// <returns>攻击操作发出的子弹</returns> | |||
| public Bullet? Attack(XY pos, PlaceType place) | |||
| { | |||
| if (TrySubBulletNum()) | |||
| return BulletFactory.GetBullet(this, place, pos); | |||
| else | |||
| return null; | |||
| } | |||
| /// <summary> | |||
| /// 尝试将子弹数量减1 | |||
| /// </summary> | |||
| /// <returns>减操作是否成功</returns> | |||
| private bool TrySubBulletNum() | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| if (bulletNum > 0) | |||
| { | |||
| --bulletNum; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 尝试将子弹数量加1 | |||
| /// </summary> | |||
| /// <returns>加操作是否成功</returns> | |||
| public bool TryAddBulletNum() | |||
| #endregion | |||
| #region 血量相关的基本属性及方法 | |||
| public int MaxHp { get; protected set; } // 最大血量 | |||
| protected int hp; | |||
| public int HP | |||
| { | |||
| lock (gameObjLock) | |||
| get => hp; | |||
| set | |||
| { | |||
| if (bulletNum < maxBulletNum) | |||
| if (value > 0) | |||
| { | |||
| ++bulletNum; | |||
| return true; | |||
| lock (gameObjLock) | |||
| hp = value <= MaxHp ? value : MaxHp; | |||
| } | |||
| return false; | |||
| else | |||
| lock (gameObjLock) | |||
| hp = 0; | |||
| } | |||
| } | |||
| @@ -360,101 +311,140 @@ namespace GameClass.GameObj | |||
| Debugger.Output(this, " hp has subed to: " + hp.ToString()); | |||
| return previousHp - hp; | |||
| } | |||
| /* /// <summary> | |||
| /// 增加死亡次数 | |||
| /// </summary> | |||
| /// <returns>当前死亡次数</returns> | |||
| private int AddDeathCount() | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| ++deathCount; | |||
| return deathCount; | |||
| } | |||
| }*/ | |||
| /// <summary> | |||
| /// 加分 | |||
| /// </summary> | |||
| /// <param name="add">增加量</param> | |||
| public void AddScore(int add) | |||
| private double vampire = 0; // 回血率:0-1之间 | |||
| public double Vampire | |||
| { | |||
| lock (gameObjLock) | |||
| get => vampire; | |||
| set | |||
| { | |||
| score += add; | |||
| Debugger.Output(this, " 's score has been added to: " + score.ToString()); | |||
| if (value > 1) | |||
| lock (gameObjLock) | |||
| vampire = 1; | |||
| else if (value < 0) | |||
| lock (gameObjLock) | |||
| vampire = 0; | |||
| else | |||
| lock (gameObjLock) | |||
| vampire = value; | |||
| } | |||
| } | |||
| private double oriVampire = 0; | |||
| public double OriVampire | |||
| { | |||
| get => oriVampire; | |||
| set | |||
| { | |||
| if (value > 1) | |||
| lock (gameObjLock) | |||
| vampire = 1; | |||
| else if (value < 0) | |||
| lock (gameObjLock) | |||
| vampire = 0; | |||
| else | |||
| lock (gameObjLock) | |||
| vampire = value; | |||
| } | |||
| } | |||
| #endregion | |||
| private PlayerStateType playerState = PlayerStateType.Null; | |||
| public PlayerStateType PlayerState | |||
| { | |||
| get | |||
| { | |||
| if (IsMoving) return PlayerStateType.IsMoving; | |||
| return playerState; | |||
| } | |||
| set | |||
| { | |||
| if (!(value == PlayerStateType.IsMoving)) | |||
| lock (gameObjLock) | |||
| IsMoving = false; | |||
| lock (gameObjLock) playerState = (value == PlayerStateType.IsMoving) ? PlayerStateType.Null : value; | |||
| } | |||
| } | |||
| public bool Commandable() => (playerState != PlayerStateType.IsDeceased && playerState != PlayerStateType.IsEscaped | |||
| && playerState != PlayerStateType.IsAddicted && playerState != PlayerStateType.IsRescuing | |||
| && playerState != PlayerStateType.IsSwinging && playerState != PlayerStateType.IsTryingToAttack | |||
| && playerState != PlayerStateType.IsClimbingThroughWindows && playerState != PlayerStateType.IsStunned); | |||
| public bool InteractingWithMapWithoutMoving() => (playerState == PlayerStateType.IsLockingOrOpeningTheDoor || playerState == PlayerStateType.IsFixing || playerState == PlayerStateType.IsOpeningTheChest); | |||
| public bool NullOrMoving() => (playerState == PlayerStateType.Null || playerState == PlayerStateType.IsMoving); | |||
| private int score = 0; | |||
| public int Score | |||
| { | |||
| get => score; | |||
| } | |||
| private Prop[] propInventory = new Prop[GameData.maxNumOfPropInPropInventory] | |||
| {new NullProp(), new NullProp(),new NullProp() }; | |||
| public Prop[] PropInventory | |||
| { | |||
| get => propInventory; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| propInventory = value; | |||
| Debugger.Output(this, " prop becomes " + (PropInventory == null ? "null" : PropInventory.ToString())); | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 减分 | |||
| /// 使用物品栏中的道具 | |||
| /// </summary> | |||
| /// <param name="sub">减少量</param> | |||
| public void SubScore(int sub) | |||
| /// <returns>被使用的道具</returns> | |||
| public Prop UseProp(int indexing) | |||
| { | |||
| if (indexing < 0 || indexing >= GameData.maxNumOfPropInPropInventory) | |||
| return new NullProp(); | |||
| lock (gameObjLock) | |||
| { | |||
| score -= sub; | |||
| Debugger.Output(this, " 's score has been subed to: " + score.ToString()); | |||
| Prop prop = propInventory[indexing]; | |||
| PropInventory[indexing] = new NullProp(); | |||
| return prop; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 遭受攻击 | |||
| /// 如果indexing==GameData.maxNumOfPropInPropInventory表明道具栏为满 | |||
| /// </summary> | |||
| /// <param name="subHP"></param> | |||
| /// <param name="hasSpear"></param> | |||
| /// <param name="attacker">伤害来源</param> | |||
| /// <returns>人物在受到攻击后死了吗</returns> | |||
| public bool BeAttacked(Bullet bullet) | |||
| public int IndexingOfAddProp() | |||
| { | |||
| int indexing = 0; | |||
| for (; indexing < GameData.maxNumOfPropInPropInventory; ++indexing) | |||
| if (PropInventory[indexing].GetPropType() == PropType.Null) | |||
| break; | |||
| return indexing; | |||
| } | |||
| lock (beAttackedLock) | |||
| { | |||
| if (hp <= 0) | |||
| return false; // 原来已经死了 | |||
| if (bullet.Parent.TeamID != this.TeamID) | |||
| { | |||
| if (HasShield) | |||
| { | |||
| if (bullet.HasSpear) | |||
| _ = TrySubHp(bullet.AP); | |||
| else | |||
| return false; | |||
| } | |||
| else | |||
| { | |||
| bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP))); | |||
| } | |||
| #if DEBUG | |||
| Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}."); | |||
| #endif | |||
| if (hp <= 0) | |||
| TryActivatingLIFE(); // 如果有复活甲 | |||
| } | |||
| return hp <= 0; | |||
| /// <summary> | |||
| /// 加分 | |||
| /// </summary> | |||
| /// <param name="add">增加量</param> | |||
| public void AddScore(int add) | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| score += add; | |||
| Debugger.Output(this, " 's score has been added to: " + score.ToString()); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 攻击被反弹,反弹伤害不会再被反弹 | |||
| /// 减分 | |||
| /// </summary> | |||
| /// <param name="subHP"></param> | |||
| /// <param name="hasSpear"></param> | |||
| /// <param name="bouncer">反弹伤害者</param> | |||
| /// <returns>是否因反弹伤害而死</returns> | |||
| private bool BeBounced(int subHP, bool hasSpear, Character? bouncer) | |||
| /// <param name="sub">减少量</param> | |||
| public void SubScore(int sub) | |||
| { | |||
| lock (beAttackedLock) | |||
| lock (gameObjLock) | |||
| { | |||
| if (hp <= 0) | |||
| return false; | |||
| if (!(bouncer?.TeamID == this.TeamID)) | |||
| { | |||
| if (hasSpear || !HasShield) | |||
| _ = TrySubHp(subHP); | |||
| if (hp <= 0) | |||
| TryActivatingLIFE(); | |||
| } | |||
| return hp <= 0; | |||
| score -= sub; | |||
| Debugger.Output(this, " 's score has been subed to: " + score.ToString()); | |||
| } | |||
| } | |||
| @@ -501,7 +491,6 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| } | |||
| #endregion | |||
| #region 角色拥有的buff相关属性、方法 | |||
| public void AddMoveSpeed(int buffTime, double add = 2.0) => buffManager.AddMoveSpeed(add, buffTime, newVal => | |||
| @@ -17,7 +17,7 @@ namespace GameClass.GameObj | |||
| public override bool IsRigid => true; | |||
| public override ShapeType Shape => ShapeType.Square; | |||
| private Prop[] propInChest = new Prop[GameData.maxNumOfPropInChest]; | |||
| private Prop[] propInChest = new Prop[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; | |||
| public Prop[] PropInChest => propInChest; | |||
| private bool isOpen = false; | |||
| @@ -13,11 +13,11 @@ namespace GameClass.GameObj | |||
| /// </summary> | |||
| public static uint[,] defaultMap = new uint[,] { | |||
| { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 9, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| @@ -26,8 +26,8 @@ namespace GameClass.GameObj | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 13, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 5, 7, 7, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| @@ -45,13 +45,13 @@ namespace GameClass.GameObj | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 13, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 6, 6, 6, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| @@ -60,7 +60,7 @@ namespace GameClass.GameObj | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, | |||
| { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } | |||
| }; | |||
| } | |||
| @@ -101,9 +101,9 @@ namespace GameClass.GameObj | |||
| } | |||
| public override PropType GetPropType() => PropType.Key6; | |||
| } | |||
| public sealed class Null : Prop | |||
| public sealed class NullProp : Prop | |||
| { | |||
| public Null(XY initPos, PlaceType placeType) : base(initPos, placeType) | |||
| public NullProp(PlaceType placeType = PlaceType.Wall) : base(new XY(1, 1), placeType) | |||
| { | |||
| } | |||
| public override PropType GetPropType() => PropType.Null; | |||
| @@ -25,8 +25,8 @@ namespace Gaming | |||
| { | |||
| if (player.IsResetting) | |||
| return; | |||
| Prop? prop = player.UseProp(indexing); | |||
| switch (prop?.GetPropType()) | |||
| Prop prop = player.UseProp(indexing); | |||
| switch (prop.GetPropType()) | |||
| { | |||
| case PropType.Spear: | |||
| player.AddSpear(GameData.PropDuration); | |||
| @@ -59,7 +59,7 @@ namespace Gaming | |||
| if (indexing == GameData.maxNumOfPropInPropInventory) | |||
| return false; | |||
| Prop? pickProp = null; | |||
| Prop pickProp = new NullProp(); | |||
| if (propType == PropType.Null) // 自动检查有无道具可捡 | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Prop].EnterReadLock(); | |||
| @@ -100,7 +100,7 @@ namespace Gaming | |||
| } | |||
| } | |||
| if (pickProp != null) | |||
| if (pickProp.GetPropType() != PropType.Null) | |||
| { | |||
| gameMap.Remove(pickProp); | |||
| gameMap.Add(new PickedProp(pickProp)); | |||
| @@ -114,8 +114,8 @@ namespace Gaming | |||
| { | |||
| if (!gameMap.Timer.IsGaming || player.IsResetting) | |||
| return; | |||
| Prop? prop = player.UseProp(indexing); | |||
| if (prop == null) | |||
| Prop prop = player.UseProp(indexing); | |||
| if (prop.GetPropType() == PropType.Null) | |||
| return; | |||
| prop.ReSetPos(player.Position, gameMap.GetPlaceType(player.Position)); | |||
| @@ -142,7 +142,7 @@ namespace Gaming | |||
| private Chest GetChest(Random r) | |||
| { | |||
| int index = r.Next(0, GameData.numOfChest); | |||
| while (((Chest)(gameMap.GameObjDict[GameObjType.Chest][index])).PropInChest[0] != null) index = (index + 1) % GameData.numOfChest; | |||
| while (((Chest)(gameMap.GameObjDict[GameObjType.Chest][index])).PropInChest[0].GetPropType() != PropType.Null) index = (index + 1) % GameData.numOfChest; | |||
| return (Chest)(gameMap.GameObjDict[GameObjType.Chest][index]); | |||
| } | |||
| @@ -181,7 +181,7 @@ namespace Gaming | |||
| foreach (Chest chest in gameMap.GameObjDict[GameObjType.Chest]) | |||
| { | |||
| if (chest.PropInChest[0] == null) | |||
| if (chest.PropInChest[0].GetPropType() == PropType.Null) | |||
| { | |||
| chest.PropInChest[0] = ProduceOnePropNotKey(r, chest.Position); | |||
| chest.PropInChest[1] = ProduceOnePropNotKey(r, chest.Position); | |||
| @@ -54,6 +54,7 @@ namespace Server | |||
| return Protobuf.PropType.NullPropType; | |||
| } | |||
| } | |||
| private static Protobuf.PlayerState ToPlayerState(Preparation.Utility.PlayerStateType playerState) | |||
| { | |||
| switch (playerState) | |||