#!/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 GameWorldProcess  
 | 
import IpyGameDataPY  
 | 
import ChConfig  
 | 
import PyGameData  
 | 
import PlayerControl  
 | 
import NPCCommon  
 | 
import ItemCommon  
 | 
import ChPyNetSendPack  
 | 
import ShareDefine  
 | 
import EventShell  
 | 
import NPCCustomRefresh  
 | 
import PlayerSuccess  
 | 
import PlayerActivity  
 | 
import NetPackCommon  
 | 
import PlayerVip  
 | 
import PlayerMagicWeapon  
 | 
import PlayerBossReborn  
 | 
import PlayerFairyCeremony  
 | 
import PlayerNewFairyCeremony  
 | 
import PlayerWeekParty  
 | 
import PlayerActLogin  
 | 
import EventReport  
 | 
  
 | 
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  
 | 
  
 | 
FBPlayerDict_Rank = "FBPlayerDict_Rank" # Íæ¼ÒÅÅÃû  
 | 
  
 | 
g_npcHurtDict = {}  
 | 
  
 | 
  
 | 
def OnFBPlayerOnLogin(curPlayer):  
 | 
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_FMTDouble):  
 | 
        GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_FMTDouble, 1)  
 | 
        needViplv = IpyGameDataPY.GetFuncCfg('DemonJarSpecial')  
 | 
        if curPlayer.GetVIPLv() >= needViplv:  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FMTOldDouble, 1)  
 | 
            GameWorld.DebugLog('1.3°æ±¾Ç°¿ÉÒÔË«±¶ÌôÕ½')  
 | 
    NotifyFMTDouble(curPlayer)  
 | 
    return  
 | 
  
 | 
  
 | 
## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  
 | 
#  @param curPlayer Íæ¼ÒʵÀý  
 | 
#  @param mapID µØÍ¼ID  
 | 
#  @param lineID Ïß·id  
 | 
#  @param tick Ê±¼ä´Á  
 | 
#  @return ²¼¶ûÖµ  
 | 
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  
 | 
    IsDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)  
 | 
    newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')  
 | 
    if IsDouble and lineID not in newbielineList:  
 | 
        enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)  
 | 
        maxCnt = FBCommon.GetEnterFBMaxCnt(curPlayer, mapID)  
 | 
        if enterCnt + 2 > maxCnt:  
 | 
            return False  
 | 
    return True  
 | 
  
 | 
  
 | 
##¸±±¾Íæ¼Ò½øÈëµã  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param mapID µØÍ¼ID  
 | 
# @param lineId ·ÖÏßID  
 | 
# @param ipyEnterPosInfo ¹¦ÄÜÏß·IPYÅäÖÃ×ø±êÐÅÏ¢  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return posX, posY, Ëæ»ú°ë¾¶(¿ÉÑ¡)  
 | 
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  
 | 
    return ipyEnterPosInfo  
 | 
  
 | 
### ²éѯµØÍ¼ÊÇ·ñ¿ªÆô  
 | 
##  @param 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):  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    if mapID == ChConfig.Def_FBMapID_SealDemonEx:  
 | 
        return  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    bossID = CurFBLineBOSSID(lineID)  
 | 
    key = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID  
 | 
    GameWorld.GetGameWorld().SetGameWorldDict(key, 1)  
 | 
    GameWorld.DebugLog('    Ë¢BOSSbossID=%s' % bossID)  
 | 
      
 | 
      
 | 
    refreshIDList = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_SealDemon, lineID)  
 | 
    if refreshIDList:  
 | 
        for refreshID in refreshIDList:  
 | 
            NPCCustomRefresh.SetNPCRefreshByID(refreshID)  
 | 
      
 | 
      
 | 
    return  
 | 
  
 | 
## ½ø¸±±¾  
 | 
#  @param curPlayer  
 | 
#  @param tick  
 | 
#  @return None  
 | 
def DoEnterFB(curPlayer, tick):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    if mapID == ChConfig.Def_FBMapID_SealDemonEx:  
 | 
        lineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ReqFBFuncLine)  
 | 
        FBCommon.SetFBPropertyMark(lineID)  
 | 
    else:  
 | 
        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  
 | 
    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)  
 | 
        newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')  
 | 
        if lineID not in newbielineList:  
 | 
            pass  
 | 
#            FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_SealDemon)  
 | 
#            # Ã¿Èջ  
 | 
#            PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_SealDemon)  
 | 
        else:  
 | 
            hasEnter = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [ChConfig.Def_FBMapID_SealDemon])  
 | 
            if hasEnter:  
 | 
                GameWorld.DebugLog("    ÒѽøÈë¹ý¸ÃÐÂÊÖÏß· %s" % lineID, playerID)  
 | 
                PlayerControl.PlayerLeaveFB(curPlayer)  
 | 
                return  
 | 
        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)  
 | 
      
 | 
    gameWorld.SetPropertyID(0)  
 | 
    return  
 | 
  
 | 
##Íæ¼ÒÍ˳ö¸±±¾  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
def DoExitFB(curPlayer, tick):  
 | 
    global g_npcHurtDict  
 | 
    gameWorld = GameWorld.GetGameWorld()  
 | 
    # Çå³ý¹ÄÎèbuff  
 | 
    FBCommon.ClearEncourageBuff(curPlayer, tick)  
 | 
    #×îºóÒ»ÈË  
 | 
    if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:  
 | 
        mapID = GameWorld.GetMap().GetMapID()  
 | 
        if mapID != ChConfig.Def_FBMapID_SealDemonEx:#µ¥È˵IJ»¹Ü  
 | 
            lineID = gameWorld.GetPropertyID() - 1  
 | 
            PyGameData.g_sealDemonPlayerHurtDict[lineID] = {}  
 | 
            g_npcHurtDict[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_sealDemonPlayerHurtDict.get(lineID, {})  
 | 
    playerHurtDict.pop(curPlayer.GetPlayerID(), 0)  
 | 
    PyGameData.g_sealDemonPlayerHurtDict[lineID] = playerHurtDict  
 | 
    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):  
 | 
    #É˺¦ÅÅÐÐÐÅÏ¢  
 | 
    hurtInfo = []  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    playerHurtList = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {}).items()  
 | 
    npcHurtList = g_npcHurtDict.get(lineID, {}).items()  
 | 
      
 | 
    syncHurtList = (playerHurtList + npcHurtList)[:5]  
 | 
    syncHurtList.sort(key=lambda asd:asd[1][1], reverse=True)  
 | 
          
 | 
    for i, info in enumerate(syncHurtList, 1):  
 | 
        playerName, hurt = info[1]  
 | 
        hurtDict = {}  
 | 
        hurtDict["rank"] = i  
 | 
        hurtDict["playerName"] = playerName  
 | 
        hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue  
 | 
        hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue  
 | 
        hurtInfo.append(hurtDict)  
 | 
    myRank = __GetSelfHurtRank(curPlayer)  
 | 
    if myRank and myRank > 5:  
 | 
        hurtDict = {}  
 | 
        hurtDict["rank"] = myRank  
 | 
        info = playerHurtList[myRank - 1]  
 | 
        playerName, hurt = info[1]  
 | 
        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)   
 | 
    remainHP = GetBossRemainHP(lineID, tick)  
 | 
    totalHP = __GetBossTotalHP()  
 | 
    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}  
 | 
    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())  
 | 
    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)  
 | 
    return  
 | 
  
 | 
def __GetSelfHurtRank(curPlayer):  
 | 
    #»ñÈ¡×Ô¼ºµÄÅÅÃû  
 | 
    playerName = curPlayer.GetName()  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    playerHurtList = __GetSortHurtList(lineID)  
 | 
    myRank = 0  
 | 
    for i, info in enumerate(playerHurtList):  
 | 
        if playerName == info[1][0]:  
 | 
            myRank = i + 1  
 | 
            break  
 | 
    return myRank  
 | 
  
 | 
## ¸±±¾ÐÐΪ  
 | 
#  @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)  
 | 
    return  
 | 
#  
 | 
def UpdateHurtInfo(curPlayer, hurtHP, isAdd=False):  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    if mapID == ChConfig.Def_FBMapID_SealDemonEx:  
 | 
        return  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
      
 | 
    playerName = curPlayer.GetName()   
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    playerHurtDict = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {})  
 | 
    if playerID not in playerHurtDict:  
 | 
        if not isAdd:  
 | 
            return  
 | 
        playerHurtDict[playerID] = [playerName, hurtHP]  
 | 
    else:  
 | 
        playerHurtDict[playerID][1] += hurtHP  
 | 
    PyGameData.g_sealDemonPlayerHurtDict[lineID] = playerHurtDict  
 | 
    return  
 | 
  
 | 
## Íæ¼Ò¶ÔNPCÔì³ÉÉ˺¦  
 | 
#  @param curPlayer µ±Ç°Íæ¼Ò  
 | 
#  @param curNPC   
 | 
#  @param hurtHP   
 | 
#  @return None  
 | 
def DoFB_NPC_HurtNPC(curNPC, tagNPC, hurtHP):  
 | 
    global g_npcHurtDict  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    npcID = curNPC.GetNPCID()  
 | 
    guardNPCIDList = __GetGuardNPCIDList(lineID)  
 | 
      
 | 
    if npcID not in guardNPCIDList:  
 | 
        return  
 | 
    npcHurtDict = g_npcHurtDict.get(lineID, {})  
 | 
    if npcID not in npcHurtDict:  
 | 
        npcName = curNPC.GetName().decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())  
 | 
        npcHurtDict[npcID] = [npcName, hurtHP]  
 | 
    else:  
 | 
        npcHurtDict[npcID][1] += hurtHP  
 | 
    g_npcHurtDict[lineID] = npcHurtDict  
 | 
    return  
 | 
  
 | 
def __GetGuardNPCIDList(lineID):  
 | 
    guardNPCIDList = []  
 | 
    refreshIDList = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_SealDemon, lineID)  
 | 
    if refreshIDList:  
 | 
        for refreshID in refreshIDList:  
 | 
            ipyData = IpyGameDataPY.GetIpyGameData("NPCCustomRefresh", refreshID)  
 | 
            if not ipyData:  
 | 
                continue  
 | 
            npcID = ipyData.GetRefreshNPCID()  
 | 
            guardNPCIDList.append(npcID)  
 | 
    return guardNPCIDList  
 | 
  
 | 
##---¸±±¾×ÜÂß¼¼ÆÊ±Æ÷---  
 | 
# @param tick:ʱ¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  
 | 
def OnProcess(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)  
 | 
    # ½áËã20ÃëºóÇ¿ÖÆ¹Ø±Õ¸±±¾, ·ÀÖ¹Íæ¼Ò²»¼ñ¶«Î÷µ¼Ö²»½áË㣬ǿ¹ØºóµØ°åÉϵĶ«Î÷»áÓʼþ·¢·Å¸øÍæ¼Ò  
 | 
    if overTick and tick - overTick >= ChConfig.Def_FBPickupItemTime:  
 | 
        GameWorld.Log("Ç¿ÖÆÌß³öÍæ¼Ò¹Ø±Õ¸±±¾: overTick=%s,tick=%s" % (overTick, tick))  
 | 
        FBCommon.DoLogic_FBKickAllPlayer()  
 | 
        return  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    if mapID == ChConfig.Def_FBMapID_SealDemonEx:  
 | 
        return  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    if lineID <0:  
 | 
        return  
 | 
    gameWorld = GameWorld.GetGameWorld()  
 | 
    startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)  
 | 
    if not startTick:  
 | 
        return  
 | 
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)  
 | 
    __CheckBossHP(tick)  
 | 
      
 | 
      
 | 
    return  
 | 
  
 | 
def __CheckBossHP(tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    isOver = gameFB.GetGameFBDictByKey(FBDict_IsOver)  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')  
 | 
    isNewbieLine = lineID in newbielineList  
 | 
    if not isOver and GetBossRemainHP(lineID, tick) == 0:  
 | 
        guardNPCIDList = __GetGuardNPCIDList(lineID)  
 | 
        bossID = CurFBLineBOSSID(lineID)  
 | 
        curBoss = GameWorld.FindNPCByNPCID(bossID)  
 | 
        dropPosX, dropPosY = 0, 0  
 | 
        if curBoss:  
 | 
            dropPosX, dropPosY = curBoss.GetPosX(), curBoss.GetPosY()  
 | 
          
 | 
        #½áÊø ÉèÖÃBOSSËÀÍö  
 | 
        FBCommon.ClearFBNPC(guardNPCIDList)  
 | 
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)  
 | 
        GameWorld.DebugLog('½áÊø ÉèÖÃBOSSËÀÍö lineID=%s' % lineID)  
 | 
        playerHurtList = __GetSortHurtList(lineID)  
 | 
        if not isNewbieLine:  
 | 
            if playerHurtList:  
 | 
                killerName, hurtValue = playerHurtList[0][1]  
 | 
                NPCCommon.GameServer_KillGameWorldBoss(bossID, killerName, hurtValue)  
 | 
                  
 | 
            NPCCommon.GameServe_GameWorldBossState(bossID, 0)  
 | 
              
 | 
        __DoLogicSealDemonOver(1, tick, dropPosX, dropPosY)  
 | 
        gameFB.SetGameFBDict(FBDict_IsOver, tick)  
 | 
          
 | 
    return  
 | 
  
 | 
def __GetSortHurtList(lineID):  
 | 
    playerHurtDict = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {})  
 | 
    playerHurtList = sorted(playerHurtDict.iteritems(), key=lambda asd:asd[1][1], reverse=True)  
 | 
    return playerHurtList  
 | 
  
 | 
def __DoLogicSealDemonOver(isPass, tick, dropPosX, dropPosY):  
 | 
    #½áËã  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID) * 1000  
 | 
    playerHurtList = __GetSortHurtList(lineID)  
 | 
    playerManager = GameWorld.GetPlayerManager()  
 | 
    for rank, hurtInfo in enumerate(playerHurtList, 1):  
 | 
        playerID = hurtInfo[0]  
 | 
        curPlayer = playerManager.FindPlayerByID(playerID)  
 | 
          
 | 
        if curPlayer:  
 | 
            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)  
 | 
        else:  
 | 
            leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID)  
 | 
            if not leaveTick:  
 | 
                continue  
 | 
            if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime:  
 | 
                #ÀëÏß³¬¹ý3·ÖÖӵIJ»¸ø½±Àø  
 | 
                continue  
 | 
            msgStr = str([playerID, lineID, rank])  
 | 
            GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'SealDemonOver', msgStr, len(msgStr))  
 | 
    return  
 | 
  
 | 
def GiveSealDemonAward(curPlayer, lineID, rank, isMail=False, isClientSend=False, dropItemMapInfo=[]):  
 | 
    newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')  
 | 
    isNewbieLine = lineID in newbielineList  
 | 
    prizeMultiple = 1  
 | 
    addCnt = 1  
 | 
    if isNewbieLine:  
 | 
        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 # µÚÒ»ÃûÖ´ÐÐË«±¶µôÂä½±Àø£¬ÆäËûÒ»´Î  
 | 
        isDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)  
 | 
        if isDouble:  
 | 
            addCnt = 2  
 | 
    equipList = []  
 | 
    prizeItemDict ={}  
 | 
    bossID = CurFBLineBOSSID(lineID)  
 | 
    #for _ in xrange(addCnt):  
 | 
    jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_SealDemon, {bossID:addCnt},   
 | 
                                                                        mailTypeKey="SealDemonMail", isMail=isMail, prizeMultiple=prizeMultiple,   
 | 
                                                                        dropItemMapInfo=dropItemMapInfo)  
 | 
    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 not isMail:  
 | 
    #    for itemDict in prizeItemList:  
 | 
    #        itemID = itemDict["ItemID"]  
 | 
    #        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  
 | 
    #        if not itemData:  
 | 
    #            continue  
 | 
    #        userData = itemDict.get("UserData", '')  
 | 
    #        equipInfo = [itemData.GetEquipPlace(), ItemCommon.GetItemClassLV(itemData), itemData.GetItemColor(),   
 | 
    #                 itemData.GetItemQuality(), userData]  
 | 
    #        mapID = ChConfig.Def_FBMapID_SealDemon  
 | 
    #        NPCCommon.SendGameServerGoodItemRecord(mapID, bossID, curPlayer.GetName(),   
 | 
    #                                               curPlayer.GetPlayerID(), itemID, equipInfo)  
 | 
    #===============================================================================================  
 | 
      
 | 
      
 | 
    if rank == 1:  
 | 
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FMTFirst, addCnt)  
 | 
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_SealDemon, addCnt)  
 | 
  
 | 
    #»÷É±ÌØ¶¨NPC³É¾Í  
 | 
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, addCnt, [bossID])  
 | 
  
 | 
    #ÐÂÊÖÏß·µÄ¸üнøÈ¥¼Ç¼  
 | 
    newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')  
 | 
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, 1, False, [ChConfig.Def_FBMapID_SealDemon])  
 | 
    if lineID in newbielineList:  
 | 
        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)  
 | 
      
 | 
    PlayerMagicWeapon.SetMWPrivilegeData(curPlayer, ChConfig.MWPrivilege_SealDemonAddAttr, addCnt, True)  
 | 
    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)  
 | 
    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:  
 | 
        bossID = CurFBLineBOSSID(lineID)  
 | 
        NPCCommon.GameServer_KillGameWorldBoss(bossID, curPlayer.GetName(), hurt, False)  
 | 
      
 | 
    if not prizeItemList:  
 | 
        leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID) * 1000  
 | 
        GameWorld.Log("ûÓн±Àø£¬Ö±½Ó֪ͨǰ¶Ë½áËã!mapID=%s,lineID=%s" % (mapID, lineID), curPlayer.GetPlayerID())  
 | 
        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, 1, overDict)  
 | 
        return  
 | 
      
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    gameFB.SetGameFBDict(FBDict_IsOver, tick)  
 | 
    gameFB.SetPlayerGameFBDict(curPlayer.GetPlayerID(), FBPlayerDict_Rank, rank)  
 | 
    curPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)  
 | 
    return  
 | 
  
 | 
  
 | 
def UpdateHPReduceSpeed(tick, isExit=False):  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    if mapID == ChConfig.Def_FBMapID_SealDemonEx:  
 | 
        return  
 | 
    playerCnt = GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount()  
 | 
    playerCnt = playerCnt - 1 if isExit else playerCnt  
 | 
    if playerCnt <=0:  
 | 
        return  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    if lineID < 0:  
 | 
        return  
 | 
    gameWorld = GameWorld.GetGameWorld()  
 | 
    startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)  
 | 
    lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID)  
 | 
    remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)  
 | 
    curSpeed = int(min(1 + 0.08 * (playerCnt - 1), 1.8) * 1000)  
 | 
    if not startTick:  
 | 
        startTick = tick   
 | 
        lastSpeed = curSpeed  
 | 
        remainHP = __GetBossTotalHP()  
 | 
    remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))  
 | 
    gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)  
 | 
    gameWorld.SetGameWorldDict(FBDict_Speed % lineID, curSpeed)  
 | 
    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 __GetBossTotalHP():  
 | 
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1  
 | 
    bossID = CurFBLineBOSSID(lineID)  
 | 
    ipyData = IpyGameDataPY.GetIpyGameData('SealDemon', bossID)  
 | 
    if not ipyData:  
 | 
        return 0  
 | 
    return ipyData.GetKillTime() * 1000  
 | 
  
 | 
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 startTick:  
 | 
        startTick = tick  
 | 
        remainHP = __GetBossTotalHP()  
 | 
    else:  
 | 
        remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))  
 | 
    return remainHP  
 | 
  
 | 
def GetBossRemainHPPer(lineID, tick):  
 | 
    remainHP = GetBossRemainHP(lineID, tick)  
 | 
    totalHP = __GetBossTotalHP()  
 | 
    if not totalHP:  
 | 
        return 0  
 | 
    return remainHP * 100 / totalHP  
 | 
  
 | 
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  
 | 
  
 | 
##Íæ¼ÒËÀÍö.  
 | 
# @param curPlayer:ËÀÍöµÄÍæ¼Ò   
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
def DoPlayerDead(curPlayer):  
 | 
    return  
 | 
  
 | 
  
 | 
#// B1 03 ÉèÖ÷âħ̳¶à±¶»÷ɱ #tagCMSetFMTDouble  
 | 
#  
 | 
#struct    tagCMSetFMTDouble  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    BYTE        IsDouble;        //ÊÇ·ñË«±¶  
 | 
#};  
 | 
def SetFMTDouble(playerIndex, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)  
 | 
    if GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_SealDemon:  
 | 
        return  
 | 
    if not curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTOldDouble) and not PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_FMTDouble):  
 | 
        return  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FMTDouble, clientData.IsDouble)  
 | 
    NotifyFMTDouble(curPlayer)  
 | 
    return  
 | 
  
 | 
def NotifyFMTDouble(curPlayer):  
 | 
    packData = ChPyNetSendPack.tagMCFMTDoubleState()  
 | 
    packData.IsDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)  
 | 
    packData.OldDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTOldDouble)  
 | 
    NetPackCommon.SendFakePack(curPlayer, packData)  
 | 
    return  
 | 
  
 |