From fff7319fd0fb06d03364c5be64edc5bc22e1fe3f Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 28 八月 2025 18:04:18 +0800 Subject: [PATCH] 129 【战斗】战斗系统-服务端(NPC支持成长属性;NPC支持关联武将;) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 198 +++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 156 insertions(+), 42 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py index f595ce4..dab5601 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py @@ -434,6 +434,8 @@ self.teamMax = 1 # 当前波最大小队,某场战斗可能包含多个小队,所有小队混流击杀完才算过了本波 self.nextTeam = False # 下次前端请求战斗是否是下一小队,否则都是重新刷新当前进度怪 self.waveLineupList = [] # 小队列表 + self.strongerLV = 0 + self.difficulty = 0 self.turnFight = GetTurnFightMgr().addTurnFight(ChConfig.Def_FBMapID_Main, 0, playerID) return @@ -499,9 +501,11 @@ return lineupInfo -def GetNPCLineupInfo(lineupID): +def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0): ## 获取NPC阵容信息 # @param lineupID: 阵容ID + # @param npcLV: 成长NPC等级 + # @param difficulty: 成长NPC难度系数 # @return: 阵容全部信息json字典,前端通用格式 ipyData = IpyGameDataPY.GetIpyGameData("NPCLineup", lineupID) if not ipyData: @@ -514,9 +518,46 @@ npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)() if not npcID: continue - npcData = NPCCommon.GetNPCDataPy(npcID) - if not npcData: + battleDict = GetNPCBattleDict(npcID, strongerLV, difficulty) + if not battleDict: continue + heroDict[str(posNum)] = battleDict + + lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict} + return lineupInfo + +def GetNPCBattleDict(npcID, strongerLV=0, difficulty=0): + ## 获取NPC战斗相关字典,支持成长NPC + # @param strongerLV: 成长等级 + # @param difficulty: 难度系数 + npcData = NPCCommon.GetNPCDataPy(npcID) + if not npcData: + return + heroID = npcData.GetRelatedHeroID() + npcLV = npcData.GetLV() + + lvIpyData = None + heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None + npcStronger = IpyGameDataPY.GetIpyGameDataNotLog("NPCStronger", npcID) + if npcStronger and strongerLV: + lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", strongerLV) + if lvIpyData: + npcLV = strongerLV + if not lvIpyData: + lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", npcLV) + + if heroIpyData and lvIpyData: + skinIDList = heroIpyData.GetSkinIDList() + skinID = skinIDList[0] if skinIDList else 0 + skillIDList = GetNPCHeroSkillIDList(heroID, heroIpyData, lvIpyData.GetReHeroBreakLV(), lvIpyData.GetReHeroAwakeLV()) + else: + heroID = 0 + skinID = 0 + skillIDList = [] + npcData.GetSkillIDList() + + # 成长怪属性 + batAttrDict = GetNPCStrongerAttrDict(npcID, lvIpyData, npcStronger, difficulty) + 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(), ChConfig.AttrID_MissRate:npcData.GetMissRate(), ChConfig.AttrID_MissRateDef:npcData.GetMissRateDef(), @@ -527,14 +568,68 @@ ChConfig.AttrID_SuckHPPer:npcData.GetSuckHPPer(), ChConfig.AttrID_SuckHPPerDef:npcData.GetSuckHPPerDef(), } batAttrDict.update(npcData.GetSpecAttrInfo()) - skillIDList = [] + npcData.GetSkillIDList() - heroDict[str(posNum)] = {"NPCID":npcID, - "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0}, - "SkillIDList":skillIDList - } - lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict} - return lineupInfo + battleDict = {"NPCID":npcID, + "HeroID":heroID, + "SkinID":skinID, + "LV":npcLV, + "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0}, + "SkillIDList":skillIDList, + } + + GameWorld.DebugLog("GetNPCBattleDict npcID=%s,strongerLV=%s,difficulty=%s,%s" % (npcID, strongerLV, difficulty, battleDict)) + return battleDict + +def GetNPCHeroSkillIDList(heroID, heroIpyData, breakLV, awakeLV): + ## 获取NPC对应武将的技能ID列表 + normalSkillID = heroIpyData.GetNormalSkillID() + angerSkillID = heroIpyData.GetAngerSkillID() + skillIDList = [normalSkillID, angerSkillID] + + breakIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroBreak", heroID) + if breakIpyDataList: + for breakIpyData in breakIpyDataList: + if breakIpyData.GetBreakLV() > breakLV: + break + skillID = breakIpyData.GetSkillID() + if skillID: + skillIDList.append(skillID) + + awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID) + if awakeIpyDataList: + for awakeIpyData in awakeIpyDataList: + if awakeIpyData.GetAwakeLV() > awakeLV: + break + skillID = awakeIpyData.GetSkillID() + if skillID: + skillIDList.append(skillID) + + return skillIDList + +def GetNPCStrongerAttrDict(npcID, lvIpyData, npcStronger, difficulty): + ## 获取NPC成长属性 + # @param strongerLV: 成长等级 + # @param difficulty: 难度系数 + + batAttrDict = {} + if not lvIpyData or not npcStronger or not difficulty: + return batAttrDict + lv = lvIpyData.GetLV() + for attrID in ChConfig.CalcBattleAttrIDList: + attrIpyData = IpyGameDataPY.GetIpyGameData("PlayerAttr", attrID) + if not attrIpyData: + continue + attrName = attrIpyData.GetParameter() + if not hasattr(lvIpyData, "GetRe%s" % attrName): + continue + reValue = getattr(lvIpyData, "GetRe%s" % attrName)() # 基础参考值 + ratio = getattr(npcStronger, "Get%sRatio" % attrName)() if hasattr(npcStronger, "Get%sRatio" % attrName) else 1 # 属性系数 + attrValue = int(reValue * ratio * difficulty) + batAttrDict[attrID] = attrValue + #GameWorld.DebugLog(" attrID=%s,attrValue=%s,reValue=%s,ratio=%s,difficulty=%s" % (attrID, attrValue, reValue, ratio, difficulty)) + + GameWorld.DebugLog("NPC成长属性: npcID=%s,lv=%s,difficulty=%s,%s" % (npcID, lv, difficulty, batAttrDict)) + return batAttrDict def SummonLineupObjs(batLineup, faction, num, lineupInfo, playerID=0): '''召唤阵容战斗实例 @@ -559,37 +654,46 @@ for posNumKey, heroInfo in heroDict.items(): posNum = int(posNumKey) - npcID, heroID, skinID = 0, 0, 0 atkBackSkillID = 0 # 反击技能ID fightPower = 0 skillIDList = [] # 战斗对象可能改变属性或技能,重新创建,防止误修改来源值 attrDict = {} skillIDList += heroInfo.get("SkillIDList", []) attrDict.update(heroInfo.get("AttrDict", {})) - objName = "" - if lineupPlayerID: - heroID = heroInfo.get("HeroID", 0) - skinID = heroInfo.get("SkinID", 0) - lv = heroInfo.get("LV", 1) - fightPower = heroInfo.get("FightPower", 0) - heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) - if not heroIpyData: - continue + npcID = heroInfo.get("NPCID", 0) + heroID = heroInfo.get("HeroID", 0) + skinID = heroInfo.get("SkinID", 0) + lv = heroInfo.get("LV", 1) + heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None + if heroIpyData: atkDistType = heroIpyData.GetAtkDistType() objName = heroIpyData.GetName() + country = heroIpyData.GetCountry() + sex = heroIpyData.GetSex() + + if lineupPlayerID: + fightPower = heroInfo.get("FightPower", 0) + if not heroIpyData: + continue + else: - npcID = heroInfo.get("NPCID", 0) npcDataEx = NPCCommon.GetNPCDataPy(npcID) if not npcDataEx: continue - objName = npcDataEx.GetNPCName() - atkDistType = npcDataEx.GetAtkDistType() - lv = npcDataEx.GetLV() - + if not heroIpyData: + atkDistType = npcDataEx.GetAtkDistType() + objName = npcDataEx.GetNPCName() + country = npcDataEx.GetCountry() + sex = npcDataEx.GetSex() + batObj = batObjMgr.addBatObj() if not batObj: break objID = batObj.GetID() + if npcID: + batObj.SetNPCID(npcID) + elif lineupPlayerID: + batObj.SetOwnerID(lineupPlayerID) batObj.SetTFGUID(tfGUID) batObj.SetName(objName) batObj.SetFaction(faction) @@ -597,11 +701,10 @@ batObj.SetFightPower(fightPower) batObj.SetLV(lv) batObj.SetAtkDistType(atkDistType) - if npcID: - batObj.SetNPCID(npcID) - elif lineupPlayerID: - batObj.SetOwnerHero(lineupPlayerID, heroID, skinID) - + batObj.SetCountry(country) + batObj.SetSex(sex) + batObj.SetHero(heroID, skinID) + if atkDistType == ChConfig.AtkDistType_Short: atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0 elif atkDistType == ChConfig.AtkDistType_Long: @@ -614,7 +717,7 @@ skillManager.LearnSkillByID(skillID) batLineup.posObjIDDict[posNum] = objID - GameWorld.DebugLog("AddBatObj ID:%s,%s,skill=%s" % (objID, GetObjName(batObj), skillIDList)) + GameWorld.DebugLog("AddBatObj %s,skill=%s" % (GetObjName(batObj), skillIDList)) batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP) return @@ -729,6 +832,8 @@ GameWorld.DebugLog("没有设置主阵容!", playerID) return + strongerLV = levelIpyData.GetNPCLV() + difficulty = levelIpyData.GetDifficulty() mainFightMgr = GetMainFightMgr(curPlayer) mainFightMgr.nextTeam = False mainFightMgr.chapterID = chapterID @@ -738,15 +843,17 @@ mainFightMgr.waveLineupList = waveLineupList mainFightMgr.teamNum = teamNum mainFightMgr.teamMax = teamMax + mainFightMgr.strongerLV = strongerLV + mainFightMgr.difficulty = difficulty turnMax = IpyGameDataPY.GetFuncCfg("Mainline", 2) mapID, funcLineID = ChConfig.Def_FBMapID_Main, PlayerControl.ComMainLevelValue(chapterID, levelNum, wave) - GameWorld.DebugLog("设置起始关卡波: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s" - % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID), playerID) + GameWorld.DebugLog("设置起始关卡波: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s,strongerLV=%s,difficulty=%s" + % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID, strongerLV, difficulty), playerID) turnFight = mainFightMgr.turnFight turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax}) turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}) - turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)}) + turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, strongerLV, difficulty)}) turnFight.sortActionQueue() turnFight.startFight() return @@ -802,7 +909,9 @@ if not lineupMainInfo: GameWorld.DebugLog("没有设置主阵容!", playerID) return - + + strongerLV = levelIpyData.GetNPCLV() + difficulty = levelIpyData.GetDifficulty() mainFightMgr = GetMainFightMgr(curPlayer) mainFightMgr.nextTeam = False mainFightMgr.chapterID = chapterID @@ -812,15 +921,17 @@ mainFightMgr.waveLineupList = waveLineupList mainFightMgr.teamNum = teamNum mainFightMgr.teamMax = teamMax + mainFightMgr.strongerLV = strongerLV + mainFightMgr.difficulty = difficulty turnMax = IpyGameDataPY.GetFuncCfg("Mainline", 3) mapID, funcLineID = ChConfig.Def_FBMapID_MainBoss, PlayerControl.ComMainLevelValue(chapterID, levelNum, wave) - GameWorld.DebugLog("设置关卡boss: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s" - % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID), playerID) + GameWorld.DebugLog("设置关卡boss: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s,strongerLV=%s,difficulty=%s" + % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID, strongerLV, difficulty), playerID) turnFight = mainFightMgr.turnFight turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax}) turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}) - turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)}) + turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, strongerLV, difficulty)}) turnFight.sortActionQueue() turnFight.startFight() @@ -858,7 +969,7 @@ mainFightMgr.nextTeam = False turnFight.resetTurn({"teamNum":teamNum}) # 切换小队时,玩家阵容不需要处理,保留状态 - turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)}) + turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, mainFightMgr.strongerLV, mainFightMgr.difficulty)}) turnFight.sortActionQueue() turnFight.startFight() @@ -1088,10 +1199,13 @@ num = batObj.lineupNum posNum = batObj.posNum heroID = batObj.heroID - if not heroID: - heroID = batObj.npcID + npcID = batObj.npcID objName = GameWorld.CodeToGbk(batObj.GetName()) - return "%s%s-%s [%s-%s] %s" % ("A" if faction == ChConfig.Def_FactionA else "B", num, posNum, batObj.GetID(), heroID, objName) + if heroID: + objName += " Hero:%s" % heroID + if npcID: + objName += " NPC:%s" % npcID + return "%s%s-P%s ID:%s %s" % ("A" if faction == ChConfig.Def_FactionA else "B", num, posNum, batObj.GetID(), objName) def EntryLogic(turnFight): ## 执行进场逻辑 -- Gitblit v1.8.0