129 【战斗】战斗系统-服务端(增加GM命令输出指定章节关卡或者副本阵容NPC属性: NPCAttr)
| | |
| | | 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等级
|
| | |
| | | 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
|
| | |
| | | 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: 难度系数
|
| | |
| | | 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(),
|
| | |
| | | "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):
|
| | |
| | |
|
| | | return skillIDList
|
| | |
|
| | | def GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty):
|
| | | def GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty, isLog=True):
|
| | | ## 获取NPC成长属性
|
| | | # @param strongerLV: 成长等级
|
| | | # @param difficulty: 难度系数
|
| | |
| | | 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):
|
| New file |
| | |
| | | #!/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
|