129 【战斗】战斗系统-服务端(增加GM命令输出指定章节关卡或者副本阵容NPC属性: NPCAttr)
1个文件已修改
1个文件已添加
222 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/NPCAttr.py 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -640,7 +640,7 @@
    lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType, "Hero":heroDict}
    return lineupInfo
def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0):
def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0, isLog=True):
    ## 获取NPC阵容信息
    # @param lineupID: 阵容ID
    # @param npcLV: 成长NPC等级
@@ -662,7 +662,7 @@
        npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)()
        if not npcID:
            continue
        battleDict = GetNPCBattleDict(ipyData, npcID, strongerLV, difficulty)
        battleDict = GetNPCBattleDict(ipyData, npcID, strongerLV, difficulty, isLog)
        if not battleDict:
            continue
        heroDict[str(posNum)] = battleDict
@@ -775,7 +775,7 @@
    lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict, "BossID":0, "BossPosView":0}
    return lineupInfo
    
def GetNPCBattleDict(lineupIpyData, npcID, strongerLV=0, difficulty=0):
def GetNPCBattleDict(lineupIpyData, npcID, strongerLV=0, difficulty=0, isLog=True):
    ## 获取NPC战斗相关字典,支持成长NPC
    # @param strongerLV: 成长等级
    # @param difficulty: 难度系数
@@ -820,10 +820,10 @@
                random.shuffle(randSkillIDExList)
                randSkillIDExList = randSkillIDExList[:skillExCnt]
            skillIDList += randSkillIDExList
            GameWorld.DebugLogEx("阵容boss技能: %s, 随机附加技能: %s", skillIDList, randSkillIDExList)
            isLog and GameWorld.DebugLogEx("阵容boss技能: %s, 随机附加技能: %s", skillIDList, randSkillIDExList)
            
    # 成长怪属性
    batAttrDict = GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty)
    batAttrDict = GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty, isLog)
    if not batAttrDict:
        batAttrDict = {ChConfig.AttrID_Atk:npcData.GetAtk(), ChConfig.AttrID_Def:npcData.GetDef(), ChConfig.AttrID_MaxHP:npcData.GetMaxHP(), 
                       ChConfig.AttrID_FinalDamPer:npcData.GetFinalDamPer(), ChConfig.AttrID_FinalDamPerDef:npcData.GetFinalDamPerDef(), 
@@ -850,7 +850,7 @@
                  "SkillIDList":skillIDList,
                  }
    
    GameWorld.DebugLogEx("GetNPCBattleDict npcID=%s,strongerLV=%s,difficulty=%s,reModelID=%s,%s", npcID, strongerLV, difficulty, reModelID, battleDict)
    isLog and GameWorld.DebugLogEx("GetNPCBattleDict npcID=%s,strongerLV=%s,difficulty=%s,reModelID=%s,%s", npcID, strongerLV, difficulty, reModelID, battleDict)
    return battleDict
def GetNPCHeroSkillIDList(heroID, heroIpyData, breakLV, awakeLV):
@@ -879,7 +879,7 @@
                
    return skillIDList
def GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty):
def GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty, isLog=True):
    ## 获取NPC成长属性
    # @param strongerLV: 成长等级
    # @param difficulty: 难度系数
@@ -901,7 +901,7 @@
        batAttrDict[attrID] = attrValue
        #GameWorld.DebugLogEx("    attrID=%s,attrValue=%s,reValue=%s,ratio=%s,difficulty=%s", attrID, attrValue, reValue, ratio, difficulty)
        
    GameWorld.DebugLogEx("NPC成长属性: npcID=%s,lv=%s,difficulty=%s,%s", npcID, lv, difficulty, batAttrDict)
    isLog and GameWorld.DebugLogEx("NPC成长属性: npcID=%s,lv=%s,difficulty=%s,%s", npcID, lv, difficulty, batAttrDict)
    return batAttrDict
def SummonLineupObjs(batLineup, faction, num, lineupInfo, reqPlayerID=0):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/NPCAttr.py
New file
@@ -0,0 +1,206 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.NPCAttr
#
# @todo:输出NPC属性
# @author hxp
# @date 2026-1-4
# @version 1.0
#
# 详细描述: 输出NPC属性
#
#-------------------------------------------------------------------------------
#"""Version = 2026-1-4 11:00"""
#-------------------------------------------------------------------------------
import FBCommon
import GameWorld
import TurnAttack
import IpyGameDataPY
import NPCCommon
import ChConfig
import os
def OnExec(curPlayer, paramList):
    if not paramList:
        GameWorld.DebugAnswer(curPlayer, "输出副本属性: NPCAttr mapID lineID")
        GameWorld.DebugAnswer(curPlayer, "输出主线boss: NPCAttr 2 章节 关卡ID")
        GameWorld.DebugAnswer(curPlayer, "导出主线属性: NPCAttr e main")
        return
    value = paramList[0]
    if value == "e":
        __exportNPCAttr(curPlayer, paramList)
        return
    GameWorld.DebugAnswer(curPlayer, "---------------------------")
    mapID = value
    if mapID in [ChConfig.Def_FBMapID_Main, ChConfig.Def_FBMapID_MainBoss]:
        chapterID = paramList[1] if len(paramList) > 1 else 1
        levelNum = paramList[2] if len(paramList) > 2 else 1
        levelIpyData = IpyGameDataPY.GetIpyGameData("MainLevel", chapterID, levelNum)
        if not levelIpyData:
            GameWorld.DebugAnswer(curPlayer, "不存在该章节关卡! %s-%s" % (chapterID, levelNum))
            return
        lineupIDList = levelIpyData.GetBossLineupIDList() # Boss波阵容ID列表,小队1阵容ID|小队2阵容ID|...
        strongerLV = levelIpyData.GetNPCLV()
        difficulty = levelIpyData.GetDifficulty()
        GameWorld.DebugAnswer(curPlayer, "主线章关: %s-%s" % (chapterID, levelNum))
    else:
        funcLineID = paramList[1] if len(paramList) > 1 else 0
        fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, funcLineID)
        if not fbLineIpyData:
            GameWorld.DebugAnswer(curPlayer, "不存在该副本关卡! %s-%s" % (mapID, funcLineID))
            return
        lineupIDList = fbLineIpyData.GetLineupIDList()
        strongerLV = fbLineIpyData.GetNPCLV()
        difficulty = fbLineIpyData.GetDifficulty()
        GameWorld.DebugAnswer(curPlayer, "副本关卡: %s-%s" % (mapID, funcLineID))
    __printNPCLineupAttr(curPlayer, lineupIDList, strongerLV, difficulty)
    return
def __exportNPCAttr(curPlayer, paramList):
    ## 导出NPC属性,供策划检查对比
    mapID = paramList[1] if len(paramList) > 1 else "main"
    if mapID == "main":
        __exportMainLevelNPCAttr(curPlayer, mapID)
    return
def __printNPCLineupAttr(curPlayer, lineupIDList, npcLV, difficulty):
    GameWorld.DebugAnswer(curPlayer, "阵容:%s,LV:%s,难度:%s" % (lineupIDList, npcLV, difficulty))
    for lineupID in lineupIDList:
        lineupInfo = TurnAttack.GetNPCLineupInfo(lineupID, npcLV, difficulty, False)
        if not lineupInfo:
            continue
        heroDict = lineupInfo["Hero"]
        bossID = lineupInfo["BossID"] # 无boss时为0
        for posNum in range(1, 1 + 10):
            if str(posNum) not in heroDict:
                continue
            attrInfo = heroDict[str(posNum)]
            posNum = int(posNum)
            npcID = attrInfo["NPCID"]
            heroID = attrInfo["HeroID"]
            #realNPCLV = attrInfo["LV"]
            skillIDList = attrInfo["SkillIDList"]
            attrDict = attrInfo["AttrDict"]
            isBoss = 1 if bossID == npcID else 0
            attrDict2 = {}
            for attrID, value in attrDict.items():
                attrID = int(attrID)
                if not value:
                    continue
                attrDict2[attrID] = value
            npcData = NPCCommon.GetNPCDataPy(npcID)
            if not npcData:
                continue
            GameWorld.DebugAnswer(curPlayer, "----------")
            objName = GameWorld.CodeToGbk(npcData.GetNPCName())
            if heroID:
                objName += " Hero:%s" % heroID
            if npcID:
                objName += " NPC:%s" % npcID
            objName = "P%s:%s" % (posNum, objName)
            GameWorld.DebugAnswer(curPlayer, "%s%s" % (objName, "【Boss】" if isBoss else ""))
            GameWorld.DebugAnswer(curPlayer, "攻:%s,防:%s,HP:%s"
                                  % (attrDict2.get(ChConfig.AttrID_Atk, 0),
                                     attrDict2.get(ChConfig.AttrID_Def, 0),
                                     attrDict2.get(ChConfig.AttrID_MaxHP, 0)))
            attrStr = ""
            attrIDList = attrDict2.keys()
            attrIDList.sort()
            for attrID in attrIDList:
                if attrID in [ChConfig.AttrID_Atk, ChConfig.AttrID_Def, ChConfig.AttrID_MaxHP]:
                    continue
                attrValue = attrDict2[attrID]
                if attrValue:
                    attrStr += "%s=%s;" % (attrID, attrValue)
            GameWorld.DebugAnswer(curPlayer, "属性:%s" % attrStr)
            GameWorld.DebugAnswer(curPlayer, "技能: %s,%s" % (len(skillIDList), skillIDList))
    return
def __exportMainLevelNPCAttr(curPlayer, mapID):
    fieldList = ["章节", "关卡", "波", "阵容ID", "IsBoss", "NPCID", "HeroID", "LV", "SkillIDList"]
    valueList = []
    attrIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetMainLevelCount()):
        ipyData = ipyDataMgr.GetMainLevelByIndex(index)
        chapterID = ipyData.GetChapterID()
        levelNum = ipyData.GetLevelNum()
        npcLV = ipyData.GetNPCLV()
        difficulty = ipyData.GetDifficulty()
        waveLineupIDList = []
        for wave in range(1, 1 + 6):
            if not hasattr(ipyData, "GetWaveLineupIDList%s" % wave):
                break
            lineupIDList = getattr(ipyData, "GetWaveLineupIDList%s" % wave)()
            waveLineupIDList.append(lineupIDList)
        bossLineupIDList = ipyData.GetBossLineupIDList() # Boss波阵容ID列表
        if bossLineupIDList:
            waveLineupIDList.append(bossLineupIDList) # boss当做最后一波
        for wave, lineupIDList in enumerate(waveLineupIDList, 1):
            for lineupID in lineupIDList:
                lineupInfo = TurnAttack.GetNPCLineupInfo(lineupID, npcLV, difficulty, False)
                if not lineupInfo:
                    continue
                heroDict = lineupInfo["Hero"]
                bossID = lineupInfo["BossID"] # 无boss时为0
                for posNum, attrInfo in heroDict.items():
                    posNum = int(posNum)
                    npcID = attrInfo["NPCID"]
                    heroID = attrInfo["HeroID"]
                    realNPCLV = attrInfo["LV"]
                    skillIDList = attrInfo["SkillIDList"]
                    attrDict = attrInfo["AttrDict"]
                    isBoss = 1 if bossID == npcID else 0
                    attrDict2 = {}
                    for attrID, value in attrDict.items():
                        attrID = int(attrID)
                        if attrID not in attrIDList:
                            attrIDList.append(attrID)
                        attrDict2[attrID] = value
                    values = [chapterID, levelNum, wave, lineupID, isBoss, npcID, heroID, realNPCLV, skillIDList, attrDict2]
                    valueList.append(values)
    # 按顺序整理存在的属性
    attrIDList.sort()
    attrNameList = []
    for attrID in attrIDList:
        attrIpyData = IpyGameDataPY.GetIpyGameData("PlayerAttr", attrID)
        attrName = attrIpyData.GetParameter() if attrIpyData else "%s" % attrID
        attrNameList.append(attrName)
    fieldList += attrNameList # 最终字段
    folderPath = os.path.join("C:\NPCAttr")
    if not os.path.exists(folderPath):
        os.makedirs(folderPath)
    exportFilePath = os.path.join(folderPath, "NPCAttrMapID_%s.txt" % (mapID))
    lineFormat = "%s" + "\t%s"*(len(fieldList) - 1)
    fp = open(exportFilePath, "w")
    fp.write("%s\n" % (lineFormat % tuple(fieldList)))
    for values in valueList:
        attrDict2 = values[-1]
        writeValues = values[:-1]
        for attrID in attrIDList:
            writeValues.append(attrDict2.get(attrID, 0))
        fp.write("%s\n" % (lineFormat % tuple(writeValues)))
    fp.close()
    GameWorld.DebugAnswer(curPlayer, "导出:%s" % exportFilePath)
    return