diff --git a/logic/Client/MainWindow.xaml.cs b/logic/Client/MainWindow.xaml.cs index ebf837f..7c5701f 100644 --- a/logic/Client/MainWindow.xaml.cs +++ b/logic/Client/MainWindow.xaml.cs @@ -833,7 +833,7 @@ namespace Client int i = 0; foreach (var skill in occupation.ListOfIActiveSkill) { - var iActiveSkill = SkillFactory.FindIActiveSkill(skill); + var iActiveSkill = SkillFactory.FindActiveSkill(skill); coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; ++i; } @@ -848,7 +848,7 @@ namespace Client int j = 0; foreach (var skill in occupation1.ListOfIActiveSkill) { - var iActiveSkill = SkillFactory.FindIActiveSkill(skill); + var iActiveSkill = SkillFactory.FindActiveSkill(skill); coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; ++j; } diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 3218853..1132ff5 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -11,37 +11,32 @@ namespace GameClass.GameObj private readonly IOccupation occupation; public IOccupation Occupation => occupation; - private Dictionary timeUntilActiveSkillAvailable = new(); - public Dictionary TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable; + private Dictionary activeSkillDictionary = new(); + public Dictionary ActiveSkillDictionary => activeSkillDictionary; - private Dictionary iActiveSkillDictionary = new(); - public Dictionary IActiveSkillDictionary => iActiveSkillDictionary; - - public IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType) + public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType) { if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) { - return IActiveSkillDictionary[activeSkillType]; + return ActiveSkillDictionary[activeSkillType]; } return new NullSkill(); } public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable) { - if (TimeUntilActiveSkillAvailable.ContainsKey(activeSkillType)) + if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) { - lock (gameObjLock) - this.timeUntilActiveSkillAvailable[activeSkillType] = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0; + ActiveSkillDictionary[activeSkillType].TimeUntilActiveSkillAvailable = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0; return true; } return false; } public bool AddTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int addTimeUntilActiveSkillAvailable) { - if (TimeUntilActiveSkillAvailable.ContainsKey(activeSkillType)) + if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) { - lock (gameObjLock) - this.timeUntilActiveSkillAvailable[activeSkillType] = (timeUntilActiveSkillAvailable[activeSkillType] + addTimeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable[activeSkillType] + addTimeUntilActiveSkillAvailable : 0; + ActiveSkillDictionary[activeSkillType].TimeUntilActiveSkillAvailable += addTimeUntilActiveSkillAvailable; return true; } return false; @@ -72,12 +67,10 @@ namespace GameClass.GameObj foreach (var activeSkill in this.Occupation.ListOfIActiveSkill) { - this.IActiveSkillDictionary.Add(activeSkill, SkillFactory.FindIActiveSkill(activeSkill)); - this.TimeUntilActiveSkillAvailable.Add(activeSkill, 0); + this.ActiveSkillDictionary.Add(activeSkill, SkillFactory.FindActiveSkill(activeSkill)); } - // UsePassiveSkill(); //创建player时开始被动技能,这一过程也可以放到gamestart时进行 - // 这可以放在AddPlayer中做 + // UsePassiveSkill(); //这一过程放到gamestart时进行 Debugger.Output(this, "constructed!"); } diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs index 0b7727c..9181015 100644 --- a/logic/GameClass/GameObj/GameObj.cs +++ b/logic/GameClass/GameObj/GameObj.cs @@ -9,7 +9,7 @@ namespace GameClass.GameObj /// public abstract class GameObj : IGameObj { - private ReaderWriterLockSlim gameObjReaderWriterLock = new(); + private readonly ReaderWriterLockSlim gameObjReaderWriterLock = new(); public ReaderWriterLockSlim GameObjReaderWriterLock => gameObjReaderWriterLock; protected readonly object gameObjLock = new(); public object GameLock => gameObjLock; diff --git a/logic/GameClass/GameObj/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs index 5955a57..9684a08 100644 --- a/logic/GameClass/GameObj/Map/Door.cs +++ b/logic/GameClass/GameObj/Map/Door.cs @@ -150,7 +150,12 @@ namespace GameClass.GameObj whoLockOrOpen = null; isOpen = true; } - if (character != null) character.SetPlayerState(); + if (character != null) + { + lock (character.ActionLock) + if (character.PlayerState == PlayerStateType.OpeningTheDoor) + character.SetPlayerState(); + } } } } diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index 3a3869f..8626712 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -193,13 +193,12 @@ namespace GameClass.GameObj { if (playerID == person.ID) { - if (person.CharacterType == CharacterType.TechOtaku && person.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed) + if (person.CharacterType == CharacterType.TechOtaku) { Debugger.Output(person, person.PlayerID.ToString()); foreach (Character character in gameObjDict[GameObjType.Character]) { - Debugger.Output(character, character.PlayerID.ToString()); - if (person.PlayerID + GameData.numOfPeople == character.PlayerID) + if (((UseRobot)person.FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID == character.PlayerID) { player = character; break; diff --git a/logic/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs index ff124df..1600361 100644 --- a/logic/GameClass/GameObj/Moveable.cs +++ b/logic/GameClass/GameObj/Moveable.cs @@ -162,13 +162,13 @@ namespace GameClass.GameObj } } - protected long moveSpeed; + protected int moveSpeed; /// /// 移动速度 /// - public long MoveSpeed + public int MoveSpeed { - get => Interlocked.Read(ref moveSpeed); + get => Interlocked.CompareExchange(ref moveSpeed, 0, 1); set => Interlocked.Exchange(ref moveSpeed, value); } /// diff --git a/logic/GameClass/GameObj/Prop/Gadget.cs b/logic/GameClass/GameObj/Prop/Gadget.cs index e9a94e2..82611b3 100644 --- a/logic/GameClass/GameObj/Prop/Gadget.cs +++ b/logic/GameClass/GameObj/Prop/Gadget.cs @@ -21,11 +21,11 @@ namespace GameClass.GameObj public abstract bool IsUsable(); public abstract PropType GetPropType(); - public Gadget(XY initPos, int radius = GameData.PropRadius) : + public Gadget(XY initPos, int radius = GameData.propRadius) : base(initPos, radius, GameObjType.Gadget) { this.canMove = false; - this.MoveSpeed = GameData.PropMoveSpeed; + this.MoveSpeed = GameData.propMoveSpeed; } } public abstract class Tool : Gadget diff --git a/logic/GameClass/GameObj/Prop/Item.cs b/logic/GameClass/GameObj/Prop/Item.cs index 76d02b5..c8838a5 100644 --- a/logic/GameClass/GameObj/Prop/Item.cs +++ b/logic/GameClass/GameObj/Prop/Item.cs @@ -13,7 +13,7 @@ namespace GameClass.GameObj public abstract PropType GetPropType(); - public Item(XY initPos, int radius = GameData.PropRadius) : + public Item(XY initPos, int radius = GameData.propRadius) : base(initPos, radius, GameObjType.Item) { this.canMove = false; diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index faec44b..569472f 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -26,7 +26,7 @@ namespace Gaming gameMap.Remove((GameObj)collisionObj); } } - if (player.FindIActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost()) + if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost()) { if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); @@ -117,7 +117,7 @@ namespace Gaming if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) gameMap.NumOfRepairedGenerators++; if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator) - player.SetPlayerState(); + player.SetPlayerState();//Num == player.StateNum }, timeInterval: GameData.frameDuration, finallyReturn: () => 0 @@ -215,7 +215,7 @@ namespace Gaming loopToDo: () => { if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) - playerTreated.SetPlayerState(); + playerTreated.SetPlayerState();// }, timeInterval: GameData.frameDuration, finallyReturn: () => 0 @@ -426,7 +426,10 @@ namespace Gaming if (!doorToLock.TryLock(player)) { player.ReleaseTool(propType); - player.SetPlayerState(); + lock (player.ActionLock) + { + if (stateNum == player.StateNum) player.SetPlayerState(); + } player.ThreadNum.Release(); } else @@ -495,7 +498,10 @@ namespace Gaming if (!doorToLock.TryOpen(player)) { player.ReleaseTool(propType); - player.SetPlayerState(); + lock (player.ActionLock) + { + if (stateNum == player.StateNum) player.SetPlayerState(); + } player.ThreadNum.Release(); } else diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs index bf9bd6d..f7a3f19 100644 --- a/logic/Gaming/CharacterManager.cs +++ b/logic/Gaming/CharacterManager.cs @@ -284,7 +284,7 @@ namespace Gaming if (student.CharacterType == CharacterType.StraightAStudent) { - ((WriteAnswers)student.FindIActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0; + ((WriteAnswers)student.FindActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0; } student.SetDegreeOfTreatment0(); @@ -382,8 +382,8 @@ namespace Gaming var parent = ((Golem)player).Parent; if (parent != null && parent.CharacterType == CharacterType.TechOtaku) { - ((SummonGolem)(parent.FindIActiveSkill(ActiveSkillType.SummonGolem))).GolemSummoned = null; - player.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false; + ((SummonGolem)(parent.FindActiveSkill(ActiveSkillType.SummonGolem))).DeleteGolem((int)(player.PlayerID - parent.PlayerID) / GameData.numOfPeople - 1); + //player.FindActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false; } return; } diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index 3481cd0..4fe007c 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -107,7 +107,7 @@ namespace Gaming if (pickProp.GetPropType() != PropType.Null) { - gameMap.Remove(pickProp); + gameMap.RemoveJustFromMap(pickProp); //gameMap.Add(new Item(pickProp)); return true; } diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index fccac32..5d52443 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -15,7 +15,7 @@ namespace Gaming { if ((!player.Commandable())) return false; - IActiveSkill skill = player.FindIActiveSkill(ActiveSkillType.CanBeginToCharge); + ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.CanBeginToCharge); Debugger.Output(player, "can begin to charge!"); @@ -31,7 +31,7 @@ namespace Gaming public bool ShowTime(Character player) { if ((!player.Commandable())) return false; - IActiveSkill skill = player.FindIActiveSkill(ActiveSkillType.ShowTime); + ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.ShowTime); return ActiveSkillEffect(skill, player, () => { @@ -93,7 +93,7 @@ namespace Gaming public static bool BecomeInvisible(Character player) { if ((!player.Commandable())) return false; - IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.BecomeInvisible); + ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible); return ActiveSkillEffect(activeSkill, player, () => { player.AddScore(GameData.ScoreBecomeInvisible); @@ -106,20 +106,21 @@ namespace Gaming public bool UseRobot(Character player) { - IGolem? golem = (IGolem?)(((SummonGolem)player.FindIActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned); - if ((!player.Commandable()) || ((SummonGolem)player.FindIActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned == null) return false; + /* + IGolem? golem = (IGolem?)(((SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned); + if ((!player.Commandable()) || ((SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned == null) return false; Debugger.Output(player, "use robot!"); - IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.UseRobot); + IActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.UseRobot); activeSkill.IsBeingUsed = (activeSkill.IsBeingUsed) ? false : true; if (activeSkill.IsBeingUsed) player.SetPlayerState(PlayerStateType.UsingSkill); - else player.SetPlayerState(); + else player.SetPlayerState();*/ return true; } public static bool JumpyBomb(Character player) { if ((!player.Commandable())) return false; - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.JumpyBomb), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.JumpyBomb), player, () => { player.BulletOfPlayer = BulletType.BombBomb; Debugger.Output(player, "uses jumpybomb!"); @@ -131,7 +132,7 @@ namespace Gaming public bool WriteAnswers(Character player) { if ((!player.Commandable())) return false; - IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.WriteAnswers); + ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.WriteAnswers); return ActiveSkillEffect(activeSkill, player, () => { Generator? generator = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator); @@ -149,25 +150,30 @@ namespace Gaming public bool SummonGolem(Character player) { - if ((!player.Commandable())) return false; - IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.SummonGolem); - if (((SummonGolem)activeSkill).GolemSummoned != null) return false; - XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2); - if (actionManager.moveEngine.CheckCollision(player, res) != null) - return false; - Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player); - if (golem == null) return false; - ((SummonGolem)activeSkill).GolemSummoned = golem; + ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem); + long num = ((SummonGolem)activeSkill).AddGolem(); + if (num >= GameData.maxSummonedGolemNum) return false; + num = (num + 1) * GameData.numOfPeople + player.PlayerID; + + /* if ((!player.Commandable())) return false; + XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2); + if (actionManager.moveEngine.CheckCollision(player, res) != null) + return false; + Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player); + if (golem == null) return false; + ((SummonGolem)activeSkill).GolemSummoned = golem; + */ return ActiveSkillEffect(activeSkill, player, () => { }, () => { }); + } public static bool UseKnife(Character player) { - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.UseKnife), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.UseKnife), player, () => { player.BulletOfPlayer = BulletType.FlyingKnife; Debugger.Output(player, "uses flyingknife!"); @@ -179,7 +185,7 @@ namespace Gaming public bool Howl(Character player) { if ((!player.Commandable())) return false; - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Howl), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Howl), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); try @@ -207,7 +213,7 @@ namespace Gaming public bool Punish(Character player) { if ((!player.Commandable())) return false; - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Punish), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Punish), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); try @@ -240,7 +246,7 @@ namespace Gaming public bool Rouse(Character player) { if ((!player.Commandable())) return false; - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Rouse), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Rouse), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); try @@ -270,7 +276,7 @@ namespace Gaming public bool Encourage(Character player) { if ((!player.Commandable())) return false; - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Encourage), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Encourage), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); try @@ -299,7 +305,7 @@ namespace Gaming public bool Inspire(Character player) { if ((!player.Commandable())) return false; - return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Inspire), player, () => + return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Inspire), player, () => { gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); try @@ -323,24 +329,23 @@ namespace Gaming { }); } - public static bool ActiveSkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) + public static bool ActiveSkillEffect(ActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) { - lock (activeSkill.ActiveSkillLock) + lock (activeSkill.ActiveSkillUseLock) { - ActiveSkillType activeSkillType = SkillFactory.FindActiveSkillType(activeSkill); - if (player.TimeUntilActiveSkillAvailable[activeSkillType] == 0) + if (activeSkill.TimeUntilActiveSkillAvailable == 0) { - player.SetTimeUntilActiveSkillAvailable(activeSkillType, activeSkill.SkillCD); + activeSkill.TimeUntilActiveSkillAvailable = activeSkill.SkillCD; new Thread (() => { startSkill(); - activeSkill.IsBeingUsed = true; + activeSkill.IsBeingUsed = 1; new FrameRateTaskExecutor( () => !player.IsRemoved, () => { - player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); + activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration; }, timeInterval: GameData.frameDuration, () => 0, @@ -353,14 +358,14 @@ namespace Gaming .Start(); endSkill(); - activeSkill.IsBeingUsed = false; + activeSkill.IsBeingUsed = 0; Debugger.Output(player, "return to normal."); new FrameRateTaskExecutor( - loopCondition: () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsRemoved, + loopCondition: () => activeSkill.TimeUntilActiveSkillAvailable > 0, loopToDo: () => { - player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); + activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration; }, timeInterval: GameData.frameDuration, finallyReturn: () => 0 @@ -371,7 +376,7 @@ namespace Gaming } .Start(); - player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0); + activeSkill.TimeUntilActiveSkillAvailable = 0; Debugger.Output(player, "ActiveSkill is ready."); } ) diff --git a/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs index 399624e..e1b965f 100644 --- a/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs @@ -15,7 +15,7 @@ namespace Gaming // 被动技能开局时就释放,持续到游戏结束 public void Meditate(Character player) { const int learningDegree = GameData.basicFixSpeed / 4; - WriteAnswers activeSkill = (WriteAnswers)player.FindIActiveSkill(ActiveSkillType.WriteAnswers); + WriteAnswers activeSkill = (WriteAnswers)player.FindActiveSkill(ActiveSkillType.WriteAnswers); new Thread ( () => diff --git a/logic/Preparation/Interface/IMoveable.cs b/logic/Preparation/Interface/IMoveable.cs index 725b750..ad87c31 100644 --- a/logic/Preparation/Interface/IMoveable.cs +++ b/logic/Preparation/Interface/IMoveable.cs @@ -7,7 +7,7 @@ namespace Preparation.Interface public interface IMoveable : IGameObj { object ActionLock { get; } - public long MoveSpeed { get; } + public int MoveSpeed { get; } public bool IsMoving { get; set; } public bool IsRemoved { get; } public bool IsAvailableForMove { get; } diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index 68f2632..de436ff 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -315,13 +315,13 @@ namespace Preparation.Interface } public class TechOtaku : IStudentType { - private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.75); + private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 288 / 300); public int MoveSpeed => moveSpeed; private const int maxHp = (int)(GameData.basicHp * 0.9); public int MaxHp => maxHp; - private const int maxGamingAddiction = (int)(GameData.basicMaxGamingAddiction * 1.1); + private const int maxGamingAddiction = (int)(GameData.basicMaxGamingAddiction); public int MaxGamingAddiction => maxGamingAddiction; public BulletType InitBullet => BulletType.Null; @@ -329,13 +329,13 @@ namespace Preparation.Interface public List ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.SummonGolem, ActiveSkillType.UseRobot }); public List ListOfIPassiveSkill => new(new PassiveSkillType[] { }); - public const int fixSpeed = (int)(GameData.basicFixSpeed * 1.1); + public const int fixSpeed = (int)(GameData.basicFixSpeed * 110 / 123); public int FixSpeed => fixSpeed; - public const int treatSpeed = GameData.basicTreatSpeed * 9 / 10; + public const int treatSpeed = GameData.basicTreatSpeed; public int TreatSpeed => treatSpeed; - public const double concealment = GameData.basicConcealment; + public const double concealment = GameData.basicConcealment * 1.1; public double Concealment => concealment; public const int alertnessRadius = (int)(GameData.basicStudentAlertnessRadius); @@ -347,10 +347,10 @@ namespace Preparation.Interface public int speedOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking; public int SpeedOfOpeningOrLocking => speedOfOpeningOrLocking; - public int speedOfClimbingThroughWindows = (int)(GameData.basicStudentSpeedOfClimbingThroughWindows * 3 / 4); + public int speedOfClimbingThroughWindows = (int)(GameData.basicStudentSpeedOfClimbingThroughWindows * 1100 / 1222); public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows; - public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; + public int speedOfOpenChest = GameData.basicSpeedOfOpenChest * 1100 / 1250; public int SpeedOfOpenChest => speedOfOpenChest; } public class Sunshine : IStudentType diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index f4abea0..0d9e29d 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -1,5 +1,6 @@ using Preparation.Interface; using Preparation.Utility; +using System.Threading; namespace Preparation.Interface { @@ -13,241 +14,181 @@ namespace Preparation.Interface { public int SkillCD { get; } public int DurationTime { get; } //技能持续时间 - public object ActiveSkillLock { get; } - public bool IsBeingUsed { get; set; } + public object ActiveSkillUseLock { get; } + public int IsBeingUsed { get; set; } } - public class CanBeginToCharge : IActiveSkill + + public abstract class ActiveSkill : IActiveSkill { - public int SkillCD => GameData.commonSkillCD * 2; - public int DurationTime => GameData.commonSkillTime * 3 / 10; + public abstract int SkillCD { get; } + public abstract int DurationTime { get; } + + private readonly object activeSkillUseLock = new(); + public object ActiveSkillUseLock => activeSkillUseLock; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; + private readonly object skillLock = new(); + public object SkillLock => skillLock; - public bool isBeingUsed = false; - public bool IsBeingUsed + private int timeUntilActiveSkillAvailable = 0; + public int TimeUntilActiveSkillAvailable { - get => isBeingUsed; set => isBeingUsed = value; + get => Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1); + set + { + if (value < 0) value = 0; + else if (value > SkillCD) value = SkillCD; + Interlocked.Exchange(ref timeUntilActiveSkillAvailable, value); + } } - } - - public class BecomeInvisible : IActiveSkill - { - public int SkillCD => GameData.commonSkillCD * 4 / 3; - public int DurationTime => GameData.commonSkillTime; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed + public int isBeingUsed = 0;//实为bool + public int IsBeingUsed { - get => isBeingUsed; set => isBeingUsed = value; + get => Interlocked.CompareExchange(ref isBeingUsed, 0, 1); + set => Interlocked.Exchange(ref isBeingUsed, value); } } - public class Punish : IActiveSkill + public class CanBeginToCharge : ActiveSkill { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => 0; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public override int SkillCD => GameData.commonSkillCD * 2; + public override int DurationTime => GameData.commonSkillTime * 3 / 10; } - public class Rouse : IActiveSkill + public class BecomeInvisible : ActiveSkill { - public int SkillCD => GameData.commonSkillCD * 4; - public int DurationTime => 0; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public override int SkillCD => GameData.commonSkillCD * 4 / 3; + public override int DurationTime => GameData.commonSkillTime; } - public class Encourage : IActiveSkill + public class Punish : ActiveSkill { - public int SkillCD => GameData.commonSkillCD * 4; - public int DurationTime => 0; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public override int SkillCD => GameData.commonSkillCD; + public override int DurationTime => 0; } - public class Inspire : IActiveSkill + public class Rouse : ActiveSkill { - public int SkillCD => GameData.commonSkillCD * 4; - public int DurationTime => 0; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public override int SkillCD => GameData.commonSkillCD * 4; + public override int DurationTime => 0; } - public class Howl : IActiveSkill + public class Encourage : ActiveSkill { - public int SkillCD => GameData.commonSkillCD * 25 / 30; - public int DurationTime => 0; - - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public override int SkillCD => GameData.commonSkillCD * 4; + public override int DurationTime => 0; } - public class ShowTime : IActiveSkill + public class Inspire : ActiveSkill { - public int SkillCD => GameData.commonSkillCD * 8 / 3; - public int DurationTime => GameData.commonSkillTime; + public override int SkillCD => GameData.commonSkillCD * 4; + public override int DurationTime => 0; + } - private readonly object commonSkillLock = new(); - public object ActiveSkillLock => commonSkillLock; + public class Howl : ActiveSkill + { + public override int SkillCD => GameData.commonSkillCD * 25 / 30; + public override int DurationTime => 0; + } - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public class ShowTime : ActiveSkill + { + public override int SkillCD => GameData.commonSkillCD * 8 / 3; + public override int DurationTime => GameData.commonSkillTime; } - public class JumpyBomb : IActiveSkill + public class JumpyBomb : ActiveSkill { - public int SkillCD => GameData.commonSkillCD / 2; - public int DurationTime => GameData.commonSkillTime * 3 / 10; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; + public override int SkillCD => GameData.commonSkillCD / 2; + public override int DurationTime => GameData.commonSkillTime * 3 / 10; + } - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = value; - } + public class UseKnife : ActiveSkill + { + public override int SkillCD => GameData.commonSkillCD; + public override int DurationTime => GameData.commonSkillTime / 10; } - public class UseKnife : IActiveSkill + public class UseRobot : ActiveSkill { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => GameData.commonSkillTime / 10; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; + public override int SkillCD => GameData.commonSkillCD / 300; + public override int DurationTime => 0; - public bool isBeingUsed = false; - public bool IsBeingUsed + private int nowPlayerID; + public int NowPlayerID { - get => isBeingUsed; set => isBeingUsed = value; + get => Interlocked.CompareExchange(ref nowPlayerID, 0, 1); + set => Interlocked.Exchange(ref nowPlayerID, value); } } - public class UseRobot : IActiveSkill + public class WriteAnswers : ActiveSkill { - public int SkillCD => GameData.commonSkillCD / 300; - public int DurationTime => 0; - private readonly object commonSkillLock = new(); - public object ActiveSkillLock => commonSkillLock; + public override int SkillCD => GameData.commonSkillCD; + public override int DurationTime => 0; - public bool isBeingUsed = false; - public bool IsBeingUsed + private int degreeOfMeditation = 0; + public int DegreeOfMeditation { - get => isBeingUsed; set => isBeingUsed = value; + get => Interlocked.CompareExchange(ref degreeOfMeditation, 0, 1); + set => Interlocked.Exchange(ref degreeOfMeditation, value); } } - public class WriteAnswers : IActiveSkill + public class SummonGolem : ActiveSkill { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => 0; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; + public override int SkillCD => GameData.commonSkillCD * 4 / 3; + public override int DurationTime => 6; - private int degreeOfMeditation = 0; - public int DegreeOfMeditation + private bool[] golemIDArray = new bool[GameData.maxSummonedGolemNum] { false, false, false }; + public bool[] GolemIDArray { - get => degreeOfMeditation; - set + get { - lock (commonSkillLock) - { - degreeOfMeditation = value; - } + lock (SkillLock) { return golemIDArray; } } } - public bool isBeingUsed = false; - public bool IsBeingUsed + private int nowPtr = 0; + public int NowPtr { - get => isBeingUsed; set => isBeingUsed = value; + get + { + lock (SkillLock) { return nowPtr; } + } } - } - - public class SummonGolem : IActiveSkill - { - public int SkillCD => GameData.commonSkillCD * 4 / 3; - public int DurationTime => 6; - private readonly object commonSkillLock = new(); - public object ActiveSkillLock => commonSkillLock; - - private IGolem? golemSummoned = null; - public IGolem? GolemSummoned + public int AddGolem() { - get => golemSummoned; - set + lock (SkillLock) { - lock (commonSkillLock) - { - golemSummoned = value; - } + if (nowPtr == GameData.maxSummonedGolemNum) return GameData.maxSummonedGolemNum; + int num = nowPtr; + golemIDArray[nowPtr] = true; + while ((++nowPtr) < GameData.maxSummonedGolemNum && golemIDArray[nowPtr]) ; + return num; } } - - public bool isBeingUsed = false; - public bool IsBeingUsed + public void DeleteGolem(int num) { - get => isBeingUsed; set => isBeingUsed = value; + lock (SkillLock) + { + golemIDArray[num] = false; + if (num < nowPtr) + { + nowPtr = num; + } + } } } - public class NullSkill : IActiveSkill + public class NullSkill : ActiveSkill { - public int SkillCD => GameData.commonSkillCD; - public int DurationTime => GameData.commonSkillTime; - private readonly object commonSkillLock = new object(); - public object ActiveSkillLock => commonSkillLock; - - public bool isBeingUsed = false; - public bool IsBeingUsed - { - get => isBeingUsed; set => isBeingUsed = false; - } + public override int SkillCD => GameData.commonSkillCD; + public override int DurationTime => GameData.commonSkillTime; } public static class SkillFactory { - public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType) + public static ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType) { switch (activeSkillType) { diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index d58c44f..41bf740 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -92,10 +92,10 @@ namespace Preparation.Utility public const int basicTreatSpeed = 100; public const int basicFixSpeed = 123; - public const int basicSpeedOfOpeningOrLocking = 4000; + public const int basicSpeedOfOpeningOrLocking = 5000; public const int basicStudentSpeedOfClimbingThroughWindows = 1222; public const int basicGhostSpeedOfClimbingThroughWindows = 2540; - public const int basicSpeedOfOpenChest = 1000; + public const int basicSpeedOfOpenChest = 1250; public const int basicHp = 3000000; // 初始血量 public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 @@ -228,10 +228,12 @@ namespace Preparation.Utility public const int checkIntervalWhenShowTime = 200; public const int addAddictionPer100msWhenShowTime = 300; + + public const int maxSummonedGolemNum = 3; #endregion #region 道具相关 - public const int PropRadius = numOfPosGridPerCell / 2; - public const int PropMoveSpeed = 3000; + public const int propRadius = characterRadius; + public const int propMoveSpeed = 3000; public const int PropMaxMoveDistance = 15 * numOfPosGridPerCell; public const long PropProduceTime = 20000; public const int PropDuration = 10000; diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs index a4b9030..d7e3cd9 100644 --- a/logic/Server/CopyInfo.cs +++ b/logic/Server/CopyInfo.cs @@ -80,9 +80,9 @@ namespace Server } }; - foreach (var keyValue in player.TimeUntilActiveSkillAvailable) - msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value); - for (int i = 0; i < GameData.maxNumOfSkill - player.TimeUntilActiveSkillAvailable.Count; ++i) + foreach (var keyValue in player.ActiveSkillDictionary) + msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value.TimeUntilActiveSkillAvailable); + for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i) msg.StudentMessage.TimeUntilSkillAvailable.Add(-1); foreach (var value in player.PropInventory) @@ -121,10 +121,9 @@ namespace Server BulletType = Transformation.ToBulletType((Preparation.Utility.BulletType)player.BulletOfPlayer) } }; - - foreach (var keyValue in player.TimeUntilActiveSkillAvailable) - msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value); - for (int i = 0; i < GameData.maxNumOfSkill - player.TimeUntilActiveSkillAvailable.Count; ++i) + foreach (var keyValue in player.ActiveSkillDictionary) + msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value.TimeUntilActiveSkillAvailable); + for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i) msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1); foreach (var value in player.PropInventory)