| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_HorsePetBoss  | 
| #  | 
| # @todo:Æï³èboss  | 
| # @author xdh  | 
| # @date 2019-03-22  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: Æï³èboss  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2019-03-22 14:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import FBCommon  | 
| import GameWorld  | 
| import IPY_GameWorld  | 
| import GameWorldProcess  | 
| import IpyGameDataPY  | 
| import ChConfig  | 
| import PyGameData  | 
| import PlayerControl  | 
| import ShareDefine  | 
| import PlayerActivity  | 
| import NPCCustomRefresh  | 
| import ItemControler  | 
| import EventReport  | 
| import NPCCommon  | 
|   | 
| FBDict_StartTick = 'FBDict_StartTick%s' #¿ªÊ¼Ê±¼ä  | 
| FBDict_Speed = 'FBDict_Speed%s' #µôѪËÙ¶È /s  | 
| FBDict_RemainHP = 'FBDict_RemainHP%s' #Ê£Óàʱ¼ä  | 
| FBPlayerDict_EncourageLV = 'FBPlayerDict_EncourageLV'   # ¹ÄÎèµÈ¼¶  | 
| FBDict_IsOver = 'FBDict_IsOver' #ÊÇ·ñÒѽáËã, ½áËãʱµÄtick  | 
| FBDict_IsReduceing = 'FBDict_IsReduceing%s' #ÊÇ·ñµôѪÖÐ  | 
| FBPlayerDict_Rank = "FBPlayerDict_Rank" # Íæ¼ÒÅÅÃû  | 
| FBDict_BossTotalHP = 'FBDict_BossTotalHP%s' #BOSSѪÁ¿  | 
| FBDict_LastHurtTick = 'FBDict_LastHurtTick'  #ÉÏ´ÎÉ˺¦Ê±¼ä  | 
| FBDict_LastHPNotify = 'FBDict_LastHPNotify'  #ÉÏÒ»¸öѪÁ¿¹ã²¥  | 
|   | 
|   | 
| (  | 
| Def_BossTime,  #BOSSʱ¼ä  | 
| Def_LeaveTime,  #À뿪ʱ¼ä  | 
| Def_HPSpeed,  #µôѪËٶȹ«Ê½  | 
| ) = range(3)  | 
|       | 
| #µ±Ç°¸±±¾µØÍ¼µÄ״̬  | 
| (  | 
| FB_Step_Open,  # ¸±±¾¿ªÆô  | 
| FB_Step_Fighting,  # ¸±±¾½øÐÐÖÐ  | 
| FB_Step_Over,  # ¸±±¾½áÊø  | 
| FB_Step_Close,  # ¸±±¾¹Ø±Õ  | 
| ) = range(4)  | 
|       | 
| def OnFBPlayerOnLogin(curPlayer):  | 
|     return  | 
|   | 
| def OnFBPlayerOnDay(curPlayer):  | 
|     return  | 
|   | 
|   | 
| ## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param mapID µØÍ¼ID  | 
| #  @param lineID Ïß·id  | 
| #  @param tick Ê±¼ä´Á  | 
| #  @return ²¼¶ûÖµ  | 
| def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|     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 tick Ê±¼ä´Á  | 
| ##  @return ²¼¶ûÖµ  | 
| #def OnCanOpen(tick):  | 
| #    return True  | 
|   | 
| ##²éѯÊÇ·ñ¿ÉÒÔ½øÈëµØÍ¼  | 
| # @param ask:ÇëÇó½á¹¹Ìå(IPY_BMChangeMapAsk)  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return IPY_GameWorld.cme Ã¶¾Ù  | 
| def OnChangeMapAsk(ask, tick):  | 
|     return IPY_GameWorld.cmeAccept  | 
|   | 
| ##¿ªÆô¸±±¾  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ¿ªÆô¸±±¾  | 
| def OnOpenFB(tick):  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     bossID = CurFBLineBOSSID(lineID)  | 
|     if not bossID:  | 
|         return  | 
|     NPCCustomRefresh.SetNPCRefresh(101, [bossID])  | 
|     BossTime = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_HorsePetBoss, lineID)[Def_BossTime]  | 
|     GameWorld.GetGameWorld().SetGameWorldDict(FBDict_BossTotalHP%lineID, BossTime * 1000)  | 
|     return  | 
|   | 
| def OnHorsePetBossStateChange(state, tick):  | 
|     #»î¶¯×´Ì¬±ä¸ü  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     if mapID != ChConfig.Def_FBMapID_HorsePetBoss:  | 
|         return  | 
|     GameWorld.DebugLog('    Æï³èBOSS»î¶¯×´Ì¬±ä¸ü state=%s' % state)  | 
|   | 
|     if not state:  | 
|         if GameWorld.GetGameFB().GetFBStep() == FB_Step_Fighting:  | 
|             GameWorld.GetGameFB().SetGameFBDict(FBDict_IsOver, tick)  | 
|             __DoLogicHorsePetBossOver(0, tick, 0, 0)  | 
|     return  | 
|   | 
| ## ½ø¸±±¾  | 
| #  @param curPlayer  | 
| #  @param tick  | 
| #  @return None  | 
| def DoEnterFB(curPlayer, tick):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|   | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1      | 
|       | 
|     playerCnt = GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount()  | 
|     GameWorld.DebugLog("DoEnterFB...playerCnt=%s,lineID=%s" % (playerCnt, lineID), playerID)  | 
|       | 
|     if lineID < 0:  | 
|         PlayerControl.PlayerLeaveFB(curPlayer)  | 
|         return  | 
|     fbStep = GameWorld.GetGameFB().GetFBStep()  | 
|     if fbStep >= FB_Step_Over:  | 
|         PlayerControl.PlayerLeaveFB(curPlayer)  | 
|         return  | 
|     hadDelTicket = FBCommon.GetHadDelTicket(curPlayer)  | 
|     if not hadDelTicket:  | 
|         FBCommon.SetHadDelTicket(curPlayer)  | 
|         PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_HorsePetBoss, 1)  | 
|         EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_HorsePetBoss, 0, ChConfig.CME_Log_Start)  | 
|   | 
|         if fbStep == FB_Step_Open:  | 
|             FBCommon.SetFBStep(FB_Step_Fighting, tick)  | 
|     UpdateHurtInfo(curPlayer, 0, True)  | 
|       | 
|     UpdateHPReduceSpeed(tick)          | 
|     gameFB = GameWorld.GetGameFB()  | 
|     # ÉϹÄÎèbuff  | 
|     encourageLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EncourageLV)  | 
|     if encourageLV > 0:  | 
|         FBCommon.AddFbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, tick)  | 
|     else:  | 
|         FBCommon.SendFBEncourageInfo(curPlayer, encourageLV)  | 
|           | 
|     DoFBHelp(curPlayer, tick)  | 
|     return  | 
|   | 
| ##¹Ø±Õ¸±±¾  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks   | 
| def OnCloseFB(tick):  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     lineID = gameWorld.GetPropertyID() - 1  | 
|     gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, 0)  | 
|     gameWorld.SetGameWorldDict(FBDict_Speed % lineID, 0)  | 
|     gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, 0)  | 
|     PyGameData.g_horsePetBossPlayerHurtDict[lineID] = {}  | 
|     gameWorld.SetPropertyID(0)  | 
|     return  | 
|   | 
| ##Íæ¼ÒÍ˳ö¸±±¾  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoExitFB(curPlayer, tick):  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     # Çå³ý¹ÄÎèbuff  | 
|     FBCommon.ClearEncourageBuff(curPlayer, tick)  | 
| #    #×îºóÒ»ÈË  | 
| #    if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:  | 
| #        lineID = gameWorld.GetPropertyID() - 1  | 
| #        PyGameData.g_horsePetBossPlayerHurtDict[lineID] = {}  | 
| #        gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, 0)  | 
| #        GameWorld.GetGameFB().ClearGameFBDict()  | 
| #        GameWorldProcess.CloseFB(tick)  | 
| #        return  | 
|           | 
|     UpdateHPReduceSpeed(tick, True)  | 
|       | 
|     return  | 
|   | 
| ##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| def DoPlayerLeaveFB(curPlayer, tick):  | 
|     #FBCommon.SetHadDelTicket(curPlayer, 0)  | 
|     #Ö÷¶¯Í˳öµÄÈ¥µôÅÅÐаñÐÅÏ¢  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     playerHurtDict = PyGameData.g_horsePetBossPlayerHurtDict.get(lineID, {})  | 
|     playerHurtDict.pop(curPlayer.GetPlayerID(), 0)  | 
|     PyGameData.g_horsePetBossPlayerHurtDict[lineID] = playerHurtDict  | 
|     if not playerHurtDict: #°ñÉÏûÈË£¬Í£Ö¹µôѪ  | 
|         StopReduceHP(lineID, tick)  | 
|     return  | 
|   | 
| ##Íæ¼ÒÇл»µØÍ¼  | 
| def DoPlayerChangeMapLogic(curPlayer):  | 
|     #FBCommon.SetHadDelTicket(curPlayer, 0)  | 
|     return  | 
|   | 
| ## ÊÇ·ñ¸±±¾¸´»î  | 
| #  @param None  | 
| #  @return ÊÇ·ñ¸±±¾¸´»î  | 
| def OnPlayerReborn():  | 
|     return True  | 
|   | 
|   | 
| ## »ñµÃ¸±±¾°ïÖúÐÅÏ¢  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò£¨±»Í¨Öª¶ÔÏó£©  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| def DoFBHelp(curPlayer, tick):  | 
|     #É˺¦ÅÅÐÐÐÅÏ¢  | 
|     if GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_IsOver):  | 
|         return  | 
|     hurtInfo = []  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     | 
|     playerHurtList = __GetSortHurtList(lineID)  | 
|     myPlayerID = curPlayer.GetPlayerID()  | 
|     myRank, myHurt = 0, 0  | 
|     for i, info in enumerate(playerHurtList, 1):  | 
|         playerID = info[0]  | 
|         playerName, hurt = info[1][:2]  | 
|         if playerID == myPlayerID:  | 
|             myRank, myHurt = i, hurt  | 
|         if i <= 5:  | 
|             hurtDict = {}  | 
|             hurtDict["rank"] = i  | 
|             hurtDict["playerName"] = playerName  | 
|             hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue  | 
|             hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue  | 
|             hurtInfo.append(hurtDict)  | 
|   | 
|       | 
|     curSpeed = GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_Speed % lineID)   | 
|     isReduceing = GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_IsReduceing % lineID)   | 
|     remainHP = GetBossRemainHP(lineID, tick)  | 
|     totalHP = __GetBossTotalHP(lineID)  | 
|     hpReduceSpeed = curSpeed * 10000 / totalHP if totalHP else 0  | 
|     remainHPPer = min(1000000, remainHP * 1000000 / totalHP) if totalHP else 0  | 
|   | 
|     fbHelpDict = {FBCommon.Help_lineID:lineID, "hurtInfo":hurtInfo, 'hpReduceSpeed':hpReduceSpeed,   | 
|                   'remainHPPer':remainHPPer, 'isReduceing':isReduceing,'myHurt':myHurt % ChConfig.Def_PerPointValue,  | 
|                   'myHurtEx':myHurt / ChConfig.Def_PerPointValue, 'myRank':myRank  | 
|                   }  | 
|     GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())  | 
|     FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)  | 
|     return  | 
|   | 
|   | 
| ## ¸±±¾ÐÐΪ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param actionType ÐÐΪÀàÐÍ  | 
| #  @param actionInfo ÐÐΪÐÅÏ¢  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| def DoFBAction(curPlayer, actionType, actionInfo, tick):  | 
|     if actionType == 0:  | 
|         FBCommon.FbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, actionInfo, tick)  | 
|     return  | 
|   | 
|   | 
|   | 
| ## Íæ¼Ò¶ÔNPCÔì³ÉÉ˺¦  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curNPC   | 
| #  @param hurtHP   | 
| #  @return None  | 
| def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):  | 
|     UpdateHurtInfo(curPlayer, hurtHP)  | 
|     #ÓÐÈËÉϰñ¿ªÊ¼µôѪ  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     StartReduceHP(lineID, GameWorld.GetGameWorld().GetTick())  | 
|     GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, GameWorld.GetGameWorld().GetTick())  | 
|     return  | 
| #  | 
| def UpdateHurtInfo(curPlayer, hurtHP, isAdd=False):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|   | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     playerName = curPlayer.GetName()   | 
|   | 
|     playerHurtDict = PyGameData.g_horsePetBossPlayerHurtDict.get(lineID, {})  | 
|     if playerID not in playerHurtDict:  | 
|         if not isAdd:  | 
|             return  | 
|         playerHurtDict[playerID] = [playerName, hurtHP]  | 
|     else:  | 
|         playerHurtDict[playerID][1] += hurtHP  | 
|     PyGameData.g_horsePetBossPlayerHurtDict[lineID] = playerHurtDict  | 
|     return  | 
|   | 
| ##---¸±±¾×ÜÂß¼¼ÆÊ±Æ÷---  | 
| # @param tick:ʱ¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  | 
| def OnProcess(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)  | 
|     fbStep = gameFB.GetFBStep()  | 
|     lineID = gameWorld.GetPropertyID() - 1  | 
|     if lineID < 0:  | 
|         return  | 
|     if fbStep == FB_Step_Over:  | 
|         mapID = GameWorld.GetMap().GetMapID()  | 
|         leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID)[Def_LeaveTime] * 1000  | 
|         if tick - GameWorld.GetGameFB().GetFBStepTick() > leaveTick:  | 
|             GameWorld.Log("Ç¿ÖÆÌß³öÍæ¼Ò¹Ø±Õ¸±±¾: overTick=%s,tick=%s" % (overTick, tick))  | 
|             GameWorldProcess.CloseFB(tick)  | 
|             FBCommon.SetFBStep(FB_Step_Close, tick)  | 
|             return  | 
|       | 
|     elif fbStep == FB_Step_Fighting:  | 
|         startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)  | 
|         if not startTick or overTick:  | 
|             return  | 
|         lastHurtTick = gameFB.GetGameFBDictByKey(FBDict_LastHurtTick)  | 
|         if lastHurtTick and tick - lastHurtTick >= 2000:  | 
|             StopReduceHP(lineID, tick)  | 
|             gameFB.SetGameFBDict(FBDict_LastHurtTick, 0)  | 
|                   | 
|         FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)  | 
|         __CheckBossHP(tick)  | 
|       | 
|     return  | 
|   | 
|   | 
| def __GetSortHurtList(lineID):  | 
|     playerHurtDict = PyGameData.g_horsePetBossPlayerHurtDict.get(lineID, {})  | 
|     playerHurtList = sorted(playerHurtDict.iteritems(), key=lambda asd:asd[1][1], reverse=True)  | 
|     return playerHurtList  | 
|   | 
|   | 
| def __DoLogicHorsePetBossOver(isPass, tick, dropPosX, dropPosY):  | 
|     #½áËã  | 
|     FBCommon.SetFBStep(FB_Step_Over, tick)  | 
|       | 
|   | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     msgStr = str(lineID)  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'HorsePetBossOver', msgStr, len(msgStr))  | 
|       | 
|     leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID)[Def_LeaveTime] * 1000  | 
|     playerHurtList = __GetSortHurtList(lineID)  | 
|     if not playerHurtList:  | 
|         GameWorld.Log(' __DoLogicHorsePetBossOver£¬ É˺¦°ñÉÏûÓÐÈË£¡£¡lineID=%s'%lineID)  | 
|         return  | 
|     | 
|     event = ["HorsePetBoss", False, {}]  | 
|     batchPlayerIDList, batchAddItemList, batchParamList, batchDetailList = [], [], [], []  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     worldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)  | 
|     for rank, hurtInfo in enumerate(playerHurtList, 1):  | 
|         playerID = hurtInfo[0]  | 
|         if isPass:  | 
|             auctionItemList, itemList = __GetHorsePetBossAward(lineID, rank, worldLV)  | 
|         else:  | 
|             auctionItemList, itemList = [], []  | 
|         GameWorld.Log('auctionItemList=%s,itemList=%s'%(auctionItemList, itemList))  | 
|         giveItemList = auctionItemList+itemList  | 
|         player = playerManager.FindPlayerByID(playerID)  | 
|         if player:  | 
|             overDict = {FBCommon.Over_rank:rank}  | 
|             if auctionItemList:  | 
|                 overDict['AuctionItem'] = FBCommon.GetJsonItemList(auctionItemList)  | 
|             if itemList:  | 
|                 overDict[FBCommon.Over_itemInfo] = FBCommon.GetJsonItemList(itemList)  | 
|             if giveItemList:  | 
|                 NPCCommon.DoVirtualItemDrop(player, giveItemList, dropPosX, dropPosY)  | 
|                   | 
|                 ItemControler.GivePlayerItemOrMail(player, giveItemList, 'QCBOSS1', event)  | 
|             player.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)  | 
|             FBCommon.NotifyFBOver(player, ChConfig.Def_FBMapID_HorsePetBoss, lineID, isPass, overDict)  | 
|         elif giveItemList:  | 
|             batchPlayerIDList.append([playerID])  | 
|             batchAddItemList.append(giveItemList)  | 
|             batchParamList.append([])  | 
|             batchDetailList.append({'rank':rank, 'lineID':lineID})  | 
|     if batchPlayerIDList:  | 
|         PlayerControl.SendMailBatch("QCBOSS2", batchPlayerIDList, batchAddItemList, batchParamList, batchDetail=batchDetailList)  | 
|     return  | 
|   | 
| def __GetHorsePetBossAward(lineID, rank, worldLV):  | 
|     auctionItemList, itemList = [], []  | 
|       | 
|     ipyDataList = IpyGameDataPY.GetIpyGameDataList('HorsePetBossAward', lineID)  | 
|     if not ipyDataList:  | 
|         return auctionItemList, itemList  | 
|     awardRateList = []  | 
|     awardPieRateDict = {}  | 
|     for ipyData in ipyDataList:  | 
|         worldLVList = ipyData.GetWorldLV()  | 
|         if worldLV < worldLVList[0] or worldLV > worldLVList[1]:  | 
|             continue  | 
|         rankList = ipyData.GetRank()  | 
|         if rank < rankList[0] or rank > rankList[1]:  | 
|             continue  | 
|         awardRateList = ipyData.GetAward1()  | 
|         awardPieRateDict = ipyData.GetAward2()  | 
|     if not awardRateList and not awardPieRateDict:  | 
|         GameWorld.ErrLog('Æï³èBoss½±Àø±í Î´ÅäÖøý±Àø lineID=%s, rank=%s,worldLV=%s' % (lineID, rank, worldLV))  | 
|         return auctionItemList, itemList  | 
|     for rate, itemInfo in awardRateList:  | 
|         if not GameWorld.CanHappen(rate, 10000):  | 
|             continue  | 
|         if len(itemInfo) != 3:  | 
|             GameWorld.ErrLog('Æï³èBoss½±Àø±í ÅäÖôíÎó itemInfo=%s' % itemInfo)  | 
|             continue  | 
|         if itemInfo[2]:  | 
|             auctionItemList.append(itemInfo)  | 
|         else:  | 
|             itemList.append(itemInfo)  | 
|       | 
|     for doCnt, awardPieRateList in awardPieRateDict.items():  | 
|         for _ in xrange(doCnt):  | 
|             resultItem = GameWorld.GetResultByRandomList(awardPieRateList)  | 
|             if len(resultItem) != 3:  | 
|                 GameWorld.ErrLog('Æï³èBoss½±Àø±íÅäÖôíÎó itemInfo=%s' % resultItem)  | 
|                 continue  | 
|             if resultItem[2]:  | 
|                 auctionItemList.append(resultItem)  | 
|             else:  | 
|                 itemList.append(resultItem)  | 
|     return auctionItemList, itemList  | 
|   | 
|   | 
|   | 
| def __CheckBossHP(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     isOver = gameFB.GetGameFBDictByKey(FBDict_IsOver)  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|      | 
|     if not isOver:  | 
|         bossID = CurFBLineBOSSID(lineID)  | 
|         if GetBossRemainHP(lineID, tick) == 0:  | 
|   | 
|               | 
|             curBoss = GameWorld.FindNPCByNPCID(bossID)  | 
|             dropPosX, dropPosY = 0, 0  | 
|             if curBoss:  | 
|                 dropPosX, dropPosY = curBoss.GetPosX(), curBoss.GetPosY()  | 
|               | 
|             #½áÊø ÉèÖÃBOSSËÀÍö  | 
|             FBCommon.ClearFBNPC()  | 
|             FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)  | 
|             GameWorld.DebugLog('½áÊø ÉèÖÃBOSSËÀÍö lineID=%s' % lineID)  | 
|               | 
|             __DoLogicHorsePetBossOver(1, tick, dropPosX, dropPosY)  | 
|             gameFB.SetGameFBDict(FBDict_IsOver, tick)  | 
|         else:  | 
|             #ѪÁ¿¹ã²¥  | 
|             needNotifyHPPerList = [50, 20]  | 
|             lastIndex = gameFB.GetGameFBDictByKey(FBDict_LastHPNotify)  | 
|             if lastIndex >= len(needNotifyHPPerList):  | 
|                 return  | 
|             remainPer = GetBossRemainHPPer(lineID, tick)  | 
|             notifyHPPer = needNotifyHPPerList[lastIndex]  | 
|             if remainPer == notifyHPPer or remainPer - 1 == notifyHPPer:  | 
|                 gameFB.SetGameFBDict(FBDict_LastHPNotify, lastIndex + 1)  | 
|                 lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|                 msgMark = 'QCBOSSHP1'  | 
|                 PlayerControl.WorldNotify(0, msgMark, [bossID, notifyHPPer])  | 
|     return  | 
|   | 
| def UpdateHPReduceSpeed(tick, isExit=False):  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     playerCnt = gameWorld.GetMapCopyPlayerManager().GetPlayerCount()  | 
|     playerCnt = playerCnt - 1 if isExit else playerCnt  | 
|     if playerCnt <=0:  | 
|         return  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     if lineID < 0:  | 
|         return  | 
|   | 
|     curSpeed = eval(FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_HorsePetBoss, lineID)[Def_HPSpeed])  | 
|     gameWorld.SetGameWorldDict(FBDict_Speed % lineID, curSpeed)  | 
|     if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):  | 
|         return  | 
|       | 
|     startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)  | 
|     remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)  | 
|     lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID)  | 
|     if not startTick:  | 
|         startTick = tick   | 
|         lastSpeed = curSpeed  | 
|         remainHP = __GetBossTotalHP(lineID)  | 
|     remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))  | 
|     gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)  | 
|       | 
|     gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, remainHP)  | 
|     GameWorld.DebugLog('    curSpeed=%s, remainHP=%s, passTime=%s, lastSpeed=%s' % (curSpeed, remainHP, tick - startTick, lastSpeed))  | 
|     FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)  | 
|     return  | 
|   | 
| def StopReduceHP(lineID, tick):  | 
|     ##ÔÝÍ£BOSSѪÁ¿¼õÉÙ  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):  | 
|         return  | 
|     remainHP = GetBossRemainHP(lineID, tick)  | 
|     if not remainHP:  | 
|         return  | 
|     gameWorld.SetGameWorldDict(FBDict_IsReduceing % lineID, 0)  | 
|     gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, remainHP)  | 
|     return  | 
|   | 
| def StartReduceHP(lineID, tick):  | 
|     ##¿ªÊ¼BOSSµôѪ  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     if gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):  | 
|         return  | 
|     gameWorld.SetGameWorldDict(FBDict_IsReduceing % lineID, 1)  | 
|     startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)  | 
|     if not startTick:  | 
|         gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, __GetBossTotalHP(lineID))  | 
|     gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)  | 
|     FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)  | 
|     return  | 
|   | 
| def __GetBossTotalHP(lineID):return GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_BossTotalHP%lineID)  | 
|       | 
|   | 
| def GetBossRemainHP(lineID, tick):  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)  | 
|     lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID)   | 
|     remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)  | 
|     if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):  | 
|         return remainHP  | 
|     if not startTick:  | 
|         startTick = tick  | 
|         remainHP = __GetBossTotalHP(lineID)  | 
|     else:  | 
|         remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))  | 
|     return remainHP  | 
|   | 
| def GetBossRemainHPPer(lineID, tick):  | 
|     remainHP = GetBossRemainHP(lineID, tick)  | 
|     totalHP = __GetBossTotalHP(lineID)  | 
|     if not totalHP:  | 
|         return 100  | 
|     return remainHP * 100 / totalHP  | 
|   | 
| def CurFBLineBOSSID(lineID= -1):  | 
|     #¸Ã·ÖÏßË¢µÄBOSSID  | 
|     if lineID == -1:  | 
|         lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     refreshNPCInfo = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_HorsePetBoss, lineID)  | 
|     if not refreshNPCInfo:  | 
|         return 0  | 
|     bossID = int(refreshNPCInfo)  | 
|     return bossID  | 
|   | 
| ##Íæ¼ÒËÀÍö.  | 
| # @param curPlayer:ËÀÍöµÄÍæ¼Ò   | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| def DoPlayerDead(curPlayer):  | 
|     return  | 
|   | 
| ## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return bool  | 
| def CheckCanAttackTagObjInFB(attacker, defender):  | 
|       | 
|     return True  | 
|   | 
| ##´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param defender ·ÀÊØÕß  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks ´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼  | 
| def DoFBOnKill_Player(atkobj, defender, tick):  | 
|     return True |