From e926fc46837c5fb26c537ecb15945a78e2f3423f Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 17 十一月 2025 19:53:58 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(完善战斗相关公式参数;竞技增减伤属性、战力系数改为PVP增减伤;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py |  177 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 156 insertions(+), 21 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 408a0bd..814a105 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -48,6 +48,8 @@
 import time
 import json
 
+g_gmTestFightReq = []
+
 PosNumMax = 7 # 最大站位编号
 ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
 
@@ -73,6 +75,7 @@
         self.shapeType = 0 # 阵型
         self.fightPower = 0 # 阵容总战力
         self.posObjIDDict = {} # 站位对应战斗实体 {站位编号:batObjID, ...}, 站位编号小于0为非主战单位,如主公、红颜等
+        self.heroObjIDDict = {} # 武将ID对应ObjID {heroID:batObjID, ...}
         self.lingshouObjIDDict = {} # 灵兽战斗单位 {位置编号:batObjID, ...}
         self.beautyObjIDDict = {} # 红颜战斗单位 {位置编号:batObjID, ...}
         self.actionNum = ActionNumStart # 行动位置,从1开始
@@ -109,6 +112,7 @@
         for objID in self.beautyObjIDDict.values():
             batObjMgr.delBatObj(objID)
         self.posObjIDDict = {}
+        self.heroObjIDDict = {}
         self.lingshouObjIDDict = {}
         self.beautyObjIDDict = {}
         self.fightPower = 0
@@ -229,6 +233,8 @@
         self.tagPlayerID = tagPlayerID
         self.tagViewCache = tagViewCache
         return
+    
+    def getPVPPlayerID(self): return self.tagPlayerID # 获取PVP目标玩家ID,也可用于判断是否PVP
     
     def isFBMap(self):
         ## 是否副本地图中,非主线的均视为副本
@@ -621,7 +627,10 @@
     # @param lineupID: 阵容ID
     # @param npcLV: 成长NPC等级
     # @param difficulty: 成长NPC难度系数
-    # @return: 阵容全部信息json字典,前端通用格式
+    # @return: 阵容全部信息json字典,前端通用格式    
+    lineupInfo = GetGMTestNPCLineupInfo(lineupID, strongerLV, difficulty)
+    if lineupInfo:
+        return lineupInfo
     ipyData = IpyGameDataPY.GetIpyGameData("NPCLineup", lineupID)
     if not ipyData:
         return {}
@@ -643,6 +652,93 @@
     lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict, "BossID":bossID, "BossPosView":bossPosView}
     return lineupInfo
 
+def GMTestFight(curPlayer, heroIDList, isAllSkill):
+    ## GM测试战斗,指定武将
+    global g_gmTestFightReq
+    g_gmTestFightReq = [heroIDList, isAllSkill]
+    __doMainLevelWave(curPlayer, True)
+    g_gmTestFightReq = []
+    return
+
+def GetGMTestNPCLineupInfo(lineupID, strongerLV=0, difficulty=0):
+    ## 获取GM测试战斗阵容信息
+    if not g_gmTestFightReq:
+        return
+    heroIDList, isAllSkill = g_gmTestFightReq
+    
+    lineupIpyData = IpyGameDataPY.GetIpyGameData("NPCLineup", lineupID)
+    if not lineupIpyData:
+        return
+    
+    npcDict = {}
+    heroNPCIDDict = {}
+    for posNum in range(1, 1 + 6):
+        if not hasattr(lineupIpyData, "GetPosNPCID%s" % posNum):
+            break
+        npcID = getattr(lineupIpyData, "GetPosNPCID%s" % posNum)()
+        if not npcID:
+            continue
+        battleDict = GetNPCBattleDict(lineupIpyData, npcID, strongerLV, difficulty)
+        if not battleDict:
+            continue
+        npcDict[npcID] = battleDict
+        heroID = battleDict["HeroID"]
+        heroNPCIDDict[heroID] = npcID
+        
+    if not npcDict:
+        return
+    
+    heroDict = {}
+    # 原先阵容刚好有的直接用
+    for posNum, heroID in enumerate(heroIDList, 1):
+        if heroID not in heroNPCIDDict:
+            continue
+        npcID = heroNPCIDDict[heroID]
+        heroDict[str(posNum)] = npcDict[npcID]
+        heroIDList[posNum - 1] = 0
+        
+    lineupNPCID = npcDict.keys()[0]
+    ipyNPCIDList = []
+    ipyHeroIDList = []
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in xrange(ipyDataMgr.GetNPCCount()):
+        ipyData = ipyDataMgr.GetNPCByIndex(index)
+        heroID = ipyData.GetRelatedHeroID()
+        npcID = ipyData.GetNPCID()
+        ipyNPCIDList.append(npcID)
+        ipyHeroIDList.append(heroID)
+        
+    lineupNPCIndex = ipyNPCIDList.index(lineupNPCID)
+    # 从参考阵容先往前检索,再往后检索,还没有对应武将的NPC
+    loopIndexList = range(lineupNPCIndex + 1)[::-1] + range(lineupNPCIndex + 1, ipyDataMgr.GetNPCCount())
+    for index in loopIndexList:
+        npcID = ipyNPCIDList[index]
+        heroID = ipyHeroIDList[index]
+        if heroID not in heroIDList:
+            continue
+        battleDict = GetNPCBattleDict(lineupIpyData, npcID, strongerLV, difficulty)
+        if not battleDict:
+            continue
+        
+        for posNum, posHeroID in enumerate(heroIDList, 1):
+            if not posHeroID or heroID != posHeroID:
+                continue
+            heroIDList[posNum - 1] = 0
+            heroDict[str(posNum)] = battleDict
+        
+        if heroIDList.count(0) == len(heroIDList):
+            break
+        
+    if isAllSkill:
+        for battleDict in heroDict.values():
+            heroID = battleDict["HeroID"]
+            heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None
+            skillIDList = GetNPCHeroSkillIDList(heroID, heroIpyData, 99999, 99999) # 默认取突破、觉醒都满级时的技能
+            battleDict["SkillIDList"] = skillIDList
+            
+    lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict, "BossID":0, "BossPosView":0}
+    return lineupInfo
+    
 def GetNPCBattleDict(lineupIpyData, npcID, strongerLV=0, difficulty=0):
     ## 获取NPC战斗相关字典,支持成长NPC
     # @param strongerLV: 成长等级
@@ -771,7 +867,9 @@
     @param lineupInfo: 阵容信息
     @param playerID: 发起的玩家ID,系统场次为0
     '''
-    GameWorld.DebugLog("SummonLineupObjs faction:%s,num:%s,lineupInfo=%s" % (faction, num, lineupInfo), playerID)
+    lineupPlayerID = lineupInfo.get("PlayerID", 0) # 阵容所属玩家ID
+    npcLineupID = lineupInfo.get("NPCLineupID", 0)
+    GameWorld.DebugLog("SummonLineupObjs faction:%s,num:%s,npcLineupID=%s,lineupPlayerID=%s" % (faction, num, npcLineupID, lineupPlayerID), playerID)
     if playerID:
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
         if not curPlayer:
@@ -779,7 +877,6 @@
         
     turnFight = batLineup.turnFight
     tfGUID = turnFight.guid
-    lineupPlayerID = lineupInfo.get("PlayerID", 0) # 阵容所属玩家ID
     heroDict = lineupInfo.get("Hero", {})
     
     batObjMgr = BattleObj.GetBatObjMgr()
@@ -845,6 +942,7 @@
             skillManager.LearnSkillByID(skillID)
             
         batLineup.posObjIDDict[posNum] = objID
+        batLineup.heroObjIDDict[heroID] = objID
         GameWorld.DebugLog("AddBatObj %s,skill=%s" % (GetObjName(batObj), skillManager.GetSkillIDList()))
         ResetObjSkill(batObj)
         
@@ -1462,7 +1560,7 @@
     
     batObjMgr = BattleObj.GetBatObjMgr()
     for faction, num in turnFight.actionSortList:
-        GameWorld.DebugLog("大回合开始逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
+        GameWorld.DebugLog("大回合开始逻辑: turnNum=%s,faction=%s,num=%s" % (turnNum, faction, num))
         batFaction = turnFight.getBatFaction(faction)
         batLineup = batFaction.getBatlineup(num)
         batLineup.actionNum = 1
@@ -1476,8 +1574,9 @@
             turnFight.ResetOneActionUseSkillCnt()
             batObj.SetTiming(ChConfig.TurnTiming_Before) # 重置时机到回合前
             if turnNum > 1: # 第1回合不用刷新技能
-                RefreshObjSkillByTurn(batObj)
-                
+                RefreshObjSkillByBigTurn(batObj)
+                RefreshObjByBigTurn(turnFight, batObj)
+            batObj.ResetBigTurn() # 每大回合重置
             TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnStart)
             
     return
@@ -1552,7 +1651,7 @@
         
     return
 
-def RefreshObjSkillByTurn(batObj):
+def RefreshObjSkillByBigTurn(batObj):
     '''按回合刷新技能:默认以大回合统一减1回合
     '''
     curID = batObj.GetID()
@@ -1572,8 +1671,31 @@
         remainTime -= 1
         curSkill.SetRemainTime(remainTime)
         GameWorld.DebugLog("    更新技能CD: curID=%s,skillID=%s,remainTime=%s" % (curID, skillID, remainTime))
-        
-    batObj.ResetSkillTurnUseCnt() # 重置回合使用次数,放刷新CD后重置
+    return
+
+def RefreshObjByBigTurn(turnFight, batObj):
+    ## 根据大回合开始刷新buff持续时间,每个大回合-1,第1回合不处理
+    curID = batObj.GetID()
+    buffMgr = batObj.GetBuffManager()
+    for index in range(buffMgr.GetBuffCount())[::-1]:
+        buff = buffMgr.GetBuffByIndex(index)
+        buffID = buff.GetBuffID()
+        skillID = buff.GetSkillID()
+        skillData = buff.GetSkillData()
+        if skillData.GetLastTimeType() != ChConfig.BuffLastTimeType_BigTurn:
+            continue
+        if skillData.GetSkillType() in ChConfig.Def_LstBuff_List:
+            #GameWorld.DebugLog("    持续类buff由触发时机决定剩余时间! curID=%s,index=%s,skillID=%s,buffID=%s" % (curID, index, skillID, buffID))
+            continue
+        if skillData.GetSkillType() == ChConfig.Def_SkillType_Halo and buff.GetOwnerID() != curID:
+            GameWorld.DebugLog("    光环buff非光源不处理! curID=%s,index=%s,skillID=%s,buffID=%s" % (curID, index, skillID, buffID))
+            continue
+        remainTime = buff.GetRemainTime()
+        if remainTime <= 0:
+            continue
+        remainTime -= 1
+        GameWorld.DebugLog("    更新buff回合: curID=%s,buffID=%s,skillID=%s,remainTime=%s" % (curID, buffID, skillID, remainTime))
+        TurnBuff.SetBuffRemainTime(turnFight, batObj, buff, remainTime)
     return
 
 def RefreshObjBuffTime(turnFight, batObj):
@@ -1588,8 +1710,13 @@
         buffID = buff.GetBuffID()
         skillID = buff.GetSkillID()
         skillData = buff.GetSkillData()
+        if skillData.GetLastTimeType() != ChConfig.BuffLastTimeType_Default:
+            continue
         if skillData.GetSkillType() in ChConfig.Def_LstBuff_List:
             #GameWorld.DebugLog("    持续类buff由触发时机决定剩余时间! curID=%s,index=%s,skillID=%s,buffID=%s" % (curID, index, skillID, buffID))
+            continue
+        if skillData.GetSkillType() == ChConfig.Def_SkillType_Halo and buff.GetOwnerID() != curID:
+            GameWorld.DebugLog("    光环buff非光源不处理! curID=%s,index=%s,skillID=%s,buffID=%s" % (curID, index, skillID, buffID))
             continue
         remainTime = buff.GetRemainTime()
         if remainTime <= 0:
@@ -1606,13 +1733,9 @@
             continue
         remainTime -= 1
         GameWorld.DebugLog("    更新buff回合: curID=%s,buffID=%s,skillID=%s,remainTime=%s,addTiming=%s" % (curID, buffID, skillID, remainTime, addTiming))
-        if remainTime > 0:
-            buff.SetRemainTime(remainTime)
-            TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
-        else:
-            TurnBuff.DoBuffDel(turnFight, batObj, buff)
+        TurnBuff.SetBuffRemainTime(turnFight, batObj, buff, remainTime)
     return
-                        
+
 def AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID=0):
     ## 回合对象添加治疗值
     # @param curObj: 获得治疗的对象
@@ -1629,22 +1752,21 @@
         
     return
 
-def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, skillID=0, isBounce=False):
+def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, skillID=0, lostType=""):
     ## 回合对象添加伤害值
-    # @param isBounce: 是否反弹伤害
     if hurtValue <= 0:
         return
     curID = curBatObj.GetID()
     tagID = tagBatObj.GetID()
     if curID != tagID:
         updStatValue = curBatObj.StatHurtValue(hurtValue)
-        GameWorld.DebugLog("        统计伤血: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s,isBounce=%s" 
-                       % (curID, tagID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
+        GameWorld.DebugLog("        统计输出: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s,lostType=%s" 
+                       % (curID, tagID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), lostType))
         
         if tagBatObj:
             updStatValue = tagBatObj.StatDefValue(hurtValue)
-            GameWorld.DebugLog("        统计承伤: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s,isBounce=%s" 
-                           % (tagID, curID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
+            GameWorld.DebugLog("        统计承伤: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s,lostType=%s" 
+                           % (tagID, curID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), lostType))
             
     else:
         # 如换血类技能,自残的伤害不算输出
@@ -1748,6 +1870,19 @@
     # 暂时只算主线小怪
     if curPlayer and turnFight.mapID == ChConfig.Def_FBMapID_Main and gameObj.GetFaction() != ChConfig.Def_FactionA:
         GetMainFightMgr(curPlayer).killNPCCnt += 1
+        
+    # 清除光源buff
+    buffMgr = gameObj.GetBuffManager()
+    for index in range(buffMgr.GetBuffCount())[::-1]:
+        buff = buffMgr.GetBuffByIndex(index)
+        skillID = buff.GetSkillID()
+        skillData = buff.GetSkillData()
+        if skillData.GetSkillType() != ChConfig.Def_SkillType_Halo:
+            continue
+        if buff.GetOwnerID() != objID:
+            continue
+        GameWorld.DebugLog("删除光环buff: objID=%s,skillID=%s" % (objID, skillID))
+        TurnBuff.DoBuffDel(turnFight, gameObj, buff)
     return True
 
 def OnTurnAllOver(guid):

--
Gitblit v1.8.0