xdh
2019-03-26 02e97056134c570be30922f6ee3bb3b17b209524
6351 【后端】【2.1】新版骑宠争夺
17个文件已修改
2个文件已添加
829 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerHorsePetBoss.py 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_HorsePetBoss.py 589 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoat.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 7 ●●●● 补丁 | 查看 | 原始文档 | 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 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -1808,7 +1808,7 @@
{
    list        WorldLV;    //世界等级
    list        Rank;    //排名
    list        Award;    //奖励 [[独立概率万分率,[物品ID,数量,拍品分组]],..]
    list        Award;    //奖励 [[独立概率万分率,[物品ID,数量,是否拍品]],..]
};
//装备洗练等级上限
@@ -1818,4 +1818,14 @@
    BYTE        _Type;        //按装备位对应类型查找
    BYTE        _Star;    // 装备星数
    WORD        LevelMax;    //洗练等级上限
};
//骑宠Boss奖励表
struct tagHorsePetBossAward
{
    BYTE        _LineID;    // 线路ID
    list        WorldLV;    //世界等级
    list        Rank;    //排名
    list        Award;    //奖励 [[独立概率万分率,[物品ID,数量,是否拍品]],..]
};
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -682,6 +682,8 @@
Def_FBMapID_CrossRealmPK = 32010
#跨服蓬莱仙境
Def_FBMapID_CrossPenglai = 32020
#骑宠Boss
Def_FBMapID_HorsePetBoss = 31200
#需要刷世界BOSS的副本
WorldBossFBMapIDList = [Def_FBMapID_SealDemon, Def_FBMapID_ZhuXianBoss]
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -36,6 +36,7 @@
import PlayerUniversalGameRec
import GameWorldAverageLv
import PlayerFamilyBoss
import PlayerHorsePetBoss
import GameWorldProcess
import ChPyNetSendPack
import NetPackCommon
@@ -1269,6 +1270,9 @@
    elif dictName in [ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyBoss1,
                      ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyBoss2,]:
        PlayerFamilyBoss.OnAllFamilyBossStateChange(isOpen)
    #骑宠BOSS
    elif dictName in [ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_HorsePetBoss]:
        PlayerHorsePetBoss.OnHorsePetBossStateChange(isOpen)
    
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -42,7 +42,7 @@
import PlayerZhuXianBoss
import PlayerXMZZ
import PlayerTruck
import HighLadder
import PlayerHorsePetBoss
import EventReport
import PlayerCompensation
import PlayerFamilyRedPacket
@@ -189,7 +189,8 @@
        CrossRealmPK.OnPlayerLogin(curPlayer)
        #诛仙BOSS
        PlayerZhuXianBoss.OnPlayerLogin(curPlayer)
        #骑宠boss状态通知
        PlayerHorsePetBoss.OnLogin(curPlayer)
        GMT_CTG.OnPlayerLogin(curPlayer)
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py
@@ -149,6 +149,8 @@
Def_BossRebornCnt = "BossRebornCnt"
#多仙盟Boss击杀时间
Def_AllFamilyBossTime = "AllFamilyBossTime"
#骑宠Boss击杀时间
Def_HorsePetBossTime = "HorsePetBossTime%s"
#跨服服务器是否维护中
Def_CrossServerClose = "CrossServerClose"
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -21,6 +21,7 @@
#---------------------------------------------------------------------
import GameWorldBoss
import PlayerFamilyBoss
import PlayerHorsePetBoss
import GameWorldFamilyWar
import PlayerControl
import PyGameData
@@ -130,6 +131,14 @@
        if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_AllFamilyBossTime):
            #BOSS已被击杀
            return
    #骑宠BOSS 是否已结束
    elif tagMapID == ChConfig.Def_FBMapID_HorsePetBoss:
        if not PlayerHorsePetBoss.IsInHorsePetBoss():
            #活动未开启
            return
        if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime % tagLineID):
            #BOSS已被击杀
            return
    # MapServer_QueryPlayer(int srcPlayerID, int queryType, int queryID, int mapID, char *callName, char *cmd,WORD cmdLen, int RouteServerIndex)
    playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, tagMapID,
                queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex())
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerHorsePetBoss.py
New file
@@ -0,0 +1,92 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
##@package PlayerHorsePetBoss
#
# @todo:骑宠boss副本
# @author xdh
# @date 2019-03-21
# @version 1.0
#
# 详细描述: 骑宠boss副本
#
#---------------------------------------------------------------------
#"""Version = 2019-03-21 18:00"""
#---------------------------------------------------------------------
import GameWorld
import ChPyNetSendPack
import NetPackCommon
import ShareDefine
import PlayerDBGSEvent
import PlayerControl
import time
Def_LineCnt = 2
## 玩家登录
#  @param curPlayer 玩家实例
#  @return None
def OnLogin(curPlayer):
    if IsInHorsePetBoss():
        NotifyHorsePetBossState(curPlayer)
    return
def OnHorsePetBossStateChange(isOpen):
    if isOpen:
        #本次开启时间距离上次击杀时间超过1小时则重置
        isNotify = False
        curTime = int(time.time())
        for i in xrange(Def_LineCnt):
            lastKillTime = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime%i)
            if abs(curTime-lastKillTime)> 3600:
                PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime%i, 0)
                isNotify = True
        if isNotify:
            #֪ͨ
            NotifyHorsePetBossState()
    return
def HorsePetBossKilled(lineID):
    if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime%lineID):
        GameWorld.Log('多骑宠Boss已被击杀,不可重复!!lineID=%s'%lineID)
        return
    curTime = int(time.time())
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime%lineID, curTime)
    GameWorld.Log('多骑宠Boss被击杀!!lineID=%s'%lineID)
    NotifyHorsePetBossState()
    return
def NotifyHorsePetBossState(curPlayer=None):
    IsEnd = 0
    for i in xrange(Def_LineCnt):
        lastKillTime = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime%i)
        if lastKillTime:
            IsEnd |=pow(2, 1)
    bossInfo = ChPyNetSendPack.tagGCHorsePetBossInfo()
    bossInfo.IsEnd = IsEnd
    if curPlayer == None:
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            if PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, bossInfo)
    else:
        if PlayerControl.GetIsTJG(curPlayer):
            return
        NetPackCommon.SendFakePack(curPlayer, bossInfo)
    return
#是否在骑宠BOSS活动中
def IsInHorsePetBoss():
    state = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_HorsePetBoss)
    return state
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -54,6 +54,7 @@
#import PlayerFamilyTech
import PlayerFamilyRedPacket
import PlayerFBHelpBattle
import PlayerHorsePetBoss
#import PlayerFamilyStore
import PlayerFamilySWRH
import GameWorldProcess
@@ -844,6 +845,10 @@
    if callName =="AllFamilyBossOver":
        PlayerFamilyBoss.AllFamilyBossKilled()
        return
    #骑宠BOSS结束
    if callName =="HorsePetBossOver":
        PlayerHorsePetBoss.HorsePetBossKilled(int(resultName))
        return
    
#---return分割线-----------------------------------------------------------------
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1519,7 +1519,8 @@
DailyActionID_CrossReamPK, # 跨服PK  21
DailyActionID_FamilyBoss1, # 仙盟BOSS第一场  22
DailyActionID_FamilyBoss2, # 仙盟BOSS第二场  23
) = range(1, 23 + 1)
DailyActionID_HorsePetBoss, # 骑宠BOSS  24
) = range(1, 24 + 1)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1800,6 +1800,8 @@
Def_FBMapID_CrossPenglai = 32020
#多仙盟Boss
Def_FBMapID_AllFamilyBoss = 31260
#骑宠Boss
Def_FBMapID_HorsePetBoss = 31200
#注册上传跨服服务器数据后直接进入跨服服务器的地图
RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai]
@@ -1826,7 +1828,7 @@
Def_MapID_LineIDToPropertyID = [Def_FBMapID_ElderBattlefield]
                      
# 进入副本需要发送到GameServer的地图
Def_MapID_SendToGameServer = [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_FamilyWar, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss] + Def_MapID_LineIDToPropertyID
## 进入副本需要根据请求的功能线路处理的地图, hxp-改了进入模式,暂不需要了 180320
#Def_MapID_ReqFBFuncLine = [Def_FBMapID_KirinHome, Def_FBMapID_BZZD, Def_FBMapID_SealDemonEx,
@@ -1834,7 +1836,7 @@
#                            + Def_FBMapID_ClearDevil
# 刷新标识点在无玩家的情况下也需要刷新的地图
Def_NoPlayerNeedProcessRefreshPointMap = [Def_FBMapID_SealDemon, Def_FBMapID_GodArea, Def_FBMapID_BossHome, Def_FBMapID_GatherSoul, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss]
Def_NoPlayerNeedProcessRefreshPointMap = [Def_FBMapID_HorsePetBoss, Def_FBMapID_SealDemon, Def_FBMapID_GodArea, Def_FBMapID_BossHome, Def_FBMapID_GatherSoul, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss]
# 可重复进的副本
Def_NoLimitEnterCntMap = [Def_FBMapID_AllFamilyBoss, Def_FBMapID_FamilyParty, Def_FBMapID_FamilyWar, Def_FBMapID_FamilyInvade, Def_FBMapID_ElderBattlefield, Def_FBMapID_ZhuXianBoss]
@@ -1900,6 +1902,7 @@
                'ZhuXianBoss':[Def_FBMapID_ZhuXianBoss],#诛仙BOSS
                'ZhuXianTower':[Def_FBMapID_ZhuXianTower],#诛仙塔
                'AllFamilyBoss':[Def_FBMapID_AllFamilyBoss],#多仙盟BOSS
                'HorsePetBoss':[Def_FBMapID_HorsePetBoss],#骑宠BOSS
                }
#特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
@@ -28,6 +28,7 @@
import GameLogic_ZhuXianBoss
import GameLogic_ZhuXianTower
import GameLogic_AllFamilyBoss
import GameLogic_HorsePetBoss
## GM命令执行入口
#  @param curPlayer 当前玩家
@@ -55,6 +56,12 @@
        #仙盟BOSS击杀怪
        GameWorld.GetGameWorld().SetGameWorldDict(GameLogic_AllFamilyBoss.FBDict_RemainHP, 1)
        return
    if curPlayer.GetMapID() == ChConfig.Def_FBMapID_HorsePetBoss:
        #骑宠BOSS击杀怪
        gameWorld = GameWorld.GetGameWorld()
        lineID = gameWorld.GetPropertyID() - 1
        gameWorld.SetGameWorldDict(GameLogic_HorsePetBoss.FBDict_RemainHP % lineID, 1)
        return
    isMapAllNPC = 0
    if len(playerList) > 0:
        isMapAllNPC = playerList[0]
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_HorsePetBoss.py
New file
@@ -0,0 +1,589 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameWorldLogic.FBProcess.GameLogic_HorsePetBoss
#
# @todo:骑宠boss
# @author xdh
# @date 2019-03-22
# @version 1.0
#
# 详细描述: 骑宠boss
#
#-------------------------------------------------------------------------------
#"""Version = 2019-03-22 14:30"""
#-------------------------------------------------------------------------------
import FBCommon
import GameWorld
import IPY_GameWorld
import GameWorldProcess
import IpyGameDataPY
import ChConfig
import PyGameData
import PlayerControl
import ShareDefine
import PlayerActivity
import NPCCustomRefresh
import ItemControler
import EventReport
import NPCCommon
FBDict_StartTick = 'FBDict_StartTick%s' #开始时间
FBDict_Speed = 'FBDict_Speed%s' #掉血速度 /s
FBDict_RemainHP = 'FBDict_RemainHP%s' #剩余时间
FBPlayerDict_EncourageLV = 'FBPlayerDict_EncourageLV'   # 鼓舞等级
FBDict_IsOver = 'FBDict_IsOver' #是否已结算, 结算时的tick
FBDict_IsReduceing = 'FBDict_IsReduceing%s' #是否掉血中
FBPlayerDict_Rank = "FBPlayerDict_Rank" # 玩家排名
FBDict_BossTotalHP = 'FBDict_BossTotalHP%s' #BOSS血量
FBDict_LastHurtTick = 'FBDict_LastHurtTick'  #上次伤害时间
FBDict_LastHPNotify = 'FBDict_LastHPNotify'  #上一个血量广播
(
Def_BossTime,  #BOSS时间
Def_LeaveTime,  #离开时间
Def_HPSpeed,  #掉血速度公式
) = range(3)
#当前副本地图的状态
(
FB_Step_Open,  # 副本开启
FB_Step_Fighting,  # 副本进行中
FB_Step_Over,  # 副本结束
FB_Step_Close,  # 副本关闭
) = range(4)
def OnFBPlayerOnLogin(curPlayer):
    return
def OnFBPlayerOnDay(curPlayer):
    return
## 是否能够通过活动查询进入
#  @param curPlayer 玩家实例
#  @param mapID 地图ID
#  @param lineID 线路id
#  @param tick 时间戳
#  @return 布尔值
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
    return True
##副本玩家进入点
# @param curPlayer 玩家实例
# @param mapID 地图ID
# @param lineId 分线ID
# @param ipyEnterPosInfo 功能线路IPY配置坐标信息
# @param tick 时间戳
# @return posX, posY, 随机半径(可选)
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
    return ipyEnterPosInfo
### 查询地图是否开启
##  @param tick 时间戳
##  @return 布尔值
#def OnCanOpen(tick):
#    return True
##查询是否可以进入地图
# @param ask:请求结构体(IPY_BMChangeMapAsk)
# @param tick:时间戳
# @return IPY_GameWorld.cme 枚举
def OnChangeMapAsk(ask, tick):
    return IPY_GameWorld.cmeAccept
##开启副本
# @param tick 时间戳
# @return 返回值无意义
# @remarks 开启副本
def OnOpenFB(tick):
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    bossID = CurFBLineBOSSID(lineID)
    if not bossID:
        return
    NPCCustomRefresh.SetNPCRefresh(101, [bossID])
    BossTime = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_HorsePetBoss, lineID)[Def_BossTime]
    GameWorld.GetGameWorld().SetGameWorldDict(FBDict_BossTotalHP%lineID, BossTime * 1000)
    return
def OnHorsePetBossStateChange(state, tick):
    #活动状态变更
    mapID = GameWorld.GetMap().GetMapID()
    if mapID != ChConfig.Def_FBMapID_HorsePetBoss:
        return
    GameWorld.DebugLog('    骑宠BOSS活动状态变更 state=%s' % state)
    if not state:
        if GameWorld.GetGameFB().GetFBStep() == FB_Step_Fighting:
            GameWorld.GetGameFB().SetGameFBDict(FBDict_IsOver, tick)
            __DoLogicHorsePetBossOver(0, tick, 0, 0)
    return
## 进副本
#  @param curPlayer
#  @param tick
#  @return None
def DoEnterFB(curPlayer, tick):
    playerID = curPlayer.GetPlayerID()
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    playerCnt = GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount()
    GameWorld.DebugLog("DoEnterFB...playerCnt=%s,lineID=%s" % (playerCnt, lineID), playerID)
    if lineID < 0:
        PlayerControl.PlayerLeaveFB(curPlayer)
        return
    fbStep = GameWorld.GetGameFB().GetFBStep()
    if fbStep >= FB_Step_Over:
        PlayerControl.PlayerLeaveFB(curPlayer)
        return
    hadDelTicket = FBCommon.GetHadDelTicket(curPlayer)
    if not hadDelTicket:
        FBCommon.SetHadDelTicket(curPlayer)
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_HorsePetBoss, 1)
        EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_HorsePetBoss, 0, ChConfig.CME_Log_Start)
        if fbStep == FB_Step_Open:
            FBCommon.SetFBStep(FB_Step_Fighting, tick)
    UpdateHurtInfo(curPlayer, 0, True)
    UpdateHPReduceSpeed(tick)
    gameFB = GameWorld.GetGameFB()
    # 上鼓舞buff
    encourageLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EncourageLV)
    if encourageLV > 0:
        FBCommon.AddFbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, tick)
    else:
        FBCommon.SendFBEncourageInfo(curPlayer, encourageLV)
    DoFBHelp(curPlayer, tick)
    return
##关闭副本
# @param tick 时间戳
# @return 无意义
# @remarks
def OnCloseFB(tick):
    gameWorld = GameWorld.GetGameWorld()
    lineID = gameWorld.GetPropertyID() - 1
    gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, 0)
    gameWorld.SetGameWorldDict(FBDict_Speed % lineID, 0)
    gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, 0)
    gameWorld.SetPropertyID(0)
    return
##玩家退出副本
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 无意义
def DoExitFB(curPlayer, tick):
    gameWorld = GameWorld.GetGameWorld()
    # 清除鼓舞buff
    FBCommon.ClearEncourageBuff(curPlayer, tick)
#    #最后一人
#    if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:
#        lineID = gameWorld.GetPropertyID() - 1
#        PyGameData.g_horsePetBossPlayerHurtDict[lineID] = {}
#        gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, 0)
#        GameWorld.GetGameFB().ClearGameFBDict()
#        GameWorldProcess.CloseFB(tick)
#        return
    UpdateHPReduceSpeed(tick, True)
    return
##玩家主动离开副本.
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 返回值无意义
def DoPlayerLeaveFB(curPlayer, tick):
    #FBCommon.SetHadDelTicket(curPlayer, 0)
    #主动退出的去掉排行榜信息
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    playerHurtDict = PyGameData.g_horsePetBossPlayerHurtDict.get(lineID, {})
    playerHurtDict.pop(curPlayer.GetPlayerID(), 0)
    PyGameData.g_horsePetBossPlayerHurtDict[lineID] = playerHurtDict
    if not playerHurtDict: #榜上没人,停止掉血
        StopReduceHP(lineID, tick)
    return
##玩家切换地图
def DoPlayerChangeMapLogic(curPlayer):
    #FBCommon.SetHadDelTicket(curPlayer, 0)
    return
## 是否副本复活
#  @param None
#  @return 是否副本复活
def OnPlayerReborn():
    return True
## 获得副本帮助信息
#  @param curPlayer 当前玩家(被通知对象)
#  @param tick 当前时间
#  @return None
def DoFBHelp(curPlayer, tick):
    #伤害排行信息
    if GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_IsOver):
        return
    hurtInfo = []
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    playerHurtList = __GetSortHurtList(lineID)
    myPlayerID = curPlayer.GetPlayerID()
    myRank, myHurt = 0, 0
    for i, info in enumerate(playerHurtList, 1):
        playerID = info[0]
        playerName, hurt = info[1][:2]
        if playerID == myPlayerID:
            myRank, myHurt = i, hurt
        if i <= 5:
            hurtDict = {}
            hurtDict["rank"] = i
            hurtDict["playerName"] = playerName
            hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue
            hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue
            hurtInfo.append(hurtDict)
    curSpeed = GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_Speed % lineID)
    isReduceing = GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_IsReduceing % lineID)
    remainHP = GetBossRemainHP(lineID, tick)
    totalHP = __GetBossTotalHP(lineID)
    hpReduceSpeed = curSpeed * 10000 / totalHP if totalHP else 0
    remainHPPer = min(1000000, remainHP * 1000000 / totalHP) if totalHP else 0
    fbHelpDict = {FBCommon.Help_lineID:lineID, "hurtInfo":hurtInfo, 'hpReduceSpeed':hpReduceSpeed,
                  'remainHPPer':remainHPPer, 'isReduceing':isReduceing,'myHurt':myHurt % ChConfig.Def_PerPointValue,
                  'myHurtEx':myHurt / ChConfig.Def_PerPointValue, 'myRank':myRank
                  }
    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
    return
## 副本行为
#  @param curPlayer 玩家
#  @param actionType 行为类型
#  @param actionInfo 行为信息
#  @param tick 当前时间
#  @return None
def DoFBAction(curPlayer, actionType, actionInfo, tick):
    if actionType == 0:
        FBCommon.FbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, actionInfo, tick)
    return
## 玩家对NPC造成伤害
#  @param curPlayer 当前玩家
#  @param curNPC
#  @param hurtHP
#  @return None
def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
    UpdateHurtInfo(curPlayer, hurtHP)
    #有人上榜开始掉血
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    StartReduceHP(lineID, GameWorld.GetGameWorld().GetTick())
    GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, GameWorld.GetGameWorld().GetTick())
    return
#
def UpdateHurtInfo(curPlayer, hurtHP, isAdd=False):
    playerID = curPlayer.GetPlayerID()
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    playerName = curPlayer.GetName()
    playerHurtDict = PyGameData.g_horsePetBossPlayerHurtDict.get(lineID, {})
    if playerID not in playerHurtDict:
        if not isAdd:
            return
        playerHurtDict[playerID] = [playerName, hurtHP]
    else:
        playerHurtDict[playerID][1] += hurtHP
    PyGameData.g_horsePetBossPlayerHurtDict[lineID] = playerHurtDict
    return
##---副本总逻辑计时器---
# @param tick:时间戳
# @return 无意义
# @remarks 副本总逻辑计时器
def OnProcess(tick):
    gameFB = GameWorld.GetGameFB()
    gameWorld = GameWorld.GetGameWorld()
    overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)
    fbStep = gameFB.GetFBStep()
    lineID = gameWorld.GetPropertyID() - 1
    if lineID < 0:
        return
    if fbStep == FB_Step_Over:
        mapID = GameWorld.GetMap().GetMapID()
        leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID)[Def_LeaveTime] * 1000
        if tick - GameWorld.GetGameFB().GetFBStepTick() > leaveTick:
            GameWorld.Log("强制踢出玩家关闭副本: overTick=%s,tick=%s" % (overTick, tick))
            GameWorldProcess.CloseFB(tick)
            FBCommon.SetFBStep(FB_Step_Close, tick)
            return
    elif fbStep == FB_Step_Fighting:
        startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
        if not startTick or overTick:
            return
        lastHurtTick = gameFB.GetGameFBDictByKey(FBDict_LastHurtTick)
        if lastHurtTick and tick - lastHurtTick >= 2000:
            StopReduceHP(lineID, tick)
            gameFB.SetGameFBDict(FBDict_LastHurtTick, 0)
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
        __CheckBossHP(tick)
    return
def __GetSortHurtList(lineID):
    playerHurtDict = PyGameData.g_horsePetBossPlayerHurtDict.get(lineID, {})
    playerHurtList = sorted(playerHurtDict.iteritems(), key=lambda asd:asd[1][1], reverse=True)
    return playerHurtList
def __DoLogicHorsePetBossOver(isPass, tick, dropPosX, dropPosY):
    #结算
    FBCommon.SetFBStep(FB_Step_Over, tick)
    mapID = GameWorld.GetMap().GetMapID()
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    msgStr = str(lineID)
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'HorsePetBossOver', msgStr, len(msgStr))
    leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID)[Def_LeaveTime] * 1000
    playerHurtList = __GetSortHurtList(lineID)
    if not playerHurtList:
        GameWorld.Log(' __DoLogicHorsePetBossOver, 伤害榜上没有人!!lineID=%s'%lineID)
        return
    event = ["HorsePetBoss", False, {}]
    batchPlayerIDList, batchAddItemList, batchParamList, batchDetailList = [], [], [], []
    playerManager = GameWorld.GetMapCopyPlayerManager()
    worldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
    for rank, hurtInfo in enumerate(playerHurtList, 1):
        playerID = hurtInfo[0]
        if isPass:
            auctionItemList, itemList = __GetHorsePetBossAward(lineID, rank, worldLV)
        else:
            auctionItemList, itemList = [], []
        GameWorld.Log('auctionItemList=%s,itemList=%s'%(auctionItemList, itemList))
        giveItemList = auctionItemList+itemList
        player = playerManager.FindPlayerByID(playerID)
        if player:
            overDict = {FBCommon.Over_rank:rank}
            if auctionItemList:
                overDict['AuctionItem'] = FBCommon.GetJsonItemList(auctionItemList)
            if itemList:
                overDict[FBCommon.Over_itemInfo] = FBCommon.GetJsonItemList(itemList)
            if giveItemList:
                NPCCommon.DoVirtualItemDrop(player, giveItemList, dropPosX, dropPosY)
                ItemControler.GivePlayerItemOrMail(player, giveItemList, 'QCBOSS1', event)
            player.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
            FBCommon.NotifyFBOver(player, ChConfig.Def_FBMapID_HorsePetBoss, lineID, isPass, overDict)
        elif giveItemList:
            batchPlayerIDList.append([playerID])
            batchAddItemList.append(giveItemList)
            batchParamList.append([])
            batchDetailList.append({'rank':rank, 'lineID':lineID})
    if batchPlayerIDList:
        PlayerControl.SendMailBatch("QCBOSS2", batchPlayerIDList, batchAddItemList, batchParamList, batchDetail=batchDetailList)
    return
def __GetHorsePetBossAward(lineID, rank, worldLV):
    auctionItemList, itemList = [], []
    ipyDataList = IpyGameDataPY.GetIpyGameDataList('HorsePetBossAward', lineID)
    if not ipyDataList:
        return auctionItemList, itemList
    awardRateList = []
    for ipyData in ipyDataList:
        worldLVList = ipyData.GetWorldLV()
        if worldLV < worldLVList[0] or worldLV > worldLVList[1]:
            continue
        rankList = ipyData.GetRank()
        if rank < rankList[0] or rank > rankList[1]:
            continue
        awardRateList = ipyData.GetAward()
    if not awardRateList:
        GameWorld.ErrLog('骑宠Boss奖励表 未配置该奖励 lineID=%s, rank=%s,worldLV=%s' % (lineID, rank, worldLV))
        return auctionItemList, itemList
    for rate, itemInfo in awardRateList:
        if not GameWorld.CanHappen(rate, 10000):
            continue
        if len(itemInfo) != 3:
            GameWorld.ErrLog('骑宠Boss奖励表 配置错误 itemInfo=%s' % itemInfo)
            continue
        if itemInfo[2]:
            auctionItemList.append(itemInfo)
        else:
            itemList.append(itemInfo)
    return auctionItemList, itemList
def __CheckBossHP(tick):
    gameFB = GameWorld.GetGameFB()
    isOver = gameFB.GetGameFBDictByKey(FBDict_IsOver)
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    if not isOver:
        bossID = CurFBLineBOSSID(lineID)
        if GetBossRemainHP(lineID, tick) == 0:
            curBoss = GameWorld.FindNPCByNPCID(bossID)
            dropPosX, dropPosY = 0, 0
            if curBoss:
                dropPosX, dropPosY = curBoss.GetPosX(), curBoss.GetPosY()
            #结束 设置BOSS死亡
            FBCommon.ClearFBNPC()
            FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
            GameWorld.DebugLog('结束 设置BOSS死亡 lineID=%s' % lineID)
            __DoLogicHorsePetBossOver(1, tick, dropPosX, dropPosY)
            gameFB.SetGameFBDict(FBDict_IsOver, tick)
        else:
            #血量广播
            needNotifyHPPerList = [50, 20]
            lastIndex = gameFB.GetGameFBDictByKey(FBDict_LastHPNotify)
            if lastIndex >= len(needNotifyHPPerList):
                return
            remainPer = GetBossRemainHPPer(lineID, tick)
            notifyHPPer = needNotifyHPPerList[lastIndex]
            if remainPer == notifyHPPer or remainPer - 1 == notifyHPPer:
                gameFB.SetGameFBDict(FBDict_LastHPNotify, lastIndex + 1)
                lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
                msgMark = 'QCBOSSHP1'
                PlayerControl.WorldNotify(0, msgMark, [bossID, remainPer])
    return
def UpdateHPReduceSpeed(tick, isExit=False):
    gameWorld = GameWorld.GetGameWorld()
    playerCnt = gameWorld.GetMapCopyPlayerManager().GetPlayerCount()
    playerCnt = playerCnt - 1 if isExit else playerCnt
    if playerCnt <=0:
        return
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    if lineID < 0:
        return
    curSpeed = eval(FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_HorsePetBoss, lineID)[Def_HPSpeed])
    gameWorld.SetGameWorldDict(FBDict_Speed % lineID, curSpeed)
    if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):
        return
    startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
    remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)
    lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID)
    if not startTick:
        startTick = tick
        lastSpeed = curSpeed
        remainHP = __GetBossTotalHP(lineID)
    remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))
    gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)
    gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, remainHP)
    GameWorld.DebugLog('    curSpeed=%s, remainHP=%s, passTime=%s, lastSpeed=%s' % (curSpeed, remainHP, tick - startTick, lastSpeed))
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
    return
def StopReduceHP(lineID, tick):
    ##暂停BOSS血量减少
    gameWorld = GameWorld.GetGameWorld()
    if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):
        return
    remainHP = GetBossRemainHP(lineID, tick)
    if not remainHP:
        return
    gameWorld.SetGameWorldDict(FBDict_IsReduceing % lineID, 0)
    gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, remainHP)
    return
def StartReduceHP(lineID, tick):
    ##开始BOSS掉血
    gameWorld = GameWorld.GetGameWorld()
    if gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):
        return
    gameWorld.SetGameWorldDict(FBDict_IsReduceing % lineID, 1)
    startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
    if not startTick:
        gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, __GetBossTotalHP(lineID))
    gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
    return
def __GetBossTotalHP(lineID):return GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_BossTotalHP%lineID)
def GetBossRemainHP(lineID, tick):
    gameWorld = GameWorld.GetGameWorld()
    startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
    lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID)
    remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)
    if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing%lineID):
        return remainHP
    if not startTick:
        startTick = tick
        remainHP = __GetBossTotalHP(lineID)
    else:
        remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))
    return remainHP
def GetBossRemainHPPer(lineID, tick):
    remainHP = GetBossRemainHP(lineID, tick)
    totalHP = __GetBossTotalHP(lineID)
    if not totalHP:
        return 0
    return remainHP * 100 / totalHP
def CurFBLineBOSSID(lineID= -1):
    #该分线刷的BOSSID
    if lineID == -1:
        lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    refreshNPCInfo = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_HorsePetBoss, lineID)
    if not refreshNPCInfo:
        return 0
    bossID = int(refreshNPCInfo)
    return bossID
##玩家死亡.
# @param curPlayer:死亡的玩家
# @param tick 时间戳
# @return 返回值无意义
# @remarks 玩家主动离开副本.
def DoPlayerDead(curPlayer):
    return
## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
#  @param attacker 攻击方
#  @param defender 防守方
#  @return bool
def CheckCanAttackTagObjInFB(attacker, defender):
    return True
##处理副本中杀死玩家逻辑
# @param curPlayer 玩家实例
# @param defender 防守者
# @param tick 时间戳
# @return 布尔值
# @remarks 处理副本中杀死玩家逻辑
def DoFBOnKill_Player(atkobj, defender, tick):
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1409,6 +1409,13 @@
                        ("BYTE", "Star", 1),
                        ("WORD", "LevelMax", 0),
                        ),
                "HorsePetBossAward":(
                        ("BYTE", "LineID", 1),
                        ("list", "WorldLV", 0),
                        ("list", "Rank", 0),
                        ("list", "Award", 0),
                        ),
                }
@@ -4294,7 +4301,7 @@
        
    def GetWorldLV(self): return self.WorldLV # 世界等级
    def GetRank(self): return self.Rank # 排名
    def GetAward(self): return self.Award # 奖励 [[独立概率万分率,[物品ID,数量,拍品分组]],..]
    def GetAward(self): return self.Award # 奖励 [[独立概率万分率,[物品ID,数量,是否拍品]],..]
# 装备洗练等级上限
class IPY_ItemWashMax():
@@ -4308,6 +4315,21 @@
    def GetType(self): return self.Type # 按装备位对应类型查找
    def GetStar(self): return self.Star #  装备星数
    def GetLevelMax(self): return self.LevelMax # 洗练等级上限
# 骑宠Boss奖励表
class IPY_HorsePetBossAward():
    def __init__(self):
        self.LineID = 0
        self.WorldLV = []
        self.Rank = []
        self.Award = []
        return
    def GetLineID(self): return self.LineID #  线路ID
    def GetWorldLV(self): return self.WorldLV # 世界等级
    def GetRank(self): return self.Rank # 排名
    def GetAward(self): return self.Award # 奖励 [[独立概率万分率,[物品ID,数量,是否拍品]],..]
def Log(msg, playerID=0, par=0):
@@ -4615,6 +4637,8 @@
        self.ipyFamilyBossAwardLen = len(self.ipyFamilyBossAwardCache)
        self.ipyItemWashMaxCache = self.__LoadFileData("ItemWashMax", IPY_ItemWashMax)
        self.ipyItemWashMaxLen = len(self.ipyItemWashMaxCache)
        self.ipyHorsePetBossAwardCache = self.__LoadFileData("HorsePetBossAward", IPY_HorsePetBossAward)
        self.ipyHorsePetBossAwardLen = len(self.ipyHorsePetBossAwardCache)
        Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict))
        Log("IPY_DataMgr InitOK!")
        return
@@ -5063,6 +5087,8 @@
    def GetFamilyBossAwardByIndex(self, index): return self.ipyFamilyBossAwardCache[index]
    def GetItemWashMaxCount(self): return self.ipyItemWashMaxLen
    def GetItemWashMaxByIndex(self, index): return self.ipyItemWashMaxCache[index]
    def GetHorsePetBossAwardCount(self): return self.ipyHorsePetBossAwardLen
    def GetHorsePetBossAwardByIndex(self, index): return self.ipyHorsePetBossAwardCache[index]
IPYData = IPY_DataMgr()
def IPY_Data(): return IPYData
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -587,6 +587,27 @@
    #GameWorld.DebugLog("    totalExp=%s,totalMoney=%s,needSpace=%s,jsonItemList=%s" % (totalExp, totalMoney, needSpace, jsonItemList))
    return jsonItemList, totalExp, totalMoney
def DoVirtualItemDrop(curPlayer, dropItemList, dropPosX, dropPosY):
    ##前端假掉落表现
    gameMap = GameWorld.GetMap()
    index = 0
    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
        itemInfo = dropItemList[index]
        index += 1
        itemID, itemCount, isAuctionItem = itemInfo
        curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem)
        dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)
        SendVirtualItemDrop(curPlayer, itemID, resultX, resultY, dropItemDataStr)
        curItem.Clear()
    return
################################### NPC掉落 ###################################
Def_NPCMaxDropRate = 1000000 # NPC掉落相关的最大概率, 数值设定
@@ -4156,7 +4177,7 @@
            if mapID == ChConfig.Def_FBMapID_GatherSoul:#聚魂副本特殊处理
                GameLogic_GatherSoul.KillGatherSoulNPCDropAward(itemID, itemCnt, isAuctionItem)
                dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)
                self.SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
                SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
                curItem.Clear()
                continue
            
@@ -4166,21 +4187,10 @@
                #可以放入背包
                if ItemControler.DoLogic_PutItemInPack(ownerPlayer, curItem, event=["NPCDrop", False, {"npcID":npcID}]):
                    #通知客户端
                    self.SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
                    SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
                    
            else:
                self.__MapCreateItem(curItem, resultX, resultY, ownerType, ownerID)
        return
    def SendVirtualItemDrop(self, player, itemID, posX, posY, userDataStr):
        #通知客户端
        vItemDrop = ChPyNetSendPack.tagMCVirtualItemDrop()
        vItemDrop.ItemTypeID = itemID
        vItemDrop.PosX = posX
        vItemDrop.PosY = posY
        vItemDrop.UserData = userDataStr
        vItemDrop.UserDataLen = len(vItemDrop.UserData)
        NetPackCommon.SendFakePack(player, vItemDrop)
        return
    #---------------------------------------------------------------------
    ## NPC被杀死逻辑处理
@@ -5080,6 +5090,17 @@
        return curItem
    
#---------------------------------------------------------------------
def SendVirtualItemDrop(player, itemID, posX, posY, userDataStr):
    #通知客户端假物品掉落
    vItemDrop = ChPyNetSendPack.tagMCVirtualItemDrop()
    vItemDrop.ItemTypeID = itemID
    vItemDrop.PosX = posX
    vItemDrop.PosY = posY
    vItemDrop.UserData = userDataStr
    vItemDrop.UserDataLen = len(vItemDrop.UserData)
    NetPackCommon.SendFakePack(player, vItemDrop)
    return
def GetNPCExp(curPlayer, npcID):
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
    if not npcData:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoat.py
@@ -190,7 +190,7 @@
# @param destIndex 目标索引
# @return 
def SwitchCoat(curPlayer, srcBackpack, desBackPack, srcIndex, destIndex):
    clothesPlaceList = [ShareDefine.retWeaponSkin, ShareDefine.retClothesSkin, ShareDefine.retWeapon2Skin]
    clothesPlaceList = [6,7,8]#[ShareDefine.retWeaponSkin, ShareDefine.retClothesSkin, ShareDefine.retWeapon2Skin]
    if not ((desBackPack == IPY_GameWorld.rptEquip and srcBackpack == ShareDefine.rptTempSwap and destIndex in clothesPlaceList) \
    or (srcBackpack == IPY_GameWorld.rptEquip and desBackPack == ShareDefine.rptTempSwap and srcIndex in clothesPlaceList)):
        return False
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -71,6 +71,7 @@
import GameLogic_FamilyInvade
import GameLogic_ElderBattlefield
import GameLogic_AllFamilyBoss
import GameLogic_HorsePetBoss
import GameLogic_FamilyBoss
import GameLogic_FamilyWar
import OpenServerCampaign
@@ -1381,7 +1382,11 @@
                 ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyBoss2,]:
        if gameWorldMgr.GetGameWorldDictByKey(key) != value:
            GameLogic_AllFamilyBoss.OnAllFamilyBossStateChange(value, tick)
    # 骑宠BOSS
    elif key == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_HorsePetBoss:
        if gameWorldMgr.GetGameWorldDictByKey(key) != value:
            GameLogic_HorsePetBoss.OnHorsePetBossStateChange(value, tick)
    # OnDayEx
    elif key == ShareDefine.Def_Notify_WorldKey_OnDayEx:
        if value and gameWorldMgr.GetGameWorldDictByKey(key) != value:
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_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]:
        tagMapPropertyID = tagMapLineID + 1 # 因为PropertyID默认是0,所以使用时从1开始
        resultLineID = -1  # 结果lineID
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -97,4 +97,5 @@
g_Qudao_DoubleBill = {} # 渠道删档充值返利
g_allfamilyBossDict = {} # 多仙盟boss信息 {familyID:[familyName, 伤害, [playerID], ...}
g_allfamilyBossDict = {} # 多仙盟boss信息 {familyID:[familyName, 伤害, [playerID], ...}
g_horsePetBossPlayerHurtDict = {} #骑宠boss信息 {lineID:{playerID:[playerName,hurt]}}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1519,7 +1519,8 @@
DailyActionID_CrossReamPK, # 跨服PK  21
DailyActionID_FamilyBoss1, # 仙盟BOSS第一场  22
DailyActionID_FamilyBoss2, # 仙盟BOSS第二场  23
) = range(1, 23 + 1)
DailyActionID_HorsePetBoss, # 骑宠BOSS  24
) = range(1, 24 + 1)