From e30efe2e7a2b42393cdd64c14363fd1c36586c5a Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期日, 01 三月 2020 22:43:59 +0800
Subject: [PATCH] 8392 【主干】【后端】宝石镶嵌优化(支持使用低等级宝石做为材料升级)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStone.py |  154 ++++++++++++++++++++++++++++++++-------------------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py           |   11 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                        |    1 
 3 files changed, 108 insertions(+), 58 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStone.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStone.py
index 893f4fb..3a6faf5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStone.py
+++ b/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,76 +380,115 @@
                       % (holeIndex, stoneItemID, curEffID), playerID)
         return
     stoneEffType = curStoneEff.GetEffectValue(0)
-    level = curStoneEff.GetEffectValue(1)
+    stoneLevel = curStoneEff.GetEffectValue(1)
     upgradeStoneID = curStoneEff.GetEffectValue(2)
-
-    GameWorld.DebugLog("stoneEffType=%s,level=%s,upgradeStoneID=%s" % (stoneEffType, level, upgradeStoneID))
-
+    upgradeStoneLV = stoneLevel + 1
+    
+    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)
+        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
+            extraItemNeedCount = extraItemCnt * tagLVStoneLackCount
+            exItemNeedCountDict[extraItemID] = exItemNeedCountDict.get(extraItemID, 0) + extraItemNeedCount # 额外材料ID可能重复,做累加
+            GameWorld.DebugLog("        额外材料: extraItemID=%s,extraItemNeedCount=%s, %s" % (extraItemID, extraItemNeedCount, exItemNeedCountDict))
+            
+        # 等级宝石统计,每级宝石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
-        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))
-            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}
-
-        if 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))
+        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
-            delItemList.append([itemIndexList, itemCnt])
-        for delItemIndexList, delCnt in delItemList:
-            ItemCommon.ReduceItem(curPlayer, itemPack, delItemIndexList, delCnt, False,
-                                  ChConfig.ItemDel_StoneUpgrade,
-                                  {"equipPackIndex": equipPackIndex, "HoleIndex": holeIndex})
-
-
+            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
+    
+    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)
 
     # 刷新属性
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
index 5d07b0a..28c4c1a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
+++ b/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)
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index f1c16f7..e288d29 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/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:属性列表, ...}, ...}

--
Gitblit v1.8.0