hxp
2019-04-13 11e82d25c1aa5b91706689d0414fdc893ed52627
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossDemonKing.py
@@ -4,42 +4,47 @@
#
##@package GameWorldLogic.FBProcess.GameLogic_CrossDemonKing
#
# @todo:跨服妖王
# @todo:本服、跨服妖王
# @author hxp
# @date 2019-04-11
# @date 2019-04-13
# @version 1.0
#
# 详细描述: 跨服妖王
# 详细描述: 本服、跨服妖王
#
#-------------------------------------------------------------------------------
#"""Version = 2019-04-11 14:30"""
#"""Version = 2019-04-13 11:00"""
#-------------------------------------------------------------------------------
import FBCommon
import GameWorld
import ItemCommon
import IPY_GameWorld
import IpyGameDataPY
import ChConfig
import PyGameData
import NPCCommon
import ItemCommon
import PlayerFairyDomain
import GameWorldProcess
import PlayerControl
import ShareDefine
import PlayerSuccess
import PlayerActLogin
import PyGameData
import ChConfig
import ChItem
FBDict_StartTick = 'FBDict_StartTick%s' #开始时间
FBDict_Speed = 'FBDict_Speed%s' #掉血速度 /s
FBDict_RemainHP = 'FBDict_RemainHP%s' #剩余时间
FBDict_IsOver = 'FBDict_IsOver' #是否已结算, 结算时的tick
FBDict_IsReduceing = 'FBDict_IsReduceing%s' #是否掉血中
FBDict_BossTotalHP = 'FBDict_BossTotalHP%s' #BOSS血量,需要的总时间
FBDict_LastHurtTick = 'FBDict_LastHurtTick'  #上次伤害时间
g_heroHurtDict = {} #{playerID:hurt}
g_ownerInfo = {} # 归属者信息 {funcLineID:[ownerID, ownerName], }
def __SetDemonKingVisitState(curPlayer, mapID, lineID, state):
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":lineID})
    if not ipyData:
        return False
    eventID = ipyData.GetID()
    if not PlayerFairyDomain.SetFairyDomainEventState(curPlayer, eventID, state):
        return False
    return True
## 是否能够通过活动查询进入
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
    if not __SetDemonKingVisitState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visiting):
        return False
    return True
## 查询是否可以进入地图
@@ -48,45 +53,86 @@
## 开启副本
def OnOpenFB(tick):
    lineID = GetCurFBFuncLineID()
    killTime = 60
    GameWorld.GetGameWorld().SetGameWorldDict(FBDict_BossTotalHP % lineID, killTime * 1000)
    return
## 副本玩家进入点
# @return posX, posY, 随机半径(可选)
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
    return ipyEnterPosInfo
def GetCurFBLineBOSSID(lineID=-1):
    #该分线刷的BOSSID
    if lineID == -1:
        lineID = GetCurFBFuncLineID()
    if lineID == -1:
        return 0
    mapID = ChConfig.Def_FBMapID_CrossDemonKing if GameWorld.IsCrossServer() else ChConfig.Def_FBMapID_DemonKing
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":lineID})
    if not ipyData:
        return 0
    bossID = ipyData.GetBossID()
    return bossID
def GetCurFBFuncLineID():
    ## 获取本线路功能线路ID
    if GameWorld.IsCrossServer():
        return GameWorld.GetGameWorld().GetPropertyID() % 1000
    return GameWorld.GetGameWorld().GetPropertyID() - 1
def GetCurFBLineZoneID():
    ## 获取本线路所属跨服分区
    if GameWorld.IsCrossServer():
        return GameWorld.GetGameWorld().GetPropertyID() / 1000
    return 0
## 进副本
def DoEnterFB(curPlayer, tick):
    playerID = curPlayer.GetPlayerID()
    zoneID = GetCurFBLineZoneID()
    funcLineID = GetCurFBFuncLineID()
    GameWorld.DebugLog("DoEnterFB zoneID=%s,funcLineID=%s" % (zoneID, funcLineID), playerID)
    bossID = GetCurFBLineBOSSID(funcLineID)
    visitCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FairyDomainVisitCnt)
    GameWorld.Log("DoEnterFB zoneID=%s,funcLineID=%s,bossID=%s,visitCount=%s" % (zoneID, funcLineID, bossID, visitCount), playerID)
    PyGameData.g_fbPickUpItemDict.pop(playerID, 0)
    return
## 副本总逻辑计时器
def OnProcess(tick):
    gameFB = GameWorld.GetGameFB()
    overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)
    if overTick and tick - overTick >= ChConfig.Def_FBPickupItemTime:
        GameWorld.Log("强制踢出玩家关闭副本: overTick=%s,tick=%s" % (overTick, tick))
        FBCommon.DoLogic_FBKickAllPlayer()
        return
    return
## 关闭副本
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)
    funcLineID = GetCurFBFuncLineID()
    g_ownerInfo.pop(funcLineID, None)
    GameWorld.GetGameWorld().SetPropertyID(0)
    return
## 玩家退出副本
def DoExitFB(curPlayer, tick):
    UpdateHPReduceSpeed(tick, True)
    gameFB = GameWorld.GetGameFB()
    overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)
    gameWorld = GameWorld.GetGameWorld()
    #最后一人退出副本则关闭地图
    if overTick and gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:
        GameWorldProcess.CloseFB(tick)
    return
##玩家主动离开副本.
def DoPlayerLeaveFB(curPlayer, tick):
#    FBCommon.SetHadDelTicket(curPlayer, 0)
#    #主动退出的去掉排行榜信息
#    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
#    playerHurtDict = PyGameData.g_ZhuXianBossPlayerHurtDict.get(lineID, {})
#    playerHurtDict.pop(curPlayer.GetPlayerID(), 0)
#    PyGameData.g_ZhuXianBossPlayerHurtDict[lineID] = playerHurtDict
#    if not playerHurtDict: #榜上没人,停止掉血
#        StopReduceHP(lineID, tick)
    gameWorld = GameWorld.GetGameWorld()
    #最后一人退出副本则关闭地图
    if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:
        GameWorldProcess.CloseFB(tick)
    return
## 是否副本复活
@@ -95,148 +141,73 @@
## 获得副本帮助信息
def DoFBHelp(curPlayer, tick):
    if GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_IsOver):
    return
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):
    bossID = curNPC.GetNPCID()
    funcLineID = GetCurFBFuncLineID()
    if bossID != GetCurFBLineBOSSID(funcLineID):
        return
    
    lineID = GetCurFBFuncLineID()
    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, 'hpReduceSpeed':hpReduceSpeed, 'remainHPPer':remainHPPer, 'isReduceing':isReduceing}
    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
    return
## 玩家对NPC造成伤害
def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
    return
    lineID = GetCurFBFuncLineID()
    #有人上榜开始掉血
    StartReduceHP(lineID, GameWorld.GetGameWorld().GetTick())
    GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, GameWorld.GetGameWorld().GetTick())
    return
##---副本总逻辑计时器---
# @param tick:时间戳
# @return 无意义
# @remarks 副本总逻辑计时器
def OnProcess(tick):
    return
    zoneID = GetCurFBLineZoneID()
    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()
    gameFB.SetGameFBDict(FBDict_IsOver, tick)
    ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
    ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID) if ownerType == ChConfig.Def_NPCHurtTypePlayer else 0
    isCrossServer = GameWorld.IsCrossServer()
    mapID = ChConfig.Def_FBMapID_CrossDemonKing if isCrossServer else ChConfig.Def_FBMapID_DemonKing
    GameWorld.Log("击杀妖王: zoneID=%s,mapID=%s,funcLineID=%s,ownerID=%s,bossID=%s" % (zoneID, mapID, funcLineID, ownerID, bossID))
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":funcLineID})
    if not ipyData:
        return
    lineID = GetCurFBFuncLineID()
    if lineID < 0:
        return
    gameWorld = GameWorld.GetGameWorld()
    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)
        GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, 0)
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
    __CheckBossHP(tick)
    return
def __DoLogicZhuXianBossOver(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)
#    if not playerHurtList:
#        GameWorld.Log(' __DoLogicZhuXianBossOver, 伤害榜上没有人!!lineID=%s' % lineID)
#        return
#    firsthurtInfo = playerHurtList[0]
#    firstPlayerID = firsthurtInfo[0]
#    firstPlayerFamilyID = firsthurtInfo[1][2]
#    playerManager = GameWorld.GetMapCopyPlayerManager()#GameWorld.GetPlayerManager()
#    firstPlayer = playerManager.FindPlayerByID(firstPlayerID)
#    if firstPlayer:
#        gameFB.SetPlayerGameFBDict(firstPlayerID, FBPlayerDict_Rank, 1)
#        if not dropPosX or not dropPosY:
#            dropPosX, dropPosY = firstPlayer.GetPosX(), firstPlayer.GetPosY()
#        prizeItemList = GiveZhuXianBossAward(firstPlayer, lineID, dropItemMapInfo=[dropPosX, dropPosY, True, True])
#        if not prizeItemList:
#            # 没有掉落时直接通知结算,防止卡副本
#            firstPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
#            overDict = {FBCommon.Over_rank:1, FBCommon.Over_itemInfo:prizeItemList}
#            FBCommon.NotifyFBOver(firstPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, isPass, overDict)
#        else:
#            firstPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)
#    else:
#        leaveServerTick = PlayerControl.GetPlayerLeaveServerTick(firstPlayerID)
#        if leaveServerTick and tick - leaveServerTick < ChConfig.Def_PlayerOfflineProtectTime:
#            #离线超过3分钟的不给奖励
#            msgStr = str([ShareDefine.Def_UniversalGameRecType_ZhuXianBossRecord, [firstPlayerID, lineID], [], 0, 0])
#            GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'AddUniversalGameRec', msgStr, len(msgStr))
#
#    helpItemList = FBCommon.GetFBLineReward(mapID, lineID)
#    if helpItemList: #同盟协助奖励
#        jsonItemList = FBCommon.GetJsonItemList(helpItemList)
#        for index in range(0 , playerManager.GetPlayerCount()):
#            curPlayer = playerManager.GetPlayerByIndex(index)
#            curPlayerID = curPlayer.GetPlayerID()
#            if not curPlayerID:
#                continue
#            if curPlayerID == firstPlayerID:
#                continue
#            curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
#            remainCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhuXianBossHelpCnt)
#            if curPlayer.GetFamilyID() == firstPlayerFamilyID and remainCnt:
#                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ZhuXianBossHelpCnt, remainCnt - 1)
#                ItemControler.GivePlayerItemOrMail(curPlayer, helpItemList, 'ZXBossHelperReward')
#                overDict = {FBCommon.Over_rank:0, FBCommon.Over_itemInfo:jsonItemList}
#                FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, isPass, overDict)
#            else:
#                overDict = {FBCommon.Over_rank:0}
#                FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, 0, overDict)
    return
def GiveZhuXianBossAward(curPlayer, lineID, isMail=False, dropItemMapInfo=[]):
    ##给归属者奖励
    addCnt = 1
    equipList = []
    prizeItemDict = {}
    bossID = GetCurFBLineBOSSID(lineID)
    jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, {bossID:addCnt},
                                                                        mailTypeKey="ZXBossBelongerReward", isMail=isMail,
                                                                        dropItemMapInfo=dropItemMapInfo)
    for jsonItem in jsonItemList:
        if 'UserData' in jsonItem:
            equipList.append(jsonItem)
    eventID = ipyData.GetID()
    ownerName = ""
    dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()
    serverGroupIDList = []
    msgInfo = {}
    playerManager = GameWorld.GetMapCopyPlayerManager()
    for index in xrange(playerManager.GetPlayerCount()):
        curPlayer = playerManager.GetPlayerByIndex(index)
        if not curPlayer:
            continue
        playerID = curPlayer.GetPlayerID()
        isOwner = playerID == ownerID
        if isOwner:
            ownerName = curPlayer.GetPlayerName()
        giveItemList = __GetDemonKingPrizeItemList(curPlayer, mapID, funcLineID, eventID, isOwner)
        GameWorld.Log("玩家奖励: %s" % giveItemList, playerID)
        ChItem.DropItem(curPlayer, giveItemList, bossID, dropPosX, dropPosY, isOnlySelfSee=True, isDropDisperse=True)
        #curPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)
        if not isCrossServer:
            __SetDemonKingVisitState(curPlayer, mapID, funcLineID, PlayerFairyDomain.FDEventState_Visited)
        else:
            itemID, itemCnt = jsonItem['ItemID'], jsonItem.get('Count', 1)
            prizeItemDict[itemID] = prizeItemDict.get(itemID, 0) + itemCnt
            serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
            if serverGroupID not in serverGroupIDList:
                serverGroupIDList.append(serverGroupID)
            msgInfo[playerID] = [serverGroupID, mapID, funcLineID]
    g_ownerInfo[funcLineID] = [ownerID, ownerName]
    
    GameWorld.DebugLog("诛仙boss结算奖励: lineID=%s,bossID=%s,totalExp=%s,totalMoney=%s,jsonItemList=%s"
                       % (lineID, bossID, totalExp, totalMoney, jsonItemList), curPlayer.GetPlayerID())
    prizeItemList = equipList + FBCommon.GetJsonItemList(prizeItemDict.items())
    #PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_ZhuXianBoss, addCnt)
    if msgInfo:
        GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_FBEnd, msgInfo, serverGroupIDList)
    return
    #击杀特定NPC成就
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, addCnt, [bossID])
    FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, addCnt)
    # 每日活动
    #PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_ZhuXianBoss, addCnt)
    PlayerActLogin.AddLoginAwardActionCnt(curPlayer, ChConfig.Def_LoginAct_ZhuXianBOSS, addCnt)
    return prizeItemList
## 结束跨服副本
def OnEndCrossFB(curPlayer, mapID, lineID, exData):
    __SetDemonKingVisitState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visited)
    return
def OnPickUpItem(curPlayer, curItem, tick):
    mapItemType = curItem.GetType()
@@ -246,12 +217,12 @@
    isEquip = ItemCommon.CheckItemIsEquip(curItem)
    jsonItem = ItemCommon.GetJsonItem(curItem)
    if playerID in PyGameData.g_fbPickUpItemDict:
        if isEquip:
        if isEquip or jsonItem.get("IsAuctionItem"):
            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"):
                if itemInfo["ItemID"] == jsonItem["ItemID"] and itemInfo.get("IsAuctionItem") == jsonItem.get("IsAuctionItem"):
                    itemInfo["Count"] = itemInfo.get("Count", 1) + jsonItem.get("Count", 1)
                    isIn = True
                    break
@@ -276,142 +247,63 @@
        return
    
    isPass = 1
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    leaveTick = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_ZhuXianBoss, lineID) * 1000
    gameFB = GameWorld.GetGameFB()
    rank = 1###gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_Rank)
    jsonItemList = PyGameData.g_fbPickUpItemDict.get(playerID, [])
    mapID = ChConfig.Def_FBMapID_CrossDemonKing if GameWorld.IsCrossServer() else ChConfig.Def_FBMapID_DemonKing
    funcLineID = GetCurFBFuncLineID()
    leaveTick = FBCommon.GetFBLineStepTime(mapID, funcLineID) * 1000
    ownerID, ownerName = g_ownerInfo.pop(funcLineID, [0, ""])
    jsonItemList = PyGameData.g_fbPickUpItemDict.pop(playerID, [])
    overDict = {FBCommon.Over_ownerID:ownerID, FBCommon.Over_ownerName:ownerName, FBCommon.Over_itemInfo:jsonItemList}
    FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isPass, overDict)
    curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
    overDict = {FBCommon.Over_rank:rank, FBCommon.Over_itemInfo:jsonItemList}
    FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, isPass, overDict)
    return
def __CheckBossHP(tick):
    gameFB = GameWorld.GetGameFB()
    isOver = gameFB.GetGameFBDictByKey(FBDict_IsOver)
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    if not isOver and GetBossRemainHP(lineID, tick) == 0:
        bossID = GetCurFBLineBOSSID(lineID)
        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)
        ###playerHurtList = __GetSortHurtList(lineID)
        playerHurtList = []
        if playerHurtList:
            killerName, hurtValue = playerHurtList[0][1][:2]
            NPCCommon.GameServer_KillGameWorldBoss(bossID, killerName, hurtValue)
        NPCCommon.GameServe_GameWorldBossState(bossID, 0)
        ###__DoLogicZhuXianBossOver(1, tick, dropPosX, dropPosY)
        gameFB.SetGameFBDict(FBDict_IsOver, tick)
## 客户端进入自定义场景
def OnEnterCustomScene(curPlayer, mapID, lineID):
    __SetDemonKingVisitState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visiting)
    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 = int(min(1 + 0.08 * (playerCnt - 1), 1.8) * 1000)
    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 GetCurFBLineBOSSID(lineID= -1):
    #该分线刷的BOSSID
    if lineID == -1:
        lineID = GetCurFBFuncLineID()
    if lineID == -1:
        return 0
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":ChConfig.Def_FBMapID_CrossDemonKing, "LineID":lineID})
## 客户端发送刷新自定义副本奖励
def OnRefreshCustomFBPrize(curPlayer, mapID, lineID):
    visitCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FairyDomainVisitCnt)
    fakeImmortalCount = IpyGameDataPY.GetFuncCfg("FakeImmortalCount", 1)
    if visitCount > fakeImmortalCount:
        GameWorld.DebugLog("当前寻访次数不能获取自定义副本奖励!visitCount=%s" % visitCount)
        return []
    if not __SetDemonKingVisitState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visiting):
        GameWorld.DebugLog("寻访状态异常不能获取自定义副本奖励!")
        return []
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":lineID})
    if not ipyData:
        return 0
    bossID = ipyData.GetBossID()
    return bossID
        return []
    eventID = ipyData.GetID()
    isOwner = True
    giveItemList = __GetDemonKingPrizeItemList(curPlayer, mapID, lineID, eventID, isOwner)
    return giveItemList
def GetCurFBFuncLineID(): return GameWorld.GetGameWorld().GetPropertyID() % 1000
def GetCurFBLineZoneID(): return GameWorld.GetGameWorld().GetPropertyID() / 1000
##玩家死亡.
# @param curPlayer:死亡的玩家
# @param tick 时间戳
# @return 返回值无意义
# @remarks 玩家主动离开副本.
def DoPlayerDead(curPlayer):
## 给自定义副本奖励后续处理
def OnGiveCustomFBPrizeOK(curPlayer, mapID, lineID):
    __SetDemonKingVisitState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visited)
    return
##处理副本中杀死玩家逻辑
def DoFBOnKill_Player(atkobj, defender, tick):
    return True
def __GetDemonKingPrizeItemList(curPlayer, mapID, lineID, eventID, isOwner):
    giveItemList = PlayerFairyDomain.GetFairyAppointAward(curPlayer, eventID)
    if giveItemList:
        return giveItemList
    # 没有定制奖励则取常规奖励
    # {物品ID:[归属者获得个数饼图[[概率, 个数], ...], 非归属者获得个数饼图[[概率, 个数], ...], 是否拍品], ...}
    giveItemList = []
    awardDict = FBCommon.GetFBLineReward(mapID, lineID)
    for itemID, itemInfo in awardDict.items():
        ownerCountRateList, notOwnerCountRateList, isAuctionItem = itemInfo
        if isOwner:
            itemCount = GameWorld.GetResultByRandomList(ownerCountRateList)
        else:
            itemCount = GameWorld.GetResultByRandomList(notOwnerCountRateList)
        if not itemCount:
            continue
        giveItemList.append([itemID, itemCount, isAuctionItem])
    return giveItemList