| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | | |
| | | /// <summary> |
| | |
| | | [SerializeField] protected SkillTips skillTipsRed; // 红方技能提示 |
| | | [SerializeField] protected SkillTips skillTipsBlue; // 蓝方技能提示 |
| | | [SerializeField] protected Text txtBattleRound; // 回合信息 (Arena的txtWaveInfo, Story/Bone的txtBattleRound) |
| | | |
| | | [SerializeField] protected GameObject minggeObj; |
| | | |
| | | private List<MinggeBuffCell> redMinggeBuffCells = new List<MinggeBuffCell>(); |
| | | private List<MinggeBuffCell> blueMinggeBuffCells = new List<MinggeBuffCell>(); |
| | | protected BattleRootNode battleRootNode = null; |
| | | protected BattleField battleField; // 当前战斗的战场实例 |
| | | |
| | | |
| | | protected override void InitComponent() |
| | | { |
| | |
| | | |
| | | if (btnPass != null) |
| | | btnPass.AddListener(OnClickPass); |
| | | |
| | | InitMingge(); |
| | | } |
| | | |
| | | protected virtual void InitMingge() |
| | | { |
| | | if (null == minggeObj) |
| | | return; |
| | | |
| | | for (int i = 1; i <= 4; i++) |
| | | { |
| | | GameObject redCell = minggeObj.transform.Find("RedMinggeBuff/MinggeBuffCell" + i).gameObject; |
| | | redMinggeBuffCells.Add(redCell.GetComponent<MinggeBuffCell>()); |
| | | |
| | | GameObject blueCell = minggeObj.transform.Find("BlueMinggeBuff/MinggeBuffCell" + i).gameObject; |
| | | blueMinggeBuffCells.Add(blueCell.GetComponent<MinggeBuffCell>()); |
| | | } |
| | | } |
| | | |
| | | protected void RefreshBuffCells(List<BattleBuffCell> cells, List<HB428_tagSCBuffRefresh> datas) |
| | | { |
| | | if (datas == null) |
| | | { |
| | | for (int i = 0; i < cells.Count; i++) |
| | | { |
| | | cells[i].SetActive(false); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (battleField.battleSwitch.BuffIcon) |
| | | { |
| | | for (int i = 0; i < cells.Count; i++) |
| | | { |
| | | var cell = cells[i]; |
| | | if (i < datas.Count) |
| | | { |
| | | cell.SetActive(true); |
| | | HB428_tagSCBuffRefresh buffData = datas[i]; |
| | | SkillConfig skillConfig = SkillConfig.Get((int)buffData.SkillID); |
| | | cell.Init(buffData, () => |
| | | { |
| | | // 点击buff图标 显示buff描述/当前身上所有buff |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | cell.SetActive(false); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | for (int i = 0; i < cells.Count; i++) |
| | | { |
| | | cells[i].SetActive(false); |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | protected virtual void BindMingge() |
| | | { |
| | | if (minggeObj == null) |
| | | return; |
| | | |
| | | if (battleField == null) |
| | | return; |
| | | |
| | | MinggeBattleObject redMingge = battleField.battleObjMgr.redMingge; |
| | | if (null != redMingge) |
| | | { |
| | | redMingge.GetBuffMgr().onBuffChanged -= RefreshRedMinggeBuff; |
| | | redMingge.GetBuffMgr().onBuffChanged += RefreshRedMinggeBuff; |
| | | } |
| | | |
| | | MinggeBattleObject blueMingge = battleField.battleObjMgr.blueMingge; |
| | | if (null != blueMingge) |
| | | { |
| | | blueMingge.GetBuffMgr().onBuffChanged -= RefreshBlueMinggeBuff; |
| | | blueMingge.GetBuffMgr().onBuffChanged += RefreshBlueMinggeBuff; |
| | | } |
| | | |
| | | } |
| | | |
| | | protected void RefreshRedMinggeBuff() |
| | | { |
| | | if (battleField == null) |
| | | return; |
| | | MinggeBattleObject redMingge = battleField.battleObjMgr.redMingge; |
| | | BattleObjectBuffMgr redMinggeBuffMgr = redMingge?.GetBuffMgr(); |
| | | if (null != redMinggeBuffMgr) |
| | | { |
| | | RefreshMinggeBuff(redMinggeBuffCells, redMinggeBuffMgr.GetBuffIconList()); |
| | | } |
| | | else |
| | | { |
| | | RefreshMinggeBuff(redMinggeBuffCells, null); |
| | | } |
| | | } |
| | | |
| | | protected void RefreshBlueMinggeBuff() |
| | | { |
| | | if (battleField == null) |
| | | return; |
| | | MinggeBattleObject blueMingge = battleField.battleObjMgr.blueMingge; |
| | | BattleObjectBuffMgr blueBuffMgr = blueMingge?.GetBuffMgr(); |
| | | if (null != blueBuffMgr) |
| | | { |
| | | RefreshMinggeBuff(blueMinggeBuffCells, blueBuffMgr.GetBuffIconList()); |
| | | } |
| | | else |
| | | { |
| | | RefreshMinggeBuff(blueMinggeBuffCells, null); |
| | | } |
| | | } |
| | | |
| | | protected void RefreshMinggeBuff(List<MinggeBuffCell> cells, List<HB428_tagSCBuffRefresh> buffList) |
| | | { |
| | | for (int i = 0; i < cells.Count; i++) |
| | | { |
| | | var cell = cells[i]; |
| | | if (buffList != null && i < buffList.Count) |
| | | { |
| | | var buff = buffList[i]; |
| | | cells[i].SetActive(true); |
| | | cells[i].Init(buffList[i], () => OnClickMinggeBuff(cell, buff)); |
| | | } |
| | | else |
| | | { |
| | | cells[i].SetActive(false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnClickMinggeBuff(MinggeBuffCell cell, HB428_tagSCBuffRefresh buff) |
| | | { |
| | | SmallTipWin.showText = Language.Get("SmallTipFomat", SkillConfig.Get((int)buff.SkillID)?.SkillName, SkillConfig.Get((int)buff.SkillID)?.Description); |
| | | SmallTipWin.worldPos = cell.transform.position; |
| | | SmallTipWin.isDownShow = true; |
| | | UIManager.Instance.OpenWindow<SmallTipWin>(); |
| | | } |
| | | |
| | | protected virtual void UnbindMingge() |
| | | { |
| | | if (minggeObj == null) |
| | | return; |
| | | |
| | | if (battleField == null) |
| | | return; |
| | | |
| | | MinggeBattleObject redMingge = battleField.battleObjMgr.redMingge; |
| | | if (null != redMingge) |
| | | { |
| | | redMingge.GetBuffMgr().onBuffChanged -= RefreshRedMinggeBuff; |
| | | } |
| | | |
| | | MinggeBattleObject blueMingge = battleField.battleObjMgr.blueMingge; |
| | | if (null != blueMingge) |
| | | { |
| | | blueMingge.GetBuffMgr().onBuffChanged -= RefreshBlueMinggeBuff; |
| | | } |
| | | } |
| | | |
| | | protected override void OnPreOpen() |
| | |
| | | if (BattleManager.Instance.storyBattleField != null) |
| | | BattleManager.Instance.storyBattleField.IsPause = false; |
| | | |
| | | battleField?.SetFocus(false); |
| | | // battleField?.SetFocus(false); |
| | | |
| | | if (battleField != null) |
| | | { |
| | |
| | | battleField.OnRoundChange -= OnRoundChange; |
| | | battleField.OnRoundChange += OnRoundChange; |
| | | OnRoundChange(battleField.round, battleField.turnMax); // 立即执行一次以显示初始回合 |
| | | |
| | | BindMingge(); |
| | | RefreshRedMinggeBuff(); |
| | | RefreshBlueMinggeBuff(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 跳过战斗 |
| | | /// </summary> |
| | | protected virtual void OnClickPass() |
| | | { |
| | | if (null == battleField) |
| | | if (!IsPass()) |
| | | return; |
| | | // 检查是否为永久特权卡玩家 |
| | | bool hasForeverPrivilege = InvestModel.Instance.IsInvested(InvestModel.foreverCardType); |
| | | |
| | | if (!hasForeverPrivilege && !FuncOpen.Instance.IsFuncOpen(BattleManager.Instance.passFuncId, true)) |
| | | return; |
| | | |
| | | int passRound = BattleManager.Instance.defaultPassRound; |
| | | var name = battleField.ToString(); |
| | | |
| | | |
| | | if (hasForeverPrivilege) |
| | | { |
| | | // 永久特权卡玩家逻辑 |
| | | if (BattleConst.FieldNameToIndex.ContainsKey(name)) |
| | | { |
| | | int index = BattleConst.FieldNameToIndex[name]; |
| | | if (BattleManager.Instance.foreverPrivilegePassDict.ContainsKey(index)) |
| | | { |
| | | passRound = BattleManager.Instance.foreverPrivilegePassDict[index]; |
| | | } |
| | | else |
| | | { |
| | | // 未配置的战场类型,使用普通玩家规则 |
| | | if (BattleManager.Instance.passDict.ContainsKey(index)) |
| | | { |
| | | passRound = BattleManager.Instance.passDict[index]; |
| | | } |
| | | // 否则使用默认配置 |
| | | } |
| | | } |
| | | // 如果战场类型不在 FieldNameToIndex 中,使用默认配置 |
| | | } |
| | | else |
| | | { |
| | | // 普通玩家逻辑 |
| | | if (BattleConst.FieldNameToIndex.ContainsKey(name)) |
| | | { |
| | | int index = BattleConst.FieldNameToIndex[name]; |
| | | if (BattleManager.Instance.passDict.ContainsKey(index)) |
| | | { |
| | | passRound = BattleManager.Instance.passDict[index]; |
| | | } |
| | | // 否则使用默认配置 |
| | | } |
| | | // 如果战场类型不在 FieldNameToIndex 中,使用默认配置 |
| | | } |
| | | |
| | | int nowRound = battleField.round; |
| | | int realPassRound = passRound + 1; // 配置是超过x回合可以跳,意味着x+1回合可以跳 |
| | | if (nowRound < realPassRound) |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("BattlePass", realPassRound - nowRound); |
| | | 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("BattlePass4", 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) |
| | | { |
| | | int lv = PlayerDatas.Instance.baseData.LV; |
| | | if (lv <= BattleManager.Instance.passLV) |
| | | { |
| | | if (!hasForeverPrivilege || IsStoryBossChapterLimited()) |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("BattlePass3", waitRound, BattleManager.Instance.passChapterID); |
| | | } |
| | | else |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("BattlePass", waitRound); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (hasForeverPrivilege && IsStoryBossChapterLimited()) |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("BattlePass3", waitRound, BattleManager.Instance.passChapterID); |
| | | } |
| | | else |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("BattlePass", waitRound); |
| | | } |
| | | } |
| | | } |
| | | // 其他战场提示 |
| | | else |
| | | { |
| | | SysNotifyMgr.Instance.ShowTip("BattlePass", waitRound); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 检查主线BOSS是否受到章节限制 |
| | | /// </summary> |
| | | private bool IsStoryBossChapterLimited() |
| | | { |
| | | long currentProgress = PlayerDatas.Instance.baseData.ExAttr2; |
| | | int nowChapterID = (int)(currentProgress / 10000); |
| | | |
| | | return nowChapterID <= BattleManager.Instance.passChapterID; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 改变速度 |
| | |
| | | { |
| | | if (null == battleField) |
| | | return; |
| | | |
| | | // 计算下一个速度档位的索引 |
| | | int nextSpeedIndex = (BattleManager.Instance.speedIndex + 1) % BattleManager.Instance.speedGear.Length; |
| | | // 检查下一档倍速功能是否开启 |
| | | int nextSpeedFuncId = BattleManager.Instance.speedIndexfuncIdArr[nextSpeedIndex]; |
| | | bool isOpen = FuncOpen.Instance.IsFuncOpen(nextSpeedFuncId); |
| | | if (!isOpen && FuncOpenLVConfig.HasKey(nextSpeedFuncId)) |
| | | bool isOpen = false; |
| | | if (InvestModel.Instance.IsActiveFightSpeed(3)) |
| | | { |
| | | var config = FuncOpenLVConfig.Get(nextSpeedFuncId); |
| | | SysNotifyMgr.Instance.ShowTip("BattleSpeedTip", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID), nextSpeedIndex + 1); |
| | | 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 (battleField == null || battleField.guid != guid) |
| | | return; |
| | | |
| | | if (null == teamHero) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | BattleObject battleObject = battleField.battleObjMgr.GetBattleObject(teamHero.ObjID); |
| | | if (battleObject == null) |
| | | return; |