From ea1ec0723d36ee1f493505ccdb81906bd009b27e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 29 十月 2019 16:57:41 +0800
Subject: [PATCH] 8315 【恺英】【后端】一键自动购买材料及拍品满概率升星

---
 ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py                                         |   35 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py |  230 +++++++++++++-------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py          |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                      |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                  |   68 ++++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                           |   11 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                       |   68 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAuctionHouse.py        |    4 
 PySysDB/PySysDBG.h                                                                                      |   13 +
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py                           |  208 ++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                         |    5 
 11 files changed, 559 insertions(+), 96 deletions(-)

diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index 4a29f46..b52dd3c 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -659,6 +659,19 @@
 	WORD		LVLimit;	//限制等级
 };
 
+//装备升星表
+
+struct tagEquipStarUp
+{
+	BYTE		_ClassLV;	//阶级
+	BYTE		_EquipPlace;	//装备位
+	BYTE		_Star;	//星数
+	list		CostEquipPlace;	//可用装备部位
+	BYTE		IsJobLimit;	//是否只用本职业装备材料
+	list		CostEquipColor;	//可用装备品质
+	BYTE		UnSuitRate;	//单件非套装加成概率
+};
+
 //仙盟联赛排名奖励表
 
 struct tagFamilyWarRankAward
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 81617d5..4049f76 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -9290,6 +9290,7 @@
     CostEquipCnt = 0    #(BYTE CostEquipCnt)// 装备个数
     CostEquipIndex = list()    #(vector<WORD> CostEquipIndex)// 装备索引
     CostEquipID = list()    #(vector<DWORD> CostEquipID)// 装备物品ID
+    AutoBuy = 0    #(BYTE AutoBuy)// 自动购买 0-不自动购买,1-自动购买并升星,2-自动购买预览(未满概率时预览消耗时使用)
     data = None
 
     def __init__(self):
@@ -9309,6 +9310,7 @@
         for i in range(self.CostEquipCnt):
             value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
             self.CostEquipID.append(value)
+        self.AutoBuy,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         return _pos
 
     def Clear(self):
@@ -9320,6 +9322,7 @@
         self.CostEquipCnt = 0
         self.CostEquipIndex = list()
         self.CostEquipID = list()
+        self.AutoBuy = 0
         return
 
     def GetLength(self):
@@ -9329,6 +9332,7 @@
         length += 1
         length += 2 * self.CostEquipCnt
         length += 4 * self.CostEquipCnt
+        length += 1
 
         return length
 
@@ -9341,6 +9345,7 @@
             data = CommFunc.WriteWORD(data, self.CostEquipIndex[i])
         for i in range(self.CostEquipCnt):
             data = CommFunc.WriteDWORD(data, self.CostEquipID[i])
+        data = CommFunc.WriteBYTE(data, self.AutoBuy)
         return data
 
     def OutputString(self):
@@ -9349,14 +9354,16 @@
                                 EquipPackIndex:%d,
                                 CostEquipCnt:%d,
                                 CostEquipIndex:%s,
-                                CostEquipID:%s
+                                CostEquipID:%s,
+                                AutoBuy:%d
                                 '''\
                                 %(
                                 self.Head.OutputString(),
                                 self.EquipPackIndex,
                                 self.CostEquipCnt,
                                 "...",
-                                "..."
+                                "...",
+                                self.AutoBuy
                                 )
         return DumpString
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index b994baa..b2eec9c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -7789,6 +7789,74 @@
 
 
 #------------------------------------------------------
+# B5 11 部位升星自动购买拍品消耗信息 #tagGCEquipStarAutoBuyCostInfo
+
+class  tagGCEquipStarAutoBuyCostInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ClassLV", c_ubyte),    # 当前要升星的境界阶
+                  ("EquipPlace", c_ubyte),    #当前要升星的装备位
+                  ("CurStar", c_ubyte),    #当前星级
+                  ("CurRate", c_ubyte),    #当前自动购买后的总概率,不满100则代表拍品库存不足
+                  ("AutoBuyCostMoney", c_ushort),    #自动购买所需总消耗
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB5
+        self.SubCmd = 0x11
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB5
+        self.SubCmd = 0x11
+        self.ClassLV = 0
+        self.EquipPlace = 0
+        self.CurStar = 0
+        self.CurRate = 0
+        self.AutoBuyCostMoney = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCEquipStarAutoBuyCostInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B5 11 部位升星自动购买拍品消耗信息 //tagGCEquipStarAutoBuyCostInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ClassLV:%d,
+                                EquipPlace:%d,
+                                CurStar:%d,
+                                CurRate:%d,
+                                AutoBuyCostMoney:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ClassLV,
+                                self.EquipPlace,
+                                self.CurStar,
+                                self.CurRate,
+                                self.AutoBuyCostMoney
+                                )
+        return DumpString
+
+
+m_NAtagGCEquipStarAutoBuyCostInfo=tagGCEquipStarAutoBuyCostInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCEquipStarAutoBuyCostInfo.Cmd,m_NAtagGCEquipStarAutoBuyCostInfo.SubCmd))] = m_NAtagGCEquipStarAutoBuyCostInfo
+
+
+#------------------------------------------------------
 # B5 05 拍卖行仙盟拍卖中的物品信息 #tagGCFamilyAuctionItemInfo
 
 class  tagGCFamilyAuctionItem(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
index c1a2563..f668b8b 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
@@ -20,6 +20,7 @@
 import DataRecordPack
 import PyGameDataStruct
 import PlayerCompensation
+import IPY_PlayerDefine
 import ChPyNetSendPack
 import PlayerDBGSEvent
 import IpyGameDataPY
@@ -869,7 +870,7 @@
         auctionItemMgr.sysBuyoutItemByTimeList.sort(key=operator.attrgetter("SysBuyTime"))
     return
 
-def __EndAuctionItem(endItemList, endEvent):
+def __EndAuctionItem(endItemList, endEvent, funcAutoBuyout=False):
     ''' 结束拍品竞拍
     @param delItemStateDict: 删除的拍品竞拍状态
     '''
@@ -896,10 +897,14 @@
             
             # 竞拍成功邮件,发放物品
             if bidderID:
-                paramList = [bidderPrice]
-                detail = {"ItemGUID":itemGUID}
-                addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
-                PlayerCompensation.SendMailByKey("PaimaiMail3", [bidderID], addItemList, paramList, detail=detail)
+                if funcAutoBuyout:
+                    # 功能自动购买的不给物品,由功能根据功能需求处理
+                    pass
+                else:
+                    paramList = [bidderPrice]
+                    detail = {"ItemGUID":itemGUID}
+                    addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
+                    PlayerCompensation.SendMailByKey("PaimaiMail3", [bidderID], addItemList, paramList, detail=detail)
                 AddAuctionRecord(auctionItem, AuctionRecordResult_BidOK)
             
             # 拍卖成功收益,都以玩家收益向上取整
@@ -1086,6 +1091,13 @@
         itemGUID = queryData[0]
         __DoUnsellAuctionItem(curPlayer, itemGUID)
         return
+        
+    # 升星自动购买
+    elif queryType == "EquipStarAutoBuy":
+        buyResult = __DoEquipStarAutoBuyEquip(curPlayer, queryData,  tick)
+        if buyResult == None:
+            return
+        result = buyResult
         
     elif queryType == "ClearAuctionItem":
         __DoGMClearAuctionItem(curPlayer)
@@ -1275,12 +1287,13 @@
     __EndAuctionItem([auctionItem], "Unsell")
     return
 
-def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, isOnlyCheck):
+def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, isOnlyCheck, funcAutoBuyout=False):
     ''' 玩家竞价物品
     @param curPlayer: 竞价的玩家
     @param itemGUID: 拍品GUID
     @param biddingPrice: 竞价
     @param isOnlyCheck: 是否仅检查可否竞价
+    @param funcAutoBuyout: 是否功能自动购买
     '''
     
     errInfo = ""
@@ -1341,7 +1354,7 @@
         auctionItem.BiddingQueryTick = tick
         return itemID, errInfo
     
-    if auctionItem.BiddingQueryID != playerID:
+    if not funcAutoBuyout and auctionItem.BiddingQueryID != playerID:
         PlayerControl.NotifyCode(curPlayer, "Paimai2")
         errInfo = "bidding player error"
         return itemID, errInfo
@@ -1420,8 +1433,8 @@
         auctionItemMgr.sysBuyoutItemByTimeList.remove(auctionItem)
         #GameWorld.DebugLog("拍品有人竞价了,移除系统一口价拍品列表!")
         
-    if isBuyout:        
-        __EndAuctionItem([auctionItem], "Buyout")
+    if isBuyout:
+        __EndAuctionItem([auctionItem], "Buyout", funcAutoBuyout)
     else:
         if __AddAuctionItemEndTimeByBid(auctionItem):
             __SortAuctionitem(isSortWorldItem=False)
@@ -1433,6 +1446,183 @@
         
     return itemID, errInfo
 
+def __DoEquipStarAutoBuyEquip(curPlayer, queryData, tick):
+    ## 升星自动购买
+    classLV, equipPlace, curPartStar, equipPackIndex, isAutoBuyPreview, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, playerGoldPaper = queryData
+    GameWorld.DebugLog("升星自动购买装备: classLV=%s, equipPlace=%s, curPartStar=%s, equipPackIndex=%s" % (classLV, equipPlace, curPartStar, equipPackIndex))
+    GameWorld.DebugLog("    是否预览 %s, curRate=%s,lackItemCostMoney=%s, playerGoldPaper=%s" % (isAutoBuyPreview, curRate, lackItemCostMoney, playerGoldPaper))
+    nextStar = curPartStar + 1
+    ipyData = IpyGameDataPY.GetIpyGameData("EquipStarUp", classLV, equipPlace, nextStar)
+    if not ipyData:
+        return
+    costEquipPlaceList = ipyData.GetCostEquipPlace()
+    costEquipColorList = ipyData.GetCostEquipColor()
+    isJobLimit = ipyData.GetIsJobLimit()
+    unSuitRate = ipyData.GetUnSuitRate()
+    
+    curTime = int(time.time())
+    fullRate = IpyGameDataPY.GetFuncCfg("EquipStarRate", 4)
+    autoBuyOtherClassItemDict = {}
+    buyEquipCostMoney = 0
+    autoBuyItemList = []
+    auctionItemMgr = PyDataManager.GetAuctionItemManager()
+    #GameWorld.DebugLog("世界拍品个数: %s" % len(auctionItemMgr.worldAuctionItemList))
+    for i, worldAuctionItem in enumerate(auctionItemMgr.worldAuctionItemList):
+                
+        itemID = worldAuctionItem.ItemID
+        aucItemJob = worldAuctionItem.ItemJobLimit
+        if not aucItemJob:
+            #GameWorld.DebugLog("    %s 职业通用的, 不购买!itemID=%s" % (i, itemID))
+            continue
+        if isJobLimit and aucItemJob != curPlayer.GetJob():
+            #GameWorld.DebugLog("    %s 职业不可用, 不购买!itemID=%s,aucItemJob=%s != %s" % (i, itemID, aucItemJob, curPlayer.GetJob()))
+            continue
+        
+        itemIDStr = str(itemID)
+        aucItemColor = int(itemIDStr[3:4])
+        aucItemPlace = int(itemIDStr[4:6])
+        aucItemIsSuit = int(itemIDStr[-1])
+        
+        if aucItemColor not in costEquipColorList:
+            #GameWorld.DebugLog("    %s 颜色限制, 不购买!itemID=%s,aucItemColor=%s not in %s" % (i, itemID, aucItemColor, costEquipColorList))
+            continue
+        if aucItemPlace not in costEquipPlaceList:
+            #GameWorld.DebugLog("    %s 装备位限制, 不购买!itemID=%s,aucItemPlace=%s not in %s" % (i, itemID, aucItemPlace, costEquipPlaceList))
+            continue
+        if aucItemIsSuit:
+            #套装不允许自动购买
+            #GameWorld.DebugLog("    %s 套装, 不购买!itemID=%s" % (i, itemID))
+            continue
+        
+        aucIpyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
+        if not aucIpyData:
+            continue
+        buyoutPrice = aucIpyData.GetBuyoutPrice()
+        if not buyoutPrice:
+            #GameWorld.DebugLog("    %s 没有一口价, 不购买!itemID=%s,buyoutPrice=%s" % (i, itemID, buyoutPrice))
+            continue
+                
+        if curTime > worldAuctionItem.EndTime:
+            #GameWorld.DebugLog("    %s 拍品已结束竞价, 不购买!itemID=%s" % (i, itemID))
+            continue
+        
+        noticeMinutes = aucIpyData.GetNoticeSaleMinutes()
+        if noticeMinutes:
+            addTimeStr = worldAuctionItem.AddTime
+            addTime = GameWorld.ChangeTimeStrToNum(addTimeStr)
+            passMinutes = (curTime - addTime) / 60
+            if passMinutes < noticeMinutes:
+                #GameWorld.DebugLog("    %s 拍品尚未开放竞价, 不购买!itemID=%s" % (i, itemID))
+                continue
+            
+        aucItemClassLV = worldAuctionItem.ItemClassLV
+        # 本阶的直接处理
+        if aucItemClassLV == classLV:
+            autoBuyItemList.append([worldAuctionItem, buyoutPrice])
+            curRate += unSuitRate
+            buyEquipCostMoney += buyoutPrice
+            GameWorld.DebugLog("    %s 本阶优先购买!itemID=%s,classLV=%s,curRate=%s,buyoutPrice=%s,buyEquipCostMoney=%s" 
+                               % (i, itemID, classLV, curRate, buyoutPrice, buyEquipCostMoney))
+            if curRate >= fullRate:
+                curRate = 100
+                GameWorld.DebugLog("        自动购买本阶概率已满足!curRate=%s" % (curRate))
+                break
+            
+        # 其他阶的需要按阶的优先级进行处理
+        else:
+            if aucItemClassLV not in autoBuyOtherClassItemDict:
+                autoBuyOtherClassItemDict[aucItemClassLV] = []
+            classItemList = autoBuyOtherClassItemDict[aucItemClassLV]
+            classItemList.append([worldAuctionItem, buyoutPrice])
+            GameWorld.DebugLog("    %s 非本阶, 暂不处理! itemID=%s,aucItemClassLV=%s" % (i, itemID, aucItemClassLV))
+          
+    # 未满概率时再购买其他阶
+    if curRate < 100:
+        lowClassList, highClassList = [], []
+        for othClassLV in autoBuyOtherClassItemDict.keys():
+            if othClassLV <= classLV:
+                lowClassList.append(othClassLV)
+            else:
+                highClassList.append(othClassLV)
+        lowClassList.sort(reverse=True)
+        highClassList.sort()
+        buyClassLVList = lowClassList + highClassList
+        GameWorld.DebugLog("本阶概率未满,检查购买其他阶! curRate=%s,buyClassLVList=%s" % (curRate, buyClassLVList))
+        
+        diffClassChangeRatePerInfo = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 1)
+        unSuitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 2)
+        for othClassLV in buyClassLVList:
+            classItemList = autoBuyOtherClassItemDict[othClassLV]
+            for worldAuctionItem, buyoutPrice in classItemList:
+                baseRate = unSuitRate
+                minRate, maxRate = unSuitRateRange
+                
+                costClassLV = worldAuctionItem.ItemClassLV
+                itemID = worldAuctionItem.ItemID
+                
+                #吞高阶
+                if costClassLV > classLV:
+                    diffClassChangeRatePer = diffClassChangeRatePerInfo[0] * (costClassLV - classLV)
+                    addRate = int(math.ceil(round(baseRate * (100 + diffClassChangeRatePer) /100.0, 2)))
+                    GameWorld.DebugLog("    吞高阶 itemID=%s,costClassLV=%s,classLV=%s,baseRate=%s,diffClassChangeRatePer=%s,addRate=%s" 
+                                       % (itemID, costClassLV, classLV, baseRate, diffClassChangeRatePer, addRate))
+                #吞低阶
+                elif costClassLV < classLV:
+                    diffClassChangeRatePer = diffClassChangeRatePerInfo[1] * (classLV - costClassLV)
+                    addRate = int(math.ceil(round(baseRate * (100 - diffClassChangeRatePer) /100.0, 2)))
+                    GameWorld.DebugLog("    吞低阶 itemID=%s,costClassLV=%s,classLV=%s,baseRate=%s,diffClassChangeRatePer=%s,addRate=%s" 
+                                       % (itemID, costClassLV, classLV, baseRate, diffClassChangeRatePer, addRate))
+                else:
+                    addRate = baseRate
+                addRate = max(minRate, min(addRate, maxRate))
+                
+                autoBuyItemList.append([worldAuctionItem, buyoutPrice])
+                curRate += addRate
+                buyEquipCostMoney += buyoutPrice
+                GameWorld.DebugLog("        curRate=%s,buyoutPrice=%s,buyEquipCostMoney=%s" % (curRate, buyoutPrice, buyEquipCostMoney))
+                if curRate >= fullRate:
+                    GameWorld.DebugLog("        自动购买补充其他阶概率已满足!curRate=%s" % (curRate))
+                    curRate = 100
+                    break
+            if curRate >= fullRate:
+                break
+            
+    totalCostMoney = lackItemCostMoney + buyEquipCostMoney
+    GameWorld.DebugLog("    lackItemCostMoney=%s,buyEquipCostMoney=%s,totalCostMoney=%s,curRate=%s" % (lackItemCostMoney, buyEquipCostMoney, totalCostMoney, curRate))
+    if isAutoBuyPreview:
+        __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney)
+        return
+    
+    if curRate < 100:
+        # 自动购买必须满概率
+        # 因为确认购买不是实时的,所以存在拍卖行预览消耗装备可能被其他玩家买走导致无法满赶驴,所以这里需要补同步一次
+        __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney)
+        PlayerControl.NotifyCode(curPlayer, "AutoBuyEquipLackEquip")
+        return
+    
+    if playerGoldPaper < totalCostMoney:
+        # 因为确认购买不是实时的,所以存在拍卖行预览消耗的价格与实际购买可能出现消耗价格不一致的情况,所以这里需要补同步一次
+        __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney)
+        PlayerControl.NotifyCode(curPlayer, "AutoBuyEquipLackMoney", [IPY_PlayerDefine.TYPE_Price_Gold_Paper])
+        return
+    
+    for worldAuctionItem, buyoutPrice in autoBuyItemList:
+        # 这里认为一定可以购买成功,不对返回值做处理,即使无法购买也认为购买成功,玩家的消耗照常扣除
+        __DoPlayerBidAuctionItem(curPlayer, worldAuctionItem.ItemGUID, buyoutPrice, tick, False, funcAutoBuyout=True)
+        
+    return classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, buyEquipCostMoney
+
+def __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney):
+    ## 通知自动购买预览结果
+    costInfo = ChPyNetSendPack.tagGCEquipStarAutoBuyCostInfo()
+    costInfo.ClassLV = classLV
+    costInfo.EquipPlace = equipPlace
+    costInfo.CurStar = curPartStar
+    costInfo.CurRate = curRate
+    costInfo.AutoBuyCostMoney = totalCostMoney
+    NetPackCommon.SendFakePack(curPlayer, costInfo)
+    return
+
 def __SyncRefreshAuctionItem(auctionItemList):
     ''' // B5 08 拍卖行刷新拍品 #tagGCRefreshAuctionItemInfo
         1-仙盟拍品转移到全服时通知; 2-拍品有人竞价时刷新
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index b5d1a56..6d05c4d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -547,6 +547,16 @@
                         ("WORD", "LVLimit", 0),
                         ),
 
+                "EquipStarUp":(
+                        ("BYTE", "ClassLV", 1),
+                        ("BYTE", "EquipPlace", 1),
+                        ("BYTE", "Star", 1),
+                        ("list", "CostEquipPlace", 0),
+                        ("BYTE", "IsJobLimit", 0),
+                        ("list", "CostEquipColor", 0),
+                        ("BYTE", "UnSuitRate", 0),
+                        ),
+
                 "FamilyWarRankAward":(
                         ("WORD", "WarWorldLV", 1),
                         ("BYTE", "WarRank", 0),
@@ -1639,6 +1649,27 @@
     def GetNotifyInfoLoop(self): return self.NotifyInfoLoop # 全服提示信息 - 循环广播[间隔分钟, 广播key]
     def GetLVLimit(self): return self.LVLimit # 限制等级
 
+# 装备升星表
+class IPY_EquipStarUp():
+    
+    def __init__(self):
+        self.ClassLV = 0
+        self.EquipPlace = 0
+        self.Star = 0
+        self.CostEquipPlace = []
+        self.IsJobLimit = 0
+        self.CostEquipColor = []
+        self.UnSuitRate = 0
+        return
+        
+    def GetClassLV(self): return self.ClassLV # 阶级
+    def GetEquipPlace(self): return self.EquipPlace # 装备位
+    def GetStar(self): return self.Star # 星数
+    def GetCostEquipPlace(self): return self.CostEquipPlace # 可用装备部位
+    def GetIsJobLimit(self): return self.IsJobLimit # 是否只用本职业装备材料
+    def GetCostEquipColor(self): return self.CostEquipColor # 可用装备品质
+    def GetUnSuitRate(self): return self.UnSuitRate # 单件非套装加成概率
+
 # 仙盟联赛排名奖励表
 class IPY_FamilyWarRankAward():
     
@@ -1785,6 +1816,8 @@
         self.ipyNewUniquenessArriveLen = len(self.ipyNewUniquenessArriveCache)
         self.ipyActLuckyTreasureCache = self.__LoadFileData("ActLuckyTreasure", IPY_ActLuckyTreasure)
         self.ipyActLuckyTreasureLen = len(self.ipyActLuckyTreasureCache)
+        self.ipyEquipStarUpCache = self.__LoadFileData("EquipStarUp", IPY_EquipStarUp)
+        self.ipyEquipStarUpLen = len(self.ipyEquipStarUpCache)
         self.ipyFamilyWarRankAwardCache = self.__LoadFileData("FamilyWarRankAward", IPY_FamilyWarRankAward)
         self.ipyFamilyWarRankAwardLen = len(self.ipyFamilyWarRankAwardCache)
         self.ipyFairyDomainCache = self.__LoadFileData("FairyDomain", IPY_FairyDomain)
@@ -2051,6 +2084,8 @@
     def GetNewUniquenessArriveByIndex(self, index): return self.ipyNewUniquenessArriveCache[index]
     def GetActLuckyTreasureCount(self): return self.ipyActLuckyTreasureLen
     def GetActLuckyTreasureByIndex(self, index): return self.ipyActLuckyTreasureCache[index]
+    def GetEquipStarUpCount(self): return self.ipyEquipStarUpLen
+    def GetEquipStarUpByIndex(self, index): return self.ipyEquipStarUpCache[index]
     def GetFamilyWarRankAwardCount(self): return self.ipyFamilyWarRankAwardLen
     def GetFamilyWarRankAwardByIndex(self, index): return self.ipyFamilyWarRankAwardCache[index]
     def GetFairyDomainCount(self): return self.ipyFairyDomainLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index ee484d5..e77ec82 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4656,10 +4656,11 @@
 Def_Cost_LuckyTreasure, #幸运鉴宝
 Def_Cost_MysteryShopRefresh, # 神秘商店刷新
 Def_Cost_AuctionBid, # 拍卖行竞价
-Def_Cost_BuyDailyActionCnt, # 购买活动次数
+Def_Cost_BuyDailyActionCnt, # 购买活动次数 45
 Def_Cost_FBBuyBuff, # 副本买buff
 Def_Cost_CreatFamily, # 创建仙盟
 Def_Cost_BuyKillBossCnt, #购买boss次数
+Def_Cost_EquipStar, #装备升星
 #-----------以下为暂时没用的,先不删除,如有新增消费点则放在这些之前------------
 Def_Cost_RefreshArrestTask, # 刷新悬赏任务
 Def_Cost_OffLineExp, # 兑换离线经验
@@ -4672,7 +4673,7 @@
 Def_Cost_Trade, # 交易
 Def_Cost_Rename, # 改名
 Def_Cost_SkillLvUp, # 技能升级
-) = range(2000, 2000 + 60)
+) = range(2000, 2000 + 61)
 
 Def_Cost_Reason_SonKey = "reason_name_son" # 消费点原因子类说明key
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 81617d5..4049f76 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -9290,6 +9290,7 @@
     CostEquipCnt = 0    #(BYTE CostEquipCnt)// 装备个数
     CostEquipIndex = list()    #(vector<WORD> CostEquipIndex)// 装备索引
     CostEquipID = list()    #(vector<DWORD> CostEquipID)// 装备物品ID
+    AutoBuy = 0    #(BYTE AutoBuy)// 自动购买 0-不自动购买,1-自动购买并升星,2-自动购买预览(未满概率时预览消耗时使用)
     data = None
 
     def __init__(self):
@@ -9309,6 +9310,7 @@
         for i in range(self.CostEquipCnt):
             value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
             self.CostEquipID.append(value)
+        self.AutoBuy,_pos = CommFunc.ReadBYTE(_lpData, _pos)
         return _pos
 
     def Clear(self):
@@ -9320,6 +9322,7 @@
         self.CostEquipCnt = 0
         self.CostEquipIndex = list()
         self.CostEquipID = list()
+        self.AutoBuy = 0
         return
 
     def GetLength(self):
@@ -9329,6 +9332,7 @@
         length += 1
         length += 2 * self.CostEquipCnt
         length += 4 * self.CostEquipCnt
+        length += 1
 
         return length
 
@@ -9341,6 +9345,7 @@
             data = CommFunc.WriteWORD(data, self.CostEquipIndex[i])
         for i in range(self.CostEquipCnt):
             data = CommFunc.WriteDWORD(data, self.CostEquipID[i])
+        data = CommFunc.WriteBYTE(data, self.AutoBuy)
         return data
 
     def OutputString(self):
@@ -9349,14 +9354,16 @@
                                 EquipPackIndex:%d,
                                 CostEquipCnt:%d,
                                 CostEquipIndex:%s,
-                                CostEquipID:%s
+                                CostEquipID:%s,
+                                AutoBuy:%d
                                 '''\
                                 %(
                                 self.Head.OutputString(),
                                 self.EquipPackIndex,
                                 self.CostEquipCnt,
                                 "...",
-                                "..."
+                                "...",
+                                self.AutoBuy
                                 )
         return DumpString
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index b994baa..b2eec9c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -7789,6 +7789,74 @@
 
 
 #------------------------------------------------------
+# B5 11 部位升星自动购买拍品消耗信息 #tagGCEquipStarAutoBuyCostInfo
+
+class  tagGCEquipStarAutoBuyCostInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ClassLV", c_ubyte),    # 当前要升星的境界阶
+                  ("EquipPlace", c_ubyte),    #当前要升星的装备位
+                  ("CurStar", c_ubyte),    #当前星级
+                  ("CurRate", c_ubyte),    #当前自动购买后的总概率,不满100则代表拍品库存不足
+                  ("AutoBuyCostMoney", c_ushort),    #自动购买所需总消耗
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB5
+        self.SubCmd = 0x11
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB5
+        self.SubCmd = 0x11
+        self.ClassLV = 0
+        self.EquipPlace = 0
+        self.CurStar = 0
+        self.CurRate = 0
+        self.AutoBuyCostMoney = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCEquipStarAutoBuyCostInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B5 11 部位升星自动购买拍品消耗信息 //tagGCEquipStarAutoBuyCostInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ClassLV:%d,
+                                EquipPlace:%d,
+                                CurStar:%d,
+                                CurRate:%d,
+                                AutoBuyCostMoney:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ClassLV,
+                                self.EquipPlace,
+                                self.CurStar,
+                                self.CurRate,
+                                self.AutoBuyCostMoney
+                                )
+        return DumpString
+
+
+m_NAtagGCEquipStarAutoBuyCostInfo=tagGCEquipStarAutoBuyCostInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCEquipStarAutoBuyCostInfo.Cmd,m_NAtagGCEquipStarAutoBuyCostInfo.SubCmd))] = m_NAtagGCEquipStarAutoBuyCostInfo
+
+
+#------------------------------------------------------
 # B5 05 拍卖行仙盟拍卖中的物品信息 #tagGCFamilyAuctionItemInfo
 
 class  tagGCFamilyAuctionItem(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py
index 552a0be..df20996 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py
@@ -22,6 +22,7 @@
 import PlayerControl
 import IPY_GameWorld
 import DataRecordPack
+import PlayerAuctionHouse
 import IpyGameDataPY
 import GameWorld
 import EventShell
@@ -32,8 +33,8 @@
 #-------------------------------------------------------------------------------------------
 
 
-#===============================================================================
 #// A5 C5 装备部位升星 #tagCMEquipPartStarUp
+#
 #struct    tagCMEquipPartStarUp
 #{
 #    tagHead        Head;
@@ -41,13 +42,8 @@
 #    BYTE    CostEquipCnt;    // 装备个数
 #    WORD    CostEquipIndex[CostEquipCnt];    // 装备索引
 #    DWORD    CostEquipID[CostEquipCnt];    // 装备物品ID
+#    BYTE    AutoBuy;        // 自动购买 0-不自动购买,1-自动购买并升星,2-自动购买预览(未满概率时预览消耗时使用)
 #};
-#===============================================================================
-## 部位升星
-#  @param playerIndex: 玩家
-#  @param clientData: 封包
-#  @param tick: 当前时间
-#  @return None
 def OnEquipPartStarUp(playerIndex, clientData, tick):    
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
     playerID = curPlayer.GetPlayerID()
@@ -68,9 +64,9 @@
         return
     
     # 当前装备等级是否到达最高等级
-    curPack = curPlayer.GetItemManager().GetPack(packType)
-    curEquip = curPack.GetAt(equipPackIndex)
-    if not curEquip or curEquip.IsEmpty():
+    equipPack = curPlayer.GetItemManager().GetPack(packType)
+    curEquip = equipPack.GetAt(equipPackIndex)
+    if not ItemCommon.CheckItemCanUse(curEquip):
         GameWorld.DebugLog("OnEquipPartStarUp() equip is empty")
         return
     
@@ -79,53 +75,127 @@
     if curPartStar >= maxStar:
         GameWorld.Log("OnEquipPartStarUp:curPartStar(%s) >= maxStar(%s)" % (curPartStar, maxStar), playerID)
         return
-
-    # 升星处理
-    result = DoLogic_EquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, clientData)
-    if result == ChConfig.Def_ComposeState_None:
+    
+    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+    costEquipIndexList = clientData.CostEquipIndex
+    costEquipIDList = clientData.CostEquipID
+    autoBuy = clientData.AutoBuy
+    
+    checkCostResult = __CheckCostInfo(curPlayer, classLV, equipPlace, curPartStar, costEquipIndexList, costEquipIDList, itemPack, autoBuy)
+    if not checkCostResult:
         return
+    curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney = checkCostResult
+    
+    if autoBuy:
+        isAutoBuyPreview = autoBuy == 2
+        # 概率未满 且 自动购买, 则需要执行拍卖行购买装备
+        if curRate < 100:
+            playerGoldPaper = curPlayer.GetGoldPaper()
+            queryData = [classLV, equipPlace, curPartStar, equipPackIndex, isAutoBuyPreview, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, playerGoldPaper]
+            PlayerAuctionHouse.QueryGameServer_AuctionHouse(playerID, "EquipStarAutoBuy", queryData)
+            return
+        
+        if lackItemCostMoney:
+            if isAutoBuyPreview:
+                # 满概率时自动购买必要材料的,暂不处理,前端自己判断就行
+                return
+            
+            if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, lackItemCostMoney):
+                GameWorld.DebugLog("自动购买必要物品货币不足,无法升星! %s" % lackItemCostMoney, playerID)
+                return
+            
+    elif lackItemCostMoney:
+        GameWorld.DebugLog("缺少必要物品,不自动购买,无法升星! %s" % lackItemCostMoney, playerID)
+        return
+    
+    # 升星处理
+    buyEquipCostMoney = 0
+    __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, buyEquipCostMoney)
+    return
+
+def GameServer_EquipStarAutoBuy(curPlayer, result):
+    ## GameServer自动购买拍品结果返回
+    classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, buyEquipCostMoney = result
+    __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, buyEquipCostMoney)
+    return
+
+def __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney, buyEquipCostMoney):
+    ## 执行装备部位升星
+    
+    playerID = curPlayer.GetPlayerID()
+    #自动购买货币
+    costMoneyTotal = lackItemCostMoney + buyEquipCostMoney
+    if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costMoneyTotal):
+        return
+    
+    nextStar = curPartStar + 1
+    totalEquipStars = ChEquip.GetTotalEquipStars(curPlayer)
+    if totalEquipStars < IpyGameDataPY.GetFuncCfg('EquipStarCustomized'):
+        curRate = 100
+    isOK = GameWorld.CanHappen(curRate, 100)
+    GameWorld.DebugLog("装备升星最终总概率: %s, isOK=%s, lackItemCostMoney=%s,buyEquipCostMoney=%s" 
+                       % (curRate, isOK, lackItemCostMoney, buyEquipCostMoney), playerID)
+    
+    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+    #扣材料物品
+    for indexList, delCount in delItemInfoList:
+        ItemCommon.ReduceItem(curPlayer, itemPack, indexList, delCount, True, ChConfig.ItemDel_EquipStarUp)
+    ItemCommon.ReduceItem(curPlayer, itemPack, delEquipIndexList, len(delEquipIndexList), True, ChConfig.ItemDel_EquipStarUp)
+    drDict = {"PlayerID":playerID, "AccID":curPlayer.GetAccID(), "classLV":classLV, "equipPlace":equipPlace, "IsSuccess":isOK,
+              "curRate":curRate, "nextStar":nextStar, 'totalEquipStars':totalEquipStars,
+              "lackItemCostMoney":lackItemCostMoney, "buyEquipCostMoney":buyEquipCostMoney}
+    if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costMoneyTotal, ChConfig.Def_Cost_EquipStar, drDict):
+        return
+    
+    if isOK:
+        ChEquip.SetEquipPartStar(curPlayer, equipPackIndex, nextStar)
+        ChEquip.NotifyEquipPartStar(curPlayer, equipPackIndex)
+        result = ChConfig.Def_ComposeState_Sucess
+    else:
+        result = ChConfig.Def_ComposeState_Fail
+    curPlayer.Sync_MakeItemAnswer(ShareDefine.Def_mitEquipStarUp, result)
+    DataRecordPack.SendEventPack("EquipStarUp", drDict, curPlayer)
+    
+    if not isOK:
+        return
+        
+    EventShell.EventRespons_EquipStarUp(curPlayer)
     updPartStar = ChEquip.GetEquipPartStar(curPlayer, equipPackIndex)
-    GameWorld.DebugLog("   装备升星 equipPackIndex=%s result=%s,curPartStar=%s,updPartStar=%s" % (equipPackIndex, result, curPartStar, updPartStar), playerID)
-    if result == ChConfig.Def_ComposeState_Sucess:
-        # 星级变更时处理
-        #刷新属性
-        ChEquip.RefreshPlayerEquipAttribute(curPlayer, classLV)
-        playControl = PlayerControl.PlayerControl(curPlayer)
-        playControl.RefreshPlayerAttrState()
-  
-        if updPartStar in IpyGameDataPY.GetFuncEvalCfg('EquipPartStarNotify'):
+    GameWorld.DebugLog("    装备升星 equipPackIndex=%s result=%s,curPartStar=%s,updPartStar=%s" % (equipPackIndex, result, curPartStar, updPartStar), playerID)
+    
+    # 星级变更时处理
+    # 刷新属性
+    ChEquip.RefreshPlayerEquipAttribute(curPlayer, classLV)
+    playControl = PlayerControl.PlayerControl(curPlayer)
+    playControl.RefreshPlayerAttrState()
+    
+    if updPartStar in IpyGameDataPY.GetFuncEvalCfg('EquipPartStarNotify'):
+        equipPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
+        curEquip = equipPack.GetAt(equipPackIndex)
+        if ItemCommon.CheckItemCanUse(curEquip):
             itemID = curEquip.GetItemTypeID()
             userData = curEquip.GetUserData()
             guid = ItemCommon.CacheNotifyEquipDetailInfo(curPlayer, curEquip)
             msgParamList = [curPlayer.GetPlayerName(), itemID, userData, guid, updPartStar]
             PlayerControl.WorldNotify(0, "StarLevelUp", msgParamList)
-        EventShell.EventRespons_EquipStarUp(curPlayer)
+            
     return
-     
 
-## 开始装备升星
-#  @param index 为装备位
-#  @return 
-def DoLogic_EquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, clientData):
-    result = ChConfig.Def_ComposeState_None
+def __CheckCostInfo(curPlayer, classLV, equipPlace, curPartStar, costEquipIndexList, costEquipIDList, itemPack, isAutoBuy):
     nextStar = curPartStar + 1
     ipyData = IpyGameDataPY.GetIpyGameData("EquipStarUp", classLV, equipPlace, nextStar)
     if not ipyData:
-        return result
+        return
     
-    costEquipCnt = ipyData.GetCostEquipCnt()
-    if clientData.CostEquipCnt < costEquipCnt:
-        GameWorld.DebugLog(' 开始装备升星,装备材料不足 %s' % costEquipCnt)
-        return result
+    costEquipCnt = ipyData.GetCostEquipCnt() # 是否消耗装备
     costEquipPlaceList = ipyData.GetCostEquipPlace()
     costEquipColorList = ipyData.GetCostEquipColor()
     isJobLimit = ipyData.GetIsJobLimit()
-    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
     delEquipIndexList = []
     totalEquipStars = ChEquip.GetTotalEquipStars(curPlayer)
     
     if not costEquipCnt:
-        curRate = 100
+        curRate = 100 # 不用消耗装备的默认满概率
     else:
         curRate = 0 #成功概率
         diffClassChangeRatePerInfo = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 1)
@@ -133,24 +203,24 @@
         suitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 3)
         if len(diffClassChangeRatePerInfo) != 2 or len(unSuitRateRange) != 2 or len(suitRateRange) != 2:
             GameWorld.ErrLog('升星不同阶概率配置错误!')
-            return result
+            return
         
-        for i, index in enumerate(clientData.CostEquipIndex):
+        for i, index in enumerate(costEquipIndexList):
             costEquip = itemPack.GetAt(index)
             if not costEquip or costEquip.IsEmpty():
-                return result
+                return
             equipID = costEquip.GetItemTypeID()
-            if equipID != clientData.CostEquipID[i]:
-                GameWorld.ErrLog('   装备升星 客户端发的物品索引与实际物品ID不对应  index=%s,eatItemID=%s,wantEatItemID=%s' % (index, equipID, clientData.CostEquipID[i]))
-                return result
-            itemColor = costEquip.GetItemColor()
-            equipPlace = costEquip.GetEquipPlace()
-            if itemColor not in costEquipColorList:
-                return result
-            if equipPlace not in costEquipPlaceList:
-                return result
+            if equipID != costEquipIDList[i]:
+                GameWorld.ErrLog('   装备升星 客户端发的物品索引与实际物品ID不对应  index=%s,eatItemID=%s,wantEatItemID=%s' % (index, equipID, costEquipIDList[i]))
+                return
+            costEquipColor = costEquip.GetItemColor()
+            costEquipPlace = costEquip.GetEquipPlace()
+            if costEquipColor not in costEquipColorList:
+                return
+            if costEquipPlace not in costEquipPlaceList:
+                return
             if isJobLimit and not ItemCommon.CheckJob(curPlayer, costEquip):
-                return result
+                return
             
             if costEquip.GetSuiteID():
                 baseRate = ipyData.GetSuitRate()
@@ -166,47 +236,47 @@
             #吞高阶
             if costClassLV > classLV:
                 diffClassChangeRatePer = diffClassChangeRatePerInfo[0] * (costClassLV - classLV)
-                addRate = int(math.ceil(round(baseRate * (100 + diffClassChangeRatePer) /100.0, 2)))
+                addRate = int(math.ceil(round(baseRate * (100 + diffClassChangeRatePer) / 100.0, 2)))
                 GameWorld.DebugLog("    吞高阶 costClassLV=%s,classLV=%s,diffClassChangeRatePer=%s,addRate=%s" % (costClassLV, classLV, diffClassChangeRatePer, addRate))
             #吞低阶
             elif costClassLV < classLV:
                 diffClassChangeRatePer = diffClassChangeRatePerInfo[1] * (classLV - costClassLV)
-                addRate = int(math.ceil(round(baseRate * (100 - diffClassChangeRatePer) /100.0, 2)))
+                addRate = int(math.ceil(round(baseRate * (100 - diffClassChangeRatePer) / 100.0, 2)))
                 GameWorld.DebugLog("    吞低阶 costClassLV=%s,classLV=%s,diffClassChangeRatePer=%s,addRate=%s" % (costClassLV, classLV, diffClassChangeRatePer, addRate))
             addRate = max(minRate, min(addRate, maxRate))
             curRate += addRate
             GameWorld.DebugLog("    本件装备增加概率=%s,当前总概率=%s" % (addRate, curRate))
             delEquipIndexList.append(index)
-    if totalEquipStars < IpyGameDataPY.GetFuncCfg('EquipStarCustomized'):
-        curRate = 100
-    if curRate <= 0:
-        GameWorld.Log('装备升星异常 概率为0!!equipPackIndex=%s'%equipPackIndex)
-        return result
-    isOK = GameWorld.CanHappen(curRate, 100)
-    GameWorld.DebugLog("装备升星最终总概率: %s, isOK=%s" % (curRate, isOK))
-    #判断普通物品材料 成功才扣
+            
+    delItemInfoList = []
+    lackItemCostMoney = 0
     costItemDict = ipyData.GetCostItemDict()
-    if isOK and costItemDict:
-        delItemDict = {}
+    if costItemDict:
         for itemID, itemCnt in costItemDict.items():
             hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(itemID, itemPack, itemCnt)
             if not hasEnough:
-                return result
-            delItemDict[tuple(indexList)] = itemCnt
-        for itemIndexList, delCnt in delItemDict.items():
-            ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, delCnt, True, ChConfig.ItemDel_EquipStarUp)
-    #扣装备
-    ItemCommon.ReduceItem(curPlayer, itemPack, delEquipIndexList, len(delEquipIndexList), True, ChConfig.ItemDel_EquipStarUp)
-    
-    if isOK:
-        ChEquip.SetEquipPartStar(curPlayer, equipPackIndex, nextStar)
-        ChEquip.NotifyEquipPartStar(curPlayer, equipPackIndex)
-        result = ChConfig.Def_ComposeState_Sucess
-    else:
-        result = ChConfig.Def_ComposeState_Fail
-    curPlayer.Sync_MakeItemAnswer(ShareDefine.Def_mitEquipStarUp, result)
-    drDict = {"PlayerID":curPlayer.GetPlayerID(), "AccID":curPlayer.GetAccID(), "classLV":classLV, "equipPlace":equipPlace, "IsSuccess":isOK,
-              "curRate":curRate, "nextStar":nextStar, 'totalEquipStars':totalEquipStars}
-    DataRecordPack.SendEventPack("EquipStarUp", drDict, curPlayer)
-    return result
+                if not isAutoBuy:
+                    GameWorld.DebugLog("    缺少必要物品,不自动购买!itemID=%s,lackCnt=%s" % (itemID, lackCnt))
+                    return
+                itemGoldPaper = ItemCommon.GetShopItemPrice(itemID, IPY_GameWorld.TYPE_Price_Gold_Paper)
+                if not itemGoldPaper:
+                    GameWorld.DebugLog("    找不到物品自动购买消耗货币!itemID=%s,lackCnt=%s" % (itemID, lackCnt))
+                    return
+                lackItemCostMoney += itemGoldPaper * lackCnt
+                delCount = itemCnt - lackCnt
+                GameWorld.DebugLog("    缺少必要物品: itemID=%s,lackMoney(%s)*Count(%s)=%s" % (itemID, itemGoldPaper, lackCnt, itemGoldPaper * lackCnt))
+            else:
+                delCount = itemCnt
+            delItemInfoList.append([indexList, delCount])
+            
+    if totalEquipStars < IpyGameDataPY.GetFuncCfg('EquipStarCustomized'):
+        curRate = 100
+    #if curRate <= 0:
+    #    GameWorld.ErrLog('装备升星异常 概率为0!!classLV=%s, equipPlace=%s' % (classLV, equipPlace))
+    #    return
+    if curRate >= IpyGameDataPY.GetFuncCfg("EquipStarRate", 4): # 优化高概率体验
+        curRate = 100
+        
+    return curRate, delEquipIndexList, delItemInfoList, lackItemCostMoney
+
 
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 d4836b4..49b0c70 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
@@ -1457,7 +1457,7 @@
     ''' 获取商城物品对应价格 '''
     # 系统固定商店类型: 仙玉(2-常用道具,3-成长变强),绑玉(4-绑玉商城)
     priceTypeShopTypeDict = {IPY_GameWorld.TYPE_Price_Gold_Money:[2, 3],
-                             IPY_GameWorld.TYPE_Price_Gold_Paper:[4],
+                             IPY_GameWorld.TYPE_Price_Gold_Paper:[5, 4],
                              }
     ipyData = None
     if priceType in priceTypeShopTypeDict:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAuctionHouse.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAuctionHouse.py
index d5ed238..d0025ce 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAuctionHouse.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAuctionHouse.py
@@ -20,6 +20,7 @@
 import DataRecordPack
 import PlayerControl
 import ItemControler
+import Operate_EquipStar
 import ItemCommon
 import ChConfig
 import ShareDefine
@@ -108,6 +109,9 @@
         itemID = result[0]
         __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, itemID)
     
+    elif queryType == "EquipStarAutoBuy":
+        Operate_EquipStar.GameServer_EquipStarAutoBuy(curPlayer, result)
+        
     return
 
 def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, itemID):

--
Gitblit v1.8.0