| @@ -15,6 +15,7 @@ namespace GameClass.GameObj | |||
| public override int AP => GameData.basicApOfGhost; | |||
| public override int Speed => GameData.basicBulletMoveSpeed; | |||
| public override bool IsToBomb => false; | |||
| public override int CastTime => GameData.basicCastTime; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool CanAttack(GameObj target) | |||
| @@ -36,6 +37,7 @@ namespace GameClass.GameObj | |||
| public override int AP => GameData.basicApOfGhost / 5 * 4; | |||
| public override int Speed => GameData.basicBulletMoveSpeed * 2; | |||
| public override bool IsToBomb => false; | |||
| public override int CastTime => GameData.basicCastTime; | |||
| public override int Backswing => GameData.basicBackswing / 5 * 3; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit / 4 * 3; | |||
| public override bool CanAttack(GameObj target) | |||
| @@ -57,6 +59,7 @@ namespace GameClass.GameObj | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange / 9 * 7; | |||
| public override int AP => GameData.basicApOfGhost / 3 * 7; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2; | |||
| public override int CastTime => GameData.basicCastTime; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| @@ -80,6 +83,7 @@ namespace GameClass.GameObj | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange / 2; | |||
| public override int AP => GameData.basicApOfGhost / 6 * 5; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 6 * 5; | |||
| public override int CastTime => GameData.basicCastTime; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| @@ -102,6 +106,7 @@ namespace GameClass.GameObj | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange; | |||
| public override int AP => (int)(0.5 * GameData.basicApOfGhost); | |||
| public override int Speed => 5 * GameData.basicBulletMoveSpeed / 3; | |||
| public override int CastTime => GameData.basicCastTime; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| @@ -125,6 +130,7 @@ namespace GameClass.GameObj | |||
| public override double BulletAttackRange => 0.1 * GameData.basicAttackShortRange; | |||
| public override int AP => GameData.basicApOfGhost / 3 * 2; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 3; | |||
| public override int CastTime => GameData.basicCastTime; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| @@ -14,6 +14,7 @@ namespace GameClass.GameObj | |||
| public abstract int AP { get; } | |||
| public abstract int Speed { get; } | |||
| public abstract bool IsToBomb { get; } | |||
| public abstract int CastTime { get; } | |||
| public abstract int Backswing { get; } | |||
| public abstract int RecoveryFromHit { get; } | |||
| @@ -0,0 +1,17 @@ | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Numerics; | |||
| using System.Runtime.InteropServices; | |||
| using System.Threading; | |||
| namespace GameClass.GameObj | |||
| { | |||
| public class Ghost : Character | |||
| { | |||
| public Ghost(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType) : base(initPos, initRadius, initPlace, characterType) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| @@ -60,7 +60,7 @@ namespace GameClass.GameObj | |||
| }; | |||
| } | |||
| public Character(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType, ActiveSkillType commonSkillType) : | |||
| public Character(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType) : | |||
| base(initPos, initRadius, initPlace, GameObjType.Character) | |||
| { | |||
| this.CanMove = true; | |||
| @@ -0,0 +1,107 @@ | |||
| using Preparation.Utility; | |||
| namespace GameClass.GameObj | |||
| { | |||
| public class Student : Character | |||
| { | |||
| protected int fixSpeed = GameData.basicFixSpeed; | |||
| /// <summary> | |||
| /// 修理电机速度 | |||
| /// </summary> | |||
| public int FixSpeed | |||
| { | |||
| get => fixSpeed; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| fixSpeed = value; | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 原初修理电机速度 | |||
| /// </summary> | |||
| public int OrgFixSpeed { get; protected set; } = GameData.basicFixSpeed; | |||
| protected int treatSpeed = GameData.basicTreatSpeed; | |||
| public int TreatSpeed | |||
| { | |||
| get => treatSpeed; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| treatSpeed = value; | |||
| } | |||
| } | |||
| } | |||
| public int OrgTreatSpeed { get; protected set; } = GameData.basicTreatSpeed; | |||
| protected int rescueSpeed = GameData.basicRescueSpeed; | |||
| public int RescueSpeed | |||
| { | |||
| get => rescueSpeed; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| rescueSpeed = value; | |||
| } | |||
| } | |||
| } | |||
| public int OrgRescueSpeed { get; protected set; } = GameData.basicRescueSpeed; | |||
| public int MaxGamingAddiction { get; protected set; } | |||
| private int gamingAddiction; | |||
| public int GamingAddiction | |||
| { | |||
| get => gamingAddiction; | |||
| set | |||
| { | |||
| if (gamingAddiction > 0) | |||
| lock (gameObjLock) | |||
| gamingAddiction = value <= MaxGamingAddiction ? value : MaxGamingAddiction; | |||
| else | |||
| lock (gameObjLock) | |||
| gamingAddiction = 0; | |||
| } | |||
| } | |||
| private int selfHealingTimes = 1;//剩余的自愈次数 | |||
| public int SelfHealingTimes | |||
| { | |||
| get => selfHealingTimes; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| selfHealingTimes = (value > 0) ? value : 0; | |||
| } | |||
| } | |||
| private int degreeOfTreatment = 0; | |||
| public int DegreeOfTreatment | |||
| { | |||
| get => degreeOfTreatment; | |||
| set | |||
| { | |||
| if (value > 0) | |||
| lock (gameObjLock) | |||
| degreeOfTreatment = (value < MaxHp - HP) ? value : MaxHp - HP; | |||
| else | |||
| lock (gameObjLock) | |||
| degreeOfTreatment = 0; | |||
| } | |||
| } | |||
| public void Escape() | |||
| { | |||
| lock (gameObjLock) | |||
| IsResetting = true; | |||
| PlayerState = PlayerStateType.IsEscaped; | |||
| } | |||
| public Student(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType) : base(initPos, initRadius, initPlace, characterType) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| @@ -31,54 +31,6 @@ namespace GameClass.GameObj | |||
| } | |||
| public int OrgCD { get; protected set; } | |||
| protected int fixSpeed = GameData.basicFixSpeed; | |||
| /// <summary> | |||
| /// 修理电机速度 | |||
| /// </summary> | |||
| public int FixSpeed | |||
| { | |||
| get => fixSpeed; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| fixSpeed = value; | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 原初修理电机速度 | |||
| /// </summary> | |||
| public int OrgFixSpeed { get; protected set; } = GameData.basicFixSpeed; | |||
| protected int treatSpeed = GameData.basicTreatSpeed; | |||
| public int TreatSpeed | |||
| { | |||
| get => treatSpeed; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| treatSpeed = value; | |||
| } | |||
| } | |||
| } | |||
| public int OrgTreatSpeed { get; protected set; } = GameData.basicTreatSpeed; | |||
| protected int rescueSpeed = GameData.basicRescueSpeed; | |||
| public int RescueSpeed | |||
| { | |||
| get => rescueSpeed; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| rescueSpeed = value; | |||
| } | |||
| } | |||
| } | |||
| public int OrgRescueSpeed { get; protected set; } = GameData.basicRescueSpeed; | |||
| protected int maxBulletNum; | |||
| public int MaxBulletNum => maxBulletNum; // 人物最大子弹数 | |||
| protected int bulletNum; | |||
| @@ -102,22 +54,6 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| public int MaxGamingAddiction { get; protected set; } | |||
| private int gamingAddiction; | |||
| public int GamingAddiction | |||
| { | |||
| get => gamingAddiction; | |||
| set | |||
| { | |||
| if (gamingAddiction > 0) | |||
| lock (gameObjLock) | |||
| gamingAddiction = value <= MaxGamingAddiction ? value : MaxGamingAddiction; | |||
| else | |||
| lock (gameObjLock) | |||
| gamingAddiction = 0; | |||
| } | |||
| } | |||
| private PlayerStateType playerState = PlayerStateType.Null; | |||
| public PlayerStateType PlayerState | |||
| { | |||
| @@ -129,11 +65,10 @@ namespace GameClass.GameObj | |||
| } | |||
| set | |||
| { | |||
| if (value != PlayerStateType.IsMoving && value != PlayerStateType.Null) | |||
| lock (gameObjLock) | |||
| CanMove = false; | |||
| lock (gameObjLock) | |||
| CanMove = (value == PlayerStateType.IsMoving || value == PlayerStateType.Null); | |||
| lock (gameObjLock) playerState = value; | |||
| lock (gameObjLock) playerState = (value == PlayerStateType.IsMoving) ? PlayerStateType.Null : value; | |||
| } | |||
| } | |||
| @@ -183,32 +118,6 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| private int selfHealingTimes = 1;//剩余的自愈次数 | |||
| public int SelfHealingTimes | |||
| { | |||
| get => selfHealingTimes; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| selfHealingTimes = (value > 0) ? value : 0; | |||
| } | |||
| } | |||
| private int degreeOfTreatment = 0; | |||
| public int DegreeOfTreatment | |||
| { | |||
| get => degreeOfTreatment; | |||
| set | |||
| { | |||
| if (value > 0) | |||
| lock (gameObjLock) | |||
| degreeOfTreatment = (value < MaxHp - HP) ? value : MaxHp - HP; | |||
| else | |||
| lock (gameObjLock) | |||
| degreeOfTreatment = 0; | |||
| } | |||
| } | |||
| public readonly BulletType OriBulletOfPlayer; | |||
| private BulletType bulletOfPlayer; | |||
| public BulletType BulletOfPlayer | |||
| @@ -561,12 +470,6 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| public void Escape() | |||
| { | |||
| lock (gameObjLock) | |||
| IsResetting = true; | |||
| PlayerState = PlayerStateType.IsEscaped; | |||
| } | |||
| public override bool IsRigid => true; | |||
| public override ShapeType Shape => ShapeType.Circle; | |||
| protected override bool IgnoreCollideExecutor(IGameObj targetObj) | |||
| @@ -15,12 +15,14 @@ namespace Gaming | |||
| { | |||
| // 人物移动 | |||
| public void MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | |||
| public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) | |||
| { | |||
| if (playerToMove.PlayerState != PlayerStateType.Null) return false; | |||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); | |||
| return true; | |||
| } | |||
| public bool Fix(Character player)// 自动检查有无发电机可修 | |||
| public bool Fix(Student player)// 自动检查有无发电机可修 | |||
| { | |||
| if (player.PlayerState != PlayerStateType.Null || player.IsGhost()) | |||
| return false; | |||
| @@ -53,7 +55,7 @@ namespace Gaming | |||
| () => | |||
| { | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => player.PlayerState == PlayerStateType.IsFixing && generatorForFix.DegreeOfFRepair < GameData.degreeOfFixedGenerator && GameData.ApproachToInteract(player.Position, generatorForFix.Position), | |||
| loopCondition: () => player.PlayerState == PlayerStateType.IsFixing && gameMap.Timer.IsGaming && generatorForFix.DegreeOfFRepair < GameData.degreeOfFixedGenerator && GameData.ApproachToInteract(player.Position, generatorForFix.Position), | |||
| loopToDo: () => | |||
| { | |||
| return !generatorForFix.Repair(player.FixSpeed * GameData.frameDuration); | |||
| @@ -63,48 +65,48 @@ namespace Gaming | |||
| ) | |||
| .Start(); | |||
| if (generatorForFix.DegreeOfFRepair == GameData.degreeOfFixedGenerator) | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock(); | |||
| try | |||
| { | |||
| Doorway exit = (Doorway)gameMap.GameObjDict[GameObjType.Doorway][1]; | |||
| if (!exit.PowerSupply) | |||
| { | |||
| int numOfFixedGenerator = 0; | |||
| foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator]) | |||
| if (generator.DegreeOfFRepair == GameData.degreeOfFixedGenerator) | |||
| ++numOfFixedGenerator; | |||
| if (numOfFixedGenerator >= GameData.numOfGeneratorRequiredForRepair) | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock(); | |||
| try | |||
| { | |||
| foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway]) | |||
| doorway.PowerSupply = true; | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock(); | |||
| } | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| if (generatorForFix.DegreeOfFRepair == GameData.degreeOfFixedGenerator) | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock(); | |||
| try | |||
| { | |||
| Doorway exit = (Doorway)gameMap.GameObjDict[GameObjType.Doorway][1]; | |||
| if (!exit.PowerSupply) | |||
| { | |||
| int numOfFixedGenerator = 0; | |||
| foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator]) | |||
| if (generator.DegreeOfFRepair == GameData.degreeOfFixedGenerator) | |||
| ++numOfFixedGenerator; | |||
| if (numOfFixedGenerator >= GameData.numOfGeneratorRequiredForRepair) | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock(); | |||
| try | |||
| { | |||
| foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway]) | |||
| doorway.PowerSupply = true; | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock(); | |||
| } | |||
| return true; | |||
| } | |||
| return false; | |||
| return true; | |||
| } | |||
| public bool Escape(Character player) | |||
| public bool Escape(Student player) | |||
| { | |||
| if (!(player.PlayerState == PlayerStateType.Null || player.PlayerState == PlayerStateType.IsMoving) || player.IsGhost()) | |||
| return false; | |||
| @@ -137,7 +139,7 @@ namespace Gaming | |||
| return false; | |||
| } | |||
| public bool Treat(Character player, Character playerTreated) | |||
| public bool Treat(Student player, Student playerTreated) | |||
| { | |||
| if (playerTreated.PlayerState == PlayerStateType.Null || player.PlayerState == PlayerStateType.Null || playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position)) | |||
| return false; | |||
| @@ -146,21 +148,21 @@ namespace Gaming | |||
| { | |||
| playerTreated.HP = playerTreated.MaxHp; | |||
| playerTreated.DegreeOfTreatment = 0; | |||
| return true; | |||
| return false; | |||
| } | |||
| if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree) | |||
| { | |||
| playerTreated.HP += GameData.basicTreatmentDegree; | |||
| playerTreated.DegreeOfTreatment = 0; | |||
| return true; | |||
| return false; | |||
| } | |||
| new Thread | |||
| ( | |||
| () => | |||
| { | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => playerTreated.PlayerState == PlayerStateType.IsTreated && player.PlayerState == PlayerStateType.IsTreating && playerTreated.HP + playerTreated.DegreeOfTreatment < playerTreated.MaxHp && playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree && GameData.ApproachToInteract(playerTreated.Position, player.Position), | |||
| loopCondition: () => playerTreated.PlayerState == PlayerStateType.IsTreated && player.PlayerState == PlayerStateType.IsTreating && gameMap.Timer.IsGaming && playerTreated.HP + playerTreated.DegreeOfTreatment < playerTreated.MaxHp && playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree && GameData.ApproachToInteract(playerTreated.Position, player.Position), | |||
| loopToDo: () => | |||
| { | |||
| playerTreated.DegreeOfTreatment += GameData.frameDuration * player.TreatSpeed; | |||
| @@ -170,30 +172,28 @@ namespace Gaming | |||
| ) | |||
| .Start(); | |||
| if (playerTreated.PlayerState == PlayerStateType.IsTreated) playerTreated.PlayerState = PlayerStateType.Null; | |||
| if (player.PlayerState == PlayerStateType.IsTreating) player.PlayerState = PlayerStateType.Null; | |||
| if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp) | |||
| { | |||
| playerTreated.HP = playerTreated.MaxHp; | |||
| playerTreated.DegreeOfTreatment = 0; | |||
| } | |||
| else | |||
| if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree) | |||
| { | |||
| playerTreated.HP += GameData.basicTreatmentDegree; | |||
| playerTreated.DegreeOfTreatment = 0; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| if (playerTreated.PlayerState == PlayerStateType.IsTreated) playerTreated.PlayerState = PlayerStateType.Null; | |||
| if (player.PlayerState == PlayerStateType.IsTreating) player.PlayerState = PlayerStateType.Null; | |||
| if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp) | |||
| { | |||
| playerTreated.HP = playerTreated.MaxHp; | |||
| playerTreated.DegreeOfTreatment = 0; | |||
| return true; | |||
| } | |||
| if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree) | |||
| { | |||
| playerTreated.HP += GameData.basicTreatmentDegree; | |||
| playerTreated.DegreeOfTreatment = 0; | |||
| return true; | |||
| } | |||
| return false; | |||
| return true; | |||
| } | |||
| public bool Rescue(Character player, Character playerRescued) | |||
| public bool Rescue(Student player, Student playerRescued) | |||
| { | |||
| if (player.PlayerState != PlayerStateType.Null || playerRescued.PlayerState != PlayerStateType.IsAddicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position)) | |||
| return false; | |||
| @@ -205,7 +205,7 @@ namespace Gaming | |||
| () => | |||
| { | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => playerRescued.PlayerState == PlayerStateType.IsRescued && player.PlayerState == PlayerStateType.IsRescuing && GameData.ApproachToInteract(playerRescued.Position, player.Position), | |||
| loopCondition: () => playerRescued.PlayerState == PlayerStateType.IsRescued && player.PlayerState == PlayerStateType.IsRescuing && gameMap.Timer.IsGaming && GameData.ApproachToInteract(playerRescued.Position, player.Position), | |||
| loopToDo: () => | |||
| { | |||
| rescuedDegree += GameData.frameDuration; | |||
| @@ -216,21 +216,22 @@ namespace Gaming | |||
| ) | |||
| .Start(); | |||
| if (rescuedDegree == 1000) | |||
| { | |||
| if (playerRescued.PlayerState == PlayerStateType.IsRescued) playerRescued.PlayerState = PlayerStateType.Null; | |||
| if (player.PlayerState == PlayerStateType.IsRescuing) player.PlayerState = PlayerStateType.Null; | |||
| } | |||
| else | |||
| { | |||
| if (playerRescued.PlayerState == PlayerStateType.IsRescued) playerRescued.PlayerState = PlayerStateType.Null; | |||
| if (player.PlayerState == PlayerStateType.IsRescuing) player.PlayerState = PlayerStateType.IsAddicted; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| if (rescuedDegree == 1000) | |||
| { | |||
| if (playerRescued.PlayerState == PlayerStateType.IsRescued) playerRescued.PlayerState = PlayerStateType.Null; | |||
| if (player.PlayerState == PlayerStateType.IsRescuing) player.PlayerState = PlayerStateType.Null; | |||
| return true; | |||
| } | |||
| else | |||
| { | |||
| if (playerRescued.PlayerState == PlayerStateType.IsRescued) playerRescued.PlayerState = PlayerStateType.Null; | |||
| if (player.PlayerState == PlayerStateType.IsRescuing) player.PlayerState = PlayerStateType.IsAddicted; | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| /* | |||
| @@ -37,7 +37,7 @@ namespace Gaming | |||
| ); | |||
| } | |||
| public void BeAddictedToGame(Character player) | |||
| public void BeAddictedToGame(Student player) | |||
| { | |||
| new Thread | |||
| (() => | |||
| @@ -46,7 +46,7 @@ namespace Gaming | |||
| player.GamingAddiction = GameData.MidGamingAddiction; | |||
| player.PlayerState = PlayerStateType.IsAddicted; | |||
| new FrameRateTaskExecutor<int>( | |||
| () => player.PlayerState == PlayerStateType.IsAddicted && player.GamingAddiction < player.MaxGamingAddiction, | |||
| () => player.PlayerState == PlayerStateType.IsAddicted && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming, | |||
| () => | |||
| { | |||
| player.GamingAddiction += GameData.frameDuration; | |||
| @@ -54,12 +54,10 @@ namespace Gaming | |||
| timeInterval: GameData.frameDuration, | |||
| () => | |||
| { | |||
| if (player.GamingAddiction == player.MaxGamingAddiction) | |||
| if (player.GamingAddiction == player.MaxGamingAddiction && gameMap.Timer.IsGaming) | |||
| { | |||
| player.PlayerState = PlayerStateType.Null; | |||
| Die(player); | |||
| } | |||
| else player.CanMove = true; | |||
| return 0; | |||
| } | |||
| ) | |||
| @@ -140,11 +138,11 @@ namespace Gaming | |||
| switch (objBeingShot.Type) | |||
| { | |||
| case GameObjType.Character: | |||
| Character playerBeingShot = (Character)objBeingShot; | |||
| if (playerBeingShot.BeAttacked(bullet)) | |||
| { | |||
| BeAddictedToGame(playerBeingShot); | |||
| } | |||
| if (!((Character)objBeingShot).IsGhost()) | |||
| if (((Character)objBeingShot).BeAttacked(bullet)) | |||
| { | |||
| BeAddictedToGame((Student)objBeingShot); | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| @@ -187,8 +185,7 @@ namespace Gaming | |||
| { | |||
| if (bullet.Backswing > 0) | |||
| { | |||
| bullet.Parent.CanMove = false; | |||
| bullet.Parent.IsMoving = false; | |||
| bullet.Parent.PlayerState = PlayerStateType.IsSwinging; | |||
| new Thread | |||
| (() => | |||
| @@ -197,7 +194,7 @@ namespace Gaming | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| bullet.Parent.PlayerState = PlayerStateType.Null; | |||
| } | |||
| } | |||
| ) | |||
| @@ -210,8 +207,7 @@ namespace Gaming | |||
| BombObj(bullet, objBeingShot); | |||
| if (bullet.RecoveryFromHit > 0) | |||
| { | |||
| bullet.Parent.CanMove = false; | |||
| bullet.Parent.IsMoving = false; | |||
| bullet.Parent.PlayerState = PlayerStateType.IsSwinging; | |||
| new Thread | |||
| (() => | |||
| @@ -221,7 +217,7 @@ namespace Gaming | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| bullet.Parent.PlayerState = PlayerStateType.Null; | |||
| } | |||
| } | |||
| ) | |||
| @@ -270,8 +266,7 @@ namespace Gaming | |||
| { | |||
| if (bullet.Backswing > 0) | |||
| { | |||
| bullet.Parent.CanMove = false; | |||
| bullet.Parent.IsMoving = false; | |||
| bullet.Parent.PlayerState = PlayerStateType.IsSwinging; | |||
| new Thread | |||
| (() => | |||
| @@ -280,7 +275,7 @@ namespace Gaming | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| bullet.Parent.PlayerState = PlayerStateType.Null; | |||
| } | |||
| } | |||
| ) | |||
| @@ -291,8 +286,7 @@ namespace Gaming | |||
| { | |||
| if (bullet.RecoveryFromHit > 0) | |||
| { | |||
| bullet.Parent.CanMove = false; | |||
| bullet.Parent.IsMoving = false; | |||
| bullet.Parent.PlayerState = PlayerStateType.IsSwinging; | |||
| new Thread | |||
| (() => | |||
| @@ -302,7 +296,7 @@ namespace Gaming | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| bullet.Parent.PlayerState = PlayerStateType.Null; | |||
| } | |||
| } | |||
| ) | |||
| @@ -322,8 +316,9 @@ namespace Gaming | |||
| return false; | |||
| } | |||
| if (player.IsResetting) | |||
| if (player.PlayerState != PlayerStateType.Null || player.PlayerState != PlayerStateType.IsMoving) | |||
| return false; | |||
| Bullet? bullet = player.RemoteAttack( | |||
| new XY // 子弹紧贴人物生成。 | |||
| ( | |||
| @@ -331,6 +326,24 @@ namespace Gaming | |||
| (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Sin(angle)) | |||
| ) | |||
| ); | |||
| if (bullet.CastTime > 0) | |||
| { | |||
| player.PlayerState = PlayerStateType.IsSwinging; | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(bullet.CastTime); | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| player.PlayerState = PlayerStateType.Null; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| if (bullet != null) | |||
| { | |||
| bullet.CanMove = true; | |||
| @@ -16,13 +16,11 @@ namespace Gaming | |||
| public long teamID; | |||
| public long playerID; | |||
| public CharacterType characterType; | |||
| public ActiveSkillType commonSkill; | |||
| public PlayerInitInfo(uint birthPointIndex, long teamID, long playerID, CharacterType characterType, ActiveSkillType commonSkill) | |||
| public PlayerInitInfo(uint birthPointIndex, long teamID, long playerID, CharacterType characterType) | |||
| { | |||
| this.birthPointIndex = birthPointIndex; | |||
| this.teamID = teamID; | |||
| this.characterType = characterType; | |||
| this.commonSkill = commonSkill; | |||
| this.playerID = playerID; | |||
| } | |||
| } | |||
| @@ -41,7 +39,7 @@ namespace Gaming | |||
| XY pos = gameMap.BirthPointList[playerInitInfo.birthPointIndex].Position; | |||
| // Console.WriteLine($"x,y: {pos.x},{pos.y}"); | |||
| Character newPlayer = new(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.characterType, playerInitInfo.commonSkill); | |||
| Character newPlayer = (GameData.IsGhost(playerInitInfo.characterType)) ? new Ghost(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.characterType) : new Student(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.characterType); | |||
| gameMap.BirthPointList[playerInitInfo.birthPointIndex].Parent = newPlayer; | |||
| gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| try | |||
| @@ -175,20 +173,21 @@ namespace Gaming | |||
| }*/ | |||
| gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); | |||
| } | |||
| public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle) | |||
| public bool MovePlayer(long playerID, int moveTimeInMilliseconds, double angle) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return; | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| actionManager.MovePlayer(player, moveTimeInMilliseconds, angle); | |||
| return actionManager.MovePlayer(player, moveTimeInMilliseconds, angle); | |||
| #if DEBUG | |||
| Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!"); | |||
| #endif | |||
| } | |||
| else | |||
| { | |||
| return false; | |||
| #if DEBUG | |||
| Console.WriteLine($"PlayerID:{playerID} player does not exists!"); | |||
| #endif | |||
| @@ -198,11 +197,12 @@ namespace Gaming | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| Character? playerTreated = gameMap.FindPlayer(playerTreatedID); | |||
| ICharacter? player = gameMap.FindPlayer(playerID); | |||
| ICharacter? playerTreated = gameMap.FindPlayer(playerTreatedID); | |||
| if (player != null && playerTreated != null) | |||
| { | |||
| return actionManager.Treat(player, playerTreated); | |||
| if (!playerTreated.IsGhost() && !player.IsGhost()) | |||
| return actionManager.Treat((Student)player, (Student)playerTreated); | |||
| } | |||
| return false; | |||
| } | |||
| @@ -210,11 +210,12 @@ namespace Gaming | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| Character? playerRescued = gameMap.FindPlayer(playerRescuedID); | |||
| ICharacter? player = gameMap.FindPlayer(playerID); | |||
| ICharacter? playerRescued = gameMap.FindPlayer(playerRescuedID); | |||
| if (player != null && playerRescued != null) | |||
| { | |||
| return actionManager.Treat(player, playerRescued); | |||
| if (!playerRescued.IsGhost() && !player.IsGhost()) | |||
| return actionManager.Treat((Student)player, (Student)playerRescued); | |||
| } | |||
| return false; | |||
| } | |||
| @@ -222,10 +223,11 @@ namespace Gaming | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| ICharacter? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| return actionManager.Fix(player); | |||
| if (!player.IsGhost()) | |||
| return actionManager.Fix((Student)player); | |||
| } | |||
| return false; | |||
| } | |||
| @@ -233,10 +235,11 @@ namespace Gaming | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| ICharacter? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| return actionManager.Escape(player); | |||
| if (!player.IsGhost()) | |||
| return actionManager.Escape((Student)player); | |||
| } | |||
| return false; | |||
| } | |||
| @@ -8,5 +8,7 @@ namespace Preparation.Interface | |||
| public long TeamID { get; } | |||
| public int HP { get; set; } | |||
| public double Vampire { get; } | |||
| public PlayerStateType PlayerState { get; set; } | |||
| public bool IsGhost(); | |||
| } | |||
| } | |||
| @@ -18,6 +18,7 @@ namespace Preparation.Utility | |||
| IsFixing = 8, | |||
| IsTreated = 9, | |||
| IsRescued = 10, | |||
| IsStunned = 11, | |||
| } | |||
| public enum GameObjType | |||
| { | |||
| @@ -43,6 +43,15 @@ namespace Preparation.Utility | |||
| { | |||
| return Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2)) <= 1 && Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2)) <= 1; | |||
| } | |||
| public static bool IsGhost(CharacterType characterType) | |||
| { | |||
| return characterType switch | |||
| { | |||
| CharacterType.Assassin => true, | |||
| _ => false, | |||
| }; | |||
| } | |||
| #endregion | |||
| #region 角色相关 | |||
| public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径 | |||
| @@ -57,6 +66,7 @@ namespace Preparation.Utility | |||
| public const int basicRescueDegree = 100000; | |||
| public const int basicHp = 3000000; // 初始血量 | |||
| public const int basicCD = 3000; // 初始子弹冷却 | |||
| public const int basicCastTime = 500;//基本前摇时间 | |||
| public const int basicBackswing = 500;//基本后摇时间 | |||
| public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长 | |||
| public const int basicBulletNum = 3; // 基本初始子弹量 | |||