| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_FamilyInvade  | 
| #  | 
| # @todo:Õ½Ã˸±±¾ - Òì½çÈëÇÖ(ÊØÎÀÈË»Ê)  | 
| # @author hxp  | 
| # @date 2017-01-04  | 
| # @version 1.1  | 
| #  | 
| # @change: "2017-03-20 15:00" hxp ¸±±¾¶¨Ê±¾Ñ鸣ÀûÖ§³Ö³¬¹ý20ÒÚ  | 
| #  | 
| # ÏêϸÃèÊö: Õ½Ã˸±±¾ - Òì½çÈëÇÖ  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2017-03-20 15:00"""  | 
| #-------------------------------------------------------------------------------  | 
| import FBCommon  | 
| import IPY_GameWorld  | 
| import NPCCustomRefresh  | 
| import PlayerControl  | 
| import IpyGameDataPY  | 
| import GameWorld  | 
| import ChConfig  | 
| import GameWorldProcess  | 
| import PlayerWeekParty  | 
| import PyGameData  | 
| import ShareDefine  | 
| import EventReport  | 
| import GameObj  | 
| import SkillCommon  | 
| import BuffSkill  | 
| import PlayerFamily  | 
|   | 
| Map_FamilyInvadeFB_FamilyID = "FamilyPartyFB_FamilyID"     # ¶ÔÓ¦µÄ¼Ò×åid  | 
| Map_FamilyInvadeFB_KillNPCCnt = "FamilyInvadeFB_KillNPCCnt"     # ÒÑ»÷ɱÊýÁ¿  | 
| Map_FamilyInvadeFB_GuardDead = "FamilyInvadeFB_GuardDead"     # ÊØÎÀÊÇ·ñËÀÍö  | 
|   | 
| GameFBDict_LastEnterFbDay = 'LastEnterFbDay_%s' #ÉϴνøÈë»î¶¯µÄ¿ª·þÌì  | 
| Map_FamilyInvadeFB_StartTick = "Map_FamilyInvadeFB_StartTick_%s"     # ¸±±¾¿ªÊ¼Ê±¼ä  | 
| FBPlayerDict_TotalExp = 'FBPlayerDict_TotalExp'   # »ñµÃµÄ×ܾÑé  | 
| FBPlayerDict_TotalExpPoint = 'FBPlayerDict_TotalExpPoint'   # »ñµÃµÄ×ܾÑéµã  | 
|   | 
|   | 
| Def_Devil_TimeType = IPY_GameWorld.tttLeaveFamilyWar  | 
|   | 
| (  | 
| Def_Time_MapPrepare, # ×¼±¸Ê±¼ä, Ãë  | 
| Def_FightTime, # Õ½¶·Ê±¼ä, Ãë  | 
| Def_Time_Leave, # ½áÊøÊ±¼ä, Ãë  | 
| Def_FInvade_TDFileName, # TDË¢¹ÖÎļþ±ê¼ÇÃû  | 
| Def_FInvade_RMarkList, # ³ö¹Ö±êʶµãÁÐ±í  | 
| Def_FInvade_RMarkTower, # ÈË»Êˢбêʶµã¡¢NPCID  | 
| Def_FInvade_GuardDict, # ÊØÎÀNPCID {±êʶµã:ÊØ»¤NPCID, ...}  | 
| ) = range(7)  | 
|   | 
|   | 
| #µ±Ç°¸±±¾µØÍ¼µÄ״̬  | 
| (  | 
| FB_Step_Open, # µØÍ¼¿ªÆô  | 
| FB_Step_MapPrepare, # µØÍ¼×¼±¸  | 
| FB_Step_Fighting, # Õ½¶·ÖÐ  | 
| FB_Step_LeaveTime, # ×ÔÓÉʱ¼ä  | 
| FB_Step_Over, # ¸±±¾¹Ø±Õ  | 
| ) = range(5)  | 
|   | 
| Def_FILoseReason_Timeout = 1 # Ê§°ÜÔÒò - Ê±¼äµ½  | 
| Def_FILoseReason_TowerBroken = 2 # Ê§°ÜÔÒò - Ë®¾§±»ÆÆ»µ  | 
| Def_FILoseReason_LeaveFB = 3 # Ê§°ÜÔÒò - Ö÷¶¯À뿪¸±±¾¹Ø±Õ  | 
|   | 
|   | 
| def GetFamilyInvadeCfg():  | 
|     return IpyGameDataPY.GetFuncEvalCfg('FamilyInvadeCfg')  | 
|   | 
| def GetDefaultMaxAngryNPCIDList():  | 
|     towerNPCIDList = GetFamilyInvadeCfg()[Def_FInvade_GuardDict].values()  | 
|     towerNPCIDList.append(GetFamilyInvadeCfg()[Def_FInvade_RMarkTower][1])  | 
|     return towerNPCIDList  | 
|   | 
| def OnOpenFB(tick):  | 
|     ##¿ªÆô¸±±¾  | 
|     FBCommon.SetFBStep(FB_Step_Open, tick)  | 
|     GameWorld.GetGameFB().SetGameFBDict(Map_FamilyInvadeFB_FamilyID, 0)  | 
|     return  | 
|   | 
| def OnCloseFB(tick):  | 
|     ##¹Ø±Õ¸±±¾  | 
| #      | 
| #    gameFB = GameWorld.GetGameFB()  | 
| #    fbStep = gameFB.GetFBStep()  | 
| #  | 
| #      | 
| #    if fbStep == FB_Step_Fighting:  | 
| #        # ¹Ø±Õ¸±±¾Ê±£¬Èç¹ûÊÇÕ½¶·×´Ì¬ÔòÉèÖÃΪ¸±±¾Ê§°Ü½áÊø  | 
| #        __DoInvadeOver(tick, Def_FILoseReason_LeaveFB)  | 
|     return  | 
|   | 
| ## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param mapID µØÍ¼ID  | 
| #  @param lineID Ïß·id  | 
| #  @param tick Ê±¼ä´Á  | 
| #  @return ²¼¶ûÖµ  | 
| def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|     if not curPlayer.GetFamilyID():  | 
|         GameWorld.DebugLog("OnEnterFBEvent not family!")  | 
|         return False  | 
|     if curPlayer.GetFamilyLV() < IpyGameDataPY.GetFuncCfg('SWRHFamilyLV'):  | 
|         return  | 
| #    startTick = GameWorld.GetGameWorld().GetGameWorldDictByKey(Map_FamilyInvadeFB_StartTick)  | 
| #    invadeCfg = GetFamilyInvadeCfg()  | 
| #    if tick - startTick > invadeCfg[Def_Time_MapPrepare] * 1000:  | 
| #        openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay)  | 
| #        isEnter = GameWorld.GetGameWorld().GetGameWorldDictByKey(GameFBDict_LastEnterFbDay % curPlayer.GetID()) == openServerDay + 1  | 
| #        if isEnter:  | 
| #            PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_676165")  | 
| #            return False  | 
|     return True  | 
|   | 
| ## »ñÈ¡È볡Я´øÐÅÏ¢  | 
| #  @param curPlayer  | 
| #  @param lineId ·ÖÏß  | 
| #  @return ×Ö·ûÐÍ ½øÈëÐéÄâ·ÖÏßID  | 
| def GetPlayerResetWorldPosFBMsg(curPlayer, lineId):  | 
|     return '[%s,%s]' % (curPlayer.GetPlayerID(), curPlayer.GetFamilyID())  | 
|   | 
| ##²éѯÊÇ·ñ¿ÉÒÔ½øÈëµØÍ¼  | 
| # @param ask:ÇëÇó½á¹¹Ìå(IPY_BMChangeMapAsk)  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return IPY_GameWorld.cme Ã¶¾Ù  | 
| def OnChangeMapAsk(ask, tick):  | 
|     playerIDStr = ask.GetMsg()  | 
|     GameWorld.DebugLog("OnChangeMapAsk playerIDStr=%s" % playerIDStr)  | 
|     #Я´øÍæ¼ÒIDÈ볡  | 
|     if playerIDStr in ['']:  | 
|         return IPY_GameWorld.cmeCustom  | 
|     playerID, familyID = eval(playerIDStr)  | 
|       | 
|   | 
|     #¿É½øÈë  | 
|     return IPY_GameWorld.cmeAccept  | 
|   | 
|   | 
|   | 
| ##Íæ¼Ò½øÈ븱±¾  | 
| # @param curPlayer:Íæ¼ÒʵÀý  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoEnterFB(curPlayer, tick):  | 
|     invadeCfg = GetFamilyInvadeCfg()  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = gameFB.GetFBStep()  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     familyID = curPlayer.GetFamilyID()  | 
|     if not gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_FamilyID):  | 
|         gameFB.SetGameFBDict(Map_FamilyInvadeFB_FamilyID, familyID)  | 
|         GameWorld.DebugLog('    ÏÉÃËID=%s ÓÐÈ˽øÈë,¿ªÊ¼Ë¢¹ÖÁË£¡' % familyID, playerID)  | 
|           | 
|         # Ë¢ÐÂË®¾§  | 
|         towerRMark, towerNPCID = invadeCfg[Def_FInvade_RMarkTower]  | 
|         NPCCustomRefresh.SetNPCRefresh(towerRMark, [towerNPCID])  | 
|         # Ë¢ÊØÎÀ  | 
|         for rmark, npcid in invadeCfg[Def_FInvade_GuardDict].items():  | 
|             NPCCustomRefresh.SetNPCRefresh(rmark, [npcid])  | 
|           | 
|         if fbStep == FB_Step_Open:  | 
|             FBCommon.SetFBStep(FB_Step_MapPrepare, tick)  | 
|             gameWorld.SetGameWorldDict(Map_FamilyInvadeFB_StartTick % familyID, tick)  | 
|       | 
|     openServerDay = gameWorld.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay)  | 
|     if gameWorld.GetGameWorldDictByKey(GameFBDict_LastEnterFbDay % playerID) != openServerDay + 1:  | 
|         gameWorld.SetGameWorldDict(GameFBDict_LastEnterFbDay % playerID, openServerDay + 1)  | 
|         FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_FamilyInvade)  | 
|         EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_FamilyInvade, 0, ChConfig.CME_Log_Start)  | 
|         PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_SWRH, 1)  | 
|         if familyID in PyGameData.g_swrhPlayerIDDict:  | 
|             if playerID not in PyGameData.g_swrhPlayerIDDict[familyID]:  | 
|                 PyGameData.g_swrhPlayerIDDict[familyID].append(playerID)  | 
|         else:  | 
|             PyGameData.g_swrhPlayerIDDict[familyID] = [playerID]  | 
|     fbStep = gameFB.GetFBStep()  | 
|     if fbStep == FB_Step_MapPrepare:  | 
|         #³õʼ»¯²¢Í¨ÖªµÈ´ýµ¹¼ÆÊ±  | 
|         notify_tick = invadeCfg[Def_Time_MapPrepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)  | 
|     | 
|     elif fbStep == FB_Step_Fighting:  | 
|         #֪ͨ½øÈëʱ¼ä  | 
|         notify_tick = invadeCfg[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, notify_tick, True)  | 
|      | 
|     __CheckGuardExpBuff(tick)  | 
|     __SortHurtInfo()  | 
|     DoFBHelp(curPlayer, tick)  | 
|     return  | 
|   | 
| def OnFamilyInvadeStateChange(state, tick):  | 
|     #»î¶¯×´Ì¬±ä¸ü  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     if mapID != ChConfig.Def_FBMapID_FamilyInvade:  | 
|         return  | 
|     GameWorld.DebugLog('    ÊØÎÀÈ˻ʻ״̬±ä¸ü state=%s' % state)  | 
|   | 
|     if state == 1:  | 
|         PyGameData.g_swrhPlayerHurtDict = {}  | 
|     return  | 
|   | 
|   | 
| ##¸±±¾Íæ¼Ò½øÈëµã  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param lineId ·ÖÏßID  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ×ø±êÁбí(X,Y)  | 
| def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  | 
|     return ipyEnterPosInfo  | 
|   | 
| ##Íæ¼ÒÍ˳ö¸±±¾  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoExitFB(curPlayer, tick):  | 
|     guardBuffIDList = IpyGameDataPY.GetFuncEvalCfg('FamilyInvadeCfg', 4)  | 
|     if BuffSkill.DelBuffBySkillID(curPlayer, guardBuffIDList[0], tick):  | 
|         playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|         playerControl.RefreshPlayerAttrByBuff()  | 
|   | 
|     return  | 
|   | 
| ##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def DoPlayerLeaveFB(curPlayer, tick):  | 
|     return  | 
|   | 
| def DoFBHelp(curPlayer, tick):  | 
|     npcInfoDict = {}  | 
|     wheelNum = None  | 
|     rMarkList = GetFamilyInvadeCfg()[Def_FInvade_RMarkList]  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     for rMark in rMarkList:  | 
|         npcCnt = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_NPCCnt % rMark)  | 
|         npcBossCnt = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_NPCBossCnt % rMark)  | 
|         npcInfoDict[rMark] = [npcCnt - npcBossCnt, npcBossCnt]  | 
|         if wheelNum == None:  | 
|             wheelNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark) + 1  | 
|               | 
|     playerID = curPlayer.GetPlayerID()  | 
|     exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)  | 
|     expPoint = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExpPoint)  | 
|       | 
|     killNPCCnt = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_KillNPCCnt)  | 
|       | 
|     #É˺¦ÅÅÐÐÐÅÏ¢  | 
|     hurtInfo = []  | 
|     familyID = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_FamilyID)  | 
|     playerHurtList = PyGameData.g_swrhPlayerHurtDict.get(familyID, [])  | 
|     #playerHurtList = sorted(playerHurtDict.iteritems(), key=lambda asd:asd[1], reverse=True)  | 
|     syncHurtList = playerHurtList[:5]  | 
|     for i, info in enumerate(syncHurtList, 1):  | 
|         playerName, hurt = info  | 
|         hurtDict = {}  | 
|         hurtDict["rank"] = i  | 
|         hurtDict["playerName"] = playerName  | 
|         hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue  | 
|         hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue  | 
|         hurtInfo.append(hurtDict)  | 
|     myRank = __GetSelfHurtRank(curPlayer, playerHurtList)  | 
|     if myRank and myRank > 5:  | 
|         hurtDict = {}  | 
|         hurtDict["rank"] = myRank  | 
|         info = playerHurtList[myRank - 1]  | 
|         playerName, hurt = info  | 
|         hurtDict["playerName"] = playerName  | 
|         hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue  | 
|         hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue  | 
|         hurtInfo.append(hurtDict)  | 
|           | 
|          | 
|     #¸±±¾°ïÖú(֪ͨ¿Í»§¶ËÏÔʾ)  | 
|     fbHelpDict = {  | 
|                   FBCommon.Help_npc:FBCommon.GetJsonNPCHPPerList(__GetNPCHPPerInfo()),  | 
|                   FBCommon.Help_wheel:wheelNum,  | 
|                   FBCommon.Help_npcTotal:killNPCCnt,  | 
|                   FBCommon.Help_exp:exp, FBCommon.Help_expPoint:expPoint,  | 
|                   "hurtInfo":hurtInfo  | 
|                   }  | 
|     GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())  | 
|     FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)  | 
|     return  | 
|   | 
| def __GetNPCHPPerInfo():  | 
|     #»ñÈ¡ÊØÎÀµÄÊ£ÓàѪÁ¿°Ù·Ö±È  | 
|     queryNPCIDList = GetDefaultMaxAngryNPCIDList()  | 
|       | 
|     gameNPCManager = GameWorld.GetNPCManager()  | 
|     hpPerDict = {}  | 
|     for npcid in queryNPCIDList:  | 
|         hpPerDict[npcid] = 0  | 
|     for index in range(gameNPCManager.GetNPCCount()):  | 
|         curNPC = gameNPCManager.GetNPCByIndex(index)  | 
|         curID = curNPC.GetID()  | 
|         if curID == 0:  | 
|             continue  | 
|         curNPCID = curNPC.GetNPCID()  | 
|         if curNPCID not in queryNPCIDList:  | 
|             continue  | 
|   | 
|         curHP = GameObj.GetHP(curNPC)  | 
|         maxHP = GameObj.GetMaxHP(curNPC)  | 
|         hpPer = max(1, curHP * 100 / maxHP) if curHP else 0  | 
|         hpPerDict[curNPCID] = hpPer  | 
|       | 
|     return hpPerDict  | 
|   | 
| ##¸±±¾¶¨Ê±Æ÷  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ¸±±¾¶¨Ê±Æ÷  | 
| def OnProcess(tick):  | 
|       | 
|     fbStep = GameWorld.GetGameFB().GetFBStep()  | 
|       | 
|     if fbStep == FB_Step_MapPrepare:  | 
|         __DoLogic_MapPrepare(tick)  | 
|     elif fbStep == FB_Step_Fighting:  | 
|         __DoLogic_MapFighting(tick)  | 
|     elif fbStep == FB_Step_LeaveTime:  | 
|         __DoLogic_MapLeave(tick)  | 
|           | 
|     return  | 
|   | 
|   | 
| def __DoLogic_MapPrepare(tick):  | 
|     invadeCfg = GetFamilyInvadeCfg()  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < invadeCfg[Def_Time_MapPrepare] * 1000:  | 
|         return  | 
|      | 
|     __OnFBInvadeStart(tick)  | 
|     return  | 
|   | 
| def __DoLogic_MapFighting(tick):  | 
|     invadeCfg = GetFamilyInvadeCfg()  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < invadeCfg[Def_FightTime] * 1000:  | 
|         gameFB = GameWorld.GetGameFB()  | 
|         lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)  | 
|         if tick - lastTick < 5000:  | 
|             return  | 
|         gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)  | 
|         __SortHurtInfo()  | 
|         playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for index in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(index)  | 
|             if not curPlayer:  | 
|                 continue  | 
|             DoFBHelp(curPlayer, tick)  | 
|         #FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 2000)  | 
|         return  | 
|     __DoInvadeOver(tick, Def_FILoseReason_Timeout)  | 
|       | 
|     return  | 
|   | 
| def __DoLogic_MapLeave(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     invadeCfg = GetFamilyInvadeCfg()  | 
|     if tick - gameFB.GetFBStepTick() < invadeCfg[Def_Time_Leave] * 1000:  | 
|         return  | 
|     FBCommon.SetFBStep(FB_Step_Over, tick)  | 
|       | 
|     familyID = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_FamilyID)  | 
|     #¸ø²ÎÓë½±Àø  | 
|     joinPlayerIDList = PyGameData.g_swrhPlayerIDDict.pop(familyID, [])  | 
|     joinAward = FBCommon.GetFBLineReward(ChConfig.Def_FBMapID_FamilyInvade, 0)  | 
|     if joinAward:  | 
|         PlayerControl.SendMailByKey('SwrhReward', joinPlayerIDList, joinAward)  | 
|       | 
|     PyGameData.g_swrhPlayerHurtDict.pop(familyID, [])  | 
|     # Ê±¼äµ½£¬Ìß³ö»¹ÔÚ¸±±¾µÄÍæ¼ÒµÈ...  | 
|     FBCommon.DoLogic_FBKickAllPlayer()  | 
|     GameWorld.GetGameWorld().SetPropertyID(0)  | 
|     GameWorldProcess.CloseFB(tick)  | 
|     return  | 
|   | 
| def __OnFBInvadeStart(tick):  | 
|     FBCommon.SetFBStep(FB_Step_Fighting, tick)  | 
|           | 
|     invadeCfg = GetFamilyInvadeCfg()  | 
|     tdFileName = invadeCfg[Def_FInvade_TDFileName]  | 
|     rMarkList = invadeCfg[Def_FInvade_RMarkList]  | 
|     for index, rMark in enumerate(rMarkList):  | 
|         FBCommon.OpenTDNPCRefresh(rMark, tdFileName, 0, tick, index == 0)  | 
|   | 
|     # Õ½ÃËÆµµÀ֪ͨ¿ªÊ¼  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, invadeCfg[Def_FightTime] * 1000)  | 
|     return  | 
|   | 
| def __CheckGuardExpBuff(tick):  | 
|     guardDeadCnt = GameWorld.GetGameFB().GetGameFBDictByKey(Map_FamilyInvadeFB_GuardDead)  | 
|     guardBuffIDList = IpyGameDataPY.GetFuncEvalCfg('FamilyInvadeCfg', 4)  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for index in range(0 , playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer.GetPlayerID():  | 
|             continue  | 
|         if guardDeadCnt >= len(guardBuffIDList):  | 
|             #È¥µôBUFF  | 
|             BuffSkill.DelBuffBySkillID(curPlayer, guardBuffIDList[0], tick)  | 
|             continue  | 
|         skillBuffID = guardBuffIDList[0 if guardDeadCnt == 1 else 1]  | 
|         skillBuff = GameWorld.GetGameData().GetSkillBySkillID(skillBuffID)  | 
|         if not skillBuff:  | 
|             GameWorld.Log("FbEncourageBuff   ÕÒ²»µ½¼¼ÄÜ%s" % skillBuffID)  | 
|             continue  | 
|           | 
|         buffType = SkillCommon.GetBuffType(skillBuff)  | 
|         BuffSkill.DoAddBuff(curPlayer, buffType, skillBuff, tick)  | 
|     return  | 
|   | 
| ##¸±±¾ÓÐNPCÕÙ³ö  | 
| # @param curNPC:  | 
| # @param tick:tick  | 
| # @return None  | 
| def DoFBRebornNPC(curNPC, tick):  | 
|     fromRefreshValue = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshValue)  | 
|       | 
|     # ÈëÇÖ¹Ö  | 
|     if fromRefreshValue == GetFamilyInvadeCfg()[Def_FInvade_TDFileName]:  | 
|         curNPC.SetIsNeedProcess(True)  | 
|         FBCommon.UpdTDNPCCnt(curNPC, 1)  | 
|                   | 
|     return  | 
|   | 
| def OnTDCurWheelOver(refreshMark, tick):  | 
|     rMarkList = GetFamilyInvadeCfg()[Def_FInvade_RMarkList]  | 
|     isWheelRefreshOver = FBCommon.IsTDWheelRefreshOver(rMarkList) # ±¾´ó²¨ËùÓеãË¢¹ÖÍê±Ï  | 
|     if isWheelRefreshOver:  | 
|         GameWorld.DebugLog("±¾´ó²¨ËùÓеãË¢Íê, Ç¿ÖÆÍ¬²½Ò»´Î¹ÖÎïÊý")  | 
|         __SortHurtInfo()  | 
|         FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # Ç¿ÖÆÍ¬²½Ò»´Î  | 
|           | 
|     return  | 
|   | 
| ## ¹ÖÎï¾ÑéÖµ  | 
| def OnGetNPCExp(curPlayer, curNPC):  | 
|     baseExp = curNPC.GetExp()  | 
|     reExp = PlayerControl.GetPlayerReExp(curPlayer)  | 
|     add_Exp = eval(IpyGameDataPY.GetFuncCompileCfg("SwrhMonsterExp", 1))  | 
|     return add_Exp  | 
|   | 
| def DoFB_Npc_KillNPC(attacker, curNPC, tick):  | 
|     __DoOnNPCKilled(attacker, curNPC, tick)  | 
|     return  | 
|   | 
| def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  | 
|     __DoOnNPCKilled(curPlayer, curNPC, tick)  | 
|     return  | 
|   | 
| def DoFB_NPCSelfDestruction(curNPC, tick):  | 
|     __DoOnNPCKilled(None, curNPC, tick)  | 
|     return  | 
|   | 
| def __DoOnNPCKilled(attacker, curNPC, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     npcID = curNPC.GetNPCID()  | 
|     towerNPCID = GetFamilyInvadeCfg()[Def_FInvade_RMarkTower][1]  | 
|     if npcID == towerNPCID: #ÈË»ÊËÀÁË  | 
|         __DoInvadeOver(tick, Def_FILoseReason_TowerBroken)  | 
|         return  | 
|     #ÊØÎÀËÀÁË  | 
|     guardNPCIDList = GetFamilyInvadeCfg()[Def_FInvade_GuardDict].values()  | 
|     if npcID in guardNPCIDList:  | 
|         guardDead = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_GuardDead)  | 
|         gameFB.SetGameFBDict(Map_FamilyInvadeFB_GuardDead, guardDead + 1)  | 
|         __CheckGuardExpBuff(tick)  | 
|         return  | 
|           | 
|     fromRefreshValue = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshValue)  | 
|     # ÈëÇÖ¹Ö  | 
|     if fromRefreshValue == GetFamilyInvadeCfg()[Def_FInvade_TDFileName]:  | 
|         __OnInvadeNPCKilled(curNPC, tick)  | 
|         if attacker and attacker.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|             #»÷ɱ¹Ö£¬È«µØÍ¼µÄÈ˶¼ÏíÓоÑé  | 
|             baseExp = curNPC.GetExp()  | 
|             copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|             for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
|                 curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|                 if curPlayer == None or curPlayer.IsEmpty():  | 
|                     continue   | 
|                 if curPlayer.GetID() == attacker.GetID():  | 
|                     continue  | 
|                 reExp = PlayerControl.GetPlayerReExp(curPlayer)  | 
|                 add_Exp = eval(IpyGameDataPY.GetFuncCompileCfg("SwrhMonsterExp", 1))  | 
|                 playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|                 playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC)  | 
|                | 
|         return  | 
|       | 
|     return  | 
|   | 
| def __OnInvadeNPCKilled(curNPC, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(Map_FamilyInvadeFB_KillNPCCnt, gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_KillNPCCnt) + 1)  | 
|       | 
|     FBCommon.UpdTDNPCCnt(curNPC, -1) # ¹ÖÎïÊý-1  | 
|       | 
|     rMarkList = GetFamilyInvadeCfg()[Def_FInvade_RMarkList]  | 
|     isAllRefresh = FBCommon.IsTDNPCRefreshOver(rMarkList) # ËùÓйÖÊÇ·ñÈ«²¿Ë¢Íê  | 
|     isAllKilled = FBCommon.IsTDNPCCurWheelAllKilled(rMarkList) # ±¾²¨¹ÖÊÇ·ñÈ«²¿±»»÷ɱ  | 
|       | 
|     if isAllRefresh and isAllKilled:  | 
|         GameWorld.DebugLog("È«²¿¹ÖË¢ÐÂÍê±ÏÇÒÒѱ»É±Íê, ´¦Àí½áÊøÂß¼")  | 
|         __DoInvadeOver(tick)  | 
|           | 
|     elif isAllKilled:  | 
|         GameWorld.DebugLog("±¾²¨¹ÖÈ«²¿É±Í꣬½øÈëÏÂÒ»²¨£¡")  | 
|         __DoInvadeNextWheelStart(tick)  | 
|           | 
|     return  | 
|   | 
| def __DoInvadeNextWheelStart(tick):  | 
|     GameWorld.DebugLog("ÏÂÒ»´ó²¨¿ªÊ¼Ë¢¹Ö...")  | 
|           | 
|     passWheel = None  | 
|     gameFB = GameWorld.GetGameFB()  | 
|       | 
|     rMarkList = GetFamilyInvadeCfg()[Def_FInvade_RMarkList]  | 
|     for index, rMark in enumerate(rMarkList):  | 
|           | 
|         if passWheel == None:  | 
|             passWheel = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark) + 1  | 
|             #__NotifyDifficultyWheelPass(passWheel)  | 
|             | 
|         FBCommon.SetEnterTDNextWheel(rMark, tick, index == 0)  | 
|         if index == 0:  | 
|             FBCommon.Sync_TDNextWheelTick(None, rMark, Def_Devil_TimeType, tick)  | 
|     __SortHurtInfo()          | 
|     FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # ²¨ÊýÇл»Ç¿ÖÆÍ¬²½Ò»´Î  | 
|     return  | 
|   | 
| ## »ñµÃ¾Ñé  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param addExp »ñµÃµÄ¾Ñé  | 
| #  @param expViewType ¾ÑéÀàÐÍ  | 
| #  @return True or False  | 
| def OnGetExp(curPlayer, addExp, expViewType):  | 
|       | 
|     if expViewType != ShareDefine.Def_ViewExpType_KillNPC:  | 
|         return  | 
|       | 
|     playerID = curPlayer.GetID()   | 
|     gameFB = GameWorld.GetGameFB()  | 
|     exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)  | 
|     expPoint = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExpPoint)  | 
|     totalExp = expPoint * ChConfig.Def_PerPointValue + exp  | 
|     updTotalExp = totalExp + addExp  | 
|     updExp = updTotalExp % ChConfig.Def_PerPointValue  | 
|     updExpPoint = updTotalExp / ChConfig.Def_PerPointValue  | 
|     gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_TotalExp, updExp)  | 
|     gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_TotalExpPoint, updExpPoint)  | 
|       | 
|     GameWorld.DebugLog("OnGetExp() totalExp=%s,addExp=%s,updTotalExp=%s"   | 
|                        % (totalExp, addExp, updTotalExp), playerID)  | 
|       | 
|     return  | 
|   | 
| def __DoInvadeOver(tick, loseReason=0):  | 
|     # ¸±±¾½áÊøÂß¼  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     isAllPass = not loseReason  | 
|     familyID = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_FamilyID)  | 
|     GameWorld.DebugLog("´¦Àí¸±±¾½áÊøÂß¼, isAllPass=%s,loseReason=%s, familyID=%s" % (isAllPass, loseReason, familyID))  | 
|     invadeCfg = GetFamilyInvadeCfg()  | 
|     costTime = tick - GameWorld.GetGameFB().GetFBStepTick()  | 
|     FBCommon.SetFBStep(FB_Step_LeaveTime, tick)  | 
|       | 
|     # Çå¹Ö  | 
|     #towerNPCIDList = GetDefaultMaxAngryNPCIDList()  | 
|     #FBCommon.ClearFBNPC(towerNPCIDList)  | 
|     __SortHurtInfo()  | 
|     FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # ¸±±¾½áÊøÇ¿ÖÆÍ¬²½Ò»´Î  | 
|   | 
|     msgStr = str(familyID)  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'SWRHFBOver', msgStr, len(msgStr))  | 
|     passWheel = 0 # Í¨¹ýµÄ²¨Êý  | 
|     rMarkList = GetFamilyInvadeCfg()[Def_FInvade_RMarkList]  | 
|       | 
|     # ¹Ø±ÕËùÓÐË¢¹Öµã  | 
|     for rMark in rMarkList:  | 
|         if passWheel == 0:  | 
|             wheelNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark)  | 
|             passWheel = wheelNum + 1 if isAllPass else wheelNum  | 
|         FBCommon.CloseTDNPCRefresh(rMark, True)  | 
|     if isAllPass:  | 
|         guardDeadCnt = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_GuardDead)  | 
|         if guardDeadCnt == 0:  | 
|             passGrade = 5 #s  | 
|         elif guardDeadCnt == 1:  | 
|             passGrade = 4 #a  | 
|         elif guardDeadCnt == 2:  | 
|             passGrade = 3 #b  | 
|     else:  | 
|         passGrade = 1 #d  | 
|       | 
|     overMsgDict = {FBCommon.Over_dataMapID:ChConfig.Def_FBMapID_FamilyInvade, FBCommon.Over_isPass:int(isAllPass), FBCommon.Over_grade:passGrade, FBCommon.Over_costTime:costTime}  | 
|     killNPCCnt = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_KillNPCCnt)  | 
|     GameWorld.Log("¸±±¾½áËã: familyID=%s, overMsgDict=%s,passWheel=%s,killNPCCnt=%s" % (familyID, overMsgDict, passWheel, killNPCCnt), familyID)  | 
|       | 
|     leaveTick = invadeCfg[Def_Time_Leave] * 1000  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
|           | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|           | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|           | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)  | 
|           | 
|         playerID = curPlayer.GetPlayerID()  | 
|         exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)  | 
|         expPoint = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExpPoint)  | 
|           | 
|         #ÆÀ·Ö½±Àø  | 
|         myRank = __GetSelfHurtRank(curPlayer)  | 
|         scoreExpNum = __GiveScoreAward(curPlayer, passGrade, passWheel)  | 
|         scoreExpPoint, scoreExp = scoreExpNum / ChConfig.Def_PerPointValue, scoreExpNum % ChConfig.Def_PerPointValue  | 
|         overMsgDict.update({FBCommon.Over_rank:myRank, FBCommon.Over_exp:exp, FBCommon.Over_expPoint:expPoint, "scoreExp":scoreExp, "scoreExpPoint":scoreExpPoint})  | 
|         FBCommon.Notify_FB_Over(curPlayer, overMsgDict)  | 
|         PlayerFamily.AddFamilyActivity(curPlayer, ShareDefine.FamilyActive_SWRH)  | 
|     return  | 
|   | 
| def __GiveScoreAward(curPlayer, star, passWheel):  | 
|     #ÆÀ·Ö½±Àø  | 
|     reExp = PlayerControl.GetPlayerReExp(curPlayer)  | 
|     starPerDict = IpyGameDataPY.GetFuncEvalCfg('FamilyInvadeCfg', 2)  | 
|     starPer = starPerDict.get(star, 0)  | 
|     expFormula = IpyGameDataPY.GetFuncCompileCfg('FamilyInvadeCfg', 3)  | 
|     scoreExp = eval(expFormula)  | 
|     playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|     playerControl.AddExp(scoreExp)  | 
|     return scoreExp  | 
|   | 
| def __GetSelfHurtRank(curPlayer, playerHurtList=[]):  | 
|     #»ñÈ¡×Ô¼ºµÄÅÅÃû  | 
|     playerName = curPlayer.GetName()  | 
|     if not playerHurtList:  | 
|         familyID = curPlayer.GetFamilyID()  | 
|         playerHurtList = PyGameData.g_swrhPlayerHurtDict.get(familyID, [])  | 
|         playerHurtList = sorted(playerHurtList, key=lambda asd:asd[1], reverse=True)  | 
|     myRank = 0  | 
|     for i, info in enumerate(playerHurtList):  | 
|         if playerName == info[0]:  | 
|             myRank = i + 1  | 
|             break  | 
|     return myRank  | 
|   | 
|   | 
| ## Íæ¼Ò¶ÔNPCÔì³ÉÉ˺¦  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curNPC   | 
| #  @param hurtHP   | 
| #  @return None  | 
| def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = GameWorld.GetGameFB().GetFBStep()  | 
|       | 
|     # ¸±±¾×¼±¸  | 
|     if fbStep != FB_Step_Fighting:  | 
|         return  | 
|     familyID = gameFB.GetGameFBDictByKey(Map_FamilyInvadeFB_FamilyID)  | 
|     playerName = curPlayer.GetName()   | 
|     playerHurtDict = dict(PyGameData.g_swrhPlayerHurtDict.get(familyID, []))  | 
|       | 
|     playerHurtDict[playerName] = playerHurtDict.get(playerName, 0) + hurtHP  | 
|     PyGameData.g_swrhPlayerHurtDict[familyID] = playerHurtDict.items()  | 
|     GameWorld.DebugLog('g_familyPlayerHurtDict=%s' % PyGameData.g_swrhPlayerHurtDict)  | 
|     return  | 
|   | 
| def __SortHurtInfo():  | 
|     #ÅÅÐò  | 
|     familyID = GameWorld.GetGameFB().GetGameFBDictByKey(Map_FamilyInvadeFB_FamilyID)  | 
|     if familyID not in PyGameData.g_swrhPlayerHurtDict:  | 
|         return  | 
|     playerHurtList = PyGameData.g_swrhPlayerHurtDict[familyID]  | 
|     playerHurtList = sorted(playerHurtList, key=lambda asd:asd[1], reverse=True)  | 
|     PyGameData.g_swrhPlayerHurtDict[familyID] = playerHurtList  | 
|     return  | 
|   | 
| ## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return bool  | 
| def CheckCanAttackTagObjInFB(attacker, defender):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() != FB_Step_Fighting:  | 
|         return False  | 
|     return True  | 
|   | 
| #def __NotifyDifficultyWheelPass(passWheel):  | 
| #    # µ¥²¨Êý¹ý¹ØÍ¨Öª  | 
| #   | 
| #    familyID = GameWorld.GetGameWorld().GetPropertyID()  | 
| #    overDict = {"passWheel":passWheel, "difficulty":difficulty}  | 
| #    GameWorld.Log("¸±±¾µ¥²¨½áËã: familyID=%s, %s" % (familyID, overDict), familyID)  | 
| #      | 
| #    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
| #    for i in xrange(copyMapPlayerManager.GetPlayerCount()):  | 
| #          | 
| #        curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
| #          | 
| #        if curPlayer == None or curPlayer.IsEmpty():  | 
| #            continue  | 
| #        FBCommon.Notify_FB_Over(curPlayer, overDict)  | 
| #          | 
| #    return  | 
|   | 
| # -------------------------------------------------------------------------------------------------  | 
|   | 
|   | 
|   |