From 0c3ef8a641c968e6a2f51abeb84f890342e4cb0c Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 15 十二月 2025 11:42:13 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(优化效果6011可指定检查自己还是检查目标的buff;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py |  200 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 130 insertions(+), 70 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
index 76ecda7..90ef549 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
@@ -28,7 +28,6 @@
 import PyGameData
 import GameWorld
 import ChConfig
-import ObjPool
 import random
 
 # 记录攻击类型
@@ -215,12 +214,12 @@
     playerID = curPlayer.GetPlayerID()
     playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
     matchScoreList = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 1)
+    needMatchCount = len(matchScoreList)
     
     GameWorld.DebugLog("竞技场玩家刷新匹配列表: isRefresh=%s,playerScore=%s,gmMatchIDList=%s,isSys=%s" % (isRefresh, playerScore, gmMatchIDList, isSys), playerID)
-    GameWorld.DebugLog("    matchScoreList=%s" % (matchScoreList), playerID)
+    GameWorld.DebugLog("needMatchCount=%s,matchScoreList=%s" % (needMatchCount, matchScoreList), playerID)
     
     # 匹配对象缓存
-    needMatchCount = len(matchScoreList)
     if playerID not in PyGameData.g_arenaPlayerMatchDict:
         PyGameData.g_arenaPlayerMatchDict[playerID] = []
     matchIDList = PyGameData.g_arenaPlayerMatchDict[playerID]
@@ -236,69 +235,124 @@
         if not costMoney or not moneyValue or not PlayerControl.PayMoney(curPlayer, costMoney, moneyValue, "Arena"):
             return
         
-    billboardMgr = DBDataMgr.GetBillboardMgr()
-    billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
-    if not billBoard:
-        return
-    maxOrder = billBoard.GetCount()
-    playerOrder = billBoard.IndexOfByID(playerID) + 1  # 玩家在排行榜中的名次,没有名次为-1
-    
-    matchRobotCntDict = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 3)
-    if playerOrder > 0:
-        matchRobotRange = GameWorld.GetOrderValueByDict(matchRobotCntDict, playerOrder)
-        matchRobotCnt = random.randint(matchRobotRange[0], matchRobotRange[1])
-    else:
-        matchRobotCnt = needMatchCount
-    matchPlayerCnt = needMatchCount - matchRobotCnt
-    GameWorld.DebugLog("    maxOrder=%s,playerOrder=%s,matchRobotCnt=%s,matchPlayerCnt=%s" % (maxOrder, playerOrder, matchRobotCnt, matchPlayerCnt), playerID)
-    
-    fromLowerCnt, matchPerRank = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 2)
-    toOrder = playerOrder + fromLowerCnt * matchPerRank # 从低名次往高名次匹配
-    GameWorld.DebugLog("    fromLowerCnt=%s,matchPerRank=%s,toOrder=%s" % (fromLowerCnt, matchPerRank, toOrder), playerID)
+    matchIDList = [] # 最终匹配的玩家ID列表
     matchOrderList = [] # 匹配到的名次
     viewCacheDict = {}
-    for _ in range(matchPlayerCnt):
-        fromOrder = max(1, toOrder - matchPerRank)
-        if toOrder <= fromOrder:
-            break
-        orderList = range(fromOrder, toOrder)
-        random.shuffle(orderList)
-        if playerOrder in orderList:
-            orderList.remove(playerOrder) # 不包含自己
-        if not orderList:
-            break
-        
-        for order in orderList:
-            if order > maxOrder:
+    
+    robotFPCoefficient =  IpyGameDataPY.GetFuncCfg("ArenaMatchRobot", 1) # 必定匹配机器人的玩家战力系数,玩家战力*该系数<=机器人最高战力时必定匹配机器人
+    playerFightPower = PlayerControl.GetFightPower(curPlayer)
+    robotFPSortList = PlayerViewCache.GetRobotFightPowerSortList()
+    robotFightPowerMax = robotFPSortList[0][0] if robotFPSortList else 0
+    robotCntTotal = len(robotFPSortList)
+    GameWorld.DebugLog("玩家战力=%s,机器人最大战力=%s,匹配机器人战力系数=%s,机器人总数=%s" 
+                       % (playerFightPower, robotFightPowerMax, robotFPCoefficient, robotCntTotal), playerID)
+    reFightPower = playerFightPower * robotFPCoefficient # 参考战力
+    if reFightPower <= robotFightPowerMax:
+        # 匹配机器人相对玩家战力百分比范围列表  [[相对玩家战力百分比A, B], ..],支持负数,如-30就是机器人比玩家低30%战力,10就是机器人比玩家高10%战力
+        matchRobotFPPerList = IpyGameDataPY.GetFuncEvalCfg("ArenaMatchRobot", 2)
+        GameWorld.DebugLog("全部匹配机器人: %s, reFightPower=%s <= %s" % (matchRobotFPPerList, reFightPower, robotFightPowerMax), playerID)
+        loopIndex = 0
+        for fpPerRange in matchRobotFPPerList[::-1]: # 从高战力往低战力匹配
+            fpPerA, fpPerB = fpPerRange
+            GameWorld.DebugLog("    处理匹配机器人战力段: fpPerA=%s,fpPerB=%s,loopIndex=%s" % (fpPerA, fpPerB, loopIndex), playerID)
+            if loopIndex >= robotCntTotal:
                 continue
-            billData = billBoard.At(order - 1)
-            tagID = billData.GetID()
-            viewCache = PlayerViewCache.FindBattleViewCache(tagID)
-            if not viewCache:
-                GameWorld.DebugLog("    无战斗缓存的玩家不匹配: tagID=%s,order=%s,fromOrder=%s,toOrder=%s" % (tagID, order, fromOrder, toOrder), playerID)
-                continue
-            matchOrderList.append(order)
-            viewCacheDict[tagID] = viewCache
-            
-            if fromOrder == 1:
-                if len(matchOrderList) >= matchPlayerCnt:
+            robotFPIDList = []
+            for robotIndex in range(loopIndex, robotCntTotal):
+                robotFightPower, robotID = robotFPSortList[robotIndex]
+                fpPer = (robotFightPower / float(playerFightPower) - 1) * 100
+                if fpPer < fpPerA:
+                    GameWorld.DebugLog("        比低百分比还小的战力跳出,进入下一段匹配逻辑: %s,robotID=%s,robotFightPower=%s,fpPer=%s < %s" 
+                                       % (robotIndex, robotID, robotFightPower, fpPer, fpPerA), playerID)
                     break
-            else:
+                loopIndex = robotIndex + 1
+                if fpPer > fpPerB:
+                    #GameWorld.DebugLog("        比高百分比还大的战力跳过,不匹配: %s,robotID=%s,robotFightPower=%s,fpPer=%s > %s" 
+                    #                   % (robotIndex, robotID, robotFightPower, fpPer, fpPerB), playerID)
+                    continue
+                robotFPIDList.append([robotFightPower, robotID])
+                #GameWorld.DebugLog("        战力在匹配段范围内,可匹配: %s,robotID=%s,robotFightPower=%s,%s <= fpPer(%s) <= %s" 
+                #                   % (robotIndex, robotID, robotFightPower, fpPerA, fpPer, fpPerB), playerID)
+                
+            if not robotFPIDList:
+                GameWorld.DebugLog("        该战力范围段没有符合的机器人!", playerID)
+                continue
+            random.shuffle(robotFPIDList)
+            robotFightPower, robotID = robotFPIDList[0]
+            matchIDList.append(robotID)
+            GameWorld.DebugLog("        匹配机器人: robotID=%s,robotFightPower=%s" % (robotID, robotFightPower), playerID)
+            
+        if len(matchIDList) < needMatchCount:
+            GameWorld.DebugLog("    可匹配的机器人还不够,从剩下未遍历的机器人内匹配: loopIndex=%s" % loopIndex, playerID)
+            if loopIndex < robotCntTotal:
+                randIndexList = range(loopIndex, robotCntTotal)
+                random.shuffle(randIndexList)
+                matchIndexList = randIndexList[:needMatchCount-len(matchIDList)]
+                matchIndexList.sort()
+                for robotIndex in matchIndexList:
+                    robotFightPower, robotID = robotFPSortList[robotIndex]
+                    matchIDList.append(robotID)
+                    GameWorld.DebugLog("        匹配机器人: robotID=%s,robotFightPower=%s" % (robotID, robotFightPower), playerID)
+                    
+    else:
+        # 匹配真人
+        GameWorld.DebugLog("匹配真人: reFightPower=%s > %s" % (reFightPower, robotFightPowerMax), playerID)
+        billboardMgr = DBDataMgr.GetBillboardMgr()
+        billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
+        if not billBoard:
+            return
+        
+        maxOrder = billBoard.GetCount()
+        playerOrder = billBoard.IndexOfByID(playerID) + 1  # 玩家在排行榜中的名次,没有名次为-1
+        leastRobotCnt = IpyGameDataPY.GetFuncCfg("ArenaMatchRobot", 3)
+        matchPlayerCnt = needMatchCount - leastRobotCnt
+        GameWorld.DebugLog("    maxOrder=%s,playerOrder=%s,matchPlayerCnt=%s,leastRobotCnt=%s" % (maxOrder, playerOrder, matchPlayerCnt, leastRobotCnt), playerID)
+        
+        fromLowerCnt, matchPerRank = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 2)
+        toOrder = playerOrder + fromLowerCnt * matchPerRank # 从低名次往高名次匹配
+        GameWorld.DebugLog("    fromLowerCnt=%s,matchPerRank=%s,toOrder=%s" % (fromLowerCnt, matchPerRank, toOrder), playerID)
+        
+        for _ in range(matchPlayerCnt):
+            fromOrder = max(1, toOrder - matchPerRank)
+            if toOrder <= fromOrder:
+                break
+            orderList = range(fromOrder, toOrder)
+            random.shuffle(orderList)
+            if playerOrder in orderList:
+                orderList.remove(playerOrder) # 不包含自己
+            if not orderList:
                 break
             
-        GameWorld.DebugLog("    匹配玩家: fromOrder=%s,toOrder=%s,matchOrderList=%s" % (fromOrder, toOrder, matchOrderList), playerID)
-        toOrder = fromOrder - 1
+            for order in orderList:
+                if order > maxOrder:
+                    continue
+                billData = billBoard.At(order - 1)
+                tagID = billData.GetID()
+                viewCache = PlayerViewCache.FindBattleViewCache(tagID)
+                if not viewCache:
+                    GameWorld.DebugLog("    无战斗缓存的玩家不匹配: tagID=%s,order=%s,fromOrder=%s,toOrder=%s" % (tagID, order, fromOrder, toOrder), playerID)
+                    continue
+                matchOrderList.append(order)
+                viewCacheDict[tagID] = viewCache
+                
+                if fromOrder == 1:
+                    if len(matchOrderList) >= matchPlayerCnt:
+                        break
+                else:
+                    break
+                
+            GameWorld.DebugLog("    匹配玩家: fromOrder=%s,toOrder=%s,matchOrderList=%s" % (fromOrder, toOrder, matchOrderList), playerID)
+            toOrder = fromOrder - 1
+            
+        matchOrderList.sort()
+        for matchOrder in matchOrderList:
+            if matchOrder > maxOrder or matchOrder <= 0:
+                break
+            billData = billBoard.At(matchOrder - 1)
+            tagID = billData.GetID()
+            matchIDList.append(tagID)
+        GameWorld.DebugLog("    匹配榜单结果: matchIDList=%s,matchOrderList=%s" % (matchIDList, matchOrderList), playerID)
         
-    matchOrderList.sort()
-    matchIDList = [] # 最终匹配的玩家ID列表
-    for matchOrder in matchOrderList:
-        if matchOrder > maxOrder or matchOrder <= 0:
-            break
-        billData = billBoard.At(matchOrder - 1)
-        tagID = billData.GetID()
-        matchIDList.append(tagID)
-    GameWorld.DebugLog("    匹配榜单结果: matchIDList=%s,matchOrderList=%s" % (matchIDList, matchOrderList), playerID)
-    
     # GM指定匹配测试
     if gmMatchIDList != None and curPlayer.GetGMLevel():
         for gmMatchID in gmMatchIDList:
@@ -322,18 +376,24 @@
         GameWorld.DebugLog("    指定匹配结果: matchIDList=%s" % (matchIDList), playerID)
         
     needRobotCnt = needMatchCount - len(matchIDList)
-    GameWorld.DebugLog("    还需机器人数=%s" % (needRobotCnt), playerID)
-    ipyDataMgr = IpyGameDataPY.IPY_Data()
-    robotMax = ipyDataMgr.GetRobotCount()
+    GameWorld.DebugLog("    最终还需机器人数=%s" % (needRobotCnt), playerID)
+    robotFPIDList = []
     doCnt = 100
-    while doCnt > 0 and needRobotCnt > 0 and robotMax:
+    while doCnt > 0 and needRobotCnt > 0 and robotCntTotal:
         doCnt -= 1
-        robotIndex = random.randint(0, robotMax - 1)
-        robotIpyData = ipyDataMgr.GetRobotByIndex(robotIndex)
-        robotID = robotIpyData.GetID()
+        robotIndex = random.randint(0, robotCntTotal - 1)
+        robotFightPower, robotID = robotFPSortList[robotIndex]
         if robotID not in matchIDList:
             matchIDList.append(robotID)
+            robotFPIDList.append([robotFightPower, robotID])
             needRobotCnt -= 1
+    if robotFPIDList:
+        robotFPIDList.sort(reverse=True)
+        #GameWorld.DebugLog("    补充机器人战力ID排序=%s" % (robotFPIDList), playerID)
+        for _, robotID in robotFPIDList:
+            if robotID in matchIDList:
+                matchIDList.remove(robotID)
+                matchIDList.append(robotID)
     GameWorld.DebugLog("    最终匹配结果: matchIDList=%s" % matchIDList, playerID)
     
     PyGameData.g_arenaPlayerMatchDict[playerID] = matchIDList
@@ -342,8 +402,7 @@
 
 def __SyncMatchList(curPlayer, matchIDList, viewCacheDict={}):
     ## 同步匹配列表
-    objPool = ObjPool.GetPoolMgr()
-    clientPack = objPool.acquire(ChPyNetSendPack.tagSCArenaMatchList)
+    clientPack = ChPyNetSendPack.tagSCArenaMatchList()
     clientPack.MatchList = []
     for matchID in matchIDList:
         if matchID in viewCacheDict:
@@ -352,7 +411,7 @@
             viewCache = PlayerViewCache.FindBattleViewCache(matchID)
         if not viewCache:
             continue
-        matchInfo = objPool.acquire(ChPyNetSendPack.tagSCArenaMatchInfo)
+        matchInfo = ChPyNetSendPack.tagSCArenaMatchInfo()
         matchInfo.PlayerID = matchID
         if viewCache:
             matchInfo.PlayerName = viewCache.GetPlayerName()
@@ -371,7 +430,8 @@
     return
 
 def Sync_ArenaInfo(curPlayer):
-    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCArenaPlayerInfo)
+    clientPack = ChPyNetSendPack.tagSCArenaPlayerInfo()
     clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
+    clientPack.WinCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaWinCnt)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return

--
Gitblit v1.8.0