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 abstract class BattleObject { public BattleField battleField; public BattleObjectLayerMgr layerMgr; public int ObjID { get; set; } public BattleCamp Camp { get; protected set; } public BattleObject(BattleField _battleField) { battleField = _battleField; } // ============ 抽象访问方法(子类返回各自的Team类型信息) ============ public abstract int GetPositionNum(); public abstract float GetModelScale(); public abstract string GetName(); // Buff 管理器访问方法(Hero 有 buff,Mingge 返回 null) public abstract BattleObjectBuffMgr GetBuffMgr(); // 状态查询抽象方法 protected abstract bool GetIsStunned(); protected abstract bool GetIsFrozen(); protected abstract bool GetIsStoned(); protected abstract bool GetIsSlient(); protected abstract bool GetIsDisarmed(); protected abstract bool GetIsInvincible(); protected abstract bool GetIsDead(); public abstract int GetRage(); // 血量相关抽象方法(Hero 特有,Mingge 返回默认值) public abstract long GetCurHp(); public abstract long GetMaxHp(); public abstract void SetCurHp(long value); public abstract void SetIsDead(bool value); // 其他属性访问方法 public abstract int GetNPCID(); public abstract long GetFightPower(); public abstract void Run(); public abstract void Pause(); public abstract void Resume(); public abstract void Destroy(); // ============ 动画相关抽象方法(替代 motionBase 直接调用) ============ /// /// 播放动画 /// public abstract void PlayAnimation(MotionName motionName, bool loop); /// /// 显示幻影残影 /// public abstract void ShowIllusionShadow(bool show, Color? color = null); /// /// 播放技能动画 /// public abstract Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, bool isCounter, Action onComplete); /// /// 检查是否可以开始死亡 /// public abstract bool CanStartDeath(); /// /// 检查是否可以释放技能 /// public abstract bool CanCastSkillAnimation(SkillConfig skillConfig); /// /// 获取骨骼动画组件(用于特效挂载等) /// public abstract SkeletonAnimation GetSkeletonAnimation(); /// /// 设置骨骼动画透明度 /// public abstract void SetSkeletonAlpha(float alpha); /// /// 获取 RectTransform(用于移动等操作) /// public virtual RectTransform GetRectTransform() => null; /// /// 获取 GameObject /// public virtual GameObject GetGameObject() => null; /// /// 获取 Transform(用于特效挂载等) /// public virtual Transform GetTransform() => null; /// /// 获取世界坐标位置 /// public virtual Vector3 GetPosition() => Vector3.zero; /// /// 获取血条信息栏 /// public virtual BattleHeroInfoBar GetHeroInfoBar() => null; /// /// 刷新Buff显示 /// public virtual void RefreshBuff(List buffList) { } /// /// 更新血量显示 /// public virtual void UpdateHP(float percentage) { } /// /// 是否正在复活中 /// public virtual bool IsReborning() => false; /// /// 设置复活状态 /// public virtual void SetReborning(bool value) { } /// /// 设置 GameObject 激活状态 /// public virtual void SetActive(bool active) { } /// /// 重置位置到原点 /// public virtual void ResetPosition() { } /// /// 设置朝向(通过缩放) /// public virtual void SetFacing(float direction) { } /// /// 重置朝向(朝向右边) /// public virtual void ResetFacing() { } /// /// 停止所有移动动画 /// public virtual void StopMoveAnimation() { } /// /// 显示提示信息(简单版本) /// public virtual void ShowTips(string message, bool useArtText = false, bool followCharacter = true, float scaleRatio = 1f) { } /// /// 显示提示信息(完整版本) /// public virtual void ShowTips(BattleHeroInfoBar.TipsInfo tipsInfo) { } /// /// 设置死亡状态(Hero 特定) /// public virtual void SetDeath() { } /// /// 复活后处理(Hero 特定) /// public virtual void AfterReborn() { } /// /// 复活前准备(Hero 特定) /// public virtual void PreReborn(bool reviveSelf = false) { } /// /// 复活动作(Hero 特定) /// public virtual void OnReborn(HB427_tagSCUseSkill.tagSCUseSkillHurt vNetData, bool reviveSelf = false, RecordAction parentAction = null) { } public virtual void OnObjInfoRefresh(H0418_tagObjInfoRefresh _refreshInfo) { // 子类实现 } // 眩晕 public bool IsStunned() { return GetIsStunned(); } // 冰冻 public bool IsFrozen() { return GetIsFrozen(); } // 石化 public bool IsStoned() { return GetIsStoned(); } // 被沉默 public bool IsSlient() { return GetIsSlient(); } // 被缴械 public bool IsDisarmed() { return GetIsDisarmed(); } // 是否无敌 public bool IsInvincable() { return GetIsInvincible(); } // 是否死亡 public bool IsDead() { return GetIsDead(); } // 是否被控住了 public bool IsCrowdControlled() { return IsStunned() || IsStoned() || IsFrozen(); } public virtual bool IsCanCastSkill() { // 被控住 if (IsCrowdControlled()) { return false; } // 被沉默 if (IsSlient()) { return false; } // 看看怒气是否达到释放要求 return GetRage() >= 100; } public virtual bool IsCanNormalAttack() { // 被控住 if (IsCrowdControlled()) { return false; } // 缴械 if (IsDisarmed()) { return false; } return true; } public abstract DeathRecordAction Hurt(BattleHurtParam battleHurtParam, SkillRecordAction _parentSkillAction = null); public abstract void OnDodgeBegin(DamageType damageType); public abstract void OnDodgeEnd(Action _complete = null); public abstract void OnDeath(Action _onDeathAnimationComplete, bool withoutAnime = false); protected abstract BattleDmgInfo PopDamage(BattleHurtParam battleHurtParam); protected abstract BattleDmgInfo PopDamageForCaster(BattleHurtParam battleHurtParam); 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 abstract void HaveRest(); protected BattleDrops m_battleDrops; public virtual void PushDropItems(BattleDrops _battleDrops) { m_battleDrops = _battleDrops; } public virtual void PerformDrop() { if (null == m_battleDrops) return; EventBroadcast.Instance.Broadcast( EventName.BATTLE_DROP_ITEMS, battleField.guid, m_battleDrops, OnPerformDropFinish); } protected virtual void OnPerformDropFinish() { m_battleDrops = null; } public void SetBack() { layerMgr.SetBack(); } public void SetFront() { layerMgr.SetFront(); } public abstract void SetSpeedRatio(float ratio); public abstract void OnObjPropertyRefreshView(HB418_tagSCObjPropertyRefreshView vNetData); #if UNITY_EDITOR_STOP_USING public abstract void EditorRevive(); 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 // BattleObject.cs public virtual void OnHurtTarget(BattleHurtParam battleHurtParam) { // 检查是否有吸血或反伤 bool hasSuckHp = battleHurtParam.caster.suckHpList != null && battleHurtParam.caster.suckHpList.Count > 0; bool hasReflectHp = battleHurtParam.caster.reflectHpList != null && battleHurtParam.caster.reflectHpList.Count > 0; if (!hasSuckHp && !hasReflectHp) { return; } // ============ 应用施法者的血量和护盾变化 ============ bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1; ApplyHurtToCaster(battleHurtParam, isLastHit); // 和Hurt一样,调用PopDamage处理吸血/反伤的显示 BattleDmgInfo casterDmgInfo = PopDamageForCaster(battleHurtParam); // 如果有反伤,施法者播放受击动画 if (hasReflectHp && casterDmgInfo.casterDamageList != null && casterDmgInfo.casterDamageList.Count > 0) { long totalReflect = casterDmgInfo.casterDamageList.Sum(d => d.damage); var buffMgr = GetBuffMgr(); if (totalReflect > 0 && buffMgr != null && !buffMgr.isControled[BattleConst.HardControlGroup]) { OnPlayHitAnimation(); } } } /// /// 应用施法者的血量和护盾变化(吸血和反伤) /// private void ApplyHurtToCaster(BattleHurtParam battleHurtParam, bool isLastHit) { BattleCastObj caster = battleHurtParam.caster; // 应用血量变化(由子类实现) ApplyCasterHpChange(caster.toHp); // 打印所有角色的名字和当前血量跟总血量 // foreach (var obj in battleField.battleObjMgr.allBattleObjDict.Values) // { // Debug.LogError($"[ApplyHurtToCaster] ObjID: {obj.ObjID}, Name: {obj.teamHero.heroConfig.Name}, CurHp: {obj.teamHero.curHp}, MaxHp: {obj.teamHero.maxHp} Skill {battleHurtParam.hB427_TagSCUseSkill.packUID} " ); // } // 护盾值由buff系统自动管理,不需要手动设置 #if UNITY_EDITOR // 最后一击时验证血量是否与服务器一致 if (isLastHit) { BattleUtility.ValidateHpConsistencyForCaster(battleHurtParam, "施法者吸血/反伤"); } #endif } public bool IsTianziBoss() { return battleField.MapID == 30020 && battleField.FindBoss() == this; } /// /// 播放受击动画(只有 Hero 有实现,Mingge 留空) /// protected abstract void OnPlayHitAnimation(); /// /// 应用施法者血量变化(吸血/反伤) /// protected abstract void ApplyCasterHpChange(long newHp); }