xdh
2019-01-22 ccaefa2a93fb82d0db5fc7e74832a292fb860984
5919 【后端】【1.5.100】诛仙塔功能开发
8个文件已修改
2个文件已添加
865 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetZhuXianTower.py 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ZhuXianBoss.py 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ZhuXianTower.py 642 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -1590,4 +1590,16 @@
    WORD        KillTime;    //击杀总时间秒
    WORD        RealmLV;    //需要境界
    DWORD        ZhuXianScore;    //需要诛仙总评分
};
//诛仙塔表
struct tagZhuXianTower
{
    DWORD        _ID;    //塔编号
    DWORD        NPCID;    //npcid
    list        FirstAward;    //首次S级奖励
    dict        GradeAward;    //评级奖励
    WORD        UnLockEquipPlace;    //解锁的装备位
    DWORD        NeedPower;    //推荐战力
};
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -583,7 +583,7 @@
            ShareDefine.Def_BT_Campaign_PetLV           : 100,           #灵宠等级(开服活动榜)  
            ShareDefine.Def_BT_FCCostGold               : 5,             #消费排行榜(仙界盛典)
            ShareDefine.Def_BT_FBHelpBattle             : 100,           #助战次数榜
            ShareDefine.Def_BT_ZhuXianTower             : 100,           #诛仙塔榜
            ShareDefine.Def_BT_HighLadder               : 1000,          #玩家天梯竞技场排行
            ShareDefine.Def_BT_HighLadder_Yester        : 1000,          #玩家天梯竞技场昨日排行
            ShareDefine.Def_BT_RechargeTeHuiLast        : 20,            #充值特惠活动排行榜-上一期记录 
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -27413,6 +27413,58 @@
#------------------------------------------------------
# B2 13 诛仙塔通关层数 #tagMCZhuXianTowerInfo
class  tagMCZhuXianTowerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Floor", c_int),    # 已通关层
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x13
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB2
        self.SubCmd = 0x13
        self.Floor = 0
        return
    def GetLength(self):
        return sizeof(tagMCZhuXianTowerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 13 诛仙塔通关层数 //tagMCZhuXianTowerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                Floor:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Floor
                                )
        return DumpString
m_NAtagMCZhuXianTowerInfo=tagMCZhuXianTowerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCZhuXianTowerInfo.Cmd,m_NAtagMCZhuXianTowerInfo.SubCmd))] = m_NAtagMCZhuXianTowerInfo
#------------------------------------------------------
# B4 11 新增恶意攻击玩家 #tagMCAddMaliciousAtkPlayer
class  tagMCAddMaliciousAtkPlayer(Structure):
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -570,6 +570,8 @@
    Def_BT_Campaign_Recharge,                 #累计充值(开服活动榜)
    Def_BT_Campaign_PetLV,                    #灵宠等级(开服活动榜)
    
    Def_BT_ZhuXianTower,                      #诛仙塔榜
    Def_BT_HighLadder,                        #天梯竞技场排行
    Def_BT_HighLadder_Yester,                 #天梯竞技场昨日排行
    Def_BT_RechargeTeHuiLast,                 #充值特惠活动排行榜-上一期记录
@@ -584,7 +586,7 @@
    Def_BT_CostTeHuiLast,                     #消费特惠排行榜上一期
    
    Def_BT_Max,                               #排行榜最大类型
) = range(0, 32 + 2)
) = range(0, 33 + 2)
    
#职业对应战力排行榜类型
JobFightPowerBillboardDict = {
@@ -596,7 +598,7 @@
#排行榜Value1存储境界信息的榜单列表
BTValue1_OfficialRankList = [Def_BT_FightPower, Def_BT_FightPower_Warrior, Def_BT_FightPower_Wizard, Def_BT_FightPower_Assassin, 
                             Def_BT_LV, Def_BT_FightPower_Horse, Def_BT_FightPower_Pet, Def_BT_TrialTower, Def_BT_OffLineEfficient,
                             Def_BT_FBHelpBattle,
                             Def_BT_FBHelpBattle, Def_BT_ZhuXianTower,
                             ]
##---比率---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1809,6 +1809,8 @@
Def_FBMapID_SealDemonEx = 52020
#诛仙BOSS
Def_FBMapID_ZhuXianBoss = 31380
#诛仙塔
Def_FBMapID_ZhuXianTower = 31370
#仙魔之争
Def_FBMapID_XMZZ = 31010
#神兽副本
@@ -1918,6 +1920,7 @@
                'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
                'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
                'ZhuXianBoss':[Def_FBMapID_ZhuXianBoss],#诛仙BOSS
                'ZhuXianTower':[Def_FBMapID_ZhuXianTower],#诛仙塔
                }
#特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
@@ -3644,7 +3647,8 @@
#试炼之塔
Def_Player_Dict_TrialTower_PassLV = "TrialTower_PassLV"  # 试炼之塔通关层数
Def_Player_Dict_TrialTower_LastDayPassLV = "Tower_LastDayPassLV"  # 试炼之塔昨日通关层数
#诛仙塔
Def_Player_Dict_ZhuXianTowerPassLV = "ZhuXianTowerPassLV"  # 诛仙塔通关层数
#古神禁地
Def_Player_Dict_GodArea_Anger = "GodArea_Anger"  # 古神禁地怒气值
Def_Player_Dict_GodArea_LastAddAngerTime = "GodArea_LastAddAngerTime"  # 古神禁地上一次增加怒气值的时间
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetZhuXianTower.py
New file
@@ -0,0 +1,44 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
##@package GM.Commands.SetZhuXianTower
#
# @todo:诛仙塔过关数设置
# @author xdh
# @date 2019-01-21 16:10
# @version 1.0
#
#
# 详细描述: 诛仙塔过关数设置
#
#---------------------------------------------------------------------
#"""Version = 2019-01-21 16:10"""
#---------------------------------------------------------------------
import GameLogic_ZhuXianTower
import ShareDefine
import PlayerBillboard
import GameWorld
#---------------------------------------------------------------------
#全局变量
#---------------------------------------------------------------------
#---------------------------------------------------------------------
## 逻辑实现
## GM命令执行入口
#  @param curPlayer
#  @param cmdList 参数列表
#  @return None
def OnExec(curPlayer, cmdList):
    if len(cmdList) != 1:
        return
    fbLevel = cmdList[0]
    GameLogic_ZhuXianTower.SetZhuXianTowerCurPassLV(curPlayer, fbLevel)
    #更新诛仙塔排行榜
    PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_ZhuXianTower, fbLevel, 100)
    GameLogic_ZhuXianTower.SyncZhuXianLevelInfo(curPlayer)
    GameWorld.DebugAnswer(curPlayer, "诛仙塔过关数设置 floor=%s!"%fbLevel)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ZhuXianBoss.py
@@ -27,16 +27,10 @@
import ItemCommon
import ChPyNetSendPack
import ShareDefine
import EventShell
import NPCCustomRefresh
import PlayerSuccess
import PlayerActivity
import NetPackCommon
import ItemControler
import PlayerMagicWeapon
import PlayerBossReborn
import PlayerFairyCeremony
import PlayerWeekParty
import EventReport
FBDict_StartTick = 'FBDict_StartTick%s' #开始时间
@@ -48,7 +42,7 @@
FBPlayerDict_Rank = "FBPlayerDict_Rank" # 玩家排名
FBDict_BossTotalHP = 'FBDict_BossTotalHP%s' #BOSS血量
g_npcHurtDict = {}
g_heroHurtDict = {} #{playerID:hurt}
def OnFBPlayerOnLogin(curPlayer):
@@ -151,9 +145,9 @@
#  @param tick
#  @return None
def DoEnterFB(curPlayer, tick):
    global g_heroHurtDict
    playerID = curPlayer.GetPlayerID()
    mapID = GameWorld.GetMap().GetMapID()
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1    
    
    playerCnt = GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount()
@@ -166,6 +160,7 @@
    if not hadDelTicket:
        FBCommon.SetHadDelTicket(curPlayer)
        PyGameData.g_fbPickUpItemDict.pop(playerID, 0)
        g_heroHurtDict.pop(playerID, 0)
#        if playerCnt == 1:
#            posX, posY = IpyGameDataPY.GetFuncEvalCfg('ZhuXianBossFirstPos')
#            GameWorld.ResetPlayerPos(curPlayer, posX, posY)
@@ -204,7 +199,6 @@
# @param tick 时间戳
# @return 无意义
def DoExitFB(curPlayer, tick):
    global g_npcHurtDict
    gameWorld = GameWorld.GetGameWorld()
    # 清除鼓舞buff
    FBCommon.ClearEncourageBuff(curPlayer, tick)
@@ -212,7 +206,6 @@
    if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:
        lineID = gameWorld.GetPropertyID() - 1
        PyGameData.g_ZhuXianBossPlayerHurtDict[lineID] = {}
        g_npcHurtDict[lineID] = {}
        gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, 0)
        GameWorld.GetGameFB().ClearGameFBDict()
        GameWorldProcess.CloseFB(tick)
@@ -255,12 +248,13 @@
#  @return None
def DoFBHelp(curPlayer, tick):
    #伤害排行信息
    if GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_IsOver):
        return
    hurtInfo = []
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    playerHurtList = PyGameData.g_ZhuXianBossPlayerHurtDict.get(lineID, {}).items()
    npcHurtList = g_npcHurtDict.get(lineID, {}).items()
    syncHurtList = (playerHurtList + npcHurtList)[:5]
    syncHurtList = playerHurtList[:5]
    syncHurtList.sort(key=lambda asd:asd[1][1], reverse=True)
        
    for i, info in enumerate(syncHurtList, 1):
@@ -271,16 +265,16 @@
        hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue
        hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue
        hurtInfo.append(hurtDict)
    myRank = __GetSelfHurtRank(curPlayer)
    if myRank and myRank > 5:
        hurtDict = {}
        hurtDict["rank"] = myRank
        info = playerHurtList[myRank - 1]
        playerName, hurt = info[1][:2]
        hurtDict["playerName"] = playerName
        hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue
        hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue
        hurtInfo.append(hurtDict)
#    myRank = __GetSelfHurtRank(curPlayer)
#    if myRank and myRank > 5:
#        hurtDict = {}
#        hurtDict["rank"] = myRank
#        info = playerHurtList[myRank - 1]
#        playerName, hurt = info[1][:2]
#        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) 
@@ -288,7 +282,11 @@
    totalHP = __GetBossTotalHP(lineID)
    hpReduceSpeed = curSpeed * 10000 / totalHP if totalHP else 0
    remainHPPer = min(100, remainHP * 100 / totalHP) if totalHP else 0
    fbHelpDict = {FBCommon.Help_lineID:lineID, "hurtInfo":hurtInfo, 'hpReduceSpeed':hpReduceSpeed, 'remainHPPer':remainHPPer, 'isReduceing':isReduceing}
    myHurt = g_heroHurtDict.get(curPlayer.GetID(), 0)
    fbHelpDict = {FBCommon.Help_lineID:lineID, "hurtInfo":hurtInfo, 'hpReduceSpeed':hpReduceSpeed,
                  'remainHPPer':remainHPPer, 'isReduceing':isReduceing,'myHurt':myHurt % ChConfig.Def_PerPointValue,
                  'myHurtEx':myHurt / ChConfig.Def_PerPointValue
                  }
    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
    return
@@ -328,6 +326,10 @@
    return
#
def UpdateHurtInfo(curPlayer, hurtHP, isAdd=False):
    global g_heroHurtDict
    playerID = curPlayer.GetPlayerID()
    g_heroHurtDict[playerID] = g_heroHurtDict.get(playerID, 0) + hurtHP
    enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_ZhuXianBoss)
    if enterCnt >= FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss):
        #没归属的不进伤害榜
@@ -335,7 +337,7 @@
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    
    playerName = curPlayer.GetName() 
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    playerHurtDict = PyGameData.g_ZhuXianBossPlayerHurtDict.get(lineID, {})
    if playerID not in playerHurtDict:
@@ -361,14 +363,13 @@
        GameWorld.Log("强制踢出玩家关闭副本: overTick=%s,tick=%s" % (overTick, tick))
        FBCommon.DoLogic_FBKickAllPlayer()
        return
    mapID = GameWorld.GetMap().GetMapID()
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    if lineID <0:
        return
    gameWorld = GameWorld.GetGameWorld()
    startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
    if not startTick:
    if not startTick or overTick:
        return
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
    __CheckBossHP(tick)
@@ -405,7 +406,7 @@
    playerManager = GameWorld.GetMapCopyPlayerManager()#GameWorld.GetPlayerManager()
    firstPlayer = playerManager.FindPlayerByID(firstPlayerID)
    if firstPlayer:
        #gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_Rank, rank)
        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])
@@ -548,7 +549,7 @@
            dropPosX, dropPosY = curBoss.GetPosX(), curBoss.GetPosY()
        
        #结束 设置BOSS死亡
        FBCommon.ClearFBNPC()
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
        GameWorld.DebugLog('结束 设置BOSS死亡 lineID=%s' % lineID)
        playerHurtList = __GetSortHurtList(lineID)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ZhuXianTower.py
New file
@@ -0,0 +1,642 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
##@package GameWorldLogic.FBProcess.GameLogic_ZhuXianTower
#
# @todo:诛仙塔
# @author xdh
# @date 2019-01-21
# @version 1.0
# 详细描述: 诛仙塔
#
#---------------------------------------------------------------------
#"""Version = 2019-01-21 11:00"""
#---------------------------------------------------------------------
import FBCommon
import GameWorld
import IPY_GameWorld
import PlayerControl
import NPCCustomRefresh
import ChPyNetSendPack
import ItemControler
import NetPackCommon
import ShareDefine
import IpyGameDataPY
import ItemCommon
import ChConfig
import ChPlayer
import PlayerSuccess
import GameWorldProcess
import PlayerBillboard
import EventReport
import random
import math
Def_MaxStar = 5  #S级评级
FBDict_Level = 'FBDict_Level'  # 副本关卡
FBDict_FBStar = 'FBDict_FBStar'  # 当前副本星级
FBDict_isFirstS= 'FBDict_isFirstS'  # 是否首次S级过关
FBDict_StartTick = 'FBDict_StartTick'  #开始时间
FBDict_Speed = 'FBDict_Speed'  #掉血速度 /s
FBDict_RemainHP = 'FBDict_RemainHP'  #剩余时间
FBDict_IsReduceing = 'FBDict_IsReduceing'  #是否掉血中
FBDict_BossTotalHP = 'FBDict_BossTotalHP'  #BOSS血量
FBDict_LastHurtTick = 'FBDict_LastHurtTick'  #上次伤害时间
FBDict_HasGiveAward = 'FBDict_HasGiveAward'  # 是否有给奖励
# 副本通用配置
(
Def_PrepareTime,  # 每关准备时间,秒
Def_FightTime,  # 每关战斗时间,秒
Def_ExitTime,  # 退出时间, 秒
Def_StarTime,  # 星级对应耗时配置, 秒
) = range(4)
# 副本状态
(
FB_State_Open,  # 副本开启
FB_State_FightPrepare,  # 战斗准备时间
FB_State_Fighting,  # 战斗
FB_State_FreeTime,  # 活动结束准备(胜利/失败)
FB_State_Close,  # 关闭副本
) = range(5)
## 诛仙塔配置
def __GetZhuXianCfg(): return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_ZhuXianTower)
def GetTowerIpyData(level):
    return IpyGameDataPY.GetIpyGameData('ZhuXianTower', level)
def OnFBPlayerLogin(curPlayer):
    SyncZhuXianLevelInfo(curPlayer)
    return
## 同步诛仙塔关卡信息
#  @fbLevel 为0时默认全部同步,> 0时仅同步该关卡
def SyncZhuXianLevelInfo(curPlayer):
    ttInfo = ChPyNetSendPack.tagMCZhuXianTowerInfo()
    ttInfo.Clear()
    ttInfo.Floor = __GetZhuXianTowerCurPassLV(curPlayer)
    NetPackCommon.SendFakePack(curPlayer, ttInfo)
    return
## 获取当前已通关关卡
def __GetZhuXianTowerCurPassLV(curPlayer):
    return curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ZhuXianTowerPassLV)
## 更新当前已通关关卡
def SetZhuXianTowerCurPassLV(curPlayer, passlv):
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ZhuXianTowerPassLV, passlv)
    #PlayerRune.DoUnlockRuneHole(curPlayer)
    #PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_Tower, passlv, False)
    GameWorld.DebugLog(' 更新诛仙塔已通关数 %s' % passlv)
    return
## 是否可进入
#  @param curPlayer
#  @param mapID 地图ID
#  @param lineId 分线ID
#  @param tick
#  @return 是否可进入
def OnEnterFBEvent(curPlayer, mapID, lineId, tick):
    return True
## 检查可否进行挑战
def __CheckCanChallenge(curPlayer):
    #判断次数
    enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_ZhuXianTower)
    if enterCnt >= FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower):
        GameWorld.Log('进入次数不足!!')
        return 0
    curFloor = __GetZhuXianTowerCurPassLV(curPlayer)
    ipyMgr = IpyGameDataPY.IPY_Data()
    maxFloor = ipyMgr.GetZhuXianTowerByIndex(ipyMgr.GetZhuXianTowerCount() - 1).GetID()
    if curFloor >= maxFloor:
        return maxFloor
    return curFloor + 1
##玩家切换地图
def DoPlayerChangeMapLogic(curPlayer):
    FBCommon.UpdateFBEnterTick(curPlayer)
    return
##副本玩家进入点
# @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 ask 请求信息
#  @param tick
#  @return 回复是否通过请求
def OnChangeMapAsk(ask, tick):
    return IPY_GameWorld.cmeAccept
## 进副本
#  @param curPlayer
#  @param tick
#  @return None
def DoEnterFB(curPlayer, tick):
    # 不做处理,有副本行为客户端发包选择挑战关卡
    EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower, 0, ChConfig.CME_Log_Start)
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    ZhuXianCfg = __GetZhuXianCfg()
    if fbStep <= FB_State_FightPrepare:
        notify_tick = ZhuXianCfg[Def_PrepareTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
        curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)
    elif fbStep == FB_State_Fighting:
        notify_tick = ZhuXianCfg[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
        curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
        __UpdZhuXianTowerFBStar(tick, True, curPlayer)
    return
## 副本时间到关闭
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def OnCloseFB(tick):
    return
##玩家退出副本.
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 返回值无意义
# @remarks 玩家主动离开副本.
def DoExitFB(curPlayer, tick):
    # 玩家退出默认关闭副本
    #GameWorldProcess.CloseFB(tick)
    return
##副本总逻辑计时器
# @param tick 时间戳
# @return 无意义
# @remarks 副本总逻辑计时器
def OnProcess(tick):
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep == FB_State_FightPrepare:
        __DoLogic_FightPrepare(tick)
    elif fbStep == FB_State_Fighting:
        __DoLogic_Fighting(tick)
        __CheckBossHP(tick)
        __UpdZhuXianTowerFBStar(tick)
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
    elif fbStep == FB_State_FreeTime:
        __DoLogic_FreeTime(tick)
    elif fbStep == FB_State_Close:
        pass
    return
## 更新当前副本星级
def __UpdZhuXianTowerFBStar(tick, isEnter=False, curPlayer=None):
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep != FB_State_Fighting:
        return
    curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)
    if curStar == 1:
        return curStar
    mapID = GameWorld.GetMap().GetMapID()
    useSecond = int(math.ceil((tick - gameFB.GetFBStepTick()) / 1000.0))
    chaosDemonCfg = FBCommon.GetFBLineStepTime(mapID)
    starTimeList = chaosDemonCfg[Def_StarTime]
    diffSecond = 0
    updStar = 1  # 默认至少1星
    for star, starTime in enumerate(starTimeList, 2):
        if useSecond <= starTime:
            updStar = star
            diffSecond = starTime - useSecond
    if curStar == updStar and not isEnter:
        return curStar
    gameFB.SetGameFBDict(FBDict_FBStar, updStar)
    GameWorld.DebugLog("__UpdFBStar useSecond=%s,curStar=%s,updStar=%s, diffSecond=%s"
                       % (useSecond, curStar, updStar, diffSecond))
    if curPlayer:
        DoFBHelp(curPlayer, tick)
        if updStar != 1:
            curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)
    else:
        playerManager = GameWorld.GetMapCopyPlayerManager()
        for index in xrange(playerManager.GetPlayerCount()):
            curPlayer = playerManager.GetPlayerByIndex(index)
            if not curPlayer:
                continue
            DoFBHelp(curPlayer, tick)
            if updStar != 1:
                curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)
    return updStar
## 获取BossID
def __GetZhuXianBossID(fbLevel=-1):
    gameFB = GameWorld.GetGameFB()
    if fbLevel == -1:
        fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)
    ipyData = GetTowerIpyData(fbLevel)
    if not ipyData:
        GameWorld.ErrLog("__GetZhuXianBossID() can not find %s in tagZhuXianTower.txt" % fbLevel)
        return 0
    return ipyData.GetNPCID()
##战斗准备时间
# @param tick  时钟
# @return 无意义
def __DoLogic_FightPrepare(tick):
    gameFB = GameWorld.GetGameFB()
    ZhuXianCfg = __GetZhuXianCfg()
    if tick - gameFB.GetFBStepTick() < ZhuXianCfg[Def_PrepareTime] * 1000:
        return
    bossID = __GetZhuXianBossID()
    if not bossID:
        FBCommon.DoLogic_FBKickAllPlayer()
        return
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, ZhuXianCfg[Def_FightTime] * 1000)
    NPCCustomRefresh.SetNPCRefresh(FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_ZhuXianTower, 0), [bossID])
    #转入战斗
    FBCommon.SetFBStep(FB_State_Fighting, tick)
    return
## 开始副本关卡
def StartFBLevel(curPlayer, fbLevel, tick):
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
        GameWorld.DebugLog("复活玩家...", curPlayer.GetPlayerID())
        ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_City, tick)
    curPlayer.SetHP(curPlayer.GetMaxHP())
    FBCommon.ClearFBNPC()
    gameFB = GameWorld.GetGameFB()
    gameFB.SetGameFBDict(FBDict_Level, fbLevel)
    playerPower = curPlayer.GetFightPower()
    ipyData = GetTowerIpyData(fbLevel)
    needPower = ipyData.GetNeedPower()
    totalHP = eval(IpyGameDataPY.GetFuncCompileCfg('ZhuXianTowerBossTime'))
    gameFB.SetGameFBDict(FBDict_BossTotalHP, totalHP * 1000)
    gameFB.SetGameFBDict(FBDict_Speed, 1000)  #速度默认1000
    gameFB.SetGameFBDict(FBDict_RemainHP, totalHP * 1000)
    prepareTick = __GetZhuXianCfg()[Def_PrepareTime] * 1000
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttAddUpTime, prepareTick)
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, prepareTick)
    FBCommon.SetFBStep(FB_State_FightPrepare, tick)
    DoFBHelp(curPlayer, tick)
    GameWorld.DebugLog("StartFBLevel, fbLevel=%s,totalHP=%s" % (fbLevel, totalHP), curPlayer.GetPlayerID())
    return
##战斗时间
# @param tick  时钟
# @return 无意义
def __DoLogic_Fighting(tick):
    gameFB = GameWorld.GetGameFB()
    #判断时间结束
    if tick - gameFB.GetFBStepTick() < __GetZhuXianCfg()[Def_FightTime] * 1000:
        lastHurtTick = gameFB.GetGameFBDictByKey(FBDict_LastHurtTick)
        if lastHurtTick and tick - lastHurtTick >= 2000:
            StopReduceHP(tick)
            GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, 0)
        return
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)
    playerManager = GameWorld.GetMapCopyPlayerManager()
    for index in xrange(playerManager.GetPlayerCount()):
        curPlayer = playerManager.GetPlayerByIndex(index)
        if not curPlayer:
            continue
        __SendZhuXianTowerOverInfo(curPlayer, fbLevel, False)
    #游戏结束
    __SetFBToFreeTime(tick)
    return
##设置副本进入离开状态
# @param tick  时钟
# @return 无意义
def __SetFBToFreeTime(tick):
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, __GetZhuXianCfg()[Def_ExitTime] * 1000)
    FBCommon.SetFBStep(FB_State_FreeTime, tick)
    return
##比赛结束的空闲时间
# @param tick  时钟
# @return 无意义
# @remarks 比赛结束的空闲时间
def __DoLogic_FreeTime(tick):
    if tick - GameWorld.GetGameFB().GetFBStepTick() < __GetZhuXianCfg()[Def_ExitTime] * 1000:
        return
    #FBCommon.DoLogic_FBKickAllPlayer()
    return
def DoZhuXianTowerOver(tick):
    gameFB = GameWorld.GetGameFB()
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)
    # 过关全服广播
    ipyData = GetTowerIpyData(fbLevel)
    if not ipyData:
        return
    curPlayer = FBCommon.GetCurSingleFBPlayer()
    if not curPlayer:
        GameWorldProcess.CloseFB(tick)
        return
    # 记录过关
    #EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower, 0, ChConfig.CME_Log_End, 0, 1)
    unLockEquipPlace = ipyData.GetUnLockEquipPlace()
    if unLockEquipPlace:
        PlayerControl.WorldNotify(0, 'KillGodTowerInfo_1', [curPlayer.GetPlayerName(), fbLevel, unLockEquipPlace])
    ipyMgr = IpyGameDataPY.IPY_Data()
    maxFloor = ipyMgr.GetZhuXianTowerByIndex(ipyMgr.GetZhuXianTowerCount() - 1).GetID()
    # 过关时间
    costTime = tick - GameWorld.GetGameFB().GetFBStepTick()
    curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)
    isFirstS = 0
    if fbLevel < maxFloor and curStar == Def_MaxStar:
        #更新关卡
        SetZhuXianTowerCurPassLV(curPlayer, fbLevel)
        #更新诛仙塔排行榜
        PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_ZhuXianTower, fbLevel, costTime/1000)
        isFirstS = 1  #是否首次S通关
    gameFB.SetGameFBDict(FBDict_isFirstS, isFirstS)
    # 给过关奖励
    prizeItemList = __GiveFBPassPrize(curPlayer, False)
    prizeDict = {FBCommon.Over_costTime:costTime, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(prizeItemList)}
    __SendZhuXianTowerOverInfo(curPlayer, fbLevel, True if prizeItemList else False, prizeDict)
    #任务
    #EventShell.EventRespons_ZhuXianTowerCnt(curPlayer, fbLevel)
    SyncZhuXianLevelInfo(curPlayer)  # 同步最新关卡信息
    __SetFBToFreeTime(tick)
    #每日任务
    #PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_Tower)
    return
## 杀怪
#  @param curPlayer
#  @param curNPC 被杀的怪
#  @param tick
#  @return None
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
    return
## 给过关奖励
def __GiveFBPassPrize(curPlayer, isGive=True):
    gameFB = GameWorld.GetGameFB()
    preFloor = gameFB.GetGameFBDictByKey(FBDict_Level)
    ipyData = GetTowerIpyData(preFloor)
    if not ipyData:
        return []
    isFirstPass = gameFB.GetGameFBDictByKey(FBDict_isFirstS)  #是否首次s通关
    if isFirstPass:
        prizeItemList = ipyData.GetFirstAward()
    else:
        curStar = gameFB.GetGameFBDictByKey(FBDict_FBStar)
        prizeItemList = ipyData.GetGradeAward().get(curStar, [])
    if not prizeItemList:
        return []
    if not isGive:
        return prizeItemList
    if gameFB.GetGameFBDictByKey(FBDict_HasGiveAward):
        GameWorld.Log('本层奖励已给,不能重复给!!', curPlayer.GetID())
        return
    # 发邮件或放入背包
    needSpace = len(prizeItemList)
    emptySpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
    isSendMail = int(needSpace > emptySpace)  # 是否发送邮件
    if isSendMail:
        PlayerControl.SendMailByKey('KillGodTowerReward', [curPlayer.GetPlayerID()], prizeItemList)
        GameWorld.DebugLog("背包空间不够,发送邮件: mailItemList=%s" % str(prizeItemList), curPlayer.GetPlayerID())
    else:
        for itemID, itemCnt, isBind in prizeItemList:
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem],
                                            event=["ZhuXianTower", False, {}])
    FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_ZhuXianTower, 1)
    gameFB.SetGameFBDict(FBDict_HasGiveAward, 1)
    return
##副本帮助信息
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 无意义
# @remarks 用于通知阵营比分条
def DoFBHelp(curPlayer, tick):
    gameFB = GameWorld.GetGameFB()
    star = gameFB.GetGameFBDictByKey(FBDict_FBStar)
    curSpeed = gameFB.GetGameFBDictByKey(FBDict_Speed)
    isReduceing = gameFB.GetGameFBDictByKey(FBDict_IsReduceing)
    remainHP = GetBossRemainHP(tick)
    totalHP = __GetBossTotalHP()
    hpReduceSpeed = curSpeed * 10000 / totalHP if totalHP else 0
    remainHPPer = min(100, remainHP * 100 / totalHP) if totalHP else 0
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)
    fbHelpDict = {FBCommon.Help_wheel:fbLevel, FBCommon.Help_grade:star, 'hpReduceSpeed':hpReduceSpeed, 'remainHPPer':remainHPPer, 'isReduceing':isReduceing}
    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
    return
## 发送挑战结果信息
def __SendZhuXianTowerOverInfo(curPlayer, fbLevel, isPass, overDict={}):
    overDict[FBCommon.Over_dataMapID] = ChConfig.Def_FBMapID_ZhuXianTower
    overDict[FBCommon.Over_wheel] = fbLevel
    overDict[FBCommon.Over_isPass] = int(isPass)
    GameWorld.DebugLog("__SendZhuXianTowerOverInfo overDict=%s" % (str(overDict)), curPlayer.GetPlayerID())
    FBCommon.Notify_FB_Over(curPlayer, overDict)
    return
## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
#  @param attacker 攻击方
#  @param defender 防守方
#  @return bool
def CheckCanAttackTagObjInFB(attacker, defender):
    gameFB = GameWorld.GetGameFB()
    if gameFB.GetFBStep() != FB_State_Fighting:
        return False
    return True
##玩家死亡.
# @param curPlayer:死亡的玩家
# @param tick 时间戳
# @return 返回值无意义
# @remarks 玩家主动离开副本.
def DoPlayerDead(curPlayer):
    gameFB = GameWorld.GetGameFB()
    fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)
    __SendZhuXianTowerOverInfo(curPlayer, fbLevel, False)
    tick = GameWorld.GetGameWorld().GetTick()
    #游戏结束
    __SetFBToFreeTime(tick)
    return
## 是否副本复活
#  @param None
#  @return 是否副本复活
def OnPlayerReborn():
    return True
## 副本行为
#  @param curPlayer 玩家
#  @param actionType 行为类型
#  @param actionInfo 行为信息
#  @param tick 当前时间
#  @return None
def DoFBAction(curPlayer, actionType, actionInfo, tick):
    # 默认为选择关卡,由客户端决定,进场及副本选关通用此行为
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if actionType == 0:
        if fbStep in [FB_State_FightPrepare, FB_State_Fighting]:
            GameWorld.DebugLog("准备或战斗中, 无法变更关卡!")
            return
        newFloor = __CheckCanChallenge(curPlayer)
        if not newFloor:
            FBCommon.DoLogic_FBKickAllPlayer()
            return
        StartFBLevel(curPlayer, newFloor, tick)
    elif actionType == 1:
        #领取奖励
        if fbStep != FB_State_FreeTime:
            return
        __GiveFBPassPrize(curPlayer, False)
    return
def __CheckBossHP(tick):
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep == FB_State_Fighting and GetBossRemainHP(tick) == 0:
        #结束 设置BOSS死亡
        FBCommon.ClearFBNPC()
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
        GameWorld.DebugLog('结束 设置BOSS死亡 ')
        DoZhuXianTowerOver(tick)
    return
def StopReduceHP(tick):
    ##暂停BOSS血量减少
    gameFB = GameWorld.GetGameFB()
    if not gameFB.GetGameFBDictByKey(FBDict_IsReduceing):
        return
    remainHP = GetBossRemainHP(tick)
    if not remainHP:
        return
    gameFB.SetGameFBDict(FBDict_IsReduceing, 0)
    gameFB.SetGameFBDict(FBDict_RemainHP, remainHP)
    GameWorld.DebugLog('    暂停BOSS血量减少')
    return
def StartReduceHP(tick):
    ##开始BOSS掉血
    gameFB = GameWorld.GetGameFB()
    if gameFB.GetGameFBDictByKey(FBDict_IsReduceing):
        return
    gameFB.SetGameFBDict(FBDict_IsReduceing, 1)
    startTick = gameFB.GetGameFBDictByKey(FBDict_StartTick)
    if not startTick:
        gameFB.SetGameFBDict(FBDict_RemainHP, __GetBossTotalHP())
    gameFB.SetGameFBDict(FBDict_StartTick, tick)
    GameWorld.DebugLog('    开始BOSS掉血')
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
    return
def __GetBossTotalHP():return GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_BossTotalHP)
def GetBossRemainHP(tick):
    gameFB = GameWorld.GetGameFB()
    startTick = gameFB.GetGameFBDictByKey(FBDict_StartTick)
    lastSpeed = gameFB.GetGameFBDictByKey(FBDict_Speed)
    remainHP = gameFB.GetGameFBDictByKey(FBDict_RemainHP)
    if not gameFB.GetGameFBDictByKey(FBDict_IsReduceing):
        return remainHP
    if not startTick:
        startTick = tick
        remainHP = __GetBossTotalHP()
    else:
        remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))
    return remainHP
## 玩家对NPC造成伤害
#  @param curPlayer 当前玩家
#  @param curNPC
#  @param hurtHP
#  @return None
def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
    tick = GameWorld.GetGameWorld().GetTick()
    GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, tick)
    StartReduceHP(tick)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1249,6 +1249,15 @@
                        ("WORD", "RealmLV", 0),
                        ("DWORD", "ZhuXianScore", 0),
                        ),
                "ZhuXianTower":(
                        ("DWORD", "ID", 1),
                        ("DWORD", "NPCID", 0),
                        ("list", "FirstAward", 0),
                        ("dict", "GradeAward", 0),
                        ("WORD", "UnLockEquipPlace", 0),
                        ("DWORD", "NeedPower", 0),
                        ),
                }
@@ -3806,6 +3815,25 @@
    def GetKillTime(self): return self.KillTime # 击杀总时间秒
    def GetRealmLV(self): return self.RealmLV # 需要境界
    def GetZhuXianScore(self): return self.ZhuXianScore # 需要诛仙总评分
# 诛仙塔表
class IPY_ZhuXianTower():
    def __init__(self):
        self.ID = 0
        self.NPCID = 0
        self.FirstAward = []
        self.GradeAward = {}
        self.UnLockEquipPlace = 0
        self.NeedPower = 0
        return
    def GetID(self): return self.ID # 塔编号
    def GetNPCID(self): return self.NPCID # npcid
    def GetFirstAward(self): return self.FirstAward # 首次S级奖励
    def GetGradeAward(self): return self.GradeAward # 评级奖励
    def GetUnLockEquipPlace(self): return self.UnLockEquipPlace # 解锁的装备位
    def GetNeedPower(self): return self.NeedPower # 推荐战力
def Log(msg, playerID=0, par=0):
@@ -4069,6 +4097,8 @@
        self.ipyLoginAwardLen = len(self.ipyLoginAwardCache)
        self.ipyZhuXianBossCache = self.__LoadFileData("ZhuXianBoss", IPY_ZhuXianBoss)
        self.ipyZhuXianBossLen = len(self.ipyZhuXianBossCache)
        self.ipyZhuXianTowerCache = self.__LoadFileData("ZhuXianTower", IPY_ZhuXianTower)
        self.ipyZhuXianTowerLen = len(self.ipyZhuXianTowerCache)
        Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict))
        Log("IPY_DataMgr InitOK!")
        return
@@ -4473,6 +4503,8 @@
    def GetLoginAwardByIndex(self, index): return self.ipyLoginAwardCache[index]
    def GetZhuXianBossCount(self): return self.ipyZhuXianBossLen
    def GetZhuXianBossByIndex(self, index): return self.ipyZhuXianBossCache[index]
    def GetZhuXianTowerCount(self): return self.ipyZhuXianTowerLen
    def GetZhuXianTowerByIndex(self, index): return self.ipyZhuXianTowerCache[index]
IPYData = IPY_DataMgr()
def IPY_Data(): return IPYData
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -570,6 +570,8 @@
    Def_BT_Campaign_Recharge,                 #累计充值(开服活动榜)
    Def_BT_Campaign_PetLV,                    #灵宠等级(开服活动榜)
    
    Def_BT_ZhuXianTower,                      #诛仙塔榜
    Def_BT_HighLadder,                        #天梯竞技场排行
    Def_BT_HighLadder_Yester,                 #天梯竞技场昨日排行
    Def_BT_RechargeTeHuiLast,                 #充值特惠活动排行榜-上一期记录
@@ -584,7 +586,7 @@
    Def_BT_CostTeHuiLast,                     #消费特惠排行榜上一期
    
    Def_BT_Max,                               #排行榜最大类型
) = range(0, 32 + 2)
) = range(0, 33 + 2)
    
#职业对应战力排行榜类型
JobFightPowerBillboardDict = {
@@ -596,7 +598,7 @@
#排行榜Value1存储境界信息的榜单列表
BTValue1_OfficialRankList = [Def_BT_FightPower, Def_BT_FightPower_Warrior, Def_BT_FightPower_Wizard, Def_BT_FightPower_Assassin, 
                             Def_BT_LV, Def_BT_FightPower_Horse, Def_BT_FightPower_Pet, Def_BT_TrialTower, Def_BT_OffLineEfficient,
                             Def_BT_FBHelpBattle,
                             Def_BT_FBHelpBattle, Def_BT_ZhuXianTower,
                             ]
##---比率---