| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package Event.EventSrc.Operate_EquipStar  | 
| #  | 
| # @todo:¹«¹²²¿Î»ÐÇÊý  | 
| # @author xdh  | 
| # @date 2019-3-1  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¹«¹²²¿Î»ÐÇÊý  | 
| #  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2019-3-1 18:00"""  | 
| #---------------------------------------------------------------------  | 
| import ItemCommon  | 
| import ShareDefine  | 
| import PlayerControl  | 
| import IPY_GameWorld  | 
| import DataRecordPack  | 
| import PlayerAuctionHouse  | 
| import IpyGameDataPY  | 
| import GameWorld  | 
| import EventShell  | 
| import ChConfig  | 
| import ChEquip  | 
|   | 
| import math  | 
| #-------------------------------------------------------------------------------------------  | 
|   | 
|   | 
| #// A5 C5 ×°±¸²¿Î»ÉýÐÇ #tagCMEquipPartStarUp  | 
| #  | 
| #struct    tagCMEquipPartStarUp  | 
| #{  | 
| #    tagHead        Head;  | 
| #    WORD    EquipPackIndex;    // ²¿Î»¸ñ×ÓË÷Òý  | 
| #    BYTE    CostEquipCnt;    // ×°±¸¸öÊý  | 
| #    WORD    CostEquipIndex[CostEquipCnt];    // ×°±¸Ë÷Òý  | 
| #    DWORD    CostEquipID[CostEquipCnt];    // ×°±¸ÎïÆ·ID  | 
| #    BYTE    AutoBuy;        // ×Ô¶¯¹ºÂò 0-²»×Ô¶¯¹ºÂò£¬1-×Ô¶¯¹ºÂò²¢ÉýÐÇ£¬2-×Ô¶¯¹ºÂòÔ¤ÀÀ(δÂú¸ÅÂÊʱԤÀÀÏûºÄʱʹÓÃ)  | 
| #};  | 
| def OnEquipPartStarUp(playerIndex, clientData, tick):      | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     equipPackIndex = clientData.EquipPackIndex  | 
|     packType = IPY_GameWorld.rptEquip  | 
|       | 
|     if packType not in ChConfig.Pack_EquipPart_CanPlusStar:  | 
|         return  | 
|     ipyData = IpyGameDataPY.GetIpyGameDataByCondition('EquipPlaceIndexMap', {'GridIndex':equipPackIndex})  | 
|     if not ipyData:  | 
|         return  | 
|     classLV = ipyData.GetClassLV()  | 
|     equipPlace = ipyData.GetEquipPlace()  | 
|     placeList = ChConfig.Pack_EquipPart_CanPlusStar[packType]  | 
|     if equipPlace not in placeList:  | 
|         GameWorld.Log("    equipPlace %s not in ChConfig.Pack_EquipPart_CanPlusStar" % equipPlace, playerID)  | 
|         return  | 
|       | 
|     # µ±Ç°×°±¸µÈ¼¶ÊÇ·ñµ½´ï×î¸ßµÈ¼¶  | 
|     equipPack = curPlayer.GetItemManager().GetPack(packType)  | 
|     curEquip = equipPack.GetAt(equipPackIndex)  | 
|     if not ItemCommon.CheckItemCanUse(curEquip):  | 
|         GameWorld.DebugLog("OnEquipPartStarUp() equip is empty")  | 
|         return  | 
|       | 
|     maxStar = ItemCommon.GetItemMaxStar(curEquip)  | 
|     curPartStar = ChEquip.GetEquipPartStar(curPlayer, equipPackIndex)  | 
|     if curPartStar >= maxStar:  | 
|         GameWorld.Log("OnEquipPartStarUp:curPartStar(%s) >= maxStar(%s)" % (curPartStar, maxStar), playerID)  | 
|         return  | 
|       | 
|     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, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney = checkCostResult  | 
|       | 
|     if autoBuy:  | 
|         isAutoBuyPreview = autoBuy == 2  | 
|         # ¸ÅÂÊδÂú ÇÒ ×Ô¶¯¹ºÂò£¬ ÔòÐèÒªÖ´ÐÐÅÄÂôÐйºÂò×°±¸  | 
|         if curRate < 100:  | 
|             playerGoldPaper = curPlayer.GetGoldPaper()  | 
|             queryData = [classLV, equipPlace, curPartStar, equipPackIndex, isAutoBuyPreview, curRate, delEquipGUIDDict, delItemInfoDict, 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, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney)  | 
|     return  | 
|   | 
| def GameServer_EquipStarAutoBuy(curPlayer, result):  | 
|     ## GameServer×Ô¶¯¹ºÂòÅÄÆ·½á¹û·µ»Ø  | 
|     classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney = result  | 
|     __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney)  | 
|     return  | 
|   | 
| def __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, 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)  | 
|     #¿Û²ÄÁÏÎïÆ·£¬ÒòΪ¿ÉÄÜ»¹ÐèÒªÏȵ½GameServer£¬ÔÙ»ØMapServer¿Û³ýÎïÆ·£¬¹ÊÖмä¹ý³ÌÎïÆ·Î»ÖÿÉÄÜ·¢Éú±ä»¯£¬ËùÒÔÕâÀï²»ÄÜÖ±½Óͨ¹ýindexÈ¥¿ÛÎïÆ·£¬ÐèÒªÖØÐ¾«È·¶¨Î»  | 
|     for delItemID, delCount in delItemInfoDict.items():  | 
|         if not delCount:  | 
|             continue  | 
|         hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(delItemID, itemPack, delCount)  | 
|         GameWorld.DebugLog("    ¿Û³ýµÀ¾ß: delItemID=%s,delCount=%s,indexList=%s" % (delItemID, delCount, indexList))  | 
|         ItemCommon.ReduceItem(curPlayer, itemPack, indexList, delCount, True, ChConfig.ItemDel_EquipStarUp)  | 
|           | 
|     delItemByGUIDDict = {}  | 
|     for index, itemGUID in delEquipGUIDDict.items():  | 
|         delCnt = 1  | 
|         curEquip = itemPack.GetAt(index)  | 
|         if not ItemCommon.CheckItemCanUse(curEquip) or curEquip.GetGUID() != itemGUID:  | 
|             delItemByGUIDDict[itemGUID] = delCnt  | 
|             continue  | 
|         GameWorld.DebugLog("    ¿Û³ý×°±¸: index=%s, %s" % (index, itemGUID))  | 
|         ItemCommon.DelItem(curPlayer, curEquip, delCnt, recordName=ChConfig.ItemDel_EquipStarUp)  | 
|     if delItemByGUIDDict:  | 
|         GameWorld.DebugLog("    ¿Û³ý×°±¸Î»ÖôíÎó£¬Í¨¹ýGUID²¹¿Û! %s" % delItemByGUIDDict)  | 
|         ItemCommon.DelItemByGUID(curPlayer, itemPack, delItemByGUIDDict, recordName=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)  | 
|       | 
|     # ÐǼ¶±ä¸üʱ´¦Àí  | 
|     # Ë¢ÐÂÊôÐÔ  | 
|     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)  | 
|               | 
|     return  | 
|   | 
| def __CheckCostInfo(curPlayer, classLV, equipPlace, curPartStar, costEquipIndexList, costEquipIDList, itemPack, isAutoBuy):  | 
|     nextStar = curPartStar + 1  | 
|     ipyData = IpyGameDataPY.GetIpyGameData("EquipStarUp", classLV, equipPlace, nextStar)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     costEquipCnt = ipyData.GetCostEquipCnt() # ÊÇ·ñÏûºÄ×°±¸  | 
|     costEquipPlaceList = ipyData.GetCostEquipPlace()  | 
|     costEquipColorList = ipyData.GetCostEquipColor()  | 
|     isJobLimit = ipyData.GetIsJobLimit()  | 
|     delEquipGUIDDict = {}  | 
|     totalEquipStars = ChEquip.GetTotalEquipStars(curPlayer)  | 
|       | 
|     if not costEquipCnt:  | 
|         curRate = 100 # ²»ÓÃÏûºÄ×°±¸µÄĬÈÏÂú¸ÅÂÊ  | 
|     else:  | 
|         curRate = 0 #³É¹¦¸ÅÂÊ  | 
|         diffClassChangeRatePerInfo = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 1)  | 
|         unSuitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 2)  | 
|         suitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 3)  | 
|         if len(diffClassChangeRatePerInfo) != 2 or len(unSuitRateRange) != 2 or len(suitRateRange) != 2:  | 
|             GameWorld.ErrLog('ÉýÐDz»Í¬½×¸ÅÂÊÅäÖôíÎó£¡')  | 
|             return  | 
|           | 
|         for i, index in enumerate(costEquipIndexList):  | 
|             costEquip = itemPack.GetAt(index)  | 
|             if not costEquip or costEquip.IsEmpty():  | 
|                 return  | 
|             equipID = costEquip.GetItemTypeID()  | 
|             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  | 
|               | 
|             if costEquip.GetSuiteID():  | 
|                 baseRate = ipyData.GetSuitRate()  | 
|                 minRate, maxRate = suitRateRange  | 
|             else:  | 
|                 baseRate = ipyData.GetUnSuitRate()  | 
|                 minRate, maxRate = unSuitRateRange  | 
|                   | 
|             GameWorld.DebugLog("equipID=%s,baseRate=%s,minRate=%s,maxRate=%s" % (equipID, baseRate, minRate, maxRate))  | 
|             addRate = baseRate  | 
|             costClassLV = ItemCommon.GetItemClassLV(costEquip)  | 
|               | 
|             #ÍÌ¸ß½×  | 
|             if costClassLV > classLV:  | 
|                 diffClassChangeRatePer = diffClassChangeRatePerInfo[0] * (costClassLV - classLV)  | 
|                 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)))  | 
|                 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))  | 
|             delEquipGUIDDict[index] = costEquip.GetGUID()  | 
|               | 
|     delItemInfoDict = {}  | 
|     lackItemCostMoney = 0  | 
|     costItemDict = ipyData.GetCostItemDict()  | 
|     if costItemDict:  | 
|         for itemID, itemCnt in costItemDict.items():  | 
|             hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(itemID, itemPack, itemCnt)  | 
|             if not hasEnough:  | 
|                 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  | 
|             delItemInfoDict[itemID] = 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, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney  | 
|   | 
|   |