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 partial class Character : GameObj, ICharacter // 负责人LHR摆烂终了 { private readonly object beAttackedLock = new(); #region 角色的基本属性及方法,包括与道具的交互方法 /// /// 装弹冷却 /// protected int cd; public int CD { get => cd; private set { lock (gameObjLock) { cd = value; Debugger.Output(this, string.Format("'s CD has been set to: {0}.", value)); } } } public int OrgCD { get; protected set; } protected int maxBulletNum; public int MaxBulletNum => maxBulletNum; // 人物最大子弹数 protected int bulletNum; public int BulletNum => bulletNum; // 目前持有的子弹数 public int MaxHp { get; protected set; } // 最大血量 protected int hp; public int HP { get => hp; set { if (value > 0) { lock (gameObjLock) hp = value <= MaxHp ? value : MaxHp; } else lock (gameObjLock) hp = 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) IsMoving = false; lock (gameObjLock) playerState = (value == PlayerStateType.IsMoving) ? PlayerStateType.Null : value; } } // private int deathCount = 0; // public int DeathCount => deathCount; // 玩家的死亡次数 private int score = 0; public int Score { get => score; } // public double AttackRange => BulletFactory.BulletAttackRange(this.BulletOfPlayer); private double vampire = 0; // 回血率:0-1之间 public double Vampire { get => vampire; set { if (value > 1) lock (gameObjLock) vampire = 1; else if (value < 0) lock (gameObjLock) vampire = 0; else lock (gameObjLock) vampire = value; } } private double oriVampire = 0; public double OriVampire { get => oriVampire; set { if (value > 1) lock (gameObjLock) vampire = 1; else if (value < 0) lock (gameObjLock) vampire = 0; else lock (gameObjLock) vampire = value; } } public readonly BulletType OriBulletOfPlayer; private BulletType bulletOfPlayer; public BulletType BulletOfPlayer { get => bulletOfPlayer; set { lock (gameObjLock) bulletOfPlayer = value; } } private Prop? propInventory; public Prop? PropInventory // 持有的道具 { get => propInventory; set { lock (gameObjLock) { propInventory = value; Debugger.Output(this, " prop becomes " + (PropInventory == null ? "null" : PropInventory.ToString())); } } } /// /// 使用物品栏中的道具 /// /// 被使用的道具 public Prop? UseProp() { lock (gameObjLock) { var oldProp = PropInventory; PropInventory = null; return oldProp; } } /// /// 是否在隐身 /// private bool isInvisible = false; public bool IsInvisible { get => isInvisible; set { lock (gameObjLock) { isInvisible = value; } } } /// /// 进行一次远程攻击 /// /// 子弹初始位置偏差值 /// 攻击操作发出的子弹 public Bullet? RemoteAttack(XY posOffset) { if (TrySubBulletNum()) return ProduceOneBullet(this.Position + posOffset); else return null; } protected Bullet? ProduceOneBullet(XY initPos) { var newBullet = BulletFactory.GetBullet(this); newBullet?.SetPosition(initPos); return newBullet; } /// /// 尝试将子弹数量减1 /// /// 减操作是否成功 private bool TrySubBulletNum() { lock (gameObjLock) { if (bulletNum > 0) { --bulletNum; return true; } return false; } } /// /// 尝试将子弹数量加1 /// /// 加操作是否成功 public bool TryAddBulletNum() { lock (gameObjLock) { if (bulletNum < maxBulletNum) { ++bulletNum; return true; } return false; } } /// /// 尝试加血 /// /// 欲加量 /// 加操作是否成功 public bool TryAddHp(int add) { if (hp < MaxHp) { lock (gameObjLock) hp = MaxHp > hp + add ? hp + add : MaxHp; Debugger.Output(this, " hp has added to: " + hp.ToString()); return true; } return false; } /// /// 尝试减血 /// /// 减血量 /// 减操作是否成功 public int TrySubHp(int sub) { int previousHp = hp; lock (gameObjLock) hp = hp >= sub ? 0 : hp - sub; Debugger.Output(this, " hp has subed to: " + hp.ToString()); return previousHp - hp; } /* /// /// 增加死亡次数 /// /// 当前死亡次数 private int AddDeathCount() { lock (gameObjLock) { ++deathCount; return deathCount; } }*/ /// /// 加分 /// /// 增加量 public void AddScore(int add) { lock (gameObjLock) { score += add; Debugger.Output(this, " 's score has been added to: " + score.ToString()); } } /// /// 减分 /// /// 减少量 public void SubScore(int sub) { lock (gameObjLock) { score -= sub; Debugger.Output(this, " 's score has been subed to: " + score.ToString()); } } /// /// 遭受攻击 /// /// /// /// 伤害来源 /// 人物在受到攻击后死了吗 public bool BeAttacked(Bullet bullet) { lock (beAttackedLock) { if (hp <= 0) return false; // 原来已经死了 if (bullet.Parent.TeamID != this.TeamID) { if (HasShield) { if (bullet.HasSpear) _ = TrySubHp(bullet.AP); else return false; } else { bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP))); } #if DEBUG Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}."); #endif if (hp <= 0) TryActivatingLIFE(); // 如果有复活甲 } return hp <= 0; } } /// /// 攻击被反弹,反弹伤害不会再被反弹 /// /// /// /// 反弹伤害者 /// 是否因反弹伤害而死 private bool BeBounced(int subHP, bool hasSpear, Character? bouncer) { lock (beAttackedLock) { if (hp <= 0) return false; if (!(bouncer?.TeamID == this.TeamID)) { if (hasSpear || !HasShield) _ = TrySubHp(subHP); if (hp <= 0) TryActivatingLIFE(); } return hp <= 0; } } /// /// 角色所属队伍ID /// private long teamID = long.MaxValue; public long TeamID { get => teamID; set { lock (gameObjLock) { teamID = value; Debugger.Output(this, " joins in the team: " + value.ToString()); } } } private long playerID = long.MaxValue; public long PlayerID { get => playerID; set { lock (gameObjLock) { playerID = value; } } } /// /// 角色携带的信息 /// private string message = "THUAI6"; public string Message { get => message; set { lock (gameObjLock) { message = value; } } } #endregion #region 角色拥有的buff相关属性、方法 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 => buffManager.HasFasterSpeed; public void AddShield(int shieldTime) => buffManager.AddShield(shieldTime); public bool HasShield => buffManager.HasShield; public void AddLIFE(int LIFETime) => buffManager.AddLIFE(LIFETime); public bool HasLIFE => buffManager.HasLIFE; public void AddSpear(int spearTime) => buffManager.AddSpear(spearTime); public bool HasSpear => buffManager.HasSpear; private Array buffTypeArray = Enum.GetValues(typeof(BuffType)); public Dictionary Buff { get { Dictionary buff = new Dictionary(); foreach (BuffType type in buffTypeArray) { if (type != BuffType.Null) buff.Add(type, GetBuffStatus(type)); } return buff; } } private bool GetBuffStatus(BuffType type) { switch (type) { case BuffType.Spear: return this.HasSpear; case BuffType.AddSpeed: return this.HasFasterSpeed; case BuffType.Shield: return this.HasShield; case BuffType.AddLIFE: return this.HasLIFE; default: return false; } } private void TryActivatingLIFE() { if (buffManager.TryActivatingLIFE()) { hp = MaxHp; } } #endregion public override void Reset() // 要加锁吗? { lock (gameObjLock) { // _ = AddDeathCount(); base.Reset(); this.MoveSpeed = OrgMoveSpeed; HP = MaxHp; PropInventory = null; BulletOfPlayer = OriBulletOfPlayer; lock (gameObjLock) bulletNum = maxBulletNum; buffManager.ClearAll(); IsInvisible = false; this.Vampire = this.OriVampire; } } public override bool IsRigid => true; public override ShapeType Shape => ShapeType.Circle; protected override bool IgnoreCollideExecutor(IGameObj targetObj) { if (targetObj.Type == GameObjType.Prop) // 自己队的地雷忽略碰撞 { return true; } return false; } } }