From 5a91f4aa6a702388948d551158a2e92a65329834 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 14 十一月 2025 18:52:41 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(buff持续时间增加大回合支持;增加光环buff;优化攻击、治疗计算逻辑,甄宓、曹仁、董白平摊伤害技能支持;优化B427封包支持额外目标;优化dot、持续治疗结算逻辑及通知;)其他: 1. TurnFight 命令支持指定敌方武将阵容测试,直接在主线战斗 2. B424初始化前的血量变更0418通知屏蔽
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 153 insertions(+), 18 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..3e741e5 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
@@ -621,7 +625,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 +650,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 +865,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 +875,6 @@
turnFight = batLineup.turnFight
tfGUID = turnFight.guid
- lineupPlayerID = lineupInfo.get("PlayerID", 0) # 阵容所属玩家ID
heroDict = lineupInfo.get("Hero", {})
batObjMgr = BattleObj.GetBatObjMgr()
@@ -845,6 +940,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 +1558,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,7 +1572,8 @@
turnFight.ResetOneActionUseSkillCnt()
batObj.SetTiming(ChConfig.TurnTiming_Before) # 重置时机到回合前
if turnNum > 1: # 第1回合不用刷新技能
- RefreshObjSkillByTurn(batObj)
+ RefreshObjSkillByBigTurn(batObj)
+ RefreshObjByBigTurn(turnFight, batObj)
TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnStart)
@@ -1552,7 +1649,7 @@
return
-def RefreshObjSkillByTurn(batObj):
+def RefreshObjSkillByBigTurn(batObj):
'''按回合刷新技能:默认以大回合统一减1回合
'''
curID = batObj.GetID()
@@ -1576,6 +1673,31 @@
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):
'''刷新buff持续时间:以武将自身回合前、回合后处理buff持续时间
回合前添加的buff在回合开始减1,回合后添加的buff在回合结束减1
@@ -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