| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_FamilyBoss  | 
| #  | 
| # @todo:Õ½ÃËboss¸±±¾  | 
| # @author xdh  | 
| # @date 2018-02-08  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: Õ½ÃËboss¸±±¾  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2018-02-08 17:20"""  | 
| #---------------------------------------------------------------------  | 
| import FBCommon  | 
| import GameWorldProcess  | 
| import IPY_GameWorld  | 
| import PlayerControl  | 
| import GameWorld  | 
| import NPCCustomRefresh  | 
| import IpyGameDataPY  | 
| import PlayerFamily  | 
| import ShareDefine  | 
| import EventReport  | 
| import PyGameData  | 
| import ChConfig  | 
|   | 
| import math  | 
|   | 
| #µ±Ç°¸±±¾µØÍ¼µÄ״̬  | 
| (  | 
| FB_Step_Open, # µØÍ¼¿ªÆô  | 
| FB_Step_MapPrepare, # µØÍ¼×¼±¸  | 
| FB_Step_Fighting, # Õ½¶·ÖÐ  | 
| FB_Step_LeaveTime, # ×ÔÓÉʱ¼ä  | 
| FB_Step_Over, # ¸±±¾¹Ø±Õ  | 
| ) = range(5)  | 
|   | 
| #---Õ½Ã˸±±¾---  | 
| FamilyBossFB_Star = 'FamilyBossFB_Star' #ÆÀ¼¶  | 
| Map_FamilyBossFB_FamilyID = "FamilyBossFB_FamilyID"     # ¶ÔÓ¦µÄ¼Ò×åid  | 
|   | 
| (  | 
| Def_Time_MapPrepare, # ×¼±¸Ê±¼ä, Ãë  | 
| Def_Time_Fight, # ³ÖÐøÊ±¼ä, Ãë  | 
| Def_Time_Leave, # ½áÊøÊ±¼ä, Ãë  | 
| Def_StarTime, # ÐǼ¶¶ÔÓ¦ºÄʱÅäÖÃ, Ãë  | 
| ) = range(4)  | 
|   | 
| def GetFamilyBossFBTimeCfg():return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_FamilyBossMap, 0)  | 
|   | 
| def GameServerOpenFamilyBoss(familyID, openCount):  | 
|     if familyID in PyGameData.g_familyBossOpenCountDict:  | 
|         curOpenCount = PyGameData.g_familyBossOpenCountDict[familyID]  | 
|         if curOpenCount == openCount:  | 
|             return  | 
|     PyGameData.g_familyBossOpenCountDict[familyID] = openCount  | 
|     if familyID in PyGameData.g_familyBossPlayer:  | 
|         PyGameData.g_familyBossPlayer.pop(familyID)  | 
|     GameWorld.DebugLog("¿ªÆôÏÉÃËBoss: familyID=%s,openCount=%s" % (familyID, openCount))  | 
|     return  | 
|   | 
| def AddFamilyBossPlayer(curPlayer):  | 
|     familyID = curPlayer.GetFamilyID()  | 
|     if not familyID:  | 
|         return  | 
|     if familyID not in PyGameData.g_familyBossOpenCountDict:  | 
|         return  | 
|     openCount = PyGameData.g_familyBossOpenCountDict[familyID]  | 
|     familyPlayerList = PyGameData.g_familyBossPlayer.get(familyID, [])  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID in familyPlayerList:  | 
|         return  | 
|     familyPlayerList.append(playerID)  | 
|     PyGameData.g_familyBossPlayer[familyID] = familyPlayerList  | 
|     GameWorld.DebugLog("ÏÉÃ˲ÎÓëÍæ¼Ò: %s" % PyGameData.g_familyBossPlayer)  | 
|     EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_FamilyBossMap, openCount, ChConfig.CME_Log_Start)  | 
|     return  | 
|   | 
|   | 
|   | 
| ##¿ªÆô¸±±¾  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ¿ªÆô¸±±¾  | 
| def OnOpenFB(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(Map_FamilyBossFB_FamilyID, 0)  | 
|     gameFB.SetGameFBDict(FamilyBossFB_Star, 0)  | 
|     return  | 
|   | 
|   | 
| ##¹Ø±Õ¸±±¾  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks   | 
| def OnCloseFB(tick):  | 
|     #¸±±¾Ìß³öÍæ¼Ò  | 
|     # Í¨ÖªGameServer¸±±¾½áÊø  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)  | 
|     msgStr = str([familyID, 0])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))  | 
|       | 
|     if familyID in PyGameData.g_familyBossOpenCountDict:  | 
|         PyGameData.g_familyBossOpenCountDict.pop(familyID)  | 
|         GameWorld.DebugLog("ÒÆ³ýÏÉÃË¿ªÆôbossÊý£º%s" % PyGameData.g_familyBossOpenCountDict)  | 
|     if familyID in PyGameData.g_familyBossPlayer:  | 
|         PyGameData.g_familyBossPlayer.pop(familyID)  | 
|         GameWorld.DebugLog("ÒÆ³ýÏÉÃ˲ÎÓëÍæ¼Ò£º%s" % PyGameData.g_familyBossPlayer)  | 
|           | 
|     GameWorld.GetGameWorld().SetPropertyID(0)  | 
|     FBCommon.DoLogic_FBKickAllPlayer()  | 
|     return  | 
|   | 
|   | 
| ## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param mapID µØÍ¼ID  | 
| #  @param lineID Ïß·id  | 
| #  @param tick Ê±¼ä´Á  | 
| #  @return ²¼¶ûÖµ  | 
| def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|     return __CheckEnter(curPlayer, mapID)  | 
|   | 
|   | 
| ##½øÈ븱±¾¼ì²é  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param mapID µØÍ¼ID  | 
| #  @param lineID Ïß·id  | 
| # @return None  | 
| def __CheckEnter(curPlayer, mapID):  | 
|       | 
|     # ÊÇ·ñÓÐÕ½ÃË  | 
|     if curPlayer.GetFamilyID() <= 0:  | 
|         GameWorld.DebugLog("ûÓÐÕ½ÃË£¬²»ÄܽøÈëÕ½ÃËboss¸±±¾£¡")  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
|   | 
| ##¸±±¾Íæ¼Ò½øÈëµã  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param lineId ·ÖÏßID  | 
| # @param ipyEnterPosInfo ¹¦ÄÜÏß·IPYÅäÖÃ×ø±êÐÅÏ¢  | 
| # @param tick Ê±¼ä´Á  | 
| # @return posX, posY, Ëæ»ú°ë¾¶(¿ÉÑ¡)  | 
| def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  | 
|     return ipyEnterPosInfo  | 
|      | 
|   | 
|   | 
| ##ÊÇ·ñ¿ÉÒÔ½øÈë  | 
| # @param ask ÇëÇó½á¹¹Ìå  | 
| # @param tick Ê±¼ä´Á  | 
| # @return TChangeMapError  | 
| # @remarks ÑéÖ¤¼Ò×åÊÇ·ñÔÚ½ñÌìµÄ¼Ò×åÕ½±í  | 
| def OnChangeMapAsk(ask, tick):  | 
|     return IPY_GameWorld.cmeAccept  | 
|   | 
|   | 
| ##Íæ¼Ò½øÈ븱±¾  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks Íæ¼Ò½øÈ븱±¾  | 
| def DoEnterFB(curPlayer, tick):  | 
|     mapID = GameWorld.GetGameWorld().GetMapID()  | 
|     | 
|     if not __CheckEnter(curPlayer, mapID):  | 
|         PlayerControl.PlayerLeaveFB(curPlayer)  | 
|         return  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = gameFB.GetFBStep()  | 
|       | 
|     if fbStep == FB_Step_Open:  | 
|         FBCommon.SetFBStep(FB_Step_MapPrepare, tick)  | 
|         familyID = curPlayer.GetFamilyID()  | 
|         gameFB.SetGameFBDict(Map_FamilyBossFB_FamilyID, familyID)  | 
|         msgStr = str([familyID, 1])  | 
|         GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))  | 
|     familyBossFBCfg = GetFamilyBossFBTimeCfg()      | 
|     fbStep = gameFB.GetFBStep()  | 
|     if fbStep == FB_Step_MapPrepare:  | 
|         #³õʼ»¯²¢Í¨ÖªµÈ´ýµ¹¼ÆÊ±  | 
|         __EnterFBInPrepare(curPlayer, familyBossFBCfg[Def_Time_MapPrepare] * 1000, gameFB, tick)  | 
|      | 
|     elif fbStep == FB_Step_Fighting:  | 
|         #֪ͨ½øÈëʱ¼ä  | 
|         notifyTick = max(familyBossFBCfg[Def_Time_Fight] * 1000 - (tick - gameFB.GetFBStepTick()), 0)  | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, notifyTick, True)  | 
|         __UpdFamilyBossFBStar(tick, True, curPlayer)  | 
|           | 
|     DoFBHelp(curPlayer, tick)  | 
|       | 
|     AddFamilyBossPlayer(curPlayer)  | 
|     return  | 
|   | 
|   | 
| ##¸±±¾¶¨Ê±Æ÷  | 
| # @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 __UpdFamilyBossFBStar(tick, isForce=False, curPlayer=None):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)  | 
|     if curStar == 1:  | 
|         return curStar  | 
|       | 
|     useSecond = int(math.ceil((tick - gameFB.GetFBStepTick()) / 1000.0))  | 
|     familyBossFBCfg = GetFamilyBossFBTimeCfg()  | 
|     starTimeList = familyBossFBCfg[Def_StarTime]  | 
|     diffSecond = 0  | 
|     updStar = 1 # Ä¬ÈÏÖÁÉÙ1ÐÇ  | 
|     for star, starTime in enumerate(starTimeList, 2):  | 
|         if useSecond <= starTime:  | 
|             updStar = star  | 
|             diffSecond = starTime-useSecond  | 
|               | 
|     if curStar == updStar and not isForce:  | 
|         return curStar  | 
|           | 
|     gameFB.SetGameFBDict(FamilyBossFB_Star, updStar)  | 
|       | 
|     GameWorld.DebugLog("__UpdFamilyBossFBStar useSecond=%s,curStar=%s,updStar=%s, diffSecond=%s"   | 
|                        % (useSecond, curStar, updStar, diffSecond))  | 
|       | 
|     if curPlayer:  | 
|         DoFBHelp(curPlayer, tick)  | 
|         if updStar != 1:  | 
|             curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)  | 
|     else:  | 
|         playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for index in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(index)  | 
|             if not curPlayer:  | 
|                 continue  | 
|             DoFBHelp(curPlayer, tick)  | 
|             if updStar != 1:  | 
|                 curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)  | 
|                   | 
|               | 
|     return updStar  | 
|   | 
|   | 
| def __EnterFBInPrepare(curPlayer, downTime, gameFB, tick, notifyEff=False):  | 
|     #֪ͨ׼±¸µ¹¼ÆÊ±  | 
|     notifyTick = max(downTime - (tick - gameFB.GetFBStepTick()), 0)  | 
|     curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, notifyTick, True)  | 
|       | 
|     if notifyEff:  | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, notifyTick, True)  | 
|     return  | 
|   | 
|   | 
| def __DoLogic_MapPrepare(tick):  | 
|     invadeCfg = GetFamilyBossFBTimeCfg()  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < invadeCfg[Def_Time_MapPrepare] * 1000:  | 
|         return  | 
|     __OnFamilyBossFBStart(tick)  | 
|     return  | 
|   | 
|   | 
| def __DoLogic_MapFighting(tick):  | 
|     invadeCfg = GetFamilyBossFBTimeCfg()  | 
|       | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() >= invadeCfg[Def_Time_Fight] * 1000:  | 
|         __DoFamilyBossFBOver(tick, False)  | 
|         return  | 
|     __UpdFamilyBossFBStar(tick)  | 
|     return  | 
|   | 
| def __DoLogic_MapLeave(tick):  | 
|     invadeCfg = GetFamilyBossFBTimeCfg()  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < invadeCfg[Def_Time_Leave] * 1000:  | 
|         return  | 
|       | 
|     # Ê±¼äµ½£¬Ìß³ö»¹ÔÚ¸±±¾µÄÍæ¼ÒµÈ...  | 
|     GameWorldProcess.CloseFB(tick)  | 
|     FBCommon.SetFBStep(FB_Step_Over, tick)  | 
|     FBCommon.DoLogic_FBKickAllPlayer()  | 
|     return  | 
|   | 
| def __OnFamilyBossFBStart(tick):  | 
|     FBCommon.SetFBStep(FB_Step_Fighting, tick)  | 
|     refreshMark, bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)  | 
|     NPCCustomRefresh.SetNPCRefresh(refreshMark, [bossID])  | 
|   | 
|     # Õ½ÃËÆµµÀ֪ͨ¿ªÊ¼  | 
|     familyBossFBCfg = GetFamilyBossFBTimeCfg()  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, familyBossFBCfg[Def_Time_Fight] * 1000)   | 
|       | 
|     __UpdFamilyBossFBStar(tick)  | 
|     return  | 
|   | 
|   | 
| def __DoFamilyBossFBOver(tick, isKill):  | 
|     # ¸±±¾½áÊøÂß¼  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() == FB_Step_LeaveTime:  | 
|         return  | 
|     GameWorld.DebugLog("´¦ÀíÏÉÃËBOSS¸±±¾½áÊøÂß¼")  | 
|     invadeCfg = GetFamilyBossFBTimeCfg()  | 
|     FBCommon.SetFBStep(FB_Step_LeaveTime, tick)  | 
|   | 
|     familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)  | 
|     msgStr = str([familyID, 2])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))  | 
|       | 
|     grade = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)  | 
|     GameWorld.Log("ÏÉÃËBOSS¸±±¾½áËã: familyID=%s, grade=%s" % (familyID, grade), familyID)  | 
|     leaveTick = invadeCfg[Def_Time_Leave] * 1000  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     playerCount = copyMapPlayerManager.GetPlayerCount()  | 
|     for i in xrange(playerCount):  | 
|           | 
|         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)  | 
|           | 
|         if curPlayer == None or curPlayer.IsEmpty():  | 
|             continue  | 
|           | 
|         curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)  | 
|         if isKill:  | 
|             PlayerFamily.AddFamilyActivity(curPlayer, ShareDefine.FamilyActive_BOSS)  | 
|           | 
|     if isKill:  | 
|         doCountRate = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 1))  | 
|         doCountAdd = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 2))  | 
|         FBCommon.SetNPCDropDoCountRate(gameFB, doCountRate, doCountAdd)  | 
|     return  | 
|   | 
| ## ÊÇ·ñ¸±±¾¸´»î  | 
| #  @param None  | 
| #  @return ÊÇ·ñ¸±±¾¸´»î  | 
| def OnPlayerReborn():  | 
|     return True  | 
|   | 
| ## ÖØÖø±±¾¸´»îÍæ¼Ò×ø±êµã  | 
| # @param None  | 
| # @return ÎÞÒâÒå  | 
| def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):  | 
|     ipyEnterPosInfo = FBCommon.GetFBLineEnterPosInfo(ChConfig.Def_FBMapID_FamilyBossMap, 0)  | 
|     posX, posY = ipyEnterPosInfo[:2]  | 
|     curPlayer.ResetPos(posX, posY)  | 
|     return  | 
|   | 
| ##Íæ¼ÒÍ˳ö¼Ò×å´¦Àí  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def OnLeaveFamily(curPlayer, tick):  | 
|     #GameWorld.DebugLog("OnLeaveFamily...")  | 
|     #curPlayerID = curPlayer.GetPlayerID()  | 
|     PlayerControl.PlayerLeaveFB(curPlayer)  | 
|     return  | 
|   | 
| ##»ñµÃ¸±±¾°ïÖúÐÅÏ¢  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ÓÃÓÚ֪ͨÕóÓª±È·ÖÌõ  | 
| def DoFBHelp(curPlayer, tick):  | 
|     helpDict = {}  | 
|     | 
|     gameFB = GameWorld.GetGameFB()  | 
|     curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)  | 
|     helpDict[FBCommon.Help_grade] = curStar  | 
|     FBCommon.Notify_FBHelp(curPlayer, helpDict)  | 
|     return  | 
|   | 
|   | 
| ## Ö´Ðи±±¾É±¹ÖÂß¼  | 
| #  @param curPlayer É±¹ÖµÄÈË  | 
| #  @param curNPC ±»É±µÄ¹Ö  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  | 
|       | 
|     bossID = curNPC.GetNPCID()  | 
|     refreshMark, refreshBossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)  | 
|   | 
|     if bossID != refreshBossID:  | 
|         return  | 
|     GameWorld.DebugLog('ÏÉÃËBOSSÒѱ»»÷ɱ£¡')  | 
|       | 
| #    # È«·þ¹ã²¥  | 
| #    PlayerControl.WorldNotify(0, "jiazu_liubo_202580", [curPlayer.GetFamilyName(), mapID, bossID])  | 
|     __DoFamilyBossFBOver(tick, True)  | 
|     return  | 
|   | 
| ## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return bool  | 
| def CheckCanAttackTagObjInFB(attacker, defender):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() != FB_Step_Fighting:  | 
|         return False  | 
|     return True  | 
|   | 
|   | 
|   | 
|   |