using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// /// 战斗窗口基类 /// public abstract class BaseBattleWin : UIBase { [Header("战斗场景挂载点")] [SerializeField] protected Transform mountPoint; [Header("战斗控制按钮")] [SerializeField] protected Button btnSpeed; // 速度控制 [SerializeField] protected Text textSpeed; // 速度显示 [SerializeField] protected Button btnPass; // 跳过战斗 [Header("战斗UI组件")] [SerializeField] protected TotalDamageDisplayer totalDamageDisplayer; // 伤害统计 [SerializeField] protected SkillTips skillTipsRed; // 红方技能提示 [SerializeField] protected SkillTips skillTipsBlue; // 蓝方技能提示 [SerializeField] protected Text txtBattleRound; // 回合信息 (Arena的txtWaveInfo, Story/Bone的txtBattleRound) protected BattleRootNode battleRootNode = null; protected BattleField battleField; // 当前战斗的战场实例 protected override void InitComponent() { base.InitComponent(); // 绑定通用按钮事件 if (btnSpeed != null) btnSpeed.AddListener(ChangeSpeed); if (btnPass != null) btnPass.AddListener(OnClickPass); } protected override void OnPreOpen() { base.OnPreOpen(); UIManager.Instance.CloseWindow(); BattleManager.Instance.onBattleFieldCreate += OnCreateBattleField; RegisterBattleEvents(); // 在打开时需要暂停主线战斗 if (BattleManager.Instance.storyBattleField != null) { BattleManager.Instance.storyBattleField.IsPause = true; if (UIManager.Instance.IsOpened()) { UIManager.Instance.CloseWindow(); } } PlayBackGroundMusic(); } protected override void OnPreClose() { base.OnPreClose(); UIManager.Instance.CloseWindow(); BattleManager.Instance.onBattleFieldCreate -= OnCreateBattleField; UnregisterBattleEvents(); // 在关闭时恢复主线战斗 if (BattleManager.Instance.storyBattleField != null) BattleManager.Instance.storyBattleField.IsPause = false; // battleField?.SetFocus(false); if (battleField != null) { battleField.OnRoundChange -= OnRoundChange; } SoundPlayer.Instance.StopBackGroundMusic(); } protected override void OnClose() { base.OnClose(); if (battleRootNode != null) { battleRootNode.transform.SetParent(Launch.Instance.transform); battleRootNode.transform.localPosition = new Vector3(-10000, -10000, 0); } battleField = null; } /// /// 通用刷新逻辑 (模板方法) /// public override void Refresh() { base.Refresh(); // 1. 执行基类通用刷新逻辑 (清空旧状态) if (totalDamageDisplayer != null) totalDamageDisplayer.SetActive(false); if (skillTipsBlue != null) skillTipsBlue.SetActive(false); if (skillTipsRed != null) skillTipsRed.SetActive(false); // 刷新速度显示 if (textSpeed != null && BattleManager.Instance != null) textSpeed.text = (BattleManager.Instance.speedIndex + 1).ToString(); // 2. 调用子类特定的刷新逻辑 if (battleField != null) // 确保战场存在后再调用特定刷新 { RefreshSpecific(); } } /// /// 子类实现的特定刷新逻辑 /// protected abstract void RefreshSpecific(); /// /// 当战斗字段创建时 (子类必须重写, 以匹配特定的战场类型) /// /// /// protected abstract void OnCreateBattleField(string guid, BattleField field); // 示例: // protected override void OnCreateBattleField(string guid, BattleField field) // { // // 检查是否是当前窗口关心的战场类型 // if (field is ArenaBattleField arenaField) // { // SetBattleField(arenaField); // 调用SetBattleField // } // } /// /// 设置战斗字段 /// public virtual void SetBattleField(BattleField _battleField) { // 1. 清理旧的战场 if (battleField != null) { battleField.OnRoundChange -= OnRoundChange; battleField = null; } // 2. 设置新的战场 battleField = _battleField; if (battleField == null) return; // 3. 关联战斗场景根节点 if (battleRootNode != null) // 归还旧的 { battleRootNode.transform.localPosition = Vector3.zero; battleRootNode.transform.SetParent(Launch.Instance.transform); } battleRootNode = battleField.battleRootNode; if (battleRootNode == null) return; battleRootNode.transform.SetParent(mountPoint); // 挂载新的 battleRootNode.transform.localPosition = Vector3.zero; battleRootNode.transform.localScale = Vector3.one; // 4. 打开或获取HUD BattleHUDWin ui = UIManager.Instance.GetUI(); if (null == ui) { ui = UIManager.Instance.OpenWindow(); } ui.SetBattleField(battleField); // 5. 更新Canvas battleField.UpdateCanvas(canvas); // 6. 刷新UI Refresh(); // 7. 监听回合变更 battleField.OnRoundChange -= OnRoundChange; battleField.OnRoundChange += OnRoundChange; OnRoundChange(battleField.round, battleField.turnMax); // 立即执行一次以显示初始回合 } /// /// 跳过战斗 /// protected virtual void OnClickPass() { if (!IsPass()) return; battleField.ForceFinish(); } public bool IsPass() { if (null == battleField) return true; bool hasForeverPrivilege = InvestModel.Instance.IsInvested(InvestModel.foreverCardType); string battleFieldName = battleField.ToString(); // 检查功能开启状态 if (!IsPassOpen(hasForeverPrivilege, battleFieldName)) return false; // 获取配置的回合限制 int configRoundLimit = GetRequiredPassRound(hasForeverPrivilege, battleFieldName); int nowRound = battleField.round > 0 ? battleField.round : 1; if (nowRound >= configRoundLimit + 1) { return true; } ShowSkipWaitTip(configRoundLimit, battleFieldName, hasForeverPrivilege); return false; } private bool IsPassOpen(bool hasForeverPrivilege, string battleFieldName) { // 拥有永久特权卡,无视功能开启限制 if (hasForeverPrivilege) return true; int passFuncId = BattleManager.Instance.passFuncId; // 检查功能ID是否开启 if (FuncOpen.Instance.IsFuncOpen(passFuncId)) return true; if (!FuncOpenLVConfig.HasKey(passFuncId)) return true; int lv = FuncOpenLVConfig.Get(passFuncId).LimitLV; SysNotifyMgr.Instance.ShowTip("BattlePass2", lv); return false; } private int GetRequiredPassRound(bool hasForeverPrivilege, string battleFieldName) { // 初始化默认值 int resultRound = BattleManager.Instance.defaultPassRound; // 尝试获取普通配置(覆盖默认值) if (BattleConst.FieldNameToIndex.TryGetValue(battleFieldName, out int index)) { if (BattleManager.Instance.passDict.TryGetValue(index, out int normalRound)) { resultRound = normalRound; } } else { // 如果连索引都找不到,直接返回默认值,无需后续判断 return resultRound; } // 如果没有特权,直接返回普通配置 if (!hasForeverPrivilege) return resultRound; // 判断特权是否生效 bool isPrivilegeEffective = true; // 特殊规则:主线BOSS需要达到指定章节,特权才生效 if (battleFieldName == BattleConst.StoryBossBattleField) { if (IsStoryBossChapterLimited()) { isPrivilegeEffective = false; } } if (isPrivilegeEffective) { var vipDict = BattleManager.Instance.foreverPrivilegePassDict; // 只有当特权表里显式配置了该战场,才进行覆盖 if (vipDict.TryGetValue(index, out int vipRound)) { resultRound = vipRound; } } return resultRound; } private void ShowSkipWaitTip(int configRoundLimit, string battleFieldName, bool hasForeverPrivilege) { int waitRound = Mathf.Max(configRoundLimit - battleField.round + 1, 0); // 主线BOSS战场特殊提示 if (battleFieldName == BattleConst.StoryBossBattleField) { if (!hasForeverPrivilege || IsStoryBossChapterLimited()) { SysNotifyMgr.Instance.ShowTip("BattlePass3", waitRound, BattleManager.Instance.passChapterID); } else { SysNotifyMgr.Instance.ShowTip("BattlePass", waitRound); } } // 其他战场提示 else { if (hasForeverPrivilege) { SysNotifyMgr.Instance.ShowTip("BattlePass", waitRound); } else { SysNotifyMgr.Instance.ShowTip("BattlePass1", waitRound); } } } /// /// 检查主线BOSS是否受到章节限制 /// private bool IsStoryBossChapterLimited() { long currentProgress = PlayerDatas.Instance.baseData.ExAttr2; int nowChapterID = (int)(currentProgress / 10000); return nowChapterID <= BattleManager.Instance.passChapterID; } /// /// 改变速度 /// protected virtual void ChangeSpeed() { if (null == battleField) return; // 计算下一个速度档位的索引 int nextSpeedIndex = (BattleManager.Instance.speedIndex + 1) % BattleManager.Instance.speedGear.Length; bool isOpen = false; if (InvestModel.Instance.IsActiveFightSpeed(3)) { isOpen = true; } else { // 检查下一档倍速功能是否开启 int nextSpeedFuncId = BattleManager.Instance.speedIndexfuncIdArr[nextSpeedIndex]; isOpen = FuncOpen.Instance.IsFuncOpen(nextSpeedFuncId); if (!isOpen && FuncOpenLVConfig.HasKey(nextSpeedFuncId)) { var config = FuncOpenLVConfig.Get(nextSpeedFuncId); SysNotifyMgr.Instance.ShowTip("BattleSpeedTip", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID), nextSpeedIndex + 1); } } BattleManager.Instance.speedIndex = !isOpen ? 0 : nextSpeedIndex; battleField.SetSpeedRatio(BattleManager.Instance.speedGear[BattleManager.Instance.speedIndex]); if (textSpeed != null) textSpeed.text = (BattleManager.Instance.speedIndex + 1).ToString(); } /// /// 注册战斗事件 /// protected virtual void RegisterBattleEvents() { EventBroadcast.Instance.AddListener(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken); EventBroadcast.Instance.AddListener(EventName.BATTLE_CAST_SKILL, OnCastSkill); } /// /// 注销战斗事件 /// (BattleWin 应该重写此方法并置空) /// protected virtual void UnregisterBattleEvents() { EventBroadcast.Instance.RemoveListener(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken); EventBroadcast.Instance.RemoveListener(EventName.BATTLE_CAST_SKILL, OnCastSkill); } /// /// 造成伤害 /// protected virtual void OnDamageTaken(BattleDmgInfo damageInfo) { if (battleField == null || damageInfo.battleFieldGuid != battleField.guid) return; // 通用逻辑:显示伤害数字 if (totalDamageDisplayer != null) totalDamageDisplayer.SetDamage(damageInfo); } /// /// 释放技能 (通用:显示技能Tips) /// protected virtual void OnCastSkill(string guid, SkillConfig skillConfig, TeamHero teamHero) { if (battleField == null || battleField.guid != guid) return; BattleObject battleObject = battleField.battleObjMgr.GetBattleObject(teamHero.ObjID); if (battleObject == null) return; bool isRed = battleObject.Camp == BattleCamp.Red; SkillTips tips = isRed ? skillTipsRed : skillTipsBlue; if (tips != null) tips.PlayMotion(battleField, isRed, teamHero, skillConfig); } /// /// 回合变更 (通用:刷新回合显示) /// protected virtual void OnRoundChange(int round, int maxRound) { if (txtBattleRound != null) { txtBattleRound.text = Language.Get("RoundText", round, maxRound); } } protected virtual void PlayBackGroundMusic() { SoundPlayer.Instance.PlayBackGroundMusic(39); } }