From 364bb6a6623e49eec17075074a33121b6706fb31 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期五, 19 十二月 2025 11:12:19 +0800
Subject: [PATCH] Merge branch 'master' of http://mobile.secondworld.net.cn:10010/r/Project_SG_scripts

---
 Main/System/Battle/BattleField/BattleField.cs                     |   29 +++--
 Main/System/Battle/StoryBossBattleWin.cs                          |   52 +++++++++
 Main/System/Battle/BattleField/RecordActions/BattleStartAction.cs |    4 
 Main/System/Settlement/BattleSettlementManager.cs                 |   29 +++--
 Main/System/Battle/BoneFieldBattleWin.cs                          |   50 +++++++++
 Main/System/Battle/BaseBattleWin.cs                               |   27 ++++
 Main/System/Battle/TianziBillboradBattleWin.cs                    |   25 +++-
 Main/Component/UI/Common/PopupWindowsProcessor.cs                 |   10 +
 Main/System/Battle/ArenaBattleWin.cs                              |   46 +++++++++
 9 files changed, 231 insertions(+), 41 deletions(-)

diff --git a/Main/Component/UI/Common/PopupWindowsProcessor.cs b/Main/Component/UI/Common/PopupWindowsProcessor.cs
index dd730d9..ec4d9b9 100644
--- a/Main/Component/UI/Common/PopupWindowsProcessor.cs
+++ b/Main/Component/UI/Common/PopupWindowsProcessor.cs
@@ -27,12 +27,13 @@
     /// </summary>
     /// <param name="name">绐楀彛鍚嶇О</param>
     /// <param name="functionId">鍔熻兘ID锛岀敤浜庢寚瀹氱獥鍙g殑鍏蜂綋鍔熻兘鎴栨樉绀烘ā寮�</param>
-    public void Add(string name, bool isNeedHomeWin = true, int functionId = 0)
+    public void Add(string name, bool isNeedHomeWin = true, string battleFieldName = "", int functionId = 0)
     {
         var popupWindow = new PopupWindow()
         {
             window = name,
             isNeedHomeWin = isNeedHomeWin,
+            battleFieldName = battleFieldName,
             functionId = functionId,
         };
 
@@ -114,10 +115,10 @@
         // 绛夊緟x绉�
         if (Time.realtimeSinceStartup - firstTime < stayTime)
             return;
-        
-        // 鍙湪鈥滄病鏈夋垬鏂椻�濆拰鈥滀富绾挎垬鏂椻�濇椂鍏佽寮圭獥
+
+        // 鍙湪鈥滄病鏈夋垬鏂椻�濆拰鈥滀富绾挎垬鏂椻�濆拰鈥滆嚜宸辩殑鎴樺満鈥濇椂鍏佽寮圭獥
         string activeBattleName = BattleManager.Instance.GetActiveBattleName();
-        if (activeBattleName != "" && activeBattleName != "StoryBattleField")
+        if (activeBattleName != "" && activeBattleName != "StoryBattleField" && activeBattleName != popupWindowQueue[0].battleFieldName)
             return;
 
         if (UIManager.Instance.IsOpened(popupWindowQueue[0].window))
@@ -158,6 +159,7 @@
         public int functionId;
 
         public bool isNeedHomeWin;
+        public string battleFieldName;
     }
 
 }
\ No newline at end of file
diff --git a/Main/System/Battle/ArenaBattleWin.cs b/Main/System/Battle/ArenaBattleWin.cs
index ac89408..8cce6cd 100644
--- a/Main/System/Battle/ArenaBattleWin.cs
+++ b/Main/System/Battle/ArenaBattleWin.cs
@@ -47,6 +47,7 @@
     {
         base.OnPreOpen();
         MainWin.TabChangeEvent += OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow += OnOpenWindow;
         bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
         transButtons.localPosition = new Vector3(0, isOpenBattleChangeTab ? 130 : 0, 0);
         if (isOpenBattleChangeTab)
@@ -57,12 +58,14 @@
         {
             UIManager.Instance.CloseWindow<MainWin>();
         }
+        isClickSkip = false;
     }
 
     protected override void OnPreClose()
     {
         base.OnPreClose();
         MainWin.TabChangeEvent -= OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
         bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
         if (isOpenBattleChangeTab)
         {
@@ -72,8 +75,51 @@
         {
             UIManager.Instance.OpenWindow<MainWin>();
         }
+
+        if (isClickSkip)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
     }
 
+    void OnOpenWindow(UIBase win)
+    {
+        if (win is ArenaBattleVictoryWin || win is ArenaBattleFailWin)
+        {
+            isClickSkip = false;
+        }
+    }
+    bool isClickSkip = false;
+    protected override void OnClickPass()
+    {
+        if (!IsPass())
+            return;
+        isClickSkip = true;
+        clickTime = Time.time;  // 璁板綍鐐瑰嚮鏃堕棿
+        battleField.ForceFinish();
+    }
+
+    float stayTime = 2f;
+    float clickTime = 0f;
+    void LateUpdate()
+    {
+        if (isClickSkip && Time.time - clickTime >= stayTime)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
+    }
+
+    private void TryPass()
+    {
+        if (UIManager.Instance.IsOpened<ArenaBattleVictoryWin>() ||
+            UIManager.Instance.IsOpened<ArenaBattleFailWin>())
+            return;
+        CloseWindow();
+        Debug.LogError($"OnBattleEnd 寮傚父鍏抽棴");
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.ArenaBattleField);
+    }
     private void OnTabChangeEvent()
     {
         UIManager.Instance.CloseWindow<ArenaBattleWin>();
diff --git a/Main/System/Battle/BaseBattleWin.cs b/Main/System/Battle/BaseBattleWin.cs
index 7e7a8ee..8d514ed 100644
--- a/Main/System/Battle/BaseBattleWin.cs
+++ b/Main/System/Battle/BaseBattleWin.cs
@@ -200,12 +200,24 @@
     public bool IsPass()
     {
         if (null == battleField)
-            return false;
+            return true;
         // 妫�鏌ユ槸鍚︿负姘镐箙鐗规潈鍗$帺瀹�
         bool hasForeverPrivilege = InvestModel.Instance.IsInvested(InvestModel.foreverCardType);
 
-        if (!hasForeverPrivilege && !FuncOpen.Instance.IsFuncOpen(BattleManager.Instance.passFuncId, true))
+        string battleFieldName = battleField.ToString();
+        if (!hasForeverPrivilege && !FuncOpen.Instance.IsFuncOpen(BattleManager.Instance.passFuncId))
+        {
+            if (battleFieldName != BattleConst.StoryBossBattleField)
+            {
+                //绛夌骇杈惧埌20绾у悗瑙i攣鎴栧紑閫氱粓韬壒鏉冭В閿�
+                SysNotifyMgr.Instance.ShowTip("BattlePass2");
+            }
+            else
+            {
+                FuncOpen.Instance.ProcessorFuncErrorTip(BattleManager.Instance.passFuncId);
+            }
             return false;
+        }
 
         int passRound = BattleManager.Instance.defaultPassRound;
         var name = battleField.ToString();
@@ -254,7 +266,16 @@
             int realPassRound = passRound + 1;  // 閰嶇疆鏄秴杩噚鍥炲悎鍙互璺�,鎰忓懗鐫�x+1鍥炲悎鍙互璺�
             if (nowRound < realPassRound)
             {
-                SysNotifyMgr.Instance.ShowTip("BattlePass", realPassRound - nowRound);
+                if (battleFieldName != BattleConst.StoryBossBattleField)
+                {
+                    //%s0鍥炲悎鍚庡彲璺宠繃锛屽紑閫氱粓韬壒鏉冪珛鍗宠烦杩�
+                    SysNotifyMgr.Instance.ShowTip("BattlePass1", realPassRound - nowRound);
+                }
+                else
+                {
+                    SysNotifyMgr.Instance.ShowTip("BattlePass", realPassRound - nowRound);
+                }
+
                 return false;
             }
         }
diff --git a/Main/System/Battle/BattleField/BattleField.cs b/Main/System/Battle/BattleField/BattleField.cs
index 0c7e101..772a929 100644
--- a/Main/System/Battle/BattleField/BattleField.cs
+++ b/Main/System/Battle/BattleField/BattleField.cs
@@ -273,7 +273,7 @@
 
         // 娓呯悊姝讳骸澶勭悊璁板綍
         processingDeathObjIds.Clear();
-        
+
         // 娓呯┖褰撳墠鎴樺満鐨勮閲忚褰�
         if (BattleHeroInfoBar.largestPackUID.ContainsKey(guid))
         {
@@ -303,7 +303,7 @@
         }
         if (recordPlayer == null || battleObjMgr == null)
             return;
-        
+
         recordPlayer.Run();
         battleObjMgr.Run();
         battleEffectMgr.Run();
@@ -315,7 +315,7 @@
         }
 
         operationAgent.Run();
-        
+
         // 瑙﹀彂 UI 灞傜殑鏇存柊鍥炶皟
         OnBattleRun?.Invoke();
     }
@@ -475,7 +475,7 @@
         {
             // 杩囨护鎺夋鍦ㄥ鐞嗘浜$殑瑙掕壊锛岄伩鍏嶉噸澶嶅鐞�
             List<BattleDeadPack> validDeadList = new List<BattleDeadPack>();
-            
+
             foreach (var deadPack in deadPackList)
             {
                 var objID = deadPack.deadPack.ObjID;
@@ -485,21 +485,21 @@
                     // Debug.LogWarning($"OnObjsDead: 瑙掕壊姝e湪澶勭悊姝讳骸锛屽拷鐣ラ噸澶嶆浜℃秷鎭� ObjID={objID}");
                     continue;
                 }
-                
+
                 BattleObject battleObj = battleObjMgr.GetBattleObject((int)objID);
                 if (battleObj == null)
                 {
                     Debug.LogError($"OnObjsDead: 鎵句笉鍒拌鑹� ObjID={objID}");
                     continue;
                 }
-                
+
                 // 娣诲姞鍒板鐞嗕腑鍒楄〃
                 processingDeathObjIds.Add(objID);
                 validDeadList.Add(deadPack);
 
 
             }
-            
+
             // 鍙鐞嗘湁鏁堢殑姝讳骸娑堟伅
             if (validDeadList.Count > 0)
             {
@@ -583,7 +583,7 @@
         {
             obj.layerMgr.UpdateLayer();
         }
-        
+
         battleRootNode.SetSortingOrder();
         // RendererAdjuster[] adjusters = battleRootNode.GetComponentsInChildren<RendererAdjuster>(true);
         // if (null != adjusters)
@@ -681,7 +681,10 @@
 
             IsBattleFinish = true;
 
-
+            if (!string.IsNullOrEmpty(guid))
+            {
+                Debug.Log($"OnBattleEnd guid {guid}");
+            }
             //鎻愪緵澶栭儴 鑳滃埄绛夊鍔辨樉绀�
             EventBroadcast.Instance.Broadcast<string, JsonData>(EventName.BATTLE_END, guid, turnFightStateData);
         });
@@ -698,10 +701,10 @@
         battleObjMgr.DestroyTeam(BattleCamp.Blue);
         SetBattleStartState();
         SetBattleMode(BattleMode.Stop);
-        
+
         // 娓呯悊姝讳骸澶勭悊璁板綍
         processingDeathObjIds.Clear();
-        
+
         // 娓呯┖褰撳墠鎴樺満鐨勮閲忚褰�
         if (BattleHeroInfoBar.largestPackUID.ContainsKey(guid))
         {
@@ -730,7 +733,7 @@
         battleObjMgr.DestroyTeam(BattleCamp.Blue);
         BattleManager.Instance.ClearStoryQueue();
         SetBattleStartState();
-        
+
         // 娓呯悊姝讳骸澶勭悊璁板綍
         processingDeathObjIds.Clear();
     }
@@ -764,7 +767,7 @@
     {
         recordPlayer.ForceFinish();
     }
-    
+
 
     //鏆傚仠鐨勫師鍥犳湁寰堝锛岄渶瑕佹鏌ュ悇绉嶇姸鎬�
     protected virtual bool CanResumeGame()
diff --git a/Main/System/Battle/BattleField/RecordActions/BattleStartAction.cs b/Main/System/Battle/BattleField/RecordActions/BattleStartAction.cs
index 44f26c2..271d5a7 100644
--- a/Main/System/Battle/BattleField/RecordActions/BattleStartAction.cs
+++ b/Main/System/Battle/BattleField/RecordActions/BattleStartAction.cs
@@ -41,6 +41,10 @@
 
 			UniTaskExtension.DelayTime((GameObject)null, 1f, () =>
 			{
+				if (battleField ==null|| battleField.battleRootNode == null|| battleField.battleRootNode.battleStartNode == null)
+				{
+					return;
+				}
 				battleField.battleRootNode.battleStartNode.SetActive(false);
 				StartBattleCallback();
 			});
diff --git a/Main/System/Battle/BoneFieldBattleWin.cs b/Main/System/Battle/BoneFieldBattleWin.cs
index d5bf43c..9b5932a 100644
--- a/Main/System/Battle/BoneFieldBattleWin.cs
+++ b/Main/System/Battle/BoneFieldBattleWin.cs
@@ -18,6 +18,7 @@
     {
         base.OnPreOpen();
         MainWin.TabChangeEvent += OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow += OnOpenWindow;
         bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
         transButtons.localPosition = new Vector3(0, isOpenBattleChangeTab ? 130 : 0, 0);
         if (isOpenBattleChangeTab)
@@ -28,6 +29,7 @@
         {
             UIManager.Instance.CloseWindow<MainWin>();
         }
+        isClickSkip = false;
     }
 
     protected override void OnPreClose()
@@ -35,6 +37,7 @@
         base.OnPreClose();
 
         MainWin.TabChangeEvent -= OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
         bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
         if (isOpenBattleChangeTab)
         {
@@ -54,8 +57,53 @@
             bossBattleObject = null;
         }
 
+        if (isClickSkip)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
     }
 
+    void OnOpenWindow(UIBase win)
+    {
+        if (win is BoneBattleVictoryWin || win is BoneBattleFailWin)
+        {
+            isClickSkip = false;
+        }
+    }
+
+    bool isClickSkip = false;
+    protected override void OnClickPass()
+    {
+        if (!IsPass())
+            return;
+        isClickSkip = true;
+        clickTime = Time.time;  // 璁板綍鐐瑰嚮鏃堕棿
+        battleField.ForceFinish();
+
+    }
+
+    float stayTime = 2f;
+    float clickTime = 0f;
+    void LateUpdate()
+    {
+        if (isClickSkip && Time.time - clickTime >= stayTime)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
+    }
+
+    private void TryPass()
+    {
+        if (UIManager.Instance.IsOpened<BoneBattleVictoryWin>() ||
+            UIManager.Instance.IsOpened<BoneBattleFailWin>())
+            return;
+        CloseWindow();
+        Debug.LogError($"OnBattleEnd 寮傚父鍏抽棴");
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.BoneBattleField);
+
+    }
     private void OnTabChangeEvent()
     {
         UIManager.Instance.CloseWindow<BoneFieldBattleWin>();
@@ -142,7 +190,7 @@
     {
         // Debug.LogError("OnDamageTaken 琚皟鐢� 璋冪敤鑰呮槸 " + info.battleHurtParam.caster.casterObj?.teamHero.name + " 瀵硅薄 " + info.battleHurtParam.hurter.hurtObj?.teamHero.name);
         base.OnDamageTaken(info);
-        
+
         if (battleField == null || info.battleFieldGuid != battleField.guid)
             return;
 
diff --git a/Main/System/Battle/StoryBossBattleWin.cs b/Main/System/Battle/StoryBossBattleWin.cs
index 6106063..ca75718 100644
--- a/Main/System/Battle/StoryBossBattleWin.cs
+++ b/Main/System/Battle/StoryBossBattleWin.cs
@@ -1,4 +1,5 @@
-锘縰sing System.Collections.Generic;
+锘縰sing System;
+using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -22,14 +23,15 @@
     protected override void OnPreOpen()
     {
         base.OnPreOpen();
-
+        UIManager.Instance.OnOpenWindow += OnOpenWindow;
         UIManager.Instance.CloseWindow<MainWin>();
+        isClickSkip = false;
     }
 
     protected override void OnPreClose()
     {
         base.OnPreClose();
-
+        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
         if (!UIManager.Instance.IsOpened<MainWin>())
             UIManager.Instance.OpenWindow<MainWin>();
 
@@ -38,8 +40,52 @@
             bossBattleObject.buffMgr.onBuffChanged -= OnBuffChanged;
             bossBattleObject = null;
         }
+
+        if (isClickSkip)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
     }
 
+    bool isClickSkip = false;
+    protected override void OnClickPass()
+    {
+        if (!IsPass())
+            return;
+        isClickSkip = true;
+        clickTime = Time.time;  // 璁板綍鐐瑰嚮鏃堕棿
+        battleField.ForceFinish();
+    }
+
+    void OnOpenWindow(UIBase win)
+    {
+        if (win is BattleVictoryWin || win is BattleFailWin)
+        {
+            isClickSkip = false;
+        }
+    }
+
+    float stayTime = 2f;
+    float clickTime = 0f;
+    void LateUpdate()
+    {
+        if (isClickSkip && Time.time - clickTime >= stayTime)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
+    }
+
+    private void TryPass()
+    {
+        if (UIManager.Instance.IsOpened<BattleVictoryWin>() ||
+            UIManager.Instance.IsOpened<BattleFailWin>())
+            return;
+        CloseWindow();
+        Debug.LogError($"OnBattleEnd 寮傚父鍏抽棴");
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.StoryBossBattleField);
+    }
     protected override void OnCreateBattleField(string guid, BattleField field)
     {
         if (field is StoryBossBattleField)
diff --git a/Main/System/Battle/TianziBillboradBattleWin.cs b/Main/System/Battle/TianziBillboradBattleWin.cs
index 9c55ef3..4cbc9e2 100644
--- a/Main/System/Battle/TianziBillboradBattleWin.cs
+++ b/Main/System/Battle/TianziBillboradBattleWin.cs
@@ -28,6 +28,7 @@
         TianziBillboradManager.Instance.OnUpdateBarInfoEvent += OnUpdateBarInfoEvent;
         TianziBillboradManager.Instance.PlayUiEffectAction += OnPlayUiEffectAction;
         MainWin.TabChangeEvent += OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow += OnOpenWindow;
         bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
         transButtons.localPosition = new Vector3(0, isOpenBattleChangeTab ? 130 : 0, 0);
         if (isOpenBattleChangeTab)
@@ -55,6 +56,7 @@
         TianziBillboradManager.Instance.OnUpdateBarInfoEvent -= OnUpdateBarInfoEvent;
         TianziBillboradManager.Instance.PlayUiEffectAction -= OnPlayUiEffectAction;
         MainWin.TabChangeEvent -= OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
         bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
         if (isOpenBattleChangeTab)
         {
@@ -81,14 +83,23 @@
         }
     }
 
+    void OnOpenWindow(UIBase win)
+    {
+        if (win is TianziBillboradVictoryWin)
+        {
+            isClickSkip = false;
+        }
+    }
+
     bool isClickSkip = false;
     protected override void OnClickPass()
     {
         if (!IsPass())
             return;
-        battleField.ForceFinish();
         isClickSkip = true;
         clickTime = Time.time;  // 璁板綍鐐瑰嚮鏃堕棿
+        battleField.ForceFinish();
+
     }
 
     float stayTime = 2f;
@@ -104,12 +115,12 @@
 
     private void TryPass()
     {
-        if (!UIManager.Instance.IsOpened<TianziBillboradVictoryWin>())
-        {
-            CloseWindow();
-            BattleSettlementManager.Instance.WinShowOver(BattleConst.TianziBillboradBattleField);
-            TianziBillboradManager.Instance.isSweepVictory = false;
-        }
+        if (UIManager.Instance.IsOpened<TianziBillboradVictoryWin>())
+            return;
+        CloseWindow();
+        Debug.LogError($"OnBattleEnd 寮傚父鍏抽棴");
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.TianziBillboradBattleField);
+        TianziBillboradManager.Instance.isSweepVictory = false;
     }
 
     private void OnUpdateBarInfoEvent(ulong loaclNowHunt, ulong loaclMaxHp, int loaclHpNum)
diff --git a/Main/System/Settlement/BattleSettlementManager.cs b/Main/System/Settlement/BattleSettlementManager.cs
index 1b324a9..37ccea0 100644
--- a/Main/System/Settlement/BattleSettlementManager.cs
+++ b/Main/System/Settlement/BattleSettlementManager.cs
@@ -42,16 +42,16 @@
         switch (battleName)
         {
             case BattleConst.ArenaBattleField:
-                PopupWindowsProcessor.Instance.Add(isWin ? "ArenaBattleVictoryWin" : "ArenaBattleFailWin", false);
+                PopupWindowsProcessor.Instance.Add(isWin ? "ArenaBattleVictoryWin" : "ArenaBattleFailWin", false, BattleConst.ArenaBattleField);
                 break;
             case BattleConst.BoneBattleField:
-                PopupWindowsProcessor.Instance.Add(isWin ? "BoneBattleVictoryWin" : "BoneBattleFailWin", false);
+                PopupWindowsProcessor.Instance.Add(isWin ? "BoneBattleVictoryWin" : "BoneBattleFailWin", false, BattleConst.BoneBattleField);
                 break;
             case BattleConst.TianziBillboradBattleField:
-                PopupWindowsProcessor.Instance.Add("TianziBillboradVictoryWin", false);
+                PopupWindowsProcessor.Instance.Add("TianziBillboradVictoryWin", false, BattleConst.TianziBillboradBattleField);
                 break;
             default:
-                PopupWindowsProcessor.Instance.Add(isWin ? "BattleVictoryWin" : "BattleFailWin", false);
+                PopupWindowsProcessor.Instance.Add(isWin ? "BattleVictoryWin" : "BattleFailWin", false, BattleConst.StoryBossBattleField);
                 break;
         }
     }
@@ -108,20 +108,29 @@
     {
         if (string.Empty == _guid)
             return;
+        Debug.Log($"OnBattleEnd 缁撶畻 guid {_guid}");
         var battle = BattleManager.Instance.GetBattleField(_guid);
         if (battle == null)
             return;
         var battleName = battle.ToString();
-        battleSettlementDic[battleName] = _data;
-        if (battleAwardDic.ContainsKey(battleName))
+        try
         {
-            //鍚堝苟鎴樻姤鍜岀粨绠楁暟鎹�
-            JsonData extendData = battleAwardDic[battleName];
-            foreach (var key in extendData.Keys)
+            battleSettlementDic[battleName] = _data;
+            if (battleAwardDic.ContainsKey(battleName))
             {
-                _data[key] = extendData[key];
+                //鍚堝苟鎴樻姤鍜岀粨绠楁暟鎹�
+                JsonData extendData = battleAwardDic[battleName];
+                foreach (var key in extendData.Keys)
+                {
+                    _data[key] = extendData[key];
+                }
             }
         }
+        catch (Exception e)
+        {
+            Debug.LogError(e.ToString());
+        }
+
 
         string activeBattleName = BattleManager.Instance.GetActiveBattleName();
 

--
Gitblit v1.8.0