| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| ##@package PlayerControl  | 
| # @todo: Íæ¼Ò¿ØÖÆÆ÷  | 
| #  | 
| # @author Alee  | 
| # @date 2010-02-20 16:30  | 
| # @version 1.0  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2017-07-17 15:00"""  | 
| #---------------------------------------------------------------------  | 
| import GameWorld  | 
| import ChEquip  | 
| import SkillShell  | 
| import ChConfig  | 
| import EventShell  | 
| import EffGetSet  | 
| import PlayerHorse  | 
| import PlayerTruck  | 
| import PlayerTrade  | 
| import PlayerTeam  | 
| import SkillCommon  | 
| import GameMap  | 
| import FBLogic  | 
| import GameWorldProcess  | 
| import NPCCommon  | 
| import ItemCommon  | 
| import ReadChConfig  | 
| import PlayerGMOper  | 
| import BuffSkill  | 
| import PetControl  | 
| import OperControlManager  | 
| import PlayerFamily  | 
| import ShareDefine  | 
| import PlayerBillboard  | 
| import GameServerRefresh  | 
| import IPY_GameWorld  | 
| import PlayerGameWallow  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import DataRecordPack  | 
| import CalcNoLineEffect  | 
| import CalcLineEffect  | 
| import PlayerEquipDecompose  | 
| import FormulaControl  | 
| import PlayerDienstgrad  | 
| import PlayerPrestigeSys  | 
| import OpenServerCampaign  | 
| import PlayerGodWeapon  | 
| import PlayerExpandPackCfgMgr  | 
| import PlayerWorldAverageLv  | 
| import PlayerActivity  | 
| import FBCommon  | 
| import PlayerViewCacheTube  | 
| import PassiveBuffEffMng  | 
| import PlayerGameEvent  | 
| import EventReport  | 
| import PlayerGatherSoul  | 
| import PlayerSuccess  | 
| import PlayerPet  | 
| import PlayerGreatMaster  | 
| import ItemControler  | 
| import GameFuncComm  | 
| import IpyGameDataPY  | 
| import PlayerRune  | 
| import GameLogic_DuJie  | 
| import PyGameData  | 
| import PlayerMagicWeapon  | 
| import PlayerFeastTravel  | 
| import PlayerActTurntable  | 
| import GameLogic_SealDemon  | 
| import GameLogic_ZhuXianBoss  | 
| import GameLogic_CrossDemonKing  | 
| import PlayerTJG  | 
| import PlayerVip  | 
| import PlayerRefineStove  | 
| import PlayerFamilyTech  | 
| import PlayerFamilyZhenfa  | 
| import PlayerCostRebate  | 
| import PlayerActGarbageSorting  | 
| import GY_Query_CrossRealmReg  | 
| import PlayerTongTianLing  | 
| import PlayerCrossRealmPK  | 
| import FunctionNPCCommon  | 
| import IPY_PlayerDefine  | 
| import CrossRealmPlayer  | 
| import CrossPlayerData  | 
| import NPCHurtManager  | 
| import ChNetSendPack  | 
| import PlayerLianTi  | 
| import PlayerCoat  | 
| import PlayerAssist  | 
| import PlayerState  | 
| import QuestCommon  | 
| import PlayerDogz  | 
| import PlayerFaQi  | 
| import PlayerLove  | 
| import PlayerGubao  | 
| import PlayerShentong  | 
| import PlayerCharm  | 
| import ChPlayer  | 
| import GMShell  | 
| import GameObj  | 
|   | 
| import random  | 
| import types  | 
| import math  | 
| import time  | 
| import json  | 
| #---------------------------------------------------------------------  | 
| #ÐÅÏ¢ÌáʾÁÐ±í  | 
| NotifyCodeList = IPY_GameWorld.IPY_NotifyCodeList()  | 
|   | 
| #buff×Ö¶ÎDieContinueλ±íʾ±êʶ  | 
| Def_Buff_Clear_Die = 0x1  # ËÀÍöÇå³ýbuff  | 
| Def_Buff_Clear_Disconnect = 0x2  # ÏÂÏßÇå³ýbuff  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##¿Í»§¶Ë·¢ËÍÒÆ¶¯·â°ü¼ì²é  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param clientWorldTick ÉÏ´ÎÒÆ¶¯Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÕæ, ¿ÉÒÔÒÆ¶¯  | 
| # @remarks ¿Í»§¶Ë·¢ËÍÒÆ¶¯·â°ü¼ì²é  | 
| def PlayerMoveCheckClientWorldTick(curPlayer, clientWorldTick, sendPack_PosX, sendPack_PosY):  | 
|     gameWorldTick = GameWorld.GetGameWorld().GetTick()  | 
|     Def_Max_Move_Tick = 5000  | 
|    | 
|     if abs(gameWorldTick - clientWorldTick) >= Def_Max_Move_Tick:  | 
|         curPlayer.Sync_ClientTick()  | 
|         #ʱ¼äÏà²î¹ý´ó£¬¿ÉÄÜÒòÍøÂçÒýÆð£¬À»Ø  | 
|         GameWorld.DebugLog("PlayerMoveCheckClientWorldTick -- ·þÎñÆ÷tick %s-¿Í»§¶Ë%sʱ¼äÏà²î¹ý´ó£¬¿ÉÄÜÒòÍøÂçÒýÆð£¬À»Ø" % (  | 
|                             gameWorldTick, clientWorldTick), curPlayer.GetID())  | 
|         return False  | 
|       | 
|     if gameWorldTick - curPlayer.GetDictByKey("CheckTick") > 60000:  | 
|         # 1·ÖÖÓ¾ÀÕýÒ»´Îtick,ͬʱÓÃÓÚÕ½¶·ºÍÒÆ¶¯µÄ¼ì²é  | 
|         curPlayer.SetMoveCount(0)  | 
|         curPlayer.SetDict("CheckTick", gameWorldTick)  | 
|       | 
|     lastMoveTick = curPlayer.GetClientMoveTick()  | 
|     if clientWorldTick < lastMoveTick:  | 
|         #and GameWorld.GetGameWorld().GetTick() - curPlayer.GetLoginTick() > 15000:  | 
|         #Íæ¼ÒµÇÈëʱ¼ä´óÓÚ15Ãë, ²Å»áÌß³öÍæ¼Ò  | 
|         #2009.4.16. bug:  | 
|         #Íæ¼ÒÇл»µØÍ¼, ·þÎñÆ÷»º´æ×ß··â°ü, µ½´ïеØÍ¼, »º´æÖеķâ°üÊÕµ½, ½á¹ûÌß³öÁËÍæ¼Ò  | 
|         GameWorld.DebugLog('---clientWorldTick < lastMoveTick: %s, TickÌ«Âý' % curPlayer.GetAccID())  | 
|         #curPlayer.Kick(IPY_GameWorld.disTickError)  | 
|         errCnt = curPlayer.GetMoveCount()  | 
|         curPlayer.SetMoveCount(errCnt + 1)  | 
|         if errCnt > 5:  | 
|             return False  | 
|       | 
|     # ÑéÖ¤Á½´Îtick¼ä¿ÉÄܲúÉúµÄ×ø±ê²î  | 
|     dist = GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), sendPack_PosX, sendPack_PosY)  | 
|     canMoveDist = math.ceil((clientWorldTick - lastMoveTick) / float(curPlayer.GetSpeed())) + 2  | 
|     #if clientWorldTick - curPlayer.GetPlayerAttackTick() < GetAtkInterval(curPlayer):  | 
|     #    # ¹¥»÷²úÉúµÄÎ»ÒÆ¿ÉÄÜÒòΪ¹¥»÷ËÙ¶È¸Ä±ä¶ø±ä¿ì£¬¹¥»÷ÆÚ¼äµÄÒÆ¶¯°üÔÊÐí¶àÒÆ¶¯1Ã×µÄËÙ¶È  | 
|     #    canMoveDist += 2  | 
|           | 
|     if dist > canMoveDist:  | 
|         GameWorld.DebugLog("¾àÀë²î%s ×ø±êS/C:%s---ÑéÖ¤Á½´Îtick¼ä¿ÉÄܲúÉúµÄ×ø±ê²î%s %s - %s" % (dist, [curPlayer.GetPosX(),  | 
|                             curPlayer.GetPosY(), sendPack_PosX, sendPack_PosY], canMoveDist, clientWorldTick, lastMoveTick))  | 
|         errCnt = curPlayer.GetMoveCount()  | 
|         curPlayer.SetMoveCount(errCnt + 1)  | 
|         if errCnt > 5:  | 
|             return False  | 
|       | 
|     #ʱ¼ä²î  | 
| #    curPlayer.UpdatePosByTick(gameWorldTick - clientWorldTick + gameWorldTick)  | 
|     #curPlayer.UpdatePos()  | 
|     return True  | 
|   | 
|   | 
| # notifyCnt ´ú±í¹ã²¥ÖÜÎ§Íæ¼ÒµÄÊýÁ¿£¬0Ϊȫ²¿¹ã²¥ -1Ϊָ¶¨ÁбíËæ»ú£¬ ÆäËûÊý×ÖΪָ¶¨Ö¸  | 
| def PyNotifyAll(curPlayer, sendPack, notifySelf=True, notifyCnt=0):  | 
|     if notifyCnt == -1:  | 
|         notifyCnt = 8  | 
|     #GameWorld.DebugLog("PyNotifyAll %s"%notifyCnt)  | 
|   | 
|     curPlayer.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength(), notifySelf, notifyCnt)  | 
|       | 
|       | 
| #---------------------------------------------------------------------  | 
| ##Ö´ÐÐÍæ¼ÒÔÚÕϰµãÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ²¼¶ûÖµ, FlaseÎªÍæ¼Ò²»ÔÚÕϰµãÖÐ  | 
| # @remarks Ö´ÐÐÍæ¼ÒÔÚÕϰµãÂß¼  | 
| def DoLogic_PlayerInBarrierPoint(curPlayer):  | 
|     curPlayerPosX = curPlayer.GetPosX()  | 
|     curPlayerPosY = curPlayer.GetPosY()  | 
|     curPlayerID = curPlayer.GetID()  | 
|       | 
|     #---Íæ¼Ò²»ÔÚÕϰµãÖÐ---  | 
|     if GameWorld.GetMap().CanMove(curPlayerPosX, curPlayerPosY):  | 
|         return False  | 
|       | 
|     #---Íæ¼ÒÔÚÕϰµãÖÐ---  | 
|       | 
|     #ÔÚÕϰµã¸½¼þ2¸ñѰÕÒºÏÊÊλÖà  | 
|     curFindPos = GameMap.GetEmptyPlaceInArea(curPlayerPosX, curPlayerPosY, 3)  | 
|     curFindPosX = curFindPos.GetPosX()  | 
|     curFindPosY = curFindPos.GetPosY()  | 
|       | 
|     #Íæ¼ÒÎÞ·¿É×ß  | 
|     if curFindPosX == curPlayerPosX and curFindPosY == curPlayerPosY:  | 
|         curPlayer.StopMove()  | 
| #===============================================================================  | 
| #            playerControl = PlayerControl(curPlayer)  | 
| #            playerControl.SetToBornPlace()  | 
| #===============================================================================  | 
|         GameWorld.Log("Íæ¼ÒÎÞ·¿É×ß, ´ò»ØÖØÉúµã!(%d,%d)" % (curPlayerPosX, curPlayerPosY), curPlayerID)  | 
|     #ÕϰµãÖܱ߿ÉÒÔÒÆ¶¯, ½«Íæ¼ÒÖÃλ  | 
|     else:  | 
|         curPlayer.ResetPos(curFindPosX, curFindPosY)  | 
|         curPlayer.StopMove()  | 
|         GameWorld.Log("Íæ¼ÒÕ¾ÔÚÕϰµãÖÐ, Í£Ö¹Òƶ¯ (%d,%d)" % (curPlayerPosX, curPlayerPosY), curPlayerID)  | 
|           | 
|     return True  | 
| #---------------------------------------------------------------------  | 
| ## ÏûÏ¢Ìáʾ  | 
| #  @param curPlayer ÌáʾµÄÍæ¼Ò  | 
| #  @param msgMark ÌáʾÐÅÏ¢Mark  | 
| #  @param msgParamList ÐÅÏ¢²ÎÊýÁÐ±í  | 
| #  @return ÎÞ·µ»ØÖµ  | 
| #  @remarks   | 
| def NotifyCode(curPlayer, msgMark, msgParamList=[]):  | 
|     if curPlayer == None:  | 
|         GameWorld.ErrLog('NotifyCode Player = None')  | 
|         return  | 
|         | 
|     curPlayer.NotifyCode(msgMark, __GetNotifyCodeList(msgParamList))  | 
|     return  | 
|       | 
| ## ÊÀ½ç¹ã²¥  | 
| #  @param country ÌáʾµÄ¹ú¼Ò  | 
| #  @param msgMark ÌáʾÐÅÏ¢Mark  | 
| #  @param msgParamList ÐÅÏ¢²ÎÊýÁÐ±í  | 
| #  @param lineID:Ïß·ID£¨Ä¬ÈÏ0£¬±íʾȫ·þ¹ã²¥£©  | 
| #  @param mergeMinOSD ¸ÃÌáʾÕë¶Ô¿ç·þ×Ó·þÓÐЧµÄ×îС¿ª·þÌì, >=0ʱÓÐÏÞÖÆ  | 
| #  @param mergeMaxOSD ¸ÃÌáʾÕë¶Ô¿ç·þ×Ó·þÓÐЧµÄ×î´ó¿ª·þÌì, >=0ʱÓÐÏÞÖÆ  | 
| #  @param mergeMapInfo ¸ÃÌáʾËùÊôµÄ¿ç·þ»î¶¯µØÍ¼ÐÅÏ¢, Ö÷ÒªÓÃÓÚ²»Í¬×Ó·þ¶ÔÓ¦Ëù¿çµÄ»î¶¯µØÍ¼ID  | 
| #  @return ÎÞ·µ»ØÖµ  | 
| def WorldNotify(country, msgMark, msgParamList=[], lineID=0, mergeMinOSD=-1, mergeMaxOSD=-1, mergeMapInfo=[]):  | 
|     GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(country, 0, msgMark, __GetNotifyCodeList(msgParamList), lineID)  | 
|     return  | 
|   | 
| def GetCrossWorldNotifyInfo(country, msgMark, msgParamList=[]):  | 
|     return {"Type":ShareDefine.CrossNotify_World, "Params":[country, msgMark, msgParamList]}  | 
|   | 
| def GetCrossFamilyNotifyInfo(familyID, msgMark, msgParamList=[]):  | 
|     return {"Type":ShareDefine.CrossNotify_Family, "Params":[familyID, msgMark, msgParamList]}  | 
|   | 
| def CrossNotify(serverGroupIDList, crossNotifyList):  | 
|     ''' ¿ç·þ¹ã²¥ÐÅÏ¢Ìáʾ£¬Ö§³Öͬ²½¶àÌõ£¬Í¬Ê±Ò²½¨Òé¶àÌõÒ»Æðͬ²½  | 
|     @param serverGroupIDList: ÐèҪͬ²½µ½µÄÄ¿±ê·þÎñÆ÷×éIDÁÐ±í  | 
|     @param crossNotifyList: ÐÅÏ¢ÌáʾÁÐ±í£¬Í¨¹ý GetCrossWorldNotifyInfo GetCrossFamilyNotifyInfo º¯Êý»ñµÃ·µ»ØÖµÌí¼Óµ½ÁÐ±í  | 
|     '''  | 
|     sendMsg = str([serverGroupIDList, crossNotifyList])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossNotify", sendMsg, len(sendMsg))  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## ¼Ò×å¹ã²¥  | 
| #  @param familyID ÌáʾµÄ¼Ò×åID  | 
| #  @param msgMark ÌáʾÐÅÏ¢Mark  | 
| #  @param msgParamList ÐÅÏ¢²ÎÊýÁÐ±í  | 
| #  @return ÎÞ·µ»ØÖµ  | 
| #  @remarks   | 
| def FamilyNotify(familyID, msgMark, msgParamList=[]):  | 
|     GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(0, familyID, msgMark, __GetNotifyCodeList(msgParamList))  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##±¾µØÍ¼ÄÚµÄ֪ͨ  | 
| #  @param msgMark ÌáʾÐÅÏ¢Mark  | 
| #  @param msgParamList ÐÅÏ¢²ÎÊýÁÐ±í  | 
| #  @return ÎÞ·µ»ØÖµ  | 
| #  @remarks   | 
| def FBNotify(msgMark, msgParamList=[]):  | 
|     GameWorld.GetMapCopyPlayerManager().BroadcastFB_NotifyCode(msgMark, __GetNotifyCodeList(msgParamList))  | 
|     return  | 
|   | 
| def FBFactionNotifySelf(faction, msgMark, msgParamList=[]):  | 
|     ## ¸±±¾×Ô¼ºÕóÓª¹ã²¥  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|         if curPlayer.GetFaction() == faction:  | 
|             NotifyCode(curPlayer, msgMark, msgParamList)  | 
|     return  | 
|   | 
| def FBFactionNotifyOther(faction, msgMark, msgParamList=[]):  | 
|     ## ¸±±¾ÆäËûÕóÓª¹ã²¥  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|         if curPlayer.GetFaction() != faction:  | 
|             NotifyCode(curPlayer, msgMark, msgParamList)  | 
|     return  | 
|   | 
| def FBFactionNotify(faction, selfMsgMark, selfMsgParamList, otherMsgMark, otherMsgParamList):  | 
|     ## ¸±±¾¹ã²¥×Ô¼º¼°ÆäËûÕóÓª£¬Çø·Ö¹ã²¥ÐÅÏ¢  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|         if curPlayer.GetFaction() == faction:  | 
|             NotifyCode(curPlayer, selfMsgMark, selfMsgParamList)  | 
|         else:  | 
|             NotifyCode(curPlayer, otherMsgMark, otherMsgParamList)  | 
|     return  | 
|   | 
| ## ¶ÓÎé¹ã²¥  | 
| #  @param teamID ¶ÓÎéID  | 
| #  @param msgMark ÌáʾÐÅÏ¢Mark  | 
| #  @param msgParamList ÐÅÏ¢²ÎÊýÁÐ±í  | 
| #  @return ÎÞ·µ»ØÖµ  | 
| def TeamNotify(teamID, msgMark, msgParamList=[]):  | 
|     if teamID == 0:  | 
|         return  | 
|       | 
|     sendMsg = '("%s", %s)' % (msgMark, msgParamList)  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, teamID, 'TeamNotify', sendMsg, len(sendMsg))  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| def SendMailBatch(mailTypeKey, batchPlayerIDList, batchAddItemList=[], batchParamList=[], batchGold=[], batchGoldPaper=[], batchSilver=[], batchDetail=[], moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):  | 
|     '''ÅúÁ¿·¢ËÍÓʼþ, ÓÃÓÚ˲¼äÐèÒª·¢ËͶà·â£¨´óÁ¿£©ÓʼþµÄ£¬±ÈÈçһЩ¹«¹²¸±±¾»î¶¯µÈ½áËãʱ  | 
|     @param mailTypeKey: ÓʼþÄ£°åkey  | 
|     @param batchPlayerIDList: [playerIDList, playerIDList, ...]  | 
|     @param batchAddItemList: [addItemList, addItemList, ...]  | 
|     @param batchParamList: [paramList, paramList, ...]  | 
|     @param batchGold: [batchGold, batchGold, ...]  | 
|     @param batchGoldPaper: [batchGoldPaper, batchGoldPaper, ...]  | 
|     @param batchSilver: [batchSilver, batchSilver, ...]  | 
|     @param batchDetail: [¼Ç¼ÓʼþÁ÷ÏòÓÃ, ...]  | 
|     @param moneySource: »õ±ÒÀ´Ô´  | 
|     '''  | 
|       | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i, playerIDList in enumerate(batchPlayerIDList):  | 
|         for playerID in playerIDList[::-1]:  | 
|             curPlayer = copyMapPlayerManager.FindPlayerByID(playerID)  | 
|             if curPlayer and not curPlayer.GetGameServerInitOK():  | 
|                 bAddItemList = [batchAddItemList[i]] if len(batchAddItemList) > i else []  | 
|                 bParamList = [batchParamList[i]] if len(batchParamList) > i else []  | 
|                 bGold = [batchGold[i]] if len(batchGold) > i else []  | 
|                 bGoldPaper = [batchGoldPaper[i]] if len(batchGoldPaper) > i else []  | 
|                 bSilver = [batchSilver[i]] if len(batchSilver) > i else []  | 
|                 bDetail = [batchDetail[i]] if len(batchDetail) > i else []  | 
|                 AddUnLoginOKPlayerMailCache(playerID, "ByMailTemplate", [mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail])  | 
|                 playerIDList.pop(playerIDList.index(playerID))  | 
|                 continue  | 
|               | 
|     msgInfo = str([mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource, crossMail])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendMailBatch", msgInfo, len(msgInfo))  | 
|     GameWorld.Log("SendMailBatch %s, batchPlayerIDList=%s, batchAddItemList=%s, batchParamList=%s, batchGold=%s, batchGoldPaper=%s, batchSilver=%s"   | 
|                   % (mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver))  | 
|     return  | 
|   | 
| def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):  | 
|     '''  | 
|     @param detail: ¼Ç¼ÓʼþÁ÷ÏòÓà  | 
|     '''  | 
|     if not mailTypeKey:  | 
|         mailTypeKey = ShareDefine.DefaultLackSpaceMailType  | 
|       | 
|     content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, json.dumps(paramList, ensure_ascii=False))  | 
|     SendMail("", content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)  | 
|     return  | 
|   | 
| def SendCrossMail(serverGroupID, mailTypeKey, playerIDList, addItemList, paramList=[]):  | 
|     ## ·¢ËÍ¿ç·þÓʼþ  | 
|     if not serverGroupID:  | 
|         return  | 
|     dataMsg = {"MailTypeKey":mailTypeKey, "Player":playerIDList}  | 
|     if addItemList:  | 
|         dataMsg["Item"] = CombineMailItem(addItemList)  | 
|     if paramList:  | 
|         dataMsg["Param"] = paramList  | 
|     GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_SendMail, dataMsg, [serverGroupID])  | 
|     return  | 
|   | 
| def SendEntireMail(mailTypeKey, getDays, limitLV, limitLVType, addItemList=[], paramList=[], \  | 
|                    gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail):  | 
|     ''' ·¢ËÍÈ«·þÓʼþ  | 
|     @param mailTypeKey: ÓʼþÄ£°åkey  | 
|     @param getDays: ÓÐЧÌìÊý  | 
|     @param limitLV: ÁìÈ¡×îµÍµÈ¼¶ÏÞÖÆ  | 
|     @param limitLVType: µÈ¼¶²»×ãµÄÉý¼¶ºóÊÇ·ñ¿ÉÁì 0-²»¿É£¬1-¿ÉÒÔ  | 
|     '''  | 
|       | 
|     # ÓÐЧÌìÊýÏÞÖÆ  | 
|     if not mailTypeKey or getDays <= 0:  | 
|         return  | 
|       | 
|     # ¿ç·þ·þÎñÆ÷²»ÔÊÐí·¢ËÍÓʼþ  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     combineItemList = CombineMailItem(addItemList)  | 
|     cmdList = [mailTypeKey, getDays, limitLV, limitLVType, combineItemList, paramList, gold, goldPaper, silver, detail, moneySource]  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendEntireMail", '%s' % (cmdList), len(str(cmdList)))  | 
|     GameWorld.Log("·¢ËÍÈ«·þÓʼþ: %s,getDays=%s,limitLV=%s,limitLVType=%s,combineItemList=%s,paramList=%s,gold=%s,goldPaper=%s,silver=%s,detail=%s,moneySource=%s" %   | 
|                   (mailTypeKey, getDays, limitLV, limitLVType, combineItemList, paramList, gold, goldPaper, silver, detail, moneySource))  | 
|     return  | 
|   | 
| ## ¹¦ÄÜ·¢·ÅÎïÆ·²¹³¥/½±ÀøÓʼþ  | 
| #  @param addItemList [(itemID, itemCnt, ÊÇ·ñÅÄÆ·), {»òÎïÆ·ÐÅÏ¢×Öµä}, ...]  | 
| #  @return  | 
| def SendMail(title, content, getDays, playerIDList, addItemList, gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):  | 
|     if not playerIDList:  | 
|         return  | 
|       | 
| #    if not addItemList:  | 
| #        return  | 
|       | 
|     # ÓÐЧÌìÊýÏÞÖÆ  | 
|     if getDays <= 0:  | 
|         return  | 
|       | 
|     # ¿ç·þ·þÎñÆ÷²»ÔÊÐí·¢ËÍÓʼþ  | 
|     if GameWorld.IsCrossServer() and not crossMail:  | 
|         return  | 
|       | 
|     sendPlayerIDList = []  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for playerID in playerIDList:  | 
|         curPlayer = copyMapPlayerManager.FindPlayerByID(playerID)  | 
|         if curPlayer and not curPlayer.GetGameServerInitOK():  | 
|             AddUnLoginOKPlayerMailCache(playerID, "ByMailContent", [title, content, getDays, addItemList, gold, goldPaper, silver, detail, moneySource])  | 
|             continue  | 
|         sendPlayerIDList.append(playerID)  | 
|           | 
|     combineItemList = CombineMailItem(addItemList)  | 
|     cmdList = [title, content, getDays, sendPlayerIDList, combineItemList, gold, goldPaper, silver, detail, moneySource, crossMail]  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendMail", '%s' % (cmdList), len(str(cmdList)))  | 
|     return True  | 
|   | 
| def AddUnLoginOKPlayerMailCache(playerID, cacheType, mailInfo):  | 
|     ''' Ìí¼ÓδµÇ¼³É¹¦µÄÍæ¼Ò¸öÈËÓʼþ·¢ËÍ»º´æ  | 
|     '''  | 
|     if playerID not in PyGameData.g_unLoginOKPlayerMailInfo:  | 
|         PyGameData.g_unLoginOKPlayerMailInfo[playerID] = []  | 
|     mailList = PyGameData.g_unLoginOKPlayerMailInfo[playerID]  | 
|     if [cacheType, mailInfo] in mailList:  | 
|         GameWorld.Log("###ÖØ¸´Ìí¼ÓGetGameServerInitOKδµÇ¼³É¹¦µÄÍæ¼Ò¸öÈËÓʼþ·¢ËÍ»º´æ! ²»Ìí¼Ó! mailCount=%s, mailInfo=%s"   | 
|                       % (len(mailList), str(mailInfo)), playerID)  | 
|         return  | 
|     if len(mailList) >= 30: # ×ö¸öÏÞÖÆ£¬·ÀÖ¹³öÎÊÌâË¢Óʼþ  | 
|         GameWorld.Log("###ÏÞÖÆÌí¼ÓGetGameServerInitOKδµÇ¼³É¹¦µÄÍæ¼Ò¸öÈËÓʼþ·¢ËÍ»º´æ! ³¬³ö×î´ó¿ÉÌí¼ÓÊý£¬²»Ìí¼Ó! mailCount=%s, mailInfo=%s"   | 
|                       % (len(mailList), str(mailInfo)), playerID)  | 
|         return  | 
|     mailList.append([cacheType, mailInfo])  | 
|     # curPlayer.GetGameServerInitOK()  | 
|     GameWorld.Log("Ìí¼ÓGetGameServerInitOKδµÇ¼³É¹¦µÄÍæ¼Ò¸öÈËÓʼþ·¢ËÍ»º´æ! µÈ´ý·¢ËÍ! mailCount=%s, mailInfo=%s"   | 
|                   % (len(mailList), str(mailInfo)), playerID)  | 
|     return  | 
|   | 
| def SendUnLoginOKPlayerMailCache(curPlayer):  | 
|     ## Î´µÇ¼³É¹¦µÄÍæ¼Ò¸öÈËÓʼþ·¢ËÍ»º´æ  - µÇ¼³É¹¦ºó´¦Àí  | 
|     if not curPlayer.GetGameServerInitOK():  | 
|         return  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_unLoginOKPlayerMailInfo:  | 
|         return  | 
|     mailList = PyGameData.g_unLoginOKPlayerMailInfo.pop(playerID)  | 
|     for cacheType, mailInfo in mailList:  | 
|         playerIDList = [playerID]  | 
|         GameWorld.Log("·¢ËÍδµÇ¼³É¹¦Ê±»º´æµÄ´ý·¢ËÍÓʼþ! cacheType=%s, mailInfo=%s" % (cacheType, str(mailInfo)), playerID)  | 
|         if cacheType == "ByMailContent":  | 
|             title, content, getDays, addItemList, gold, goldPaper, silver, detail, moneySource = mailInfo  | 
|             SendMail(title, content, getDays, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource)  | 
|         elif cacheType == "ByMailTemplate":  | 
|             mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail = mailInfo  | 
|             SendMailBatch(mailTypeKey, [playerIDList], bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail)  | 
|     return  | 
|   | 
| def CombineMailItem(addItemList):  | 
|     ## ºÏ²¢ÓʼþÎïÆ·  | 
|     itemCountDict = {}  | 
|     combineItemList = [] # ºÏ²¢ºóµÄÎïÆ·ÁÐ±í  | 
|     for mailItem in addItemList:  | 
|         if isinstance(mailItem, dict):  | 
|             combineItemList.append(mailItem)  | 
|             continue  | 
|           | 
|         if len(mailItem) != 3:  | 
|             continue  | 
|           | 
|         itemID, itemCnt, isAuctionItem = mailItem  | 
|           | 
|         if ItemControler.GetAppointItemRealID(itemID):  | 
|             # ¶¨ÖÆÎïÆ·×ª»¯ÎªÎïÆ·ÐÅÏ¢×Öµä  | 
|             appointItemObj = ItemControler.GetItemByData(ItemControler.GetAppointItemDictData(itemID, isAuctionItem))  | 
|             if not appointItemObj:  | 
|                 GameWorld.ErrLog("Óʼþ¶¨ÖÆÎïÆ·×ª»¯Ê§°Ü£¡itemID, itemCnt, isAuctionItem" % (itemID, itemCnt, isAuctionItem))  | 
|                 continue  | 
|             combineItemList.append(ItemCommon.GetMailItemDict(appointItemObj))  | 
|             appointItemObj.Clear()  | 
|         elif isAuctionItem:  | 
|             combineItemList.append((itemID, itemCnt, isAuctionItem))  | 
|         else:  | 
|             key = (itemID, isAuctionItem)  | 
|             itemCountDict[key] = itemCountDict.get(key, 0) + itemCnt  | 
|               | 
|     for key, itemCnt in itemCountDict.items():  | 
|         itemID, isAuctionItem = key  | 
|         combineItemList.append((itemID, itemCnt, isAuctionItem))  | 
|     return combineItemList  | 
|   | 
| ## ¹¹½¨ÏµÍ³Ìáʾ²ÎÊýÁÐ±í  | 
| #  @param msgParamList ÐÅÏ¢²ÎÊýÁÐ±í  | 
| #  @return ÏµÍ³Ìáʾ²ÎÊýÁбí IPY_NotifyCodeList  | 
| #  @remarks   | 
| def __GetNotifyCodeList(msgParamList):  | 
|     #ÏûÏ¢ÌáʾÁбí, ÏÈÇåÔÚÌí¼Ó  | 
|     global NotifyCodeList  | 
|     NotifyCodeList.Clear()  | 
|       | 
|     if not msgParamList:  | 
|         return NotifyCodeList  | 
|       | 
|     for msg in msgParamList:  | 
|         itemPythonType = type(msg)  | 
|           | 
|         if itemPythonType is types.IntType:  | 
|             #PythonÒªÑéÖ¤ÕûÐͺͳ¤ÕûÐÍ  | 
|             NotifyCodeList.AddInt(msg)  | 
|         elif itemPythonType is types.LongType:  | 
|             NotifyCodeList.AddStr(str(msg))  | 
|         else:  | 
|             NotifyCodeList.AddStr(msg)  | 
|   | 
|     return NotifyCodeList  | 
| #---------------------------------------------------------------------  | 
| ##»ñµÃÍæ¼Òµ±Ç°ÀۼƵÄÀëÏß·ÖÖÓÊý  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ÀۼƵķÖÖÓÊý  | 
| # @remarks ¿Í»§¶Ë·â°üÏìÓ¦  | 
| def GetPlayerLeaveServerMinute(curPlayer):  | 
|     #µ±Ç°ÀëÏßʱ¼ä×Ö·û´«  | 
|     logoffTimeStr = curPlayer.GetLogoffTime()  | 
|   | 
|     if logoffTimeStr == "" or logoffTimeStr == '0':  | 
|         return 0  | 
|   | 
|     logoffTime = GameWorld.GetDateTimeByStr(logoffTimeStr)  | 
|     loginTime = GameWorld.GetDateTimeByStr(GameWorld.GetCurrentDataTimeStr())  | 
|   | 
|     return GameWorld.GetDiff_Minute(loginTime, logoffTime)  | 
|   | 
| ##»ñµÃÍæ¼Òµ±Ç°ÀۼƵÄÀëÏßÃëÊý  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ÀۼƵÄÃëÊý  | 
| # @remarks ¿Í»§¶Ë·â°üÏìÓ¦  | 
| def GetPlayerLeaveServerSecond(curPlayer):  | 
|     #µ±Ç°ÀëÏßʱ¼ä×Ö·û´«  | 
|     logoffTimeStr = curPlayer.GetLogoffTime()  | 
|   | 
|     if logoffTimeStr == "" or logoffTimeStr == '0':  | 
|         return 0  | 
|   | 
|     logoffTime = GameWorld.GetDateTimeByStr(logoffTimeStr)  | 
|     loginTime = GameWorld.GetDateTimeByStr(GameWorld.GetCurrentDataTimeStr())  | 
|   | 
|     diff_Time = loginTime - logoffTime  | 
|     #ÌìÊý * 24Сʱ * 60 ·ÖÖÓ + Ãë  | 
|     return diff_Time.days * 24 * 60 * 60 + diff_Time.seconds  | 
|   | 
|   | 
| ##»ñµÃÍæ¼Òµ±Ç°Ê±¼ä¾àÀëÉÏ´ÎÀëÏßʱ¼äµÄÌìÊý  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return   | 
| def GetPlayerLastLeaveServerPastDay(curPlayer):  | 
|     #µ±Ç°ÀëÏßʱ¼ä×Ö·û´«  | 
|     logoffTimeStr = curPlayer.GetLogoffTime()  | 
|   | 
|     if logoffTimeStr == "" or logoffTimeStr == '0':  | 
|         return 0  | 
|       | 
|     logoffTimeStr = logoffTimeStr.split()[0]  | 
|     loginTimeStr = GameWorld.GetCurrentDataTimeStr().split()[0]  | 
|       | 
|     logoffTime = GameWorld.GetDateTimeByStr(logoffTimeStr, ChConfig.TYPE_Time_Format_Day)  | 
|     loginTime = GameWorld.GetDateTimeByStr(loginTimeStr, ChConfig.TYPE_Time_Format_Day)  | 
|       | 
|     diffTime = loginTime - logoffTime  | 
|       | 
|     return diffTime.days  | 
|       | 
| #---------------------------------------------------------------------  | 
| ## ¼ì²éÍæ¼Ò״̬ÊÇ·ñ¿ÉÒÔ´«ËÍ  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return ²¼¶ûÖµ  | 
| #  @remarks ¼ì²éÍæ¼Ò״̬ÊÇ·ñ¿ÉÒÔ´«ËÍ  | 
| def CheckPlayerTransport(curPlayer):  | 
|     #ËÀÍö²»¿ÉʹÓà  | 
|     if GameObj.GetHP(curPlayer) <= 0:  | 
|         return False  | 
|       | 
| #    if curPlayer.GetPKValue() > 0:  | 
| #        #PK_lhs_161795  | 
| #        NotifyCode(curPlayer, "PK_lhs_161795")  | 
| #        return False  | 
|       | 
|     #¼ì²éÍæ¼Ò״̬  | 
|     if not CheckTransState(curPlayer):  | 
|         return False  | 
|       | 
| #    #Ñ£ÔÎʱ£¬²»¿É´«ËÍ  | 
| #    if curPlayer.GetAbnormalState() == IPY_GameWorld.sctFaint:  | 
| #        return False  | 
|       | 
|     #=========================================================================================================  | 
|     # #ÀïÚ³µÖУ¬È˲»ÔÚïÚ³µÖÐÒ²²»ÄÜ´«ËÍ  | 
|     # if curPlayer.GetTruck() != None:  | 
|     #    NotifyCode(curPlayer, "HaveTruck_No_Trans")  | 
|     #    return False  | 
|     #=========================================================================================================  | 
|       | 
| #    #±»¹¥»÷ʱºò, ÎÞ·¨Ê¹Óà  | 
| #    if curPlayer.IsBattleState():  | 
| #        NotifyCode(curPlayer, "CannotAtk09")  | 
| #        return False  | 
| #      | 
| #    #¶ÔÖÅÖÐ, ÎÞ·¨Ê¹Óà  | 
| #    if curPlayer.GetIsConfronting():  | 
| #        NotifyCode(curPlayer, "CannotAtk09")  | 
| #        return False  | 
|       | 
|     #¼ì²éÍæ¼ÒÊÇ·ñÔÚÆÕͨµØÍ¼  | 
|     if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|         #²¿·Ö¸±±¾ÔÊÐí´«ËͳöÈ¥  | 
|         if GameWorld.GetMap().GetMapID() not in IpyGameDataPY.GetFuncEvalCfg('DungeonDeliver', 1):  | 
|             NotifyCode(curPlayer, "Carry_lhs_844170")   | 
|             return False  | 
|           | 
|     if not GameWorld.IsCrossServer() and GetCrossMapID(curPlayer):  | 
|         NotifyCode(curPlayer, "CrossMap10")   | 
|         return False  | 
|       | 
|     if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):  | 
|         GameWorld.Log("¿Í»§¶Ë×Ô¶¨Ò峡¾°ÏÂÎÞ·¨´«ËÍ!", curPlayer.GetPlayerID())  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
|   | 
| ##µØÍ¼ÌØÊâÏÞÖÆ¼ì²é, ×°±¸¼ì²é  | 
| # @param curPlayer  | 
| # @return bool  | 
| def CheckEquipCanTrans(curPlayer, destMapID):  | 
|     if destMapID != 10060:  | 
|         return True  | 
|       | 
|     #Óгá°ò¿ÉÒÔÉÏÌì¿Õ  | 
|     playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  | 
|     curEquip = playerEquip.GetAt(IPY_GameWorld.retWing)  | 
|     if curEquip and not curEquip.IsEmpty():  | 
|         return True  | 
|       | 
|     #GeRen_lhs_861048  | 
|     NotifyCode(curPlayer, "GeRen_lhs_861048", [destMapID])  | 
|     return False  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##֪ͨ¿Í»§¶Ë, Íæ¼ÒLoading¿ªÊ¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param prepareTime Loadingʱ¼ä  | 
| # @param prepareType LoadingÀàÐÍ  | 
| # @param prepareID LoadingNPCID, Ä¬ÈÏΪ0, ²»ÉèÖà  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Í¨Öª¿Í»§¶Ë, Íæ¼ÒLoading¿ªÊ¼  | 
| # ÌØÊâ˵Ã÷ChangePlayerAction -> SetPlayerAction ÖРÔÚÀÌõ״̬»á֪ͨ Sync_PrepareEnd£¬Ä¬ÈϽø¶ÈÌõÀàÐÍ  | 
| # Sync_PrepareEnd Í¨Öª0²ÅËã½ø¶ÈÌõ³É¹¦£¬ÆäËûΪʧ°Ü£¬×Ôµ÷ÓÃÂ߼ʱÇë×¢Òâ  | 
| def Sync_PrepareBegin(curPlayer, prepareTime, prepareType, prepareID=0):  | 
|     #ÖжÏÕ½¶·¶ÔÖÅ  | 
|     ExitPlayerConfronting(curPlayer)  | 
|     #´ò¶ÏÒÆ¶¯  | 
|     curPlayer.StopMove()  | 
|     #ÉèÖü¤»îÍæ¼Ò  | 
|     SetIsNeedProcess(curPlayer, True)  | 
|     #¿ªÊ¼Í¨ÖªLoading  | 
|     curPlayer.SetPrepareTime(prepareTime)  | 
|     curPlayer.SetPrepareState(prepareType)  | 
|     curPlayer.SetPrepareID(prepareID)  | 
|     curPlayer.Sync_PrepareBegin()  | 
|       | 
|     #¿ÕÏÐת±äΪÆäËû״̬Ôòɾ³ýÓÐÏÞÎÞµÐBUFF  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     DelLimitSuperBuff(curPlayer, tick)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò״̬¸Ä±ä  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param changeAction Çл»µÄ״̬  | 
| # @param forceChange ÊÇ·ñÇ¿ÖÆ×ª»»  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò״̬¸Ä±ä  | 
| def ChangePlayerAction(curPlayer, changeAction, forceChange=False):  | 
|     curPlayerAction = curPlayer.GetPlayerAction()  | 
|       | 
|     if curPlayerAction == changeAction:  | 
|         return  | 
|       | 
|     #״̬±ä¸üҪ֪ͨվÁ¢  | 
|     DoPlayerStand(curPlayer)  | 
|       | 
|     #ÖжÏÕ½¶·¶ÔÖÅ  | 
|     if changeAction in ChConfig.Def_PlayerCancelConfronting:  | 
|         ExitPlayerConfronting(curPlayer)  | 
|       | 
|     #ʼþ״̬²»Çл», ±ÜÃâ¶Ô»°¿¨×¡  | 
|     if curPlayerAction == IPY_GameWorld.paEvent and not forceChange:  | 
|         if changeAction in [IPY_GameWorld.paNull, IPY_GameWorld.paAttack]:  | 
|             GameWorld.DebugLog("²»Ç¿ÖÆ×ª»»×´Ì¬ %s" % changeAction, curPlayer.GetID())  | 
|             return  | 
|       | 
|     # ²É¼¯Çл»  | 
|     if curPlayerAction == IPY_GameWorld.paPreparing:  | 
|         DoExitPreparing(curPlayer)  | 
|       | 
|     curPlayer.SetPlayerAction(changeAction)  | 
|       | 
|     if changeAction == IPY_GameWorld.paNull:  | 
|         return  | 
|       | 
|     #¿ÕÏÐת±äΪÆäËû״̬Ôòɾ³ýÓÐÏÞÎÞµÐBUFF  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     DelLimitSuperBuff(curPlayer, tick)  | 
|       | 
|     return  | 
|   | 
| ##Í˳ö²É¼¯  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def DoExitPreparing(curPlayer):  | 
|     NPCCommon.ClearCollectNPC(curPlayer)  | 
|     tagObj = curPlayer.GetActionObj()  | 
|       | 
|     if tagObj == None:  | 
|         #ûÓÐÄ¿±ê  | 
|         GameWorld.Log("DoExitPreparing -> Ã»ÓÐÄ¿±ê", curPlayer.GetPlayerID())  | 
|         return  | 
|               | 
|     if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         #̸»°¶ÔÏó²»¶Ô  | 
|         GameWorld.Log("DoExitPreparing -> ²É¼¯¶ÔÏó²»¶Ô", curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())  | 
|     if curNPC == None:  | 
|         #ûÓÐÕâ¸öNPC  | 
|         GameWorld.Log("DoExitPreparing ->ûÓÐÕâ¸öNPC", curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     curNPC_HurtList = curNPC.GetPlayerHurtList()  | 
|     curNPC_HurtList.Clear()  | 
|     return  | 
|   | 
| ## Íæ¼Ò״̬¸Ä±ä(½Å±¾×Ô¶¨Òåö¾Ù)  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param changeAction Çл»µÄ״̬  | 
| #  @return None  | 
| def ChangePyPlayerAction(curPlayer, changeAction):  | 
|     if GetPyPlayerAction(curPlayer, changeAction):  | 
|         #ÒѾÊÇÕâ¸ö״̬  | 
|         return  | 
|       | 
|     state = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PyPlayerAction)  | 
|     state = state | pow(2, changeAction)  | 
|       | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PyPlayerAction, state)  | 
|     return  | 
|   | 
|   | 
| ## »ñÈ¡ÊÇ·ñÓиÃ״̬  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param changeAction Çл»µÄ״̬  | 
| #  @return ÊÇ·ñÓиÃ״̬  | 
| def GetPyPlayerAction(curPlayer, action):  | 
|     receiveState = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PyPlayerAction)  | 
|       | 
|     state = receiveState & pow(2, action)   | 
|     #GameWorld.DebugLog("receiveState = %s, state = %s" % (receiveState, state))  | 
|     return state != 0  | 
|   | 
|   | 
| #---------------------------------------------------------------------  | 
| ##ÉèÖÃÍæ¼ÒÊÇ·ñ¼¤»î  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param isNeedProcess ÊÇ·ñ¼¤»î  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ÉèÖÃÍæ¼ÒÊÇ·ñ¼¤»î  | 
| def SetIsNeedProcess(curPlayer, isNeedProcess):  | 
|     curPlayerIsNeedProcess = curPlayer.GetIsNeedProcess()  | 
|       | 
|     if curPlayerIsNeedProcess == isNeedProcess:  | 
|         return  | 
|       | 
|     curPlayer.SetIsNeedProcess(isNeedProcess)  | 
|     GameWorld.GodLog(curPlayer, 'ÉèÖÃÍæ¼ÒÊÇ·ñ¼¤»î:%s' % isNeedProcess)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÊÇ·ñÔÚÕ½¶·×´Ì¬.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks Íæ¼ÒÊÇ·ñÔÚÕ½¶·×´Ì¬  | 
| def IsPlayerInFight(curPlayer):  | 
| #    #Ö÷¶¯¶ÔÖÅÖÐ  | 
| #    if curPlayer.GetIsConfronting():  | 
| #        return True  | 
|       | 
|     # ¹¥»÷ÖÐ  | 
|     if curPlayer.GetPlayerAction() == IPY_GameWorld.paAttack:  | 
|         return True  | 
|       | 
| #    # ½øÈëÕ½¶·×´Ì¬  | 
| #    if curPlayer.IsBattleState():  | 
| #        return True  | 
|   | 
|     return False  | 
| #---------------------------------------------------------------------  | 
| ##×Ô¶¯½øÈëÕ½¶·¶ÔÖÅ //ÕâÀï²»¼ÓÏêϸÑéÖ¤  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ×Ô¶¯½øÈëÕ½¶·¶ÔÖÅ //ÕâÀï²»¼ÓÏêϸÑéÖ¤  | 
| def AutoEnterPlayerConfronting(curPlayer):  | 
| #      | 
| #    if curPlayer.GetIsConfronting():  | 
| #        return  | 
| #      | 
| #    actObj = curPlayer.GetActionObj()  | 
| #      | 
| #    if not actObj:  | 
| #        return  | 
| #      | 
| #    curPlayer.SetIsConfronting(True)  | 
| #    #֪ͨ¿Í»§¶Ë //0½øÈë;ÆäËûÍ˳ö  | 
| #    curPlayer.View_PlayerBattle(actObj.GetID(), actObj.GetGameObjType(), 0)  | 
| #      | 
| #    #Ìí¼Ó²âÊÔÐÅÏ¢  | 
| #    GameWorld.GodLog(curPlayer, 'Server×Ô¶¯½øÈëÕ½¶·¶ÔÖųɹ¦')  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##//¶ÔÍâ½Ó¿Ú, Öж϶ÔÖÅ  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks //¶ÔÍâ½Ó¿Ú, Öж϶ÔÖÅ  | 
| def ExitPlayerConfronting(curPlayer):  | 
| #    if not curPlayer.GetIsConfronting():  | 
| #        return  | 
| #      | 
| #    #Í˳ö¶ÔÖÅ  | 
| #    curPlayer.SetIsConfronting(False)  | 
| #    #֪ͨ¿Í»§¶Ë //0½øÈë;ÆäËûÍ˳ö  | 
| #    curPlayer.View_PlayerBattle(0, 0, 1)  | 
| #      | 
| #    #Çå³ýÕ½³è³ðºÞ  | 
| #    PetControl.ClearFightPetAngry(curPlayer)  | 
| #      | 
| #    #Ìí¼Ó²âÊÔÐÅÏ¢  | 
| #    GameWorld.GodLog(curPlayer, 'Í˳öÕ½¶·¶ÔÖųɹ¦')  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##²É¼¯´ò¶Ï  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ²É¼¯´ò¶Ï  | 
| def BreakPlayerCollect(curPlayer):  | 
| #    #²É¼¯¶¼²»´ò¶Ï  | 
| #    return  | 
|       | 
|     if curPlayer.GetPlayerAction() != IPY_GameWorld.paPreparing:  | 
|         return  | 
|     #GameWorld.Log('    ²É¼¯´ò¶Ï curPlayer.GetPrepareState()=%s'%curPlayer.GetPrepareState())  | 
|     if curPlayer.GetPrepareState() not in [IPY_GameWorld.pstMissionCollecting, ShareDefine.Def_PstProduce]:  | 
|         #¼´²»ÊÇÈÎÎñ²É¼¯Ò²²»ÊÇÉú²ú²É¼¯  | 
|         return  | 
|       | 
|     #¸±±¾Öв»´ò¶Ï  | 
|     #if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|     #    return  | 
|       | 
|     tagObj = curPlayer.GetActionObj()  | 
|       | 
|     if tagObj == None:  | 
|         #ûÓÐÄ¿±ê  | 
|         #GameWorld.Log("BreakPlayerCollect -> Ã»ÓÐÄ¿±ê", curPlayer.GetPlayerID())  | 
|         return  | 
|               | 
|     if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         #²É¼¯¶ÔÏó²»¶Ô  | 
|         #GameWorld.Log("BreakPlayerCollect -> ²É¼¯¶ÔÏó²»¶Ô", curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())  | 
|     if curNPC == None:  | 
|         #ûÓÐÕâ¸öNPC  | 
|         #GameWorld.Log("BreakPlayerCollect ->ûÓÐÕâ¸öNPC", curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     npcID = curNPC.GetNPCID()  | 
|     collectNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CollectNPC", npcID)  | 
|     if not collectNPCIpyData:  | 
|         return  | 
|       | 
|     if not collectNPCIpyData.GetCanBreakCollect():  | 
|         return  | 
|       | 
|     #È¡Ïû²É¼¯×´Ì¬  | 
|     ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)  | 
|       | 
|     if curPlayer.GetActionObj() != None:  | 
|         curPlayer.SetActionObj(None)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò´ò×ø  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò´ò×ø  | 
| def DoPlayerSit(curPlayer, tick):  | 
|     #ÒѾÔÚ´ò×ø×´Ì¬ÁË  | 
|     if curPlayer.GetPlayerAction() == IPY_GameWorld.paSit:  | 
|         return  | 
|       | 
|     #Í¨ÖªÍ£Ö¹ÒÆ¶¯  | 
|     curPlayer.StopMove()  | 
|     #¼¤»îÍæ¼Ò״̬, »Ø¸´CDÊÇ3Ãë, Íæ¼Ò´ôÖÍΪ5Ãë, Òª¼¤»îһϠ | 
|     SetIsNeedProcess(curPlayer, True)  | 
|     #Íæ¼Ò×øÏÂ  | 
|     curPlayer.Sit()  | 
|       | 
|     #ÉèÖÃÕæÆø¿ªÊ¼»Ö¸´Ê±¼ä  | 
|     #curPlayer.SetDict(ChConfig.Def_PlayerKey_SitForZhenQi, tick)  | 
|     #ÉèÖøßЧÁ·¹¦¿ªÊ¼Ê±¼ä  | 
|     #curPlayer.SetDict(ChConfig.Def_PlayerKey_EfficientSit, tick)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÕ¾Æð  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÕ¾Æð  | 
| def DoPlayerStand(curPlayer):  | 
|     #²»ÔÚ´ò×ø×´Ì¬  | 
|     if curPlayer.GetPlayerAction() != IPY_GameWorld.paSit:  | 
|         return  | 
|       | 
|     curPlayer.Stand()  | 
|       | 
|       | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò²¥·Å±íÇé  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò²¥·Å±íÇé  | 
| def DoPlayerShowPlayerFace(curPlayer, faceType):  | 
|     #Çå¿ÕÍæ¼Òµã»÷  | 
|     curPlayer.SetActionObj(None)  | 
|     #֪ͨÖжÏÕ½¶·¶ÔÖÅ  | 
|     ExitPlayerConfronting(curPlayer)  | 
|     #Í¨ÖªÍ£Ö¹ÒÆ¶¯  | 
|     curPlayer.StopMove()  | 
|     #֪ͨ¿Í»§¶Ë²¥·Å±íÇé  | 
|     curPlayer.View_ShowPlayerFace(faceType)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒËÀÍö  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒËÀÍö  | 
| def DoPlayerDead(curPlayer):  | 
|       | 
|     #Í¨ÖªÍ£Ö¹ÒÆ¶¯  | 
|     curPlayer.StopMove()  | 
|   | 
|     #Íæ¼ÒËÀÍö  | 
|     curPlayer.SetDead(curPlayer.GetDictByKey(ChConfig.Def_NPCDead_KillerID),  | 
|                       curPlayer.GetDictByKey(ChConfig.Def_NPCDead_KillerType))  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒË¢ÐÂ×ø±ê  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param checkObj ¼ì²é¶ÔÏó  | 
| # @param posX Æðµã×ø±êX  | 
| # @param posY Æðµã×ø±êY  | 
| # @param canChangeClientPos ÊÇ·ñÖØÖõ½¿Í»§¶Ë×ø±êµã  | 
| # @return ·µ»ØÖµÕæ, Ë¢Ð³ɹ¦  | 
| # @remarks Íæ¼ÒË¢ÐÂ×ø±ê  | 
| def PlayerRefreshPos(curPlayer, checkObj, posX, posY, canChangeClientPos=True):  | 
|     if not curPlayer.GetMapLoadOK():  | 
|         #Ë¢ÐÂʧ°Ü  | 
|         #×¢Òâ: Ò»¶¨ÒªÅжÏ, ÒòΪÔÚÍæ¼ÒʹÓü¼ÄܵÄʱºò»áË¢ÐÂÕâÀï  | 
|         #Èç¹ûÍæ¼Ò¶ÁȡûÓгɹ¦, ¾Í²»´¦ÀíÕâ¸ö·â°ü  | 
|         GameWorld.Log('µØÍ¼Ã»ÓжÁÈ¡³É¹¦, Ë¢ÐÂʧ°Ü', curPlayer.GetPlayerID())  | 
|         return False  | 
|       | 
|     if not curPlayer.GetSpeed():  | 
|         GameWorld.Log("ûÓÐËٶȲ»ÄÜË¢ÐÂ×ø±ê!", curPlayer.GetPlayerID())  | 
|         return False  | 
|       | 
|     curMap = GameWorld.GetMap()  | 
|       | 
|     #¼ì²éÍæ¼ÒͣϵÄ×ø±êÊÇ·ñÕýÈ·  | 
|     needResetPos = False  | 
|       | 
|     if curMap.CanMove(posX, posY) != True:  | 
|         #ÌßÍæ¼ÒÏÂÏß  | 
|         #curPlayer.Kick(IPY_GameWorld.disPlayerPosError)  | 
|         #°ÑÍæ¼Ò´ò»ØÖØÉúµã  | 
| #        playerControl = PlayerControl(curPlayer)  | 
| #        playerControl.SetToBornPlace()  | 
|         #ÒÔÉÏ´¦ÀíÌ«¹ýÑϸñ, Ä¿Ç°²»Åж¨  | 
|         #-----------------------------------------  | 
|         #ÔÚÍæ¼ÒÖÜΧÕÒµ½Ò»¸ö¿É×ߵĵã, °ÑËû·Å¹ýÈ¥  | 
|         resultPos = GameMap.GetEmptyPlaceInArea(posX, posY, ChConfig.Def_DropItemDist)  | 
|   | 
|         if resultPos.GetPosX() == posX and resultPos.GetPosY() == posY:  | 
|             #Íæ¼ÒÖØÖÃλÖÃʧ°Ü  | 
|             GameWorld.Log('Íæ¼ÒÖØÖÃλÖÃʧ°Ü, °ÑÍæ¼Ò´ò»ØÖØÉúµã posX = %s posY = %s' \  | 
|                           % (posX, posY), curPlayer.GetPlayerID())  | 
| #===============================================================================  | 
| #            playerControl = PlayerControl(curPlayer)  | 
| #            playerControl.SetToBornPlace()  | 
| #===============================================================================  | 
|             #ÔÝʱÍêÈ«ÐÅÈοͻ§¶Ë×ø±ê£¬±ÜÃâ±ßÔµ»¯ÎÞ·¨¹¥»÷ÎÊÌâ  | 
|             return False  | 
|           | 
|         GameWorld.Log("×ø±ê´íÎ󣬼ì²éÍæ¼ÒͣϵÄ×ø±êÊÇ·ñÕýÈ· posX = %d, posY = %d, ÖØÖÃλÖÃ:posX = %d, posY = %d" \  | 
|                       % (posX, posY, resultPos.GetPosX(), resultPos.GetPosY()), curPlayer.GetPlayerID())  | 
|           | 
|         posX = resultPos.GetPosX()  | 
|         posY = resultPos.GetPosY()  | 
|           | 
|         #±ßÔµÕϰµãÈÿͻ§¶ËÐÐ×ߣ¬·þÎñ¶Ë¸Ä±äλÖò»Í¨Öª  | 
|         #needResetPos = True  | 
|         #checkObj.ResetPos(posX, posY)  | 
|       | 
|     #µ±Ç°¶ÔÏó×ø±ê  | 
|     objPosX = checkObj.GetPosX()  | 
|     objPosY = checkObj.GetPosY()  | 
| #    objDestPosX = checkObj.GetDestPosX()  | 
| #    objDestPosY = checkObj.GetDestPosY()  | 
| #    objStartX = checkObj.GetStartPosX()  | 
| #    objStartY = checkObj.GetStartPosY()  | 
|     #¼ÆËãÍæ¼Ò·¢¹ýÀ´µÄֹͣλÖúͷþÎñÆ÷ÒÑÓÐ×ø±êµÄ¾àÀë  | 
|     dist = GameWorld.GetDist(posX, posY, objPosX, objPosY)  | 
|       | 
|     #ÒÆ¶¯µÄÌØµã£º¿Í»§¶ËÒÆ¶¯Îª1Ã×С¼ä¸ô·¢°ü£¬·þÎñ¶ËµÄUpdatePos ¾³£ Î´Ö´Ðе¼ÖÂÎÞ·¨Òƶ¯£¬Òƶ¯ÐÐΪ±ä³É  __FixPlayerPos-¡·ChangePos¿ØÖÆ  | 
|     #Íâ²ãÒÆ¶¯tick ¿ØÖƼä¸ô·ÀÖ¹Íâ¹Ò°ü  | 
|     if dist <= 3:  | 
|         #µÚÒ»ÖÖÇé¿ö:¿Í»§¶ËºÍ·þÎñÆ÷¶Ë¾àÀë²î¾à·ûºÏÒªÇó  | 
|         #λÖÿÉÒÔ½ÓÊÜ  | 
|         __FixPlayerPos(checkObj, posX, posY, needResetPos, canChangeClientPos)  | 
|         return True  | 
|     else:  | 
|         #¾àÀëÆ«²îÌ«´ó£¬À»ØÎ»Öò»×öÌßÈËÂß¼  | 
|         needResetPos = True  | 
|         GameWorld.DebugLog('Client=(%s,%s), Server=(%s,%s), ²îÒì¾àÀë=%s' \  | 
|                      % (posX, posY, objPosX, objPosY, dist))  | 
|         posX = objPosX  | 
|         posY = objPosY  | 
|         __FixPlayerPos(checkObj, posX, posY, needResetPos, canChangeClientPos)  | 
|         return False  | 
|       | 
|     # Êµ¼Ê´Ëº¯ÊýÔÚ¶Ô»°  ¹¥»÷ Òƶ¯¶¼»á×ß½øÀ´Åж¨  | 
|     #===========================================================================  | 
|     # curPlayer.SetMoveCount(curPlayer.GetMoveCount() + 1)  | 
|     # if curPlayer.GetMoveCount() >= 10:  | 
|     #    curPlayer.SetMoveCount(0)  | 
|     #    curPlayer.SetMoveDistDiff(0)  | 
|     #    needResetPos = True  | 
|     #      | 
|     # if curPlayer.GetMoveDistDiff() >= 30:  | 
|     #    curPlayer.SetMoveCount(0)  | 
|     #    curPlayer.SetMoveDistDiff(0)  | 
|     #    needResetPos = True  | 
|     #===========================================================================  | 
|     __FixPlayerPos(checkObj, posX, posY, needResetPos, canChangeClientPos)  | 
|   | 
|     return True  | 
| #    curPlayer.SetMoveCount(curPlayer.GetMoveCount() + 1)  | 
| #      | 
| #    #Def_PlayerMoveCheckClearCount:  | 
| #    #Íæ¼ÒÒÆ¶¯¶àÉÙ´ÎÇå¿ÕÕâ¸öÀۼƴíÎó          | 
| #    if curPlayer.GetMoveCount() >= ReadChConfig.GetEvalChConfig('Def_PlayerMoveCheckClearCount'):  | 
| #        curPlayer.SetMoveCount(0)  | 
| #        curPlayer.SetMoveDistDiff(0)  | 
| #      | 
| #    #¾àÀë(Æðµã-¿Í»§¶ËλÖÃ-·þÎñÆ÷¶ËλÖÃ-ÖÕµã)  | 
| #    severDist = GameWorld.GetDist(objPosX, objPosY, objDestPosX, objDestPosY)  | 
| #    severTotalDist = GameWorld.GetDist(objStartX, objStartY, objDestPosX, objDestPosY)  | 
| #    clientDist = GameWorld.GetDist(posX, posY, objDestPosX, objDestPosY)  | 
| #      | 
| #    clientSlow = False  | 
| #      | 
| #    if clientDist >= severDist and clientDist <= severTotalDist:  | 
| #        #·½Ïò  | 
| #        severDir = GameWorld.GetAngle(objStartX, objStartY, objDestPosX, objDestPosY)   | 
| #        clientDir = GameWorld.GetAngle(posX, posY, objDestPosX, objDestPosY)  | 
| #      | 
| #        clientSlow = True      | 
| ##===============================================================================  | 
| ##        #2011-1-19 ´ËÖÖÇé¿öÒ²Òª¼ÆËãÎó²î  | 
| ##        #Èç¹û½Ç¶È²î±ð10¶È, ÔòÈÏΪ¿ÉÒÔ½ÓÊÜ  | 
| ##        dirDiff = 10  | 
| ##        dirDiffValue = abs(severDir - clientDir)  | 
| ##          | 
| ##        if dirDiffValue <= dirDiff:  | 
| ##            #µÚ¶þÖÖÇé¿ö:·þÎñÆ÷±È¿Í»§¶Ë¿ì  | 
| ##            #¿ÉÒÔ½ÓÊÜ  | 
| ##            __FixPlayerPos(checkObj, posX, posY, needResetPos, canChangeClientPos)  | 
| ##            return True  | 
| ##===============================================================================  | 
| #    #·þÎñÆ÷±È¿Í»§¶ËÂý#ChConfig.Def_AcceptPlayerStopPlaceDist:  | 
| #    if dist > ReadChConfig.GetEvalChConfig('Def_AcceptPlayerStopPlaceDist'):  | 
| #        return False  | 
| #        #ÌßÍæ¼ÒÏÂÏß  | 
| #        if clientSlow:  | 
| #            GameWorld.ErrLog("³¬´óÎó²î, ¿Í»§¶Ë±È·þÎñÆ÷Âý %d" % dist, curPlayer.GetPlayerID())  | 
| #        else:  | 
| #            GameWorld.ErrLog("³¬´óÎó²î, ·þÎñÆ÷±È¿Í»§¶ËÂý %d" % dist, curPlayer.GetPlayerID())  | 
| #            #·þÎñÆ÷¶Ë±È¿Í»§¶ËÂý¿ÉÒÔ½ÓÊÜ  | 
| #            return False  | 
| #          | 
| #        #GameWorld.GodLog(curPlayer, '³¬´óÎó²î, Ôݲ»´¦Àí, clientSlow = %s, dist = %s'%(clientSlow, dist))  | 
| #          | 
| #        #³¬´óÎó²î·âÍ£Õ˺Åʱ¼ä  | 
| #        closeAccIDTime = ReadChConfig.GetEvalChConfig('Def_BigErrorDistCloseAccTime')  | 
| #      | 
| #        if closeAccIDTime > 0:  | 
| #            #³¬´óÎó²î·âÍ£Íæ¼Ò  | 
| #            PlayerGMOper.ClosePlayerByAccID(curPlayer, closeAccIDTime, 'BigErrorDist = %s Kick' % (dist))  | 
| #        else:  | 
| #            #³¬´óÎó²îÌß³öÍæ¼Ò  | 
| #            curPlayer.Kick(IPY_GameWorld.disPlayerMoveToFar)  | 
| #      | 
| #        return False  | 
| #      | 
| #    #ֹͣλÖÿɽÓÊÜ,µ±Ðè¼Ç¼  | 
| #    curMoveDistDiff = curPlayer.GetMoveDistDiff() + dist  | 
| #    curPlayer.SetMoveDistDiff(curMoveDistDiff)  | 
| #      | 
| #    #ÐÂÔöÒÆ¶¯×ø±ê²îÖµDebugÌáʾÐÅÏ¢,·½±ã¿Í»§¶Ë²éѯ  | 
| #    GameWorld.GodLog(curPlayer, 'Client=(%s,%s), Server=(%s,%s), ÀÛ¼Ó¾àÀë=%s, ÀÛ¼Ó×ÜÖµ=%s' \  | 
| #                     % (posX, posY, objPosX, objPosY, dist, curPlayer.GetMoveDistDiff()))  | 
| #      | 
| #    #Íæ¼ÒÒÆ¶¯100´Î¼ì²éÒ»´Î  | 
| #    if curPlayer.GetMoveCount() >= ReadChConfig.GetEvalChConfig('Def_PlayerMoveCheckCount'):  | 
| #        maxMoveDistDiff = ReadChConfig.GetEvalChConfig('Def_PlayerMoveCheckDist')  | 
| #        #2009/07/15 Òò¸±±¾ÀÈË˲¼ä¾àÀë¹ý´ó£¬¸±±¾Åж¨¾àÀëË«±¶  | 
| #        if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
| #            maxMoveDistDiff = maxMoveDistDiff * 2  | 
| #          | 
| #        if curMoveDistDiff >= maxMoveDistDiff:  | 
| #            return False  | 
| #            GameWorld.Log("Íæ¼ÒÒÆ¶¯´íÎó´ÎÊý = %s, Òƶ¯ÀۼƾàÀë = %s, ÌßÍæ¼ÒÏÂÏß" \  | 
| #                          % (curPlayer.GetMoveCount(), curMoveDistDiff), curPlayer.GetPlayerID())  | 
| #              | 
| #            closeAccIDTime = ReadChConfig.GetEvalChConfig('Def_MoveDistErrorCloseAccTime')  | 
| #              | 
| #            if closeAccIDTime > 0:  | 
| #                PlayerGMOper.ClosePlayerByAccID(curPlayer, closeAccIDTime, 'MoveCheckKick, ErrDist = %s' \  | 
| #                                                % (curMoveDistDiff))  | 
| #            else:  | 
| #                curPlayer.Kick(IPY_GameWorld.disPlayerMoveAddUpError)  | 
| #  | 
| #            return False  | 
| #  | 
| #    #µÚ3ÖÖÇé¿ö:¼Ç¼²¢½ÃÕý×ø±ê  | 
| #    __FixPlayerPos(checkObj, posX, posY, needResetPos, canChangeClientPos)  | 
| #    return True  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##½ÃÕýÍæ¼Ò×ø±ê  | 
| # @param checkObj ¼ì²éµÄ¶ÔÏó  | 
| # @param changePosX ½ÃÕýµÄ×ø±êX  | 
| # @param changePosY ½ÃÕýµÄ×ø±êY  | 
| # @param needResetServerPos  ÊÇ·ñ°´·þÎñÆ÷λÖÃÖØÖà  | 
| # @param needChangeClientPos ÊÇ·ñ°´¿Í»§¶ËλÖÃÖØÖà  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ½ÃÕýÍæ¼Ò×ø±ê  | 
| def __FixPlayerPos(checkObj, changePosX, changePosY, needResetServerPos, needChangeClientPos):  | 
|     #---°´·þÎñÆ÷λÖÃÖØÖÃ---  | 
|     if needResetServerPos:  | 
|         checkObj.ResetPos(changePosX, changePosY)  | 
|         return  | 
|       | 
|     #---°´¿Í»§¶ËλÖÃÖØÖÃ---  | 
|     if needChangeClientPos:  | 
|         checkObj.ChangePos(changePosX, changePosY)  | 
|         return  | 
|       | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##ɱËÀÍæ¼ÒËùÓеÄÕÙ»½ÊÞËÀÍö  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks É±ËÀÍæ¼ÒËùÓеÄÕÙ»½ÊÞËÀÍö  | 
| def KillPlayerSummonNPC(curPlayer):  | 
|     #½«Éæ¼°µ½C++ÖÐÁбíɾ³ýµÄ¹¦ÄÜ,ͳһ¸Ä³É -> ¸´ÖÆPyÁбíºó,È»ºó½øÐÐɾ³ýÂß¼ (ÒòWhileÓм¸Âʽ«µ¼ÖÂËÀËø)  | 
|     summon_List = []  | 
|     for index in range(curPlayer.GetSummonCount()):  | 
|         curSummonNPC = curPlayer.GetSummonNPCAt(index)  | 
|         summon_List.append(curSummonNPC)  | 
|       | 
|     for summonNPC in summon_List:  | 
|         NPCCommon.SetDeadEx(summonNPC)      | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##¼ì²éÍæ¼ÒͨÓõÄ״̬ת»»  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÕæ, ÔÊÐíÇл»×´Ì¬  | 
| # @remarks ¼ì²éÍæ¼ÒͨÓõÄ״̬ת»»  | 
| def PlayerCanStateTransfer(curPlayer):  | 
|     curPlayerAction = curPlayer.GetPlayerAction()  | 
|     #Èç¹ûÍæ¼ÒÊÇ×øÏÂ״̬, ×Ô¶¯×ª»»ÎªÕ¾Á¢×´Ì¬  | 
|     #DoPlayerStand(curPlayer)  | 
|           | 
|     return (curPlayerAction in ChConfig.Def_Player_Can_Transfer_State)  | 
|   | 
| #------------------------------Íæ¼ÒÀ뿪·þÎñÆ÷µÄÂß¼------------------------------------  | 
| #---------------------------------------------------------------------  | 
| ##ïÚ³µÏÂÏßÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ïÚ³µÏÂÏßÂß¼  | 
| def __TruckPlayerDisconnect(curPlayer):  | 
|     return  | 
|   | 
|     #ÔÚïÚ³µ  | 
|     if PlayerTruck.GetHaveAutoTruck(curPlayer):  | 
|         curPlayerTruck = curPlayer.GetTruck()  | 
|         curPlayerTruck.SetOwner(None)  | 
|         PlayerTruck.PlayerTruckDown(curPlayer, curPlayerTruck)  | 
|           | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##ÆïÂíÏÂÏßÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ÆïÂíÏÂÏßÂß¼  | 
| def __RidingHorsePlayerDisconnect(curPlayer):  | 
|     #ÔÚÆïÂí  | 
|     if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse:  | 
|         #Ö´ÐÐÏÂÂíÂß¼  | 
|         PlayerHorse.PlayerRideHorseDown(curPlayer, False)  | 
|           | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÏÂÏß/Íæ¼ÒÇл»µØÍ¼¹«ÓÃÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÏÂÏß/Íæ¼ÒÇл»µØÍ¼¹«ÓÃÂß¼  | 
| def __PlayerLeaveServerLogic(curPlayer, tick, isDisconnect):  | 
|     #¸øÓèÍæ¼Ò²¹³¥  | 
|     #PlayerExpiation.GivePlayerExpiation(curPlayer, tick)  | 
|       | 
|     #ÔËÐÐÀëÏßxml  | 
|     EventShell.EventResponse_OnLeaveMap(curPlayer)  | 
|       | 
|     #Èç¹ûÍæ¼ÒÓÐæô³µ, °Ñæô³µµÄÖ÷ÈËÉèÖÃΪNone  | 
|     curPlayerTruck = curPlayer.GetTruck()  | 
|       | 
|     if curPlayerTruck != None:  | 
|         curPlayerTruck.SetOwner(None)  | 
|   | 
|     #ˢм¼ÄÜÊ£Óàʱ¼ä  | 
|     SkillCommon.RefreshAllSkillRemainTime(curPlayer, tick)  | 
|       | 
|     #Èç¹ûÔÚ½»Ò×״̬,È¡Ïû½»Ò×Ë«·½µÄ½»Ò×״̬²¢½â³ý½»Ò×À¸ÖÐÎïÆ·Ëø¶¨×´Ì¬  | 
|     PlayerTrade.LeaveTrade(curPlayer, 0)  | 
|       | 
|     #¶ÓÎéÍæ¼ÒÍ˳öµØÍ¼  | 
|     PlayerTeam.TeamPlayerLeaveMap(curPlayer, tick, isDisconnect)  | 
|   | 
|     #Í˳ö²É¼¯  | 
|     NPCCommon.ClearCollectNPC(curPlayer)  | 
|     #½áÊøÊ¼þ  | 
|     EventShell.DoExitEvent(curPlayer)  | 
|   | 
|     #ÉèÖÃÍæ¼ÒµÄµØÍ¼Î»ÖÃ, Èç¹ûÊǸ±±¾, À뿪¸±±¾  | 
| #    ¸±±¾¹æÔò:  | 
| #    1. Ò»¸ö¶ÓÎéÖ»ÓÐÒ»¸ö¸±±¾, Èç¹ûÓжÓÔ±µÄ¸±±¾ºÍ¶ÓÎ鸱±¾²»Ò»ÖÂ, Ôò´Ó¸±±¾ÖÐÌß³ö´Ë¶ÓÔ±  | 
| #    2. Íæ¼ÒÏÂÏßÔÙÉÏ, ¾ÍÀ뿪¸±±¾  | 
| #    3. Èç¹ûûÓÐÍæ¼Ò´æÔÚ, ¸±±¾»ØÊÕ  | 
|     if GameWorld.GetMap().GetMapFBType() != 0:  | 
|         #À뿪¸±±¾  | 
|         fbIndex = GameWorld.GetGameWorld().GetCurGameWorldIndex()  | 
|         exitFBType = 1 if isDisconnect else 2  | 
|         PyGameData.g_lastExitFBType[fbIndex] = [exitFBType, tick]  | 
|         #GameWorld.DebugLog("Íæ¼ÒÀ뿪¸±±¾£ºfbIndex=%s,exitFBType=%s, %s" % (fbIndex, exitFBType, PyGameData.g_lastExitFBType), curPlayer.GetPlayerID())  | 
|         FBLogic.DoExitFBLogic(curPlayer, tick)  | 
|       | 
|     #Çå¿ÕËùÓв»ÊôÓÚ×Ô¼ºµÄ¹â»·  | 
|     #__ClearNoMeAuraBuff(curPlayer)  | 
|       | 
|     #Çå¿ÕËùÓÐÀ뿪µØÍ¼²»ÐèÒª±£´æµÄBuff  | 
|     __ClearLeaveNoSaveBuff(curPlayer)  | 
|       | 
|     #---±£´æÍæ¼ÒÔÚÏßʱ¼ä(°´ÃëËã)---  | 
|     UpdateOnLineTime(curPlayer, tick)  | 
|       | 
|     PassiveBuffEffMng.OnPlayerLeaveMap(curPlayer)  | 
|       | 
|     #À뿪µØÍ¼Çå¿Õ¶ñÒâ¹¥»÷×Ô¼ºÍæ¼ÒÐÅÏ¢  | 
|     if curPlayer.GetPlayerID() in PyGameData.g_maliciousAttackDict:  | 
|         PyGameData.g_maliciousAttackDict.pop(curPlayer.GetPlayerID())  | 
|           | 
|     PyGameData.g_needRefreshMapServerState = True # ÓÐÍæ¼ÒÀ뿪µØÍ¼ÉèÖÃÐèҪˢР | 
|       | 
|     PlayerSuccess.FinishDelayAddSuccessProgress(curPlayer, tick)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if not isDisconnect:  | 
|         CrossPlayerData.ClearCrossSyncDataCache(curPlayer)  | 
|         PyGameData.g_fbBuyBuffTimeDict.pop(playerID, None)  | 
|     #Çå³ýµØÍ¼Íæ¼Ò»º´æ  | 
|     PyGameData.g_playerFuncAttrDict.pop(playerID, None)  | 
|     PyGameData.g_playerEquipPartAttrDict.pop(playerID, None)  | 
|     PyGameData.g_equipChangeClassLVInfo.pop(playerID, None)  | 
|     NPCCommon.ClearPriWoodPile(curPlayer)  | 
|     #ÒÆ³ýµØÍ¼»º´æµÄ¾³½çÄѶÈÍæ¼ÒIDÐÅÏ¢  | 
|     for playerIDList in PyGameData.g_realmDiffPlayerDict.values():  | 
|         if playerID in playerIDList:  | 
|             playerIDList.remove(playerID)  | 
|     return  | 
|   | 
| ##¸üб£´æÍæ¼ÒÔÚÏßʱ¼ä  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ätick  | 
| # @return   | 
| def UpdateOnLineTime(curPlayer, tick):  | 
|     #---±£´æÍæ¼ÒÔÚÏßʱ¼ä(°´ÃëËã)---  | 
|     lastCalcTick = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CalcOLTimeTick)  | 
|     if lastCalcTick <= 0:  | 
|         curPlayer.SetDict(ChConfig.Def_PlayerKey_CalcOLTimeTick, tick)  | 
|         return  | 
|       | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_CalcOLTimeTick, tick)  | 
|       | 
|     diffSec = (tick - lastCalcTick) / 1000  | 
|     if diffSec > 0:  | 
|         curPlayer.SetWeekOnlineTime(curPlayer.GetWeekOnlineTime() + diffSec)  | 
|         curPlayer.SetOnlineTime(curPlayer.GetOnlineTime() + diffSec)  | 
|         SyncOnLineTimeTotal(curPlayer)  | 
|           | 
|     return  | 
|   | 
| ##ͬ²½ÔÚÏßʱ¼ä  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return   | 
| def SyncOnLineTimeTotal(curPlayer):  | 
|     sendPack = ChPyNetSendPack.tagMCOnLineTimeTotal()  | 
|     sendPack.Clear()  | 
|     sendPack.OnLineTimeTotal = curPlayer.GetOnlineTime()  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
| ##ͬ²½×îºóÒ»´Î±³°ü¿ª¸ñÔÚÏßʱ¼ä  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param packType ±³°üÀàÐÍ  | 
| # @return   | 
| def SyncOnLineTimeLastOpenPack(curPlayer, packType):  | 
|     return  | 
|     sendPack = ChPyNetSendPack.tagMCOnlineTimeLastOpenPack()  | 
|     sendPack.Clear()  | 
|     sendPack.PackType = packType  | 
|     sendPack.LastOnLineTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_LastAutoOpenPackTick % packType)  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
| ##À뿪µØÍ¼Çå¿Õ²»±£´æµÄBuff  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks À뿪µØÍ¼Çå¿Õ²»±£´æµÄBuff  | 
| def __ClearLeaveNoSaveBuff(curPlayer):  | 
|     #×°±¸BuffºÍ±»¶¯BuffÕâÀï²»Çå, Çл»µØÍ¼ºó»áÖØÐ¼ÆËã  | 
|       | 
|     #Çå¿ÕËùÓг¡¾°ÀàBuff  | 
|     curPlayer.GetMapBuff().Clear()  | 
|       | 
|     #2011-01-28 ÐÞ¸ÄΪ¿É±£´æ£¬¹Ê´Ë´¦²»É¾³ý  | 
|     #Çå¿ÕËùÓпØÖÆÀàBUFF  | 
|     #BUG: ¿ØÖÆÀàBUFF²»´æÊý¾Ý¿â£¬ÇеØÍ¼ºó²»Í¨ÖªÏûʧ£¬¿Í»§¶ËÎÞ·¨É¾³ý  | 
|     #curPlayer.GetActionBuffManager().Clear()  | 
|     return  | 
|   | 
|   | 
| ## Çå³ýÏÂÏßÏûʧµÄbuff, ÔÚ¸üÐÂÅÅÐаñ֮ǰ  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return   | 
| def __DisconnectClearBuff(curPlayer, tick):  | 
|   | 
|     #ÐèÒª¿¼ÂÇbuff,deBuff,aura,incBuff,mapBuff,³ýÁËequipBuff²»¿¼ÂÇ  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetBuffState(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetDeBuffState(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetAura(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetIncBuff(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetMapBuff(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetActionBuffManager(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetProcessBuffState(), ClearBuffByDisconnect, tick)  | 
|     PlayerClearBuff_Single(curPlayer, curPlayer.GetProcessDeBuffState(), ClearBuffByDisconnect, tick)  | 
|       | 
|     #BUFFЧ¹ûÔÚÍâ²ã¼ÆËã  | 
|     #SkillShell.RefreshPlayerBuffOnAttrAddEffect(curPlayer)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÀ뿪·þÎñÆ÷  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÀ뿪·þÎñÆ÷  | 
| def PlayerLeaveServer(curPlayer, tick):  | 
|     #³èÎïÏÂÏßÂß¼, ÕâÀïÒª½øÐÐÅÅÐаñ, ÓÅÏÈ×ö, ±ÜÃâÍæ¼Ò¹â»·µÈÊôÐÔÓ°Ïì³èÎïÊôÐÔʧЧ  | 
|     PetControl.DoLogic_PetInfo_OnLeaveServer(curPlayer, tick)  | 
|       | 
|     #Çå³ýÏÂÏßÏûʧµÄbuff, ÔÚ¸üÐÂÅÅÐаñ֮ǰ  | 
|     __DisconnectClearBuff(curPlayer, tick)  | 
|       | 
|     #Çå³ý»ØÊÕÕ½  | 
|     #DelRecylcePack(curPlayer)  | 
|       | 
|     #ÖØÐÂˢнÇÉ«ÊôÐÔ  | 
|     playerControl = PlayerControl(curPlayer)  | 
|     playerControl.RefreshAllState()  | 
|               | 
|     #Íæ¼ÒÏÂÏ߸üÐÂÅÅÐаñ  | 
|     PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer) #ÅÅÐаñÒÑʵʱ¸üУ¬¹ÊÏÂÏß²»ÔÙͬ²½  | 
|       | 
|     #Íæ¼ÒÏÂÏß֪ͨgameserver¼Ç¼»º´æ£¨·ÅÔÚÏÂÏ߸üÐÂÅÅÐаñÖ®ºó£¬·½±ãGameserverÅжÏÊÇ·ñÐèÒª´æÈëÊý¾Ý¿âÖУ©  | 
|     PlayerViewCacheTube.OnPlayerLogOut(curPlayer, tick)  | 
|       | 
|     #Íæ¼ÒÏÂÏß/Íæ¼ÒÇл»µØÍ¼¹«ÓÃÂß¼  | 
|     __PlayerLeaveServerLogic(curPlayer, tick, True)  | 
|     #ÆïÂíÍæ¼ÒÏÂÏßÂß¼  | 
|     __RidingHorsePlayerDisconnect(curPlayer)  | 
|     #ïÚ³µÏÂÏßÂß¼  | 
|     __TruckPlayerDisconnect(curPlayer)  | 
|     #ÕÙ»½ÊÞËÀÍö  | 
|     KillPlayerSummonNPC(curPlayer)  | 
|     #¸üдӱ¾µØÍ¼ÀëÏßÐÅÏ¢  | 
|     PyGameData.g_disconnectPlayer[curPlayer.GetPlayerID()] = [tick, curPlayer.GetPosX(), curPlayer.GetPosY()]  | 
|     GameWorld.DebugLog("Íæ¼Ò´Ó±¾µØÍ¼ÀëÏß: %s" % PyGameData.g_disconnectPlayer, curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def GetPlayerLeaveServerTick(playerID):  | 
|     # »ñÈ¡Íæ¼Ò´Ó±¾µØÍ¼ÖÐÀëÏßʱµÄtick, ×î´óÖ§³Ö1Сʱ, Èç¹ûÓÐÐèÒª´óÓÚ1СʱµÄÇëµ÷Õû³¬Ê±ÏÞÖÆ  | 
|     # ×¢: ·µ»ØÖµÎª0ʱ£¬Ö»ÄÜ´ú±íÍæ¼Ò²»ÊÇÔÚ±¾µØÍ¼ÀëÏß1СʱÄÚ£¬²¢²»ÄÜ´ú±íÍæ¼Òµ±Ç°ÊÇ·ñÔÚÏß״̬£¬¿ÉÄÜÔÚÆäËûµØÍ¼  | 
|     if playerID not in PyGameData.g_disconnectPlayer:  | 
|         return 0  | 
|     return PyGameData.g_disconnectPlayer[playerID][0]  | 
|   | 
| def GetPlayerLeaveServerPos(playerID):  | 
|     # »ñÈ¡Íæ¼Ò´Ó±¾µØÍ¼ÖÐÀëÏßʱµÄ×ø±ê  | 
|     # ×¢£ºÊ¹Óñ¾º¯Êýʱ£¬Ò»¶¨ÒªÏÈʹÓú¯Êý GetPlayerLeaveServerTick È·±£ÊÇ´Ó±¾µØÍ¼ÖÐÀëÏߵIJſÉʹÓà  | 
|     # @return: posX, posY  | 
|     if playerID not in PyGameData.g_disconnectPlayer:  | 
|         return 0, 0  | 
|     return PyGameData.g_disconnectPlayer[playerID][1:3]  | 
|   | 
| def RemoveTimeoutLeaveServerPlayerInfo(tick):  | 
|     # Ôݶ¨Ã¿ÌìÁ賿5µãÖ´ÐÐÒ»´Î  | 
|     for playerID, leaveInfo in PyGameData.g_disconnectPlayer.items():  | 
|         leaveTick = leaveInfo[0]  | 
|         if tick - leaveTick > 3600000: # Çå³ý³¬Ê±1СʱµÄ¼Ç¼  | 
|             PyGameData.g_disconnectPlayer.pop(playerID)  | 
|     return  | 
|   | 
| def RemoveLeaveServerPlayerInfo(playerID):  | 
|     # ÉÏÏßÒÆ³ýÔÚ±¾µØÍ¼ÏÂÏߵļǼ  | 
|     if playerID in PyGameData.g_disconnectPlayer:  | 
|         PyGameData.g_disconnectPlayer.pop(playerID)  | 
|         GameWorld.DebugLog("½øÈë±¾µØÍ¼£¬ÒƳýÉÏ´ÎÔÚ±¾µØÍ¼ÀëÏ߼Ǽ!", playerID)  | 
|     return  | 
|   | 
|   | 
| ##Çå³ý»ØÊÕÕ½  | 
| # @param None  | 
| # @return None  | 
| def DelRecylcePack(curPlayer):  | 
|     backPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptRecycle)  | 
|       | 
|     for i in range(backPack.GetCount()):  | 
|         curItem = backPack.GetAt(i)  | 
|           | 
|         if not curItem or curItem.IsEmpty():  | 
|             continue  | 
|           | 
|         curItem.Clear()  | 
|       | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_DelPackIndex, 0)  | 
|     return  | 
|   | 
|   | 
| ##Çл»µØÍ¼ïÚ³µÉ趨  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÕæ,¿ÉÒÔ´øÉÏïÚ³µÇл»µØÍ¼  | 
| # @remarks Çл»µØÍ¼ïÚ³µÉ趨  | 
| def __GetCanChangeMapSetTruck(curPlayer):  | 
|     curTruck = curPlayer.GetTruck()  | 
|     #GameWorld.Log("Íæ¼Ò æô³µ Çл»µØÍ¼Âß¼")  | 
|     if curTruck == None:  | 
|         #GameWorld.Log("Íæ¼Ò Ã»ÓРæô³µ")  | 
|         return False  | 
|       | 
|     dist = GameWorld.GetDist(curTruck.GetPosX(), curTruck.GetPosY(),  | 
|                              curPlayer.GetPosX(), curPlayer.GetPosY())  | 
|     if dist > ChConfig.Def_PlayerTruckEventDist:  | 
|         #GameWorld.Log("Íæ¼ÒºÍæô³µ¾àÀë¹ýÔ¶, æô³µ²»Çл»  %d" %dist)  | 
|         return False  | 
|       | 
| #    #Íæ¼ÒÏÂæô³µ  | 
| #    if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvTruck :  | 
| #        PlayerTruck.PlayerTruckDown(curPlayer,curTruck)  | 
|     #GameWorld.Log("Íæ¼ÒºÍæô³µÒ»ÆðÇл»µØÍ¼")  | 
|     #1. ÔÚ¶Ô·½µØÍ¼´´½¨æô³µ  | 
|     #curTruck.ResetWorldPos(mapID, targetPosX, targetPosY)  | 
|     #2. Ïûʧ±¾µØÍ¼æô³µ  | 
|       | 
|     return True  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò¿ªÊ¼Çл»µØÍ¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò¿ªÊ¼Çл»µØÍ¼  | 
| def DoPlayerResetWorldPos(curPlayer, tick):  | 
|     NotifyStartChangeMap(curPlayer) # Í¨Öª¿ªÊ¼Çл»µØÍ¼  | 
|     #Ôڴ˺¯ÊýÖв»¿ÉÖжÏ, Ò»¶¨Òªµ÷ÓÃDoResetWorldPosAndClearº¯Êý  | 
|     #·ñÔò, »áÔÚBalanceServerÖп¨×¡  | 
|     takeTruck = curPlayer.GetChangeMapTakeTruck()  | 
|       | 
|     #Èç¹ûÓÐæô³µ, ´øÉÏæô³µ  | 
|     if takeTruck == True:  | 
|         if not __GetCanChangeMapSetTruck(curPlayer):  | 
|             takeTruck = False  | 
|               | 
|     #Èç¹û²»Èôøæô³µ, ²¢ÇÒÍæ¼ÒÔÚÈËïÚºÏһ״̬, ÄÇôÈÃÍæ¼Òϳµ  | 
|     if takeTruck == False and curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvTruck:  | 
|         curTruck = curPlayer.GetTruck()  | 
|         if curTruck:  | 
|             PlayerTruck.PlayerTruckDown(curPlayer, curTruck)  | 
|           | 
|     curPlayer.SetChangeMapTakeTruck(takeTruck)  | 
|       | 
|     #À뿪µØÍ¼·þÎñÆ÷  | 
|     __PlayerLeaveServerLogic(curPlayer, tick, False)  | 
|       | 
|     FBLogic.DoPlayerChangeMapLogic(curPlayer, tick)  | 
|     #summonList = list()  | 
|     #ÕٻسèÎï  | 
|     PetControl.ReCallFightPet(curPlayer)  | 
|     #1. É¾³ý×Ô¼º²»ÐèÒªµÄÕÙ»½ÊÞ(»ðÑæÖ®ÁéµÈ)  | 
|     #±ØÐëÓÃwhile, ÒòΪÔÚÑ»·ÖÐҪɾ³ý  | 
|     # ÕÙ»½ÊÞÇеØÍ¼²»´ø¹ýÈ¥  | 
|     while curPlayer.GetSummonCount():  | 
|         summonNPC = curPlayer.GetSummonNPCAt(0)  | 
|         NPCCommon.SetDeadEx(summonNPC)  | 
|   | 
| #    summonIndex = 0  | 
| #    while summonIndex < curPlayer.GetSummonCount():  | 
| #        summonNPC = curPlayer.GetSummonNPCAt(summonIndex)  | 
| #          | 
| #        #2009.4.21, Èç¹ûÕÙ»½ÊÞµÄËÙ¶ÈΪ0, ´ú±íÕâ¸öÕÙ»½ÊÞΪÕÈ×Ó  | 
| #        #Çл»µØÍ¼²»¿É´ø¹ýÈ¥  | 
| #        #֮ǰÓÃÓ²Åж¨µÄ  | 
| #        if summonNPC.GetSpeed() == 0:  | 
| #            #Çл»µØÍ¼²»ÄÜ´ø¹ýÈ¥  | 
| #            NPCCommon.SetDeadEx(summonNPC)  | 
| #            continue  | 
| #              | 
| #        #Çл»µØÍ¼¿ÉÒÔ´ø¹ýÈ¥ , Çå¿ÕÕÙ»½ÊÞ³ðºÞ,ÉËѪÁÐ±í  | 
| #        summonNPCControl = NPCCommon.NPCControl(summonNPC)  | 
| #        summonNPCControl.ClearNPCAngry()  | 
| #        summonNPCControl.ClearNPCHurtList()  | 
| #        summonList.append(summonNPC)  | 
| #        summonIndex += 1  | 
|           | 
|     changeMapID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ChangeMapID)  | 
|     # ¸üÐÂ×îºóÒ»´ÎÀ뿪µÄ·ÇÖÐÁ¢³£¹æµØÍ¼, ´ÓÖÐÁ¢µØÍ¼Í˳öʱÐèÒª»Øµ½¸ÃµØ·½£¬±ØÐëÔÚ DoResetWorldPosAndClear Ö®Ç°¸üР | 
|     if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull and curPlayer.GetMapID() not in IpyGameDataPY.GetFuncEvalCfg("MapLine", 4):  | 
|         mapID = curPlayer.GetMapID()  | 
|         posX = curPlayer.GetPosX()  | 
|         posY = curPlayer.GetPosY()  | 
|         lineID = curPlayer.GetClientLineID() # ³£¹æµØÍ¼Ó÷ÖÏßID  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromMapID, mapID)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromPosX, posX)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromPosY, posY)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromLineID, lineID)  | 
|         GameWorld.DebugLog("×îºóÒ»´ÎÀ뿪µÄ·ÇÖÐÁ¢³£¹æµØÍ¼¸üÐÂ!mapID=%s,lineID=%s,Pos(%s,%s)" % (mapID, lineID, posX, posY))  | 
|     # µ±Ç°Êǿɷµ»ØµÄ¸±±¾µØÍ¼ ÇÒ Ä¿±êµØÍ¼Îª¸±±¾  | 
|     elif curPlayer.GetMapID() in ChConfig.Def_CanBackFBMap and curPlayer.GetMapID() != changeMapID \  | 
|         and GameWorld.GetMap().GetMapFBTypeByMapID(changeMapID) != IPY_GameWorld.fbtNull:  | 
|         mapID = curPlayer.GetMapID()  | 
|         posX = curPlayer.GetPosX()  | 
|         posY = curPlayer.GetPosY()  | 
|         lineID = GetFBFuncLineID(curPlayer) # ¸±±¾Óù¦ÄÜÏß·ID  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBMapID, mapID)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBPosX, posX)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBPosY, posY)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBLineID, lineID)  | 
|         GameWorld.DebugLog("½øÈ븱±¾Ê±£¬×îºóÒ»´ÎÀ뿪µÄ¿É·µ»ØµÄ¸±±¾ID¸üÐÂ!mapID=%s,lineID=%s,Pos(%s,%s)" % (mapID, lineID, posX, posY))  | 
|           | 
|     # À뿪µØÍ¼  | 
|     PlayerAssist.OnPlayerLeaveMap(curPlayer)  | 
|       | 
|     # ´Ó¸±±¾ÖÐÇÐͼ  | 
|     if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|         #ĬÈÏ»ØÂúѪ  | 
|         if GameObj.GetHP(curPlayer) > 0 and curPlayer.GetPlayerAction() != IPY_GameWorld.paDie and GameObj.GetHP(curPlayer) < GameObj.GetMaxHP(curPlayer):  | 
|             GameObj.SetHPFull(curPlayer)  | 
|               | 
|     #2. µ÷ÓÃÇл»µØÍ¼½Ó¿Ú  | 
|     curPlayer.DoResetWorldPosAndClear()  | 
|       | 
|     #3. Íæ¼ÒÒѾ´«Ë͹ýÈ¥ÁË, É¾³ýÕâ¸öÍæ¼ÒµÄ¸½¼ÓÕÙ»½ÊÞ(æô³µ, »òÕß»ÆÈªÊ¹Õß)  | 
|     #for curSummon in summonList:  | 
|     #    NPCCommon.SetDeadEx(curSummon)  | 
|           | 
|     if takeTruck == True:  | 
|         curTruck = curPlayer.GetTruck()  | 
|           | 
|         if curTruck != None:  | 
|             curPlayer.SetTruck(None)  | 
|             curTruck.Disappear()  | 
|               | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÀ뿪¸±±¾  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÀ뿪¸±±¾  | 
| def PlayerLeaveFB(curPlayer):  | 
|     if not curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RouteServerInitOK):  | 
|         #RouteServerδ³õʼ»¯²»ÔÊÐíÇл»µØÍ¼, »º´æ´¦Àí  | 
|         GameServerRefresh.Set_PlayerRouteServerInitOK_OnLeaveFB(curPlayer, 1)  | 
|         return  | 
|       | 
|     GameWorld.Log("PlayerLeaveFB...", curPlayer.GetPlayerID())  | 
|     if GameWorld.IsCrossServer():  | 
|         CrossRealmPlayer.PlayerExitCrossServer(curPlayer)  | 
|         return  | 
|       | 
|     funcLineID = 0  | 
|     enterFBFree = False  | 
|     #ÖÐÁ¢µØÍ¼»Øµ½ÉÏÒ»´Î·ÇÖÐÁ¢³£¹æµØÍ¼      | 
|     if curPlayer.GetMapID() in IpyGameDataPY.GetFuncEvalCfg("MapLine", 4) or curPlayer.GetMapID() in ChConfig.Def_CanBackFBMap:  | 
|         mapID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromMapID)  | 
|         posX = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromPosX)  | 
|         posY = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromPosY)  | 
|         lineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromLineID)  | 
|         # ÖØÖÃ  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromMapID, 0)  | 
|         # ÀϺÅÖ§³Ö£¬±¾À´¾ÍÔÚÖÐÁ¢µØÍ¼µÄ£¬·µ»ØÐÂÊÖ´å  | 
|         if not mapID:  | 
|             # {Ö°Òµ:[dataMapID,posX,posY], ...}  | 
|             createRoleMapDict = IpyGameDataPY.GetFuncEvalCfg("CreateRoleMap", 1, {})  | 
|             if not createRoleMapDict:  | 
|                 return  | 
|             job = curPlayer.GetJob()  | 
|             lineID = 0  | 
|             if job in createRoleMapDict:  | 
|                 mapID, posX, posY = createRoleMapDict[job]  | 
|             else:  | 
|                 mapInfoList = createRoleMapDict.values()  | 
|                 mapID, posX, posY = mapInfoList[0]  | 
|     #À뿪¸±±¾  | 
|     else:  | 
|         fromFBMapID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromFBMapID)  | 
|         # »Øµ½ÉÏÒ»´Î¿É·µ»ØµÄ¸±±¾Àï  | 
|         if fromFBMapID:  | 
|             mapID = fromFBMapID  | 
|             posX = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromFBPosX)  | 
|             posY = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromFBPosY)  | 
|             lineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FromFBLineID)  | 
|             funcLineID = lineID # »Ø¸±±¾µÄÒªÖ¸¶¨¹¦ÄÜÏß·ID  | 
|             enterFBFree = True # ·µ»ØµÄÃâ·Ñ½øÈë  | 
|             # ÖØÖÃ  | 
|             NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBMapID, 0)  | 
|             GameWorld.DebugLog("À뿪¸±±¾£¬·µ»Ø¿É֮ǰ¿É·µ»ØµÄ¸±±¾! fromFBMapID=%s,lineID=%s,posXY(%s,%s)" % (mapID, lineID, posX, posY))  | 
|         else:  | 
|             mapID = curPlayer.GetFromMapID()  | 
|             posX = curPlayer.GetFromPosX()  | 
|             posY = curPlayer.GetFromPosY()  | 
|             lineID = curPlayer.GetFromLineID()  | 
|               | 
|     if mapID == curPlayer.GetMapID():  | 
|         # Èç¹ûÔÚͬһÕŵØÍ¼, È¡DBÖØÉúµã, ÆÕͨµØÍ¼ÏÂÏßÖØÉÏʱFromMapID»á±»ÉèÖÃΪ±¾µØÍ¼  | 
|         gameMap = GameWorld.GetMap()  | 
|         mapID, posX, posY = gameMap.GetRebornMapID(), gameMap.GetRebornMapX(), gameMap.GetRebornMapY()  | 
|         #posX, posY = GameMap.GetNearbyPosByDis(posX, posY, ChConfig.Def_RebornPos_Area_Range)  | 
|           | 
|     #copyMapID = curPlayer.GetCopyMapID()  | 
|     GameWorld.Log("PlayerLeaveFB MapID = %d, PosX = %d, PosY = %d" % (mapID, posX, posY), curPlayer.GetPlayerID())  | 
|       | 
|     if GameWorldProcess.IsNoPlayerNeedCloseFB() and GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount() == 1:  | 
|         #Èç¹û¸±±¾ÖÐÖ»ÓÐÕâÒ»¸öÈË, ÄÇô°ÑÕâ¸ö¸±±¾ÉèÖÃÎªÍæ¼Ò°²È«ÏÂÏß, ¹Ø±Õ¸±±¾  | 
|         gameFB = GameWorld.GetGameFB()  | 
|         gameFB.SetIsSafeClose(1)  | 
|       | 
|     #===============================================================================================  | 
|     # #Èç¹ûÍæ¼ÒÊÇËÀÍö״̬£¬ÔòÏȸ´»î£¬ÊÖÓβ߻®²»Ï븴»îÍ˳ö  | 
|     # if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  | 
|     #    curPlayer.Reborn(ChConfig.rebornType_System)  | 
|     #    GameObj.SetHPFull(curPlayer)  | 
|     #    ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)  | 
|     #===============================================================================================  | 
|       | 
|     PlayerResetWorldPosFB(curPlayer, mapID, posX, posY, False, lineID, funcLineID=funcLineID, enterFBFree=enterFBFree)  | 
|       | 
|     #ÔÚ¿ÕÏлòÕßÒÆ¶¯×´Ì¬ÏÂ,²ÅÄÜËøËÀÍæ¼Ò  | 
|     if curPlayer.GetPlayerAction() in [IPY_GameWorld.paNull] or curPlayer.IsMoving():  | 
|         #°ÑÍæ¼ÒËøËÀ  | 
|         curPlayer.BeginEvent()  | 
|       | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
|   | 
| def PlayerEnterCrossServer(curPlayer, mapID, lineID):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     GameWorld.Log("Íæ¼ÒÇëÇó½øÈë¿ç·þµØÍ¼: mapID=%s,lineID=%s" % (mapID, lineID), playerID)  | 
|     if mapID not in ChConfig.Def_CrossMapIDList:  | 
|         return  | 
|       | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     lastRequestTick = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_RequestEnterCrossServerTick)  | 
|     if lastRequestTick and tick - lastRequestTick < 5000:  | 
|         GameWorld.DebugLog("    ÇëÇó½øÈë¿ç·þCDÖÐ!", playerID)  | 
|         NotifyCode(curPlayer, "RequestEnterCrossServerCD")  | 
|         return  | 
|       | 
|     crossRegisterMap = curPlayer.NomalDictGetProperty(ChConfig.Def_PlayerKey_CrossRegisterMap)  | 
|     if crossRegisterMap:  | 
|         GameWorld.ErrLog("¿ç·þÒѾÔÚÉÏ´«Êý¾Ý£¬²»Öظ´Ìá½»!crossRegisterMap=%s,mapID=%s" % (crossRegisterMap, mapID), playerID)  | 
|         return  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         GameWorld.DebugLog("¿ç·þ·þÎñÆ÷²»ÔÊÐí¸Ã²Ù×÷!")  | 
|         return  | 
|       | 
|     if GetCrossMapID(curPlayer):  | 
|         GameWorld.ErrLog("Íæ¼Òµ±Ç°Îª¿ç·þ״̬£¬²»ÔÊÐíÔÙ´ÎÇëÇó½øÈë¿ç·þ!", curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     if not CrossRealmPlayer.IsCrossServerOpen():  | 
|         NotifyCode(curPlayer, "CrossMatching18")  | 
|         return  | 
|       | 
|     if GameObj.GetHP(curPlayer) <= 0:  | 
|         NotifyCode(curPlayer, "CrossMap4")  | 
|         return  | 
|       | 
|     if PlayerCrossRealmPK.GetIsCrossPKMatching(curPlayer):  | 
|         NotifyCode(curPlayer, "CrossMap3")  | 
|         return  | 
|       | 
|     if PlayerState.IsInPKState(curPlayer):  | 
|         NotifyCode(curPlayer, "SingleEnterPK", [mapID])  | 
|         return  | 
|       | 
|     fbIpyData = FBCommon.GetFBIpyData(mapID)  | 
|     if fbIpyData:  | 
|         fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID, False)  | 
|         if not fbLineIpyData:  | 
|             GameWorld.DebugLog("¸±±¾±íÕÒ²»µ½¸±±¾¶ÔÓ¦¹¦ÄÜÏß·!mapID=%s,lineID=%s" % (mapID, lineID))  | 
|             return  | 
|         ret = FBCommon.CheckCanEnterFBComm(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData)  | 
|         if ret != ShareDefine.EntFBAskRet_OK:  | 
|             return  | 
|           | 
|         if not FBLogic.OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|             GameWorld.DebugLog("    OnEnterFBEvent False!", curPlayer.GetPlayerID())  | 
|             if mapID in [ChConfig.Def_FBMapID_CrossBattlefield]:  | 
|                 NotifyCode(curPlayer, "GeRen_chenxin_268121")  | 
|             else:  | 
|                 NotifyCode(curPlayer, "SingleEnterDefaul")  | 
|             return  | 
|           | 
|     # ÐèÒª¶¯Ì¬·Ö²¼Ïß·µÄµØÍ¼£¬·¢Ë͵½¿ç·þ·þÎñÆ÷½øÐзÖÅä  | 
|     if mapID in ChConfig.Def_CrossDynamicLineMap:  | 
|         extendInfo = {}  | 
|         if mapID == ChConfig.Def_FBMapID_CrossDemonKing:  | 
|             bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID(mapID, lineID)  | 
|             if not bossID:  | 
|                 return  | 
|             extendInfo["BossID"] = bossID  | 
|               | 
|         msgDict = {"PlayerID":curPlayer.GetPlayerID(), "MapID":mapID, "FuncLineID":lineID, "LV":curPlayer.GetLV()}  | 
|         if extendInfo:  | 
|             msgDict.update(extendInfo)  | 
|         GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_EnterFB, msgDict)  | 
|     else:  | 
|         isSend = GY_Query_CrossRealmReg.RegisterEnterCrossServer(curPlayer, mapID, lineID=lineID)  | 
|         if not isSend:  | 
|             return  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_RequestEnterCrossServerTick, tick)  | 
|     return  | 
|   | 
| ##Íæ¼Ò½øÈ븱±¾  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param posX ×ø±êX  | 
| # @param posY ×ø±êY  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Òµ¥¶À½øÈ븱±¾  | 
| def PlayerEnterFB(curPlayer, mapID, lineID, posX=0, posY=0):  | 
|     mapID = FBCommon.GetRecordMapID(mapID)  | 
|     GameWorld.Log("Íæ¼ÒÇëÇó½øÈ븱±¾! mapID=%s,lineID=%s,posX=%s,posY=%s"   | 
|                   % (mapID, lineID, posX, posY), curPlayer.GetPlayerID())  | 
|       | 
|     # µ±ÈÕ»»Õ½Ã˲»¿É½øÈëµÄµØÍ¼, ¸ÄΪ°´Ð¡Ê±Ëã  | 
|     #if mapID in ChConfig.Def_ChangeFamilyCanNotEnterMap:  | 
|     #    if PlayerFamily.GetPlayerChangeFamilyPastHour(curPlayer) < 24:  | 
|     #        NotifyCode(curPlayer, 'jiazu_xyj_671654')  | 
|     #        return  | 
|           | 
| #    #¿ç·þ»î¶¯ÈËÊý·ÖÁ÷´¦Àí  | 
| #    if GameWorld.IsCrossServer():  | 
| #        reqMapID = mapID  | 
| #        mapID = __GetMergeFBPlayerMapID(curPlayer, reqMapID)  | 
| #        if not mapID:  | 
| #            GameWorld.ErrLog("ÕÒ²»µ½¿É·ÖÅä½øÈëµÄ¿ç·þ»î¶¯µØÍ¼ID! reqMapID=%s" % reqMapID)  | 
| #            return  | 
|         | 
|     #¹ýÂË·â°üµØÍ¼ID  | 
|     if not GameWorld.GetMap().IsMapIDExist(mapID):  | 
|         GameWorld.ErrLog('###·Ç·¨µØÍ¼Êý¾Ý£¬mapID: %s' % (mapID), curPlayer.GetID())  | 
|         return  | 
|    | 
| #    if not GameWorld.GetMap().CanMove(curPlayer.GetPosX(), curPlayer.GetPosY()):  | 
| #        # ×ø±ê²»¿ÉÒÆ¶¯Ôò²»ÄÜ´«ËÍ£¬²»È»»áµ¼ÖÂÍ˳ö¸±±¾ÎÞ·¨ÍË»ØÀ´Ô´µØ  | 
| #        GameWorld.ErrLog("ÔÕϰµãÎÞ·¨Çл»µØÍ¼ %s" % ([curPlayer.GetPosX(), curPlayer.GetPosY()]))  | 
| #        return  | 
|    | 
|     #½øÈ븱±¾Í¨Óüì²é  | 
|     fbIpyData = FBCommon.GetFBIpyData(mapID)  | 
|     fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID)  | 
|     sceneMapID = mapID if not fbLineIpyData else fbLineIpyData.GetMapID()  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     if CheckMoveToFB(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, tick) != ShareDefine.EntFBAskRet_OK:  | 
|         return  | 
| #    if mapID == ChConfig.Def_FBMapID_XMZZ:  | 
| #        #ÏÉħ֮Õù  | 
| #        GameLogic_XMZZ.XMZZStartFight(curPlayer)  | 
| #        return  | 
|     if posX == 0 and posY == 0:  | 
|         ipyEnterPosInfo = FBCommon.GetFBLineEnterPosInfo(mapID, lineID, fbLineIpyData)  | 
|         retPos = FBLogic.OnGetFBEnterPos(curPlayer, mapID, lineID, ipyEnterPosInfo, tick)  | 
|           | 
|         if not retPos:  | 
|             GameWorld.ErrLog("δÕÒµ½½øÈ븱±¾×ø±ê£¡mapID=%s,lineID=%s" % (mapID, lineID))  | 
|             return  | 
|           | 
|         posX, posY = retPos  | 
|           | 
|     #===============================================================================================  | 
|     # if not EventShell.DoLogic_EnterFbGameEvent(curPlayer, mapID, tick):  | 
|     #    GameWorld.Log("DoLogic_EnterFbGameEvent False£¡mapID=%s,lineID=%s" % (mapID, lineID))  | 
|     #    return   | 
|     #===============================================================================================  | 
|       | 
|     if curPlayer.IsMoving():  | 
|         curPlayer.StopMove()  | 
|       | 
|     fbID = 0 # ºó¶ËµÄÐéÄâÏß·  | 
|     isSendToGameServer = False  | 
|     mapFBType = GameWorld.GetMap().GetMapFBTypeByMapID(sceneMapID) # ÅжÏÊÇ·ñ×é¶Ó±¾ÐèÒªÒÔ³¡¾°µØÍ¼Åжϣ¬ÒòΪ²ß»®¿ÉÄÜÉ趨²»Í¬¹¦ÄÜÏß·IDµÄ¸±±¾ÀàÐͲ»Ò»Ñù£¬±ÈÈçС¾³½ç¡¢´ó¾³½ç  | 
|     if mapFBType == IPY_GameWorld.fbtTeam and curPlayer.GetTeamID():  | 
|         if curPlayer.GetTeamLV() != IPY_GameWorld.tmlLeader:  | 
|             GameWorld.Log("·Ç¶Ó³¤£¬ÎÞ·¨·¢Æð½øÈë×é¶Ó¸±±¾ÇëÇó!", curPlayer.GetPlayerID())  | 
|             return  | 
|         isSendToGameServer = True  | 
|     if isSendToGameServer or mapID in ChConfig.Def_MapID_SendToGameServer \  | 
|         or mapID in ReadChConfig.GetEvalChConfig("MapID_SendToGameServer"):  | 
|         extendParamList = []  | 
|         if mapID == ChConfig.Def_FBMapID_SealDemon:  | 
|             newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine', 1)  | 
|             # ÐÂÊÖÏßÂ·ÌØÊâ´¦Àí£¬Ö±½Ó½øÈë  | 
|             if lineID in newbielineList:  | 
|                 GameWorld.DebugLog("·âħ̳ÐéÄâÏß·ֻÄÜͨ¹ý×Ô¶¨Ò峡¾°½øÈëÌôÕ½£¡")  | 
|                 #PlayerResetWorldPosFB(curPlayer, mapID, posX, posY, False, fbID, funcLineID=lineID)  | 
|                 return  | 
|             else:  | 
|                 bossID = GameLogic_SealDemon.CurFBLineBOSSID(lineID)  | 
|                 extendParamList = [bossID]  | 
|         elif mapID == ChConfig.Def_FBMapID_ZhuXianBoss:  | 
|             bossID = GameLogic_ZhuXianBoss.CurFBLineBOSSID(lineID)  | 
|             extendParamList = [bossID, -1]  | 
|             enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_ZhuXianBoss)  | 
|             if enterCnt >= FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss):  | 
|                 if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhuXianBossHelpCnt):  | 
|                     extendParamList = [bossID, curPlayer.GetFamilyID()]  | 
|         elif mapID == ChConfig.Def_FBMapID_DemonKing:  | 
|             bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID(mapID, lineID)  | 
|             extendParamList = [bossID]  | 
|         elif mapID in ChConfig.Def_MapID_LineIDToPropertyID:  | 
|             enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)  | 
|             extendParamList = [enterCnt]  | 
|         SendToGameServerEnterFB(curPlayer, mapID, lineID, tick, extendParamList)  | 
|         return  | 
|       | 
|     PlayerResetWorldPosFB(curPlayer, mapID, posX, posY, False, fbID, funcLineID=lineID)  | 
|     return  | 
|   | 
| ##·¢Ë͵½GameServerÇëÇó½øÈ븱±¾  | 
| #@param curPlayer Íæ¼Ò  | 
| #@param mapID µØÍ¼id  | 
| #@param lineID Ïß·id  | 
| #@param tick Ê±¼ä´Á  | 
| #@return ·µ»ØÖµÎÞÒâÒå  | 
| def SendToGameServerEnterFB(curPlayer, mapID, lineID, tick, extendParamList=[]):  | 
|     #lineID = FBLogic.GetPlayerFBLineID(curPlayer, mapID, tick)  | 
|       | 
|     GameWorld.Log("SendToGameServerEnterFB mapID=%s,lineID=%s,extendParamList=%s"   | 
|                   % (mapID, lineID, extendParamList), curPlayer.GetID())  | 
|     # »ñÈ¡Íæ¼ÒËùÊô·ÖÏß  | 
|     if lineID == None:  | 
|         lineID = FBLogic.GetPlayerFBLineID(curPlayer, mapID, tick)  | 
|           | 
|     #GameWorld.DebugLog("send GameServer_QueryPlayerByID")  | 
|     # ÇëÇóGameServerÄ¿±ê¸±±¾GameWorldË÷Òý  | 
|     sendMsg = [mapID, lineID]  | 
|     sendMsg.extend(extendParamList)  | 
|     sendMsg = "%s" % sendMsg  | 
|     curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_EnterFB, 0, 'EnterFB', sendMsg, len(sendMsg))  | 
|     return  | 
|       | 
| ##¼ì²éÍæ¼Ò״̬ÊÇ·ñ¿ÉÒÔÒÆ¶¯µ½¸±±¾  | 
| #@param curPlayer Íæ¼ÒʵÀý  | 
| #@return ·µ»ØÖµÎÞÒâÒå  | 
| #@remarks ¼ì²éÍæ¼Ò״̬ÊÇ·ñ¿ÉÒÔÒÆ¶¯µ½¸±±¾  | 
| def CheckMoveToFB(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, tick, isNotify=True, isTeamAsk=False):  | 
|     '''ÅжϿɷñ½øÈ븱±¾£¬°üº¬ÊÖ¶¯¼°Æ¥Åä  | 
|     @param isTeamAsk: ÊÇ·ñÊǶÓÎé½øÈëÇëÇóµÄ£¬Ò»°ãÊǶÓÎé״̬Ï£¬¶Ó³¤·¢Æð½øÈ븱±¾£¬ÐèÒª¼ì²é¶ÓÔ±¿É·ñ½øÈ룬´ËʱΪTrue£¬¿É×öһЩ¸½¼Ó´¦Àí  | 
|     @note: ²ß»®ÒªÇóÌáʾ°´ÓÅÏȼ¶À´£¬¸±±¾×ÔÉíµÄÌõ¼þÏÞÖÆÓÅÏÈÌáʾ£¬ÆäËû¸½¼ÓÌáʾÓÅÏȼ¶½ÏµÍ  | 
|     '''  | 
|     ret = FBCommon.CheckCanEnterFBComm(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, 1, isNotify, isTeamAsk)  | 
|     if ret != ShareDefine.EntFBAskRet_OK:  | 
|         return ret  | 
|       | 
|     if GameObj.GetHP(curPlayer) <= 0:  | 
|         GameWorld.Log("Íæ¼ÒÒѾËÀÍö, ÎÞ·¨½øÈ븱±¾!")  | 
|         return ShareDefine.EntFBAskRet_Dead  | 
|       | 
|     if PlayerTJG.GetIsTJG(curPlayer):  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "SingleEnterDefaul", [mapID])  | 
|         return ShareDefine.EntFBAskRet_TJG  | 
|       | 
|     ## ¶ÓÎé¼ì²éµÄÇé¿ö£¬¶Ó³¤²»´¦Àí£¬Ö»´¦Àí¶ÓÔ±  | 
|     if isTeamAsk and curPlayer.GetTeamLV() != IPY_GameWorld.tmlLeader:  | 
|         # ºó¶ËÖ»×öboss״̬Ï£¬±»¶¯½øÈ븱±¾ÏÞÖÆ£¬·ÀÖ¹´òbossÖб»À½øÈ¥¸±±¾  | 
|         # boss״̬µÄÆäËû´«ËÍÏÞÖÆÓÉǰ¶Ë¿ØÖÆ£¬ÒòΪ²ß»®Òª¸ù¾Ý½çÃæÀ´´¦Àí£¬ÓÐЩ½çÃæÔÊÐí´«ËÍ£¬ÓÐЩ²»ÔÊÐí  | 
|         if PlayerState.IsInBossState(curPlayer):  | 
|             return ShareDefine.EntFBAskRet_BossState  | 
|           | 
|     ## PK״̬¼ì²é  | 
|     if PlayerState.IsInPKState(curPlayer):  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "SingleEnterPK", [mapID])  | 
|         return ShareDefine.EntFBAskRet_PKState  | 
|       | 
|     ## ¿ç·þPKÆ¥ÅäÖÐ  | 
|     if PlayerCrossRealmPK.GetIsCrossPKMatching(curPlayer):  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "CrossMatching8", [mapID])              | 
|         return ShareDefine.EntFBAskRet_CrossPKMatching  | 
|       | 
|     ## ¿ç·þµØÍ¼ÖÐ  | 
|     if GetCrossMapID(curPlayer) and mapID not in ChConfig.Def_CrossMapIDList:  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "CrossMap5", [mapID])  | 
|         return ShareDefine.EntFBAskRet_InCrossMap  | 
|       | 
|     #===============================================================================================  | 
|     # # ÕâÀï²»×ö״̬ÏÞÖÆ£¬ÓÉǰ¶Ë´¦Àí£¬ÒòΪ²ß»®Òª¸ù¾Ý½çÃæÀ´´¦Àí£¬Í¬Ò»´«Ë͹¦ÄÜÓпÉÄÜÔÚ²»Í¬½çÃæ  | 
|     # # PK״̬¼ì²é  | 
|     # if PlayerState.IsInPKState(curPlayer):  | 
|     #    if isNotify:  | 
|     #        NotifyCode(curPlayer, "SingleEnterPK", [mapID])  | 
|     #    return ShareDefine.EntFBAskRet_PKState  | 
|     #   | 
|     # # ´òboss״̬¼ì²é  | 
|     # if PlayerState.IsInBossState(curPlayer):  | 
|     #    if isNotify:  | 
|     #        NotifyCode(curPlayer, "SingleEnterBoss", [mapID])  | 
|     #    return ShareDefine.EntFBAskRet_BossState  | 
|     #===============================================================================================  | 
|       | 
|     playerAction = curPlayer.GetPlayerAction()  | 
|     if playerAction == IPY_GameWorld.paPreparing:  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "SingleEnterGather", [mapID])  | 
|         return ShareDefine.EntFBAskRet_Preparing  | 
|       | 
|     if playerAction == IPY_GameWorld.paSit:  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "Carry_lhs_697674")  | 
|         return ShareDefine.EntFBAskRet_Sit  | 
|       | 
|     if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "Carry_lhs_697674")  | 
|         GameWorld.Log("¿Í»§¶Ë×Ô¶¨Ò峡¾°ÏÂÎÞ·¨½øÈ븱±¾!", curPlayer.GetPlayerID())  | 
|         return ShareDefine.EntFBAskRet_Other  | 
|       | 
|     if playerAction in ChConfig.Def_Player_Cannot_TransState:  | 
|         #Carry_lhs_697674£ºÄúµ±Ç°Ëù´¦µÄ״̬²»ÄܽøÐд«ËÍ!  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "Carry_lhs_697674")  | 
|         return ShareDefine.EntFBAskRet_Other  | 
|       | 
|     for index in ChConfig.Def_Player_NotCan_EnterFbPyGameEvenState:  | 
|         if GetPyPlayerAction(curPlayer, index):  | 
|             #Carry_lhs_697674£ºÄúµ±Ç°Ëù´¦µÄ״̬²»ÄܽøÐд«ËÍ!  | 
|             if isNotify:  | 
|                 NotifyCode(curPlayer, "Carry_lhs_697674")  | 
|             return ShareDefine.EntFBAskRet_Other  | 
|           | 
|     #ÒÆ¶¯Öв»Ö´Ðд˲Ù×÷  | 
| #    if curPlayer.IsMoving():  | 
| #        #NotifyCode(curPlayer, "GeRen_lhs_0")  | 
| #        return False  | 
|   | 
| #    #ÀïÚÖÐÎÞ·¨´«Ë͵½¸±±¾  | 
| #    if curPlayer.GetTruck():  | 
| #        #NotifyCode(curPlayer, "Convey_Duplicate_Lost01")  | 
| #        return False  | 
|   | 
|     #Õ½¶·×´Ì¬ÖÐÎÞ·¨´«Ë͵½¸±±¾  | 
|     #if curPlayer.IsBattleState():  | 
|     #    NotifyCode(curPlayer, "Carry_lhs_202580")  | 
|     #    return False  | 
|   | 
|     #µ±Ç°µØÍ¼²»ÊÇÆÕͨµØÍ¼  | 
|     if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|         canFBMoveToOther = False  | 
|         fbEnableTransportMap = ReadChConfig.GetEvalChConfig("FBEnableTransportMap")  | 
|         curMapID = GameWorld.GetMap().GetMapID()  | 
|         if curMapID in fbEnableTransportMap and mapID in fbEnableTransportMap[curMapID]:  | 
|             canFBMoveToOther = True  | 
|         if curMapID in ChConfig.Def_CanBackFBMap:  | 
|             canFBMoveToOther = True  | 
|         toMapFBType = GameWorld.GetMap().GetMapFBTypeByMapID(mapID)  | 
|         if toMapFBType == IPY_GameWorld.fbtNull:  | 
|             if curMapID in IpyGameDataPY.GetFuncEvalCfg('DungeonDeliver', 1):  | 
|                 canFBMoveToOther = True  | 
|         elif FBCommon.GetRecordMapID(curMapID) == FBCommon.GetRecordMapID(mapID):  | 
|             if FBLogic.CanChangeSameDataMapFB(curPlayer, mapID, lineID):  | 
|                 canFBMoveToOther = True  | 
|                   | 
|         if not canFBMoveToOther:  | 
|             if isNotify:  | 
|                 NotifyCode(curPlayer, "SingleEnterDungeon", [mapID])  | 
|             return ShareDefine.EntFBAskRet_InFB  | 
|       | 
|     if not FBLogic.OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|         GameWorld.DebugLog("    OnEnterFBEvent False!", curPlayer.GetPlayerID())  | 
|         if isNotify:  | 
|             NotifyCode(curPlayer, "SingleEnterDefaul")  | 
|         return ShareDefine.EntFBAskRet_Other  | 
|       | 
|     return ShareDefine.EntFBAskRet_OK  | 
| #---------------------------------------------------------------------  | 
| ##Ë¢ÐÂÍæ¼ÒʱÖÓ£¬ÇеØÍ¼Íæ¼ÒʱÖӼǼÇå¿Õ£¬´¦ÀíÏàÓ¦Âß¼  | 
| # @param curPlayer Íæ¼Ò  | 
| # @return ÎÞÒâÒå  | 
| # @remarks Ë¢ÐÂÍæ¼ÒʱÖÓ£¬ÇеØÍ¼Íæ¼ÒʱÖӼǼÇå¿Õ£¬´¦ÀíÏàÓ¦Âß¼  | 
| def RefreshPlayerTick(curPlayer):  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|       | 
|     #·À³ÁÃÔÇÐÏßʱ¼ä  | 
|     PlayerGameWallow.DoLogic_WallowOnlineTime(curPlayer, tick)  | 
|     return  | 
|   | 
|   | 
| #---------------------------------------------------------------------  | 
|   | 
| def PlayerResetWorldPosFBLineID(curPlayer, mapID, posX, posY, funcLineID):  | 
|     '''Íæ¼ÒÇл»µ½Ö¸¶¨¸±±¾¶ÔÓ¦µÄ¹¦ÄÜÏß·ID£¬ÊÊÓÃÓڶೡ¾°ºÏ²¢Ò»ÕŵØÍ¼µÄÇé¿ö£¬ºó¶ËÐèÔÚͬһÕÅÎïÀíµØÍ¼²ÅÄÜʹÓøú¯Êý  | 
|     ÓÉÓÚǰ¶ËµØÍ¼ºÏ²¢µÄ³¡¾°¼ÓÔØÊÇ·Ö¿ªµÄ£¬ËùÒÔÔÚÇг¡¾°µÄʱºò²»ÄÜÖ±½ÓÉèÖÃ×ø±ê£¬ÒòΪǰ¶Ëʵ¼ÊÉϲ»´æÔÚ¸Ã×ø±ê  | 
|     Íæ¼ÒÖ±½ÓÔÚµØÍ¼ÖÐÇл»¹¦ÄÜÏß·ID£¬´Ëʱǰ¶ËÐèÒª×ßÕý³£µÄÇÐͼÁ÷³Ì²ÅÄܼÓÔØÄ¿±ê¹¦ÄÜÏß·ID¶ÔÓ¦µÄ³¡¾°  | 
|     ¹ÊÕâÀï×ö¸öÐé¼ÙÇÐͼÁ÷³Ì  | 
|     '''  | 
|     if curPlayer.GetMapID() != mapID:  | 
|         return  | 
|       | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ReqFBFuncLine, funcLineID)  | 
|     GameWorld.Log("Íæ¼Ò¸±±¾Öбä¸ü¹¦ÄÜÏß·ÐéÄâÇеØÍ¼: mapID=%s,posX=%s,posY=%s,funcLineID=%s"   | 
|                   % (mapID, posX, posY, funcLineID), curPlayer.GetPlayerID())  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ChangeMapID, mapID)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ResetFBLinePosX, posX)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ResetFBLinePosY, posY)  | 
|       | 
|     NotifyPrepareChangeMap(curPlayer, mapID, funcLineID)  | 
|     NotifyStartChangeMap(curPlayer)  | 
|       | 
|     ## ·¢ËÍ 04 01 ÈËÎïËùÔڵij¡¾°³õʼ»¯#tagPlayerMapInit  | 
|     playerMapInit = ChNetSendPack.tagPlayerMapInit()  | 
|     playerMapInit.Clear()  | 
|     playerMapInit.MapID = mapID  | 
|     playerMapInit.PosX = posX  | 
|     playerMapInit.PosY = posY  | 
|     NetPackCommon.SendFakePack(curPlayer, playerMapInit)  | 
|       | 
|     curPlayer.SetSight(0) # ÊÓÒ°ÖÃ0£¬Çгɹ¦ºó»Ö¸´ÊÓÒ°£¬·ÀÖ¹½ÓÏÂÀ´ÌáǰÉèÖÃ×ø±êµ¼ÖÂǰ¶ËÊÓÒ°Ë¢ÐÂÒì³£  | 
|     curPlayer.ResetPos(posX, posY) # ÕâÀïÖ±½ÓÉèÖÃ×ø±ê£¬·Àֹǰ¶Ëδ¼ÓÔØ³¡¾°³É¹¦µôÏßµ¼ÖÂÖØµÇºó×ø±ê´íÎó  | 
|     SetFBFuncLineID(curPlayer, funcLineID) # ÕâÀïÖ±½ÓÉèÖóÉÄ¿±ê¹¦ÄÜÏß·ID£¬·Àֹǰ¶Ëδ¼ÓÔØ³¡¾°³É¹¦µôÏßµ¼ÖÂÖØµÇºó¼ÓÔØ³¡¾°Òì³£  | 
|       | 
|     ## ·¢ËÍ 01 09 ·þÎñÆ÷×¼±¸¾ÍÐ÷#tagServerPrepareOK  | 
|     prepareOK = ChNetSendPack.tagServerPrepareOK()  | 
|     prepareOK.Clear()  | 
|     NetPackCommon.SendFakePack(curPlayer, prepareOK)  | 
|     return  | 
|   | 
|   | 
| ##Íæ¼ÒÇл»µ½Ö¸¶¨¸±±¾ID  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param posX ×ø±êX  | 
| # @param posY ×ø±êY  | 
| # @param takeTruck ÊÇ·ñ´øïÚ³µ  | 
| # @param FBID ¸±±¾ID, ÐéÄâÏß·ID  | 
| # @param msg Ð¯´ýÐÅÏ¢  | 
| # @param canLock ÊÇ·ñËø¶¨Íæ¼Ò  | 
| # @param funcLineID ¸±±¾¹¦ÄÜÏß·ID£¬ÓÉǰ¶ËÇëÇó  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÇл»µ½Ö¸¶¨¸±±¾ID  | 
| def PlayerResetWorldPosFB(curPlayer, mapID, posX, posY, takeTruck, fbID=0, msg='', canLock=True, funcLineID=0, enterFBFree=False):  | 
|     '''  | 
|     ²ÎÊý˵Ã÷:  | 
|         @param fbID:  | 
|             ´óÓÚ0µÄÕûÊý:  | 
|                 Èç¹û²ÎÊýmapIDÖ¸¶¨µÄµØÍ¼´æÔÚfbIDÖ¸¶¨µÄ·ÖÏߣ¬ÔòÖ±½Ó´«Ë͵½²ÎÊýmapIDËùÖ¸¶¨µÄµØÍ¼µÄfbIDËùÖ¸¶¨µÄ·ÖÏߣ¬·ñÔòÔÚËùÓдæÔڵķÖÏßÖУ¬Ëæ»úѡһÌõ·ÖÏß´«Èë¡£fbIDµÄ¼ÆËã¼ûÏÂÃæfbID=-1µÄ˵Ã÷¡£  | 
|             -1£º  | 
|                 ½Ó¿ÚÄÚ²¿×Ô¶¯Ìæ»»³Éµ±Ç°fbID£¬´«Èë²ÎÊýmapIDËùÖ¸¶¨µÄµØÍ¼£¨ÕâÀï²ÎÊýmapIDÆäʵÊÇDataMapID£©µÄͬһfbIDµÄµØÍ¼(Èç¹ûÓУ¬Ã»ÓÐÔòËæ»ú)¡£  | 
|                 Ï־͵±Ç°fbIDµÄ¼ÆËã,¾ÙÀý˵Ã÷,¼ÙÉèµØÍ¼AºÍµØÍ¼BÔÚMapID.txtÅäÖÃÈçÏ£º  | 
|                 MapName     MapID   DataMapID FBCount  | 
|                 µØÍ¼A         101     101     3  | 
|                 µØÍ¼B         102     101     3   | 
|                 ¼´µØÍ¼AºÍµØÍ¼BÓй²Í¬µÄDataMapID,ÄÇôµØÍ¼B½ø³ÌÄÚ²¿µÄµÚÒ»Ìõ·ÖÏߵĿͻ§¶ËID¾ÍÊÇ3(ËùÓзÖÏߵĿͻ§¶Ë·ÖÏßID:0¡¢1¡¢2¡¢3¡¢4¡¢5)  | 
|             -2£º  | 
|                 Ö±½ÓËæ»ú´«µ½²ÎÊýmapIDËùÖ¸¶¨µÄµØÍ¼µÄijһÄÚ²¿·ÖÏߣ¬ÕâÀïµÄijһÄÚ²¿·ÖÏßÏÞÓÚMapID.txtÖÐmapIDΪ´«Èë²ÎÊýmapIDµÄµØÍ¼½ø³ÌµÄ·ÖÏß¡£  | 
|       | 
|         @param funcLineID: ¹¦ÄÜÏß·ID  | 
|     '''  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     lastTransTick = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TransTick)  | 
|     #Ôݶ¨1Ãë  | 
|     if tick - lastTransTick < 1000:  | 
|         GameWorld.Log("Íæ¼ÒÇÐͼCDÖÐ: mapID=%s,posX=%s,posY=%s,takeTruck=%s,fbID=%s,msg=%s,funcLineID=%s,tick=%s,lastTransTick=%s"   | 
|                       % (mapID, posX, posY, takeTruck, fbID, msg, funcLineID, tick, lastTransTick), curPlayer.GetPlayerID())  | 
|         NotifyCode(curPlayer, "MapMoveCD")  | 
|         return  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_TransTick, tick)  | 
|       | 
|     sceneMapID = mapID  | 
|     if GameWorld.GetMap().GetMapFBTypeByMapID(mapID) != IPY_GameWorld.fbtNull:  | 
|         # ¸±±¾¹¦Äܳ¡¾°µØÍ¼  | 
|         mapID = FBCommon.GetRecordMapID(mapID)  | 
|         fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, funcLineID)  | 
|         if fbLineIpyData:  | 
|             sceneMapID = fbLineIpyData.GetMapID()  | 
|               | 
|     # µØÍ¼·ÖÁ÷, ¼õÉÙµ¥µØÍ¼Ñ¹Á¦  | 
|     FBMapShuntDict = ReadChConfig.GetEvalChConfig("FBMapShunt")  | 
|     if mapID in FBMapShuntDict:  | 
|         shuntList = FBMapShuntDict[mapID]  | 
|         if shuntList:  | 
|             sceneMapID = random.choice(shuntList)  | 
|             GameWorld.DebugLog("µ¥È˵ØÍ¼·ÖÁ÷ sceneMapID=%s" % sceneMapID)  | 
|               | 
|     #´«ËÍʱ, Ëø¶¨Íæ¼Ò, ´«Ëͳɹ¦, ÔÚÄ¿±êµØÍ¼½âËø, ´«ËÍʧ°Ü, ÔÚ´«Ëͻص÷º¯ÊýPlayerChangeMapFailCallbackÖнâËø  | 
|     if canLock:  | 
|         curPlayer.BeginEvent()  | 
|       | 
|     if not takeTruck:  | 
|         #È¡Ïû×Ô¶¯ÔËïÚ  | 
|         PlayerTruck.SetAutoTruckState(curPlayer, ShareDefine.Def_Out_Truck)  | 
|     #GameWorld.Log(1, "SetXP=%s"%(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_RecordXPValue)))  | 
|     #curPlayer.SetXP(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_RecordXPValue))  | 
|     #»ñÈ¡¸±±¾´«È븱±¾ÐèҪЯ´øµÄÐÅÏ¢  | 
|     msg = FBLogic.GetPlayerResetWorldPosFBMsg(curPlayer, mapID, funcLineID)  | 
|       | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ReqFBFuncLine, funcLineID)  | 
|     GameWorld.Log("Íæ¼ÒÇëÇó¿ªÊ¼ÇÐͼ: sceneMapID=%s,posX=%s,posY=%s,takeTruck=%s,fbID=%s,msg=%s,funcLineID=%s,tick=%s,lastTransTick=%s"   | 
|                   % (sceneMapID, posX, posY, takeTruck, fbID, msg, funcLineID, tick, lastTransTick), curPlayer.GetPlayerID())  | 
|     if enterFBFree:  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_EnterFBFree, 1)  | 
|         GameWorld.DebugLog("    ±¾´ÎÃâ·Ñ½øÈ븱±¾!")  | 
|     curPlayer.ResetWorldPosReq(sceneMapID, posX, posY, takeTruck, fbID, msg)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ChangeMapID, sceneMapID)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ChangeLineID, max(0, fbID))  | 
|       | 
|     #ÇеØÍ¼´¦ÀíÍæ¼ÒʱÖÓ¾ÀÕýÎÊÌ⣨ÐèҪһֱͨ¹ýÍæ¼ÒʱÖÓ¼ÆËãµÄ£©  | 
|     RefreshPlayerTick(curPlayer)  | 
|     NotifyPrepareChangeMap(curPlayer, sceneMapID, funcLineID)  | 
|     return  | 
|   | 
| # Í¨Öª×¼±¸Çл»µØÍ¼  | 
| def NotifyPrepareChangeMap(curPlayer, sceneMapID, funcLineID):  | 
|     curPlayer.SetVisible(False)  | 
|     sendPack = ChPyNetSendPack.tagMCPrepareChangeMap()  | 
|     sendPack.Clear()  | 
|     sendPack.MapID = GameWorld.GetMapDataMapID(sceneMapID)  | 
|     sendPack.FuncLineID = funcLineID  | 
|       | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     GameWorld.Log("×¼±¸Çл»µØÍ¼", curPlayer.GetID())  | 
|     return  | 
|   | 
| # Í¨Öª¿ªÊ¼Çл»µØÍ¼  | 
| def NotifyStartChangeMap(curPlayer):  | 
|     sendPack = ChPyNetSendPack.tagMCStartChangeMap()  | 
|     sendPack.Clear()  | 
|     sendPack.MapID = GameWorld.GetMapDataMapID(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ChangeMapID))  | 
|     sendPack.FuncLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ReqFBFuncLine)  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|       | 
|     GameWorld.Log("֪ͨ¿ªÊ¼Çл»µØÍ¼", curPlayer.GetID())  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò»»Ïß  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param changLineID Ïß·ID  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò»»Ïß  | 
| def PlayerChangeLine(curPlayer, changLineID):  | 
|     #---µØÍ¼·ÖÏß¼ì²é---  | 
|     if GameWorld.GetGameWorld().GetLineID() == changLineID:  | 
|         GameWorld.ErrLog('changLineID SameLine = %s' % (changLineID))  | 
|         return  | 
|       | 
|     #---µØÍ¼ÊôÐÔ¼ì²é---  | 
|     gameMap = GameWorld.GetMap()  | 
|       | 
|     #1. Ö»ÓÐÆÕͨµØÍ¼²ÅÄÜ»»Ïß  | 
|     if gameMap.GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|         #GeRen_liubo_180377    <n color="0,255,0">¶Ô²»Æð£¬Ä¿Ç°¸ÃµØÍ¼Ã»Óпª·Å·ÖÁ÷£¬ÎÞ·¨Çл»Ïß·!</n>  256 -  | 
|         NotifyCode(curPlayer, "GeRen_liubo_180377")  | 
|         return  | 
|       | 
|     #2. »»ÏßµÄÄ¿µÄµØ±ØÐë´æÔÚ  | 
|     if changLineID >= gameMap.GetMaxFbCount():  | 
|         GameWorld.ErrLog("»»ÏßµÄÄ¿µÄµØ²»´æÔÚ = %s, %s" % (changLineID, gameMap.GetMaxFbCount()), curPlayer.GetID())  | 
|         return  | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PlayChangeLineID, changLineID + 1)  | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FuncChangeLineID, 0)  | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_HighChangeLineID, 0)  | 
|       | 
|     #---¿ªÊ¼Çл»Ïß·---  | 
|     PlayerResetWorldPosFB(curPlayer, curPlayer.GetMapID(), curPlayer.GetPosX(), curPlayer.GetPosY(), False, changLineID)  | 
|       | 
|     GameWorld.Log('Íæ¼Ò = %s Çл»·ÖÏß = %s, Ëø×¡' % (curPlayer.GetName(), changLineID), curPlayer.GetID())  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÇл»µØÍ¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param posX ×ø±êX  | 
| # @param posY ×ø±êY  | 
| # @param takeTruck ÊÇ·ñЯ´øïÚ³µ  | 
| # @param lineID Ïß·ID -1´ú±íµ±Ç°Ïß  | 
| # @param msg Çл»µØÍ¼Ð¯´øµÄÐÅÏ¢  | 
| # @param canLock ÊÇ·ñ¿ÉÒÔËø¶¨Íæ¼Ò(´«Ë͵㲻¿ÉËø¶¨, ÒòΪҪ¿çµØÍ¼Ñ°Â·)  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÇл»µØÍ¼  | 
| def PlayerResetWorldPos(curPlayer, mapID, posX, posY, takeTruck, lineID=-1, msg='', canLock=True, exData1=0):  | 
|     #¸ü¸Ä: ËÀÍöÔÊÐíÇл»µØÍ¼, ÔÚ¸±±¾Öб»¹Ö´òËÀ, ¸±±¾Ê±¼äµ½, »ØÊÕ¸±±¾  | 
| #    if GameObj.GetHP(curPlayer) <= 0 :  | 
| #        GameWorld.Log("ËÀÍöÎÞ·¨Çл»µØÍ¼")  | 
| #        return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     shuntLineID = GetResetWorldPosShuntLineID(curPlayer, gameWorld.GetMapID(), gameWorld.GetLineID(), mapID, lineID, exData1) # ·ÖÁ÷Ïß·ID  | 
|     GameWorld.DebugLog("·ÖÁ÷ mapID=%s,lineID=%s,shuntLineID=%s" % (mapID, lineID, shuntLineID), curPlayer.GetPlayerID())  | 
|       | 
|     #---ͬµØÍ¼ID, Í¬·ÖÏß, ½öÇл»×ø±ê---  | 
|     #lingID = -1, ´ú±íĬÈϵ±Ç°Ïß, ÈçÖ÷³Ç2´«Ëͽ£×Ú, µ½´ï½£×Ú2  | 
|     if gameWorld.GetMapID() == mapID and (shuntLineID == -1 or gameWorld.GetLineID() == shuntLineID):  | 
|         if exData1:  | 
|             #bossµÄÓÃmove£¬Í¨ÖªÇ°¶Ë£¬ÓÉǰ¶Ë·¢Æðmove  | 
|             ChPlayer.NotifyPlayerMove(curPlayer, posX, posY, exData1)  | 
|         else:  | 
|             #ÖØÖÃ×ø±ê  | 
|             GameWorld.ResetPlayerPos(curPlayer, posX, posY)  | 
|         #@bug: ÔÚ°ÚÌ¯Çø¿ìËÙ´«ËÍÖÁ·Ç°ÚÌ¯Çø, ¿ÉÒÔ°Ú̯, ÕâÀïË¢ÐÂһϳ¡¾°Buff  | 
|         SkillShell.ProcessMapBuff(curPlayer, GameWorld.GetGameWorld().GetTick())  | 
|         return  | 
|       | 
|     #---²»Í¬µØÍ¼IDÇл»µØÍ¼---  | 
|     PlayerResetWorldPosFB(curPlayer, mapID, posX, posY, takeTruck, shuntLineID, msg, canLock)  | 
|       | 
|     #Èç¹ûÊÇ·þÎñÆ÷ÖÐ×îºóÒ»¸öÈËÀ뿪, Ôò¹Øµô¸±±¾  | 
|     GameWorldProcess.OnPlayerLeaveMapCloseFB()  | 
|     return  | 
|   | 
| def GetResetWorldPosShuntLineID(curPlayer, curMapID, curLineID, tagMapID, tagLineID, bossID=0):  | 
|     '''»ñÈ¡ÇÐͼÏß·ID  | 
|     ÇÐÏßÓÐÈýÖÖÇé¿ö  | 
|     1. Íæ¼ÒÊÖ¶¯Çл»Ïß·£¬ÓÅÏȼ¶×î¸ß  | 
|             ¼Ç¼key  Def_Player_Dict_PlayChangeLineID£¬ ÀëÏß³¬¹ý±£»¤Ê±¼äºóÖØÖã¬È·±£¶ÏÏßÖØÁ¬Õý³£¼´¿É  | 
|               | 
|     2. ¹¦ÄÜÇл»µ½Ö¸¶¨Ïß·£¬Èç´òboss¡¢´«Ë͵½Ä¿±êÍæ¼ÒÏß·£¨±»»÷ɱÇйýÈ¥°ï棩  | 
|             ¼Ç¼key  Def_Player_Dict_FuncChangeLineID£¬ ÀëÏß³¬¹ý±£»¤Ê±¼äºóÖØÖã¬È·±£¶ÏÏßÖØÁ¬Õý³£¼´¿É  | 
|               | 
|     3. ³£¹æÇÐͼ  | 
|             Ïß·ѡÔñÓÅÏȼ¶: ÊÖ¶¯ÇÐÏ߼Ǽ > ¹¦ÄÜÇÐÏ߼Ǽ > ¸ßµÍÇÐÏ߼Ǽ > ÏµÍ³·ÖÁ÷ÇÐÏß¹æÔò  | 
|               | 
|             ÏµÍ³·ÖÁ÷ÇÐÏß¹æÔò: µ±Ç°µØÍ¼Ïß· ¶ÔÓ¦ Ä¿±êµØÍ¼Ïß·ÈËÊý Èç¹ûµ½´ï¶î¶¨Öµ²Å½øÐзÖÁ÷£¬·ÖÁ÷µ½ÈËÊý½ÏÉÙµÄÏß·  | 
|               | 
|         ÌØÊâboss·ÖÁ÷:   | 
|         @param bossID: ·ÖÁ÷bossID  | 
|     '''  | 
|     if PlayerTJG.GetIsTJG(curPlayer):  | 
|         GameWorld.DebugLog("ÍÑ»úµÄÍæ¼Ò²»´¦Àí·ÖÁ÷£¡", curPlayer.GetPlayerID())  | 
|         return tagLineID  | 
|     if GameWorld.IsCrossServer():  | 
|         return tagLineID  | 
|     # ·Ç³£¹æµØÍ¼Ö®¼äµÄÇл»²»´¦Àí  | 
|     if curMapID not in PyGameData.g_commMapLinePlayerCountDict or tagMapID not in PyGameData.g_commMapLinePlayerCountDict:  | 
|         return tagLineID  | 
|     tagLinePlayerCountDict = PyGameData.g_commMapLinePlayerCountDict[tagMapID] # ´Ë·ÖÏß°üº¬ËùÓзÖÏߣ¬º¬Î´¿ª·ÅµÄ¼°»î¶¯·ÖÏß  | 
|       | 
|     if bossID and tagMapID != ChConfig.Def_FBMapID_BossHome:  | 
|         tagLineID = 0 # BossµÄ»°Î´·ÖÁ÷ǰÏÈÇ¿ÖÆ1Ïߣ¬¼´Îª0  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     playChangeLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PlayChangeLineID)  | 
|     funcChangeLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FuncChangeLineID)  | 
|     highChangeLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_HighChangeLineID)  | 
|       | 
|     GameWorld.DebugLog("´¦Àí·ÖÁ÷,curMapID=%s,curLineID=%s,tagMapID=%s,tagLineID=%s,bossID=%s"   | 
|                        % (curMapID, curLineID, tagMapID, tagLineID, bossID), playerID)  | 
|     # ÓÐÖ¸¶¨Ïß·£¬Ö±½Ó·µ»Ø£¬²»·ÖÁ÷  | 
|     if tagLineID != -1:  | 
|         # »¹Ã»Ö¸¶¨·ÖÏ߼ǼµÄÔòÒª¼Ç¼£¬ÒѾ¼Ç¼¹ýµÄ²»Öظ´¼Ç¼£¬Ö±µ½Ï´λص½ÔÏß·ºó²ÅÖØÖÃ0  | 
|         if not playChangeLineID and not funcChangeLineID and not highChangeLineID:  | 
|             NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FuncChangeLineID, curLineID + 1)  | 
|             GameWorld.DebugLog("¹¦ÄÜÖ¸¶¨Çл»Ä¿±êÏß·£¬¼Ç¼µ±Ç°Ïß·ºóÐøÇÐÏß±¸ÓÃ! curLineID=%s,tagLineID=%s" % (curLineID, tagLineID), playerID)  | 
|               | 
|         if bossID and NPCCommon.IsMapNeedBossShunt(tagMapID):  | 
|             bossShuntLineID = __GetBossShuntLineID(curPlayer, curMapID, curLineID, tagMapID, bossID, tagLinePlayerCountDict.keys())  | 
|             if bossShuntLineID != -1:  | 
|                 tick = GameWorld.GetGameWorld().GetTick()  | 
|                 GameWorld.DebugLog("·ÖÁ÷boss, bossID=%s,bossShuntLineID=%s" % (bossID, bossShuntLineID), playerID)  | 
|                 NPCCommon.AddBossShuntRelatedPlayer(curPlayer, tagMapID, bossShuntLineID, bossID, tick)  | 
|                 return bossShuntLineID  | 
|         return tagLineID  | 
|       | 
|     if curMapID == tagMapID:  | 
|         GameWorld.DebugLog("ͬµØÍ¼Çл»×ø±ê²»´¦Àí·ÖÁ÷£¡", playerID)  | 
|         return tagLineID  | 
|       | 
|     # ¿ÉÒÔÓÃÀ´³£¹æ·ÖÁ÷µÄÏß·ÈËÊý×ÖµäÐÅÏ¢, ²¢²»ÊÇËùÓÐÏß·¶¼¿ÉÒÔÓÃÀ´×öÈËÊý·ÖÁ÷µÄ£¬±ÈÈçÖÐÁ¢µØÍ¼ÓжàÌõÏßÓÃÀ´·ÖÁ÷boss£¬µ«ÊÇÖ»ÓÐ1ÌõÏß¿ÉÓÃÀ´×ö³£¹æµÄÈËÊý·ÖÁ÷  | 
|     mapLineDict = IpyGameDataPY.GetFuncCfg("MapLine", 1)  | 
|     if tagMapID in mapLineDict:  | 
|         tagMapMaxLine = mapLineDict[tagMapID]  | 
|         tagLinePlayerCountShuntDict = {}  | 
|         for k, v in tagLinePlayerCountDict.items():  | 
|             if k >= tagMapMaxLine:  | 
|                 continue  | 
|             tagLinePlayerCountShuntDict[k] = v  | 
|     else:  | 
|         tagLinePlayerCountShuntDict = tagLinePlayerCountDict  | 
|         tagMapMaxLine = len(tagLinePlayerCountShuntDict)  | 
|     GameWorld.DebugLog("Ä¿±êµØÍ¼¿ÉÓ÷ÖÁ÷Ïß·ÈËÊýÐÅÏ¢: tagMapID=%s,%s" % (tagMapID, tagLinePlayerCountShuntDict))  | 
|       | 
|     # ÓÐÖ÷¶¯Çл»¹ý  | 
|     if playChangeLineID and playChangeLineID <= len(tagLinePlayerCountShuntDict):  | 
|         GameWorld.DebugLog("ÓÐÖ÷¶¯Çл»¹ýÏß·!playChangeLineID=%s" % playChangeLineID, playerID)  | 
|         return playChangeLineID - 1  | 
|       | 
|     # ¹¦ÄÜÓÐÖ¸¶¨Ïß·¹ý  | 
|     if funcChangeLineID and funcChangeLineID <= len(tagLinePlayerCountShuntDict):  | 
|         GameWorld.DebugLog("¹¦ÄÜÓÐÖ¸¶¨¹ýÏß·ÀúÊ·Ïß·,funcChangeLineID=%s" % funcChangeLineID, playerID)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FuncChangeLineID, 0) # ´¥·¢»ØÔÏß·ºóÖØÖà  | 
|         return funcChangeLineID - 1  | 
|       | 
|     # ÓиßÏßÇеÍÏ߼Ǽ  | 
|     if highChangeLineID and highChangeLineID <= len(tagLinePlayerCountShuntDict):  | 
|         GameWorld.DebugLog("ÓиßÏßÇеÍÏßÀúÊ·Ïß·,highChangeLineID=%s" % highChangeLineID, playerID)  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_HighChangeLineID, 0) # ´¥·¢»ØÔÏß·ºóÖØÖà  | 
|         return highChangeLineID - 1  | 
|       | 
|     if curLineID not in tagLinePlayerCountShuntDict:  | 
|         GameWorld.DebugLog("Ä¿±êµØÍ¼²»´æÔÚ¸ÃÏß·,curLineID=%s" % curLineID, playerID)  | 
|         shuntLineID = __GetShuntLineID(curPlayer, tagMapID, tagLinePlayerCountShuntDict)  | 
|           | 
|         # Èç¹ûûÓд¥·¢·ÖÁ÷£¬ÔòÐè¼ÇÂ¼Íæ¼Ò´Ó¸ßÏß·µØÍ¼Çл»µ½µÍÏß·µØÍ¼Ê±µÄ¸ßÏß·ID  | 
|         if shuntLineID == -1 and not playChangeLineID and not funcChangeLineID and not highChangeLineID:  | 
|             NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_HighChangeLineID, curLineID + 1)  | 
|             GameWorld.DebugLog("¸ßÏßÇеÍÏߣ¬¼Ç¼µ±Ç°Ïß·ºóÐøÇÐÏß±¸ÓÃ! curLineID=%s,tagLineID=%s" % (curLineID, tagLineID), playerID)  | 
|               | 
|     else:  | 
|         shuntLineID = __GetShuntLineID(curPlayer, tagMapID, tagLinePlayerCountShuntDict, curLineID)  | 
|           | 
|     if shuntLineID == -1 and (curLineID + 1) > tagMapMaxLine:  | 
|         shuntLineID = tagMapMaxLine - 1  | 
|         GameWorld.DebugLog("³£¹æ·ÖÁ÷ºóµÄlineIDΪ-1£¬µ«ÊÇÄ¿±êµØÍ¼µ±Ç°Ïß·²»¿ÉÓ㡲»¿É´«Ë͵½¸ÃÏß·£¡curLineID=%s + 1 > tagMapMaxLine(%s), Ç¿ÖÆ·ÖÁ÷µ½Ïß·(shuntLineID=%s)"   | 
|                            % (curLineID, tagMapMaxLine, shuntLineID))  | 
|           | 
|     return shuntLineID  | 
|   | 
| def __GetShuntLineID(curPlayer, tagMapID, tagLinePlayerCountShuntDict, curLineID=None):  | 
|     # ÒÔÏÂ×ßϵͳ×Ô¶¯·ÖÁ÷Âß¼  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if curPlayer.GetLV() > IpyGameDataPY.GetFuncCfg("SetWorldPosShunt", 2):  | 
|         GameWorld.DebugLog("³¬¹ýÖ¸¶¨µÈ¼¶²»·ÖÁ÷", playerID)  | 
|         return -1  | 
|       | 
|     mapShuntDict = IpyGameDataPY.GetFuncEvalCfg("SetWorldPosShunt", 1) # {mapID:ÈËÊý, ...}  | 
|     if tagMapID not in mapShuntDict:  | 
|         GameWorld.DebugLog("Ä¿±êµØÍ¼²»ÐèÒª·ÖÁ÷", playerID)  | 
|         return -1  | 
|     lineMaxPlayerCount = mapShuntDict[tagMapID]  | 
|       | 
|     if curLineID != None:  | 
|         tagLinePlayerCount = tagLinePlayerCountShuntDict[curLineID]  | 
|         if tagLinePlayerCount < lineMaxPlayerCount:  | 
|             GameWorld.DebugLog("δ´ïµ½¶î¶¨ÈËÊýÖµ,²»Ó÷ÖÁ÷,curLineID=%s,Ä¿±êµØÍ¼µ±Ç°Ïß·ÈËÊý: %s/%s"   | 
|                                % (curLineID, tagLinePlayerCount, lineMaxPlayerCount), playerID)  | 
|             return -1  | 
|           | 
|     # ·ÖÁ÷µ½ÈËÊý½ÏÉÙµÄÏß·  | 
|     linePlayerList = [[playerCount, lineID] for lineID, playerCount in tagLinePlayerCountShuntDict.items()]  | 
|     linePlayerList.sort() # ÉýÐòÅÅ, ÔòË÷Òý0µÄÏß·Ϊ×î¼ÑÑ¡Ôñ  | 
|     shuntLineID = linePlayerList[0][1]  | 
|     GameWorld.DebugLog("·ÖÁ÷µ½ÈËÊý½ÏÉÙµÄÏß·,tagMapID=%s,linePlayerList[count,lineID]=%s" % (tagMapID, linePlayerList), playerID)  | 
|     return shuntLineID  | 
|   | 
| def __GetBossShuntLineID(curPlayer, curMapID, curLineID, tagMapID, npcID, lineIDList):  | 
|     '''»ñȡĿ±êµØÍ¼boss·ÖÁ÷Ïß·  | 
|                 ¸ù¾ÝÈËÊý·ÖÁ÷Íæ¼Ò£¬ÓÅÏÈ·ÖÅäµ½»î×ŵÄÏß·  | 
|                 ¶ÓÎéĬÈÏ·ÖÅäµ½¶ÓÎé¶ÓÔ±¶àµÄÄÇÌõÏß  | 
|                 ÐÖúĬÈÏ·ÖÅ䵽Ŀ±êÍæ¼ÒÏß·£¬ÓÅÏȼ¶×î¸ß  | 
|                         | 
|                 Ç°¶Ë£º  | 
|         1.ÔÚÖÐÁ¢µØÍ¼µÄʱºò£¬ÏÔʾµ±Ç°Ïß·BOSSµÄ״̬  | 
|         2.ÔÚ³£¹æµØÍ¼µÄʱºò£¬ÏÔÊ¾Íæ¼Ò»÷ɱBOSSµÄCDʱ¼ä  | 
|         3.±¾µØÍ¼²»»»Ïߣ¬60Ãë¹æÔò±£³Ö²»±ä  | 
|         4.½øÈëBOSSÇøÓòÀˢÐÂBOSS״̬  | 
|           | 
|                 Íæ¼ÒÔÚ·ÇÖÐÁ¢µØÍ¼£º  | 
|                 ±¾µØÍ¼²»»»Ïߣ¬60Ãë¹æÔò±£³Ö²»±ä£¨£©  | 
|                   | 
|                 Íæ¼ÒÔÚÖÐÁ¢µØÍ¼  | 
|                 Ã»ÓÐ60Ãë¹æÔò  | 
|                 Ö±½Ó·¢´«ËͰü£¬Óɺó¶Ë¾ö¶¨£¨ÓжÓÔ±ÔÚ²»Í¬Ïß·´òͬһֻboss£¬Ôò´«ËÍ£¬·ñÔòmove£©  | 
|     '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     playerTeamID = curPlayer.GetTeamID()  | 
|       | 
|     hurtTeamLineID = -1  | 
|     hurtTeamMemCount = -1  | 
|       | 
|     bossLinePlayerDict = {1:[-1, []], 0:[-1, []]} # {ÊÇ·ñ±»»÷ɱ:[¸Ã״̬ÈËÊý¿ÕµÄÏß·, [[Íæ¼ÒÊý, Ïß·], ...]], ...}  | 
|       | 
|     bossLineStateDict = PyGameData.g_bossShuntLineState.get(npcID, {})  | 
|       | 
|     haveAliveLine = False # ÊÇ·ñÓлî×ŵÄÏß·  | 
|     activityMapLineDict = IpyGameDataPY.GetFuncEvalCfg("MapLine", 2, {})  | 
|       | 
|     GameWorld.DebugLog("Íæ¼Òboss·ÖÁ÷: playerTeamID=%s,tagMapID=%s,npcID=%s,lineIDList=%s,bossLineStateDict=%s,g_bossShuntPlayerInfo=%s"   | 
|                        % (playerTeamID, tagMapID, npcID, lineIDList, bossLineStateDict, PyGameData.g_bossShuntPlayerInfo), playerID)  | 
|     if tagMapID in activityMapLineDict:  | 
|         activityLineID = max(0, activityMapLineDict[tagMapID] - 1)  | 
|         # ·Ç1ÏߵĻÏß·²»²ÎÓë·ÖÁ÷  | 
|         if activityLineID != 0 and activityLineID in lineIDList:  | 
|             lineIDList.remove(activityLineID)  | 
|             GameWorld.DebugLog("    ·Ç1ÏߵĻÏß·²»²ÎÓë·ÖÁ÷: activityLineID=%s,lineIDList=%s" % (activityLineID, lineIDList), playerID)  | 
|               | 
|     assistTagPlayerID = GetAssistTagPlayerID(curPlayer)  | 
|     for lineID in lineIDList:  | 
|         key = (tagMapID, lineID)  | 
|         # boss·ÖÁ÷Íæ¼ÒÐÅÏ¢{(mapID, lineID):{playerID:[bossID, teamID, relatedTick], ...}, ...}  | 
|         shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})  | 
|         if assistTagPlayerID and assistTagPlayerID in shuntPlayerDict:  | 
|             GameWorld.DebugLog("    ·ÖÁ÷µ½ÐÖúÄ¿±êÍæ¼ÒÏß· assistTagPlayerID=%s,lineID=%s" % (assistTagPlayerID, lineID), playerID)  | 
|             return lineID  | 
|         playerCount = 0  | 
|         teamPlayerCount = 0  | 
|         for shuntPlayerID, shuntInfo in shuntPlayerDict.items():  | 
|             bossID = shuntInfo[0]  | 
|             if npcID != bossID:  | 
|                 continue  | 
|             playerCount += 1  | 
|             shuntTeamID = shuntInfo[1]  | 
|             if playerTeamID and playerTeamID == shuntTeamID and shuntPlayerID != playerID:  | 
|                 teamPlayerCount += 1  | 
|           | 
|         if teamPlayerCount and teamPlayerCount > hurtTeamMemCount:  | 
|             hurtTeamMemCount = teamPlayerCount  | 
|             hurtTeamLineID = lineID  | 
|               | 
|         lineIsAlive = bossLineStateDict.get(lineID, 0)  | 
|         lineBossIsDead = 1 if not lineIsAlive else 0 # µ±Ç°Ïß·bossÊÇ·ñËÀÍö  | 
|         emptyLineID, linePlayerCountList = bossLinePlayerDict[lineBossIsDead]  | 
|         if not playerCount and emptyLineID == -1:  | 
|             emptyLineID = lineID  | 
|         linePlayerCountList.append([playerCount, lineID])  | 
|         bossLinePlayerDict[lineBossIsDead] = [emptyLineID, linePlayerCountList]  | 
|           | 
|         if not lineBossIsDead:  | 
|             haveAliveLine = True  | 
|               | 
|         GameWorld.DebugLog("    lineID=%s,lineBossIsDead=%s,playerCount=%s,teamPlayerCount=%s,hurtTeamMemCount=%s,hurtTeamLineID=%s"   | 
|                            % (lineID, lineBossIsDead, playerCount, teamPlayerCount, hurtTeamMemCount, hurtTeamLineID), playerID)  | 
|           | 
|     if hurtTeamLineID >= 0:  | 
|         GameWorld.DebugLog("    ·ÖÁ÷µ½¶ÓÓÑÈËÊý¶àµÄÏß· hurtTeamLineID=%s" % hurtTeamLineID, playerID)  | 
|         return hurtTeamLineID  | 
|       | 
|     if curMapID == tagMapID and curMapID in IpyGameDataPY.GetFuncEvalCfg("MapLine", 4):  | 
|         GameWorld.DebugLog("    ÖÐÁ¢µØÍ¼ÔÚ±¾µØÍ¼ÖÐĬÈϵ±Ç°Ïß· curLineID=%s" % curLineID, playerID)  | 
|         return curLineID  | 
|       | 
|     shuntBossIsDead = 0 if haveAliveLine else 1 # ÓÅÏÈ·ÖÁ÷µ½»î×ŵÄÏß·  | 
|     GameWorld.DebugLog("    boss״̬¶ÔÓ¦Ïß·ÈËÊý: haveAliveLine=%s, ×´Ì¬key0Ϊ»î×Å: %s" % (haveAliveLine, bossLinePlayerDict))  | 
|     emptyLineID, linePlayerCountList = bossLinePlayerDict[shuntBossIsDead]  | 
|     linePlayerCountList.sort() # ÉýÐò  | 
|     playerCount, minPlayerCntLineID = linePlayerCountList[0]  | 
|     bossShuntPlayerCountMax = IpyGameDataPY.GetFuncCfg("BossShunt", 2)  | 
|     if playerCount >= bossShuntPlayerCountMax and emptyLineID >= 0:  | 
|         GameWorld.DebugLog("    ·ÖÁ÷µ½¿ÕÐÂÏß· shuntBossIsDead=%s,emptyLineID=%s" % (shuntBossIsDead, emptyLineID), playerID)  | 
|         return emptyLineID  | 
|       | 
|     GameWorld.DebugLog("    ·ÖÁ÷µ½ÈËÊý×îÉÙµÄÏß· shuntBossIsDead=%s,minPlayerCntLineID=%s,linePlayerCountList=%s"   | 
|                        % (shuntBossIsDead, minPlayerCntLineID, linePlayerCountList), playerID)  | 
|     return minPlayerCntLineID  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##È¡ºÏ·¨ÖØÉúµã  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param posX ÖØÉúµãx×ø±ê  | 
| # @param posy ÖØÉúµãy×ø±ê  | 
| # @param round ÖØÉúµã·¶Î§  | 
| # @return ÖØÉúµã(×ø±êx£¬ ×ø±êy)  | 
| # @remarks   | 
| def __GetLegitRebornPoint(curPlayer, posX, posY, round):  | 
|     rebornPosX = 0  | 
|     rebornPosY = 0  | 
|       | 
|     curMapID = curPlayer.GetMapID()  | 
|       | 
|     gameMap = GameWorld.GetMap()  | 
|       | 
|     #Ìí¼Ó×ø±êµãÒì³£¼ì²é(ÖØÉúµã×ø±ê³¬¹ýµØÍ¼±ß½ç)  | 
|     if not gameMap.IsValidPos(posX, posY):  | 
|         GameWorld.ErrLog('ÖØÉúµãÒì³££¬³¬¹ýµØÍ¼(%s)±ß½ç posX = %s, posY = %s, round = %s' \  | 
|                          % (curMapID, posX, posY, round))  | 
|       | 
|     else:  | 
|         # Ëæ»úÈ¡µ½·ÇÕϰµã  | 
|         rebornPosX, rebornPosY = GameMap.GetNearbyPosByDis(posX, posY, round)  | 
|               | 
|         #²¼µÄÖØÉúµã·¶Î§ÄÚÕÒ²»µ½·ÇÕϰµã  | 
|         if rebornPosX <= 0 or rebornPosY <= 0:  | 
|             GameWorld.Log("ÖØÉúµã·¶Î§ÄÚÕÒ²»µ½¸ÃµØÍ¼(%s)µÄ·ÇÕÏ°ÖØÉúµã posX = %s, posY = %s, round = %s" % \  | 
|                           (curMapID, posX, posY, round), curPlayer.GetPlayerID())  | 
|       | 
|     return (rebornPosX, rebornPosY)  | 
|   | 
|                       | 
| #---------------------------------------------------------------------  | 
| ##Ë¢ÐÂÍæ¼ÒµÄÖØÉúµãÐÅÏ¢  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Ë¢ÐÂÍæ¼ÒµÄÖØÉúµãÐÅÏ¢  | 
| def RefreshRebornPoint(curPlayer, tick):  | 
|     #---¸´»îµãË¢ÐÂÅжÏ˳Ðò1.µØÍ¼²¼¸´»îµã 2.tagChinMap.txtÄÚ¸´»îµã 3.´´½¨½ÇÉ«³õʼ³öÉúµã---  | 
|       | 
|     gameMap = GameWorld.GetMap()  | 
|       | 
|     # ³õʼ»¯ÖØÉúµØÍ¼Îªµ±Ç°Íæ¼ÒËùÔÚµØÍ¼  | 
|     rebornMapID = curPlayer.GetMapID()  | 
|     rebornPosX = curPlayer.GetRebornPosX()  | 
|     rebornPosY = curPlayer.GetRebornPosY()  | 
|       | 
|     #---µØÍ¼Éϲ¼µÄÖØÉúµãÅжÏ---  | 
|       | 
|     # µØÍ¼ÉÏÊÇ·ñÓв¼¸´»îË¢Ð嵋  | 
|     hasBornRefreshPoint = True  | 
|       | 
|     gameData = GameWorld.GetGameData()  | 
|     bornRefreshCount = gameData.GetBornRefreshCount()  | 
|   | 
|     #Ò»°ãµØÍ¼²¼µÄÖØÉúµãÁбí,¸ù¾Ý¹ú¼®É¸Ñ¡  | 
|     bornList = []  | 
|     #¸±±¾µØÍ¼²¼µÄÖØÉúµãÁбí,²»É¸Ñ¡  | 
|     fbBornList = []  | 
|       | 
|     # Ã»Óв¼ÖØÉúµã  | 
|     if not bornRefreshCount:  | 
|         GameWorld.Log("´ËµØÍ¼Ã»ÓÐÖØÉúµã", curPlayer.GetPlayerID())  | 
|         hasBornRefreshPoint = False  | 
|     else:  | 
|         #´´½¨ÖØÉúµãÁÐ±í  | 
|         for i in range(0, bornRefreshCount):  | 
|             bornRefreshPoint = gameData.GetBornRefreshByIndex(i)  | 
|             fbBornList.append(i)  | 
|               | 
|             if GameWorld.IsSameCountry(curPlayer, bornRefreshPoint):  | 
|                 bornList.append(i)  | 
|       | 
|         if not bornList:  | 
|             GameWorld.Log("´ËµØÍ¼Ã»ÓкÏÊÊÍæ¼ÒµÄÖØÉúµã", curPlayer.GetPlayerID())  | 
|             hasBornRefreshPoint = False  | 
|   | 
|     #---¸ÃµØÍ¼Óв¼ÖØÉúˢеã---  | 
|     if hasBornRefreshPoint:  | 
|         # Ëæ»ú»ñÈ¡ÖØÉúË¢Ð嵋  | 
|         bornIndex = random.choice(bornList)  | 
|         bornRefreshPoint = gameData.GetBornRefreshByIndex(bornIndex)  | 
|           | 
|         bRP_PosX = bornRefreshPoint.GetPosX()  | 
|         bRP_PosY = bornRefreshPoint.GetPosY()  | 
|         bRP_RoundPos = bornRefreshPoint.GetRound()  | 
|           | 
|         rebornPosX, rebornPosY = __GetLegitRebornPoint(curPlayer, bRP_PosX, bRP_PosY, bRP_RoundPos)  | 
|           | 
|         #²¼µÄÖØÉúµã·¶Î§ÄÚÕÒ²»µ½ºÏ·¨ÖØÉúµã  | 
|         if rebornPosX <= 0 or rebornPosY <= 0 or rebornMapID <= 0:  | 
|             GameWorld.Log("µØÍ¼Éϲ¼µÄÖØÉúµã·¶Î§ÄÚÕÒ²»µ½¸ÃµØÍ¼(%s)µÄºÏ·¨ÖØÉúµã" \  | 
|                           % curPlayer.GetMapID(), curPlayer.GetPlayerID())  | 
|             # Òì³££¬Éè±ê־ΪFalse,´ÓtagChinMap.txt±íÄÚÕÒ¸´»îµã  | 
|             hasBornRefreshPoint = False  | 
|       | 
|     # ÔÚtagChinMap.txt±íÄÚÊÇ·ñÄÜÕÒµ½¸´»îµã  | 
|     hasBornPointInTxt = True    | 
|       | 
|     #---¸ÃµØÍ¼Ã»ÓÐÖØÉúˢе㣬´ÓtagChinMap.txt±íÄÚÕÒ¸´»îµã---      | 
|     if not hasBornRefreshPoint:  | 
|         rebornMapID = gameMap.GetRebornMapID()  | 
|         rebornPosX = gameMap.GetRebornMapX()  | 
|         rebornPosY = gameMap.GetRebornMapY()  | 
|           | 
|         #ÑéÖ¤ÊÇ·ñ±¾µØÍ¼¸´»îµã ½øÐÐÂß¼´¦Àí, ·Ç±¾µØÍ¼¸´»îµãÎÞ·¨Åжϣ¬ ÒªÇó²ß»®Ò»¶¨ÅäÖÃÕýÈ·  | 
|         if gameMap.GetMapID() == rebornMapID:  | 
|             # Ëæ»úÈ¡µ½·ÇÕϰµã  | 
|             rebornPosX, rebornPosY = __GetLegitRebornPoint(curPlayer, \  | 
|                                                            rebornPosX, rebornPosY, ChConfig.Def_RebornPos_Area_Range)  | 
|   | 
|         #tagChinMap.txt±íÉÏÕÒ²»µ½ºÏ·¨ÖØÉúµã  | 
|         if rebornPosX <= 0 or rebornPosY <= 0 or rebornMapID <= 0:  | 
|             GameWorld.Log("tagChinMap.txtÄÚÕÒ²»µ½¸ÃµØÍ¼(%s)µÄºÏ·¨ÖØÉúµã" \  | 
|                           % curPlayer.GetMapID(), curPlayer.GetPlayerID())  | 
|             hasBornPointInTxt = False  | 
|               | 
|     #---ÔÚtagChinMap.txt±íÄÚÒ²ÕÒ²»µ½¸´»îµã,Ö±½ÓÖØÖõ½´´½¨½ÇɫʱµÄ³õʼµã---  | 
|     if not hasBornPointInTxt:  | 
|         curPlayerJob = curPlayer.GetJob()  | 
|           | 
|         #´´½¨Íæ¼ÒλÖöÁ±í{ Ö°Òµ:[(map,x,y),(map1,x1,y1)..] }  | 
|         posList = ReadChConfig.GetEvalChConfig('Player_Reborn_Place')  | 
|           | 
|         pos = random.choice(posList[curPlayerJob])  | 
|         rebornMapID = pos[0]  | 
|         bornRange = 1  | 
|         rebornPosX = pos[2] + random.randint(-bornRange, bornRange)  | 
|         rebornPosY = pos[3] + random.randint(-bornRange, bornRange)  | 
|         GameWorld.Log("""tagBornRefresh.txtºÍtagChinMap.txtÄÚ¶¼ÕÒ²»µ½¸ÃµØÍ¼(%s)  | 
| µÄºÏ·¨ÖØÉúµã£¬ÉèÖÃÍæ¼ÒÖØÉúµãΪ´´½¨½ÇɫʱµÄ³õʼµã%s-(%s,%s)""" % \  | 
|                       (curPlayer.GetMapID(), rebornMapID, rebornPosX, rebornPosY), curPlayer.GetPlayerID())          | 
|                                   | 
|     #Íæ¼Ò²»ÔÚ¸±±¾ÖÐ  | 
|     if gameMap.GetMapFBType() == IPY_GameWorld.fbtNull:  | 
|         # ÉèÖÃÒ»°ãµØÍ¼ÖØÉúµã  | 
|         curPlayer.SetRebornMapID(rebornMapID)  | 
|         curPlayer.SetRebornPosX(rebornPosX)  | 
|         curPlayer.SetRebornPosY(rebornPosY)  | 
|         GameWorld.Log("Íæ¼Ò%s,ÉèÖÃĬÈÏÖØÉúµãÍê±Ï mapID = %s-(%s,%s)" % (curPlayer.GetPlayerName(), rebornMapID, rebornPosX, rebornPosY), curPlayer.GetPlayerID())  | 
|         return  | 
|   | 
| #===============================================================================  | 
| #        #´å³¤¼ÒµÄµØÍ¼ID  | 
| #        cunZhangJiaMapID = 21  | 
| #      | 
| #        #ÓÐÖØÉúµã  | 
| #        #ÐÂÊÖ³¡ÅÂÍæ¼Ò¿¨ËÀÕϰµã£¬ÉèÖÃΪµ±Ç°×ø±ê  | 
| #        if curPlayerMapID == cunZhangJiaMapID:  | 
| #            curPlayer.SetRebornMapID( curPlayerMapID )  | 
| #            curPlayer.SetRebornPosX( curPlayer.GetPosX() )  | 
| #            curPlayer.SetRebornPosY( curPlayer.GetPosY() )  | 
| #            return  | 
| #          | 
| #        #À뿪ÐÂÊÖ³¡¾°ºó£¬ÖØÖÃÒ»´ÎÖØÉúµã£¬·ÀÖ¹Íæ¼ÒÔٻص½ÐÂÊÖ³¡¾°  | 
| #        if curPlayerRebornMapID == cunZhangJiaMapID:  | 
| #            curPlayer.SetRebornMapID( curPlayerMapID )  | 
| #            curPlayer.SetRebornPosX( bornX )  | 
| #            curPlayer.SetRebornPosY( bornY )  | 
| #            return  | 
| #===============================================================================  | 
|       | 
|     #ÏÈÉèÖÃĬÈϵĸ±±¾ÖØÉúµã  | 
|     curPlayer.SetFBRebornMapID(rebornMapID)  | 
|     curPlayer.SetFBRebornPosX(rebornPosX)  | 
|     curPlayer.SetFBRebornPosY(rebornPosY)  | 
|     GameWorld.Log("Íæ¼Ò%s,ÉèÖø±±¾Ä¬ÈÏÖØÉúµãÍê±Ï mapID = %s-(%s,%s)" % (curPlayer.GetPlayerName(), rebornMapID, rebornPosX, rebornPosY), curPlayer.GetPlayerID())  | 
|       | 
|     # ÌØÊ⸱±¾¸´»îµãÂß¼  | 
|     FBLogic.OnRebornPlace(curPlayer, fbBornList)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##»ñÈ¡¾ôλ  | 
| # @param curLV µÈ¼¶  | 
| # @return ·µ»ØÖµ, ¾ôλµÈ¼¶  | 
| # @remarks »ñÈ¡¾ôλ  | 
| def GetRank(curLV):  | 
|     if curLV > 0 and curLV < 21:  | 
|         return 1  | 
|     else:  | 
|         return (curLV - 1) / 10  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##»ñµÃÖ¸¶¨·½Î»ÄÚ¶ÓÎé³ÉÔ±ÁÐ±í  | 
| # @param curTeam ¶ÓÎéʵÀý  | 
| # @param centerX ÆðµãX  | 
| # @param centerY ÆðµãY  | 
| # @param area ·¶  | 
| # @return ·µ»ØÖµ, ³ÉÔ±ÁÐ±í  | 
| # @remarks »ñµÃÖ¸¶¨·½Î»ÄÚ¶ÓÎé³ÉÔ±ÁÐ±í  | 
| def GetAreaTeamMember(curTeam, centerX, centerY, area=ChConfig.Def_Team_GetExpScreenDist, isLog=False):     | 
|     playerlist = list()  | 
|   | 
|     if curTeam == None:  | 
|         GameWorld.ErrLog("»ñÈ¡¶ÓÎéÇøÓò³ÉÔ±£¬¶ÓÎé²»´æÔÚ£¡")  | 
|         return playerlist  | 
|       | 
|     playerIDList = []  | 
|     #if isLog:  | 
|     #    GameWorld.Log("GetAreaTeamMember,teamID=%s,centerX=%s,centerY=%s,area=%s" % (curTeam.GetTeamID(), centerX, centerY, area))  | 
|           | 
|     #±éÀú¶ÓÎé,°ë¾¶ÎªÒ»ÆÁ°ëµÄ¾àÀëÄÚµÄËùÓжÓÎé/ÍŶӳÉÔ±£¬¿ÉÒÔ»ñµÃ¾Ñé  | 
|     for i in range(0, curTeam.GetMemberCount()):  | 
|         curTeamPlayer = curTeam.GetMember(i)  | 
|         if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  | 
|             #if isLog:  | 
|             #    GameWorld.Log("    i=%s,³ÉÔ±²»´æÔÚ!" % (i))  | 
|             continue  | 
|           | 
|         if GameObj.GetHP(curTeamPlayer) <= 0:  | 
|             #if isLog:  | 
|             #    GameWorld.Log("    i=%s,³ÉԱѪÁ¿Îª0!playerID=%s" % (i, curTeamPlayer.GetPlayerID()))  | 
|             continue  | 
|           | 
|         #===========================================================================================  | 
|         # # ¶ÓÎéÒÑÓÉÿÌõÐéÄâÏß·¶À×Ô¹ÜÀí£¬´Ë´¦¿É²»ÔÙÅÐ¶Ï  | 
|         # if curTeamPlayer.GetCopyMapID() != GameWorld.GetGameWorld().GetCopyMapID():  | 
|         #    if isLog:  | 
|         #        GameWorld.Log("    i=%s,³ÉÔ±ÐéÄâÏß·²»Í¬!playerID=%s,copyMapID=%s,mapCopyMapID=%s"   | 
|         #                      % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetCopyMapID(), GameWorld.GetGameWorld().GetCopyMapID()))  | 
|         #    #¸±±¾ID²»Í¬  | 
|         #    continue  | 
|         #===========================================================================================  | 
|           | 
|         if GameWorld.GetDist(centerX, centerY, curTeamPlayer.GetPosX(),  | 
|                              curTeamPlayer.GetPosY()) > area:  | 
|             #if isLog:  | 
|             #    GameWorld.Log("    i=%s,³ÉÔ±²»ÔÚ·¶Î§ÄÚ!playerID=%s,centerPos(%s,%s),playerPos=(%s,%s),area=%s"   | 
|             #                  % (i, curTeamPlayer.GetPlayerID(), centerX, centerY, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), area))  | 
|             continue  | 
|           | 
|         playerlist.append(curTeamPlayer)  | 
|         playerIDList.append(curTeamPlayer.GetPlayerID())  | 
|           | 
|     #if isLog:  | 
|     #    GameWorld.Log("    teamAreaPlayerIDList=%s" % (playerIDList))  | 
|     return playerlist  | 
|   | 
| def GetMapTeamMember(curTeam):  | 
|     ''' »ñȡͬµØÍ¼ÖеĶÓÔ± '''  | 
|       | 
|     playerlist = list()  | 
|     if curTeam == None:  | 
|         return playerlist  | 
|       | 
|     for i in xrange(curTeam.GetMemberCount()):  | 
|         curTeamPlayer = curTeam.GetMember(i)  | 
|         if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  | 
|             continue  | 
|         playerlist.append(curTeamPlayer)  | 
|           | 
|     return playerlist  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##»ñÈ¡Íæ¼Ò»õ±ÒÊý  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param TYPE_Price ,»õ±ÒÀàÐÍ  | 
| # @return  | 
| def GetMoney(curPlayer, TYPE_Price):  | 
|       | 
|     #½ð×Ó  | 
|     if TYPE_Price == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         return curPlayer.GetGold()  | 
|           | 
|     #½ðƱ  | 
|     elif TYPE_Price == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         return curPlayer.GetGoldPaper()  | 
|          | 
|     #Òø×Ó  | 
|     elif TYPE_Price == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         return GetSilver(curPlayer)  | 
|           | 
|     #񿮱  | 
|     elif TYPE_Price == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         return curPlayer.GetSilverPaper()  | 
|       | 
|     #×Ô¶¨Òå»õ±Ò  | 
|     elif TYPE_Price in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         return GetPlayerCurrency(curPlayer, TYPE_Price)  | 
|       | 
|     return 0  | 
|   | 
| def GetMoneyReal(curPlayer, moneyType):  | 
|     ## »ñÈ¡»õ±Òʵ¼ÊÖµ£¬Ö§³Ö¸ºÖµ  | 
|     moneyMinus = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MoneyMinus % moneyType)  | 
|     if moneyMinus != 0:  | 
|         return -moneyMinus  | 
|     return GetMoney(curPlayer, moneyType)  | 
|   | 
| def SetMoney(curPlayer, moneyType, value):  | 
|     ## ÉèÖûõ±ÒÖµ£¬Ö§³Ö¸ºÖµ  | 
|     if moneyType in ShareDefine.MoneyMinusRefreshDict:  | 
|         moneyMinus = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MoneyMinus % moneyType)  | 
|         if value < 0:  | 
|             if moneyMinus != value:  | 
|                 SetMoneyMinus(curPlayer, moneyType, value)  | 
|             value = 0  | 
|         else:  | 
|             if moneyMinus != 0:  | 
|                 SetMoneyMinus(curPlayer, moneyType, 0)  | 
|                   | 
|     #½ð×Ó  | 
|     if moneyType == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         curPlayer.SetGold(value)  | 
|           | 
|     #½ðƱ  | 
|     elif moneyType == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         curPlayer.SetGoldPaper(value)  | 
|           | 
|     #Òø×Ó  | 
|     elif moneyType == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         SetSilver(curPlayer, value)  | 
|           | 
|     #񿮱  | 
|     elif moneyType == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         curPlayer.SetSilverPaper(value)  | 
|           | 
|     #×Ô¶¨Òå»õ±Ò  | 
|     elif moneyType in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         SetPlayerCurrency(curPlayer, moneyType, value)  | 
|           | 
|     return  | 
|   | 
| def SetMoneyMinus(curPlayer, moneyType, value):  | 
|     value = abs(value) # ´æÖµ¼°Í¨ÖªÊ¹ÓÃÕýÊý  | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MoneyMinus % moneyType, value)  | 
|     #֪ͨ¿Í»§¶Ë  | 
|     if moneyType not in ShareDefine.MoneyMinusRefreshDict:  | 
|         return  | 
|     refreshType = ShareDefine.MoneyMinusRefreshDict[moneyType]  | 
|     if refreshType != None:  | 
|         SendPropertyRefresh(curPlayer, refreshType, value)  | 
|     return  | 
|   | 
| ## »ñÈ¡Íæ¼Ò²Ö¿â½ðÇ®Êý  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param moneyType: ½ðÇ®ÀàÐÍ  | 
| #  @return: Íæ¼ÒÉíÉϽðÇ®Êý  | 
| def GetWarehouseMoney(curPlayer, moneyType):  | 
|     if moneyType == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         return curPlayer.GetWarehouseGold()  | 
|       | 
|     if moneyType == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         return curPlayer.GetWarehouseGoldPaper()  | 
|       | 
|     if moneyType == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         return curPlayer.GetWarehouseSilver()  | 
|       | 
|     if moneyType == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         return curPlayer.GetWarehouseSilverPaper()  | 
|       | 
|     GameWorld.ErrLog("GetWarehouseMoney, moneyType:%d Err" % (moneyType))  | 
|     return 0  | 
|   | 
| ## »ñµÃ×Ô¶¨Òå»õ±Ò£¨»ý·Ö£©  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return  | 
| def GetPlayerCurrency(curPlayer, currencyType):  | 
|     return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Currency % currencyType)  | 
|   | 
| ## ÉèÖÃ×Ô¶¨Òå»õ±Ò£¨»ý·Ö£©  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return  | 
| def SetPlayerCurrency(curPlayer, currencyType, value):  | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Currency % currencyType, value)  | 
|     #֪ͨ¿Í»§¶Ë  | 
|     NotifyPlayerCurrency(curPlayer, currencyType, value)  | 
|     return  | 
|   | 
| def NotifyPlayerCurrency(curPlayer, currencyType, value=-1):  | 
|     if currencyType not in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         return  | 
|     refreshType = ShareDefine.TYPE_Price_CurrencyDict[currencyType]  | 
|     if refreshType == None:  | 
|         # ²»ÐèҪ֪ͨ¿Í»§¶Ë  | 
|         return  | 
|     if value < 0:  | 
|         value = GetPlayerCurrency(curPlayer, currencyType)  | 
|     SendPropertyRefresh(curPlayer, refreshType, value)  | 
|     return  | 
|   | 
| # Í¨ÖªÍæ¼ÒËùÓÐ×Ô¶¨Òå»õ±Ò  | 
| def NotifyPlayerAllCurrency(curPlayer):  | 
|     notifyList = []  | 
|     for currencyType in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         refreshType = ShareDefine.TYPE_Price_CurrencyDict[currencyType]  | 
|         if refreshType == None:  | 
|             # ²»ÐèҪ֪ͨ¿Í»§¶Ë  | 
|             continue  | 
|           | 
|         #´Ë´¦¸ù¾ÝÐèÇóÈôValueΪ0 ¿É²»Í¨Öª¿Í»§¶Ë£¬¾ßÌ幦ÄÜÖÆ×÷Õß¾ö¶¨  | 
|         value = GetPlayerCurrency(curPlayer, currencyType)  | 
|         notifyStruct = ChPyNetSendPack.tagRefreshType()  | 
|         notifyStruct.RefreshType = refreshType  | 
|         notifyStruct.Value = value  | 
|         notifyList.append(notifyStruct)  | 
|           | 
|     # ¸ºÖµ»õ±Ò  | 
|     for moneyType, refreshType in ShareDefine.MoneyMinusRefreshDict.items():  | 
|         if refreshType == None:  | 
|             # ²»ÐèҪ֪ͨ¿Í»§¶Ë  | 
|             continue  | 
|         value = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MoneyMinus % moneyType)  | 
|         if not value:  | 
|             continue  | 
|         notifyStruct = ChPyNetSendPack.tagRefreshType()  | 
|         notifyStruct.RefreshType = refreshType  | 
|         notifyStruct.Value = value  | 
|         notifyList.append(notifyStruct)  | 
|           | 
|     #ÊôÐÔ×éºÏ°ü Í¨Öª×Ô¼º  | 
|     sendPack = ChPyNetSendPack.tagObjInfoListRefresh()  | 
|     sendPack.Clear()  | 
|     sendPack.ObjID = curPlayer.GetID()  | 
|     sendPack.ObjType = curPlayer.GetGameObjType()  | 
|     sendPack.Count = len(notifyList)  | 
|     sendPack.RefreshType = notifyList  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
|   | 
| ##Íæ¼ÒÊÇ·ñÓÐÇ®¿î  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param TYPE_Price ,»õ±ÒÀàÐÍ  | 
| # @param Price ,»õ±Ò¼Û¸ñ  | 
| # @return ·µ»ØÖµÕæ, Í¨¹ý  | 
| # @remarks Íæ¼ÒÊÇ·ñÓÐÇ®¿î  | 
| def HaveMoney(curPlayer, TYPE_Price, Price, needNotify=True):  | 
|     if Price < 0:  | 
|         return False  | 
|       | 
|     needMoneyCount = 0  | 
|     notifyCode = ''  | 
|     #½ð×ÓÖ§¸¶  | 
|     if TYPE_Price == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         needMoneyCount = curPlayer.GetGold()  | 
|         notifyCode = "GoldErr"  | 
|           | 
|     #½ðƱ֧¸¶  | 
|     elif TYPE_Price == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         needMoneyCount = curPlayer.GetGoldPaper()  | 
|         notifyCode = "GoldPaperErr"  | 
|          | 
|     #Òø×ÓÖ§¸¶  | 
|     elif TYPE_Price == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         needMoneyCount = GetSilver(curPlayer)  | 
|         notifyCode = "SilverErr"  | 
|           | 
|     #ÒøÆ±Ö§¸¶  | 
|     elif TYPE_Price == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         needMoneyCount = curPlayer.GetSilverPaper()  | 
|         notifyCode = "SilverPaperErr"  | 
|           | 
|     #×Ô¶¨Òå»õ±Ò  | 
|     elif TYPE_Price in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         needMoneyCount = GetPlayerCurrency(curPlayer, TYPE_Price)  | 
|     else:  | 
|         GameWorld.Log("¸¶·Ñ½ðÇ®Òì³£ TYPE_Price = %s" % (TYPE_Price), curPlayer.GetPlayerID())  | 
|         return False     | 
|       | 
|     if needMoneyCount < Price:  | 
|         lackPrice = Price - needMoneyCount # »¹È±¶àÉÙÇ®  | 
|         tagMoneyInfo = GetEqualMoneyInfo(TYPE_Price, lackPrice)  | 
|         if tagMoneyInfo:  | 
|             tagMoneyType, tagMoneyValue = tagMoneyInfo  | 
|             if HaveMoney(curPlayer, tagMoneyType, tagMoneyValue, False):  | 
|                 GameWorld.DebugLog("HaveMoney¿ÉʹÓõȼۻõ±Ò²¹×ã¿Û³ý: TYPE_Price=%s, Price=%s, lackPrice=%s, tagMoneyType=%s, tagMoneyValue=%s"   | 
|                                    % (TYPE_Price, Price, lackPrice, tagMoneyType, tagMoneyValue), curPlayer.GetPlayerID())  | 
|                 return True  | 
|               | 
|     #---Ç®²»¹» ·µ»Ø¼ÙÈç¹ûÐèÒªÌáʾµÄ»° ÌáʾÐÅÏ¢---  | 
|     if needMoneyCount < Price:  | 
|         if needNotify and notifyCode:  | 
|             NotifyCode(curPlayer, notifyCode)  | 
|         GameWorld.DebugLog("»õ±Ò²»×ã: TYPE_Price=%s, Price=%s, curMoneyCount=%s" % (TYPE_Price, Price, needMoneyCount))  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| def GetEqualMoneyInfo(moneyType, needValue):  | 
|     equalMoneyInfo = IpyGameDataPY.GetFuncEvalCfg("EqualValueMoney", 2, {})  | 
|     if str(moneyType) not in equalMoneyInfo:  | 
|         return  | 
|     tagMoneyType = equalMoneyInfo[str(moneyType)]  | 
|     exchangeMoneyInfo = IpyGameDataPY.GetFuncEvalCfg("EqualValueMoney", 1, {})  | 
|     if str(tagMoneyType) not in exchangeMoneyInfo:  | 
|         return  | 
|     exchangeInfo = exchangeMoneyInfo[str(tagMoneyType)]  | 
|     if moneyType != exchangeInfo[0]:  | 
|         return  | 
|     multiple = exchangeInfo[1]  | 
|     tagMoneyValue = int(math.ceil(needValue / float(multiple)))  | 
|     #GameWorld.DebugLog("µÈ¼Û»õ±ÒÐÅÏ¢: moneyType=%s,needValue=%s,multiple=%s,tagMoneyType=%s,tagMoneyValue=%s"   | 
|     #                   % (moneyType, needValue, multiple, tagMoneyType, tagMoneyValue))  | 
|     return tagMoneyType, tagMoneyValue  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÊÇ·ñÓÐÇ®¿î  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param TYPE_Price ,»õ±ÒÀàÐÍ  | 
| # @param Price ,»õ±Ò¼Û¸ñ  | 
| # @return ·µ»ØÖµ[[type1,price1], [type2,price2]]  | 
| # @remarks Íæ¼ÒÊÇ·ñÓÐÇ®¿î  | 
| def HaveMoneyEx(curPlayer, TYPE_Price, Price, needNotify=True):  | 
|     if Price < 0:  | 
|         return []  | 
|     if TYPE_Price == ShareDefine.TYPE_Price_Gold_Paper_Money:  | 
|         TYPE_Price = IPY_GameWorld.TYPE_Price_Gold_Money #аæÎÞ°óÓñ£¬ÔÏȰóÓñÔÙÏÉÓñµÄ¿Û·¨¸Ä³É ¿ÛÏÉÓñ 2019/3/26  | 
|         #âýÓ¢°æ£º »Ö¸´°óÓñ£¬µ«ÊDz»Ê¹ÓÃÏȰóÓñÔÙÏÉÓñµÄ¹æÔò£¬ÔÀ´ÏȰóÓñÔÙÏÉÓñµÄ¹æÔòÒ»ÑùΪĬÈÏ¿ÛÏÉÓñ 2019/10/8  | 
|           | 
|     if TYPE_Price in [IPY_GameWorld.TYPE_Price_Gold_Money, IPY_GameWorld.TYPE_Price_Gold_Paper,  | 
|                       IPY_GameWorld.TYPE_Price_Silver_Money, IPY_GameWorld.TYPE_Price_Silver_Paper]:  | 
|         if HaveMoney(curPlayer, TYPE_Price, Price, needNotify):  | 
|             return [[TYPE_Price, Price]]  | 
|         return []  | 
|       | 
|     #ÏÈÀñȯÔÙÔª±¦  | 
|     elif TYPE_Price == ShareDefine.TYPE_Price_Gold_Paper_Money:  | 
|         goldPaper = curPlayer.GetGoldPaper() # Àñȯ  | 
|         gold = curPlayer.GetGold() # Ôª±¦  | 
|           | 
|         if goldPaper + gold < Price: # Ç®²»¹»  | 
|             if needNotify:  | 
|                 NotifyCode(curPlayer, "GoldErr")  | 
|             return []  | 
|               | 
|         if goldPaper >= Price: # Ö»ÓÃÀñȯ¾Í¹»ÁË  | 
|             return [[IPY_GameWorld.TYPE_Price_Gold_Paper, Price]]  | 
|         needGold = Price - goldPaper # ÓÃÍêÀñȯ£¬»¹ÐèÒªÔª±¦  | 
|         return [[IPY_GameWorld.TYPE_Price_Gold_Paper, goldPaper], [IPY_GameWorld.TYPE_Price_Gold_Money, needGold]]  | 
| #    #ÓÃÕ½Ã˹±Ï×¶È  | 
| #    elif TYPE_Price == ShareDefine.TYPE_Price_Family_Contribution:  | 
| #        return []  | 
|     else:  | 
|         GameWorld.Log("¸¶·Ñ½ðÇ®Òì³£ TYPE_Price = %s" % (TYPE_Price), curPlayer.GetPlayerID())  | 
|         return []     | 
|       | 
|     return []  | 
|   | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò¸¶¿î  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param type_Price ,»õ±ÒÀàÐÍ  | 
| # @param price ,»õ±Ò¼Û¸ñ  | 
| # @param costType ,Ïû·ÑµãÀàÐÍ  | 
| # @param infoDict ,À©Õ¹ÐÅÏ¢, ×ÓÏû·Ñ¶ÔÏó¿ÉÒÔͨ¹ýÉèÖÃChConfig.Def_Cost_Reason_SonKey keyÖµ  | 
| # @param quantity ,ÊýÁ¿  | 
| # @param isMinus ,ÊÇ·ñÔÊÐí¿Û³É¸ºÖµ  | 
| # @return ·µ»ØÖµÕæ, ¸¶¿î³É¹¦  | 
| # @remarks Íæ¼Ò¸¶¿î  | 
| def PayMoney(curPlayer, type_Price, price, costType=ChConfig.Def_Cost_Unknown, infoDict={}, quantity=1, costVIPGold= -1, isNotify=True, isMinus=False):  | 
|     if price == 0:  | 
|         return True  | 
|     if price < 0:  | 
|         GameWorld.Log('###---¿ÛÇ®Òì³£ = %s' % (price), curPlayer.GetPlayerID())  | 
|         return False  | 
|     lostMoney = price  | 
|       | 
|     #20190917 »Ö¸´°óÓñ  | 
| #    if type_Price == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
| #        type_Price = IPY_GameWorld.TYPE_Price_Gold_Money #аæÎÞ°óÓñ£¬ÔÏȰóÓñÔÙÏÉÓñµÄ¿Û·¨¸Ä³É ¿ÛÏÉÓñ 2019/6/3  | 
|           | 
|     #½ð×ÓÖ§¸¶  | 
|     if type_Price == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         curPlayerGold = GetMoneyReal(curPlayer, type_Price)  | 
|         if curPlayerGold < price and not isMinus:  | 
|             NotifyCode(curPlayer, "GoldErr")  | 
|             return False  | 
|         updPlayerGold = curPlayerGold - price  | 
|         SetMoney(curPlayer, type_Price, updPlayerGold)  | 
|           | 
|         curBourseMoney = GetMoney(curPlayer, ShareDefine.TYPE_Price_BourseMoney)  | 
|         updBourseMoney = curBourseMoney  | 
|         #µ±Êǽ»Ò×Ëù¿Û·Ñ¡¢×êʯºì°üʱ£¬Ôò±Ø¶¨¿Û³ý½»Ò×¶î¶È  | 
|         if costType in ChConfig.UnUseInner_CostType:  | 
|             updBourseMoney = max(0, curBourseMoney - price)  | 
|         #ÆäËûÈç¹ûµ±Ç°½ð×ӱȽ»Ò×¶î¶È»¹ÉÙ£¬ÔòÇ¿ÖÆµ÷Õû½»Ò×¶î¶ÈΪµ±Ç°½ð×ÓÊý(ÕâÖÖÇé¿öÒ»°ãÊǷǽ»Ò×ËùÏû·ÑµÄ£¬ÐèҪͬ²½¿Û³ý½»Ò×Ëù¿É¹ºÂò¶î¶È)  | 
|         elif updPlayerGold < updBourseMoney:  | 
|             updBourseMoney = updPlayerGold  | 
|         updBourseMoney = max(0, updBourseMoney)  | 
|         if updBourseMoney != curBourseMoney:  | 
|             SetPlayerCurrency(curPlayer, ShareDefine.TYPE_Price_BourseMoney, updBourseMoney)  | 
|         infoDict["BourseMoney"] = updBourseMoney  | 
|           | 
|     #½ðƱ֧¸¶  | 
|     elif type_Price == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         curPlayerGoldPaper = GetMoneyReal(curPlayer, type_Price)  | 
|         if curPlayerGoldPaper < price and not isMinus:  | 
|             NotifyCode(curPlayer, "GoldPaperErr")  | 
|             return False  | 
|         updGoldPaper = curPlayerGoldPaper - price  | 
|         SetMoney(curPlayer, type_Price, updGoldPaper)  | 
|           | 
|     #Òø×ÓÖ§¸¶  | 
|     elif type_Price == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         curPlayerSilver = GetSilver(curPlayer)  | 
|         if curPlayerSilver < price:  | 
|             NotifyCode(curPlayer, "SilverErr")  | 
|             return False  | 
|         #ÓÐ×ã¹»µÄǮ֧¸¶  | 
|         SetSilver(curPlayer, curPlayerSilver - price)  | 
|           | 
|     #ÒøÆ±Ö§¸¶  | 
|     elif type_Price == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         curPlayerSilverPaper = curPlayer.GetSilverPaper()  | 
|         if curPlayerSilverPaper < price:  | 
|             NotifyCode(curPlayer, "SilverPaperErr")  | 
|             return False  | 
|         #ÓÐ×ã¹»µÄǮ֧¸¶  | 
|         curPlayer.SetSilverPaper(curPlayerSilverPaper - price)  | 
|     #×Ô¶¨Òå»õ±Ò  | 
|     elif type_Price in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         curCurrency = GetPlayerCurrency(curPlayer, type_Price)  | 
|         if curCurrency < price:  | 
|             lostMoney = curCurrency  | 
|             lackPrice = price - curCurrency # »¹È±¶àÉÙÇ®  | 
|             tagMoneyInfo = GetEqualMoneyInfo(type_Price, lackPrice)  | 
|             if tagMoneyInfo:  | 
|                 tagMoneyType, tagMoneyValue = tagMoneyInfo  | 
|                 if not PayMoney(curPlayer, tagMoneyType, tagMoneyValue, costType, infoDict, quantity, costVIPGold, isNotify, isMinus):  | 
|                     #GameWorld.Log("µÈ¼Û»õ±ÒÒ²²»×ã")  | 
|                     return False  | 
|                 GameWorld.Log("µÈ¼Û»õ±Ò²¹×ã¿Û³ý: type_Price%s, price=%s, curCurrency=%s, lackPrice=%s, tagMoneyType=%s, tagMoneyValue=%s"   | 
|                                    % (type_Price, price, curCurrency, lackPrice, tagMoneyType, tagMoneyValue), curPlayer.GetPlayerID())  | 
|             else:  | 
|                 #GameWorld.Log("ûÓеȼۻõ±Ò£¬ÎÞ·¨¿Û³ý")  | 
|                 return False  | 
|         #ÓÐ×ã¹»µÄǮ֧¸¶  | 
|         SetPlayerCurrency(curPlayer, type_Price, curCurrency - lostMoney)  | 
|     else:  | 
|         GameWorld.Log("¸¶·Ñ½ðÇ®Òì³£ type_Price = %s" % (type_Price), curPlayer.GetPlayerID())  | 
|         return False  | 
|       | 
|     #¸¶¿îÒÔºóºóÐø²Ù×÷  | 
|     __PayMoneyAfter(curPlayer, type_Price, lostMoney, costType, infoDict, quantity, costVIPGold)  | 
|       | 
|     #֪ͨ¿Í»§¶Ëʧȥ½ðÇ®  | 
|     if isNotify:  | 
|         NotifyCode(curPlayer, "LostMoney", [type_Price, lostMoney])  | 
|     return True  | 
|   | 
| ## ¸¶¿îÒÔºóºóÐø²Ù×÷  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param type_Price ,»õ±ÒÀàÐÍ  | 
| #  @param price ,»õ±Ò¼Û¸ñ  | 
| #  @param costType ,Ïû·ÑÀàÐÍ  | 
| #  @param infoDict ,À©Õ¹ÐÅÏ¢  | 
| #  @param quantity Ïû·ÑÊýÁ¿  | 
| #  @return None  | 
| def __PayMoneyAfter(curPlayer, type_Price, price, costType, infoDict, quantity, costVIPGold):  | 
|     #½ð×ÓÖ§¸¶  | 
|     if type_Price == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         __PayMoneyAfterByGoldMoney(curPlayer, type_Price, price, costType, infoDict, costVIPGold)  | 
|               | 
|     #½ðƱ֧¸¶  | 
|     elif type_Price == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         __PayMoneyAfterByGoldPaper(curPlayer, price, costType, infoDict)  | 
|       | 
|     #Òø×ÓÖ§¸¶  | 
|     elif type_Price == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         __PayMoneyAfterBySilverMoney(curPlayer, price)  | 
|       | 
|     #ÒøÆ±Ö§¸¶  | 
|     elif type_Price == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         __PayMoneyAfterBySilverPaper(curPlayer, price)  | 
|       | 
|     EventShell.EventRespons_OnMoneyChange(curPlayer, type_Price)  | 
|       | 
|     #»îÔ¾¶È´¦Àí  | 
|     PlayerActivity.OnPayMoneyActivity(curPlayer, type_Price, price)  | 
|     #תÅ̻  | 
|     PlayerActTurntable.OnPlayerUseGold(curPlayer, type_Price, price)  | 
|       | 
|     unitPrice = price if quantity == 1 else int(math.ceil(price * 1.0 / quantity)) # µ¥¼Û  | 
|     #reason_name = "Unknown" if not costType else costType  | 
|     reason_name = costType  | 
|     eventName = reason_name  | 
|     if costType in ChConfig.Def_CostType_Dict:  | 
|         eventName = ChConfig.Def_CostType_Dict[costType]  | 
|     #===========================================================================  | 
|     # isDivSonKey = False # ÊÇ·ñÇø·ÖÏû·Ñ¶ÔÏó  | 
|     # if costType in ChConfig.Def_CostType_Dict:  | 
|     #    eventName, reason_name, isDivSonKey = ChConfig.Def_CostType_Dict[costType]  | 
|     #    if costType in ChConfig.CostGroupToGoldShop:  | 
|     #        reason_name = ChConfig.Def_CostType_Dict[ChConfig.Def_Cost_BuyStoreItem][1]  | 
|     #      | 
|     # if isDivSonKey and isinstance(infoDict, dict) and ChConfig.Def_Cost_Reason_SonKey in infoDict:  | 
|     #    reasonSon = infoDict[ChConfig.Def_Cost_Reason_SonKey]  | 
|     # else:  | 
|     #    reasonSon = reason_name  | 
|     # # Í³Ò»¸ñʽ: ¡¸Ïû·Ñ×é:Ïû·Ñ¶ÔÏó¡¹ ; Ã»ÓÐÉèÖÃÏû·Ñ¶ÔÏóµÄĬÈÏΪÏû·Ñ×é  | 
|     # reason_name = "%s:%s" % (reason_name, reasonSon)  | 
|     #===========================================================================  | 
|       | 
|     # ³ý×êʯ¼°°ó×êÍ⣬δָ¶¨²Ù×÷ÀàÐ͵IJ»¼Ç¼  | 
|     if type_Price not in [IPY_GameWorld.TYPE_Price_Gold_Money, IPY_GameWorld.TYPE_Price_Gold_Paper] \  | 
|         and costType == ChConfig.Def_Cost_Unknown:  | 
|         #GameWorld.DebugLog("¸Ã»õ±ÒûÓÐÖ¸¶¨Ïû·ÑÀàÐͲ»¼Ç¼!type_Price=%s,costType=%s" % (type_Price, costType))  | 
|         return  | 
|     # Á÷ÏòÓàeventName  | 
|     #if eventName:  | 
|     DataRecordPack.DR_UseMoney(curPlayer, eventName, type_Price, price, infoDict) # Á÷Ïò  | 
|     EventReport.WriteEvent_virtual_resource(curPlayer, type_Price, reason_name, quantity,  | 
|                                             unitPrice, ShareDefine.Def_UserAction_Money_Use, infoDict)  | 
|               | 
|     #===========================================================================  | 
|     # if type_Price == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|     #    EventReport.WriteEvent_virtual_cost(curPlayer, quantity, unitPrice, reason_name)  | 
|     # elif type_Price in [IPY_GameWorld.TYPE_Price_Gold_Paper, IPY_GameWorld.TYPE_Price_Silver_Money]:  | 
|     #      | 
|     #    # ½ð±Òδָ¶¨Ïû·ÑÀàÐ͵IJ»¼Ç¼  | 
|     #    if type_Price == IPY_GameWorld.TYPE_Price_Silver_Money and costType == ChConfig.Def_Cost_Unknown:  | 
|     #        return  | 
|     #    EventReport.WriteEvent_virtual_resource(curPlayer, type_Price, reason_name, quantity,   | 
|     #                                            unitPrice, ShareDefine.Def_UserAction_Money_Use)  | 
|     #      | 
|     # # ×Ô¶¨Òå¼Ç¼  | 
|     # priceNameDict = {IPY_GameWorld.TYPE_Price_Gold_Money:["×êʯ", "GetGold", 0],  | 
|     #                 IPY_GameWorld.TYPE_Price_Gold_Paper:["°ó×ê", "GetGoldPaper", 0],  | 
|     #                 IPY_GameWorld.TYPE_Price_Silver_Money:["½ð±Ò", "GetSilver", ChConfig.Def_DRRecord_Min_Silver],  | 
|     #                 }  | 
|     # if type_Price in priceNameDict:  | 
|     #    typeName, moneyFuncName, minPrice = priceNameDict[type_Price]  | 
|     #    if minPrice <= 0 or price >= minPrice:   | 
|     #        EventReport.WriteEvent_pay_money(curPlayer, reason_name, typeName, price, getattr(curPlayer, moneyFuncName)())  | 
|     #===========================================================================  | 
|     return  | 
|   | 
| ## ¸¶¿îÒÔºóºóÐø²Ù×÷(½ð×Ó)  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param price ,»õ±Ò¼Û¸ñ  | 
| #  @return None  | 
| def __PayMoneyAfterByGoldMoney(curPlayer, type_Price, price, costType, infoDict, costVIPGold):  | 
|           | 
|       | 
|     # ³äÖµ»î¶¯Íæ¼ÒÏûºÄÔª±¦´¦Àí  | 
|     #PlayerGoldAction.PlayerUseGold(curPlayer, price)  | 
|       | 
|     # Ïû·Ñ·µÀû  | 
|     if costType not in ChConfig.CostRebate_DisableType:  | 
|         PlayerCostRebate.AddCostRebateGold(curPlayer, costType, price, infoDict)  | 
|         PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_UseGold, price)  | 
|         PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_UseGold, price)  | 
|     else:  | 
|         GameWorld.DebugLog("²»¼ÆÈëÏû·Ñ»î¶¯µÄÏû·ÑÀàÐÍ!costType=%s" % costType, curPlayer.GetPlayerID())  | 
|           | 
|     # Ê¼þ»ã±¨  | 
|     #===========================================================================  | 
|     # if costType == ChConfig.Def_Cost_BourseBuy:  | 
|     #    # ½»Ò×Ëù¹ºÂòÎïÆ·£¬»ã±¨½»Ò××êʯ  | 
|     #    playerName = curPlayer.GetPlayerName()  | 
|     #    leftGold = curPlayer.GetGold()  | 
|     #    eventParam = "RoleID=%s,Price=%s,TradeType=Lost,LeftGold=%s" \  | 
|     #                    % (playerName, price, leftGold)  | 
|     #    EventReport.EventReport(ShareDefine.Def_UserAction_TradeGold, eventParam, curPlayer)  | 
|     # else:  | 
|     #    playerName = curPlayer.GetPlayerName()  | 
|     #    leftGold = curPlayer.GetGold()  | 
|     #    eventParam = "RoleID=%s,CostType=%s,ItemID=%s,Price=%s,LeftGold=%s" \  | 
|     #                    % (playerName, costType, infoDict, price, leftGold)  | 
|     #    EventReport.EventReport(ShareDefine.Def_UserAction_UseGold, eventParam, curPlayer)  | 
|     #===========================================================================  | 
|       | 
|     # Í¨ÖªÔª±¦Ïû·Ñ¼Ç¼  | 
|     #__Sync_GoldCostReport(curPlayer, costType, price, expandValue)  | 
|     return  | 
|   | 
|   | 
| ## Í¨ÖªÔª±¦Ïû·Ñ¼Ç¼  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param costType: Ïû·ÑµãÀàÐÍ  | 
| #  @param price: Ïû·Ñ¶î¶È  | 
| #  @param itemID: ÎïÆ·id£¬Ïû·ÑÀàÐÍΪÎïÆ·Ê±¿ÉÌî  | 
| #  @return None  | 
| def __Sync_GoldCostReport(curPlayer, costType, price, itemID=0):  | 
|     sendPack = ChPyNetSendPack.tagMCGoldCostReport()  | 
|     sendPack.Clear()  | 
|     sendPack.CostType = costType  | 
|     sendPack.Price = price  | 
|     sendPack.ItemID = itemID  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
|   | 
| ## ¸¶¿îÒÔºóºóÐø²Ù×÷(½ðƱ)  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param price ,»õ±Ò¼Û¸ñ  | 
| #  @return None  | 
| def __PayMoneyAfterByGoldPaper(curPlayer, price, costType, infoDict):      | 
|       | 
|     # Ê¼þ»ã±¨  | 
|     #===========================================================================  | 
|     # playerName = curPlayer.GetPlayerName()  | 
|     # leftGoldPaper = curPlayer.GetGoldPaper()  | 
|     # eventParam = "RoleID=%s,CostType=%s,ItemID=%s,Price=%s,LeftGoldPaper=%s" \  | 
|     #                % (playerName, costType, infoDict, price, leftGoldPaper)  | 
|     # EventReport.EventReport(ShareDefine.Def_UserAction_UseGoldPaper, eventParam, curPlayer)  | 
|     #===========================================================================  | 
|     return  | 
|   | 
|   | 
| ## ¸¶¿îÒÔºóºóÐø²Ù×÷(½ðƱ)  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param price ,»õ±Ò¼Û¸ñ  | 
| #  @return None  | 
| def __PayMoneyAfterBySilverMoney(curPlayer, price):      | 
|     return  | 
|   | 
|   | 
| ## ¸¶¿îÒÔºóºóÐø²Ù×÷(½ðƱ)  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param price ,»õ±Ò¼Û¸ñ  | 
| #  @return None  | 
| def __PayMoneyAfterBySilverPaper(curPlayer, price):      | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò»ñµÃ½ðÇ®  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param value ,»õ±Ò¼Û¸ñ  | 
| # @param priceType ,»õ±ÒÀàÐÍ  | 
| # @return ·µ»ØÖµÕæ, ¸øÇ®³É¹¦  | 
| # @param isSysHint ÊÇ·ñϵͳÌáʾ£¨Ä¬ÈÏÊÇ£©  | 
| # @remarks Íæ¼Ò»ñµÃ½ðÇ®  | 
| def GiveMoney(curPlayer, priceType, value, giveType=ChConfig.Def_GiveMoney_Unknown, addDataDict={}, isSysHint=True, isGiveBourseMoney=True):  | 
|     if value == 0:  | 
|         return True  | 
|       | 
|     if value < 0:  | 
|         GameWorld.Log('Íæ¼Ò»ñµÃ½ðÇ®Òì³£ £¬ value = %s , priceType = %s ,' % (value, priceType))  | 
|         return  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         serverGroupID = GetPlayerServerGroupID(curPlayer)  | 
|         msgInfo = {"PlayerID":curPlayer.GetPlayerID(), "MoneyType":priceType, "Value":value, "GiveType":giveType, "AddDataDict":addDataDict}  | 
|         GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_GiveMoney, msgInfo, [serverGroupID])  | 
|         return True  | 
|           | 
|     if priceType == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         updPlayerGold = GetMoneyReal(curPlayer, priceType) + value  | 
|         if updPlayerGold > ChConfig.Def_PlayerTotalMoney_Gold:  | 
|             #³¬¹ý½ðÇ®ÉÏÏÞ  | 
|             NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
|             return  | 
|         SetMoney(curPlayer, priceType, updPlayerGold)  | 
|           | 
|         if isGiveBourseMoney and updPlayerGold > 0:  | 
|             GiveMoney(curPlayer, ShareDefine.TYPE_Price_BourseMoney, min(value, updPlayerGold))  | 
|         addDataDict["BourseMoney"] = GetMoney(curPlayer, ShareDefine.TYPE_Price_BourseMoney)  | 
|           | 
|     elif priceType == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         updPlayerGoldPaper = GetMoneyReal(curPlayer, priceType)  + value  | 
|         if updPlayerGoldPaper > ChConfig.Def_PlayerTotalMoney_Gold:  | 
|             #³¬¹ý½ðÇ®ÉÏÏÞ  | 
|             NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
|             return  | 
|         SetMoney(curPlayer, priceType, updPlayerGoldPaper)  | 
|           | 
|     elif priceType == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         # ½ðǮ֧³Ö³¬¹ý20ÒÚ, Ôݲ»×öÉÏÏÞ¿ØÖÆ  | 
| #        if curSilver + value > ChConfig.Def_PlayerTotalMoney_Silver:  | 
| #            #³¬¹ý½ðÇ®ÉÏÏÞ  | 
| #            NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
| #            return  | 
|         SetSilver(curPlayer, GetSilver(curPlayer) + value)  | 
|          | 
|           | 
|     elif priceType == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         if curPlayer.GetSilverPaper() + value > ChConfig.Def_PlayerTotalMoney_Silver:  | 
|             #³¬¹ý½ðÇ®ÉÏÏÞ  | 
|             NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
|             return  | 
|           | 
|         curPlayer.SetSilverPaper(curPlayer.GetSilverPaper() + value)  | 
|   | 
|     #×Ô¶¨Òå»õ±Ò  | 
|     elif priceType in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         curCurrency = GetPlayerCurrency(curPlayer, priceType)  | 
|         if curCurrency >= ChConfig.Def_UpperLimit_DWord:  | 
|             return  | 
|         updValue = min(ChConfig.Def_UpperLimit_DWord, curCurrency + value)  | 
|         SetPlayerCurrency(curPlayer, priceType, updValue)  | 
|         if priceType == ShareDefine.TYPE_Price_RealmPoint:  | 
|             PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_GetRealmPoint, value)  | 
|             EventShell.EventRespons_GetRealmPoint(curPlayer)  | 
|     else:  | 
|         GameWorld.ErrLog("½ðÇ®ÀàÐÍ´íÎó, priceType=%s,value=%s,giveType=%s" % (priceType, value, giveType), curPlayer.GetPlayerID())  | 
|         DataRecordPack.DR_GiveMoneyError(curPlayer, priceType, value, giveType, addDataDict)  | 
|         return  | 
|       | 
|     if isSysHint and priceType != ShareDefine.TYPE_Price_BourseMoney:  | 
|         #֪ͨ¿Í»§¶ËµÃµ½½ðÇ®  | 
|         NotifyCode(curPlayer, "GetMoney", [priceType, value])  | 
|           | 
|     __GiveMoneyAfter(curPlayer, priceType, value, giveType, addDataDict)  | 
|       | 
|     return True  | 
|   | 
| def __GiveMoneyAfter(curPlayer, priceType, value, giveType, addDataDict):  | 
|     # ³ý×êʯ¼°°ó×êÍ⣬δָ¶¨²Ù×÷ÀàÐ͵IJ»¼Ç¼  | 
|       | 
|     EventShell.EventRespons_OnMoneyChange(curPlayer, priceType)  | 
|       | 
|     if priceType not in [IPY_GameWorld.TYPE_Price_Gold_Money, IPY_GameWorld.TYPE_Price_Gold_Paper] \  | 
|         and giveType == ChConfig.Def_GiveMoney_Unknown:  | 
|         #GameWorld.DebugLog("¸Ã»õ±ÒûÓÐÖ¸¶¨À´Ô´ÀàÐͲ»¼Ç¼!priceType=%s,giveType=%s" % (priceType, giveType))  | 
|         return  | 
|     eventName = giveType  | 
|     if giveType in ChConfig.Def_GetType_Dict:  | 
|         eventName = ChConfig.Def_GetType_Dict[giveType]  | 
|         addDataDict["eventName"] = eventName  | 
|           | 
|     DataRecordPack.DR_GiveMoney(curPlayer, eventName, priceType, value, addDataDict)  | 
|     EventReport.WriteEvent_virtual_resource(curPlayer, priceType, giveType, 1, value,  | 
|                                             ShareDefine.Def_UserAction_Money_Get, addDataDict)  | 
| #===============================================================================  | 
| #    reason_name = "Unknown" if not giveType else giveType  | 
| #    eventName = reason_name  | 
| #    if giveType in ChConfig.Def_GetType_Dict:  | 
| #        eventName, reason_name = ChConfig.Def_GetType_Dict[giveType][:2]  | 
| #    if isinstance(addDataDict, dict) and ChConfig.Def_Give_Reason_SonKey in addDataDict:  | 
| #        reasonSon = addDataDict[ChConfig.Def_Give_Reason_SonKey]  | 
| #    else:  | 
| #        reasonSon = reason_name  | 
| #    # Í³Ò»¸ñʽ: ¡¸»ñµÃ×é:»ñµÃÔÒò¡¹  | 
| #    reason_name = "%s:%s" % (reason_name, reasonSon)  | 
| #              | 
| #    # Á÷ÏòÓàeventName  | 
| #    if eventName:  | 
| #        DataRecordPack.DR_GiveMoney(curPlayer, eventName, priceType, value, addDataDict)  | 
| #          | 
| #    if priceType == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
| #        playerName = curPlayer.GetPlayerName()  | 
| #        eventParam = "RoleID=%s,AddGold=%s,LeftGold=%s,AddDataDict=%s" \  | 
| #                    % (playerName, value, curPlayer.GetGold(), addDataDict)  | 
| #        EventReport.EventReport(ShareDefine.Def_UserAction_GameMakeGold, eventParam, curPlayer)  | 
| #          | 
| #    elif priceType == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
| #        playerName = curPlayer.GetPlayerName()  | 
| #        eventParam = "RoleID=%s,AddGoldPaper=%s,LeftGoldPaper=%s,AddDataDict=%s" \  | 
| #                        % (playerName, value, curPlayer.GetGoldPaper(), addDataDict)  | 
| #        EventReport.EventReport(ShareDefine.Def_UserAction_GameMakeGoldPaper, eventParam, curPlayer)  | 
| #      | 
| #   | 
| #    if priceType == IPY_GameWorld.TYPE_Price_Gold_Money: #and eventName != "CoinToGold":  | 
| #        EventReport.WriteEvent_virtual_reward(curPlayer, value, reason_name)  | 
| #    # ¶þ¼¶»õ±Ò²ú³ö¼Ç¼, ÔÝÖ»¼Ç¼°ó×ê¡¢½ð±Ò  | 
| #    elif priceType in [IPY_GameWorld.TYPE_Price_Gold_Paper, IPY_GameWorld.TYPE_Price_Silver_Money]:  | 
| #        EventReport.WriteEvent_virtual_resource(curPlayer, priceType, reason_name, 1, value,  | 
| #                                                ShareDefine.Def_UserAction_Money_Get)  | 
| #          | 
| #    # ×Ô¶¨Òå¼Ç¼  | 
| #    priceNameDict = {IPY_GameWorld.TYPE_Price_Gold_Money:["×êʯ", "GetGold", 0],  | 
| #                     IPY_GameWorld.TYPE_Price_Gold_Paper:["°ó×ê", "GetGoldPaper", 0],  | 
| #                     IPY_GameWorld.TYPE_Price_Silver_Money:["½ð±Ò", "GetSilver", ChConfig.Def_DRRecord_Min_Silver],  | 
| #                     }  | 
| #    if priceType in priceNameDict:  | 
| #        typeName, moneyFuncName, minPrice = priceNameDict[priceType]  | 
| #        if minPrice <= 0 or value >= minPrice:   | 
| #            EventReport.WriteEvent_give_money(curPlayer, reason_name, typeName, value, getattr(curPlayer, moneyFuncName)())  | 
| #===============================================================================  | 
|           | 
|     return  | 
|   | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼ÒÄÜ·ñ»ñµÃ½ðÇ®  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param value ,»õ±Ò¼Û¸ñ  | 
| # @param type ,»õ±ÒÀàÐÍ  | 
| # @return ·µ»ØÖµÕæ, Í¨¹ý  | 
| # @remarks Íæ¼ÒÄÜ·ñ»ñµÃ½ðÇ®  | 
| def CanGiveMoney(curPlayer, priceType, value):  | 
|     if value == 0:  | 
|         return True  | 
|       | 
|     if priceType == IPY_GameWorld.TYPE_Price_Gold_Money:  | 
|         if curPlayer.GetGold() + value > ChConfig.Def_PlayerTotalMoney_Gold:  | 
|             #³¬¹ý½ðÇ®ÉÏÏÞ  | 
|             NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
|             return False   | 
|     elif priceType == IPY_GameWorld.TYPE_Price_Gold_Paper:  | 
|         if curPlayer.GetGoldPaper() + value > ChConfig.Def_PlayerTotalMoney_Gold:  | 
|             #³¬¹ý½ðÇ®ÉÏÏÞ  | 
|             NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
|             return False  | 
|     elif priceType == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|         #½ð±ÒÖ§³Ö³¬¹ý20ÒÚ£¬Ôݲ»×öÉÏÏÞ¿ØÖÆ  | 
|         pass  | 
| #        if GetSilver(curPlayer) + value > ChConfig.Def_PlayerTotalMoney_Silver:  | 
| #            #³¬¹ý½ðÇ®ÉÏÏÞ  | 
| #            NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
| #            return False  | 
|     elif priceType == IPY_GameWorld.TYPE_Price_Silver_Paper:  | 
|         if curPlayer.GetSilverPaper() + value > ChConfig.Def_PlayerTotalMoney_Silver:  | 
|             #³¬¹ý½ðÇ®ÉÏÏÞ  | 
|             NotifyCode(curPlayer, "MoneyIsFull", [priceType])  | 
|             return False  | 
|     elif priceType in ShareDefine.TYPE_Price_CurrencyDict:  | 
|         curCurrency = GetPlayerCurrency(curPlayer, priceType)  | 
|         if curCurrency + value > ChConfig.Def_UpperLimit_DWord:  | 
|             return False  | 
|     else:  | 
|           | 
|         GameWorld.Log("½ðÇ®ÀàÐÍ = %sÌî´íÀ²" % (priceType), curPlayer.GetPlayerID())  | 
|         return False   | 
|       | 
|     return True  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò×Ô¶¯»ØÑª  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò×Ô¶¯»ØÑª  | 
| def PlayerAutoRestoreHP(curPlayer, tick):  | 
|     return  | 
|       | 
| #---------------------------------------------------------------------  | 
| ##Íæ¼Ò×Ô¶¯»ØÄ§  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼Ò×Ô¶¯»ØÄ§  | 
| def PlayerAutoRestoreMP(curPlayer, tick):  | 
|     return  | 
|   | 
|   | 
| ##»ñµÃµ±Ç°Íæ¼ÒµÄ²Î¿¼¾Ñé  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµ, ²Î¿¼¾Ñé  | 
| # @remarks »ñµÃµ±Ç°Íæ¼ÒµÄ²Î¿¼¾Ñé  | 
| def GetPlayerReExp(curPlayer):  | 
|     lvIpyData = GetPlayerLVIpyData(curPlayer.GetLV())  | 
|     if not lvIpyData:  | 
|         return 0  | 
|     return lvIpyData.GetReExp()  | 
|   | 
| ## »ñµÃµ±Ç°Íæ¼ÒµÄ²Î¿¼½ðÇ®  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return  | 
| def GetPlayerReMoney(curPlayer):  | 
|     return 0  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##Ôö¼ÓÍæ¼ÒµÄPKÖµ  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Ôö¼ÓÍæ¼ÒµÄPKÖµ  | 
| def AddPlayerPKValue(curPlayer, tick):  | 
|     curPlayerPKValue = curPlayer.GetPKValue()  | 
|     maxPKValue = GetMaxPKValue()  | 
|     if curPlayerPKValue >= maxPKValue:  | 
|         #µ±Ç°PKÖµÒѵ½ÉÏÏÞ,²»Ìí¼Ó  | 
|         return  | 
|       | 
|     #Ìí¼ÓµãÊý  | 
|     addPoint = 1  | 
|     changePKValue = ChangePKValue(curPlayer, addPoint, tick)  | 
|       | 
|     if changePKValue >= maxPKValue:  | 
|         #PK_wll_0: ÄúɱÄõ¹ýÖØ£¬ÔÚºìÃû״̬ÏûʧǰÄú½«²»ÄܼÌÐø¶øÒѹ¥»÷ËûÈË  | 
|         NotifyCode(curPlayer, "PK_lhs_202580")  | 
|           | 
|     #Íæ¼ÒïÚ³µÉíÉϼÇÂ¼Íæ¼ÒÃû×ÖÑÕÉ«ÐÅÏ¢(±ØÐëÔÚÉèÖúìÃûÒÔºó)  | 
|     #PlayerTruck.ChangeTruckNoteInfo(curPlayer)  | 
|     return  | 
|   | 
| def ChangePKValue(curPlayer, addValue, tick):  | 
|     '''¸ü¸ÄPKÖµ'''  | 
|     curPlayerPKValue = curPlayer.GetPKValue()  | 
|     maxPKValue = GetMaxPKValue()  | 
|     newPKValue = max(0, min(maxPKValue, curPlayerPKValue + addValue))  | 
|     if newPKValue == curPlayerPKValue:  | 
|         return newPKValue  | 
|       | 
|     GameWorld.DebugLog("¸üÐÂPKÖµ: curPlayerPKValue=%s,newPKValue=%s,addValue=%s" % (curPlayerPKValue, newPKValue, addValue), curPlayer.GetPlayerID())  | 
|     if newPKValue == 0:  | 
|         ClearPKValue(curPlayer)  | 
|     else:  | 
|         addBuffID = ChConfig.Def_SkillID_Red  | 
|         curPlayer.SetPKValue(newPKValue)  | 
|         findBuffInfo = SkillCommon.FindBuffByID(curPlayer, addBuffID)  | 
|         redBuff = findBuffInfo[0]  | 
|         addTimeValue = newPKValue - curPlayerPKValue  | 
|         if not redBuff:  | 
|             SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, addBuffID, tick)  | 
|             if newPKValue > 1:  | 
|                 findBuffInfo = SkillCommon.FindBuffByID(curPlayer, addBuffID)  | 
|                 redBuff = findBuffInfo[0]  | 
|                 addTimeValue = newPKValue - 1  | 
|                   | 
|         if addTimeValue and redBuff:  | 
|             __AddPKValueRedBuffTime(curPlayer, redBuff, addTimeValue)  | 
|     return newPKValue  | 
|   | 
| def __AddPKValueRedBuffTime(curPlayer, redBuff, addTimeValue):  | 
|     '''Ôö¼ÓPKÖµ¶ÔÓ¦buffʱ³¤  | 
|     @param addTimeValue: Ôö¼ÓµÄbuffµ¥Î»Ê±³¤´ÎÊý, Ö§³ÖÕý¸º  | 
|     '''  | 
|     buffSkill = redBuff.GetSkill()  | 
|     if not buffSkill:  | 
|         return  | 
|     buffType = SkillCommon.GetBuffType(buffSkill)  | 
|     addTime = buffSkill.GetLastTime() * addTimeValue # ÓÐÕý¸º  | 
|     remainTime = redBuff.GetRemainTime()  | 
|     resultTime = min(max(0, remainTime + addTime), ChConfig.Def_Max_Buff_RemainTime)  | 
|     redBuff.SetRemainTime(resultTime)  | 
|     BuffSkill.PYSync_RefreshBuff(curPlayer, redBuff, buffType)  | 
|     GameWorld.DebugLog("    Ôö¼ÓºìÃûbuffʱ³¤: addTimeValue=%s,remainTime=%s,addTime=%s,resultTime=%s"   | 
|                        % (addTimeValue, remainTime, addTime, resultTime), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def RefreshPKValueByRedBuff(curPlayer):  | 
|     ## Ë¢ÐºìÃû¶ÔÓ¦PKValue  | 
|     curPKValue = curPlayer.GetPKValue()  | 
|     if not curPKValue:  | 
|         return  | 
|     if PlayerTJG.GetIsTJG(curPlayer):  | 
|         return  | 
|     redBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_Red)[0]  | 
|     if not redBuff:  | 
|         curPlayer.SetPKValue(0)  | 
|         return  | 
|     buffSkill = redBuff.GetSkill()  | 
|     if not buffSkill:  | 
|         return  | 
|     remainTime = redBuff.GetRemainTime()  | 
|     perPKValueTime = buffSkill.GetLastTime()  | 
|     pkValue = int(math.ceil(remainTime / float(perPKValueTime)))  | 
|     if curPKValue != pkValue:  | 
|         curPlayer.SetPKValue(pkValue)  | 
|         GameWorld.DebugLog("¸üÐÂÍæ¼ÒPKÖµ: remainTime=%s,pkValue=%s" % (remainTime, pkValue), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def ClearPKValue(curPlayer):  | 
|     '''Çå³ýPKÖµ'''  | 
|     curPlayer.SetPKValue(0)  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_Red, tick)  | 
|     return  | 
|   | 
| def GetMaxPKValue():  | 
|     '''»ñÈ¡×î´óPKÖµ'''  | 
|     return IpyGameDataPY.GetFuncCfg("PKConfig", 2)  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##»ñµÃÍæ¼ÒÉý¼¶, »ñµÃµÄÊôÐ﵋  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµ, »ñµÃµÄÊôÐ﵋  | 
| # @remarks »ñµÃÍæ¼ÒÉý¼¶, »ñµÃµÄÊôÐ﵋  | 
| def GetLvUp_AddPoint(curPlayer):  | 
|     curPlayerID = curPlayer.GetID()  | 
|     curLV = curPlayer.GetLV() # µ±Ç°µÈ¼¶  | 
|       | 
|     addPointDict = IpyGameDataPY.GetFuncEvalCfg("LVUPAddPoint", 1, {})  | 
|     addPoint = GameWorld.GetDictValueByRangeKey(addPointDict, curLV, 0)  | 
|       | 
|     if addPoint == None:  | 
|         raise Exception('Íæ¼Ò»ñµÃÉý¼¶ÊôÐÔµãÒì³£, curLV = %s PlayerID = %s' % (curLV, curPlayerID))  | 
|         return  | 
|     return int(addPoint+ GetFabaoAddPoint(curPlayer) + GetTitleAddExtraPoint(curPlayer))  | 
|   | 
| def GetAllPointByLV(curPlayer):  | 
|     ##»ñÈ¡µ±Ç°µÈ¼¶¿ÉµÃµ½ÊôÐÔµãÊý  | 
|     openLV = GameFuncComm.GetFuncLimitLV(ShareDefine.GameFuncID_AddPoint)  | 
|     curLV = curPlayer.GetLV()  | 
|     if curLV < openLV:  | 
|         return 0  | 
|     # ³õʼµã+(Éý¼¶µã+·¨±¦Ð§¹û)*³ÆºÅЧ¹û±¶Êý+¾³½çµã  | 
|     setFreePoint = IpyGameDataPY.GetFuncCfg("LVUPAddPoint", 2)  | 
|     fabaoAddPoint = GetFabaoAddPoint(curPlayer)  | 
|     titleAddPoint = GetTitleAddExtraPoint(curPlayer)  | 
|     addPointDict = IpyGameDataPY.GetFuncEvalCfg("LVUPAddPoint", 1, {})  | 
|     for rangLVs, point in addPointDict.items():  | 
|         if curLV < rangLVs[0]:  | 
|             continue  | 
|         setFreePoint += (point + fabaoAddPoint + titleAddPoint) * (min(curLV, rangLVs[1]) - rangLVs[0] + 1)  | 
|       | 
|     #¾³½çÌáÉýµãÊý  | 
|     setFreePoint += curPlayer.GetOfficialRank() * IpyGameDataPY.GetFuncCfg("LVUPAddPoint", 3)  | 
|     return setFreePoint  | 
|   | 
| def GetTitleAddExtraPoint(curPlayer):  | 
|     # ³ÆºÅ¶îÍâÔö¼ÓÍæ¼Òÿ¼¶»ñµÃµÄÁé¸ùµã  | 
|     titleID = IpyGameDataPY.GetFuncCfg("TitleAddPoint")  | 
|     if titleID and curPlayer.GetDienstgradManager().GetDienstgrad(titleID):  | 
|         return IpyGameDataPY.GetFuncCfg("TitleAddPoint", 2)  | 
|     return 0  | 
|   | 
| def GetFabaoAddPoint(curPlayer):  | 
|     #·¨±¦¶îÍâÔö¼ÓÍæ¼Òÿ¼¶»ñµÃµÄÁé¸ùµã  | 
|     mwID = IpyGameDataPY.GetFuncCfg('FabaoAddPoint', 1)  | 
|     if not PlayerMagicWeapon.GetIsActiveMagicWeapon(curPlayer, mwID, lv=1):  | 
|         return 0  | 
|     return IpyGameDataPY.GetFuncCfg('FabaoAddPoint', 2)  | 
|   | 
| def DoAddPointOpen(curPlayer):  | 
|     '''¼Óµã¹¦ÄÜ¿ªÆô'''  | 
|     beforeFreePoint = curPlayer.GetFreePoint()  | 
|       | 
|     setFreePoint = GetAllPointByLV(curPlayer)  | 
|     curLV = curPlayer.GetLV()  | 
|     addDataDict = {'beforeFreePoint':beforeFreePoint}  | 
|     curPlayer.SetFreePoint(setFreePoint)  | 
|     DataRecordPack.DR_Freepoint(curPlayer, "AddPointOpen", setFreePoint, addDataDict)  | 
|     GameWorld.DebugLog('    ¼Óµã¹¦ÄÜ¿ªÆô´¦Àí  beforeFreePoint=%s,curLV=%s, setFreePoint=%s'%(beforeFreePoint, curLV, setFreePoint), curPlayer.GetID())  | 
|     return  | 
|   | 
|       | 
| #---------------------------------------------------------------------  | 
|   | 
| ## ¹¦ÄÜÄ£¿éÕ½¶·Á¦Àà  | 
| #  | 
| #  ·ÖÄ£¿é¼ÆËãÕ½¶·Á¦  | 
| class ModuleFightPower():  | 
|       | 
|     __AttrName = "%s" # ²ÎÊýΪChConfig.Def_Calc_AllAttrType_MAX¶ÔÓ¦ËùÓÐÊôÐÔÁбíË÷Òý  | 
|     __AttrNameNoline = "Noline_%s" # ²ÎÊýΪChConfig.Def_Calc_AllAttrType_MAX¶ÔÓ¦ËùÓÐÊôÐÔÁбíË÷Òý  | 
|     __NolineAttrList = [ChConfig.TYPE_Calc_AttrSpeed] # ÐèÒª¼Ç¼µÄ·ÇÏßÐÔÕ½¶·ÊôÐÔ  | 
|       | 
|     ## ³õʼ»¯  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks ³õʼ»¯  | 
|     def __init__(self, mfpType):  | 
|         self.mfpType = mfpType  | 
|         self.ClearAttr()  | 
|         return  | 
|               | 
|     ## ÖØÖÃËùÓÐÊôÐÔ  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     def ClearAttr(self):  | 
|         for attrIndex in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):  | 
|             value = 0  | 
|             setattr(self, self.__AttrName % attrIndex, value)  | 
|         for attrIndex in self.__NolineAttrList:  | 
|             setattr(self, self.__AttrNameNoline % attrIndex, 0)              | 
|         return  | 
|               | 
|     ## ¸ù¾ÝÕ½¶·ÊôÐÔÁбíÉèÖüÆËãÕ½¶·Á¦ÊôÐÔ  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     def SetCalcMFPBattleAttr(self, allAttrList):  | 
|         battleAttrDict = allAttrList[ChConfig.CalcAttr_Battle]  | 
|         # ÉèÖñ¾Ä£¿éÔö¼ÓµÄÏßÐÔÕ½¶·ÊôÐÔ£¬·ÇÏßÐÔÕ½¶·ÊôÐÔÔö¼ÓµÄÔÚË¢ÊôÐÔʱÀÛ¼ÓÉÏÈ¥  | 
|         for attrIndex, value in battleAttrDict.items():  | 
|             self.AddCalcMFPAttr(attrIndex, value)  | 
|               | 
|         # ·ÇÏßÐÔÕ½¶·ÊôÐÔ½öÉèÖÃʱ¼Ç¼¼´¿É  | 
|         battleNolineAttrDict = allAttrList[ChConfig.CalcAttr_BattleNoline]  | 
|         for attrIndex, value in battleNolineAttrDict.items():  | 
|             if attrIndex in self.__NolineAttrList:  | 
|                 setattr(self, self.__AttrNameNoline % attrIndex, value)  | 
|         return  | 
|       | 
|     ## ÉèÖüÆËãÕ½¶·Á¦ÊôÐÔÖµ  | 
|     def SetCalcMFPAttr(self, attrIndex, value):  | 
|         if 1 <= attrIndex < ChConfig.Def_Calc_AllAttrType_MAX:  | 
|             attrName = self.__AttrName % attrIndex  | 
|             setattr(self, attrName, value)  | 
|         return  | 
|               | 
|     ## Ôö¼Ó¼ÆËãÕ½¶·Á¦ÊôÐÔ  | 
|     #  @param self ÀàʵÀý  | 
|     #  @param key ¼ÆËãÊôÐÔÀàÐÍ  | 
|     #  @param value ¼ÆËãÊôÐÔÊýÖµ  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     def AddCalcMFPAttr(self, attrIndex, value):  | 
|         # Èç¹ûÓдæÔÚ¼ÆËãÕ½¶·Á¦ËùÐèµÄ²ÎÊýkeyÖµ£¬ÔòÔö¼ÓÉÏÈ¥  | 
|         if 1 <= attrIndex < ChConfig.Def_Calc_AllAttrType_MAX:  | 
|             attrName = self.__AttrName % attrIndex  | 
|             setattr(self, attrName, getattr(self, attrName) + value)  | 
|       | 
|     def GetModuleFightPower(self, fpParam, curPlayer):  | 
|         MaxHP = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrMaxHP) # ×î´óѪÁ¿  | 
|         MinAtk = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrATKMin) # ×îС¹¥»÷  | 
|         MaxAtk = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrATKMax) # ×î´ó¹¥»÷  | 
|         Def = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrDEF) # Îï·À  | 
|         Hit = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrHit) * fpParam.GetCftHit() # ÃüÖÐÖµ  | 
|         Miss = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrMiss) * fpParam.GetCftMiss() # ÉÁ±ÜÖµ  | 
|         AtkSpeed = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrAtkSpeed) # ¹¥»÷ËÙ¶È£¨ÊýÖµ·Ç¹¥»÷¼ä¸ô£©  | 
|         SuperHitRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_SuperHitRate) * fpParam.GetCftSuperHitRate() # ±©»÷ÂÊ  | 
|         SuperHitRateReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_SuperHitRateReduce) * fpParam.GetCftSuperHitRateReduce() # ±©»÷¸ÅÂÊ¿¹ÐÔ  | 
|         SuperHit = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_SuperHit) # ±©»÷É˺¦¹Ì¶¨Öµ  | 
|         SuperHitReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_SuperHitReduce) # ±©»÷¹Ì¶¨¼õÉË  | 
|         LuckyHitRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_LuckyHitRate) * fpParam.GetCftLuckyHitRate() # »áÐÄÒ»»÷  | 
|         LuckyHitRateReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_LuckyHitRateReduce) * fpParam.GetCftLuckyHitRateReduce() # »áÐÄÒ»»÷¸ÅÂÊ¿¹ÐÔ  | 
|         LuckyHit = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_LuckyHit) # »áÐÄÒ»»÷É˺¦¹Ì¶¨Öµ  | 
|         LuckyHitReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_LuckyHitReduce) # »áÐÄÒ»»÷É˺¦¹Ì¶¨¼õÉË  | 
|         SkillAtkRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_SkillAtkRate) * fpParam.GetCftSkillAtkRate() # ¼¼Äܹ¥»÷±ÈÀý¼Ó³É  | 
|         SkillAtkRateReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_SkillAtkRateReduce) * fpParam.GetCftSkillAtkRateReduce() # ¼¼Äܹ¥»÷±ÈÀý¼õÉÙ  | 
|         DamagePVP = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamagePVP)  # PVP¹Ì¶¨É˺¦  | 
|         DamagePVPReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamagePVPReduce)  # PVP¹Ì¶¨¼õÉË  | 
|         DamagePVE = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamagePVE)  # PVE¹Ì¶¨É˺¦  | 
|         HPRestore = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_HPRestorePer) # ×Ô¶¯»Ø¸´ÑªÁ¿£¬¹Ì¶¨Öµ  | 
|         DamBackPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamBackPer) * fpParam.GetCftDamBackPer() # ·´ÉË°Ù·Ö±È  | 
|         SpeedValue = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrSpeed) # Òƶ¯ËÙ¶ÈÖµ  | 
|         SpeedPer = 0#getattr(self, self.__AttrNameNoline % ChConfig.TYPE_Calc_AttrSpeed) * fpParam.GetCftSpeedPer() # Òƶ¯ËٶȰٷֱÈϵÊý  | 
|         PetMinAtk = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_PetMinAtk) # ³èÎï×îС¹¥»÷  | 
|         PetMaxAtk = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_PetMaxAtk) # ³èÎï×î´ó¹¥»÷  | 
|         PetDamPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_PetDamPer) # ³èÎïÉ˺¦°Ù·Ö±ÈÌáÉý  | 
|         IceAtk = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrIceAtk) # ±ù¹¥, ÔªËع¥»÷  | 
|         IceDef = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AttrIceDef) # ±ù·À, ÔªËØ·ÀÓù  | 
|         IgnoreDefRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_IgnoreDefRate) * fpParam.GetCftIgnoreDefRate() # ÎÞÊÓ·ÀÓù¼¸ÂÊ  | 
|         IgnoreDefRateReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_IgnoreDefRateReduce) * fpParam.GetCftIgnoreDefRateReduce() # ÎÞÊÓ·ÀÓù¸ÅÂÊ¿¹ÐÔ  | 
|         DamChanceDef = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamChanceDef) * fpParam.GetCftDamChanceDef() # 20%µÄ¸ÅÂʵÖÓùÉ˺¦±ÈÂÊ  | 
|         BleedDamage = 0#getattr(self, self.__AttrName % ChConfig.TYPE_Calc_BleedDamage) * fpParam.GetCftBleedDamage() # Á÷ѪÉ˺¦  | 
|         AtkBackHP = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AtkBackHPPer) # ¹¥»÷»Ø¸´ÑªÁ¿  | 
|         FaintRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FaintRate) * fpParam.GetCftFaintRate() # ´¥·¢»÷ÔÎ  | 
|         FaintDefRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FaintDefRate) * fpParam.GetCftFaintDefRate() # »÷Ôεֿ¹  | 
|         FinalHurt = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FinalHurt) # ×îÖչ̶¨É˺¦Ôö¼Ó  | 
|         FinalHurtReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FinalHurtReduce) # ×îÖչ̶¨É˺¦¼õÉÙ  | 
|         FinalHurtPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FinalHurtPer) * fpParam.GetCftFinalHurtPer() # ×îÖÕÉ˺¦Íò·ÖÂÊ  | 
|         FinalHurtReducePer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FinalHurtReducePer) * fpParam.GetCftFinalHurtReducePer() # ×îÖÕÉ˺¦¼õÉÙÍò·ÖÂÊ  | 
|         DamagePerPVP = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamagePerPVP) * fpParam.GetCftDamagePerPVP() # É˺¦Êä³ö¼ÆËã°Ù·Ö±ÈPVP  | 
|         DamagePerPVPReduce = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_DamagePerPVPReduce) * fpParam.GetCftDamagePerPVPReduce() # É˺¦Êä³ö¼ÆËã°Ù·Ö±ÈPVP¼õÉÙ  | 
|         JobAHurtAddPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_JobAHurtAddPer) * fpParam.GetCftJobAHurtAddPer() # ¶ÔÄ¿±êսʿÉ˺¦¼Ó³É  | 
|         JobBHurtAddPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_JobBHurtAddPer) * fpParam.GetCftJobBHurtAddPer() # ¶ÔÄ¿±ê·¨Ê¦É˺¦¼Ó³É  | 
|         JobCHurtAddPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_JobCHurtAddPer) * fpParam.GetCftJobCHurtAddPer() # ¶ÔÄ¿±ê¹¼ýÉ˺¦¼Ó³É  | 
|         JobAAtkReducePer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_JobAAtkReducePer) * fpParam.GetCftJobAAtkReducePer() # Õ½Ê¿¹¥»÷É˺¦¼õÃâ  | 
|         JobBAtkReducePer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_JobBAtkReducePer) * fpParam.GetCftJobBAtkReducePer() # ·¨Ê¦¹¥»÷É˺¦¼õÃâ  | 
|         JobCAtkReducePer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_JobCAtkReducePer) * fpParam.GetCftJobCAtkReducePer() # ¹¼ý¹¥»÷É˺¦¼õÃâ  | 
|         AffairSpeedPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_AffairSpeedPer) * fpParam.GetCftAffairSpeedPer() # ÏÉÃËÊÂÎñËÙ¶È¼Ó³É  | 
|         FamilyBossHurtPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FamilyBossHurtPer) * fpParam.GetCftFamilyBossHurtPer() # ÏÉÃËBOSSÉ˺¦¼Ó³É  | 
|         FamilyWarHPPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FamilyWarHPPer) * fpParam.GetCftFamilyWarHPPer() # ÏÉÃËÁªÈüÉúÃü¼Ó³É  | 
|         FamilyWarAtkPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FamilyWarAtkPer) * fpParam.GetCftFamilyWarAtkPer() # ÏÉÃËÁªÈü¹¥»÷¼Ó³É  | 
|         FamilySitExpPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FamilySitExpPer) * fpParam.GetCftFamilySitExpPer() # ÏÉÃË´ò×ø¾Ñé¼Ó³É  | 
|           | 
|         NormalHurt = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_NormalHurt)   | 
|         NormalHurtPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_NormalHurtPer) * fpParam.GetCftNormalHurtPer() # ÆÕͨ¸½¼ÓÉ˺¦¼Ó³É  | 
|         FabaoHurt = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FabaoHurt)  | 
|         FabaoHurtPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_FabaoHurtPer) * fpParam.GetCftFabaoHurtPer() # ·¨±¦¸½¼ÓÉ˺¦¼Ó³É  | 
|         Luck = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_Luck)  | 
|           | 
|         ComboRate = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_ComboRate) # Á¬»÷¼¸ÂÊ  | 
|         ComboDamPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_ComboDamPer) # Á¬»÷É˺¦  | 
|         #MaxProDef = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_MaxProDef) # ×î´ó·À»¤Öµ  | 
|         #ProDefAbsorb = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_ProDefAbsorb) # ·À»¤ÖµÎüÊÕÉ˺¦±ÈÂÊ  | 
|         ProDefPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_ProDefHPPer) # ·À»¤×ª»¯°Ù·Ö±È  | 
|           | 
|         OnlyFinalHurt = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_OnlyFinalHurt) # ¶îÍâÊä³öÉ˺¦  | 
|         PVPAtkBackHP = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_PVPAtkBackHP) # PVP¹¥»÷»ØÑª  | 
|         NPCHurtAddPer = getattr(self, self.__AttrName % ChConfig.TYPE_Calc_NPCHurtAddPer) * fpParam.GetCftNPCHurtAddPer() # ¶Ô¹ÖÎïÉ˺¦¼Ó³É  | 
|           | 
|         #ÆäËûÐè×÷Ϊ¹«Ê½²ÎÊýµÄϵÊý  | 
|         AtkSpeedParameter = fpParam.GetCftAtkSpeed()  | 
|         LuckyHitParameter = 0#fpParam.GetCftLuckyHit()  | 
|           | 
|         #È¡×ÜÊôÐ﵀  | 
|         SuperHitRateTotal = curPlayer.GetSuperHitRate()  | 
|         LuckyHitRateTotal = curPlayer.GetLuckyHitRate()  | 
|           | 
|         job = curPlayer.GetJob()  | 
|         diffAttrDict = self.__GetAttrFightPowerParamDiff(job)  | 
|         for paramName, diffValue in diffAttrDict.items():  | 
|             exec("%s = max(0, %s - %s)" % (paramName, paramName, diffValue))  | 
|               | 
|         #»ñÈ¡²ß»®ÅäÖõıí¸ñ  | 
|         FightpowerFormula = IpyGameDataPY.GetFuncCfg("FightpowerFormula")  | 
|         totalFightPower = eval(FormulaControl.GetCompileFormula("FightpowerFormula", FightpowerFormula))  | 
|           | 
|         #GameWorld.DebugLog("MfpType=%s,FightPower=%s, %s" % (self.mfpType, totalFightPower, self.GetMFPAttrStr()))  | 
|         if totalFightPower > ShareDefine.Def_UpperLimit_DWord:  | 
|             GameWorld.ErrLog("Ä£¿éÕ½Á¦³¬¹ýÊýÖµÉÏÏÞ, MfpType=%s,fightPower=%s, %s" % (self.mfpType, totalFightPower, self.GetMFPAttrStr()))  | 
|             totalFightPower = ShareDefine.Def_UpperLimit_DWord  | 
|         return totalFightPower  | 
|           | 
|     def __GetAttrFightPowerParamDiff(self, job):  | 
|         ## Õ½Á¦¼ÆËãÊôÐÔ²ÎÊýÓëʵ¼ÊÊôÐÔ²îÖµ  | 
|           | 
|         #½ÇÉ«»ù´¡Ä£¿éijЩÊôÐÔ²»¼ÆËãÕ½Á¦  | 
|         if self.mfpType != ShareDefine.Def_MFPType_Role:  | 
|             return {}  | 
|           | 
|         roleBaseAttrDict = IpyGameDataPY.GetFuncEvalCfg("CreatRoleBaseAttr", 1)  | 
|         notFightPowerEffIDNameDict = IpyGameDataPY.GetFuncEvalCfg("CreatRoleBaseAttr", 2)  | 
|         if job not in roleBaseAttrDict:  | 
|             return {}  | 
|           | 
|         diffAttrDict = {}  | 
|         jobBaseAttrDict = roleBaseAttrDict[job]  | 
|         for attrID, paramName in notFightPowerEffIDNameDict.items():  | 
|             if attrID not in jobBaseAttrDict:  | 
|                 continue  | 
|             diffAttrDict[paramName] = jobBaseAttrDict[attrID]  | 
|         return diffAttrDict  | 
|       | 
|     def GetMFPAttrStr(self):  | 
|         attrStr = ""  | 
|         for attrIndex in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):  | 
|             attrName = self.__AttrName % attrIndex  | 
|             attrValue = getattr(self, attrName)  | 
|             if attrValue <= 0:  | 
|                 continue  | 
|               | 
|             attrStr += "%s=%s," % (attrName, attrValue)  | 
|               | 
|         for attrIndex in self.__NolineAttrList:  | 
|             attrName = self.__AttrNameNoline % attrIndex  | 
|             attrValue = getattr(self, attrName)  | 
|             if attrValue <= 0:  | 
|                 continue  | 
|               | 
|             attrStr += "%s=%s," % (attrName, attrValue)  | 
|         return attrStr  | 
|   | 
| ###############################################################  | 
| #ÈËÎï¿ØÖÆÀà  | 
|   | 
| ## ÈËÎï¿ØÖÆÀà  | 
| #  | 
| #  ÈËÎïËÀÍöµÈÂß¼´¦Àí  | 
| class PlayerControl:  | 
|     __Player = None  | 
|     __fpTypeObjDict = {}  | 
|     #---------------------------------------------------------------------  | 
|     ## ³õʼ»¯  | 
|     #  @param self ÀàʵÀý  | 
|     #  @param iPlayer Íæ¼ÒʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks ³õʼ»¯  | 
|     def __init__(self, iPlayer):  | 
|         self.__Player = iPlayer  | 
|       | 
|     ## »ñȡģ¿éÕ½¶·Á¦¶ÔÏó  | 
|     #  @param self ÀàʵÀý  | 
|     #  @param fpType Õ½¶·Á¦ÀàÐÍ  | 
|     #  @return ·µ»ØÕ½¶·Á¦¶ÔÏó  | 
|     def GetModuleFightPowerObj(self, fpType):  | 
|         fpObj = self.__fpTypeObjDict.get(fpType)  | 
|         if not fpObj:  | 
|             fpObj = ModuleFightPower(fpType)  | 
|             self.__fpTypeObjDict[fpType] = fpObj  | 
|         return fpObj  | 
|       | 
|     ## »ñȡģ¿éÕ½¶·Á¦¶ÔÏó  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÕ½¶·Á¦¶ÔÏó  | 
|     def ResetFightPowerObj(self):  | 
|         for obj in self.__fpTypeObjDict.values():  | 
|             obj.ClearAttr()  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     ## Íæ¼ÒÉý¼¶¼Óµã¼Ó¼¼Äܠǰ20¼¶×Ô¶¯¼Óµã 20¼¶ºó ÒÔǰÊǼӼ¼ÄܵãÏָijÉÖ±½ÓÉý¼¶ºó¶Á±í¼Ó¼¼ÄÜ  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return None  | 
|     #  @remarks Íæ¼ÒÉý¼¶ ¼Óµã 2010-05-26 adawsÐ޸ĠÔÀ´ÓмӼ¼Äܵã ÏÖ½«Éý¼¶¼Ó¼¼ÄÜÌá³ö   | 
|     def __DoLVUPAddPoint(self):  | 
|         curPlayer = self.__Player  | 
|         if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_AddPoint):  | 
|             # Î´¿ªÆôǰ²»¿É¼Óµã£¬ÒòΪDoAddPointOpen»áÒ»´ÎÐÔ²¹Æë£¬±ÜÃâÒâÍâÇé¿ö¶à¼ÓÁ˵ãÊý  | 
|             return  | 
|   | 
|         curFreePoint = curPlayer.GetFreePoint()  | 
|         addPoint = GetLvUp_AddPoint(curPlayer)  | 
|         if addPoint != 0:  | 
|             setFreePoint = curFreePoint + addPoint  | 
|             #NotifyCode(curPlayer, "ObtainAttributeDot", [addPoint])  | 
|               | 
|             DataRecordPack.DR_Freepoint(curPlayer, "LvUP", addPoint)  | 
|             curPlayer.SetFreePoint(setFreePoint)  | 
|   | 
|         return  | 
|     #---------------------------------------------------------------------  | 
|     ## ¼ì²éÍæ¼ÒÊÇ·ñÐèÒª·â¾ô  | 
|     #  @param self ÀàʵÀý  | 
|     #  @param curPlayer Íæ¼ÒʵÀý  | 
|     #  @param curLV µ±Ç°µÈ¼¶  | 
|     #  @return ·µ»ØÖµÕæ, ÐèÒª  | 
|     #  @remarks ¼ì²éÍæ¼ÒÊÇ·ñÐèÒª·â¾ô  | 
|     def __LVUpDoInvestiture(self, curPlayer, curLV):  | 
| #===============================================================================  | 
| #        ´ËÂß¼²»ÄÜÓàGetTotalExp,   | 
| #        ¸Ä¶¯ÇëÉ÷ÖØ!  | 
| #===============================================================================  | 
|         #1. ¼ì²éÍæ¼ÒÊÇ·ñÔÚ·â¾ôµÈ¼¶  | 
|         if curLV < 20 or curLV % 10 != 0:  | 
|             return False  | 
|           | 
|         curMission = curPlayer.FindMission(curLV * 100)  | 
|         if curMission != None and curMission.GetState() == ChConfig.Def_Mission_State_Over:  | 
|             #ÈÎÎñÍê³É  | 
|             return False  | 
|               | 
|         if curMission == None:  | 
|             #2. Èç¹ûÔÚ·â¾ôµÈ¼¶, ²¢ÇÒ¼´½«Éýµ½ÏÂÒ»¼¶, ´¥·¢·â¾ôÈÎÎñ  | 
|             if EventShell.EventResponse_LVFull(curPlayer) != True:  | 
|                 GameWorld.Log("´¥·¢·â¾ôÈÎÎñʧ°Ü", curPlayer.GetPlayerID())  | 
|                 return False  | 
|               | 
|         return True  | 
|       | 
|     #---------------------------------------------------------------------  | 
|       | 
|     ## ¼Ó¾ÑéÖµ   | 
|     #  @param self ÀàʵÀý  | 
|     #  @param addExp Ìí¼ÓµÄ¾Ñé  | 
|     #  @param exp_rate ¾Ñé±¶ÂÊ  | 
|     #  @param expViewType ¾Ñé»ñµÃµÄÇþµÀ  | 
|     #  @param isSysHint ÊÇ·ñϵͳÌáʾ£¨Ä¬ÈÏÊÇ£©  | 
|     #  @return ²¼¶ûÖµ  | 
|     def AddExp(self, addExp, expViewType=ShareDefine.Def_ViewExpType_Mission, isSysHint=True, addSkillID=0, expRateEx=0):  | 
|         curPlayer = self.__Player  | 
|         finalAddExp, expNotifyType = self.__AddExp(curPlayer, addExp, expViewType, isSysHint, addSkillID, expRateEx)  | 
|           | 
|         # Í¨Öª¿Í»§¶Ë¾ÑéÀ´Ô´  | 
|         if finalAddExp:  | 
|             sendPack = ChPyNetSendPack.tagMCAddExp()  | 
|             sendPack.ExpPoint = finalAddExp / ChConfig.Def_PerPointValue  | 
|             sendPack.Exp = finalAddExp % ChConfig.Def_PerPointValue  | 
|             sendPack.Source = expNotifyType # ¿Í»§¶ËչʾÓà  | 
|             NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|               | 
|         #¸±±¾»ñµÃ¾Ñé, ÎÞÂÛ»ñµÃ¶àÉÙ¾Ñé¾ùÐè֪ͨ, ÓÐЩ¸±±¾Âß¼ÐèҪͨ¹ý»ñµÃ¾Ñéʱ»ú´¦Àí  | 
|         if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|             FBLogic.OnGetExp(curPlayer, finalAddExp, expViewType)  | 
|               | 
|         return finalAddExp  | 
|       | 
|     # ²ÎÊý addSkillID ±íʾÒòʲô¼¼ÄÜɱËÀNPC»ñµÃ¾Ñé  | 
|     def __AddExp(self, curPlayer, addExp, expViewType, isSysHint, addSkillID=0, expRateEx=0):  | 
|         if addExp == 0:  | 
|             # ²»½øÈë¼ÆËã  | 
|             return addExp, expViewType  | 
|           | 
|         #È¡µÃÈËÎﵱǰ¾Ñé  | 
|         #curTotalExp = GetPlayerTotalExp(curPlayer)  | 
|         curTotalExp = curPlayer.GetExpPoint() * ChConfig.Def_PerPointValue + curPlayer.GetTotalExp()  | 
|   | 
|         maxLV = IpyGameDataPY.GetFuncCfg("PlayerMaxLV", 1)  | 
|         maxLVExpStore = IpyGameDataPY.GetFuncCfg("MaxLVExpStore", 1)  | 
|           | 
|         curLV = curPlayer.GetLV()              | 
| #        # ¼ì²éתÉúµÈ¼¶  | 
| #        if curLV >= nextReinLV and curTotalExp >= maxLVExpStore:  | 
| #            self.__NotifyExpFull(curPlayer, "GeRen_liubo_260986")  | 
| #            GameWorld.DebugLog("¾ÑéÒÑÂú£¡ÐèÏÈתÉú£¡curLV=%s,reinLV=%s" % (curLV, nextReinLV), curPlayer.GetPlayerID())  | 
| #            return 0  | 
|   | 
|         # ¼ì²é×î´óµÈ¼¶  | 
|         if curLV >= maxLV and curTotalExp >= maxLVExpStore:  | 
|             self.__NotifyExpFull(curPlayer, "GeRen_admin_825676")  | 
|             #GameWorld.DebugLog("¾ÑéÒÑÂú£¡ÒÑÂú¼¶£¡curLV=%s" % (curLV), curPlayer.GetPlayerID())  | 
|             return 0, expViewType  | 
|           | 
|         # É±¹Ö  | 
|         if expViewType == ShareDefine.Def_ViewExpType_KillNPC:  | 
|             exp_rate = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)  | 
|             superRate = PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(curPlayer, None, None, ChConfig.TriggerType_AddExpRate)  | 
|             if superRate:  | 
|                 # Áú·ïïí ¾Ñé  | 
|                 expViewType = ShareDefine.Def_ViewExpType_KillNPCSuper  | 
|             if addSkillID == ChConfig.Def_SkillID_LXHY_AddExpRate:  | 
|                 addSkill = GameWorld.GetGameData().GetSkillBySkillID(addSkillID)  | 
|                 hasEffect = SkillCommon.GetSkillEffectByEffectID(addSkill, ChConfig.Def_Skill_Effect_AddExpRate)  | 
|                 if hasEffect:  | 
|                     #ÁÒÑæÕ½Éñ ¾Ñé  | 
|                     superRate += hasEffect.GetEffectValue(0)  | 
|                     expViewType = ShareDefine.Def_ViewExpType_LYZS  | 
|             exp_rate += superRate  | 
|                   | 
|         elif expViewType in [ShareDefine.Def_ViewExpType_GameEvent, ShareDefine.Def_ViewExpType_Sit]:  | 
|             exp_rate = curPlayer.GetGameEventExpRate()  | 
|             exp_rate += GetFamilySitExpPer(curPlayer)  | 
|             exp_rate += expRateEx  | 
|         else:  | 
|             exp_rate = max(GameWorld.GetGameWorld().GetExpRate(), ChConfig.Def_MaxRateValue)  | 
|               | 
|         #ÊäÈëµÄ¾ÑéÓпÉÄÜΪlongÐÍ  | 
|         addExp = int(addExp * exp_rate / float(ChConfig.Def_MaxRateValue))  | 
|           | 
|         #·À³ÁÃÔ¼ÆËã  | 
|         addExp = PlayerGameWallow.ChangeExpByWallow(curPlayer, addExp)  | 
|           | 
|         #===========================================================================================  | 
|         # #ÌØÊâµØÍ¼É±¹Ö¾ÑéÍâ²ã¼Ó³É  | 
|         # if expViewType == ShareDefine.Def_ViewExpType_KillNPC:  | 
|         #    #mapID = GameWorld.GetMap().GetMapID()  | 
|         #    #if mapID in ChConfig.Def_FBMapID_BZZDAll:  | 
|         #    #    nobleVIPOuterRate = ...  | 
|         #    #    #nobleVIPAddExp += 0 if not nobleVIPOuterRate else int(addExp * nobleVIPOuterRate / float(ChConfig.Def_MaxRateValue))  | 
|         #    #    nobleVIPAddExp += nobleVIPOuterRate  | 
|         #      | 
|         #    outerExpRate = FBLogic.OnGetOuterExpRate(curPlayer)  | 
|         #    if outerExpRate > 0:  | 
|         #        addExp = int(addExp * outerExpRate / float(ChConfig.Def_MaxRateValue))  | 
|         #===========================================================================================  | 
|           | 
|         # ²»¿ÉÔÙÉý¼¶Ê±£¬Ôö¼ÓºóµÄ¾Ñé²»¿É³¬¹ý×î´ó¿É´æ´¢¾Ñé  | 
|         #if curLV >= nextReinLV or curLV >= maxLV:  | 
|         if curLV >= maxLV:  | 
|             addExp = min(addExp, max(0, maxLVExpStore - curTotalExp))  | 
|   | 
|         if addExp <= 0:  | 
|             #ÎÞ·¨»ñµÃ¾Ñé  | 
|             GameWorld.DebugLog("ÎÞ·¨»ñµÃ¾Ñé")  | 
|             return 0, expViewType  | 
|           | 
|         #addExp = min(addExp, ChConfig.Def_UpperLimit_DWord) # µ¥´Î¼Ó¾Ñé²»³¬¹ý20ÒÚ  | 
|   | 
|         #»º´æ»ñÈ¡µÄ¾ÑéÖµ, ÓÃÓÚ¶Ò»»¼Ò×åÈÙÓþ  | 
|         #if curPlayer.GetFamilyID() != 0:  | 
|         #    curPlayer.SetPerExp(min(curPlayer.GetPerExp() + addExp, ChConfig.Def_UpperLimit_DWord))  | 
|   | 
|         #ÈËÎïÍ·¶¥Ìáʾ  | 
|         #=======================================================================  | 
|         # viewExpCnt = min(2, addExp / ChConfig.Def_UpperLimit_DWord) # ×î¶àÆ®Á½´Î20ÒÚµÄ  | 
|         # viewExp = addExp % ChConfig.Def_UpperLimit_DWord  | 
|         # for _ in range(viewExpCnt):  | 
|         #    curPlayer.Notify_GetExpView(ChConfig.Def_UpperLimit_DWord, expViewType)  | 
|         # if viewExp:  | 
|         #    curPlayer.Notify_GetExpView(viewExp, expViewType)  | 
|         #   | 
|         # if isSysHint:  | 
|         #    # É±¹Ö¸½¼Ó¼Ó³ÉÏÔʾ  | 
|         #    if expViewType == ShareDefine.Def_ViewExpType_KillNPC:  | 
|         #        nobleVIPAddExp = int(nobleVIPAddExp / 100.0)  | 
|         #        #NotifyCode(curPlayer, "GeRen_liubo_74717", [addExp, nobleVIPAddExp])  | 
|         #    elif expViewType in [ShareDefine.Def_ViewExpType_GameEvent,  | 
|         #                         ShareDefine.Def_ViewExpType_Sit]:  | 
|         #        #СÓÎϷʼþÌØÊâÌáʾ,´ò×ø»ñÈ¡¾Ñé  | 
|         #        NotifyCode(curPlayer, "ObtainExperience", [addExp])  | 
|         #    elif expViewType == ShareDefine.Def_ViewExpType_MousePos:  | 
|         #        #Êó±êλÖÃÌáʾ»ñµÃ¾Ñé  | 
|         #        NotifyCode(curPlayer, "GeRen_admin_887936", [addExp])  | 
|         #    else:  | 
|         #        #Õý³£ÐÅÏ¢Ìáʾ  | 
|         #        NotifyCode(curPlayer, "GeRen_lhs_0", [addExp])  | 
|         #=======================================================================  | 
|                   | 
|         #¸øÈËÎï¾Ñé ÏÈÉè¾ÑéºóÉý¼¶  | 
|         #SetPlayerTotalExp(curPlayer, curTotalExp + addExp)  | 
|         totalExp = curTotalExp + addExp  | 
|         curExp = totalExp % ChConfig.Def_PerPointValue  | 
|         expPoint = totalExp / ChConfig.Def_PerPointValue  | 
|           | 
|         if curPlayer.GetExpPoint() != expPoint:  | 
|             curPlayer.SetExpPoint(expPoint)  | 
|         if curPlayer.GetTotalExp() != curExp:  | 
|             curPlayer.SetTotalExp(curExp)  | 
|           | 
|         #GameWorld.Log("Íæ¼Ò = %s µÃµ½¾Ñé = %s ,µ±Ç°¾Ñé±¶ÂÊ = %s"%(curPlayer.GetName(), addExp,expRate ))  | 
|         #СÓÚתÉúµÈ¼¶²Å¿ÉÉý¼¶  | 
|         #if curLV < nextReinLV and curLV < maxLV:  | 
|         if curLV < maxLV:  | 
|             self.PlayerLvUp()  | 
|           | 
|         #Ìí¼Ó¾Ñé³É¹¦  | 
|         return addExp, expViewType  | 
|       | 
|     ## ¾ÑéÂúÌáʾ  | 
|     def __NotifyExpFull(self, curPlayer, expFullNotifyMark):  | 
|         expFullNotifyState = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ExpFullNotify)  | 
|         if not expFullNotifyState:  | 
|             NotifyCode(curPlayer, expFullNotifyMark)  | 
|             curPlayer.SetDict(ChConfig.Def_PlayerKey_ExpFullNotify, 1)  | 
|         return  | 
|       | 
|     ## ÈËÎïÉý¼¶ »ØÂúѪ »ØÂúħ£¬´¥·¢Ìí¼Ó¼¼ÄÜ£¬ÈÎÎñ£¬¼ÓÊôÐԵ㣨ÔÀ´²¿·Öº¯Êý²Ù×÷·ÅÔÚ¼Ó¾ÑéÖРÏÖÔÚÌá³öÀ´£©  | 
|     #  @param handLvUp: ÊÇ·ñÊÇÊÖ¶¯Éý¼¶  | 
|     #  @return: None  | 
|     #  @remarks: Èç¹ûÊÇ×Ô¶¯Éý¼¶²»¸ø²ÎÊý ¶øÈç¹ûÊÇÊÖ¶¯Éý¼¶ÐèÒª¸ø²ÎÊý ÊÇÊÖ¶¯Éý¼¶ True   | 
|     #  1-20¼¶×Ô¶¯Éý¼¶Ö±½Ó¼Óµã Ö®ºó±ØÐëÊÖ¶¯Éý¼¶ ¸ø×ÔÓÉÊôÐ﵋  | 
|     def PlayerLvUp(self, handLvUp=False):  | 
|         curPlayer = self.__Player  | 
|           | 
|         if GameObj.GetHP(curPlayer) <= 0:  | 
|             #Íæ¼ÒËÀÍö²»¿ÉÉý¼¶  | 
|             return  | 
|           | 
|         #lvIpyData = GetPlayerLVIpyData(curPlayer.GetLV())  | 
|         lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", curPlayer.GetLV())  | 
|         if not lvIpyData:  | 
|             GameWorld.ErrLog("¾Ñé±íÒì³£  lv= %s" % curPlayer.GetLV())  | 
|             return  | 
|           | 
|         #lvUpNeedExp = GetLVUPTotalExpNeed(lvIpyData)  | 
|         lvUpNeedExp = lvIpyData.GetExpPoint() * ChConfig.Def_PerPointValue + lvIpyData.GetExp()  | 
|           | 
|         if lvUpNeedExp <= 0:  | 
|             return  | 
|           | 
|         #Ôö¼Ó¾Ñé  | 
|         #curTotalExp = GetPlayerTotalExp(curPlayer)  | 
|         curTotalExp = curPlayer.GetExpPoint() * ChConfig.Def_PerPointValue + curPlayer.GetTotalExp()  | 
|         #δ´ïµ½Éý¼¶¾Ñé  | 
|         if curTotalExp < lvUpNeedExp:  | 
|             return  | 
|         needSyncTalentPoint = False  | 
|         playerNeedDoLVUp = False  | 
|         curLV = curPlayer.GetLV()  | 
|         maxLV = IpyGameDataPY.GetFuncCfg("PlayerMaxLV", 1)  | 
|           | 
|         curPlayer.BeginRefreshState()  | 
|         #befXP = curPlayer.GetXP()  | 
|         befLV = curPlayer.GetLV()  | 
|         befFreePoint = curPlayer.GetFreePoint()  | 
|         befBaseSTR = curPlayer.GetBaseSTR()  | 
|         befBasePNE = curPlayer.GetBasePNE()  | 
|         befBasePHY = curPlayer.GetBasePHY()  | 
|         befBaseCON = curPlayer.GetBaseCON()  | 
|           | 
|         #Éý¼¶Ç°µÄÊÀ½çµÈ¼¶¾Ñé  | 
|         #beforeExpRate = PlayerWorldAverageLv.GetWorldAverageLvExpRate(curPlayer)  | 
|           | 
|         while curTotalExp >= lvUpNeedExp and curLV < maxLV:  | 
|               | 
|             playerNeedDoLVUp = True  | 
|               | 
|             #---ÈËÎïÉý¼¶³É¹¦---  | 
|             curLV = curLV + 1  | 
|               | 
|             isNotifyServer = True  | 
|             if curLV < 50:  | 
|                 # ¼õÉÙǰÆÚµÄ¹ã²¥£¬³ÌÐò¿ØÖÆ  | 
|                 isNotifyServer = False  | 
|               | 
|             curPlayer.SetLV(curLV, isNotifyServer)  | 
|             EventReport.WriteEvent_level_up(curPlayer)  | 
|                          | 
|             # ¼ÇÂ¼Íæ¼ÒÉý¼¶  | 
|             DataRecordPack.DR_PlayerUpgrade(curPlayer, curPlayer.GetLV(), GetPlayerTotalExp(curPlayer), lvUpNeedExp)  | 
|             DataRecordPack.Cache_FightPowerChangeInfo(curPlayer, ChConfig.PowerDownType_LVUP, {'lv':curLV})  | 
|             self.__GiveLVMailAward(curLV)  | 
|             self.__DoLVUPAddPoint()  # Éý¼¶¼Óµã  | 
|             #self.__DoLvUpAddSkill()  # Éý¼¶¼Ó¼¼ÄÜ  | 
|               | 
|             lvIpyData = GetPlayerLVIpyData(curPlayer.GetLV())  | 
|             # ´óʦÌ츳µã  | 
|             if lvIpyData:  | 
|                 addTalentPoint = lvIpyData.GetTalentPoint()  | 
|                 if addTalentPoint:  | 
|                     needSyncTalentPoint = True  | 
|                     PlayerGreatMaster.AddGreatMasterSkillPointByLV(curPlayer, addTalentPoint)  | 
|               | 
|             EventShell.EventResponse_LVUp(curPlayer)  # Éý¼¶´¥·¢Ê¼þ  | 
|               | 
|             PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_LVUp, 1)  | 
|             #---ÊÇ·ñ¼ÌÐøÑ»·---  | 
|             curTotalExp = curTotalExp - lvUpNeedExp  | 
|               | 
|             #»ñµÃÏÂÒ»¼¶µÄ¾Ñé±í  | 
|             lvUpNeedExp = GetLVUPTotalExpNeed(lvIpyData)  | 
|               | 
|             if lvUpNeedExp <= 0:  | 
|                 break  | 
|               | 
|         curPlayer.EndRefreshState() # ½áÊøË¢Ðºó£¬Óбä¸üµÄÊôÐÔҪ֪ͨ¿Í»§¶ËµÄÐèÖØÐÂÉèÖÃÒ»´Î  | 
|         #---------------------------------------------------  | 
|         #ÓÐÉý¼¶, ×ªÉúʱ¸ÕºÃÊÇתÉúµÈ¼¶»áĬÈÏ+1¼¶  | 
|         if playerNeedDoLVUp:  | 
|             aftLV = curPlayer.GetLV()  | 
|             aftFreePoint = curPlayer.GetFreePoint()  | 
|             aftBaseSTR = curPlayer.GetBaseSTR()  | 
|             aftBasePNE = curPlayer.GetBasePNE()  | 
|             aftBasePHY = curPlayer.GetBasePHY()  | 
|             aftBaseCON = curPlayer.GetBaseCON()  | 
|             if aftLV > befLV:  | 
|                 curPlayer.SetLV(aftLV, False) # ÕâÀï²»ÔÙ֪ͨGameServer  | 
|                 PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_HeroLV, aftLV)  | 
|                 PlayerActivity.DoAddActivityByLV(curPlayer, befLV, aftLV)  | 
|                   | 
|             if aftFreePoint > befFreePoint:  | 
|                 curPlayer.SetFreePoint(aftFreePoint)  | 
|                 #NotifyCode(curPlayer, "ObtainAttributeDot", [aftFreePoint - befFreePoint])  | 
|             if aftBaseSTR > befBaseSTR:  | 
|                 curPlayer.SetBaseSTR(aftBaseSTR)  | 
|             if aftBasePNE > befBasePNE:  | 
|                 curPlayer.SetBasePNE(aftBasePNE)  | 
|             if aftBasePHY > befBasePHY:  | 
|                 curPlayer.SetBasePHY(aftBasePHY)  | 
|             if aftBaseCON > befBaseCON:  | 
|                 curPlayer.SetBaseCON(aftBaseCON)  | 
|             #===================================================================  | 
|             # if curPlayer.GetXP() != befXP:  | 
|             #    curPlayer.SetXP(curPlayer.GetXP())  | 
|             #===================================================================  | 
|                   | 
|             #ÏíÊÜÊÀ½çµÈ¼¶  | 
|             #===================================================================  | 
|             #curExpRate = PlayerWorldAverageLv.GetWorldAverageLvExpRate(curPlayer)  | 
|             #if beforeExpRate <= 0 and curExpRate > 0:  | 
|             #    NotifyCode(curPlayer, "GeRen_liubo_127574")  | 
|               | 
|             #===================================================================  | 
|             # Ì츳µã֪ͨ  | 
|             if needSyncTalentPoint:  | 
|                 PlayerGreatMaster.Sync_GreatMasterFreeSkillPoint(curPlayer)  | 
|             # Éý¼¶ÐèÒªÖ´ÐеÄÓÎÏ·¹¦ÄÜ´¦Àí  | 
|             GameFuncComm.DoFuncOpenLogic(curPlayer)  | 
|             ChEquip.RefreshPlayerLingQiEquipAttr(curPlayer) # ÁéÆ÷ÊôÐÔ»áËæµÈ¼¶³É³¤  | 
|             if aftLV%10 == 0:  | 
|                 # ¿ØÖÆÏÂˢдÎÊý  | 
|                 PlayerPet.CalcPetItemAddPlayerAttr(curPlayer)   # ³èÎïÓÐËæµÈ¼¶±ä»¯µÄ¼¼ÄÜ  | 
|               | 
|             self.RefreshPlayerAttrState(billboardFunc=PlayerBillboard.UpdatePlayerLVBillboard)  | 
|             #·ÅÔÚ¹¦ÄÜ¿ªÆôºóÃæ  | 
|             PlayerWorldAverageLv.UpdatePlayerWorldAverageLv(curPlayer)  | 
|             #½«ÑªÉèÖÃΪ×î´ó  | 
|             GameObj.SetHPFull(curPlayer)  | 
|             if curPlayer.GetMaxMP() > 0:  | 
|                 curPlayer.SetMP(curPlayer.GetMaxMP())  | 
|               | 
|             FBLogic.OnPlayerLVUp(curPlayer)  | 
|             # ¼Ç¼¿ª·þ»î¶¯³å¼¶Êý¾Ý  | 
|             #OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_LV, curPlayer.GetLV())  | 
|             #ÉñÃØÏÞ¹º  | 
|             FunctionNPCCommon.MysticalLimitShopOpen(curPlayer, befLV, aftLV)  | 
|   | 
|         #²»ÐèÒª×öÉý¼¶ÈÎÎñ, ÉèÖÃÍæ¼Ò¾Ñé  | 
|         SetPlayerTotalExp(curPlayer, curTotalExp)   | 
|         return  | 
|       | 
|     def __GiveLVMailAward(self, curLV):  | 
|         # ¸øµÈ¼¶Óʼþ½±Àø  | 
|         mailLVAwardDict = IpyGameDataPY.GetFuncEvalCfg("MailLVAward", 1, {})  | 
|         if curLV not in mailLVAwardDict:  | 
|             return  | 
|         mailTypeKey, mailItemList = mailLVAwardDict[curLV]  | 
|         curPlayer = self.__Player  | 
|         SendMailByKey(mailTypeKey, [curPlayer.GetPlayerID()], mailItemList, [curLV])  | 
|         return  | 
|       | 
|     #---------------------------------------------------------------------  | 
|   | 
|     def CalcRoleBaseAttr(self, curPlayer):  | 
|         # ¼ÆËãÍæ¼Ò½ÇÉ«»ù´¡ÊôÐÔÖµ  | 
|           | 
|         curPlayerID = curPlayer.GetID()  | 
|         job = curPlayer.GetJob()  | 
|           | 
|         lvAttrDict = IpyGameDataPY.GetFuncEvalCfg("LVUPAttr%s" % job, 1)  | 
|           | 
|         if not lvAttrDict:  | 
|             GameWorld.ErrLog('ÎÞ´ËÖ°ÒµµÈ¼¶Ë¢ÊôÐÔÅäÖÃ!job=%s' % (job), curPlayerID)  | 
|             return  | 
|           | 
|         allAttrList = [{} for _ in range(4)]  | 
|           | 
|         # Ö°Òµ³õʼÊôÐÔ  | 
|         roleBaseAttrDict = IpyGameDataPY.GetFuncEvalCfg("CreatRoleBaseAttr", 1)  | 
|         if job in roleBaseAttrDict:  | 
|             for roleBaseAttrID, value in roleBaseAttrDict[job].items():  | 
|                 CalcAttrDict_Type(roleBaseAttrID, value, allAttrList)  | 
|         #GameWorld.DebugLog("³õʼ¼ÓÊôÐÔ: %s" % allAttrList)  | 
|                   | 
|         # µÈ¼¶³É³¤ÊôÐÔ  | 
|         LV = curPlayer.GetLV()  | 
|         for lvAttrID, formula in lvAttrDict.items():  | 
|             calcValue = eval(FormulaControl.GetCompileFormula("LVUPAttr%s_%s" % (job, lvAttrID), formula))  | 
|             CalcAttrDict_Type(lvAttrID, calcValue, allAttrList)  | 
|             #GameWorld.DebugLog("    lvAttrID=%s,calcValue=%s" % (lvAttrID, calcValue))  | 
|         #GameWorld.DebugLog("µÈ¼¶¼ÓÊôÐÔ: %s" % allAttrList)  | 
|           | 
|         # ÊôÐÔµãÊôÐÔ  | 
|         hadRefreshAttr = curPlayer.GetDictByKey(ChConfig.Def_Player_HadRefreshAttr) # ±¾µØÍ¼ÊÇ·ñˢйýÊôÐÔ  | 
|         pointFightPowerEx = 0  | 
|         pointValueInfo = {ShareDefine.Def_Effect_Metal:[lambda curObj:GetMetal(curObj), lambda curObj, value:SetMetalQualityLV(curObj, value), lambda curObj:GetMetalQualityLV(curObj)],  | 
|                           ShareDefine.Def_Effect_Wood:[lambda curObj:GetWood(curObj), lambda curObj, value:SetWoodQualityLV(curObj, value), lambda curObj:GetWoodQualityLV(curObj)],  | 
|                           ShareDefine.Def_Effect_Water:[lambda curObj:GetWater(curObj), lambda curObj, value:SetWaterQualityLV(curObj, value), lambda curObj:GetWaterQualityLV(curObj)],  | 
|                           ShareDefine.Def_Effect_Fire:[lambda curObj:GetFire(curObj), lambda curObj, value:SetFireQualityLV(curObj, value), lambda curObj:GetFireQualityLV(curObj)],  | 
|                           ShareDefine.Def_Effect_Earth:[lambda curObj:GetEarth(curObj), lambda curObj, value:SetEarthQualityLV(curObj, value), lambda curObj:GetEarthQualityLV(curObj)],  | 
|                           }  | 
|         hasChange_Qualitylv = False #Áé¸ùÆ·¼¶ÊÇ·ñÓбä¸ü  | 
|         lingGenQualityAttrList = [{} for _ in range(4)]  | 
|         for pointAttrID, pointFuncInfo in pointValueInfo.items():  | 
|             pointValue = pointFuncInfo[0](curPlayer)  | 
|             befPQLV = pointFuncInfo[2](curPlayer)  | 
|             pointFuncInfo[1](curPlayer, 0)  | 
|             if not pointValue:  | 
|                 if 0 != befPQLV:  | 
|                     hasChange_Qualitylv = True  | 
|                 continue  | 
|             ipyData = IpyGameDataPY.GetIpyGameData("RolePoint", pointAttrID)  | 
|             if not ipyData:  | 
|                 continue  | 
|             # Ã¿µãÊôÐÔ  | 
|             perPointAddAttrDict = ipyData.GetAddAttrInfoPerPoint() # {"Ö°Òµ":[[ÿXµã,ÊôÐÔID,Öµ], ...], ..}  | 
|             addAttrList = perPointAddAttrDict.get(str(job), [])  | 
|             for needPoint, pointAddAttrID, pointAddAttrValue in addAttrList:  | 
|                 pointAddValueTotal = pointAddAttrValue * (pointValue / needPoint)  | 
|                 CalcAttrDict_Type(pointAddAttrID, pointAddValueTotal, allAttrList)  | 
|                 #GameWorld.DebugLog("    ÊôÐÔµã(%s)¼ÓÊôÐÔ: pointValue=%s,pointAddAttrID=%s,pointAddValueTotal=%s" % (pointAttrID, pointValue, pointAddAttrID, pointAddValueTotal))  | 
|                   | 
|             pointFightPowerEx += (ipyData.GetFightPowerPerPoint() * pointValue)  | 
|               | 
|             # µãÊýÆ·ÖÊÊôÐÔ  | 
|             curPQLV = 0  | 
|             pqIntervalList = ipyData.GetPointQualityIntervalList()  | 
|             for pqLV, pqValue in enumerate(pqIntervalList, 1): # Áé¸ùÆ·¼¶´Ó1¿ªÊ¼  | 
|                 if pointValue >= pqValue:  | 
|                     curPQLV = pqLV  | 
|                 else:  | 
|                     break  | 
|             pointFuncInfo[1](curPlayer, curPQLV)  | 
|             if curPQLV != befPQLV:  | 
|                 hasChange_Qualitylv = True  | 
|             if not curPQLV:  | 
|                 continue  | 
|             pqAttrInfoDict = ipyData.GetPointQualityAttrDict().get(str(curPlayer.GetJob()), {})  | 
|             for pqAttrID, pqAttrValueList in pqAttrInfoDict.items():  | 
|                 pqAttrValue = 0 if curPQLV > len(pqAttrValueList) else pqAttrValueList[curPQLV - 1]  | 
|                 CalcAttrDict_Type(int(pqAttrID), pqAttrValue, lingGenQualityAttrList)  | 
|             #GameWorld.DebugLog("        ÊôÐÔµã(%s)Æ·½×µÈ¼¶ÊôÐÔ: befPQLV=%s,curPQLV=%s,pqAttrInfoDict=%s" % (pointAttrID, befPQLV, curPQLV, pqAttrInfoDict))  | 
|             if hadRefreshAttr and befPQLV < curPQLV:  | 
|                 for pqlv in xrange(befPQLV+1, curPQLV+1):  | 
|                     EventShell.EventRespons_LingGenQualityUP(curPlayer, pointAttrID, pqlv)  | 
|                   | 
|         #GameWorld.DebugLog("µÈ¼¶ÊôÐÔµã¼ÓÊôÐÔ: %s" % allAttrList)  | 
|         #GameWorld.DebugLog("Áé¸ùÆ·½×µÈ¼¶ÊôÐÔ: %s" % lingGenQualityAttrList)  | 
|         #GameWorld.DebugLog("Áé¸ùµãÊý¸½¼ÓÕ½Á¦: %s" % pointFightPowerEx)  | 
|         curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_Role, pointFightPowerEx)   | 
|         SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_RoleBase, allAttrList)  | 
|         SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_LingGenQuailty, lingGenQualityAttrList)  | 
|         return hasChange_Qualitylv  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     def NotifyAllState(self, playerStateDict):  | 
|         curPlayer = self.__Player  | 
|         notifySelfList = []  | 
|         notifyAllList = []  | 
|         notifyAllAttrState = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_NotifyAllAttrState)  | 
|           | 
|         #ÔÚ´Ë´¦°ÑËùÓÐÊôÐԵIJ»Í¬Í¨Öª¸ø¿Í»§¶Ë  | 
|         for index, value in playerStateDict.items():  | 
|               | 
|             curPlayerState, attrType, notifySelf, notifyAll = EffGetSet.GetValueByEffIndexEx(curPlayer, index)  | 
|               | 
|             if not attrType:  | 
|                 continue  | 
|               | 
|             if notifyAllAttrState and curPlayerState == value:  | 
|                 #GameWorld.Log("µÚ%d¸ö£¬ÔÖµ%dµÈÓÚÏÖÖµ%d£¬²»·¢¸ø¿Í»§¶Ë"%( index, value, curPlayerState ) )  | 
|                 continue  | 
|             notifyStruct = ChPyNetSendPack.tagRefreshType()  | 
|             notifyStruct.RefreshType = attrType  | 
|             if attrType in [IPY_PlayerDefine.CDBPlayerRefresh_HP, IPY_PlayerDefine.CDBPlayerRefresh_MaxHP]:  | 
|                 notifyStruct.Value = curPlayerState % ShareDefine.Def_PerPointValue  | 
|                 notifyStruct.ValueEx = curPlayerState / ShareDefine.Def_PerPointValue  | 
|             else:  | 
|                 notifyStruct.Value = curPlayerState                 | 
|             if notifySelf:  | 
|                 notifySelfList.append(notifyStruct)  | 
|             if notifyAll:  | 
|                 notifyAllList.append(notifyStruct)  | 
|           | 
|         #ÊôÐÔ×éºÏ°ü  | 
|         #֪ͨ×Ô¼º  | 
|         if notifySelfList:  | 
|             sendPack = ChPyNetSendPack.tagObjInfoListRefresh()  | 
|             sendPack.Clear()  | 
|             sendPack.ObjID = curPlayer.GetID()  | 
|             sendPack.ObjType = curPlayer.GetGameObjType()  | 
|             sendPack.Count = len(notifySelfList)  | 
|             sendPack.RefreshType = notifySelfList  | 
|             NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|               | 
|         if len(notifyAllList) != 0:  | 
|             #¹ã²¥ÖÜÎ§Íæ¼Ò  | 
|             sendPack = ChPyNetSendPack.tagObjInfoListRefresh()  | 
|             sendPack.Clear()  | 
|             sendPack.ObjID = curPlayer.GetID()  | 
|             sendPack.ObjType = curPlayer.GetGameObjType()  | 
|             sendPack.Count = len(notifyAllList)  | 
|             sendPack.RefreshType = notifyAllList  | 
|             PyNotifyAll(curPlayer, sendPack, False, -1)  | 
|               | 
|         if not notifyAllAttrState:  | 
|             curPlayer.SetDict(ChConfig.Def_PlayerKey_NotifyAllAttrState, 1)  | 
|         return  | 
|       | 
|     ## Ë¢ÐÂÍæ¼ÒËùÓÐ״̬  | 
|     #  @param self ÀàʵÀý  | 
|     #  @param isForce ÊÇ·ñÇ¿ÖÆË¢Ð  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Ë¢ÐÂÍæ¼ÒËùÓÐ״̬  | 
|     def RefreshAllState(self, isSyncBuff=False, billboardFunc=None, isForce=False):  | 
|         GameWorld.DebugLog("Start RefreshAllState!!!")  | 
|           | 
|         self.RefreshPlayerActionState()  | 
|         self.RefreshPlayerAttrState(billboardFunc, isForce)  | 
|         return  | 
|       | 
|       | 
|     ## ÖؼÆË㲢ˢÐÂÍæ¼ÒËùÓÐ״̬, Ä¿Ç°Ö»ÓÃÓëÇл»µØÍ¼  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Ë¢ÐÂÍæ¼ÒËùÓÐ״̬  | 
|     def ReCalcAllState(self):  | 
|         GameWorld.DebugLog("Start ReCalcAllState!!!")  | 
|         curPlayer = self.__Player  | 
|           | 
|         for funcIndex in ChConfig.CalcAttrFuncList:  | 
|             ClearCalcAttrListValue(curPlayer, funcIndex)  | 
|               | 
|         #ÏÈѹÈëBUFFµÄЧ¹ûÖµ¼°¼¼ÄÜÕ½¶·Á¦  | 
|         self.RefreshAllSkill()  | 
|         ChEquip.RefreshPlayerEquipAttribute(curPlayer)  | 
|         ChEquip.RefreshPlayerLingQiEquipAttr(curPlayer)  | 
|         #SkillShell.RefreshPlayerBuffOnAttrAddEffect(curPlayer)  | 
|         PlayerHorse.CalcHorseAttrEx(curPlayer)  | 
|         PlayerPrestigeSys.CalcOfficialRankAttr(curPlayer)  | 
|         PlayerGodWeapon.CalcGodWeaponAttr(curPlayer)  | 
|         PlayerDienstgrad.CalcAllDienstgradAttr(curPlayer)  | 
|         PlayerPet.CalcPetItemAddPlayerAttr(curPlayer)  | 
|         PlayerRune.RefreshRuneAttr(curPlayer)  | 
|         PlayerMagicWeapon.CalcMagicWeaponAttr(curPlayer)  | 
|         PlayerSuccess.CalcSuccessAttr(curPlayer)  | 
|         PlayerVip.CalcVIPAttr(curPlayer)  | 
|         PlayerRefineStove.CalcStoveAttr(curPlayer)  | 
|         PlayerFamilyTech.CalcFamilyTechAttr(curPlayer)  | 
|         PlayerEquipDecompose.RefreshEDAttr(curPlayer)  | 
|         PlayerDogz.RefreshDogzAttr(curPlayer)  | 
|         PlayerGatherSoul.RefreshGatherSoulAttr(curPlayer)  | 
|         PlayerCoat.CalcClothesCoatSkinAttr(curPlayer)  | 
|         PlayerFaQi.CalcFaQiAttr(curPlayer)  | 
|         PlayerLove.CalcLoveAttr(curPlayer)  | 
|         PlayerCharm.CalcCharmAttr(curPlayer)  | 
|         PlayerLianTi.CalcLianTiAttr(curPlayer)  | 
|         PlayerShentong.CalcShentongAttr(curPlayer)  | 
|         PlayerFamilyZhenfa.CalcZhenfaAttr(curPlayer)  | 
|         self.RefreshAllState(isForce=True)  | 
|         GameWorld.DebugLog("End ReCalcAllState!!!")  | 
|         return  | 
|       | 
|       | 
|     # BUFF²ãµ¥¶ÀË¢ÐÂÊôÐÔ£¬¹¦ÄÜÊôÐÔÈ¡»º´æ---------------------------------------------  | 
|     def RefreshPlayerAttrByBuff(self, isForce=False):  | 
|         curPlayer = self.__Player  | 
|         curPlayer.SetDict(ChConfig.Def_Player_RefreshAttrByBuff, 1)  | 
|           | 
|         if isForce:  | 
|             self.RefreshPlayerAttrByBuffEx()  | 
|         return True  | 
|       | 
|     # BUFF²ãµ¥¶ÀË¢ÐÂÊôÐÔ  | 
|     def RefreshPlayerAttrByBuffEx(self):  | 
|           | 
|         curPlayer = self.__Player  | 
|         if curPlayer.GetDictByKey(ChConfig.Def_Player_RefreshAttrByBuff) != 1:  | 
|             return  | 
|           | 
|         GameWorld.DebugLog("Start RefreshPlayerAttrByBuffEx!!!")  | 
|         beforeMaxHP = GameObj.GetMaxHP(curPlayer)  | 
|         beforeMoveSpeedValue = GetSpeedValue(curPlayer)  | 
|         #¹¹½¨Íæ¼ÒË¢ÐÂ֪ͨ¿Í»§¶Ë×Öµä, »º´æ[Ë÷Òý, ÊýÖµ]  | 
|         playerStateDict = {}  | 
|         for index in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):  | 
|             playerStateDict.update({index:EffGetSet.GetValueByEffIndex(curPlayer, index)})  | 
|         #GameWorld.DebugLog("Ë¢ÊôÐÔǰ=%s" % playerStateDict)  | 
|         #self.PrintAttr(curPlayer, "ˢ֮ǰ")  | 
|         #---------------------------¿ªÊ¼¼ÆËã-------------------------------------  | 
|         curPlayer.BeginRefreshState()  | 
|         # »Ö¸´¹¦ÄÜÊýÖµ  ²»Äܵ÷Óú¯Êýself.InitPlayerState()  | 
|         EffGetSet.RestorePlayerFuncAttr(curPlayer)  | 
|           | 
|         # 6.¼ÆËãbuffÊôÐÔ, buff²ã¼¶µÄ²»ËãÈçÕ½¶·Á¦  | 
|         self.__RefreshBuffAttr()  | 
|           | 
|         # 7.Ë¢ÍêÊôÐÔºóÐèÒª´¦ÀíµÄÂß¼  | 
|         self.__DoRefreshAttrAfterLogic(beforeMaxHP, beforeMoveSpeedValue, playerStateDict)  | 
|           | 
|         curPlayer.SetDict(ChConfig.Def_Player_RefreshAttrByBuff, 0)  | 
|         GameWorld.DebugLog("End RefreshPlayerAttrByBuffEx!!!")  | 
|         return  | 
|       | 
|       | 
|     #===========================================================================  | 
|     # #×°±¸ºÍBUFF Ð§¹ûµÄ¼ÆËãÒÆµ½Íâ²ã  | 
|     # #RefreshPlayerBuffOnAttrAddEffect  | 
|     # #RefreshPlayerEquipAttribute(curPlayer)  | 
|     #===========================================================================  | 
|     ## Ë¢ÐÂÍæ¼ÒÊôÐÔµ÷Óô˺¯Êý£¬Á¢¼´Ë¢Ð¸ÄΪ֪ͨˢУ¬ÓÉProcessStatueͳһˢÐÂÒ»´Î  | 
|     ## ÅÅÐаñÀàµÄË¢ÐÂisForceÐèҪΪTrue  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     def RefreshPlayerAttrState(self, billboardFunc=None, isForce=False):  | 
|         curPlayer = self.__Player  | 
|         curPlayer.SetDict(ChConfig.Def_Player_RefreshAttr, 1)  | 
|               | 
|         if billboardFunc and billboardFunc not in PyGameData.g_refreshAttrBillboardFunc:  | 
|             PyGameData.g_refreshAttrBillboardFunc.append(billboardFunc)  | 
|               | 
|         if isForce:  | 
|             self.RefreshPlayerAttrStateEx()  | 
|               | 
|         return  | 
|       | 
|     def PrintAttr(self, curPlayer, mark):  | 
|         attrInfo = ""  | 
|         for index in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):  | 
|             value = EffGetSet.GetValueByEffIndex(curPlayer, index)  | 
|             if value:  | 
|                 attrInfo = "%s,%s=%s" % (attrInfo, index, value)  | 
|         GameWorld.DebugLog("%s AttrInfo=%s" % (mark, attrInfo))  | 
|         return  | 
|       | 
|     def RefreshPlayerAttrStateEx(self):  | 
|         ''' ±¾ÏîĿˢÊôÐÔ¹æÔò  | 
|                     ÊôÐÔ£º  | 
|             1.¹Ì¶¨ÊôÐÔ£ºÈç¹¥»÷+100  | 
|             2.°Ù·Ö±ÈÊôÐÔ£º Èç¹¥»÷+5%£¬°Ù·Ö±È¼Ó³É»ùÖµ½öΪ¹Ì¶¨ÊôÐÔ£¬°Ù·Ö±È¼Ó³ÉÊôÐÔÖµ²»±»³ýbuff°Ù·Ö±ÈÍâµÄÈκΰٷֱÈÊôÐÔ¶þ´Î¼Ó³É  | 
|               | 
|                     ²ã¼¶£º  | 
|             1.ÊôÐԲ㼶£ºËùÓй¦ÄÜͬһ²ã¼¶  | 
|             2.buff²ã¼¶£º°Ù·Ö±È¿É¶Ô¹¦ÄܰٷֱȼӳɵÄÊôÐÔ½øÐжþ´Î¼Ó³É  | 
|               | 
|                     ¹¦ÄÜÄ£¿é£º¶¨ÒåÒ»¸ö¹¦ÄÜ£¬±ÈÈçÁé¸ùÄ£¿é£¬Ò»¸öÄ£¿é¿ÉÄܰüº¬¶à¸ö¹¦ÄÜµã  | 
|                     ¹¦Äܵ㣺ij¸öÄ£¿éϵĸ÷¸öÊôÐÔ¹¦Äܵ㣬ÈçÁé¸ùÄ£¿é¿ÉÄܰüº¬ Áé¸ù»ù´¡¡¢Áé¸ùÆ·ÖÊ Á½¸ö¹¦ÄܵãÊôÐÔ  | 
|           | 
|                     °Ù·Ö±È¼Ó³ÉÖµ£º°Ù·Ö±È¼Ó³ÉÊôÐÔÖµ²»±»³ýbuff°Ù·Ö±ÈÍâµÄÈκΰٷֱÈÊôÐÔ2´Î¼Ó³É  | 
|             1.¹¦ÄÜÄÚ²¿ÊôÐ԰ٷֱȼӳɣº¹¦ÄܰٷֱÈÊôÐÔ¶Ô×Ô¼º¹¦Ä̶ܹ¨Öµ¼Ó³É  | 
|             2.¹¦Äܽ»²æÊôÐ԰ٷֱȼӳɣº¹¦ÄܰٷֱÈÊôÐÔ¶ÔÆäËû¹¦Ä̶ܹ¨Öµ¼Ó³É  | 
|             3.¹¦Ä̶ܹ¨ÊôÐ԰ٷֱȼӳɣº¹¦ÄܰٷֱÈÊôÐÔ¶ÔËùÓй¦Ä̶ܹ¨Öµ¼Ó³É  | 
|             4.buff²ã¼¶°Ù·Ö±È£º¶ÔËùÓÐÊôÐÔ½øÐжþ´Î¼Ó³É  | 
|               | 
|                     ¼¼ÄÜÊôÐÔ£º¹Ì¶¨Öµ²»ÏíÊ̶ܹ¨°Ù·Ö±È¼Ó³É  | 
|                       | 
|         buff²ã¼¶£º  | 
|             1.²»ËãÕ½Á¦  | 
|             2.ÏÈËã°Ù·Ö±È¼Ó³ÉÔټӹ̶¨Öµ  | 
|               | 
|                     ÊôÐÔËã·¨£º  | 
|                        Ä£¿é¹Ì¶¨ÊôÐÔ    = ¹¦ÄܵãA¹Ì¶¨Öµ + ¹¦ÄܵãB¹Ì¶¨Öµ + ...  | 
|                         ¹Ì¶¨×ÜÊôÐÔ        = Ä£¿éA¹Ì¶¨Öµ + Ä£¿éB¹Ì¶¨Öµ + ...  | 
|                         ÎÞbuff×ÜÊôÐÔ  = ¹Ì¶¨×ÜÊôÐÔ + ÄÚ²¿°Ù·Ö±È¼Ó³ÉÖµ + ½»²æ°Ù·Ö±È¼Ó³É  + ¹Ì¶¨×ÜÊôÐ԰ٷֱȼӳɠ  + ¼¼ÄܰٷֱȶԹ̶¨ÊôÐԼӳɠ + ¼¼Ä̶ܹ¨Öµ  | 
|                         º¬buff×ÜÊôÐÔ  = ÎÞbuff×ÜÊôÐÔ * buff°Ù·Ö±È¼Ó³É  +  buff¹Ì¶¨Öµ  | 
|         '''  | 
|         curPlayer = self.__Player  | 
|           | 
|         if curPlayer.GetDictByKey(ChConfig.Def_Player_RefreshAttr) != 1:  | 
|             return False  | 
|           | 
|         PlayerGubao.CalcGubaoAttr(curPlayer) # ¹Å±¦¶¨Î»Îª¶Ô¹áͨËùÓÐÓÎÏ·¹¦ÄÜϵͳµÄÊôÐÔÍæ·¨£¬ËùÒÔÿ´Î¶¼ÖØÐÂˢР | 
|           | 
|         GameWorld.DebugLog("Start RefreshPlayerAttrStateEx!!!")  | 
|           | 
|         #beforeAtkInterval = curPlayer.GetAtkInterval()  | 
|         beforeMaxHP = GameObj.GetMaxHP(curPlayer)  | 
|         beforeMoveSpeedValue = GetSpeedValue(curPlayer)  | 
|         beforeMaxProDef = GetMaxProDef(curPlayer)  | 
|         #[½ðľˮ»ðÍÁ]  | 
|         beforePointList = [GetMetal(curPlayer), GetWood(curPlayer), GetWater(curPlayer), GetFire(curPlayer), GetEarth(curPlayer)]  | 
|         #¹¹½¨Íæ¼ÒË¢ÐÂ֪ͨ¿Í»§¶Ë×Öµä, »º´æ[Ë÷Òý, ÊýÖµ]  | 
|         playerStateDict = {}  | 
|         for index in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):  | 
|             playerStateDict.update({index:EffGetSet.GetValueByEffIndex(curPlayer, index)})  | 
|         #GameWorld.DebugLog("Ë¢ÊôÐÔǰ=%s" % playerStateDict)  | 
|         #self.PrintAttr(curPlayer, "ˢ֮ǰ")  | 
|         #---------------------------¿ªÊ¼¼ÆËã-------------------------------------  | 
|         curPlayer.BeginRefreshState()  | 
|         self.ResetFightPowerObj()  | 
|         #self.PrintAttr(curPlayer, "ÖØÖúó")  | 
|         notAttrList = [{} for _ in range(4)]  | 
|           | 
|         # 1.³õʼ»¯ÈËÎï¸÷Ïî״̬¼°ÊôÐÔ  | 
|         self.InitPlayerState()  | 
|         #self.PrintAttr(curPlayer, "³õʼ»¯")  | 
|           | 
|         # ¹¦ÄÜÊôÐԲ㼶һ...  | 
|         # 2.¼ÆËã»ù´¡ÊôÐÔ  | 
|         #    2.1 »ñÈ¡ËùÓй¦ÄܼÆËãµã¼ÆËãµÄÊôÐÔÖµ, Í³¼Æ»ù´¡ÊôÐÔÀÛ¼Ó  | 
|         baseAttrDict = {}  | 
|         baseAttrNolineDict = {}  | 
|         funcAttrLen = len(ChConfig.CalcAttrFuncList)  | 
|         funcAttrInfoList = [[{} for _ in range(4)]] * funcAttrLen  | 
|         funcInsidePerAttrList = [{}] * funcAttrLen # ¹¦ÄÜÄÚ²¿°Ù·Ö±È¸½¼ÓÊôÐÔ  | 
|         for funcIndex in ChConfig.CalcAttrFuncList:  | 
|             # »ù´¡ÊôÐԵȹ¦ÄÜ»ã×ÜÍêºóͳһˢУ¬ÒòΪ¸÷¹¦ÄÜ¿ÉÄÜ»á¼ÓÊôÐÔµãÊý  | 
|             if funcIndex in [ChConfig.Def_CalcAttrFunc_RoleBase, ChConfig.Def_CalcAttrFunc_LingGenQuailty]:  | 
|                 continue  | 
|             attrInfo, insidePerAttrDict = GetCalcAttrListValue(curPlayer, funcIndex)[:2]  | 
|             if attrInfo == notAttrList and not insidePerAttrDict:  | 
|                 continue  | 
|             GameWorld.DebugLog("¹¦ÄܵãÊôÐÔ: %s(%s), %s, ÄÚ²ã°Ù·Ö±È¸½¼Ó: %s" % (funcIndex, ChConfig.FuncIndexName.get(funcIndex, ""), attrInfo, insidePerAttrDict))  | 
|             funcAttrInfoList[funcIndex] = attrInfo  | 
|             funcInsidePerAttrList[funcIndex] = insidePerAttrDict  | 
|             # ²»Í¬¹¦Äܵã¼äµÄÊýÖµÀÛ¼Ó£¬ÐèʹÓÃÖ§³ÖË¥¼õµÝÔöµÄ¼ÆË㷽ʽ  | 
|             AddAttrDictValue(baseAttrDict, attrInfo[ChConfig.CalcAttr_Base])  | 
|             AddAttrDictValue(baseAttrNolineDict, attrInfo[ChConfig.CalcAttr_BaseNoline])  | 
|               | 
|         #    2.2 ½«»ù´¡ÊôÐÔÀÛ¼Óµ½Íæ¼ÒÉíÉÏ  | 
|         if baseAttrDict or baseAttrNolineDict:  | 
|             # ÒòΪ»ù´¡ÊôÐÔ»áÓ°ÏìÕ½¶·ÊôÐÔ¼ÆË㣬ËùÒÔÏÈͳ¼ÆÔö¼Ó»ù´¡ÊôÐÔ  | 
|             GameWorld.DebugLog("¹¦Äܸ½¼Óµã: baseAttrDict=%s,baseAttrNolineDict=%s" % (baseAttrDict, baseAttrNolineDict))  | 
|             CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, baseAttrDict)  | 
|             CalcNoLineEffect.ChangePlayerAttrInNoLineEffectList(curPlayer, baseAttrNolineDict)  | 
|               | 
|         # ¹¦ÄÜÓмӻù´¡ÊôÐÔÖµ£¬ÕâÀïÔÙÖØÐÂË¢ÐÂһϻù´¡ÊôÐÔ, »ù´¡ÊôÐÔ»áÓ°ÏìÕ½¶·ÊôÐÔ, Ã¿´Î¶¼Ë¢Ð½ÇÉ«»ù´¡ÊôÐÔ  | 
|         hasChange_Qualitylv = self.CalcRoleBaseAttr(curPlayer)  | 
|         roleBaseAttrInfo, roleInsidePerAttrDict = GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_RoleBase)[:2]  | 
|         lingGenQualityAttrList, lingGenQualityInsidePerAttrDict = GetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_LingGenQuailty)[:2]  | 
|         funcAttrInfoList[ChConfig.Def_CalcAttrFunc_RoleBase] = roleBaseAttrInfo  | 
|         funcInsidePerAttrList[ChConfig.Def_CalcAttrFunc_RoleBase] = roleInsidePerAttrDict  | 
|         funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LingGenQuailty] =  lingGenQualityAttrList  | 
|         funcInsidePerAttrList[ChConfig.Def_CalcAttrFunc_LingGenQuailty] =  lingGenQualityInsidePerAttrDict  | 
|         GameWorld.DebugLog("¹¦ÄܵãÊôÐÔ: %s(%s), %s, ÄÚ²ã°Ù·Ö±È¸½¼Ó: %s"   | 
|                            % (ChConfig.Def_CalcAttrFunc_RoleBase, ChConfig.FuncIndexName.get(ChConfig.Def_CalcAttrFunc_RoleBase, ""), roleBaseAttrInfo, roleInsidePerAttrDict))  | 
|         GameWorld.DebugLog("¹¦ÄܵãÊôÐÔ: %s(%s), %s, ÄÚ²ã°Ù·Ö±È¸½¼Ó: %s"   | 
|                            % (ChConfig.Def_CalcAttrFunc_LingGenQuailty, ChConfig.FuncIndexName.get(ChConfig.Def_CalcAttrFunc_LingGenQuailty, ""), lingGenQualityAttrList, lingGenQualityInsidePerAttrDict))  | 
|           | 
|         #self.PrintAttr(curPlayer, "»ù´¡ºó")  | 
|           | 
|         # 3.¼ÆËãÕ½¶·ÊôÐÔ  | 
|         #    3.1 Õ½¶·ÊôÐԲ㼶½»²æÓ°Ïì»ùÖµÊýÖµ»ã×Ü  | 
|         #        »ù´¡²ã¼¶(½ÇÉ«»ù´¡ÊôÐÔ)  | 
|         baseAttrList = AddAttrListValue([funcAttrInfoList[ChConfig.Def_CalcAttrFunc_RoleBase],  | 
|                                          funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LingGen],  | 
|                                          funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LingGenQuailty],  | 
|                                          ])  | 
|         #GameWorld.DebugLog("»ù´¡²ã¼¶: %s" % baseAttrList)  | 
|           | 
|         #        ¹¦Äܵ㽻²æÓ°Ïì·ÇÏßÐÔ²ã¶ÔÓ¦ÊôÐÔ»ùÖµÁÐ±í  | 
|         funcAttrPerInfo = {ChConfig.TYPE_Calc_BaseAtkAddPer:baseAttrList,  | 
|                            ChConfig.TYPE_Calc_BaseMaxHPAddPer:baseAttrList,  | 
|                            ChConfig.TYPE_Calc_BaseDefAddPer:baseAttrList,  | 
|                            ChConfig.TYPE_Calc_BaseHitAddPer:baseAttrList,  | 
|                            ChConfig.TYPE_Calc_BaseMissAddPer:baseAttrList,  | 
|                            ChConfig.TYPE_Calc_GodWeaponMaxHPPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_GodWeapon],  | 
|                            ChConfig.TYPE_Calc_GodWeaponAtkPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_GodWeapon],  | 
|                            ChConfig.TYPE_Calc_StoneMaxHPPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Stone],  | 
|                            ChConfig.TYPE_Calc_StoneAtkPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Stone],  | 
|                            ChConfig.TYPE_Calc_StoneBasePer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Stone],  | 
|                            ChConfig.TYPE_Calc_RealmBasePer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Prestige],  | 
|                            ChConfig.TYPE_Calc_HorseAtkPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Horse],  | 
|                            ChConfig.TYPE_Calc_HorseMaxHPPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Horse],  | 
|                            ChConfig.TYPE_Calc_HorseTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_HorseTarin],  | 
|                            ChConfig.TYPE_Calc_PetTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_PetTarin],  | 
|                            ChConfig.TYPE_Calc_GuardTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_GuardTarin],  | 
|                            ChConfig.TYPE_Calc_WingTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_WingTarin],  | 
|                            ChConfig.TYPE_Calc_PeerlessWeaponTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_PeerlessWeaponTrain],  | 
|                            ChConfig.TYPE_Calc_PeerlessWeapon2TrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_PeerlessWeapon2Train],  | 
|                            ChConfig.TYPE_Calc_LianTiAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LianTi],  | 
|                            }  | 
|         #    3.2 Í³¼Æ¸÷¹¦ÄÜÖ®¼ä·ÇÏßÐÔÊôÐÔ½»²æÓ°ÏìÀÛ¼Ó  | 
|         funcCrossAttrPerInfoDict = {} # °Ù·Ö±È½»²æÓ°ÏìËùÌáÉýµÄÊôÐÔÖµ {¹¦ÄÜÊôÐÔ±àºÅ:{ÌáÉýµÄÊôÐÔÀàÐÍ:ÊýÖµ, ...}, ...}  | 
|         for i, funcAttrList in enumerate(funcAttrInfoList):  | 
|             battleNoLineAttrDict = funcAttrList[ChConfig.CalcAttr_BattleNoline] # ÔÝдËÀֻȡս¶··ÇÏßÐ﵀  | 
|             if not battleNoLineAttrDict:  | 
|                 continue  | 
|             addAttrDict = {}  | 
|             #GameWorld.DebugLog("½»²æ¹¦Äܵã: i=%s,%s" % (i,battleNoLineAttrDict))  | 
|             for noLineAttrType, addAttrPer in battleNoLineAttrDict.items():  | 
|                 if noLineAttrType not in funcAttrPerInfo or noLineAttrType not in ChConfig.FuncNoLinearAttrDict:  | 
|                     continue  | 
|                 # Ê¹ÓõĻùֵĿ±ê¹¦ÄÜË÷Òý  | 
|                 attrRate = addAttrPer / float(ChConfig.Def_MaxRateValue)  | 
|                 addAttrTypeList = ChConfig.FuncNoLinearAttrDict[noLineAttrType]  | 
|                 useAttrDict = funcAttrPerInfo[noLineAttrType][ChConfig.CalcAttr_Battle] # Ä¬ÈÏÔö¼ÓµÄÊÇÕ½¶·ÏßÐÔ  | 
|                 for attrType in addAttrTypeList:  | 
|                     # Ä¬ÈÏÌáÉýµÄÊôÐÔÔÚÏßÐÔÕ½¶·ÊôÐÔÀï  | 
|                     if attrType not in useAttrDict:  | 
|                         continue  | 
|                     baseValue = useAttrDict[attrType] # Ö»ÊÇÓõ½Ä¿±ê¹¦ÄܵĻùÖµ  | 
|                     addValue = int(baseValue * attrRate)  | 
|                     addAttrDict[attrType] = addAttrDict.get(attrType, 0) + addValue  | 
|                     #GameWorld.DebugLog("    attrID=%s,per=%s,rate=%s,baseValue=%s,attrType=%s,addValue=%s" % (noLineAttrType, addAttrPer, attrRate, baseValue, attrType, addValue))  | 
|                       | 
|             if addAttrDict:  | 
|                 # Ôö¼ÓµÄÊýֵͳ¼Æµ½°Ù·Ö±ÈÊôÐÔËùÊô¹¦ÄÜµã  | 
|                 # Èç·ûÎÄÓиöÎäÆ÷¹¥»÷°Ù·Ö±ÈÔö¼ÓÊôÐÔ£¬Ôö¼ÓµÄÊýÖµÊôÓÚ·ûÎŦÄÜ£¬²»ÊôÓÚÎäÆ÷¹¦ÄܵãµÄ£¬Ö»ÊÇ»ùֵʹÓÃÁËÎäÆ÷¹¥»÷       | 
|                 funcCrossAttrPerInfoDict[i] = addAttrDict # Ïȶ¼Í³¼ÆÍêºóÔÙÀÛ¼Óµ½¶ÔÓ¦¹¦ÄÜÊôÐÔÀ²»È»¿ÉÄܻᵼÖ¹¦ÄÜ»ùÖµ±ä¸ü  | 
|                   | 
|         GameWorld.DebugLog("½»²æÓ°ÏìÊôÐÔ: %s" % funcCrossAttrPerInfoDict)  | 
|           | 
|         #    3.3 Í³¼ÆËùÓй¦Ä̶ܹ¨ÊôÐÔÓ°ÏìÀÛ¼Ó  | 
|         allFixAttrDict = {} # ¹Ì¶¨ÊôÐԲ㼶×ÜÊôÐÔ»ùÖµ  | 
|         for funcIndex, funcAttrList in enumerate(funcAttrInfoList):  | 
|             # ¼¼ÄÜÄ£¿é²»¼ÆÈ빦Ä̶ܹ¨ÊôÐÔ¡¢²»¼ÆÕ½Á¦  | 
|             if funcIndex in ChConfig.CalcAttrFuncSkillList:  | 
|                 continue  | 
|             AddAttrDictValue(allFixAttrDict, funcAttrList[ChConfig.CalcAttr_Battle])  | 
|               | 
|         fixAttrPerAddExDict = {} # ¹Ì¶¨×ÜÊôÐÔ°Ù·Ö±ÈÓ°ÏìËùÌáÉýµÄÊôÐÔÖµ {¹¦ÄÜÊôÐÔ±àºÅ:{ÌáÉýµÄÊôÐÔÀàÐÍ:ÊýÖµ, ...}, ...}  | 
|         for funcIndex, funcAttrList in enumerate(funcAttrInfoList):  | 
|             fixAddPerDict = funcAttrList[ChConfig.CalcAttr_BattleNoline]  | 
|             if not fixAddPerDict:  | 
|                 continue  | 
|             addValueExDict = {}  | 
|             for fixAttrType, addPer in fixAddPerDict.items():  | 
|                 if fixAttrType not in allFixAttrDict:  | 
|                     continue  | 
|                 curFixValue = allFixAttrDict[fixAttrType]  | 
|                 addValueEx = int(curFixValue * addPer / 10000.0)  | 
|                 addValueExDict[fixAttrType] = addValueEx  | 
|             fixAttrPerAddExDict[funcIndex] = addValueExDict  | 
|               | 
|         GameWorld.DebugLog("¹Ì¶¨ÊôÐÔ×ܺÍ: %s" % allFixAttrDict)  | 
|         GameWorld.DebugLog("¹Ì¶¨°Ù·Ö±È¸½¼ÓÊôÐÔ: %s" % fixAttrPerAddExDict)  | 
|           | 
|         # 4. ¼ÆËãÊôÐÔ¼°Õ½Á¦, ÐèÔÚ¼ÆËãbuff²ã֮ǰ¼ÆËã  | 
|         curLV = curPlayer.GetLV()  | 
|         fpParam = IpyGameDataPY.GetIpyGameData("FightPowerParam", curLV)  | 
|         mfpDict = {} # Ä£¿éÕ½¶·Á¦  | 
|         mfpObjDict = {}  | 
|         for mfpType, attrFuncIndexList in ChConfig.MFPTypeAttrFuncIndexDict.items():  | 
|             mfpAttrList = [{} for _ in range(4)]  | 
|             mfpAttrExDict = {}  | 
|             for funcIndex in attrFuncIndexList:  | 
|                 if funcIndex in ChConfig.CalcAttrFuncSkillList:  | 
|                     # ¼¼ÄÜÄ£¿é²»¼ÆÈ빦Ä̶ܹ¨ÊôÐÔ¡¢²»¼ÆÕ½Á¦  | 
|                     continue  | 
|                 funcAttrList = funcAttrInfoList[funcIndex]  | 
|                 funcInsidePerAttrDict = funcInsidePerAttrList[funcIndex] # ¹¦ÄܵãÄÚ²¿°Ù·Ö±È¼Ó³ÉÊôÐÔ  | 
|                 funcCrossPerAttrDict = funcCrossAttrPerInfoDict.get(funcIndex, {}) # ¹¦Äܵ㽻²æ°Ù·Ö±È¼Ó³ÉÊôÐÔ  | 
|                 fixPerAttrDict = fixAttrPerAddExDict.get(funcIndex, {}) # ¹¦ÄÜ×̶ܹ¨ÊôÐ԰ٷֱȼӳÉÊôÐÔ  | 
|                   | 
|                 CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, funcAttrList[ChConfig.CalcAttr_Battle])  | 
|                 CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, funcInsidePerAttrDict)  | 
|                 CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, funcCrossPerAttrDict)  | 
|                 CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, fixPerAttrDict)  | 
|                 # ²»ËãÕ½Á¦µÄ  | 
|                 if funcIndex in ChConfig.CalcAttrFuncNoFightPowerList:  | 
|                     continue  | 
|                 mfpAttrList = AddAttrListValue([mfpAttrList, funcAttrList])  | 
|                 AddAttrDictValue(mfpAttrExDict, funcInsidePerAttrDict)  | 
|                 AddAttrDictValue(mfpAttrExDict, funcCrossPerAttrDict)  | 
|                 AddAttrDictValue(mfpAttrExDict, fixPerAttrDict)  | 
|                   | 
|             mfpObj = self.GetModuleFightPowerObj(mfpType)  | 
|             mfpObj.SetCalcMFPBattleAttr(mfpAttrList)  | 
|             for attrIndex, value in mfpAttrExDict.items():  | 
|                 mfpObj.AddCalcMFPAttr(attrIndex, value)  | 
|             mfpObjDict[mfpType] = mfpObj  | 
|               | 
|         # ÒòΪ¼ÆËãÕ½Á¦ÐèҪȡµ½×ÜÊôÐÔ£¬ËùÒԵȸ÷¹¦ÄܵãÊôÐÔÀÛ¼ÓÍêºóÔÙ¼ÆËã  | 
|         for mfpType, mfpObj in mfpObjDict.items():  | 
|             mfpValue = 0 if not fpParam else mfpObj.GetModuleFightPower(fpParam, curPlayer)  | 
|             mfpSkill = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPSkill % mfpObj.mfpType)  | 
|             mfpEx = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPEx % mfpObj.mfpType)  | 
|             mfpEx = GetMFPExFightPower(curPlayer, mfpType)  | 
|             mfpTotal = mfpValue + mfpSkill + mfpEx  | 
|             mfpDict[mfpObj.mfpType] = min(mfpTotal, ChConfig.Def_UpperLimit_DWord)  | 
|               | 
|             if mfpType == ShareDefine.Def_MFPType_Plus:  | 
|                 OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_Plus, mfpTotal)  | 
|             elif mfpType == ShareDefine.Def_MFPType_Horse:  | 
|                 OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_Horse, mfpTotal)  | 
|             elif mfpType == ShareDefine.Def_MFPType_Wash:  | 
|                 OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_Wash, mfpTotal)  | 
|                   | 
|         #GameWorld.DebugLog("ÕûÌå²ã¼¶ÏßÐÔÊôÐÔ: %s" % allAttrList)  | 
|           | 
|         # 5.±»¶¯¼¼Äܸ½¼ÓÊôÐÔ£¬²»ËãÕ½Á¦  | 
|         passiveSkillAttrList = [{} for _ in range(4)]  | 
|         SkillShell.CalcPassiveAttr_Effect(curPlayer, passiveSkillAttrList)  # ÊôÐÔÀ༼ÄÜÓëbuffͬ²ã  | 
|         for funcIndex in ChConfig.CalcAttrFuncSkillList:  | 
|             passiveSkillAttrList = AddAttrListValue([passiveSkillAttrList, funcAttrInfoList[funcIndex]])      | 
|         GameWorld.DebugLog("ÎÞÕ½Á¦±»¶¯ÊôÐÔ: %s" % passiveSkillAttrList)  | 
|           | 
|         skillFixAttrExDict = {}  | 
|         skillFixAddPerDict = passiveSkillAttrList[ChConfig.CalcAttr_BattleNoline]  | 
|         for fixAttrType, addPer in skillFixAddPerDict.items():  | 
|             if fixAttrType not in allFixAttrDict:  | 
|                 continue  | 
|             curFixValue = allFixAttrDict[fixAttrType]  | 
|             addValueEx = int(curFixValue * addPer / 10000.0)  | 
|             skillFixAttrExDict[fixAttrType] = addValueEx  | 
|         CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, passiveSkillAttrList[ChConfig.CalcAttr_Battle])  | 
|         CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, skillFixAttrExDict)  | 
|                   | 
|         #ÌØÊâÖ¸¶¨ÊôÐÔ¹«Ê½  | 
|         GameMap.SpecialMapSetAttrValueByFormat(curPlayer)  | 
|           | 
|         #»¤¶ÜֵˢР | 
|         self.__RefreshMaxProDef(beforeMaxProDef)  | 
|           | 
|         # ¡¾µ½´ËËùÓй¦ÄÜÊôÐÔ¶¼ÒÑˢд¦ÀíÍê±Ï£¬¸´ÖÆÒ»·Ý ¹¦ÄÜÊôÐÔµÄˢнá¹û£¬ÓÃÓÚBUFFÊôÐÔµ¥¶ÀˢС¿  | 
|         EffGetSet.CopyPlayerFuncAttr(curPlayer)  | 
|           | 
|         # 6.¼ÆËãbuffÊôÐÔ, buff²ã¼¶µÄ²»ËãÈçÕ½¶·Á¦  | 
|         self.__RefreshBuffAttr()  | 
|           | 
|         # 7.Ë¢ÍêÊôÐÔºóÐèÒª´¦ÀíµÄÂß¼  | 
|         self.__DoRefreshAttrAfterLogic(beforeMaxHP, beforeMoveSpeedValue, playerStateDict)  | 
|           | 
|         #֪ͨ»ù´¡ÊôÐÔ  | 
|         self.__SyncBaseAttr(curPlayer, baseAttrList)  | 
|         #ÎåÐÐÁé¸ù±ä¸üÐèÒª´¦ÀíµÄÂß¼  | 
|         afterPointList = [GetMetal(curPlayer), GetWood(curPlayer), GetWater(curPlayer), GetFire(curPlayer), GetEarth(curPlayer)]  | 
|         if beforePointList != afterPointList:  | 
|             diffPointAttrList = []  | 
|             for i, attrID in enumerate([ShareDefine.Def_Effect_Metal, ShareDefine.Def_Effect_Wood, ShareDefine.Def_Effect_Water,  | 
|                            ShareDefine.Def_Effect_Fire, ShareDefine.Def_Effect_Earth]):  | 
|                 if beforePointList[i] != afterPointList[i]:  | 
|                     diffPointAttrList.append(attrID)  | 
|             SkillShell.RefreshElementSkillByAttr(curPlayer, diffPointAttrList)  | 
| #        if hasChange_Qualitylv:  | 
| #            #Áé¸ùÆ·¼¶±ä»¯´¦Àí  | 
| #            ChEquip.ChangeEquipfacadeByLingGen(curPlayer)  | 
|               | 
|         # ¸üпª·þ»î¶¯Áé¸ùÊý¾Ý  | 
|         OpenServerCampaign.UpdOpenServerCampaignLingGenData(curPlayer)  | 
|           | 
|         # Í¬²½Ç°¶ËÕ½Á¦£¬ÒòΪÓРSetFightPower ËùÒÔÀÛ¼ÓÕ½Á¦·ÅÔÚÕâÀïËùÓÐˢм°¼ÆËã´¦ÀíÍêºó²Å´¦Àí£¬²ÅÄÜÕý³£´¥·¢setͬ²½Ç°¶Ë  | 
|         self.SendModuleFightPowerPack(curPlayer, mfpDict)  | 
|         billFuncCnt = len(PyGameData.g_refreshAttrBillboardFunc) # Ö»´¦Àí¹Ì¶¨´ÎÊý£¬·ÀÖ¹ËÀÑ»·  | 
|         while billFuncCnt > 0 and PyGameData.g_refreshAttrBillboardFunc:  | 
|             billFuncCnt -= 1  | 
|             billboardFunc = PyGameData.g_refreshAttrBillboardFunc.pop(0)  | 
|             GameWorld.DebugLog("»Øµ÷ÅÅÐаñ: %s" % billboardFunc)  | 
|             billboardFunc(curPlayer, isForceUpdate=True)  | 
|               | 
|         # ÔÝͣˢÐÂÊôÐÔ±êÖ¾£¬±ØÐë±»µ÷Óà  | 
|         curPlayer.SetDict(ChConfig.Def_Player_RefreshAttr, 0)  | 
|         curPlayer.SetDict(ChConfig.Def_Player_RefreshAttrByBuff, 0)  | 
|         curPlayer.SetDict(ChConfig.Def_Player_HadRefreshAttr, 1)  | 
|         GameWorld.DebugLog("End RefreshPlayerAttrStateEx!!!")  | 
|         return True  | 
|       | 
|       | 
|     # ÉúÃüת»¯Îª·À»¤Öµ  | 
|     def __RefreshMaxProDef(self, beforeMaxProDef):  | 
|         curPlayer = self.__Player  | 
|         if GetProDefHPPer(curPlayer) == 0:  | 
|             return  | 
|         maxHP = GameObj.GetMaxHP(curPlayer)  | 
|         proDefPer = GetProDefHPPer(curPlayer)  | 
|           | 
|         #»ñÈ¡²ß»®ÅäÖõıí¸ñ  | 
|         GodWeapon4 = IpyGameDataPY.GetFuncCfg("GodWeapon4", 2)  | 
|         maxProDef = eval(FormulaControl.GetCompileFormula("GodWeapon4", GodWeapon4))  | 
|         maxProDef = min(maxProDef, ChConfig.Def_UpperLimit_DWord)  | 
|           | 
|         SetMaxProDef(curPlayer, int(maxProDef))  | 
|           | 
|         afterMaxProDef = GetMaxProDef(curPlayer)  | 
|         addValue = max(0, afterMaxProDef - beforeMaxProDef)  | 
|         curProDef = GetProDef(curPlayer)  | 
|           | 
|         if beforeMaxProDef > 0 and addValue > 0 and curPlayer.GetPlayerAction() != IPY_GameWorld.paDie:  | 
|             # Í¬²½Ôö¼Ó (ËÀÍö״̬ϲ»Ë¢)  | 
|             SetProDef(curPlayer, min(curProDef + addValue, afterMaxProDef))  | 
|         elif curProDef > afterMaxProDef:  | 
|             # ×öÒ»´Î·À·¶¾ÀÕý  | 
|             SetProDef(curPlayer, min(curProDef, afterMaxProDef))  | 
|               | 
|         return  | 
|       | 
|     def __RefreshBuffAttr(self):  | 
|         ## Ë¢ÐÂbuff²ãÊôÐÔ£¬¸Ã²ãÊôÐÔÖ»»á¸Ä±äÍæ¼Ò×îÖÕÊôÐÔ£¬²»»áÓ°ÏìÕ½Á¦µÈ  | 
|         curPlayer = self.__Player  | 
|         allAttrListBuffs = [{} for _ in range(4)]  | 
|         # 6.¼ÆËãbuffÊôÐÔ, buff²ã¼¶µÄ²»ËãÈçÕ½¶·Á¦  | 
|         #        ËãÕ½¶·Á¦×Üֵʱ¸Ã²ãÓ°ÏìµÄÊýÖµ²»Í³¼Æ£¬µ«Ë¢ÊôÐÔʱÐè¼ÆËã  | 
|         SkillShell.CalcBuffers_Effect(curPlayer, allAttrListBuffs)  | 
|         # ¶É½Ù¸±±¾»¤·¨ÊôÐÔ¼Ó³É  | 
|         GameLogic_DuJie.CalcDujieFBAttrAdd(curPlayer, allAttrListBuffs)  | 
|               | 
|         #        ²ã·ÇÏßÐÔÕ½¶·ÊôÐÔÀÛ¼Ó  | 
|         battleNolineAttrBuff = allAttrListBuffs[ChConfig.CalcAttr_BattleNoline]  | 
|         CalcNoLineEffect.AddPlayerMapAttrNolineEffect(curPlayer, battleNolineAttrBuff)  | 
|         CalcNoLineEffect.ChangePlayerAttrInNoLineEffectList(curPlayer, battleNolineAttrBuff, isBuffAttr=True)  | 
|           | 
|         battleAttrBuff = allAttrListBuffs[ChConfig.CalcAttr_Battle]  | 
|         CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, battleAttrBuff, isBuffAttr=True)  | 
|           | 
|         #        ËÙ¶ÈÌØÊâ´¦Àí ¼ÆËãÒ»´Î  | 
|         self.__RefreshMoveSpeed(allAttrListBuffs)  | 
|           | 
|         # GM²âÊÔÊôÐÔÌØÊâÂß¼  | 
|         self.__DoRefreshGMAttr()  | 
|           | 
|         #        Ë¢Ð¹¥»÷ËÙ¶È  | 
|         self.__SetAtkInterval()  | 
|         GameWorld.DebugLog("Buff²ãÊôÐÔ: %s" % allAttrListBuffs)  | 
|         return  | 
|       | 
|     def __DoRefreshGMAttr(self):  | 
|         ## Ë¢ÐÂGM²âÊÔÊôÐÔ  | 
|         curPlayer = self.__Player  | 
|         platform = GameWorld.GetPlatform()  | 
|         if platform not in GMShell.TestPlatformList:  | 
|             return  | 
|         if curPlayer.GetGMLevel() != ChConfig.Def_GM_LV_God:  | 
|             return  | 
|           | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         if not ipyDataMgr.GetGMAttrCount():  | 
|             return  | 
|           | 
|         playerAccID = GameWorld.GetPlatformAccID(curPlayer.GetAccID())  | 
|         gmIpyData = None  | 
|         commIpyData = None  | 
|         for i in xrange(ipyDataMgr.GetGMAttrCount()):  | 
|             ipyData = ipyDataMgr.GetGMAttrByIndex(i)  | 
|             if not ipyData.GetIsValid():  | 
|                 continue  | 
|             gmMaxLV = ipyData.GetGMMaxLV()  | 
|             if curPlayer.GetLV() > gmMaxLV:  | 
|                 continue  | 
|             gmAccID = ipyData.GetGMAccID()  | 
|             if gmAccID == playerAccID:  | 
|                 gmIpyData = ipyData  | 
|                 break  | 
|               | 
|             if not gmAccID and not commIpyData:  | 
|                 commIpyData = ipyData  | 
|                   | 
|         if not gmIpyData:  | 
|             if not commIpyData:  | 
|                 return  | 
|             gmIpyData = commIpyData  | 
|               | 
|         setAttrDict = {}  | 
|         specAttrDict = gmIpyData.GetAttrSpecDict()  | 
|         attrLV = gmIpyData.GetAttrLV()  | 
|         attrPer = gmIpyData.GetAttrPer()  | 
|         if attrLV:  | 
|             if attrLV == 1:  | 
|                 attrLV = curPlayer.GetLV()  | 
|             lvIpyData = GetPlayerLVIpyData(attrLV)  | 
|             if lvIpyData:  | 
|                 setAttrDict[ChConfig.AttrName_MaxHP] = int(lvIpyData.GetReMaxHP() * attrPer) # ×î´óÉúÃüÖµ  | 
|                 setAttrDict[ChConfig.AttrName_Atk] = int(lvIpyData.GetReAtk() * attrPer) # ¹¥»÷£¨×îС¡¢×î´ó¹¥»÷£©  | 
|                 setAttrDict[ChConfig.AttrName_Def] = int(lvIpyData.GetReDef() * attrPer) # ·ÀÓù  | 
|                 setAttrDict[ChConfig.AttrName_Hit] = int(lvIpyData.GetReHit() * attrPer) # ÃüÖÐ  | 
|                 setAttrDict[ChConfig.AttrName_DefRate] = int(lvIpyData.GetReMiss() * attrPer) # ÉÁ±Ü  | 
|                 setAttrDict[ChConfig.AttrName_AtkSpeed] = int((lvIpyData.GetReAtkSpeed() + 10000) * attrPer) # ¹¥»÷ËÙ¶È, ²ß»®µÈ¼¶±íÅäÖõÄÊǸ½¼ÓÖµ£¬ËùÒÔÕâÀïÒª¼Ó  | 
|                 setAttrDict[ChConfig.AttrName_SkillAtkRate] = int(max(0, lvIpyData.GetReSkillAtkRate() - 10000) * attrPer) # ¼¼ÄÜÉ˺¦±ÈÀý, ²ß»®µÈ¼¶±íÅäÖõÄÊÇ×îÖÕÖµ£¬³õʼֵÊÇ0£¬ËùÒÔÕâÀïÒª¼õ  | 
|                 setAttrDict[ChConfig.AttrName_DamagePVP] = int(lvIpyData.GetReDamagePer() * attrPer) # PVP¹Ì¶¨É˺¦  | 
|                 setAttrDict[ChConfig.AttrName_DamagePVPReduce] = int(lvIpyData.GetReDamReduce() * attrPer) # PVP¹Ì¶¨¼õÉË  | 
|                 setAttrDict[ChConfig.AttrName_IgnoreDefRate] = int(lvIpyData.GetReIgnoreDefRate() * attrPer) # ÎÞÊÓ·ÀÓù±ÈÀý  | 
|                 setAttrDict[ChConfig.AttrName_LuckyHitRate] = int(lvIpyData.GetReLuckyHitRate() * attrPer) # »áÐÄÒ»»÷ÂÊ  | 
|                 setAttrDict[ChConfig.AttrName_LuckyHit] = int(lvIpyData.GetReLuckyHit() * attrPer) # »áÐÄÒ»»÷É˺¦  | 
|                 setAttrDict[ChConfig.AttrName_BleedDamage] = int(lvIpyData.GetReBleedDamage() * attrPer) # Á÷ѪÉ˺¦Ôö¼Ó  | 
|                 setAttrDict[ChConfig.AttrName_IceAtk] = int(lvIpyData.GetReIceAtk() * attrPer) # ÕæÊµÉ˺¦  | 
|                 setAttrDict[ChConfig.AttrName_IceDef] = int(lvIpyData.GetReIceDef() * attrPer) # ÕæÊµµÖÓù  | 
|                 setAttrDict[ChConfig.AttrName_PetAtk] = int(lvIpyData.GetRePetAtk() * attrPer) # Áé³è¹¥»÷  | 
|                 setAttrDict[ChConfig.AttrName_PetSkillAtkRate] = int(max(0, lvIpyData.GetRePetSkillAtkRate() - 10000) * attrPer) # Áé³è¼¼ÄÜ, ²ß»®µÈ¼¶±íÅäÖõÄÊÇ×îÖÕÖµ£¬³õʼֵÊÇ0£¬ËùÒÔÕâÀïÒª¼õ  | 
|                 setAttrDict[ChConfig.AttrName_PetDamPer] = int(lvIpyData.GetRePetDamPer() * attrPer) # Áé³èÉ˺¦Ôö¼Ó  | 
|                 setAttrDict[ChConfig.AttrName_FinalHurt] = int(lvIpyData.GetReFinalHurt() * attrPer) # ¹Ì¶¨É˺¦Ôö¼Ó  | 
|                 setAttrDict[ChConfig.AttrName_FinalHurtReduce] = int(lvIpyData.GetReFinalHurtReduce() * attrPer) # ¹Ì¶¨É˺¦¼õÉÙ  | 
|                   | 
|         # ÌØÊâÊôÐÔµÄÖ±½ÓÓÅÏȼ¶×î¸ß£¬Ö±½Ó¸²¸Ç  | 
|         for attrType, attrValue in specAttrDict.items():  | 
|             setAttrDict[attrType] = attrValue  | 
|               | 
|         gmAttrSetInfo = [{} for _ in range(4)]  | 
|         for attrType, attrValue in setAttrDict.items():  | 
|             if not attrValue:  | 
|                 setAttrDict.pop(attrType)  | 
|                 continue  | 
|             CalcAttrDict_Type(attrType, attrValue, gmAttrSetInfo)  | 
|               | 
|         # Ö±½ÓÉèÖõÄÊôÐÔ  | 
|         if gmAttrSetInfo:  | 
|             for key, value in gmAttrSetInfo[ChConfig.CalcAttr_Battle].items():  | 
|                 EffGetSet.SetValueByEffIndex(curPlayer, key, value)  | 
|                   | 
|         # ¸½¼ÓÊôÐÔ  | 
|         attrExDict = gmIpyData.GetAttrExDict()  | 
|         gmAttrExInfo = [{} for _ in range(4)]  | 
|         for attrType, attrValue in attrExDict.items():  | 
|             CalcAttrDict_Type(attrType, attrValue, gmAttrExInfo)  | 
|         CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, gmAttrExInfo[ChConfig.CalcAttr_Battle])  | 
|           | 
|         GameWorld.DebugLog("GM²âÊÔÉèÖÃÊôÐÔ: GMAttrID=%s,playerAccID=%s" % (gmIpyData.GetGMAttrID(), playerAccID))  | 
|         GameWorld.DebugLog("    GMµÈ¼¶ÊôÐÔ: GMAttrLV=%s,attrPer=%s,setAttrDict=%s,specAttrDict=%s,%s"   | 
|                            % (attrLV, attrPer, setAttrDict, specAttrDict, gmAttrSetInfo))  | 
|         GameWorld.DebugLog("    GM¸½¼ÓÊôÐÔ: attrExDict=%s,%s" % (attrExDict, gmAttrExInfo))  | 
|         return  | 
|       | 
|     def __DoRefreshAttrAfterLogic(self, beforeMaxHP, beforeMoveSpeedValue, playerStateDict):  | 
|         '''Ë¢Íê×ÜÊôÐÔ(¹¦ÄÜÊôÐÔ + buffÊôÐÔ) ºóÐèÒª´¦ÀíµÄÂß¼  | 
|             °üº¬Ò»Ð©ÊýÖµ¾ÀÕý¡¢ÊôÐÔ±ä¸ü֪ͨµÈ  | 
|             @attention: ´Ëº¯ÊýΪˢ ¹¦ÄÜÊôÐÔ ¼° buffÊôÐԠͨÓÃÂß¼£¬ËùÒÔ²»ÊÇÊÜbuffÓ°ÏìµÄÏà¹Ø´¦ÀíÇë²»Òª·ÅÕâÀ±ÈÈçÕ½¶·Á¦µÈ  | 
|         '''  | 
|         curPlayer = self.__Player  | 
|         #------------------------------¼ÆËãÍê±Ï--------------------------------  | 
|         afterMaxHP = GameObj.GetMaxHP(curPlayer)  | 
|         addMaxHP = max(0, afterMaxHP - beforeMaxHP)  | 
|         if beforeMaxHP > 0 and addMaxHP > 0 and curPlayer.GetPlayerAction() != IPY_GameWorld.paDie:  | 
|             # ×î´óѪÁ¿Ôö¼Óʱ£¬Í¬²½Ôö¼ÓµÈÁ¿µÄµ±Ç°ÑªÁ¿ (ËÀÍö״̬ϲ»Ë¢µ±Ç°ÑªÁ¿)  | 
|             GameObj.SetHP(curPlayer, min(GameObj.GetHP(curPlayer) + addMaxHP, afterMaxHP))  | 
|         #self.PrintAttr(curPlayer, "×îÖÕµÄ")  | 
|         curPlayer.EndRefreshState() # Í³Ò»ÔÚË¢ÊôÐÔ½áÊøÂß¼Öе÷Óà  | 
|         #---------------------------------------------------------------------  | 
|         #°ÑÊôÐԺϲ¢Í¨Öª  | 
|         self.NotifyAllState(playerStateDict)  | 
|           | 
|         #ÒÆ¶¯ËٶȲ»Í¬Ôò֪ͨ¸ø¿Í»§¶Ë, ¹¦Äܲ㴦ÀíµÄÊÇ SpeedNotBuff , Í¨Öª¿Í»§¶ËµÄÐèÒªÊÇ×îÖյĠSpeedValue  | 
|         if beforeMoveSpeedValue != GetSpeedValue(curPlayer):  | 
|             SetSpeedValue(curPlayer, GetSpeedValue(curPlayer))  | 
|               | 
|         #¾ÀÕýµ±Ç°ÑªÄ§Á¿²»³¬¹ý×î´óÖµ  | 
|         self.__RestoreHPMP()  | 
|           | 
|         #֪ͨ¿Í»§¶ËÍæ¼Òµ±Ç°¾Ñé±¶ÂÊ  | 
|         Sync_ExpRateChange(curPlayer)  | 
|         return  | 
|       | 
|     def __SyncBaseAttr(self, curPlayer, baseAttrList):  | 
|         baseBattleAttrDict = baseAttrList[ChConfig.CalcAttr_Battle]  | 
|         attrTypeKeyDict = {ChConfig.TYPE_Calc_AttrATKMin:[ChConfig.Def_PlayerKey_BaseAtkMin, ShareDefine.CDBPlayerRefresh_BaseAtkMin],  | 
|                            ChConfig.TYPE_Calc_AttrATKMax:[ChConfig.Def_PlayerKey_BaseAtkMax, ShareDefine.CDBPlayerRefresh_BaseAtkMax],  | 
|                            ChConfig.TYPE_Calc_AttrMaxHP:[ChConfig.Def_PlayerKey_BaseMaxHP, ShareDefine.CDBPlayerRefresh_BaseMaxHP],  | 
|                            ChConfig.TYPE_Calc_AttrDEF:[ChConfig.Def_PlayerKey_BaseDef, ShareDefine.CDBPlayerRefresh_BaseDef],  | 
|                            ChConfig.TYPE_Calc_AttrHit:[ChConfig.Def_PlayerKey_BaseHit, ShareDefine.CDBPlayerRefresh_BaseHit],  | 
|                            ChConfig.TYPE_Calc_AttrMiss:[ChConfig.Def_PlayerKey_BaseMiss, ShareDefine.CDBPlayerRefresh_BaseMiss],  | 
|                            }  | 
|           | 
|         notifySList = []  | 
|         for attrType, attrInfo in attrTypeKeyDict.items():  | 
|             attrKey, refreshType = attrInfo  | 
|             baseValue = baseBattleAttrDict.get(attrType, 0)  | 
|             curBaseValue = curPlayer.GetDictByKey(attrKey)  | 
|             if baseValue != curBaseValue:  | 
|                 curPlayer.SetDict(attrKey, baseValue)  | 
|                   | 
|                 notifyStruct = ChPyNetSendPack.tagRefreshType()  | 
|                 notifyStruct.RefreshType = refreshType  | 
|                 notifyStruct.Value = baseValue  | 
|                 notifySList.append(notifyStruct)  | 
|                   | 
|         # Í¨Öª»ù´¡ÊôÐÔ  | 
|         if notifySList:  | 
|             sendPack = ChPyNetSendPack.tagObjInfoListRefresh()  | 
|             sendPack.Clear()  | 
|             sendPack.ObjID = curPlayer.GetID()  | 
|             sendPack.ObjType = curPlayer.GetGameObjType()  | 
|             sendPack.Count = len(notifySList)  | 
|             sendPack.RefreshType = notifySList  | 
|             NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|         return  | 
|       | 
|     #---------------------------------------------------------------------  | 
|       | 
|     ## Ë¢ÐÂÍæ¼Ò¼¼ÄÜÕ½¶·Á¦  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Ë¢ÐÂÍæ¼Ò±»¶¯¼¼ÄÜBuff  | 
|     def RefreshAllSkill(self):  | 
|         curPlayer = self.__Player  | 
|           | 
|         skillManager = curPlayer.GetSkillManager()  | 
|           | 
|         # ÖØÖÃÄ£¿é¼¼ÄÜÕ½¶·Á¦  | 
|         for mfpType in ShareDefine.ModuleFightPowerTypeList:  | 
|             curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPSkill % mfpType, 0)  | 
|           | 
|         for i in range(0, skillManager.GetSkillCount()):  | 
|             curSkill = skillManager.GetSkillByIndex(i)  | 
|   | 
|             mfpType = ChConfig.Def_SkillFuncType_MFPType.get(curSkill.GetFuncType(), ShareDefine.Def_MFPType_Role)  | 
|   | 
|             skillMFP = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPSkill % mfpType)  | 
|             curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPSkill % mfpType, skillMFP + curSkill.GetFightPower())  | 
|           | 
|         return  | 
|       | 
|     ## ¼¼ÄÜÉý¼¶Ë¢ÊôÐÔÕ½¶·Á¦´¦Àí  | 
|     def RefreshSkillFightPowerEx(self, skillID, beforeFightPower, isRefreshState=True):  | 
|         curPlayer = self.__Player  | 
|         # Ð¼¼ÄÜÕ½Á¦-¾É¼¼ÄÜÕ½Á¦ÎªÔö¼ÓµÄ¼¼ÄÜÕ½Á¦  | 
|         curSkill = GameWorld.GetGameData().GetSkillBySkillID(skillID)  | 
|         if not curSkill:  | 
|             return  | 
|           | 
|         mfpType = ChConfig.Def_SkillFuncType_MFPType.get(curSkill.GetFuncType(), ShareDefine.Def_MFPType_Role)  | 
|         addFightPower = curSkill.GetFightPower() - beforeFightPower  | 
|         skillMFP = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPSkill % mfpType)  | 
|         curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPSkill % mfpType, max(0, skillMFP + addFightPower))  | 
|         GameWorld.DebugLog("ˢм¼Äܸ½¼ÓÕ½¶·Á¦: skillID=%s,beforeFightPower=%s,mfpType=%s,skillMFP=%s,updMFP=%s"   | 
|                            % (skillID, beforeFightPower, mfpType, skillMFP, skillMFP + addFightPower), curPlayer.GetPlayerID())  | 
|           | 
|         if isRefreshState:  | 
|             # Èç¹ûÐèҪͬ²½ÅÅÐаñµÄ»°ÏÈÇ¿ÖÆË¢ÊôÐÔ  | 
|             self.RefreshPlayerAttrState()  | 
|               | 
|         return  | 
|       | 
|     def RefreshSkillFightPowerByDel(self, delSkillID, isRefreshState=True):  | 
|         curPlayer = self.__Player  | 
|         # Ð¼¼ÄÜÕ½Á¦-¾É¼¼ÄÜÕ½Á¦ÎªÔö¼ÓµÄ¼¼ÄÜÕ½Á¦  | 
|         curSkill = GameWorld.GetGameData().GetSkillBySkillID(delSkillID)  | 
|         if not curSkill:  | 
|             return  | 
|         delFightPower = curSkill.GetFightPower()  | 
|         mfpType = ChConfig.Def_SkillFuncType_MFPType.get(curSkill.GetFuncType(), ShareDefine.Def_MFPType_Role)  | 
|         skillMFP = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPSkill % mfpType)  | 
|         curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPSkill % mfpType, max(0, skillMFP - delFightPower))  | 
|         GameWorld.DebugLog("ˢм¼Äܸ½¼ÓÕ½¶·Á¦: delSkillID=%s,mfpType=%s,skillMFP=%s,delFightPower=%s"   | 
|                            % (delSkillID, mfpType, skillMFP, delFightPower), curPlayer.GetPlayerID())  | 
|           | 
|         if isRefreshState:  | 
|             # Èç¹ûÐèҪͬ²½ÅÅÐаñµÄ»°ÏÈÇ¿ÖÆË¢ÊôÐÔ  | 
|             self.RefreshPlayerAttrState()  | 
|               | 
|         return  | 
|       | 
|     ## ¼ÆËã±»¶¯buffÊôÐÔ¼Ó³É  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return   | 
|     def CalcPassiveBuffAttr(self):  | 
|         #=======================================================================  | 
|         # curPlayer = self.__Player  | 
|         # allAttrListPassive = [{} for i in range(4)]  | 
|         # SkillShell.CalcCurBuffer_Effect(curPlayer.GetPassiveBuf(), curPlayer, allAttrListPassive)  | 
|         # SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PassiveBuf, allAttrListPassive)  | 
|         #=======================================================================  | 
|         return  | 
|       | 
|     ## //A3 A1 ¸÷¹¦ÄÜÄ£¿éÕ½¶·Á¦ÐÅÏ¢ #tagMCModuleFightPowerInfo  | 
|     #  @param curPlayer Íæ¼Ò  | 
|     #  @return None  | 
|     def SendModuleFightPowerPack(self, curPlayer, mfpDict):  | 
|         mfpDataList = []  | 
|         totalFightPower = 0  | 
|         GameWorld.DebugLog("Õ½Á¦¹¦Äܵã: %s" % ChConfig.MFPTypeAttrFuncIndexDict)  | 
|         GameWorld.DebugLog("Ä£¿éÕ½Á¦: %s" % mfpDict)  | 
|         for mfpType, fightPower in mfpDict.items():  | 
|             SetMFPFightPower(curPlayer, mfpType, fightPower)  | 
|             mfpData = ChPyNetSendPack.tagMCModuleFightPower()  | 
|             mfpData.Clear()  | 
|             mfpData.MfpType = mfpType  | 
|             mfpData.FightPower = fightPower # µ±Ç°Ä£¿éÕ½¶·Á¦ÊýÖµ  | 
|             mfpDataList.append(mfpData)  | 
|             totalFightPower += fightPower # ÀÛ¼Ó×ÜÕ½¶·Á¦  | 
|               | 
|         # //A3 A1 ¸÷¹¦ÄÜÄ£¿éÕ½¶·Á¦ÐÅÏ¢ #tagMCModuleFightPowerInfo  | 
|         mfpInfo = ChPyNetSendPack.tagMCModuleFightPowerInfo()  | 
|         mfpInfo.Clear()  | 
|           | 
|         mfpInfo.TotalFightPower = totalFightPower % ChConfig.Def_PerPointValue  | 
|         mfpInfo.TotalFightPoweEx = totalFightPower / ChConfig.Def_PerPointValue  | 
|         mfpInfo.MFPCnt = len(mfpDataList)  | 
|         mfpInfo.MFPList = mfpDataList  | 
|         NetPackCommon.SendFakePack(curPlayer, mfpInfo)  | 
|         beforeFightPower = GetFightPower(curPlayer)  | 
|         SetFightPower(curPlayer, totalFightPower)  | 
|         if totalFightPower < beforeFightPower:  | 
|             DataRecordPack.DR_FightPowerChangeInfo(curPlayer, beforeFightPower)  | 
|         highestFightPower = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FightPower_Highest, 0,  | 
|                                                            ChConfig.Def_PDictType_FightPower)  | 
|         highestFightPower += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FightPower_HighestEx, 0,   | 
|                                                             ChConfig.Def_PDictType_FightPower) * ChConfig.Def_PerPointValue  | 
|         if totalFightPower > highestFightPower:  | 
|             highestFightPower = totalFightPower  | 
|             NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FightPower_Highest, highestFightPower % ChConfig.Def_PerPointValue,  | 
|                                  ChConfig.Def_PDictType_FightPower)  | 
|             NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FightPower_HighestEx, highestFightPower / ChConfig.Def_PerPointValue,  | 
|                                  ChConfig.Def_PDictType_FightPower)  | 
|         GameWorld.DebugLog("×ÜÕ½Á¦: %s, ÀúÊ·×î¸ßÕ½Á¦: %s, beforeFightPower=%s" % (totalFightPower, highestFightPower, beforeFightPower))  | 
|         PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)  | 
|         # ¼Ç¼¿ª·þ»î¶¯Êý¾Ý£¬¿ª·þ»î¶¯Ç°XÌìÀíÂÛÉϲ»»á³¬¹ý20E£¬Ôݲ»´¦Àí  | 
|         OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_FightPower, min(totalFightPower, ChConfig.Def_UpperLimit_DWord))  | 
|         if beforeFightPower != totalFightPower:  | 
|             CrossPlayerData.OnPlayerFightPowerChange(curPlayer)  | 
|         return  | 
|       | 
|     def __RefreshMoveSpeed(self, allAttrListBuffs):  | 
|         ## Ë¢ÐÂÒÆ¶¯ËÙ¶È  | 
|         curPlayer = self.__Player  | 
|           | 
|         moveSpeedFormat = IpyGameDataPY.GetFuncCfg("MoveSpeed")  | 
|           | 
|         if PlayerTruck.GetHaveAutoTruck(curPlayer):  | 
|             speed = IpyGameDataPY.GetFuncCfg("MoveSpeed", 3)  | 
|             GameWorld.DebugLog("ÔËïڹ̶¨ËÙ¶ÈÖµ: speed=%s" % speed)  | 
|         else:  | 
|             speed = GetSpeedNotBuff(curPlayer)  | 
|             GameWorld.DebugLog("¹¦ÄÜÒÆ¶¯ËÙ¶ÈÖµ: speed=%s" % speed)  | 
|               | 
|             # Æï³Ë״̬¼ÓÉÏÆï³Ë¸½¼ÓËÙ¶È  | 
|             if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse:  | 
|                 speedHorse = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SpeedHorse)  | 
|                 speed += speedHorse  | 
|                 GameWorld.DebugLog("    Æï³Ë״̬¸½¼ÓÖµ: %s, speed=%s" % (speedHorse, speed))  | 
|               | 
|                   | 
|             buffBattleAttr = allAttrListBuffs[ChConfig.CalcAttr_Battle]  | 
|             buffBattleNolineAttr = allAttrListBuffs[ChConfig.CalcAttr_BattleNoline]  | 
|             #buffËٶȼӳɠ      | 
|             buffSpeed = buffBattleAttr.get(ChConfig.TYPE_Calc_AttrSpeed, 0)  | 
|             buffSpeedPer = buffBattleNolineAttr.get(ChConfig.TYPE_Calc_AttrSpeed, 0)  | 
|               | 
|             if buffSpeed or buffSpeedPer:  | 
|                 speed = int(speed * (ShareDefine.Def_MaxRateValue + buffSpeedPer) / float(ShareDefine.Def_MaxRateValue) + buffSpeed)  | 
|                 GameWorld.DebugLog("    buffÓ°ÏìºóËÙ¶ÈÖµ: speed=%s,buffSpeedPer=%s,buffSpeed=%s" % (speed, buffSpeedPer, buffSpeed))  | 
|                   | 
|             speed = max(speed, 0)   #·ÀСÓÚ0´íÎó  | 
|         if GetSpeedValue(curPlayer) != speed:  | 
|             SetSpeedValue(curPlayer, speed)  | 
|             moveSpeed = eval(FormulaControl.GetCompileFormula("MoveSpeed", moveSpeedFormat))  | 
|             curPlayer.SetSpeed(moveSpeed)  | 
|             GameWorld.DebugLog("¹«Ê½¼ÆËãºóÒÆ¶¯ÆµÂÊ: moveSpeed=%s ºÁÃë/¸ñ" % moveSpeed)  | 
|               | 
|             fightPet = curPlayer.GetPetMgr().GetFightPet()  | 
|             #ÎÞ³öÕ½³èÎï  | 
|             if fightPet:  | 
|                 fightPet.SetSpeed(moveSpeed)  | 
|                   | 
|         return  | 
|   | 
|     ##ˢй¥»÷¼ä¸ô  | 
|     # @param self ÀàʵÀý  | 
|     # @return None  | 
|     def __SetAtkInterval(self):  | 
|         curPlayer = self.__Player  | 
|           | 
|         atkSpeed = GameObj.GetAtkSpeed(curPlayer)  | 
|           | 
|         formula = IpyGameDataPY.GetFuncCfg("AtkInterval")  | 
|         atkInterval = 0 if not formula else eval(FormulaControl.GetCompileFormula("AtkInterval", formula))  | 
|         curPlayer.SetAtkInterval(atkInterval)  | 
|         return  | 
|       | 
|       | 
|     ## Ë¢ÐÂÍæ¼ÒËùÓÐÐÐΪBUFF״̬  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Ë¢ÐÂÍæ¼ÒËùÓÐÐÐΪBUFF״̬  | 
|     def RefreshPlayerActionState(self):  | 
|         GameWorld.DebugLog("Start RefreshPlayerActionState!!!")  | 
|         #curTime = time.clock()  | 
|         curPlayer = self.__Player  | 
|           | 
|         #ÏÈÇå³ýËùÓÐ״̬  | 
|         OperControlManager.ClearObjActionState(curPlayer)  | 
|           | 
|         #ÔÙ¸ù¾ÝBUFF ¼ÓÉÏ״̬  | 
|         SkillShell.CalcBuffer_ActionState(curPlayer)  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     ## Ë¢ÐÂѪÁ¿ºÍħ  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Ë¢ÐÂѪÁ¿ºÍħ  | 
|     def __RestoreHPMP(self):  | 
|         curPlayer = self.__Player  | 
|           | 
|         if not curPlayer.GetInitOK():  | 
|             #Íæ¼Òδ³õʼ»¯³É¹¦, ²»ÐÞÕýѪÁ¿ºÍħ·¨Öµ, Òò´ËʱÓпÉÄÜÒòΪijЩӰÏìÖ÷½ÇµÄÎïÆ·Î´³õʼ»¯Íê±Ï(Èç³èÎï×°±¸)  | 
|             return  | 
|           | 
|         curPlayerHP = GameObj.GetHP(curPlayer)  | 
|         curPlayerMaxHP = GameObj.GetMaxHP(curPlayer)  | 
|         #=======================================================================  | 
|         # curPlayerMP = curPlayer.GetMP()  | 
|         # curPlayerMaxMP = curPlayer.GetMaxMP()  | 
|         #=======================================================================  | 
|           | 
|         if curPlayerHP > curPlayerMaxHP:  | 
|             GameObj.SetHPFull(curPlayer)  | 
|           | 
|         #=======================================================================  | 
|         # if curPlayerMP > curPlayerMaxMP:  | 
|         #    curPlayer.SetMP(curPlayerMaxMP)  | 
|         #=======================================================================  | 
|   | 
|         return  | 
|     #---------------------------------------------------------------------  | 
|     ## ³õʼ»¯Íæ¼Ò»ù±¾×´Ì¬ ÕâÀï²»¶Ô£¨ ¼ÆËãÏÖÓÐÕ½¶·ÊôÐÔÖеÄÔªËØ½øÐд¦Àí £©  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks ³õʼ»¯Íæ¼Ò»ù±¾×´Ì¬ ÕâÀï²»¶Ô£¨ ¼ÆËãÏÖÓÐÕ½¶·ÊôÐÔÖеÄÔªËØ½øÐд¦Àí £©  | 
|     def InitPlayerState(self):  | 
|         curPlayer = self.__Player  | 
|         #Çå¿ÕÕ½¶·ÊôÐÔ //Õ½¶·ÊôÐÔÉèÖÃÊýֵΪ0µÄ, ÓÉC++´¦Àí ÈçÔªËØÊôÐÔ,ÃüÖÐµÈ  | 
|         curPlayer.ClearBattleEffect()  | 
|           | 
|         initAttrDict = {  | 
|                         #ChConfig.TYPE_Calc_AttrCurSTR:curPlayer.GetBaseSTR(),  | 
|                         #ChConfig.TYPE_Calc_AttrCurPNE:curPlayer.GetBasePNE(),  | 
|                         #ChConfig.TYPE_Calc_AttrCurPHY:curPlayer.GetBasePHY(),  | 
|                         #ChConfig.TYPE_Calc_AttrCurCON:curPlayer.GetBaseCON(),  | 
|                         #ChConfig.TYPE_Calc_AttrSpeed:curPlayer.GetBaseSpeed(),  | 
|                         ChConfig.TYPE_Calc_AttrAtkSpeed:ChConfig.Def_BaseAtkSpeed,  | 
|                         ChConfig.TYPE_Calc_AttrFightExpRate:GameWorld.GetGameWorld().GetExpRate(),  | 
|                         ChConfig.TYPE_Calc_AttrGameExpRate:GameWorld.GetGameWorld().GetExpRate(),  | 
|                         ChConfig.TYPE_Calc_AttrPetExpRate:GameWorld.GetGameWorld().GetExpRate(),  | 
|                         ChConfig.TYPE_Calc_HitSucessRate:ChConfig.Def_MaxRateValue,  | 
|                         ChConfig.TYPE_Calc_CurePer:ChConfig.Def_MaxRateValue,  | 
|                         ChConfig.TYPE_Calc_YinjiTime:IpyGameDataPY.GetFuncCfg('Yinji', 1),  # Ã¿XÃë×Ô¶¯Ïûʧһ¸öÓ¡¼Ç  | 
|                         }  | 
|           | 
|         for i in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):  | 
|             if i in [ChConfig.TYPE_Calc_AttrHP, ChConfig.TYPE_Calc_AttrMP, ChConfig.TYPE_Calc_ProDef]:  | 
|                 continue  | 
|             value = 0 if i not in initAttrDict else initAttrDict[i]  | 
|             EffGetSet.SetValueByEffIndex(curPlayer, i, value)  | 
|               | 
|         #³õʼ»¯Ê°È¡¾àÀë  | 
|         if curPlayer.GetPickupDist() != ChConfig.Def_RolePickupItemDist:  | 
|             curPlayer.SetPickupDist(ChConfig.Def_RolePickupItemDist)  | 
|               | 
|         #Íæ¼Ò³õʼ»¯¿É¹¥»÷  | 
|         if not curPlayer.GetCanAttack():  | 
|             curPlayer.SetCanAttack(True)  | 
|               | 
|         #³õʼ»¯Áé¸ù  | 
|         SetMetal(curPlayer, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % ShareDefine.Def_Effect_Metal))  | 
|         SetWood(curPlayer, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % ShareDefine.Def_Effect_Wood))  | 
|         SetWater(curPlayer, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % ShareDefine.Def_Effect_Water))  | 
|         SetFire(curPlayer, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % ShareDefine.Def_Effect_Fire))  | 
|         SetEarth(curPlayer, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % ShareDefine.Def_Effect_Earth))  | 
|         return True  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     ## ³õʼ»¯³¡¾°buff  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks ³õʼ»¯³¡¾°buff  | 
|     def InitMapBuffState(self):  | 
|         curPlayer = self.__Player  | 
|           | 
|         #³õʼ»¯ÇøÓò, Ä¬ÈÏΪÆÕÍ¨ÇøÓò  | 
|         if GameMap.GetAreaTypeByMapPos(curPlayer.GetPosX(), curPlayer.GetPosY()) != IPY_GameWorld.gatNormal:  | 
|             curPlayer.SetAreaType(IPY_GameWorld.gatNormal)  | 
|               | 
|         return  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     ## ½«Íæ¼ÒÉèÖõ½ÖØÉúµã  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks ½«Íæ¼ÒÉèÖõ½ÖØÉúµã  | 
|     def SetToBornPlace(self):  | 
|         curPlayer = self.__Player  | 
|         mapFBType = GameWorld.GetMap().GetMapFBType()  | 
|         #Íæ¼Ò²»ÔÚ¸±±¾ÖÐ  | 
|         if mapFBType == IPY_GameWorld.fbtNull:  | 
| #            gameMap = GameWorld.GetMap()  | 
| #            rebornMapID = gameMap.GetRebornMapID()  | 
| #            rebornPosX = gameMap.GetRebornMapX()  | 
| #            rebornPosY = gameMap.GetRebornMapY()  | 
| #              | 
| #            #ÑéÖ¤ÊÇ·ñ±¾µØÍ¼¸´»îµã ½øÐÐÂß¼´¦Àí  | 
| #            if gameMap.GetMapID() == rebornMapID:  | 
| #                posX, posY = GameMap.GetNearbyPosByDis(rebornPosX, rebornPosY, ChConfig.Def_RebornPos_Area_Range)  | 
| #            else:  | 
| #                posX, posY = rebornPosX, rebornPosY  | 
| #                  | 
| #            #ÕÒ²»µ½·ÇÕϰµã¸´»î£¬ÔòÉèÎªÍæ¼ÒµÄÖØÉúµã¸´»î  | 
| #            if posX <= 0 or posY <= 0 or rebornMapID <= 0:  | 
| #                rebornMapID = curPlayer.GetRebornMapID()  | 
| #                posX = curPlayer.GetRebornPosX()  | 
| #                posY = curPlayer.GetRebornPosY()  | 
|             rebornMapID = curPlayer.GetRebornMapID()  | 
|             rebornPosX = curPlayer.GetRebornPosX()  | 
|             rebornPosY = curPlayer.GetRebornPosY()  | 
|   | 
|         #Íæ¼ÒÔÚ¸±±¾ÖÐ  | 
|         else:  | 
|             rebornMapID = curPlayer.GetFBRebornMapID()  | 
|             rebornPosX = curPlayer.GetFBRebornPosX()  | 
|             rebornPosY = curPlayer.GetFBRebornPosY()  | 
|           | 
|         if rebornMapID == 0:  | 
|             NotifyCode(curPlayer, "ObjectMapNonentity")  | 
|             GameWorld.Log("ÈËÎïÖØÉúµØÍ¼ID = %sÒì³£!" % (rebornMapID) , curPlayer.GetPlayerID())  | 
|             return  | 
|           | 
|         if rebornMapID == curPlayer.GetMapID():  | 
|             GameWorld.ResetPlayerPos(curPlayer, rebornPosX, rebornPosY)  | 
|             return  | 
|           | 
|         #°ÑÈËÎïÉèÖûØÖØÉúµã  | 
|         PlayerResetWorldPos(curPlayer, rebornMapID, rebornPosX, rebornPosY, False)  | 
|         return  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     ## Íæ¼ÒËÀÍöÂß¼  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Íæ¼ÒËÀÍöÂß¼  | 
|     def SetDead(self):  | 
|         #Ö÷½ÇÉèÖÃΪËÀÍö״̬  | 
|         curPlayer = self.__Player  | 
|           | 
|         #֪ͨ¸±±¾Íæ¼ÒËÀÍö  | 
|         FBLogic.DoPlayerDead(curPlayer)  | 
|           | 
|         #Íæ¼Ò״̬´¦Àí  | 
|         ReSetPlayerState(curPlayer)  | 
|           | 
|         #Çå¿ÕËùÓÐËÀÍö²»±£ÁôµÄbuff  | 
|         self.__PlayerDeadClearBuff()  | 
|   | 
|         #ɱËÀËùÓÐÕÙ»½µÄÁé  | 
|         KillPlayerSummonNPC(curPlayer)  | 
|           | 
|         #ÕÙ»½»Ø³öÕ½µÄ³èÎï  | 
|         PetControl.ReCallFightPet(curPlayer)  | 
|           | 
|         #ÀïÚÍæ¼ÒËÀÍö´¦Àí  | 
|         PlayerTruck.DoPlayerDead(curPlayer)  | 
|         #Çå¿ÕʹÓü¼ÄܼǼ  | 
|         curPlayer.ClearUseSkillRec()  | 
|           | 
|         #¸ÄΪ¸´»îµÄʱºòË¢ÐÂ״̬  | 
| #===============================================================================  | 
| #        #Ë¢ÐÂ״̬  | 
| #        self.RefreshAllState()  | 
| #===============================================================================  | 
|           | 
|         if GameObj.GetHP(curPlayer) != 0:  | 
|             GameObj.SetHP(curPlayer, 0)  | 
|           | 
|         #Çå¿ÕÒÆ¶¯´íÎó¾àÀë  | 
|         GameWorld.ClearPlayerPosCount(curPlayer)  | 
|           | 
|         #¼Ç¼Ö÷½ÇËÀÍö´ÎÊýºÍËÀÍöʱ¼ä  | 
|         self.SetPlayerDeadCnt(curPlayer)  | 
|           | 
|         #ËÀÍö´¥·¢¼¼ÄÜ  | 
|         tick = GameWorld.GetGameWorld().GetTick()  | 
|           | 
|         #֪ͨËÀÍö  | 
|         DoPlayerDead(curPlayer)  | 
|           | 
|         PlayerTJG.PlayerTJGReborn(curPlayer, tick)  | 
|         GameObj.ClearPyPlayerState(curPlayer)  | 
|         return  | 
|       | 
|       | 
|     ## ¼Ç¼Ö÷½ÇËÀÍö´ÎÊý  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     def SetPlayerDeadCnt(self, curPlayer):  | 
|         #playerLv = curPlayer.GetLV()  | 
|         #¼Ç¼ËÀÍöʱ¼ä  | 
|         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_DeadTime, int(time.time()))  | 
|         #ÉíÉÏÓÐ5²ã¸´»îÆ£ÀÍbuffʱÔټǼ  | 
|         findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_ReviveTired)[0]  | 
|         if not (findBuff and findBuff.GetSkill().GetSkillLV() == findBuff.GetSkill().GetSkillMaxLV()):  | 
|             return  | 
|           | 
| #        if playerLv < int(ReadChConfig.GetEvalChConfig('BeginRecordDeadCntLV')):  | 
| #            return  | 
|           | 
|         #ÉϴμǼµÄÍæ¼ÒËÀÍö´ÎÊý  | 
| #         lastDeadCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PlayerDeadCnt)  | 
| #         #GameWorld.Log("ÉÏ´ÎÍæ¼ÒËÀÍö´ÎÊý=%s"%lastDeadCnt)  | 
| #           | 
| #         #ËÀÍö´ÎÊý×î´óÀÛ¼ÓÖµ  | 
| #         maxDeadCnt = int(ReadChConfig.GetEvalChConfig('PlayerDeadMaxCnt'))  | 
| #           | 
| #         #»ñÈ¡ÉÏ´ÎËÀÍöʱ¼ä  | 
| #         lastDeadTimeTick = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)  | 
| #         #GameWorld.Log("»ñÈ¡ÉÏ´ÎËÀÍöʱ¼ä=%s"%lastDeadTimeTick)  | 
| #           | 
| #         #ÿ¸ô¼¸ºÁÃë¼õÒ»´ÎËÀÍö´ÎÊý  | 
| #         timeSpace = int(ReadChConfig.GetEvalChConfig('DelDeadCntTime'))   | 
| #           | 
| #         #µ±Ç°Ê±¼ä  | 
| #         curGameWorldTick = int(time.time())  | 
| #         delCnt = max(curGameWorldTick - lastDeadTimeTick, 0) / timeSpace  | 
| #           | 
| #         #GameWorld.Log("###delCnt=%s"%delCnt)  | 
| #         #µ±Ç°ËÀÍö´ÎÊý(°üÀ¨Õâ´ÎËÀµÄ)  | 
| #         curDeadCnt = min(max(lastDeadCnt - delCnt, 0) + 1, maxDeadCnt)  | 
| #           | 
| #         #GameWorld.Log("###curDeadCnt=%s"%curDeadCnt)  | 
| #         #GameWorld.Log("###curTimeTick=%s"%curGameWorldTick)  | 
| #         #¼Ç¼µ±Ç°ËÀÍö´ÎÊý  | 
| #         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PlayerDeadCnt, curDeadCnt)  | 
|           | 
|         #֪ͨËÀÍöʱ¼ä  | 
|         self.NotifyPlayerDeadTime(curPlayer)  | 
|         return  | 
|       | 
|     ## Í¨ÖªÉÏ´ÎËÀÍöʱ¼ä  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Íæ¼ÒËÀÍöÂß¼, ºìÃûµôÂä  | 
|     def NotifyPlayerDeadTime(self, curPlayer):  | 
|         #Èç¹ûÓÐ5²ã¸´»îÆ£ÀÍbuff ²¢ÇÒÊDZ»Íæ¼ÒɱËÀµÄÔò֪ͨ  | 
|         findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_ReviveTired)[0]  | 
|         if findBuff and findBuff.GetSkill().GetSkillLV() == findBuff.GetSkill().GetSkillMaxLV():  | 
|             if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_IsAddReviveTired):  | 
|                 lastDeadTimeTick = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)  | 
|                 packData = ChPyNetSendPack.tagMCPlayerDeadTime()  | 
|                 packData.DeadTime = lastDeadTimeTick  | 
|                 NetPackCommon.SendFakePack(curPlayer, packData)  | 
|         return  | 
|       | 
|     #---------------------------------------------------------------------  | 
|     ## Çå¿ÕËùÓеĿÉÒÔɾ³ýµÄbuff  | 
|     #  @param self ÀàʵÀý  | 
|     #  @return ·µ»ØÖµÎÞÒâÒå  | 
|     #  @remarks Çå¿ÕËùÓеĿÉÒÔɾ³ýµÄbuff  | 
|     def __PlayerDeadClearBuff(self):  | 
|         curPlayer = self.__Player  | 
|         tick = GameWorld.GetGameWorld().GetTick()  | 
|           | 
|         #ÐèÒª¿¼ÂÇbuff,deBuff,aura,incBuff,mapBuff,³ýÁËequipBuff²»¿¼ÂÇ  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetBuffState(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetDeBuffState(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetAura(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetIncBuff(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetMapBuff(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetActionBuffManager(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetProcessBuffState(), ClearBuffByDie, tick)  | 
|         PlayerClearBuff_Single(curPlayer, curPlayer.GetProcessDeBuffState(), ClearBuffByDie, tick)  | 
|           | 
|         return  | 
|       | 
| #---------------------------------------------------------------------  | 
| ## Çå¿Õbuff(²ÎÊý -> buff¹ÜÀíÆ÷)  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param buffState buff¹ÜÀíÆ÷  | 
| #  @param tick Ê±¼ä´Á  | 
| #  @return ·µ»ØÖµÎÞÒâÒå  | 
| #  @remarks Çå¿Õbuff(²ÎÊý -> buff¹ÜÀíÆ÷)  | 
| def PlayerClearBuff_Single(curPlayer, buffState, funcClearBuff, tick):  | 
|   | 
|     curPlayerID = curPlayer.GetPlayerID()  | 
|     index = 0  | 
|     buffSkillIDList = []  | 
|       | 
|     passiveEff = PassiveBuffEffMng.GetPassiveEffManager().GetPassiveEff(curPlayer)  | 
|     while index < buffState.GetBuffCount():  | 
|         curBuff = buffState.GetBuff(index)  | 
|         #Òì³£  | 
|         if not curBuff:  | 
|             GameWorld.Log("###Íæ¼ÒÇå¿Õbuffʧ°Ü,Ë÷Òý = %s" % (index), curPlayerID)  | 
|             index += 1  | 
|             continue  | 
|           | 
|         #buff²»Ïûʧ  | 
|         if funcClearBuff and funcClearBuff(curBuff):  | 
|             index += 1  | 
|             continue  | 
|           | 
|         #BuffSkill.DoBuffDisApper(curPlayer, curBuff, tick)  | 
|         #buffSkillIDList.append([curBuff.GetSkill().GetSkillID(), curBuff.GetOwnerID(), curBuff.GetOwnerType()])  | 
|         buffSkillIDList.append(curBuff.GetSkill().GetSkillID())  | 
|         #GameWorld.DebugLog("ËÀÍöÇåÀí-----%s"%curBuff.GetSkill().GetSkillID())  | 
|         if passiveEff:  | 
|             passiveEff.DelBuffInfo(curBuff.GetSkill())  | 
|               | 
|         #ɾ³ýÕâ¸öbuff  | 
|         buffState.DeleteBuffByIndex(index)  | 
|           | 
|           | 
|     SkillShell.ClearBuffEffectBySkillIDList(curPlayer, buffState, buffSkillIDList)  | 
|     return  | 
|   | 
|   | 
| ## ËÀÍöbuffÊÇ·ñÏûʧ  | 
| #  @param curBuff: buffʵÀý  | 
| #  @return: ËÀÍöbuffÊÇ·ñÏûʧ  | 
| def ClearBuffByDie(curBuff):  | 
|     skill = curBuff.GetSkill()  | 
|     return skill.GetDieContinue() & Def_Buff_Clear_Die > 0  | 
|   | 
|   | 
| ## ÏÂÏßbuffÊÇ·ñÏûʧ  | 
| #  @param curBuff: buffʵÀý  | 
| #  @return: ËÀÍöbuffÊÇ·ñÏûʧ  | 
| def ClearBuffByDisconnect(curBuff):  | 
|     skill = curBuff.GetSkill()  | 
|     return skill.GetDieContinue() & Def_Buff_Clear_Disconnect > 0  | 
|               | 
| #---------------------------------------------------------------------  | 
| ##´«Ëͼì²é(ÊÇ·ñ·Ç·¨µØÍ¼)  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param destMapID Ä¿±êµØÍ¼ID  | 
| # @return ·µ»ØÖµÕæ, Í¨¹ý  | 
| # @remarks ´«Ëͼì²é  | 
| def CheckTagCountry(curPlayer, destMapID):  | 
|     gameMap = GameWorld.GetMap()  | 
|       | 
|     if not gameMap.IsMapIDExist(destMapID):  | 
|         GameWorld.ErrLog('###·Ç·¨µØÍ¼Êý¾Ý£¬mapID: %s' % (destMapID), curPlayer.GetPlayerID())  | 
|         NotifyCode(curPlayer, "ObjectMapNonentity")  | 
|         return False  | 
|       | 
| #===============================================================================  | 
| #    #ÐÂÊִ峡¾°²»ÔÊÐí½øÈëºÍ´«³ö  | 
| #    if GameWorld.GetMap().GetMapID() == 21 or destMapID == 21:  | 
| #        NotifyCode(curPlayer, "CS_VillageHead_Fail")  | 
| #        return   | 
| #===============================================================================  | 
|       | 
|     #¼ì²éÍæ¼ÒÊÇ·ñ´«Ë͵йú×ø±ê  | 
|     mapCountry = gameMap.GetCountryByMapID(destMapID)  | 
|       | 
|     if not GameWorld.IsSameCountry_Name(mapCountry, curPlayer.GetCountry()):  | 
|         NotifyCode(curPlayer, "Enemy_State_No_Trans")  | 
|         return False  | 
|       | 
|     #¼ì²é´«ËÍÖÁµÄµØÍ¼ÊÇ·ñÊÇÆÕͨµØÍ¼  | 
|     if gameMap.GetMapFBTypeByMapID(destMapID) != IPY_GameWorld.fbtNull:  | 
|         #¸±±¾ºÍ»î¶¯³¡¾°ÎÞ·¨´«ËÍ  | 
|         NotifyCode(curPlayer, "Carry_lhs_306641")  | 
|         return False  | 
|       | 
|     #¼ì²éÍæ¼ÒµÈ¼¶ÊÇ·ñ×ã¹»½øÈë´ËµØÍ¼  | 
|     if not CanEnterMap(curPlayer, destMapID):  | 
|         return False  | 
|       | 
|     #¼ì²é´ËµØÍ¼ÊÇ·ñΪָ¶¨·ÖÁ÷ÓµÓÐµÄ  | 
|     mapLineID = GetPlayerLineID(curPlayer)  | 
|       | 
|     mapLineCheckDict = ReadChConfig.GetEvalChConfig('TransportMapLineCheck')  | 
|     canEnterLineID = 0  | 
|       | 
|     for lineID, mapIDList in mapLineCheckDict.items():  | 
|         if destMapID not in mapIDList:  | 
|             continue  | 
|           | 
|         if mapLineID == lineID:  | 
|             #´Ë·ÖÁ÷¿ÉÒÔ½øÈë  | 
|             return True  | 
|   | 
|         #¼Ç¼һÏ¿ÉÒÔ½øÈëµÄÏß·  | 
|         canEnterLineID = lineID  | 
|   | 
|     if canEnterLineID > 0:  | 
|         #´Ë·ÖÁ÷²»¿É½øÈë  | 
|         NotifyCode(curPlayer, "Carry_yeqian_0", [destMapID, canEnterLineID])  | 
|         return False  | 
|   | 
|     #¿ÉÒÔ½øÈë  | 
|     return True  | 
| #---------------------------------------------------------------------  | 
| ##²éÍæ¼ÒµÈ¼¶ÊÇ·ñ×ã¹»½øÈë´ËµØÍ¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param destMapID Ä¿±êµØÍ¼ID  | 
| # @return ·µ»ØÖµÕæ, Í¨¹ý  | 
| # @remarks ²éÍæ¼ÒµÈ¼¶ÊÇ·ñ×ã¹»½øÈë´ËµØÍ¼  | 
| def CanEnterMap(curPlayer, destMapID, isShowSys=True):  | 
|     #µØÍ¼ÌØÊâ¼ì²é  | 
|     #if not CheckEquipCanTrans(curPlayer, destMapID):  | 
|         #return False  | 
|       | 
|     if not CheckLVCanEnterMap(curPlayer, destMapID, isShowSys):  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
|       | 
| ##²éÍæ¼ÒµÈ¼¶ÊÇ·ñ×ã¹»½øÈë´ËµØÍ¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param destMapID Ä¿±êµØÍ¼ID  | 
| # @return ·µ»ØÖµÕæ, Í¨¹ý  | 
| def CheckLVCanEnterMap(curPlayer, destMapID, isShowSys=True):  | 
|     mapData = GameWorld.GetGameData().GetChinMap().GetMapByID(destMapID)  | 
|     if not mapData:  | 
|         return   | 
|     enterLV = mapData.GetLV()  | 
|   | 
|     if curPlayer.GetLV() < enterLV:  | 
|         #¶Ô²»Æð£¬¸Ã³¡¾°ÐèÒªXX¼¶²ÅÄܽøÈë!  | 
|         if isShowSys:  | 
|             NotifyCode(curPlayer, "Carry_hwj35_0", [enterLV])  | 
|         return False  | 
|     openMapStep = mapData.GetTreasureID() #ÐèÒªÍê³ÉµÄÖ÷ÏßÈÎÎñID  | 
|     if openMapStep and not IsMapOpen(curPlayer, openMapStep):  | 
|         #GameWorld.DebugLog('¶Ô²»Æð£¬¸Ã³¡¾°destMapID=%sÐèÒªÍê³ÉÖ÷ÏßÈÎÎñ%s²ÅÄܽøÈë!' % (destMapID, openMapStep))  | 
|         return False  | 
|     return True  | 
|   | 
|   | 
| def IsMapOpen(curPlayer, openMapStep):  | 
|     # Ö÷ÏßÈÎÎñÍê³Éʱ»áÉèÖñêÖ¾¿É½øµØÍ¼±êÖ¾  | 
|     mission_1 = QuestCommon.GetCommonMission(curPlayer)  | 
|     if not mission_1:  | 
|         return False  | 
|     if openMapStep > mission_1.GetProperty("OpenMap"):  | 
|         return False  | 
|     return True  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##¹ØÓÚ´«ËÍ ÑéÖ¤Íæ¼Ò״̬  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÕæ, Í¨¹ý  | 
| # @remarks ¹ØÓÚ´«ËÍ ÑéÖ¤Íæ¼Ò״̬  | 
| def CheckTransState(curPlayer):  | 
|     #¿ÉÒÔ½øÈë´«Ë͵Ä״̬  | 
|     playerAction = curPlayer.GetPlayerAction()  | 
|     if playerAction in ChConfig.Def_Player_Cannot_TransState:  | 
|         #Carry_lhs_697674£ºÄúµ±Ç°Ëù´¦µÄ״̬²»ÄܽøÐд«ËÍ!  | 
|         NotifyCode(curPlayer, "Carry_lhs_697674")  | 
|         return False  | 
|       | 
|     #ÒÆ¶¯Öв»Ö´Ðд˲Ù×÷  | 
|     if curPlayer.IsMoving():  | 
|         curPlayer.StopMove()  | 
|       | 
|       | 
|     if playerAction == IPY_GameWorld.paSit:  | 
|         DoPlayerStand(curPlayer)  | 
|       | 
|     #ÇëÇó´«ËÍ״̬, ÅжϷþÎñ¶ËÏÞÖÆ  | 
|     if not OperControlManager.IsObjCanDoAction(  | 
|                                         curPlayer,  | 
|                                         ChConfig.Def_Obj_ActState_ServerAct,  | 
|                                         IPY_GameWorld.oalTransmit  | 
|                                         ):  | 
|         return False  | 
|       | 
|     return True   | 
| #---------------------------------------------------------------------  | 
| ##Çå³ýÓÐÏÞÎÞµÐBUF  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Çå³ýÓÐÏÞÎÞµÐBUF  | 
| def DelLimitSuperBuff(curPlayer, tick):  | 
|     if curPlayer.GetCanAttack():  | 
|         return  | 
|       | 
|     if not tick:  | 
|         tick = GameWorld.GetGameWorld().GetTick()  | 
|           | 
|     if BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_LimitSuperBuff, tick):  | 
|       | 
|         PlayerControl(curPlayer).RefreshPlayerAttrByBuff()  | 
|       | 
| #---------------------------------------------------------------------  | 
| ##ÌØÊâ״̬´¦Àí  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ÌØÊâ״̬´¦Àí  | 
| def ReSetPlayerState(curPlayer):  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|       | 
|     #---Íæ¼Ò״̬´¦Àí---  | 
|     curPlayerAction = curPlayer.GetPlayerAction()  | 
|       | 
|     #Íæ¼Ò½»Ò×ÖÐ, À뿪½»Ò×  | 
|     if curPlayerAction == IPY_GameWorld.paTrade:  | 
|         PlayerTrade.LeaveTrade(curPlayer, 0)  | 
|                       | 
|     #Íæ¼Òʼþ״̬ÖÐ, Í˳öʼþ  | 
|     elif curPlayerAction == IPY_GameWorld.paEvent:  | 
|         EventShell.DoExitEvent(curPlayer)  | 
|           | 
|     elif curPlayerAction == IPY_GameWorld.paGameEvent:  | 
|         PlayerGameEvent.StopGameEvent(curPlayer, tick)  | 
|           | 
|     if curPlayerAction == IPY_GameWorld.paPreparing:  | 
|         DoExitPreparing(curPlayer)  | 
|       | 
|     #---Íæ¼Ò½»Í¨¹¤¾ß´¦Àí---  | 
|     curPlayerVehicle = curPlayer.GetPlayerVehicle()  | 
|       | 
|     #Íæ¼ÒÆïÂíÖÐ, ÏÂÂí  | 
|     if curPlayerVehicle == IPY_GameWorld.pvHorse:  | 
|         #Ö´ÐÐÏÂÂíÂß¼  | 
|         PlayerHorse.PlayerRideHorseDown(curPlayer, False)  | 
|           | 
|     #Íæ¼ÒïÚ³µÖÐ, Ï³µ  | 
|     elif curPlayerVehicle == IPY_GameWorld.pvTruck:  | 
|         PlayerTruck.PlayerTruckDown(curPlayer, curPlayer.GetTruck())  | 
|       | 
|     #---ÆäËûϵͳ´¦Àí---  | 
|       | 
|     #ÖжÏÕ½¶·¶ÔÖÅ  | 
|     ExitPlayerConfronting(curPlayer)  | 
|       | 
|     #Çå¿Õµ±Ç°¹¥»÷¶ÔÏó  | 
|     curPlayer.SetActionObj(None)  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ##³õʼ»¯Öк͵ØÍ¼¶Áȡʱ²»À»Ø  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ³õʼ»¯Öк͵ØÍ¼¶Áȡʱ²»À»Ø  | 
| def __CanPullPlayer(curPlayer):  | 
|     if not curPlayer.GetInitOK():  | 
|         return False  | 
|       | 
|     if curPlayer.GetIsLoginOff():  | 
|         return False  | 
|       | 
|     return True  | 
| #------------------------------------------------------------------------------------   | 
| ##·µ»ØÍæ¼Òµ±Ç°ÊÇ·ñÔÚ¿ÕÏÐ״̬  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ÊÇ·ñÔÚ¿ÕÏÐ״̬  | 
| # @remarks ·µ»ØÍæ¼Òµ±Ç°ÊÇ·ñÔÚ¿ÕÏÐ״̬£¨²ß»®²ãÃæÉϵĿÕÏУ©  | 
| def IsPlanStateNull(curPlayer):  | 
|       | 
|     #·Ç¿ÕÏÐ״̬  | 
|     if curPlayer.GetPlayerAction() != IPY_GameWorld.paNull:  | 
|         return False  | 
|       | 
|     #ÒÆ¶¯ÖÐ  | 
|     if curPlayer.IsMoving():  | 
|         return False  | 
|       | 
|     #Õ½¶·ÖÐ  | 
|     if curPlayer.IsBattleState():  | 
|         return False  | 
|       | 
| #    #¶ÔÖÅÖÐ  | 
| #    if curPlayer.GetIsConfronting():  | 
| #        return False  | 
|       | 
| #    #Ñ£ÔÎÖÐ  | 
| #    if curPlayer.GetAbnormalState() == IPY_GameWorld.sctFaint:  | 
| #        return False  | 
|       | 
|     return True  | 
| #------------------------------------------------------------------------------------  | 
| ##³õʼ»¯Íæ¼Ò±³°ü.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ³õʼ»¯Íæ¼Ò±³°ü  | 
| def Init_ItemPack(curPlayer):  | 
|     packType = IPY_GameWorld.rptItem  | 
|       | 
|     #³õʼ»¯Íæ¼Ò±³°ü  | 
|     if packType not in ChConfig.Def_Type_CanBuyPack_PlayerDict.keys():  | 
|         return  | 
|       | 
|     #»ñÈ¡Íæ¼Ò±³°ü  | 
|     curPack = curPlayer.GetItemManager().GetPack(packType)  | 
|       | 
|     #ĬÈÏ14¸ñ×Ó + ¿ªÆôµÄ  | 
|     keyName = ChConfig.Def_Type_CanBuyPack_PlayerDict.get(packType)[ChConfig.Def_PlayerPackDict_Index_Key]  | 
|     count = ChConfig.Def_PlayerFirstLoginOpenBackCnt + curPlayer.NomalDictGetProperty(keyName)  | 
|     curPack.SetCount(count)  | 
|           | 
|     #֪ͨ¿Í»§¶Ë±³°ü¸ñ×ÓÊýÄ¿  | 
| #    curPlayer.Sync_ItemCount(curPack.GetCount())  | 
|     curPack.Sync_PackCanUseCount()  | 
|     return  | 
|   | 
| #------------------------------------------------------------------------------------  | 
| ##³õʼ»¯Íæ¼Ò²Ö¿â.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ³õʼ»¯Íæ¼Ò²Ö¿â  | 
| def Init_Warehouse(curPlayer):  | 
|       | 
|     packType = IPY_GameWorld.rptWarehouse  | 
|       | 
|     #³õʼ»¯Íæ¼Ò±³°ü  | 
|     if packType not in ChConfig.Def_Type_CanBuyPack_PlayerDict.keys():  | 
|         return  | 
|       | 
|     #»ñÈ¡Íæ¼Ò±³°ü  | 
|     curPack = curPlayer.GetItemManager().GetPack(packType)  | 
|       | 
|     #ĬÈÏ42¸ñ×Ó + ¿ªÆôµÄ  | 
|     keyName = ChConfig.Def_Type_CanBuyPack_PlayerDict.get(packType)[ChConfig.Def_PlayerPackDict_Index_Key]  | 
|     count = ChConfig.Def_FirstLogin_OpenWareHouseCnt + curPlayer.NomalDictGetProperty(keyName)  | 
|       | 
|     curPack.SetCount(count)  | 
|       | 
|     #֪ͨ¿Í»§¶Ë  | 
|     curPack.Sync_PackCanUseCount()  | 
|     return  | 
|       | 
|   | 
|   | 
|   | 
| ##³õʼ»¯Ñ°±¦±³°ü  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return None  | 
| def Init_TreasurePack(curPlayer):  | 
|     curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptTreasure)  | 
|     curPack.SetCount(ChConfig.Def_PackCnt_Treasure)  | 
|       | 
|     #֪ͨ¿Í»§¶Ë  | 
|     curPack.Sync_PackCanUseCount()  | 
|     return  | 
|   | 
| ##³õʼ»¯Íæ¼ÒÊÕÄɹñ  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param packType ±³°üÀàÐÍ  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def Init_CabinetCountByType(curPlayer, packType):  | 
|     keyName = ChConfig.Def_Type_CanBuyPack_PlayerDict.get(packType)[ChConfig.Def_PlayerPackDict_Index_Key]  | 
|     if keyName == None:  | 
|         GameWorld.ErrLog("Init_Pack Error type=%s" % packType)  | 
|         return  | 
|       | 
|     #³õʼ»¯Ê±×°ÎäÆ÷±³°ü  | 
|     curPack = curPlayer.GetItemManager().GetPack(packType)  | 
|     #ĬÈÏ14¸ñ×Ó + ¿ªÆôµÄ  | 
|     count = ChConfig.Def_PackCnt_WeaponCoat + curPlayer.NomalDictGetProperty(keyName)  | 
|     curPack.SetCount(count)  | 
|       | 
|     #֪ͨ¿Í»§¶Ë  | 
|     curPack.Sync_PackCanUseCount()  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| def RefreshOperationAction_ExpRate():  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for i in xrange(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or not curPlayer.GetInitOK():  | 
|             continue  | 
|         Sync_ExpRateChange(curPlayer)  | 
|     return  | 
|   | 
| ##Í¨ÖªÍæ¼Ò¾Ñé±¶ÂÊ  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Í¨ÖªÍæ¼Ò¾Ñé±¶ÂÊ  | 
| def Sync_ExpRateChange(curPlayer):  | 
|     totalExpRate = GetPlayerExpRate(curPlayer)  | 
|     fightExpRate = curPlayer.GetFightExpRate() # ÏµÍ³¼°¹¦ÄÜÀÛ¼Ó  | 
|     fightExpRate += PlayerWorldAverageLv.GetWorldAverageLvExpRate(curPlayer) # ÊÀ½çµÈ¼¶  | 
|     fightExpRate += PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_FightExpRate) # VIP¼Ó³É  | 
|       | 
|     actExpRateInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_ExpRate, {})# ¶à±¶¾Ñé»î¶¯¼Ó³É  | 
|     if not PlayerTJG.GetIsTJG(curPlayer) and actExpRateInfo.get(ShareDefine.ActKey_State):  | 
|         actExpIpyData = IpyGameDataPY.GetIpyGameData("ActExpRate", actExpRateInfo.get(ShareDefine.ActKey_CfgID))  | 
|         if actExpIpyData and curPlayer.GetLV() >= actExpIpyData.GetLVLimit():  | 
|             fightExpRate += actExpIpyData.GetAddExpRate()  | 
|               | 
|     if curPlayer.GetMapID() not in [ChConfig.Def_FBMapID_FamilyInvade]: #ÊØÎÀÈ˻ʲ»¼Ó×é¶Ó¼Ó³É  | 
|         fightExpRate += curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TeamExpRate) # ×é¶Ó  | 
|       | 
|     #µØÍ¼¶à±¶¾Ñé¼Ó³É£¬Ä¬ÈÏÊÇ1±¶²»¼Ó³É  | 
|     mapExpAddMultiple = max(0, FBCommon.GetAreaRewardMultiple(curPlayer) - 1)  | 
|     fightExpRate += mapExpAddMultiple * ChConfig.Def_MaxRateValue  | 
|       | 
|     if totalExpRate != fightExpRate:  | 
|         curPlayer.SetDict(ChConfig.Def_PlayerKey_TotalExpRate, fightExpRate)  | 
|         curPlayer.Sync_CurExpRate(fightExpRate)  | 
|     return  | 
|   | 
| ##»ñÈ¡Íæ¼ÒµÄ¾Ñé±¶ÂÊ  | 
| def GetPlayerExpRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)  | 
| def GetLimitExpRate(curPlayer, limitType=None):  | 
|     ''' »ñÈ¡ÊÜÏÞ¹¦ÄÜ×ܾÑé±¶ÂÊ  | 
|     @param limitType: ÊÜÏ޵ŦÄÜÀàÐÍ  | 
|     '''  | 
|     totalExpRate = GetPlayerExpRate(curPlayer)  | 
|     if limitType == None:  | 
|         return totalExpRate  | 
|       | 
|     # ¿Û³ýÔöÖµbuffÖжÔÓ¦ÏÞÖÆµÄ¼Ó³É  | 
|     buffState = curPlayer.GetIncBuff()  | 
|     for i in xrange(buffState.GetBuffCount()):  | 
|         curBuff = buffState.GetBuff(i)  | 
|         buffSkill = curBuff.GetSkill()  | 
|         for j in range(buffSkill.GetEffectCount()):  | 
|             curEffect = buffSkill.GetEffect(j)  | 
|             effectID = curEffect.GetEffectID()  | 
|             if effectID == 0:  | 
|                 break  | 
|               | 
|             if effectID != ChConfig.TYPE_Calc_AttrFightExpRate:  | 
|                 continue  | 
|               | 
|             effExpRate = curEffect.GetEffectValue(0)  | 
|             calcType = curEffect.GetEffectValue(1)  | 
|             limitTypeValue = curEffect.GetEffectValue(2) # °´Î»¼ÆËã  | 
|               | 
|             if calcType != ChConfig.EffCalcType_LinePlus or not limitTypeValue:  | 
|                 continue  | 
|               | 
|             if limitTypeValue & pow(2, limitType):  | 
|                 totalExpRate -= effExpRate  | 
|                   | 
|     return totalExpRate  | 
|   | 
| ##¼ÇÂ¼Íæ¼Òʧȥ½ðÇ®µÄÁ÷Ïò¼Ç¼£¬ÏûÏ¢Öлá¼ÇÂ¼Íæ¼ÒÓµÓеĽðÇ®ÐÅÏ¢  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param moneyType ½ðÇ®ÀàÐÍ  | 
| # @param logIndex Á÷Ïò¼Ç¼Ë÷Òý  | 
| # @param tagID ÔÚ´ËÓÃÓÚ¼ÇÂ¼ÌØ±ð±êʶ(ÎïÆ·ID£©  | 
| # @param par ÔÚ´ËÓÃÓڼǼ½ð¶î  | 
| # @param msg ¼ÇÂ¼ÌØ±ðµÄÐÅÏ¢  | 
| # @return None   | 
| def DataServerMoneyLog(curPlayer, moneyType, logIndex, tagID=0, par=0, msg=""):  | 
|     return  | 
|   | 
| #===============================================================================  | 
| #---Íæ¼ÒÀ©Õ¹×Ö¶Î---  | 
|   | 
| #---À©Õ¹×Ö¶Î2,3,5,9,12,13,14---  | 
| #---À©Õ¹×Ö¶Î1-Ö°Òµ½×¼¶£»4-µ±Ç°·À»¤Öµ£»6-ÍÇ®µã£»7-SPÕæÆøÖµ£»8-SPÕæÆøÖµÀ©Õ¹µã£»10-¿ç·þÔ¤ÈüÅÅλ£»11-¹Ù¾ôÐǼ¶£»---  | 
| # SetExAttr1 ~ SetExAttr14(DWORD uiExAttr10, bool bNotifyAll = false, bool bNotifyGameServer = false)  | 
| # @param bNotifyAll: ÊÇ·ñ¹ã²¥ËùÖÜÎ§Íæ¼Ò£¬Ä¬ÈÏfalse£¬Ö»»á·¢¸ø×Ô¼º  | 
| # @param bNotifyGameServer: ÊÇ·ñͬ²½GameServer£¬Ä¬ÈÏfalse  | 
| # SetExAttr15 ~ SetExAttr20(DWORD uiExAttr15)   | 
| #     15~20À©Õ¹ÊôÐÔͬ²½·â°ü£º0309 Ñ¡½ÇµÇ¼¼ò¶ÌÐÅÏ¢¡¢0434 ÖÜÎ§Íæ¼Ò³öÏÖ¡¢0102 µÇ¼µØÍ¼Íæ¼ÒÐÅÏ¢£»  | 
| #     Í¬²½Ç°¶Ë¼°GameServerÐèÒª×Ô¼ºÐ´Í¨Öª£¬ÉèÖú¯Êý×ÔÉí²»´øÍ¨Öª²ÎÊý  | 
| #  | 
| # ·¢ËÍ0418°ü  | 
| # SendPropertyRefresh(int inputType, int inputValue, int inputValueEx, bool boardCast, bool includeSelf = true)  | 
| # @param : boardCast-ÊÇ·ñ¹ã²¥ÖÜÎ§Íæ¼Ò£»includeSelf-ÊÇ·ñ°üº¬×Ô¼º  | 
| #  | 
| # Í¨ÖªGsmeServer;   | 
| # SendGameServerRefreshState(int inputType, int inputValue, int inputValueEx)  | 
|   | 
| def SendPropertyRefresh(curPlayer, inputType, value, boardCast=False):  | 
|     ''' ·¢ËÍ0418°ü  | 
|     @param boardCast: ÊÇ·ñ¹ã²¥ÖÜÎ§Íæ¼Ò£¬Ò»¶¨»á·¢¸ø×Ô¼º  | 
|     '''  | 
|     curPlayer.SendPropertyRefresh(inputType, value % ShareDefine.Def_PerPointValue, value / ShareDefine.Def_PerPointValue, boardCast)  | 
|     return  | 
|   | 
| def SendGameServerRefreshState(curPlayer, inputType, value):  | 
|     ## Í¬²½ÊôÐÔµ½GameServer IPY_GRefreshPlayerProperty  | 
|     curPlayer.SendGameServerRefreshState(inputType, value % ShareDefine.Def_PerPointValue, value / ShareDefine.Def_PerPointValue)  | 
|     return  | 
|   | 
| # ½ûÑԠ֪ͨgameServer  | 
| def SetGMForbidenTalk(curPlayer, value):  | 
|     ''' ÉèÖÃÊÇ·ñ½ûÑÔ  | 
|     @param value: 0-½â½û£»1-½ûÑÔ£»2-½ûÉ豸£»3-½âÉ豸  | 
|       | 
|     ½ûÉ豸Á÷³Ì  | 
|     1.ÏÈÉèÖÃ2֪ͨǰ¶ËдÈë½ûÉ豸¼Ç¼£¨Ç°¶Ë´¦Àíµ±Îª2ʱ±¾µØÉ豸±ê¼ÇΪ½ûÉ豸£©   | 
|     2.ÔÙÉèÖÃ1£¬´Ëʱǰºó¶Ë״̬¾ùΪ1£¬¼´½ÇÉ«½ûÑÔ  | 
|       | 
|     ½â½ûÉ豸Á÷³Ì  | 
|     1.ÏÈÉèÖÃ3֪ͨǰ¶Ëɾ³ý½ûÉ豸¼Ç¼  | 
|     2.ÔÙÉèÖÃ0£¬´Ëʱǰºó¶Ë״̬¾ùΪ1£¬¼´½ÇÉ«½â½û  | 
|     '''  | 
|     __SetGMForbidenTalkValue(curPlayer, value)  | 
|       | 
|     #ͬ²½ÉèÖÃÀëÏßDBÍæ¼ÒÕ˺Å״ֵ̬  | 
|     accState = curPlayer.GetAccState()  | 
|     if value == 2:  | 
|         accState = accState | pow(2, ChConfig.Def_PysForbidTalkDevice)  | 
|         accState = accState | pow(2, ChConfig.Def_PysForbidTalk)  | 
|     elif value == 1:  | 
|         accState = accState | pow(2, ChConfig.Def_PysForbidTalk)  | 
|     elif value == 3:  | 
|         if (accState & pow(2, ChConfig.Def_PysForbidTalkDevice)):  | 
|             accState = accState ^ pow(2, ChConfig.Def_PysForbidTalkDevice)  | 
|         if (accState & pow(2, ChConfig.Def_PysForbidTalk)):  | 
|             accState = accState ^ pow(2, ChConfig.Def_PysForbidTalk)  | 
|     elif (accState & pow(2, ChConfig.Def_PysForbidTalk)) > 0:  | 
|         accState = accState ^ pow(2, ChConfig.Def_PysForbidTalk)  | 
|     SetPlayerAccState(curPlayer, accState)  | 
|     return  | 
|   | 
| def __SetGMForbidenTalkValue(curPlayer, value):  | 
|     curPlayer.SetGMForbidenTalk(value)  | 
|     SendGameServerRefreshState(curPlayer, ShareDefine.CDBPlayerRefresh_ForbidenTalk, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ForbidenTalk, value)  | 
|     GameWorld.DebugLog("__SetGMForbidenTalkValue %s" % value, curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def SetPlayerAccState(curPlayer, accState):  | 
|     curPlayer.SetAccState(accState)  | 
|     curPlayer.SetExAttr17(accState) # Í¬²½ÉèÖøÃÖµ 0309 ·â°üµÇ¼ʱÐèÒªÓõ½  | 
|     SendGameServerRefreshState(curPlayer, ShareDefine.CDBPlayerRefresh_ExAttr17, accState)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ExAttr17, accState)  | 
|     GameWorld.DebugLog("SetPlayerAccState %s" % (accState), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def DoGMForbidenTalkOnLogin(curPlayer):  | 
|     ## ÀëÏßʱ±»½ûÑÔ£¬´ËʱDBµÄÕ˺Å״ֵ̬Ϊ½ûÑÔ״̬£¬µ«ÊÇGMOperÔÝʱûÓнûÑÔ²Ù×÷ÃüÁ¹ÊÉÏÏßʱ¼ì²éÉèÖÃÏÂÀëÏß½ûÑÔ״̬  | 
|     ## Ä¿Ç°ÀëÏßʱ±»½ûÑԵģ¬ÔÝʱֻ´¦ÀíAccState ExAttr17, GMOperÃüÁîÔݲ»´¦Àí£¬ËùÒÔΪÓÀ¾Ã½ûÑÔ  | 
|       | 
|     if curPlayer.GetAccState() & pow(2, ChConfig.Def_PysForbidTalkDevice):  | 
|         GameWorld.Log("ÉÏÏßʱ½ÇɫΪ±»É豸½ûÑÔ״̬!", curPlayer.GetPlayerID())  | 
|         __SetGMForbidenTalkValue(curPlayer, 2)  | 
|         __SetGMForbidenTalkValue(curPlayer, 1)  | 
|     elif curPlayer.GetAccState() & pow(2, ChConfig.Def_PysForbidTalk):  | 
|         GameWorld.Log("ÉÏÏßʱ½ÇɫΪ±»½ûÑÔ״̬!", curPlayer.GetPlayerID())  | 
|         __SetGMForbidenTalkValue(curPlayer, 1)  | 
|     else:  | 
|         SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ForbidenTalk, 0)  | 
|     return  | 
|   | 
| ## ÐÖúÄ¿±êÍæ¼ÒID  | 
| def SetAssistTagPlayerID(curPlayer, value):  | 
|     curPlayer.SetExAttr1(value, True, False) # ²»Í¨ÖªGameServer  | 
|     NPCHurtManager.OnSetAssistTagPlayerID(curPlayer, value)  | 
|     return  | 
| def GetAssistTagPlayerID(curPlayer): return curPlayer.GetExAttr1()  | 
|   | 
| ## ¶ÓÎéÏà¹ØÉóºË¿ª¹Ø×´Ì¬, joinReqCheck-Èë¶ÓÉêÇëÊÇ·ñÐèÒªÉóºË; inviteCheck-×é¶ÓÑûÇëÊÇ·ñÐèÒªÉóºË;  | 
| def SetTeamCheckStateEx(curPlayer, joinReqCheck, inviteCheck): return SetTeamCheckState(curPlayer, joinReqCheck * 10 + inviteCheck)  | 
| def SetTeamCheckState(curPlayer, checkState): return curPlayer.SetExAttr2(checkState, False, True)  | 
| def GetTeamCheckState(curPlayer): return curPlayer.GetExAttr2()  | 
|   | 
| ## ¸±±¾¹¦ÄÜÏß·ID, ÕâÀï×ödb´æ´¢£¬·ÀÖ¹Ôںϲ¢µØÍ¼¸±±¾ÖеôÏßÖØÉÏʱǰ¶ËÎÞ·¨¼ÓÔØÕýÈ·µÄ³¡¾°×ÊÔ´£¬µÇ¼¼ÓÔØ³¡¾°Ê±»úΪ0102°ü  | 
| def SetFBFuncLineID(curPlayer, funcLineID): return curPlayer.SetExAttr3(funcLineID, False, True)  | 
| def GetFBFuncLineID(curPlayer): return curPlayer.GetExAttr3()  | 
|   | 
| ## ¿ç·þ״̬ËùÔÚµØÍ¼ID: 0-·Ç¿ç·þ״̬£¬·Ç0-¿ç·þ״̬¶ÔÓ¦µÄµØÍ¼ID  | 
| def GetCrossMapID(curPlayer): return curPlayer.GetExAttr5()  | 
| def SetCrossMapID(curPlayer, value):  | 
|     curPlayer.SetExAttr5(value, False, True)  | 
|     if not value:  | 
|         CrossPlayerData.ClearCrossSyncDataCache(curPlayer)  | 
|     return  | 
|   | 
| ## Ç°¶Ë×Ô¶¨Ò峡¾°  | 
| def GetCustomMapID(curPlayer): return curPlayer.GetExAttr14() / 1000  | 
| def GetCustomLineID(curPlayer): return curPlayer.GetExAttr14() % 1000  | 
| ## ×Ô¶¨Ò峡¾°ºó¶ËÅжÏÒѽáËãºóÐèÖ±½ÓÖØÖÃΪ0£¬·Àֹǰ¶ËûÓÐÍ˳ö³¡¾°Ö±½ÓÏÂÏßµ¼ÖÂÊý¾ÝûÓÐÖØÖ㬿ÉÄÜÒý·¢¿ÉÒÔÖØ¸´½ø  | 
| def SetCustomMap(curPlayer, mapID, lineID):  | 
|     value = mapID * 1000 + lineID  | 
|     if value != curPlayer.GetExAttr14():  | 
|         curPlayer.SetExAttr14(value, False, True)  | 
|     return  | 
|   | 
| ## ÍÇ®µã, Ö§³ÖÍÇ®³¬20ÒÚ  | 
| def GetSilver(curPlayer): return curPlayer.GetExAttr6() * ChConfig.Def_PerPointValue + curPlayer.GetSilver()  | 
| def SetSilver(curPlayer, totalSilver):  | 
|     silver = totalSilver % ChConfig.Def_PerPointValue  | 
|     silverPoint = min(totalSilver / ChConfig.Def_PerPointValue, ChConfig.Def_UpperLimit_DWord)  | 
|     if silver != curPlayer.GetSilver():  | 
|         curPlayer.SetSilver(silver)  | 
|     if silverPoint != curPlayer.GetExAttr6():  | 
|         curPlayer.SetExAttr6(silverPoint)  | 
|     return  | 
|   | 
| ##VIPµ½ÆÚʱ¼ä, ÐèҪͬ²½GameServer  | 
| def GetVIPExpireTime(curPlayer): return 0  | 
| def SetVIPExpireTime(curPlayer, expireTime): return  | 
|   | 
| ##×î½üÒ»´ÎÌáÉýVIPµÈ¼¶Ê±¼ä  | 
| def GetVIPLVUpTime(curPlayer): return curPlayer.GetExAttr9()  | 
| def SetVIPLVUpTime(curPlayer, lvUpTime): return curPlayer.SetExAttr9(lvUpTime, False, True)  | 
|   | 
| ##ÁÄÌìÆøÅÝ¿ò  | 
| def GetChatBubbleBox(curPlayer): return curPlayer.GetExAttr10()  | 
| def SetChatBubbleBox(curPlayer, value): return curPlayer.SetExAttr10(value, False, True)  | 
|   | 
| ##°é  | 
| def GetCoupleID(curPlayer):  | 
|     coupleInfo = GetCoupleInfo(curPlayer.GetPlayerID())  | 
|     return coupleInfo[0] if coupleInfo else 0  | 
| def GetCoupleName(curPlayer):  | 
|     coupleInfo = GetCoupleInfo(curPlayer.GetPlayerID())  | 
|     return coupleInfo[1] if coupleInfo else ""  | 
| def GetCoupleJob(curPlayer):  | 
|     coupleInfo = GetCoupleInfo(curPlayer.GetPlayerID())  | 
|     return coupleInfo[2] if coupleInfo else 1  | 
| def GetBridePriceMaxID(curPlayer):  | 
|     coupleInfo = GetCoupleInfo(curPlayer.GetPlayerID())  | 
|     return coupleInfo[3] if coupleInfo else 0  | 
| def GetCoupleInfo(playerID):  | 
|     if playerID not in PyGameData.g_coupleInfo:  | 
|         return  | 
|     return PyGameData.g_coupleInfo[playerID]  | 
| def SetCoupleInfo(playerID, coupleInfo):  | 
|     if not coupleInfo:  | 
|         PyGameData.g_coupleInfo.pop(playerID, None)  | 
|     else:  | 
|         PyGameData.g_coupleInfo[playerID] = coupleInfo  | 
|     return  | 
|   | 
| ## Íæ¼ÒËùÊô·þÎñÆ÷×éID  | 
| def GetPlayerServerGroupID(curPlayer): return curPlayer.GetExAttr13()  | 
| def UpdPlayerServerGroupID(curPlayer):  | 
|     # ¸üÐÂ×Ô¼ºµÄ·þÎñÆ÷×éID, ¿ç·þ·þÎñÆ÷²»´¦Àí  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|     serverGroupID = GameWorld.GetServerGroupID()  | 
|     if not serverGroupID:  | 
|         return  | 
|     playerServerGroupID = curPlayer.GetExAttr13()  | 
|     if playerServerGroupID != serverGroupID:  | 
|         curPlayer.SetExAttr13(serverGroupID, False, True)  | 
|         GameWorld.DebugLog("¸üÐÂÍæ¼ÒËùÊô·þÎñÆ÷×éID: serverGroupID=%s" % serverGroupID)  | 
|     return  | 
|   | 
| ##Ó°ÏìÍâ¹ÛµÄ3²¿Î»Ë÷Òý¼Ç¼ 123456789  123:ÎäÆ÷¸ñ×ÓË÷Òý 456£º¸±ÊÖ  789£ºÒ·þ  | 
| def GetFaceEquipIndexList(curPlayer):  | 
|     attr15 = curPlayer.GetExAttr15()  | 
|     return [attr15%1000, attr15/1000%1000, attr15/1000000]  | 
| def SetFaceEquipIndex(curPlayer, value): return curPlayer.SetExAttr15(value)  | 
|   | 
| # ·µ»Ø×î´óµÄÁé¸ùϵ  | 
| def GetLingGenMaxIndex(curPlayer):  | 
|     return curPlayer.GetExAttr16()  | 
|   | 
| def SetLingGenMaxIndex(curPlayer):  | 
|     indexList = [  | 
|                     ShareDefine.Def_Effect_Metal, # ½ð  | 
|                     ShareDefine.Def_Effect_Wood, # Ä¾  | 
|                     ShareDefine.Def_Effect_Water, # Ë®  | 
|                     ShareDefine.Def_Effect_Fire, # »ð  | 
|                     ShareDefine.Def_Effect_Earth, # ÍÁ  | 
|                 ]  | 
|       | 
|       | 
|     tempList = [curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % attrID) for attrID in indexList]  | 
|       | 
|     curPlayer.SetExAttr16(indexList[tempList.index(max(tempList))])  | 
|   | 
| # ¾³½çÄѶȵȼ¶  | 
| def GetRealmDifficulty(curPlayer): return curPlayer.GetExAttr18()  | 
| def SetRealmDifficulty(curPlayer, realmDifficulty):  | 
|     ''' ÉèÖþ³½çÄѶȵȼ¶£¬ÈκεØÍ¼¾ù¿ÉÑ¡Ôñ  | 
|     '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     if realmDifficulty:  | 
|         needRealmLV = GetDifficultyRealmLV(realmDifficulty)  | 
|         curRealmLV = curPlayer.GetOfficialRank()  | 
|         if curRealmLV < needRealmLV:  | 
|             GameWorld.DebugLog("µ±Ç°¾³½çµÍÓÚ¾³½çÄѶȣ¬ÎÞ·¨Ñ¡Ôñ! curRealmLV(%s) < %s" % (curRealmLV, needRealmLV), playerID)  | 
|             return  | 
|           | 
|         difficultyRealmList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 2)  | 
|         if needRealmLV not in difficultyRealmList:  | 
|             GameWorld.ErrLog("realmDifficulty(%s) needRealmLV(%s) not in difficultyRealmList(%s)"   | 
|                              % (realmDifficulty, needRealmLV, difficultyRealmList), playerID)  | 
|             return  | 
|           | 
|     GameWorld.DebugLog("SetRealmDifficulty: realmDifficulty=%s" % realmDifficulty, playerID)  | 
|     realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)  | 
|     mapID = curPlayer.GetMapID()  | 
|     if mapID in realmMapIDList:  | 
|         # ÏÈÒÆ³ý֮ǰѡµÄÄÑ¶È  | 
|         for playerIDList in PyGameData.g_realmDiffPlayerDict.values():  | 
|             if playerID in playerIDList:  | 
|                 playerIDList.remove(playerID)  | 
|                   | 
|         # ¼ÓÈëÐÂÄѶȣ¬0ÄѶȲ»´¦Àí  | 
|         if realmDifficulty:  | 
|             if realmDifficulty not in PyGameData.g_realmDiffPlayerDict:  | 
|                 PyGameData.g_realmDiffPlayerDict[realmDifficulty] = []  | 
|             playerIDList = PyGameData.g_realmDiffPlayerDict[realmDifficulty]  | 
|             if playerID not in playerIDList:  | 
|                 playerIDList.append(playerID)  | 
|                   | 
|         SetPlayerSightLevel(curPlayer, realmDifficulty)  | 
|           | 
|     if curPlayer.GetExAttr18() != realmDifficulty:  | 
|         curPlayer.SetExAttr18(realmDifficulty)  | 
|         SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ExAttr18, realmDifficulty)  | 
|     return  | 
| def GetDifficultyRealmLV(realmDifficulty): return realmDifficulty - 100  | 
| def GetMapRealmDifficulty(curPlayer):  | 
|     ## »ñÈ¡Íæ¼ÒÔÚ±¾µØÍ¼Öеľ³½çÄѶȲ㼶£¬±ØÐëÔÚ¾³½çµØÍ¼ÇÒÓÐÑ¡Ôñ¾³½çÄѶȲÅË㣬·ñÔòΪĬÈÏ0£»¸ÃÄѶÈֵͬʱҲÊÇÊÓÒ°²ã¼¶  | 
|     realmDifficulty = GetRealmDifficulty(curPlayer)  | 
|     if not realmDifficulty:  | 
|         return 0  | 
|     mapID = curPlayer.GetMapID()  | 
|     realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)  | 
|     if mapID not in realmMapIDList:  | 
|         return 0  | 
|     return realmDifficulty  | 
|   | 
| ##»ñµÃÍæ¼ÒÍþÍûÖµ  | 
| def GetPrestige(curPlayer): return 0  | 
| def SetPrestige(curPlayer, value): return  | 
|   | 
| ##×ÜÕ½¶·Á¦£¬Ö§³Ö³¬¹ý20E  | 
| def GetFightPower(curPlayer): return curPlayer.GetFightPowerEx() * ChConfig.Def_PerPointValue + curPlayer.GetFightPower()  | 
| def SetFightPower(curPlayer, value):  | 
|     curPlayer.SetFightPower(value % ChConfig.Def_PerPointValue, value / ChConfig.Def_PerPointValue, False) # ²»Í¨ÖªGameServer bNotifyGameServer False  | 
|     return  | 
|   | 
| ## ÉèÖÃÄ£¿éÕ½¶·Á¦£¬×î´ó20E  | 
| def SetMFPFightPower(curPlayer, mfpType, fightPower):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPFightPower % mfpType, min(fightPower, ChConfig.Def_UpperLimit_DWord))  | 
|     return  | 
|   | 
| ## »ñȡģ¿éÕ½¶·Á¦  | 
| def GetMFPFightPower(curPlayer, mfpType):  | 
|     return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPFightPower % mfpType)  | 
|   | 
| ## ÉèÖÃÄ£¿é¸½¼ÓÕ½¶·Á¦£¬Ö§³Ö³¬¹ý20E  | 
| def SetMFPExFightPower(curPlayer, mfpType, fightPower):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % mfpType, fightPower % ChConfig.Def_PerPointValue)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPExPoint % mfpType, fightPower / ChConfig.Def_PerPointValue)  | 
|     return  | 
|   | 
| ## »ñȡģ¿é¸½¼ÓÕ½¶·Á¦  | 
| def GetMFPExFightPower(curPlayer, mfpType):  | 
|     return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPExPoint % mfpType) * ChConfig.Def_PerPointValue + \  | 
|         curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MFPEx % mfpType)  | 
| #===============================================================================  | 
| ##»ñÈ¡Íæ¼Ò·ÖÏßÐÅÏ¢  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return Íæ¼Òµ±Ç°·ÖÏßID  | 
| # @remarks   | 
| def GetPlayerLineID(curPlayer):  | 
|     return curPlayer.GetLineID() + 1  | 
|   | 
|   | 
| ##ÊÓÒ°ÑéÖ¤, Íâ¹ÒÊÓÒ°±äС²»»Ö¸´  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param sight ÊÓÒ°·¶Î§  | 
| # @return ÎÞÒâÒå  | 
| def SetSight(curPlayer, sight):  | 
|     import QuestCommon  | 
|     firstMission = QuestCommon.GetCommonMission(curPlayer)  | 
|     if firstMission and firstMission.GetProperty(QuestCommon.Def_NewGuyNoSight) == 1:  | 
|         curPlayer.SetSight(0)  | 
|         return  | 
|       | 
|     #Íâ¹ÒºÅ ÊÓÒ°ÑéÖ¤  | 
|     if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_State) \  | 
|                                       == ChConfig.Def_AutoCheck_State_Danger:  | 
|           | 
|         if curPlayer.GetSight() > sight:  | 
|             curPlayer.SetSight(sight)  | 
|           | 
|         return  | 
|       | 
|     curPlayer.SetSight(sight)  | 
|   | 
| ##»ñÈ¡¹¥»÷¼ä¸ô  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ¹¥»÷¼ä¸ô  | 
| def GetAtkInterval(curPlayer):  | 
|     atkInterval = curPlayer.GetAtkInterval()  | 
|       | 
|     #Íâ¹ÒºÅ ¹¥»÷¼ä¸ôÑéÖ¤  | 
|     if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_State) \  | 
|                                       == ChConfig.Def_AutoCheck_State_Danger:  | 
|         atkInterval *= 100  | 
|       | 
|     return atkInterval  | 
|   | 
| def AddZhenQiByKillNPC(curPlayer, npcSP, killCount=1):  | 
|     ## É±¹Ö¼ÓÕæÆø  | 
|     if not npcSP:  | 
|         return  | 
|     addSPValue = npcSP * killCount  | 
|     npcSPRate = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_NPCSPRate)  | 
|       | 
|     if npcSPRate:  | 
|         npcHPRate = ChConfig.Def_MaxRateValue + npcSPRate  | 
|         addSPValue = int(addSPValue * npcHPRate / float(ChConfig.Def_MaxRateValue))  | 
|     PlayerAddZhenQi(curPlayer, addSPValue)  | 
|     return  | 
|   | 
| ##Íæ¼ÒÔö¼ÓÕæÆø  | 
| # @param curPlayer Íæ¼Ò  | 
| # @param value Ôö¼ÓÊýÖµ  | 
| # @param canOverbrim ¿É·ñÒç³ö(ĬÈϲ»ÐÐ)   | 
| # @param isSysMsg ÊÇ·ñϵͳÌáʾ(ĬÈÏÐèÒª)   | 
| # @return None  | 
| def PlayerAddZhenQi(curPlayer, addValue, canOverbrim=False, isSysMsg=True, eventName="unknown", eventData=""):  | 
|     if addValue <= 0:  | 
|         return True  | 
|       | 
|     curZhenQi = GetZhenQi(curPlayer)  # µ±Ç°ÕæÆø  | 
|       | 
|     value = curZhenQi + addValue  | 
|       | 
|     if value == curZhenQi:  | 
|         #ÕæÆøÖµÃ»ÓÐ¸Ä±ä  | 
|         return False  | 
|       | 
|     #===============================================================================================  | 
|     # if isSysMsg:  | 
|     #    #GeRen_chenxin_254483:»ñµÃÕæÆøÖµXXµã  | 
|     #    NotifyCode(curPlayer, "GeRen_chenxin_254483", [addValue])  | 
|     #===============================================================================================  | 
|       | 
|     SetZhenQi(curPlayer, value)  | 
|     #EventReport.WriteEvent_add_zhenqi(curPlayer, eventName, eventData, addValue, value)  | 
|     return True  | 
|   | 
|   | 
| ##Íæ¼Ò¼õÉÙÕæÆø  | 
| # @param curPlayer Íæ¼Ò  | 
| # @param lostValue ¼õÉÙÊýÖµ  | 
| # @return None  | 
| def PlayerLostZhenQi(curPlayer, lostValue, eventName="unknown", eventData=""):  | 
|     if lostValue <= 0:  | 
|         return True  | 
|       | 
|     curZhenQi = GetZhenQi(curPlayer)  # µ±Ç°ÕæÆø  | 
|       | 
|     value = max(0, curZhenQi - lostValue)  | 
|     if value < 0:  | 
|         GameWorld.ErrLog("curZhenQi = %s, lostValue = %s" % (curZhenQi, lostValue))  | 
|         return False  | 
|       | 
|     #GeRen_chenxin_365899:ÏûºÄÕæÆøÖµXXµã.  | 
|     #NotifyCode(curPlayer, "GeRen_chenxin_365899", [lostValue])  | 
|       | 
|     SetZhenQi(curPlayer, value)  | 
|       | 
|     #EventReport.WriteEvent_lost_zhenqi(curPlayer, eventName, eventData, lostValue, value)  | 
|     return True  | 
|   | 
| ## SPÕæÆøÖµ - ÔÝ·ÏÆú ExAttr7¡¢ExAttr8 ¸ÄΪר¾«Ñ¡Ôñ֪ͨ£¬ÓÃÓÚǰ¶Ë±íÏÖÆäËûÍæ¼ÒµÄ²»Í¬×¨¾«ÌØÐ§  | 
| def GetZhenQi(curPlayer): return 0 #curPlayer.GetExAttr8() * ChConfig.Def_PerPointValue + curPlayer.GetExAttr7()  | 
| def SetZhenQi(curPlayer, totalZhenQi):  | 
| #    zhenQi = totalZhenQi % ChConfig.Def_PerPointValue  | 
| #    zhenQiPoint = min(totalZhenQi / ChConfig.Def_PerPointValue, ChConfig.Def_UpperLimit_DWord)  | 
| #    # Íæ¼Òµ¥¶À֪ͨ£¬²»¹ã²¥; c++½Ó¿ÚĬÈϹ㲥£¬¹ÊÕâÀïÉèÖÃFalse  | 
| #    if zhenQi != curPlayer.GetExAttr7():  | 
| #        curPlayer.SetExAttr7(zhenQi)  | 
| #    if zhenQiPoint != curPlayer.GetExAttr8():  | 
| #        curPlayer.SetExAttr8(zhenQiPoint)  | 
|     return  | 
|   | 
| #===============================================================================  | 
| # #@warning: ExAttr6~ExAttr10, ÐÂÔö2¸ö²¼¶ûĬÈϲÎÊý, ÊÇ·ñ֪ͨ¿Í»§¶Ë, ÊÇ·ñ֪ͨGameServer, Ä¬ÈÏֵΪFalse  | 
| #===============================================================================  | 
| #---------------------------------------------------------------------------  | 
|   | 
| ##»ñÈ¡¿ÉÃâ·Ñ¿ªÆôµÄ¸ñ×ÓÊý  | 
| # @param curPlayer Íæ¼Ò¶ÔÏó  | 
| # @param packType ±³°üÀàÐÍ  | 
| # @param openCnt Êµ¼ÊÒª¿ªÆôµÄ¸ñ×ÓÊý  | 
| # @return »ñÈ¡¿ÉÃâ·Ñ¿ªÆôµÄ¸ñ×ÓÊý  | 
| def GetCanAutoOpenPackCount(curPlayer, packType, openCnt, tick):  | 
|     if packType not in [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse]:  | 
|         return 0  | 
|     cfgObj = PlayerExpandPackCfgMgr.GetExpandPackCfg(curPlayer, packType)  | 
|     #ÕÒ²»µ½ÕâÖÖ±³°üµÄÅäÖÃÐÅÏ¢¶ÔÏó  | 
|     if not cfgObj:  | 
|         return 0  | 
|     #ÒѹºÂò»ò×Ô¶¯¿ªÆôµÄ¸ñ×ÓÊý  | 
|     keyName = ChConfig.Def_Type_CanBuyPack_PlayerDict[packType][ChConfig.Def_PlayerPackDict_Index_Key]  | 
|     curCount = curPlayer.NomalDictGetProperty(keyName)  | 
|       | 
| #    nextCountIndex = curCount + 1  | 
| #    infoObj = cfgObj.GetAttrInfoByInex(nextCountIndex)  | 
| #    if None == infoObj:  | 
| #        return 0  | 
| #    #¸üÐÂÏÂÍæ¼ÒµÄÔÚÏßʱ¼ä  | 
| #    UpdateOnLineTime(curPlayer, tick)  | 
| #    onlineTime = curPlayer.GetOnlineTime()  | 
| #    #ÐèÒªµÄʱ¼ä  | 
| #    needOnlineTime = infoObj["OnlineTime"]  | 
| #    #×îºóÒ»´Î×Ô¶¯¿ªÆô±³°üµÄÔÚÏßʱ¼ätick  | 
| #    lastAutoOpenPackTick = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_LastAutoOpenPackTick)  | 
| #    if onlineTime - lastAutoOpenPackTick > needOnlineTime:  | 
| #        return 1  | 
| #    return 0  | 
|       | 
|     #×î´ó¿ÉÔö¼ÓµÄ±³°üÊý  | 
|     maxCanAddCount = cfgObj.GetCanAddCount()  | 
|     forCount = min(openCnt, maxCanAddCount - curCount)  | 
|       | 
|     #¿ÉÒÔÔÙÔö¼ÓµÄ¸ñ×ÓÊý  | 
|     count = 0  | 
|     #±éÀú¿ÉÔö¼ÓµÄ±³°ü¸ñ×ÓÊý  | 
|     UpdateOnLineTime(curPlayer, tick)  | 
|     onlineTime = curPlayer.GetOnlineTime()  | 
|     lastAutoOpenPackTick = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_LastAutoOpenPackTick % packType)  | 
|     lastInfoObj = cfgObj.GetTotalAddAttrInfoByCount(curCount)  | 
|     notOnlineTime = 0  | 
|     if lastInfoObj:  | 
|         notOnlineTime = lastInfoObj["OnlineTime"]  | 
| #    GameWorld.Log("get online time = %s"%onlineTime)  | 
|     for i in range(forCount):  | 
|         nextCount = curCount + i + 1  | 
|         infoObj = cfgObj.GetTotalAddAttrInfoByCount(nextCount)  | 
|         if None == infoObj:  | 
|             break  | 
|         # (СÓÚ0µÄ²»¾ßÓÐÃâ·Ñ¿ªÆô¹¦ÄÜ)  | 
|         if infoObj["OnlineTime"] < 0:  | 
|             continue  | 
|         needOnlineTime = infoObj["OnlineTime"] - notOnlineTime  | 
| #        GameWorld.Log("get need online time = %s"%needOnlineTime)  | 
|         #ÒªÇóµÄÔÚÏßʱ¼ä,´óÓÚµ±Ç°µÄÔÚÏßʱ¼ä,û°ì·¨¼Ó±³°ü¸ñ×Ó  | 
|         if needOnlineTime > onlineTime - lastAutoOpenPackTick:  | 
|             break  | 
|         count += 1  | 
|     return count  | 
|   | 
|   | 
|   | 
| ## »ñÈ¡½Ú¼ÙÈÕ¾Ñé¼Ó³É  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return: ½Ú¼ÙÈÕ¾Ñé¼Ó³É  | 
| def GetHolidayExpRate(curPlayer):  | 
|     return 0  | 
|   | 
|   | 
| ## »ñÈ¡ÊÀ½çboss¾Ñé¼Ó³É  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return: ÊÀ½çboss¾Ñé¼Ó³É  | 
| def GetWorldBossExpRate(curPlayer):  | 
|     return 0  | 
|   | 
| ## »ñÈ¡Íæ¼Òµ±Ç°µÈ¼¶Éý¼¶ËùÐè×ܾÑé  | 
| #  @param playerLv Íæ¼ÒµÈ¼¶  | 
| #  @return ·µ»ØÖµ, Éý¼¶ÐèÒªµÄ×ܾÑé  | 
| def GetLVUPTotalNeedExp(curPlayer):  | 
|     curLV = curPlayer.GetLV()  | 
|     #if curLV >= IpyGameDataPY.GetFuncCfg("PlayerMaxLV") and PlayerGreatMaster.IsGreatMasterOpen(curPlayer):  | 
|     #    return PlayerGreatMaster.GetTotalExpByGreatMasterLV(curPlayer.GetLV2())  | 
|       | 
|     return GetTotalExpByPlayerLv(curLV)  | 
|   | 
| ## ¸ù¾ÝµÈ¼¶»ñµÃÉý¼¶ÐèÒªµÄ×ܾÑé  | 
| #  @param playerLv Íæ¼ÒµÈ¼¶  | 
| #  @return ·µ»ØÖµ, Éý¼¶ÐèÒªµÄ×ܾÑé  | 
| def GetTotalExpByPlayerLv(playerLV):  | 
|     lvIpyData = GetPlayerLVIpyData(playerLV)  | 
|     if not lvIpyData:  | 
|         return 0  | 
|     return GetLVUPTotalExpNeed(lvIpyData)  | 
|   | 
| def GetPlayerLVIpyData(playerLV):  | 
|     lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", playerLV)  | 
|     if not lvIpyData:  | 
|         GameWorld.ErrLog("¾Ñé±íÒì³£  lv= %s" % playerLV)  | 
|         return  | 
|     return lvIpyData  | 
|   | 
| def GetLVUPTotalExpNeed(lvIpyData):  | 
|     if not lvIpyData:  | 
|         return 0  | 
|     return lvIpyData.GetExpPoint() * ChConfig.Def_PerPointValue + lvIpyData.GetExp()  | 
|   | 
| ## »ñµÃÍæ¼Òʵ¼ÊµÈ¼¶  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @return Íæ¼Òʵ¼ÊµÈ¼¶  | 
| def GetRealPlayerLv(curPlayer):  | 
|     #µ±Ç°µÈ¼¶  | 
|     realPlayerLv = curPlayer.GetLV()  | 
|     #µ±Ç°Íæ¼Ò×ܾÑé  | 
|     curTotalExp = GetPlayerTotalExp(curPlayer)  | 
|     return GetRealPlayerLvEx(realPlayerLv, curTotalExp)  | 
|   | 
| ## »ñµÃÍæ¼Òʵ¼ÊµÈ¼¶  | 
| #  @param realPlayerLv µ±Ç°µÈ¼¶  | 
| #  @param curTotalExp ×ܾÑé  | 
| #  @return Íæ¼Òʵ¼ÊµÈ¼¶  | 
| def GetRealPlayerLvEx(realPlayerLv, curTotalExp):  | 
|     #Éý¼¶ËùÐè×ܾÑé  | 
|     needTotalExp = GetTotalExpByPlayerLv(realPlayerLv)  | 
|     if not needTotalExp:  | 
|         return realPlayerLv  | 
|       | 
|     #Ä£ÄâÉý¼¶,»ñµÃʵ¼ÊµÈ¼¶  | 
|     while curTotalExp >= needTotalExp:  | 
|         realPlayerLv += 1  | 
|         curTotalExp -= needTotalExp  | 
|         needTotalExp = GetTotalExpByPlayerLv(realPlayerLv)  | 
|         if not needTotalExp:  | 
|             break  | 
|     return realPlayerLv  | 
|   | 
| ## »ñÈ¡Íæ¼Òµ±Ç°×ܾÑé  | 
| def GetPlayerTotalExp(curPlayer):  | 
|     totalExp = curPlayer.GetTotalExp() # Î´ÂúÒ»¸ö¾ÑéµãµÄ¾Ñ飬·ÇÍæ¼Òʵ¼Ê×ܾÑé  | 
|     expPoint = curPlayer.GetExpPoint()  | 
|     totalMasterExp = expPoint * ChConfig.Def_PerPointValue + totalExp  | 
|     return totalMasterExp  | 
|   | 
| ## ÉèÖÃÍæ¼Òµ±Ç°×ܾÑé, ×ª»¯Îª¾Ñéµã¼°¾Ñé  | 
| def SetPlayerTotalExp(curPlayer, totalExp):  | 
|     curExp = totalExp % ChConfig.Def_PerPointValue  | 
|     expPoint = totalExp / ChConfig.Def_PerPointValue  | 
|       | 
|     if curPlayer.GetExpPoint() != expPoint:  | 
|         curPlayer.SetExpPoint(expPoint)  | 
|     if curPlayer.GetTotalExp() != curExp:  | 
|         curPlayer.SetTotalExp(curExp)  | 
|     #GameWorld.DebugLog("SetPlayerTotalExp totalExp=%s,expPoint=%s,curExp=%s"   | 
|     #                   % (totalExp, expPoint, curExp), curPlayer.GetPlayerID())  | 
|       | 
|     return  | 
|   | 
| #------------------------------------------------------------------------------   | 
|   | 
| ## Í¨ÖªÑ¡ÖÐÄ¿±ê  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return None  | 
| def Sync_SelectObj(curPlayer, objType, objID, isSelect):  | 
|     selectObj = ChPyNetSendPack.tagMCNotifySelectObj()  | 
|     selectObj.Clear()  | 
|     selectObj.Type = objType  | 
|     selectObj.ID = objID  | 
|     selectObj.isSelect = isSelect  | 
|     NetPackCommon.SendFakePack(curPlayer, selectObj)  | 
|     return  | 
|   | 
|   | 
| ## Í³¼ÆÍæ¼ÒÊôÐÔ£¬ÀÛ¼Ó  | 
| #  @param attrType ÊôÐÔÀàÐÍ£¬Ð§¹ûID»òÕß×Ö·û´®  | 
| #  @param value ÊôÐÔÖµ  | 
| #  @param allAttrList ÊôÐÔÁÐ±í  | 
| #  @return None  | 
| def CalcAttrDict_Type(attrType, value, allAttrList):  | 
|     if value == 0:  | 
|         return  | 
|       | 
|     #[ÊôÐÔË÷Òý, ÊÇ·ñ»ù´¡ÊôÐÔ£¬(·Ç)ÏßÐÔ]  | 
|     attrInfo = ChConfig.ItemEffect_AttrDict.get(attrType, [])  | 
|     if attrInfo == []:  | 
|         return  | 
|       | 
|     index = ChConfig.Def_CalcAttrIndexDict[(attrInfo[1], attrInfo[2])]  | 
|       | 
|     attrDict = allAttrList[index]  | 
|     for i in attrInfo[0]:  | 
|         GameWorld.AddDictValue(attrDict, {i:value})  | 
|     return  | 
|   | 
| def CalcAttrDict_TypeEx(attrType, value, allAttrDict):  | 
|     ## Í³¼ÆÍæ¼ÒÊôÐÔ£¬ÀÛ¼Ó  | 
|     if value == 0:  | 
|         return  | 
|       | 
|     #[ÊôÐÔË÷Òý, ÊÇ·ñ»ù´¡ÊôÐÔ£¬(·Ç)ÏßÐÔ]  | 
|     attrInfo = ChConfig.ItemEffect_AttrDict.get(attrType, [])  | 
|     if attrInfo == []:  | 
|         return  | 
|     for i in attrInfo[0]:  | 
|         GameWorld.AddDictValue(allAttrDict, {i:value})  | 
|     return  | 
|   | 
| #===============================================================================  | 
| # CalcAttr_Base,  | 
| # CalcAttr_BaseNoline,  | 
| # CalcAttr_Battle,  | 
| # CalcAttr_BattleNoline,  | 
| #===============================================================================  | 
|   | 
| # ´ÓsrcAttrList¼ÆËã³öaddAttrList´øÀ´µÄ¹Ì¶¨ÊôÐÔ£¬ÓÃÓÚºóÐø¼ÆËãʹÓà  | 
| #===============================================================================  | 
| # def CalcAddFuncAttrByAttrList(srcAttrList, addAttrList):  | 
| #    for addKey, addValue in addAttrList[ChConfig.CalcAttr_BaseNoline].items():  | 
| #        value = srcAttrList[ChConfig.CalcAttr_Base].get(addKey, 0)  | 
| #        if value == 0:  | 
| #            continue  | 
| #          | 
| #        addAttrList[ChConfig.CalcAttr_Base][addKey]  = addAttrList[ChConfig.CalcAttr_Base].get(addKey, 0)\  | 
| #                                                         + value*addValue / ChConfig.Def_MaxRateValue  | 
| #   | 
| #    addAttrList[ChConfig.CalcAttr_BaseNoline] = {}  | 
| #    for addKey, addValue in addAttrList[ChConfig.CalcAttr_BattleNoline].items():  | 
| #        value = srcAttrList[ChConfig.CalcAttr_Battle].get(addKey, 0)  | 
| #        if value == 0:  | 
| #            continue  | 
| #          | 
| #        addAttrList[ChConfig.CalcAttr_Battle][addKey]  = addAttrList[ChConfig.CalcAttr_Battle].get(addKey, 0)\  | 
| #                                                         + value*addValue / ChConfig.Def_MaxRateValue  | 
| #   | 
| #    addAttrList[ChConfig.CalcAttr_BattleNoline] = {}  | 
| #    return addAttrList  | 
| #===============================================================================  | 
| ## ÷ÈÁ¦µÈ¼¶  | 
| def GetCharmLV(curPlayer): return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CharmLV)  | 
| def SetCharmLV(curPlayer, charmLV):  | 
|     NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CharmLV, charmLV)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_CharmLV, charmLV)  | 
|     return  | 
|   | 
| def GetTotalLingGenPoint(curPlayer):  | 
|     # ×ÜÁé¸ùµãÊý(½ðľˮ»ðÍÁ+×ÔÓɵãÊý)  | 
|     return GetMetal(curPlayer) + GetWood(curPlayer) + GetWater(curPlayer) + GetFire(curPlayer) + GetEarth(curPlayer) + curPlayer.GetFreePoint()  | 
|   | 
| # Áé¸ù - ½ðľˮ»ðÍÁ  | 
| def GetMetal(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Metal)  | 
| def SetMetal(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_Metal, value)  | 
| def GetWood(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Wood)  | 
| def SetWood(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_Wood, value)  | 
| def GetWater(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Water)  | 
| def SetWater(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_Water, value)  | 
| def GetFire(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Fire)  | 
| def SetFire(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_Fire, value)  | 
| def GetEarth(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Earth)  | 
| def SetEarth(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_Earth, value)  | 
| # Áé¸ùÆ·¼¶ - ½ðľˮ»ðÍÁ  | 
| def GetMetalQualityLV(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MetalQualityLV)  | 
| def SetMetalQualityLV(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_MetalQualityLV, value)  | 
| def GetWoodQualityLV(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_WoodQualityLV)  | 
| def SetWoodQualityLV(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_WoodQualityLV, value)  | 
| def GetWaterQualityLV(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_WaterQualityLV)  | 
| def SetWaterQualityLV(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_WaterQualityLV, value)  | 
| def GetFireQualityLV(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FireQualityLV)  | 
| def SetFireQualityLV(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FireQualityLV, value)  | 
| def GetEarthQualityLV(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_EarthQualityLV)  | 
| def SetEarthQualityLV(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_EarthQualityLV, value)  | 
|   | 
| #---Íæ¼ÒÀ©Õ¹½Ó¿Ú, Õ½¶·ÊôÐÔ£¬²»´æÊý¾Ý¿â£¬Ö»Í¨Öª±¾ÈË---  | 
|   | 
| ##Íæ¼ÒÒÆ¶¯ËÙ¶ÈÖµ, ²»º¬buff¶ÔËٶȵÄÓ°Ï죻 ¹¦ÄܵȶÔËٶȵÄÓ°ÏìÖ±½Ó¸Ä±ä´ËÖµ  | 
| def GetSpeedNotBuff(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SpeedValueNotBuff)  | 
| def SetSpeedNotBuff(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SpeedValueNotBuff, value)  | 
| ##Íæ¼ÒÒÆ¶¯ËÙ¶ÈÖµ, º¬buff¶ÔËٶȵÄÓ°Ï죻 ´ËÊýÖµ²»ÊÇÕæÕýµÄÒÆ¶¯ËÙ¶È£¬Ö»ÊÇÓÃÓÚ¼ÆËãÒÆ¶¯ËٶȵIJÎÊýÖµ  | 
| def GetSpeedValue(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SpeedValue)  | 
| def SetSpeedValue(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_SpeedValue, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_SpeedValue, value, True) # Òƶ¯ËÙ¶ÈÖµÔݶ¨¹ã²¥ÖÜÎ§Íæ¼Ò  | 
|       | 
| #---¹¥»÷»Ø¸´ÑªÁ¿±ÈÂÊ----  | 
| ## »ñÈ¡Íæ¼Ò¹¥»÷»Ø¸´ÑªÁ¿±ÈÂÊ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return   | 
| def GetAtkBackHPPer(curPlayer):  | 
|     return curPlayer.GetBattleValEx2()  | 
|   | 
|   | 
| ## ÉèÖÃÍæ¼Ò¹¥»÷»Ø¸´ÑªÁ¿±ÈÂÊ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return None  | 
| def SetAtkBackHPPer(curPlayer, value):  | 
|     curPlayer.SetBattleValEx2(value)  | 
|   | 
| ## »ñÈ¡Íæ¼Ò¹¥»÷»Ø¸´À¶Á¿±ÈÂÊ  | 
| def GetAtkBackMPPer(curPlayer): return 0  | 
| def SetAtkBackMPPer(curPlayer, value): return  | 
|   | 
| ## Íæ¼Ò¼õ¼¼ÄÜCD±ÈÀý  | 
| def GetReduceSkillCDPer(curPlayer): return curPlayer.GetBattleValEx3()  | 
| def SetReduceSkillCDPer(curPlayer, reducePer): return curPlayer.SetBattleValEx3(reducePer)  | 
|   | 
| ## ³£¹æµØÍ¼¾Ñé±¶ÂÊ¼Ó³É  | 
| def GetCommMapExpRate(curPlayer):  | 
|     if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:  | 
|         return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CommMapExpRate)  | 
|     return 0  | 
| def SetCommMapExpRate(curPlayer, expRate): return curPlayer.SetDict(ChConfig.Def_PlayerKey_CommMapExpRate, expRate)  | 
|   | 
| ## ¶Ô¹ÖÎïÉ˺¦¼Ó³É  | 
| def GetNPCHurtAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_NPCHurtAddPer)  | 
| def SetNPCHurtAddPer(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_NPCHurtAddPer, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_NPCHurtAddPer, value)  | 
|       | 
| #---Ö°ÒµÉ˺¦¼Ó³É---  | 
| ## Ä¿±êսʿÉ˺¦¼Ó³É  | 
| def GetJobAHurtAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_JobAHurtAddPer)  | 
| def SetJobAHurtAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_JobAHurtAddPer, value)  | 
| ## Ä¿±ê·¨Ê¦É˺¦¼Ó³É  | 
| def GetJobBHurtAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_JobBHurtAddPer)  | 
| def SetJobBHurtAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_JobBHurtAddPer, value)  | 
| ## Ä¿±ê¹ÊÖÉ˺¦¼Ó³É  | 
| def GetJobCHurtAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_JobCHurtAddPer)  | 
| def SetJobCHurtAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_JobCHurtAddPer, value)  | 
|   | 
| #---É˺¦¼õÃâ---  | 
| ## NPC¹¥»÷É˺¦¼õÃâ  | 
| def GetNPCAtkReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_NPCAtkReducePer)  | 
| def SetNPCAtkReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_NPCAtkReducePer, value)  | 
| ## Õ½Ê¿¹¥»÷É˺¦¼õÃâ  | 
| def GetJobAAtkReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_JobAAtkReducePer)  | 
| def SetJobAAtkReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_JobAAtkReducePer, value)  | 
| ## ·¨Ê¦¹¥»÷É˺¦¼õÃâ  | 
| def GetJobBAtkReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_JobBAtkReducePer)  | 
| def SetJobBAtkReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_JobBAtkReducePer, value)  | 
| ## ¹ÊÖ¹¥»÷É˺¦¼õÃâ  | 
| def GetJobCAtkReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_JobCAtkReducePer)  | 
| def SetJobCAtkReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_JobCAtkReducePer, value)  | 
|   | 
| #---ÌØÊâÉ˺¦¼õÃâ---  | 
| ## »áÐÄÒ»»÷É˺¦¼õÃâ¹Ì¶¨Öµ  | 
| def GetLuckyHitReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_LuckyHitReduce)  | 
| def SetLuckyHitReduce(curPlayer, value):   | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_LuckyHitReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_LuckyHitReduce, value)  | 
|       | 
| ## ×¿Ô½Ò»»÷É˺¦¼õÃâ  | 
| def GetGreatHitReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GreatHitReducePer)  | 
| def SetGreatHitReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GreatHitReducePer, value)  | 
| ## ±©»÷É˺¦¼õÃâ  | 
| def GetSuperHitReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SuperHitReduce)  | 
| def SetSuperHitReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_SuperHitReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_SuperHitReduce, value)  | 
| ## ÎÞÊÓ·ÀÓùÉ˺¦¼õÃâ  | 
| def GetIgnoreDefReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IgnoreDefReducePer)  | 
| def SetIgnoreDefReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_IgnoreDefReducePer, value)  | 
|   | 
| #---¿¹ÌØÊâÉ˺¦¸ÅÂÊ---  | 
| ## ¿¹»áÐÄÒ»»÷¸ÅÂÊ  | 
| def GetLuckyHitRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_LuckyHitRateReduce)  | 
| def SetLuckyHitRateReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_LuckyHitRateReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_LuckyHitRateReduce, value)  | 
| ## ¿¹×¿Ô½Ò»»÷¸ÅÂÊ  | 
| def GetGreatHitRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GreatHitRateReduce)  | 
| def SetGreatHitRateReduce(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GreatHitRateReduce, value)  | 
| ## ¿¹ÎÞÊÓ·ÀÓù¸ÅÂÊ  | 
| def GetIgnoreDefRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IgnoreDefRateReduce)  | 
| def SetIgnoreDefRateReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_IgnoreDefRateReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_IgnoreDefRateReduce, value)  | 
|       | 
| #---ÌØÊâÉ˺¦¸ÅÂÊ---  | 
| ## ¸»ºÀÒ»»÷¸ÅÂÊ  | 
| def GetFuhaoHitRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FuhaoHitRate)  | 
| def SetFuhaoHitRate(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FuhaoHitRate, value)  | 
|   | 
| ## Á÷ѪÉ˺¦  | 
| def GetBleedDamage(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BleedDamage)  | 
| def SetBleedDamage(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_BleedDamage, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_BleedDamage, value)  | 
|       | 
| ## ×îÖÕÉ˺¦°Ù·Ö±È  | 
| def GetFinalHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtPer)  | 
| def SetFinalHurtPer(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtPer, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtPer, value)  | 
|       | 
| ## ×îÖÕÉ˺¦¼õÃâ°Ù·Ö±È  | 
| def GetFinalHurtReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtReducePer)  | 
| def SetFinalHurtReducePer(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtReducePer, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtReducePer, value)  | 
|       | 
| ## ×îÖչ̶¨É˺¦Ôö¼Ó  | 
| def GetFinalHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurt)  | 
| def SetFinalHurt(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurt, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurt, value)  | 
| ## ×îÖչ̶¨É˺¦¼õÉÙ  | 
| def GetFinalHurtReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtReduce)  | 
| def SetFinalHurtReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtReduce, value)  | 
| ## ¶ÔÖ¸¶¨bossÉ˺¦¼Ó³É¹Ì¶¨Öµ  | 
| def GetBossIDHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BossIDHurt)  | 
| def SetBossIDHurt(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BossIDHurt, value)  | 
| ## ¶ÔÖ¸¶¨bossÉ˺¦¼Ó³É±¶ÂÊ  | 
| def GetBossIDHurtAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BossIDHurtAddPer)  | 
| def SetBossIDHurtAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BossIDHurtAddPer, value)  | 
| ## ×°±¸µôÂäÖ´ÐдÎÊý¼Ó³ÉÍò·ÖÂÊ  | 
| def GetDropEquipDoCount(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_DropEquipDoCount)  | 
| def SetDropEquipDoCount(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_DropEquipDoCount, value)  | 
|   | 
| # »ù´¡¹¥»÷°Ù·Ö±È  | 
| def GetBaseAtkAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BaseAtkAddPer)  | 
| def SetBaseAtkAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BaseAtkAddPer, value)  | 
| # »ù´¡ÉúÃü°Ù·Ö±È  | 
| def GetBaseMaxHPAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BaseMaxHPAddPer)  | 
| def SetBaseMaxHPAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BaseMaxHPAddPer, value)  | 
| # »ù´¡·ÀÓù°Ù·Ö±È  | 
| def GetBaseDefAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BaseDefAddPer)  | 
| def SetBaseDefAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BaseDefAddPer, value)  | 
| # »ù´¡ÃüÖÐ°Ù·Ö±È  | 
| def GetBaseHitAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BaseHitAddPer)  | 
| def SetBaseHitAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BaseHitAddPer, value)  | 
| # »ù´¡ÉÁ±Ü°Ù·Ö±È  | 
| def GetBaseMissAddPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BaseMissAddPer)  | 
| def SetBaseMissAddPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BaseMissAddPer, value)  | 
| # Éñ±øÉúÃü°Ù·Ö±È  | 
| def GetGodWeaponMaxHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GodWeaponMaxHPPer)  | 
| def SetGodWeaponMaxHPPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GodWeaponMaxHPPer, value)  | 
| # Éñ±ø¹¥»÷°Ù·Ö±È  | 
| def GetGodWeaponAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GodWeaponAtkPer)  | 
| def SetGodWeaponAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GodWeaponAtkPer, value)  | 
| # ±¦Ê¯ÉúÃü°Ù·Ö±È  | 
| def GetStoneMaxHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_StoneMaxHPPer)  | 
| def SetStoneMaxHPPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_StoneMaxHPPer, value)  | 
| # ±¦Ê¯¹¥»÷°Ù·Ö±È  | 
| def GetStoneAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_StoneAtkPer)  | 
| def SetStoneAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_StoneAtkPer, value)  | 
| # ÑªÆ¿»Ö¸´Ð§¹û  | 
| def GetHPCureEnhance(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HPCureEnhance)  | 
| def SetHPCureEnhance(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HPCureEnhance, value)  | 
|   | 
| # ¶îÍâÊä³öÉ˺¦  | 
| def GetOnlyFinalHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_OnlyFinalHurt)  | 
| def SetOnlyFinalHurt(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_OnlyFinalHurt, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_OnlyFinalHurt, value)  | 
|     return  | 
|   | 
| # PVP¹¥»÷»ØÑª  | 
| def GetPVPAtkBackHP(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PVPAtkBackHP)  | 
| def SetPVPAtkBackHP(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PVPAtkBackHP, value)  | 
|   | 
| # ÃüÖгɹ¦ÂÊ  | 
| def GetHitSucessRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HitSucessRate)  | 
| def SetHitSucessRate(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HitSucessRate, value)  | 
|   | 
| # ÉÁ±Ü³É¹¦ÂÊ  | 
| def GetMissSucessRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MissSucessRate)  | 
| def SetMissSucessRate(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_MissSucessRate, value)  | 
|   | 
| # ÖÎÁƼӳɠĬÈϰٷְ٠ | 
| def GetCurePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CurePer)  | 
| def SetCurePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_CurePer, value)  | 
|   | 
| # ¼ÓÉîÊܵ½É˺¦°Ù·Ö±È  | 
| def GetBeHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BeHurtPer)  | 
| def SetBeHurtPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BeHurtPer, value)  | 
|   | 
| # ×øÆï¹¥»÷°Ù·Ö±È  | 
| def GetHorseAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HorseAtkPer)  | 
| def SetHorseAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HorseAtkPer, value)  | 
|   | 
| # ×øÆïÉúÃü¼Ó³É  | 
| def GetHorseMaxHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HorseMaxHPPer)  | 
| def SetHorseMaxHPPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HorseMaxHPPer, value)  | 
|   | 
| # Áé³è¹¥»÷¼Ó³É  | 
| def GetPetAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PetAtkPer)  | 
| def SetPetAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PetAtkPer, value)  | 
|   | 
| # ×øÆïÅàÑøÊôÐÔ¼Ó³É  | 
| def GetHorseTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HorseTrainAttrPer)  | 
| def SetHorseTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HorseTrainAttrPer, value)  | 
|   | 
| # Áé³èÅàÑøÊôÐÔ¼Ó³É  | 
| def GetPetTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PetTrainAttrPer)  | 
| def SetPetTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PetTrainAttrPer, value)  | 
|   | 
| # ÊØ»¤ÅàÑøÊôÐÔ¼Ó³É  | 
| def GetGuardTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GuardTrainAttrPer)  | 
| def SetGuardTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GuardTrainAttrPer, value)  | 
|   | 
| # ³á°òÅàÑøÊôÐÔ¼Ó³É  | 
| def GetWingTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_WingTrainAttrPer)  | 
| def SetWingTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_WingTrainAttrPer, value)  | 
|   | 
| # ÃðÊÀÅàÑøÊôÐÔ¼Ó³É  | 
| def GetPeerlessWeaponTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PeerlessWeaponTrainAttrPer)  | 
| def SetPeerlessWeaponTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PeerlessWeaponTrainAttrPer, value)  | 
|   | 
| # ß±ÉñÅàÑøÊôÐÔ¼Ó³É  | 
| def GetPeerlessWeapon2TrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PeerlessWeapon2TrainAttrPer)  | 
| def SetPeerlessWeapon2TrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PeerlessWeapon2TrainAttrPer, value)  | 
|   | 
| # Á¶ÌåÊôÐÔÊôÐÔ¼Ó³É  | 
| def GetLianTiAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_LianTiAttrPer)  | 
| def SetLianTiAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_LianTiAttrPer, value)  | 
|   | 
| def GetAttr160(curPlayer): return 0  | 
| def SetAttr160(curPlayer, value): pass  | 
|   | 
| # ÏÉÃËÊÂÎñËÙ¶È¼Ó³É  | 
| def GetAffairSpeedPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AffairSpeedPer)  | 
| def SetAffairSpeedPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AffairSpeedPer, value)  | 
|   | 
| # ÏÉÃËBOSSÉ˺¦¼Ó³É  | 
| def GetFamilyBossHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FamilyBossHurtPer)  | 
| def SetFamilyBossHurtPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FamilyBossHurtPer, value)  | 
|   | 
| # ÏÉÃËÁªÈüÉúÃü¼Ó³É  | 
| def GetFamilyWarHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FamilyWarHPPer)  | 
| def SetFamilyWarHPPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FamilyWarHPPer, value)  | 
|   | 
| # ÏÉÃËÁªÈü¹¥»÷¼Ó³É  | 
| def GetFamilyWarAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FamilyWarAtkPer)  | 
| def SetFamilyWarAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FamilyWarAtkPer, value)  | 
|   | 
| # ÏÉÃË´ò×ø¾Ñé¼Ó³É  | 
| def GetFamilySitExpPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FamilySitExpPer)  | 
| def SetFamilySitExpPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FamilySitExpPer, value)  | 
|   | 
| # ±¦Ê¯»ù´¡ÊôÐÔ°Ù·Ö±È  | 
| def GetStoneBasePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_StoneBasePer)  | 
| def SetStoneBasePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_StoneBasePer, value)  | 
|   | 
| # ¾³½ç»ù´¡ÊôÐÔ°Ù·Ö±È  | 
| def GetRealmBasePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_RealmBasePer)  | 
| def SetRealmBasePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_RealmBasePer, value)  | 
|   | 
| # ³á°òÉúÃü°Ù·Ö±È  | 
| def GetWingHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_WingHPPer)  | 
| def SetWingHPPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_WingHPPer, value)  | 
|   | 
| # Ì××°»ù´¡ÊôÐÔ°Ù·Ö±È  | 
| def GetSuiteBasePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SuiteBasePer)  | 
| def SetSuiteBasePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SuiteBasePer, value)  | 
|   | 
| # Ç¿»¯»ù´¡¹¥»÷°Ù·Ö±È  | 
| def GetPlusBaseAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PlusBaseAtkPer)  | 
| def SetPlusBaseAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PlusBaseAtkPer, value)  | 
|   | 
| ## ÔÝÎÞÓÃ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return   | 
| def GetAddBackHPPer(curPlayer):  | 
|     return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AddBackHPPer)  | 
|   | 
| ## ÔÝÎÞÓÃ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return None  | 
| def SetAddBackHPPer(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AddBackHPPer, value)  | 
|       | 
| #---½µµÍÉúÃü»Ö¸´Ð§¹û----  | 
| ## »ñÈ¡½µµÍÉúÃü»Ö¸´Ð§¹ûÍò·ÖÂÊ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return   | 
| def GetReduceBackHPPer(curPlayer):  | 
|     return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ReduceBackHPPer)  | 
|   | 
| ## ÉèÖýµµÍÉúÃü»Ö¸´Ð§¹ûÍò·ÖÂÊ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return None  | 
| def SetReduceBackHPPer(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ReduceBackHPPer, value)  | 
|   | 
| #---´¥·¢¶¨Éí----  | 
| def GetAtkerFreezed(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrAtkerFreezed)  | 
| def SetAtkerFreezed(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrAtkerFreezed, value)  | 
|       | 
| #---Ôö¼Ó³ðºÞ----  | 
| def GetAddAngry(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrAddAngry)  | 
| def SetAddAngry(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrAddAngry, value)  | 
|   | 
| #---¼¼Äܹ¥»÷±ÈÀý¼õÉÙ----  | 
| def GetSkillAtkRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAtkRateReduce)  | 
| def SetSkillAtkRateReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAtkRateReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_SkillAtkRateReduce, value)  | 
| #---PVP¹Ì¶¨É˺¦----  | 
| def GetDamagePVP(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDamagePVP)  | 
| def SetDamagePVP(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDamagePVP, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_DamagePVP, value)  | 
| #---PVP¹Ì¶¨É˺¦¼õÉÙ----  | 
| def GetDamagePVPReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDamagePVPReduce)  | 
| def SetDamagePVPReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDamagePVPReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_DamagePVPReduce, value)  | 
| #---É˺¦Êä³ö¹Ì¶¨Öµ¼ÆËã¶ÔNPC¸½¼Ó----  | 
| def GetDamagePVE(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDamagePVE)  | 
| def SetDamagePVE(curPlayer, value):   | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDamagePVE, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_DamagePVE, value)  | 
|       | 
| #---É˺¦Êä³ö¼ÆËã°Ù·Ö±È¶ÔÍæ¼Ò¸½¼Ó----  | 
| def GetDamagePerPVP(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDamagePerPVP)  | 
| def SetDamagePerPVP(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDamagePerPVP, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_DamagePerPVP, value)  | 
| def GetDamagePerPVPReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDamagePerPVPReduce)  | 
| def SetDamagePerPVPReduce(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDamagePerPVPReduce, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_DamagePerPVPReduce, value)  | 
|       | 
| #---ÊÜÉ˼ÆËã°Ù·Ö±È----  | 
| def GetHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrHurtPer)  | 
| def SetHurtPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrHurtPer, value)  | 
|     | 
| #---×Ô¶¯»Ö¸´XPÖµ±ÈÂÊ----  | 
| def GetXPRestorePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrXPRestorePer)  | 
| def SetXPRestorePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrXPRestorePer, value)  | 
|   | 
| #---ħ·¨¶ÜÉ˺¦ÎüÊÕÀ¶ºÄ±ÈÂÊ----  | 
| def GetShieldMPCostRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrShieldMPCostRate)  | 
| def SetShieldMPCostRate(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrShieldMPCostRate, value)  | 
|     | 
| #---20%µÄ¸ÅÂʵÖÓùÉ˺¦±ÈÂÊ----  | 
| def GetDamChanceDef(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDamChanceDef)  | 
| def SetDamChanceDef(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDamChanceDef, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_DamChanceDef, value)  | 
|       | 
| #---µ±Ç°·À»¤Öµ£¬Ðè´æDB----  | 
| def GetProDef(curPlayer): return curPlayer.GetExAttr4()  | 
| def SetProDef(curPlayer, value):  | 
|     if GameWorld.IsCrossServer():  | 
|         curPlayer.SetExAttr4(value, True) # ¿ç·þ·þÎñÆ÷ÐèÒª¹ã²¥ÖÜÎ§Íæ¼Ò  | 
|     else:  | 
|         curPlayer.SetExAttr4(value)  | 
|       | 
| #---×î´ó·À»¤Öµ----  | 
| def GetMaxProDef(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrMaxProDef)  | 
| def SetMaxProDef(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrMaxProDef, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_MaxProDef, value) # ÖÜÎ§Íæ¼ÒÐèҪ֪ͨ  | 
|       | 
| #---ÉúÃüÉÏÏÞ»»ËãΪ·À»¤ÖµµÄ°Ù·Ö±È----  | 
| def GetProDefHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrProDefHPPer)  | 
| def SetProDefHPPer(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrProDefHPPer, value)  | 
|     #SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ProDefHPPer, value)  | 
|       | 
| #---·À»¤ÖµÎüÊÕÉ˺¦±ÈÂÊ----  | 
| def GetProDefAbsorb(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrProDefAbsorb)  | 
| def SetProDefAbsorb(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrProDefAbsorb, value)  | 
|     #SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ProDefAbsorb, value)  | 
|       | 
| #---³èÎï¹¥»÷ÌáÉýÖµ----  | 
| def GetPetMinAtk(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrPetMinAtk)  | 
| def SetPetMinAtk(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrPetMinAtk, value)  | 
| def GetPetMaxAtk(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrPetMaxAtk)  | 
| def SetPetMaxAtk(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrPetMaxAtk, value)  | 
|   | 
| #---³èÎïÉ˺¦°Ù·Ö±ÈÌáÉý----ÒÆµ½GameObjÏ  | 
| #===============================================================================  | 
| # def GetPetDamPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrPetDamPer)  | 
| # def SetPetDamPer(curPlayer, value):   | 
| #    curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrPetDamPer, value)  | 
| #    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_PetDamPer, value)  | 
| #===============================================================================  | 
| #---³èÎï¼¼ÄÜÉ˺¦°Ù·Ö±ÈÌáÉý----  | 
| def GetPetSkillAtkRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PetSkillAtkRate)  | 
| def SetPetSkillAtkRate(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PetSkillAtkRate, value)  | 
|       | 
| #---ÿ1¼¶+%s¹¥»÷, ÊýֵȡÍò·ÖÂÊ£¬Ö§³ÖСÊýËã·¨----  | 
| def GetPerLVAtk(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrPerLVAtk)  | 
| def SetPerLVAtk(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrPerLVAtk, value)  | 
| #---ÿ1¼¶+%sÉúÃü, ÊýֵΪ¹Ì¶¨Öµ----  | 
| def GetPerLVMaxHP(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrPerLVMaxHP)  | 
| def SetPerLVMaxHP(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrPerLVMaxHP, value)  | 
|   | 
| #---×°±¸µôÂÊ----  | 
| def GetDropEquipPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrDropEquipPer)  | 
| def SetDropEquipPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrDropEquipPer, value)  | 
|   | 
| #---¹¦Äܲã·ÀÓùÖµ----  | 
| def GetFuncDef(curPlayer): return EffGetSet.GetCopyFuncAttrValue(curPlayer, ChConfig.TYPE_Calc_AttrDEF)  | 
| def SetFuncDef(curPlayer, value): EffGetSet.SetCopyFuncAttrValue(curPlayer, ChConfig.TYPE_Calc_AttrDEF, value)  | 
|   | 
| #ÆÕͨ¹¥»÷ÔöÉË£ºÆÕͨ¹¥»÷¸½¼ÓµÄ¹Ì¶¨ÖµÉ˺¦  | 
| def GetNormalHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_NormalHurt)  | 
| def SetNormalHurt(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_NormalHurt, value)  | 
| #ÆÕͨ¹¥»÷¼Ó³É£ºÆÕͨ¹¥»÷¸½¼ÓµÄÉ˺¦°Ù·Ö±È  | 
| def GetNormalHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_NormalHurtPer)  | 
| def SetNormalHurtPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_NormalHurtPer, value)  | 
| #·¨±¦¼¼ÄÜÔöÉË£º·¨±¦¼¼Äܹ¥»÷¸½¼ÓµÄ¹Ì¶¨ÖµÉ˺¦  | 
| def GetFabaoHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FabaoHurt)  | 
| def SetFabaoHurt(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FabaoHurt, value)  | 
| #·¨±¦¼¼Äܼӳɣº·¨±¦¼¼Äܹ¥»÷¸½¼ÓµÄÉ˺¦°Ù·Ö±È  | 
| def GetFabaoHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FabaoHurtPer)  | 
| def SetFabaoHurtPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_FabaoHurtPer, value)  | 
|   | 
| # Ã¿XÃë×Ô¶¯Ïûʧһ¸öÓ¡¼Ç£¬ ºÁÃë¼Ç¼  | 
| def GetLostYinjiTime(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_LostYinjiTime)  | 
| def SetLostYinjiTime(curPlayer, value):   | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_LostYinjiTime, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_YinjiTime, value)  | 
|   | 
| # µ±Ç°Ó¡¼ÇÊý  | 
| def GetYinjiCnt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_YinjiCnt)  | 
| def SetYinjiCnt(curPlayer, value):   | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_YinjiCnt, value)  | 
|     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_YinjiCnt, value)  | 
|   | 
| # ¼õÉÙÖ¸¶¨¼¼ÄÜ×éCD XX%  | 
| def GetTheFBSkillsCD(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TheFBSkillsCD)  | 
| def SetTheFBSkillsCD(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_TheFBSkillsCD, value)  | 
| # ×ÆÉչ̶¨É˺¦  | 
| def GetBurnValue(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BurnValue)  | 
| def SetBurnValue(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BurnValue, value)  | 
| # ÑÓ³¤×ÆÉÕʱ¼ä°Ù·Ö±È  | 
| def GetBurnTimePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_BurnTimePer)  | 
| def SetBurnTimePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_BurnTimePer, value)  | 
| # ¼õÒÆ¶¯ËÙ¶È°Ù·Ö±È  | 
| def GetSubSpeedPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SubSpeedPer)  | 
| def SetSubSpeedPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SubSpeedPer, value)  | 
|   | 
| # ¼¼ÄÜÉ˺¦ÔöÇ¿  | 
| def GetSkillAddPer1(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer1)  | 
| def SetSkillAddPer1(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer1, value)  | 
| def GetSkillAddPer2(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer2)  | 
| def SetSkillAddPer2(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer2, value)  | 
| def GetSkillAddPer3(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer3)  | 
| def SetSkillAddPer3(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer3, value)  | 
| def GetSkillAddPer4(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer4)  | 
| def SetSkillAddPer4(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer4, value)  | 
| def GetSkillAddPer5(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer5)  | 
| def SetSkillAddPer5(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer5, value)  | 
| def GetSkillAddPer6(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer6)  | 
| def SetSkillAddPer6(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer6, value)  | 
| def GetSkillAddPer7(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAddPer7)  | 
| def SetSkillAddPer7(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillAddPer7, value)  | 
|   | 
| # Êܵ½¼¼ÄÜÉ˺¦¼õÉÙ  | 
| def GetSkillReducePer1(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer1)  | 
| def SetSkillReducePer1(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer1, value)  | 
| def GetSkillReducePer2(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer2)  | 
| def SetSkillReducePer2(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer2, value)  | 
| def GetSkillReducePer3(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer3)  | 
| def SetSkillReducePer3(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer3, value)  | 
| def GetSkillReducePer4(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer4)  | 
| def SetSkillReducePer4(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer4, value)  | 
| def GetSkillReducePer5(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer5)  | 
| def SetSkillReducePer5(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer5, value)  | 
| def GetSkillReducePer6(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer6)  | 
| def SetSkillReducePer6(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer6, value)  | 
| def GetSkillReducePer7(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillReducePer7)  | 
| def SetSkillReducePer7(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_SkillReducePer7, value)  | 
|   | 
| #---ÖïÏÉÒ»»÷¸ÅÂÊ---  | 
| def GetZhuXianRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ZhuxianRate)  | 
| def SetZhuXianRate(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_ZhuxianRate, value)  | 
|   | 
| #---ÖïÏÉ»¤Ìå¼õÉË---  | 
| def GetZhuXianReducePer(curPlayer): return 0#curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ZhuXianReducePer)  | 
| def SetZhuXianReducePer(curPlayer, value): return #curPlayer.SetDict(ChConfig.Def_PlayerKey_ZhuXianReducePer, value)  | 
|   | 
| ## ¼ÆË㹦Äܱ³°üÎïÆ·ÊôÐÔ   | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param packType ±³°üÀàÐÍ  | 
| #  @param allAttrListEquip ÊôÐÔÁÐ±í  | 
| #  @return None  | 
| def CalcFuncPackItem(curPlayer, packType, allAttrListEquip):  | 
|     #===========================================================================  | 
|     # funcPack = curPlayer.GetItemManager().GetPack(packType)  | 
|     # equipPartIndexList = ChConfig.Pack_EquipPart_CanPlusStar.get(packType, [])  | 
|     #   | 
|     # #Íæ¼Òµ±Ç°¿É×°±¸µÄ×°±¸ÀàÐÍ  | 
|     # for equipIndex in range(0, funcPack.GetCount()):  | 
|     #      | 
|     #    curEquip = funcPack.GetAt(equipIndex)  | 
|     #    if curEquip.IsEmpty():  | 
|     #        continue  | 
|     #      | 
|     #    #¼ÆËãЧ¹û  | 
|     #    for i in range(0, curEquip.GetEffectCount()):  | 
|     #        curEffect = curEquip.GetEffectByIndex(i)  | 
|     #        if not curEffect:  | 
|     #            break  | 
|     #          | 
|     #        effectID = curEffect.GetEffectID()  | 
|     #        if effectID == 0:  | 
|     #            #×îºóÒ»¸ö  | 
|     #            break  | 
|     #          | 
|     #        effectValue = curEffect.GetEffectValue(0)  | 
|     #        if not effectValue:  | 
|     #            continue  | 
|     #          | 
|     #        #Ìí¼ÓÎïÆ·Ð§¹ûµÄÊôÐÔÖµ  | 
|     #        CalcAttrDict_Type(effectID, effectValue, allAttrListEquip)  | 
|     #      | 
|     #      | 
|     #===========================================================================  | 
|     return  | 
|   | 
| #-------------------------------------------------------------------------------  | 
|   | 
| ## ÉèÖñ£´æ¹¦ÄÜÊÂÏȼÆËãºÃµÄÊôÐÔÖµ  | 
| def SetCalcAttrListValue(curPlayer, funcIndex, allAttrList, insidePerAttrDict=None, customAttrDict=None):  | 
|     # ÉèÖÃֵ֮ǰÏÈÇå¿ÕÖØÖà  | 
|     # @param customAttrDict: ×Ô¶¨ÒåµÄÊôÐÔÐÅÏ¢£¬±ØÐëÊǸñʽ {"×Ô¶¨ÒåÊôÐÔÃèÊöÃûkey":ÊôÐÔÐÅÏ¢, ...}  ×Ô¶¨ÒåÊôÐÔÃèÊöÃûkey - ½¨Ò鲻ͬ¹¦ÄܵãÖ®¼ä²»ÒªÖظ´  | 
|     ClearCalcAttrListValue(curPlayer, funcIndex)  | 
|     if insidePerAttrDict == None:  | 
|         insidePerAttrDict = {}  | 
|     if customAttrDict == None:  | 
|         customAttrDict = {}  | 
|           | 
|     battleAttrDict = allAttrList[ChConfig.CalcAttr_Battle]  | 
|     if ChConfig.TYPE_Calc_PerLVAtk in battleAttrDict:  | 
|         # Ã¿1¼¶¼ÓµÄ¹¥»÷Á¦²»Ò»¶¨Âú1µã£¬ËùÒÔÕâÀï°´Íò·ÖÂÊÀ´Ë㣬֧³ÖСÊýËã·¨  | 
|         addAtk = int(curPlayer.GetLV() * battleAttrDict[ChConfig.TYPE_Calc_PerLVAtk] / float(ShareDefine.Def_MaxRateValue))  | 
|         battleAttrDict[ChConfig.TYPE_Calc_AttrATKMin] = battleAttrDict.get(ChConfig.TYPE_Calc_AttrATKMin, 0) + addAtk  | 
|         battleAttrDict[ChConfig.TYPE_Calc_AttrATKMax] = battleAttrDict.get(ChConfig.TYPE_Calc_AttrATKMax, 0) + addAtk  | 
|           | 
|     if ChConfig.TYPE_Calc_PerLVMaxHP in battleAttrDict:  | 
|         # Ã¿1¼¶¼ÓµÄÉúÃüÖµ²»»áÉÙÓÚ1µã£¬ËùÒÔÖ±½Ó³Ë  | 
|         addMaxHP = curPlayer.GetLV() * battleAttrDict[ChConfig.TYPE_Calc_PerLVMaxHP]  | 
|         battleAttrDict[ChConfig.TYPE_Calc_AttrMaxHP] = battleAttrDict.get(ChConfig.TYPE_Calc_AttrMaxHP, 0) + addMaxHP  | 
|           | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_playerFuncAttrDict:  | 
|         PyGameData.g_playerFuncAttrDict[playerID] = {}  | 
|     funcAttrDict = PyGameData.g_playerFuncAttrDict[playerID]  | 
|     funcAttrDict[funcIndex] = [allAttrList, insidePerAttrDict, customAttrDict]  | 
|     #GameWorld.DebugLog("±£´æ¹¦ÄܵãÊôÐÔ: funcIndex=%s, %s, %s" % (funcIndex, allAttrList, insidePerAttrDict))  | 
|     return  | 
|   | 
| def GetCalcAttrListValue(curPlayer, funcIndex):  | 
|     ## »ñÈ¡¹¦ÄܵãÔ¤ÏȼÆËãµÄËù¼ÓÊôÐÔÖµ  | 
|     attrList = [{} for _ in range(4)]  | 
|     insidePerAttrDict = {}  | 
|     customAttrDict = {}  | 
|     if isinstance(funcIndex, int):  | 
|         funcIndexList = [funcIndex]  | 
|     elif isinstance(funcIndex, list):  | 
|         funcIndexList = funcIndex  | 
|     else:  | 
|         return attrList, insidePerAttrDict, customAttrDict  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_playerFuncAttrDict:  | 
|         return attrList, insidePerAttrDict, customAttrDict  | 
|     funcAttrDict = PyGameData.g_playerFuncAttrDict[playerID]  | 
|     for funcIndex in funcIndexList:  | 
|         if funcIndex not in funcAttrDict:  | 
|             continue  | 
|         funcAttrList, funcInsidePerAttrDict, funcCustomAttrDict = funcAttrDict[funcIndex]  | 
|         for i, attrDict in enumerate(attrList):  | 
|             curAttrDict = funcAttrList[i]  | 
|             AddAttrDictValue(attrDict, curAttrDict)  | 
|         customAttrDict.update(funcCustomAttrDict)  | 
|         AddAttrDictValue(insidePerAttrDict, funcInsidePerAttrDict)  | 
|     return attrList, insidePerAttrDict, customAttrDict  | 
|   | 
| ## ÖØÖûº´æ  | 
| def ClearCalcAttrListValue(curPlayer, funcIndex):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_playerFuncAttrDict:  | 
|         return  | 
|     funcAttrDict = PyGameData.g_playerFuncAttrDict[playerID]  | 
|     funcAttrDict.pop(funcIndex, None)  | 
|     return  | 
|   | 
| def AddAttrListValue(attrList):  | 
|     addAttrList = [{} for _ in range(4)]  | 
|     for aList in attrList:  | 
|         for i in ChConfig.CalcAttrIndexList:  | 
|             AddAttrDictValue(addAttrList[i], aList[i])  | 
|     return addAttrList  | 
|   | 
| ## ÊôÐÔÖµ×ÖµäÀÛ¼Ó  | 
| def AddAttrDictValue(dict1, dict2):  | 
|     for key, value in dict2.items():  | 
|         if key not in dict1:  | 
|             dict1[key] = value  | 
|         else:  | 
|             aValue = dict1[key]  | 
|             if key in ChConfig.TYPE_Calc_DeclineList:  | 
|                 # ÕâÖÖËã·¨µÄÊôÐÔÒ»°ãÊÇÍò·ÖÂʵģ¬×î´ó²»³¬¹ý°Ù·Ö°Ù£¬¹ÊÔÝĬÈÏÍò·ÖÂÊ, ÈôÓв»ÊÇÍò·ÖÂʵÄÊôÐÔÔÙ×ö´¦Àí  | 
|                 dict1[key] = 10000 - (10000 - aValue) * (10000 - value)  | 
|             else:  | 
|                 dict1[key] = aValue + value  | 
|     return  | 
|   | 
| #-------------------------------------------------------------------------------  | 
| ## ÉèÖÃÍæ¼Ò×ÖµäÖµ, ´æ¿â  | 
| def NomalDictSetProperty(curPlayer, key, value, dType=0):  | 
|     if CrossPlayerData.IsNeedProcessCrossPlayer(curPlayer) and key not in \  | 
|         [ChConfig.Def_PDict_FightPower_Total, ChConfig.Def_PDict_FightPower_TotalEx, ChConfig.Def_PlayerKey_CrossRegisterMap]:  | 
|         playerID = curPlayer.GetPlayerID()  | 
|         changeDict = PyGameData.g_crossPlayerDictChangeInfo.get(playerID, {})  | 
|         changeDict[(key, dType)] = value  | 
|         PyGameData.g_crossPlayerDictChangeInfo[playerID] = changeDict  | 
|           | 
|     if value == 0:  | 
|         curPlayer.NomalDictDelProperty(key, dType)  | 
|         return  | 
|     # 2^31 - 1  | 
|     curPlayer.NomalDictAddProperty(key, min(value, ChConfig.Def_UpperLimit_DWordEx), dType)  | 
|     return  | 
|   | 
| ## Í¨Öª×£¸£Öµ  | 
| def Sync_BlessValue(curPlayer, blessType, value, multiple=0):  | 
|     itemList = []  | 
|   | 
|     valuePack = ChPyNetSendPack.tagMCSyncSingleBlessValue()  | 
|     valuePack.Clear()  | 
|     valuePack.Type = blessType  | 
|     valuePack.Value = value  | 
|     valuePack.Multiple = multiple  | 
|     itemList.append(valuePack)  | 
|       | 
|     sendPack = ChPyNetSendPack.tagMCSyncBlessValue()  | 
|     sendPack.Clear()  | 
|     sendPack.TypeCnt = len(itemList)  | 
|     sendPack.BlessInfo = itemList  | 
|       | 
|     #֪ͨ¿Í»§¶Ë  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
| #ͬ²½ÉèÖÃ Íæ¼ÒºÍ³èÎï¼°ÒÑÕÙ»½µÄÕÙ»½ÊÞ ÊÓÒ°²ã  | 
| def SetPlayerSightLevel(curPlayer, sightLevel):  | 
|     # µ±ÊÓÒ°ÉèÖÃ0ʱ£¬ÔÚ¾³½çµØÍ¼Ôò×Ô¶¯ÉèÖÃÒÑÑ¡ÔñµÄ¾³½çÄѶÈÊÓÒ°  | 
|     if sightLevel == 0:  | 
|         realmDifficulty = GetMapRealmDifficulty(curPlayer)  | 
|         if realmDifficulty:  | 
|             sightLevel = realmDifficulty  | 
|             GameWorld.DebugLog("¾³½çµØÍ¼×Ô¶¯ÉèÖÃÒÑÑ¡ÔñµÄ¾³½çÄѶÈÊÓÒ°: sightLevel=%s" % sightLevel)  | 
|               | 
|     curPlayer.SetSightLevel(sightLevel)  | 
|     rolePet = curPlayer.GetPetMgr().GetFightPet()  | 
|     #ÎÞ³öÕ½³èÎï  | 
|     if rolePet:  | 
|         rolePet.SetSightLevel(sightLevel)  | 
|       | 
|     for i in range(curPlayer.GetSummonCount()):  | 
|         curSummon = curPlayer.GetSummonNPCAt(i)  | 
|         if not curSummon:  | 
|             continue  | 
|         curSummon.SetSightLevel(sightLevel)  | 
|     return |