#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package GameWorldLogic.FBProcess.GameLogic_ZhuXianTower  
 | 
#  
 | 
# @todo:ÖïÏÉËþ  
 | 
# @author xdh  
 | 
# @date 2019-01-21  
 | 
# @version 1.0  
 | 
# ÏêϸÃèÊö: ÖïÏÉËþ  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
#"""Version = 2019-01-21 11:00"""  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
import FBCommon  
 | 
import GameWorld  
 | 
import IPY_GameWorld  
 | 
import PlayerControl  
 | 
import NPCCustomRefresh  
 | 
import ChPyNetSendPack  
 | 
import ItemControler  
 | 
import NetPackCommon  
 | 
import ShareDefine  
 | 
import IpyGameDataPY  
 | 
import ItemCommon  
 | 
import ChConfig  
 | 
import ChPlayer  
 | 
import PlayerActLogin  
 | 
import GameWorldProcess  
 | 
import PlayerBillboard  
 | 
import EventReport  
 | 
  
 | 
import random  
 | 
import math  
 | 
  
 | 
Def_MaxStar = 5  #S¼¶ÆÀ¼¶  
 | 
  
 | 
FBDict_Level = 'FBDict_Level'  # ¸±±¾¹Ø¿¨  
 | 
FBDict_FBStar = 'FBDict_FBStar'  # µ±Ç°¸±±¾ÐǼ¶  
 | 
FBDict_isFirstS= 'FBDict_isFirstS'  # ÊÇ·ñÊ×´ÎS¼¶¹ý¹Ø  
 | 
FBDict_StartTick = 'FBDict_StartTick'  #¿ªÊ¼Ê±¼ä  
 | 
FBDict_Speed = 'FBDict_Speed'  #µôѪËÙ¶È /s  
 | 
FBDict_RemainHP = 'FBDict_RemainHP'  #Ê£Óàʱ¼ä  
 | 
FBDict_IsReduceing = 'FBDict_IsReduceing'  #ÊÇ·ñµôѪÖÐ  
 | 
FBDict_BossTotalHP = 'FBDict_BossTotalHP'  #BOSSѪÁ¿  
 | 
FBDict_LastHurtTick = 'FBDict_LastHurtTick'  #ÉÏ´ÎÉ˺¦Ê±¼ä  
 | 
FBDict_HasGiveAward = 'FBDict_HasGiveAward'  # ÊÇ·ñÓиø½±Àø  
 | 
FBDict_HasPass = 'FBDict_HasPass'  # ÊÇ·ñÓÐͨ¹Ø  
 | 
  
 | 
# ¸±±¾Í¨ÓÃÅäÖà  
 | 
(  
 | 
Def_PrepareTime,  # Ã¿¹Ø×¼±¸Ê±¼ä£¬Ãë  
 | 
Def_FightTime,  # Ã¿¹ØÕ½¶·Ê±¼ä£¬Ãë  
 | 
Def_ExitTime,  # Í˳öʱ¼ä, Ãë  
 | 
Def_StarTime,  # ÐǼ¶¶ÔÓ¦ºÄʱÅäÖÃ, Ãë  
 | 
) = range(4)  
 | 
  
 | 
# ¸±±¾×´Ì¬  
 | 
(  
 | 
FB_State_Open,  # ¸±±¾¿ªÆô  
 | 
FB_State_FightPrepare,  # Õ½¶·×¼±¸Ê±¼ä  
 | 
FB_State_Fighting,  # Õ½¶·  
 | 
FB_State_FreeTime,  # »î¶¯½áÊø×¼±¸£¨Ê¤Àû/ʧ°Ü£©  
 | 
FB_State_Close,  # ¹Ø±Õ¸±±¾  
 | 
) = range(5)  
 | 
  
 | 
  
 | 
## ÖïÏÉËþÅäÖà  
 | 
def __GetZhuXianCfg(): return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_ZhuXianTower)  
 | 
  
 | 
  
 | 
def GetTowerIpyData(level):  
 | 
    return IpyGameDataPY.GetIpyGameData('ZhuXianTower', level)  
 | 
  
 | 
  
 | 
def OnFBPlayerOnLogin(curPlayer):  
 | 
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_ZXTower):  
 | 
        GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_ZXTower, 1)  
 | 
        #½±Àø±ä¸ü²¹³¥ s¼¶Í¨¹Ø½±ÀøÀïµÄ±¦Ê¯  
 | 
        curFloor = __GetZhuXianTowerCurPassLV(curPlayer)  
 | 
        if curFloor:  
 | 
            giveItemList = []  
 | 
            for floor in xrange(1, curFloor+1):  
 | 
                ipyData = GetTowerIpyData(floor)  
 | 
                if not ipyData:  
 | 
                    continue  
 | 
                for itemInfo in ipyData.GetFirstAward():  
 | 
                    itemID = itemInfo[0]  
 | 
                    itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  
 | 
                    if not itemData:  
 | 
                        continue  
 | 
                    if itemData.GetType() == ChConfig.Def_ItemType_ZhuXianStone:  
 | 
                        giveItemList.append(itemInfo)  
 | 
            if giveItemList:  
 | 
                PlayerControl.SendMailByKey('KillGodTowerCompensation', [curPlayer.GetID()], giveItemList)  
 | 
      
 | 
      
 | 
      
 | 
    SyncZhuXianLevelInfo(curPlayer)  
 | 
    return  
 | 
  
 | 
  
 | 
## Í¬²½ÖïÏÉËþ¹Ø¿¨ÐÅÏ¢  
 | 
#  @fbLevel Îª0ʱĬÈÏÈ«²¿Í¬²½£¬> 0ʱ½öͬ²½¸Ã¹Ø¿¨  
 | 
def SyncZhuXianLevelInfo(curPlayer):  
 | 
    ttInfo = ChPyNetSendPack.tagMCZhuXianTowerInfo()  
 | 
    ttInfo.Clear()  
 | 
    ttInfo.Floor = __GetZhuXianTowerCurPassLV(curPlayer)  
 | 
    ttInfo.LastFloor = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ZhuXianTowerLastFloor)  
 | 
    NetPackCommon.SendFakePack(curPlayer, ttInfo)  
 | 
    return  
 | 
  
 | 
  
 | 
## »ñÈ¡µ±Ç°ÒÑͨ¹Ø¹Ø¿¨  
 | 
def __GetZhuXianTowerCurPassLV(curPlayer):  
 | 
    return curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ZhuXianTowerPassLV)  
 | 
  
 | 
  
 | 
## ¸üе±Ç°ÒÑͨ¹Ø¹Ø¿¨  
 | 
def SetZhuXianTowerCurPassLV(curPlayer, passlv, costSeconds=0):  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ZhuXianTowerPassLV, passlv)  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ZhuXianTowerCostTime, costSeconds)  
 | 
    #¸üÐÂÖïÏÉËþÅÅÐаñ  
 | 
    PlayerBillboard.UpdateZhuXianTowerBillboard(curPlayer)  
 | 
    GameWorld.DebugLog(' ¸üÐÂÖïÏÉËþÒÑͨ¹ØÊý %s' % passlv)  
 | 
    return  
 | 
  
 | 
  
 | 
## ÊÇ·ñ¿É½øÈë  
 | 
#  @param curPlayer  
 | 
#  @param mapID µØÍ¼ID  
 | 
#  @param lineId ·ÖÏßID  
 | 
#  @param tick  
 | 
#  @return ÊÇ·ñ¿É½øÈë  
 | 
def OnEnterFBEvent(curPlayer, mapID, lineId, tick):      
 | 
    return True  
 | 
  
 | 
  
 | 
## ¼ì²é¿É·ñ½øÐÐÌôÕ½  
 | 
def __CheckCanChallenge(curPlayer):  
 | 
    #ÅжϴÎÊý  
 | 
    curFloor = __GetZhuXianTowerCurPassLV(curPlayer)  
 | 
    ipyMgr = IpyGameDataPY.IPY_Data()  
 | 
    maxFloor = ipyMgr.GetZhuXianTowerByIndex(ipyMgr.GetZhuXianTowerCount() - 1).GetID()  
 | 
    if curFloor >= maxFloor: #ÒѾ×îºó²ãʱ£¬ÅжϴÎÊý  
 | 
        enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_ZhuXianTower)  
 | 
        if enterCnt >= FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower):  
 | 
            GameWorld.Log('½øÈë´ÎÊý²»×㣡£¡')  
 | 
            return 0  
 | 
        return maxFloor  
 | 
    return curFloor + 1  
 | 
      
 | 
##Íæ¼ÒÇл»µØÍ¼  
 | 
def DoPlayerChangeMapLogic(curPlayer):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)  
 | 
    hasPass = gameFB.GetGameFBDictByKey(FBDict_HasPass)  
 | 
    if fbStep == FB_State_FreeTime: #ʧ°Ü»ò·ÇSͨ¹ØÐèÒª¼Ócd  
 | 
        if curStar != Def_MaxStar or not hasPass:  
 | 
            FBCommon.UpdateFBEnterTick(curPlayer)  
 | 
    return  
 | 
  
 | 
##¸±±¾Íæ¼Ò½øÈëµã  
 | 
# @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 »Ø¸´ÊÇ·ñͨ¹ýÇëÇó  
 | 
def OnChangeMapAsk(ask, tick):  
 | 
    return IPY_GameWorld.cmeAccept  
 | 
  
 | 
  
 | 
## ½ø¸±±¾  
 | 
#  @param curPlayer  
 | 
#  @param tick  
 | 
#  @return None  
 | 
def DoEnterFB(curPlayer, tick):  
 | 
    # ²»×ö´¦Àí£¬Óи±±¾ÐÐΪ¿Í»§¶Ë·¢°üÑ¡ÔñÌôÕ½¹Ø¿¨  
 | 
    EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower, 0, ChConfig.CME_Log_Start)  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    ZhuXianCfg = __GetZhuXianCfg()  
 | 
    if fbStep <= FB_State_FightPrepare:  
 | 
        notify_tick = ZhuXianCfg[Def_PrepareTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  
 | 
        curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)  
 | 
          
 | 
    elif fbStep == FB_State_Fighting:  
 | 
        notify_tick = ZhuXianCfg[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  
 | 
        curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)  
 | 
        __UpdZhuXianTowerFBStar(tick, True, curPlayer)  
 | 
    return  
 | 
  
 | 
  
 | 
## ¸±±¾Ê±¼äµ½¹Ø±Õ  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def OnCloseFB(tick):  
 | 
    return  
 | 
  
 | 
  
 | 
##Íæ¼ÒÍ˳ö¸±±¾.  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
def DoExitFB(curPlayer, tick):  
 | 
    # Íæ¼ÒÍ˳öĬÈϹرո±±¾  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    if fbStep == FB_State_FreeTime:  
 | 
        #Í˳öʱ£¬Èôs¼¶Ôò²¹·¢½±Àø  
 | 
        curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)  
 | 
        hasPass = gameFB.GetGameFBDictByKey(FBDict_HasPass)  
 | 
        if hasPass and curStar == Def_MaxStar:  
 | 
            __GiveFBPassPrize(curPlayer)  
 | 
        GameWorldProcess.CloseFB(tick)  
 | 
    return  
 | 
  
 | 
  
 | 
##¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  
 | 
def OnProcess(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
      
 | 
    if fbStep == FB_State_FightPrepare:  
 | 
        __DoLogic_FightPrepare(tick)  
 | 
    elif fbStep == FB_State_Fighting:  
 | 
        __DoLogic_Fighting(tick)  
 | 
        __CheckBossHP(tick)  
 | 
        __UpdZhuXianTowerFBStar(tick)  
 | 
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)  
 | 
    elif fbStep == FB_State_FreeTime:  
 | 
        __DoLogic_FreeTime(tick)  
 | 
    elif fbStep == FB_State_Close:  
 | 
        pass  
 | 
      
 | 
    return  
 | 
  
 | 
  
 | 
## ¸üе±Ç°¸±±¾ÐǼ¶  
 | 
def __UpdZhuXianTowerFBStar(tick, isEnter=False, curPlayer=None):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    if fbStep != FB_State_Fighting:  
 | 
        return  
 | 
    curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)  
 | 
    if curStar == 1:  
 | 
        return curStar  
 | 
      
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    useSecond = int(math.ceil((tick - gameFB.GetFBStepTick()) / 1000.0))  
 | 
    chaosDemonCfg = FBCommon.GetFBLineStepTime(mapID)  
 | 
    starTimeList = chaosDemonCfg[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 isEnter:  
 | 
        return curStar  
 | 
          
 | 
    gameFB.SetGameFBDict(FBDict_FBStar, updStar)  
 | 
      
 | 
    GameWorld.DebugLog("__UpdFBStar 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  
 | 
  
 | 
  
 | 
## »ñÈ¡BossID  
 | 
def __GetZhuXianBossID(fbLevel=-1):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    if fbLevel == -1:  
 | 
        fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  
 | 
    ipyData = GetTowerIpyData(fbLevel)  
 | 
      
 | 
    if not ipyData:  
 | 
        GameWorld.ErrLog("__GetZhuXianBossID() can not find %s in tagZhuXianTower.txt" % fbLevel)  
 | 
        return 0  
 | 
    return ipyData.GetNPCID()  
 | 
  
 | 
  
 | 
##Õ½¶·×¼±¸Ê±¼ä  
 | 
# @param tick  Ê±ÖÓ  
 | 
# @return ÎÞÒâÒå  
 | 
def __DoLogic_FightPrepare(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    ZhuXianCfg = __GetZhuXianCfg()  
 | 
    if tick - gameFB.GetFBStepTick() < ZhuXianCfg[Def_PrepareTime] * 1000:  
 | 
        return  
 | 
    bossID = __GetZhuXianBossID()  
 | 
    if not bossID:  
 | 
        FBCommon.DoLogic_FBKickAllPlayer()  
 | 
        return  
 | 
      
 | 
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, ZhuXianCfg[Def_FightTime] * 1000)  
 | 
      
 | 
    NPCCustomRefresh.SetNPCRefresh(FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_ZhuXianTower, 0), [bossID])  
 | 
      
 | 
    #תÈëÕ½¶·  
 | 
    FBCommon.SetFBStep(FB_State_Fighting, tick)  
 | 
    return  
 | 
  
 | 
  
 | 
## ¿ªÊ¼¸±±¾¹Ø¿¨  
 | 
def StartFBLevel(curPlayer, fbLevel, tick):  
 | 
      
 | 
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  
 | 
        GameWorld.DebugLog("¸´»îÍæ¼Ò...", curPlayer.GetPlayerID())  
 | 
        ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_City, tick)  
 | 
    curPlayer.SetHP(curPlayer.GetMaxHP())  
 | 
    FBCommon.ClearFBNPC()  
 | 
      
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    gameFB.SetGameFBDict(FBDict_Level, fbLevel)  
 | 
    playerPower = curPlayer.GetFightPower()  
 | 
    ipyData = GetTowerIpyData(fbLevel)  
 | 
    needPower = ipyData.GetNeedPower()  
 | 
    totalHP = eval(IpyGameDataPY.GetFuncCompileCfg('ZhuXianTowerBossTime'))  
 | 
    gameFB.SetGameFBDict(FBDict_BossTotalHP, totalHP * 1000)  
 | 
    gameFB.SetGameFBDict(FBDict_Speed, 1000)  #ËÙ¶ÈĬÈÏ1000  
 | 
    gameFB.SetGameFBDict(FBDict_RemainHP, totalHP * 1000)  
 | 
    gameFB.SetGameFBDict(FBDict_IsReduceing, 0)  
 | 
    gameFB.SetGameFBDict(FBDict_LastHurtTick, 0)  
 | 
    gameFB.SetGameFBDict(FBDict_HasGiveAward, 0)  
 | 
    gameFB.SetGameFBDict(FBDict_StartTick, 0)  
 | 
    gameFB.SetGameFBDict(FBDict_FBStar, 0)  
 | 
    gameFB.SetGameFBDict(FBDict_HasPass, 0)  
 | 
      
 | 
    prepareTick = __GetZhuXianCfg()[Def_PrepareTime] * 1000  
 | 
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttAddUpTime, prepareTick)  
 | 
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, prepareTick)  
 | 
    FBCommon.SetFBStep(FB_State_FightPrepare, tick)  
 | 
  
 | 
    lastFloor = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ZhuXianTowerLastFloor)  
 | 
    if fbLevel != lastFloor:  
 | 
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ZhuXianTowerLastFloor, fbLevel)  
 | 
        SyncZhuXianLevelInfo(curPlayer) # Í¬²½ÐÅÏ¢  
 | 
      
 | 
    DoFBHelp(curPlayer, tick)  
 | 
    GameWorld.DebugLog("StartFBLevel, fbLevel=%s£¬totalHP=%s" % (fbLevel, totalHP), curPlayer.GetPlayerID())  
 | 
    return  
 | 
  
 | 
  
 | 
##Õ½¶·Ê±¼ä  
 | 
# @param tick  Ê±ÖÓ  
 | 
# @return ÎÞÒâÒå  
 | 
def __DoLogic_Fighting(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
      
 | 
    #ÅжÏʱ¼ä½áÊø  
 | 
    if tick - gameFB.GetFBStepTick() < __GetZhuXianCfg()[Def_FightTime] * 1000:  
 | 
        lastHurtTick = gameFB.GetGameFBDictByKey(FBDict_LastHurtTick)  
 | 
        if lastHurtTick and tick - lastHurtTick >= 2000:  
 | 
            StopReduceHP(tick)  
 | 
            GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, 0)  
 | 
        return  
 | 
      
 | 
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  
 | 
    playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for index in xrange(playerManager.GetPlayerCount()):  
 | 
        curPlayer = playerManager.GetPlayerByIndex(index)  
 | 
        if not curPlayer:  
 | 
            continue  
 | 
        __SendZhuXianTowerOverInfo(curPlayer, fbLevel, False)  
 | 
      
 | 
    #ÓÎÏ·½áÊø  
 | 
    __SetFBToFreeTime(tick)  
 | 
    return  
 | 
  
 | 
  
 | 
##ÉèÖø±±¾½øÈëÀ뿪״̬  
 | 
# @param tick  Ê±ÖÓ  
 | 
# @return ÎÞÒâÒå  
 | 
def __SetFBToFreeTime(tick):  
 | 
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, __GetZhuXianCfg()[Def_ExitTime] * 1000)  
 | 
    FBCommon.SetFBStep(FB_State_FreeTime, tick)  
 | 
    return  
 | 
  
 | 
  
 | 
##±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  
 | 
# @param tick  Ê±ÖÓ  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  
 | 
def __DoLogic_FreeTime(tick):  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < __GetZhuXianCfg()[Def_ExitTime] * 1000:  
 | 
        return  
 | 
      
 | 
    #FBCommon.DoLogic_FBKickAllPlayer()  
 | 
    return  
 | 
  
 | 
  
 | 
def DoZhuXianTowerOver(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  
 | 
    # ¹ý¹ØÈ«·þ¹ã²¥  
 | 
    ipyData = GetTowerIpyData(fbLevel)  
 | 
    if not ipyData:  
 | 
        return  
 | 
    curPlayer = FBCommon.GetCurSingleFBPlayer()  
 | 
    if not curPlayer:  
 | 
        GameWorldProcess.CloseFB(tick)  
 | 
        return  
 | 
    # ¼Ç¼¹ý¹Ø  
 | 
    #EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower, 0, ChConfig.CME_Log_End, 0, 1)  
 | 
  
 | 
    # ¹ý¹ØÊ±¼ä  
 | 
    costTime = tick - GameWorld.GetGameFB().GetFBStepTick()  
 | 
    curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)  
 | 
    isFirstS = 0  
 | 
    if fbLevel != __GetZhuXianTowerCurPassLV(curPlayer) and curStar == Def_MaxStar:  
 | 
        #¸üйؿ¨  
 | 
        SetZhuXianTowerCurPassLV(curPlayer, fbLevel, costTime/1000)  
 | 
          
 | 
        isFirstS = 1  #ÊÇ·ñÊ×´ÎSͨ¹Ø  
 | 
    gameFB.SetGameFBDict(FBDict_isFirstS, isFirstS)  
 | 
      
 | 
    unLockEquipPlace = ipyData.GetUnLockEquipPlace()  
 | 
    if isFirstS and unLockEquipPlace:  
 | 
        PlayerControl.WorldNotify(0, 'KillGodTowerInfo_1', [curPlayer.GetPlayerName(), fbLevel, unLockEquipPlace])  
 | 
          
 | 
    # ¸ø¹ý¹Ø½±Àø  
 | 
    prizeItemList = __GiveFBPassPrize(curPlayer, False)  
 | 
      
 | 
    prizeDict = {FBCommon.Over_costTime:costTime, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(prizeItemList),  
 | 
                 FBCommon.Over_grade:curStar}  
 | 
    __SendZhuXianTowerOverInfo(curPlayer, fbLevel, True if prizeItemList else False, prizeDict)  
 | 
      
 | 
    #ÈÎÎñ  
 | 
    #EventShell.EventRespons_ZhuXianTowerCnt(curPlayer, fbLevel)  
 | 
      
 | 
    SyncZhuXianLevelInfo(curPlayer)  # Í¬²½×îйؿ¨ÐÅÏ¢  
 | 
    __SetFBToFreeTime(tick)  
 | 
    #ÿÈÕÈÎÎñ  
 | 
    #PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_Tower)  
 | 
    return  
 | 
  
 | 
  
 | 
## É±¹Ö  
 | 
#  @param curPlayer  
 | 
#  @param curNPC ±»É±µÄ¹Ö  
 | 
#  @param tick  
 | 
#  @return None  
 | 
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  
 | 
      
 | 
    return  
 | 
  
 | 
  
 | 
## ¸ø¹ý¹Ø½±Àø  
 | 
def __GiveFBPassPrize(curPlayer, isGive=True):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    preFloor = gameFB.GetGameFBDictByKey(FBDict_Level)  
 | 
    ipyData = GetTowerIpyData(preFloor)  
 | 
    if not ipyData:  
 | 
        return []  
 | 
      
 | 
    isFirstPass = gameFB.GetGameFBDictByKey(FBDict_isFirstS)  #ÊÇ·ñÊ×´Îsͨ¹Ø  
 | 
    if isFirstPass:  
 | 
        prizeItemList = ipyData.GetFirstAward()  
 | 
    else:  
 | 
        curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)  
 | 
        prizeItemList = ipyData.GetGradeAward().get(curStar, [])  
 | 
    if not prizeItemList:  
 | 
        return []  
 | 
    if not isGive:  
 | 
        return prizeItemList  
 | 
    if gameFB.GetGameFBDictByKey(FBDict_HasGiveAward):  
 | 
        GameWorld.Log('±¾²ã½±ÀøÒѸø£¬²»ÄÜÖØ¸´¸ø£¡£¡', curPlayer.GetID())  
 | 
        return  
 | 
    hasPass = gameFB.GetGameFBDictByKey(FBDict_HasPass)  
 | 
    if not hasPass:  
 | 
        return  
 | 
      
 | 
    # ·¢Óʼþ»ò·ÅÈë±³°ü  
 | 
    ItemControler.GivePlayerItemOrMail(curPlayer, prizeItemList, 'KillGodTowerReward', ["ZhuXianTower", False, {}])  
 | 
      
 | 
    #Ê×´ÎS¼¶²»¿Û´ÎÊý£¬·ÇS¼¶¸ø½±Àø¿Û´ÎÊý£¬·ÇÊ×´ÎS¿Û´ÎÊý  
 | 
    if not isFirstPass:  
 | 
        FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower, 1)  
 | 
  
 | 
          
 | 
    gameFB.SetGameFBDict(FBDict_HasGiveAward, 1)  
 | 
    PlayerActLogin.AddLoginAwardActionCnt(curPlayer, ChConfig.Def_LoginAct_ZhuXianTower, 1)  
 | 
    return  
 | 
  
 | 
  
 | 
##¸±±¾°ïÖúÐÅÏ¢  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ÓÃÓÚ֪ͨÕóÓª±È·ÖÌõ  
 | 
def DoFBHelp(curPlayer, tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    star = gameFB.GetGameFBDictByKey(FBDict_FBStar)  
 | 
      
 | 
    curSpeed = gameFB.GetGameFBDictByKey(FBDict_Speed)   
 | 
    isReduceing = gameFB.GetGameFBDictByKey(FBDict_IsReduceing)   
 | 
    remainHP = GetBossRemainHP(tick)  
 | 
    totalHP = __GetBossTotalHP()  
 | 
    hpReduceSpeed = curSpeed * 10000 / totalHP if totalHP else 0  
 | 
    remainHPPer = min(1000000, remainHP * 1000000 / totalHP) if totalHP else 0  
 | 
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  
 | 
    fbHelpDict = {FBCommon.Help_wheel:fbLevel, FBCommon.Help_grade:star, 'hpReduceSpeed':hpReduceSpeed, 'remainHPPer':remainHPPer, 'isReduceing':isReduceing}  
 | 
    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())  
 | 
    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)  
 | 
    return  
 | 
  
 | 
  
 | 
## ·¢ËÍÌôÕ½½á¹ûÐÅÏ¢  
 | 
def __SendZhuXianTowerOverInfo(curPlayer, fbLevel, isPass, overDict={}):  
 | 
      
 | 
    overDict[FBCommon.Over_dataMapID] = ChConfig.Def_FBMapID_ZhuXianTower  
 | 
    overDict[FBCommon.Over_wheel] = fbLevel  
 | 
    overDict[FBCommon.Over_isPass] = int(isPass)  
 | 
    GameWorld.DebugLog("__SendZhuXianTowerOverInfo overDict=%s" % (str(overDict)), curPlayer.GetPlayerID())  
 | 
    FBCommon.Notify_FB_Over(curPlayer, overDict)  
 | 
    GameWorld.GetGameFB().SetGameFBDict(FBDict_HasPass, int(isPass))  
 | 
    return  
 | 
  
 | 
  
 | 
## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  
 | 
#  @param attacker ¹¥»÷·½  
 | 
#  @param defender ·ÀÊØ·½  
 | 
#  @return bool  
 | 
def CheckCanAttackTagObjInFB(attacker, defender):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    if gameFB.GetFBStep() != FB_State_Fighting:  
 | 
        return False  
 | 
    return True  
 | 
  
 | 
  
 | 
##Íæ¼ÒËÀÍö.  
 | 
# @param curPlayer:ËÀÍöµÄÍæ¼Ò   
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
def DoPlayerDead(curPlayer):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  
 | 
    __SendZhuXianTowerOverInfo(curPlayer, fbLevel, False)  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    #ÓÎÏ·½áÊø  
 | 
    __SetFBToFreeTime(tick)  
 | 
    return  
 | 
  
 | 
  
 | 
## ÊÇ·ñ¸±±¾¸´»î  
 | 
#  @param None  
 | 
#  @return ÊÇ·ñ¸±±¾¸´»î  
 | 
def OnPlayerReborn():  
 | 
    return True  
 | 
  
 | 
  
 | 
## ¸±±¾ÐÐΪ  
 | 
#  @param curPlayer Íæ¼Ò  
 | 
#  @param actionType ÐÐΪÀàÐÍ  
 | 
#  @param actionInfo ÐÐΪÐÅÏ¢  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
def DoFBAction(curPlayer, actionType, actionInfo, tick):  
 | 
    # Ä¬ÈÏΪѡÔñ¹Ø¿¨£¬Óɿͻ§¶Ë¾ö¶¨£¬½ø³¡¼°¸±±¾Ñ¡¹ØÍ¨ÓôËÐÐΪ  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    if actionType == 0:  
 | 
  
 | 
        if fbStep in [FB_State_FightPrepare, FB_State_Fighting]:  
 | 
            GameWorld.DebugLog("×¼±¸»òÕ½¶·ÖÐ, ÎÞ·¨±ä¸ü¹Ø¿¨!")  
 | 
            return  
 | 
        newFloor = __CheckCanChallenge(curPlayer)  
 | 
        if not newFloor:  
 | 
            FBCommon.DoLogic_FBKickAllPlayer()  
 | 
            return  
 | 
          
 | 
        StartFBLevel(curPlayer, newFloor, tick)  
 | 
    elif actionType == 1:  
 | 
        #ÁìÈ¡½±Àø  
 | 
        if fbStep != FB_State_FreeTime:  
 | 
            return  
 | 
        __GiveFBPassPrize(curPlayer)  
 | 
    return  
 | 
  
 | 
  
 | 
def __CheckBossHP(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    fbStep = gameFB.GetFBStep()  
 | 
  
 | 
    if fbStep == FB_State_Fighting and GetBossRemainHP(tick) == 0:  
 | 
        #½áÊø ÉèÖÃBOSSËÀÍö  
 | 
        FBCommon.ClearFBNPC()  
 | 
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)  
 | 
        GameWorld.DebugLog('½áÊø ÉèÖÃBOSSËÀÍö ')  
 | 
          
 | 
        DoZhuXianTowerOver(tick)  
 | 
          
 | 
    return  
 | 
  
 | 
  
 | 
def StopReduceHP(tick):  
 | 
    ##ÔÝÍ£BOSSѪÁ¿¼õÉÙ  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    if not gameFB.GetGameFBDictByKey(FBDict_IsReduceing):  
 | 
        return  
 | 
    remainHP = GetBossRemainHP(tick)  
 | 
    if not remainHP:  
 | 
        return  
 | 
    gameFB.SetGameFBDict(FBDict_IsReduceing, 0)  
 | 
    gameFB.SetGameFBDict(FBDict_RemainHP, remainHP)  
 | 
    GameWorld.DebugLog('    ÔÝÍ£BOSSѪÁ¿¼õÉÙ')  
 | 
    return  
 | 
  
 | 
  
 | 
def StartReduceHP(tick):  
 | 
    ##¿ªÊ¼BOSSµôѪ  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    if gameFB.GetGameFBDictByKey(FBDict_IsReduceing):  
 | 
        return  
 | 
    gameFB.SetGameFBDict(FBDict_IsReduceing, 1)  
 | 
    startTick = gameFB.GetGameFBDictByKey(FBDict_StartTick)  
 | 
    if not startTick:  
 | 
        gameFB.SetGameFBDict(FBDict_RemainHP, __GetBossTotalHP())  
 | 
    gameFB.SetGameFBDict(FBDict_StartTick, tick)  
 | 
    GameWorld.DebugLog('    ¿ªÊ¼BOSSµôѪ')  
 | 
      
 | 
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)  
 | 
    return  
 | 
  
 | 
  
 | 
def __GetBossTotalHP():return GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_BossTotalHP)  
 | 
      
 | 
  
 | 
def GetBossRemainHP(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
      
 | 
    startTick = gameFB.GetGameFBDictByKey(FBDict_StartTick)  
 | 
    lastSpeed = gameFB.GetGameFBDictByKey(FBDict_Speed)   
 | 
    remainHP = gameFB.GetGameFBDictByKey(FBDict_RemainHP)  
 | 
    if not gameFB.GetGameFBDictByKey(FBDict_IsReduceing):  
 | 
        return remainHP  
 | 
    if not startTick:  
 | 
        startTick = tick  
 | 
        remainHP = __GetBossTotalHP()  
 | 
    else:  
 | 
        remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))  
 | 
    return remainHP  
 | 
  
 | 
  
 | 
## Íæ¼Ò¶ÔNPCÔì³ÉÉ˺¦  
 | 
#  @param curPlayer µ±Ç°Íæ¼Ò  
 | 
#  @param curNPC   
 | 
#  @param hurtHP   
 | 
#  @return None  
 | 
def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, tick)  
 | 
    StartReduceHP(tick)  
 | 
    return  
 |