From 9f75df2e561df58c84b48b9513849b656d57c7b9 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 17 十一月 2025 11:09:04 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(修改主线掉落按消耗战锤掉落;分解装备改为按装备固定分解;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py |  316 +++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 247 insertions(+), 69 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
index a40cae8..3829f22 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -17,15 +17,21 @@
 
 import ChConfig
 import GameWorld
+import TurnAttack
 import ShareDefine
 import IpyGameDataPY
 import PlayerControl
+import PlayerActivity
 import ChPyNetSendPack
 import ItemControler
 import IPY_GameWorld
 import NetPackCommon
+import PlayerArena
+import PlayerLLMJ
 import ItemCommon
+import PlayerTask
 import NPCCommon
+import BattleObj
 import ChEquip
 import ObjPool
 
@@ -64,34 +70,41 @@
     ipyData = ipyDataMgr.GetMainChapterByIndex(chapterCount - 1)
     return [booty[0] for booty in ipyData.GetDailyBootyUpperList()]
 
-def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID):
+def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjList, useSkill, mapID, funcLineID):
     ## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
     
     if mapID == ChConfig.Def_FBMapID_Main:
-        __doKillAward(curPlayer, atkObj, killObjIDList)
+        __doKillAward(curPlayer, atkObj, killObjList)
         
     return
 
-def __doKillAward(curPlayer, atkObj, killObjIDList):
+def __doKillAward(curPlayer, atkObj, killObjList):
     ## 计算击杀奖励
-    if not killObjIDList:
-        GameWorld.DebugLog("没有击杀不需要处理!")
+    if not killObjList:
+        GameWorld.DebugLog("没有击杀不需要处理主线奖励!")
         return
     # 结算经验
     unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
     if unXiantaoCntExp:
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, 0)
         perExp = IpyGameDataPY.GetFuncCfg("Mainline", 1) # 每个战锤增加经验
-        totalExp = unXiantaoCntExp * perExp
-        GameWorld.DebugLog("增加经验: totalExp=%s,unXiantaoCntExp=%s" % (totalExp, unXiantaoCntExp))
-        PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
-        
-    __doMainDrop(curPlayer)
+        baseExp = unXiantaoCntExp * perExp
+        mjExPer, exRemain = PlayerLLMJ.GetAddExpPerInfo(curPlayer)
+        mjEx = min(int(baseExp * mjExPer / 100.0), exRemain)
+        totalExp = baseExp + mjEx
+        GameWorld.DebugLog("增加经验: totalExp=%s,unXiantaoCntExp=%s,baseExp=%s,mjEx=%s,mjExPer=%s,exRemain=%s" 
+                           % (totalExp, unXiantaoCntExp, baseExp, mjEx, mjExPer, exRemain))
+        finalAddExp = PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
+        if mjEx and finalAddExp:
+            TurnAttack.GetMainFightMgr(curPlayer).mjExp += mjEx
+            
+    __doMainDrop(curPlayer, killObjList)
     return
 
-def __doMainDrop(curPlayer):
+def __doMainDrop(curPlayer, killObjList):
     # 装备掉落
-    __doDropEquip(curPlayer)
+    if __doDropEquip(curPlayer, killObjList) == -1:
+        return
     
     playerID = curPlayer.GetPlayerID()
     DailyBootyUpperList = []
@@ -102,10 +115,16 @@
            
     GameWorld.DebugLog("可掉落战利品上限: chapterID=%s, %s" % (chapterID, DailyBootyUpperList), playerID)
     
+    # 战利品掉落默认不堆叠,故最多只能掉落剩余空格子个数的物品
+    spaceCount = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptIdentify)
+    
     # 其他战利品掉落
     bootyDropNeedDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 1, {})
     bootyDropCntDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 2, {})
     for itemID, dropUpper in DailyBootyUpperList:
+        if spaceCount <= 0:
+            GameWorld.DebugLog("掉落背包已满!", playerID)
+            break
         if dropUpper <= 0:
             continue
         todyDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
@@ -120,6 +139,22 @@
         if dropBootyCnt <= 0:
             continue
         
+        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
+        if not itemData:
+            continue
+        
+        # 判断挑战券
+        if itemData.GetType() == ChConfig.Def_ItemType_AutoUseMoney:
+            curEff = itemData.GetEffectByIndex(0)
+            effID = curEff.GetEffectID()
+            moneyType = curEff.GetEffectValue(1)
+            if effID == ChConfig.Def_Effect_ItemGiveMoney and moneyType == ShareDefine.TYPE_Price_ArenaTicket:
+                curMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_ArenaTicket)
+                storeMax = PlayerArena.GetArenaTicketStoreMax(curPlayer)
+                if curMoney >= storeMax:
+                    GameWorld.DebugLog("挑战券已达存储上限! itemID=%s,curMoney=%s >= %s" % (itemID, curMoney, storeMax), playerID)
+                    continue
+                
         dropCntRange = bootyDropCntDict[itemID]
         if not isinstance(dropCntRange, (list, tuple)) or len(dropCntRange) != 2:
             continue
@@ -137,7 +172,8 @@
         if dropCntTotal <= 0:
             continue
         
-        GameWorld.DebugLog("掉落战利品! itemID=%s,unXiantaoCntBooty=%s,次数=%s,dropCntTotal=%s" % (itemID, unXiantaoCntBooty, dropBootyCnt, dropCntTotal), playerID)
+        GameWorld.DebugLog("掉落战利品! itemID=%s,unXiantaoCntBooty=%s,次数=%s,dropCntTotal=%s,spaceCount=%s" 
+                           % (itemID, unXiantaoCntBooty, dropBootyCnt, dropCntTotal, spaceCount), playerID)
         curItem = ItemControler.GetOutPutItemObj(itemID, dropCntTotal, False, curPlayer=curPlayer)
         if curItem == None:
             continue
@@ -147,73 +183,157 @@
         unXiantaoCntBooty = unXiantaoCntBooty % dropOneNeed
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
         SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCntTotal)
+        spaceCount -= 1
         
     return
 
-def __doDropEquip(curPlayer):
+def __doDropEquip(curPlayer, killObjList):
     ## 主线掉落装备
-    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
+    playerID = curPlayer.GetPlayerID()
+    unXiantaoCntEquip = PlayerControl.GetUnXiantaoCntEquip(curPlayer)
     dropOneNeed = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 1) # 每消耗X个战锤掉落一件装备
     dropEquipCnt = unXiantaoCntEquip / dropOneNeed
+    
     if dropEquipCnt <= 0:
-        GameWorld.DebugLog("主线暂不能掉落! unXiantaoCntEquip=%s,dropOneNeed=%s,dropEquipCnt=%s" % (unXiantaoCntEquip, dropOneNeed, dropEquipCnt))
+        GameWorld.DebugLog("主线暂不能掉落! unXiantaoCntEquip=%s,dropEquipCnt=%s" % (unXiantaoCntEquip, dropEquipCnt), playerID)
         return
+    # 根据掉落背包空间修正最终可掉落装备数
     dropEquipCnt = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptIdentify, dropEquipCnt)
     if not dropEquipCnt:
-        GameWorld.DebugLog("掉落鉴定背包没有空间!")
-        return
+        GameWorld.DebugLog("掉落背包已满!", playerID)
+        return -1
     
-    playerID = curPlayer.GetPlayerID()    
     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
     ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", treeLV)
     if not ipyData:
         return
-    equipColorRateList = ipyData.GetEquipColorRateList()
-    GameWorld.DebugLog("主线掉落装备: unXiantaoCntEquip=%s,dropEquipCnt=%s,treeLV=%s,equipColorRateList=%s" % (unXiantaoCntEquip, dropEquipCnt, treeLV, equipColorRateList), playerID)
     
-    maxRate = 10000
-    totalRate = 0
-    colorRateList = []
-    for equipColor, colorRate in enumerate(equipColorRateList, 1):
-        if not colorRate:
+    bossTypeList = []
+    bossTypeDropRateDict = {}
+    for tagObj in killObjList:
+        npcID = tagObj.GetNPCID()
+        if not npcID:
             continue
-        totalRate += colorRate
-        colorRateList.append([totalRate, equipColor])
+        npcData = NPCCommon.GetNPCDataPy(npcID)
+        if not npcData:
+            continue
+        bossType = npcData.GetBossType()
+        bossTypeList.append(bossType)
         
-    if totalRate != maxRate:
-        GameWorld.SendGameError("GameWarning", "CutTreeTotalRateError:%s!=%s,treeLV=%s" % (totalRate, maxRate, treeLV))    
-    if not colorRateList:
-        return
-    GameWorld.DebugLog("    colorRateList=%s,totalRate=%s" % (colorRateList, totalRate), playerID)
+        if bossType in bossTypeDropRateDict:
+            continue
+        
+        if hasattr(ipyData, "GetEquipColorRateList%s" % bossType):
+            equipColorRateList = getattr(ipyData, "GetEquipColorRateList%s" % bossType)()
+        else:
+            equipColorRateList = ipyData.GetEquipColorRateList()
+        totalRate = 0
+        colorRateList = []
+        for equipColor, colorRate in enumerate(equipColorRateList, 1):
+            if not colorRate:
+                continue
+            totalRate += colorRate
+            colorRateList.append([totalRate, equipColor])
+        #maxRate = 10000
+        #if totalRate != maxRate:
+        #    GameWorld.SendGameError("GameWarning", "CutTreeTotalRateError:%s!=%s,treeLV=%s" % (totalRate, maxRate, treeLV))
+        bossTypeDropRateDict[bossType] = colorRateList
+        GameWorld.DebugLog("bossType=%s,treeLV=%s,totalRate=%s,equipColorRateList=%s,colorRateList=%s," 
+                           % (bossType, treeLV, totalRate, equipColorRateList, colorRateList), playerID)
+        
+    bossTypeList.sort(reverse=True) # 按bossType优先掉落
+    GameWorld.DebugLog("主线掉落装备: unXiantaoCntEquip=%s,dropEquipCnt=%s,treeLV=%s,bossTypeList=%s" 
+                       % (unXiantaoCntEquip, dropEquipCnt, treeLV, bossTypeList), playerID)
+    dropAppointEquipDict = IpyGameDataPY.GetFuncEvalCfg("MainDropAppoint", 1, {})
+    appointDropCntMax = max(dropAppointEquipDict) if dropAppointEquipDict else 0
     
-    for _ in range(dropEquipCnt):
-        itemColor = GameWorld.GetResultByRandomList(colorRateList)
-        if not itemColor:
+    for index in range(dropEquipCnt):
+        bossType = bossTypeList[index % len(bossTypeList)]
+        if bossType not in bossTypeDropRateDict:
             continue
-        equipIDList = NPCCommon.__GetEquipIDList(0, color=itemColor, placeList=ChConfig.Def_MainEquipPlaces, findType="MainEquipDrop")
-        if not equipIDList:
-            continue
-        randEquipID = random.choice(equipIDList)
+        colorRateList = bossTypeDropRateDict.get(bossType, [])
+        GameWorld.DebugLog("bossType=%s,colorRateList=%s,totalRate=%s" % (bossType, colorRateList, totalRate), playerID)
         
-        curItem = ItemControler.GetOutPutItemObj(randEquipID, 1, False, curPlayer=curPlayer)
+        setAttrDict = None
+        appointDropEquipCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AppointDropEquipCnt) + 1
+        if appointDropEquipCnt in dropAppointEquipDict:
+            appointInfo = dropAppointEquipDict[appointDropEquipCnt]
+            randEquipID = appointInfo[0]
+            equipLV = appointInfo[1] if len(appointInfo) > 1 else 0
+            appointID = appointInfo[2] if len(appointInfo) > 2 else 0
+            setAttrDict = {}
+            if equipLV > 0:
+                setAttrDict["%s" % ShareDefine.Def_IudetItemLV] = equipLV
+            if appointID:
+                setAttrDict[ShareDefine.Def_CItemKey_AppointID] = appointID
+            GameWorld.DebugLog("定制掉落第%s次: equipID=%s,setAttrDict=%s" % (appointDropEquipCnt, randEquipID, setAttrDict))
+        else:
+            itemColor = GameWorld.GetResultByRandomList(colorRateList)
+            if not itemColor:
+                continue
+            equipIDList = NPCCommon.__GetEquipIDList(0, color=itemColor, placeList=ChConfig.Def_MainEquipPlaces, findType="MainEquipDrop")
+            if not equipIDList:
+                continue
+            randEquipID = random.choice(equipIDList)
+            
+        curItem = ItemControler.GetOutPutItemObj(randEquipID, 1, False, curPlayer=curPlayer, setAttrDict=setAttrDict)
         if curItem == None:
             continue
         curItem.SetIsBind(1) # 为1时代表是掉落
-        
         #GameWorld.DebugLog("掉落装备: randEquipID=%s,%s" % (randEquipID, curItem.GetGUID()), playerID)
         if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
             continue
         
         unXiantaoCntEquip -= dropOneNeed
+        PlayerControl.SetUnXiantaoCntEquip(curPlayer, unXiantaoCntEquip)
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
         
+        if appointDropEquipCnt <= appointDropCntMax:
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AppointDropEquipCnt, appointDropEquipCnt)
     return
 
-def GMTestKillDrop(curPlayer, unXiantao):
-    ## GM测试掉落
-    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + unXiantao
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
-    GameWorld.DebugAnswer(curPlayer, "未结算装备战锤数: %s" % unXiantaoCntEquip)
+def GMTestKill(curPlayer, useXiantao):
+    ## GM测试击杀
+    
+    mainFightMgr = TurnAttack.GetMainFightMgr(curPlayer)
+    turnFight = mainFightMgr.turnFight
+    if not turnFight.isInFight():
+        GameWorld.DebugAnswer(curPlayer, "非主线战斗中!")
+        return
+    
+    useSkill = None
+    batObjMgr = BattleObj.GetBatObjMgr()
+    
+    # 随便取一个武将击杀对方所有怪物即可
+    atkObj = None
+    batFactionA = turnFight.getBatFaction(ChConfig.Def_FactionA)
+    batLineup = batFactionA.getBatlineup(1)
+    for objID in batLineup.posObjIDDict.values():
+        atkObj = batObjMgr.getBatObj(objID)
+        if atkObj.IsAlive():
+            break
+        
+    if not atkObj:
+        GameWorld.DebugAnswer(curPlayer, "主阵容没有存活武将!")
+        return
+    
+    clientPack = ChPyNetSendPack.tagSCTurnFightReportSign()
+    clientPack.Sign = 0
+    NetPackCommon.SendFakePack(curPlayer, clientPack) # 标记开始
+    
+    killObjList = []
+    batFactionB = turnFight.getBatFaction(ChConfig.Def_FactionB)
+    batLineup = batFactionB.getBatlineup(1)
+    for objID in batLineup.posObjIDDict.values():
+        tagObj = batObjMgr.getBatObj(objID)
+        if tagObj.IsAlive():
+            killObjList.append(tagObj)
+            TurnAttack.SetObjKilled(turnFight, tagObj, atkObj, useSkill)
+            
+    unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp) + useXiantao
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, unXiantaoCntExp)
+    GameWorld.DebugAnswer(curPlayer, "未结算经验战锤数: %s" % unXiantaoCntExp)
+    GameWorld.DebugAnswer(curPlayer, "未结算装备战锤数: %s" % PlayerControl.AddUnXiantaoCntEquip(curPlayer, useXiantao))
     chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
     chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
     if chapterIpyData:
@@ -221,11 +341,16 @@
         for itemID, upperCnt in DailyBootyUpperList:
             if upperCnt <= 0:
                 continue
-            unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID) + unXiantao
+            unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID) + useXiantao
             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
             GameWorld.DebugAnswer(curPlayer, "未结算战利品(%s)战锤数: %s" % (itemID, unXiantaoCntBooty))
             
-    __doMainDrop(curPlayer)
+    OnPlayerLineupAttackResult(curPlayer, atkObj, killObjList, useSkill, turnFight.mapID, turnFight.funcLineID)
+    turnFight.checkOverByKilled()
+    
+    # 标记结束
+    clientPack.Sign = 1
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
 
 #// B4 15 主线掉落物品操作 #tagCSMainDropItemOP
@@ -298,20 +423,27 @@
         
     # 刷属性
     ChEquip.RefreshRoleEquipAttr(curPlayer)
+    
+    PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_EquipColor)
     return
 
 def __doDecomposeMainEquip(curPlayer, itemIndexList):
     playerID = curPlayer.GetPlayerID()
     GameWorld.DebugLog("分解主线装备: itemIndexList=%s" % (itemIndexList), playerID)
-    IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
-    
-    moneyType = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 2)
-    if not moneyType:
+    moneyType, moneyBase = IpyGameDataPY.GetFuncEvalCfg("MainEquipDrop", 2)
+    if not moneyType or not moneyBase:
         return
     
-    moneyTotal = 0
+    decomposeMoney = moneyBase
+    mjExPer, exRemain = PlayerLLMJ.GetAddDecomposePer(curPlayer)
+    mjEx = int(decomposeMoney * mjExPer / 100.0)
+    GameWorld.DebugLog("moneyType=%s,moneyBase=%s,mjExPer=%s,exRemain=%s,mjEx=%s" % (moneyType, moneyBase, mjExPer, exRemain, mjEx), playerID)
     
-    decomposeIndexList = []
+    moneyTotal = 0
+    mjExTotal = 0
+    decomposeCnt = 0
+    
+    IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
     for itemIndex in itemIndexList:
         if itemIndex < 0 or itemIndex >= IdentifyPack.GetCount():
             continue
@@ -323,29 +455,29 @@
         if not ItemCommon.GetIsMainEquip(curEquip):
             GameWorld.DebugLog("非主线装备: itemIndex=%s" % itemIndex, playerID)
             continue
-        itemColor = curEquip.GetItemColor()
-        
-        colorIpyData = IpyGameDataPY.GetIpyGameData("EquipColor", itemColor)
-        if not colorIpyData:
-            return
-        moneyBase = colorIpyData.GetMoneyBase() # 分解货币基础
-        if not moneyBase:
-            return
-        # 可以处理一些加成
-        
-        decomposeMoney = moneyBase
         
         moneyTotal += decomposeMoney
-        GameWorld.DebugLog("    itemIndex=%s,itemColor=%s,moneyBase=%s,decomposeMoney=%s,%s" 
-                           % (itemIndex, itemColor, moneyBase, decomposeMoney, moneyTotal), playerID)
+        if mjEx > 0:
+            mjEx = min(mjEx, exRemain)
+            exRemain -= mjEx
+            moneyTotal += mjEx
+            mjExTotal += mjEx
+        GameWorld.DebugLog("    itemIndex=%s,decomposeMoney=%s,mjEx=%s,exRemain=%s,总:%s" 
+                           % (itemIndex, decomposeMoney, mjEx, exRemain, moneyTotal), playerID)
         
         ItemCommon.DelItem(curPlayer, curEquip, curEquip.GetCount(), True, ChConfig.ItemDel_EquipDecompose)
-        decomposeIndexList.append(itemIndex)
+        decomposeCnt += 1
         
     if not moneyTotal:
         return
     
+    moneyTotal = int(round(moneyTotal)) # 四舍五入取整
+    GameWorld.DebugLog("moneyTotal=%s,mjExTotal=%s" % (moneyTotal, mjExTotal), playerID)
+    
     PlayerControl.GiveMoney(curPlayer, moneyType, moneyTotal, "DecomposeMainEquip", isSysHint=False)
+    PlayerLLMJ.AddExpDecompose(curPlayer, mjExTotal)
+    PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_EquipDecompose, decomposeCnt)
+    PlayerActivity.AddDailyTaskValue(curPlayer, ChConfig.DailyTask_EquipDecompose, decomposeCnt)
     return
 
 def __doPickupMainItem(curPlayer, itemIndexList):
@@ -368,6 +500,7 @@
             continue
         itemID = curItem.GetItemTypeID()
         item = curItem.GetItem()
+        item.SetIsBind(0) # 拾取时重置,取源SingleItem修改不通知
         itemCount = ItemControler.GetItemCount(curItem)
         GameWorld.DebugLog("主线物品拾取: itemIndex=%s,itemID=%s,itemCount=%s" % (itemIndex, itemID, itemCount), playerID)
         if not itemControl.PutInItem(IPY_GameWorld.rptItem, item):
@@ -393,3 +526,48 @@
     clientPack.Count = len(clientPack.DropBootyList)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
+
+def OnTurnFightOver(curPlayer, turnFight, mapID, funcLineID, overMsg):
+    ## 回合战斗结束
+    
+    if not curPlayer:
+        return
+    
+    #winFaction = turnFight.winFaction
+    isWin = turnFight.isWin
+    
+    playerID = curPlayer.GetPlayerID()
+    mainFightMgr = TurnAttack.GetMainFightMgr(curPlayer)
+    chapterID, levelNum, wave = PlayerControl.GetMainLevelNowInfo(curPlayer)
+    
+    if not isWin:
+        nextWave = max(1, wave - 1)
+        nowValue = PlayerControl.SetMainLevelNowInfo(curPlayer, chapterID, levelNum, nextWave)
+        GameWorld.DebugLog("主线小怪战斗失败,降一波! chapterID=%s,levelNum=%s,wave=%s,nextWave=%s,nowValue=%s" 
+                           % (chapterID, levelNum, wave, nextWave, nowValue), playerID)
+        return
+    
+    if turnFight.haveNextLineup():
+        GameWorld.DebugLog("主线小怪战斗胜利,有下一小队! chapterID=%s,levelNum=%s,wave=%s" % (chapterID, levelNum, wave), playerID)
+        return
+    
+    # 获胜过波
+    if wave < mainFightMgr.waveMax:
+        nextWave = min(mainFightMgr.waveMax, wave + 1)
+        nowValue = PlayerControl.SetMainLevelNowInfo(curPlayer, chapterID, levelNum, nextWave)
+        GameWorld.DebugLog("主线小怪波战斗胜利,下一波! chapterID=%s,levelNum=%s,wave=%s,nextWave=%s,nowValue=%s" 
+                           % (chapterID, levelNum, wave, nextWave, nowValue), playerID)
+    else:
+        GameWorld.DebugLog("主线小怪波战斗胜利,最后一波循环刷! chapterID=%s,levelNum=%s,wave=%s" % (chapterID, levelNum, wave), playerID)
+        
+    # 小怪可能会退波,所以只在有超过已过关卡进度时才更新值
+    hisPassValue = PlayerControl.GetMainLevelPassValue(curPlayer)
+    curPassValue = PlayerControl.ComMainLevelValue(chapterID, levelNum, wave)
+    if curPassValue > hisPassValue:
+        GameWorld.DebugLog("更新当前过关进度! curPassValue=%s,hisPassValue=%s" % (curPassValue, hisPassValue), playerID)
+        PlayerControl.SetMainLevelPassValue(curPlayer, curPassValue)
+    else:
+        GameWorld.DebugLog("未超过当前过关进度,不更新! curPassValue=%s <= hisPassValue=%s" % (curPassValue, hisPassValue), playerID)
+        
+    return
+

--
Gitblit v1.8.0