using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using Spine.Unity; using UnityEngine.UI; using System.Linq; public enum BattleCamp { Red, Blue } public enum BattleState { None = 0, Stunned = 1 << 0, Poisoned = 1 << 1, Bleeding = 1 << 2, Silenced = 1 << 3, Frozen = 1 << 4, Burned = 1 << 5 } public class BattleObject { public BattleField battleField; public BattleObjectBuffMgr buffMgr; public BattleObjectLayerMgr layerMgr; public int ObjID { get; set; } public BattleCamp Camp { get; protected set; } public TeamHero teamHero { get; protected set; } public MotionBase motionBase; public GameObject heroGo { get; private set; } protected BattleDrops battleDrops; private RectTransform m_heroRectTrans; public RectTransform heroRectTrans { get { if (m_heroRectTrans == null) { m_heroRectTrans = heroGo.GetComponent(); } return m_heroRectTrans; } } protected Action onDeathAnimationComplete; protected Renderer[] renderers; private List hB405_tagMCAddExps = new List(); public BattleHeroInfoBar heroInfoBar; public BattleObject(BattleField _battleField) { battleField = _battleField; } public virtual void Init(GameObject _heroGo, TeamHero _teamHero, BattleCamp _camp) { heroGo = _heroGo; teamHero = _teamHero; Camp = _camp; motionBase = new MotionBase(); motionBase.Init(heroGo.GetComponentInChildren(true)); buffMgr = new BattleObjectBuffMgr(); buffMgr.Init(this); layerMgr = new BattleObjectLayerMgr(); layerMgr.Init(this); renderers = heroGo.GetComponentsInChildren(true); heroInfoBar = heroGo.GetComponentInChildren(true); heroInfoBar.SetBattleObject(this); // 根据阵营翻转血条 var heroInfoBarScale = heroInfoBar.transform.localScale; heroInfoBarScale.x *= Camp == BattleCamp.Red ? 1 : -1; heroInfoBar.transform.localScale = heroInfoBarScale; heroInfoBar.SetActive(true); SetFront(); } public virtual void Run() { motionBase.Run(); heroInfoBar.Run(); buffMgr.Run(); } public virtual void Pause() { motionBase.Pause(); } public virtual void Resume() { motionBase.Resume(); } public virtual void Destroy() { motionBase.Release(); motionBase = null; teamHero = null; ObjID = 0; if (heroGo != null) { GameObject.DestroyImmediate(heroGo); heroGo = null; } } public void OnObjInfoRefresh(H0418_tagObjInfoRefresh _refreshInfo) { switch ((PlayerDataType)_refreshInfo.RefreshType) { case PlayerDataType.HP: long toHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp); teamHero.curHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); break; case PlayerDataType.MaxHP: teamHero.maxHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); heroInfoBar.UpdateHP(teamHero.curHp, teamHero.curHp, teamHero.maxHp); break; case PlayerDataType.XP: long toXp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); heroInfoBar.UpdateXP(teamHero.rage, toXp, 100); teamHero.rage = (int)GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); break; default: Debug.LogError("BattleObject.ObjInfoRefresh 出现意外类型 " + _refreshInfo.RefreshType.ToString()); break; } } public void ObjPropertyRefreshView(HB418_tagSCObjPropertyRefreshView vNetData) { switch ((PlayerDataType)vNetData.RefreshType) { case PlayerDataType.HP: long toHp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx); heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp); teamHero.curHp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx); break; case PlayerDataType.MaxHP: teamHero.maxHp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx); heroInfoBar.UpdateHP(teamHero.curHp, teamHero.curHp, teamHero.maxHp); break; case PlayerDataType.XP: long toXp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx); heroInfoBar.UpdateXP(teamHero.rage, toXp, 100); teamHero.rage = (int)GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx); break; default: Debug.LogError("BattleObject.ObjPropertyRefreshView 出现意外类型 " + vNetData.RefreshType.ToString()); break; } } // 眩晕 public bool IsStunned() { return teamHero.isStunned; } // 冰冻 public bool IsFrozen() { return teamHero.isFrozen; } // 石化 public bool IsStoned() { return teamHero.isStoned; } // 被沉默 public bool IsSlient() { return teamHero.isSlient; } // 被缴械 public bool IsDisarmed() { return teamHero.isDisarmed; } // 是否无敌 public bool IsInvincable() { return teamHero.isInvinceble; } // 是否死亡 public bool IsDead() { return teamHero.isDead; } // 是否被控住了 public bool IsCrowdControlled() { return IsStunned() || IsStoned() || IsFrozen(); } public virtual bool IsCanCastSkill() { // 被控住 if (IsCrowdControlled()) { return false; } // 被沉默 if (IsSlient()) { return false; } // 看看怒气是否达到释放要求 return teamHero.rage >= 100; } public virtual bool IsCanNormalAttack() { // 被控住 if (IsCrowdControlled()) { return false; } // 缴械 if (IsDisarmed()) { return false; } return true; } public virtual void Hurt(List damageValues, long _totalDamage, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig) { BattleDmgInfo dmgInfo = PopDamage(damageValues, _totalDamage, hurt, skillConfig); if (dmgInfo.IsType(DamageType.Damage) || dmgInfo.IsRealdamage()) { motionBase.PlayAnimation(MotionName.hit, false); } } public void SuckHp(uint suckHP, SkillConfig skillConfig) { } public void HurtByReflect(uint bounceHP, SkillConfig skillConfig) { } // 闪避开始 public virtual void OnDodgeBegin() { float pingpongTime = 0.2f; RectTransform rectTrans = heroRectTrans; var tween = rectTrans.DOAnchorPos(new Vector3(-30, 0, 0), pingpongTime) .SetEase(Ease.OutCubic); battleField.battleTweenMgr.OnPlayTween(tween); } // 闪避结束 public virtual void OnDodgeEnd(Action _complete = null) { float pingpongTime = 0.2f; RectTransform rectTrans = heroRectTrans; var tween = rectTrans.DOAnchorPos(Vector3.zero, pingpongTime) .SetEase(Ease.OutCubic); tween.onComplete += () => { _complete?.Invoke(); }; battleField.battleTweenMgr.OnPlayTween(tween); } public virtual void OnDeath(Action _onDeathAnimationComplete) { motionBase.PlayAnimation(MotionName.dead, false, () => { teamHero.isDead = true; OnDeadAnimationComplete(); _onDeathAnimationComplete?.Invoke(); }); } protected virtual void OnDeadAnimationComplete() { // 或许看看溶解特效? YYL TODO heroGo.SetActive(false); buffMgr.RemoveAllBuff(); } public void OnReborn(HB423_tagMCTurnFightObjReborn vNetData) { // 处理复活逻辑 teamHero.curHp = GeneralDefine.GetFactValue(vNetData.HP, vNetData.HPEx); heroGo.SetActive(true); motionBase.PlayAnimation(MotionName.idle, true); } // 伤害还要看 是否闪避 暴击 and so on 需要有一个DamageType 服务器应该会给 protected virtual BattleDmgInfo PopDamage(List damageValues, long _totalDamage, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig) { BattleDmgInfo battleDmgInfo = new BattleDmgInfo(battleField.guid, damageValues, this, hurt, skillConfig); if (battleDmgInfo.IsType(DamageType.Dodge)) { OnDodgeBegin(); DodgeFinishAction dodgeFinish = new DodgeFinishAction(battleField, this); battleField.recordPlayer.InsertRecord(dodgeFinish); } int currentHurtHp = 0; for (int i = 0; i < damageValues.Count; i++) { currentHurtHp += (int)damageValues[i]; } heroInfoBar.UpdateHP(teamHero.curHp, Math.Max(0, teamHero.curHp - currentHurtHp), teamHero.maxHp); teamHero.curHp = Math.Max(0, teamHero.curHp - currentHurtHp); // YYL TODO 是否需要挂在在自身的follow点上 EventBroadcast.Instance.Broadcast(EventName.BATTLE_DAMAGE_TAKEN, battleDmgInfo); return battleDmgInfo; } public RectTransform GetAliasTeamNode() { return battleField.GetTeamNode(Camp); } public RectTransform GetEnemyTeamNode() { return battleField.GetTeamNode(Camp == BattleCamp.Red ? BattleCamp.Blue : BattleCamp.Red); } public BattleCamp GetEnemyCamp() { return Camp == BattleCamp.Red ? BattleCamp.Blue : BattleCamp.Red; } public void HaveRest() { // YYL TODO // 休息状态 // 多一个zzz的一个特效 heroGo.SetActive(true); motionBase.HaveRest(); heroRectTrans.anchoredPosition = Vector2.zero; heroInfoBar.SetActive(false); SetFront(); } public void PushDropItems(BattleDrops _battleDrops) { battleDrops = _battleDrops; } public void PerformDrop() { if (null == battleDrops || battleDrops.dropItemPackIndex.Count == 0) return; EventBroadcast.Instance.Broadcast( EventName.BATTLE_DROP_ITEMS, battleField.guid, battleDrops, OnPerformDropFinish); } protected void OnPerformDropFinish() { battleDrops = null; } public void SetBack() { layerMgr.SetBack(); } public void SetFront() { layerMgr.SetFront(); } public void SetSpeedRatio(float ratio) { motionBase.SetSpeedRatio(ratio); } #if UNITY_EDITOR_STOP_USING public void EditorRevive() { teamHero.curHp = 100; heroGo.SetActive(true); motionBase.PlayAnimation(MotionName.idle, true); } public List TryAttack(BattleObject obj, SkillConfig skillConfig) { List damageList = new List(); int totalDamage = 100; int damage1 = (int)((float)totalDamage * 0.3f); int damage2 = (int)((float)totalDamage * 0.25f); int damage3 = totalDamage - damage1 - damage2; damageList.Add(damage1); damageList.Add(damage2); damageList.Add(damage3); return damageList; } #endif }