#!/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  
 | 
  
 | 
  
 | 
  
 | 
  
 |