hxp
2023-10-25 ee017bc9f5435bf6de2e28aab2cb5d3edc430d95
9964 【BT0.1】【主干】境界塔
5个文件已修改
2个文件已添加
499 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/RealmTower.py 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_RealmTower.py 310 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -90,6 +90,16 @@
    BYTE        AddFreePoint;    //增加自由属性点
};
//境界塔表
struct tagRealmTower
{
    DWORD        _FloorID;    //层
    WORD        NeedRealmLV;    //所需境界
    DWORD        BossID;    //BossID
    list        RewardItemList;    //奖励物品列表
};
//境界炼体属性表
struct tagLianTi
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -44522,6 +44522,58 @@
#------------------------------------------------------
# B2 17 境界塔信息 #tagMCRealmTowerInfo
class  tagMCRealmTowerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Floor", c_int),    # 已通关层
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x17
        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 = 0x17
        self.Floor = 0
        return
    def GetLength(self):
        return sizeof(tagMCRealmTowerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 17 境界塔信息 //tagMCRealmTowerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                Floor:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Floor
                                )
        return DumpString
m_NAtagMCRealmTowerInfo=tagMCRealmTowerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCRealmTowerInfo.Cmd,m_NAtagMCRealmTowerInfo.SubCmd))] = m_NAtagMCRealmTowerInfo
#------------------------------------------------------
# B2 13 天星塔通关层数 #tagMCSkyTowerInfo
class  tagMCSkyTowerServerReward(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1820,6 +1820,8 @@
Def_FBMapID_ZhuXianBoss = 31380
#天星塔/丹塔
Def_FBMapID_SkyTower = 31370
#境界塔
Def_FBMapID_RealmTower = 31310
#仙魔之争
Def_FBMapID_XMZZ = 31010
#神兽副本
@@ -1979,6 +1981,7 @@
                'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
                'ZhuXianBoss':[Def_FBMapID_ZhuXianBoss],#诛仙BOSS
                'SkyTower':[Def_FBMapID_SkyTower],#天星塔
                'RealmTower':[Def_FBMapID_RealmTower],#境界塔
                'AllFamilyBoss':[Def_FBMapID_AllFamilyBoss],#多仙盟BOSS
                'HorsePetBoss':[Def_FBMapID_HorsePetBoss],#骑宠BOSS
                'FairyTreasure':[Def_FBMapID_FairyTreasure],#缥缈宝藏
@@ -3772,6 +3775,9 @@
Def_Player_Dict_SkyTowerFloor = "SkyTowerFloor"  # 天星塔已通关层数
Def_Player_Dict_SkyTowerServerRecord = "SkyTowerServerRecord_%s"  # 天星塔全服挑战层领奖记录,参数(层)
#境界塔
Def_Player_Dict_RealmTowerFloor = "RealmTowerFloor"  # 已通关层数
#古神禁地
Def_Player_Dict_GodArea_Anger = "GodArea_Anger"  # 古神禁地怒气值
Def_Player_Dict_GodArea_LastAddAngerTime = "GodArea_LastAddAngerTime"  # 古神禁地上一次增加怒气值的时间
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -44522,6 +44522,58 @@
#------------------------------------------------------
# B2 17 境界塔信息 #tagMCRealmTowerInfo
class  tagMCRealmTowerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Floor", c_int),    # 已通关层
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x17
        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 = 0x17
        self.Floor = 0
        return
    def GetLength(self):
        return sizeof(tagMCRealmTowerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 17 境界塔信息 //tagMCRealmTowerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                Floor:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Floor
                                )
        return DumpString
m_NAtagMCRealmTowerInfo=tagMCRealmTowerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCRealmTowerInfo.Cmd,m_NAtagMCRealmTowerInfo.SubCmd))] = m_NAtagMCRealmTowerInfo
#------------------------------------------------------
# B2 13 天星塔通关层数 #tagMCSkyTowerInfo
class  tagMCSkyTowerServerReward(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/RealmTower.py
New file
@@ -0,0 +1,43 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.RealmTower
#
# @todo:境界塔
# @author hxp
# @date 2023-10-25
# @version 1.0
#
# 详细描述: 境界塔
#
#-------------------------------------------------------------------------------
#"""Version = 2023-10-25 01:30"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerControl
import GameLogic_RealmTower
import ChConfig
## 逻辑实现
## GM命令执行入口
#  @param curPlayer
#  @param cmdList 参数列表
#  @return None
def OnExec(curPlayer, cmdList):
    if not cmdList:
        GameWorld.DebugAnswer(curPlayer, "设置境界塔层: RealmTower 层")
        return
    floorID = cmdList[0]
    if not GameLogic_RealmTower.GetTowerIpyData(floorID):
        GameWorld.DebugAnswer(curPlayer, "不存在该层")
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RealmTowerFloor, floorID)
    GameLogic_RealmTower.SyncRealmTowerInfo(curPlayer)
    GameWorld.DebugAnswer(curPlayer, "境界塔层设置 floorID=%s" % floorID)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_RealmTower.py
New file
@@ -0,0 +1,310 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameWorldLogic.FBProcess.GameLogic_RealmTower
#
# @todo:境界塔
# @author hxp
# @date 2023-10-25
# @version 1.0
#
# 详细描述: 境界塔
#
#-------------------------------------------------------------------------------
#"""Version = 2023-10-25 01:30"""
#-------------------------------------------------------------------------------
import FBCommon
import GameWorld
import IPY_GameWorld
import PlayerControl
import NetPackCommon
import NPCCustomRefresh
import GameWorldProcess
import ChPyNetSendPack
import ItemControler
import IpyGameDataPY
import ChConfig
import ChPlayer
import GameObj
FBDict_Floor = 'FBDict_Floor'   # 副本关卡
# 副本通用配置
(
Def_PrepareTime, # 每关准备时间,秒
Def_FightTime, # 每关战斗时间,秒
Def_ExitTime, # 退出时间, 秒
) = range(3)
# 副本状态
(
FB_State_Open, # 副本开启
FB_State_FightPrepare, # 战斗准备时间
FB_State_Fighting, # 战斗
FB_State_FreeTime, # 活动结束准备(胜利/失败)
FB_State_Close, # 关闭副本
) = range(5)
def __GetFBTimelCfg(): return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_RealmTower)
def GetTowerIpyData(floor): return IpyGameDataPY.GetIpyGameData("RealmTower", floor)
def OnFBPlayerOnLogin(curPlayer):
    SyncRealmTowerInfo(curPlayer)
    return
def SyncRealmTowerInfo(curPlayer):
    clientPack = ChPyNetSendPack.tagMCRealmTowerInfo()
    clientPack.Clear()
    clientPack.Floor = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def OnEnterFBEvent(curPlayer, mapID, lineId, tick):
    nextFloorID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor) + 1
    return __CheckCanChallenge(curPlayer, nextFloorID)
## 检查可否进行挑战
def __CheckCanChallenge(curPlayer, floorID):
    playerID = curPlayer.GetPlayerID()
    ipyData = GetTowerIpyData(floorID)
    if not ipyData:
        GameWorld.ErrLog("境界塔层不存在: floorID=%s" % floorID, playerID)
        return False
    curFloorID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor)
    if floorID <= curFloorID:
        GameWorld.DebugLog("该境界塔层已过关: floorID=%s" % floorID, playerID)
        return False
    if floorID > curFloorID + 1:
        GameWorld.DebugLog("上一层未过关: floorID=%s > curFloorID=%s+1" % (floorID, curFloorID), playerID)
        return False
    if curPlayer.GetOfficialRank() < ipyData.GetNeedRealmLV():
        GameWorld.DebugLog("该境界塔层所需境界不足: floorID=%s,NeedRealmLV=%s" % (floorID, ipyData.GetNeedRealmLV()), playerID)
        return False
    return True
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
    return ipyEnterPosInfo
def OnChangeMapAsk(ask, tick):
    return IPY_GameWorld.cmeAccept
def DoEnterFB(curPlayer, tick):
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep == FB_State_FightPrepare:
        notify_tick = __GetFBTimelCfg()[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 = __GetFBTimelCfg()[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
        curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
    elif fbStep > FB_State_Fighting:
        PlayerControl.PlayerLeaveFB(curPlayer)
        return
    # 不做处理,有副本行为客户端发包选择挑战关卡
    return
def OnCloseFB(tick):
    return
def DoExitFB(curPlayer, tick):
    # 玩家退出默认关闭副本
    GameWorldProcess.CloseFB(tick)
    return
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)
    elif fbStep == FB_State_FreeTime:
        __DoLogic_FreeTime(tick)
    elif fbStep == FB_State_Close:
        pass
    return
## 获取BossID
def __GetRealmTowerBossID():
    gameFB = GameWorld.GetGameFB()
    floorID = gameFB.GetGameFBDictByKey(FBDict_Floor)
    ipyData = GetTowerIpyData(floorID)
    if not ipyData:
        GameWorld.ErrLog("__GetRealmTowerBossID() can not find %s in RealmTowerNPC.txt" % floorID)
        return 0
    return ipyData.GetBossID()
##战斗准备时间
# @param tick  时钟
# @return 无意义
def __DoLogic_FightPrepare(tick):
    gameFB = GameWorld.GetGameFB()
    trialCfg = __GetFBTimelCfg()
    if tick - gameFB.GetFBStepTick() < trialCfg[Def_PrepareTime] * 1000:
        return
    bossID = __GetRealmTowerBossID()
    if not bossID:
        FBCommon.DoLogic_FBKickAllPlayer()
        return
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, trialCfg[Def_FightTime] * 1000)
    NPCCustomRefresh.SetNPCRefresh(FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_RealmTower, 0), [bossID])
    #转入战斗
    FBCommon.SetFBStep(FB_State_Fighting, tick)
    return
## 开始副本关卡
def StartfloorID(curPlayer, floorID, tick):
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
        GameWorld.DebugLog("复活玩家...", curPlayer.GetPlayerID())
        ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_City, tick)
    GameObj.SetHPFull(curPlayer)
    FBCommon.ClearFBNPC()
    gameFB = GameWorld.GetGameFB()
    gameFB.SetGameFBDict(FBDict_Floor, floorID)
    prepareTick = __GetFBTimelCfg()[Def_PrepareTime] * 1000
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, prepareTick)
    FBCommon.SetFBStep(FB_State_FightPrepare, tick)
    helpDict = {FBCommon.Help_wheel:floorID}
    FBCommon.Notify_FBHelp(curPlayer, helpDict)
    GameWorld.DebugLog("StartfloorID, floorID=%s, helpDict=%s" % (floorID, str(helpDict)), curPlayer.GetPlayerID())
    return
def __DoLogic_Fighting(tick):
    gameFB = GameWorld.GetGameFB()
    #判断时间结束
    if tick - gameFB.GetFBStepTick() < __GetFBTimelCfg()[Def_FightTime] * 1000:
        return
    floorID = gameFB.GetGameFBDictByKey(FBDict_Floor)
    playerManager = GameWorld.GetMapCopyPlayerManager()
    for index in xrange(playerManager.GetPlayerCount()):
        curPlayer = playerManager.GetPlayerByIndex(index)
        if not curPlayer:
            continue
        __SendRealmTowerOverInfo(curPlayer, floorID, False)
    #游戏结束
    __SetFBToFreeTime(tick)
    return
def __SetFBToFreeTime(tick):
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, __GetFBTimelCfg()[Def_ExitTime] * 1000)
    FBCommon.SetFBStep(FB_State_FreeTime, tick)
    return
def __DoLogic_FreeTime(tick):
    if tick - GameWorld.GetGameFB().GetFBStepTick() < __GetFBTimelCfg()[Def_ExitTime] * 1000:
        return
    return
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
    gameFB = GameWorld.GetGameFB()
    if gameFB.GetFBStep() != FB_State_Fighting:
        return
    bossID = __GetRealmTowerBossID()
    if bossID != curNPC.GetNPCID():
        return
    floorID = gameFB.GetGameFBDictByKey(FBDict_Floor)
    # 过关全服广播
    ipyData = GetTowerIpyData(floorID)
    if not ipyData:
        return
    #更新关卡
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RealmTowerFloor, floorID)
    GameWorld.DebugLog('更新境界塔已通关数 %s' % floorID)
    # 给过关奖励
    giveItemList = ipyData.GetRewardItemList()
    ItemControler.GivePlayerItemOrMail(curPlayer, giveItemList, None, ["RealmTower", False, {}])
    prizeDict = {FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(giveItemList)}
    # 过关时间
    costTime = tick - GameWorld.GetGameFB().GetFBStepTick()
    prizeDict[FBCommon.Over_costTime] = costTime
    __SendRealmTowerOverInfo(curPlayer, floorID, True, prizeDict)
    SyncRealmTowerInfo(curPlayer)
    __SetFBToFreeTime(tick)
    return
## 发送挑战结果信息
def __SendRealmTowerOverInfo(curPlayer, floorID, isPass, overDict={}):
    overDict[FBCommon.Over_dataMapID] = ChConfig.Def_FBMapID_RealmTower
    overDict[FBCommon.Over_wheel] = floorID
    overDict[FBCommon.Over_isPass] = int(isPass)
    GameWorld.DebugLog("__SendRealmTowerOverInfo 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
##玩家死亡
def DoPlayerDead(curPlayer):
    gameFB = GameWorld.GetGameFB()
    floorID = gameFB.GetGameFBDictByKey(FBDict_Floor)
    __SendRealmTowerOverInfo(curPlayer, floorID, False)
    tick = GameWorld.GetGameWorld().GetTick()
    #游戏结束
    __SetFBToFreeTime(tick)
    return
## 是否副本复活
def OnPlayerReborn():
    return True
## 副本行为
def DoFBAction(curPlayer, actionType, actionInfo, tick):
    # 默认为选择关卡,由客户端决定,进场及副本选关通用此行为
    if actionInfo <= 0:
        return
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep in [FB_State_FightPrepare, FB_State_Fighting]:
        GameWorld.DebugLog("准备或战斗中, 无法变更关卡!")
        return
    floorID = actionInfo
    if not __CheckCanChallenge(curPlayer, floorID):
        FBCommon.DoLogic_FBKickAllPlayer()
        return
    StartfloorID(curPlayer, floorID, tick)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -103,6 +103,13 @@
                        ("BYTE", "AddFreePoint", 0),
                        ),
                "RealmTower":(
                        ("DWORD", "FloorID", 1),
                        ("WORD", "NeedRealmLV", 0),
                        ("DWORD", "BossID", 0),
                        ("list", "RewardItemList", 0),
                        ),
                "LianTi":(
                        ("BYTE", "LianTiLV", 1),
                        ("list", "FixedAttrType", 0),
@@ -2326,6 +2333,21 @@
    def GetExpLimit(self): return self.ExpLimit # 修为池经验上限
    def GetLearnSkillIDInfo(self): return self.LearnSkillIDInfo # 学习技能ID信息 {"职业":[技能ID, ...], ...}
    def GetAddFreePoint(self): return self.AddFreePoint # 增加自由属性点
# 境界塔表
class IPY_RealmTower():
    def __init__(self):
        self.FloorID = 0
        self.NeedRealmLV = 0
        self.BossID = 0
        self.RewardItemList = []
        return
    def GetFloorID(self): return self.FloorID # 层
    def GetNeedRealmLV(self): return self.NeedRealmLV # 所需境界
    def GetBossID(self): return self.BossID # BossID
    def GetRewardItemList(self): return self.RewardItemList # 奖励物品列表
# 境界炼体属性表
class IPY_LianTi():
@@ -6726,6 +6748,8 @@
        self.ipyRealmXXZLLen = len(self.ipyRealmXXZLCache)
        self.ipyRealmCache = self.__LoadFileData("Realm", IPY_Realm)
        self.ipyRealmLen = len(self.ipyRealmCache)
        self.ipyRealmTowerCache = self.__LoadFileData("RealmTower", IPY_RealmTower)
        self.ipyRealmTowerLen = len(self.ipyRealmTowerCache)
        self.ipyLianTiCache = self.__LoadFileData("LianTi", IPY_LianTi)
        self.ipyLianTiLen = len(self.ipyLianTiCache)
        self.ipyGodWeaponCache = self.__LoadFileData("GodWeapon", IPY_GodWeapon)
@@ -7336,6 +7360,8 @@
    def GetRealmXXZLByIndex(self, index): return self.ipyRealmXXZLCache[index]
    def GetRealmCount(self): return self.ipyRealmLen
    def GetRealmByIndex(self, index): return self.ipyRealmCache[index]
    def GetRealmTowerCount(self): return self.ipyRealmTowerLen
    def GetRealmTowerByIndex(self, index): return self.ipyRealmTowerCache[index]
    def GetLianTiCount(self): return self.ipyLianTiLen
    def GetLianTiByIndex(self, index): return self.ipyLianTiCache[index]
    def GetGodWeaponCount(self): return self.ipyGodWeaponLen