hxp
2019-04-13 11e82d25c1aa5b91706689d0414fdc893ed52627
6459 【后端】【2.0】缥缈仙域开发单(妖王初版)
26个文件已修改
832 ■■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossDemonKing.py 500 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_ClientServerReceiveMsg.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPutInItem.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -679,11 +679,13 @@
Def_FBMapID_CrossPenglai = 32020
#跨服妖王
Def_FBMapID_CrossDemonKing = 32030
#本服妖王
Def_FBMapID_DemonKing = 22030
#骑宠Boss
Def_FBMapID_HorsePetBoss = 31200
#需要刷世界BOSS的副本
WorldBossFBMapIDList = [Def_FBMapID_SealDemon, Def_FBMapID_ZhuXianBoss]
WorldBossFBMapIDList = [Def_FBMapID_SealDemon, Def_FBMapID_ZhuXianBoss, Def_FBMapID_DemonKing]
#跨服地图
Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonKing]
#跨服分区类型配置, 没配置的默认 CrossZoneComm
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -254,7 +254,7 @@
            PlayerFB.CrossServerMsg_EnterFBRet(msgData, tick)
            
        # 需要发送到地图服务器处理的
        elif msgType in [ShareDefine.CrossServerMsg_RebornRet, ShareDefine.CrossServerMsg_CollectNPCOK]:
        elif msgType in [ShareDefine.CrossServerMsg_RebornRet, ShareDefine.CrossServerMsg_CollectNPCOK, ShareDefine.CrossServerMsg_FBEnd]:
            MapServer_ClientServerReceiveMsg(msgType, msgData)
            
        elif msgType == ShareDefine.CrossServerMsg_CrossServerState:
@@ -273,6 +273,22 @@
def MapServer_ClientServerReceiveMsg(msgType, msgData):
    ## 收到跨服服务器信息,需要发送到地图服务器处理
    
    if msgType in [ShareDefine.CrossServerMsg_FBEnd]:
        curServerGroupID = GameWorld.GetServerGroupID()
        for tagPlayerID, msgInfo in msgData.items():
            if not msgInfo:
                continue
            serverGroupID = msgInfo[0]
            if curServerGroupID != serverGroupID:
                continue
            tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID)
            if not tagPlayer:
                continue
            msgInfo = str([msgType, msgInfo[1:]])
            tagPlayer.MapServer_QueryPlayerResult(0, 0, "ClientServerReceiveMsg", msgInfo, len(msgInfo))
        return
    if not isinstance(msgData, dict):
        return
    tagPlayerID = msgData.get("PlayerID")
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
@@ -482,9 +482,8 @@
        isAlive = __GetIsAlive(bossID)
        if not isAlive:
            continue
        mapID = ipyData.GetMapID()
        if mapID not in ChConfig.WorldBossFBMapIDList:
            GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)
        #if mapID not in ChConfig.WorldBossFBMapIDList:
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)
    return
## 玩家登录通知
ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
@@ -386,7 +386,7 @@
    # 离线的话直接发邮件
    GameWorld.Log("收到跨服获得物品,玩家不在线,直接发邮件! itemInfo=%s" % str(itemInfo), playerID)
    itemID, itemCount, isBind, itemUserData = itemData
    addItemList = [{"ItemID":itemID, "Count":itemCount, "IsBind":isBind, "UserData":itemUserData}]
    addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":isBind, "UserData":itemUserData}]
    PlayerCompensation.SendMailByKey("", [playerID], addItemList, detail={"CrossPutInItem":1, "Event":event})
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -117,8 +117,11 @@
        mapPosInfo = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 2)
    else:
        return
    posX, posY = mapPosInfo
    posX, posY = mapPosInfo[:2]
    dist = mapPosInfo[2] if len(mapPosInfo) > 2 else 0
    if dist > 0:
        posX, posY = random.randint(posX - dist, posX + dist), random.randint(posY - dist, posY + dist)
    for playerID in playerIDList:
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
        if not curPlayer:
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1199,6 +1199,7 @@
CrossServerMsg_NPCInfoRet = "NPCInfoRet"                # 跨服地图NPC信息
CrossServerMsg_CollectNPCOK = "CollectNPCOK"            # 采集NPC完成
CrossServerMsg_EnterFBRet = "EnterFBRet"                # 请求进入跨服副本返回信息
CrossServerMsg_FBEnd = "FBEnd"                          # 完成跨服副本
# 子服发送跨服信息定义
ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -315,7 +315,7 @@
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 8
RegisterPackCount = 10
PacketCMD_1=0xA5
PacketSubCMD_1=0x08
@@ -349,13 +349,21 @@
PacketSubCMD_8=0x04
PacketCallFunc_8=OnClientStartFB
PacketCMD_9=0xB1
PacketSubCMD_9=0x08
PacketCallFunc_9=OnRefreshCustomFBPrize
PacketCMD_10=0xB1
PacketSubCMD_10=0x09
PacketCallFunc_10=OnGiveCustomFBPrize
;玩家相关
[ChPlayer]
ScriptName = Player\ChPlayer.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 21
RegisterPackCount = 22
PacketCMD_1 = 0xA5
PacketSubCMD_1 = 0x04
@@ -441,6 +449,10 @@
PacketSubCMD_21=0x06
PacketCallFunc_21=OnAddPoint
PacketCMD_22=0xA2
PacketSubCMD_22=0x33
PacketCallFunc_22=OnClientExitCustomScene
;购买相关的
[BuySomething]
ScriptName = Event\EventSrc\Operate_PlayerBuyZhenQi.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
@@ -114,8 +114,8 @@
            return
        
        if curPlayer != None:
            FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
            NPCCommon.OnPlayerAttackNPCDie(curTagNPC, curPlayer, skill)
            FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
            
        curTagNormalNPCControl = NPCCommon.NPCControl(curTagNPC)
        curTagNormalNPCControl.SetKilled()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
@@ -113,8 +113,8 @@
        if not ChNPC.OnCheckCanDie(curPlayer, curTagNormalNPC, skill, tick):
            return
        #执行击杀NPC逻辑
        FBLogic.DoFB_Player_KillNPC(curPlayer , curTagNormalNPC , tick)
        NPCCommon.OnPlayerAttackNPCDie(curTagNormalNPC, curPlayer, skill)
        FBLogic.DoFB_Player_KillNPC(curPlayer , curTagNormalNPC , tick)
        #NPC死亡
        curTagNormalNPCControl = NPCCommon.NPCControl(curTagNormalNPC)
        curTagNormalNPCControl.SetKilled()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
@@ -148,8 +148,8 @@
    
    #2011-05-12 chenxuewei 有没主人都只要通知一次即可,避免重复通知
    if curPlayer != None:
        FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
        NPCCommon.OnPlayerAttackNPCDie(curTagNPC, curPlayer, skill)
        FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
    else:
        #副本
        FBLogic.DoFB_Npc_KillNPC(curSummonNPC, curTagNPC, tick)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1776,6 +1776,8 @@
Def_FBMapID_CrossPenglai = 32020
#跨服妖王
Def_FBMapID_CrossDemonKing = 32030
#本服妖王
Def_FBMapID_DemonKing = 22030
#多仙盟Boss
Def_FBMapID_AllFamilyBoss = 31260
#骑宠Boss
@@ -1796,7 +1798,8 @@
#副本关闭时未拾取的物品邮件发放给玩家
#这里只有需要的副本才配置,不做默认逻辑,防止某些副本实际不能给导致刷物品,如麒麟之府
Def_SendUnPickItemMailMapIDList = [Def_FBMapID_IceLode, Def_FBMapID_PersonalBoss, Def_FBMapID_MunekadoTrial, 
                                   Def_FBMapID_SealDemon, Def_FBMapID_SealDemonEx, Def_FBMapID_ZhuXianBoss]
                                   Def_FBMapID_SealDemon, Def_FBMapID_SealDemonEx, Def_FBMapID_ZhuXianBoss,
                                   Def_FBMapID_DemonKing, Def_FBMapID_CrossDemonKing]
#金钱不掉物品直接给玩家的地图
Def_GiveMoneyMapIDList = []
@@ -1810,7 +1813,8 @@
Def_MapID_LineIDToPropertyID = [Def_FBMapID_ElderBattlefield]
                      
# 进入副本需要发送到GameServer的地图
Def_MapID_SendToGameServer = [Def_FBMapID_HorsePetBoss, Def_FBMapID_FamilyInvade, Def_FBMapID_FamilyBossMap, Def_FBMapID_SealDemon, Def_FBMapID_FamilyWar, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss] + Def_MapID_LineIDToPropertyID
Def_MapID_SendToGameServer = [Def_FBMapID_HorsePetBoss, Def_FBMapID_FamilyInvade, Def_FBMapID_FamilyBossMap, Def_FBMapID_SealDemon, Def_FBMapID_DemonKing,
                              Def_FBMapID_FamilyWar, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss] + Def_MapID_LineIDToPropertyID
## 进入副本需要根据请求的功能线路处理的地图, hxp-改了进入模式,暂不需要了 180320
#Def_MapID_ReqFBFuncLine = [Def_FBMapID_KirinHome, Def_FBMapID_BZZD, Def_FBMapID_SealDemonEx,
@@ -1880,7 +1884,7 @@
                'SealDemon':[Def_FBMapID_SealDemon, Def_FBMapID_SealDemonEx], #封魔坛
                'XMZZ':[Def_FBMapID_XMZZ], #仙魔之争
                'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
                'CrossDemonKing':[Def_FBMapID_CrossDemonKing], #跨服妖王
                'CrossDemonKing':[Def_FBMapID_DemonKing, Def_FBMapID_CrossDemonKing], #妖王
                'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
                'ZhuXianBoss':[Def_FBMapID_ZhuXianBoss],#诛仙BOSS
                'ZhuXianTower':[Def_FBMapID_ZhuXianTower],#诛仙塔
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -2143,6 +2143,51 @@
    
    return callFunc(curPlayer, tick)
## 客户端进入自定义场景
def OnEnterCustomScene(curPlayer, mapID, lineID):
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnEnterCustomScene"))
    if callFunc == None:
        return
    return callFunc(curPlayer, mapID, lineID)
## 客户端发送刷新自定义副本奖励
def OnRefreshCustomFBPrize(curPlayer, mapID, lineID):
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnRefreshCustomFBPrize"))
    if callFunc == None:
        return []
    return callFunc(curPlayer, mapID, lineID)
## 给自定义副本奖励后续处理
def OnGiveCustomFBPrizeOK(curPlayer, mapID, lineID):
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnGiveCustomFBPrizeOK"))
    if callFunc == None:
        return
    return callFunc(curPlayer, mapID, lineID)
## 结束跨服副本
def OnEndCrossFB(curPlayer, mapID, lineID, exData):
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnEndCrossFB"))
    if callFunc == None:
        return
    return callFunc(curPlayer, mapID, lineID, exData)
def OnPlayerLVUp(curPlayer):
    ## 玩家升级
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
@@ -96,6 +96,8 @@
Over_leaderID = 'leaderID' #渡劫玩家ID
Over_xianyuanCoin = 'xianyuanCoin' #获得仙缘币信息 [获得仙缘币数, 没有获得的原因] 原因: 1-达到助战次数上限,2-达到每日获得仙缘币上限
Over_helpPlayer = 'helpPlayer' #助战玩家信息 {"玩家ID":{玩家信息key:value, ...}, ...}
Over_ownerID = 'ownerID' #归属玩家ID
Over_ownerName = 'ownerName' #归属玩家名
#副本行为
(
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
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -1780,6 +1780,53 @@
    return
#---------------------------------------------------------------------
def DropItem(curPlayer, itemList, npcID, dropPosX, dropPosY, isOnlySelfSee=True, isDropDisperse=True):
    if not itemList:
        return
    if isDropDisperse:
        dropItemList = []
        for itemInfo in itemList:
            if isinstance(itemInfo, list):
                itemID, itemCount, isAuctionItem = itemInfo
                # 拍品不拆
                if isAuctionItem:
                    dropItemList.append(itemInfo)
                    continue
                for _ in xrange(itemCount):
                    dropItemList.append([itemID, 1, isAuctionItem])
            else:
                dropItemList.append(itemInfo)
    else:
        dropItemList = itemList
    index = 0
    playerID = curPlayer.GetPlayerID()
    gameMap = GameWorld.GetMap()
    for posX, posY in ChConfig.Def_DropItemAreaMatrix:
        resultX = dropPosX + posX
        resultY = dropPosY + posY
        if not gameMap.CanMove(resultX, resultY):
            #玩家不可移动这个点
            continue
        if index > len(dropItemList) - 1:
            break
        curItem = dropItemList[index]
        index += 1
        if isinstance(curItem, list):
            itemID, itemCount, isAuctionItem = curItem
            curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer)
        if not curItem:
            continue
        AddMapDropItem(resultX, resultY, curItem, ownerInfo=[ChConfig.Def_NPCHurtTypePlayer, playerID],
                       dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee)
    return
## 在地上添加物品(统一接口)
#  @param itemPosX 位置x
#  @param itemPosY 位置y
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -2559,13 +2559,16 @@
def GivePlayerItemOrMail(curPlayer, itemList, mailKey=None, event=["", False, {}]):
    ##给物品,背包满则发邮件
    needPackSpaceDict = {}
    for itemID, itemCnt, isAuctionItem in itemList:
    for itemInfo in itemList:
        itemID, itemCount, isAuctionItem, userData = GetItemInfo(itemInfo)
        if not itemID:
            continue
        curItem = GameWorld.GetGameData().GetItemByTypeID(itemID)
        if not curItem:
            GameWorld.ErrLog('GivePlayerItemOrMail 物品ID不存在 itemID=%s'%itemID, curPlayer.GetID())
            return
        packType = ChConfig.GetItemPackType(curItem.GetType())
        needSpace = GetItemNeedPackCount(packType, curItem, itemCnt, isAuctionItem)
        needSpace = GetItemNeedPackCount(packType, curItem, itemCount, isAuctionItem)
        needPackSpaceDict[packType] = needPackSpaceDict.get(packType, 0) + needSpace
    isSendMail = False
    for packType, needSpace in needPackSpaceDict.items():
@@ -2576,7 +2579,37 @@
    if isSendMail:
        PlayerControl.SendMailByKey(mailKey, [curPlayer.GetPlayerID()], itemList)
        GameWorld.DebugLog("GivePlayerItemOrMail背包空间不够,发送邮件: mailItemList=%s" % str(itemList), curPlayer.GetPlayerID())
    else:
        for itemID, itemCnt, isAuctionItem in itemList:
            GivePlayerItem(curPlayer, itemID, itemCnt, isAuctionItem, [IPY_GameWorld.rptItem], event=event)
        return
    playerItemControl = PlayerItemControler(curPlayer)
    for itemInfo in itemList:
        itemID, itemCount, isAuctionItem, userData = GetItemInfo(itemInfo)
        if not itemID:
            continue
        if GetAppointItemRealID(itemID):
            curCreateItem = GetItemByData(GetAppointItemDictData(itemID, isAuctionItem))
        else:
            curCreateItem = ItemCommon.CreateSingleItem(itemID, itemCount, isAuctionItem)
        if not curCreateItem:
            continue
        if userData:
            curCreateItem.SetUserData(userData, len(userData))
        ItemCommon.MakeEquipGS(curCreateItem)
        #放入玩家背包
        playerItemControl.PutInItem(IPY_GameWorld.rptItem, curCreateItem, event=event)
    return
def GetItemInfo(itemInfo):
    if isinstance(itemInfo, dict):
        itemID = itemInfo['ItemID']
        itemCount = itemInfo['Count']
        isAuctionItem = itemInfo['IsAuctionItem']
        userData = itemInfo['UserData']
    elif isinstance(itemInfo, list) and len(itemInfo) == 3:
        itemID, itemCount, isAuctionItem = itemInfo
        userData = ""
    else:
        return 0, 0, 0, ""
    return itemID, itemCount, isAuctionItem, userData
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -50,6 +50,7 @@
import PlayerBossReborn
import PlayerFairyCeremony
import PlayerNewFairyCeremony
import GameLogic_CrossDemonKing
import PlayerWeekParty
import PlayerActLogin
import FamilyRobBoss
@@ -2020,6 +2021,9 @@
            if not zoneIpyData:
                return
            zoneID = zoneIpyData.GetZoneID()
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0)
        elif dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
            zoneID = GameLogic_CrossDemonKing.GetCurFBLineZoneID()
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0)
        else:
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 0)
@@ -4101,10 +4105,10 @@
        mapID = GameWorld.GetMap().GetMapID()
        mapID = FBCommon.GetRecordMapID(mapID)
        isGameBoss = ChConfig.IsGameBoss(curNPC)
        if mapID in [ChConfig.Def_FBMapID_MunekadoTrial, ChConfig.Def_FBMapID_DemonKing]:
            return
        if isGameBoss:
            GameWorld.Log("NPC开始掉落: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID())
        if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
            return
        ipyDrop = GetNPCDropIpyData(npcID)
        if not ipyDrop:
            if isGameBoss:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
@@ -337,6 +337,9 @@
    if mapID == ChConfig.Def_FBMapID_SealDemon:
        bossID = GameLogic_SealDemon.CurFBLineBOSSID()
        stoneNPCID = 0
    elif mapID == ChConfig.Def_FBMapID_DemonKing:
        bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID()
        stoneNPCID = 0
    elif mapID == ChConfig.Def_FBMapID_ZhuXianBoss:
        bossID = GameLogic_ZhuXianBoss.CurFBLineBOSSID()
        stoneNPCID = 0
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -230,13 +230,26 @@
#struct    tagCMClientStartCustomScene
#{
#    tagHead        Head;
#    DWORD        MapID;
#    WORD        FuncLineID;
#};
def OnClientStartCustomScene(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    DoEnterCustomScene(curPlayer)
    DoEnterCustomScene(curPlayer, clientData.MapID, clientData.FuncLineID)
    return
def DoEnterCustomScene(curPlayer):
#// A2 33 前端退出自定义场景 #tagCMClientExitCustomScene
#
#struct    tagCMClientExitCustomScene
#{
#    tagHead        Head;
#};
def OnClientExitCustomScene(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    DoExitCustomScene(curPlayer)
    return
def DoEnterCustomScene(curPlayer, mapID, lineID):
    ## 进入自定义场景状态
    curPlayer.SetCanAttack(False)
    curPlayer.SetVisible(False)
@@ -247,6 +260,8 @@
        
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomScene, 1)
    GameWorld.Log("玩家开始自定义场景!", curPlayer.GetPlayerID())
    if mapID:
        FBLogic.OnEnterCustomScene(curPlayer, mapID, lineID)
    return
def DoExitCustomScene(curPlayer):
@@ -474,7 +489,8 @@
        # 离线过久恢复为非跨服状态
        if PlayerControl.GetCrossMapID(curPlayer):
            PlayerControl.SetCrossMapID(curPlayer, 0)
        PyGameData.g_customFBPrizeInfo.pop(curPlayer.GetPlayerID(), None)
    SyncGuideState(curPlayer)
    
    #上线检查一次装备属性
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -1617,6 +1617,15 @@
        NotifyCode(curPlayer, "SingleEnterPK", [mapID])
        return
    
    tick = GameWorld.GetGameWorld().GetTick()
    for mapIDList in ChConfig.Def_FB_MapID.values():
        if mapID not in mapIDList:
            continue
        if not FBLogic.OnEnterFBEvent(curPlayer, mapID, lineID, tick):
            NotifyCode(curPlayer, "SingleEnterDefaul")
            return
        break
    # 需要动态分布线路的地图,发送到跨服服务器进行分配
    if mapID in ChConfig.Def_CrossDynamicLineMap:
        extendInfo = {}
@@ -1728,6 +1737,9 @@
            if enterCnt >= FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss):
                if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhuXianBossHelpCnt):
                    extendParamList = [bossID, curPlayer.GetFamilyID()]
        elif mapID == ChConfig.Def_FBMapID_DemonKing:
            bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID(lineID)
            extendParamList = [bossID]
            
        SendToGameServerEnterFB(curPlayer, mapID, lineID, tick, extendParamList)
        return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
@@ -38,6 +38,8 @@
import ShareDefine
import GameFuncComm
import FBHelpBattle
import ItemControler
import PyGameData
import time
import math
@@ -448,4 +450,64 @@
    return
#// B1 08 刷新自定义副本奖励 #tagCMRefreshCustomFBPrize
#
#struct    tagCMRefreshCustomFBPrize
#{
#    tagHead         Head;
#    DWORD        MapID;
#    WORD        FuncLineID;
#};
def OnRefreshCustomFBPrize(playerIndex, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
    playerID = curPlayer.GetPlayerID()
    mapID = clientData.MapID
    funcLineID = clientData.FuncLineID
    prizeItemList = FBLogic.OnRefreshCustomFBPrize(curPlayer, mapID, funcLineID)
    if not prizeItemList:
        return
    PyGameData.g_customFBPrizeInfo[playerID] = [mapID, funcLineID, prizeItemList]
    prizePack = ChPyNetSendPack.tagMCCuntomFBPrizeInfo()
    prizePack.MapID = mapID
    prizePack.FuncLineID = funcLineID
    prizePack.PrizeItemList = []
    for prizeItemInfo in prizeItemList:
        itemID, itemCount, isAuctionItem, userData = ItemControler.GetItemInfo(prizeItemInfo)
        if not itemID:
            continue
        prizeItem = ChPyNetSendPack.tagMCCuntomFBPrizeItem()
        prizeItem.ItemID = itemID
        prizeItem.Count = itemCount
        prizeItem.IsAuctionItem = isAuctionItem
        prizeItem.UserData = userData
        prizeItem.UserDataLen = len(prizeItem.UserData)
        prizePack.PrizeItemList.append(prizeItem)
    prizePack.PrizeItemCount = len(prizePack.PrizeItemList)
    NetPackCommon.SendFakePack(curPlayer, prizePack)
    return
#// B1 09 结算自定义副本奖励 #tagCMGiveCustomFBPrize
#
#struct    tagCMGiveCustomFBPrize
#{
#    tagHead         Head;
#    DWORD        MapID;
#    WORD        FuncLineID;
#};
def OnGiveCustomFBPrize(playerIndex, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
    playerID = curPlayer.GetPlayerID()
    packMapID = clientData.MapID
    packFuncLineID = clientData.FuncLineID
    prizeInfo = PyGameData.g_customFBPrizeInfo.pop(playerID, None)
    if not prizeInfo:
        return
    mapID, funcLineID, prizeItemList = prizeInfo
    if mapID != packMapID or funcLineID != packFuncLineID:
        return
    FBLogic.OnGiveCustomFBPrizeOK(curPlayer, mapID, funcLineID)
    ItemControler.GivePlayerItemOrMail(curPlayer, prizeItemList)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_ClientServerReceiveMsg.py
@@ -19,6 +19,7 @@
import ShareDefine
import NPCCommon
import ChPlayer
import FBLogic
#------------------------------------------------------------------------------ 
@@ -45,6 +46,11 @@
    elif msgType == ShareDefine.CrossServerMsg_CollectNPCOK:
        NPCCommon.CrossServerMsg_CollectNPCOK(curPlayer, msgData)
        
    elif msgType == ShareDefine.CrossServerMsg_FBEnd:
        mapID, lineID = msgData[:2]
        exData = msgData[2:]
        FBLogic.OnEndCrossFB(curPlayer, mapID, lineID, exData)
    return
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPutInItem.py
@@ -49,8 +49,8 @@
    itemData = itemInfo["ItemData"]
    packIndex = itemInfo["PackIndex"]
    event = itemInfo["Event"]
    itemID, itemCount, isBind, itemUserData = itemData
    curItem = ItemCommon.CreateSingleItem(itemID, itemCount, not isBind)
    itemID, itemCount, isAuctionItem, itemUserData = itemData
    curItem = ItemCommon.CreateSingleItem(itemID, itemCount, isAuctionItem)
    if not curItem:
        return
    if itemUserData and itemUserData != "{}":
@@ -61,7 +61,7 @@
    
    # 放入失败发邮件
    GameWorld.Log("收到跨服获得物品,放入失败,直接发邮件! itemInfo=%s" % str(itemInfo), playerID)
    addItemList = [{"ItemID":itemID, "Count":itemCount, "IsBind":isBind, "UserData":itemUserData}]
    addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":isAuctionItem, "UserData":itemUserData}]
    PlayerControl.SendMailByKey("", [playerID], addItemList, detail={"CrossPutInItem":1, "Event":event})
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py
@@ -145,7 +145,7 @@
#            GameWorld.DebugLog("    创建新战盟家园: tagFamilyID=%s,tagFamilyHomeLV=%s,resultLineID=%s" 
#                               % (tagFamilyID, tagFamilyHomeLV, resultLineID))
#===================================================================================================
    elif tagMapID in [ChConfig.Def_FBMapID_HorsePetBoss, ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_AllFamilyBoss]:
    elif tagMapID in [ChConfig.Def_FBMapID_HorsePetBoss, ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_AllFamilyBoss, ChConfig.Def_FBMapID_DemonKing]:
        tagMapPropertyID = tagMapLineID + 1 # 因为PropertyID默认是0,所以使用时从1开始
        resultLineID = -1  # 结果lineID
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -98,4 +98,6 @@
g_Qudao_DoubleBill = {} # 渠道删档充值返利
g_allfamilyBossDict = {} # 多仙盟boss信息 {familyID:[familyName, 伤害, [playerID], ...}
g_horsePetBossPlayerHurtDict = {} #骑宠boss信息 {lineID:{playerID:[playerName,hurt]}}
g_horsePetBossPlayerHurtDict = {} #骑宠boss信息 {lineID:{playerID:[playerName,hurt]}}
g_customFBPrizeInfo = {} #自定义副本奖励 {playerID:[mapID, funcLineID, [奖励物品列表], ...}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1199,6 +1199,7 @@
CrossServerMsg_NPCInfoRet = "NPCInfoRet"                # 跨服地图NPC信息
CrossServerMsg_CollectNPCOK = "CollectNPCOK"            # 采集NPC完成
CrossServerMsg_EnterFBRet = "EnterFBRet"                # 请求进入跨服副本返回信息
CrossServerMsg_FBEnd = "FBEnd"                          # 完成跨服副本
# 子服发送跨服信息定义
ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功