From 898d9af4209a3cb6ab02a67ecd6d2de3fbac3927 Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 27 May 2023 03:39:42 +0800
Subject: [PATCH 1/8] refactor: :lock: lock the treatSpeed
---
.../GameClass/GameObj/Character/Character.Skill.cs | 2 +-
.../GameObj/Character/Character.Student.cs | 13 +++++++++----
logic/GameClass/GameObj/Moveable.cs | 3 ++-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs
index f2d887e..1f00ef3 100644
--- a/logic/GameClass/GameObj/Character/Character.Skill.cs
+++ b/logic/GameClass/GameObj/Character/Character.Skill.cs
@@ -36,7 +36,7 @@ namespace GameClass.GameObj
this.buffManager = new BuffManager();
this.occupation = OccupationFactory.FindIOccupation(characterType);
this.MaxHp = this.hp = Occupation.MaxHp;
- this.MoveSpeed = this.OrgMoveSpeed = Occupation.MoveSpeed;
+ this.MoveSpeed = this.orgMoveSpeed = Occupation.MoveSpeed;
this.BulletOfPlayer = this.OriBulletOfPlayer = Occupation.InitBullet;
this.concealment = Occupation.Concealment;
this.alertnessRadius = Occupation.AlertnessRadius;
diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs
index d0a4902..a068eae 100644
--- a/logic/GameClass/GameObj/Character/Character.Student.cs
+++ b/logic/GameClass/GameObj/Character/Character.Student.cs
@@ -32,19 +32,24 @@ namespace GameClass.GameObj
///
protected readonly int orgFixSpeed;
+ private readonly object treatLock = new();
protected int treatSpeed = GameData.basicTreatSpeed;
public int TreatSpeed
{
- get => treatSpeed;
+ get
+ {
+ lock (treatLock)
+ return treatSpeed;
+ }
set
{
- lock (gameObjLock)
+ lock (treatLock)
{
treatSpeed = value;
}
}
}
- public int OrgTreatSpeed { get; protected set; }
+ protected readonly int orgTreatSpeed;
public int MaxGamingAddiction { get; protected set; }
private int gamingAddiction;
@@ -128,7 +133,7 @@ namespace GameClass.GameObj
public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType)
{
this.orgFixSpeed = this.fixSpeed = ((IStudentType)Occupation).FixSpeed;
- this.TreatSpeed = this.OrgTreatSpeed = ((IStudentType)Occupation).TreatSpeed;
+ this.TreatSpeed = this.orgTreatSpeed = ((IStudentType)Occupation).TreatSpeed;
this.MaxGamingAddiction = ((IStudentType)Occupation).MaxGamingAddiction;
}
}
diff --git a/logic/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs
index 9d3cd00..1652e9f 100644
--- a/logic/GameClass/GameObj/Moveable.cs
+++ b/logic/GameClass/GameObj/Moveable.cs
@@ -127,7 +127,8 @@ namespace GameClass.GameObj
///
/// 原初移动速度
///
- public int OrgMoveSpeed { get; protected set; }
+ protected int orgMoveSpeed;
+ public int OrgMoveSpeed => orgMoveSpeed;
/* ///
/// 复活时数据重置
From ab65b563a5d37b22082f6b7ae93ad83105da5d31 Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 27 May 2023 03:55:31 +0800
Subject: [PATCH 2/8] perf: :lock: add the addictionLock
---
.../GameObj/Character/Character.Student.cs | 31 ++++++++++++++++---
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs
index a068eae..6c2eebf 100644
--- a/logic/GameClass/GameObj/Character/Character.Student.cs
+++ b/logic/GameClass/GameObj/Character/Character.Student.cs
@@ -51,18 +51,39 @@ namespace GameClass.GameObj
}
protected readonly int orgTreatSpeed;
- public int MaxGamingAddiction { get; protected set; }
+ private readonly object addictionLock = new();
+ private int maxGamingAddiction;
+ public int MaxGamingAddiction
+ {
+ get
+ {
+ lock (addictionLock)
+ return maxGamingAddiction;
+ }
+ protected set
+ {
+ lock (addictionLock)
+ {
+ if (value < gamingAddiction) gamingAddiction = value;
+ maxGamingAddiction = value;
+ }
+ }
+ }
private int gamingAddiction;
public int GamingAddiction
{
- get => gamingAddiction;
+ get
+ {
+ lock (addictionLock)
+ return gamingAddiction;
+ }
set
{
if (value > 0)
- lock (gameObjLock)
- gamingAddiction = value <= MaxGamingAddiction ? value : MaxGamingAddiction;
+ lock (addictionLock)
+ gamingAddiction = value <= maxGamingAddiction ? value : maxGamingAddiction;
else
- lock (gameObjLock)
+ lock (addictionLock)
gamingAddiction = 0;
}
}
From 770115a6c9c8d36e45a861f14d4c26126415884d Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 27 May 2023 14:46:37 +0800
Subject: [PATCH 3/8] perf: :zap: delete the faceDirection of Immovable and add
the attackLock
---
logic/GameClass/GameObj/Bullet/BombedBullet.cs | 3 ++-
.../GameObj/Character/Character.Student.cs | 11 -----------
logic/GameClass/GameObj/Character/Character.cs | 17 +++++++++--------
logic/GameClass/GameObj/GameObj.cs | 3 ---
logic/GameClass/GameObj/Immovable.cs | 2 --
logic/GameClass/GameObj/Moveable.cs | 8 +++++++-
logic/Preparation/Interface/IGameObj.cs | 1 -
logic/Preparation/Interface/IMoveable.cs | 1 +
8 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/logic/GameClass/GameObj/Bullet/BombedBullet.cs b/logic/GameClass/GameObj/Bullet/BombedBullet.cs
index 492ecb8..8f3f327 100644
--- a/logic/GameClass/GameObj/Bullet/BombedBullet.cs
+++ b/logic/GameClass/GameObj/Bullet/BombedBullet.cs
@@ -8,7 +8,8 @@ namespace GameClass.GameObj
public override ShapeType Shape => ShapeType.Circle;
public override bool IsRigid => false;
public long MappingID { get; }
- public Bullet bulletHasBombed;
+ public readonly Bullet bulletHasBombed;
+ public readonly XY facingDirection;
public BombedBullet(Bullet bullet) :
base(bullet.Position, bullet.Radius, GameObjType.BombedBullet)
diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs
index 6c2eebf..ed34031 100644
--- a/logic/GameClass/GameObj/Character/Character.Student.cs
+++ b/logic/GameClass/GameObj/Character/Character.Student.cs
@@ -88,17 +88,6 @@ namespace GameClass.GameObj
}
}
- private int selfHealingTimes = 1;//剩余的自愈次数
- public int SelfHealingTimes
- {
- get => selfHealingTimes;
- set
- {
- lock (gameObjLock)
- selfHealingTimes = (value > 0) ? value : 0;
- }
- }
-
private int degreeOfTreatment = 0;
public int DegreeOfTreatment
{
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index 3e6b937..22f8134 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -17,6 +17,7 @@ namespace GameClass.GameObj
public object InventoryLock => inventoryLock;
#region 装弹、攻击相关的基本属性及方法
+ private readonly object attackLock = new();
///
/// 装弹冷却
///
@@ -25,7 +26,7 @@ namespace GameClass.GameObj
{
get
{
- lock (actionLock)
+ lock (attackLock)
{
return cd;
}
@@ -36,7 +37,7 @@ namespace GameClass.GameObj
{
get
{
- lock (actionLock)
+ lock (attackLock)
return orgCD;
}
}
@@ -47,14 +48,14 @@ namespace GameClass.GameObj
{
get
{
- lock (actionLock)
+ lock (attackLock)
{
return bulletOfPlayer;
}
}
set
{
- lock (actionLock)
+ lock (attackLock)
{
bulletOfPlayer = value;
cd = orgCD = (BulletFactory.BulletCD(value));
@@ -69,7 +70,7 @@ namespace GameClass.GameObj
{
get
{
- lock (actionLock)
+ lock (attackLock)
{
return maxBulletNum;
}
@@ -80,7 +81,7 @@ namespace GameClass.GameObj
public int UpdateBulletNum(int time)
{
- lock (actionLock)
+ lock (attackLock)
{
if (bulletNum < maxBulletNum)
{
@@ -98,7 +99,7 @@ namespace GameClass.GameObj
/// 攻击操作发出的子弹
public Bullet? Attack(double angle, int time)
{
- lock (actionLock)
+ lock (attackLock)
{
if (bulletOfPlayer == BulletType.Null)
return null;
@@ -115,7 +116,7 @@ namespace GameClass.GameObj
Bullet? bullet = BulletFactory.GetBullet(this, res, this.bulletOfPlayer);
if (bullet == null) return null;
if (TryAddAp()) bullet.AddAP(GameData.ApPropAdd);
- facingDirection = new(angle, bullet.AttackDistance);
+ FacingDirection = new(angle, bullet.AttackDistance);
return bullet;
}
else
diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs
index c528b52..0e070e2 100644
--- a/logic/GameClass/GameObj/GameObj.cs
+++ b/logic/GameClass/GameObj/GameObj.cs
@@ -26,9 +26,6 @@ namespace GameClass.GameObj
protected XY position;
public abstract XY Position { get; }
- protected XY facingDirection = new(1, 0);
- public abstract XY FacingDirection { get; }
-
public abstract bool CanMove { get; }
public abstract bool IsRigid { get; }
diff --git a/logic/GameClass/GameObj/Immovable.cs b/logic/GameClass/GameObj/Immovable.cs
index 8820399..f6f496b 100644
--- a/logic/GameClass/GameObj/Immovable.cs
+++ b/logic/GameClass/GameObj/Immovable.cs
@@ -7,8 +7,6 @@ namespace GameClass.GameObj
public override XY Position => position;
- public override XY FacingDirection => facingDirection;
-
public override bool CanMove => false;
public Immovable(XY initPos, int initRadius, GameObjType initType) : base(initPos, initRadius, initType)
diff --git a/logic/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs
index 1652e9f..85d9e83 100644
--- a/logic/GameClass/GameObj/Moveable.cs
+++ b/logic/GameClass/GameObj/Moveable.cs
@@ -52,13 +52,19 @@ namespace GameClass.GameObj
}
}
- public override XY FacingDirection
+ protected XY facingDirection = new(1, 0);
+ public XY FacingDirection
{
get
{
lock (actionLock)
return facingDirection;
}
+ set
+ {
+ lock (actionLock)
+ facingDirection = value;
+ }
}
private int isMoving = 0;
diff --git a/logic/Preparation/Interface/IGameObj.cs b/logic/Preparation/Interface/IGameObj.cs
index 017226f..74699e5 100644
--- a/logic/Preparation/Interface/IGameObj.cs
+++ b/logic/Preparation/Interface/IGameObj.cs
@@ -7,7 +7,6 @@ namespace Preparation.Interface
public GameObjType Type { get; }
public long ID { get; }
public XY Position { get; } // if Square, Pos equals the center
- public XY FacingDirection { get; }
public bool IsRigid { get; }
public ShapeType Shape { get; }
public bool CanMove { get; }
diff --git a/logic/Preparation/Interface/IMoveable.cs b/logic/Preparation/Interface/IMoveable.cs
index ad87c31..6854d15 100644
--- a/logic/Preparation/Interface/IMoveable.cs
+++ b/logic/Preparation/Interface/IMoveable.cs
@@ -6,6 +6,7 @@ namespace Preparation.Interface
{
public interface IMoveable : IGameObj
{
+ public XY FacingDirection { get; set; }
object ActionLock { get; }
public int MoveSpeed { get; }
public bool IsMoving { get; set; }
From 02231accf25a9dcea0246262e11c176b267cc3c8 Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 27 May 2023 19:09:47 +0800
Subject: [PATCH 4/8] chore: :art: add some notes
---
.../GameClass/GameObj/Character/Character.cs | 23 ++++++++++---------
logic/GameClass/GameObj/Moveable.cs | 2 +-
logic/Server/CopyInfo.cs | 2 +-
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index 22f8134..d6565f6 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -8,14 +8,6 @@ namespace GameClass.GameObj
{
public partial class Character : Moveable, ICharacter // 负责人LHR摆烂终了
{
-
- private readonly ReaderWriterLockSlim hpReaderWriterLock = new();
- public ReaderWriterLockSlim HPReadWriterLock => hpReaderWriterLock;
- private readonly object vampireLock = new();
- public object VampireLock => vampire;
- private readonly object inventoryLock = new();
- public object InventoryLock => inventoryLock;
-
#region 装弹、攻击相关的基本属性及方法
private readonly object attackLock = new();
///
@@ -79,17 +71,17 @@ namespace GameClass.GameObj
private int bulletNum;
private int updateTimeOfBulletNum = 0;
- public int UpdateBulletNum(int time)
+ public int UpdateBulletNum(int time)//通过该函数获取真正的bulletNum
{
lock (attackLock)
{
- if (bulletNum < maxBulletNum)
+ if (bulletNum < maxBulletNum && time - updateTimeOfBulletNum >= cd)
{
int add = Math.Min(maxBulletNum - bulletNum, (time - updateTimeOfBulletNum) / cd);
updateTimeOfBulletNum += add * cd;
return (bulletNum += add);
}
- return maxBulletNum;
+ return bulletNum;
}
}
@@ -195,6 +187,9 @@ namespace GameClass.GameObj
}
#endregion
#region 血量相关的基本属性及方法
+ private readonly ReaderWriterLockSlim hpReaderWriterLock = new();
+ public ReaderWriterLockSlim HPReadWriterLock => hpReaderWriterLock;
+
private long maxHp;
public long MaxHp
{
@@ -285,6 +280,9 @@ namespace GameClass.GameObj
}
}
+ private readonly object vampireLock = new();
+ public object VampireLock => vampire;
+
private double vampire = 0; // 回血率:0-1之间
public double Vampire
{
@@ -620,6 +618,9 @@ namespace GameClass.GameObj
}
#region 道具和buff相关属性、方法
+ private readonly object inventoryLock = new();
+ public object InventoryLock => inventoryLock;
+
private Gadget[] propInventory = new Gadget[GameData.maxNumOfPropInPropInventory]
{new NullProp(), new NullProp(),new NullProp() };
public Gadget[] PropInventory
diff --git a/logic/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs
index 85d9e83..41f1ea5 100644
--- a/logic/GameClass/GameObj/Moveable.cs
+++ b/logic/GameClass/GameObj/Moveable.cs
@@ -8,7 +8,7 @@ namespace GameClass.GameObj
{
protected readonly object actionLock = new();
public object ActionLock => actionLock;
- //player.actionLock>其他.actionLock
+ //player.actionLock>其他.actionLock/其他Lock,应当避免两个player的actionlock互锁
private readonly ReaderWriterLockSlim moveReaderWriterLock = new();
public ReaderWriterLockSlim MoveReaderWriterLock => moveReaderWriterLock;
//规定moveReaderWriterLock
Date: Sat, 27 May 2023 19:39:50 +0800
Subject: [PATCH 5/8] chore: :construction: Rename UseProp to ConsumeProp
---
.../GameObj/Character/Character.Skill.cs | 3 --
.../GameClass/GameObj/Character/Character.cs | 36 ++++++++++---------
logic/Gaming/CharacterManager.cs | 2 +-
logic/Gaming/Game.cs | 2 +-
logic/Gaming/PropManager.cs | 6 ++--
logic/Server/RpcServices.cs | 2 +-
6 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs
index 1f00ef3..b57c3a5 100644
--- a/logic/GameClass/GameObj/Character/Character.Skill.cs
+++ b/logic/GameClass/GameObj/Character/Character.Skill.cs
@@ -50,9 +50,6 @@ namespace GameClass.GameObj
{
this.ActiveSkillDictionary.Add(activeSkill, SkillFactory.FindActiveSkill(activeSkill));
}
-
- // UsePassiveSkill(); //这一过程放到gamestart时进行
-
Debugger.Output(this, "constructed!");
}
}
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index d6565f6..68dfdcc 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -306,7 +306,7 @@ namespace GameClass.GameObj
}
public double OriVampire { get; protected set; }
#endregion
- #region 状态相关的基本属性与方法
+ #region 查询状态相关的基本属性与方法
private PlayerStateType playerState = PlayerStateType.Null;
public PlayerStateType PlayerState
{
@@ -370,6 +370,8 @@ namespace GameClass.GameObj
|| playerState == PlayerStateType.Stunned || playerState == PlayerStateType.Charmed
|| playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving);
}
+ #endregion
+ #region 更改状态相关的属性和方法
private GameObj? whatInteractingWith = null;
public GameObj? WhatInteractingWith
{
@@ -382,19 +384,6 @@ namespace GameClass.GameObj
}
}
- public bool StartThread(long stateNum, RunningStateType runningState)
- {
- lock (ActionLock)
- {
- if (this.StateNum == stateNum)
- {
- this.runningState = runningState;
- return true;
- }
- }
- return false;
- }
-
private long ChangePlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
{
//只能被SetPlayerState引用
@@ -572,6 +561,19 @@ namespace GameClass.GameObj
}
}
+ public bool StartThread(long stateNum, RunningStateType runningState)
+ {
+ lock (ActionLock)
+ {
+ if (this.StateNum == stateNum)
+ {
+ this.runningState = runningState;
+ return true;
+ }
+ }
+ return false;
+ }
+
public bool TryToRemoveFromGame(PlayerStateType playerStateType)
{
lock (actionLock)
@@ -641,7 +643,7 @@ namespace GameClass.GameObj
/// 使用物品栏中的道具
///
/// 被使用的道具
- public Gadget UseProp(int indexing)
+ public Gadget ConsumeProp(int indexing)
{
if (indexing < 0 || indexing >= GameData.maxNumOfPropInPropInventory)
return new NullProp();
@@ -654,7 +656,7 @@ namespace GameClass.GameObj
}
}
- public Gadget UseProp(PropType propType)
+ public Gadget ConsumeProp(PropType propType)
{
if (propType == PropType.Null)
{
@@ -689,7 +691,7 @@ namespace GameClass.GameObj
return new NullProp();
}
- public bool UseTool(PropType propType)
+ public bool UseTool(PropType propType)//占用道具,使其不能重复使用和被消耗
{
lock (inventoryLock)
{
diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs
index a95ca20..53903ce 100644
--- a/logic/Gaming/CharacterManager.cs
+++ b/logic/Gaming/CharacterManager.cs
@@ -393,7 +393,7 @@ namespace Gaming
for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++)
{
- Gadget? prop = player.UseProp(i);
+ Gadget? prop = player.ConsumeProp(i);
if (prop != null)
{
prop.ReSetPos(player.Position);
diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs
index 04af9bd..c9a7268 100644
--- a/logic/Gaming/Game.cs
+++ b/logic/Gaming/Game.cs
@@ -238,7 +238,7 @@ namespace Gaming
Character? player = gameMap.FindPlayerToAction(playerID);
if (player != null)
{
- propManager.UseProp(player, propType);
+ propManager.ConsumeProp(player, propType);
}
}
public void ThrowProp(long playerID, PropType propType = PropType.Null)
diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs
index 5127f64..7bd672b 100644
--- a/logic/Gaming/PropManager.cs
+++ b/logic/Gaming/PropManager.cs
@@ -17,11 +17,11 @@ namespace Gaming
private readonly CharacterManager characterManager;
private readonly List availableCellForGenerateProp;
- public void UseProp(Character player, PropType propType)
+ public void ConsumeProp(Character player, PropType propType)
{
if (player.CharacterType == CharacterType.Robot || player.IsRemoved)
return;
- Gadget prop = player.UseProp(propType);
+ Gadget prop = player.ConsumeProp(propType);
switch (prop.GetPropType())
{
case PropType.ShieldOrSpear:
@@ -117,7 +117,7 @@ namespace Gaming
{
if (!gameMap.Timer.IsGaming || player.IsRemoved)
return;
- Gadget prop = player.UseProp(propType);
+ Gadget prop = player.ConsumeProp(propType);
if (prop.GetPropType() == PropType.Null)
return;
diff --git a/logic/Server/RpcServices.cs b/logic/Server/RpcServices.cs
index f624250..10af4b9 100644
--- a/logic/Server/RpcServices.cs
+++ b/logic/Server/RpcServices.cs
@@ -305,7 +305,7 @@ namespace Server
public override Task UseProp(PropMsg request, ServerCallContext context)
{
#if DEBUG
- Console.WriteLine($"UseProp ID: {request.PlayerId}");
+ Console.WriteLine($"ConsumeProp ID: {request.PlayerId}");
#endif
BoolRes boolRes = new();
if (request.PlayerId >= spectatorMinPlayerID)
From e06638d9f00748021c345e3be0aebef0438125ec Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sun, 28 May 2023 02:05:11 +0800
Subject: [PATCH 6/8] refactor: :lock: add a lock for the degreeTreatment
---
docs/GameRules.md | 7 ++-
.../GameObj/Character/Character.Student.cs | 38 -------------
.../GameClass/GameObj/Character/Character.cs | 57 +++++++++++++++++++
3 files changed, 63 insertions(+), 39 deletions(-)
diff --git a/docs/GameRules.md b/docs/GameRules.md
index 6511cf9..e007606 100644
--- a/docs/GameRules.md
+++ b/docs/GameRules.md
@@ -277,7 +277,12 @@ $$
- 主动技能
0. 惩罚 Punish
- CD:45s
- - “使用瞬间,在视野距离/3范围内(不是可视范围)的翻窗、开锁门、攻击前后摇、使用技能期间的捣蛋鬼会被眩晕(3070+$\frac{500×已受伤害}{基本伤害(1500000)×2^{开局老师数量-1}}$)ms”
+ - 使用瞬间,在视野距离/3范围内(不是可视范围)的翻窗、开锁门、攻击前后摇、使用技能期间的捣蛋鬼会被眩晕
+
+ $$
+ (3070+\frac{500×已受伤害}{基本伤害(1500000)×2^{开局老师数量-1}})ms
+ $$
+
- 其眩晕得分为正常眩晕得分/2^开局老师数量-1^
1. 喝茶 HaveTea
- CD:90s
diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs
index ed34031..89d64b4 100644
--- a/logic/GameClass/GameObj/Character/Character.Student.cs
+++ b/logic/GameClass/GameObj/Character/Character.Student.cs
@@ -88,44 +88,6 @@ namespace GameClass.GameObj
}
}
- private int degreeOfTreatment = 0;
- public int DegreeOfTreatment
- {
- get => degreeOfTreatment;
- private set
- {
- degreeOfTreatment = value;
- }
- }
- public void SetDegreeOfTreatment0()
- {
- DegreeOfTreatment = 0;
- }
- public bool SetDegreeOfTreatment(int value, Student whoTreatYou)
- {
- if (value <= 0) { degreeOfTreatment = 0; return false; }
- if (value >= MaxHp - HP)
- {
- whoTreatYou.AddScore(GameData.StudentScoreTreat(MaxHp - HP));
- HP = MaxHp;
- degreeOfTreatment = 0;
- return true;
- }
- if (value >= GameData.basicTreatmentDegree)
- {
- whoTreatYou.AddScore(GameData.StudentScoreTreat(GameData.basicTreatmentDegree));
- HP += GameData.basicTreatmentDegree;
- DegreeOfTreatment = 0;
- return true;
- }
- DegreeOfTreatment = value;
- return false;
- }
- public bool AddDegreeOfTreatment(int value, Student student)
- {
- return SetDegreeOfTreatment(value + degreeOfTreatment, student);
- }
-
private int timeOfRescue = 0;
public int TimeOfRescue
{
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index 68dfdcc..e6d0ae3 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -305,6 +305,63 @@ namespace GameClass.GameObj
}
}
public double OriVampire { get; protected set; }
+
+ private readonly object treatLock = new();
+ private int degreeOfTreatment = 0;
+ public int DegreeOfTreatment
+ {
+ get
+ {
+ HPReadWriterLock.EnterReadLock();
+ try
+ {
+ return degreeOfTreatment;
+ }
+ finally
+ {
+ HPReadWriterLock.ExitReadLock();
+ }
+ }
+ }
+ public void SetDegreeOfTreatment0()
+ {
+ HPReadWriterLock.EnterWriteLock();
+ try
+ {
+ degreeOfTreatment = 0;
+ }
+ finally
+ {
+ HPReadWriterLock.ExitWriteLock();
+ }
+ }
+ public bool AddDegreeOfTreatment(int value, Student whoTreatYou)
+ {
+ HPReadWriterLock.EnterWriteLock();
+ try
+ {
+ if (value >= maxHp - hp)
+ {
+ whoTreatYou.AddScore(GameData.StudentScoreTreat(maxHp - hp));
+ hp = maxHp;
+ degreeOfTreatment = 0;
+ return true;
+ }
+ if (value >= GameData.basicTreatmentDegree)
+ {
+ whoTreatYou.AddScore(GameData.StudentScoreTreat(GameData.basicTreatmentDegree));
+ hp += GameData.basicTreatmentDegree;
+ degreeOfTreatment = 0;
+ return true;
+ }
+ degreeOfTreatment = value;
+ }
+ finally
+ {
+ HPReadWriterLock.ExitWriteLock();
+ }
+ return false;
+ }
#endregion
#region 查询状态相关的基本属性与方法
private PlayerStateType playerState = PlayerStateType.Null;
From 8f1af377141b716ddd8b37870c428edacf48e8b5 Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sun, 28 May 2023 02:50:55 +0800
Subject: [PATCH 7/8] perf: :lock: Interlock the lockDegree and lock the parent
---
.../GameObj/Character/Character.Student.cs | 9 +++++++--
logic/GameClass/GameObj/Map/Door.cs | 20 +++++++------------
logic/Gaming/ActionManager.cs | 5 +++--
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs
index 89d64b4..1b52f08 100644
--- a/logic/GameClass/GameObj/Character/Character.Student.cs
+++ b/logic/GameClass/GameObj/Character/Character.Student.cs
@@ -111,13 +111,18 @@ namespace GameClass.GameObj
}
public class Golem : Student, IGolem
{
+ private readonly object parentLock = new();
private Character? parent; // 主人
public Character? Parent
{
- get => parent;
+ get
+ {
+ lock (parentLock)
+ return parent;
+ }
set
{
- lock (gameObjLock)
+ lock (parentLock)
{
parent = value;
}
diff --git a/logic/GameClass/GameObj/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs
index ab459b5..ab63c62 100644
--- a/logic/GameClass/GameObj/Map/Door.cs
+++ b/logic/GameClass/GameObj/Map/Door.cs
@@ -57,17 +57,11 @@ namespace GameClass.GameObj
private int lockDegree = 0;
public int LockDegree
{
- get
- {
- lock (gameObjLock)
- return lockDegree;
- }
- set
- {
- value = (value > GameData.degreeOfLockingOrOpeningTheDoor) ? GameData.degreeOfLockingOrOpeningTheDoor : value;
- lock (gameObjLock)
- lockDegree = value;
- }
+ get => Interlocked.CompareExchange(ref lockDegree, -1, -1);
+ }
+ public int AddLockDegree(int add)
+ {
+ return Interlocked.Add(ref lockDegree, add);
}
private long openStartTime = 0;
@@ -119,7 +113,7 @@ namespace GameClass.GameObj
{
if (!isOpen) return false;
if (whoLockOrOpen != null) return false;
- lockDegree = 0;
+ Interlocked.Exchange(ref lockDegree, 0);
whoLockOrOpen = character;
return true;
}
@@ -128,7 +122,7 @@ namespace GameClass.GameObj
{
lock (gameObjLock)
{
- if (lockDegree >= GameData.degreeOfLockingOrOpeningTheDoor)
+ if (LockDegree >= GameData.degreeOfLockingOrOpeningTheDoor)
isOpen = false;
whoLockOrOpen = null;
}
diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs
index 89d930e..54749af 100644
--- a/logic/Gaming/ActionManager.cs
+++ b/logic/Gaming/ActionManager.cs
@@ -515,12 +515,13 @@ namespace Gaming
}
Thread.Sleep(GameData.checkInterval);
new FrameRateTaskExecutor(
- loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.LockDegree < GameData.degreeOfLockingOrOpeningTheDoor,
+ loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () =>
{
if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null)
return false;
- doorToLock.LockDegree += GameData.checkInterval * player.SpeedOfOpeningOrLocking;
+ if (doorToLock.AddLockDegree(GameData.checkInterval * player.SpeedOfOpeningOrLocking) >= GameData.basicSpeedOfOpeningOrLocking)
+ return false;
return true;
},
timeInterval: GameData.checkInterval,
From eb9af24a5433a50d344e270d163f03ffc099f79a Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sun, 28 May 2023 20:17:00 +0800
Subject: [PATCH 8/8] fix: :bug: delete the set of HP
---
.../GameClass/GameObj/Character/Character.cs | 56 +++++++++++--------
logic/GameClass/GameObj/Map/Door.cs | 28 +++-------
logic/GameClass/GameObj/Map/Doorway.cs | 3 +-
logic/Gaming/ActionManager.cs | 46 ++++++---------
logic/Gaming/CharacterManager.cs | 10 ++--
logic/Gaming/PropManager.cs | 2 +-
.../SkillManager/SkillManager.ActiveSkill.cs | 4 +-
logic/Preparation/Interface/ICharacter.cs | 3 +-
8 files changed, 68 insertions(+), 84 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index e6d0ae3..c9c6153 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -133,7 +133,7 @@ namespace GameClass.GameObj
if (!(bouncer?.TeamID == this.TeamID))
{
if (hasSpear || !HasShield)
- _ = TrySubHp(subHP);
+ _ = SubHp(subHP);
if (hp <= 0)
TryActivatingLIFE();
}
@@ -218,7 +218,8 @@ namespace GameClass.GameObj
HPReadWriterLock.ExitWriteLock();
}
}
- } // 最大血量
+ }
+ // 最大血量
protected long hp;
public long HP
{
@@ -234,22 +235,23 @@ namespace GameClass.GameObj
HPReadWriterLock.ExitReadLock();
}
}
- set
+ }
+
+ public long SetHP(long value)
+ {
+ HPReadWriterLock.EnterWriteLock();
+ try
{
- HPReadWriterLock.EnterWriteLock();
- try
+ if (value > 0)
{
- if (value > 0)
- {
- hp = value <= maxHp ? value : maxHp;
- }
- else
- hp = 0;
- }
- finally
- {
- HPReadWriterLock.ExitWriteLock();
+ return hp = value <= maxHp ? value : maxHp;
}
+ else
+ return hp = 0;
+ }
+ finally
+ {
+ HPReadWriterLock.ExitWriteLock();
}
}
@@ -257,7 +259,7 @@ namespace GameClass.GameObj
/// 尝试减血
///
/// 减血量
- public long TrySubHp(long sub)
+ public long SubHp(long sub)
{
HPReadWriterLock.EnterWriteLock();
try
@@ -280,6 +282,20 @@ namespace GameClass.GameObj
}
}
+ public long AddHP(long add)
+ {
+ HPReadWriterLock.EnterWriteLock();
+ try
+ {
+ long previousHp = hp;
+ return (hp = (hp + add > maxHp) ? maxHp : hp + add) - previousHp;
+ }
+ finally
+ {
+ HPReadWriterLock.ExitWriteLock();
+ }
+ }
+
private readonly object vampireLock = new();
public object VampireLock => vampire;
@@ -537,13 +553,7 @@ namespace GameClass.GameObj
if (value == PlayerStateType.Rescued) return -1;
Door door = (Door)lastObj!;
door.StopOpen();
- ReleaseTool(door.DoorNum switch
- {
- 3 => PropType.Key3,
- 5 => PropType.Key5,
- _ => PropType.Key6,
- }
- );
+ ReleaseTool(door.KeyType);
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.UsingSkill:
{
diff --git a/logic/GameClass/GameObj/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs
index ab63c62..0f03d72 100644
--- a/logic/GameClass/GameObj/Map/Door.cs
+++ b/logic/GameClass/GameObj/Map/Door.cs
@@ -13,23 +13,16 @@ namespace GameClass.GameObj
public Door(XY initPos, PlaceType placeType) :
base(initPos, GameData.numOfPosGridPerCell / 2, GameObjType.Door)
{
- switch (placeType)
+ keyType = placeType switch
{
- case PlaceType.Door3:
- doorNum = 3;
- break;
- case PlaceType.Door5:
- doorNum = 5;
- break;
- case PlaceType.Door6:
- default:
- doorNum = 6;
- break;
- }
+ PlaceType.Door3 => PropType.Key3,
+ PlaceType.Door5 => PropType.Key5,
+ _ => PropType.Key6,
+ };
}
- private readonly int doorNum;
- public int DoorNum => doorNum;
+ private readonly PropType keyType;
+ public PropType KeyType => keyType;
public override bool IsRigid => !isOpen;
public override ShapeType Shape => ShapeType.Square;
@@ -151,12 +144,7 @@ namespace GameClass.GameObj
{
if (character.PlayerState == PlayerStateType.OpeningTheDoor)
{
- character.ReleaseTool(DoorNum switch
- {
- 3 => PropType.Key3,
- 5 => PropType.Key5,
- _ => PropType.Key6,
- });
+ character.ReleaseTool(KeyType);
character.SetPlayerStateNaturally();
}
else if (character.PlayerState == PlayerStateType.LockingTheDoor)
diff --git a/logic/GameClass/GameObj/Map/Doorway.cs b/logic/GameClass/GameObj/Map/Doorway.cs
index 1373fd8..d5e70ca 100644
--- a/logic/GameClass/GameObj/Map/Doorway.cs
+++ b/logic/GameClass/GameObj/Map/Doorway.cs
@@ -1,5 +1,4 @@
-using Google.Protobuf.WellKnownTypes;
-using Preparation.Interface;
+using Preparation.Interface;
using Preparation.Utility;
using System;
diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs
index 54749af..585d7ff 100644
--- a/logic/Gaming/ActionManager.cs
+++ b/logic/Gaming/ActionManager.cs
@@ -321,7 +321,7 @@ namespace Gaming
if (playerRescued.AddTimeOfRescue(GameData.checkInterval))
{
playerRescued.SetPlayerStateNaturally();
- playerRescued.HP = playerRescued.MaxHp / 2;
+ playerRescued.SetHP(playerRescued.MaxHp / 2);
player.AddScore(GameData.StudentScoreRescue);
return false;
}
@@ -479,19 +479,12 @@ namespace Gaming
Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
if (doorToLock == null) return false;
- PropType propType = doorToLock.DoorNum switch
- {
- 3 => PropType.Key3,
- 5 => PropType.Key5,
- _ => PropType.Key6,
- };
-
- if (!player.UseTool(propType)) return false;
+ if (!player.UseTool(doorToLock.KeyType)) return false;
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.LockingTheDoor, doorToLock);
if (stateNum == -1)
{
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToLock.KeyType);
return false;
}
@@ -502,13 +495,13 @@ namespace Gaming
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToLock.KeyType);
player.ThreadNum.Release();
return;
}
if (!doorToLock.TryLock(player))
{
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToLock.KeyType);
player.ResetPlayerState(stateNum);
player.ThreadNum.Release();
return;
@@ -529,7 +522,7 @@ namespace Gaming
)
.Start();
doorToLock.StopLock();
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToLock.KeyType);
player.ThreadNum.Release();
player.ResetPlayerState(stateNum);
}
@@ -542,22 +535,15 @@ namespace Gaming
public bool OpenDoor(Character player)
{
if (player.CharacterType == CharacterType.Robot) return false;
- Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
- if (doorToLock == null) return false;
-
- PropType propType = doorToLock.DoorNum switch
- {
- 3 => PropType.Key3,
- 5 => PropType.Key5,
- _ => PropType.Key6,
- };
+ Door? doorToOpen = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
+ if (doorToOpen == null) return false;
- if (!player.UseTool(propType)) return false;
+ if (!player.UseTool(doorToOpen.KeyType)) return false;
- long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoor, doorToLock);
+ long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoor, doorToOpen);
if (stateNum == -1)
{
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToOpen.KeyType);
return false;
}
@@ -568,13 +554,13 @@ namespace Gaming
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToOpen.KeyType);
player.ThreadNum.Release();
return;
}
- if (!doorToLock.TryOpen(player))
+ if (!doorToOpen.TryOpen(player))
{
- player.ReleaseTool(propType);
+ player.ReleaseTool(doorToOpen.KeyType);
if (player.ResetPlayerState(stateNum))
player.ThreadNum.Release();
return;
@@ -583,8 +569,8 @@ namespace Gaming
if (player.ResetPlayerState(stateNum))
{
- doorToLock.StopOpen();
- player.ReleaseTool(propType);
+ doorToOpen.StopOpen();
+ player.ReleaseTool(doorToOpen.KeyType);
player.ThreadNum.Release();
}
}
diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs
index 53903ce..1db03b5 100644
--- a/logic/Gaming/CharacterManager.cs
+++ b/logic/Gaming/CharacterManager.cs
@@ -326,12 +326,12 @@ namespace Gaming
{
if (bullet.HasSpear)
{
- long subHp = student.TrySubHp(bullet.AP);
+ long subHp = student.SubHp(bullet.AP);
#if DEBUG
Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString());
#endif
bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp) + GameData.ScorePropUseSpear);
- bullet.Parent.HP = (long)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
+ bullet.Parent.AddHP((long)bullet.Parent.Vampire * subHp);
}
else return;
}
@@ -340,14 +340,14 @@ namespace Gaming
long subHp;
if (bullet.HasSpear)
{
- subHp = student.TrySubHp(bullet.AP + GameData.ApSpearAdd);
+ subHp = student.SubHp(bullet.AP + GameData.ApSpearAdd);
#if DEBUG
Debugger.Output(this, "is being shot with Spear! Now his hp is" + student.HP.ToString());
#endif
}
else
{
- subHp = student.TrySubHp(bullet.AP);
+ subHp = student.SubHp(bullet.AP);
#if DEBUG
Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString());
#endif
@@ -358,7 +358,7 @@ namespace Gaming
student.AddScore(subHp * GameData.factorOfScoreWhenTeacherAttacked / GameData.basicApOfGhost / FactorTeacher);
}
- bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
+ bullet.Parent.AddHP((long)(bullet.Parent.Vampire * subHp));
}
if (student.HP <= 0)
student.TryActivatingLIFE(); // 如果有复活甲
diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs
index 7bd672b..75426af 100644
--- a/logic/Gaming/PropManager.cs
+++ b/logic/Gaming/PropManager.cs
@@ -46,7 +46,7 @@ namespace Gaming
if (!player.IsGhost())
if (player.HP < player.MaxHp)
{
- player.HP += GameData.basicTreatmentDegree / 2;
+ player.AddHP(GameData.basicTreatmentDegree / 2);
player.AddScore(GameData.ScorePropAddHp);
}
else player.AddAp(GameData.PropDuration);
diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
index 8f6d003..48502e9 100644
--- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
+++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
@@ -421,7 +421,7 @@ namespace Gaming
if ((character.PlayerState == PlayerStateType.Addicted) && gameMap.CanSee(player, character))
{
character.SetPlayerStateNaturally();
- character.HP = GameData.RemainHpWhenAddLife;
+ character.SetHP(GameData.RemainHpWhenAddLife);
((Student)character).SetTimeOfRescue(0);
player.AddScore(GameData.StudentScoreRescue);
break;
@@ -452,7 +452,7 @@ namespace Gaming
if ((character.HP < character.MaxHp) && gameMap.CanSee(player, character))
{
player.AddScore(GameData.StudentScoreTreat(GameData.addHpWhenEncourage));
- character.HP += GameData.addHpWhenEncourage;
+ character.AddHP(GameData.addHpWhenEncourage);
((Student)character).SetDegreeOfTreatment0();
break;
}
diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs
index 9fe6927..07f0b93 100644
--- a/logic/Preparation/Interface/ICharacter.cs
+++ b/logic/Preparation/Interface/ICharacter.cs
@@ -6,7 +6,8 @@ namespace Preparation.Interface
public interface ICharacter : IMoveable
{
public long TeamID { get; }
- public long HP { get; set; }
+ public long HP { get; }
+ public long AddHP(long add);
public long Score { get; }
public void AddScore(long add);
public double Vampire { get; }