| @@ -13,16 +13,6 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| public Ghost(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType) : base(initPos, initRadius, initPlace, characterType) | public Ghost(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType) : base(initPos, initRadius, initPlace, characterType) | ||||
| { | { | ||||
| switch (characterType) | |||||
| { | |||||
| case CharacterType.Assassin: | |||||
| this.Occupation = new Assassin(); | |||||
| break; | |||||
| default: | |||||
| this.Occupation = null; | |||||
| break; | |||||
| } | |||||
| this.CharacterType = characterType; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -7,9 +7,10 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| public partial class Character | public partial class Character | ||||
| { | { | ||||
| public CharacterType CharacterType { protected set; get; } | |||||
| public IOccupation Occupation { protected set; get; } | |||||
| private readonly CharacterType characterType; | |||||
| public CharacterType CharacterType => characterType; | |||||
| private readonly IOccupation occupation; | |||||
| public IOccupation Occupation => occupation; | |||||
| private Dictionary<ActiveSkillType, int> timeUntilActiveSkillAvailable; | private Dictionary<ActiveSkillType, int> timeUntilActiveSkillAvailable; | ||||
| public Dictionary<ActiveSkillType, int> TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable; | public Dictionary<ActiveSkillType, int> TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable; | ||||
| @@ -65,7 +66,18 @@ namespace GameClass.GameObj | |||||
| this.score = 0; | this.score = 0; | ||||
| this.propInventory = null; | this.propInventory = null; | ||||
| this.buffManager = new BuffManager(); | this.buffManager = new BuffManager(); | ||||
| switch (characterType) | |||||
| { | |||||
| case CharacterType.Assassin: | |||||
| this.occupation = new Assassin(); | |||||
| break; | |||||
| case CharacterType.Athlete: | |||||
| this.occupation = new Athlete(); | |||||
| break; | |||||
| default: | |||||
| this.occupation = null; | |||||
| break; | |||||
| } | |||||
| this.MaxHp = Occupation.MaxHp; | this.MaxHp = Occupation.MaxHp; | ||||
| this.hp = Occupation.MaxHp; | this.hp = Occupation.MaxHp; | ||||
| this.OrgMoveSpeed = Occupation.MoveSpeed; | this.OrgMoveSpeed = Occupation.MoveSpeed; | ||||
| @@ -75,6 +87,7 @@ namespace GameClass.GameObj | |||||
| this.bulletNum = maxBulletNum; | this.bulletNum = maxBulletNum; | ||||
| this.bulletOfPlayer = Occupation.InitBullet; | this.bulletOfPlayer = Occupation.InitBullet; | ||||
| this.OriBulletOfPlayer = Occupation.InitBullet; | this.OriBulletOfPlayer = Occupation.InitBullet; | ||||
| this.characterType = characterType; | |||||
| foreach (var activeSkill in this.Occupation.ListOfIActiveSkill) | foreach (var activeSkill in this.Occupation.ListOfIActiveSkill) | ||||
| { | { | ||||
| @@ -95,7 +95,7 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| } | } | ||||
| public void Escape() | |||||
| public Student(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType) : base(initPos, initRadius, initPlace, characterType) | |||||
| { | { | ||||
| lock (gameObjLock) | lock (gameObjLock) | ||||
| IsResetting = true; | IsResetting = true; | ||||
| @@ -113,7 +113,6 @@ namespace GameClass.GameObj | |||||
| break; | break; | ||||
| } | } | ||||
| this.fixSpeed = ((IStudent)Occupation).FixSpeed; | this.fixSpeed = ((IStudent)Occupation).FixSpeed; | ||||
| this.CharacterType = characterType; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -470,11 +470,22 @@ namespace GameClass.GameObj | |||||
| this.Vampire = this.OriVampire; | this.Vampire = this.OriVampire; | ||||
| } | } | ||||
| } | } | ||||
| public void Die(PlayerStateType playerStateType) | |||||
| { | |||||
| lock (gameObjLock) | |||||
| { | |||||
| playerState = playerStateType; | |||||
| CanMove = false; | |||||
| IsResetting = true; | |||||
| } | |||||
| } | |||||
| public override bool IsRigid => true; | public override bool IsRigid => true; | ||||
| public override ShapeType Shape => ShapeType.Circle; | public override ShapeType Shape => ShapeType.Circle; | ||||
| protected override bool IgnoreCollideExecutor(IGameObj targetObj) | protected override bool IgnoreCollideExecutor(IGameObj targetObj) | ||||
| { | { | ||||
| if (IsResetting) | |||||
| return true; | |||||
| if (targetObj.Type == GameObjType.Prop) // 自己队的地雷忽略碰撞 | if (targetObj.Type == GameObjType.Prop) // 自己队的地雷忽略碰撞 | ||||
| { | { | ||||
| return true; | return true; | ||||
| @@ -3,6 +3,7 @@ using System.Threading; | |||||
| using Preparation.Interface; | using Preparation.Interface; | ||||
| using Preparation.Utility; | using Preparation.Utility; | ||||
| using System; | using System; | ||||
| using GameClass.GameObj; | |||||
| namespace GameClass.GameObj | namespace GameClass.GameObj | ||||
| { | { | ||||
| @@ -72,6 +73,40 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| return player; | return player; | ||||
| } | } | ||||
| public bool Remove(GameObj gameObj) | |||||
| { | |||||
| bool flag = false; | |||||
| GameObjLockDict[gameObj.Type].EnterWriteLock(); | |||||
| try | |||||
| { | |||||
| foreach (GameObj obj in GameObjDict[gameObj.Type]) | |||||
| { | |||||
| if (gameObj.ID == obj.ID) | |||||
| { | |||||
| GameObjDict[gameObj.Type].Remove(obj); | |||||
| flag = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| finally | |||||
| { | |||||
| GameObjLockDict[gameObj.Type].ExitWriteLock(); | |||||
| } | |||||
| return flag; | |||||
| } | |||||
| public void Add(GameObj gameObj) | |||||
| { | |||||
| GameObjLockDict[gameObj.Type].EnterWriteLock(); | |||||
| try | |||||
| { | |||||
| GameObjDict[gameObj.Type].Add(gameObj); | |||||
| } | |||||
| finally | |||||
| { | |||||
| GameObjLockDict[gameObj.Type].ExitWriteLock(); | |||||
| } | |||||
| } | |||||
| public Map(uint[,] mapResource) | public Map(uint[,] mapResource) | ||||
| { | { | ||||
| gameObjDict = new Dictionary<GameObjType, IList<IGameObj>>(); | gameObjDict = new Dictionary<GameObjType, IList<IGameObj>>(); | ||||
| @@ -132,7 +132,7 @@ namespace Gaming | |||||
| if (doorwayForEscape != null && doorwayForEscape.IsOpen) | if (doorwayForEscape != null && doorwayForEscape.IsOpen) | ||||
| { | { | ||||
| player.Escape(); | |||||
| player.Die(PlayerStateType.IsEscaped); | |||||
| return true; | return true; | ||||
| } | } | ||||
| else | else | ||||
| @@ -100,7 +100,7 @@ namespace Gaming | |||||
| gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock(); | gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock(); | ||||
| } | } | ||||
| player.Reset(); | |||||
| // player.Reset(); | |||||
| // ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 | // ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 | ||||
| /* new Thread | /* new Thread | ||||
| @@ -154,31 +154,9 @@ namespace Gaming | |||||
| Debugger.Output(bullet, "bombed!"); | Debugger.Output(bullet, "bombed!"); | ||||
| #endif | #endif | ||||
| bullet.CanMove = false; | bullet.CanMove = false; | ||||
| gameMap.GameObjLockDict[GameObjType.Bullet].EnterWriteLock(); | |||||
| try | |||||
| { | |||||
| foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjType.Bullet]) | |||||
| { | |||||
| if (_bullet.ID == bullet.ID) | |||||
| { | |||||
| gameMap.GameObjLockDict[GameObjType.BombedBullet].EnterWriteLock(); | |||||
| try | |||||
| { | |||||
| gameMap.GameObjDict[GameObjType.BombedBullet].Add(new BombedBullet(bullet)); | |||||
| } | |||||
| finally | |||||
| { | |||||
| gameMap.GameObjLockDict[GameObjType.BombedBullet].ExitWriteLock(); | |||||
| } | |||||
| gameMap.GameObjDict[GameObjType.Bullet].Remove(_bullet); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| finally | |||||
| { | |||||
| gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock(); | |||||
| } | |||||
| if (gameMap.Remove(bullet) && bullet.IsToBomb) | |||||
| gameMap.Add(new BombedBullet(bullet)); | |||||
| if (!bullet.IsToBomb) | if (!bullet.IsToBomb) | ||||
| { | { | ||||
| @@ -334,12 +312,27 @@ namespace Gaming | |||||
| new Thread | new Thread | ||||
| (() => | (() => | ||||
| { | { | ||||
| Thread.Sleep(bullet.CastTime); | |||||
| if (gameMap.Timer.IsGaming && player.PlayerState == PlayerStateType.IsTryingToAttack) | |||||
| new FrameRateTaskExecutor<int>( | |||||
| loopCondition: () => player.PlayerState == PlayerStateType.IsTryingToAttack && gameMap.Timer.IsGaming, | |||||
| loopToDo: () => | |||||
| { | |||||
| }, | |||||
| timeInterval: GameData.frameDuration, | |||||
| finallyReturn: () => 0, | |||||
| maxTotalDuration: bullet.CastTime | |||||
| ) | |||||
| .Start(); | |||||
| if (gameMap.Timer.IsGaming) | |||||
| { | { | ||||
| player.PlayerState = PlayerStateType.Null; | |||||
| if (player.PlayerState == PlayerStateType.IsTryingToAttack) | |||||
| { | |||||
| player.PlayerState = PlayerStateType.Null; | |||||
| } | |||||
| else | |||||
| bullet.IsMoving = false; | |||||
| gameMap.Remove(bullet); | |||||
| } | } | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -81,6 +81,7 @@ namespace Preparation.Utility | |||||
| public const int bulletRadius = 200; // 默认子弹半径 | public const int bulletRadius = 200; // 默认子弹半径 | ||||
| public const int reviveTime = 30000; // 复活时间 | public const int reviveTime = 30000; // 复活时间 | ||||
| public const int shieldTimeAtBirth = 3000; // 复活时的护盾时间 | public const int shieldTimeAtBirth = 3000; // 复活时的护盾时间 | ||||
| public static XY PosWhoDie = new XY(1, 1); | |||||
| public static bool IsGhost(CharacterType characterType) | public static bool IsGhost(CharacterType characterType) | ||||
| { | { | ||||
| @@ -392,17 +392,17 @@ namespace Server | |||||
| msg.MessageOfBullet.ParentTeamID = bullet.Parent.TeamID; | msg.MessageOfBullet.ParentTeamID = bullet.Parent.TeamID; | ||||
| switch (bullet.Place) | switch (bullet.Place) | ||||
| { | { | ||||
| case Preparation.Utility.PlacccceType.Land: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlacccceType.Land; | |||||
| case Preparation.Utility.PlaceType.Null: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlaceType.Null; | |||||
| break; | break; | ||||
| case Preparation.Utility.PlacccceType.Grass1: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlacccceType.Grass1; | |||||
| case Preparation.Utility.PlaceType.Grass: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlaceType.Grass; | |||||
| break; | break; | ||||
| case Preparation.Utility.PlacccceType.Grass2: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlacccceType.Grass2; | |||||
| case Preparation.Utility.PlaceType.Grass: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlaceType.Grass; | |||||
| break; | break; | ||||
| case Preparation.Utility.PlacccceType.Grass3: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlacccceType.Grass3; | |||||
| case Preparation.Utility.PlaceType.Grass: | |||||
| msg.MessageOfBullet.Place = Communication.Proto.PlaceType.Grass; | |||||
| break; | break; | ||||
| default: | default: | ||||
| msg.MessageOfBullet.Place = Communication.Proto.PlacccceType.NullPlaceType; | msg.MessageOfBullet.Place = Communication.Proto.PlacccceType.NullPlaceType; | ||||
| @@ -459,17 +459,17 @@ namespace Server | |||||
| } | } | ||||
| switch (prop.Place) | switch (prop.Place) | ||||
| { | { | ||||
| case Preparation.Utility.PlacccceType.Land: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlacccceType.Land; | |||||
| case Preparation.Utility.PlaceType.Null: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlaceType.Null; | |||||
| break; | break; | ||||
| case Preparation.Utility.PlacccceType.Grass1: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlacccceType.Grass1; | |||||
| case Preparation.Utility.PlaceType.Grass: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlaceType.Grass; | |||||
| break; | break; | ||||
| case Preparation.Utility.PlacccceType.Grass2: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlacccceType.Grass2; | |||||
| case Preparation.Utility.PlaceType.Grass: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlaceType.Grass; | |||||
| break; | break; | ||||
| case Preparation.Utility.PlacccceType.Grass3: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlacccceType.Grass3; | |||||
| case Preparation.Utility.PlaceType.Grass: | |||||
| msg.MessageOfProp.Place = Communication.Proto.PlaceType.Grass; | |||||
| break; | break; | ||||
| default: | default: | ||||
| msg.MessageOfProp.Place = Communication.Proto.PlacccceType.NullPlaceType; | msg.MessageOfProp.Place = Communication.Proto.PlacccceType.NullPlaceType; | ||||