refactor: 🚧 refactor the skill fuction
tags/v0.1.0
| @@ -833,7 +833,7 @@ namespace Client | |||||
| int i = 0; | int i = 0; | ||||
| foreach (var skill in occupation.ListOfIActiveSkill) | foreach (var skill in occupation.ListOfIActiveSkill) | ||||
| { | { | ||||
| var iActiveSkill = SkillFactory.FindIActiveSkill(skill); | |||||
| var iActiveSkill = SkillFactory.FindActiveSkill(skill); | |||||
| coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; | coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; | ||||
| ++i; | ++i; | ||||
| } | } | ||||
| @@ -848,7 +848,7 @@ namespace Client | |||||
| int j = 0; | int j = 0; | ||||
| foreach (var skill in occupation1.ListOfIActiveSkill) | foreach (var skill in occupation1.ListOfIActiveSkill) | ||||
| { | { | ||||
| var iActiveSkill = SkillFactory.FindIActiveSkill(skill); | |||||
| var iActiveSkill = SkillFactory.FindActiveSkill(skill); | |||||
| coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; | coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; | ||||
| ++j; | ++j; | ||||
| } | } | ||||
| @@ -11,37 +11,32 @@ namespace GameClass.GameObj | |||||
| private readonly IOccupation occupation; | private readonly IOccupation occupation; | ||||
| public IOccupation Occupation => occupation; | public IOccupation Occupation => occupation; | ||||
| private Dictionary<ActiveSkillType, int> timeUntilActiveSkillAvailable = new(); | |||||
| public Dictionary<ActiveSkillType, int> TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable; | |||||
| private Dictionary<ActiveSkillType, ActiveSkill> activeSkillDictionary = new(); | |||||
| public Dictionary<ActiveSkillType, ActiveSkill> ActiveSkillDictionary => activeSkillDictionary; | |||||
| private Dictionary<ActiveSkillType, IActiveSkill> iActiveSkillDictionary = new(); | |||||
| public Dictionary<ActiveSkillType, IActiveSkill> IActiveSkillDictionary => iActiveSkillDictionary; | |||||
| public IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType) | |||||
| public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType) | |||||
| { | { | ||||
| if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) | if (Occupation.ListOfIActiveSkill.Contains(activeSkillType)) | ||||
| { | { | ||||
| return IActiveSkillDictionary[activeSkillType]; | |||||
| return ActiveSkillDictionary[activeSkillType]; | |||||
| } | } | ||||
| return new NullSkill(); | return new NullSkill(); | ||||
| } | } | ||||
| public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable) | 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 true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| public bool AddTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int addTimeUntilActiveSkillAvailable) | 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 true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| @@ -72,12 +67,10 @@ namespace GameClass.GameObj | |||||
| foreach (var activeSkill in this.Occupation.ListOfIActiveSkill) | 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!"); | Debugger.Output(this, "constructed!"); | ||||
| } | } | ||||
| @@ -9,7 +9,7 @@ namespace GameClass.GameObj | |||||
| /// </summary> | /// </summary> | ||||
| public abstract class GameObj : IGameObj | public abstract class GameObj : IGameObj | ||||
| { | { | ||||
| private ReaderWriterLockSlim gameObjReaderWriterLock = new(); | |||||
| private readonly ReaderWriterLockSlim gameObjReaderWriterLock = new(); | |||||
| public ReaderWriterLockSlim GameObjReaderWriterLock => gameObjReaderWriterLock; | public ReaderWriterLockSlim GameObjReaderWriterLock => gameObjReaderWriterLock; | ||||
| protected readonly object gameObjLock = new(); | protected readonly object gameObjLock = new(); | ||||
| public object GameLock => gameObjLock; | public object GameLock => gameObjLock; | ||||
| @@ -150,7 +150,12 @@ namespace GameClass.GameObj | |||||
| whoLockOrOpen = null; | whoLockOrOpen = null; | ||||
| isOpen = true; | isOpen = true; | ||||
| } | } | ||||
| if (character != null) character.SetPlayerState(); | |||||
| if (character != null) | |||||
| { | |||||
| lock (character.ActionLock) | |||||
| if (character.PlayerState == PlayerStateType.OpeningTheDoor) | |||||
| character.SetPlayerState(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -193,13 +193,12 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| if (playerID == person.ID) | 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()); | Debugger.Output(person, person.PlayerID.ToString()); | ||||
| foreach (Character character in gameObjDict[GameObjType.Character]) | 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; | player = character; | ||||
| break; | break; | ||||
| @@ -162,13 +162,13 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| } | } | ||||
| protected long moveSpeed; | |||||
| protected int moveSpeed; | |||||
| /// <summary> | /// <summary> | ||||
| /// 移动速度 | /// 移动速度 | ||||
| /// </summary> | /// </summary> | ||||
| public long MoveSpeed | |||||
| public int MoveSpeed | |||||
| { | { | ||||
| get => Interlocked.Read(ref moveSpeed); | |||||
| get => Interlocked.CompareExchange(ref moveSpeed, 0, 1); | |||||
| set => Interlocked.Exchange(ref moveSpeed, value); | set => Interlocked.Exchange(ref moveSpeed, value); | ||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -21,11 +21,11 @@ namespace GameClass.GameObj | |||||
| public abstract bool IsUsable(); | public abstract bool IsUsable(); | ||||
| public abstract PropType GetPropType(); | 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) | base(initPos, radius, GameObjType.Gadget) | ||||
| { | { | ||||
| this.canMove = false; | this.canMove = false; | ||||
| this.MoveSpeed = GameData.PropMoveSpeed; | |||||
| this.MoveSpeed = GameData.propMoveSpeed; | |||||
| } | } | ||||
| } | } | ||||
| public abstract class Tool : Gadget | public abstract class Tool : Gadget | ||||
| @@ -13,7 +13,7 @@ namespace GameClass.GameObj | |||||
| public abstract PropType GetPropType(); | 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) | base(initPos, radius, GameObjType.Item) | ||||
| { | { | ||||
| this.canMove = false; | this.canMove = false; | ||||
| @@ -26,7 +26,7 @@ namespace Gaming | |||||
| gameMap.Remove((GameObj)collisionObj); | 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) | if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) | ||||
| player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); | player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); | ||||
| @@ -117,7 +117,7 @@ namespace Gaming | |||||
| if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) | if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) | ||||
| gameMap.NumOfRepairedGenerators++; | gameMap.NumOfRepairedGenerators++; | ||||
| if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator) | if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator) | ||||
| player.SetPlayerState(); | |||||
| player.SetPlayerState();//Num == player.StateNum | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | timeInterval: GameData.frameDuration, | ||||
| finallyReturn: () => 0 | finallyReturn: () => 0 | ||||
| @@ -215,7 +215,7 @@ namespace Gaming | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) | if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player)) | ||||
| playerTreated.SetPlayerState(); | |||||
| playerTreated.SetPlayerState();// | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | timeInterval: GameData.frameDuration, | ||||
| finallyReturn: () => 0 | finallyReturn: () => 0 | ||||
| @@ -426,7 +426,10 @@ namespace Gaming | |||||
| if (!doorToLock.TryLock(player)) | if (!doorToLock.TryLock(player)) | ||||
| { | { | ||||
| player.ReleaseTool(propType); | player.ReleaseTool(propType); | ||||
| player.SetPlayerState(); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) player.SetPlayerState(); | |||||
| } | |||||
| player.ThreadNum.Release(); | player.ThreadNum.Release(); | ||||
| } | } | ||||
| else | else | ||||
| @@ -495,7 +498,10 @@ namespace Gaming | |||||
| if (!doorToLock.TryOpen(player)) | if (!doorToLock.TryOpen(player)) | ||||
| { | { | ||||
| player.ReleaseTool(propType); | player.ReleaseTool(propType); | ||||
| player.SetPlayerState(); | |||||
| lock (player.ActionLock) | |||||
| { | |||||
| if (stateNum == player.StateNum) player.SetPlayerState(); | |||||
| } | |||||
| player.ThreadNum.Release(); | player.ThreadNum.Release(); | ||||
| } | } | ||||
| else | else | ||||
| @@ -284,7 +284,7 @@ namespace Gaming | |||||
| if (student.CharacterType == CharacterType.StraightAStudent) | if (student.CharacterType == CharacterType.StraightAStudent) | ||||
| { | { | ||||
| ((WriteAnswers)student.FindIActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0; | |||||
| ((WriteAnswers)student.FindActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0; | |||||
| } | } | ||||
| student.SetDegreeOfTreatment0(); | student.SetDegreeOfTreatment0(); | ||||
| @@ -382,8 +382,8 @@ namespace Gaming | |||||
| var parent = ((Golem)player).Parent; | var parent = ((Golem)player).Parent; | ||||
| if (parent != null && parent.CharacterType == CharacterType.TechOtaku) | 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; | return; | ||||
| } | } | ||||
| @@ -107,7 +107,7 @@ namespace Gaming | |||||
| if (pickProp.GetPropType() != PropType.Null) | if (pickProp.GetPropType() != PropType.Null) | ||||
| { | { | ||||
| gameMap.Remove(pickProp); | |||||
| gameMap.RemoveJustFromMap(pickProp); | |||||
| //gameMap.Add(new Item(pickProp)); | //gameMap.Add(new Item(pickProp)); | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -15,7 +15,7 @@ namespace Gaming | |||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| IActiveSkill skill = player.FindIActiveSkill(ActiveSkillType.CanBeginToCharge); | |||||
| ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.CanBeginToCharge); | |||||
| Debugger.Output(player, "can begin to charge!"); | Debugger.Output(player, "can begin to charge!"); | ||||
| @@ -31,7 +31,7 @@ namespace Gaming | |||||
| public bool ShowTime(Character player) | public bool ShowTime(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| IActiveSkill skill = player.FindIActiveSkill(ActiveSkillType.ShowTime); | |||||
| ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.ShowTime); | |||||
| return ActiveSkillEffect(skill, player, () => | return ActiveSkillEffect(skill, player, () => | ||||
| { | { | ||||
| @@ -93,7 +93,7 @@ namespace Gaming | |||||
| public static bool BecomeInvisible(Character player) | public static bool BecomeInvisible(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.BecomeInvisible); | |||||
| ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible); | |||||
| return ActiveSkillEffect(activeSkill, player, () => | return ActiveSkillEffect(activeSkill, player, () => | ||||
| { | { | ||||
| player.AddScore(GameData.ScoreBecomeInvisible); | player.AddScore(GameData.ScoreBecomeInvisible); | ||||
| @@ -106,20 +106,21 @@ namespace Gaming | |||||
| public bool UseRobot(Character player) | 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!"); | Debugger.Output(player, "use robot!"); | ||||
| IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.UseRobot); | |||||
| IActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.UseRobot); | |||||
| activeSkill.IsBeingUsed = (activeSkill.IsBeingUsed) ? false : true; | activeSkill.IsBeingUsed = (activeSkill.IsBeingUsed) ? false : true; | ||||
| if (activeSkill.IsBeingUsed) player.SetPlayerState(PlayerStateType.UsingSkill); | if (activeSkill.IsBeingUsed) player.SetPlayerState(PlayerStateType.UsingSkill); | ||||
| else player.SetPlayerState(); | |||||
| else player.SetPlayerState();*/ | |||||
| return true; | return true; | ||||
| } | } | ||||
| public static bool JumpyBomb(Character player) | public static bool JumpyBomb(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.JumpyBomb), player, () => | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.JumpyBomb), player, () => | |||||
| { | { | ||||
| player.BulletOfPlayer = BulletType.BombBomb; | player.BulletOfPlayer = BulletType.BombBomb; | ||||
| Debugger.Output(player, "uses jumpybomb!"); | Debugger.Output(player, "uses jumpybomb!"); | ||||
| @@ -131,7 +132,7 @@ namespace Gaming | |||||
| public bool WriteAnswers(Character player) | public bool WriteAnswers(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.WriteAnswers); | |||||
| ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.WriteAnswers); | |||||
| return ActiveSkillEffect(activeSkill, player, () => | return ActiveSkillEffect(activeSkill, player, () => | ||||
| { | { | ||||
| Generator? generator = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator); | Generator? generator = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator); | ||||
| @@ -149,25 +150,30 @@ namespace Gaming | |||||
| public bool SummonGolem(Character player) | 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, () => | return ActiveSkillEffect(activeSkill, player, () => | ||||
| { | { | ||||
| }, | }, | ||||
| () => | () => | ||||
| { }); | { }); | ||||
| } | } | ||||
| public static bool UseKnife(Character 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; | player.BulletOfPlayer = BulletType.FlyingKnife; | ||||
| Debugger.Output(player, "uses flyingknife!"); | Debugger.Output(player, "uses flyingknife!"); | ||||
| @@ -179,7 +185,7 @@ namespace Gaming | |||||
| public bool Howl(Character player) | public bool Howl(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Howl), player, () => | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Howl), player, () => | |||||
| { | { | ||||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | ||||
| try | try | ||||
| @@ -207,7 +213,7 @@ namespace Gaming | |||||
| public bool Punish(Character player) | public bool Punish(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Punish), player, () => | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Punish), player, () => | |||||
| { | { | ||||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | ||||
| try | try | ||||
| @@ -240,7 +246,7 @@ namespace Gaming | |||||
| public bool Rouse(Character player) | public bool Rouse(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Rouse), player, () => | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Rouse), player, () => | |||||
| { | { | ||||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | ||||
| try | try | ||||
| @@ -270,7 +276,7 @@ namespace Gaming | |||||
| public bool Encourage(Character player) | public bool Encourage(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Encourage), player, () => | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Encourage), player, () => | |||||
| { | { | ||||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | ||||
| try | try | ||||
| @@ -299,7 +305,7 @@ namespace Gaming | |||||
| public bool Inspire(Character player) | public bool Inspire(Character player) | ||||
| { | { | ||||
| if ((!player.Commandable())) return false; | if ((!player.Commandable())) return false; | ||||
| return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Inspire), player, () => | |||||
| return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Inspire), player, () => | |||||
| { | { | ||||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | ||||
| try | 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 | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| startSkill(); | startSkill(); | ||||
| activeSkill.IsBeingUsed = true; | |||||
| activeSkill.IsBeingUsed = 1; | |||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| () => !player.IsRemoved, | () => !player.IsRemoved, | ||||
| () => | () => | ||||
| { | { | ||||
| player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); | |||||
| activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration; | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | timeInterval: GameData.frameDuration, | ||||
| () => 0, | () => 0, | ||||
| @@ -353,14 +358,14 @@ namespace Gaming | |||||
| .Start(); | .Start(); | ||||
| endSkill(); | endSkill(); | ||||
| activeSkill.IsBeingUsed = false; | |||||
| activeSkill.IsBeingUsed = 0; | |||||
| Debugger.Output(player, "return to normal."); | Debugger.Output(player, "return to normal."); | ||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsRemoved, | |||||
| loopCondition: () => activeSkill.TimeUntilActiveSkillAvailable > 0, | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); | |||||
| activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration; | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | timeInterval: GameData.frameDuration, | ||||
| finallyReturn: () => 0 | finallyReturn: () => 0 | ||||
| @@ -371,7 +376,7 @@ namespace Gaming | |||||
| } | } | ||||
| .Start(); | .Start(); | ||||
| player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0); | |||||
| activeSkill.TimeUntilActiveSkillAvailable = 0; | |||||
| Debugger.Output(player, "ActiveSkill is ready."); | Debugger.Output(player, "ActiveSkill is ready."); | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -15,7 +15,7 @@ namespace Gaming // 被动技能开局时就释放,持续到游戏结束 | |||||
| public void Meditate(Character player) | public void Meditate(Character player) | ||||
| { | { | ||||
| const int learningDegree = GameData.basicFixSpeed / 4; | const int learningDegree = GameData.basicFixSpeed / 4; | ||||
| WriteAnswers activeSkill = (WriteAnswers)player.FindIActiveSkill(ActiveSkillType.WriteAnswers); | |||||
| WriteAnswers activeSkill = (WriteAnswers)player.FindActiveSkill(ActiveSkillType.WriteAnswers); | |||||
| new Thread | new Thread | ||||
| ( | ( | ||||
| () => | () => | ||||
| @@ -7,7 +7,7 @@ namespace Preparation.Interface | |||||
| public interface IMoveable : IGameObj | public interface IMoveable : IGameObj | ||||
| { | { | ||||
| object ActionLock { get; } | object ActionLock { get; } | ||||
| public long MoveSpeed { get; } | |||||
| public int MoveSpeed { get; } | |||||
| public bool IsMoving { get; set; } | public bool IsMoving { get; set; } | ||||
| public bool IsRemoved { get; } | public bool IsRemoved { get; } | ||||
| public bool IsAvailableForMove { get; } | public bool IsAvailableForMove { get; } | ||||
| @@ -315,13 +315,13 @@ namespace Preparation.Interface | |||||
| } | } | ||||
| public class TechOtaku : IStudentType | 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; | public int MoveSpeed => moveSpeed; | ||||
| private const int maxHp = (int)(GameData.basicHp * 0.9); | private const int maxHp = (int)(GameData.basicHp * 0.9); | ||||
| public int MaxHp => maxHp; | 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 int MaxGamingAddiction => maxGamingAddiction; | ||||
| public BulletType InitBullet => BulletType.Null; | public BulletType InitBullet => BulletType.Null; | ||||
| @@ -329,13 +329,13 @@ namespace Preparation.Interface | |||||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.SummonGolem, ActiveSkillType.UseRobot }); | public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.SummonGolem, ActiveSkillType.UseRobot }); | ||||
| public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { }); | public List<PassiveSkillType> 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 int FixSpeed => fixSpeed; | ||||
| public const int treatSpeed = GameData.basicTreatSpeed * 9 / 10; | |||||
| public const int treatSpeed = GameData.basicTreatSpeed; | |||||
| public int TreatSpeed => treatSpeed; | public int TreatSpeed => treatSpeed; | ||||
| public const double concealment = GameData.basicConcealment; | |||||
| public const double concealment = GameData.basicConcealment * 1.1; | |||||
| public double Concealment => concealment; | public double Concealment => concealment; | ||||
| public const int alertnessRadius = (int)(GameData.basicStudentAlertnessRadius); | public const int alertnessRadius = (int)(GameData.basicStudentAlertnessRadius); | ||||
| @@ -347,10 +347,10 @@ namespace Preparation.Interface | |||||
| public int speedOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking; | public int speedOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking; | ||||
| public int SpeedOfOpeningOrLocking => speedOfOpeningOrLocking; | 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 SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows; | ||||
| public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; | |||||
| public int speedOfOpenChest = GameData.basicSpeedOfOpenChest * 1100 / 1250; | |||||
| public int SpeedOfOpenChest => speedOfOpenChest; | public int SpeedOfOpenChest => speedOfOpenChest; | ||||
| } | } | ||||
| public class Sunshine : IStudentType | public class Sunshine : IStudentType | ||||
| @@ -1,5 +1,6 @@ | |||||
| using Preparation.Interface; | using Preparation.Interface; | ||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using System.Threading; | |||||
| namespace Preparation.Interface | namespace Preparation.Interface | ||||
| { | { | ||||
| @@ -13,241 +14,181 @@ namespace Preparation.Interface | |||||
| { | { | ||||
| public int SkillCD { get; } | public int SkillCD { get; } | ||||
| public int DurationTime { 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 class SkillFactory | ||||
| { | { | ||||
| public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType) | |||||
| public static ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType) | |||||
| { | { | ||||
| switch (activeSkillType) | switch (activeSkillType) | ||||
| { | { | ||||
| @@ -92,10 +92,10 @@ namespace Preparation.Utility | |||||
| public const int basicTreatSpeed = 100; | public const int basicTreatSpeed = 100; | ||||
| public const int basicFixSpeed = 123; | public const int basicFixSpeed = 123; | ||||
| public const int basicSpeedOfOpeningOrLocking = 4000; | |||||
| public const int basicSpeedOfOpeningOrLocking = 5000; | |||||
| public const int basicStudentSpeedOfClimbingThroughWindows = 1222; | public const int basicStudentSpeedOfClimbingThroughWindows = 1222; | ||||
| public const int basicGhostSpeedOfClimbingThroughWindows = 2540; | public const int basicGhostSpeedOfClimbingThroughWindows = 2540; | ||||
| public const int basicSpeedOfOpenChest = 1000; | |||||
| public const int basicSpeedOfOpenChest = 1250; | |||||
| public const int basicHp = 3000000; // 初始血量 | public const int basicHp = 3000000; // 初始血量 | ||||
| public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 | public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 | ||||
| @@ -228,10 +228,12 @@ namespace Preparation.Utility | |||||
| public const int checkIntervalWhenShowTime = 200; | public const int checkIntervalWhenShowTime = 200; | ||||
| public const int addAddictionPer100msWhenShowTime = 300; | public const int addAddictionPer100msWhenShowTime = 300; | ||||
| public const int maxSummonedGolemNum = 3; | |||||
| #endregion | #endregion | ||||
| #region 道具相关 | #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 int PropMaxMoveDistance = 15 * numOfPosGridPerCell; | ||||
| public const long PropProduceTime = 20000; | public const long PropProduceTime = 20000; | ||||
| public const int PropDuration = 10000; | public const int PropDuration = 10000; | ||||
| @@ -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); | msg.StudentMessage.TimeUntilSkillAvailable.Add(-1); | ||||
| foreach (var value in player.PropInventory) | foreach (var value in player.PropInventory) | ||||
| @@ -121,10 +121,9 @@ namespace Server | |||||
| BulletType = Transformation.ToBulletType((Preparation.Utility.BulletType)player.BulletOfPlayer) | 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); | msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1); | ||||
| foreach (var value in player.PropInventory) | foreach (var value in player.PropInventory) | ||||