feat: ✨ rebuild the fix,rescue,treat functions and make a pl…
tags/0.1.0
| @@ -32,16 +32,15 @@ namespace GameClass.GameObj | |||
| { | |||
| } | |||
| public override double BulletBombRange => 0; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange * 13; | |||
| public override int AP => GameData.basicApOfGhost / 3 * 7; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2; | |||
| public override bool IsToBomb => true; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override double BulletAttackRange => GameData.basicRemoteAttackRange * 13; | |||
| public override int AP => GameData.basicApOfGhost / 5 * 4; | |||
| public override int Speed => GameData.basicBulletMoveSpeed * 2; | |||
| public override bool IsToBomb => false; | |||
| public override int Backswing => GameData.basicBackswing / 5 * 3; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit / 4 * 3; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| // 圆形攻击范围 | |||
| return XY.Distance(this.Position, target.Position) <= BulletBombRange; | |||
| return false; | |||
| } | |||
| public override BulletType TypeOfBullet => BulletType.FlyingKnife; | |||
| @@ -8,11 +8,11 @@ namespace GameClass.GameObj | |||
| { | |||
| public partial class Character | |||
| { | |||
| private readonly BuffManeger buffManeger; | |||
| private readonly BuffManager buffManager; | |||
| /// <summary> | |||
| /// 角色携带的buff管理器 | |||
| /// </summary> | |||
| private class BuffManeger | |||
| private class BuffManager | |||
| { | |||
| [StructLayout(LayoutKind.Explicit, Size = 8)] | |||
| private struct BuffValue // buff参数联合体类型,可能是int或double | |||
| @@ -158,7 +158,7 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| public BuffManeger() | |||
| public BuffManager() | |||
| { | |||
| var buffTypeArray = Enum.GetValues(typeof(BuffType)); | |||
| buffList = new LinkedList<BuffValue>[buffTypeArray.Length]; | |||
| @@ -66,7 +66,7 @@ namespace GameClass.GameObj | |||
| this.CanMove = true; | |||
| this.score = 0; | |||
| this.propInventory = null; | |||
| this.buffManeger = new BuffManeger(); | |||
| this.buffManager = new BuffManager(); | |||
| switch (characterType) | |||
| { | |||
| case CharacterType.Assassin: | |||
| @@ -31,7 +31,7 @@ namespace GameClass.GameObj | |||
| } | |||
| public int OrgCD { get; protected set; } | |||
| protected int fixSpeed = 1; | |||
| protected int fixSpeed = GameData.basicFixSpeed; | |||
| /// <summary> | |||
| /// 修理电机速度 | |||
| /// </summary> | |||
| @@ -49,7 +49,35 @@ namespace GameClass.GameObj | |||
| /// <summary> | |||
| /// 原初修理电机速度 | |||
| /// </summary> | |||
| public int OrgFixSpeed { get; protected set; } | |||
| 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; // 人物最大子弹数 | |||
| @@ -63,20 +91,49 @@ namespace GameClass.GameObj | |||
| get => hp; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| hp = value <= MaxHp ? value : MaxHp; | |||
| if (value > 0) | |||
| { | |||
| lock (gameObjLock) | |||
| hp = value <= MaxHp ? value : MaxHp; | |||
| } | |||
| else | |||
| lock (gameObjLock) | |||
| hp = 0; | |||
| } | |||
| } | |||
| private bool isEscaped = false; | |||
| public bool IsEscaped | |||
| public int MaxGamingAddiction { get; protected set; } | |||
| private int gamingAddiction; | |||
| public int GamingAddiction | |||
| { | |||
| get => isEscaped; | |||
| get => gamingAddiction; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| if (!isEscaped && !IsGhost()) | |||
| isEscaped = value; | |||
| if (gamingAddiction > 0) | |||
| lock (gameObjLock) | |||
| gamingAddiction = value <= MaxGamingAddiction ? value : MaxGamingAddiction; | |||
| else | |||
| lock (gameObjLock) | |||
| gamingAddiction = 0; | |||
| } | |||
| } | |||
| private PlayerStateType playerState = PlayerStateType.Null; | |||
| public PlayerStateType PlayerState | |||
| { | |||
| get | |||
| { | |||
| if (IsResetting) return PlayerStateType.IsResetting; | |||
| if (IsMoving) return PlayerStateType.IsMoving; | |||
| return playerState; | |||
| } | |||
| set | |||
| { | |||
| if (value != PlayerStateType.IsMoving && value != PlayerStateType.Null) | |||
| lock (gameObjLock) | |||
| CanMove = false; | |||
| lock (gameObjLock) playerState = value; | |||
| } | |||
| } | |||
| @@ -126,6 +183,32 @@ 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 | |||
| @@ -166,22 +249,6 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 是否正在更换道具(包括捡起与抛出) | |||
| /// </summary> | |||
| private bool isModifyingProp = false; | |||
| public bool IsModifyingProp | |||
| { | |||
| get => isModifyingProp; | |||
| set | |||
| { | |||
| lock (gameObjLock) | |||
| { | |||
| isModifyingProp = value; | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// 是否在隐身 | |||
| /// </summary> | |||
| @@ -423,19 +490,19 @@ namespace GameClass.GameObj | |||
| #endregion | |||
| #region 角色拥有的buff相关属性、方法 | |||
| public void AddMoveSpeed(int buffTime, double add = 2.0) => buffManeger.AddMoveSpeed(add, buffTime, newVal => | |||
| public void AddMoveSpeed(int buffTime, double add = 2.0) => buffManager.AddMoveSpeed(add, buffTime, newVal => | |||
| { MoveSpeed = newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed; }, | |||
| OrgMoveSpeed); | |||
| public bool HasFasterSpeed => buffManeger.HasFasterSpeed; | |||
| public bool HasFasterSpeed => buffManager.HasFasterSpeed; | |||
| public void AddShield(int shieldTime) => buffManeger.AddShield(shieldTime); | |||
| public bool HasShield => buffManeger.HasShield; | |||
| public void AddShield(int shieldTime) => buffManager.AddShield(shieldTime); | |||
| public bool HasShield => buffManager.HasShield; | |||
| public void AddLIFE(int LIFETime) => buffManeger.AddLIFE(LIFETime); | |||
| public bool HasLIFE => buffManeger.HasLIFE; | |||
| public void AddLIFE(int LIFETime) => buffManager.AddLIFE(LIFETime); | |||
| public bool HasLIFE => buffManager.HasLIFE; | |||
| public void AddSpear(int spearTime) => buffManeger.AddSpear(spearTime); | |||
| public bool HasSpear => buffManeger.HasSpear; | |||
| public void AddSpear(int spearTime) => buffManager.AddSpear(spearTime); | |||
| public bool HasSpear => buffManager.HasSpear; | |||
| private Array buffTypeArray = Enum.GetValues(typeof(BuffType)); | |||
| public Dictionary<BuffType, bool> Buff | |||
| @@ -469,7 +536,7 @@ namespace GameClass.GameObj | |||
| } | |||
| private void TryActivatingLIFE() | |||
| { | |||
| if (buffManeger.TryActivatingLIFE()) | |||
| if (buffManager.TryActivatingLIFE()) | |||
| { | |||
| hp = MaxHp; | |||
| } | |||
| @@ -488,7 +555,7 @@ namespace GameClass.GameObj | |||
| lock (gameObjLock) | |||
| bulletNum = maxBulletNum; | |||
| buffManeger.ClearAll(); | |||
| buffManager.ClearAll(); | |||
| IsInvisible = false; | |||
| this.Vampire = this.OriVampire; | |||
| } | |||
| @@ -497,7 +564,8 @@ namespace GameClass.GameObj | |||
| public void Escape() | |||
| { | |||
| lock (gameObjLock) | |||
| IsResetting = IsEscaped = true; | |||
| IsResetting = true; | |||
| PlayerState = PlayerStateType.IsEscaped; | |||
| } | |||
| public override bool IsRigid => true; | |||
| public override ShapeType Shape => ShapeType.Circle; | |||
| @@ -9,13 +9,6 @@ namespace GameClass.Skill | |||
| { | |||
| public class BecomeVampire : IActiveSkill // 化身吸血鬼 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed; | |||
| public int MoveSpeed => moveSpeed; | |||
| private const int maxHp = (int)(GameData.basicHp / 6 * 9.5); | |||
| public int MaxHp => maxHp; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD / 3 * 4; | |||
| public int DurationTime => GameData.commonSkillTime; | |||
| @@ -56,15 +49,6 @@ namespace GameClass.Skill | |||
| } | |||
| public class NuclearWeapon : IActiveSkill // 核武器 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed / 3 * 4; | |||
| public int MoveSpeed => moveSpeed; | |||
| private const int maxHp = GameData.basicHp; | |||
| public int MaxHp => maxHp; | |||
| private const int maxBulletNum = GameData.basicBulletNum * 2 / 3; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD / 3 * 7; | |||
| public int DurationTime => GameData.commonSkillTime / 10; | |||
| private readonly object commonSkillLock = new object(); | |||
| @@ -80,17 +64,25 @@ namespace GameClass.Skill | |||
| { player.BulletOfPlayer = player.OriBulletOfPlayer; }); | |||
| } | |||
| } | |||
| public class UseKnife : IActiveSkill | |||
| { | |||
| public int SkillCD => GameData.commonSkillCD / 3 * 2; | |||
| public int DurationTime => GameData.commonSkillTime / 10; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| public bool SkillEffect(Character player) | |||
| { | |||
| return ActiveSkillFactory.SkillEffect(this, player, () => | |||
| { | |||
| player.BulletOfPlayer = BulletType.FlyingKnife; | |||
| Debugger.Output(player, "uses flyingknife!"); | |||
| }, | |||
| () => | |||
| { player.BulletOfPlayer = player.OriBulletOfPlayer; }); | |||
| } | |||
| } | |||
| public class SuperFast : IActiveSkill // 3倍速 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed * 4 / 3; | |||
| public int MoveSpeed => moveSpeed; | |||
| private const int maxHp = GameData.basicHp / 6 * 4; | |||
| public int MaxHp => maxHp; | |||
| private const int maxBulletNum = GameData.basicBulletNum * 4 / 3; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD; | |||
| public int DurationTime => GameData.commonSkillTime / 10 * 4; | |||
| private readonly object commonSkillLock = new object(); | |||
| @@ -108,15 +100,6 @@ namespace GameClass.Skill | |||
| } | |||
| public class NoCommonSkill : IActiveSkill // 这种情况不该发生,定义着以防意外 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed; | |||
| public int MoveSpeed => moveSpeed; | |||
| private const int maxHp = GameData.basicHp; | |||
| public int MaxHp => maxHp; | |||
| private const int maxBulletNum = GameData.basicBulletNum; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD; | |||
| public int DurationTime => GameData.commonSkillTime; | |||
| private readonly object commonSkillLock = new object(); | |||
| @@ -1,8 +1,5 @@ | |||
| using GameClass.GameObj; | |||
| using System.Threading; | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| namespace GameClass.Skill | |||
| @@ -33,7 +30,7 @@ namespace GameClass.Skill | |||
| public BulletType InitBullet => BulletType.CommonAttackOfGhost; | |||
| public List<IActiveSkill> ListOfIActiveSkill => new(new IActiveSkill[] { new BecomeInvisible(), }); | |||
| public List<IActiveSkill> ListOfIActiveSkill => new(new IActiveSkill[] { new BecomeInvisible(), new UseKnife() }); | |||
| public List<IPassiveSkill> ListOfIPassiveSkill => new(new IPassiveSkill[] { }); | |||
| } | |||
| @@ -1,8 +1,10 @@ | |||
| using System; | |||
| using System.Runtime.InteropServices; | |||
| using System.Threading; | |||
| using GameClass.GameObj; | |||
| using GameEngine; | |||
| using Preparation.Utility; | |||
| using Timothy.FrameRateTask; | |||
| namespace Gaming | |||
| { | |||
| @@ -18,9 +20,9 @@ namespace Gaming | |||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); | |||
| } | |||
| public bool TryToFix(Character player)// 自动检查有无发电机可修 | |||
| public bool Fix(Character player)// 自动检查有无发电机可修 | |||
| { | |||
| if (player.IsResetting || player.IsGhost()) | |||
| if (player.PlayerState != PlayerStateType.Null || player.IsGhost()) | |||
| return false; | |||
| Generator? generatorForFix = null; | |||
| @@ -42,54 +44,72 @@ namespace Gaming | |||
| gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock(); | |||
| } | |||
| if (generatorForFix == null || generatorForFix.DegreeOfFRepair == GameData.degreeOfFixedGenerator) | |||
| return false; | |||
| player.PlayerState = PlayerStateType.IsFixing; | |||
| new Thread | |||
| ( | |||
| () => | |||
| { | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => player.PlayerState == PlayerStateType.IsFixing && generatorForFix.DegreeOfFRepair < GameData.degreeOfFixedGenerator && GameData.ApproachToInteract(player.Position, generatorForFix.Position), | |||
| loopToDo: () => | |||
| { | |||
| return !generatorForFix.Repair(player.FixSpeed * GameData.frameDuration); | |||
| }, | |||
| timeInterval: GameData.frameDuration, | |||
| finallyReturn: () => 0 | |||
| ) | |||
| .Start(); | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| if (generatorForFix != null) | |||
| if (generatorForFix.DegreeOfFRepair == GameData.degreeOfFixedGenerator) | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock(); | |||
| try | |||
| { | |||
| if (generatorForFix.Repair(player.FixSpeed)) | |||
| Doorway exit = (Doorway)gameMap.GameObjDict[GameObjType.Doorway][1]; | |||
| if (!exit.PowerSupply) | |||
| { | |||
| 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) | |||
| { | |||
| 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 | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock(); | |||
| try | |||
| { | |||
| foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway]) | |||
| doorway.PowerSupply = true; | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock(); | |||
| } | |||
| 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; | |||
| } | |||
| else | |||
| return false; | |||
| return false; | |||
| } | |||
| public bool TryToEscape(Character player) | |||
| public bool Escape(Character player) | |||
| { | |||
| if (player.IsResetting || player.IsGhost()) | |||
| if (!(player.PlayerState == PlayerStateType.Null || player.PlayerState == PlayerStateType.IsMoving) || player.IsGhost()) | |||
| return false; | |||
| Doorway? doorwayForEscape = null; | |||
| gameMap.GameObjLockDict[GameObjType.Doorway].EnterReadLock(); | |||
| try | |||
| { | |||
| @@ -116,6 +136,103 @@ namespace Gaming | |||
| else | |||
| return false; | |||
| } | |||
| public bool Treat(Character player, Character playerTreated) | |||
| { | |||
| if (playerTreated.PlayerState == PlayerStateType.Null || player.PlayerState == PlayerStateType.Null || playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position)) | |||
| return false; | |||
| 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; | |||
| } | |||
| 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), | |||
| loopToDo: () => | |||
| { | |||
| playerTreated.DegreeOfTreatment += GameData.frameDuration * player.TreatSpeed; | |||
| }, | |||
| timeInterval: GameData.frameDuration, | |||
| finallyReturn: () => 0 | |||
| ) | |||
| .Start(); | |||
| } | |||
| ) | |||
| { 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; | |||
| } | |||
| public bool Rescue(Character player, Character playerRescued) | |||
| { | |||
| if (player.PlayerState != PlayerStateType.Null || playerRescued.PlayerState != PlayerStateType.IsAddicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position)) | |||
| return false; | |||
| player.PlayerState = PlayerStateType.IsRescuing; | |||
| playerRescued.PlayerState = PlayerStateType.IsRescued; | |||
| int rescuedDegree = 0; | |||
| new Thread | |||
| ( | |||
| () => | |||
| { | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => playerRescued.PlayerState == PlayerStateType.IsRescued && player.PlayerState == PlayerStateType.IsRescuing && GameData.ApproachToInteract(playerRescued.Position, player.Position), | |||
| loopToDo: () => | |||
| { | |||
| rescuedDegree += GameData.frameDuration; | |||
| }, | |||
| timeInterval: GameData.frameDuration, | |||
| finallyReturn: () => 0, | |||
| maxTotalDuration: 1000 | |||
| ) | |||
| .Start(); | |||
| } | |||
| ) | |||
| { 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; | |||
| } | |||
| } | |||
| /* | |||
| private void ActivateMine(Character player, Mine mine) | |||
| { | |||
| @@ -5,6 +5,7 @@ using GameClass.GameObj; | |||
| using Preparation.Utility; | |||
| using GameEngine; | |||
| using Preparation.Interface; | |||
| using Timothy.FrameRateTask; | |||
| namespace Gaming | |||
| { | |||
| @@ -35,75 +36,114 @@ namespace Gaming | |||
| } | |||
| ); | |||
| } | |||
| private bool CanBeBombed(Bullet bullet, GameObjType gameObjType) | |||
| public void BeAddictedToGame(Character player) | |||
| { | |||
| if (gameObjType == GameObjType.Character) return true; | |||
| return false; | |||
| new Thread | |||
| (() => | |||
| { | |||
| if (player.GamingAddiction > GameData.BeginGamingAddiction && player.GamingAddiction < GameData.MidGamingAddiction) | |||
| player.GamingAddiction = GameData.MidGamingAddiction; | |||
| player.PlayerState = PlayerStateType.IsAddicted; | |||
| new FrameRateTaskExecutor<int>( | |||
| () => player.PlayerState == PlayerStateType.IsAddicted && player.GamingAddiction < player.MaxGamingAddiction, | |||
| () => | |||
| { | |||
| player.GamingAddiction += GameData.frameDuration; | |||
| }, | |||
| timeInterval: GameData.frameDuration, | |||
| () => | |||
| { | |||
| if (player.GamingAddiction == player.MaxGamingAddiction) | |||
| { | |||
| player.PlayerState = PlayerStateType.Null; | |||
| Die(player); | |||
| } | |||
| else player.CanMove = true; | |||
| return 0; | |||
| } | |||
| ) | |||
| .Start(); | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| private void BombObj(Bullet bullet, GameObj objBeingShot) | |||
| public void Die(Character player) | |||
| { | |||
| switch (objBeingShot.Type) | |||
| player.CanMove = false; | |||
| player.IsResetting = true; | |||
| // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| // try | |||
| //{ | |||
| // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot); | |||
| // } | |||
| // finally | |||
| //{ | |||
| // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); | |||
| // } | |||
| Prop? dropProp = null; | |||
| if (player.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 | |||
| { | |||
| case GameObjType.Character: | |||
| Character playerBeingShot = (Character)objBeingShot; | |||
| if (playerBeingShot.BeAttacked(bullet)) | |||
| dropProp = player.PropInventory; | |||
| dropProp.SetNewPos(GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell)); | |||
| } | |||
| gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock(); | |||
| try | |||
| { | |||
| if (dropProp != null) | |||
| gameMap.GameObjDict[GameObjType.Prop].Add(dropProp); | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock(); | |||
| } | |||
| player.Reset(); | |||
| // ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 | |||
| /* new Thread | |||
| (() => | |||
| { | |||
| playerBeingShot.CanMove = false; | |||
| playerBeingShot.IsResetting = true; | |||
| Thread.Sleep(GameData.reviveTime); | |||
| playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾 | |||
| // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| // try | |||
| //{ | |||
| // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot); | |||
| // } | |||
| // finally | |||
| //{ | |||
| // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); | |||
| // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot); | |||
| // } | |||
| // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); } | |||
| Prop? dropProp = null; | |||
| if (playerBeingShot.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| dropProp = playerBeingShot.PropInventory; | |||
| dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell)); | |||
| playerBeingShot.CanMove = true; | |||
| } | |||
| gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock(); | |||
| try | |||
| { | |||
| if (dropProp != null) | |||
| gameMap.GameObjDict[GameObjType.Prop].Add(dropProp); | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock(); | |||
| } | |||
| playerBeingShot.Reset(); | |||
| ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 | |||
| /* new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(GameData.reviveTime); | |||
| playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾 | |||
| // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| // try | |||
| //{ | |||
| // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot); | |||
| // } | |||
| // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); } | |||
| playerBeingShot.IsResetting = false; | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| */ | |||
| } | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| playerBeingShot.CanMove = true; | |||
| } | |||
| playerBeingShot.IsResetting = false; | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| */ | |||
| private bool CanBeBombed(Bullet bullet, GameObjType gameObjType) | |||
| { | |||
| if (gameObjType == GameObjType.Character) return true; | |||
| return false; | |||
| } | |||
| private void BombObj(Bullet bullet, GameObj objBeingShot) | |||
| { | |||
| switch (objBeingShot.Type) | |||
| { | |||
| case GameObjType.Character: | |||
| Character playerBeingShot = (Character)objBeingShot; | |||
| if (playerBeingShot.BeAttacked(bullet)) | |||
| { | |||
| BeAddictedToGame(playerBeingShot); | |||
| } | |||
| break; | |||
| } | |||
| @@ -57,7 +57,7 @@ namespace Gaming | |||
| newPlayer.TeamID = playerInitInfo.teamID; | |||
| newPlayer.PlayerID = playerInitInfo.playerID; | |||
| /*new Thread //人物装弹 | |||
| new Thread //人物装弹 | |||
| ( | |||
| () => | |||
| { | |||
| @@ -84,17 +84,17 @@ namespace Gaming | |||
| finallyReturn: () => 0 | |||
| ) | |||
| { | |||
| AllowTimeExceed = true | |||
| AllowTimeExceed = true/*, | |||
| MaxTolerantTimeExceedCount = 5, | |||
| TimeExceedAction = exceedTooMuch => | |||
| { | |||
| if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!"); | |||
| } | |||
| }*/ | |||
| } | |||
| .Start(); | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start();*/ | |||
| { IsBackground = true }.Start(); | |||
| return newPlayer.ID; | |||
| } | |||
| @@ -194,6 +194,52 @@ namespace Gaming | |||
| #endif | |||
| } | |||
| } | |||
| public bool Treat(long playerID, long playerTreatedID) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| Character? playerTreated = gameMap.FindPlayer(playerTreatedID); | |||
| if (player != null && playerTreated != null) | |||
| { | |||
| return actionManager.Treat(player, playerTreated); | |||
| } | |||
| return false; | |||
| } | |||
| public bool Rescue(long playerID, long playerRescuedID) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| Character? playerRescued = gameMap.FindPlayer(playerRescuedID); | |||
| if (player != null && playerRescued != null) | |||
| { | |||
| return actionManager.Treat(player, playerRescued); | |||
| } | |||
| return false; | |||
| } | |||
| public bool Fix(long playerID) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| return actionManager.Fix(player); | |||
| } | |||
| return false; | |||
| } | |||
| public bool Escape(long playerID) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| return false; | |||
| Character? player = gameMap.FindPlayer(playerID); | |||
| if (player != null) | |||
| { | |||
| return actionManager.Escape(player); | |||
| } | |||
| return false; | |||
| } | |||
| public void Attack(long playerID, double angle) | |||
| { | |||
| if (!gameMap.Timer.IsGaming) | |||
| @@ -5,6 +5,20 @@ namespace Preparation.Utility | |||
| /// 存放所有用到的枚举类型 | |||
| /// </summary> | |||
| // public const int numOfObjNotMap = 5;在GameData中 | |||
| public enum PlayerStateType | |||
| { | |||
| Null = 0, | |||
| IsAddicted = 1, | |||
| IsEscaped = 2, | |||
| IsSwinging = 3, | |||
| IsResetting = 4, | |||
| IsMoving = 5, | |||
| IsTreating = 6, | |||
| IsRescuing = 7, | |||
| IsFixing = 8, | |||
| IsTreated = 9, | |||
| IsRescued = 10, | |||
| } | |||
| public enum GameObjType | |||
| { | |||
| Null = 0, | |||
| @@ -72,7 +86,7 @@ namespace Preparation.Utility | |||
| BecomeVampire = 2, | |||
| NuclearWeapon = 3, | |||
| SuperFast = 4, | |||
| ASkill4 = 5, | |||
| UseKnife = 5, | |||
| ASkill5 = 6 | |||
| } | |||
| public enum PassiveSkillType | |||
| @@ -6,11 +6,12 @@ namespace Preparation.Utility | |||
| #region 基本常数与常方法 | |||
| public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 | |||
| public const int numOfStepPerSecond = 20; // 每秒行走的步数 | |||
| public const int frameDuration = 50; // 每帧时长 | |||
| public const int lengthOfMap = 50000; // 地图长度 | |||
| public const int rows = 50; // 行数 | |||
| public const int cols = 50; // 列数 | |||
| public const long gameDuration = 600000; // 游戏时长600000ms = 10min | |||
| public const long frameDuration = 50; // 每帧时长 | |||
| public const int MinSpeed = 1; // 最小速度 | |||
| public const int MaxSpeed = int.MaxValue; // 最大速度 | |||
| @@ -45,8 +46,16 @@ namespace Preparation.Utility | |||
| #endregion | |||
| #region 角色相关 | |||
| public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径 | |||
| public const int basicApOfGhost = 500; // 初始攻击力 | |||
| public const int basicHp = 1003; // 初始血量 | |||
| public const int basicApOfGhost = 1500000; // 攻击力 | |||
| public const int basicTreatSpeed = 100; | |||
| public const int basicFixSpeed = 100; | |||
| public const int basicRescueSpeed = 100; | |||
| public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 | |||
| public const int BeginGamingAddiction = 10003; | |||
| public const int MidGamingAddiction = 30000; | |||
| public const int basicTreatmentDegree = 1500000; | |||
| public const int basicRescueDegree = 100000; | |||
| public const int basicHp = 3000000; // 初始血量 | |||
| public const int basicCD = 3000; // 初始子弹冷却 | |||
| public const int basicBackswing = 500;//基本后摇时间 | |||
| public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长 | |||
| @@ -78,7 +87,7 @@ namespace Preparation.Utility | |||
| public const long PropProduceTime = 10000; | |||
| public const int PropDuration = 10000; | |||
| public const int degreeOfFixedGenerator = 2000; | |||
| public const int degreeOfFixedGenerator = 10300000; | |||
| #endregion | |||
| #region 游戏帧相关 | |||
| public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 | |||