#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#---------------------------------------------------------------------  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
##@package PlayerRefineStove  
 | 
# @todo: Íæ¼ÒÁ¶µ¤Â¯  
 | 
#  
 | 
# @author: sgj  
 | 
# @date 2017-11-07  
 | 
# @version 1.0  
 | 
#  
 | 
# @note:   
 | 
#---------------------------------------------------------------------  
 | 
#"""Version = 2017-11-07 16:40"""  
 | 
#---------------------------------------------------------------------  
 | 
import ChConfig  
 | 
import GameWorld  
 | 
import IPY_GameWorld  
 | 
import ItemControler  
 | 
import PlayerControl  
 | 
import ChPyNetSendPack  
 | 
import NetPackCommon  
 | 
import GameFuncComm  
 | 
import ShareDefine  
 | 
import ItemCommon  
 | 
import PlayerSuccess  
 | 
import PlayerAttrFruit  
 | 
import IpyGameDataPY  
 | 
import EventShell  
 | 
import PlayerActivity  
 | 
import PlayerFairyCeremony  
 | 
  
 | 
import copy  
 | 
  
 | 
##¹¦ÄÜ¿ªÆô  
 | 
def DoRefineStoveOpen(curPlayer):  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AlchemyLV, 1)  
 | 
    PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_AlchemyLV, 1)  
 | 
    Sycn_AlchemyMsg(curPlayer)  
 | 
    return True  
 | 
  
 | 
##µÇ¼´¦Àí  
 | 
def DoOnLogin(curPlayer, tick):  
 | 
    Sycn_AlchemyMsg(curPlayer)  
 | 
    return  
 | 
  
 | 
  
 | 
#// A5 76 Íæ¼ÒÁ¶µ¤ #tagCMPlayerRefine  
 | 
#  
 | 
#struct tagCMPlayerRefine  
 | 
#{  
 | 
#    tagHead    Head;  
 | 
#    WORD    RefineNum;    // Åä·½±àºÅ  
 | 
#    DWORD   UseRateItem;  // ¸½¼Ó²ÄÁÏID  
 | 
#};  
 | 
def PlayerRefineItem(index, clientPack, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_RefineStove):  
 | 
        GameWorld.DebugLog("Á¶µ¤Â¯¹¦ÄÜ먦Æô£¡", playerID)  
 | 
        return  
 | 
      
 | 
    alchemyID = clientPack.RefineNum  
 | 
    specID = clientPack.UseRateItem # ÌØÊâÁ¶µ¤ID  
 | 
    GameWorld.DebugLog("Íæ¼ÒÁ¶µ¤: alchemyID=%s,specID=%s" % (alchemyID, specID), playerID)  
 | 
    alchemyIpyData = IpyGameDataPY.GetIpyGameData("Alchemy", alchemyID)  
 | 
    if not alchemyIpyData:  
 | 
        GameWorld.DebugLog("Åä·½²»´æÔÚ£¡alchemyID=%s" % alchemyID, playerID)  
 | 
        return  
 | 
      
 | 
    specAlchemyIpyData = None  
 | 
    if specID:  
 | 
        specAlchemyIDList = alchemyIpyData.GetSpecAlchemyID()  
 | 
        if specID not in specAlchemyIDList:  
 | 
            GameWorld.DebugLog("·Ç·¨ÌØÊâÅä·½£¡alchemyID=%s,specID=%s" % (alchemyID, specID), playerID)  
 | 
            return  
 | 
        specAlchemyIpyData = IpyGameDataPY.GetIpyGameData("AlchemySpec", specID)  
 | 
        if not specAlchemyIpyData:  
 | 
            GameWorld.DebugLog("ÌØÊâÅä·½²»´æÔÚ£¡alchemyID=%s,specID=%s" % (alchemyID, specID), playerID)  
 | 
            return  
 | 
          
 | 
    # µÈ¼¶ÅÐ¶Ï  
 | 
    alchemyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyLV)  
 | 
    if alchemyLV < alchemyIpyData.GetNeedAlchemyLV():          
 | 
        GameWorld.DebugLog("Å䷽먦Æô£¡alchemyID=%s,needAlchemyLV=%s,curAlchemyLV=%s"   
 | 
                           % (alchemyID, alchemyIpyData.GetNeedAlchemyLV(), alchemyLV), playerID)  
 | 
        return  
 | 
    if specAlchemyIpyData:  
 | 
        if alchemyLV < specAlchemyIpyData.GetNeedAlchemyLV():          
 | 
            GameWorld.DebugLog("ÌØÊâÅ䷽먦Æô£¡alchemyID=%s,specID=%s,needAlchemyLV=%s,curAlchemyLV=%s"   
 | 
                               % (alchemyID, specID, specAlchemyIpyData.GetNeedAlchemyLV(), alchemyLV), playerID)  
 | 
            return  
 | 
          
 | 
        alchemyItemList = specAlchemyIpyData.GetAlchemyItem()  
 | 
        alchemyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyCountSpec % specID)  
 | 
        SpecialAlchemyDict = IpyGameDataPY.GetFuncEvalCfg("SpecialAlchemy", 2)  
 | 
        SpecialAlchemyCountItemDict = SpecialAlchemyDict.get(specID, {})  
 | 
    else:  
 | 
        alchemyItemList = alchemyIpyData.GetAlchemyItem()  
 | 
        alchemyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyCount % alchemyID)  
 | 
        SpecialAlchemyDict = IpyGameDataPY.GetFuncEvalCfg("SpecialAlchemy", 1)  
 | 
        SpecialAlchemyCountItemDict = SpecialAlchemyDict.get(alchemyID, {})  
 | 
          
 | 
    updAlchemyCount = 0  
 | 
    if SpecialAlchemyCountItemDict:  
 | 
        nextAlchemyCount = alchemyCount + 1  
 | 
        if nextAlchemyCount <= max(SpecialAlchemyCountItemDict):  
 | 
            updAlchemyCount = nextAlchemyCount # Ö»Òª»¹Ã»´ïµ½×î´óÏ´Á·´ÎÊýÌØÊâ²ú³ö£¬Ôòÿ´ÎÀÛ¼Ó´ÎÊý  
 | 
            # ·ÇÌØÊâ²ÄÁÏÅä·½µÄÇé¿öÏ£¬´ïµ½Ö¸¶¨´ÎÊýÔòʹÓÃÌØÊâ´ÎÊýÖ¸¶¨²ú³ö¿â  
 | 
            if nextAlchemyCount in SpecialAlchemyCountItemDict:  
 | 
                alchemyItemList = SpecialAlchemyCountItemDict[nextAlchemyCount]  
 | 
                GameWorld.DebugLog("Á¶µ¤´ÎÊýÌØÊâ²ú³ö¿â: Á¶µ¤±àºÅ=%s,ÌØÊâID=%s,´ÎÊý=%s,ÌØÊâ²ú³ö¿â=%s"   
 | 
                                   % (alchemyID, specID, nextAlchemyCount, alchemyItemList), playerID)  
 | 
                  
 | 
    # È¥³ýÏÞÖÆ²ú³öµÄÎïÆ·  
 | 
    outPutCountLimitDict = IpyGameDataPY.GetFuncEvalCfg("SpecialAlchemy", 3)  
 | 
    if outPutCountLimitDict:  
 | 
        limitItemInfoList = []  
 | 
        alchemyItemList = copy.copy(alchemyItemList)  
 | 
        for itemInfo in alchemyItemList:  
 | 
            itemID = itemInfo[1]  
 | 
            if itemID not in outPutCountLimitDict:  
 | 
                continue  
 | 
            limitCount = outPutCountLimitDict[itemID]  
 | 
            outputCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyOutputCount % itemID)  
 | 
            if outputCount >= limitCount:  
 | 
                limitItemInfoList.append(itemInfo)  
 | 
                GameWorld.DebugLog("ÒÑ´ïµ½×î´ó²ú³ö´ÎÊý£¬´Ó²ú³ö¿âÖÐÒÆ³ý! alchemyItemList=%s,itemID=%s,outputCount=%s,limitCount=%s"   
 | 
                                   % (alchemyItemList, itemID, outputCount, limitCount), playerID)  
 | 
                  
 | 
        for limitItemInfo in limitItemInfoList:  
 | 
            alchemyItemList.remove(limitItemInfo)  
 | 
              
 | 
    if not alchemyItemList:  
 | 
        GameWorld.DebugLog("Åä·½²ú³öÎïÆ·ÅäÖôíÎó!alchemyID=%s,specID=%s" % (alchemyID, specID), playerID)  
 | 
        return  
 | 
          
 | 
    packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, 1)   
 | 
    if not packSpace:  
 | 
        PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_998371")  
 | 
        return  
 | 
      
 | 
    # »ù´¡¹Ì¶¨ÏûºÄ  
 | 
    needMaterialDict = alchemyIpyData.GetMaterial()  
 | 
    # ÌØÊâÅä·½¶îÍâÏûºÄ  
 | 
    if specAlchemyIpyData:  
 | 
        needMaterialDict = copy.deepcopy(needMaterialDict)  
 | 
        needMaterialDict[specAlchemyIpyData.GetMaterialID()] = specAlchemyIpyData.GetMaterialCnt()  
 | 
          
 | 
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  
 | 
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needMaterialDict, itemPack, False)  
 | 
    if lackItemDict:  
 | 
        GameWorld.DebugLog("Åä·½²ÄÁϲ»×㣡alchemyID=%s,specID=%s,needMaterialDict=%s,lackItemDict=%s,hasItemDict=%s"   
 | 
                           % (alchemyID, specID, needMaterialDict, lackItemDict, delInfoDict), playerID)  
 | 
        return  
 | 
      
 | 
    makeItemInfo = GameWorld.GetResultByWeightList(alchemyItemList)  
 | 
    if not makeItemInfo:  
 | 
        GameWorld.ErrLog("Åä·½ºÏ³É½á¹û´íÎó£¡alchemyID=%s,specID=%s" % (alchemyID, specID), playerID)  
 | 
        return  
 | 
    makeItemID, itemCount = makeItemInfo  
 | 
    GameWorld.DebugLog("ºÏ³ÉÅä·½: alchemyID=%s,specID=%s,makeItemID=%s,itemCount=%s,alchemyItemList=%s"   
 | 
                       % (alchemyID, specID, makeItemID, itemCount, alchemyItemList), playerID)  
 | 
    #¼ì²é°´µ¤Â¯µÈ¼¶½ø½×µÄµ¤Ò©  
 | 
    makeItemID = __GetAlchemyUpItemID(makeItemID, alchemyLV, alchemyIpyData.GetAlchemyUp())  
 | 
    makeItemData = GameWorld.GetGameData().GetItemByTypeID(makeItemID)  
 | 
    if not makeItemData:  
 | 
        return  
 | 
      
 | 
    if updAlchemyCount:  
 | 
        if specID:  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AlchemyCountSpec % specID, updAlchemyCount)  
 | 
        else:  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AlchemyCount % alchemyID, updAlchemyCount)  
 | 
        GameWorld.DebugLog("¸üÐÂÁ¶µ¤´ÎÊýÀÛ¼Æ: alchemyID=%s,ÌØÊâID=%s,´ÎÊý=%s" % (alchemyID, specID, updAlchemyCount), playerID)  
 | 
          
 | 
    #¿ÛÏûºÄ  
 | 
    delItemHasBind = ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, ChConfig.ItemDel_Alchemy)  
 | 
      
 | 
    #¼Ó¾Ñé  
 | 
    addExp = alchemyIpyData.GetAlchemyExp()  
 | 
    if specAlchemyIpyData:  
 | 
        addExp += specAlchemyIpyData.GetAlchemyExp()  
 | 
    AddRefineExp(curPlayer, addExp)  
 | 
      
 | 
    #¼Ó²ú³ö´ÎÊý  
 | 
    if makeItemID in outPutCountLimitDict:  
 | 
        outputCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyOutputCount % makeItemID) + 1  
 | 
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AlchemyOutputCount % makeItemID, outputCount)  
 | 
        GameWorld.DebugLog("¸üÐÂÁ¶µ¤²ú³öÌØÊâÎïÆ·´ÎÊý: makeItemID=%s,outputCount=%s" % (makeItemID, outputCount), playerID)  
 | 
          
 | 
    #¸øÎïÆ·  
 | 
    ItemControler.GivePlayerItem(curPlayer, makeItemID, itemCount, delItemHasBind, [IPY_GameWorld.rptItem],   
 | 
                                 event=[ChConfig.ItemGive_Refine, False, {}])  
 | 
      
 | 
    Sycn_AlchemyMsg(curPlayer, makeItemID)  
 | 
      
 | 
    #×ÏÉ«¼°ÒÔÉÏÈ«·þ¹ã²¥  
 | 
    notifyColor = IpyGameDataPY.GetFuncCfg("AlchemyNotify", 1)  
 | 
    needNotifyItemIDList = IpyGameDataPY.GetFuncEvalCfg("AlchemyNotify", 2)  
 | 
    notNotifyItemIDList = IpyGameDataPY.GetFuncEvalCfg("AlchemyNotify", 3)  
 | 
    if makeItemID not in notNotifyItemIDList and (makeItemID in needNotifyItemIDList or makeItemData.GetItemColor() >= notifyColor):  
 | 
        PlayerControl.WorldNotify(0, "AchemyGreatSuccess", [curPlayer.GetPlayerName(), makeItemID])  
 | 
          
 | 
    #Íê³É1´ÎÁ¶µ¤³É¾Í  
 | 
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_RefineItem, 1)  
 | 
    #Íê³É1´ÎXÆ·ÖÊÎïÆ·Á¶µ¤³É¾Í  
 | 
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_RefineStoveColor, 1, [makeItemData.GetItemColor()])  
 | 
    #ÈÎÎñ  
 | 
    EventShell.EventRespons_RefineItem(curPlayer, alchemyIpyData.GetNeedAlchemyLV())  
 | 
    #ÈÕ³£ÈÎÎñ  
 | 
    costItemCnt = sum(needMaterialDict.values())  
 | 
    PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_RefineStove, costItemCnt)  
 | 
    PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_RefineStove, 1)  
 | 
    return   
 | 
  
 | 
def __GetAlchemyUpItemID(itemID, alchemyLV, alchemyUpCfg):  
 | 
    #»ñÈ¡°´µ¤Â¯µÈ¼¶½ø½×µÄµ¤Ò©ID  
 | 
    if not alchemyUpCfg:  
 | 
        return itemID  
 | 
    itemIDStr = str(itemID)  
 | 
    upItemList = []  
 | 
    for alchemyUpItemDict in alchemyUpCfg:  
 | 
        if itemIDStr in alchemyUpItemDict:  
 | 
            for upID, upLV in alchemyUpItemDict.items():  
 | 
                upItemList.append([upLV, int(upID)])  
 | 
                  
 | 
    if not upItemList:  
 | 
        return itemID  
 | 
    upItemList.sort(reverse=True)  
 | 
    for upLV, makeItemID in upItemList:  
 | 
        if alchemyLV >= upLV:  
 | 
            GameWorld.DebugLog("    »ñµÃ½ø½×µ¤Ò©: itemID=%s to upItemID=%s" % (itemID, makeItemID))  
 | 
            return makeItemID  
 | 
    return itemID  
 | 
  
 | 
def AddRefineExp(curPlayer, addExp):  
 | 
    #Ôö¼ÓÁ¶µ¤Â¯¾Ñé  
 | 
    if addExp <= 0:  
 | 
        return  
 | 
      
 | 
    alchemyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyLV)  
 | 
    alchemyExp = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyExp) + addExp, ShareDefine.Def_UpperLimit_DWord)  
 | 
    GameWorld.DebugLog("Ôö¼ÓÁ¶µ¤¾Ñé: alchemyLV=%s,addExp=%s,alchemyExp=%s" % (alchemyLV, addExp, alchemyExp), curPlayer.GetPlayerID())  
 | 
      
 | 
    isLVUp = False  
 | 
    stoveIpyData = IpyGameDataPY.GetIpyGameDataNotLog("RefineStove", alchemyLV)  
 | 
    while stoveIpyData and stoveIpyData.GetUpNeedExp() and alchemyExp >= stoveIpyData.GetUpNeedExp():  
 | 
        needExp = stoveIpyData.GetUpNeedExp()  
 | 
        nextLV = alchemyLV + 1  
 | 
        stoveIpyData = IpyGameDataPY.GetIpyGameDataNotLog("RefineStove", nextLV)  
 | 
        if not stoveIpyData:  
 | 
            GameWorld.DebugLog("ûÓÐÏÂÒ»¼¶Êý¾ÝÁË£¬ÒÑÂú¼¶£¡²»¿ÉÉý¼¶£¡", curPlayer.GetPlayerID())  
 | 
            break  
 | 
          
 | 
        alchemyExp -= needExp  
 | 
        alchemyLV += 1  
 | 
        GameWorld.DebugLog("    Á¶µ¤Éý¼¶: alchemyLV=%s,alchemyExp=%s" % (alchemyLV, alchemyExp), curPlayer.GetPlayerID())  
 | 
        isLVUp = True  
 | 
        EventShell.EventRespons_RefineStoveUp(curPlayer, alchemyLV)  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AlchemyExp, alchemyExp)  
 | 
    if not isLVUp:  
 | 
        return False  
 | 
      
 | 
    GameWorld.DebugLog("Éý¼¶ºóÊ£Óà¾Ñ飺 %s" % alchemyExp, curPlayer.GetPlayerID())  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AlchemyLV, alchemyLV)  
 | 
    PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_AlchemyLV, alchemyLV)  
 | 
      
 | 
    RefreshStoveAttr(curPlayer)  
 | 
      
 | 
    # ½âËø¹ã²¥  
 | 
    ipyGameData = IpyGameDataPY.IPY_Data()  
 | 
    for i in xrange(ipyGameData.GetAlchemyCount()):  
 | 
        ipyData = ipyGameData.GetAlchemyByIndex(i)  
 | 
        if alchemyLV == ipyData.GetNeedAlchemyLV():  
 | 
            PlayerControl.WorldNotify(0, "FurnaceLVUp", [curPlayer.GetPlayerName(), alchemyLV, ipyData.GetAlchemyID()])  
 | 
            break  
 | 
          
 | 
    return True  
 | 
  
 | 
def Sycn_AlchemyMsg(curPlayer, itemID=0):  
 | 
    # Í¨Öª¿Í»§¶ËÁ¶µ¤Â¯ÐÅÏ¢  
 | 
    if not itemID and not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_RefineStove):  
 | 
        return  
 | 
    pack = ChPyNetSendPack.tagMCPlayerStoveMsg()  
 | 
    pack.StoveExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyExp)  
 | 
    pack.StoveLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyLV)  
 | 
    pack.ItemID = itemID  
 | 
    NetPackCommon.SendFakePack(curPlayer, pack)  
 | 
    return  
 | 
  
 | 
def RefreshStoveAttr(curPlayer):  
 | 
    CalcStoveAttr(curPlayer)  
 | 
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()  
 | 
    return  
 | 
  
 | 
def CalcStoveAttr(curPlayer):  
 | 
    # ¹ûʵ¼Ó³É  
 | 
    allAttrYaoList = [{} for _ in range(4)]  
 | 
    PlayerAttrFruit.CalcAttrFruitAddAtrr(curPlayer, allAttrYaoList, ShareDefine.Def_AttrFruitFunc_Stove)  
 | 
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_StoveYao, allAttrYaoList)  
 | 
      
 | 
    allAttrList = [{} for _ in range(4)]  
 | 
    alchemyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyLV)  
 | 
    stoveIpyData = IpyGameDataPY.GetIpyGameData("RefineStove", alchemyLV)  
 | 
    if stoveIpyData:  
 | 
        attrTypeList = stoveIpyData.GetAddAttrType()  
 | 
        attrValueList = stoveIpyData.GetAddAttrNum()  
 | 
        for i, attrID in enumerate(attrTypeList):  
 | 
            PlayerControl.CalcAttrDict_Type(attrID, attrValueList[i], allAttrList)  
 | 
      
 | 
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Stove, allAttrList)  
 | 
    return  
 |