| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #  | 
| ##@package E:/GameSVN/U3DGame/ProjectSServer/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py  | 
| # @todo:   | 
| #  | 
| # @author: Alee  | 
| # @date 2017-10-24 ÏÂÎç09:18:54  | 
| # @version 1.0  | 
| #  | 
| # @note:   | 
| #  | 
| #---------------------------------------------------------------------  | 
| #------------------------------------------------------------------------------   | 
| import GameWorld  | 
| import IPY_GameWorld  | 
| import PlayerControl  | 
| import ItemCommon  | 
| import GameMap  | 
| import EventShell  | 
| import NPCCommon  | 
| import ReadChConfig  | 
| import BuffSkill  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import SkillCommon  | 
| import IpyGameDataPY  | 
| import PlayerFB  | 
| import ShareDefine  | 
| import EventReport  | 
| import PlayerFamily  | 
| import PlayerActivity  | 
| import ItemControler  | 
| import PlayerSuccess  | 
| import GameFuncComm  | 
| import PyGameData  | 
| import PlayerVip  | 
| import GameObj  | 
| import FBLogic  | 
| import ChConfig  | 
| import PlayerGoldInvest  | 
|   | 
| import datetime  | 
| import random  | 
| import json  | 
| import math  | 
| import time  | 
| import copy  | 
| #---------------------------------------------------------------------  | 
| #È«¾Ö±äÁ¿  | 
| Def_VSFB_CanEnter = 'VSFB_CanEnter'                   #¿ÉÒÔ½øÈë  | 
| Def_VSFB_IsClose = 'VSFB_IsClose'                     #¸±±¾¹Ø±Õ  | 
| Def_VSFB_NotFamilyID = 'VSFB_NotFamilyID'             #½ñÈÕ¶ÔÕ½Î޴˼Ò×åID  | 
| Def_VSFB_NotFight = 'VSFB_NotFight'                   #½ñÈÕÎÞ¶ÔÕ½ÐÅÏ¢  | 
|   | 
| #¸±±¾°ïÖúÐÅϢͨÓÃkey  | 
| Help_lineID = 'lineID' #¹¦ÄÜÏß·ID  | 
| Help_step = 'step' #µ±Ç°¸±±¾²½Ö裬´Ó1¿ªÊ¼£¬1~n  | 
| Help_wheel = 'wheel' #µ±Ç°²¨Êý(¹Ø¿¨±àºÅ)£¬´Ó1¿ªÊ¼£¬1~n  | 
| Help_wheelTotal = 'wheelTotal' #×ܲ¨Êý(¹Ø¿¨±àºÅ)£¬´Ó1¿ªÊ¼£¬1~n  | 
| Help_npc = 'npc' #NPCÒÑ»÷ɱ¸öÊý [{"NPCID":150,"killCnt":100}]  | 
| Help_npcTotal = 'npcTotal' #NPC×ÜÒÑ»÷ɱ¸öÊý  | 
| Help_npcTotalNeed = 'npcTotalNeed' #NPC×ÜÐè»÷ɱ¸öÊý  | 
| Help_exp = 'exp' #ÒÑ»ñµÃ¾Ñé  | 
| Help_expPoint = 'expPoint' #ÒÑ»ñµÃ¾Ñéµã  | 
| Help_money = 'money' #ÒÑ»ñµÃÇ® [{"moneyType":3,"moneyValue":1000}]  | 
| Help_score = 'score' #ÒÑ»ñµÃ»ý·Ö  | 
| Help_grade = 'grade' #ÆÀ¼¶(5-S,4-A,3-B,2-C,1-D)  | 
| Help_leaderID = 'leaderID' #¶É½ÙÍæ¼ÒID  | 
| Help_isHelp = 'isHelp' #±¾´ÎÊÇ·ñÊÇÖúÕ½  | 
| Help_helpCount = 'helpCount' #¸Ã¸±±¾½ñÈÕÒÑÖúÕ½´ÎÊý  | 
| Help_relation = 'relation' #¸Ã¸±±¾¹ØÏµ¼Ó³ÉÐÅÏ¢ [ÓÅÏȹØÏµ, ×ܼӳÉ]  | 
| Help_robotJob = 'robotJob' #»úÆ÷ÈËÖ°Òµ {"ObjID":job, ...}  | 
| Help_isAuto = 'isAuto' #ÊÇ·ñ×Ô¶¯ÕÙ»½  | 
| Help_hasRefreshBoss = 'hasRefreshBoss' #ÊÇ·ñÒÑË¢ÐÂboss  | 
| Help_gsItemInfo = 'gsItemInfo' #¾Û»ê¸±±¾ÎïÆ·ÐÅÏ¢ {"²¨Êý":[[{"ItemID":101, "ItemCount":10}]]}  | 
|   | 
| #¸±±¾½áËãÐÅϢͨÓÃkey  | 
| Over_dataMapID = 'dataMapID' #Êý¾ÝµØÍ¼ID  | 
| Over_lineID = 'lineID' #¹¦ÄÜÏß·ID  | 
| Over_isPass = 'isPass' #ÊÇ·ñ¹ý¹Ø0»ò1  | 
| Over_isSweep = 'isSweep' #ÊÇ·ñɨµ´  | 
| Over_exp = 'exp' #»ñµÃ¾Ñé  | 
| Over_expPoint = 'expPoint' #»ñµÃ¾Ñéµã  | 
| Over_extraExp = 'extraExp' #»ñµÃ¶îÍâ¾Ñé  | 
| Over_extraExpPoint = 'extraExpPoint' #»ñµÃ¶îÍâ¾Ñéµã  | 
| Over_money = 'money' #»ñµÃÇ® [{"moneyType":3,"moneyValue":1000}]  | 
| Over_sp = 'sp' #»ñµÃspÖµ  | 
| Over_costTime = 'costTime' #ºÄʱ£¬ºÁÃë  | 
| Over_rank = 'rank' #ºÄʱ£¬ºÁÃë  | 
| Over_npcTotal = 'npcTotal' #NPC×ÜÒÑ»÷ɱ¸öÊý  | 
| Over_wheel = 'wheel' #µ±Ç°²¨Êý(¹Ø¿¨±àºÅ)£¬´Ó1¿ªÊ¼£¬1~n  | 
| Over_grade = 'grade' #ÆÀ¼¶(5-S,4-A,3-B,2-C,1-D)  | 
| Over_itemInfo = 'itemInfo' #ÎïÆ·Áбí [{"ItemID":101, "ItemCount":10, "IsBind":1, "IsSuite":1, "UserData":"×Ô¶¨ÒåÊôÐÔ×Ö·û´®"}]  | 
| Over_succItemInfo = 'succItemInfo' #ÎïÆ·ÁÐ±í  | 
| Over_firstPassItem = 'firstPassItem' #ÎïÆ·ÁÐ±í  | 
| Over_score = 'score' #ÒÑ»ñµÃ»ý·Ö  | 
| Over_extrScore = 'extrScore' #ÒÑ»ñµÃ¶îÍâ»ý·Ö  | 
| Over_enterLV = 'enterLV' #½øÈëʱµÈ¼¶  | 
| Over_leaderID = 'leaderID' #¶É½ÙÍæ¼ÒID  | 
| Over_helpPlayer = 'helpPlayer' #ÖúÕ½Íæ¼ÒÐÅÏ¢ {"Íæ¼ÒID":{Íæ¼ÒÐÅÏ¢key:value, ...}, ...}  | 
| Over_ownerID = 'ownerID' #¹éÊôÍæ¼ÒID  | 
| Over_ownerName = 'ownerName' #¹éÊôÍæ¼ÒÃû  | 
| Over_isAssist = 'isAssist' #ÊÇ·ñÐÖú  | 
|   | 
| #¸±±¾ÐÐΪ  | 
| (  | 
| Def_FbActionEncourage, # ¹ÄÎè  | 
| Def_FbActionChangeLine, # ±ä¸üÌôÕ½µÄ¹¦ÄÜÏß  | 
| ) = range(2)  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## GameFB pyÊý¾Ý»º´æ, Ã¿ÌõÐéÄâ·ÖÏßÊý¾Ý¶ÀÁ¢¹ÜÀí£¬¸±±¾ÓÐÐèÒªÓÃʱ±ØÐëÏÈ SetGameFBData  | 
| def SetGameFBData(attrKey, data): setattr(PyGameData, "GFBD_%s_%s" % (attrKey, GameWorld.GetGameWorld().GetLineID()), data)  | 
| def GetGameFBData(attrKey): return getattr(PyGameData, "GFBD_%s_%s" % (attrKey, GameWorld.GetGameWorld().GetLineID()))  | 
| #---------------------------------------------------------------------  | 
| def GetFBIpyData(mapID):  | 
|     mapID = GetRecordMapID(mapID)  | 
|     return IpyGameDataPY.GetIpyGameDataNotLog("FBFunc", mapID)  | 
| def GetFBLineIpyData(mapID, lineID, isDefaultLine=True):  | 
|     mapID = GetRecordMapID(mapID)  | 
|     fbLineIpyData = IpyGameDataPY.GetIpyGameDataNotLog("FBLine", mapID, lineID)  | 
|     if not fbLineIpyData and isDefaultLine:  | 
|         #GameWorld.DebugLog("ûÓÐÖ¸¶¨¹¦ÄÜÏß·µÄÔòĬÈÏÈ¡0£¬ÔÙûÓеϰ¾ÍÊDz»ÐèÒªµÄmapID=%s, lineID=%s" % (mapID, lineID))  | 
|         fbLineIpyData = IpyGameDataPY.GetIpyGameDataNotLog("FBLine", mapID, 0)  | 
|     return fbLineIpyData  | 
|   | 
| def GetFBLineEnterPosInfo(mapID, lineID, fbLineIpyData=None):  | 
|     # ×ø±êÐÅÏ¢  | 
|     if not fbLineIpyData:  | 
|         fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|     return None if not fbLineIpyData else fbLineIpyData.GetEnterPosInfo()  | 
| def GetFBLineStepTime(mapID, lineID=0):  | 
|     # ½×¶Îʱ¼äÐÅÏ¢  | 
|     fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|     return None if not fbLineIpyData else fbLineIpyData.GetStepTime()  | 
| def GetFBLineRefreshNPC(mapID, lineID=0):   | 
|     # Ë¢¹ÖÐÅÏ¢  | 
|     fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|     return None if not fbLineIpyData else fbLineIpyData.GetRefreshNPC()  | 
| def GetFBLineGrade(mapID, lineID=0):  | 
|     # ÆÀ¼¶¹æÔòÐÅÏ¢  | 
|     fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|     return None if not fbLineIpyData else fbLineIpyData.GetGradeInfo()  | 
| def GetFBLineReward(mapID, lineID):  | 
|     # ½±ÀøÐÅÏ¢£»Ö§³Öɨµ´È¡½±Àø  | 
|     fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|     return None if not fbLineIpyData else fbLineIpyData.GetRewardInfo()  | 
|   | 
| def GetFBGradeRewardRateList(mapID):  | 
|     fbIpyData = GetFBIpyData(mapID)  | 
|     return [] if not fbIpyData else fbIpyData.GetRewardRate()  | 
|   | 
| def GetFBFuncOpenState(dataMapID):  | 
|     ## »ñÈ¡¸±±¾¿ªÆô״̬ @return: 0-¹Ø±Õ£»1-¿ªÆô  | 
|     # ÓÐÅäÖÿª·Åʱ¼äÏÞÖÆµÄ£¬ÓÉGameServer¾ö¶¨  | 
|     if dataMapID in PyGameData.FBEnterTimeLimiitMapID:  | 
|         return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_FBCanEnter % dataMapID)  | 
|       | 
|     return 1  | 
|   | 
| def GetFBHasOpenToday(dataMapID, dayStr):  | 
|     #»ñÈ¡¸±±¾µ±ÌìÊÇ·ñÓпªÆô¹ý '0314'´ú±í3ÔÂ14ºÅ  | 
|     if dataMapID not in PyGameData.FBOpenTimeRecord:  | 
|         return  | 
|     return dayStr in PyGameData.FBOpenTimeRecord[dataMapID]  | 
|   | 
|   | 
| def CheckCanEnterFBComm(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, reqEnterCnt=1, isNotify=True, isTeamAsk=False):  | 
|     # ¿É·ñ½øÈ븱±¾Í¨Óüì²é, É¨µ´Í¨Óà  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     if not FBLogic.OnNeedCheckCanEnterFBComm(curPlayer, mapID, lineID):  | 
|         return ShareDefine.EntFBAskRet_OK  | 
|       | 
|     # ×ܱíͨÓüì²é  | 
|     if fbIpyData:  | 
|         #¿ª·þÌ쿪·Å¼ì²é  | 
|         if not GetFBFuncOpenState(mapID):  | 
|             GameWorld.Log("µ±Ç°Ê±¼ä먦·Å¸Ã¸±±¾!mapID=%s" % (mapID), playerID)  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(curPlayer, "FBIsNotOpen")  | 
|             return ShareDefine.EntFBAskRet_FBClose  | 
|           | 
|         #½øÈë´ÎÊýÅÐ¶Ï  | 
|         canEnter, notifyMark = __CheckCanEnterFBByTime(curPlayer, mapID, lineID, fbIpyData, reqEnterCnt, isTeamAsk)  | 
|         if not canEnter:  | 
|             if notifyMark:  | 
|                 PlayerControl.NotifyCode(curPlayer, notifyMark, [mapID])  | 
|             return ShareDefine.EntFBAskRet_NoEnterCnt  | 
|           | 
|         #½øÈëCDÅÐ¶Ï  | 
|         if CheckIsEnterCD(curPlayer, mapID):  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(curPlayer, "SingleEnterCD", [mapID])  | 
|             return ShareDefine.EntFBAskRet_EnterCD  | 
|     # ¹¦ÄÜÏß·ͨÓüì²é  | 
|     if fbLineIpyData:  | 
|         #µÈ¼¶ÅÐ¶Ï  | 
|         curLV = curPlayer.GetLV()  | 
|         lvLimitMin = fbLineIpyData.GetLVLimitMin()  | 
|         lvLimitMax = fbLineIpyData.GetLVLimitMax()  | 
|         if lvLimitMin and curLV < lvLimitMin:  | 
|             GameWorld.Log("Íæ¼ÒµÈ¼¶²»×ã, ÎÞ·¨½øÈ븱±¾!mapID=%s,lineID=%s,curLV(%s) < lvLimitMin(%s)"   | 
|                           % (mapID, lineID, curLV, lvLimitMin), playerID)  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(curPlayer, "FbLV", [mapID])  | 
|             return ShareDefine.EntFBAskRet_LVLimit  | 
|         if lvLimitMax and curLV > lvLimitMax:  | 
|             GameWorld.Log("Íæ¼ÒµÈ¼¶³¬¹ý, ÎÞ·¨½øÈ븱±¾!mapID=%s,lineID=%s,curLV(%s) > lvLimitMax(%s)"   | 
|                           % (mapID, lineID, curLV, lvLimitMax), playerID)  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(curPlayer, "FbLV", [mapID])  | 
|             return ShareDefine.EntFBAskRet_LVLimit  | 
|           | 
|         #ÃÅÆ±ÅÐ¶Ï  | 
|         if not GetFBEnterTicket(curPlayer, mapID, lineID, fbLineIpyData, reqEnterCnt, isTeamAsk)[0]:  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_157069", [mapID])  | 
|             return ShareDefine.EntFBAskRet_NoTicket  | 
|           | 
|     return ShareDefine.EntFBAskRet_OK  | 
|   | 
| def __CheckCanEnterFBByTime(curPlayer, mapID, lineID, fbIpyData, reqEnterCnt, isTeamAsk):  | 
|     #½øÈë´ÎÊýÅÐ¶Ï  | 
|     maxTimes = fbIpyData.GetDayTimes()  | 
|     if not maxTimes:  | 
|         return True, ""  | 
|       | 
|     # Ê״νøÈëÃâ·Ñ  | 
|     if mapID in [ChConfig.Def_FBMapID_PersonalBoss]:  | 
|         curfbStar = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [mapID])  | 
|         if not curfbStar:  | 
|             GameWorld.DebugLog("OnEnterFBEvent Ê״νøÈë¸Ã¸±±¾Ïß·Ãâ·Ñ!mapID=%s,lineID=%s" % (mapID, lineID))  | 
|             return True, ""  | 
|           | 
|     #playerID = curPlayer.GetPlayerID()  | 
|     enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)  | 
|     maxCnt = GetEnterFBMaxCnt(curPlayer, mapID)  | 
|     if enterCnt + reqEnterCnt <= maxCnt:  | 
|         return True, ""  | 
|       | 
|     ### ÒÔÏÂÊǵ½´ï´ÎÊýÉÏÏÞºóµÄ´¦Àí  | 
|     fbType = GameWorld.GetMap().GetMapFBTypeByMapID(mapID)  | 
|       | 
|     # µ¥È˸±±¾´ïµ½´ÎÊýºó²»¿ÉÔÙ½øÈë  | 
|     if fbType == IPY_GameWorld.fbtSingle:  | 
|         #GameWorld.Log("ÒÑ´ïµ½µ±ÈÕ×î´ó½øÈë´ÎÊý!µ¥È˸±±¾ mapID=%s,enterCnt=%s,reqEnterCnt=%s,maxTimes=%s,maxCnt=%s"   | 
|         #              % (mapID, enterCnt, reqEnterCnt, maxTimes, maxCnt), playerID)  | 
|         return False, "GeRen_chenxin_268121"  | 
|       | 
|     # ×é¶Ó¸±±¾  | 
|     if fbType == IPY_GameWorld.fbtTeam:  | 
|         # ÎÞÖúÕ½µÄ²»¿ÉÔÙ½øÈë  | 
|         if not fbIpyData.GetHelpPoint():  | 
|             #GameWorld.Log("ÒÑ´ïµ½µ±ÈÕ×î´ó½øÈë´ÎÊý!×é¶Ó¸±±¾ mapID=%s,enterCnt=%s,reqEnterCnt=%s,maxTimes=%s,maxCnt=%s"   | 
|             #              % (mapID, enterCnt, reqEnterCnt, maxTimes, maxCnt), playerID)  | 
|             return False, "GeRen_chenxin_268121"  | 
|           | 
|         # ¿ÉÖúÕ½µÄ²»¿Éµ¥È˽øÈëÖúÕ½£¬¿É·¢ÆðÆ¥Åä  | 
|         if not isTeamAsk and (not curPlayer.GetTeamID() or curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TeamMemCount) <= 1):  | 
|             #GameWorld.Log("ÒÑ´ïµ½µ±ÈÕ×î´ó½øÈë´ÎÊý!×é¶Ó¸±±¾²»¿Éµ¥ÈËÖúÕ½£¡ mapID=%s,enterCnt=%s,reqEnterCnt=%s,maxTimes=%s,maxCnt=%s"   | 
|             #              % (mapID, enterCnt, reqEnterCnt, maxTimes, maxCnt), playerID)  | 
|             return False, "TeamSingleEnter"  | 
|           | 
|     elif mapID not in ChConfig.Def_NoLimitEnterCntMap:  | 
|         #GameWorld.Log("ÒÑ´ïµ½µ±ÈÕ×î´ó½øÈë´ÎÊý! mapID=%s,enterCnt=%s,reqEnterCnt=%s,maxTimes=%s,maxCnt=%s"   | 
|         #              % (mapID, enterCnt, reqEnterCnt, maxTimes, maxCnt), playerID)  | 
|         return False, "GeRen_chenxin_268121"  | 
|       | 
|     # ÖܽøÈë´ÎÊýÔݲ»×ö£¬´ýÀ©Õ¹...  | 
|       | 
|     return True, ""  | 
|   | 
| ## »ñÈ¡¸±±¾½øÈëÃÅÆ±ÐÅÏ¢  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param mapID µØÍ¼id  | 
| #  @param lineID Ïß·id  | 
| #  @return [ÊÇ·ñ¿É½ø, [[ÃÅÆ±Ë÷ÒýÁбí, delCnt], ...], É¾³ý¸öÊý, ÊÇ·ñÓаó¶¨, ¿ÛÇ®ÐÅÏ¢]  | 
| def GetFBEnterTicket(curPlayer, mapID, lineID=0, fbLineIpyData=None, reqEnterCnt=1, isTeamAsk=False):  | 
|     #ÃÅÆ±ÅÐ¶Ï  | 
|     if not fbLineIpyData:  | 
|         fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|           | 
|     ticketID = fbLineIpyData.GetTicketID()  | 
|     if not ticketID:  | 
|         return True, [], 0, False, []  | 
|       | 
|     ticketCostCntList = fbLineIpyData.GetTicketCostCnt()  | 
|     if not ticketCostCntList:  | 
|         GameWorld.ErrLog("ûÓÐÅäÖÃÃÅÆ±ÏûºÄ!mapID=%s,lineID=%s" % (mapID, lineID), curPlayer.GetPlayerID())  | 
|         return False, [], 0, False, []  | 
|       | 
|     enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)  | 
|     costCnt = ticketCostCntList[-1] if enterCnt >= len(ticketCostCntList) else ticketCostCntList[enterCnt]  | 
|     totalCostCnt = costCnt*reqEnterCnt  | 
|     if not totalCostCnt:  | 
|         GameWorld.ErrLog("ûÓÐÅäÖÃÃÅÆ±ÏûºÄ!mapID=%s,lineID=%s" % (mapID, lineID), curPlayer.GetPlayerID())  | 
|         return False, [], 0, False, []  | 
|       | 
|     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|     enough, indexList, hasBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(ticketID, itemPack, totalCostCnt)  | 
|     if not enough:  | 
|         ticketPrice = fbLineIpyData.GetTicketPrice()  | 
|         if ticketPrice and not isTeamAsk: #×é¶Ó½ø×é¶Ó¸±±¾Ê±±ØÐëÒªÓÐÃÅÆ±µÀ¾ß  | 
|             costMoney = ticketPrice * lackCnt  | 
|             costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, costMoney)  | 
|             return bool(costMoneyList), indexList, totalCostCnt, hasBind, costMoneyList  | 
|         GameWorld.DebugLog("ÃÅÆ±²»×ã, ÎÞ·¨½øÈ븱±¾!mapID=%s,lineID=%s,ticketID=%s,reqEnterCnt=%s,totalCostCnt=%s"   | 
|                       % (mapID, lineID, ticketID, reqEnterCnt, totalCostCnt), curPlayer.GetPlayerID())  | 
|         return False, [], 0, False, []  | 
|       | 
|     return enough, indexList, totalCostCnt, hasBind, []  | 
|   | 
| ## »ñÈ¡¸±±¾½øÈëÃÅÆ±ÐÅÏ¢  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param mapID µØÍ¼id  | 
| #  @param lineID Ïß·id  | 
| #  @return ÊÇ·ñ³É¹¦¿Û³ý, ÊÇ·ñʹÓÃÁ˰ó¶¨ÃÅÆ±  | 
| def DelFBEnterTicket(curPlayer, mapID, lineID=0, enterCnt=1):  | 
|     isEnough, indexList, delCnt, hasBind, costMoneyList = GetFBEnterTicket(curPlayer, mapID, lineID, None, enterCnt)  | 
|     if not isEnough:  | 
|         return False, hasBind  | 
|     if costMoneyList:  | 
|         infoDict = {"MapID":mapID, "LineID":lineID, 'EnterCount':enterCnt}  | 
|         for moneyType, moneyNum in costMoneyList:  | 
|             if not PlayerControl.PayMoney(curPlayer, moneyType, moneyNum, ChConfig.Def_Cost_EnterFB, infoDict):  | 
|                 return False, hasBind  | 
|     if not indexList:  | 
|         return True, hasBind  | 
|     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|     ItemCommon.ReduceItem(curPlayer, itemPack, indexList, delCnt, False, "FBTicket")  | 
|     return True, hasBind  | 
|   | 
|   | 
| ## »ñÈ¡¸±±¾Íæ¼ÒÊý¾Ý¿â×ÖµäÐÅÏ¢Öµ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param key ×Öµäkey  | 
| #  @param defaultValue Ä¬ÈÏÖµ  | 
| #  @return  | 
| def GetFBPDictValue(curPlayer, key, defaultValue=0):  | 
|     return curPlayer.NomalDictGetProperty(key, defaultValue, ChConfig.Def_PDictType_FB)  | 
|   | 
| ## ÉèÖø±±¾Íæ¼ÒÊý¾Ý¿â×ÖµäÐÅÏ¢Öµ  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param key ×Öµäkey  | 
| #  @param value ÉèÖõÄÖµ  | 
| #  @return  | 
| def SetFBPDictValue(curPlayer, key, value):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, key, value, ChConfig.Def_PDictType_FB)  | 
|     return  | 
|   | 
| def UpdFBLineNPCStrengthenLV(playerID, isLeave):  | 
|     '''¶¯Ì¬¸üи±±¾NPC³É³¤µÈ¼¶  | 
|     '''  | 
|     attrStrengthenInfo = ReadChConfig.GetEvalChConfig("NPCAttrStrengthen")  | 
|     if not attrStrengthenInfo:  | 
|         return  | 
|       | 
|     mapID = GetRecordMapID(GameWorld.GetMap().GetMapID())  | 
|     if mapID not in attrStrengthenInfo[NPCCommon.NPCAttr_DynNPCLVMap]:  | 
|         #GameWorld.DebugLog("·Ç¶¯Ì¬¸üи±±¾NPC³É³¤µÈ¼¶µÄµØÍ¼!")  | 
|         return  | 
|       | 
|     maxLV = 0  | 
|     totalLV = 0  | 
|     playerCnt = 0  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|         if isLeave and curPlayer.GetPlayerID() == playerID:  | 
|             continue  | 
|         curLV = curPlayer.GetLV()  | 
|         totalLV += curLV  | 
|         playerCnt += 1  | 
|         if maxLV < curLV:  | 
|             maxLV = curLV  | 
|     if not playerCnt:  | 
|         return  | 
|     averageLV = totalLV / playerCnt  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_NPCStrengthenAverageLV, averageLV)  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_NPCStrengthenMaxLV, maxLV)  | 
|     GameWorld.Log("NPC³É³¤¶¯Ì¬µÈ¼¶±ä¸ü: isLeave=%s,totalLV=%s,playerCnt=%s,averageLV=%s,maxLV=%s"   | 
|                   % (isLeave, totalLV, playerCnt, averageLV, maxLV), playerID)  | 
|     # ÉϹÅÕ½³¡ÌØÊâ´¦Àí  | 
|     if mapID == ChConfig.Def_FBMapID_ElderBattlefield:  | 
|         lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|         fbLineIpyData = GetFBLineIpyData(mapID, lineID)  | 
|         lvLimitMin = 0 if not fbLineIpyData else fbLineIpyData.GetLVLimitMin()  | 
|         robotLVDiff = IpyGameDataPY.GetFuncCfg("ElderBattlefieldCfg", 5)  | 
|         robotLVMin, robotLVMax = averageLV - robotLVDiff, averageLV  | 
|         robotLVMin = max(lvLimitMin, robotLVMin)  | 
|         gameFB.SetGameFBDict(ChConfig.Def_FB_NPCStrengthenMaxLV, robotLVMax)  | 
|         gameFB.SetGameFBDict(ChConfig.Def_FB_NPCStrengthenMinLV, robotLVMin)  | 
|         GameWorld.Log("    ¸üÐÂÉϹŻúÆ÷È˵ȼ¶·¶Î§: lineID=%s,robotLVDiff=%s,robotLV=(%s~%s)" % (lineID, robotLVDiff, robotLVMin, robotLVMax))  | 
|     return True  | 
|   | 
| def UpdFBLineNPCStrengthenPlayerCnt(playerID, isLeave):  | 
|     '''¶¯Ì¬¸üи±±¾NPC³É³¤ÈËÊý  | 
|     '''  | 
|     attrStrengthenInfo = ReadChConfig.GetEvalChConfig("NPCAttrStrengthen")  | 
|     if not attrStrengthenInfo:  | 
|         return  | 
|       | 
|     mapID = GetRecordMapID(GameWorld.GetMap().GetMapID())  | 
|     coefficientDict = attrStrengthenInfo[NPCCommon.NPCAttr_DynPCCoefficientMap]  | 
|     if mapID not in coefficientDict:  | 
|         #GameWorld.DebugLog("·Ç¶¯Ì¬¸üи±±¾NPC³É³¤ÈËÊýµÄµØÍ¼!")  | 
|         return  | 
|     isRefreshNPCAttrNow = coefficientDict[mapID] # ÊÇ·ñÂíÉÏË¢ÐÂÊôÐÔ  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     playerCount = GameWorld.GetMapCopyPlayerManager().GetPlayerCount()  | 
|     if isLeave:  | 
|         playerCount = max(1, playerCount - 1)  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_NPCStrengthenPlayerCnt, playerCount)  | 
|     GameWorld.Log("NPC³É³¤¶¯Ì¬ÈËÊý±ä¸ü: playerCount=%s,isLeave=%s,isRefreshNPCAttrNow=%s"   | 
|                   % (playerCount, isLeave, isRefreshNPCAttrNow), playerID)  | 
|       | 
|     if isRefreshNPCAttrNow:  | 
|         #GameWorld.DebugLog("    Á¢ÂíË¢ÐÂNPCÊôÐÔ!")  | 
|         gameNPCManager = GameWorld.GetNPCManager()  | 
|         for index in xrange(gameNPCManager.GetNPCCount()):  | 
|             curNPC = gameNPCManager.GetNPCByIndex(index)  | 
|             if curNPC.GetID() == 0:  | 
|                 continue  | 
|             if curNPC.GetType() in [IPY_GameWorld.ntFunctionNPC, IPY_GameWorld.ntPet]:  | 
|                 continue  | 
|             NPCCommon.DoNPCAttrStrengthen(curNPC, False, True)  | 
|               | 
|     return True  | 
|   | 
| def SetNPCDropDoCountRate(gameFB, doCountRate, doCountAdd):  | 
|     ## ÉèÖùÖÎïµôÂäÖ´ÐдÎÊýÍò·ÖÂÊ  | 
|     ''' ÉèÖùÖÎïµôÂäÖ´ÐдÎÊýÍò·ÖÂÊ ¼° ¹Ì¶¨¼Ó³É´ÎÊýÖµ  | 
|     @param doCountRate: ´ÎÊýÍò·ÖÂÊ  | 
|     @param doCountAdd: ´ÎÊý¹Ì¶¨Öµ      | 
|     '''  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_DropDoCountRate, doCountRate)  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_DropDoCountAdd, doCountAdd)  | 
|     GameWorld.Log("ÉèÖùÖÎïµôÂäÖ´ÐдÎÊýÐÅÏ¢: doCountRate=%s, doCountAdd=%s" % (doCountRate, doCountAdd))  | 
|     return  | 
|   | 
| def GetHadSetFBPropertyMark():  | 
|     #ÊÇ·ñÒѾÉèÖùý¸±±¾Ïß·ÊôÐÔ  | 
|     return GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Map_FBDict_PropertyMark) > 0  | 
| ## »ñÈ¡¸±±¾ÊôÐÔmark  | 
| #  @param   | 
| #  @return  | 
| def GetFBPropertyMark():  | 
|     return GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Map_FBDict_PropertyMark) - 1 # È¡ÖµÊ±-1  | 
|   | 
| ## »ñÈ¡¸±±¾ÊôÐÔmark  | 
| #  @param propertyMark  | 
| #  @return  | 
| def SetFBPropertyMark(propertyMark, setPlayer=None):  | 
|     GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_FBDict_PropertyMark, propertyMark + 1) # ´æ´¢Ê±+1²ÅÄÜÅжÏÊÇ·ñ´æ´¢¹ý  | 
| #    if setPlayer != None:  | 
| #        PlayerControl.SetFBFuncLineID(setPlayer, propertyMark)  | 
| #        GameWorld.DebugLog("SetFBPropertyMark ÉèÖÃÍæ¼Ò¸±±¾¹¦ÄÜÏß·ID: %s" % propertyMark, setPlayer.GetPlayerID())  | 
| #        return  | 
| #      | 
| #    playerManager = GameWorld.GetMapCopyPlayerManager()  | 
| #    for index in xrange(playerManager.GetPlayerCount()):  | 
| #        curPlayer = playerManager.GetPlayerByIndex(index)  | 
| #        if not curPlayer.GetPlayerID():  | 
| #            continue  | 
| #        PlayerControl.SetFBFuncLineID(curPlayer, propertyMark)  | 
| #        GameWorld.DebugLog("SetFBPropertyMark ¹ã²¥Íæ¼Ò¸±±¾¹¦ÄÜÏß·ID: %s" % propertyMark, curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| ## ÊÇ·ñÒѾ¿Û³ýÈ볡ȯ/½øÈë´ÎÊýµÈ  | 
| #  @param   | 
| #  @return  | 
| def GetHadDelTicket(curPlayer):  | 
|     return GameWorld.GetGameFB().GetPlayerGameFBDictByKey(curPlayer.GetID(), ChConfig.FBPlayerDict_IsDelTicket)  | 
|   | 
| ## ÉèÖÃÒѾ¿Û³ýÈ볡ȯ  | 
| #  @param propertyMark  | 
| #  @return  | 
| def SetHadDelTicket(curPlayer, delSign=1):  | 
|     GameWorld.GetGameFB().SetPlayerGameFBDict(curPlayer.GetID(), ChConfig.FBPlayerDict_IsDelTicket, delSign)  | 
|     return  | 
|   | 
| ## ×Ô¶¨Ò峡¾°½×¶Î  | 
| def GetCustomMapStep(curPlayer, mapID, lineID):  | 
|     return curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_CustomMapStep % (mapID, lineID))  | 
| def SetCustomMapStep(curPlayer, mapID, lineID, step):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_CustomMapStep % (mapID, lineID), step)  | 
|     if step == ChConfig.CustomMapStep_Over:  | 
|         PlayerControl.SetCustomMap(curPlayer, 0, 0)  | 
|     return  | 
|   | 
| def GetCurSingleFBPlayer():  | 
|     ''' »ñÈ¡µ±Ç°µ¥È˸±±¾Íæ¼Ò '''  | 
|     curPlayer = None  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     if playerManager.GetPlayerCount() > 0:  | 
|         curPlayer = playerManager.GetPlayerByIndex(0)  | 
|     return curPlayer  | 
|   | 
| def GetFBJoinType(curPlayer, isHelpFight):  | 
|     ## »ñÈ¡¸±±¾²ÎÓëÀàÐÍ  | 
|     if isHelpFight:  | 
|         return ChConfig.FB_JoinType_Help  | 
|     if curPlayer.GetTeamID() and GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_TeamPlayerCount) > 1:  | 
|         return ChConfig.FB_JoinType_Multi  | 
|     return ChConfig.FB_JoinType_Single  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##¡¡»ñµÃ¸±±¾Ê£Óàʱ¼ä  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return Ê£Óàʱ¼ä  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetFB_RemainTime(tick):  | 
|     lastTick = tick - GameWorld.GetGameWorld().GetOpenFBTick()  | 
|     existTime = GameWorld.GetMap().GetExistTime()  | 
|     return existTime - lastTick  | 
| #---------------------------------------------------------------------  | 
| def UpdateFBGrade(tick, gradeTimeList, curPlayer=None, timeType=IPY_GameWorld.tttFlagTake):  | 
|     '''¸üе±Ç°¸±±¾ÐǼ¶¡¢ÆÀ¼¶  | 
|     @param gradeTimeList: ÆÀ¼¶·Ö¶Îʱ¼äÁÐ±í£¬µ¥Î»Ãë [×î¸ßÆÀ¼¶¿ÉÓÃʱ¼ä, Ï¼¶¿ÉÓÃʱ¼ä, ..., ×îµÍ¼¶¿ÉÓÃʱ¼ä]  | 
|     @param curPlayer: ´¥·¢µÄÍæ¼Ò£¬Ò»°ãÊÇDoEnterʱµ÷Ó㬻áͬ²½¸üÐÂÒ»´Î¸±±¾ÆÀ¼¶²¢½«ÐÅϢ֪ͨ¸ÃÍæ¼Ò  | 
|     @note: ÐǼ¶£º1-1ÐÇ£»2-2ÐÇ ...            [60, 20, 10]  | 
|             ÆÀ¼¶£º1-D£»2-C£»3-B£»4-A£»5-S;    [60, 30, 30, 20, 10]  | 
|     '''  | 
|     lowest = 1  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     curGrade = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_Grade)  | 
|     #×îºóÒ»¸öÆÀ¼¶ÁË£¬²»ÔÙ´¦Àí  | 
|     if curGrade == lowest:  | 
|         if curPlayer:  | 
|             FBLogic.DoFBHelp(curPlayer, tick)  | 
|         return curGrade  | 
|       | 
|     useSecond = int((tick - gameFB.GetFBStepTick()) / 1000.0) # Õ½¶·½×¶ÎÒѺÄ×ÜÃëÊý  | 
|     diffSecond = 0  | 
|     updGrade = len(gradeTimeList)  | 
|     gSecondTotal = 0  | 
|     for gSecond in gradeTimeList:  | 
|         gSecondTotal += gSecond  | 
|         diffSecond = gSecondTotal - useSecond  | 
|         # »¹ÔÚµ±Ç°ÆÀ¼¶¶Î  | 
|         if diffSecond > 0:  | 
|             break  | 
|         updGrade -= 1 # ÓÃʱ³¬¹ýµ±Ç°ÆÀ¼¶¶Î£¬½µ¼¶  | 
|     updGrade = max(lowest, updGrade) # ±£µ××îµÍ¼¶  | 
|     if curGrade == updGrade and not curPlayer:  | 
|         return curGrade  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_Grade, updGrade)  | 
|       | 
|     GameWorld.DebugLog("UpdateFBGrade useSecond=%s,gradeTimeList=%s,curGrade=%s,updGrade=%s,diffSecond=%s"   | 
|                        % (useSecond, gradeTimeList, curGrade, updGrade, diffSecond))  | 
|     if curPlayer:  | 
|         FBLogic.DoFBHelp(curPlayer, tick)  | 
|         if updGrade != lowest:  | 
|             curPlayer.Sync_TimeTick(timeType, 0, diffSecond * 1000, True)  | 
|     else:  | 
|         playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for index in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(index)  | 
|             if not curPlayer:  | 
|                 continue  | 
|             FBLogic.DoFBHelp(curPlayer, tick)  | 
|             if updGrade != lowest:  | 
|                 curPlayer.Sync_TimeTick(timeType, 0, diffSecond * 1000, True)  | 
|     return updGrade  | 
|   | 
| def UpdateCustomFBGrade(curPlayer, tick, gradeTimeList, timeType=IPY_GameWorld.tttFlagTake):  | 
|     '''¸üе±Ç°¸±±¾ÐǼ¶¡¢ÆÀ¼¶  | 
|     @param gradeTimeList: ÆÀ¼¶·Ö¶Îʱ¼äÁÐ±í£¬µ¥Î»Ãë [×î¸ßÆÀ¼¶¿ÉÓÃʱ¼ä, Ï¼¶¿ÉÓÃʱ¼ä, ..., ×îµÍ¼¶¿ÉÓÃʱ¼ä]  | 
|     @param curPlayer: ´¥·¢µÄÍæ¼Ò£¬Ò»°ãÊÇDoEnterʱµ÷Ó㬻áͬ²½¸üÐÂÒ»´Î¸±±¾ÆÀ¼¶²¢½«ÐÅϢ֪ͨ¸ÃÍæ¼Ò  | 
|     @note: ÐǼ¶£º1-1ÐÇ£»2-2ÐÇ ...            [60, 20, 10]  | 
|             ÆÀ¼¶£º1-D£»2-C£»3-B£»4-A£»5-S;    [60, 30, 30, 20, 10]  | 
|     '''  | 
|     lowest = 1  | 
|     curGrade = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomSceneGrade)  | 
|     #×îºóÒ»¸öÆÀ¼¶ÁË£¬²»ÔÙ´¦Àí  | 
|     if curGrade == lowest:  | 
|         return curGrade  | 
|       | 
|     fbStepTick = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick)  | 
|     useSecond = int((tick - fbStepTick) / 1000.0) # Õ½¶·½×¶ÎÒѺÄ×ÜÃëÊý  | 
|     diffSecond = 0  | 
|     updGrade = len(gradeTimeList)  | 
|     gSecondTotal = 0  | 
|     for gSecond in gradeTimeList:  | 
|         gSecondTotal += gSecond  | 
|         diffSecond = gSecondTotal - useSecond  | 
|         # »¹ÔÚµ±Ç°ÆÀ¼¶¶Î  | 
|         if diffSecond > 0:  | 
|             break  | 
|         updGrade -= 1 # ÓÃʱ³¬¹ýµ±Ç°ÆÀ¼¶¶Î£¬½µ¼¶  | 
|     updGrade = max(lowest, updGrade) # ±£µ××îµÍ¼¶  | 
|     if curGrade == updGrade:  | 
|         return curGrade  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneGrade, updGrade)  | 
|       | 
|     GameWorld.DebugLog("UpdateCustomFBGrade useSecond=%s,gradeTimeList=%s,curGrade=%s,updGrade=%s,diffSecond=%s"   | 
|                        % (useSecond, gradeTimeList, curGrade, updGrade, diffSecond))  | 
|       | 
|     Notify_FBHelp(curPlayer, {Help_grade:updGrade})  | 
|     if updGrade != lowest:  | 
|         curPlayer.Sync_TimeTick(timeType, 0, diffSecond * 1000, True)  | 
|     return updGrade  | 
|   | 
| def NotifyFBOver(curPlayer, dataMapID, lineID, isPass, overDict={}):  | 
|     ## Í¨ÖªÍæ¼Ò¸±±¾×ܽá, ¸Ãº¯Êýͳһ¼¸¸ö±Ø´ø²ÎÊý  | 
|     overDict.update({Over_dataMapID:dataMapID, Over_lineID:lineID, Over_isPass:int(isPass)})  | 
|     overMsg = json.dumps(overDict, ensure_ascii=False)  | 
|     curPlayer.Frm_FBEnd(overMsg)  | 
|     GameWorld.DebugLog("NotifyFBOver: %s" % overMsg, curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def NotifyFBHelp(curPlayer, lineID, helpDict={}):  | 
|     ## Í¨ÖªÍæ¼Ò¸±±¾°ïÖúÐÅÏ¢, ¸Ãº¯Êýͳһ¼¸¸ö±Ø´ø²ÎÊý  | 
|     helpDict.update({Help_lineID:lineID})  | 
|     helpMsg = json.dumps(helpDict, ensure_ascii=False)  | 
|     curPlayer.Frm_FBHelp(helpMsg)  | 
|     GameWorld.DebugLog("NotifyFBHelp: %s" % helpMsg, curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| ## Í¨ÖªÍæ¼Ò¸±±¾×Ü½á  | 
| #  @param curPlayer ±»Í¨ÖªµÄÍæ¼Ò  | 
| #  @param msgDict ½áÊøÐÅÏ¢×Öµä  | 
| #  @return None  | 
| def Notify_FB_Over(curPlayer, msgDict):  | 
|     msgDict = json.dumps(msgDict, ensure_ascii=False)  | 
|     curPlayer.Frm_FBEnd('%s' % msgDict)  | 
|     return  | 
|   | 
| def Notify_FBHelp(curPlayer, helpDict):  | 
|     ## Í¨ÖªÍæ¼Ò¸±±¾°ïÖúÐÅÏ¢  | 
|     helpDict = json.dumps(helpDict, ensure_ascii=False)  | 
|     curPlayer.Frm_FBHelp('%s' % str(helpDict))  | 
|     return  | 
|   | 
| def GetJsonItemList(itemList):  | 
|     ## [[itemID,itemCount,isAuctionItem], curItem] -> [{"ItemID":101, "Count":10, "IsAuctionItem":1, "UserData":"×Ô¶¨ÒåÊôÐÔ×Ö·û´®"}]  | 
|     jsonItemList = []  | 
|     for itemInfo in itemList:  | 
|         itemDict = {}  | 
|         if isinstance(itemInfo, list) or isinstance(itemInfo, tuple):  | 
|             infolen = len(itemInfo)  | 
|             if infolen > 0:  | 
|                 itemDict['ItemID'] = itemInfo[0]  | 
|             if infolen > 1:  | 
|                 itemDict['Count'] = itemInfo[1]  | 
|             if infolen > 2:  | 
|                 itemDict['IsAuctionItem'] = int(itemInfo[2])  | 
|         elif isinstance(itemInfo, int):  | 
|             itemDict['ItemID'] = itemInfo  | 
|         elif isinstance(itemInfo, dict):  | 
|             itemDict = itemInfo  | 
|         else: #ÎïÆ·ÊµÀý  | 
|             if not ItemCommon.CheckItemCanUse(itemInfo):  | 
|                 continue  | 
|             itemDict['ItemID'] = itemInfo.GetItemTypeID()  | 
|             itemDict['Count'] = itemInfo.GetCount()  | 
|             itemDict['IsAuctionItem'] = ItemControler.GetIsAuctionItem(itemInfo)  | 
|             #itemDict['IsSuite'] = int(itemInfo.GetIsSuite())  | 
|             itemDict['UserData'] = itemInfo.GetUserData()  | 
|         jsonItemList.append(itemDict)  | 
|     return jsonItemList  | 
|   | 
| def GetJsonMoneyList(moneyDict):  | 
|     ## {moneyType:moneyValue} -> [{"moneyType":3,"moneyValue":1000}]  | 
|     moneyList = []  | 
|     for moneyType, moneyValue in moneyDict.items():  | 
|         moneyList.append({"moneyType":moneyType, "moneyValue":moneyValue})  | 
|     return moneyList  | 
|   | 
| def GetJsonNPCKillList(npcDict):  | 
|     ## {npcid:killcnt} -> [{"NPCID":150,"killCnt":100}]  | 
|     killList = []  | 
|     for npcid, killCnt in npcDict.items():  | 
|         killList.append({"NPCID":npcid, "killCnt":killCnt})  | 
|     return killList  | 
|   | 
| def GetJsonNPCHPPerList(npcDict):  | 
|     ## {npcid:HPPer} -> [{"NPCID":150,"HPPer":100}]  | 
|     killList = []  | 
|     for npcid, HPPer in npcDict.items():  | 
|         killList.append({"NPCID":npcid, "HPPer":HPPer})  | 
|     return killList  | 
|   | 
| def OnPickUpItem(curPlayer, curItem, tick, overFunc):  | 
|     mapItemType = curItem.GetType()  | 
|     if mapItemType != ChConfig.Def_ItemType_Money:  | 
|         playerID = curPlayer.GetID()  | 
|         isEquip = ItemCommon.CheckItemIsEquip(curItem)  | 
|         jsonItem = ItemCommon.GetJsonItem(curItem)  | 
|         if playerID in PyGameData.g_fbPickUpItemDict:  | 
|             if isEquip:  | 
|                 PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)  | 
|             else:  | 
|                 isIn = False  | 
|                 for itemInfo in PyGameData.g_fbPickUpItemDict[playerID]:  | 
|                     if not isinstance(itemInfo, dict):  | 
|                         continue  | 
|                     if itemInfo["ItemID"] == jsonItem["ItemID"] and itemInfo.get("IsBind") == jsonItem.get("IsBind"):  | 
|                         itemInfo["Count"] = itemInfo.get("Count", 1)+ jsonItem.get("Count", 1)  | 
|                         isIn = True  | 
|                         break  | 
|                 if not isIn:  | 
|                     PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)  | 
|         else:  | 
|             PyGameData.g_fbPickUpItemDict[playerID] = [jsonItem]  | 
|               | 
|     if overFunc == None:  | 
|         return  | 
|       | 
|     playerItemCount = 0  | 
|     mapItemManager = GameWorld.GetMapItemManager()  | 
|     for index in xrange(mapItemManager.GetMapItemCount()):  | 
|         mapItem = mapItemManager.GetMapItemByIndex(index)  | 
|         if not mapItem or mapItem.IsEmpty():  | 
|             continue  | 
|           | 
|         # »¹ÓÐÊôÓÚ×Ô¼ºµÄ¶«Î÷û¼ñ²»Í¨Öª½áÊø  | 
|         if mapItem.GetOwnerID() == curPlayer.GetPlayerID():  | 
|             playerItemCount += 1  | 
|           | 
|     isItemAllPickUp = (playerItemCount <= 1)  | 
|     if isItemAllPickUp:  | 
|         overFunc(curPlayer, tick)  | 
|           | 
|     return  | 
| #---------------------------------------------------------------------  | 
| def SyncDynamicBarrierState(barrierPointList, state, curPlayer=None):  | 
|     '''ͬ²½¶¯Ì¬ÕϰÎïÊÇ·ñÓÐЧÐÔ  | 
|     @param barrierPointList: ÕϰÎïµãÁбí [[aPosX,aPosY,bPosX,bPosY,angle¿ÉÑ¡], [aPosX,aPosY,bPosX,bPosY,angle¿ÉÑ¡], ...]  | 
|     @param state: ÊÇ·ñÓÐЧ  | 
|     @param curPlayer: Ö¸¶¨Í¨ÖªÄ¿±êÍæ¼Ò£¬ÎªNoneʱ¹ã²¥±¾µØÍ¼ËùÓÐÍæ¼Ò  | 
|     '''  | 
|     barrierStatePack = ChPyNetSendPack.tagMCDynamicBarrierState()  | 
|     barrierStatePack.Clear()  | 
|     barrierStatePack.State = state  | 
|     barrierStatePack.BarrierList = []  | 
|     for posInfo in barrierPointList:  | 
|         aPosX, aPosY, bPosX, bPosY = posInfo[:4]  | 
|         angle = posInfo[4] if len(posInfo) > 4 else 0  | 
|         barrier = ChPyNetSendPack.tagMCDynamicBarrier()  | 
|         barrier.APosX = aPosX  | 
|         barrier.APosY = aPosY  | 
|         barrier.BPosX = bPosX  | 
|         barrier.BPosY = bPosY  | 
|         barrier.Angle = angle  | 
|         barrierStatePack.BarrierList.append(barrier)  | 
|     barrierStatePack.Count = len(barrierStatePack.BarrierList)  | 
|     if curPlayer:  | 
|         NetPackCommon.SendFakePack(curPlayer, barrierStatePack)  | 
|     else:  | 
|         playManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for i in range(playManager.GetPlayerCount()):  | 
|             curPlayer = playManager.GetPlayerByIndex(i)  | 
|             if not curPlayer:  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(curPlayer, barrierStatePack)  | 
|     return  | 
|   | 
| ## ÃÅÏÔÒþ  | 
| #  @param doorIDList npcÁÐ±í  | 
| #  @param type 1£ºÃſɼû£» ÆäËû£ºÃŲ»¿É¼û  | 
| #  @return None  | 
| #  @remarks Ö§³Ö¹âǽIDÖØ¸´  | 
| def OpenOrCloseDoorEx(doorIDList, type, isReborn=False):  | 
|     gameNPCManager = GameWorld.GetNPCManager()  | 
|       | 
|     for i in xrange(gameNPCManager.GetNPCCount()):  | 
|         curNPC = gameNPCManager.GetNPCByIndex(i)  | 
|         if curNPC == None:  | 
|             continue  | 
|         npcID = curNPC.GetNPCID()  | 
|         if npcID not in doorIDList:  | 
|             continue  | 
|           | 
|         curType = curNPC.GetVisible()  | 
|           | 
|         #---Ãſɼû---  | 
|         if type == 1:  | 
|             if curType:  | 
|                 continue  | 
|   | 
|             if isReborn:  | 
|                 tick = GameWorld.GetGameWorld().GetTick()  | 
|                 NPCCommon.NPCControl(curNPC).DoNPCReborn(tick)  | 
|             curNPC.SetVisible(True)  | 
|             continue  | 
|               | 
|         #---ÃŲ»¿É¼û---  | 
|         if not curType:  | 
|             continue  | 
|           | 
|         curNPC.SetVisible(False)  | 
|           | 
|     return  | 
|   | 
| ## ÃÅÏÔÒþ  | 
| #  @param doorIDList npcÁÐ±í  | 
| #  @param type 1£ºÃſɼû£» ÆäËû£ºÃŲ»¿É¼û  | 
| #  @return None  | 
| #  @remarks ½öÖ§³Ö¹âǽID²»Öظ´µÄ  | 
| def OpenOrCloseDoor(doorIDList, type, isReborn=False):  | 
|     gameNPCManager = GameWorld.GetNPCManager()  | 
|       | 
|     for npcID in doorIDList:  | 
|         curNPC = gameNPCManager.FindGameNPCByNPCID(npcID)  | 
|         if curNPC == None:  | 
|             GameWorld.ErrLog('¸±±¾ÎÞ·¨²éÕÒ, ÃÅID = %s' % (npcID))  | 
|             continue  | 
|               | 
|         curType = curNPC.GetVisible()  | 
|           | 
|         #---Ãſɼû---  | 
|         if type == 1:  | 
|             if curType:  | 
|                 continue  | 
|   | 
|             if isReborn:  | 
|                 tick = GameWorld.GetGameWorld().GetTick()  | 
|                 NPCCommon.NPCControl(curNPC).DoNPCReborn(tick)  | 
|             curNPC.SetVisible(True)  | 
|             continue  | 
|               | 
|         #---ÃŲ»¿É¼û---  | 
|         if not curType:  | 
|             continue  | 
|           | 
|         curNPC.SetVisible(False)  | 
|   | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## ³õʼ»¯¸±±¾»ý·ÖÅÅÐаæ(×î´ó´ÎÊý)  | 
| #  @param maxCount ×î´ó´ÎÊý  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def InitBillBoard(maxCount):  | 
|     GameWorld.GetGameFB().Broadcast_FbBillboard(maxCount)  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## ³õʼ»¯Íæ¼Ò¸±±¾»ý·ÖÅÅÐаñ  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def InitBillBoardPlayer(curPlayer):  | 
|     curPlayerID = curPlayer.GetPlayerID()  | 
|     curPlayerName = curPlayer.GetName()  | 
|     playerBillBoard = GameWorld.GetGameFB().GetFbBillBoardPlayer(curPlayerID)  | 
|     playerBillBoard.SetPlayerID(curPlayerID)  | 
|     playerBillBoard.SetPlayerName(curPlayerName)  | 
| #    playerBillBoard.SetCountry(curPlayer.GetCountry())  | 
|     playerBillBoard.SetPoint(0)  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## Ôö¼Ó/¼õÉÙÍæ¼Ò¸±±¾»ý·ÖÅÅÐаñ   | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param type ²Ù×÷ÀàÐÍ type = 1,¼Ó,,2,¼õ   | 
| #  @param value ²Ù×÷Öµ  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def AddorReduceBillBoard(curPlayer , type , value):  | 
|     playerBillBoard = GameWorld.GetGameFB().GetFbBillBoardPlayer(curPlayer.GetPlayerID())  | 
|     #Ôö¼Ó»ý·Ö  | 
|     if type == 1:  | 
|         point = min((playerBillBoard.GetPoint() + value), 65535)  | 
|     #¼õÉÙ»ý·Ö  | 
|     else:  | 
|         point = max((playerBillBoard.GetPoint() - value), 0)  | 
|           | 
|     playerBillBoard.SetPoint(point)  | 
|     return point  | 
| #---------------------------------------------------------------------  | 
| ## ÉèÖÃÅÅÐаñÍæ¼Ò¹ú¼®  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def SetCountryBillBoard(curPlayer, country):  | 
|     playerBillBoard = GameWorld.GetGameFB().GetFbBillBoardPlayer(curPlayer.GetPlayerID())  | 
|     playerBillBoard.SetCountry(country)  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃµ±Ç°Íæ¼ÒµÄ¸±±¾»ý·ÖÅÅÐаñ  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetPlayerBillBoardPoint(curPlayer):  | 
|     playerBillBoard = GameWorld.GetGameFB().GetFbBillBoardPlayer(curPlayer.GetPlayerID())  | 
|     return playerBillBoard.GetPoint()  | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃÍæ¼ÒÔÚ¸±±¾»ý·ÖÅÅÐаñÖеÄλÖà  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetPlayerIndex_InBillBoard(curPlayer):  | 
|     playerBillBoard = GameWorld.GetGameFB().GetFbBillBoardPlayer(curPlayer.GetPlayerID())  | 
|     return playerBillBoard.GetBillboardIndex()  | 
| #---------------------------------------------------------------------  | 
| ## Ë¢Ð»ý·ÖÅÅÐаñ  | 
| #  @param maxCount ÅÅÐаñ×î´ó¸öÊý  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def NotifyBillBoard(maxCount):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     #ÅÅÐòÅÅÐаñ  | 
|     gameFB.SortFbBillBoardPlayer()  | 
|     #֪ͨ¿Í»§¶Ë  | 
|     gameFB.Broadcast_FbBillboard(maxCount)  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## ÉèÖø±±¾×´Ì¬  | 
| #  @param step ²½ÖèÊý  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def SetFBStep(step, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetFBStep(step)  | 
|     gameFB.SetFBStepTick(tick)  | 
|     GameWorld.Log("SetFBStep %s, tick=%s" % (step, tick), GameWorld.GetGameWorld().GetPropertyID())  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## ¸ø¿Í»§¶Ëµ¯ÏûÏ¢  | 
| #  @param keepTime ³ÖÐøÊ±¼äs  | 
| #  @param msgType ASCIIÂë TFbSystemMessageType  | 
| #  @param msg ÏûÏ¢  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def Sync_FbSystemMessage(keepTime , msgType , msg):  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|       | 
|     for i in range(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(i)  | 
|         if not curPlayer.GetPlayerID():  | 
|             continue  | 
|           | 
|         #(int keepTime, int msgType, char * msg)  | 
|         #msgType -> IPY_GameWorld.fmtUseSystemMessage , IPY_GameWorld.fmtUseAscII  | 
|         curPlayer.Sync_FbSystemMessage(keepTime , msgType , msg)  | 
|           | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## ¸ø¿Í»§¶Ë·¢ËÍÍ¨ÖªÍæ¼Òµ¹¼ÆÊ±ÐÅÏ¢  | 
| #  @param msgType ÈçIPY_GameWorld.tttWaitStart  | 
| #  @param msgTick ¿ªÊ¼µÄtick  | 
| #  @param npcID   | 
| #  @param isContinue ³ÖÐøÍ¨Öª  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def Sync_Player_TimeTick(msgType , msgTick , npcID=0 , isContinue=True):  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|       | 
|     for index in range(0 , playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer.GetPlayerID():  | 
|             continue  | 
|           | 
|         curPlayer.Sync_TimeTick(msgType , npcID, msgTick, isContinue)  | 
|           | 
|     return  | 
|   | 
| ## ¸ø¿Í»§¶Ë·¢ËÍÍ¨ÖªÍæ¼Òµ¹¼ÆÊ±ÐÅÏ¢  | 
| #  @param msgType ÈçIPY_GameWorld.tttWaitStart  | 
| #  @param msgTick ¿ªÊ¼µÄtick  | 
| #  @param isSendPrevMsg ÊÇ·ñ·¢ËÍÇå¿ÕÉÏÒ»¸öµ¹¼ÆÊ±ÐÅÏ¢ÀàÐÍ  | 
| #  @param npcID   | 
| #  @param isContinue ³ÖÐøÍ¨Öª  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def Sync_Player_TimeTickEx(msgType , msgTick , isSendPrevMsg, npcID=0 , isContinue=True):  | 
|     prevMsgType = None  | 
|     if isSendPrevMsg:  | 
|         prevMsgType = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Map_FBDict_PrevFBTimeType)  | 
|         if prevMsgType and prevMsgType != msgType: # ÓÐÉÏÒ»¸öÐÅÏ¢£¬ÇÒÓ뵱ǰÐÅÏ¢²»Í¬²Å·¢  | 
|             isSendPrevMsg = True  | 
|         else:  | 
|             isSendPrevMsg = False  | 
|           | 
|     GameWorld.Log("Sync_Player_TimeTickEx() prevMsgType=%s,msgType=%s" % (prevMsgType, msgType))  | 
|     GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_FBDict_PrevFBTimeType, msgType)  | 
|       | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|       | 
|     for index in range(0 , playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer.GetPlayerID():  | 
|             continue  | 
|           | 
|         if isSendPrevMsg and prevMsgType:  | 
|             curPlayer.Sync_TimeTick(prevMsgType , npcID, 0, isContinue)  | 
|         curPlayer.Sync_TimeTick(msgType , npcID, msgTick, isContinue)  | 
|           | 
|     return  | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃÊÇ·ñ¿ÉÒÔ½øÈë¶ÔÕ½¸±±¾  | 
| #  @param familyID ¼Ò×åID  | 
| #  @return ×Ö·û´® Èç'VSFB_CanEnter'  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetCanEnterVSFB(familyID):  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     todayNotFight = True  | 
|       | 
|     for index in range(gameWorld.GetGameWorldCount()):  | 
|         gameFB = gameWorld.GetGameFBByFbIndex(index)  | 
|           | 
|         familyVsManager = gameFB.GetFamilyVS()  | 
|         attackID = familyVsManager.GetFamilyID()  | 
|         defenceID = familyVsManager.GetVSFamilyID()  | 
|         #½ñÈÕÓÐÈüÊ  | 
|         if attackID or defenceID:  | 
|             todayNotFight = False  | 
|           | 
|         #²»ÊÇÕⳡս¶·  | 
|         if familyID not in [ attackID , defenceID ]:  | 
|             continue  | 
|           | 
|         if gameWorld.GetOpenStateByFbIndex(index) != IPY_GameWorld.fbosOpen:  | 
|             #¸±±¾ÒÑ¹Ø±Õ  | 
|             return Def_VSFB_IsClose  | 
|           | 
|         #¿ÉÒÔ½øÈë  | 
|         return Def_VSFB_CanEnter  | 
|       | 
|     #½ñÈÕÎÞÈüÊ  | 
|     if todayNotFight:  | 
|         return Def_VSFB_NotFight  | 
|       | 
|     #ÎÞ·¨²éÕÒ¶ÔÕ½¼Ò×å  | 
|     return Def_VSFB_NotFamilyID  | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃÖ¸¶¨Ïß·µÄ¸±±¾¹ÜÀíÆ÷¼°Ïß·  | 
| #  @param familyID ¼Ò×åID  | 
| #  @return None , None or gameFB , index  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def Get_VS_Line_GameFB(familyID):  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     for index in range(gameWorld.GetGameWorldCount()):  | 
|         gameFB = gameWorld.GetGameFBByFbIndex(index)  | 
|           | 
|         familyVsManager = gameFB.GetFamilyVS()  | 
|         attackID = familyVsManager.GetFamilyID()  | 
|         defenceID = familyVsManager.GetVSFamilyID()  | 
|           | 
|         if familyID in [ attackID , defenceID ]:  | 
|             return gameFB , index  | 
|           | 
|     return None , None  | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃÖ¸¶¨ÏßÂ·Íæ¼Ò¹ÜÀíÆ÷  | 
| #  @param Ïß·Ë÷Òý  | 
| #  @return Íæ¼Ò¹ÜÀíÆ÷ IPY_MapCopyPlayerManager      | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def Get_Line_PlayerManager(lineIndex):  | 
|     return GameWorld.GetGameWorld().GetMapCopyPlayerManagerByFbIndex(lineIndex)  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃ×é¶Ó¸±±¾,µØÍ¼¹ÜÀíÆ÷  | 
| #  @param teamID ¶ÓÎéID  | 
| #  @return None or gameWorld  ÐÂʵÀý»¯µÄIPY_GameWorld  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def Get_TeamFB_Line_GameFB(teamID):  | 
|     gameMap = GameWorld.GetMap()  | 
|     #²»ÊÇ×é¶Ó¸±±¾, ÔÊÐí½øÈë  | 
|     if gameMap.GetMapFBType() != IPY_GameWorld.fbtTeam:  | 
|         GameWorld.Log('###µ÷Óú¯ÊýÒì³£ Get_TeamFB_Line_GameFB = %s' % (gameMap.GetMapFBType()))  | 
|         return  | 
|       | 
|     #и±±¾, ÔÊÐí½øÈë  | 
|     if not teamID:  | 
|         return  | 
|       | 
|     gameWorldManager = GameWorld.GetGameWorld()  | 
|       | 
|     for index in range(gameWorldManager.GetGameWorldCount()):  | 
|         gameWorld = IPY_GameWorld.IPY_GameWorld(index)  | 
|           | 
|         if gameWorld.GetPropertyID() != teamID:  | 
|             continue  | 
|           | 
|         return gameWorld  | 
|       | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##¼ì²éµ±Ç°¸±±¾×´Ì¬ÊÇ·ñ¿ÉÒÔ½øÈë  | 
| # @param teamID ×é¶ÓID  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks  | 
| def CheckFBStateCanEnter(askStruct):  | 
|     gameMapFBType = GameWorld.GetMap().GetMapFBType()  | 
|       | 
|     #---×é¶Ó¸±±¾¼ì²é---  | 
|     if gameMapFBType == IPY_GameWorld.fbtTeam:  | 
|         gameWorld = Get_TeamFB_Line_GameFB(askStruct.GetTeamID())  | 
|         if not gameWorld:  | 
|             #¿ÉÒÔ½øÈë  | 
|             return True  | 
|           | 
|         if gameWorld.GetCloseFBTick() > 0:  | 
|             #²»¿É½øÈë  | 
|             return False  | 
|           | 
|         if askStruct.GetTeamLV() == IPY_GameWorld.tmlLeader:  | 
|             '''ÔÒò£º   | 
|                                 ¶Ó³¤Í˳ö×é¶Ó¸±±¾£¬ÆäËû¶ÓÔ±»¹ÔÚÀïÃæ£¬´Ëʱ¸±±¾²»»á±»¹Ø±Õ  | 
|                                  ¶Ó³¤ÔÚ¶ÓÎéID²»±äµÄÇé¿öÏÂÓÖ×éÁËÆäËûÈË£¬È»ºóÓÖÏë½øÈ¥¸Ã¸±±¾£¬ÄÇôÕâʱ»á½øÈë֮ǰ¶ÓÔ±»¹ÔÚµÄÄÇÌõ¶ÓÎé·ÖÏߣ¬µ¼Ö¶ÓÎéÏß·´íÂÒ  | 
|                                 ËùÒÔ´Ë´¦²»ÔÊÐí¸Ã¶Ó³¤½øÈ룬²¢ÌáʾÆäµÈ´ý»òÖØÐ½¨¶Ó½øÈë  | 
|                                   | 
|             FBinCantEnter ¸±±¾ÇåÀíÖУ¬ÇëµÈ´ý¹Ø±Õ»òÖØÐ´´½¨¶ÓÎé½øÈë  | 
|             '''  | 
|             return False, "FBinCantEnter"  | 
|           | 
|         #¸±±¾Ôڵȴý¹Ø±Õ״̬²»ÔÊÐíÍæ¼Ò½øÈë  | 
|         return (gameWorld.GetOpenState() != IPY_GameWorld.fbosWaitForClose)  | 
|   | 
|     #¿ÉÒÔ½øÈë  | 
|     return True  | 
| #---------------------------------------------------------------------  | 
| def Sync_FBNPC(mapID=0, npcIDList=[], curPlayer=None):  | 
|     ## Í¬²½µ±Ç°¸±±¾NPC¸ø¸±±¾ÖеÄËùÓÐÍæ¼Ò  | 
|     if not mapID:  | 
|         mapID = GameWorld.GetMap().GetMapID()  | 
|         mapID = GetRecordMapID(mapID)  | 
|     npcCntDict = {}  | 
|     gameNPCManager = GameWorld.GetNPCManager()  | 
|     for index in xrange(gameNPCManager.GetNPCCount()):  | 
|         curNPC = gameNPCManager.GetNPCByIndex(index)  | 
|         npcID = curNPC.GetNPCID()  | 
|         if not npcID:  | 
|             continue  | 
|         if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  | 
|             continue  | 
|         if npcIDList and npcID not in npcIDList:  | 
|             continue  | 
|         npcCntDict[npcID] = npcCntDict.get(npcID, 0) + 1  | 
|           | 
|     if curPlayer:  | 
|         NPCCommon.SyncNPCCntInfo(curPlayer, mapID, npcCntDict)  | 
|     else:  | 
|         playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for i in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(i)  | 
|             if curPlayer.GetID() == 0:  | 
|                 continue  | 
|             NPCCommon.SyncNPCCntInfo(curPlayer, mapID, npcCntDict)  | 
|     return npcCntDict  | 
|   | 
| ##»ñµÃµØÍ¼ÉϵÄNPCÁÐ±í  | 
| # @param ÎÞ²ÎÊý  | 
| # @return ·µ»ØÖµ, NPCʵÀýÁбí[curNPC,curNPC,,,,,]  | 
| # @remarks »ñµÃµØÍ¼ÉϵÄNPCÁÐ±í  | 
| def GetMapNPCList():  | 
|     gameNPCList = []  | 
|     gameNPCManager = GameWorld.GetNPCManager()  | 
|       | 
|     for index in range(gameNPCManager.GetNPCCount()):  | 
|         curNPC = gameNPCManager.GetNPCByIndex(index)  | 
|           | 
|         if curNPC.GetID() == 0:  | 
|             continue  | 
|           | 
|         #@warning: ³èÎïÉè¼ÆÎªÎ´³öÕ½NPC, ÕâÀïÒª¹ýÂË  | 
|         if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  | 
|             continue  | 
|           | 
|         gameNPCList.append(curNPC)  | 
|       | 
|     return gameNPCList  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##»ñµÃµØÍ¼ÉϵÄϵͳNPCÊýÁ¿  | 
| # @param ÎÞ²ÎÊý  | 
| # @return NPCÁÐ±í  | 
| # @remarks ¿Í»§¶Ë·â°üÏìÓ¦  | 
| def GetMapSystemNPCList():  | 
|     #»ñÈ¡µØÍ¼¹«¹²NPCÁÐ±í  | 
|     findNPCList = []  | 
|       | 
|     #¸ù¾Ý¸±±¾ÐèÇó, ¹ýÂËNPC  | 
|     gameNPCManager = GameWorld.GetNPCManager()  | 
|     for index in range(gameNPCManager.GetNPCCount()):  | 
|         curNPC = gameNPCManager.GetNPCByIndex(index)  | 
|           | 
|         if curNPC.GetID() == 0 or GameObj.GetHP(curNPC) <= 0:  | 
|             continue  | 
|           | 
|         if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  | 
|             continue  | 
|           | 
|         #ÕÙ»½ÊÞÌØÊâÅÐ¶Ï  | 
|         if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:  | 
|             curNPCDetail = GameWorld.GetObjDetail(curNPC)  | 
|               | 
|             if curNPCDetail == None:  | 
|                 continue  | 
|               | 
|             curNPCOwner = curNPCDetail.GetOwner()  | 
|               | 
|             if curNPCOwner != None and curNPCOwner.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|                 #Íæ¼ÒµÄÕÙ»½ÊÞ²»¼Ç¼  | 
|                 continue  | 
|           | 
|         #·ûºÏÌõ¼þµÄ±¾µØÍ¼µÄNPCÁÐ±í  | 
|         findNPCList.append(curNPC)  | 
|       | 
|     return findNPCList  | 
| #---------------------------------------------------------------------  | 
| ##Ç¿ÖÆT³ö¸±±¾ÖÐËùÓеÄÍæ¼Ò  | 
| # @param ÎÞ²ÎÊý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks  | 
| def DoLogic_FBKickAllPlayer():  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|       | 
|     for i in range(0, playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(i)  | 
|           | 
|         if curPlayer.GetID() == 0:  | 
|             continue  | 
|           | 
|         #Íæ¼ÒÖ÷¶¯À뿪¸±±¾  | 
|         PlayerControl.PlayerLeaveFB(curPlayer)  | 
|       | 
|     return  | 
| #---------------------------------------------------------------------  | 
|   | 
| ##»ñµÃµØÍ¼ÉϵÄϵͳNPCÊýÁ¿(²»°üº¬npcµÄÕлÃÊÞ£¬ Ö»ÓÃÓÚÇå³ýfb¹Ö)  | 
| # @param ÎÞ²ÎÊý  | 
| # @return NPCÁÐ±í  | 
| # @remarks ¿Í»§¶Ë·â°üÏìÓ¦  | 
| def GetMapSystemNPCListEx():  | 
|     #»ñÈ¡µØÍ¼¹«¹²NPCÁÐ±í  | 
|     gameNPCList = GetMapNPCList()  | 
|     findNPCList = []  | 
|       | 
|     #¸ù¾Ý¸±±¾ÐèÇó, ¹ýÂËNPC  | 
|     for curNPC in gameNPCList:  | 
|         #ʬÌå²»´¦Àí  | 
|         if GameObj.GetHP(curNPC) <= 0:  | 
|             continue  | 
|           | 
|         #ÕÙ»½ÊÞÌØÊâÅÐ¶Ï  | 
|         if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:  | 
|               | 
|             curNPCDetail = GameWorld.GetObjDetail(curNPC)              | 
|             if curNPCDetail == None:  | 
|                 continue  | 
|               | 
|             curNPCOwner = curNPCDetail.GetOwner()              | 
|             if curNPCOwner != None and curNPCOwner.GetGameObjType() in (IPY_GameWorld.gotPlayer,  | 
|                                                                          IPY_GameWorld.gotNPC):  | 
|                 continue  | 
|           | 
|         #·ûºÏÌõ¼þµÄ±¾µØÍ¼µÄNPCÁÐ±í  | 
|         findNPCList.append(curNPC)  | 
|       | 
|     return findNPCList  | 
|   | 
|   | 
| ##Çå³ý¸±±¾npc  | 
| # @param ÎÞ²ÎÊý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def ClearFBNPC(ignoreIDList=[]):  | 
|       | 
|     #»÷ɱËùÓи±±¾ÕÙ»½³öÀ´µÄNPC  | 
|     for curNPC in GetMapSystemNPCListEx():  | 
|         if curNPC == None:  | 
|             continue  | 
|           | 
|         if curNPC.GetType() in [IPY_GameWorld.ntFunctionNPC, IPY_GameWorld.ntPet]:   | 
|             #³èÎï ¹¦ÄÜNPC³ýÍâ  | 
|             continue  | 
|   | 
|         if curNPC.GetNPCID() in ignoreIDList:  | 
|             #ºöÂÔÁÐ±í  | 
|             continue  | 
|           | 
|         NPCCommon.SetDeadEx(curNPC)      | 
|     return  | 
|   | 
| ##Çå³ý¸±±¾npc  | 
| # @param ÎÞ²ÎÊý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def ClearFBNPCEx(clearNPCIDList):  | 
|       | 
|     #»÷ɱËùÓи±±¾ÕÙ»½³öÀ´µÄNPC  | 
|     for curNPC in GetMapSystemNPCListEx():  | 
|         if curNPC == None:  | 
|             continue  | 
|           | 
|         if curNPC.GetType() in [IPY_GameWorld.ntFunctionNPC, IPY_GameWorld.ntPet]:   | 
|             #³èÎï ¹¦ÄÜNPC³ýÍâ  | 
|             continue  | 
|   | 
|         if curNPC.GetNPCID() not in clearNPCIDList:  | 
|             #ºöÂÔÁÐ±í  | 
|             continue  | 
|           | 
|         NPCCommon.SetDeadEx(curNPC)      | 
|     return  | 
|   | 
| ##»ñÈ¡¸±±¾NPC¸öÊý  | 
| # @param npcIDList: ÒªÍ³¼ÆµÄNPCIDÁÐ±í  | 
| # @param npcIDList: ²»°üº¬µÄNPCIDÁÐ±í  | 
| # @return ¸öÊý  | 
| def GetFBNPCCnt(npcIDList=[], ignoreIDList=[]):  | 
|       | 
|     npcCnt = 0  | 
|     for curNPC in GetMapSystemNPCListEx():  | 
|         if curNPC == None:  | 
|             continue  | 
|           | 
|         if curNPC.GetType() in [IPY_GameWorld.ntFunctionNPC, IPY_GameWorld.ntPet]:  | 
|             continue  | 
|   | 
|         npcID = curNPC.GetNPCID()  | 
|         if npcIDList and npcID not in npcIDList:  | 
|             continue  | 
|           | 
|         if ignoreIDList and npcID in ignoreIDList:  | 
|             continue  | 
|           | 
|         npcCnt += 1  | 
|           | 
|     return npcCnt  | 
|   | 
| ##ÉèÖõØÍ¼Ëæ»úË¢¹Ö  | 
| # @param refreshMark: Ë¢¹Ö±êʶµãmark  | 
| # @param npcID: Ë¢¹ÖNPCID  | 
| # @param needRefreshCnt: ÐèҪˢµÄ¸öÊý  | 
| # @param perMaxCnt: Ã¿¸öµã×î´óË¢¹ÖÊý  | 
| # @return  | 
| def SetRandomRefreshMapNPC(refreshMark, npcID, needRefreshCnt, perMaxCnt):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|       | 
|     npcIDKey = ChConfig.Map_NPC_RandomMapNPCID % refreshMark  | 
|     needCntKey = ChConfig.Map_NPC_RandomMapNPCNeedCnt % refreshMark  | 
|     perMaxCntKey = ChConfig.Map_NPC_RandomMapNPCPerMaxCnt % refreshMark  | 
|       | 
|     gameFB.SetGameFBDict(npcIDKey, npcID)  | 
|     gameFB.SetGameFBDict(needCntKey, needRefreshCnt)  | 
|     gameFB.SetGameFBDict(perMaxCntKey, perMaxCnt)  | 
|     return  | 
|   | 
| ## ---------------------------------- TD ---------------------------------------  | 
| # TDË¢¹ÖÅäÖÃ  | 
| (  | 
| Def_TDCfg_NextWheelTime, # Ç¿ÖƽøÈëÏÂÒ»´ó²¨Ê±¼ä(ÀÛ¼ÆÊ±¼ä)  | 
| Def_TDCfg_PrepareTime, # ´ó²¨¿ªÊ¼Ç°×¼±¸Ê±¼ä  | 
| Def_TDCfg_SmallWheelSpace, # Ð¡²¨Ë¢¹Ö¼ä¸ôʱ¼ä  | 
| Def_TDCfg_NotifyMark, # ´ó²¨Ë¢¹Ö¸±±¾¹ã²¥mark  | 
| ) = range(4)  | 
|   | 
| ## ¿ªÆôTDË¢¹ÖµãË¢¹Ö  | 
| # @param rMark: Ë¢¹Ö±êʶµãmark  | 
| # @param fileNum: Ë¢¹ÖÎļþ±ê¼Ç  | 
| # @param sign: Ë¢¹ÖÎļþÄÚ²ãNPC×é±ê¼Ç  | 
| # @param tick:   | 
| # @param isNotify: ÊÇ·ñ¹ã²¥  | 
| # @return  | 
| def OpenTDNPCRefresh(rMark, fileNum, sign, tick, isNotify):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshFileNum % rMark, fileNum)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshSignKey % rMark, sign)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshStartTick % rMark, tick)  | 
|       | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshSmallWheelNum % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_CurWheelStartTick % rMark, tick)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_CurWheelIsOver % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_AllWheelIsOver % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_NPCCnt % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_NPCBossCnt % rMark, 0)  | 
|       | 
|     if isNotify:  | 
|         __TDStartRefreshNotify(gameFB, fileNum, 0, sign)  | 
|     return  | 
|   | 
| ## ¹Ø±ÕTDË¢¹ÖµãË¢¹Ö  | 
| # @param rMark: Ë¢¹Ö±êʶµãmark  | 
| # @param isResetNPC: ÊÇ·ñÖØÖÃNPC¸öÊý  | 
| # @return  | 
| def CloseTDNPCRefresh(rMark, isResetNPC=True):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshFileNum % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshSignKey % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshStartTick % rMark, 0)  | 
|       | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshSmallWheelNum % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_CurWheelStartTick % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_CurWheelIsOver % rMark, 0)  | 
|       | 
|     if isResetNPC:  | 
|         gameFB.SetGameFBDict(ChConfig.Map_TDNPC_NPCCnt % rMark, 0)  | 
|         gameFB.SetGameFBDict(ChConfig.Map_TDNPC_NPCBossCnt % rMark, 0)  | 
|     return  | 
|   | 
| ## ¼ì²éTDË¢¹ÖµãÊÇ·ñÈ«²¿Ë¢¹Ö½áÊø  | 
| # @param rMarkList: ¼ì²é±êʶµãÁÐ±í  | 
| # @return  | 
| def IsTDNPCRefreshOver(rMarkList):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     for rMark in rMarkList:  | 
|         if not gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_AllWheelIsOver % rMark):  | 
|             return False  | 
|           | 
|     return True  | 
|   | 
| ## ¼ì²éTDË¢¹Öµã´ó²¨ÊÇ·ñË¢¹Ö½áÊø  | 
| # @param rMarkList: ¼ì²é±êʶµãÁÐ±í  | 
| # @return  | 
| def IsTDWheelRefreshOver(rMarkList):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     for rMark in rMarkList:  | 
|         if not gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_CurWheelIsOver % rMark):  | 
|             return False  | 
|     return True  | 
|   | 
| ## ¼ì²éTD±¾´ó²¨Ë¢µÄ¹ÖÊÇ·ñÈ«²¿±»»÷ɱ  | 
| def IsTDNPCCurWheelAllKilled(rMarkList):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     for rMark in rMarkList:  | 
|         npcCnt = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_NPCCnt % rMark)  | 
|         curWheelIsOver = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_CurWheelIsOver % rMark)  | 
|         # »¹Óй֠»ò ±¾²¨¹Ö»¹Ã»Ë¢Íê  | 
|         if npcCnt > 0 or not curWheelIsOver:  | 
|             return False  | 
|           | 
|     return True  | 
|   | 
| ## ¼ì²éÊÇ·ñÇ¿ÖÆ½øÈëÏÂÒ»²¨  | 
| # @param rMark: ±êʶµã  | 
| # @param tick:   | 
| # @return  | 
| def CheckForceEnterNextWheel(rMark, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     startTick = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshStartTick % rMark)  | 
|     curWheelNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark)  | 
|       | 
|     fileNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshFileNum % rMark)  | 
|     if fileNum <= 0:  | 
|         return False  | 
|       | 
|     refreshCfgList = ReadChConfig.GetEvalChConfig("TD_%s_Cfg" % fileNum)  | 
|     if curWheelNum >= len(refreshCfgList):  | 
|         return False  | 
|       | 
|     wheelInfoList = refreshCfgList[curWheelNum]  | 
|     forceNextWheelTime = wheelInfoList[Def_TDCfg_NextWheelTime]  | 
|     passTick = tick - startTick  | 
|     # 0ĬÈÏΪ²»Åжϣ¬Èç×îºóÒ»¹ØÖ±½ÓÌî0  | 
|     return forceNextWheelTime > 0 and passTick >= forceNextWheelTime  | 
|   | 
| ## ÉèÖýøÈëÏÂÒ»²¨  | 
| # @param rMark: ±êʶµã  | 
| # @param tick:   | 
| # @return  | 
| def SetEnterTDNextWheel(rMark, tick, isNotify):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     curWheelNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark)  | 
|     nextWheelNum = curWheelNum + 1  | 
|       | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark, nextWheelNum)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_RefreshSmallWheelNum % rMark, 0)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_CurWheelStartTick % rMark, tick)  | 
|     gameFB.SetGameFBDict(ChConfig.Map_TDNPC_CurWheelIsOver % rMark, 0)  | 
|       | 
|     fileNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshFileNum % rMark)  | 
|     if fileNum > 0 and isNotify:  | 
|         signKey = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshSignKey % rMark)  | 
|         __TDStartRefreshNotify(gameFB, fileNum, nextWheelNum, signKey)  | 
|           | 
|     GameWorld.DebugLog("TD ½øÈëÏÂÒ»²¨£ºfileNum=%s,rMark=%s,nextWheelNum=%s" % (fileNum, rMark, nextWheelNum))  | 
|     return  | 
|   | 
| ## ¿ªÊ¼Ë¢¹Ö¹ã²¥  | 
| # @param rMark: ±êʶµã  | 
| # @param fileNum:   | 
| # @return  | 
| def __TDStartRefreshNotify(gameFB, fileNum, wheelNum, sign):  | 
|     if fileNum <= 0:  | 
|         return  | 
|     refreshNPCDict = ReadChConfig.GetEvalChConfig("TD_%s_NPCID" % fileNum)  | 
|     refreshNPCList = refreshNPCDict.get(sign,[])  | 
|     if wheelNum >= len(refreshNPCList):  | 
|         return  | 
|     npcid = refreshNPCList[wheelNum][0][0][0]  | 
|     refreshCfgList = ReadChConfig.GetEvalChConfig("TD_%s_Cfg" % fileNum)  | 
|     if wheelNum < len(refreshCfgList):  | 
|         wheelInfoList = refreshCfgList[wheelNum]  | 
|         notifyMark = wheelInfoList[Def_TDCfg_NotifyMark]  | 
|         if notifyMark:  | 
|             # 0´ú±íµÚÒ»²¨  | 
|             PlayerControl.FBNotify(notifyMark, [npcid])  | 
|     return  | 
|   | 
|   | 
| ## ¸üбêʶµã¹ÖÎï¸öÊý  | 
| # @param curNPC: NPCʵÀý  | 
| # @param value: ¸üÐÂÖµ, Ö§³ÖÕý¸ºÊý  | 
| # @return  | 
| def UpdTDNPCCnt(curNPC, value):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     rMark = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshMark)  | 
|       | 
|     curMarkNPCBossCntKey = ChConfig.Map_TDNPC_NPCBossCnt % rMark  | 
|     bossCnt = gameFB.GetGameFBDictByKey(curMarkNPCBossCntKey)  | 
|     isBoss = ChConfig.IsGameBoss(curNPC)  | 
|     if isBoss:  | 
|         bossCnt = max(0, bossCnt + value)  | 
|         gameFB.SetGameFBDict(curMarkNPCBossCntKey, bossCnt)  | 
|           | 
|     curMarkNPCCntKey = ChConfig.Map_TDNPC_NPCCnt % rMark  | 
|     npcCnt = gameFB.GetGameFBDictByKey(curMarkNPCCntKey)  | 
|     updCnt = npcCnt + value  | 
|     updCnt = max(0, updCnt)  | 
|     gameFB.SetGameFBDict(curMarkNPCCntKey, updCnt)  | 
|     GameWorld.DebugLog("UpdTDNPCCnt rMark=%s,updCnt=%s,bossCnt=%s,isBoss=%s" % (rMark, updCnt, bossCnt, isBoss))  | 
|     return updCnt  | 
|   | 
| ## Í¨ÖªÏ²¨Ë¢¹Öʱ¼ä  | 
| #  @param curPlayer:Noneʱ¹ã²¥¸±±¾ÖÐËùÓÐÍæ¼Ò  | 
| #  @param rMark:  | 
| #  @param msgType:  | 
| #  @param tick:ʱ¼ä´Á  | 
| #  @return  | 
| def Sync_TDNextWheelTick(curPlayer, rMark, msgType, tick, msgID=0):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|       | 
|     curWheelNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark)  | 
|       | 
|     fileNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshFileNum % rMark)  | 
|     if fileNum <= 0:  | 
|         return -1  | 
|       | 
|     refreshCfgList = ReadChConfig.GetEvalChConfig("TD_%s_Cfg" % fileNum)  | 
|     if curWheelNum >= len(refreshCfgList):  | 
|         return -1  | 
|       | 
|     wheelInfoList = refreshCfgList[curWheelNum]  | 
|     nextWheelTime = wheelInfoList[Def_TDCfg_NextWheelTime]  | 
|       | 
|     if nextWheelTime <= 0:  | 
|         prepareTime = wheelInfoList[Def_TDCfg_PrepareTime]  | 
|         if not prepareTime:  | 
|             return -1  | 
|         curWheelStartTick = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_CurWheelStartTick % rMark)  | 
|         passTick = tick - curWheelStartTick  | 
|         nextWheelRemainTick = max(prepareTime - passTick, 0)  | 
|     else:  | 
|         startTick = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshStartTick % rMark)  | 
|         passTick = tick - startTick  | 
|         nextWheelRemainTick = max(nextWheelTime - passTick, 0)  | 
|     # IPY_GameWorld.tttFlagTake  | 
|     if curPlayer == None:  | 
|         Sync_Player_TimeTick(msgType, nextWheelRemainTick, msgID)  | 
|     else:  | 
|         curPlayer.Sync_TimeTick(msgType, msgID, nextWheelRemainTick, True)  | 
|     return nextWheelRemainTick  | 
|   | 
| ## ---------------------------------- TD ---------------------------------------  | 
| def GetEnterFBMaxCnt(curPlayer, mapID):  | 
|     ## »ñÈ¡¸±±¾×î´ó¿É½øÈë´ÎÊý: »ù±¾´ÎÊý + Ê±¼äÒѻָ´´ÎÊý + VIP¶îÍâ´ÎÊý + ¹ºÂò´ÎÊý + ÕһشÎÊý + Ê¹ÓõÀ¾ßÔö¼Ó´ÎÊý  | 
|     fbIpyData = GetFBIpyData(mapID)  | 
|     if not fbIpyData:  | 
|         return 0  | 
|     maxTimes = fbIpyData.GetDayTimes()  | 
|     MWPrivilegeID = fbIpyData.GetExtraTimesMWPriID()  | 
|       | 
|     mwAddCnt = 0#wmpIpyData.GetEffectValue() if wmpIpyData else 0  | 
|     extraTimesVIPPriID = fbIpyData.GetExtraTimesVIPPriID()  | 
|     extraCnt = PlayerVip.GetPrivilegeValue(curPlayer, extraTimesVIPPriID)  | 
|     buyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_BuyFbCntDay % mapID)  | 
|     recoverFbCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RecoverFbCnt % mapID)  | 
|     itemAddCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID)  | 
|     regainFbCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RegainFbCnt % mapID)  | 
|     investFBCnt = PlayerGoldInvest.GetAddFBCnt(curPlayer, mapID)  | 
|     maxCnt = maxTimes + regainFbCnt + extraCnt + buyCnt + recoverFbCnt + mwAddCnt + itemAddCnt + investFBCnt  | 
|     return maxCnt  | 
|   | 
| def GetFBDetailCntInfo(curPlayer, mapID):  | 
|     #·µ»ØFBÊ£ÓàÕý³£´ÎÊý¡¢Ê±¼ä»Ö¸´´ÎÊý¡¢vip¶îÍâ´ÎÊý¡¢ÒÑÂò´ÎÊý¡¢µÀ¾ßÔö¼Ó´ÎÊý¡¢Î´Âò´ÎÊý  | 
|     fbIpyData = GetFBIpyData(mapID)  | 
|     enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)  | 
|     maxTimes = fbIpyData.GetDayTimes()  | 
|     maxRegainFbCnt = 0  | 
|     recoverIntervalDict = IpyGameDataPY.GetFuncEvalCfg('FBCntRegainInterval', 1)  | 
|     if str(mapID) in recoverIntervalDict:  | 
|         maxRegainFbCnt = recoverIntervalDict[str(mapID)][0]  | 
|           | 
|     MWPrivilegeID = fbIpyData.GetExtraTimesMWPriID()  | 
|       | 
|     mwAddCnt = 0#wmpIpyData.GetEffectValue() if wmpIpyData else 0  | 
|     maxTimes += mwAddCnt #·¨±¦Ôö¼ÓµÄ´ÎÊý¼Óµ½»ù´¡´ÎÊýÀï  | 
|     extraTimesVIPPriID = fbIpyData.GetExtraTimesVIPPriID()  | 
|     extraCnt = PlayerVip.GetPrivilegeValue(curPlayer, extraTimesVIPPriID)  | 
|     buyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_BuyFbCntDay % mapID)  | 
|     recoverFbCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RecoverFbCnt % mapID)  | 
|     itemAddCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID)  | 
|     #ÏÈÓÃÕÒ»ØÀ´µÄ´ÎÊý£¬ÔÙÓÃVip¶îÍâ´ÎÊý£¬ÔÙÓÃÿÈÕˢдÎÊý¡¢Ê±¼ä»Ö¸´´ÎÊý¡¢ºÍVipÂò»ØÀ´µÄ´ÎÊý£¬×îºóÓþíÖá¼ÓµÄ´ÎÊý  | 
|     cntList = [recoverFbCnt, extraCnt, maxTimes, maxRegainFbCnt, buyCnt, itemAddCnt]  | 
|     rCntList = copy.deepcopy(cntList)  | 
|     sumCnt = 0  | 
|     for i, cnt in enumerate(cntList):  | 
|         sumCnt += cnt  | 
|         rCntList[i] = max(0, sumCnt - enterCnt)  | 
|         if enterCnt <= sumCnt:  | 
|             break  | 
|     rRecoverFbCnt, rExtraCnt, rCommonCnt, rRegainFbCnt, rBuyCnt, rItemAddCnt = rCntList  | 
|   | 
|     #δÂò´ÎÊý  | 
|     buyTimesVIPPriID = fbIpyData.GetBuyTimesVIPPriID()  | 
|     canBuyCnt = PlayerVip.GetPrivilegeValue(curPlayer, buyTimesVIPPriID)  | 
|     noBuyCnt = max(0, canBuyCnt - buyCnt)  | 
|     return [[rCommonCnt, rRegainFbCnt, rExtraCnt, rBuyCnt, rItemAddCnt, noBuyCnt], [maxTimes, maxRegainFbCnt, extraCnt, canBuyCnt, 10000, canBuyCnt]]  | 
|   | 
| ## Íæ¼Ò½øÈ븱±¾´ÎÊý  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param fbID ¸±±¾id  | 
| #  @return bool  | 
| def GetEnterFBCount(curPlayer, fbID, lineBit=-1):  | 
|     fbID = GetRecordMapID(fbID)  | 
|     enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % fbID)  | 
|     if lineBit >= 0:  | 
|         return GameWorld.GetDataByDigitPlace(enterCnt, lineBit)  | 
|     return enterCnt  | 
|   | 
| def AddFBCntByItem(curPlayer, itemID, mapID, addCnt):  | 
|     ## ÎïÆ·Ôö¼Ó¸±±¾´ÎÊý  | 
|     mapID = GetRecordMapID(mapID)  | 
|     itemAddCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID, itemAddCnt + addCnt)  | 
|     Sync_FBPlayerFBInfoData(curPlayer, mapID)  | 
|     PlayerControl.NotifyCode(curPlayer, 'AddActivityCount_1', [itemID, mapID, addCnt])  | 
|     OnFBCountChangeEffectRecoverCount(curPlayer, mapID)  | 
|     return  | 
|   | 
| ## Ôö¼ÓÍæ¼Ò½øÈ븱±¾´ÎÊý  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param fbID ¸±±¾id  | 
| #  @param addCount Ôö¼Ó´ÎÊý  | 
| #  @return ·µ»ØÖµÎÞÒâÒå  | 
| def AddEnterFBCount(curPlayer, fbID, addCount=1, lineBit=-1, isFree=False):  | 
|     ## @param isFree: ÊÇ·ñÃâ·Ñ½øÈëµÄ£¬Ãâ·ÑµÄ²»Ôö¼Óʵ¼Ê½øÈë´ÎÊý£¬µ«ÐèÒª´¥·¢½øÈë´ÎÊý¶îÍâ´¦Àí£¬Èç»îÔ¾¡¢³É¾ÍµÈ  | 
|     addCountEx = addCount  | 
|     addCount = 0 if isFree else addCount  | 
|     fbID = GetRecordMapID(fbID)  | 
|     enterCntKey = ChConfig.Def_Player_Dict_EnterFbCntDay % fbID  | 
|     enterCnt = curPlayer.NomalDictGetProperty(enterCntKey)  | 
|     if lineBit >= 0:  | 
|         curLineEnterCnt = GameWorld.GetDataByDigitPlace(enterCnt, lineBit)  | 
|         updEnterCnt = min(9, curLineEnterCnt + addCount)  | 
|         updValue = GameWorld.ChangeDataByDigitPlace(enterCnt, lineBit, updEnterCnt)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, enterCntKey, updValue)  | 
|     else:  | 
|         maxCnt = GetEnterFBMaxCnt(curPlayer, fbID)  | 
|         if enterCnt >= maxCnt:  | 
|             return False  | 
|         updCnt = min(maxCnt, enterCnt + addCount)  | 
|         addCount = updCnt-enterCnt  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, enterCntKey, updCnt)  | 
|           | 
|         PlayerActivity.OnEnterFBActivity(curPlayer, fbID, updCnt, addCountEx)  | 
|         PlayerSuccess.AddEnterFBSuccess(curPlayer, fbID, addCountEx)  | 
|         updValue = updCnt  | 
|     enterCntTotalKey = ChConfig.Def_Player_Dict_EnterFbCntTotal % fbID  | 
|     enterCntTotal = min(curPlayer.NomalDictGetProperty(enterCntTotalKey) + addCount, ChConfig.Def_UpperLimit_DWord)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, enterCntTotalKey, enterCntTotal)  | 
|     GameWorld.DebugLog("    AddEnterFBCount fbID=%s, addCount=%s, lineBit=%s, enterCnt=%s,updValue=%s,enterCntTotal=%s"   | 
|                        % (fbID, addCount, lineBit, enterCnt, updValue, enterCntTotal), curPlayer.GetPlayerID())  | 
|     Sync_FBPlayerFBInfoData(curPlayer, fbID)  | 
|     OnFBCountChangeEffectRecoverCount(curPlayer, fbID)  | 
|     return True  | 
|   | 
| def OnFBCountChangeEffectRecoverCount(curPlayer, mapID):  | 
|     ## ¸±±¾Ïà¹Ø´ÎÊý±ä¸ü£¬°üº¬Ôö¼Ó¡¢¿Û³ýµÈÓ°Ï츱±¾°´Ê±¼ä»Ö¸´´ÎÊýÏà¹ØÂß¼´¦Àí  | 
|       | 
|     recoverIntervalDict = IpyGameDataPY.GetFuncEvalCfg('FBCntRegainInterval', 1)  | 
|     if str(mapID) not in recoverIntervalDict:  | 
|         return  | 
|     maxCanRecoverCnt, recoverInterval = recoverIntervalDict[str(mapID)]  | 
|     curRegainFbCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RegainFbCnt % mapID) # µ±Ç°Òѻָ´´ÎÊý  | 
|     if curRegainFbCnt >= maxCanRecoverCnt:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID, 0)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainTotalTime % mapID, 0)  | 
|         GameWorld.DebugLog("¸±±¾Ê±¼ä»Ö¸´´ÎÊýÒÑ´ïµ±ÈÕÉÏÏÞ!")  | 
|     else:  | 
|         curTime = int(time.time())  | 
|         fbIpyData = GetFBIpyData(mapID)  | 
|         maxFreeTimes = fbIpyData.GetDayTimes() # ³£¹æ·â¶¥´ÎÊý  | 
|         enterCnt = GetEnterFBCount(curPlayer, mapID) # ÒѾ½øÈë´ÎÊý  | 
|         maxCnt = GetEnterFBMaxCnt(curPlayer, mapID) # µ±Ç°¿ÉÓÃ×î´ó´ÎÊý  | 
|         remainCanEnterCnt = maxCnt - enterCnt # Ê£Óà¿É½øÈë´ÎÊý  | 
|         regainStartTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID)  | 
|         passTime = curTime - regainStartTime  | 
|         # µ½´ï³£¹æ´ÎÊýÉÏÏÞ£¬ÔÝʱ»Ö¸´Ê±¼ä  | 
|         if remainCanEnterCnt >= maxFreeTimes:  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID, 0)  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainTotalTime % mapID, 0)  | 
|             GameWorld.DebugLog("¸±±¾Ê±¼ä»Ö¸´´ÎÊýÒÑ´ï³£¹æ´ÎÊý!")  | 
|         elif passTime < recoverInterval:  | 
|             pass  | 
|             #GameWorld.DebugLog("¸±±¾Ê±¼ä»Ö¸´´ÎÊý»¹Î´µ½´ï»Ö¸´CD!")  | 
|         else:  | 
|             if not regainStartTime:  | 
|                 updRegainTotalTime = recoverInterval  | 
|             else:  | 
|                 updRegainTotalTime = recoverInterval - passTime % recoverInterval  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID, curTime)  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainTotalTime % mapID, updRegainTotalTime)  | 
|             GameWorld.DebugLog("¸±±¾»¹¿É°´Ê±¼ä»Ö¸´´ÎÊý!curTime=%s,regainStartTime=%s,passTime=%s,updRegainTotalTime=%s"   | 
|                                % (curTime, regainStartTime, passTime, updRegainTotalTime))  | 
|     NotifyFBCntRegainInfo(curPlayer, [mapID])  | 
|     return  | 
|   | 
| def RegainFBCntProcess(curPlayer):  | 
|     ## °´Ê±¼ä»Ö¸´¸±±¾´ÎÊý  | 
|       | 
|     curTime = int(time.time())  | 
|     recoverIntervalDict = IpyGameDataPY.GetFuncEvalCfg('FBCntRegainInterval', 1)  | 
|     for mapIDStr, recoverInfo in recoverIntervalDict.items():  | 
|         mapID = int(mapIDStr)  | 
|         maxCanRecoverCnt, recoverInterval = recoverInfo  | 
|         curRegainFbCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RegainFbCnt % mapID) # µ±Ç°Òѻָ´´ÎÊý  | 
|         if maxCanRecoverCnt and curRegainFbCnt >= maxCanRecoverCnt:  | 
|             #GameWorld.DebugLog("Òѵ½´ï¸±±¾»Ö¸´´ÎÊýÉÏÏÞ!mapID=%s,curRegainFbCnt(%s) >= maxCanRecoverCnt(%s)" % (mapID, curRegainFbCnt, maxCanRecoverCnt))  | 
|             continue  | 
|         fbIpyData = GetFBIpyData(mapID)  | 
|         maxFreeTimes = fbIpyData.GetDayTimes() # ³£¹æ·â¶¥´ÎÊý  | 
|         enterCnt = GetEnterFBCount(curPlayer, mapID) # ÒѾ½øÈë´ÎÊý  | 
|         maxCnt = GetEnterFBMaxCnt(curPlayer, mapID) # µ±Ç°¿ÉÓÃ×î´ó´ÎÊý  | 
|         remainCanEnterCnt = maxCnt - enterCnt # Ê£Óà¿É½øÈë´ÎÊý  | 
|         if remainCanEnterCnt >= maxFreeTimes:  | 
|             #GameWorld.DebugLog("¿É½øÈë´ÎÊýÒѾµ½´ï³£¹æ·â¶¥´ÎÊý!mapID=%s,remainCanEnterCnt=%s" % (mapID, remainCanEnterCnt))  | 
|             continue  | 
|         regainStartTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID)  | 
|         if not regainStartTime:  | 
|             #GameWorld.DebugLog("»¹Î´ÉèÖø±±¾»Ö¸´´ÎÊýµ¹¼ÆÊ±!mapID=%s" % mapID)  | 
|             continue  | 
|         needTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FbCntRegainTotalTime % mapID)  | 
|         passTime = curTime - regainStartTime  | 
|         if passTime < needTime:  | 
|             continue  | 
|         remainTime = passTime - needTime # ¿Û³ý»Ö¸´µ¥´ÎºóÊ£ÓàµÄʱ¼ä£¬ÀëÏßÉÏÏߺó¿ÉÄÜÒ»´ÎÐÔ»Ö¸´¶à´Î  | 
|         recoverCnt = 1 + remainTime / recoverInterval # µ¹¼ÆÊ±Ê±¼ä¿É»Ö¸´×Ü´ÎÊý  | 
|         realRecoverCnt = min(maxFreeTimes - remainCanEnterCnt, recoverCnt) # Êµ¼Ê×î´ó¿É»Ö¸´×Ü´ÎÊý  | 
|         if maxCanRecoverCnt:  | 
|             realRecoverCnt = min(realRecoverCnt, maxCanRecoverCnt - curRegainFbCnt)  | 
|         if realRecoverCnt <= 0:  | 
|             continue  | 
|           | 
|         # ¸üÐÂʱ¼äµ¹¼ÆÊ±Òѻָ´´ÎÊý  | 
|         updRegainFbCnt = curRegainFbCnt + realRecoverCnt  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RegainFbCnt % mapID, updRegainFbCnt)  | 
|           | 
|         OnFBCountChangeEffectRecoverCount(curPlayer, mapID)  | 
|           | 
|     return  | 
|   | 
| def NotifyFBCntRegainInfo(curPlayer, syncMapIDList=[]):  | 
|     ##֪ͨ¸±±¾´ÎÊý»Ö¸´Ê£Óàʱ¼ä  | 
|     recoverIntervalDict = IpyGameDataPY.GetFuncEvalCfg('FBCntRegainInterval', 1) # {mapID:[´ÎÊý, Ã¿´Î¼ä¸ô], ...}  | 
|     if not recoverIntervalDict:  | 
|         return  | 
|     if not syncMapIDList:  | 
|         syncMapIDList = [int(mapIDStr) for mapIDStr in recoverIntervalDict.keys()]  | 
|           | 
|     infoList = []  | 
|     curTime = int(time.time())  | 
|     for mapID in syncMapIDList:  | 
|         if str(mapID) not in recoverIntervalDict:  | 
|             continue  | 
|         mapInfo = ChPyNetSendPack.tagMCFBCntRegain()  | 
|         mapInfo.Clear()  | 
|         mapInfo.DataMapID = mapID  | 
|         lastRegainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID)  | 
|         needTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FbCntRegainTotalTime % mapID)  | 
|         passTime = curTime - lastRegainTime  | 
|         mapInfo.RemainTime = max(0, needTime - passTime)  | 
|         mapInfo.RegainCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RegainFbCnt % mapID)  | 
|         infoList.append(mapInfo)  | 
|     if not infoList:  | 
|         return  | 
|     regainData = ChPyNetSendPack.tagMCFBCntRegainRemainTime()  | 
|     regainData.Clear()  | 
|     regainData.InfoList = infoList  | 
|     regainData.Cnt = len(regainData.InfoList)  | 
|     NetPackCommon.SendFakePack(curPlayer, regainData)  | 
|     return  | 
|   | 
| def SetIsHelpFight(curPlayer):  | 
|     ##ÉèÖÃÊÇ·ñÖúÕ½ ×¢Òâ!ÐèÒªÔÚÔö¼Ó¸±±¾´ÎÊý֮ǰÉèÖà  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     mapID = GetRecordMapID(mapID)  | 
|     enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)  | 
|     maxCnt = GetEnterFBMaxCnt(curPlayer, mapID)  | 
|     if enterCnt >= maxCnt:  | 
|         GameWorld.GetGameFB().SetPlayerGameFBDict(curPlayer.GetID(), ChConfig.FBPlayerDict_IsHelpFight, 1)  | 
|         return True  | 
|     return False  | 
|   | 
| def GetIsHelpFight(curPlayer):  | 
|     ##»ñÈ¡ÊÇ·ñÖúÕ½  | 
|     return GameWorld.GetGameFB().GetPlayerGameFBDictByKey(curPlayer.GetID(), ChConfig.FBPlayerDict_IsHelpFight)  | 
|   | 
| def FBOnWeek(curPlayer, onWeekType):  | 
|       | 
|     mapIDInfo = []  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetFBFuncCount()):  | 
|         ipyData = ipyDataMgr.GetFBFuncByIndex(i)  | 
|         mapID = ipyData.GetDataMapID()  | 
|         weekTimes = ipyData.GetWeekTimes()  | 
|         # Ã»ÓÐÖÜ´ÎÊýÏÞÖÆµÄ²»´¦Àí  | 
|         if not weekTimes:  | 
|             continue  | 
|         # ÖØÖÃÀàÐͲ»Í¬µÄ²»´¦Àí  | 
|         if ipyData.GetWeekResetType() != onWeekType:  | 
|             continue  | 
|           | 
|         # ÖØÖÃÖÜ´ÎÊý  | 
|         enterCntWeekKey = ChConfig.Def_Player_Dict_EnterFbCntWeek % mapID  | 
|         if curPlayer.NomalDictGetProperty(enterCntWeekKey):  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, enterCntWeekKey, 0)  | 
|             mapIDInfo.append(mapID)  | 
|               | 
|     if mapIDInfo:  | 
|         Sync_FBPlayerFBInfoData(curPlayer, mapIDInfo)  | 
|           | 
|     return  | 
|   | 
| ## Íæ¼ÒͨÓø±±¾OnDay´¦Àí  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return: None  | 
| def FBOnDay(curPlayer, onDayType):  | 
|     GameWorld.Log("¸±±¾¹ýÌì´¦Àí,FBOnDay...", curPlayer.GetPlayerID())  | 
|     FBLogic.OnFBPlayerOnDay(curPlayer, onDayType) # ÔÚÖØÖôÎÊý֮ǰ£¬¿ÉÓÃÓÚ´¦Àí×ÊÔ´ÕÒ»Ø  | 
|       | 
|     mapIDInfo = []  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetFBFuncCount()):  | 
|         ipyData = ipyDataMgr.GetFBFuncByIndex(i)  | 
|         mapID = ipyData.GetDataMapID()  | 
|           | 
|         # ÓÐÕæÊµÖúÕ½´ÎÊý½±ÀøÏÞÖÆµÄ  | 
|         if ipyData.GetDayHelpCountMax():  | 
|             helpCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FBRealHelpCount % mapID)  | 
|             if helpCount:  | 
|                 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FBRealHelpCount % mapID, 0)  | 
|                 GameWorld.DebugLog("ÖØÖÃÈÕÖúÕ½½±Àø´ÎÊýÏÞÖÆ£¡mapID=%s" % mapID)  | 
|                   | 
|         dayTimes = ipyData.GetDayTimes()  | 
|         # Ã»ÓÐÈÕ´ÎÊýÏÞÖÆµÄ²»´¦Àí  | 
|         if not dayTimes and not ipyData.GetBuyTimesVIPPriID() and not ipyData.GetExtraTimesVIPPriID() and not ipyData.GetExtraTimesMWPriID():  | 
|             #GameWorld.DebugLog("    ²»ÐèÒªÖØÖõĸ±±¾,mapID=%s,dayTimes=%s,vipBuyPriID=%s,vipExtraTime=%s"   | 
|             #                   % (mapID, dayTimes, ipyData.GetBuyTimesVIPPriID(), ipyData.GetExtraTimesVIPPriID()))  | 
|             continue  | 
|           | 
|         # ÖØÖÃÀàÐͲ»Í¬µÄ²»´¦Àí  | 
|         if ipyData.GetDayResetType() != onDayType:  | 
|             #GameWorld.DebugLog("    ÖØÖÃʱ¼äµã²»Í¬,²»´¦Àí,mapID=%s" % mapID)  | 
|             continue  | 
|           | 
|         maxCnt = GetEnterFBMaxCnt(curPlayer, mapID)  | 
|           | 
|         # ½øÈë´ÎÊý  | 
|         enterCntKey = ChConfig.Def_Player_Dict_EnterFbCntDay % mapID  | 
|         enterCnt = curPlayer.NomalDictGetProperty(enterCntKey)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, enterCntKey, 0)  | 
|               | 
|         # ¹ºÂò´ÎÊý  | 
|         buyCntKey = ChConfig.Def_Player_Dict_BuyFbCntDay % mapID  | 
|         buyCnt = curPlayer.NomalDictGetProperty(buyCntKey)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, buyCntKey, 0)  | 
|           | 
|         # ÕһشÎÊý  | 
|         recoverCntKey = ChConfig.Def_Player_Dict_RecoverFbCnt % mapID  | 
|         recoverCnt = curPlayer.NomalDictGetProperty(recoverCntKey)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, recoverCntKey, 0)  | 
|           | 
|         # ÎïÆ·Ôö¼Ó´ÎÊý  | 
|         itemAddCntKey = ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID  | 
|         itemAddCnt = curPlayer.NomalDictGetProperty(itemAddCntKey)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, itemAddCntKey, 0)  | 
|           | 
|         # Ê±¼ä»Ö¸´´ÎÊý  | 
|         regainFBCntKey = ChConfig.Def_Player_Dict_RegainFbCnt % mapID  | 
|         regainFBCnt = curPlayer.NomalDictGetProperty(regainFBCntKey)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, regainFBCntKey, 0)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainStartTime % mapID, 0)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FbCntRegainTotalTime % mapID, 0)  | 
|           | 
|         GameWorld.DebugLog("    ÖØÖÃ:mapID=%s,dayTimes=%s,buyCnt=%s,recoverCnt=%s,itemAddCnt=%s,regainFBCnt=%s,maxCnt=%s,enterCnt=%s"   | 
|                            % (mapID, dayTimes, buyCnt, recoverCnt, itemAddCnt, regainFBCnt, maxCnt, enterCnt))  | 
|         if mapID == ChConfig.Def_FBMapID_ZhuXianBoss:  | 
|             if GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_ZhuXianBoss):  | 
|                 curCnt = min(maxCnt - enterCnt + IpyGameDataPY.GetFuncCfg('ZhuXianBossCntCfg'), IpyGameDataPY.GetFuncCfg('ZhuXianBossCntCfg', 2))  | 
|                 if curCnt > dayTimes:  | 
|                     PlayerControl.NomalDictSetProperty(curPlayer, itemAddCntKey, curCnt - dayTimes)  | 
|                 elif curCnt < dayTimes:  | 
|                     PlayerControl.NomalDictSetProperty(curPlayer, enterCntKey, dayTimes - curCnt)  | 
|               | 
|         mapIDInfo.append(mapID)  | 
|           | 
|     if mapIDInfo:  | 
|         Sync_FBPlayerFBInfoData(curPlayer, mapIDInfo)  | 
|         Sync_FBPlayerFBBuyCount(curPlayer, mapIDInfo)  | 
|         NotifyFBCntRegainInfo(curPlayer, mapIDInfo)  | 
|       | 
|     return  | 
|   | 
| ## Íæ¼ÒͨÓø±±¾µÇ¼´¦Àí  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return: None  | 
| def FBOnLogin(curPlayer):  | 
|     FBLogic.OnFBPlayerOnLogin(curPlayer)  | 
|     Sync_FBPlayerFBInfoData(curPlayer)  | 
|     SyncFBEnterTick(curPlayer)  | 
|     Sync_FBPlayerFBBuyCount(curPlayer)  | 
|     #PlayerFB.Sync_PubFBSweepData(curPlayer)  | 
|     NotifyFBCntRegainInfo(curPlayer)  | 
|     #Åжϸ±±¾ÀïÀëÏß³¬¹ýÒ»¶¨Ê±¼äÔòÍ˳ö¸±±¾  | 
|     CheckFBPlayerOffine(curPlayer)  | 
|     return  | 
|   | 
| def CheckFBPlayerOffine(curPlayer):  | 
|     mapid = curPlayer.GetMapID()  | 
|       | 
|     ipyData = GetFBIpyData(mapid)  | 
|     if not ipyData:  | 
|         return  | 
|     OfflineTime = ipyData.GetOfflineTime()  | 
|     if not OfflineTime:  | 
|         return  | 
|     leaveServerSecond = PlayerControl.GetPlayerLeaveServerSecond(curPlayer) #ÀëÏßʱ¼äÃë  | 
|     if leaveServerSecond >= OfflineTime:  | 
|         GameWorld.DebugLog('Åжϸ±±¾ÀïÀëÏß³¬¹ýÒ»¶¨Ê±¼äÔòÍ˳ö¸±±¾ leaveServerSecond=%s'%leaveServerSecond)  | 
|         PlayerControl.PlayerLeaveFB(curPlayer)  | 
|     return  | 
|   | 
| #//A5 75 ¹ºÂò¸±±¾½øÈë´ÎÊý#tagCMBuyEnterCount  | 
| #  | 
| #struct    tagCMBuyEnterCount  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        FBID;   // ¸±±¾ID  | 
| #};  | 
|   | 
| def BuyFBEnterCount(playerIndex, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)  | 
|     mapID = clientData.FBID  | 
|     if mapID == ChConfig.Def_FBMapID_Love:  | 
|         coupleID = PlayerControl.GetCoupleID(curPlayer)  | 
|         if not coupleID:  | 
|             GameWorld.DebugLog("ûÓаéÂÂÎÞ·¨¹ºÂòÇéÔµ¸±±¾´ÎÊý!")  | 
|             return  | 
|     ipyData = GetFBIpyData(mapID)  | 
|     if not ipyData:  | 
|         return  | 
|     buyTimesVIPPriID = ipyData.GetBuyTimesVIPPriID()  | 
|     if not buyTimesVIPPriID:  | 
|         GameWorld.DebugLog("mapID:%s ²»¿ÉÒÔ¹ºÂò½øÈë´ÎÊý"%mapID)  | 
|         return  | 
|     canBuyCnt = PlayerVip.GetPrivilegeValue(curPlayer, buyTimesVIPPriID)  | 
|       | 
|     hasBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_BuyFbCntDay % mapID)  | 
|     maxDayTimes = ipyData.GetDayTimes()  | 
|     maxCnt = GetEnterFBMaxCnt(curPlayer, mapID)  | 
|     enterCnt = GetEnterFBCount(curPlayer, mapID)  | 
|     if mapID == ChConfig.Def_FBMapID_SealDemon and maxDayTimes and maxCnt - enterCnt >= maxDayTimes:  | 
|         GameWorld.DebugLog('µ±Ç°´ÎÊýÒÑÂú£¬ÎÞÐ蹺Âò¡£¡£')  | 
|         return  | 
|     if mapID == ChConfig.Def_FBMapID_ZhuXianBoss and maxCnt - enterCnt >= IpyGameDataPY.GetFuncCfg('ZhuXianBossCntCfg', 2):  | 
|         return  | 
|       | 
|     if hasBuyCnt >= canBuyCnt:  | 
|         GameWorld.DebugLog("¹ºÂò´ÎÊýÒѾÓÃÍêmapID=%s,buyTimesVIPPriID=%s,hasBuyCnt=%s >= canBuyCnt=%s" % (mapID, buyTimesVIPPriID, hasBuyCnt, canBuyCnt))  | 
|         return  | 
|     costGoldDict = IpyGameDataPY.GetFuncEvalCfg('BuyFBCntCost', 1, {})  | 
|     costGold = costGoldDict.get(str(mapID), '0')  | 
|     costGold = eval(costGold)  | 
|     costMoneyTypeInfo = IpyGameDataPY.GetFuncEvalCfg('BuyFBCntCost', 2, {})  | 
|     costType = costMoneyTypeInfo.get(str(mapID), ShareDefine.TYPE_Price_Gold_Paper_Money)  | 
|     if costGold <= 0:  | 
|         GameWorld.DebugLog("ûÓÐÅäÖùºÂò¸±±¾´ÎÊýÏûºÄ»õ±ÒÊý! mapID=%s,costType=%s,costGold=%s" % (mapID, costType, costGold))  | 
|         return  | 
|     costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, costType, costGold)  | 
|     #GameWorld.Log('costMoneyList=%s,costGold=%s'%(costMoneyList,costGold))  | 
|     if not costMoneyList:  | 
|         return  | 
|     infoDict = {"MapID":mapID}  | 
|       | 
|     for moneyType, moneyNum in costMoneyList:  | 
|         if not PlayerControl.PayMoney(curPlayer, moneyType, moneyNum, ChConfig.Def_Cost_BuyFBCnt, infoDict):  | 
|             GameWorld.DebugLog("ÏÉÓñ²»×ã!costGold=%s" % costGold)  | 
|             return  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_BuyFbCntDay % mapID, hasBuyCnt + 1)  | 
|     Sync_FBPlayerFBBuyCount(curPlayer, [mapID])  | 
|     PlayerControl.NotifyCode(curPlayer, 'FBEnterTimeBuy', [mapID])  | 
|     OnFBCountChangeEffectRecoverCount(curPlayer, mapID)  | 
|     if mapID == ChConfig.Def_FBMapID_Love:  | 
|         coupleID = PlayerControl.GetCoupleID(curPlayer)  | 
|         if coupleID:  | 
|             addItemList = IpyGameDataPY.GetFuncEvalCfg("LoveFB", 3)  | 
|             paramList = [curPlayer.GetPlayerName()]  | 
|             PlayerControl.SendMailByKey("BuyLoveFBCntCoupleMail", [coupleID], addItemList, paramList)  | 
|     return  | 
|   | 
| def DoFuncOpen_RunDaily(curPlayer): return EventReport.WriteFuncCMEAcceptable(curPlayer, ShareDefine.GameFuncID_RunDaily)  | 
| def DoFuncOpen_RunFamily(curPlayer): return EventReport.WriteFuncCMEAcceptable(curPlayer, ShareDefine.GameFuncID_RunFamily)  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## ¸±±¾¿ªÆôÌáʾ(¼¸·ÖÖÓ)  | 
| #  @param openTimeList ¿ªÆôʱ¼äÁбí[(¿ªÆôʱÖÓ£¬¿ªÆô·ÖÖÓ), ]  | 
| #  @param notifyMsg Ìáʾmark  | 
| #  @param notifyTimeList Ìáʾʱ¼äÁÐ±í  | 
| #  @param mergeMinOSD ¸ÃÌáʾÕë¶Ô¿ç·þ×Ó·þÓÐЧµÄ×îС¿ª·þÌì, >=0ʱÓÐÏÞÖÆ  | 
| #  @param mergeMaxOSD ¸ÃÌáʾÕë¶Ô¿ç·þ×Ó·þÓÐЧµÄ×î´ó¿ª·þÌì, >=0ʱÓÐÏÞÖÆ  | 
| #  @param mergeMapInfo ¸ÃÌáʾËùÊôµÄ¿ç·þ»î¶¯µØÍ¼ÐÅÏ¢, Ö÷ÒªÓÃÓÚ²»Í¬×Ó·þ¶ÔÓ¦Ëù¿çµÄ»î¶¯µØÍ¼ID  | 
| #  @return None  | 
| def FBOpenNotify(openTimeList, notifyMsg, notifyTimeList, mapID = 0, mergeMinOSD=-1,   | 
|                  mergeMaxOSD=-1, mergeMapInfo=[]):  | 
|       | 
|     # Ö»ÔÚµÚÒ»ÏßÖÐÌáʾ  | 
|     if GameWorld.GetGameWorld().GetCurGameWorldIndex() != 0 or not notifyTimeList:  | 
|         return  | 
|       | 
|     curTime = datetime.datetime.today()  | 
|     nextTime = curTime + datetime.timedelta(hours=1)  | 
|       | 
|     curYear, curMonth, curDay, curHour = curTime.year, curTime.month, curTime.day, curTime.hour  | 
|     nextYear, nextMonth, nextDay, nextHour = nextTime.year, nextTime.month, nextTime.day, nextTime.hour  | 
|     startTimeStrFormat = "%s-%s-%s %s:%s:%s"  | 
|       | 
|     # ÐèÒªÌáʾµÄ×î´ó·ÖÖÓ  | 
|     maxNotifyMinute = max(notifyTimeList)  | 
|       | 
|     remaindMinute = -1  | 
|     for hour, minute in openTimeList:  | 
|           | 
|         # µ±Ç°Ð¡Ê±µÄºÍÏÂÒ»¸öСʱ²ÅÓпÉÄÜÐèÒªÌáʾ  | 
|         if hour not in [curHour, nextHour]:  | 
|             continue  | 
|           | 
|         # »ñÈ¡±¾´Î±È½ÏµÄ¿ªÆôʱ¼ä  | 
|         if hour == curHour:  | 
|             startTimeStr = startTimeStrFormat % (curYear, curMonth, curDay, hour, minute, "00")  | 
|         else:  | 
|             startTimeStr = startTimeStrFormat % (nextYear, nextMonth, nextDay, hour, minute, "00")  | 
|           | 
|         # ×Ö·û´®×ª»¯Îªdatetime  | 
|         startTime = datetime.datetime.strptime(startTimeStr, ChConfig.TYPE_Time_Format)  | 
|           | 
|         # »¹Ê£¶àÉÙʱ¼ä¿ªÆô  | 
|         remainTime = startTime - curTime  | 
|           | 
|         # ¼ÆËãÊ£ÓàÃëÊý  | 
|         seconds = remainTime.seconds  | 
|           | 
|         # ¼ÆËãÊ£Óà·ÖÖÓ£¬ÌáǰһÃë֪ͨ  | 
|         remaindMinute = (seconds - 1) / 60 + 1  | 
|         if 0 < remaindMinute <= maxNotifyMinute:  | 
|             break  | 
|   | 
|     # ÔÚÅäÖÃÖÐÐèÒªÌáʾ£¬ÇÒδÌáʾ¹ý  | 
|     if remaindMinute in notifyTimeList \  | 
|     and remaindMinute != GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Map_FBDict_NotifyOpen):  | 
|         if mapID > 0:  | 
|             msgParamList = [remaindMinute, mapID]  | 
|         else:  | 
|             msgParamList = [remaindMinute]  | 
|         PlayerControl.WorldNotify(0, notifyMsg, msgParamList, 0, mergeMinOSD, mergeMaxOSD, mergeMapInfo)  | 
|         GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_FBDict_NotifyOpen, remaindMinute)  | 
|     return  | 
|   | 
|   | 
| ## Åжϵ±Ç°ÊÇ·ñʱ¸±±¾½ø³¡Ê±¼ä(×¼±¸Ê±¼ä)  | 
| #  @param openTimeList ¿ªÆôʱ¼äÁбí[(¿ªÆôʱÖÓ£¬¿ªÆô·ÖÖÓ), ]  | 
| #  @param prepareSeconds ×¼±¸Ê±¼ä£¨Ã룩  | 
| #  @return bool  | 
| def CheckIsFBPrepareTime(openTimeList, prepareSeconds):  | 
|     curTime = GameWorld.GetCurrentTime()  | 
|     prevTime = curTime - datetime.timedelta(hours=1)  | 
|       | 
|     curYear, curMonth, curDay, curHour = curTime.year, curTime.month, curTime.day, curTime.hour  | 
|     prevYear, prevMonth, prevDay, prevHour = prevTime.year, prevTime.month, prevTime.day, prevTime.hour  | 
|     startTimeStrFormat = "%s-%s-%s %s:%s:%s"  | 
|       | 
|     for hour, minute in openTimeList:  | 
|   | 
|         # µ±Ç°Ð¡Ê±µÄºÍÉÏһСʱ²ÅÓпÉÄÜʱ½øÈëʱ¼ä  | 
|         if hour not in [curHour, prevHour]:  | 
|             continue  | 
|           | 
|         # »ñÈ¡±¾´Î±È½ÏµÄ¿ªÆôʱ¼ä  | 
|         if hour == curHour:  | 
|             startTimeStr = startTimeStrFormat % (curYear, curMonth, curDay, hour, minute, "00")  | 
|         else:  | 
|             startTimeStr = startTimeStrFormat % (prevYear, prevMonth, prevDay, hour, minute, "00")  | 
|           | 
|         # ×Ö·û´®×ª»¯Îªdatetime  | 
|         startTime = datetime.datetime.strptime(startTimeStr, ChConfig.TYPE_Time_Format)  | 
|           | 
|         # ¾à¿ªÊ¼Ê±¼äµÄʱ¼ä²î  | 
|         pastTime = curTime - startTime  | 
|           | 
|         # »»Ëã³ÉÃëÊý  | 
|         pastSeconds = pastTime.seconds  | 
|   | 
|         # Èç¹ûÔڹ涨׼±¸ÃëÊýÄÚ£¬Ôò·µ»ØTrue  | 
|         if 0 <= pastSeconds <= prepareSeconds:  | 
|             return True  | 
|            | 
|     return False  | 
|   | 
|   | 
| ## ¸±±¾ÐÐΪ - ¹ÄÎèbuff  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param key ¸±±¾Íæ¼Ò×Öµäkey  | 
| #  @param encourageType ½ðÇ®ÀàÐÍ  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @param isMaxlv ÊÇ·ñÖ±½ÓÂú¼¶  | 
| #  @return None  | 
| def FbEncourageBuff(curPlayer, key, encourageType, tick, ownerID=0):  | 
|     #GameWorld.Log("FbEncourageBuff moneyType=%s" % (moneyType))  | 
|     curMapID = curPlayer.GetMapID()  | 
|     curMapID = GetRecordMapID(curMapID)  | 
|     ipyData = IpyGameDataPY.GetIpyGameData('FbEncourage', curMapID, encourageType)  | 
|     if not ipyData:  | 
|         return  | 
|     maxCnt = ipyData.GetInspireMaxLV()  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     ownerID = ownerID or curPlayer.GetID()  | 
|     encourageLV = gameFB.GetPlayerGameFBDictByKey(ownerID, key)  | 
|     encourageCntKey = 'FbEncourageCnt_%s' % encourageType  | 
|     encourageCnt = gameFB.GetPlayerGameFBDictByKey(ownerID, encourageCntKey)  | 
|     maxLV = IpyGameDataPY.GetFuncEvalCfg('FBEncourageBuff', 2, {}).get(curMapID, 0)  | 
|     if encourageLV >= maxLV:  | 
|         PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_93643")  | 
|         return  | 
|     if encourageCnt >= maxCnt:  | 
|         if encourageType == IPY_GameWorld.TYPE_Price_Silver_Money:  | 
|             PlayerControl.NotifyCode(curPlayer, "Xjmj_CopperInspireFull")  | 
|         else:  | 
|             PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_93643")  | 
|         return  | 
|       | 
|     encourageCost = eval(ipyData.GetMoneyCount())  | 
|     if curMapID == ChConfig.Def_FBMapID_SealDemon:  | 
|         isDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)  | 
|         if isDouble: #·âħ̳˫±¶ÌôÕ½Ôò¹ÄÎèË«±¶»¨·Ñ  | 
|             encourageCost *= 2  | 
|   | 
|     costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, encourageType, encourageCost)  | 
|     if not costMoneyList:  | 
|         return  | 
|       | 
|     # ¿Û³ý¹ÄÎèÏûºÄ  | 
|     infoDict = {"MapID":curMapID}  | 
|     for moneyType, moneyCnt in costMoneyList:  | 
|         if not PlayerControl.PayMoney(curPlayer, moneyType, moneyCnt, ChConfig.Def_Cost_FBEncourage, infoDict):  | 
|             return  | 
|     buffTypeID = IpyGameDataPY.GetFuncEvalCfg('FBEncourageBuff', 1, {}).get(curMapID, ChConfig.Def_SkillID_FBEncourageBuff)  | 
|     skillBuffID = buffTypeID + encourageLV  | 
|     skillBuff = GameWorld.GetGameData().GetSkillBySkillID(skillBuffID)  | 
|     if not skillBuff:  | 
|         GameWorld.Log("FbEncourageBuff   ÕÒ²»µ½¼¼ÄÜ%s" % skillBuffID)  | 
|         return  | 
|       | 
|     buffType = SkillCommon.GetBuffType(skillBuff)  | 
|       | 
|     gameFB.SetPlayerGameFBDict(ownerID, key, encourageLV+1)  | 
|     gameFB.SetPlayerGameFBDict(ownerID, encourageCntKey, encourageCnt+1)  | 
|     #GameWorld.Log("FbEncourageBuff encourage nextLV=%s success" % encourageLV)  | 
|     addHurtNum = IpyGameDataPY.GetFuncEvalCfg('FBEncourageBuff', 3, {}).get(curMapID, 0)  | 
|     if curMapID == ChConfig.Def_FBMapID_AllFamilyBoss:  | 
|         #¸ø¸±±¾ÀïËùÓÐÃ˳ÉÔ±Ìáʾ  | 
|         playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for index in xrange(playerManager.GetPlayerCount()):  | 
|             player = playerManager.GetPlayerByIndex(index)  | 
|             if not player:  | 
|                 continue  | 
|             if player.GetFamilyID() != ownerID:  | 
|                 continue  | 
|             BuffSkill.DoAddBuff(player, buffType, skillBuff, tick)  | 
|             PlayerControl.NotifyCode(player, "AllianceBossText2", [curPlayer.GetName(), encourageLV+1])  | 
|             SendFBEncourageInfo(player, encourageLV+1, ownerID)  | 
|             if player.GetID() == curPlayer.GetID():  | 
|                 PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FBEncourage, 1, [curMapID])  | 
|                 EventShell.EventRespons_FBEncourage(curPlayer, curMapID)  | 
|               | 
|     else:  | 
|         BuffSkill.DoAddBuff(curPlayer, buffType, skillBuff, tick)  | 
|         PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_628920", [(encourageLV+1)*addHurtNum])  | 
|         SendFBEncourageInfo(curPlayer, encourageLV+1, ownerID)  | 
|         #³É¾Í  | 
|         PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FBEncourage, 1, [curMapID])  | 
|         EventShell.EventRespons_FBEncourage(curPlayer, curMapID)  | 
|     return True  | 
|   | 
| ## Ìí¼Ó¸±±¾¹ÄÎèbuff£¬Ò»°ãÓÃÓÚÍæ¼ÒµôÏߺó£¬Ôڹ涨ʱ¼äÄÚÖØÐÂÉÏÏ߻ص½¸±±¾Ê±ÖØÐÂÉÏbuff  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param key ¸±±¾Íæ¼Ò×Öµäkey  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| def AddFbEncourageBuff(curPlayer, key, tick, ownerID=0):  | 
|     curPlayerID = curPlayer.GetID()  | 
|     GameWorld.Log("AddFbEncourageBuff() curPlayerID=%s" % curPlayerID)  | 
|     ownerID = ownerID or curPlayer.GetID()  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     encourageLV = gameFB.GetPlayerGameFBDictByKey(ownerID, key)  | 
|     if not encourageLV:  | 
|         return  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     mapID = GetRecordMapID(mapID)  | 
|     buffTypeID = IpyGameDataPY.GetFuncEvalCfg('FBEncourageBuff', 1, {}).get(mapID, ChConfig.Def_SkillID_FBEncourageBuff)  | 
|     skillBuffID = buffTypeID + encourageLV -1  | 
|     skillBuff = GameWorld.GetGameData().GetSkillBySkillID(skillBuffID)  | 
|     if not skillBuff:  | 
|         GameWorld.Log("FbEncourageBuff   ÕÒ²»µ½¼¼ÄÜ%s" % skillBuffID)  | 
|         return  | 
|       | 
|     buffType = SkillCommon.GetBuffType(skillBuff)  | 
|     BuffSkill.DoAddBuff(curPlayer, buffType, skillBuff, tick)  | 
|       | 
|     SendFBEncourageInfo(curPlayer, encourageLV, ownerID)  | 
|     return  | 
|   | 
| ## Çå³ý¹ÄÎèbuff  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return True - Çå³ý³É¹¦ £» False - ÎÞ¸Ãbuff  | 
| def ClearEncourageBuff(curPlayer, tick):  | 
|     for buffTypeID in list(set(IpyGameDataPY.GetFuncEvalCfg('FBEncourageBuff', 1, {}).values())):  | 
|         if BuffSkill.DelBuffBySkillID(curPlayer, buffTypeID, tick):  | 
|             playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|             playerControl.RefreshPlayerAttrByBuff()  | 
|             GameWorld.Log("ClearEncourageBuff() True")  | 
|             return True  | 
|     GameWorld.Log("ClearEncourageBuff() False")  | 
|     return False  | 
|   | 
| ## ·¢Ë͸±±¾¹ÄÎèÐÅÏ¢  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @return None  | 
| def SendFBEncourageInfo(curPlayer, lv, ownerID=0):  | 
|     #//A3 0A ¸±±¾¹ÄÎèÐÅϢ֪ͨ #tagMCFBEncourageInfo  | 
|     curMapID = curPlayer.GetMapID()  | 
|     curMapID = GetRecordMapID(curMapID)  | 
|     ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition('FbEncourage', {'DataMapID':curMapID}, True)  | 
|     if not ipyDataList:  | 
|         return  | 
|     encourageInfo = ChPyNetSendPack.tagMCFBEncourageInfo()  | 
|     encourageInfo.Clear()  | 
|     encourageInfo.InfoList = []  | 
|     encourageCntKey = 'FbEncourageCnt_%s'  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     ownerID = ownerID or curPlayer.GetID()  | 
|     for ipyData in ipyDataList:  | 
|         inspireType = ipyData.GetInspireType()  | 
|         packData = ChPyNetSendPack.tagMCFBEncourageCnt()  | 
|         packData.MoneyType = inspireType  | 
|         packData.EncourageCnt = gameFB.GetPlayerGameFBDictByKey(ownerID, encourageCntKey % inspireType)  | 
|         encourageInfo.InfoList.append(packData)  | 
|     encourageInfo.Cnt = len(encourageInfo.InfoList)  | 
|     NetPackCommon.SendFakePack(curPlayer, encourageInfo)  | 
|     return  | 
|   | 
| ## »ñÈ¡Íæ¼ÒËùÔÚ¸±±¾ÇøÓò¸£Àû±¶Öµ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @return ±¶Öµ-ĬÈÏΪ1  | 
| def GetAreaRewardMultiple(curPlayer):  | 
|     return max(1, curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AreaRewardMultiple))  | 
|   | 
| ## ÉèÖÃÍæ¼ÒËùÔÚ¸±±¾ÇøÓò¸£Àû±¶Öµ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param value ¸üб¶Öµ  | 
| #  @return  | 
| def SetAreaRewardMultiple(curPlayer, value):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_AreaRewardMultiple, value)   | 
|     return  | 
|   | 
|   | 
| ## ¼ì²éÊÇ·ñ½øÈ븱±¾CDÖÐ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param mapID   | 
| #  @return True-CDÖУ¬²»¿É½øÈ룻False-·ÇCDÖУ¬¿É½øÈë  | 
| def CheckIsEnterCD(curPlayer, mapID):  | 
|     return GetFBEnterCD(curPlayer, mapID) > 0  | 
|   | 
| ## »ñÈ¡½øÈ븱±¾CDʱ¼ä  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param mapID   | 
| #  @return <=0 ´ú±íûÓÐCD, >0±íʾ»¹Ê£ÏµÄCD tick  | 
| def GetFBEnterCD(curPlayer, mapID):  | 
|     mapID = GetRecordMapID(mapID)  | 
|     enterCDDict = IpyGameDataPY.GetFuncEvalCfg('FBEnterCD', 1)  | 
|       | 
|     if mapID not in enterCDDict:  | 
|         return 0  | 
|     lvLimitDict = IpyGameDataPY.GetFuncEvalCfg('FBEnterCD', 3)  | 
|     if mapID in lvLimitDict:  | 
|         if curPlayer.GetLV() >= lvLimitDict[mapID]:  | 
|             return 0  | 
|     cdTick = enterCDDict[mapID]  | 
|     lastEnterTick = GetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID)  | 
|     if not lastEnterTick:  | 
|         return 0  | 
|       | 
|     timeNum = GameWorld.ChangeTimeStrToNum(GameWorld.GetCurrentDataTimeStr())  | 
|     passTick = max(0, timeNum - lastEnterTick)  | 
|     curCDTick = max(0, cdTick - passTick)  | 
|     if curCDTick > 0:  | 
|         GameWorld.DebugLog("¸±±¾½øÈëCDÖУ¡mapID=%s,timeNum=%s,lastEnterTick=%s,passTick=%s,Ê£Óà=%s"   | 
|                            % (mapID, timeNum, lastEnterTick, passTick, curCDTick))  | 
|     return curCDTick  | 
|   | 
|   | 
| ## ¸üÐÂÍæ¼Ò½øÈ븱±¾Ê±¼ä  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param tick ¸üÐÂÖµ  | 
| #  @return  | 
| def UpdateFBEnterTick(curPlayer):  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     mapID = GetRecordMapID(mapID)  | 
|     enterCDDict = IpyGameDataPY.GetFuncEvalCfg('FBEnterCD', 1)  | 
|     if mapID not in enterCDDict:  | 
|         return  | 
|     timeNum = GameWorld.ChangeTimeStrToNum(GameWorld.GetCurrentDataTimeStr())  | 
|     SetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID, timeNum)  | 
|     GameWorld.DebugLog("UpdateFBEnterTick mapID=%s,timeNum=%s" % (mapID, timeNum))  | 
|     SyncFBEnterTick(curPlayer, mapID)  | 
|     return  | 
|   | 
| ## »ñÈ¡¼Ç¼ֵµÄmapID  | 
| #  @param mapID ËùÒª²éµÄmapID  | 
| #  @return  | 
| #  @remarks Ò»°ãÓÃÓÚ¼¸ÕŵØÍ¼¹«ÓÃÒ»·Ý´æ´¢¼Ç¼£¬Èç×é¶Ó¸±±¾½øÈë´ÎÊý£¬CDʱ¼äµÈÊý¾ÝÐè¹²Ïí  | 
| def GetRecordMapID(mapID):  | 
|     DataMapIDDict = IpyGameDataPY.GetConfigEx("DataMapIDDict")  | 
|     if not DataMapIDDict:  | 
|         dMapIDDict = {}  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetFBLineCount()):  | 
|             ipyData = ipyDataMgr.GetFBLineByIndex(i)  | 
|             dMapID = ipyData.GetDataMapID()  | 
|             mID = ipyData.GetMapID()  | 
|             dMapIDList= dMapIDDict.get(dMapID, [])  | 
|             if mID not in dMapIDList:  | 
|                 dMapIDList.append(mID)  | 
|                 dMapIDDict[dMapID] = dMapIDList  | 
|               | 
|         for dMapID in dMapIDDict.keys():  | 
|             if len(dMapIDDict[dMapID]) == 1:  | 
|                 dMapIDDict.pop(dMapID)  | 
|         DataMapIDDict = IpyGameDataPY.SetConfigEx("DataMapIDDict", dMapIDDict)  | 
|         #GameWorld.Log("¼ÓÔØDataMapIDDict=%s" % DataMapIDDict)  | 
|           | 
|     for dataMapID, mapIDList in DataMapIDDict.items():  | 
|         if mapID in mapIDList:  | 
|             return dataMapID  | 
|     return mapID  | 
|   | 
| def GetGeneralTrainMapIDList():  | 
|     ## »ñȡͨÓÃÑø³É¸±±¾  | 
|     GeneralTrainMapIDList = IpyGameDataPY.GetConfigEx("GeneralTrainMapIDList")  | 
|     if not GeneralTrainMapIDList:  | 
|         GeneralTrainMapIDList = []  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetFBGeneralTrainCount()):  | 
|             ipyData = ipyDataMgr.GetFBGeneralTrainByIndex(i)  | 
|             dMapID = ipyData.GetDataMapID()  | 
|             if dMapID not in GeneralTrainMapIDList:  | 
|                 GeneralTrainMapIDList.append(dMapID)  | 
|         GeneralTrainMapIDList = IpyGameDataPY.SetConfigEx("GeneralTrainMapIDList", GeneralTrainMapIDList)  | 
|         #GameWorld.Log("¼ÓÔØGeneralTrainMapIDList=%s" % GeneralTrainMapIDList)  | 
|           | 
|     return GeneralTrainMapIDList  | 
|   | 
| def GetClientCustomScene():  | 
|     ## »ñȡǰ¶Ë×Ô¶¨Ò帱±¾³¡¾°  | 
|     mapIDList = GetGeneralTrainMapIDList()  | 
|     return mapIDList + ChConfig.ClientCustomScene  | 
|   | 
| ## Í¬²½½øÈ븱±¾Ê±¼ä  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param syncMapID Í¬²½µÄµØÍ¼£¬Ä¬ÈÏ0Ϊȫ²¿  | 
| #  @return None  | 
| def SyncFBEnterTick(curPlayer, syncMapID=0):  | 
|     enterCDDict = IpyGameDataPY.GetFuncEvalCfg('FBEnterCD', 1)  | 
|     if not enterCDDict:  | 
|         return  | 
|       | 
|     timeNum = GameWorld.ChangeTimeStrToNum(GameWorld.GetCurrentDataTimeStr())  | 
|               | 
|     enterList = ChPyNetSendPack.tagMCFBEnterTickList()  | 
|     enterList.Clear()  | 
|     enterList.EnterTickList = []  | 
|     for mapID in enterCDDict.keys():  | 
|           | 
|         if syncMapID not in [0, mapID]:  | 
|             continue  | 
|           | 
|         lastEnterTick = GetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID)  | 
|           | 
|         # ÐÞÕý¸±±¾CDʱ¼ä  | 
|         if timeNum < lastEnterTick:  | 
|             SetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID, timeNum)  | 
|             lastEnterTick = timeNum  | 
|             GameWorld.DebugLog("ÐÞÕýÍæ¼Ò¸±±¾CDʱ¼ä mapID=%s,timeNum=%s" % (mapID, timeNum), curPlayer.GetPlayerID())  | 
|               | 
|         enterTickObj = ChPyNetSendPack.tagMCFBEnterTick()  | 
|         enterTickObj.Clear()  | 
|         enterTickObj.MapID = mapID  | 
|         enterTickObj.LastEnterTick = lastEnterTick#max(enterCDDict.get(mapID) - (timeNum - lastEnterTick), 0)  | 
|         enterList.EnterTickList.append(enterTickObj)  | 
|       | 
|     enterList.Cnt = len(enterList.EnterTickList)  | 
|     NetPackCommon.SendFakePack(curPlayer, enterList)    | 
|     return  | 
|   | 
| ## Í¨Öª¸öÈËͨÓø±±¾ÐÅÏ¢  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param runTime: ÒѾ½øÐÐʱ¼ä  | 
| #  @return: None  | 
| def Sync_FBPlayerFBInfoData(curPlayer, mapIDInfo=None):  | 
|     if not mapIDInfo:  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         mapIDList = [ipyDataMgr.GetFBFuncByIndex(i).GetDataMapID() for i in xrange(ipyDataMgr.GetFBFuncCount())]  | 
|     else:  | 
|         if type(mapIDInfo) not in [int, list]:  | 
|             return  | 
|         mapIDList = [mapIDInfo] if type(mapIDInfo) == int else mapIDInfo  | 
|           | 
|     fbInfoData = ChPyNetSendPack.tagMCPlayerFBInfoData()  | 
|     fbInfoData.Clear()  | 
|     fbInfoData.FBDataCnt = len(mapIDList)  | 
|     fbInfoData.FBDataList = []  | 
|       | 
|     for mID in mapIDList:  | 
|         mapInfo = ChPyNetSendPack.tagMCFBInfo()  | 
|         mapInfo.Clear()  | 
|         mapInfo.FBID = mID  | 
|         mapInfo.EnterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mID)  | 
|         mapInfo.EnterCntTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntTotal % mID)  | 
|         mapInfo.RecoverCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RecoverFbCnt % mID)  | 
|         mapInfo.ItemAddCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ItemAddFbCnt % mID)  | 
|         mapInfo.PassLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mID)  | 
|           | 
|         for keyNum in range(ChConfig.Def_FBStar_MaxKeyCnt):  | 
|             gradeValue = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PlayerFBStar_MapId % (mID, keyNum))  | 
|             mapInfo.PassGrade.append(gradeValue)  | 
|         mapInfo.PassGradeCnt = len(mapInfo.PassGrade)  | 
|         #GameWorld.DebugLog("FBID:%s---:%s"%(mapInfo.FBID,mapInfo.EnterCnt))  | 
|         fbInfoData.FBDataList.append(mapInfo)  | 
|           | 
|     NetPackCommon.SendFakePack(curPlayer, fbInfoData)  | 
|     return  | 
|   | 
|   | 
|   | 
| #// A3 BD Í¨ÖªÍæ¼Ò¹ºÂò¸±±¾½øÈë´ÎÊý #tagMCBuyEnterInfo  | 
| #  | 
| #struct    tagMCBuyEnterInfo  | 
| #{  | 
| #    tagHead            Head;  | 
| #    BYTE        FBCount;    // ¸±±¾¸öÊý  | 
| #    DWORD            tagMCFBInfo[FBCount];    // ¸±±¾ÐÅÏ¢  | 
| #};  | 
| #  | 
| #struct    tagMCBuyInfo  | 
| #{  | 
| #    tagHead            Head;  | 
| #    DWORD            FBID;        // ¸±±¾ID  | 
| #    BYTE        BuyCount;    // ÒѹºÂò´ÎÊý  | 
| #};  | 
| ## Í¨Öª¸öÈ˹ºÂò¸±±¾´ÎÊýÐÅÏ¢  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param runTime: ÒѾ½øÐÐʱ¼ä  | 
| #  @return: None  | 
| def Sync_FBPlayerFBBuyCount(curPlayer, mapIDList=[]):  | 
|     if not mapIDList:  | 
|         mapIDList = []  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetFBFuncCount()):  | 
|             ipyData = ipyDataMgr.GetFBFuncByIndex(i)  | 
|             if not ipyData.GetBuyTimesVIPPriID():  | 
|                 continue  | 
|             mapIDList.append(ipyData.GetDataMapID())  | 
|      | 
|           | 
|     fbInfoData = ChPyNetSendPack.tagMCBuyEnterInfo()  | 
|     fbInfoData.Clear()  | 
|     fbInfoData.FBInfo = []  | 
|     for mID in mapIDList:  | 
|         mapInfo = ChPyNetSendPack.tagMCBuyInfo()  | 
|         mapInfo.Clear()  | 
|         mapInfo.FBID = mID  | 
|         mapInfo.BuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_BuyFbCntDay % mID)  | 
|         fbInfoData.FBInfo.append(mapInfo)  | 
|         #GameWorld.DebugLog("FBID:%s---BuyCount:%s"%(mapInfo.FBID,mapInfo.BuyCount))  | 
|     fbInfoData.FBCount = len(fbInfoData.FBInfo)  | 
|     if fbInfoData.FBCount > 0:  | 
|         NetPackCommon.SendFakePack(curPlayer, fbInfoData)  | 
|     return  | 
|   | 
| ## ¸ù¾ÝÈËÊý·Ö×é  | 
| #  @param playerCnt: Íæ¼ÒÊý  | 
| #  @param groupCnt: ·Ö³É¼¸×é  | 
| #  @return: [[×é1Ë÷ÒýÁбí],[×é2Ë÷ÒýÁбí],[×é3Ë÷ÒýÁбí],...]  | 
| #  @remarks: °´ÕÕͷβÏÈ×éºÏ£¬ÔÙ½øÐÐËæ»ú×éºÏµÄ·½Ê½£¬¶àÓàÈËÊýËæ»ú·Ö×é  | 
| ##È磺10ÈË·Ö3×é,  ÏÈ0,5Ò»×飻1,4Ò»×飻2,3Ò»×飻ÔÙÓë6,11Ò»×é;7,10Ò»×é; 8,9Ò»×é£»Ëæ»ú×éºÏ  | 
| ##10,11Ϊ²»´æÔÚµÄÈËÊýË÷Òý£¬²»»á¼ÓÈë·Ö×飬¹Ê×îÖÕ·ÖΪÁ½×é3¸ö£¬Ò»×é4¸ö£»  | 
| ##Ë÷ÒýÅÅÐòÒ»°ãΪս¶·Á¦ÅÅÐò  | 
| def GetGroupList(playerCnt, groupCnt):  | 
|     groupList = []  | 
|     for i in xrange(groupCnt):  | 
|         groupList.append([])  | 
|           | 
|     setp = groupCnt * 2  | 
|     for i in xrange(0, playerCnt, setp):  | 
|           | 
|         tmpList = []  | 
|         for g in xrange(groupCnt):  | 
|             tmpGroup = []  | 
|             aIndex = i + g  | 
|             if aIndex < playerCnt:  | 
|                 tmpGroup.append(aIndex)  | 
|             bIndex = i + setp - (g + 1)  | 
|             if bIndex < playerCnt:  | 
|                 tmpGroup.append(bIndex)  | 
|                   | 
|             tmpList.append(tmpGroup)  | 
|                   | 
|         random.shuffle(tmpList)  | 
|         for gi, group in enumerate(groupList):  | 
|             group.extend(tmpList[gi])  | 
|               | 
|     return groupList  | 
|   | 
| def ClearAreaRewardRecord(playerID):  | 
|     ##Çå³ýÕ½³¡ÇøÓò¸£Àû¼Ç¼  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetCnt%playerID, 0)  | 
|     gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetExp%playerID, 0)  | 
|     gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetExpPoint%playerID, 0)  | 
|     gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetZhenQiTotal%playerID, 0)  | 
|     gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetTechPoint%playerID, 0)  | 
|     return  | 
|   | 
| ##Õ½³¡ÇøÓò¸£ÀûÂß¼  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoLogicAreaReward(cfgKeyName, tick, needAlive=False):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     rewardInterval = IpyGameDataPY.GetFuncCfg(cfgKeyName, 2)  | 
|     rewardFormatDict = IpyGameDataPY.GetFuncEvalCfg(cfgKeyName)  | 
|     getCntLimit = IpyGameDataPY.GetFuncCfg(cfgKeyName, 3)  | 
|     lastAwardTick = gameFB.GetGameFBDictByKey(ChConfig.Map_FBDict_LastAreaRewardTick)  | 
|     if tick - lastAwardTick < rewardInterval:  | 
|         return  | 
|     gameFB.SetGameFBDict(ChConfig.Map_FBDict_LastAreaRewardTick, tick)  | 
|       | 
|     GameWorld.DebugLog("¸øÕ½³¡¸£Àû tick=%s,needAlive=%s" % (tick, needAlive))  | 
|     # ¸üÐÂÍæ¼ÒÕ½³¡³ÖÐøÊ±¼ä  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for index in xrange(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer:  | 
|             continue  | 
|         if needAlive and GameObj.GetHP(curPlayer) <= 0:  | 
|             continue  | 
|         playerID = curPlayer.GetPlayerID()  | 
|         if getCntLimit:  | 
|             getCnt = gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetCnt%playerID)  | 
|             if getCnt >= getCntLimit:  | 
|                 continue  | 
|             gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetCnt%playerID, getCnt + 1)  | 
|           | 
|         multiple = GetAreaRewardMultiple(curPlayer) # ¸£Àû±¶Êý  | 
|         reLV = curPlayer.GetLV()  | 
|         reExp = PlayerControl.GetPlayerReExp(curPlayer)  | 
|         playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|           | 
|         if "Exp" in rewardFormatDict:  | 
|             addExp = eval(rewardFormatDict["Exp"])  | 
|             addExp = playerControl.AddExp(addExp)  | 
|             if addExp > 0:  | 
|                 totalExp = GetFBAreaRewardExp(gameWorld, playerID) + addExp  | 
|                 gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetExp%playerID, totalExp % ChConfig.Def_PerPointValue)  | 
|                 gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetExpPoint%playerID, totalExp / ChConfig.Def_PerPointValue)  | 
|                   | 
|               | 
|         if "ZhenQi" in rewardFormatDict:  | 
|             addZhenQi = eval(rewardFormatDict["ZhenQi"])  | 
|             PlayerControl.PlayerAddZhenQi(curPlayer, addZhenQi, True, True, "FB")  | 
|             totalZhenQi = gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetZhenQiTotal%playerID)  | 
|             totalZhenQi += addZhenQi  | 
|             gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetZhenQiTotal%playerID, totalZhenQi)  | 
|               | 
|         if "TechPoint" in rewardFormatDict:  | 
|             addTechPoint = eval(rewardFormatDict["TechPoint"])  | 
|             PlayerFamily.AddPlayerFamilyActiveValue(curPlayer, addTechPoint, True, ShareDefine.Def_AddFAVReason_FamilyInvade, True)  | 
|               | 
|             techPoint = gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetTechPoint%playerID)  | 
|             techPoint += addTechPoint  | 
|             gameWorld.SetGameWorldDict(ChConfig.Map_Player_AreaReward_GetTechPoint%playerID, techPoint)  | 
|               | 
|         #GameWorld.DebugLog("    Õ½³¡¸£Àû ±¶Çø=%s,reLV=%s,reExp=%s,addExp=%s,addZQ=%s,totalExp=%s,totalZQ=%s"   | 
|         #                   % (multiple, reLV, reExp, addExp, addZhenQi, totalExp, totalZhenQi), playerID)  | 
|     return  | 
|   | 
| def GetFBAreaRewardExp(gameWorld, playerID):  | 
|     exp = gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetExp%playerID)  | 
|     expPoint = gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetExpPoint%playerID)  | 
|     return expPoint * ChConfig.Def_PerPointValue + exp  | 
|   | 
| def GetFBAreaRewardZhenQi(gameWorld, playerID):  | 
|     return gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetZhenQiTotal%playerID)  | 
|   | 
| def GetFBAreaRewardTechPoint(gameWorld, playerID):  | 
|     return gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetTechPoint%playerID)  | 
|   | 
| def NotifyCopyMapPlayerFBHelp(tick, fbHelpFunc, interval=10000, befLogicFunc=None):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)  | 
|     if tick - lastTick < interval:  | 
|         return  | 
|     gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)  | 
|       | 
|     if befLogicFunc:  | 
|         befLogicFunc(tick)  | 
|           | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for index in xrange(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer:  | 
|             continue  | 
|         fbHelpFunc(curPlayer, tick)  | 
|     return  | 
|   | 
| def GetCrossDynamicLineMapZoneID():  | 
|     ## »ñÈ¡¿ç·þ¶¯Ì¬Ïß·µØÍ¼±¾Ïß·¿ç·þ·ÖÇø  | 
|     return GameWorld.GetGameWorld().GetPropertyID() / 100000  | 
|   | 
| def GetCrossDynamicLineMapFuncLineID():  | 
|     ## »ñÈ¡¿ç·þ¶¯Ì¬Ïß·µØÍ¼±¾Ïß·¹¦ÄÜÏß·ID  | 
|     return GameWorld.GetGameWorld().GetPropertyID() % 100000 / 100  | 
|   |