From baff223bc9569ec673d2f358dc21769f8968c3d8 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Sat, 18 Mar 2023 17:22:24 +0800 Subject: [PATCH] feat: :sparkles: make maxNumOfPropInPropInventory become 3 --- .../GameClass/GameObj/Character/Character.cs | 28 ++++++++--- logic/GameClass/GameObj/Map/Chest.cs | 34 +++++++++++++ logic/GameClass/GameObj/Prop.cs | 3 +- logic/Gaming/AttackManager.cs | 15 +++--- logic/Gaming/Game.cs | 8 +-- logic/Gaming/PropManager.cs | 38 +++++--------- logic/Preparation/Utility/EnumType.cs | 2 +- logic/Preparation/Utility/GameData.cs | 50 +++++++++++-------- logic/规则Logic.md | 33 +++++++++--- 9 files changed, 138 insertions(+), 73 deletions(-) create mode 100644 logic/GameClass/GameObj/Map/Chest.cs diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index c36cf0b..ba33b4c 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -76,7 +76,7 @@ namespace GameClass.GameObj && playerState != PlayerStateType.IsAddicted && playerState != PlayerStateType.IsStunned && playerState != PlayerStateType.IsSwinging && playerState != PlayerStateType.IsTryingToAttack && playerState != PlayerStateType.IsClimbingThroughWindows); - public bool InteractingWithMapWithoutMoving() => (playerState == PlayerStateType.IsLockingTheDoor || playerState == PlayerStateType.IsFixing || playerState == PlayerStateType.IsRummagingInTheChest); + public bool InteractingWithMapWithoutMoving() => (playerState == PlayerStateType.IsLockingTheDoor || playerState == PlayerStateType.IsFixing || playerState == PlayerStateType.IsOpeningTheChest); public bool NullOrMoving() => (playerState == PlayerStateType.Null || playerState == PlayerStateType.IsMoving); // private int deathCount = 0; @@ -137,8 +137,8 @@ namespace GameClass.GameObj } } - private Prop? propInventory; - public Prop? PropInventory // 持有的道具 + private Prop[] propInventory = new Prop[GameData.maxNumOfPropInPropInventory]; + public Prop[] PropInventory { get => propInventory; set @@ -155,16 +155,30 @@ namespace GameClass.GameObj /// 使用物品栏中的道具 /// /// 被使用的道具 - public Prop? UseProp() + public Prop? UseProp(int indexing) { + if (indexing < 0 || indexing >= GameData.maxNumOfPropInPropInventory) + return null; lock (gameObjLock) { - var oldProp = PropInventory; - PropInventory = null; - return oldProp; + Prop prop = propInventory[indexing]; + PropInventory[indexing] = null; + return prop; } } + /// + /// 如果indexing==GameData.maxNumOfPropInPropInventory表明道具栏为满 + /// + public int IndexingOfAddProp() + { + int indexing = 0; + for (; indexing < GameData.maxNumOfPropInPropInventory; ++indexing) + if (PropInventory[indexing] == null) + break; + return indexing; + } + /// /// 是否在隐身 /// diff --git a/logic/GameClass/GameObj/Map/Chest.cs b/logic/GameClass/GameObj/Map/Chest.cs new file mode 100644 index 0000000..975e1cf --- /dev/null +++ b/logic/GameClass/GameObj/Map/Chest.cs @@ -0,0 +1,34 @@ +using Preparation.Utility; +using System.Collections.Generic; + +namespace GameClass.GameObj +{ + /// + /// 箱子 + /// + public class Chest : GameObj + { + public Chest(XY initPos) : + base(initPos, GameData.numOfPosGridPerCell / 2, GameObjType.Chest) + { + this.place = PlaceType.Chest; + this.CanMove = false; + } + public override bool IsRigid => true; + public override ShapeType Shape => ShapeType.Square; + + private Prop[] propInChest = new Prop[GameData.maxNumOfPropInChest]; + public Prop[] PropInChest => propInChest; + + private bool isOpen = false; + public bool IsOpen + { + get => isOpen; + set + { + lock (gameObjLock) + isOpen = value; + } + } + } +} diff --git a/logic/GameClass/GameObj/Prop.cs b/logic/GameClass/GameObj/Prop.cs index 5ebcdbd..9e4fea2 100644 --- a/logic/GameClass/GameObj/Prop.cs +++ b/logic/GameClass/GameObj/Prop.cs @@ -12,7 +12,8 @@ namespace GameClass.GameObj protected override bool IgnoreCollideExecutor(IGameObj targetObj) { - if (targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet || targetObj.Type == GameObjType.Character) + if (targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet + || targetObj.Type == GameObjType.Character || targetObj.Type == GameObjType.Chest) return true; return false; } diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index d2f8b36..55dd75d 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -108,17 +108,16 @@ namespace Gaming // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); // } - Prop? dropProp = null; - if (player.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 + for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++) { - dropProp = player.PropInventory; - XY res = GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell); - dropProp.ReSetPos(res, gameMap.GetPlaceType(res)); + Prop? prop = player.UseProp(i); + if (prop != null) + { + prop.ReSetPos(player.Position, gameMap.GetPlaceType(player.Position)); + gameMap.Add(prop); + } } - if (dropProp != null) - gameMap.Add(dropProp); - // player.Reset(); // ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index efd4232..45f6729 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -293,24 +293,24 @@ namespace Gaming _ = attackManager.Attack(player, angle); } } - public void UseProp(long playerID) + public void UseProp(long playerID, int indexing) { if (!gameMap.Timer.IsGaming) return; Character? player = gameMap.FindPlayer(playerID); if (player != null) { - propManager.UseProp(player); + propManager.UseProp(player, indexing); } } - public void ThrowProp(long playerID, int timeInmillionSeconds, double angle) + public void ThrowProp(long playerID, int indexing) { if (!gameMap.Timer.IsGaming) return; Character? player = gameMap.FindPlayer(playerID); if (player != null) { - propManager.ThrowProp(player, timeInmillionSeconds, angle); + propManager.ThrowProp(player, indexing); } } public bool PickProp(long playerID, PropType propType = PropType.Null) diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index 65a8faa..d84787a 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -28,11 +28,11 @@ namespace Gaming ProduceProp(); } - public void UseProp(Character player) + public void UseProp(Character player, int indexing) { if (player.IsResetting) return; - Prop? prop = player.UseProp(); + Prop? prop = player.UseProp(indexing); switch (prop?.GetPropType()) { case PropType.Spear: @@ -62,6 +62,10 @@ namespace Gaming { if (player.IsResetting) return false; + int indexing = player.IndexingOfAddProp(); + if (indexing == GameData.maxNumOfPropInPropInventory) + return false; + Prop? pickProp = null; if (propType == PropType.Null) // 自动检查有无道具可捡 { @@ -70,9 +74,9 @@ namespace Gaming { foreach (Prop prop in gameMap.GameObjDict[GameObjType.Prop]) { - if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false) + if (GameData.IsInTheSameCell(prop.Position, player.Position)) { - pickProp = prop; + player.PropInventory[indexing] = prop; } } } @@ -92,7 +96,7 @@ namespace Gaming { if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false) { - pickProp = prop; + player.PropInventory[indexing] = prop; } } } @@ -105,42 +109,26 @@ namespace Gaming if (pickProp != null) { - // pickProp.CanMove = false; - Prop? dropProp = null; - if (player.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 - { - dropProp = player.PropInventory; - XY res = GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell); - dropProp.ReSetPos(res, gameMap.GetPlaceType(res)); - } - player.PropInventory = pickProp; gameMap.Remove(pickProp); - if (dropProp != null) gameMap.Add(dropProp); gameMap.Add(new PickedProp(pickProp)); - return true; } else return false; } - public void ThrowProp(Character player, int timeInMilliseconds, double angle) + public void ThrowProp(Character player, int indexing) { - if (!gameMap.Timer.IsGaming) - return; - if (player.IsResetting) // 移动中也能扔,但由于“惯性”,可能初始位置会有点变化 + if (!gameMap.Timer.IsGaming || player.IsResetting) return; - Prop? prop = player.UseProp(); + Prop? prop = player.UseProp(indexing); if (prop == null) return; - prop.CanMove = true; prop.ReSetPos(player.Position, gameMap.GetPlaceType(player.Position)); gameMap.Add(prop); - - timeInMilliseconds = timeInMilliseconds < GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000 ? timeInMilliseconds : GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000; - moveEngine.MoveObj(prop, timeInMilliseconds, angle); } + private void ProduceProp() { int len = availableCellForGenerateProp.Count; diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index afdb24e..5247c50 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -20,7 +20,7 @@ namespace Preparation.Utility IsStunned = 11, IsTryingToAttack = 12,//指前摇 IsLockingTheDoor = 13, - IsRummagingInTheChest = 14, + IsOpeningTheChest = 14, IsClimbingThroughWindows = 15, IsUsingSpecialSkill = 16, } diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 4abb2ad..b1e5b2b 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -52,39 +52,28 @@ namespace Preparation.Utility #endregion #region 角色相关 - public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径 - public const int basicApOfGhost = 1500000; // 攻击力 + public const int characterRadius = numOfPosGridPerCell / 2 / 5 * 4; // 人物半径 + public const int basicTreatSpeed = 100; public const int basicFixSpeed = 100; + public const int basicTimeOfOpeningOrLocking = 3000; + public const int basicTimeOfClimbingThroughWindows = 870; + + public const int basicHp = 3000000; // 初始血量 public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 public const int BeginGamingAddiction = 10003; public const int MidGamingAddiction = 30000; public const int basicTreatmentDegree = 1500000; public const int basicRescueDegree = 100000; - public const int basicHp = 3000000; // 初始血量 - public const int basicCD = 3000; // 初始子弹冷却 - public const int basicCastTime = 500;//基本前摇时间 - public const int basicBackswing = 500;//基本后摇时间 - public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长 - public const int basicBulletNum = 3; // 基本初始子弹量 - public const int MinAP = 0; // 最小攻击力 - public const int MaxAP = int.MaxValue; // 最大攻击力 - public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围 - public const double basicAttackShortRange = 2700; // 基本近程攻击范围 - public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围 + public const int basicMoveSpeed = 1260; // 基本移动速度,单位:s-1 - public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1 public const int characterMaxSpeed = 12000; // 最大速度 + public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1 + public const double basicConcealment = 1.0; public const int basicAlertnessRadius = 30700; - public const int basicTimeOfOpeningOrLocking = 3000; - public const int basicTimeOfClimbingThroughWindows = 870; + public const int maxNumOfPropInPropInventory = 3; public const int addScoreWhenKillOneLevelPlayer = 30; // 击杀一级角色获得的加分 - public const int commonSkillCD = 30000; // 普通技能标准冷却时间 - public const int commonSkillTime = 10000; // 普通技能标准持续时间 - public const int bulletRadius = 200; // 默认子弹半径 - public const int reviveTime = 30000; // 复活时间 - public const int shieldTimeAtBirth = 3000; // 复活时的护盾时间 public static XY PosWhoDie = new XY(1, 1); @@ -97,7 +86,25 @@ namespace Preparation.Utility }; } #endregion + #region 攻击与子弹相关 + public const int basicApOfGhost = 1500000; // 捣蛋鬼攻击力 + public const int MinAP = 0; // 最小攻击力 + public const int MaxAP = int.MaxValue; // 最大攻击力 + + public const int basicCD = 3000; // 初始子弹冷却 + public const int basicCastTime = 500;//基本前摇时间 + public const int basicBackswing = 500;//基本后摇时间 + public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长 + + public const int bulletRadius = 200; // 默认子弹半径 + public const int basicBulletNum = 3; // 基本初始子弹量 + public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围 + public const double basicAttackShortRange = 2700; // 基本近程攻击范围 + public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围 + #endregion #region 技能相关 + public const int commonSkillCD = 30000; // 普通技能标准冷却时间 + public const int commonSkillTime = 10000; // 普通技能标准持续时间 /// /// BeginToCharge /// @@ -117,6 +124,7 @@ namespace Preparation.Utility #endregion #region 物体相关 public const int degreeOfFixedGenerator = 10300000; + public const int maxNumOfPropInChest = 2; #endregion #region 游戏帧相关 public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 diff --git a/logic/规则Logic.md b/logic/规则Logic.md index eae9bf4..aa881fb 100644 --- a/logic/规则Logic.md +++ b/logic/规则Logic.md @@ -94,7 +94,7 @@ IsStunned = 11, IsTryingToAttack = 12,//指前摇 IsLockingTheDoor = 13, - IsRummagingInTheChest = 14, + IsOpeningTheChest = 14, IsClimbingThroughWindows = 15, IsUsingSpecialSkill = 16, } @@ -111,7 +111,7 @@ - ~~回血率/原始回血率~~ - 当前子弹类型 - 原始子弹类型 -- 持有道具 *(最多三个)(列表)* +- 持有道具 (最多三个)(数组) - 是否隐身 - 队伍ID - 玩家ID @@ -221,7 +221,7 @@ 3. 修理电机 4. 开锁门 5. 翻窗 -6. 翻找箱子 +6. 开启箱子 ### 门 - *门分别属于三个教学区:三教,五教,六教* @@ -238,10 +238,31 @@ - *翻越窗户是一种交互行为,执行时,实质是限定方向的减速运动* ### 箱子 -- *监管者和求生者都能与箱子交互,同一时刻就允许一人进行翻找* +- *监管者和求生者都能与箱子交互,同一时刻只允许一人进行开启* - *开启箱子有不同概率获得不同道具。* -- *搜寻物品的基础持续时间为10秒。* -- *未搜寻完成的箱子在下一次需要重新开始搜寻。* +- *开启箱子的基础持续时间为10秒。* +- *未开启完成的箱子在下一次需要重新开始开启。* +- *箱子开启后其中道具才可以被观测和拿取* +- [箱子道具不刷新] +- [箱子不可被关闭] +- [箱子内道具最多两个] + +### 道具 +- 每次玩家试图捡起道具时,需要确保道具栏有空位 +- indexing指道具栏数组下标从0开始 +- 扔道具 + - Logic内实现 + ~~~csharp + public void ThrowProp(long playerID, int indexing) + ~~~ + - 对应下标出现空位,不会对数组进行重新排序 +- 使用道具 + - Logic内实现 + ~~~csharp + public void UseProp(long playerID,int indexing) + ~~~ + - 对应下标出现空位,不会对数组进行重新排序 + ### 治疗 - 可行动的求生者可以对受伤的其他求生者进行治疗,治疗完成后会回复被治疗程度的血量。