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/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.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index f2d887e..b57c3a5 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; @@ -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.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index d0a4902..1b52f08 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -32,83 +32,60 @@ 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; - public int GamingAddiction + private readonly object addictionLock = new(); + private int maxGamingAddiction; + public int MaxGamingAddiction { - get => gamingAddiction; - set + get { - if (value > 0) - lock (gameObjLock) - gamingAddiction = value <= MaxGamingAddiction ? value : MaxGamingAddiction; - else - lock (gameObjLock) - gamingAddiction = 0; + lock (addictionLock) + return maxGamingAddiction; } - } - - private int selfHealingTimes = 1;//剩余的自愈次数 - public int SelfHealingTimes - { - get => selfHealingTimes; - set + protected set { - lock (gameObjLock) - selfHealingTimes = (value > 0) ? value : 0; - } - } - - private int degreeOfTreatment = 0; - public int DegreeOfTreatment - { - get => degreeOfTreatment; - private set - { - degreeOfTreatment = value; + lock (addictionLock) + { + if (value < gamingAddiction) gamingAddiction = value; + maxGamingAddiction = value; + } } } - public void SetDegreeOfTreatment0() - { - DegreeOfTreatment = 0; - } - public bool SetDegreeOfTreatment(int value, Student whoTreatYou) + private int gamingAddiction; + public int GamingAddiction { - if (value <= 0) { degreeOfTreatment = 0; return false; } - if (value >= MaxHp - HP) + get { - whoTreatYou.AddScore(GameData.StudentScoreTreat(MaxHp - HP)); - HP = MaxHp; - degreeOfTreatment = 0; - return true; + lock (addictionLock) + return gamingAddiction; } - if (value >= GameData.basicTreatmentDegree) + set { - whoTreatYou.AddScore(GameData.StudentScoreTreat(GameData.basicTreatmentDegree)); - HP += GameData.basicTreatmentDegree; - DegreeOfTreatment = 0; - return true; + if (value > 0) + lock (addictionLock) + gamingAddiction = value <= maxGamingAddiction ? value : maxGamingAddiction; + else + lock (addictionLock) + gamingAddiction = 0; } - DegreeOfTreatment = value; - return false; - } - public bool AddDegreeOfTreatment(int value, Student student) - { - return SetDegreeOfTreatment(value + degreeOfTreatment, student); } private int timeOfRescue = 0; @@ -128,19 +105,24 @@ 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; } } 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/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 3e6b937..c9c6153 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -8,15 +8,8 @@ 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(); /// /// 装弹冷却 /// @@ -25,7 +18,7 @@ namespace GameClass.GameObj { get { - lock (actionLock) + lock (attackLock) { return cd; } @@ -36,7 +29,7 @@ namespace GameClass.GameObj { get { - lock (actionLock) + lock (attackLock) return orgCD; } } @@ -47,14 +40,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 +62,7 @@ namespace GameClass.GameObj { get { - lock (actionLock) + lock (attackLock) { return maxBulletNum; } @@ -78,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 (actionLock) + 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; } } @@ -98,7 +91,7 @@ namespace GameClass.GameObj /// 攻击操作发出的子弹 public Bullet? Attack(double angle, int time) { - lock (actionLock) + lock (attackLock) { if (bulletOfPlayer == BulletType.Null) return null; @@ -115,7 +108,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 @@ -140,7 +133,7 @@ namespace GameClass.GameObj if (!(bouncer?.TeamID == this.TeamID)) { if (hasSpear || !HasShield) - _ = TrySubHp(subHP); + _ = SubHp(subHP); if (hp <= 0) TryActivatingLIFE(); } @@ -194,6 +187,9 @@ namespace GameClass.GameObj } #endregion #region 血量相关的基本属性及方法 + private readonly ReaderWriterLockSlim hpReaderWriterLock = new(); + public ReaderWriterLockSlim HPReadWriterLock => hpReaderWriterLock; + private long maxHp; public long MaxHp { @@ -222,7 +218,8 @@ namespace GameClass.GameObj HPReadWriterLock.ExitWriteLock(); } } - } // 最大血量 + } + // 最大血量 protected long hp; public long HP { @@ -238,22 +235,23 @@ namespace GameClass.GameObj HPReadWriterLock.ExitReadLock(); } } - set + } + + public long SetHP(long value) + { + HPReadWriterLock.EnterWriteLock(); + try { - HPReadWriterLock.EnterWriteLock(); - try - { - if (value > 0) - { - hp = value <= maxHp ? value : maxHp; - } - else - hp = 0; - } - finally + if (value > 0) { - HPReadWriterLock.ExitWriteLock(); + return hp = value <= maxHp ? value : maxHp; } + else + return hp = 0; + } + finally + { + HPReadWriterLock.ExitWriteLock(); } } @@ -261,7 +259,7 @@ namespace GameClass.GameObj /// 尝试减血 /// /// 减血量 - public long TrySubHp(long sub) + public long SubHp(long sub) { HPReadWriterLock.EnterWriteLock(); try @@ -284,6 +282,23 @@ 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; + private double vampire = 0; // 回血率:0-1之间 public double Vampire { @@ -306,8 +321,65 @@ 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 状态相关的基本属性与方法 + #region 查询状态相关的基本属性与方法 private PlayerStateType playerState = PlayerStateType.Null; public PlayerStateType PlayerState { @@ -371,6 +443,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 { @@ -383,19 +457,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引用 @@ -492,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: { @@ -573,6 +628,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) @@ -619,6 +687,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 @@ -639,7 +710,7 @@ namespace GameClass.GameObj /// 使用物品栏中的道具 /// /// 被使用的道具 - public Gadget UseProp(int indexing) + public Gadget ConsumeProp(int indexing) { if (indexing < 0 || indexing >= GameData.maxNumOfPropInPropInventory) return new NullProp(); @@ -652,7 +723,7 @@ namespace GameClass.GameObj } } - public Gadget UseProp(PropType propType) + public Gadget ConsumeProp(PropType propType) { if (propType == PropType.Null) { @@ -687,7 +758,7 @@ namespace GameClass.GameObj return new NullProp(); } - public bool UseTool(PropType propType) + public bool UseTool(PropType propType)//占用道具,使其不能重复使用和被消耗 { lock (inventoryLock) { 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/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs index ab459b5..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; @@ -57,17 +50,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 +106,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 +115,7 @@ namespace GameClass.GameObj { lock (gameObjLock) { - if (lockDegree >= GameData.degreeOfLockingOrOpeningTheDoor) + if (LockDegree >= GameData.degreeOfLockingOrOpeningTheDoor) isOpen = false; whoLockOrOpen = null; } @@ -157,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/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs index 9d3cd00..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 /// 原初移动速度 /// - public int OrgMoveSpeed { get; protected set; } + protected int orgMoveSpeed; + public int OrgMoveSpeed => orgMoveSpeed; /* /// /// 复活时数据重置 diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 89d930e..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,25 +495,26 @@ 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; } 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, @@ -528,7 +522,7 @@ namespace Gaming ) .Start(); doorToLock.StopLock(); - player.ReleaseTool(propType); + player.ReleaseTool(doorToLock.KeyType); player.ThreadNum.Release(); player.ResetPlayerState(stateNum); } @@ -541,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; } @@ -567,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; @@ -582,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 a95ca20..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(); // 如果有复活甲 @@ -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..75426af 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: @@ -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); @@ -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/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; } 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; } diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs index 9644826..d9d341a 100644 --- a/logic/Server/CopyInfo.cs +++ b/logic/Server/CopyInfo.cs @@ -203,7 +203,7 @@ namespace Server Type = Transformation.ToBulletType(bombedBullet.bulletHasBombed.TypeOfBullet), X = bombedBullet.bulletHasBombed.Position.x, Y = bombedBullet.bulletHasBombed.Position.y, - FacingDirection = bombedBullet.FacingDirection.Angle(), + FacingDirection = bombedBullet.facingDirection.Angle(), MappingId = bombedBullet.MappingID, BombRange = bombedBullet.bulletHasBombed.BulletBombRange } diff --git a/logic/Server/RpcServices.cs b/logic/Server/RpcServices.cs index 34ec687..79d9317 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)