hxp
2026-01-07 b0a1a6c78f4f7b3a2b83544b9e1bb664878179fc
129 【战斗】战斗系统-服务端(支持查看NPC属性;)
4个文件已修改
337 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1205,7 +1205,7 @@
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 3
RegisterPackCount = 4
PacketCMD_1=0xB4
PacketSubCMD_1=0x10
@@ -1219,6 +1219,10 @@
PacketSubCMD_3=0x14
PacketCallFunc_3=OnTurnFightReportView
PacketCMD_4=0xB4
PacketSubCMD_4=0x16
PacketCallFunc_4=OnViewNPCAttr
;仙树
[PlayerTree]
ScriptName = Player\PlayerTree.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -646,11 +646,12 @@
    lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType, "Hero":heroDict}
    return lineupInfo
def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0, isLog=True):
def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0, isLog=True, viewNPCID=0):
    ## 获取NPC阵容信息
    # @param lineupID: 阵容ID
    # @param npcLV: 成长NPC等级
    # @param difficulty: 成长NPC难度系数
    # @param viewNPCID: 查看指定的NPCID,供前端查询NPC属性用
    # @return: 阵容全部信息json字典,前端通用格式    
    lineupInfo = GetGMTestNPCLineupInfo(lineupID, strongerLV, difficulty)
    if lineupInfo:
@@ -668,10 +669,14 @@
        npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)()
        if not npcID:
            continue
        if viewNPCID and viewNPCID != npcID:
            continue
        battleDict = GetNPCBattleDict(ipyData, npcID, strongerLV, difficulty, isLog)
        if not battleDict:
            continue
        heroDict[str(posNum)] = battleDict
        if viewNPCID:
            break
        
    lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict, "BossID":bossID, "BossPosView":bossPosView}
    return lineupInfo
@@ -850,8 +855,8 @@
                  "SkinID":skinID,
                  "LV":npcLV,
                  "Star":star,
                  #"BreakLV":breakLV,
                  #"AwakeLV":awakeLV,
                  "BreakLV":breakLV,
                  "AwakeLV":awakeLV,
                  "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0},
                  "SkillIDList":skillIDList,
                  }
@@ -2185,6 +2190,82 @@
    PlayerControl.NotifyCode(curPlayer, "FightReportExpired")
    return
#// B4 16 查看NPC属性 #tagCSViewNPCAttr
#
#struct    tagCSViewNPCAttr
#{
#    tagHead        Head;
#    DWORD        MapID;        // 自定义地图ID,可用于绑定战斗地图场景功能(如主线boss、爬塔、竞技场等)
#    DWORD        FuncLineID;    // MapID对应的扩展值,如具体某个关卡等
#    DWORD        ViewNPCID;    // 指定查看某个NPCID,发0则查看该关卡阵容所有NPC
#};
def OnViewNPCAttr(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    mapID = clientData.MapID
    funcLineID = clientData.FuncLineID
    viewNPCID = clientData.ViewNPCID
    SyncLineupNPCAttr(curPlayer, mapID, funcLineID, viewNPCID)
    return
def SyncLineupNPCAttr(curPlayer, mapID, funcLineID, viewNPCID=0):
    lineupIDList = []
    strongerLV, difficulty = 0, 0
    if mapID == ChConfig.Def_FBMapID_MainBoss:
        chapterID = funcLineID / 100
        levelNum = funcLineID % 100
        levelIpyData = IpyGameDataPY.GetIpyGameData("MainLevel", chapterID, levelNum)
        if not levelIpyData:
            return
        lineupIDList = levelIpyData.GetBossLineupIDList() # Boss波阵容ID列表,小队1阵容ID|小队2阵容ID|...
        strongerLV = levelIpyData.GetNPCLV()
        difficulty = levelIpyData.GetDifficulty()
    else:
        fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, funcLineID)
        if fbLineIpyData:
            lineupIDList = fbLineIpyData.GetLineupIDList()
            strongerLV = fbLineIpyData.GetNPCLV()
            difficulty = fbLineIpyData.GetDifficulty()
        else:
            ret = FBLogic.GetFBNPCLineupInfo(curPlayer, mapID, funcLineID)
            if not ret:
                return
            lineupIDList, strongerLV, difficulty = ret
    if not lineupIDList:
        return
    npcAttrList = []
    for lineupID in lineupIDList:
        lineupInfo = GetNPCLineupInfo(lineupID, strongerLV, difficulty, False, viewNPCID=viewNPCID)
        if not lineupInfo:
            continue
        heroDict = lineupInfo["Hero"]
        for posNum, attrInfo in heroDict.items():
            posNum = int(posNum)
            npcAttr = ChPyNetSendPack.tagSCViewNPCAttr()
            npcAttr.PosNum = posNum
            npcAttr.NPCID = attrInfo["NPCID"]
            npcAttr.HeroID = attrInfo["HeroID"]
            npcAttr.LV = attrInfo["LV"]
            npcAttr.Star = attrInfo["Star"]
            npcAttr.BreakLV = attrInfo["BreakLV"]
            npcAttr.AwakeLV = attrInfo["AwakeLV"]
            npcAttr.AttrMsg = json.dumps(attrInfo["AttrDict"], ensure_ascii=False).replace(" ", "")
            npcAttr.AttrLen = len(npcAttr.AttrMsg)
            npcAttrList.append(npcAttr)
    if not npcAttrList:
        return
    clientPack = ChPyNetSendPack.tagSCViewNPCAttrRet()
    clientPack.MapID = mapID
    clientPack.FuncLineID = funcLineID
    clientPack.ViewNPCID = viewNPCID
    clientPack.NPCAttrList = npcAttrList
    clientPack.NPCCnt = len(clientPack.NPCAttrList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def SyncTurnFightReport(curPlayer, guid, reprot):
    ## 通知完整战报
    clientPack = ChPyNetSendPack.tagSCTurnFightReport()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -15177,6 +15177,66 @@
#------------------------------------------------------
# B4 16 查看NPC属性 #tagCSViewNPCAttr
class  tagCSViewNPCAttr(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("MapID", c_int),    # 自定义地图ID,可用于绑定战斗地图场景功能(如主线boss、爬塔、竞技场等)
                  ("FuncLineID", c_int),    # MapID对应的扩展值,如具体某个关卡等
                  ("ViewNPCID", c_int),    # 指定查看某个NPCID,发0则查看该关卡阵容所有NPC
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB4
        self.SubCmd = 0x16
        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 = 0xB4
        self.SubCmd = 0x16
        self.MapID = 0
        self.FuncLineID = 0
        self.ViewNPCID = 0
        return
    def GetLength(self):
        return sizeof(tagCSViewNPCAttr)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B4 16 查看NPC属性 //tagCSViewNPCAttr:
                                Cmd:%s,
                                SubCmd:%s,
                                MapID:%d,
                                FuncLineID:%d,
                                ViewNPCID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.MapID,
                                self.FuncLineID,
                                self.ViewNPCID
                                )
        return DumpString
m_NAtagCSViewNPCAttr=tagCSViewNPCAttr()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSViewNPCAttr.Cmd,m_NAtagCSViewNPCAttr.SubCmd))] = m_NAtagCSViewNPCAttr
#------------------------------------------------------
# B5 18 拍卖行修改关注物品 #tagCGAttentionAuctionItemChange
class  tagCGAttentionAuctionItemChange(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -38649,6 +38649,190 @@
#------------------------------------------------------
# B4 32 查看NPC属性结果 #tagSCViewNPCAttrRet
class  tagSCViewNPCAttr(Structure):
    PosNum = 0    #(BYTE PosNum)// 在本阵容中的站位,从1开始
    NPCID = 0    #(DWORD NPCID)// 战斗NPCID,不同的实例ID对应的NPCID可能一样
    HeroID = 0    #(DWORD HeroID)// 武将ID,玩家或NPC均可能有,如果有值则外观相关以该武将为准,否则以NPCID为准
    LV = 0    #(WORD LV)// 等级,玩家的武将等级或NPC成长等级,等级显示以该值为准
    Star = 0    #(BYTE Star)// 星级
    BreakLV = 0    #(BYTE BreakLV)// 突破
    AwakeLV = 0    #(BYTE AwakeLV)// 觉醒
    AttrLen = 0    #(WORD AttrLen)
    AttrMsg = ""    #(String AttrMsg)// 属性信息 {"属性ID":value, ...}
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.PosNum,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.NPCID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.HeroID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Star,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.BreakLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.AwakeLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.AttrLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.AttrMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.AttrLen)
        return _pos
    def Clear(self):
        self.PosNum = 0
        self.NPCID = 0
        self.HeroID = 0
        self.LV = 0
        self.Star = 0
        self.BreakLV = 0
        self.AwakeLV = 0
        self.AttrLen = 0
        self.AttrMsg = ""
        return
    def GetLength(self):
        length = 0
        length += 1
        length += 4
        length += 4
        length += 2
        length += 1
        length += 1
        length += 1
        length += 2
        length += len(self.AttrMsg)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteBYTE(data, self.PosNum)
        data = CommFunc.WriteDWORD(data, self.NPCID)
        data = CommFunc.WriteDWORD(data, self.HeroID)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Star)
        data = CommFunc.WriteBYTE(data, self.BreakLV)
        data = CommFunc.WriteBYTE(data, self.AwakeLV)
        data = CommFunc.WriteWORD(data, self.AttrLen)
        data = CommFunc.WriteString(data, self.AttrLen, self.AttrMsg)
        return data
    def OutputString(self):
        DumpString = '''
                                PosNum:%d,
                                NPCID:%d,
                                HeroID:%d,
                                LV:%d,
                                Star:%d,
                                BreakLV:%d,
                                AwakeLV:%d,
                                AttrLen:%d,
                                AttrMsg:%s
                                '''\
                                %(
                                self.PosNum,
                                self.NPCID,
                                self.HeroID,
                                self.LV,
                                self.Star,
                                self.BreakLV,
                                self.AwakeLV,
                                self.AttrLen,
                                self.AttrMsg
                                )
        return DumpString
class  tagSCViewNPCAttrRet(Structure):
    Head = tagHead()
    MapID = 0    #(DWORD MapID)// 自定义地图ID,可用于绑定战斗地图场景功能(如主线关卡、主线boss、爬塔、竞技场等)
    FuncLineID = 0    #(DWORD FuncLineID)// MapID对应的扩展值,如具体某个关卡等
    ViewNPCID = 0    #(DWORD ViewNPCID)// 指定查看某个NPCID,发0则查看该关卡阵容所有NPC
    NPCCnt = 0    #(BYTE NPCCnt)
    NPCAttrList = list()    #(vector<tagSCViewNPCAttr> NPCAttrList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB4
        self.Head.SubCmd = 0x32
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.MapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FuncLineID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ViewNPCID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.NPCCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.NPCCnt):
            temNPCAttrList = tagSCViewNPCAttr()
            _pos = temNPCAttrList.ReadData(_lpData, _pos)
            self.NPCAttrList.append(temNPCAttrList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB4
        self.Head.SubCmd = 0x32
        self.MapID = 0
        self.FuncLineID = 0
        self.ViewNPCID = 0
        self.NPCCnt = 0
        self.NPCAttrList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 4
        length += 4
        length += 1
        for i in range(self.NPCCnt):
            length += self.NPCAttrList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.MapID)
        data = CommFunc.WriteDWORD(data, self.FuncLineID)
        data = CommFunc.WriteDWORD(data, self.ViewNPCID)
        data = CommFunc.WriteBYTE(data, self.NPCCnt)
        for i in range(self.NPCCnt):
            data = CommFunc.WriteString(data, self.NPCAttrList[i].GetLength(), self.NPCAttrList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                MapID:%d,
                                FuncLineID:%d,
                                ViewNPCID:%d,
                                NPCCnt:%d,
                                NPCAttrList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.MapID,
                                self.FuncLineID,
                                self.ViewNPCID,
                                self.NPCCnt,
                                "..."
                                )
        return DumpString
m_NAtagSCViewNPCAttrRet=tagSCViewNPCAttrRet()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCViewNPCAttrRet.Head.Cmd,m_NAtagSCViewNPCAttrRet.Head.SubCmd))] = m_NAtagSCViewNPCAttrRet
#------------------------------------------------------
# B5 04 拍卖行新上架拍品 #tagGCAddAuctionItemInfo
class  tagGCAddAuctionItem(Structure):