8392 【主干】【后端】宝石镶嵌优化(支持使用低等级宝石做为材料升级)
3个文件已修改
152 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStone.py 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStone.py
@@ -31,6 +31,7 @@
import PlayerWeekParty
import ShareDefine
import EventShell
import PyGameData
g_stoneCanPlaceList = []  # 可镶嵌的位置
@@ -354,7 +355,7 @@
    # 验证背包类型合法性
    equipPackIndex = clientData.EquipIndex
    holeIndex = clientData.HoleIndex
    upWay = clientData.UpWay
    #upWay = clientData.UpWay
    GameWorld.DebugLog("宝石升级: equipPackIndex=%s,holeIndex=%s" % (equipPackIndex, holeIndex), playerID)
    equipPackType, stonePackType, placeIndex = GetPackTypeByEquipPlace(equipPackIndex)
    # 获得装备位装备实例
@@ -379,75 +380,114 @@
                      % (holeIndex, stoneItemID, curEffID), playerID)
        return
    stoneEffType = curStoneEff.GetEffectValue(0)
    level = curStoneEff.GetEffectValue(1)
    stoneLevel = curStoneEff.GetEffectValue(1)
    upgradeStoneID = curStoneEff.GetEffectValue(2)
    upgradeStoneLV = stoneLevel + 1
    GameWorld.DebugLog("stoneEffType=%s,level=%s,upgradeStoneID=%s" % (stoneEffType, level, upgradeStoneID))
    GameWorld.DebugLog("stoneEffType=%s,stoneLevel=%s,upgradeStoneID=%s,upgradeStoneLV=%s" % (stoneEffType, stoneLevel, upgradeStoneID, upgradeStoneLV))
    if not upgradeStoneID:
        GameWorld.Log("该宝石已是最大级,不能升级!stoneIndex=%s,stoneItemID=%s,curEffID=%s,upgradeStoneID=%s"
                      % (holeIndex, stoneItemID, curEffID, upgradeStoneID), playerID)
        return
    needCount = IpyGameDataPY.GetFuncCfg("GemUpCostFormula", 2)  # 合成下一级所需宝石个数
    if not needCount:
    upNeedCount = IpyGameDataPY.GetFuncCfg("GemUpCostFormula", 2)  # 合成下一级所需宝石个数
    if not upNeedCount:
        return
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition('EquipPlaceIndexMap', {'GridIndex': equipPackIndex})
    if not ipyData:
        return
    # 额外材料
    extraItemInfoDict = IpyGameDataPY.GetFuncEvalCfg("GemUpCostFormula", 3, {})
    classLV = ipyData.GetClassLV()
    if upWay == 0:  # 仙玉
        stoneTypeItemIDDict = IpyGameDataPY.GetFuncEvalCfg("GemUpCostFormula", 1)
        if stoneEffType not in stoneTypeItemIDDict:
    extraItemInfoDict = IpyGameDataPY.GetFuncEvalCfg("GemUpCostFormula", 3, {}) # 额外材料
    itemPack = curPlayer.GetItemManager().GetPack(stonePackType)
    delItemListDict = {} # 实际扣除用
    exItemNeedCountDict = {} # 所需额外材料总数
    delItemCountDict, buyItemCountDict = {}, {} # 统计用
    delExItemCountDict, buyExItemCountDict = {}, {} # 统计用
    # 优先消耗高级宝石,从升级目标等级开始向下遍历到2级
    tagLVStoneLackCount = 1 # 可理解为最终要合成1个升级目标等级宝石
    for tagLevel in xrange(upgradeStoneLV, 1, -1):
        needStoneLV = tagLevel - 1
        key = (stoneEffType, needStoneLV)
        if key not in PyGameData.g_stoneLevelIDDict:
            GameWorld.ErrLog("找不到宝石类型等级物品ID! stoneEffType=%s, needStoneLV=%s" % (stoneEffType, needStoneLV))
            return
        stoneTypeItemID = stoneTypeItemIDDict[stoneEffType]
        unitPrice = ItemCommon.GetShopItemPrice(stoneTypeItemID, IPY_GameWorld.TYPE_Price_Gold_Money)
        if not unitPrice:
            return
        costCount = pow(needCount, level - 1) * (needCount - 1)
        costGold = costCount * unitPrice
        # 额外材料
        costExtraItemDict = {}
        i, cnt =0, 1
        for lv in xrange(level+1, 1, -1):
            cnt =1 if i is 0 else pow(needCount, i-1)
            i+=1
            extraItemInfo = extraItemInfoDict.get(str(lv))
        needStoneID = PyGameData.g_stoneLevelIDDict[key]
        needStoneCount = tagLVStoneLackCount * upNeedCount # 上一个等级宝石缺少数 * 升级宝石数目
        if needStoneID == stoneID:
            needStoneCount = upNeedCount - 1 # 已镶嵌宝石自身可做为1个材料
        GameWorld.DebugLog("    tagLevel=%s,tagLVStoneLackCount=%s,needStoneID=%s,needStoneCount=%s" % (tagLevel, tagLVStoneLackCount, needStoneID, needStoneCount))
        # 额外材料统计,使用合成目标等级所需数据;额外材料无法通过迭代升级得到,直接先统计数量,后面在验证扣除数及不足数
        extraItemInfo = extraItemInfoDict.get(str(tagLevel))
            if extraItemInfo:
                extraItemID, extraItemCnt = extraItemInfo
                extraItemPrice = ItemCommon.GetShopItemPrice(extraItemID, IPY_GameWorld.TYPE_Price_Gold_Money)
                if not extraItemPrice:
                    return
                costGold += extraItemPrice * extraItemCnt * cnt
                costExtraItemDict[extraItemID] = costExtraItemDict.get(extraItemID, 0) + extraItemCnt * cnt
        if costGold <= 0:
            return
        infoDict = {"StoneItemID": stoneItemID, "CurStoneIDLV": level, "UpgradeStoneID": upgradeStoneID,
                    "CostCount": costCount, "UnitPrice": unitPrice, 'costExtraItemDict':costExtraItemDict}
            extraItemNeedCount = extraItemCnt * tagLVStoneLackCount
            exItemNeedCountDict[extraItemID] = exItemNeedCountDict.get(extraItemID, 0) + extraItemNeedCount # 额外材料ID可能重复,做累加
            GameWorld.DebugLog("        额外材料: extraItemID=%s,extraItemNeedCount=%s, %s" % (extraItemID, extraItemNeedCount, exItemNeedCountDict))
        if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold,
        # 等级宝石统计,每级宝石ID一定不一样,所以不需要统计已经计入需要扣除的
        hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(needStoneID, itemPack, needStoneCount)
        delCount = needStoneCount - lackCnt
        GameWorld.DebugLog("        宝石材料: needStoneID=%s,delCount=%s,lackCnt=%s" % (needStoneID, delCount, lackCnt))
        if delCount > 0:
            delItemListDict[needStoneID] = [indexList, delCount]
            delItemCountDict[needStoneID] = delCount
        if lackCnt > 0:
            # 所需为1级宝石还缺,直接商城购买
            if needStoneLV == 1:
                buyItemCountDict[needStoneID] = lackCnt
                break
            else:
                tagLVStoneLackCount = lackCnt # 更新下一等级宝石缺少个数
        else:
            # 基础宝石材料不缺了直接退出
            break
    # 购买消耗统计
    costGold = 0
    for buyItemID, buyCount in buyItemCountDict.items():
        unitPrice = ItemCommon.GetShopItemPrice(buyItemID, IPY_GameWorld.TYPE_Price_Gold_Money)
        if not unitPrice:
            return
        costGold += unitPrice * buyCount
        GameWorld.DebugLog("    购买不足宝石: buyItemID=%s,buyCount=%s,unitPrice=%s,costGold=%s" % (buyItemID, buyCount, unitPrice, costGold))
    for extraItemID, exNeedCount in exItemNeedCountDict.items():
        exHasEnough, exIndexList, findItemIsBind, exLackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(extraItemID, itemPack, exNeedCount)
        exDelCount = exNeedCount - exLackCnt
        if exDelCount > 0:
            delItemListDict[extraItemID] = [exIndexList, exDelCount]
            delExItemCountDict[extraItemID] = exDelCount
        if exLackCnt > 0:
            unitPrice = ItemCommon.GetShopItemPrice(extraItemID, IPY_GameWorld.TYPE_Price_Gold_Money)
            if not unitPrice:
                return
            costGold += unitPrice * exLackCnt
            buyExItemCountDict[extraItemID] = exLackCnt
            GameWorld.DebugLog("    购买额外材料: extraItemID=%s,exNeedCount=%s,exDelCount=%s,exLackCnt=%s,unitPrice=%s,costGold=%s"
                               % (extraItemID, exNeedCount, exDelCount, exLackCnt, unitPrice, costGold))
    infoDict = {"EquipPackIndex": equipPackIndex, "HoleIndex": holeIndex, "ClassLV":classLV,
                "StoneItemID": stoneItemID, "CurStoneIDLV": stoneLevel, "UpgradeStoneID": upgradeStoneID,
                "BuyItemCountDict": buyItemCountDict, "DelItemCountDict": delItemCountDict,
                "BuyExItemCountDict": buyExItemCountDict, "DelExItemCountDict": delExItemCountDict,
                }
    GameWorld.DebugLog("delItemCountDict=%s,buyItemCountDict=%s" % (delItemCountDict, buyItemCountDict))
    GameWorld.DebugLog("delExItemCountDict=%s,buyExItemCountDict=%s" % (delExItemCountDict, buyExItemCountDict))
    if costGold and not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold,
                                      ChConfig.Def_Cost_EquipStone, infoDict):
            GameWorld.DebugLog("仙玉不足!costGold=%s" % costGold)
            return
    else:
        costItemDict = {stoneItemID:needCount - 1}
        if str(level + 1) in extraItemInfoDict:
            extraItemID, extraItemCnt = extraItemInfoDict[str(level + 1)]
            costItemDict[extraItemID] = extraItemCnt
        itemPack = curPlayer.GetItemManager().GetPack(stonePackType)
        delItemList = []
        for itemID, itemCnt in costItemDict.items():
            hasEnough, itemIndexList = ItemCommon.GetItem_FromPack_ByID(itemID, itemPack, itemCnt)
            if not hasEnough:
                GameWorld.DebugLog("材料不足 itemID=%s!,needCnt=%s" % (itemID, itemCnt))
                return
            delItemList.append([itemIndexList, itemCnt])
        for delItemIndexList, delCnt in delItemList:
            ItemCommon.ReduceItem(curPlayer, itemPack, delItemIndexList, delCnt, False,
                                  ChConfig.ItemDel_StoneUpgrade,
                                  {"equipPackIndex": equipPackIndex, "HoleIndex": holeIndex})
    for delItemIndexList, delCnt in delItemListDict.values():
        ItemCommon.ReduceItem(curPlayer, itemPack, delItemIndexList, delCnt, False,
                              ChConfig.ItemDel_StoneUpgrade, infoDict)
    __DoChangeEquipHoleStone(curPlayer, equipPackIndex, holeIndex, upgradeStoneID, False, "StoneUpgrade", False)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
@@ -64,8 +64,17 @@
    gameData = GameWorld.GetGameData()
    for i in range(0, gameData.GetItemCount()):
        findItemData = gameData.GetItemAt(i)
        itemID = findItemData.GetItemTypeID()
        if GetCanUseCountDaily(findItemData):
            PyGameData.DailyUseCountLimitItemIDList.append(findItemData.GetItemTypeID())
            PyGameData.DailyUseCountLimitItemIDList.append(itemID)
        itemEff = findItemData.GetEffectByIndex(0)
        curEffID = itemEff.GetEffectID()
        if curEffID == ChConfig.Def_Effect_EquipStone:
            stoneEffType = itemEff.GetEffectValue(0)
            stoneLevel = itemEff.GetEffectValue(1)
            PyGameData.g_stoneLevelIDDict[(stoneEffType, stoneLevel)] = itemID
    if PyGameData.DailyUseCountLimitItemIDList:
        GameWorld.Log("每日有使用次数限制的物品ID列表: %s" % PyGameData.DailyUseCountLimitItemIDList)
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -20,6 +20,7 @@
InitPyItem = False # 是否加载过物品表所需要的Py数据, 每张地图只在启动时执行一次
DailyUseCountLimitItemIDList = [] # 每日有使用个数限制的物品ID列表
g_stoneLevelIDDict = {} # 宝石类型等级对应物品ID {(stoneEffType, stoneLevel):itemID, ...}
g_refreshAttrBillboardFunc = [] # 刷属性后需要触发的同步排行榜函数列表
g_playerFuncAttrDict = {} # 玩家功能点属性 {playerID:{funcIndex:属性列表, ...}, ...}