hxp
2025-10-22 5925409bdea13d819e4e4356a51043de5f3f9bd8
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGubao.py
@@ -4,121 +4,54 @@
#
##@package Player.PlayerGubao
#
# @todo:古宝系统
# @todo:古宝
# @author hxp
# @date 2023-01-05
# @date 2025-10-11
# @version 1.0
#
# 详细描述: 古宝系统
# 详细描述: 古宝
#
#-------------------------------------------------------------------------------
#"""Version = 2023-01-05 15:30"""
#"""Version = 2025-10-11 21:00"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerRune
import ItemCommon
import PlayerControl
import IpyGameDataPY
import ChPyNetSendPack
import PlayerGatherSoul
import NetPackCommon
import IPY_GameWorld
import PlayerHorse
import PlayerDogz
import PlayerPet
import ChConfig
import ItemControler
import PlayerDienstgrad
import PlayerGatherTheSoul
import PlayerActGubao
import PlayerActTask
import PlayerCoat
import PlayerOnline
import ChConfig
import ObjPool
GubaoEffType_FamilyWar = 48 # 参与仙盟联赛每X次+XXX属性    x次
GubaoEffType_ElderBattlefield = 49 # 参与上古战场每X次+XXX属性    x次
GubaoEffType_CrossBattlefield = 50 # 参与古神战场每X次+XXX属性    x次
GubaoEffType_CrossYaomoBoss = 51 # 参与魔王入侵每X次+XXX属性    x次
GubaoEffType_CrossFamilyFlagwar = 52 # 参与逐鹿万界每X次+XXX属性    x次
GubaoEffType_GoldRush = 1 # 参与淘金
GubaoEffType_Arena = 2 # 参与演武场
GubaoEffAttrIypeList = [GubaoEffType_FamilyWar, GubaoEffType_ElderBattlefield, GubaoEffType_CrossBattlefield,
                        GubaoEffType_CrossYaomoBoss, GubaoEffType_CrossFamilyFlagwar]
GubaoEffType_ActivityPlace = 33 # 活跃修炼x次可领取物品    x次
GubaoEffType_Arena = 34 # 竞技场挑战x次可领取物品    x次
GubaoEffType_KillWorldBoss = 35 # 击杀世界bossx次可领取物品    x次
GubaoEffType_KillBossHome = 36 # 击杀boss之家bossx次可领取物品    x次
GubaoEffType_KillCrossPenglaiBoss = 37 # 击杀蓬莱仙境bossx次可领取物品    x次
GubaoEffType_KillCrossDemonLandBoss = 38 # 击杀魔化之地bossx次可领取物品    x次
GubaoEffType_KillSealDemonBoss = 39 # 击杀封魔坛bossx次可领取物品    x次
GubaoEffType_CrossRealmPK = 40 # 参与跨服天梯赛x次可领取物品    x次
# 古宝领取物品特殊效果列表
GubaoEffTtemIypeList = [GubaoEffType_ActivityPlace, GubaoEffType_Arena, GubaoEffType_KillWorldBoss, GubaoEffType_KillBossHome,
                        GubaoEffType_KillCrossPenglaiBoss, GubaoEffType_KillCrossDemonLandBoss, GubaoEffType_KillSealDemonBoss,
                        GubaoEffType_CrossRealmPK,
                        ]
# 古宝灵根点特殊效果列表
GubaoEffType_RealmLVAddLinggen = 55 # 境界每级增加X点灵根
GubaoEffFreePointTypeList = [54, 55, 56]
# 需要记录EffValue的EffType列表
NeedGubaoItemEffValueTypeList = GubaoEffAttrIypeList + GubaoEffTtemIypeList + GubaoEffFreePointTypeList
def GetGubaoLVInfo(curPlayer, gubaoID):
    lvInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoLVInfo % gubaoID)
    lv = lvInfo / 100
    star = lvInfo % 100
    return lv, star
def SetGubaoLVInfo(curPlayer, gubaoID, lv, star):
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoLVInfo % gubaoID, lv * 100 + star)
def GetGubaoInfo(curPlayer, gubaoID):
    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoInfo % gubaoID)
    layer = info / 100000
    lv = info % 100000 / 100
    star = info % 100
    return lv, star, layer
def SetGubaoInfo(curPlayer, gubaoID, lv, star, layer):
    ## 特殊效果层*100000 + 等级*100 + 星级
    info = min(layer, 99) * 100000 + min(lv, 999) * 100 + min(star, 99)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoInfo % gubaoID, info)
    return
def OnPlayerLogin(curPlayer):
    DoGubaoAddFreePoint(curPlayer) # 上线检查一下,修改配置可生效
    Sync_GubaoInfo(curPlayer)
    Sync_GubaoItemEffInfo(curPlayer)
    Sync_GubaoPieceInfo(curPlayer)
    return
def AddGubaoPiece(curPlayer, gubaoID, addCount, useItemID):
    curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoPiece % gubaoID)
    updCount = min(curCount + addCount, ChConfig.Def_UpperLimit_DWord)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoPiece % gubaoID, updCount)
    Sync_GubaoPieceInfo(curPlayer, [gubaoID])
    GameWorld.Log("增加古宝碎片: gubaoID=%s,curCount=%s,addCount=%s,updCount=%s,useItemID=%s"
                  % (gubaoID, curCount, addCount, updCount, useItemID), curPlayer.GetPlayerID())
    return curCount, updCount
def DelGubaoPiece(curPlayer, gubaoID, delCount, delName):
    curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoPiece % gubaoID)
    if curCount < delCount:
        return False
    updCount = curCount - delCount
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoPiece % gubaoID, updCount)
    Sync_GubaoPieceInfo(curPlayer, [gubaoID])
    GameWorld.Log("扣除古宝碎片: gubaoID=%s,curCount=%s,delCount=%s,updCount=%s,delName=%s"
                  % (gubaoID, curCount, delCount, updCount, delName), curPlayer.GetPlayerID())
    return True
def ParseGubaoNeedItem(curPlayer, needItemList):
    ## 解析古宝功能所需物品,转化为古宝碎片+物品
    needPieceInfo, realNeedItemList = {}, []
    for itemID, itemCount in needItemList:
        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
        if not itemData:
            continue
        curEff = itemData.GetEffectByIndex(0)
        effID = curEff.GetEffectID()
        if effID != ChConfig.Def_Effect_GubaoPiece:
            realNeedItemList.append([itemID, itemCount])
            continue
        gubaoID = curEff.GetEffectValue(0)
        needPieceInfo[gubaoID] = needPieceInfo.get(gubaoID, 0) + itemCount
    GameWorld.DebugLog("转化古宝功能所需物品: needItemList=%s,realNeedItemList=%s,needPieceInfo=%s"
                       % (needItemList, realNeedItemList, needPieceInfo), curPlayer.GetPlayerID())
    return needPieceInfo, realNeedItemList
def IsGubaoActivated(curPlayer, gubaoID):
    ## 检查古宝是否已激活
    lv, star, _ = GetGubaoInfo(curPlayer, gubaoID)
    if lv or star:
        return True
    return False
#// B2 16 古宝激活 #tagCMGubaoActivate
#
@@ -131,6 +64,11 @@
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    if IsGubaoActivated(curPlayer, gubaoID):
        GameWorld.DebugLog("古宝已经激活过! gubaoID=%s" % gubaoID, playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not ipyData:
        return
@@ -139,205 +77,83 @@
    if not needItemID or not needItemCnt:
        return
    
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if lv or star:
        GameWorld.DebugLog("古宝已经激活过! gubaoID=%s" % gubaoID, playerID)
    itemCount = ItemControler.GetItemCountByID(curPlayer, needItemID)
    if itemCount < needItemCnt:
        GameWorld.DebugLog("激活古宝碎片不足! gubaoID=%s,needItemID=%s,itemCount=%s < %s" % (gubaoID, needItemID, itemCount, needItemCnt), playerID)
        return
    ItemControler.DelItemCountByID(curPlayer, needItemID, needItemCnt)
    
    needPieceInfo, realNeedItemList = ParseGubaoNeedItem(curPlayer, [[needItemID, needItemCnt]])
    if realNeedItemList:
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(needItemID, itemPack, needItemCnt)
        if not hasEnough:
            GameWorld.DebugLog("激活古宝道具不足! needItemID=%s,needItemCnt=%s" % (needItemID, needItemCnt), playerID)
            return
    for gID, needPieceCount in needPieceInfo.items():
        curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoPiece % gID)
        if curCount < needPieceCount:
            GameWorld.DebugLog("激活古宝碎片不足! gubaoID=%s,curCount=%s < needPieceCount=%s" % (gubaoID, curCount, needPieceCount), playerID)
            return
    for gID, needPieceCount in needPieceInfo.items():
        DelGubaoPiece(curPlayer, gID, needPieceCount, "Activate")
    if realNeedItemList:
        ItemCommon.ReduceItem(curPlayer, itemPack, itemList, needItemCnt, False, "Gubao")
    lv, star = 1, 1
    SetGubaoLVInfo(curPlayer, gubaoID, lv, star)
    GameWorld.Log("古宝激活成功! gubaoID=%s" % gubaoID, playerID)
    DoGubaoAddFreePoint(curPlayer, gubaoID)
    lv, star, layer = 1, 0, 0
    SetGubaoInfo(curPlayer, gubaoID, lv, star, layer)
    GameWorld.DebugLog("古宝激活成功! gubaoID=%s" % gubaoID, playerID)
    
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    PlayerActGubao.OnGubaoCost(curPlayer, needPieceInfo, realNeedItemList)
    return
#// B2 17 古宝升星 #tagCMGubaoStarUp
#
#struct    tagCMGubaoPieceUse
#{
#    WORD        GubaoID;        // 通用碎片古宝ID
#    WORD        PieceCount;    // 使用碎片个数
#};
#
#struct    tagCMGubaoStarUp
#{
#    tagHead         Head;
#    WORD        GubaoID;    
#    BYTE        PieceSelectCount;
#    tagCMGubaoPieceUse    CommPieceUseList[PieceSelectCount];    // 通用古宝碎片使用列表
#};
def OnGubaoStarUp(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
    if not IsGubaoActivated(curPlayer, gubaoID):
        GameWorld.DebugLog("古宝未激活,无法升星! gubaoID=%s" % gubaoID, playerID)
        return
    
    if not IpyGameDataPY.GetIpyGameDataNotLog("GubaoStar", gubaoID, star + 1):
        GameWorld.DebugLog("古宝已满星! gubaoID=%s,star=%s" % (gubaoID, star), playerID)
    gubaoIpyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not gubaoIpyData:
        return
    quality = gubaoIpyData.GetGubaoQuality()
    selfItemID = gubaoIpyData.GetUnlockItemID()
    
    ipyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
    if not ipyData:
        return
    needItemList = ipyData.GetStarUPNeedItemInfo()
    needQualityPiece = ipyData.GetStarUPNeedQualityPiece()
    if not needItemList and not needQualityPiece:
        return
    lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
    nextStar = star + 1
    
    needPieceInfo, realNeedItemList = ParseGubaoNeedItem(curPlayer, needItemList)
    if realNeedItemList:
    ipyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoStar", quality)
    if not ipyDataList:
        return
    nextIpyData = None
    for ipyData in ipyDataList:
        if ipyData.GetGubaoStar() == nextStar:
            nextIpyData = ipyData
            break
    if not nextIpyData:
        GameWorld.DebugLog("古宝已满星! gubaoID=%s,quality=%s,star=%s" % (gubaoID, quality, star), playerID)
        return
    needSelfCnt = nextIpyData.GetStarUPNeedSelfCnt()
    needItemList = nextIpyData.GetStarUPNeedItemList()
    if needItemList:
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(realNeedItemList, itemPack)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("古宝升星所需物品不足! star=%s,realNeedItemList=%s,lackItemDict=%s" % (star, realNeedItemList, lackItemDict), playerID)
            GameWorld.DebugLog("古宝升星所需物品不足! quality=%s,nextStar=%s,needItemList=%s,lackItemDict=%s" % (quality, nextStar, needItemList, lackItemDict), playerID)
            return
        
    if needQualityPiece:
        commPieceUseLimitInfo = IpyGameDataPY.GetFuncEvalCfg("GubaoPiece", 1, {})
        selectPieceDict = {}
        for pieceUse in curPackData.CommPieceUseList:
            useGubaoID = pieceUse.GubaoID
            usePieceCnt = pieceUse.PieceCount
            useIpyData = IpyGameDataPY.GetIpyGameData("Gubao", useGubaoID)
            if not useIpyData:
                return
            quality = useIpyData.GetGubaoQuality()
            if str(quality) not in commPieceUseLimitInfo:
                GameWorld.DebugLog("该古宝品质没有配置可作为通用碎片使用的最低星级! useGubaoID=%s" % (useGubaoID), playerID)
                return
            needStar = commPieceUseLimitInfo[str(quality)]
            _, usePieceStar = GetGubaoLVInfo(curPlayer, useGubaoID)
            if usePieceStar < needStar:
                GameWorld.DebugLog("该古宝品质星级不足,无法作为通用碎片! useGubaoID=%s,usePieceStar=%s < %s" % (useGubaoID, usePieceStar, needStar), playerID)
                return
            selectPieceDict[quality] = selectPieceDict.get(quality, 0) + usePieceCnt
            needPieceInfo[useGubaoID] = needPieceInfo.get(useGubaoID, 0) + usePieceCnt
        for quality, needCount in needQualityPiece:
            selectCount = selectPieceDict.get(quality, 0)
            if selectCount != needCount: # 需精确匹配个数,多或少都不允许升星,防止多扣或者少扣
                GameWorld.ErrLog("选择使用的品质通用碎片个数不匹配,无法升星!  gubaoID=%s,star=%s,quality=%s,selectCount=%s != %s"
                                 % (gubaoID, star, quality, selectCount, needCount), playerID)
                return
        GameWorld.DebugLog("所需古宝碎片汇总: %s" % needPieceInfo, playerID)
    for costGubaoID, needPieceCount in needPieceInfo.items():
        curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoPiece % costGubaoID)
        if curCount < needPieceCount:
            GameWorld.DebugLog("古宝升星所需古宝碎片不足! gubaoID=%s,costGubaoID=%s,curCount=%s < needPieceCount=%s" % (gubaoID, costGubaoID, curCount, needPieceCount), playerID)
    if needSelfCnt:
        if not ItemControler.CheckItemEnoughByID(curPlayer, selfItemID, needSelfCnt):
            return
        
    #扣消耗
    for costGubaoID, needPieceCount in needPieceInfo.items():
        DelGubaoPiece(curPlayer, costGubaoID, needPieceCount, "StarUp")
    if realNeedItemList:
    if selfItemID and needSelfCnt:
        ItemControler.DelItemCountByID(curPlayer, selfItemID, needSelfCnt)
    if needItemList:
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
        
    updStar = star + 1
    SetGubaoLVInfo(curPlayer, gubaoID, lv, updStar)
    GameWorld.Log("古宝升星: gubaoID=%s,updStar=%s" % (gubaoID, updStar), playerID)
    DoGubaoAddFreePoint(curPlayer, gubaoID)
    updStar = nextStar
    SetGubaoInfo(curPlayer, gubaoID, lv, updStar, layer)
    GameWorld.DebugLog("古宝升星: gubaoID=%s,updStar=%s,needSelfCnt=%s,needItemList=%s" % (gubaoID, updStar, needSelfCnt, needItemList), playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    PlayerActGubao.OnGubaoCost(curPlayer, needPieceInfo, realNeedItemList)
    PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_GubaoStarUp)
    return
def DoGubaoAddFreePoint(curPlayer, gubaoID=0):
    playerID = curPlayer.GetPlayerID()
    effPointDict = {}
    if gubaoID:
        __calcStarEffAddFreePoint(curPlayer, gubaoID, effPointDict)
    else:
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in xrange(ipyDataMgr.GetGubaoCount()):
            ipyData = ipyDataMgr.GetGubaoByIndex(index)
            gubaoID = ipyData.GetGubaoID()
            __calcStarEffAddFreePoint(curPlayer, gubaoID, effPointDict)
    if not effPointDict:
        return
    unAddFreePointTotal = 0
    for effKey, addFreePointTotal in effPointDict.items():
        gubaoID, star, effType = effKey
        # 已增加的点数
        addFreePointAlready = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType))
        unAddFreePoint = max(0, addFreePointTotal - addFreePointAlready)
        unAddFreePointTotal += unAddFreePoint
        GameWorld.DebugLog("古宝星级增加灵根点: gubaoID=%s,star=%s,effType=%s,addFreePointTotal=%s,addFreePointAlready=%s,unAddFreePoint=%s,total=%s"
                           % (gubaoID, star, effType, addFreePointTotal, addFreePointAlready, unAddFreePoint, unAddFreePointTotal), playerID)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType), addFreePointTotal)
        if unAddFreePoint:
            Sync_GubaoItemEffInfo(curPlayer, gubaoID, effType, True)
    if unAddFreePointTotal <= 0:
        return
    freePoint = curPlayer.GetFreePoint()
    updFreePoint = freePoint + unAddFreePointTotal
    curPlayer.SetFreePoint(updFreePoint)
    GameWorld.DebugLog("古宝加点: freePoint=%s,freePoint=%s,freePoint=%s" % (freePoint, unAddFreePointTotal, updFreePoint), playerID)
    return
def __calcStarEffAddFreePoint(curPlayer, gubaoID, effPointDict):
    _, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
        return
    starIpyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
    if not starIpyData:
        return
    starEffIDList = starIpyData.GetStarEffIDList()
    for effID in starEffIDList:
        effIpyData = IpyGameDataPY.GetIpyGameData("GubaoEffAttr", effID)
        if not effIpyData:
            continue
        effType = effIpyData.GetGubaoEffType()
        effCond = effIpyData.GetEffCond()
        effAttrValue = effIpyData.GetEffAttrValue()
        effKey = (gubaoID, star, effType)
        if effType == 54: # 增加x点灵根
            addFreePointTotal = effIpyData.GetEffAttrValue()
            effPointDict[effKey] = effPointDict.get(effKey, 0) + addFreePointTotal
        elif effType == 55: # 境界每级增加X点灵根
            realmLV = curPlayer.GetOfficialRank()
            addFreePointTotal = int(realmLV / effCond * effAttrValue)
            effPointDict[effKey] = effPointDict.get(effKey, 0) + addFreePointTotal
        elif effType == 56: # 等级每级增加X点灵根
            playerLV = curPlayer.GetLV()
            addFreePointTotal = int(playerLV / effCond * effAttrValue)
            effPointDict[effKey] = effPointDict.get(effKey, 0) + addFreePointTotal
    return
#// B2 18 古宝升级 #tagCMGubaoLVUp
#
@@ -351,56 +167,49 @@
    playerID = curPlayer.GetPlayerID()
    gubaoID = curPackData.GubaoID
    
    lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
    if not IsGubaoActivated(curPlayer, gubaoID):
        GameWorld.DebugLog("古宝未激活,无法升级! gubaoID=%s" % gubaoID, playerID)
        return
    
    ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not ipyData:
    gubaoIpyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not gubaoIpyData:
        return
    gubaoType = ipyData.GetGubaoType()
    quality = ipyData.GetGubaoQuality()
    quality = gubaoIpyData.GetGubaoQuality()
    
    if not IpyGameDataPY.GetIpyGameDataNotLog("GubaoLV", gubaoType, quality, lv + 1):
    ipyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoLV", quality)
    if not ipyDataList:
        return
    lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
    nextLV = lv + 1
    nextIpyData = None
    for ipyData in ipyDataList:
        if nextLV <= ipyData.GetLessEqualLV():
            nextIpyData = ipyData
            break
    if not nextIpyData:
        GameWorld.DebugLog("古宝已满级! gubaoID=%s,quality=%s,lv=%s" % (gubaoID, quality, lv), playerID)
        return
    
    lvIpyData = IpyGameDataPY.GetIpyGameData("GubaoLV", gubaoType, quality, lv)
    if not lvIpyData:
        return
    needItemList = lvIpyData.GetLVUPNeedItemInfo()
    if not needItemList:
        return
    needPieceInfo, realNeedItemList = ParseGubaoNeedItem(curPlayer, needItemList)
    if realNeedItemList:
    needItemList = nextIpyData.GetLVUPNeedItemInfo()
    if needItemList:
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(realNeedItemList, itemPack)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("古宝升级所需物品不足! quality=%s,lv=%s,realNeedItemList=%s,lackItemDict=%s"
                               % (quality, lv, realNeedItemList, lackItemDict), playerID)
            return
    for gID, needPieceCount in needPieceInfo.items():
        curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoPiece % gID)
        if curCount < needPieceCount:
            GameWorld.DebugLog("古宝升级所需古宝碎片不足! gubaoID=%s,curCount=%s < needPieceCount=%s" % (gubaoID, curCount, needPieceCount), playerID)
            GameWorld.DebugLog("古宝升级所需物品不足! quality=%s,nextLV=%s,needItemList=%s,lackItemDict=%s"
                               % (quality, nextLV, needItemList, lackItemDict), playerID)
            return
        
    #扣消耗
    for gID, needPieceCount in needPieceInfo.items():
        DelGubaoPiece(curPlayer, gID, needPieceCount, "LVUp")
    if realNeedItemList:
    if needItemList:
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
    updLV = nextLV
    SetGubaoInfo(curPlayer, gubaoID, updLV, star, layer)
    GameWorld.DebugLog("古宝升级: gubaoID=%s,quality=%s,updLV=%s,needItemList=%s" % (gubaoID, quality, updLV, needItemList), playerID)
    
    updLV = lv + 1
    SetGubaoLVInfo(curPlayer, gubaoID, updLV, star)
    GameWorld.Log("古宝升级: gubaoID=%s,gubaoType=%s,quality=%s,updLV=%s" % (gubaoID, gubaoType, quality, updLV), playerID)
    RefreshGubaoAttr(curPlayer)
    Sync_GubaoInfo(curPlayer, [gubaoID])
    PlayerActGubao.OnGubaoCost(curPlayer, needPieceInfo, realNeedItemList)
    PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_GubaoLVUp)
    return
def GetGubaoTotalLVStar(curPlayer):
@@ -410,56 +219,73 @@
    for index in xrange(ipyDataMgr.GetGubaoCount()):
        ipyData = ipyDataMgr.GetGubaoByIndex(index)
        gubaoID = ipyData.GetGubaoID()
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        lv, star, _ = GetGubaoInfo(curPlayer, gubaoID)
        totalLV += lv
        totalStar += star
    return totalLV, totalStar
def RefreshGubaoAttr(curPlayer):
    #CalcGubaoAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
def CalcGubaoAttr(curPlayer):
    allAttrList = [{} for _ in range(4)]
    allAttrListResonance = [{} for _ in range(4)]
def GetGubaoTotalCnt(curPlayer, checkCnt=0):
    ## 获取古宝激活总数
    # @param checkCnt: 可指定需要验证的所需个数,当达到该个数时直接返回该个数
    totalCount = 0
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetGubaoCount()):
        ipyData = ipyDataMgr.GetGubaoByIndex(index)
        gubaoID = ipyData.GetGubaoID()
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not star:
        if not IsGubaoActivated(curPlayer, gubaoID):
            continue
        totalCount += 1
        if checkCnt and totalCount >= checkCnt:
            break
    return totalCount
def RefreshGubaoAttr(curPlayer):
    CalcGubaoAttr(curPlayer)
    PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
    return
def CalcGubaoAttr(curPlayer):
    playerID = curPlayer.GetPlayerID()
    attrDict = {}
    gubaoStarDict = {}
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetGubaoCount()):
        ipyData = ipyDataMgr.GetGubaoByIndex(index)
        gubaoID = ipyData.GetGubaoID()
        if not IsGubaoActivated(curPlayer, gubaoID):
            continue
        
        gubaoType = ipyData.GetGubaoType()
        quality = ipyData.GetGubaoQuality()
        lvIpyData = IpyGameDataPY.GetIpyGameData("GubaoLV", gubaoType, quality, lv)
        if lvIpyData:
            lvAttrTypeList = lvIpyData.GetLVAttrTypeList()
            lvAttrValueList = lvIpyData.GetLVAttrValueList()
            for i, attrID in enumerate(lvAttrTypeList):
                attrValue = lvAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        starIpyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
        if starIpyData:
            starAttrIDList = starIpyData.GetStarAttrIDList()
            starAttrValueList = starIpyData.GetStarAttrValueList()
            for i, attrID in enumerate(starAttrIDList):
                attrValue = starAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
            starEffIDList = starIpyData.GetStarEffIDList()
            effAttrInfo = {}
            #GameWorld.DebugLog("GubaoStar属性: gubaoID=%s,star=%s,starEffIDList=%s" % (gubaoID, star, starEffIDList))
            for effID in starEffIDList:
                __calcStarEffAttrByID(curPlayer, gubaoID, effID, effAttrInfo)
                #GameWorld.DebugLog("    effID=%s,effAttrInfo=%s" % (effID, effAttrInfo))
            for attrID, attrValue in effAttrInfo.items():
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
        gubaoStarDict[gubaoID] = star
        # 基础属性
        BaseAttrIDList = ipyData.GetBaseAttrIDList()
        BaseAttrValueList = ipyData.GetBaseAttrValueList()
        BaseAttrPerStarAddList = ipyData.GetBaseAttrPerStarAddList()
        for bIndex, attrID in enumerate(BaseAttrIDList):
            baseValue = BaseAttrValueList[bIndex]
            perStarAdd = BaseAttrPerStarAddList[bIndex]
            attrValue = baseValue + perStarAdd * star
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
        GameWorld.DebugLog("古宝基础属性! gubaoID=%s,star=%s,addAttr=%s,v:%s,perStar:%s,%s"
                           % (gubaoID, star, BaseAttrIDList, BaseAttrValueList, BaseAttrPerStarAddList, attrDict), playerID)
        # 特殊属性
        attrID = ipyData.GetSpecAttrID()
        effType = ipyData.GetSpecEffType()
        SpecAttrValue = ipyData.GetSpecAttrValue()
        SpecAttrPerLVAdd = ipyData.GetSpecAttrPerLVAdd()
        SpecAttrPerStarAdd = ipyData.GetSpecAttrPerStarAdd()
        attrValue = SpecAttrValue + SpecAttrPerLVAdd *  max(lv - 1, 0) + SpecAttrPerStarAdd * star
        if effType: # 有特殊效果类型的
            attrValue *= layer
        attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
        GameWorld.DebugLog("古宝特殊属性! gubaoID=%s,lv=%s,star=%s,effType=%s,layer=%s,attrID=%s,v=%s,perLV=%s,perStar=%s,attrValue=%s,%s"
                           % (gubaoID, lv, star, effType, layer, attrID, SpecAttrValue, SpecAttrPerLVAdd, SpecAttrPerStarAdd, attrValue, attrDict), playerID)
    # 共鸣
    for index in range(ipyDataMgr.GetGubaoResonanceCount()):
        ipyData = ipyDataMgr.GetGubaoResonanceByIndex(index)
@@ -467,15 +293,8 @@
        gubaoIDList = ipyData.GetGubaoIDList()
        if not gubaoIDList:
            continue
        gubaoStarDict = {}
        for gubaoID in gubaoIDList:
            _, star = GetGubaoLVInfo(curPlayer, gubaoID)
            gubaoStarDict[gubaoID] = star
        minStar = min(gubaoStarDict.values()) # 共鸣星级,取组合中最低古宝星级
        if not minStar:
            #GameWorld.DebugLog("共鸣组合存在古宝未激活! resonanceID=%s,gubaoStarDict=%s" % (resonanceID, gubaoStarDict))
            continue
        starList = [gubaoStarDict.get(gubaoID, 0) for gubaoID in gubaoIDList]
        minStar = min(starList) # 共鸣星级,取组合中最低古宝星级
        
        attrIpyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoResonanceAttr", resonanceID)
        if not attrIpyDataList:
@@ -489,480 +308,114 @@
            resonanceAttrIpyData = attrIpyData
            
        if not resonanceAttrIpyData:
            #GameWorld.DebugLog("没有古宝共鸣属性! resonanceID=%s,minStar=%s" % (resonanceID, minStar))
            GameWorld.DebugLog("没有古宝共鸣属性! resonanceID=%s,minStar=%s,starList=%s" % (resonanceID, minStar, starList), playerID)
            continue
        
        #GameWorld.DebugLog("古宝共鸣: resonanceID=%s,resonanceStar=%s,gubaoStarDict=%s" % (resonanceID, resonanceAttrIpyData.GetResonanceStar(), gubaoStarDict))
        resonanceAttrIDList = resonanceAttrIpyData.GetResonanceAttrIDList()
        resonanceAttrValueList = resonanceAttrIpyData.GetResonanceAttrValueList()
        for i, attrID in enumerate(resonanceAttrIDList):
            attrValue = resonanceAttrValueList[i]
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListResonance)
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
        GameWorld.DebugLog("古宝共鸣: resonanceID=%s,resonanceStar=%s,starList=%s,addAttr=%s,%s,%s"
                           % (resonanceID, resonanceAttrIpyData.GetResonanceStar(), starList,
                              resonanceAttrIDList, resonanceAttrValueList, attrDict), playerID)
    # 保存计算值
    #GameWorld.DebugLog("古宝属性: %s" % allAttrList)
    #GameWorld.DebugLog("古宝共鸣属性: %s" % allAttrListResonance)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Gubao, allAttrList)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_GubaoResonance, allAttrListResonance)
    GameWorld.DebugLog("古宝属性: %s" % attrDict, playerID)
    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_Gubao, attrDict)
    return
def __calcStarEffAttrByID(curPlayer, gubaoID, effID, effAttrInfo):
    ''' 计算古宝特殊效果ID对应提升属性
    '''
    ipyData = IpyGameDataPY.GetIpyGameData("GubaoEffAttr", effID)
    if not ipyData:
        return
    effType = ipyData.GetGubaoEffType()
    effCond = ipyData.GetEffCond()
    effCond2 = ipyData.GetEffCond2()
    effCond3 = ipyData.GetEffCond3()
    attrID = ipyData.GetEffAttrID()
    effAttrValue = ipyData.GetEffAttrValue()
    if effAttrValue <= 0:
        return
    #效果类型    类型说明                                                    条件
    # 10    x品质灵宠攻击属性提升x%      x品质
    if effType == 10:
        customAttrDictPet = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Pet)[2]
        petQualityAttrInfo = customAttrDictPet.get("petQualityAttrInfo", {})
        quality = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,quality=%s,petQualityAttrInfo=%s" % (effID, effType, quality, petQualityAttrInfo))
        if quality not in petQualityAttrInfo:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, petQualityAttrInfo[quality], effAttrValue)
    # 11    灵宠总等级每x级+xx属性                   x级
    elif effType == 11:
        totalPetLV = PlayerPet.GetTotalPetLV(curPlayer)
        addAttrValue = int(totalPetLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,totalPetLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, totalPetLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    # 12    灵宠每激活x只+xx属性                        x只
    elif effType == 12:
        totalPetCount = PlayerPet.GetTotalPetCount(curPlayer)
        addAttrValue = int(totalPetCount / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,totalPetCount=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, totalPetCount, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    # 13    x品质坐骑幻化属性提升x%      x品质
    elif effType == 13:
        customAttrDictSkin = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin)[2]
        horseSkinQualityAttrInfo = customAttrDictSkin.get("horseSkinQualityAttrInfo", {})
        quality = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,quality=%s,horseSkinQualityAttrInfo=%s" % (effID, effType, quality, horseSkinQualityAttrInfo))
        if quality not in horseSkinQualityAttrInfo:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, horseSkinQualityAttrInfo[quality], effAttrValue)
    # 14    坐骑幻化激活x只+xx属性                   x只
    elif effType == 14:
        horseSkinActCount = PlayerHorse.GetHorseSkinActCount(curPlayer)
        addAttrValue = int(horseSkinActCount / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,horseSkinActCount=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, horseSkinActCount, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    # 15    每培养坐骑x次+xx属性                        x次
    elif effType == 15:
        pass
    #16    x阶装备强化属性提升x%        x阶
    elif effType == 16:
        customAttrDictPlus = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Plus)[2]
        classBaseAttrDictPlus = customAttrDictPlus.get("classBaseAttrDictPlus", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictPlus=%s" % (effID, effType, classLV, classBaseAttrDictPlus))
        if classLV not in classBaseAttrDictPlus:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictPlus[classLV], effAttrValue)
    #17    x阶装备宝石属性提升x%        x阶
    elif effType == 17:
        customAttrDictStone = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Stone)[2]
        classBaseAttrDictStone = customAttrDictStone.get("classBaseAttrDictStone", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictStone=%s" % (effID, effType, classLV, classBaseAttrDictStone))
        if classLV not in classBaseAttrDictStone:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictStone[classLV], effAttrValue)
    #18    x阶装备升星属性提升x%        x阶
    elif effType == 18:
        customAttrDictStar = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Star)[2]
        classBaseAttrDictStar = customAttrDictStar.get("classBaseAttrDictStar", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictStar=%s" % (effID, effType, classLV, classBaseAttrDictStar))
        if classLV not in classBaseAttrDictStar:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictStar[classLV], effAttrValue)
    #19    x阶装备洗炼属性提升x%        x阶
    elif effType == 19:
        customAttrDictWash = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Wash)[2]
        classBaseAttrDictWash = customAttrDictWash.get("classBaseAttrDictWash", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictWash=%s" % (effID, effType, classLV, classBaseAttrDictWash))
        if classLV not in classBaseAttrDictWash:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictWash[classLV], effAttrValue)
    #20    x阶装备附魔属性提升x%        x阶
    elif effType == 20:
        customAttrDictEnchant = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Enchant)[2]
        classBaseAttrDictEnchant = customAttrDictEnchant.get("classBaseAttrDictEnchant", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classBaseAttrDictEnchant=%s" % (effID, effType, classLV, classBaseAttrDictEnchant))
        if classLV not in classBaseAttrDictEnchant:
            return
        __addStarEffFuncAttr(ipyData, effAttrInfo, classBaseAttrDictEnchant[classLV], effAttrValue)
    #21    出战神兽装备强化每x级+xx属性    x级
    elif effType == 21:
        fightDogzTotalPlusLv = PlayerDogz.GetFightDogzTotalPlusLv(curPlayer)
        addAttrValue = int(fightDogzTotalPlusLv / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,fightDogzTotalPlusLv=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, fightDogzTotalPlusLv, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #22    天星塔每通关x层+xx属性                    x层
    elif effType == 22:
        skyTowerFloor = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_SkyTowerFloor)
        addAttrValue = int(skyTowerFloor / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,skyTowerFloor=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, skyTowerFloor, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #23    符印塔每通关x层+xx属性                    x层
    elif effType == 23:
        trialTowerPassLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_TrialTower_PassLV)
        addAttrValue = int(trialTowerPassLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,trialTowerPassLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, trialTowerPassLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #24    符印等级每每x级+xx属性                   x级
    elif effType == 24:
        runeTotalLV = PlayerRune.GetRuneTotalLV(curPlayer)
        addAttrValue = int(runeTotalLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,runeTotalLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, runeTotalLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #25    聚魂等级每每x级+xx属性                   x级
    elif effType == 25:
        soulTotalLV = PlayerGatherSoul.GetGatherSoulTotalLV(curPlayer)
        addAttrValue = int(soulTotalLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,soulTotalLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, soulTotalLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #26    x阶装备强化每x级+xx属性                x阶        x级
    elif effType == 26:
        customAttrDictPlus = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Plus)[2]
        classPlusLVDict = customAttrDictPlus.get("classPlusLVDict", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classPlusLVDict=%s" % (effID, effType, classLV, classPlusLVDict))
        if classLV not in classPlusLVDict:
            return
        totalPlusLV = classPlusLVDict[classLV]
        addAttrValue = int(totalPlusLV / effCond2 * effAttrValue)
        #GameWorld.DebugLog("        effCond=%s,effCond2=%s,totalPlusLV=%s,attrID=%s,addAttrValue=%s" % (effCond, effCond2, totalPlusLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #27    x阶装备宝石每x级+xx属性                x阶        x级
    elif effType == 27:
        customAttrDictStone = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Stone)[2]
        classStoneLVDict = customAttrDictStone.get("classStoneLVDict", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classStoneLVDict=%s" % (effID, effType, classLV, classStoneLVDict))
        if classLV not in classStoneLVDict:
            return
        totalStoneLV = classStoneLVDict[classLV]
        addAttrValue = int(totalStoneLV / effCond2 * effAttrValue)
        #GameWorld.DebugLog("        effCond=%s,effCond2=%s,totalStoneLV=%s,attrID=%s,addAttrValue=%s" % (effCond, effCond2, totalStoneLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #28    x阶装备升星每x星+xx属性                x阶        x星
    elif effType == 28:
        customAttrDictStar = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Star)[2]
        classStarLVDict = customAttrDictStar.get("classStarLVDict", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classStarLVDict=%s" % (effID, effType, classLV, classStarLVDict))
        if classLV not in classStarLVDict:
            return
        totalStarLV = classStarLVDict[classLV]
        addAttrValue = int(totalStarLV / effCond2 * effAttrValue)
        #GameWorld.DebugLog("        effCond=%s,effCond2=%s,totalStarLV=%s,attrID=%s,addAttrValue=%s" % (effCond, effCond2, totalStarLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #29    x阶装备洗练每x级+xx属性                x阶        x级
    elif effType == 29:
        customAttrDictWash = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Wash)[2]
        classWashLVDict = customAttrDictWash.get("classWashLVDict", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classWashLVDict=%s" % (effID, effType, classLV, classWashLVDict))
        if classLV not in classWashLVDict:
            return
        totalWashLV = classWashLVDict[classLV]
        addAttrValue = int(totalWashLV / effCond2 * effAttrValue)
        #GameWorld.DebugLog("        effCond=%s,effCond2=%s,totalWashLV=%s,attrID=%s,addAttrValue=%s" % (effCond, effCond2, totalWashLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #30    x阶装备附魔每x级+xx属性                x阶        x级
    elif effType == 30:
        customAttrDictEnchant = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Enchant)[2]
        classEnchantLVDict = customAttrDictEnchant.get("classEnchantLVDict", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classEnchantLVDict=%s" % (effID, effType, classLV, classEnchantLVDict))
        if classLV not in classEnchantLVDict:
            return
        totalEnchantLV = classEnchantLVDict[classLV]
        addAttrValue = int(totalEnchantLV / effCond2 * effAttrValue)
        #GameWorld.DebugLog("        effCond=%s,effCond2=%s,totalEnchantLV=%s,attrID=%s,addAttrValue=%s" % (effCond, effCond2, totalEnchantLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #31    x阶装备x件x品质装备+xx属性            x阶        x件        x品质
    elif effType == 31:
        customAttrDictEquip = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Equip)[2]
        classEquipColorDict = customAttrDictEquip.get("classEquipColorDict", {})
        classLV = effCond
        #GameWorld.DebugLog("    effID=%s,effType=%s,classLV=%s,classEquipColorDict=%s" % (effID, effType, classLV, classEquipColorDict))
        if classLV not in classEquipColorDict:
            return
        equipColorDict = classEquipColorDict[classLV]
        equipColorCnt = 0
        for itemColor in equipColorDict.values():
            if itemColor >= effCond3:
                equipColorCnt += 1
        addAttrValue = int(equipColorCnt / effCond2 * effAttrValue)
        #GameWorld.DebugLog("        effCond=%s,effCond2=%s,effCond3=%s,equipColorCnt=%s,attrID=%s,addAttrValue=%s" % (effCond, effCond2, effCond3, equipColorCnt, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #32    获得x点灵根点+xx属性                        x点
    elif effType == 32:
        totalLingGenPoint = PlayerControl.GetTotalLingGenPoint(curPlayer)
        addAttrValue = int(totalLingGenPoint / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,totalLingGenPoint=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, totalLingGenPoint, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #41    x类型神兵每X级+X属性    x类型    x级
    elif effType == 41:
        gwType = effCond
        gwLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GodWeaponLV % gwType)
        addAttrValue = int(gwLV / effCond2 * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,gwType=%s,gwLV=%s,effCond2=%s,attrID=%s,addAttrValue=%s" % (effID, effType, gwType, gwLV, effCond2, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #42    法器每X阶+X%法器总属性    x阶
    elif effType == 42:
        customAttrDictFaQi = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_FaQi)[2]
        faQiAllAttrInfo = customAttrDictFaQi.get("faQiAllAttrInfo", {})
        faQiLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaQiLV)
        addPer = int(faQiLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,faQiLV=%s,addPer=%s,faQiAllAttrInfo=%s" % (effID, effType, faQiLV, addPer, faQiAllAttrInfo))
        __addStarEffFuncAttr(ipyData, effAttrInfo, faQiAllAttrInfo, addPer)
    #43    每拥有X个X类型的称号+X属性    x类型    x个
    elif effType == 43:
        activeTypeCountDict = PlayerDienstgrad.GetDienstgradActiveTypeCountInfo(curPlayer)
        dType = effCond
        activeCount = activeTypeCountDict.get(dType, 0)
        addAttrValue = int(activeCount / effCond2 * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,dType=%s,activeTypeCountDict=%s,effCond2=%s,attrID=%s,addAttrValue=%s" % (effID, effType, dType, activeTypeCountDict, effCond2, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #44    X品质时装总星数每X星+X属性    x类型    x星
    elif effType == 44:
        costQualityLVDict = PlayerCoat.GetCoatQualityLVInfo(curPlayer)
        quality = effCond
        lvTotal = costQualityLVDict.get(quality, 0)
        addAttrValue = int(lvTotal / effCond2 * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,quality=%s,costQualityLVDict=%s,effCond2=%s,attrID=%s,addAttrValue=%s" % (effID, effType, quality, costQualityLVDict, effCond2, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #45    每X级魅力等级+X属性    x级
    elif effType == 45:
        charmLV = PlayerControl.GetCharmLV(curPlayer)
        addAttrValue = int(charmLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,charmLV=%s,effCond=%s,attrID=%s,addAttrValue=%s" % (effID, effType, charmLV, effCond, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #46    每拥有X个神通技能+X属性    x个
    elif effType == 46:
        customAttrDictShentong = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Shentong)[2]
        shentongSkillInfo = customAttrDictShentong.get("shentongSkillInfo", {})
        skillCount = len(shentongSkillInfo)
        addAttrValue = int(skillCount / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,skillCount=%s,effCond=%s,attrID=%s,addAttrValue=%s,shentongSkillInfo=%s" % (effID, effType, skillCount, effCond, attrID, addAttrValue, shentongSkillInfo))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #47    神通技能总等级每X级+X属性    x级
    elif effType == 47:
        customAttrDictShentong = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Shentong)[2]
        shentongSkillInfo = customAttrDictShentong.get("shentongSkillInfo", {})
        skillLVTotal = sum(shentongSkillInfo.values())
        addAttrValue = int(skillLVTotal / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,skillLVTotal=%s,effCond=%s,attrID=%s,addAttrValue=%s,shentongSkillInfo=%s" % (effID, effType, skillLVTotal, effCond, attrID, addAttrValue, shentongSkillInfo))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #48    参与仙盟联赛每X次+XXX属性    x次
    #49    参与上古战场每X次+XXX属性    x次
    #50    参与古神战场每X次+XXX属性    x次
    #51    参与魔王入侵每X次+XXX属性    x次
    #52    参与逐鹿万界每X次+XXX属性    x次
    elif effType in GubaoEffAttrIypeList:
        effValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType))
        addAttrValue = int(effValue / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effValue=%s,effCond=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effValue, effCond, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #53    镶嵌x品质聚魂每x个+xx属性    x品质    x个
    elif effType == 53:
        soulColor = effCond
        colorCount = PlayerGatherTheSoul.GetHoleSoulColorCount(curPlayer, soulColor, True)
        addAttrValue = int(colorCount / effCond2 * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,soulColor=%s,colorCount=%s,effCond2=%s,attrID=%s,addAttrValue=%s" % (effID, effType, soulColor, colorCount, effCond2, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #57    坐骑基础属性提升x%
    elif effType == 57:
        customAttrDict = PlayerControl.GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Horse)[2]
        horseBaseAttrInfo = customAttrDict.get("horseBaseAttrInfo", {})
        #GameWorld.DebugLog("    effID=%s,effType=%s,horseBaseAttrInfo=%s,effAttrInfo=%s" % (effID, effType, horseBaseAttrInfo, effAttrInfo))
        __addStarEffFuncAttr(ipyData, effAttrInfo, horseBaseAttrInfo, effAttrValue)
    #58    坐骑每x级+xx属性                   x级
    elif effType == 58:
        horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)
        addAttrValue = int(horseLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,horseLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, horseLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    #59    法器每X阶+xx属性    x阶
    elif effType == 59:
        faQiLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaQiLV)
        addAttrValue = int(faQiLV / effCond * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,effCond=%s,faQiLV=%s,attrID=%s,addAttrValue=%s" % (effID, effType, effCond, faQiLV, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    return
def __addStarEffFuncAttr(ipyData, effAttrInfo, funcAttrInfo, effAttrValue):
    if not funcAttrInfo or effAttrValue <= 0:
        return
    isPer = ipyData.GetIsPer()
    effAttrIDList = ipyData.GetEffFuncAttrIDList() # 提升指定功能属性ID列表
    for attrID, attrValue in funcAttrInfo.items():
        if effAttrIDList and attrID not in effAttrIDList:
            continue
        if isPer:
            addAttrValue = int(attrValue * effAttrValue / 100.0)
        else:
            addAttrValue = effAttrValue
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    return
def AddGubaoItemEffValue(curPlayer, effType, addCnt):
    if effType not in GubaoEffTtemIypeList and effType not in GubaoEffAttrIypeList:
        return
    isAttr = False
def AddGubaoSpecEffLayer(curPlayer, effType, addLayer):
    ## 增加古宝特殊效果属性层级
    gubaoIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetGubaoCount()):
        ipyData = ipyDataMgr.GetGubaoByIndex(index)
        gubaoID = ipyData.GetGubaoID()
        _, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not star:
        if not IsGubaoActivated(curPlayer, gubaoID):
            continue
        starIpyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
        if not starIpyData:
        if effType != ipyData.GetSpecEffType():
            continue
        starEffIDList = starIpyData.GetStarEffIDList()
        for effID in starEffIDList:
            effIpyData = IpyGameDataPY.GetIpyGameData("GubaoEffAttr", effID)
            if not effIpyData:
                continue
            if effType != effIpyData.GetGubaoEffType():
                continue
            effValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType))
            updValue = min(effValue + addCnt, ChConfig.Def_UpperLimit_DWord)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType), updValue)
            GameWorld.DebugLog("更新古宝物品效果类型进度值: gubaoID=%s,effID=%s,effType=%s,effValue=%s,addCnt=%s,updValue=%s"
                               % (gubaoID, effID, effType, effValue, addCnt, updValue), curPlayer.GetPlayerID())
            Sync_GubaoItemEffInfo(curPlayer, gubaoID, effType, True)
            if effType in GubaoEffAttrIypeList:
                isAttr = True
    if isAttr:
        RefreshGubaoAttr(curPlayer)
        layerMax = ipyData.GetSpecEffLayerMax()
        if not layerMax:
            continue
        lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
        if layer >= layerMax:
            continue
        layer = min(layerMax, layer + addLayer)
        SetGubaoInfo(curPlayer, gubaoID, lv, star, layer)
        gubaoIDList.append(gubaoID)
    if not gubaoIDList:
        return
    Sync_GubaoInfo(curPlayer, gubaoIDList)
    RefreshGubaoAttr(curPlayer)
    return
def GetGubaoItemEffAward(curPlayer, gubaoID, effIDStr):
    _, star = GetGubaoLVInfo(curPlayer, gubaoID)
    if not star:
        #GameWorld.DebugLog("古宝物品效果领奖! 没有星级! gubaoID=%s" % (gubaoID), curPlayer.GetPlayerID())
def GetItemGubaoIDDict():
    ## 获取物品碎片对应的古宝ID字典
    ItemGubaoIDDict = IpyGameDataPY.GetConfigEx("ItemGubaoIDDict")
    if not ItemGubaoIDDict:
        ItemGubaoIDDict = {}
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGubaoCount()):
            ipyData = ipyDataMgr.GetGubaoByIndex(index)
            gubaoID = ipyData.GetGubaoID()
            itemID = ipyData.GetUnlockItemID()
            ItemGubaoIDDict[itemID] = gubaoID
        IpyGameDataPY.SetConfigEx("ItemGubaoIDDict", ItemGubaoIDDict)
    return ItemGubaoIDDict
def AutoTransGubaoPiece(curPlayer, itemID):
    ## 自动转化溢出的古宝碎片
    ItemGubaoIDDict = GetItemGubaoIDDict()
    if itemID not in ItemGubaoIDDict:
        return
    starIpyData = IpyGameDataPY.GetIpyGameData("GubaoStar", gubaoID, star)
    if not starIpyData:
    gubaoID = ItemGubaoIDDict[itemID]
    if not IsGubaoActivated(curPlayer, gubaoID):
        return
    starEffIDList = starIpyData.GetStarEffIDList()
    effID = GameWorld.ToIntDef(effIDStr)
    if not effID or effID not in starEffIDList:
        GameWorld.DebugLog("古宝物品效果领奖! 该星级不存在该效果ID! gubaoID=%s,star=%s,effID=%s"
                           % (gubaoID, star, effID), curPlayer.GetPlayerID())
    gubaoIpyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
    if not gubaoIpyData:
        return
    effIpyData = IpyGameDataPY.GetIpyGameData("GubaoEffAttr", effID)
    if not effIpyData:
    if gubaoIpyData.GetUnlockItemID() != itemID:
        return
    effType = effIpyData.GetGubaoEffType()
    if effType not in GubaoEffTtemIypeList:
        GameWorld.DebugLog("古宝物品效果领奖! 非物品效果类型! gubaoID=%s,star=%s,effID=%s,effType=%s"
                           % (gubaoID, star, effID, effType), curPlayer.GetPlayerID())
    quality = gubaoIpyData.GetGubaoQuality()
    starIpyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoStar", quality)
    if not starIpyDataList:
        return
    condValue = effIpyData.GetEffCond()
    awardItemList = effIpyData.GetEffItemAwardList()
    if not condValue or not awardItemList:
    itemCount = ItemControler.GetItemCountByID(curPlayer, itemID)
    if itemCount <= 0:
        return
    effValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType))
    getTimes = effValue / condValue
    if getTimes <= 0:
        GameWorld.DebugLog("古宝物品效果领奖! 未达到领奖条件! gubaoID=%s,star=%s,effID=%s,effType=%s,effValue=%s,condValue=%s"
                           % (gubaoID, star, effID, effType, effValue, condValue), curPlayer.GetPlayerID())
    _, star, _ = GetGubaoInfo(curPlayer, gubaoID)
    needPieceTotal = 0 # 还需碎片个数
    for ipyData in starIpyDataList:
        if star >= ipyData.GetGubaoStar():
            continue
        needSelfCnt = ipyData.GetStarUPNeedSelfCnt() # 升星所需
        if not needSelfCnt:
            continue
        needPieceTotal += needSelfCnt
        if itemCount <= needPieceTotal:
            return
    transPieceCnt = itemCount - needPieceTotal # 溢出数量
    if transPieceCnt <= 0:
        return
    awardItemTotalList = []
    if getTimes > 1:
        for itemID, itemCount, isAuctionItem in awardItemList:
            awardItemTotalList.append([itemID, int(itemCount * getTimes), isAuctionItem])
    else:
        awardItemTotalList = awardItemList
    updValue = effValue % condValue
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType), updValue)
    Sync_GubaoItemEffInfo(curPlayer, gubaoID, effType, True)
    GameWorld.DebugLog("古宝物品效果领奖: gubaoID=%s,star=%s,effID=%s,effType=%s,effValue=%s,condValue=%s,getTimes=%s,updValue=%s,awardItemTotalList=%s"
                       % (gubaoID, star, effID, effType, effValue, condValue, getTimes, updValue, awardItemTotalList), curPlayer.GetPlayerID())
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemTotalList, event=["Gubao", False, {}])
    return
    qualityTransDict = IpyGameDataPY.GetFuncEvalCfg("Gubao", 1, {})
    if str(quality) not in qualityTransDict:
        return
    transItemID, transCount = qualityTransDict[str(quality)]
    transCountTotal = transCount * transPieceCnt
    GameWorld.DebugLog("自动转化古宝溢出碎片! gubaoID=%s,itemID=%s,itemCount=%s,star=%s,needPieceTotal=%s,transPieceCnt=%s,transItemID=%s,transCountTotal=%s"
                       % (gubaoID, itemID, itemCount, star, needPieceTotal, transPieceCnt, transItemID, transCountTotal))
    ItemControler.GivePlayerItemOrMail(curPlayer, [[transItemID, transCountTotal]], isNotifyAward=False)
    ItemControler.SetItemCountByID(curPlayer, itemID, needPieceTotal)
    return transPieceCnt
def Sync_GubaoInfo(curPlayer, gubaoIDList=None):
    if gubaoIDList == None:
@@ -976,85 +429,22 @@
        
    gubaoInfoList = []
    for gubaoID in syncIDList:
        lv, star = GetGubaoLVInfo(curPlayer, gubaoID)
        if not lv and not star and gubaoIDList == None:
        if gubaoIDList == None and not IsGubaoActivated(curPlayer, gubaoID):
            # 没有指定时只同步激活的
            continue
        gubao = ChPyNetSendPack.tagMCGubao()
        lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
        gubao = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCGubao)
        gubao.GubaoID = gubaoID
        gubao.GubaoLV = lv
        gubao.GubaoStar = star
        gubao.EffLayer = layer
        gubaoInfoList.append(gubao)
        
    if not gubaoInfoList:
        return
    
    clientPack = ChPyNetSendPack.tagMCGubaoInfo()
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCGubaoInfo)
    clientPack.GubaoInfoList = gubaoInfoList
    clientPack.Count = len(clientPack.GubaoInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_GubaoItemEffInfo(curPlayer, gubaoID=0, effType=0, force=False):
    syncIDList = []
    if not gubaoID:
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGubaoCount()):
            ipyData = ipyDataMgr.GetGubaoByIndex(index)
            syncIDList.append(ipyData.GetGubaoID())
    else:
        syncIDList = [gubaoID]
    syncEffTypeList = [effType] if effType else NeedGubaoItemEffValueTypeList
    itemEffInfoList = []
    for gubaoID in syncIDList:
        for effType in syncEffTypeList:
            effValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoItemEffValue % (gubaoID, effType))
            if not effValue and not force:
                # 非强制同步情况下只同步有值的
                continue
            eff = ChPyNetSendPack.tagMCGubaoItemEff()
            eff.GubaoID = gubaoID
            eff.EffType = effType
            eff.EffValue = effValue
            itemEffInfoList.append(eff)
    if not itemEffInfoList:
        return
    clientPack = ChPyNetSendPack.tagMCGubaoItemEffInfo()
    clientPack.ItemEffInfoList = itemEffInfoList
    clientPack.Count = len(clientPack.ItemEffInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_GubaoPieceInfo(curPlayer, gubaoIDList=None):
    if gubaoIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGubaoCount()):
            ipyData = ipyDataMgr.GetGubaoByIndex(index)
            syncIDList.append(ipyData.GetGubaoID())
    else:
        syncIDList = gubaoIDList
    pieceInfoList = []
    for gubaoID in syncIDList:
        curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoPiece % gubaoID)
        if not curCount and gubaoIDList == None:
            # 没有指定时只同步有数量的
            continue
        gubao = ChPyNetSendPack.tagMCGubaoPiece()
        gubao.GubaoID = gubaoID
        gubao.PieceCount = curCount
        pieceInfoList.append(gubao)
    if not pieceInfoList:
        return
    clientPack = ChPyNetSendPack.tagMCGubaoPieceInfo()
    clientPack.PieceInfoList = pieceInfoList
    clientPack.Count = len(clientPack.PieceInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return