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