#!/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 PlayerTongTianLing  
 | 
import PlayerWeekParty  
 | 
import IpyGameDataPY  
 | 
import PlayerSuccess  
 | 
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)  
 | 
      
 | 
    PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_Star, 1)  
 | 
      
 | 
    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)  
 | 
      
 | 
    # ³É¾Í  
 | 
    EquipStarSuccess(curPlayer, classLV)  
 | 
      
 | 
    # ÐǼ¶±ä¸üʱ´¦Àí  
 | 
    # Ë¢ÐÂÊôÐÔ  
 | 
    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)  
 | 
              
 | 
    PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_Star, 1)  
 | 
    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  
 | 
  
 | 
  
 | 
def EquipStarSuccess(curPlayer, classLV):  
 | 
    ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition('EquipPlaceIndexMap', {'ClassLV':classLV}, True)  
 | 
    if not ipyDataList:  
 | 
        return  
 | 
      
 | 
    totalStarLV = ChEquip.GetTotalEquipStars(curPlayer)  
 | 
    classStarLV = 0  
 | 
    starCountDict = {}  
 | 
    for ipyData in ipyDataList:  
 | 
        index = ipyData.GetGridIndex()  
 | 
        equipStar = ChEquip.GetEquipPartStar(curPlayer, index)  
 | 
        if not equipStar:  
 | 
            continue  
 | 
        conditionKey = (classLV, equipStar)  
 | 
        starCountDict[conditionKey] = starCountDict.get(conditionKey, 0) + 1  
 | 
        classStarLV += equipStar  
 | 
          
 | 
    #GameWorld.DebugLog("ÉýÐdzɾÍÊý¾Ý: classLV=%s,starCountDict=%s,classStarLV=%s,totalStarLV=%s" % (classLV, starCountDict, classStarLV, totalStarLV))  
 | 
    PlayerSuccess.UpdateSuccessProgressByConditions(curPlayer, ShareDefine.SuccType_EquipStar, starCountDict)  
 | 
    PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_EquipStarTotal, totalStarLV)  
 | 
    PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_EquipStarClass, classStarLV, [classLV])  
 | 
    return  
 | 
  
 |