From 4ff284edf33cbbfcb123e2ba01dead78793e9dc8 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 11 十二月 2023 16:47:01 +0800
Subject: [PATCH] 10019 【砍树】回合战斗(每回合攻击顺序改为按攻击速度倒序;每个阵营支持多个战斗实例)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py |  171 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 101 insertions(+), 70 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 375d744..d35b9d4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -77,10 +77,29 @@
 
 def DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick):
     playerID = curPlayer.GetPlayerID()
+    posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
+    
+    factionListA, factionListB = [], []
+    factionListA.append(curPlayer)
+    curPet = curPlayer.GetPetMgr().GetFightPet()
+    curPet and factionListA.append(curPet)
+    
+    # 玩家阵营的其他战斗实例,可扩展...
+    assistNPCID = 0 # 协助召唤兽
+    if assistNPCID:
+        assistNPC = NPCCommon.SummonNPC(curPlayer, assistNPCID, posX, posY)
+        assistNPC and factionListA.append(assistNPC)
+        
     tagObj = None
     if tagPlayerID:
         npcID = ChConfig.Def_NPCID_PVP
-        tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID, pvpPlayerID=tagPlayerID)
+        tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID, pvpPlayerID=tagPlayerID)
+        if not tagObj:
+            return
+        factionListB.append(tagObj)
+        
+        # 对手玩家镜像的其他战斗实例...
+        
     else:
         ipyData = IpyGameDataPY.GetIpyGameData("FBTurn", mapID, funcLineID)
         if not ipyData:
@@ -88,91 +107,83 @@
         npcID = ipyData.GetNPCID()
         if not npcID:
             return
-        tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID)
-        
-    if not tagObj:
+        tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID)
+        if not tagObj:
+            return
+        factionListB.append(tagObj)
+        summerNPCID = ipyData.GetSummerNPCID()
+        if summerNPCID:
+            summerNPC = NPCCommon.SummonNPC(tagObj, summerNPCID, posX, posY)
+            summerNPC and factionListB.append(summerNPC)
+            
+    if not factionListB:
         return
     
-    turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1)
-    curPet = curPlayer.GetPetMgr().GetFightPet()
-    tagPet = None
+    for gameObj in factionListA:
+        GameObj.SetFaction(gameObj, 1)
+    for gameObj in factionListB:
+        GameObj.SetFaction(gameObj, 2)
+        
+    #一个回合攻击顺序,由攻击速度决定,攻速相同下阵营1先攻击,还相同则由ID决定
+    fightObjList = factionListA + factionListB
+    fightObjList.sort(key=lambda o: (GameObj.GetAtkSpeed(o), (10 - GameObj.GetFaction(o)), o.GetID()), reverse=True)
     
+    turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1)
     GameWorld.DebugLog("===== 执行回合制战斗: mapID=%s,funcLineID=%s,tagPlayerID=%s,tagObjID=%s" 
                        % (mapID, funcLineID, tagPlayerID, tagObj.GetID()), playerID)
-    GameWorld.DebugLog("curPlayer.GetSightLevel=%s,tagObj.GetSightLevel=%s" 
-                       % (curPlayer.GetSightLevel(), tagObj.GetSightLevel()), playerID)
-        
-    #一个回合攻击顺序
-    #1. 快方宠物攻击,不存在跳过
-    #2. 慢方宠物攻击,不存在跳过
-    #3. 快方主体攻击
-    #4. 慢方主体攻击
-    
     # 战斗前初始化
-    factionObjMax = 0 # 某个阵营的最大战斗实例数
-    factionObjDict = {1:[curPet, curPlayer], 2:[tagPet, tagObj]}
-    for objList in factionObjDict.values():
-        if factionObjMax < len(objList):
-            factionObjMax = len(objList)
-        for gameObj in objList:
-            TurnFightObjStartInit(gameObj)
-            
-    curAtkSpeed = GameObj.GetAtkSpeed(curPlayer)
-    tagAtkSpeed = GameObj.GetAtkSpeed(tagObj)
-    orderList = [1, 2] if curAtkSpeed >= tagAtkSpeed else [2, 1]
-    GameWorld.DebugLog("playerHP=%s,tagHP=%s,curAtkSpeed=%s,tagAtkSpeed=%s" 
-                       % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj), curAtkSpeed, tagAtkSpeed), playerID)
-    
+    for gameObj in fightObjList:
+        TurnFightObjStartInit(gameObj)
+        
     isWin = None
     for turnNum in range(1, turnMax + 1):
         GameWorld.DebugLog("----- 回合制战斗轮次: %s -----" % turnNum, playerID)
         SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Fighting, turnNum, turnMax)
         
         # 回合开始: 做一些每回合重置逻辑或者某些根据回合触发的效果等
-        for objList in factionObjDict.values():
-            for gameObj in objList:
-                TurnFightObjTurnStart(gameObj, turnNum)
-                
+        for gameObj in fightObjList:
+            TurnFightObjPerTurnStart(gameObj, turnNum)
+            
         # 回合战斗: 轮流依次攻击
-        for index in range(factionObjMax):
-            for faction in orderList:
-                objList = factionObjDict[faction]
-                if index >= len(objList):
-                    continue
-                gameObj = objList[index]
-                if not gameObj:
-                    continue
-                
-                tagGameObj = tagObj if faction == 1 else curPlayer
-                objType = gameObj.GetGameObjType()
-                objID = gameObj.GetID()
-                tagObjType = tagGameObj.GetGameObjType()
-                tagObjID = tagGameObj.GetID()
-                
-                GameWorld.DebugLog("    行动: turnNum=%s,index=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s" 
-                                   % (turnNum, index, faction, objType, objID, tagObjType, tagObjID), playerID)
-                DoAttack(gameObj, tagGameObj, tick)
-                
-                if tagGameObj and GameObj.GetHP(tagGameObj) > 0:
-                    continue
-                
-                isWin = faction == 1
-                GameWorld.DebugLog("        tagObjType=%s,tagObjID=%s,被击杀,结束战斗: isWin=%s" % (tagObjType, tagObjID, isWin))
-                break
+        for actNum, gameObj in enumerate(fightObjList, 1):
+            if not gameObj:
+                continue
+            faction = GameObj.GetFaction(gameObj)
+            tagGameObj = tagObj if faction == 1 else curPlayer
+            objType = gameObj.GetGameObjType()
+            objID = gameObj.GetID()
+            tagObjType = tagGameObj.GetGameObjType()
+            tagObjID = tagGameObj.GetID()
             
-            if isWin != None:
-                break
+            GameWorld.DebugLog("    行动: turnNum=%s,actNum=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s" 
+                               % (turnNum, actNum, faction, objType, objID, tagObjType, tagObjID), playerID)
+            DoAttack(gameObj, tagGameObj, tick)
             
+            playerDead = GameObj.GetHP(curPlayer) <= 0
+            tagObjDead = (not tagObj or GameObj.GetHP(tagObj) <= 0)
+            if not playerDead and not tagObjDead:
+                continue
+            
+            if playerDead and tagObjDead:
+                isWin = False # 平局算失败
+                GameWorld.DebugLog("        双方被击杀,平局算失败: isWin=%s" % isWin)
+            elif playerDead:
+                isWin = False
+                GameWorld.DebugLog("        玩家被击杀,失败: isWin=%s" % isWin)
+            elif tagObjDead:
+                isWin = True # 胜利
+                GameWorld.DebugLog("        对手被击杀,胜利: isWin=%s" % isWin)
+            break
+        
         if isWin != None:
             break
         
     overState = FightState_Win if isWin else FightState_Fail
     SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, overState, turnNum, turnMax)
     
-    for objList in factionObjDict.values():
-        for gameObj in objList:
-            TurnFightObjOverReset(gameObj)
-            
+    for gameObj in fightObjList:
+        TurnFightObjOverReset(gameObj)
+        
     GameWorld.DebugLog("===== 回合制战斗结束: mapID=%s,funcLineID=%s,tagPlayerID=%s,isWin=%s,overState=%s" 
                        % (mapID, funcLineID, tagPlayerID, isWin, overState), playerID)
     return
@@ -187,6 +198,10 @@
     gameObj.RefreshView()
     
     objType = gameObj.GetGameObjType()
+    npcID = gameObj.GetNPCID() if objType == IPY_GameWorld.gotNPC else 0
+    GameWorld.DebugLog("    初始化实例: objID=%s,npcID=%s,faction=%s,atkSpeed=%s,HP=%s" 
+                       % (gameObj.GetID(), npcID, GameObj.GetFaction(gameObj), GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj)))
+    
     # 重置技能CD、战斗buff
     if objType == IPY_GameWorld.gotPlayer:            
         skillManager = gameObj.GetSkillManager()
@@ -198,7 +213,7 @@
         pass
     return
 
-def TurnFightObjTurnStart(gameObj, turnNum):
+def TurnFightObjPerTurnStart(gameObj, turnNum):
     ## 回合制战斗实例 - 每回合开始时处理
     if not gameObj:
         return
@@ -223,18 +238,34 @@
         return
     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 0)
     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0)
+    GameObj.SetFaction(gameObj, 0)
     
     objType = gameObj.GetGameObjType()
     if objType == IPY_GameWorld.gotPlayer:
         pass
     
     elif objType == IPY_GameWorld.gotNPC:
-        npcObjType = gameObj.GetGameNPCObjType()
-        if npcObjType != IPY_GameWorld.gnotPet and GameObj.GetHP(gameObj):
-            NPCCommon.SetDeadEx(gameObj)
-            
+        RecycleObj(gameObj)
     return
 
+def RecycleObj(gameObj):
+    npcObjType = gameObj.GetGameNPCObjType()
+    if npcObjType == IPY_GameWorld.gnotPet:
+        #GameWorld.DebugLog("RecycleObj 灵宠不回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
+        return
+    if npcObjType == IPY_GameWorld.gnotSummon:
+        curOwner = NPCCommon.GetSummonOwnerDetel(gameObj)
+        if curOwner and curOwner.GetGameObjType() == IPY_GameWorld.gotNPC:
+            #GameWorld.DebugLog("RecycleObj 召唤兽主人是NPC不回收 objID=%s,npcObjType=%s,%s,ownerID=%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID(), curOwner.GetID()))
+            return
+    if GameObj.GetHP(gameObj) <= 0:
+        #GameWorld.DebugLog("RecycleObj 已死亡,不用重复回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
+        return
+    #GameWorld.DebugLog("RecycleObj: objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
+    NPCCommon.SetDeadEx(gameObj)
+    return
+
+
 def DoAttack(curObj, tagObj, tick):
     curID = curObj.GetID()
     tagID = tagObj.GetID()

--
Gitblit v1.8.0