| | |
| | | import PyGameData
|
| | | import GameWorld
|
| | | import ChConfig
|
| | | import ObjPool
|
| | | import random
|
| | |
|
| | | # 记录攻击类型
|
| | |
| | | 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]
|
| | |
| | | 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:
|
| | |
| | | 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
|
| | |
| | |
|
| | | 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:
|
| | |
| | | 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()
|
| | |
| | | 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
|