From 1cbdeae386bdfab0b9e996ffb4df0301ce19ff9e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 01 九月 2025 10:48:01 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(修复主线战斗击杀无法结算经验、掉落bug;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 206 ++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 163 insertions(+), 43 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 d99d20f..dab5601 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -20,6 +20,7 @@
#-------------------------------------------------------------------------------
import ChConfig
+import PlayerTask
import ChPyNetSendPack
import NetPackCommon
import PlayerControl
@@ -433,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
@@ -498,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:
@@ -513,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(),
@@ -526,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):
'''召唤阵容战斗实例
@@ -558,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)
@@ -596,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:
@@ -613,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
@@ -728,6 +832,8 @@
GameWorld.DebugLog("没有设置主阵容!", playerID)
return
+ strongerLV = levelIpyData.GetNPCLV()
+ difficulty = levelIpyData.GetDifficulty()
mainFightMgr = GetMainFightMgr(curPlayer)
mainFightMgr.nextTeam = False
mainFightMgr.chapterID = chapterID
@@ -737,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
@@ -801,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
@@ -811,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()
@@ -857,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()
@@ -1087,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):
## 执行进场逻辑
@@ -1347,7 +1462,12 @@
clientPack.ObjID = objID
clientPack.KillerObjID = killerObjID
clientPack.SkillID = skillID
- turnFight.addBatPack(clientPack)
+ turnFight.addBatPack(clientPack)
+
+ curPlayer = turnFight.curPlayer
+ # 暂时只算主线小怪
+ if curPlayer and turnFight.mapID == ChConfig.Def_FBMapID_Main and gameObj.GetFaction() != ChConfig.Def_FactionA:
+ PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_KillNPC, 1)
return True
def OnTurnAllOver(guid):
--
Gitblit v1.8.0