| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_SealDemon  | 
| #  | 
| # @todo:·âħ̳  | 
| # @author xdh  | 
| # @date 2017-11-09  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ·âħ̳  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2017-11-09 14:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import FBCommon  | 
| import GameWorld  | 
| import IPY_GameWorld  | 
| import IpyGameDataPY  | 
| import ChConfig  | 
| import PyGameData  | 
| import PlayerControl  | 
| import NPCCommon  | 
| import ItemCommon  | 
| import ShareDefine  | 
| import EventShell  | 
| import PlayerSuccess  | 
| import PlayerActivity  | 
| import GameObj  | 
| import PlayerBossReborn  | 
| import PlayerFairyCeremony  | 
| import PlayerNewFairyCeremony  | 
| import PlayerFeastTravel  | 
| import PlayerWeekParty  | 
| import PlayerActLogin  | 
| import EventReport  | 
| import PlayerTeam  | 
| import NPCHurtManager  | 
| import GameWorldProcess  | 
| import PetControl  | 
| import AttackCommon  | 
| import PlayerGubao  | 
|   | 
| #µ±Ç°¸±±¾µØÍ¼µÄ״̬  | 
| (  | 
| FB_Step_Open, # ¸±±¾¿ªÆô  | 
| FB_Step_Fighting, # ¸±±¾½øÐÐÖÐ  | 
| FB_Step_Over, # ¸±±¾½áÊø  | 
| FB_Step_Close, # ¹Ø±Õ״̬  | 
| ) = range(4)  | 
|   | 
| FBPlayerDict_EncourageLV = 'FBPlayerDict_EncourageLV'   # ¹ÄÎèµÈ¼¶  | 
|   | 
| FBPlayerDict_Rank = "FBPlayerDict_Rank" # Íæ¼ÒÅÅÃû  | 
|   | 
| g_npcHurtDict = {}  | 
|   | 
| ## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|     return True  | 
|   | 
| ## ¸±±¾Íæ¼Ò½øÈëµã  | 
| def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  | 
|     return ipyEnterPosInfo  | 
|   | 
| ## ²éѯµØÍ¼ÊÇ·ñ¿ªÆô  | 
| #def OnCanOpen(tick):  | 
| #    return True  | 
|   | 
| ## ²éѯÊÇ·ñ¿ÉÒÔ½øÈëµØÍ¼  | 
| def OnChangeMapAsk(ask, tick):  | 
|     return IPY_GameWorld.cmeAccept  | 
|   | 
| ## ¿ªÆô¸±±¾  | 
| def OnOpenFB(tick):  | 
|     FBCommon.SetFBStep(FB_Step_Fighting, tick)  | 
|     return  | 
|   | 
| ## ½ø¸±±¾  | 
| 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)  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() != FB_Step_Fighting:  | 
|         PlayerControl.PlayerLeaveFB(curPlayer)  | 
|         return  | 
|       | 
|     hadDelTicket = FBCommon.GetHadDelTicket(curPlayer)  | 
|     if not hadDelTicket:  | 
|         FBCommon.SetHadDelTicket(curPlayer)  | 
|         PyGameData.g_fbPickUpItemDict.pop(playerID, 0)  | 
|         if playerCnt == 1:  | 
|             posX, posY = IpyGameDataPY.GetFuncEvalCfg('SealDemonFirstPos')  | 
|             GameWorld.ResetPlayerPos(curPlayer, posX, posY)  | 
|         EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_SealDemon, 0, ChConfig.CME_Log_Start)  | 
|           | 
|     # ÉϹÄÎèbuff  | 
|     encourageLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EncourageLV)  | 
|     if encourageLV > 0:  | 
|         FBCommon.AddFbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, tick)  | 
|     else:  | 
|         FBCommon.SendFBEncourageInfo(curPlayer, encourageLV)  | 
|           | 
|     return  | 
|   | 
| ## ¹Ø±Õ¸±±¾  | 
| def OnCloseFB(tick):  | 
|     #GameWorld.GetGameWorld().SetPropertyID(0)  | 
|     return  | 
|   | 
| ## Íæ¼ÒÍ˳ö¸±±¾  | 
| def DoExitFB(curPlayer, tick):  | 
|     # Çå³ý¹ÄÎèbuff  | 
|     FBCommon.ClearEncourageBuff(curPlayer, tick)  | 
|     return  | 
|   | 
| ## Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| def DoPlayerLeaveFB(curPlayer, tick):  | 
|     FBCommon.SetHadDelTicket(curPlayer, 0)  | 
|       | 
|     #×îºóÒ»ÈË  | 
|     if GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount() == 1:  | 
|         GameWorldProcess.CloseFB(tick)  | 
|           | 
|     return  | 
|   | 
| ## Íæ¼ÒÇл»µØÍ¼  | 
| def DoPlayerChangeMapLogic(curPlayer):  | 
|     FBCommon.SetHadDelTicket(curPlayer, 0)  | 
|     return  | 
|   | 
| ## ÊÇ·ñ¸±±¾¸´»î  | 
| def OnPlayerReborn():  | 
|     return True  | 
|   | 
| ## »ñµÃ¸±±¾°ïÖúÐÅÏ¢  | 
| def DoFBHelp(curPlayer, tick):  | 
|     return  | 
|   | 
| ## ¸±±¾ÐÐΪ  | 
| def DoFBAction(curPlayer, actionType, actionInfo, tick):  | 
|     if actionType == 0:  | 
|         FBCommon.FbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, actionInfo, tick)  | 
|     return  | 
|   | 
| ## ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  | 
| def OnProcess(tick):  | 
|       | 
|     fbStep = GameWorld.GetGameFB().GetFBStep()  | 
|     # ¸±±¾½áÊø  | 
|     if fbStep == FB_Step_Over:  | 
|         __DoLogic_FB_Over(tick)  | 
|           | 
|     return  | 
|   | 
| def __DoLogic_FB_Over(tick):  | 
|       | 
|     # ¼ä¸ôδµ½  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < ChConfig.Def_FBPickupItemTime:  | 
|         return  | 
|       | 
|     #¸±±¾¹Ø±Õ  | 
|     GameWorldProcess.CloseFB(tick)  | 
|     FBCommon.SetFBStep(FB_Step_Close, tick)  | 
|     return  | 
|   | 
| ## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return bool  | 
| def CheckCanAttackTagObjInFB(attacker, defender):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() != FB_Step_Fighting:  | 
|         return False  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1   | 
|     if defender.GetGameObjType() == IPY_GameWorld.gotNPC and defender.GetNPCID() == CurFBLineBOSSID(lineID):  | 
|         atkObjType = attacker.GetGameObjType()  | 
|         if atkObjType == IPY_GameWorld.gotPlayer:  | 
|             return NPCHurtManager.CheckPlayerCanAttackFBNPC(attacker, defender, ChConfig.Def_FBMapID_SealDemon, True)  | 
|           | 
|         elif atkObjType == IPY_GameWorld.gotNPC:  | 
|             if PetControl.IsPet(attacker) or attacker.GetGameNPCObjType()== IPY_GameWorld.gnotSummon:  | 
|                 ownerPlayer = AttackCommon.GetAttackPlayer(attacker)[0]  | 
|                 if not ownerPlayer:  | 
|                     return False  | 
|                 return NPCHurtManager.CheckPlayerCanAttackFBNPC(ownerPlayer, defender, ChConfig.Def_FBMapID_SealDemon)  | 
|               | 
|     return True  | 
|   | 
| def DoFB_Npc_KillNPC(attacker, curNPC, tick):  | 
|     __FBNPCOnKilled(curNPC, tick)  | 
|     return  | 
| def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  | 
|     __FBNPCOnKilled(curNPC, tick)  | 
|     return  | 
|   | 
| ## Ö´Ðи±±¾É±¹ÖÂß¼  | 
| def __FBNPCOnKilled(curNPC, tick):  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     bossID = CurFBLineBOSSID(lineID)  | 
|     if curNPC.GetNPCID() != bossID:  | 
|         return  | 
|     FBCommon.SetFBStep(FB_Step_Over, tick)  | 
|       | 
|     dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()  | 
|       | 
|     GameWorld.DebugLog('½áÊøÉèÖÃBOSSËÀÍö lineID=%s' % lineID)  | 
|       | 
|     NPCCommon.GameServe_GameWorldBossState(bossID, 0)  | 
|       | 
|     npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)  | 
|     if not npcHurtList:  | 
|         GameWorld.ErrLog("ûÓÐÉËѪÁбí!lineID=%s,bossID=%s" % (lineID, bossID))  | 
|         return  | 
|       | 
|     isPass = 1  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID) * 1000  | 
|     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for index in xrange(npcHurtList.GetHurtCount()):  | 
|         hurtObj = npcHurtList.GetHurtAt(index)  | 
|         hurtID = hurtObj.GetValueID()  | 
|         hurtType = hurtObj.GetValueType()  | 
|           | 
|         playerIDList = []  | 
|         if hurtType == ChConfig.Def_NPCHurtTypePlayer:  | 
|             playerIDList = [hurtID]  | 
|               | 
|         elif hurtType == ChConfig.Def_NPCHurtTypeTeam:  | 
|             teamID = hurtID  | 
|             mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID)  | 
|             for teamPlayerID in mapTeamPlayerIDList:  | 
|                 if not npcHurtList.IsNoAssistPlayer(teamPlayerID):  | 
|                     continue  | 
|                 playerIDList.append(teamPlayerID)  | 
|         else:  | 
|             continue  | 
|           | 
|         rank = index + 1  | 
|         if rank == 1:  | 
|             NPCCommon.GameServer_KillGameWorldBoss(bossID, hurtObj.GetHurtName(), hurtObj.GetHurtValue())  | 
|               | 
|         for playerID in playerIDList:  | 
|             curPlayer = copyMapPlayerManager.FindPlayerByID(playerID)  | 
|             if curPlayer == None:  | 
|                 continue  | 
|               | 
|             gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_Rank, rank)  | 
|             if not dropPosX or not dropPosY:  | 
|                 dropPosX, dropPosY = curPlayer.GetPosX(), curPlayer.GetPosY()  | 
|             prizeItemList = GiveSealDemonAward(curPlayer, lineID, rank, dropItemMapInfo=[dropPosX, dropPosY, True])  | 
|             if not prizeItemList:  | 
|                 # Ã»ÓеôÂäʱֱ½Ó֪ͨ½áË㣬·ÀÖ¹¿¨¸±±¾  | 
|                 curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)  | 
|                 overDict = {FBCommon.Over_rank:rank, FBCommon.Over_itemInfo:prizeItemList}  | 
|                 FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_SealDemon, lineID, isPass, overDict)  | 
|             else:  | 
|                 curPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)  | 
|                   | 
|     return  | 
|   | 
| def GiveSealDemonAward(curPlayer, lineID, rank, isMail=False, isClientSend=False, dropItemMapInfo=[]):  | 
|     newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')  | 
|     isNewbieLine = lineID in newbielineList  | 
|     sealDemonIpyData = GetSealDemonIpyData(lineID)  | 
|     if not sealDemonIpyData:  | 
|         return {}  | 
|     prizeMultiple = 1  | 
|     addCnt = 1  | 
|     if isNewbieLine:  | 
|         newbieLineStar = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [ChConfig.Def_FBMapID_SealDemon])  | 
|         # ÐÂÊÖ±¾¸ÄΪ¿ÉÖØ¸´½øÈë  | 
| #        hasEnter = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [ChConfig.Def_FBMapID_SealDemon])  | 
| #        if hasEnter:  | 
| #            #ÒѸø¹ý  | 
| #            return {}  | 
|     elif isClientSend:  | 
|         return {}  | 
|     else:  | 
|         #prizeMultiple = 2 if rank == 1 else 1 # µÚÒ»ÃûÖ´ÐÐË«±¶µôÂä½±Àø£¬ÆäËûÒ»´Î  | 
|         prizeMultiple = 1 # È¥³ýµÚÒ»ÃûË«±¶Âß¼£¬¸ÄΪ·ÅÔÚ¶îÍâ½±Àø²ú³ö  | 
|           | 
|     equipList = []  | 
|     prizeItemDict = {}  | 
|     bossID = CurFBLineBOSSID(lineID)  | 
|     extraItemList = sealDemonIpyData.GetOwnerAwardItemEx() * addCnt if rank == 1 else []  | 
|     jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_SealDemon, {bossID:addCnt},  | 
|                                                                         mailTypeKey="SealDemonMail", isMail=isMail, extraItemList=extraItemList, prizeMultiple=prizeMultiple,  | 
|                                                                         dropItemMapInfo=dropItemMapInfo, isVirtualDrop=isClientSend)  | 
|     for jsonItem in jsonItemList:  | 
|         if 'UserData' in jsonItem:  | 
|             equipList.append(jsonItem)  | 
|         else:  | 
|             itemID, itemCnt = jsonItem['ItemID'], jsonItem.get('Count', 1)  | 
|             prizeItemDict[itemID] = prizeItemDict.get(itemID, 0) + itemCnt  | 
|       | 
|     GameWorld.DebugLog("·âħ̳½áËã½±Àø: lineID=%s,bossID=%s,rank=%s,totalExp=%s,totalMoney=%s,jsonItemList=%s"   | 
|                        % (lineID, bossID, rank, totalExp, totalMoney, jsonItemList), curPlayer.GetPlayerID())  | 
|       | 
|     prizeItemList = equipList + FBCommon.GetJsonItemList(prizeItemDict.items())  | 
|       | 
|     if rank == 1:  | 
|         PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FMTFirst, addCnt)  | 
|     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_SealDemon, addCnt)  | 
|     PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillSealDemonBoss, addCnt)  | 
|       | 
|     #»÷É±ÌØ¶¨NPC³É¾Í  | 
|     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, addCnt, [bossID])  | 
|   | 
|     #ÐÂÊÖÏß·µÄ¸üнøÈ¥¼Ç¼  | 
|     GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, 1, False, [ChConfig.Def_FBMapID_SealDemon])  | 
|     if isNewbieLine:  | 
|         # Î´¹ý¹Ø²»¿Û´ÎÊý  | 
|         if newbieLineStar:  | 
|             FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_SealDemon, addCnt)  | 
|         else:  | 
|             FBCommon.Sync_FBPlayerFBInfoData(curPlayer, ChConfig.Def_FBMapID_SealDemon) # Í¬²½ÐÅÏ¢  | 
|     else:  | 
|         FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_SealDemon, addCnt)  | 
|           | 
|     # Ã¿Èջ  | 
|     PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_SealDemon, addCnt)  | 
|     EventShell.EventRespons_FBEvent(curPlayer, "sealdemon_%s" % (lineID + 1))  | 
|     EventShell.EventRespons_FBEvent(curPlayer, "sealdemon_0")  | 
|     #ÈÎÎñ  | 
|     if rank == 1 and lineID >= 4:  | 
|         EventShell.EventRespons_SealDemon(curPlayer)  | 
|       | 
|     PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_FMT, addCnt)  | 
|     PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_FMT, addCnt)  | 
|     PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_FMT, addCnt)  | 
|     PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_FMT, addCnt)  | 
|     PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_FMT, addCnt)  | 
|     PlayerActLogin.AddLoginAwardActionCnt(curPlayer, ChConfig.Def_LoginAct_FMT, addCnt)  | 
|     return prizeItemList  | 
|   | 
| def OnPickUpItem(curPlayer, curItem, tick):  | 
|     mapItemType = curItem.GetType()  | 
|     if mapItemType == ChConfig.Def_ItemType_Money:  | 
|         return  | 
|     playerID = curPlayer.GetID()  | 
|     isEquip = ItemCommon.CheckItemIsEquip(curItem)  | 
|     jsonItem = ItemCommon.GetJsonItem(curItem)  | 
|     if playerID in PyGameData.g_fbPickUpItemDict:  | 
|         if isEquip:  | 
|             PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)  | 
|         else:  | 
|             isIn = False  | 
|             for itemInfo in PyGameData.g_fbPickUpItemDict[playerID]:  | 
|                 if itemInfo["ItemID"] == jsonItem["ItemID"] and itemInfo.get("IsBind") == jsonItem.get("IsBind"):  | 
|                     itemInfo["Count"] = itemInfo.get("Count", 1) + jsonItem.get("Count", 1)  | 
|                     isIn = True  | 
|                     break  | 
|             if not isIn:  | 
|                 PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)  | 
|     else:  | 
|         PyGameData.g_fbPickUpItemDict[playerID] = [jsonItem]  | 
|       | 
|     playerItemCount = 0  | 
|     mapItemManager = GameWorld.GetMapItemManager()  | 
|     for index in xrange(mapItemManager.GetMapItemCount()):  | 
|         mapItem = mapItemManager.GetMapItemByIndex(index)  | 
|         if not mapItem or mapItem.IsEmpty():  | 
|             continue  | 
|           | 
|         # »¹ÓÐÊôÓÚ×Ô¼ºµÄ¶«Î÷û¼ñ²»Í¨Öª½áÊø  | 
|         if mapItem.GetOwnerID() == curPlayer.GetPlayerID():  | 
|             playerItemCount += 1  | 
|           | 
|     isItemAllPickUp = (playerItemCount <= 1)  | 
|     if not isItemAllPickUp:  | 
|         return  | 
|       | 
|     isPass = 1  | 
|     lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     leaveTick = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_SealDemon, lineID) * 1000  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     rank = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_Rank)  | 
|       | 
|     jsonItemList = PyGameData.g_fbPickUpItemDict.get(playerID, [])  | 
|     curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)  | 
|     overDict = {FBCommon.Over_rank:rank, FBCommon.Over_itemInfo:jsonItemList}  | 
|     FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_SealDemon, lineID, isPass, overDict)  | 
|     return  | 
|   | 
| def OnClientEndFB(curPlayer, mapID, lineID, dataList):  | 
|     #¿Í»§¶Ë¸±±¾·¢ËͽáÊø  | 
|     GameWorld.DebugLog('·âħ̳ ¿Í»§¶Ë¸±±¾·¢ËͽáÊømapID=%s,lineID=%s,dataList=%s' % (mapID, lineID, dataList), curPlayer.GetPlayerID())  | 
|     rank, hurt = dataList[:2]  | 
|     prizeItemList = GiveSealDemonAward(curPlayer, lineID, rank, False, True, [curPlayer.GetPosX(), curPlayer.GetPosY(), True])  | 
|     if rank == 1 and prizeItemList:  | 
|         bossID = CurFBLineBOSSID(lineID)  | 
|         NPCCommon.GameServer_KillGameWorldBoss(bossID, curPlayer.GetName(), hurt, False)  | 
|   | 
|     #GameWorld.Log("֪ͨǰ¶Ë½áËã!mapID=%s,lineID=%s" % (mapID, lineID), curPlayer.GetPlayerID())  | 
|     overDict = {FBCommon.Over_rank:rank, FBCommon.Over_itemInfo:prizeItemList}  | 
|     FBCommon.NotifyFBOver(curPlayer, mapID, lineID, 1, overDict)  | 
|     PlayerControl.SetCustomMap(curPlayer, 0, 0)  | 
|     return  | 
|       | 
|   | 
| def GetBossRemainHPPer(copyMapID, funcLineID, tick):  | 
|     bossID = CurFBLineBOSSID(funcLineID)  | 
|     curBoss = GameWorld.FindNPCByNPCIDEx(copyMapID, bossID)  | 
|     if not curBoss:  | 
|         return 100  | 
|     return GameObj.GetHP(curBoss) * 100 / GameObj.GetMaxHP(curBoss)  | 
|       | 
|   | 
| def CurFBLineBOSSID(lineID= -1):  | 
|     #¸Ã·ÖÏßË¢µÄBOSSID  | 
|     if lineID == -1:  | 
|         lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     if lineID == -1:  | 
|         return 0  | 
|     ipyData = IpyGameDataPY.GetIpyGameDataByCondition('SealDemon', {'LineID':lineID})  | 
|     if not ipyData:  | 
|         return 0  | 
|     bossID = ipyData.GetNPCID()  | 
|     return bossID  | 
|   | 
| def GetSealDemonIpyData(lineID= -1):  | 
|     #¸Ã·ÖÏßË¢µÄBOSSID  | 
|     if lineID == -1:  | 
|         lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|     if lineID == -1:  | 
|         return  | 
|     return IpyGameDataPY.GetIpyGameDataByCondition('SealDemon', {'LineID':lineID})  | 
|   | 
| ##Íæ¼ÒËÀÍö.  | 
| # @param curPlayer:ËÀÍöµÄÍæ¼Ò   | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| def DoPlayerDead(curPlayer):  | 
|     return  | 
|   | 
| #// B1 03 ÉèÖ÷âħ̳¶à±¶»÷ɱ #tagCMSetFMTDouble  | 
| #  | 
| #struct    tagCMSetFMTDouble  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        IsDouble;        //ÊÇ·ñË«±¶  | 
| #};  | 
| def SetFMTDouble(playerIndex, clientData, tick):  | 
|     return  | 
|   |