| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package Player.PlayerCutTree  | 
| #  | 
| # @todo:¿³Ê÷  | 
| # @author hxp  | 
| # @date 2023-12-13  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¿³Ê÷  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2023-12-13 11:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import ItemCommon  | 
| import ShareDefine  | 
| import NetPackCommon  | 
| import IpyGameDataPY  | 
| import ChPyNetSendPack  | 
| import PlayerPrestigeSys  | 
| import FormulaControl  | 
| import PlayerControl  | 
| import IPY_GameWorld  | 
| import ItemControler  | 
| import PlayerArena  | 
| import PlayerTask  | 
| import NPCCommon  | 
| import ChConfig  | 
| import ChEquip  | 
|   | 
| import random  | 
| import time  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)  | 
|     if not treeLV:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLV, 1)  | 
|     RefreshTreeLVUPTime(curPlayer)  | 
|     SyncTreeInfo(curPlayer)  | 
|     return  | 
|   | 
| #// B2 21 Íæ¼Ò¿³Ê÷ #tagCMCutTree  | 
| #  | 
| #struct    tagCMCutTree  | 
| #{  | 
| #    tagHead         Head;  | 
| #    BYTE        CutCount;    // ¿³¼¸´Î£¬Ä¬ÈÏ1  | 
| #};  | 
| def OnCutTree(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     cutCount = clientData.CutCount  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_CutTree, tick):  | 
|         GameWorld.DebugLog("¿³Ê÷CDÖÐ...", playerID)  | 
|         return  | 
|       | 
|     identifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)  | 
|     packCount = identifyPack.GetCount()  | 
|     for i in range(0, packCount):  | 
|         curItem = identifyPack.GetAt(i)  | 
|         if curItem and not curItem.IsEmpty():  | 
|             GameWorld.DebugLog("¿³Ê÷±³°üÖл¹ÓÐδ´¦ÀíÎïÆ·£¬ÎÞ·¨¿³Ê÷! i=%s" % i, playerID)  | 
|             return  | 
|           | 
|     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)  | 
|     canCutMax = 0  | 
|     lvCutMaxList = IpyGameDataPY.GetFuncEvalCfg("CutTree", 2)  | 
|     for curMax, needLV in enumerate(lvCutMaxList, 1):  | 
|         if treeLV >= needLV:  | 
|             canCutMax = curMax  | 
|         else:  | 
|             break  | 
|     cutCount = min(cutCount, canCutMax, identifyPack.GetCount())  | 
|     GameWorld.DebugLog("Íæ¼Ò¿³Ê÷: cutCount=%s,treeLV=%s,canCutMax=%s,packCount=%s" % (cutCount, treeLV, canCutMax, packCount), playerID)  | 
|     if not cutCount:  | 
|         return  | 
|     if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, cutCount):  | 
|         return  | 
|       | 
|     ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", treeLV)  | 
|     if not ipyData:  | 
|         return  | 
|     equipColorRateList = ipyData.GetEquipColorRateList()  | 
|     exAwardItemRateList = ipyData.GetExAwardItemRateList()  | 
|       | 
|     GameWorld.DebugLog("    equipColorRateList=%s" % equipColorRateList, playerID)  | 
|       | 
|     maxRate = 10000  | 
|     totalRate = 0  | 
|     colorRateList = []  | 
|     for equipColor, colorRate in enumerate(equipColorRateList, 1):  | 
|         if not colorRate:  | 
|             continue  | 
|         totalRate += colorRate  | 
|         colorRateList.append([totalRate, equipColor])  | 
|           | 
|     if totalRate != maxRate:  | 
|         GameWorld.SendGameError("GameWarning", "CutTreeTotalRateError:%s!=%s,treeLV=%s" % (totalRate, maxRate, treeLV))      | 
|     if not colorRateList:  | 
|         return  | 
|     GameWorld.DebugLog("    colorRateList=%s,totalRate=%s" % (colorRateList, totalRate), playerID)  | 
|       | 
|     cutCountAppointEquipDict = IpyGameDataPY.GetFuncEvalCfg("CutTree", 4)  | 
|     appointCutTreeCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AppointCutTreeCount)  | 
|     GameWorld.DebugLog("    appointCutTreeCount=%s" % (appointCutTreeCount), playerID)  | 
|     classLV, isSuit = 1, None # Ä¬ÈÏ1½×£¬²»ÏÞÖÆÊÇ·ñÌ××°  | 
|     placeList = ChConfig.EquipPlace_Base + ChConfig.EquipPlace_Special  | 
|     jobList = [curPlayer.GetJob()]  | 
|     randEquipIDList = []  | 
|     for _ in range(cutCount):  | 
|         itemColor = GameWorld.GetResultByRandomList(colorRateList)  | 
|         if not itemColor:  | 
|             continue  | 
|         equipIDList = NPCCommon.__GetEquipIDList(0, classLV, itemColor, isSuit, placeList, jobList, findType="CutTree")  | 
|         if not equipIDList:  | 
|             continue  | 
|         appointCutTreeCount += 1  | 
|         if appointCutTreeCount in cutCountAppointEquipDict:  | 
|             randEquipID, appointID = cutCountAppointEquipDict[appointCutTreeCount]  | 
|             GameWorld.DebugLog("    ¶¨ÖÆ×°±¸ID: %s, appointID=%s,appointCutTreeCount=%s" % (randEquipID, appointID, appointCutTreeCount), playerID)  | 
|         else:  | 
|             appointID = 0  | 
|             randEquipID = random.choice(equipIDList)  | 
|             GameWorld.DebugLog("    Ëæ»ú×°±¸ID: %s, itemColor=%s,%s" % (randEquipID, itemColor, equipIDList), playerID)  | 
|         randEquipIDList.append([randEquipID, appointID])  | 
|           | 
|     GameWorld.DebugLog("    Ô¤²ú³ö×°±¸: randEquipIDList=%s" % randEquipIDList, playerID)  | 
|       | 
|     giveItemListEx = []  | 
|     giveEquipIDList = []  | 
|     for equipItemID, appointID in randEquipIDList:  | 
|         setAttrDict = {}  | 
|         if appointID:  | 
|             setAttrDict[ShareDefine.Def_CItemKey_AppointID] = appointID  | 
|         curItem = ItemControler.GetOutPutItemObj(equipItemID, 1, False, curPlayer=curPlayer, setAttrDict=setAttrDict)  | 
|         if curItem == None:  | 
|             continue  | 
|         if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):  | 
|             continue  | 
|         giveEquipIDList.append(equipItemID)  | 
|           | 
|         exItem = GameWorld.GetResultByRandomList(exAwardItemRateList)  | 
|         if exItem and PlayerArena.CheckCanGiveBattleCountItem(curPlayer, exItem[0]):  | 
|             giveItemListEx.append([exItem[0], exItem[1], 0])  | 
|               | 
|     if not giveEquipIDList:  | 
|         return  | 
|     giveEquipCount = len(giveEquipIDList)  | 
|       | 
|     PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, giveEquipCount, isNotify=False)  | 
|       | 
|     ItemControler.GivePlayerItemOrMail(curPlayer, giveItemListEx)  | 
|       | 
|     GameWorld.DebugLog("    Êµ¼Ê²ú³ö: giveEquipIDList=%s,giveItemListEx=%s" % (giveEquipIDList, giveItemListEx), playerID)  | 
|     SyncCutTreeResult(curPlayer, giveEquipCount, giveItemListEx)  | 
|       | 
|     OnAddCutTreeCnt(curPlayer, giveEquipCount)  | 
|     return  | 
|   | 
| def OnAddCutTreeCnt(curPlayer, addCount):  | 
|     ## Ôö¼Ó¿³Ê÷´ÎÊý¸½¼ÓÂß¼ - ³ý×°±¸²ú³öÍâµÄÆäËûÂß¼  | 
|     cutExp = IpyGameDataPY.GetFuncCfg("CutTree", 1)  | 
|     addExp = addCount * cutExp  | 
|     if addExp > 0:  | 
|         PlayerControl.PlayerControl(curPlayer).AddExp(addExp)    | 
|           | 
|     #GameWorld.DebugLog("OnAddCutTreeCnt: addCount=%s,addExp=%s" % (addCount, addExp), curPlayer.GetPlayerID())  | 
|       | 
|     cutCountAppointEquipDict = IpyGameDataPY.GetFuncEvalCfg("CutTree", 4)  | 
|     appointCountMax = max(cutCountAppointEquipDict) if cutCountAppointEquipDict else 0  | 
|     appointCutTreeCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AppointCutTreeCount)  | 
|     updAppointCutTreeCount = min(appointCutTreeCount + addCount, appointCountMax)  | 
|     if updAppointCutTreeCount != appointCutTreeCount:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AppointCutTreeCount, updAppointCutTreeCount)  | 
|         GameWorld.DebugLog("¸üж¨ÖÆ¿³Ê÷´ÎÊý: updAppointCutTreeCount=%s" % (updAppointCutTreeCount), curPlayer.GetPlayerID())  | 
|           | 
|     PlayerPrestigeSys.AddRealmLVUpCutTreeCnt(curPlayer, addCount)  | 
|     PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_CutTree, addCount)  | 
|     return  | 
|   | 
|   | 
| #// B2 22 ¿³Ê÷×°±¸²Ù×÷ #tagCMCutTreeEquipOP  | 
| #  | 
| #struct    tagCMCutTreeEquipOP  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        IndexCount;  | 
| #    BYTE        ItemIndexList[IndexCount];    // ÎïÆ·ÔÚ¿³Ê÷±³°üµÄË÷ÒýÁÐ±í  | 
| #    BYTE        OPType;        // ²Ù×÷ÀàÐÍ£º1-Ìæ»»£»2-·Ö½â  | 
| #    BYTE        AutoDecompose;    // Ìæ»»ºóÊÇ·ñ×Ô¶¯·Ö½âÔ×°±¸£º0·ñ1ÊÇ£¬½öÌæ»»²Ù×÷ÏÂÓÐÓà  | 
| #};  | 
| def OnCutTreeEquipOP(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     opType = clientData.OPType  | 
|     itemIndexList = clientData.ItemIndexList  | 
|     autoDecompose = clientData.AutoDecompose  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     identifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)  | 
|     GameWorld.DebugLog("¿³Ê÷×°±¸²Ù×÷: itemIndexList=%s,opType=%s,autoDecompose=%s" % (itemIndexList, opType, autoDecompose), playerID)  | 
|     for itemIndex in itemIndexList:  | 
|         if itemIndex >= identifyPack.GetCount():  | 
|             GameWorld.DebugLog("¿³Ê÷±³°üË÷Òý²»´æÔÚ: itemIndex=%s" % itemIndex, playerID)  | 
|             continue  | 
|         curEquip = identifyPack.GetAt(itemIndex)  | 
|         if not ItemCommon.CheckItemCanUse(curEquip):  | 
|             GameWorld.DebugLog("¿³Ê÷±³°üÎïÆ·²»´æÔÚ: itemIndex=%s" % itemIndex, playerID)  | 
|             continue  | 
|           | 
|         # Ìæ»»  | 
|         if opType == 1:  | 
|             equipIndex = ItemCommon.GetEquipPackIndex(curEquip)  | 
|             if not ChEquip.DoPlayerEquipItem(curPlayer, curEquip, equipIndex, tick):  | 
|                 continue  | 
|               | 
|             if autoDecompose:  | 
|                 __DoEquipDecompose(curPlayer, identifyPack.GetAt(itemIndex)) # ÐèÖØÐ»ñµÃ×°±¸¶ÔÏó  | 
|                   | 
|         # ·Ö½â  | 
|         elif opType == 2:  | 
|             __DoEquipDecompose(curPlayer, curEquip)  | 
|               | 
|         # ·ÅÈ뱸ÓÃ²Ö¿â  | 
|         elif opType == 3:  | 
|             pass  | 
|       | 
|     curPlayer.Sync_MakeItemAnswer(ShareDefine.Def_mitCutTreeEquipOP, ChConfig.Def_ComposeState_Sucess)  | 
|     return  | 
|   | 
| def __DoEquipDecompose(curPlayer, curEquip):  | 
|     if not ItemCommon.CheckItemCanUse(curEquip):  | 
|         return  | 
|     itemID = curEquip.GetItemTypeID()  | 
|     itemColor = curEquip.GetItemColor()  | 
|     itemLV = ItemControler.GetItemLV(curEquip)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     colorIpyData = IpyGameDataPY.GetIpyGameData("EquipColor", itemColor)  | 
|     moneyBase = colorIpyData.GetMoneyBase() if colorIpyData else 0  | 
|     GameWorld.DebugLog("×°±¸·Ö½â: itemID=%s,itemColor=%s,itemLV=%s,moneyBase=%s" % (itemID, itemColor, itemLV, moneyBase), playerID)  | 
|       | 
|     ItemCommon.DelItem(curPlayer, curEquip, curEquip.GetCount(), True, ChConfig.ItemDel_EquipDecompose)  | 
|       | 
|     moneyType, moneyFormat = IpyGameDataPY.GetFuncEvalCfg("CutTree", 3)  | 
|     moneyValye = eval(FormulaControl.GetCompileFormula("CutTreeDecomposeMoney", moneyFormat))  | 
|     if moneyValye:  | 
|         addDataDict = {ChConfig.Def_Give_Reason_SonKey:itemID, "itemColor":itemColor, "itemLV":itemLV}  | 
|         PlayerControl.GiveMoney(curPlayer, moneyType, moneyValye, "EquipDecompose", addDataDict)  | 
|           | 
|     PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_EquipDecompose, 1)  | 
|     return  | 
|   | 
| #// B2 23 ÏÉÊ÷Éý¼¶ #tagCMTreeLVUP  | 
| #  | 
| #struct    tagCMTreeLVUP  | 
| #{  | 
| #    tagHead         Head;  | 
| #    BYTE        Type;    // 0-¿ªÊ¼Éý¼¶£¨ÇëÇó¿Û³ýÏûºÄ£¬¿ªÊ¼Éý¼¶µ¹¼ÆÊ±£©£»1-Ö´ÐÐÉý¼¶£¨µ¹¼ÆÊ±Ê±¼äµ½ºó·¢Ë͸ÃÀàÐÍ£©  | 
| #};  | 
| def OnTreeLVUP(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     upType = clientData.Type  | 
|     if upType == 1:  | 
|         DoTreeLVUP(curPlayer)  | 
|         return  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     lvupState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)  | 
|     if lvupState:  | 
|         GameWorld.DebugLog("ÏÉÊ÷ÒѾÔÚÉý¼¶ÖÐ! lvupState=%s" % lvupState, playerID)  | 
|         return  | 
|       | 
|     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)  | 
|     ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", treeLV)  | 
|     if not ipyData:  | 
|         return  | 
|     needMoney = ipyData.GetLVUPNeedMoney()  | 
|     nextTreeLV = treeLV + 1  | 
|     nextIpyData = IpyGameDataPY.GetIpyGameDataNotLog("TreeLV", nextTreeLV)  | 
|     if needMoney <= 0 or not nextIpyData:  | 
|         GameWorld.DebugLog("ÏÉÊ÷ÒÑÂú¼¶! treeLV=%s" % treeLV, playerID)  | 
|         return  | 
|       | 
|     moneyType = IpyGameDataPY.GetFuncCfg("TreeLVUP", 1)  | 
|     if not PlayerControl.PayMoney(curPlayer, moneyType, needMoney, "TreeLVUP", {"treeLV":treeLV}):  | 
|         return  | 
|     needTime = ipyData.GetLVUPNeedTime()  | 
|       | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPState, 1)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRemainTime, needTime)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRefreshTime, int(time.time()))  | 
|     GameWorld.DebugLog("ÏÉÊ÷ÇëÇó¿ªÊ¼Éý¼¶! treeLV=%s,nextTreeLV=%s,needTime=%s" % (treeLV, nextTreeLV, needTime), playerID)  | 
|     SyncTreeInfo(curPlayer)  | 
|     return  | 
|   | 
| #// B2 24 Ê¹ÓÃÏÉÊ÷Éý¼¶¼õʱÎïÆ· #tagCMUseTreeLVUPTimeItem  | 
| #  | 
| #struct    tagCMUseTreeLVUPTimeItem  | 
| #{  | 
| #    tagHead         Head;  | 
| #    DWORD        UseCount;    // Ê¹ÓøöÊý  | 
| #    BYTE        IsAutoBuy;    // ²»×ã¸öÊýÊÇ·ñ×Ô¶¯¹ºÂò  | 
| #};  | 
| def OnUseTreeLVUPTimeItem(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     useCount = clientData.UseCount  | 
|     isAutoBuy = clientData.IsAutoBuy  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     lvupState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)  | 
|     LVUPRemainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRemainTime)  | 
|     if not lvupState or not LVUPRemainTime:  | 
|         GameWorld.DebugLog("ÏÉÊ÷·ÇÉý¼¶ÖлòÊ£Óàʱ¼äΪ0£¬²»ÐèÒª¼õÉÙʱ¼ä! lvupState=%s,LVUPRemainTime=%s"   | 
|                            % (lvupState, LVUPRemainTime), playerID)  | 
|         return  | 
|       | 
|     costItemID, reduceSeconds = IpyGameDataPY.GetFuncEvalCfg("TreeLVUP", 2)  | 
|     GameWorld.DebugLog("ʹÓÃÏÉÊ÷Éý¼¶¼õʱÎïÆ·! costItemID=%s,reduceSeconds=%s,useCount=%s" % (costItemID, reduceSeconds, useCount), playerID)  | 
|     if not costItemID or not useCount:  | 
|         return  | 
|       | 
|     costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, useCount)  | 
|     lackCnt = useCount - bindCnt - unBindCnt  | 
|     if lackCnt > 0 and not isAutoBuy:  | 
|         GameWorld.DebugLog("ÏûºÄµÀ¾ß²»×ã! costItemID=%s,useCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s"   | 
|                            % (costItemID, useCount, bindCnt, unBindCnt, lackCnt), playerID)  | 
|         return  | 
|       | 
|     delCnt = useCount  | 
|     if lackCnt > 0:  | 
|         moneyType = IPY_GameWorld.TYPE_Price_Gold_Money  | 
|         lackCost = ItemCommon.GetAutoBuyItemNeedGold({costItemID:lackCnt})  | 
|         if lackCost <= 0:  | 
|             return  | 
|         GameWorld.DebugLog("×Ô¶¯¹ºÂòµÀ¾ß: lackCnt=%s,moneyType=%s,lackCost=%s" % (lackCnt, moneyType, lackCost), playerID)  | 
|         infoDict = {ChConfig.Def_Cost_Reason_SonKey:costItemID}  | 
|         if not PlayerControl.PayMoney(curPlayer, moneyType, lackCost, ChConfig.Def_Cost_BuyStoreItem, infoDict):  | 
|             return  | 
|         delCnt -= lackCnt  | 
|           | 
|     # ¿Û³ýÏûºÄ  | 
|     if delCnt:  | 
|         ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, "TreeLVUPTimeItem")  | 
|           | 
|     reduceTime = reduceSeconds * useCount  | 
|     ReduceTreeLVUPTime(curPlayer, reduceTime)  | 
|     return  | 
|   | 
| def RefreshTreeLVUPTime(curPlayer):  | 
|     ## Ë¢ÐÂÏÉÊ÷Éý¼¶Ê£Óàʱ¼ä  | 
|     lvupState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)  | 
|     LVUPRemainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRemainTime)  | 
|     if not lvupState or not LVUPRemainTime:  | 
|         return  | 
|     curTime = int(time.time())  | 
|     lastRefreshTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRefreshTime)  | 
|     if not lastRefreshTime:  | 
|         lastRefreshTime = curTime  | 
|     passSeconds = max(0, curTime - lastRefreshTime)  | 
|     updLVUPRemainTime = max(0, LVUPRemainTime - passSeconds)  | 
|       | 
|     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRemainTime, updLVUPRemainTime)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRefreshTime, curTime)  | 
|     GameWorld.DebugLog("Ë¢ÐÂÏÉÊ÷Éý¼¶Ê£Óàʱ¼ä! updLVUPRemainTime=%s,treeLV=%s,LVUPRemainTime=%s,passSeconds=%s,lastRefreshTime=%s"   | 
|                        % (updLVUPRemainTime, treeLV, LVUPRemainTime, passSeconds, lastRefreshTime), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def ReduceTreeLVUPTime(curPlayer, reduceTime):  | 
|     ## ¼õÉÙÏÉÊ÷Éý¼¶Ê£Óàʱ¼ä£¬¿ÉÄÜÊÇʹÓõÀ¾ß»òÆäËû¹¦ÄÜµÈ  | 
|     RefreshTreeLVUPTime(curPlayer)  | 
|     lvupState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)  | 
|     LVUPRemainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRemainTime)  | 
|     if not lvupState or not LVUPRemainTime:  | 
|         GameWorld.DebugLog("ÏÉÊ÷·ÇÉý¼¶ÖлòÊ£Óàʱ¼äΪ0£¬²»ÐèÒª¼õÉÙʱ¼ä! lvupState=%s,LVUPRemainTime=%s"   | 
|                            % (lvupState, LVUPRemainTime), curPlayer.GetPlayerID())  | 
|         return  | 
|     updLVUPRemainTime = max(0, LVUPRemainTime - reduceTime)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRemainTime, updLVUPRemainTime)  | 
|     GameWorld.DebugLog("¼õÉÙÏÉÊ÷Éý¼¶Ê£Óàʱ¼ä! updLVUPRemainTime=%s,LVUPRemainTime=%s,reduceTime=%s"   | 
|                        % (updLVUPRemainTime, LVUPRemainTime, reduceTime), curPlayer.GetPlayerID())  | 
|     SyncTreeInfo(curPlayer)  | 
|     return True  | 
|   | 
| def DoTreeLVUP(curPlayer):  | 
|     ## Ö´ÐÐÏÉÊ÷Éý¼¶  | 
|     RefreshTreeLVUPTime(curPlayer)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     lvupState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)  | 
|     if not lvupState:  | 
|         GameWorld.DebugLog("ÏÉÊ÷·ÇÉý¼¶ÖУ¬ÎÞ·¨Ö´ÐÐÉý¼¶! lvupState=%s" % lvupState, playerID)  | 
|         return  | 
|     LVUPRemainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRemainTime)  | 
|     if LVUPRemainTime > 0:  | 
|         GameWorld.DebugLog("ÏÉÊ÷Éý¼¶Ê£Óàʱ¼äδµ½£¬ÎÞ·¨Ö´ÐÐÉý¼¶! LVUPRemainTime=%s" % LVUPRemainTime, playerID)  | 
|         return  | 
|       | 
|     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)  | 
|     updTreeLV = treeLV + 1  | 
|     ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", updTreeLV)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLV, updTreeLV)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPState, 0)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRemainTime, 0)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLVUPRefreshTime, 0)  | 
|     GameWorld.DebugLog("Ö´ÐÐÏÉÊ÷Éý¼¶! updTreeLV=%s" % updTreeLV, playerID)  | 
|     SyncTreeInfo(curPlayer)  | 
|       | 
|     PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_TreeLV)  | 
|     return  | 
|   | 
| def SyncTreeInfo(curPlayer):  | 
|     clientPack = ChPyNetSendPack.tagMCTreeInfo()  | 
|     clientPack.TreeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)  | 
|     clientPack.LVUPState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)  | 
|     clientPack.LVUPRemainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRemainTime)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| def SyncCutTreeResult(curPlayer, equipCount, giveItemListEx):  | 
|     clientPack = ChPyNetSendPack.tagMCCutTreeResult()  | 
|     clientPack.EquipCount = equipCount  | 
|     clientPack.ExItemList = []  | 
|     for itemID, itemCount, _ in giveItemListEx:  | 
|         item = ChPyNetSendPack.tagMCCutTreeExItem()  | 
|         item.ItemID = itemID  | 
|         item.ItemCount = itemCount  | 
|         clientPack.ExItemList.append(item)  | 
|     clientPack.ExItemCount = len(clientPack.ExItemList)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  |