From 1890f0643483194e41668032aa75eb755c8a1aad Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 12 八月 2025 17:23:43 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(主阵容变更时重新开始战斗;主阵容属性变化时实时更新主线战斗;主线战斗请求CD限制1秒;计算buff属性、buff添加删除通用逻辑;4012效果状态逻辑;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py |  121 ++++++++++++++++------------------------
 1 files changed, 49 insertions(+), 72 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 1bc7528..4e600cb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -43,7 +43,6 @@
 import time
 import json
 
-FighterNPCID = 100 # 战斗NPCID,仅后端用,除怪物外,所有玩家武将均使用该NPCID
 PosNumMax = 10 # 最大站位编号
 ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
 
@@ -85,16 +84,6 @@
         SummonLineupObjs(self, self.faction, self.num, lineupInfo, self.getPlayerID())
         return
     
-    def resetLineup(self, isReborn=True):
-        ## 重置阵容
-        batObjMgr = BattleObj.GetBatObjMgr()
-        for objID in self.posObjIDDict.values():
-            batObj = batObjMgr.getBatObj(objID)
-            if not batObj:
-                continue
-            batObj.ResetBatObj(isReborn)
-        return
-    
     def clearLineup(self):
         ## 清除阵容
         if not self.posObjIDDict:
@@ -125,12 +114,6 @@
             self.lineupDict[num] = lineup
         return lineup
     
-    def resetLineups(self):
-        ## 重置所有战斗阵容
-        for lineup in self.lineupDict.values():
-            lineup.resetLineup()
-        return
-    
     def clearLineups(self):
         ## 清除所有战斗阵容
         for lineup in self.lineupDict.values():
@@ -154,6 +137,7 @@
         self.curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if playerID else None
         self.mapID = mapID
         self.funcLineID = funcLineID
+        self.state = -1 # -1 代表未战斗
         self.turnNum = 1 # 当前第x回合,默认第1回合开始
         self.turnMax = 15 # 最大回合数
         self.enterLogic = False # 是否已执行进场逻辑
@@ -195,21 +179,15 @@
         self.costTime = 0
         return
     
-    def setFactionLineup(self, faction, lineupDict, onlyReset=False):
+    def setFactionLineup(self, faction, lineupDict):
         ## 设置阵营阵容
         # @param lineupDict: {阵容编号:阵容信息, ...} 每个阵营支持多个阵容,即支持多V多
-        # @param onlyReset: 是否仅重置,一般用于玩家的阵容,重复利用阵容实例,
         batFaction = self.getBatFaction(faction)
-        if onlyReset:
-            batFaction.resetLineups()
-        else:
-            batFaction.clearLineups()
+        batFaction.clearLineups()
         for num, lineupInfo in lineupDict.items():
-            batLineup = batFaction.getBatlineup(num)
-            if onlyReset and not batLineup.isEmpty():
-                continue
             if not lineupInfo:
                 continue
+            batLineup = batFaction.getBatlineup(num)
             batLineup.setLineup(lineupInfo)
         return
     
@@ -274,16 +252,21 @@
             
         return 0
     
-    def clearBatFaction(self, faction):
-        batFaction = self.getBatFaction(faction)
-        batFaction.clearLineups()
-        return
-    
-    def clearFight(self):
+    def exitFight(self):
+        ## 退出战斗
         self.syncState(FightState_Over)
         for batFaction in self.factionDict.values():
             batFaction.clearLineups()
+        self.state = -1
         return
+    
+    def startFight(self):
+        ## 准备就绪,开始战斗
+        self.state = FightState_Start
+        self.syncInit()
+        return
+    
+    def isInFight(self): return self.state != -1
     
     def syncInit(self):
         ## 初始化通知
@@ -336,6 +319,7 @@
         return
     
     def syncState(self, state, msgDict={}):
+        self.state = state
         msg = json.dumps(msgDict, ensure_ascii=False)
         msg = msg.replace(" ", "")
         clientPack = ChPyNetSendPack.tagMCTurnFightState()
@@ -390,7 +374,7 @@
         turnFight = self.getTurnFight(guid)
         if not turnFight:
             return
-        turnFight.clearFight()
+        turnFight.exitFight()
         self.turnFightDict.pop(guid, None)
         return
     
@@ -590,8 +574,7 @@
             batObj.SetNPCID(npcID)
         elif lineupPlayerID:
             batObj.SetOwnerHero(lineupPlayerID, heroID, skinID)
-        batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
-        
+            
         if atkDistType == ChConfig.AtkDistType_Short:
             atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
         elif atkDistType == ChConfig.AtkDistType_Long:
@@ -604,8 +587,8 @@
             skillManager.LearnSkillByID(skillID)
             
         batLineup.posObjIDDict[posNum] = objID
-        GameWorld.DebugLog("AddBatObj ID:%s,faction:%s,num=%s,posNum=%s,skill=%s,atk=%s,def=%s,hp=%s" 
-                           % (objID, faction, num, posNum, skillIDList, batObj.GetAtk(), batObj.GetDef(), batObj.GetHP()))
+        GameWorld.DebugLog("AddBatObj ID:%s,faction:%s,num=%s,posNum=%s,skill=%s" % (objID, faction, num, posNum, skillIDList))
+        batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
         
     return
 
@@ -636,7 +619,7 @@
     if reqType == 2: # 前端主动请求开始关卡小怪的视为从休息中开始
         __doMainLevelWave(curPlayer, True)
     elif reqType == 3:
-        __doMainBossStart(curPlayer, tick)
+        __doMainBossStart(curPlayer)
     elif reqType == 4:
         __doMainFight(curPlayer, tick)
     else:
@@ -652,7 +635,7 @@
     mainFightMgr = GetMainFightMgr(curPlayer)
     turnFight = mainFightMgr.turnFight
     if turnFight:
-        turnFight.clearFight()
+        turnFight.exitFight()
     return
 
 def __doSetFightPoint(curPlayer, fightPoint):
@@ -735,13 +718,13 @@
     
     turnFight = mainFightMgr.turnFight
     turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
-    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
+    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
     turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
     turnFight.sortActionQueue()
-    turnFight.syncInit()
+    turnFight.startFight()
     return
 
-def __doMainBossStart(curPlayer, tick):
+def __doMainBossStart(curPlayer):
     ## 开始挑战关卡boss
     playerID = curPlayer.GetPlayerID()
     chapterID, levelNum, wave = PlayerControl.GetMainLevelPassInfo(curPlayer)
@@ -809,17 +792,27 @@
     
     turnFight = mainFightMgr.turnFight
     turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
-    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
+    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
     turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
     turnFight.sortActionQueue()
-    turnFight.syncInit()
+    turnFight.startFight()
     
     # 挑战boss无中间过程,每次执行直接挑战一队结果
-    __processTurnFight(turnFight.guid, tick)
+    __processTurnFight(turnFight.guid)
     return
 
 def __doMainFight(curPlayer, tick):
     ## 主线执行战斗
+    
+    # 限制请求CD
+    #if not GameWorld.GetGameWorld().GetDebugLevel():
+    key = "MainFightReqTick"
+    lastTick = curPlayer.GetDictByKey(key)
+    if lastTick and tick - lastTick <= 1000:
+        GameWorld.DebugLog("主线战斗请求CD中")
+        return
+    curPlayer.SetDict(key, tick)
+    
     mainFightMgr = GetMainFightMgr(curPlayer)
     turnFight = mainFightMgr.turnFight
     
@@ -840,11 +833,11 @@
             # 切换小队时,玩家阵容不需要处理,保留状态
             turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
             turnFight.sortActionQueue()
-            turnFight.syncInit()
+            turnFight.startFight()
             
             if mainFightMgr.isLevelBoss():
                 # 每次处理一小队的完整战斗,相当于一次完整战报
-                __processTurnFight(turnFight.guid, tick)
+                __processTurnFight(turnFight.guid)
                 return
         else:
             __doMainLevelWave(curPlayer, False)
@@ -975,7 +968,7 @@
             
     return
 
-def __processTurnFight(guid, tick):
+def __processTurnFight(guid):
     ## 一次性处理完一个小队的战斗
     turnFight = GetTurnFightMgr().getTurnFight(guid)
     curPlayer = turnFight.curPlayer
@@ -1052,24 +1045,6 @@
         OnTurnAllOver(turnFight.guid)
     return
 
-#// B4 10 回合制战斗 #tagCMTurnFight
-#
-#struct    tagCMTurnFight
-#{
-#    tagHead        Head;
-#    DWORD        MapID;        // 自定义地图ID,可用于绑定战斗地图场景功能(如主线关卡、主线boss、爬塔、竞技场等)
-#    DWORD        FuncLineID;    // MapID对应的扩展值,如具体某个关卡等
-#    BYTE        TagType;    // 目标类型,0-NPC阵容,1-玩家
-#    DWORD        TagID;    // 目标类型对应的ID,如阵容ID或玩家ID
-#    BYTE        ValueCount;
-#    DWORD        ValueList[ValueCount]; // 附加值列表,可选,具体含义由MapID决定
-#};
-def OnTurnFight(index, clientData, tick):
-    #curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-    #mapID = clientData.MapID
-    #funcLineID = clientData.FuncLineID
-    return
-
 def GetObjName(batObj):
     faction = batObj.faction
     num = batObj.lineupNum
@@ -1100,20 +1075,21 @@
     curID = batObj.GetID()
     buffMgr = batObj.GetBuffManager()
     GameWorld.DebugLog("更新buff: curID=%s,buffCount=%s" % (curID, buffMgr.GetBuffCount()))
-    for index in range(buffMgr.GetBuffCount()):
+    for index in range(buffMgr.GetBuffCount())[::-1]:
         buff = buffMgr.GetBuffByIndex(index)
         curRemainTime = buff.GetRemainTime()
         if not curRemainTime:
             # 永久buff不处理
             continue
         buffID = buff.GetBuffID()
+        skillID = buff.GetSkillID()
         updRemainTime = curRemainTime - 1
-        GameWorld.DebugLog("    更新buff剩余回合数: buffID=%s,updRemainTime=%s" % (buffID, updRemainTime))
+        GameWorld.DebugLog("    更新buff剩余回合数: buffID=%s,skillID=%s,updRemainTime=%s" % (buffID, skillID, updRemainTime))
         if updRemainTime > 0:
-            buff.SetRemainTime(curRemainTime - 1)
+            buff.SetRemainTime(updRemainTime)
             TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
         else:
-            TurnBuff.SyncBuffDel(turnFight, batObj, buffID)
+            TurnBuff.DoBuffDel(turnFight, batObj, buff)
             
 #    SetTimeline(gameObj, turnNum, 0)
 #    # 重置连击、反击数
@@ -1208,10 +1184,11 @@
         GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
         return
     
-    GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
+    atk = curBatObj.GetAtk()
+    curXP = curBatObj.GetXP()
+    GameWorld.DebugLog("★回合%s %s 行动 : atk=%s,curHP=%s/%s,curXP=%s" % (turnNum, objName, atk, curHP, curBatObj.GetMaxHP(), curXP))
     turnFight.syncObjAction(turnNum, objID)
     
-    curXP = curBatObj.GetXP()
     xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2) 
     skillManager = curBatObj.GetSkillManager()
     useSkillList = []

--
Gitblit v1.8.0