hxp
6 天以前 2b34924e06c0c36d77d9ccec4c4f10f1ebd16e84
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -17,18 +17,21 @@
import ChConfig
import GameWorld
import TurnAttack
import ShareDefine
import SkillCommon
import IpyGameDataPY
import PlayerControl
import ChPyNetSendPack
import ItemControler
import IPY_GameWorld
import NetPackCommon
import TurnAttack
import PlayerArena
import ItemCommon
import PlayerTask
import NPCCommon
import BattleObj
import ChEquip
import ObjPool
import random
@@ -43,6 +46,7 @@
def ResetBootyDropToday(curPlayer):
    bootyItemIDList = GetBootyItemIDList()
    for itemID in bootyItemIDList:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, 0)
        if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID):
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BootyDropToday % itemID, 0)
    SyncDropBootyInfo(curPlayer)
@@ -64,63 +68,21 @@
    ipyData = ipyDataMgr.GetMainChapterByIndex(chapterCount - 1)
    return [booty[0] for booty in ipyData.GetDailyBootyUpperList()]
def OnPlayerLineupAttackSuccess(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
    ## 回合战斗主动发起的玩家阵容释放技能成功
def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjList, useSkill, mapID, funcLineID):
    ## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
    
    if mapID == ChConfig.Def_FBMapID_Main:
        __doCostZhanchui(curPlayer, atkObj, curSkill)
        __doKillAward(curPlayer, atkObj, killObjList)
        
    return
def __doCostZhanchui(curPlayer, atkObj, curSkill):
    ## 扣除战锤消耗
    costZhanchui = 0
    isXP = SkillCommon.isAngerSkill(curSkill)
    turnBattleType = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnBattleType)
    if isXP:
        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
    elif turnBattleType == ChConfig.TurnBattleType_Combo:
        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
    elif turnBattleType == ChConfig.TurnBattleType_AtkBack:
        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
    elif SkillCommon.isTurnNormalSkill(curSkill):
        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
    if costZhanchui <= 0:
        return
    fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
    costZhanchuiTotal = costZhanchui * fightPoint
    if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, costZhanchuiTotal, isNotify=False):
        # 不足时,有多少扣多少
        nowMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao)
        PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, min(nowMoney, costZhanchuiTotal), isNotify=False)
    return
def OnPlayerLineupAttackResult(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
    if mapID == ChConfig.Def_FBMapID_Main:
        __doKillAward(curPlayer, atkObj, mapID, funcLineID)
    return
def __doKillAward(curPlayer, atkObj, mapID, funcLineID):
def __doKillAward(curPlayer, atkObj, killObjList):
    ## 计算击杀奖励
    turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(atkObj.GetID())
    if not turnFight:
    if not killObjList:
        GameWorld.DebugLog("没有击杀不需要处理!")
        return
    unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
    if not turnFight.playerKillObjIDList:
        unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
        GameWorld.DebugLog("没有击杀不需要处理! unXiantaoCntExp=%s,unXiantaoCntEquip=%s" % (unXiantaoCntExp, unXiantaoCntEquip))
        return
    killCnt = len(turnFight.playerKillObjIDList)
    # 直接重置,防止异常时重复结算
    turnFight.playerKillObjIDList = []
    # 结算经验
    unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
    if unXiantaoCntExp:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, 0)
        perExp = IpyGameDataPY.GetFuncCfg("Mainline", 1) # 每个战锤增加经验
@@ -128,129 +90,246 @@
        GameWorld.DebugLog("增加经验: totalExp=%s,unXiantaoCntExp=%s" % (totalExp, unXiantaoCntExp))
        PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
        
    __doMainDrop(curPlayer, killCnt)
    __doMainDrop(curPlayer, killObjList)
    return
def __doMainDrop(curPlayer, killCnt):
def __doMainDrop(curPlayer, killObjList):
    # 装备掉落
    __doDropEquip(curPlayer)
    if __doDropEquip(curPlayer, killObjList) == -1:
        return
    
    playerID = curPlayer.GetPlayerID()
    DailyBootyUpperList, BootyWeightList = [], []
    DailyBootyUpperList = []
    chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
    chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
    if chapterIpyData:
        DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
        BootyWeightList = chapterIpyData.GetBootyWeightList()
    bootyDropUpperDict = {k:v for k, v in DailyBootyUpperList}
    GameWorld.DebugLog("可掉落战利品上限: chapterID=%s,%s,killCnt=%s" % (chapterID, bootyDropUpperDict, killCnt), playerID)
    GameWorld.DebugLog("可掉落战利品上限: chapterID=%s, %s" % (chapterID, DailyBootyUpperList), playerID)
    # 战利品掉落默认不堆叠,故最多只能掉落剩余空格子个数的物品
    spaceCount = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptIdentify)
    
    # 其他战利品掉落
    for _ in range(killCnt):
        dropInfo = GameWorld.GetResultByWeightList(BootyWeightList)
        if not dropInfo:
            continue
        itemID = dropInfo[0]
        if not itemID:
            GameWorld.DebugLog("本次不掉落战利品!", playerID)
            continue
        if itemID not in bootyDropUpperDict:
            GameWorld.DebugLog("该战利品未解锁! itemID=%s" % itemID, playerID)
    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)
        dropUpper = bootyDropUpperDict.get(itemID, 0)
        if todyDropCnt >= dropUpper:
            GameWorld.DebugLog("战利品已达今日掉落上限! itemID=%s,todyDropCnt=%s >= %s" % (itemID, todyDropCnt, dropUpper), playerID)
            continue
        if itemID not in bootyDropNeedDict or itemID not in bootyDropCntDict:
            continue
        dropOneNeed = bootyDropNeedDict[itemID]
        unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID)
        dropBootyCnt = unXiantaoCntBooty / dropOneNeed
        if dropBootyCnt <= 0:
            continue
        
        dropMin = dropInfo[1] if len(dropInfo) > 1 else 1
        dropMax = dropInfo[2] if len(dropInfo) > 2 else 1
        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
        if not itemData:
            continue
        
        if dropMin == dropMax:
            dropCnt = dropMin
        else:
            dropCnt = random.randint(dropMin, dropMax)
        dropCnt = min(dropCnt, dropUpper - todyDropCnt)
        # 判断挑战券
        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
        dropMin = dropCntRange[0]
        dropMax = dropCntRange[1]
        
        GameWorld.DebugLog("掉落战利品! itemID=%s,dropCnt=%s" % (itemID, dropCnt), playerID)
        curItem = ItemControler.GetOutPutItemObj(itemID, dropCnt, False, curPlayer=curPlayer)
        dropCntTotal = 0
        for _ in range(dropBootyCnt):
            if dropMin == dropMax:
                dropCnt = dropMin
            else:
                dropCnt = random.randint(dropMin, dropMax)
            dropCntTotal += dropCnt
        dropCntTotal = min(dropCntTotal, dropUpper - todyDropCnt)
        if dropCntTotal <= 0:
            continue
        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
        curItem.SetIsBind(1) # 为1时代表是掉落
        if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
            continue
        SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCnt)
        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)
    dropOneNeed = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 1) # 每消耗X个战锤掉落一件装备
    dropEquipCnt = unXiantaoCntEquip / dropOneNeed
    playerID = curPlayer.GetPlayerID()
    unXiantaoCntEquip = PlayerControl.GetUnXiantaoCntEquip(curPlayer)
    bossTypeDropInfo = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 1) # 每消耗X个战锤掉落一件装备
    fightPoint = max(curPlayer.GetFightPoint(), 1) # 消耗倍率也是掉落倍率
    dropEquipCnt = 0
    objDropCntDict = {}
    for tagObj in killObjList:
        tagID = tagObj.GetID()
        npcID = tagObj.GetNPCID()
        if not npcID:
            continue
        npcData = NPCCommon.GetNPCDataPy(npcID)
        if not npcData:
            continue
        bossType = npcData.GetBossType()
        if bossType not in bossTypeDropInfo:
            continue
        dropCnt = GameWorld.GetResultByRandomList(bossTypeDropInfo[bossType])
        if not dropCnt:
            continue
        dropCnt *= fightPoint # 多倍掉落
        objDropCntDict[tagID] = [tagObj, dropCnt, bossType]
        dropEquipCnt += dropCnt
    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)
    GameWorld.DebugLog("主线掉落装备: unXiantaoCntEquip=%s,dropEquipCnt=%s,treeLV=%s,objDropCntDict=%s"
                       % (unXiantaoCntEquip, dropEquipCnt, treeLV, objDropCntDict), playerID)
    
    maxRate = 10000
    totalRate = 0
    colorRateList = []
    for equipColor, colorRate in enumerate(equipColorRateList, 1):
        if not colorRate:
            continue
        totalRate += colorRate
        colorRateList.append([totalRate, equipColor])
    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)
    for _ in range(dropEquipCnt):
        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)
        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]):
    for tagID, dropInfo in objDropCntDict.items():
        tagObj, dropCnt, bossType = dropInfo
        if hasattr(ipyData, "GetEquipColorRateList%s" % bossType):
            equipColorRateList = getattr(ipyData, "GetEquipColorRateList%s" % bossType)()
        else:
            equipColorRateList = ipyData.GetEquipColorRateList()
        GameWorld.DebugLog("tagID=%s,bossType=%s,dropCnt=%s,treeLV=%s,equipColorRateList=%s"
                           % (tagID, bossType, dropCnt, treeLV, equipColorRateList), playerID)
        if not equipColorRateList:
            continue
        
        unXiantaoCntEquip -= dropOneNeed
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
        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))
        if not colorRateList:
            return
        GameWorld.DebugLog("    colorRateList=%s,totalRate=%s" % (colorRateList, totalRate), playerID)
        
        for _ in range(dropCnt):
            if dropEquipCnt <= 0:
                break
            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)
            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
            dropEquipCnt -= 1
    return
def GMTestKillDrop(curPlayer, killCnt):
    ## GM测试掉落
    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + killCnt
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
    __doMainDrop(curPlayer, killCnt)
def GMTestKill(curPlayer, useXiantao):
    ## GM测试击杀
    
    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
    GameWorld.DebugAnswer(curPlayer, "剩余未结算装备掉落战锤数:%s" % unXiantaoCntEquip)
    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:
        DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
        for itemID, upperCnt in DailyBootyUpperList:
            if upperCnt <= 0:
                continue
            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))
    OnPlayerLineupAttackResult(curPlayer, atkObj, killObjList, useSkill, turnFight.mapID, turnFight.funcLineID)
    turnFight.checkOverByKilled()
    # 标记结束
    clientPack.Sign = 1
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
#// B4 15 主线掉落物品操作 #tagCSMainDropItemOP
@@ -276,6 +355,7 @@
    else:
        __doPickupMainItem(curPlayer, itemIndexList)
        
    ItemCommon.SyncMakeItemAnswer(curPlayer, ShareDefine.Def_mitMainDropItemOP, ChConfig.Def_ComposeState_Sucess, opType)
    return
def __doEquipMainEquip(curPlayer, itemIndexList, isAutoDecompose):
@@ -322,54 +402,67 @@
        
    # 刷属性
    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
    equipDict = {}
    IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
    for index in range(IdentifyPack.GetCount()):
        curEquip = IdentifyPack.GetAt(index)
        if not ItemCommon.CheckItemCanUse(curEquip):
            #GameWorld.DebugLog("物品为空或不可用: index=%s" % index, playerID)
            continue
        if not ItemCommon.GetIsMainEquip(curEquip):
            #GameWorld.DebugLog("非主线装备: index=%s" % index, playerID)
            continue
        equipDict[index] = curEquip
    if not equipDict:
        return
    equipCnt = len(equipDict)
    unXiantaoCntEquip = PlayerControl.GetUnXiantaoCntEquip(curPlayer)
    perEquipXiantao = unXiantaoCntEquip / float(equipCnt) if equipCnt > 1 else unXiantaoCntEquip
    decomposeMoney = max(1, moneyBase * perEquipXiantao) # 至少1个
    GameWorld.DebugLog("unXiantaoCntEquip=%s,equipCnt=%s,perEquipXiantao=%s,equipIndexList=%s"
                       % (unXiantaoCntEquip, equipCnt, perEquipXiantao, equipDict.keys()), playerID)
    GameWorld.DebugLog("moneyBase=%s,decomposeMoney=%s" % (moneyBase, decomposeMoney), playerID)
    
    moneyTotal = 0
    
    decomposeCnt = 0
    decomposeIndexList = []
    for itemIndex in itemIndexList:
        if itemIndex < 0 or itemIndex >= IdentifyPack.GetCount():
        if itemIndex not in equipDict:
            continue
        curEquip = IdentifyPack.GetAt(itemIndex)
        if not ItemCommon.CheckItemCanUse(curEquip):
            GameWorld.DebugLog("物品为空或不可用: itemIndex=%s" % itemIndex, playerID)
            continue
        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
        curEquip = equipDict[itemIndex]
        
        moneyTotal += decomposeMoney
        GameWorld.DebugLog("    itemIndex=%s,itemColor=%s,moneyBase=%s,decomposeMoney=%s,%s"
                           % (itemIndex, itemColor, moneyBase, decomposeMoney, moneyTotal), playerID)
        GameWorld.DebugLog("    itemIndex=%s,moneyBase=%s,perEquipXiantao=%s,decomposeMoney=%s,总:%s"
                           % (itemIndex, moneyBase, perEquipXiantao, decomposeMoney, moneyTotal), playerID)
        
        ItemCommon.DelItem(curPlayer, curEquip, curEquip.GetCount(), True, ChConfig.ItemDel_EquipDecompose)
        decomposeIndexList.append(itemIndex)
        decomposeCnt += 1
        unXiantaoCntEquip -= perEquipXiantao
        
    if not moneyTotal:
        return
    
    moneyTotal = int(round(moneyTotal)) # 四舍五入取整
    unXiantaoCntEquip = PlayerControl.SetUnXiantaoCntEquip(curPlayer, unXiantaoCntEquip)
    GameWorld.DebugLog("moneyTotal=%s,unXiantaoCntEquip=%s" % (moneyTotal, unXiantaoCntEquip), playerID)
    PlayerControl.GiveMoney(curPlayer, moneyType, moneyTotal, "DecomposeMainEquip", isSysHint=False)
    PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_EquipDecompose, decomposeCnt)
    return
def __doPickupMainItem(curPlayer, itemIndexList):
@@ -406,13 +499,59 @@
        syncItemIDList = GetBootyItemIDList()
    else:
        syncItemIDList = [itemID]
    clientPack = ChPyNetSendPack.tagSCDropBootyInfo()
    poolMgr = ObjPool.GetPoolMgr()
    clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCDropBootyInfo)
    clientPack.DropBootyList = []
    for itemID in syncItemIDList:
        dropBooty = ChPyNetSendPack.tagSCDropBooty()
        dropBooty = poolMgr.acquire(ChPyNetSendPack.tagSCDropBooty)
        dropBooty.ItemID = itemID
        dropBooty.TodayDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
        clientPack.DropBootyList.append(dropBooty)
    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